From 86eabc4055b9d28480424a1813a2a3b86121a3df Mon Sep 17 00:00:00 2001 From: Sour Date: Sun, 7 Jan 2018 17:53:58 -0500 Subject: [PATCH] Libretro: Force savestates to have a constant size, to allow netplay to work properly --- Libretro/libretro.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Libretro/libretro.cpp b/Libretro/libretro.cpp index 3e1ab7ef..69981237 100644 --- a/Libretro/libretro.cpp +++ b/Libretro/libretro.cpp @@ -20,6 +20,7 @@ static retro_log_printf_t logCallback = nullptr; static retro_environment_t retroEnv = nullptr; static bool _hdPacksEnabled = false; static string _mesenVersion = ""; +int32_t _saveStateSize = -1; //Include game database as an array of strings (need an automated way to generate the include file) static vector gameDb = { @@ -504,9 +505,7 @@ extern "C" { RETRO_API size_t retro_serialize_size() { - std::stringstream ss; - Console::SaveState(ss); - return ss.str().size() * 2; + return _saveStateSize; } RETRO_API bool retro_serialize(void *data, size_t size) @@ -515,7 +514,8 @@ extern "C" { Console::SaveState(ss); string saveStateData = ss.str(); - memcpy(data, saveStateData.c_str(), saveStateData.size()); + memset(data, 0, size); + memcpy(data, saveStateData.c_str(), std::min(size, saveStateData.size())); return true; } @@ -642,6 +642,15 @@ extern "C" { setupPlayerButtons(3); retroEnv(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc.data()); + + //Savestates in Mesen may change size over time + //Retroarch doesn't like this for netplay or rewinding - it requires the states to always be the exact same size + //So we need to send a large enough size to Retroarch to ensure Mesen's state will always fit within that buffer. + std::stringstream ss; + Console::SaveState(ss); + + //Round up to the next 1kb multiple + _saveStateSize = ((ss.str().size() * 2) + 0x400) & ~0x3FF; } return result;