diff --git a/src/BizHawk.Client.Common/movie/tasproj/TasMovie.History.cs b/src/BizHawk.Client.Common/movie/tasproj/TasMovie.History.cs
index ba48adf384..c56955a94e 100644
--- a/src/BizHawk.Client.Common/movie/tasproj/TasMovie.History.cs
+++ b/src/BizHawk.Client.Common/movie/tasproj/TasMovie.History.cs
@@ -28,6 +28,12 @@ namespace BizHawk.Client.Common
/// If not already recording a batch, does nothing.
///
void EndBatch();
+
+ ///
+ /// Combine the last two undo actions, making them part of one batch action.
+ ///
+ void MergeLastActions();
+
///
/// Undoes the most recent action batch, if any exist.
///
@@ -178,6 +184,17 @@ namespace BizHawk.Client.Common
}
}
+ public void MergeLastActions()
+ {
+ Debug.Assert(UndoIndex + 1 == _history.Count, "Don't merge the last actions if they aren't the last actions.");
+ Debug.Assert(_history.Count > 1, "Don't merge when there aren't actions to merge.");
+
+ _history[_history.Count - 2].AddRange(_history[_history.Count - 1]);
+ _history.RemoveAt(_history.Count - 1);
+ Names.RemoveAt(Names.Count - 1);
+ UndoIndex--;
+ }
+
public void Undo()
{
if (UndoIndex == -1)
diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs
index 6a8555ef85..0389598938 100644
--- a/src/BizHawk.Client.EmuHawk/MainForm.cs
+++ b/src/BizHawk.Client.EmuHawk/MainForm.cs
@@ -1041,6 +1041,7 @@ namespace BizHawk.Client.EmuHawk
InitializeFpsData();
}
+ if (value != _emulatorPaused) Tools.OnPauseToggle(value);
_emulatorPaused = value;
}
}
diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IToolForm.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IToolForm.cs
index 2ca7cab249..a5e13e9408 100644
--- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IToolForm.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IToolForm.cs
@@ -21,6 +21,8 @@ namespace BizHawk.Client.EmuHawk
private int _lastRefresh;
private bool _doPause;
+ private bool _extended;
+ private bool _extendNeedsMerge;
private void UpdateProgressBar()
{
@@ -55,7 +57,8 @@ namespace BizHawk.Client.EmuHawk
protected override void UpdateBefore()
{
- if (CurrentTasMovie.IsAtEnd() && !CurrentTasMovie.IsRecording())
+ _extended = CurrentTasMovie.IsAtEnd() && !CurrentTasMovie.IsRecording();
+ if (_extended)
{
CurrentTasMovie.RecordFrame(CurrentTasMovie.Emulator.Frame, MovieSession.StickySource);
}
@@ -108,6 +111,18 @@ namespace BizHawk.Client.EmuHawk
protected override void FastUpdateAfter()
{
+ // Recording multiple frames, or auto-extending the movie, while unpaused should count as a single undo action.
+ // And do this before stopping the seek, which could puase.
+ if (!MainForm.EmulatorPaused && (CurrentTasMovie.IsRecording() || _extended))
+ {
+ if (_extendNeedsMerge) CurrentTasMovie.ChangeLog.MergeLastActions();
+ _extendNeedsMerge = true;
+ }
+ else
+ {
+ _extendNeedsMerge = false;
+ }
+
if (_seekingTo != -1 && Emulator.Frame >= _seekingTo)
{
StopSeeking();
diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs
index a3b743d8bd..0771265661 100644
--- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs
@@ -890,6 +890,13 @@ namespace BizHawk.Client.EmuHawk
MainForm.TogglePause();
}
+ public override void OnPauseToggle(bool newPauseState)
+ {
+ // Consecutively recorded frames are merged into one undo action, until we pause.
+ // Then a new undo action should be used.
+ if (newPauseState) _extendNeedsMerge = false;
+ }
+
private void SetSplicer()
{
// TODO: columns selected?
diff --git a/src/BizHawk.Client.EmuHawk/tools/ToolFormBase.cs b/src/BizHawk.Client.EmuHawk/tools/ToolFormBase.cs
index cb1f8e64b8..176a21d712 100644
--- a/src/BizHawk.Client.EmuHawk/tools/ToolFormBase.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/ToolFormBase.cs
@@ -136,5 +136,7 @@ namespace BizHawk.Client.EmuHawk
}
public virtual void HandleHotkeyUpdate() { }
+
+ public virtual void OnPauseToggle(bool newPauseState) { }
}
}
diff --git a/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs b/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs
index 1b5a361241..bec31d413c 100644
--- a/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs
@@ -804,6 +804,17 @@ namespace BizHawk.Client.EmuHawk
}
}
+ public void OnPauseToggle(bool newPauseState)
+ {
+ foreach (var tool in _tools)
+ {
+ if (tool.IsActive && tool is ToolFormBase toolForm)
+ {
+ toolForm.OnPauseToggle(newPauseState);
+ }
+ }
+ }
+
private static readonly IList PossibleToolTypeNames = EmuHawk.ReflectionCache.Types.Select(t => t.AssemblyQualifiedName).ToList();
public bool IsAvailable(Type tool)