diff --git a/src/device/vi.rs b/src/device/vi.rs index 470498c..23c73c3 100644 --- a/src/device/vi.rs +++ b/src/device/vi.rs @@ -103,7 +103,9 @@ pub fn write_regs(device: &mut device::Device, address: u64, value: u32, mask: u if device.netplay.is_none() { savestates::process_savestates(device); } - let _ = device.ui.video.fps_tx.as_ref().unwrap().try_send(true); + if !netplay::in_rollback(device.netplay.as_ref()) { + let _ = device.ui.video.fps_tx.as_ref().unwrap().try_send(true); + } } } _ => { @@ -114,7 +116,9 @@ pub fn write_regs(device: &mut device::Device, address: u64, value: u32, mask: u } pub fn update_screen(device: &mut device::Device) { - ui::video::render_frame(); + if !netplay::in_rollback(device.netplay.as_ref()) { + ui::video::render_frame(); + } let (speed_limiter_toggled, paused) = ui::video::check_callback(device); @@ -122,18 +126,22 @@ pub fn update_screen(device: &mut device::Device) { reset_pace_deadline(device); } - if device - .speed_limiter - .frame_counter - .is_multiple_of(device.speed_limiter.limit_freq) + if !netplay::in_rollback(device.netplay.as_ref()) + && device + .speed_limiter + .frame_counter + .is_multiple_of(device.speed_limiter.limit_freq) && device.speed_limiter.enabled { speed_limiter(device); } - unsafe { sdl3_sys::events::SDL_PumpEvents() }; - ui::video::update_screen(); - device.speed_limiter.frame_counter += 1; + if !netplay::in_rollback(device.netplay.as_ref()) { + unsafe { sdl3_sys::events::SDL_PumpEvents() }; + ui::video::update_screen(); + device.speed_limiter.frame_counter += 1; + let _ = device.ui.video.vis_tx.as_ref().unwrap().try_send(true); + } if device.netplay.is_some() { device.netplay.as_mut().unwrap().inputs = netplay::process_requests(device); @@ -156,8 +164,6 @@ pub fn vertical_interrupt_event(device: &mut device::Device) { cheats::execute_cheats(device, device.cheats.cheats.clone()); } - let _ = device.ui.video.vis_tx.as_ref().unwrap().try_send(true); - retroachievements::do_frame(); /* toggle vi field if in interlaced mode */ diff --git a/src/netplay.rs b/src/netplay.rs index 047d1ca..4bd2918 100644 --- a/src/netplay.rs +++ b/src/netplay.rs @@ -210,6 +210,22 @@ fn check_input_delay(netplay: &mut Netplay) { } } +fn pending_frames(netplay: &Netplay) -> usize { + netplay + .requests + .iter() + .filter(|r| matches!(r, ggrs::GgrsRequest::AdvanceFrame { .. })) + .count() +} + +pub fn in_rollback(netplay: Option<&Netplay>) -> bool { + if let Some(netplay) = netplay { + pending_frames(netplay) != 0 + } else { + false + } +} + pub fn process_requests( device: &mut device::Device, ) -> Vec<(ui::input::InputData, ggrs::InputStatus)> { diff --git a/src/savestates.rs b/src/savestates.rs index 8bec72e..6664364 100644 --- a/src/savestates.rs +++ b/src/savestates.rs @@ -266,7 +266,9 @@ pub fn load_savestate(device: &mut device::Device, rewind: bool, rewind_frame: O if let Some(mut state) = state_data && device.rdram.size == state.device.rdram.size { - ui::video::idle(); + if device.netplay.is_none() { + ui::video::idle(); + } device.savestate.last_rewind_saved = state.device.vi.elapsed_time; diff --git a/src/ui/audio.rs b/src/ui/audio.rs index 17c0822..b5936dd 100644 --- a/src/ui/audio.rs +++ b/src/ui/audio.rs @@ -1,4 +1,5 @@ use crate::device; +use crate::netplay; use crate::ui; static ADJUST_LOCKED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false); @@ -174,6 +175,10 @@ pub fn play_audio(device: &device::Device, dram_addr: usize, length: u64) { return; } + if netplay::in_rollback(device.netplay.as_ref()) { + return; + } + let mut primary_buffer: Vec = vec![0; length as usize / 2]; let mut i = 0; while i < length as usize / 2 {