From 4b6fc89a71ccc914eaa40e335f61b8671c987614 Mon Sep 17 00:00:00 2001 From: Daniel Peter Rutschmann Date: Sun, 25 Jul 2021 15:09:42 +0200 Subject: [PATCH] Fix rewinds sometimes drifting 1 frame forward when loaded. (#2878) Co-authored-by: dacin21 --- .../rewind/ZeldaWinder.cs | 34 ++++++++----------- src/BizHawk.Client.Common/rewind/Zwinder.cs | 19 +++++++---- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/BizHawk.Client.Common/rewind/ZeldaWinder.cs b/src/BizHawk.Client.Common/rewind/ZeldaWinder.cs index a0b2a9306e..dfe2ecf412 100644 --- a/src/BizHawk.Client.Common/rewind/ZeldaWinder.cs +++ b/src/BizHawk.Client.Common/rewind/ZeldaWinder.cs @@ -231,31 +231,27 @@ namespace BizHawk.Client.Common if (!_active || _count == 0) return false; - if (_masterFrame == frameToAvoid && _count > 1) + if (_masterFrame == frameToAvoid) { - var index = _buffer.Count - 1; - RefillMaster(_buffer.GetState(index)); - _buffer.InvalidateEnd(index); - _stateSource.LoadStateBinary(new BinaryReader(new MemoryStream(_master, 0, _masterLength, false))); + if (_count > 1) + { + var index = _buffer.Count - 1; + RefillMaster(_buffer.GetState(index)); + _buffer.InvalidateEnd(index); + _stateSource.LoadStateBinary(new BinaryReader(new MemoryStream(_master, 0, _masterLength, false))); + } + else + { + _stateSource.LoadStateBinary(new BinaryReader(new MemoryStream(_master, 0, _masterLength, false))); + _masterFrame = -1; + } _count--; } else { + // The emulator will frame advance without giving us a chance to + // re-capture this frame, so we shouldn't invalidate this state just yet. _stateSource.LoadStateBinary(new BinaryReader(new MemoryStream(_master, 0, _masterLength, false))); - Work(() => - { - var index = _buffer.Count - 1; - if (index >= 0) - { - RefillMaster(_buffer.GetState(index)); - _buffer.InvalidateEnd(index); - } - else - { - _masterFrame = -1; - } - _count--; - }); } return true; } diff --git a/src/BizHawk.Client.Common/rewind/Zwinder.cs b/src/BizHawk.Client.Common/rewind/Zwinder.cs index dd4e048197..8b5b649bfa 100644 --- a/src/BizHawk.Client.Common/rewind/Zwinder.cs +++ b/src/BizHawk.Client.Common/rewind/Zwinder.cs @@ -66,14 +66,21 @@ namespace BizHawk.Client.Common return false; var index = Count - 1; var state = _buffer.GetState(index); - if (state.Frame == frameToAvoid && Count > 1) + if (state.Frame == frameToAvoid) { - // Do not decrement index again. We will "head" this state and not pop it since it will be advanced past - // without an opportunity to capture. This is a bit hackish. - state = _buffer.GetState(index - 1); + if (Count > 1) + { + state = _buffer.GetState(index - 1); + } + _stateSource.LoadStateBinary(new BinaryReader(state.GetReadStream())); + _buffer.InvalidateEnd(index); + } + else + { + // The emulator will frame advance without giving us a chance to + // re-capture this frame, so we shouldn't invalidate this state just yet. + _stateSource.LoadStateBinary(new BinaryReader(state.GetReadStream())); } - _stateSource.LoadStateBinary(new BinaryReader(state.GetReadStream())); - _buffer.InvalidateEnd(index); return true; }