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