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
This commit is contained in:
Flyinghead 2025-04-11 12:02:53 +02:00
parent 240be07bbb
commit aff64d43d4
1 changed files with 16 additions and 17 deletions

View File

@ -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<std::mutex> 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<std::mutex> 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);