From 1f5128bf6bbd817b6f7381cef63af70978c8b2fd Mon Sep 17 00:00:00 2001 From: RetroEdit <30182911+RetroEdit@users.noreply.github.com> Date: Fri, 14 Aug 2020 16:00:56 +0000 Subject: [PATCH] zwinder: Make GetStateClosestToFrame actually get closest state. (#2291) * zwinder: Make GetStateClosestToFrame actually get closest state. * Clarify docs --- .../movie/tasproj/IStateManager.cs | 2 +- .../movie/tasproj/ZwinderStateManager.cs | 6 +++--- .../tools/TAStudio/TAStudio.Navigation.cs | 4 +--- .../tools/TAStudio/TAStudio.cs | 13 +++++++++++-- .../Client.Common/Movie/ZwinderStateManagerTests.cs | 4 ++-- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/BizHawk.Client.Common/movie/tasproj/IStateManager.cs b/src/BizHawk.Client.Common/movie/tasproj/IStateManager.cs index 2b7087e74e..6fcd012262 100644 --- a/src/BizHawk.Client.Common/movie/tasproj/IStateManager.cs +++ b/src/BizHawk.Client.Common/movie/tasproj/IStateManager.cs @@ -33,7 +33,7 @@ namespace BizHawk.Client.Common void Clear(); /// - /// Get a nearby state. The returned frame must be less (but not equal to???) the passed frame. + /// Get a nearby state. The returned frame must be less than or equal to the passed frame. /// This may not fail; the StateManager strongly holds a frame 0 state to ensure there's always a possible result. /// /// diff --git a/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs b/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs index 9a6d99bfac..1bf75ef95f 100644 --- a/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs +++ b/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs @@ -68,7 +68,7 @@ namespace BizHawk.Client.Common { get { - var kvp = GetStateClosestToFrame(frame + 1); + var kvp = GetStateClosestToFrame(frame); if (kvp.Key != frame) return NonState; var ms = new MemoryStream(); @@ -221,10 +221,10 @@ namespace BizHawk.Client.Common public KeyValuePair GetStateClosestToFrame(int frame) { - if (frame <= 0) + if (frame < 0) throw new ArgumentOutOfRangeException(nameof(frame)); - var si = AllStates().First(s => s.Frame < frame); + var si = AllStates().First(s => s.Frame <= frame); return new KeyValuePair(si.Frame, si.Read()); } diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Navigation.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Navigation.cs index 1d23922fdc..ebfdd928a0 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Navigation.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Navigation.cs @@ -52,9 +52,7 @@ namespace BizHawk.Client.EmuHawk { TastudioPlayMode(); - // Simply getting the last state doesn't work if that state is the frame. - // display isn't saved in the state, need to emulate to frame - var lastState = CurrentTasMovie.TasStateManager.GetStateClosestToFrame(frame <= 0 ? 1 : frame); + var lastState = GetPriorStateForFramebuffer(frame); if (lastState.Key > Emulator.Frame) { LoadState(lastState); diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs index cb17cd58fa..cf481468c0 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs @@ -601,7 +601,7 @@ namespace BizHawk.Client.EmuHawk tasMovie.GreenzoneInvalidated = GreenzoneInvalidated; tasMovie.PropertyChanged += TasMovie_OnPropertyChanged; - + tasMovie.PopulateWithDefaultHeaderValues( Emulator, Game, @@ -901,6 +901,15 @@ namespace BizHawk.Client.EmuHawk } } + /// + /// Get a savestate prior to the previous frame so code following the call can frame advance and have a framebuffer. + /// If frame is 0, return the initial state. + /// + private KeyValuePair GetPriorStateForFramebuffer(int frame) + { + return CurrentTasMovie.TasStateManager.GetStateClosestToFrame(frame > 0 ? frame - 1 : 0); + } + private void StartAtNearestFrameAndEmulate(int frame, bool fromLua, bool fromRewinding) { if (frame == Emulator.Frame) @@ -910,7 +919,7 @@ namespace BizHawk.Client.EmuHawk _unpauseAfterSeeking = (fromRewinding || WasRecording) && !MainForm.EmulatorPaused; TastudioPlayMode(); - var closestState = CurrentTasMovie.TasStateManager.GetStateClosestToFrame(frame <= 0 ? 1 : frame); + var closestState = GetPriorStateForFramebuffer(frame); if (closestState.Value.Length > 0 && (frame < Emulator.Frame || closestState.Key > Emulator.Frame)) { LoadState(closestState); diff --git a/src/BizHawk.Tests/Client.Common/Movie/ZwinderStateManagerTests.cs b/src/BizHawk.Tests/Client.Common/Movie/ZwinderStateManagerTests.cs index ad7b0e3f17..33849f090b 100644 --- a/src/BizHawk.Tests/Client.Common/Movie/ZwinderStateManagerTests.cs +++ b/src/BizHawk.Tests/Client.Common/Movie/ZwinderStateManagerTests.cs @@ -62,7 +62,7 @@ namespace BizHawk.Tests.Client.Common.Movie } [TestMethod] - public void SomethingSomething() + public void StateBeforeFrame() { var ss = new StateSource { PaddingData = new byte[1000] }; var zw = new ZwinderStateManager(new ZwinderStateManagerSettings @@ -90,7 +90,7 @@ namespace BizHawk.Tests.Client.Common.Movie var kvp = zw.GetStateClosestToFrame(10440); var actual = StateSource.GetFrameNumberInState(kvp.Value); Assert.AreEqual(kvp.Key, actual); - Assert.IsTrue(actual < 10440); + Assert.IsTrue(actual <= 10440); } private class StateSource : IStatable