diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 4b6da2b3ed..a267c8a225 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -453,6 +453,7 @@ void EmuThreadStop() { // Need to keep eating frames to allow the EmuThread to exit correctly. continue; } + emuThread.join(); emuThread = std::thread(); ctx->ThreadEnd(); @@ -462,8 +463,11 @@ void EmuThreadPause() { if (emuThreadState != EmuThreadState::RUNNING) { return; } + emuThreadState = EmuThreadState::PAUSE_REQUESTED; - ctx->ThreadFrame(); + + ctx->ThreadFrame(); // Eat 1 frame + while (emuThreadState != EmuThreadState::PAUSED) { sleep_ms(1); } @@ -675,6 +679,11 @@ void retro_run(void) { retro_input(); if (useEmuThread) { + if(emuThreadState == EmuThreadState::PAUSED || emuThreadState == EmuThreadState::PAUSE_REQUESTED) { + ctx->SwapBuffers(); + return; + } + if (emuThreadState != EmuThreadState::RUNNING) { EmuThreadStart(); } @@ -705,19 +714,48 @@ struct SaveStart { } // namespace SaveState size_t retro_serialize_size(void) { + // TODO: Libretro API extension to use the savestate queue + if (useEmuThread) { + EmuThreadPause(); + } + SaveState::SaveStart state; - return (CChunkFileReader::MeasurePtr(state) + 0x800000) & ~0x7FFFFF; + return (CChunkFileReader::MeasurePtr(state) + 0x800000) & ~0x7FFFFF; // We don't unpause intentionally } bool retro_serialize(void *data, size_t size) { + // TODO: Libretro API extension to use the savestate queue + if (useEmuThread) { + EmuThreadPause(); // Does nothing if already paused + } + SaveState::SaveStart state; assert(CChunkFileReader::MeasurePtr(state) <= size); - return CChunkFileReader::SavePtr((u8 *)data, state) == CChunkFileReader::ERROR_NONE; + bool retVal = CChunkFileReader::SavePtr((u8 *)data, state) == CChunkFileReader::ERROR_NONE; + + if (useEmuThread) { + EmuThreadStart(); + sleep_ms(4); + } + + return retVal; } bool retro_unserialize(const void *data, size_t size) { + // TODO: Libretro API extension to use the savestate queue + if (useEmuThread) { + EmuThreadPause(); // Does nothing if already paused + } + SaveState::SaveStart state; - return CChunkFileReader::LoadPtr((u8 *)data, state) == CChunkFileReader::ERROR_NONE; + bool retVal = CChunkFileReader::LoadPtr((u8 *)data, state) == CChunkFileReader::ERROR_NONE; + + if (useEmuThread) { + EmuThreadStart(); + sleep_ms(4); + } + + return retVal; } void *retro_get_memory_data(unsigned id) {