From 710d92cbdd726a469673d535076efb1bc0098fb7 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Tue, 17 Sep 2024 23:42:09 +1000 Subject: [PATCH] Force-enable coprocessor delayed-sync while creating a save-state. When making a save state, all the system components are "fast forwarded" to a safe state that can be serialised. If delayedSync (called "Coprocessor Fast Sync" in the UI) is enabled, this works perfectly. If it is disabled, the accurate coprocessor synching interferes with the save-state creation, leading to the game crashing or (worse) the emulator freezing. Star Fox is a good test case - repeatedly saving state and loading it will very quickly cause the game to run super-slowly, hang, or crash. Ideally, somebody should dig into exactly what coprocessor syncing is doing that breaks the assumptions of the state-saving code, but given how complex the whole thing is, and given that it doesn't affect hardware emulation accuracy (real hardware can't save states at all), it's easiest to just force- enable delayedSync while a save-state is in progress. Fix from the jgemu bsnes fork: https://gitlab.com/jgemu/bsnes/-/commit/8b4d1b8ae5b360bbb31aad260da0a160b5a5a758 --- bsnes/sfc/system/system.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bsnes/sfc/system/system.cpp b/bsnes/sfc/system/system.cpp index 27897f50..6a6f1992 100644 --- a/bsnes/sfc/system/system.cpp +++ b/bsnes/sfc/system/system.cpp @@ -15,6 +15,12 @@ auto System::run() -> void { } auto System::runToSave() -> void { + // Enable coprocessor delayed sync if it is off - this is extremely important + // for coprocessor games, as many will not sync correctly for states when the + // option is off. + bool delay_sync_prev = configuration.hacks.coprocessor.delayedSync; + configuration.hacks.coprocessor.delayedSync = true; + auto method = configuration.system.serialization.method; //these games will periodically deadlock when using "Fast" synchronization @@ -30,6 +36,9 @@ auto System::runToSave() -> void { scheduler.mode = Scheduler::Mode::Run; scheduler.active = cpu.thread; + + // Restore coprocessor delayed sync to whatever it was previous to the state save operation + configuration.hacks.coprocessor.delayedSync = delay_sync_prev; } auto System::runToSaveFast() -> void {