From 2558e76b5d8596ac411d7170b8ea5db299911e2d Mon Sep 17 00:00:00 2001 From: goyuken Date: Mon, 23 Dec 2013 20:34:02 +0000 Subject: [PATCH] fix rewind on N64, gpgx.debug --- BizHawk.Client.Common/movie/MovieRecord.cs | 2 +- BizHawk.Client.EmuHawk/MainForm.Rewind.cs | 15 +++++++++++---- BizHawk.Emulation.Common/Interfaces/IEmulator.cs | 4 ++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/BizHawk.Client.Common/movie/MovieRecord.cs b/BizHawk.Client.Common/movie/MovieRecord.cs index 5e0529a802..e4e655730d 100644 --- a/BizHawk.Client.Common/movie/MovieRecord.cs +++ b/BizHawk.Client.Common/movie/MovieRecord.cs @@ -51,7 +51,7 @@ namespace BizHawk.Client.Common public void CaptureSate() { Lagged = Global.Emulator.IsLagFrame; - _state = Global.Emulator.SaveStateBinary(); + _state = (byte[])Global.Emulator.SaveStateBinary().Clone(); } public void ClearInput() diff --git a/BizHawk.Client.EmuHawk/MainForm.Rewind.cs b/BizHawk.Client.EmuHawk/MainForm.Rewind.cs index a518a3a455..005b64001f 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Rewind.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Rewind.cs @@ -258,7 +258,11 @@ namespace BizHawk.Client.EmuHawk class RewindThreader : IDisposable { //adelikat: tweak this to test performance with threading or not with threading - public static bool IsThreaded = true; + // natt: IEmulator.SaveStateBinary() returns a byte[] but you're not allowed to modify it, + // and if the method is called again, the data from a previous call could be invalidated. + // GPGX and N64 make use of this property. if you set IsThreaded = true, you'll need to Clone() in many cases, + // which will kill N64 for sure... + public static bool IsThreaded = false; MainForm mf; @@ -419,7 +423,7 @@ namespace BizHawk.Client.EmuHawk public void DoRewindSettings() { // This is the first frame. Capture the state, and put it in LastState for future deltas to be compared against. - LastState = Global.Emulator.SaveStateBinary(); + LastState = (byte[])Global.Emulator.SaveStateBinary().Clone(); int state_size = 0; if (LastState.Length >= Global.Config.Rewind_LargeStateSize) @@ -557,8 +561,11 @@ namespace BizHawk.Client.EmuHawk TempBuf = new byte[TempBuf.Length * 2]; goto RETRY; } - - LastState = CurrentState; + + if (LastState != null && LastState.Length == CurrentState.Length) + Buffer.BlockCopy(CurrentState, 0, LastState, 0, LastState.Length); + else + LastState = (byte[])CurrentState.Clone(); var seg = new ArraySegment(TempBuf, 0, (int)ms.Position); RewindBuf.Push(seg); } diff --git a/BizHawk.Emulation.Common/Interfaces/IEmulator.cs b/BizHawk.Emulation.Common/Interfaces/IEmulator.cs index 924a78bccf..4c6cd32426 100644 --- a/BizHawk.Emulation.Common/Interfaces/IEmulator.cs +++ b/BizHawk.Emulation.Common/Interfaces/IEmulator.cs @@ -111,6 +111,10 @@ namespace BizHawk.Emulation.Common void LoadStateText(TextReader reader); void SaveStateBinary(BinaryWriter writer); void LoadStateBinary(BinaryReader reader); + /// + /// save state binary to a byte buffer + /// + /// you may NOT modify this. if you call SaveStateBinary() again with the same core, the old data MAY be overwritten. byte[] SaveStateBinary(); ///