Add an option to RewindConfig to specify if the rewinder should allow out-of-order states. Currently, the default rewinder should but TAStudio rewinders should not.
Previously, TAStudio's ZwinderStateManager had to handle this, which made the code somewhat confusing. (Especially when I was looking at ZwinderBuffer and forgetting about the default rewinder.)
This commit is contained in:
parent
014cd51ae4
commit
822cc53252
|
@ -34,6 +34,11 @@
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int TargetRewindInterval { get; }
|
int TargetRewindInterval { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies if the rewinder should accept states that are given out of order.
|
||||||
|
/// </summary>
|
||||||
|
bool AllowOutOfOrderStates { get; }
|
||||||
|
|
||||||
public enum BackingStoreType
|
public enum BackingStoreType
|
||||||
{
|
{
|
||||||
Memory,
|
Memory,
|
||||||
|
@ -52,6 +57,8 @@
|
||||||
public bool UseFixedRewindInterval { get; set; } = false;
|
public bool UseFixedRewindInterval { get; set; } = false;
|
||||||
public int TargetFrameLength { get; set; } = 600;
|
public int TargetFrameLength { get; set; } = 600;
|
||||||
public int TargetRewindInterval { get; set; } = 5;
|
public int TargetRewindInterval { get; set; } = 5;
|
||||||
|
public bool AllowOutOfOrderStates { get; set; } = true;
|
||||||
|
|
||||||
public IRewindSettings.BackingStoreType BackingStore { get; set; } = IRewindSettings.BackingStoreType.Memory;
|
public IRewindSettings.BackingStoreType BackingStore { get; set; } = IRewindSettings.BackingStoreType.Memory;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,23 +320,12 @@ namespace BizHawk.Client.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
// We use the gap buffer for forced capture to avoid crowding the "current" buffer and thus reducing it's actual span of covered frames.
|
// We use the gap buffer for forced capture to avoid crowding the "current" buffer and thus reducing it's actual span of covered frames.
|
||||||
if (force)
|
if (NeedsGap(frame) || force)
|
||||||
{
|
{
|
||||||
CaptureGap(frame, source);
|
CaptureGap(frame, source);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We do not want to consider reserved states for a notion of Last
|
|
||||||
// reserved states can include future states in the case of branch states
|
|
||||||
if (frame <= LastRing)
|
|
||||||
{
|
|
||||||
if (NeedsGap(frame))
|
|
||||||
{
|
|
||||||
CaptureGap(frame, source);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_current.Capture(frame,
|
_current.Capture(frame,
|
||||||
s =>
|
s =>
|
||||||
{
|
{
|
||||||
|
@ -404,6 +393,12 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
private bool NeedsGap(int frame)
|
private bool NeedsGap(int frame)
|
||||||
{
|
{
|
||||||
|
// We don't want to "fill gaps" if we are past the latest state in the current/recent buffers.
|
||||||
|
if (frame >= LastRing)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// When starting to fill gaps we won't actually know the true frequency, so fall back to current
|
// When starting to fill gaps we won't actually know the true frequency, so fall back to current
|
||||||
// Current may very well not be the same as gap, but it's a reasonable behavior to have a current sized gap before seeing filler sized gaps
|
// Current may very well not be the same as gap, but it's a reasonable behavior to have a current sized gap before seeing filler sized gaps
|
||||||
var frequency = _gapFiller.Count == 0 ? _current.RewindFrequency : _gapFiller.RewindFrequency;
|
var frequency = _gapFiller.Count == 0 ? _current.RewindFrequency : _gapFiller.RewindFrequency;
|
||||||
|
|
|
@ -109,6 +109,7 @@ namespace BizHawk.Client.Common
|
||||||
BufferSize = CurrentBufferSize,
|
BufferSize = CurrentBufferSize,
|
||||||
UseFixedRewindInterval = false,
|
UseFixedRewindInterval = false,
|
||||||
TargetFrameLength = CurrentTargetFrameLength,
|
TargetFrameLength = CurrentTargetFrameLength,
|
||||||
|
AllowOutOfOrderStates = false,
|
||||||
BackingStore = CurrentStoreType
|
BackingStore = CurrentStoreType
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -120,6 +121,7 @@ namespace BizHawk.Client.Common
|
||||||
BufferSize = RecentBufferSize,
|
BufferSize = RecentBufferSize,
|
||||||
UseFixedRewindInterval = false,
|
UseFixedRewindInterval = false,
|
||||||
TargetFrameLength = RecentTargetFrameLength,
|
TargetFrameLength = RecentTargetFrameLength,
|
||||||
|
AllowOutOfOrderStates = false,
|
||||||
BackingStore = RecentStoreType
|
BackingStore = RecentStoreType
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -131,6 +133,7 @@ namespace BizHawk.Client.Common
|
||||||
BufferSize = GapsBufferSize,
|
BufferSize = GapsBufferSize,
|
||||||
UseFixedRewindInterval = false,
|
UseFixedRewindInterval = false,
|
||||||
TargetFrameLength = GapsTargetFrameLength,
|
TargetFrameLength = GapsTargetFrameLength,
|
||||||
|
AllowOutOfOrderStates = false,
|
||||||
BackingStore = GapsStoreType
|
BackingStore = GapsStoreType
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,7 @@ namespace BizHawk.Client.Common
|
||||||
_fixedRewindInterval = false;
|
_fixedRewindInterval = false;
|
||||||
_targetFrameLength = settings.TargetFrameLength;
|
_targetFrameLength = settings.TargetFrameLength;
|
||||||
}
|
}
|
||||||
|
_allowOutOfOrderStates = settings.AllowOutOfOrderStates;
|
||||||
_states = new StateInfo[STATEMASK + 1];
|
_states = new StateInfo[STATEMASK + 1];
|
||||||
_useCompression = settings.UseCompression;
|
_useCompression = settings.UseCompression;
|
||||||
}
|
}
|
||||||
|
@ -111,6 +112,8 @@ namespace BizHawk.Client.Common
|
||||||
private readonly int _targetFrameLength;
|
private readonly int _targetFrameLength;
|
||||||
private readonly int _targetRewindInterval;
|
private readonly int _targetRewindInterval;
|
||||||
|
|
||||||
|
private readonly bool _allowOutOfOrderStates;
|
||||||
|
|
||||||
private struct StateInfo
|
private struct StateInfo
|
||||||
{
|
{
|
||||||
public long Start;
|
public long Start;
|
||||||
|
@ -162,6 +165,7 @@ namespace BizHawk.Client.Common
|
||||||
_useCompression == settings.UseCompression &&
|
_useCompression == settings.UseCompression &&
|
||||||
_fixedRewindInterval == settings.UseFixedRewindInterval &&
|
_fixedRewindInterval == settings.UseFixedRewindInterval &&
|
||||||
(_fixedRewindInterval ? _targetRewindInterval == settings.TargetRewindInterval : _targetFrameLength == settings.TargetFrameLength) &&
|
(_fixedRewindInterval ? _targetRewindInterval == settings.TargetRewindInterval : _targetFrameLength == settings.TargetFrameLength) &&
|
||||||
|
_allowOutOfOrderStates == settings.AllowOutOfOrderStates &&
|
||||||
_backingStoreType == settings.BackingStore;
|
_backingStoreType == settings.BackingStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,9 +177,8 @@ namespace BizHawk.Client.Common
|
||||||
}
|
}
|
||||||
if (frameDiff < 1)
|
if (frameDiff < 1)
|
||||||
{
|
{
|
||||||
// non-linear time is from a combination of other state changing mechanisms and the rewinder
|
// Manually loading a savestate can cause this. The default rewinder should capture in this situation.
|
||||||
// not much we can say here, so just take a state
|
return _allowOutOfOrderStates;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return frameDiff >= ComputeIdealRewindInterval();
|
return frameDiff >= ComputeIdealRewindInterval();
|
||||||
}
|
}
|
||||||
|
@ -369,6 +372,7 @@ namespace BizHawk.Client.Common
|
||||||
UseFixedRewindInterval = false,
|
UseFixedRewindInterval = false,
|
||||||
TargetFrameLength = targetFrameLength,
|
TargetFrameLength = targetFrameLength,
|
||||||
TargetRewindInterval = 5,
|
TargetRewindInterval = 5,
|
||||||
|
AllowOutOfOrderStates = false,
|
||||||
UseCompression = useCompression
|
UseCompression = useCompression
|
||||||
});
|
});
|
||||||
if (ret.Size != size || ret._sizeMask != sizeMask)
|
if (ret.Size != size || ret._sizeMask != sizeMask)
|
||||||
|
|
Loading…
Reference in New Issue