Fix rewinds sometimes drifting 1 frame forward when loaded. (#2878)

Co-authored-by: dacin21 <daniel.rutschmann@gmx.ch>
This commit is contained in:
Daniel Peter Rutschmann 2021-07-25 15:09:42 +02:00 committed by GitHub
parent fd0d5a38c7
commit 4b6fc89a71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 25 deletions

View File

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

View File

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