From aff64d43d4ad9621532f33fdd70e0eccd1c2d2b2 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 11 Apr 2025 12:02:53 +0200 Subject: [PATCH] libretro: don't restart the emu in retro_serialize_size Stop the emu in retro_serialize_size and don't restart it until after the state is saved in retro_serialize. This avoids issues when the actual state size is greater than what retro_serialize_size returned. Issue #1885 --- shell/libretro/libretro.cpp | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/shell/libretro/libretro.cpp b/shell/libretro/libretro.cpp index 70a301e2a..a4bf1b0ab 100644 --- a/shell/libretro/libretro.cpp +++ b/shell/libretro/libretro.cpp @@ -1176,8 +1176,9 @@ void retro_run() glsm_ctl(GLSM_CTL_STATE_BIND, nullptr); #endif - // On the first call, we start the emulator - if (first_run) + if (!emu.running()) + // It could be the first time retro_run() is called, + // or it was paused in retro_serialize_size() and retro_serialize() was never called emu.start(); poll_cb(); @@ -2318,17 +2319,16 @@ size_t retro_serialize_size() DEBUG_LOG(SAVESTATE, "retro_serialize_size"); std::lock_guard lock(mtx_serialization); - if (!first_run) - try { - emu.stop(); - } catch (const FlycastException& e) { - ERROR_LOG(COMMON, "%s", e.what()); - return 0; - } + try { + emu.stop(); + } catch (const FlycastException& e) { + ERROR_LOG(COMMON, "%s", e.what()); + return 0; + } Serializer ser; dc_serialize(ser); - if (!first_run) + if (!first_run && ser.size() == 0) emu.start(); return ser.size(); @@ -2339,13 +2339,12 @@ bool retro_serialize(void *data, size_t size) DEBUG_LOG(SAVESTATE, "retro_serialize %d bytes", (int)size); std::lock_guard lock(mtx_serialization); - if (!first_run) - try { - emu.stop(); - } catch (const FlycastException& e) { - ERROR_LOG(COMMON, "%s", e.what()); - return false; - } + try { + emu.stop(); + } catch (const FlycastException& e) { + ERROR_LOG(COMMON, "%s", e.what()); + return false; + } Serializer ser(data, size); dc_serialize(ser);