diff --git a/src/BizHawk.Client.Common/config/RewindConfig.cs b/src/BizHawk.Client.Common/config/RewindConfig.cs index 84617e5a60..89c4226004 100644 --- a/src/BizHawk.Client.Common/config/RewindConfig.cs +++ b/src/BizHawk.Client.Common/config/RewindConfig.cs @@ -16,7 +16,6 @@ namespace BizHawk.Client.Common public int BufferSize { get; } public bool OnDisk { get; } public bool IsThreaded { get; } - public int SpeedMultiplier { get; } } public class RewindConfig : IRewindSettings diff --git a/src/BizHawk.Client.Common/rewind/Rewinder.cs b/src/BizHawk.Client.Common/rewind/Rewinder.cs index df6c5b6145..b6e70193a4 100644 --- a/src/BizHawk.Client.Common/rewind/Rewinder.cs +++ b/src/BizHawk.Client.Common/rewind/Rewinder.cs @@ -4,24 +4,24 @@ using BizHawk.Emulation.Common; namespace BizHawk.Client.Common { - public class Rewinder + public class Rewinder : IDisposable { - private IStatable _statableCore; + private readonly IStatable _statableCore; private const int MaxByteArraySize = 0x7FFFFFC7; // .NET won't let us allocate more than this in one array - private StreamBlobDatabase _rewindBuffer; + private readonly StreamBlobDatabase _rewindBuffer; private byte[] _rewindBufferBacking; private long _memoryLimit = MaxByteArraySize; - private RewindThreader _rewindThread; + private readonly RewindThreader _rewindThread; private byte[] _lastState; - private bool _rewindDeltaEnable; + private readonly bool _rewindDeltaEnable; private bool _lastRewindLoadedState; private byte[] _deltaBuffer = new byte[0]; public bool RewindActive => RewindEnabled && !SuspendRewind; - private bool RewindEnabled { get; set; } + private bool RewindEnabled { get; } public bool SuspendRewind { get; set; } @@ -33,12 +33,10 @@ namespace BizHawk.Client.Common public bool HasBuffer => _rewindBuffer != null; - public int RewindFrequency { get; private set; } + public int RewindFrequency { get; } - public void Initialize(IStatable statableCore, IRewindSettings settings) + public Rewinder(IStatable statableCore, IRewindSettings settings) { - Uninitialize(); - _statableCore = statableCore; int stateSize = _statableCore.CloneSavestate().Length; @@ -69,27 +67,7 @@ namespace BizHawk.Client.Common } } - public void Uninitialize() - { - if (_rewindThread != null) - { - _rewindThread.Dispose(); - _rewindThread = null; - } - - if (_rewindBuffer != null) - { - _rewindBuffer.Dispose(); - _rewindBuffer = null; - } - - Clear(); - - RewindEnabled = false; - RewindFrequency = 0; - } - - public void Clear() + private void Clear() { _rewindBuffer?.Clear(); _lastState = new byte[0]; @@ -367,6 +345,13 @@ namespace BizHawk.Client.Common _statableCore.LoadStateBinary(reader); } } + + public void Dispose() + { + Clear(); + _rewindBuffer?.Dispose(); + _rewindThread?.Dispose(); + } } public static class VLInteger diff --git a/src/BizHawk.Client.EmuHawk/MainForm.Events.cs b/src/BizHawk.Client.EmuHawk/MainForm.Events.cs index 8db4ddd3df..93a0e65f0b 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.Events.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.Events.cs @@ -1011,7 +1011,7 @@ namespace BizHawk.Client.EmuHawk { if (Emulator.HasSavestates()) { - using var form = new RewindConfig(Rewinder, Config, Emulator.AsStatable()); + using var form = new RewindConfig(this, Config, Emulator.AsStatable()); AddOnScreenMessage(form.ShowDialog().IsOk() ? "Rewind and State settings saved" : "Rewind config aborted"); diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs index d91fb64cf7..4e74562bbf 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.cs @@ -278,7 +278,6 @@ namespace BizHawk.Client.EmuHawk Database.InitializeDatabase(Path.Combine(PathUtils.ExeDirectoryPath, "gamedb", "gamedb.txt")); GlobalWin.MainForm = this; - Rewinder = new Rewinder(); GlobalWin.InputManager.ControllerInputCoalescer = new ControllerInputCoalescer(); GlobalWin.FirmwareManager = new FirmwareManager(); @@ -897,7 +896,7 @@ namespace BizHawk.Client.EmuHawk private Sound Sound => GlobalWin.Sound; public CheatCollection CheatList => GlobalWin.CheatList; - private Rewinder Rewinder { get; } + public Rewinder Rewinder { get; set; } private FirmwareManager FirmwareManager => GlobalWin.FirmwareManager; @@ -2100,7 +2099,7 @@ namespace BizHawk.Client.EmuHawk // skips outputting the audio. There's also a third way which is when no throttle // method is selected, but the clock throttle determines that by itself and // everything appears normal here. - var rewind = Rewinder.RewindActive && (InputManager.ClientControls["Rewind"] || PressRewind); + var rewind = Rewinder?.RewindActive == true && (InputManager.ClientControls["Rewind"] || PressRewind); var fastForward = InputManager.ClientControls["Fast Forward"] || FastForward; var turbo = IsTurboing; @@ -3823,7 +3822,11 @@ namespace BizHawk.Client.EmuHawk if (Emulator.HasSavestates()) { - Rewinder.Initialize(Emulator.AsStatable(), Config.Rewind); + Rewinder = new Rewinder(Emulator.AsStatable(), Config.Rewind); + } + else + { + Rewinder?.Dispose(); } GlobalWin.InputManager.StickyXorAdapter.ClearStickies(); @@ -3934,7 +3937,7 @@ namespace BizHawk.Client.EmuHawk StopAv(); CommitCoreSettingsToConfig(); - Rewinder.Uninitialize(); + Rewinder?.Dispose(); if (MovieSession.Movie.IsActive()) // Note: this must be called after CommitCoreSettingsToConfig() { @@ -4005,13 +4008,19 @@ namespace BizHawk.Client.EmuHawk public void EnableRewind(bool enabled) { + if (Rewinder == null && Emulator.HasSavestates()) + { + Rewinder = new Rewinder(Emulator.AsStatable(), Config.Rewind); + } + Rewinder.SuspendRewind = !enabled; AddOnScreenMessage($"Rewind {(enabled ? "enabled" : "suspended")}"); } - public void ClearRewindData() + public void DisableRewind() { - Rewinder.Clear(); + Rewinder?.Dispose(); + Rewinder = null; } // TODO: move me @@ -4069,7 +4078,7 @@ namespace BizHawk.Client.EmuHawk if (!IsRewindSlave && MovieSession.Movie.IsActive()) { - ClearRewindData(); + DisableRewind(); } if (!suppressOSD) @@ -4360,7 +4369,7 @@ namespace BizHawk.Client.EmuHawk { Master.CaptureRewind(); } - else if (!suppressCaptureRewind && Rewinder.RewindActive) + else if (!suppressCaptureRewind && Rewinder?.RewindActive == true) { Rewinder.Capture(Emulator.Frame); } @@ -4422,7 +4431,7 @@ namespace BizHawk.Client.EmuHawk return isRewinding; } - if (Rewinder.RewindActive && (InputManager.ClientControls["Rewind"] || PressRewind)) + if (Rewinder?.RewindActive == true && (InputManager.ClientControls["Rewind"] || PressRewind)) { if (EmulatorPaused) { diff --git a/src/BizHawk.Client.EmuHawk/config/RewindConfig.cs b/src/BizHawk.Client.EmuHawk/config/RewindConfig.cs index 30a2303266..5bc4ed5716 100644 --- a/src/BizHawk.Client.EmuHawk/config/RewindConfig.cs +++ b/src/BizHawk.Client.EmuHawk/config/RewindConfig.cs @@ -9,7 +9,7 @@ namespace BizHawk.Client.EmuHawk { public partial class RewindConfig : Form { - private readonly Rewinder _rewinder; + private readonly MainForm _mainForm; private readonly Config _config; private readonly IStatable _statableCore; @@ -18,9 +18,9 @@ namespace BizHawk.Client.EmuHawk private int _largeStateSize; private int _stateSizeCategory = 1; // 1 = small, 2 = med, 3 = large // TODO: enum - public RewindConfig(Rewinder rewinder, Config config, IStatable statableCore) + public RewindConfig(MainForm mainForm, Config config, IStatable statableCore) { - _rewinder = rewinder; + _mainForm = mainForm; _config = config; _statableCore = statableCore; InitializeComponent(); @@ -28,10 +28,10 @@ namespace BizHawk.Client.EmuHawk private void RewindConfig_Load(object sender, EventArgs e) { - if (_rewinder.HasBuffer) + if (_mainForm.Rewinder.HasBuffer) { - FullnessLabel.Text = $"{_rewinder.FullnessRatio * 100:0.00}%"; - RewindFramesUsedLabel.Text = _rewinder.Count.ToString(); + FullnessLabel.Text = $"{_mainForm.Rewinder.FullnessRatio * 100:0.00}%"; + RewindFramesUsedLabel.Text = _mainForm.Rewinder.Count.ToString(); } else { @@ -173,11 +173,6 @@ namespace BizHawk.Client.EmuHawk _config.Rewind.OnDisk = PutRewindSetting(_config.Rewind.OnDisk, DiskBufferCheckbox.Checked); _config.Rewind.IsThreaded = PutRewindSetting(_config.Rewind.IsThreaded, RewindIsThreadedCheckbox.Checked); - if (TriggerRewindSettingsReload) - { - _rewinder.Initialize(_statableCore, _config.Rewind); - } - // These settings are not used by DoRewindSettings _config.Rewind.SpeedMultiplier = (int)RewindSpeedNumeric.Value; _config.Savestates.CompressionLevelNormal = (int)nudCompression.Value; @@ -188,6 +183,12 @@ namespace BizHawk.Client.EmuHawk _config.Savestates.NoLowResLargeScreenshots = !LowResLargeScreenshotsCheckbox.Checked; _config.Savestates.BigScreenshotSize = (int)BigScreenshotNumeric.Value * 1024; + if (TriggerRewindSettingsReload) + { + _mainForm.Rewinder.Dispose(); + _mainForm.Rewinder = new Rewinder(_statableCore, _config.Rewind); + } + DialogResult = DialogResult.OK; Close(); } @@ -311,9 +312,9 @@ namespace BizHawk.Client.EmuHawk if (UseDeltaCompression.Checked || _stateSize == 0) { - if (_rewinder.Count > 0) + if (_mainForm.Rewinder.Count > 0) { - avgStateSize = _rewinder.Size / _rewinder.Count; + avgStateSize = _mainForm.Rewinder.Size / _mainForm.Rewinder.Count; } else { diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs index 50ca7687ca..dbde92858f 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs @@ -276,7 +276,7 @@ namespace BizHawk.Client.EmuHawk SetTextProperty(); MainForm.RelinquishControl(this); _originalEndAction = Config.Movies.MovieEndAction; - MainForm.ClearRewindData(); + MainForm.DisableRewind(); Config.Movies.MovieEndAction = MovieEndAction.Record; MainForm.SetMainformMovieInfo(); MovieSession.ReadOnly = true; @@ -794,6 +794,7 @@ namespace BizHawk.Client.EmuHawk MainForm.AddOnScreenMessage("TAStudio disengaged"); MainForm.TakeBackControl(); Config.Movies.MovieEndAction = _originalEndAction; + MainForm.EnableRewind(true); MainForm.SetMainformMovieInfo(); }