diff --git a/win32/StateManager.cpp b/statemanager.cpp similarity index 98% rename from win32/StateManager.cpp rename to statemanager.cpp index dcef99f8..7280ec89 100644 --- a/win32/StateManager.cpp +++ b/statemanager.cpp @@ -1,7 +1,7 @@ #include "statemanager.h" #include "snapshot.h" -/* Snapshot Manager Class that records snapshot data for rewinding +/* State Manager Class that records snapshot data for rewinding mostly based on SSNES's rewind code by Themaister */ diff --git a/win32/StateManager.h b/statemanager.h similarity index 90% rename from win32/StateManager.h rename to statemanager.h index 65aabb30..38f3c0d7 100644 --- a/win32/StateManager.h +++ b/statemanager.h @@ -1,7 +1,7 @@ #ifndef STATEMANAGER_H #define STATEMANAGER_H -/* Snapshot Manager Class that records snapshot data for rewinding +/* State Manager Class that records snapshot data for rewinding mostly based on SSNES's rewind code by Themaister */ diff --git a/unix/Makefile.in b/unix/Makefile.in index c7525aa5..58495689 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -7,7 +7,7 @@ OS = `uname -s -r -m|sed \"s/ /-/g\"|tr \"[A-Z]\" \"[a-z]\"|tr \"/()\" \"___\"` BUILDDIR = . -OBJECTS = ../apu/apu.o ../apu/bapu/dsp/sdsp.o ../apu/bapu/dsp/SPC_DSP.o ../apu/bapu/smp/smp.o ../apu/bapu/smp/smp_state.o ../bsx.o ../c4.o ../c4emu.o ../cheats.o ../cheats2.o ../clip.o ../conffile.o ../controls.o ../cpu.o ../cpuexec.o ../cpuops.o ../crosshairs.o ../dma.o ../dsp.o ../dsp1.o ../dsp2.o ../dsp3.o ../dsp4.o ../fxinst.o ../fxemu.o ../gfx.o ../globals.o ../logger.o ../memmap.o ../movie.o ../obc1.o ../ppu.o ../stream.o ../sa1.o ../sa1cpu.o ../screenshot.o ../sdd1.o ../sdd1emu.o ../seta.o ../seta010.o ../seta011.o ../seta018.o ../snapshot.o ../snes9x.o ../spc7110.o ../srtc.o ../tile.o ../filter/2xsai.o ../filter/blit.o ../filter/epx.o ../filter/hq2x.o ../filter/snes_ntsc.o unix.o x11.o +OBJECTS = ../apu/apu.o ../apu/bapu/dsp/sdsp.o ../apu/bapu/dsp/SPC_DSP.o ../apu/bapu/smp/smp.o ../apu/bapu/smp/smp_state.o ../bsx.o ../c4.o ../c4emu.o ../cheats.o ../cheats2.o ../clip.o ../conffile.o ../controls.o ../cpu.o ../cpuexec.o ../cpuops.o ../crosshairs.o ../dma.o ../dsp.o ../dsp1.o ../dsp2.o ../dsp3.o ../dsp4.o ../fxinst.o ../fxemu.o ../gfx.o ../globals.o ../logger.o ../memmap.o ../movie.o ../obc1.o ../ppu.o ../stream.o ../sa1.o ../sa1cpu.o ../screenshot.o ../sdd1.o ../sdd1emu.o ../seta.o ../seta010.o ../seta011.o ../seta018.o ../snapshot.o ../snes9x.o ../spc7110.o ../srtc.o ../tile.o ../filter/2xsai.o ../filter/blit.o ../filter/epx.o ../filter/hq2x.o ../filter/snes_ntsc.o ../statemanager.o unix.o x11.o DEFS = -DMITSHM ifdef S9XDEBUGGER diff --git a/unix/unix.cpp b/unix/unix.cpp index c16d04aa..938e5698 100644 --- a/unix/unix.cpp +++ b/unix/unix.cpp @@ -222,6 +222,7 @@ #ifdef DEBUGGER #include "debug.h" #endif +#include "statemanager.h" #ifdef NETPLAY_SUPPORT #ifdef _DEBUG @@ -233,6 +234,8 @@ typedef std::pair strpair_t; ConfigFile::secvec_t keymaps; +StateManager stateMan; + #define FIXED_POINT 0x10000 #define FIXED_POINT_SHIFT 16 #define FIXED_POINT_REMAINDER 0xffff @@ -275,6 +278,8 @@ struct SUnixSettings bool8 ThreadSound; uint32 SoundBufferSize; uint32 SoundFragmentSize; + uint32 rewindBufferSize; + uint32 rewindGranularity; }; struct SoundStatus @@ -290,6 +295,8 @@ struct SoundStatus static SUnixSettings unixSettings; static SoundStatus so; +static bool8 rewinding; + #ifndef NOSOUND static uint8 Buf[SOUND_BUFFER_SIZE]; #endif @@ -436,6 +443,10 @@ void S9xExtraUsage (void) S9xMessage(S9X_INFO, S9X_USAGE, " frames (use with -dumpstreams)"); S9xMessage(S9X_INFO, S9X_USAGE, ""); + S9xMessage(S9X_INFO, S9X_USAGE, "-rwbuffersize Rewind buffer size in MB"); + S9xMessage(S9X_INFO, S9X_USAGE, "-rwgranularity Rewind granularity in frames"); + S9xMessage(S9X_INFO, S9X_USAGE, ""); + S9xExtraDisplayUsage(); } @@ -534,6 +545,22 @@ void S9xParseArg (char **argv, int &i, int argc) else if (!strcasecmp(argv[i], "-dumpmaxframes")) Settings.DumpStreamsMaxFrames = atoi(argv[++i]); + else + if (!strcasecmp(argv[i], "-rwbuffersize")) + { + if (i + 1 < argc) + unixSettings.rewindBufferSize = atoi(argv[++i]); + else + S9xUsage(); + } + else + if (!strcasecmp(argv[i], "-rwgranularity")) + { + if (i + 1 < argc) + unixSettings.rewindGranularity = atoi(argv[++i]); + else + S9xUsage(); + } else S9xParseDisplayArg(argv, i, argc); } @@ -1138,6 +1165,13 @@ s9xcommand_t S9xGetPortCommandT (const char *n) return (cmd); } + } else + if (!strcmp(n,"Rewind")) + { + cmd.type = S9xButtonPort; + cmd.port[1] = 2; + + return (cmd); } return (S9xGetDisplayCommandT(n)); @@ -1168,6 +1202,9 @@ char * S9xGetPortCommandName (s9xcommand_t cmd) x += " ToggleMeta"; x += (int) cmd.port[3]; return (strdup(x.c_str())); + + case 2: + return (strdup("Rewind")); } break; @@ -1204,6 +1241,10 @@ void S9xHandlePortCommand (s9xcommand_t cmd, int16 data1, int16 data2) if (data1) js_mod[cmd.port[2]] ^= cmd.port[3]; break; + + case 2: + rewinding = (bool8) data1; + break; } break; @@ -1594,8 +1635,13 @@ int main (int argc, char **argv) unixSettings.SoundBufferSize = 100; unixSettings.SoundFragmentSize = 2048; + unixSettings.rewindBufferSize = 0; + unixSettings.rewindGranularity = 1; + memset(&so, 0, sizeof(so)); + rewinding = false; + CPU.Flags = 0; S9xLoadConfigFiles(argv, argc); @@ -1733,6 +1779,8 @@ int main (int argc, char **argv) { NetPlay.MaxFrameSkip = 10; + unixSettings.rewindBufferSize = 0; + if (!S9xNPConnectToServer(Settings.ServerName, Settings.Port, Memory.ROMName)) { fprintf(stderr, "Failed to connect to server %s on port %d.\n", Settings.ServerName, Settings.Port); @@ -1759,12 +1807,18 @@ int main (int argc, char **argv) CPU.Flags |= flags; } else - if (snapshot_filename) { - uint32 flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG); - if (!S9xUnfreezeGame(snapshot_filename)) - exit(1); - CPU.Flags |= flags; + if (snapshot_filename) + { + uint32 flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG); + if (!S9xUnfreezeGame(snapshot_filename)) + exit(1); + CPU.Flags |= flags; + } + if (unixSettings.rewindBufferSize) + { + stateMan.init(unixSettings.rewindBufferSize * 1024 * 1024); + } } S9xGraphicsMode(); @@ -1822,7 +1876,14 @@ int main (int argc, char **argv) #else if (!Settings.Paused) #endif + { + if(rewinding) + rewinding = stateMan.pop(); + else if(IPPU.TotalEmulatedFrames % unixSettings.rewindGranularity == 0) + stateMan.push(); + S9xMainLoop(); + } #ifdef NETPLAY_SUPPORT if (NP_Activated) diff --git a/unix/x11.cpp b/unix/x11.cpp index cb76f82d..d510464a 100644 --- a/unix/x11.cpp +++ b/unix/x11.cpp @@ -462,6 +462,8 @@ const char * S9xParseDisplayConfig (ConfigFile &conf, int pass) keymaps.push_back(strpair_t("M00:Pointer", "Pointer Mouse1+Superscope+Justifier1")); keymaps.push_back(strpair_t("K00:grave", "Superscope ToggleTurbo")); keymaps.push_back(strpair_t("K00:slash", "Superscope Pause")); + + keymaps.push_back(strpair_t("K00:r", "Rewind")); } GUI.no_repeat = !conf.GetBool("Unix/X11::SetKeyRepeat", TRUE); diff --git a/win32/snes9xw.vcproj b/win32/snes9xw.vcproj index 3437de14..c8c38d2c 100644 --- a/win32/snes9xw.vcproj +++ b/win32/snes9xw.vcproj @@ -2866,6 +2866,14 @@ /> + + + + @@ -3022,14 +3030,6 @@ RelativePath=".\render.h" > - - - - diff --git a/win32/wsnes9x.cpp b/win32/wsnes9x.cpp index 6baa90bf..cb8c8883 100644 --- a/win32/wsnes9x.cpp +++ b/win32/wsnes9x.cpp @@ -211,9 +211,9 @@ #include "../movie.h" #include "../controls.h" #include "../conffile.h" +#include "../statemanager.h" #include "AVIOutput.h" #include "InputCustom.h" -#include "StateManager.h" #include #if (((defined(_MSC_VER) && _MSC_VER >= 1300)) || defined(__MINGW32__))