tastudio: attempt to fix greenzone decay failing to drop states

This commit is contained in:
feos 2018-05-09 17:17:58 +03:00
parent 66b7f37327
commit 056c24e4cf
2 changed files with 55 additions and 23 deletions

View File

@ -9,8 +9,14 @@
means that we lower the priority of a state that goes at that index. Priority changes means that we lower the priority of a state that goes at that index. Priority changes
depending on current frame and amount of states. States with biggest priority get erased depending on current frame and amount of states. States with biggest priority get erased
first. With a 4-bit battern and no initial gap between states, total frame coverage is first. With a 4-bit battern and no initial gap between states, total frame coverage is
about 5 times state count. Initial state gap can screw up our patterns, so do all about 5 times state count.
calculations like gap isn't there, and take it back into account afterwards.
Initial state gap can screw up our patterns, so do all the calculations like the gap
isn't there, and take it back into account afterwards. The algo only works with integral
greenzone, so we make it think it is integral by reducing the frame numbers. Before any
decay logic starts for each state, we check if it has a marker on it (in which case we
don't drop it) or appears inside the state gap (in which case we forcibly drop it). This
step doesn't involve numbers reduction.
_zeros values are essentialy the values of rshiftby here: _zeros values are essentialy the values of rshiftby here:
bitwise view frame rshiftby priority bitwise view frame rshiftby priority
@ -59,7 +65,7 @@ namespace BizHawk.Client.Common
for (; decayStates > 0 && _tsm.StateCount > 1;) for (; decayStates > 0 && _tsm.StateCount > 1;)
{ {
int baseStateIndex = _tsm.GetStateIndexByFrame(Global.Emulator.Frame); int baseStateIndex = _tsm.GetStateIndexByFrame(Global.Emulator.Frame);
int baseStateFrame = _tsm.GetStateFrameByIndex(baseStateIndex) / _step; int baseStateFrame = _tsm.GetStateFrameByIndex(baseStateIndex) / _step; // reduce right away
int forwardPriority = -1000000; int forwardPriority = -1000000;
int backwardPriority = -1000000; int backwardPriority = -1000000;
int forwardFrame = -1; int forwardFrame = -1;
@ -76,14 +82,18 @@ namespace BizHawk.Client.Common
else if (currentFrame % _step > 0) else if (currentFrame % _step > 0)
{ {
// ignore the pattern if the state doesn't belong already, drop it blindly and skip everything // ignore the pattern if the state doesn't belong already, drop it blindly and skip everything
_tsm.RemoveState(currentFrame); if (_tsm.RemoveState(currentFrame))
decayStates--; {
// decrementing this if no state was removed is BAD
decayStates--;
// this is the kind of highly complex loops that might justify goto // this is the kind of highly complex loops that might justify goto
goto next_state; goto next_state;
}
} }
else else
{ {
// reduce to imaginary integral greenzone for all the decay logic
currentFrame /= _step; currentFrame /= _step;
} }
@ -104,7 +114,7 @@ namespace BizHawk.Client.Common
for (int currentStateIndex = _tsm.StateCount - 1; currentStateIndex > baseStateIndex; currentStateIndex--) for (int currentStateIndex = _tsm.StateCount - 1; currentStateIndex > baseStateIndex; currentStateIndex--)
{ {
int currentFrame = _tsm.GetStateFrameByIndex(currentStateIndex) / _step; int currentFrame = _tsm.GetStateFrameByIndex(currentStateIndex);
if (_tsm.StateIsMarker(currentFrame)) if (_tsm.StateIsMarker(currentFrame))
{ {
@ -113,14 +123,18 @@ namespace BizHawk.Client.Common
else if (currentFrame % _step > 0) else if (currentFrame % _step > 0)
{ {
// ignore the pattern if the state doesn't belong already, drop it blindly and skip everything // ignore the pattern if the state doesn't belong already, drop it blindly and skip everything
_tsm.RemoveState(currentFrame); if (_tsm.RemoveState(currentFrame))
decayStates--; {
// decrementing this if no state was removed is BAD
decayStates--;
// this is the kind of highly complex loops that might justify goto // this is the kind of highly complex loops that might justify goto
goto next_state; goto next_state;
}
} }
else else
{ {
// reduce to imaginary integral greenzone for all the decay logic
currentFrame /= _step; currentFrame /= _step;
} }
@ -143,30 +157,46 @@ namespace BizHawk.Client.Common
{ {
if (baseStateFrame - forwardFrame > backwardFrame - baseStateFrame) if (baseStateFrame - forwardFrame > backwardFrame - baseStateFrame)
{ {
_tsm.RemoveState(forwardFrame * _step); if (_tsm.RemoveState(forwardFrame * _step))
{
// decrementing this if no state was removed is BAD
decayStates--;
}
} }
else else
{ {
_tsm.RemoveState(backwardFrame * _step); if (_tsm.RemoveState(backwardFrame * _step))
{
// decrementing this if no state was removed is BAD
decayStates--;
}
} }
decayStates--;
} }
else if (forwardFrame > -1) else if (forwardFrame > -1)
{ {
_tsm.RemoveState(forwardFrame * _step); if (_tsm.RemoveState(forwardFrame * _step))
decayStates--; {
// decrementing this if no state was removed is BAD
decayStates--;
}
} }
else if (backwardFrame > -1) else if (backwardFrame > -1)
{ {
_tsm.RemoveState(backwardFrame * _step); if (_tsm.RemoveState(backwardFrame * _step))
decayStates--; {
// decrementing this if no state was removed is BAD
decayStates--;
}
} }
else else
{ {
// we're very sorry about failing to find states to remove, but we can't go beyond capacity, so remove at least something // we're very sorry about failing to find states to remove, but we can't go beyond capacity, so remove at least something
// this shouldn't happen, but if we don't do it here, nothing good will happen either // this shouldn't happen, but if we don't do it here, nothing good will happen either
_tsm.RemoveState(_tsm.GetStateFrameByIndex(1)); if (_tsm.RemoveState(_tsm.GetStateFrameByIndex(1)))
{
// decrementing this if no state was removed is BAD
decayStates--;
}
} }
// this is the kind of highly complex loops that might justify goto // this is the kind of highly complex loops that might justify goto

View File

@ -262,13 +262,13 @@ namespace BizHawk.Client.Common
return _movie.Markers.IsMarker(frame + 1); return _movie.Markers.IsMarker(frame + 1);
} }
public void RemoveState(int frame) public bool RemoveState(int frame)
{ {
int index = _states.IndexOfKey(frame); int index = _states.IndexOfKey(frame);
if (frame < 1 || index < 1) if (frame < 1 || index < 1)
{ {
return; return false;
} }
StateManagerState state = _states.Values[index]; StateManagerState state = _states.Values[index];
@ -283,6 +283,8 @@ namespace BizHawk.Client.Common
} }
_states.RemoveAt(index); _states.RemoveAt(index);
return true;
} }
/// <summary> /// <summary>