mirror of https://github.com/stella-emu/stella.git
First pass at continuous state saving in emulation mode, accessible by the debugger:
- Toggle this with Alt-r. When enabled, state is saved each frame to memory (up to 100 slots) - Upon entering the debugger, rewind is immediately available, allowing to rewind (for example) back past a breakpoint - Testing is definitely required.
This commit is contained in:
parent
628f981121
commit
aed2945a56
|
@ -44,7 +44,7 @@ class RewindManager
|
|||
|
||||
@param message Message to display when rewinding to this state
|
||||
*/
|
||||
bool addState(const string& message = "");
|
||||
bool addState(const string& message);
|
||||
|
||||
/**
|
||||
Rewind one level of the state list, and display the message associated
|
||||
|
|
|
@ -35,16 +35,16 @@
|
|||
StateManager::StateManager(OSystem& osystem)
|
||||
: myOSystem(osystem),
|
||||
myCurrentSlot(0),
|
||||
myActiveMode(kOffMode)
|
||||
myActiveMode(Mode::Off)
|
||||
{
|
||||
myRewindManager = make_unique<RewindManager>(myOSystem, *this);
|
||||
reset();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool StateManager::toggleRecordMode()
|
||||
{
|
||||
#if 0
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void StateManager::toggleRecordMode()
|
||||
{
|
||||
if(myActiveMode != kMovieRecordMode) // Turn on movie record mode
|
||||
{
|
||||
myActiveMode = kOffMode;
|
||||
|
@ -81,15 +81,8 @@ bool StateManager::toggleRecordMode()
|
|||
}
|
||||
|
||||
return myActiveMode == kMovieRecordMode;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool StateManager::toggleRewindMode()
|
||||
{
|
||||
// FIXME - For now, I'm going to use this to activate movie playback
|
||||
#if 0
|
||||
////////////////////////////////////////////////////////
|
||||
// FIXME - For now, I'm going to use this to activate movie playback
|
||||
// Close the writer, since we're about to re-open in read mode
|
||||
myMovieWriter.close();
|
||||
|
||||
|
@ -128,34 +121,44 @@ bool StateManager::toggleRewindMode()
|
|||
myMovieReader.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
return myActiveMode == kMoviePlaybackMode;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void StateManager::toggleRewindMode()
|
||||
{
|
||||
myActiveMode = myActiveMode == Mode::Rewind ? Mode::Off : Mode::Rewind;
|
||||
if(myActiveMode == Mode::Rewind)
|
||||
myOSystem.frameBuffer().showMessage("Continuous rewind enabled");
|
||||
else
|
||||
myOSystem.frameBuffer().showMessage("Continuous rewind disabled");
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void StateManager::update()
|
||||
{
|
||||
#if 0
|
||||
switch(myActiveMode)
|
||||
{
|
||||
case kMovieRecordMode:
|
||||
case Mode::Rewind:
|
||||
myRewindManager->addState("1 frame");
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case Mode::MovieRecord:
|
||||
myOSystem.console().controller(Controller::Left).save(myMovieWriter);
|
||||
myOSystem.console().controller(Controller::Right).save(myMovieWriter);
|
||||
myOSystem.console().switches().save(myMovieWriter);
|
||||
break;
|
||||
|
||||
case kMoviePlaybackMode:
|
||||
case Mode::MoviePlayback:
|
||||
myOSystem.console().controller(Controller::Left).load(myMovieReader);
|
||||
myOSystem.console().controller(Controller::Right).load(myMovieReader);
|
||||
myOSystem.console().switches().load(myMovieReader);
|
||||
break;
|
||||
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -33,41 +33,58 @@ class OSystem;
|
|||
class StateManager
|
||||
{
|
||||
public:
|
||||
enum class Mode {
|
||||
Off,
|
||||
Rewind,
|
||||
MovieRecord,
|
||||
MoviePlayback
|
||||
};
|
||||
|
||||
/**
|
||||
Create a new statemananger class
|
||||
Create a new statemananger class.
|
||||
*/
|
||||
StateManager(OSystem& osystem);
|
||||
|
||||
public:
|
||||
/**
|
||||
Answers whether the manager is in record or playback mode
|
||||
Answers whether the manager is in record or playback mode.
|
||||
*/
|
||||
bool isActive() const { return myActiveMode != kOffMode; }
|
||||
Mode mode() const { return myActiveMode; }
|
||||
|
||||
bool toggleRecordMode();
|
||||
bool toggleRewindMode();
|
||||
#if 0
|
||||
/**
|
||||
Toggle movie recording mode (FIXME - currently disabled)
|
||||
*/
|
||||
void toggleRecordMode();
|
||||
#endif
|
||||
|
||||
/**
|
||||
Updates the state of the system based on the currently active mode
|
||||
Toggle state rewind recording mode; this uses the RewindManager
|
||||
for its functionality.
|
||||
*/
|
||||
void toggleRewindMode();
|
||||
|
||||
/**
|
||||
Updates the state of the system based on the currently active mode.
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
Load a state into the current system
|
||||
Load a state into the current system.
|
||||
|
||||
@param slot The state 'slot' to load state from
|
||||
*/
|
||||
void loadState(int slot = -1);
|
||||
|
||||
/**
|
||||
Save the current state from the system
|
||||
Save the current state from the system.
|
||||
|
||||
@param slot The state 'slot' to save into
|
||||
*/
|
||||
void saveState(int slot = -1);
|
||||
|
||||
/**
|
||||
Switches to the next higher state slot (circular queue style)
|
||||
Switches to the next higher state slot (circular queue style).
|
||||
*/
|
||||
void changeState();
|
||||
|
||||
|
@ -92,7 +109,7 @@ class StateManager
|
|||
bool saveState(Serializer& out);
|
||||
|
||||
/**
|
||||
Resets manager to defaults
|
||||
Resets manager to defaults.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
|
@ -102,14 +119,6 @@ class StateManager
|
|||
RewindManager& rewindManager() const { return *myRewindManager; }
|
||||
|
||||
private:
|
||||
enum Mode {
|
||||
kOffMode,
|
||||
kMoviePlaybackMode,
|
||||
kMovieRecordMode,
|
||||
kRewindPlaybackMode,
|
||||
kRewindRecordMode
|
||||
};
|
||||
|
||||
enum {
|
||||
kVersion = 001
|
||||
};
|
||||
|
|
|
@ -505,12 +505,12 @@ void Debugger::setStartState()
|
|||
|
||||
// If rewinding is not enabled, always start the debugger with a clean list
|
||||
RewindManager& r = myOSystem.state().rewindManager();
|
||||
if(0) // FIXME
|
||||
if(myOSystem.state().mode() == StateManager::Mode::Off)
|
||||
r.clear();
|
||||
myDialog->rewindButton().setEnabled(!r.empty());
|
||||
|
||||
// Save initial state, but don't add it to the rewind list
|
||||
saveOldState(); // FIXME - rework this
|
||||
saveOldState();
|
||||
|
||||
// Set the 're-disassemble' flag, but don't do it until the next scheduled time
|
||||
myDialog->rom().invalidate(false);
|
||||
|
|
|
@ -197,27 +197,20 @@ void EventHandler::poll(uInt64 time)
|
|||
{
|
||||
myOSystem.console().riot().update();
|
||||
|
||||
#if 0
|
||||
// Now check if the StateManager should be saving or loading state
|
||||
// Per-frame cheats are disabled if the StateManager is active, since
|
||||
// it would interfere with proper playback
|
||||
if(myOSystem.state().isActive())
|
||||
{
|
||||
// (for rewind and/or movies
|
||||
if(myOSystem.state().mode() != StateManager::Mode::Off)
|
||||
myOSystem.state().update();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef CHEATCODE_SUPPORT
|
||||
for(auto& cheat: myOSystem.cheat().perFrame())
|
||||
cheat->evaluate();
|
||||
#endif
|
||||
|
||||
// Handle continuous snapshots
|
||||
if(myContSnapshotInterval > 0 &&
|
||||
(++myContSnapshotCounter % myContSnapshotInterval == 0))
|
||||
takeSnapshot(uInt32(time) >> 10); // not quite milliseconds, but close enough
|
||||
}
|
||||
#ifdef CHEATCODE_SUPPORT
|
||||
for(auto& cheat: myOSystem.cheat().perFrame())
|
||||
cheat->evaluate();
|
||||
#endif
|
||||
|
||||
// Handle continuous snapshots
|
||||
if(myContSnapshotInterval > 0 &&
|
||||
(++myContSnapshotCounter % myContSnapshotInterval == 0))
|
||||
takeSnapshot(uInt32(time) >> 10); // not quite milliseconds, but close enough
|
||||
}
|
||||
else if(myOverlay)
|
||||
{
|
||||
|
@ -441,6 +434,10 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
|
|||
myOSystem.frameBuffer().toggleFrameStats();
|
||||
break;
|
||||
|
||||
case KBDK_R: // Alt-r toggles continuous store rewind states
|
||||
myOSystem.state().toggleRewindMode();
|
||||
break;
|
||||
|
||||
case KBDK_S:
|
||||
if(myContSnapshotInterval == 0)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue