lightrec: Fix save states
authorPaul Cercueil <paul@crapouillou.net>
Mon, 25 Apr 2022 20:28:54 +0000 (21:28 +0100)
committerPaul Cercueil <paul@crapouillou.net>
Mon, 25 Apr 2022 20:32:09 +0000 (21:32 +0100)
To create save states the psxRegs variable must be up-to-date. Therefore
we need to store back all the registers in Lightrec's cache into psxRegs
before saving, and reload them into Lightrec's cache after loading a
save state.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
libpcsxcore/lightrec/plugin.c
libpcsxcore/misc.c
libpcsxcore/r3000a.h

index d042fc4..fe99e73 100644 (file)
@@ -554,6 +554,28 @@ static void lightrec_plugin_reset(void)
        booting = true;
 }
 
+void lightrec_plugin_prepare_load_state(void)
+{
+       struct lightrec_registers *regs;
+
+       regs = lightrec_get_registers(lightrec_state);
+       memcpy(regs->cp2d, &psxRegs.CP2, sizeof(regs->cp2d) + sizeof(regs->cp2c));
+       memcpy(regs->cp0, &psxRegs.CP0, sizeof(regs->cp0));
+       memcpy(regs->gpr, &psxRegs.GPR, sizeof(regs->gpr));
+
+       lightrec_invalidate_all(lightrec_state);
+}
+
+void lightrec_plugin_prepare_save_state(void)
+{
+       struct lightrec_registers *regs;
+
+       regs = lightrec_get_registers(lightrec_state);
+       memcpy(&psxRegs.CP2, regs->cp2d, sizeof(regs->cp2d) + sizeof(regs->cp2c));
+       memcpy(&psxRegs.CP0, regs->cp0, sizeof(regs->cp0));
+       memcpy(&psxRegs.GPR, regs->gpr, sizeof(regs->gpr));
+}
+
 R3000Acpu psxRec =
 {
        lightrec_plugin_init,
index be501a2..b02ac6f 100644 (file)
@@ -603,6 +603,15 @@ static const char PcsxHeader[32] = "STv4 PCSX v" PCSX_VERSION;
 // If you make changes to the savestate version, please increment the value below.
 static const u32 SaveVersion = 0x8b410006;
 
+static int drc_is_lightrec(void)
+{
+#if defined(LIGHTREC)
+       return 1;
+#else
+       return 0;
+#endif
+}
+
 int SaveState(const char *file) {
        void *f;
        GPUFreeze_t *gpufP;
@@ -615,6 +624,9 @@ int SaveState(const char *file) {
 
        new_dyna_before_save();
 
+       if (drc_is_lightrec())
+               lightrec_plugin_prepare_save_state();
+
        SaveFuncs.write(f, (void *)PcsxHeader, 32);
        SaveFuncs.write(f, (void *)&SaveVersion, sizeof(u32));
        SaveFuncs.write(f, (void *)&Config.HLE, sizeof(boolean));
@@ -690,12 +702,8 @@ int LoadState(const char *file) {
        if (Config.HLE)
                psxBiosInit();
 
-#if defined(LIGHTREC)
-       if (Config.Cpu != CPU_INTERPRETER)
-               psxCpu->Clear(0, UINT32_MAX); //clear all
-       else
-#endif
-       psxCpu->Reset();
+       if (!drc_is_lightrec() || Config.Cpu == CPU_INTERPRETER)
+               psxCpu->Reset();
        SaveFuncs.seek(f, 128 * 96 * 3, SEEK_CUR);
 
        SaveFuncs.read(f, psxM, 0x00200000);
@@ -704,6 +712,9 @@ int LoadState(const char *file) {
        SaveFuncs.read(f, &psxRegs, offsetof(psxRegisters, gteBusyCycle));
        psxRegs.gteBusyCycle = psxRegs.cycle;
 
+       if (drc_is_lightrec() && Config.Cpu != CPU_INTERPRETER)
+               lightrec_plugin_prepare_load_state();
+
        if (Config.HLE)
                psxBiosFreeze(0);
 
index 2d7ad40..0e21f51 100644 (file)
@@ -204,6 +204,9 @@ extern psxRegisters psxRegs;
 extern u32 event_cycles[PSXINT_COUNT];
 extern u32 next_interupt;
 
+void lightrec_plugin_prepare_save_state(void);
+void lightrec_plugin_prepare_load_state(void);
+
 void new_dyna_before_save(void);
 void new_dyna_after_save(void);
 void new_dyna_freeze(void *f, int mode);