From f458648fad4d9855e41fccda9365a2fdc9763be3 Mon Sep 17 00:00:00 2001 From: zeromus Date: Thu, 16 Feb 2017 00:29:28 -0600 Subject: [PATCH] improve rewind in tastudio by leaving editmode intact but taking care not to clobber frames. take special pains to ensure that (reverse) frame progress vs smooth rewind semantics stay as expected. --- BizHawk.Client.EmuHawk/MainForm.cs | 13 +++++++++++++ .../tools/TAStudio/TAStudio.IControlMainForm.cs | 1 + .../tools/TAStudio/TAStudio.ListView.cs | 6 ++++++ .../tools/TAStudio/TAStudio.Navigation.cs | 4 ++-- BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs | 12 +++++++----- 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 857e682c9b..55be41f2f8 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -1370,6 +1370,7 @@ namespace BizHawk.Client.EmuHawk private bool _runloopFrameProgress; private long _frameAdvanceTimestamp; private long _frameRewindTimestamp; + private bool _frameRewindWasPaused; private bool _runloopFrameadvance; private bool _lastFastForwardingOrRewinding; private bool _inResizeLoop; @@ -4121,13 +4122,25 @@ namespace BizHawk.Client.EmuHawk { isRewinding = true; _frameRewindTimestamp = currentTimestamp; + _frameRewindWasPaused = EmulatorPaused; } else { double timestampDeltaMs = (double)(currentTimestamp - _frameRewindTimestamp) / Stopwatch.Frequency * 1000.0; isRewinding = timestampDeltaMs >= Global.Config.FrameProgressDelayMs; + + //clear this flag once we get out of the progress stage + if (isRewinding) + _frameRewindWasPaused = false; + + //if we're freely running, there's no need for reverse frame progress semantics (that may be debateable though) + if (!EmulatorPaused) isRewinding = true; + + if (_frameRewindWasPaused) + if (IsSeeking) isRewinding = false; } + if (isRewinding) { runFrame = true; // TODO: the master should be deciding this! diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IControlMainForm.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IControlMainForm.cs index cad308f52a..2d89ea5fb5 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IControlMainForm.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IControlMainForm.cs @@ -94,6 +94,7 @@ namespace BizHawk.Client.EmuHawk } else { + StopSeeking(); //late breaking memo: dont know whether this is needed GoToPreviousFrame(); } return true; diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs index f61d49e285..69fafd87fb 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs @@ -59,6 +59,7 @@ namespace BizHawk.Client.EmuHawk private bool? _autoRestorePaused = null; private int? _seekStartFrame = null; private bool _wasRecording = false; + private bool _shouldUnpauseFromRewind = false; private Emulation.Common.ControllerDefinition controllerType { get { return Global.MovieSession.MovieControllerAdapter.Definition; } } @@ -105,6 +106,11 @@ namespace BizHawk.Client.EmuHawk _wasRecording = false; } Mainform.PauseOnFrame = null; + if (_shouldUnpauseFromRewind) + { + Mainform.UnpauseEmulator(); + _shouldUnpauseFromRewind = false; + } if (CurrentTasMovie != null) RefreshDialog(); } diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Navigation.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Navigation.cs index 01c799e8ef..30dc466413 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Navigation.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Navigation.cs @@ -30,7 +30,7 @@ namespace BizHawk.Client.EmuHawk } // SuuperW: I changed this to public so that it could be used by MarkerControl.cs - public void GoToFrame(int frame, bool fromLua = false) + public void GoToFrame(int frame, bool fromLua = false, bool fromRewinding = false) { // If seeking to a frame before or at the end of the movie, use StartAtNearestFrameAndEmulate // Otherwise, load the latest state (if not already there) and seek while recording. @@ -38,7 +38,7 @@ namespace BizHawk.Client.EmuHawk if (frame <= CurrentTasMovie.InputLogLength) { // Get as close as we can then emulate there - StartAtNearestFrameAndEmulate(frame, fromLua); + StartAtNearestFrameAndEmulate(frame, fromLua, fromRewinding); MaybeFollowCursor(); } diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs index 713952bd14..0ee546b090 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs @@ -807,11 +807,12 @@ namespace BizHawk.Client.EmuHawk //_autoRestoreFrame = null; } - private void StartAtNearestFrameAndEmulate(int frame, bool fromLua) + private void StartAtNearestFrameAndEmulate(int frame, bool fromLua, bool fromRewinding) { if (frame == Emulator.Frame) return; + _shouldUnpauseFromRewind = fromRewinding && !Mainform.EmulatorPaused; _wasRecording = CurrentTasMovie.IsRecording || _wasRecording; TastudioPlayMode(); KeyValuePair closestState = CurrentTasMovie.TasStateManager.GetStateClosestToFrame(frame); @@ -845,17 +846,18 @@ namespace BizHawk.Client.EmuHawk //now the next section won't happen since we're at the right spot } - // frame == Emualtor.Frame when frame == 0 + // frame == Emulator.Frame when frame == 0 if (frame > Emulator.Frame) { - if (Mainform.EmulatorPaused || Mainform.IsSeeking) // make seek frame keep up with emulation on fast scrolls + if (Mainform.EmulatorPaused || Mainform.IsSeeking || fromRewinding) // make seek frame keep up with emulation on fast scrolls { StartSeeking(frame); } else { - //GUI users hand need to be protected from clobbering their video when skipping around - //so we don't re-enable recording + //GUI users may want to be protected from clobbering their video when skipping around... + //well, users who are rewinding arent. (that gets done through the seeking system in the call above) + //users who are clicking around.. I dont know. } } }