diff --git a/BizHawk.Emulation.Common/EmulationExceptions.cs b/BizHawk.Emulation.Common/EmulationExceptions.cs index 75c4360c5e..6847a077d8 100644 --- a/BizHawk.Emulation.Common/EmulationExceptions.cs +++ b/BizHawk.Emulation.Common/EmulationExceptions.cs @@ -31,4 +31,13 @@ namespace BizHawk.Emulation.Common { } } + + public class SavestateSizeMismatchException : InvalidOperationException + { + public SavestateSizeMismatchException(string message) + : base(message) + { + + } + } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs index 7b8844a060..83917a7644 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs @@ -327,8 +327,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 byte[] data = SaveStatePrivateBuff; int bytes_used = api.SaveState(data); - writer.Write(data.Length); - writer.Write(data); + writer.Write(bytes_used); + writer.Write(data, 0, bytes_used); byte[] saveram = api.SaveSaveram(); writer.Write(saveram); @@ -346,6 +346,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 public void LoadStateBinary(BinaryReader reader) { int length = reader.ReadInt32(); + if ((_syncSettings.DisableExpansionSlot && length >= 16788288) || (!_syncSettings.DisableExpansionSlot && length < 16788288)) + { + throw new SavestateSizeMismatchException("Wrong N64 savestate size"); + } + reader.Read(SaveStatePrivateBuff, 0, length); byte[] data = SaveStatePrivateBuff; diff --git a/libmupen64plus/mupen64plus-core/src/main/savestates.c b/libmupen64plus/mupen64plus-core/src/main/savestates.c index eddd3d1e30..0fda5c49aa 100644 --- a/libmupen64plus/mupen64plus-core/src/main/savestates.c +++ b/libmupen64plus/mupen64plus-core/src/main/savestates.c @@ -483,7 +483,14 @@ EXPORT int CALL savestates_load_bkm(char * curr) size_t savestateSize; unsigned char *savestateData; - char *queue = curr + 16788288; + int hasExpansion; + + char *queue; + + hasExpansion = !(ConfigGetParamInt(g_CoreConfig, "DisableExtraMem")); + savestateSize = hasExpansion ? 16788288 : 12593984; + queue = curr + savestateSize; + curr += 44; // Parse savestate @@ -595,7 +602,7 @@ EXPORT int CALL savestates_load_bkm(char * curr) dps_register.dps_buftest_addr = GETDATA(curr, unsigned int); dps_register.dps_buftest_data = GETDATA(curr, unsigned int); - COPYARRAY(rdram, curr, unsigned int, 0x800000/4); + COPYARRAY(rdram, curr, unsigned int, (hasExpansion ? 0x800000 : 0x400000) /4); COPYARRAY(SP_DMEM, curr, unsigned int, 0x1000/4); COPYARRAY(SP_IMEM, curr, unsigned int, 0x1000/4); COPYARRAY(PIF_RAM, curr, unsigned char, 0x40); @@ -1446,10 +1453,21 @@ EXPORT int CALL savestates_save_bkm(char *curr) int queuelength; int savestate_size; + int hasExpansion; + queuelength = save_eventqueue_infos(queue); + hasExpansion = !(ConfigGetParamInt(g_CoreConfig, "DisableExtraMem")); + // Allocate memory for the save state data - savestate_size = 16788288 + queuelength; + if (hasExpansion) + { + savestate_size = 16788288 + queuelength; + } + else + { + savestate_size = 12593984 + queuelength; + } // Write the save state data to memory PUTARRAY(savestate_magic, curr, unsigned char, 8); @@ -1602,7 +1620,7 @@ EXPORT int CALL savestates_save_bkm(char *curr) PUTDATA(curr, unsigned int, dps_register.dps_buftest_addr); PUTDATA(curr, unsigned int, dps_register.dps_buftest_data); - PUTARRAY(rdram, curr, unsigned int, 0x800000/4); + PUTARRAY(rdram, curr, unsigned int, (hasExpansion ? 0x800000 : 0x400000) / 4); PUTARRAY(SP_DMEM, curr, unsigned int, 0x1000/4); PUTARRAY(SP_IMEM, curr, unsigned int, 0x1000/4); PUTARRAY(PIF_RAM, curr, unsigned char, 0x40); @@ -1967,4 +1985,4 @@ void savestates_deinit(void) { SDL_DestroyMutex(savestates_lock); savestates_clear_job(); -} +} \ No newline at end of file diff --git a/output/dll/mupen64plus.dll b/output/dll/mupen64plus.dll index 8e3f324df7..4c7aca6221 100644 Binary files a/output/dll/mupen64plus.dll and b/output/dll/mupen64plus.dll differ