From cbc973a559848ab20b52fa9498923b9f797c0ba8 Mon Sep 17 00:00:00 2001 From: Logan McNaughton <848146+loganmc10@users.noreply.github.com> Date: Sun, 31 May 2026 22:25:28 +0200 Subject: [PATCH] idle RDP before load state (#1000) * idle RDP before load state * more --- build.rs | 1 + parallel-rdp/interface.cpp | 16 +++++++--------- parallel-rdp/interface.hpp | 3 ++- src/savestates.rs | 8 +++++++- src/ui/video.rs | 8 ++++++-- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/build.rs b/build.rs index 89f3ead..201a331 100644 --- a/build.rs +++ b/build.rs @@ -204,6 +204,7 @@ fn main() { .allowlist_function("rdp_check_callback") .allowlist_function("rdp_check_framebuffers") .allowlist_function("rdp_state_size") + .allowlist_function("rdp_idle") .allowlist_function("rdp_save_state") .allowlist_function("rdp_load_state") .allowlist_function("rdp_set_fps") diff --git a/parallel-rdp/interface.cpp b/parallel-rdp/interface.cpp index 00358d4..39c6a7f 100644 --- a/parallel-rdp/interface.cpp +++ b/parallel-rdp/interface.cpp @@ -702,19 +702,17 @@ void rdp_check_framebuffers(uint32_t address, uint32_t length) { size_t rdp_state_size() { return sizeof(RDP_DEVICE); } -void rdp_save_state(uint8_t *state, bool rewind) { - if (!rewind) { // speed hack for rewind - processor->idle(); - rdram_dirty.assign(gfx_info.RDRAM_SIZE >> 3, false); - sync_signal = 0; - } +void rdp_idle() { + processor->idle(); + rdram_dirty.assign(gfx_info.RDRAM_SIZE >> 3, false); + sync_signal = 0; +} + +void rdp_save_state(uint8_t *state) { memcpy(state, &rdp_device, sizeof(RDP_DEVICE)); } void rdp_load_state(GFX_INFO _gfx_info, const uint8_t *state) { - sync_signal = 0; - rdram_dirty.assign(gfx_info.RDRAM_SIZE >> 3, false); - gfx_info = _gfx_info; memcpy(&rdp_device, state, sizeof(RDP_DEVICE)); } diff --git a/parallel-rdp/interface.hpp b/parallel-rdp/interface.hpp index 2cc2384..310bd7c 100644 --- a/parallel-rdp/interface.hpp +++ b/parallel-rdp/interface.hpp @@ -61,7 +61,8 @@ uint64_t rdp_process_commands(); void rdp_onscreen_message(const char *message, MESSAGE_LENGTH milliseconds); void rdp_check_framebuffers(uint32_t address, uint32_t length); size_t rdp_state_size(); -void rdp_save_state(uint8_t *state, bool rewind); +void rdp_idle(); +void rdp_save_state(uint8_t *state); void rdp_load_state(GFX_INFO _gfx_info, const uint8_t *state); void rdp_set_fps(uint32_t fps, uint32_t vis); diff --git a/src/savestates.rs b/src/savestates.rs index 4868062..9782f46 100644 --- a/src/savestates.rs +++ b/src/savestates.rs @@ -111,8 +111,12 @@ pub fn process_savestates(device: &mut device::Device) { } fn create_savestate(device: &mut device::Device, rewind: bool) { + if !rewind { + // skipped on rewind as a speed hack + ui::video::idle(); // to flush the RDP so the RDRAM is updated + } let mut rdp_state: Vec = vec![0; ui::video::state_size()]; - ui::video::save_state(rdp_state.as_mut_ptr(), rewind); + ui::video::save_state(rdp_state.as_mut_ptr()); let mut ra_state: Vec = vec![0; retroachievements::state_size()]; retroachievements::save_state(ra_state.as_mut_ptr(), ra_state.len()); @@ -228,6 +232,8 @@ fn load_savestate(device: &mut device::Device, rewind: bool) { if let Some(mut state) = state_data && device.rdram.size == state.device.rdram.size { + ui::video::idle(); // to flush the RDP so it doesn't overwrite the RDRAM + device.savestate.last_rewind_saved = state.device.vi.elapsed_time; std::mem::swap(&mut device.ui.storage.saves, &mut state.saves); diff --git a/src/ui/video.rs b/src/ui/video.rs index ac9f212..62d1fb1 100644 --- a/src/ui/video.rs +++ b/src/ui/video.rs @@ -161,8 +161,12 @@ pub fn state_size() -> usize { unsafe { rdp_state_size() } } -pub fn save_state(rdp_state: *mut u8, rewind: bool) { - unsafe { rdp_save_state(rdp_state, rewind) } +pub fn save_state(rdp_state: *mut u8) { + unsafe { rdp_save_state(rdp_state) } +} + +pub fn idle() { + unsafe { rdp_idle() } } pub fn load_state(device: &mut device::Device, rdp_state: *const u8) {