Show message indicating what is being done when rewinding state (ie, '1 step', '10 frames', etc).

This commit is contained in:
Stephen Anthony 2017-09-11 15:58:41 -02:30
parent 3d7c23b361
commit 86f65e8e87
4 changed files with 48 additions and 25 deletions

View File

@ -29,30 +29,31 @@ RewindManager::RewindManager(OSystem& system, StateManager& statemgr)
mySize(0),
myTop(0)
{
for(int i = 0; i < MAX_SIZE; ++i)
myStateList[i] = nullptr;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RewindManager::~RewindManager()
{
for(int i = 0; i < MAX_SIZE; ++i)
delete myStateList[i];
for(uInt8 i = 0; i < MAX_SIZE; ++i)
delete myStateList[i].data;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool RewindManager::addState(const string& message)
{
// Create a new Serializer object if we need one
if(myStateList[myTop] == nullptr)
myStateList[myTop] = new Serializer();
Serializer& s = *(myStateList[myTop]);
if(myStateList[myTop].data == nullptr)
myStateList[myTop].data = new Serializer();
if(s)
// And use it to store the serialized data and text message
if(myStateList[myTop].data != nullptr)
{
Serializer& s = *(myStateList[myTop].data);
s.reset();
if(myStateManager.saveState(s) && myOSystem.console().tia().saveDisplay(s))
{
myStateList[myTop].message = "Rewind " + message;
// Are we still within the allowable size, or are we overwriting an item?
mySize++; if(mySize > MAX_SIZE) mySize = MAX_SIZE;
myTop = (myTop + 1) % MAX_SIZE;
@ -70,12 +71,15 @@ bool RewindManager::rewindState()
{
mySize--;
myTop = myTop == 0 ? MAX_SIZE - 1 : myTop - 1;
Serializer& s = *(myStateList[myTop]);
Serializer& s = *(myStateList[myTop].data);
s.reset();
myStateManager.loadState(s);
myOSystem.console().tia().loadDisplay(s);
// Show message indicating the rewind state
myOSystem.frameBuffer().showMessage(myStateList[myTop].message);
return true;
}
else
@ -85,9 +89,9 @@ bool RewindManager::rewindState()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RewindManager::clear()
{
for(int i = 0; i < MAX_SIZE; ++i)
if(myStateList[i] != nullptr)
myStateList[i]->reset();
for(uInt8 i = 0; i < MAX_SIZE; ++i)
if(myStateList[i].data != nullptr)
myStateList[i].data->reset();
myTop = mySize = 0;
}

View File

@ -57,13 +57,20 @@ class RewindManager
private:
// Maximum number of states to save
enum { MAX_SIZE = 100 };
static constexpr uInt8 MAX_SIZE = 100;
OSystem& myOSystem;
StateManager& myStateManager;
Serializer* myStateList[MAX_SIZE];
uInt32 mySize, myTop;
struct SerialData {
Serializer* data;
string message;
SerialData(Serializer* d = nullptr) : data(d) { }
};
SerialData myStateList[MAX_SIZE];
uInt8 mySize, myTop;
private:
// Following constructors and assignment operators not supported

View File

@ -300,7 +300,7 @@ void Debugger::loadState(int state)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Debugger::step()
{
saveOldState();
saveOldState("1 step");
mySystem.clearDirtyPages();
uInt64 startCycle = mySystem.cycles();
@ -313,7 +313,6 @@ int Debugger::step()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// trace is just like step, except it treats a subroutine call as one
// instruction.
@ -328,7 +327,7 @@ int Debugger::trace()
// 32 is the 6502 JSR instruction:
if(mySystem.peek(myCpuDebug->pc()) == 32)
{
saveOldState();
saveOldState("1 trace");
mySystem.clearDirtyPages();
uInt64 startCycle = mySystem.cycles();
@ -401,7 +400,12 @@ bool Debugger::writeTrap(uInt16 t)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::nextScanline(int lines)
{
saveOldState();
ostringstream buf;
buf << lines << " scanline";
if(lines > 1)
buf << "s";
saveOldState(buf.str());
mySystem.clearDirtyPages();
unlockBankswitchState();
@ -418,7 +422,12 @@ void Debugger::nextScanline(int lines)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::nextFrame(int frames)
{
saveOldState();
ostringstream buf;
buf << frames << " frame";
if(frames > 1)
buf << "s";
saveOldState(buf.str());
mySystem.clearDirtyPages();
unlockBankswitchState();
@ -472,7 +481,7 @@ bool Debugger::patchROM(uInt16 addr, uInt8 value)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::saveOldState(bool addrewind)
void Debugger::saveOldState(string rewindMsg)
{
myCartDebug->saveOldState();
myCpuDebug->saveOldState();
@ -480,10 +489,10 @@ void Debugger::saveOldState(bool addrewind)
myTiaDebug->saveOldState();
// Add another rewind level to the Undo list
if(addrewind)
if(rewindMsg != "")
{
RewindManager& r = myOSystem.state().rewindManager();
r.addState();
r.addState(rewindMsg);
myDialog->rewindButton().setEnabled(!r.empty());
}
}
@ -501,7 +510,7 @@ void Debugger::setStartState()
myDialog->rewindButton().setEnabled(!r.empty());
// Save initial state, but don't add it to the rewind list
saveOldState(false);
saveOldState(); // FIXME - rework this
// Set the 're-disassemble' flag, but don't do it until the next scheduled time
myDialog->rom().invalidate(false);

View File

@ -231,8 +231,11 @@ class Debugger : public DialogContainer
private:
/**
Save state of each debugger subsystem.
If a message is provided, we assume that a rewind state should
be saved with the given message.
*/
void saveOldState(bool addrewind = true);
void saveOldState(string rewindMsg = "");
/**
Set initial state before entering the debugger.