mirror of https://github.com/stella-emu/stella.git
preliminary state compress code added (disabled)
This commit is contained in:
parent
bfc7574cd7
commit
3f77b95b3b
|
@ -114,49 +114,105 @@ bool RewindManager::unwindState()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void RewindManager::compressStates()
|
void RewindManager::compressStates()
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
myStateList.removeFirst(); // remove the oldest state file
|
myStateList.removeFirst(); // remove the oldest state file
|
||||||
// TODO: add smart state removal
|
#else
|
||||||
|
bool debugMode = myOSystem.eventHandler().state() == EventHandler::S_DEBUGGER;
|
||||||
|
// TODO: let user control these:
|
||||||
|
const double DENSITY = 1.15; // exponential growth of cycle intervals
|
||||||
|
const uInt32 STEP_STATES = 60; // single step rewind length
|
||||||
|
//const uInt32 SECONDS_STATES = 10; // TODO: one second rewind length
|
||||||
|
|
||||||
|
uInt64 currentCycle = myOSystem.console().tia().cycles();
|
||||||
|
uInt64 lastCycle = currentCycle;
|
||||||
|
double expectedCycles = 76 * 262.0; // == cycles of 1 frame, TODO: use actual number of scanlines
|
||||||
|
double maxDelta = 0;
|
||||||
|
uInt32 removeIdx = 0;
|
||||||
|
|
||||||
|
uInt32 idx = 0;
|
||||||
|
for(auto it = myStateList.begin(); it != myStateList.end(); ++it)
|
||||||
|
{
|
||||||
|
// test and never remove the very first saved state
|
||||||
|
if(++it == myStateList.end())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
--it; // UGLY!
|
||||||
|
|
||||||
|
if(idx >= STEP_STATES)
|
||||||
|
{
|
||||||
|
expectedCycles *= DENSITY;
|
||||||
|
|
||||||
|
double expected = expectedCycles * (1 + DENSITY);
|
||||||
|
uInt64 prev = (--it)->cycle; ++it; // UGLY!
|
||||||
|
uInt64 next = (++it)->cycle; --it; // UGLY!
|
||||||
|
double delta = expected / (prev - next);
|
||||||
|
|
||||||
|
if(delta > maxDelta)
|
||||||
|
{
|
||||||
|
maxDelta = delta;
|
||||||
|
removeIdx = idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastCycle = it->cycle;
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
if (maxDelta < 1)
|
||||||
|
{
|
||||||
|
// the horizon is getting too big
|
||||||
|
//myStateList.remove(idx - 1); // remove oldest but one
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//myStateList.remove(removeIdx); // remove
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string RewindManager::getMessage(RewindState& state)
|
string RewindManager::getMessage(RewindState& state)
|
||||||
{
|
{
|
||||||
const Int64 NTSC_FREQ = 1193182;
|
const uInt64 NTSC_FREQ = 1193182; // ~76*262*60
|
||||||
const Int64 PAL_FREQ = 1182298;
|
const uInt64 PAL_FREQ = 1182298; // ~76*312*50
|
||||||
|
const uInt64 freq = myIsNTSC ? NTSC_FREQ : PAL_FREQ; // = cycles/second
|
||||||
|
const uInt64 scanlines = myIsNTSC ? 262 : 312; // TODO: use actual number of scanlines
|
||||||
|
//const uInt64 fps = myIsNTSC ? 60 : 50; // TODO: use actual FPS
|
||||||
|
|
||||||
Int64 diff = myOSystem.console().tia().cycles() - state.cycle,
|
Int64 diff = myOSystem.console().tia().cycles() - state.cycle,
|
||||||
freq = myIsNTSC ? NTSC_FREQ : PAL_FREQ,
|
|
||||||
diffUnit;
|
diffUnit;
|
||||||
stringstream message;
|
stringstream message;
|
||||||
string unit;
|
string unit;
|
||||||
freq = NTSC_FREQ; // TODO: remove
|
|
||||||
message << (diff >= 0 ? "Rewind" : "Unwind");
|
message << (diff >= 0 ? "Rewind" : "Unwind");
|
||||||
diff = abs(diff);
|
diff = abs(diff);
|
||||||
|
|
||||||
if(diff < 76 * 2)
|
// use the lower unit up to twice the next unit, except for an exact match of the next unit
|
||||||
|
// TODO: does the latter make sense, e.g. for ROMs with changing scanlines?
|
||||||
|
if(diff < 76 * 2 && diff % 76 != 0)
|
||||||
{
|
{
|
||||||
unit = "cycle";
|
unit = "cycle";
|
||||||
diffUnit = diff;
|
diffUnit = diff;
|
||||||
}
|
}
|
||||||
else if(diff < 76 * 262 * 2)
|
else if(diff < 76 * scanlines * 2 && diff % (76 * scanlines) != 0)
|
||||||
{
|
{
|
||||||
unit = "scanline";
|
unit = "scanline";
|
||||||
diffUnit = diff / 76;
|
diffUnit = diff / 76;
|
||||||
}
|
}
|
||||||
else if(diff < NTSC_FREQ * 2)
|
else if(diff < freq * 2 && diff % freq != 0)
|
||||||
{
|
{
|
||||||
unit = "frame";
|
unit = "frame";
|
||||||
diffUnit = diff / (76 * 262);
|
diffUnit = diff / (76 * scanlines);
|
||||||
}
|
}
|
||||||
else if(diff < NTSC_FREQ * 60 * 2)
|
else if(diff < freq * 60 * 2 && diff % (freq * 60) != 0)
|
||||||
{
|
{
|
||||||
unit = "second";
|
unit = "second";
|
||||||
diffUnit = diff / NTSC_FREQ;
|
diffUnit = diff / freq;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unit = "minute";
|
unit = "minute";
|
||||||
diffUnit = diff / (NTSC_FREQ * 60);
|
diffUnit = diff / (freq * 60);
|
||||||
}
|
} // TODO: do we need hours here? don't think so
|
||||||
message << " " << diffUnit << " " << unit;
|
message << " " << diffUnit << " " << unit;
|
||||||
if(diffUnit != 1)
|
if(diffUnit != 1)
|
||||||
message << "s";
|
message << "s";
|
||||||
|
|
|
@ -71,7 +71,7 @@ class RewindManager
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Maximum number of states to save
|
// Maximum number of states to save
|
||||||
static constexpr uInt32 MAX_SIZE = 100;
|
static constexpr uInt32 MAX_SIZE = 100; // TODO: use a parameter here and allow user to define size in UI
|
||||||
|
|
||||||
OSystem& myOSystem;
|
OSystem& myOSystem;
|
||||||
StateManager& myStateManager;
|
StateManager& myStateManager;
|
||||||
|
|
|
@ -156,7 +156,7 @@ void StateManager::update()
|
||||||
switch(myActiveMode)
|
switch(myActiveMode)
|
||||||
{
|
{
|
||||||
case Mode::Rewind:
|
case Mode::Rewind:
|
||||||
myRewindManager->addState("1 frame");
|
myRewindManager->addState("add 1 frame");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
Loading…
Reference in New Issue