zwinder: Make GetStateClosestToFrame actually get closest state. (#2291)

* zwinder: Make GetStateClosestToFrame actually get closest state.

* Clarify docs
This commit is contained in:
RetroEdit 2020-08-14 16:00:56 +00:00 committed by GitHub
parent e89449ed27
commit 1f5128bf6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 18 additions and 11 deletions

View File

@ -33,7 +33,7 @@ namespace BizHawk.Client.Common
void Clear();
/// <summary>
/// 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.
/// </summary>
/// <param name="frame"></param>

View File

@ -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<int, Stream> 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<int, Stream>(si.Frame, si.Read());
}

View File

@ -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);

View File

@ -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
}
}
/// <summary>
/// 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.
/// </summary>
private KeyValuePair<int,Stream> 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);

View File

@ -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