mirror of https://github.com/stella-emu/stella.git
state compression improved
RewindManager class refactored for multiple rewinds/unwinds additional keys for faster rewinding added docs updated
This commit is contained in:
parent
984e304f43
commit
ba9d809109
|
@ -316,9 +316,11 @@ used.</p>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>The larger button at the left top (labeled '<') performs the rewind operation,
|
<p>The larger button at the left top (labeled '<') performs the rewind operation,
|
||||||
which will undo the previous Step/Trace/Scan/Frame advance, the smaller button at
|
which will undo the previous Step/Trace/Scan/Frame... advance, the smaller button at
|
||||||
the left bottom (labeled '>') performs the unwind operation, which will undo the
|
the left bottom (labeled '>') performs the unwind operation, which will undo the
|
||||||
previous rewind operation. The rewind buffer is 100 levels deep by default.<p>
|
previous rewind operation. The rewind buffer is 100 levels deep by default, the
|
||||||
|
size can be configured e.g. in the
|
||||||
|
<b><a href="index.html#Debugger">Developer Settings</a> - States</b> dialog.<p>
|
||||||
|
|
||||||
<p>The other operations are Step, Trace, Scan+1, Frame+1 and Exit (debugger).</p>
|
<p>The other operations are Step, Trace, Scan+1, Frame+1 and Exit (debugger).</p>
|
||||||
|
|
||||||
|
@ -347,11 +349,27 @@ previous rewind operation. The rewind buffer is 100 levels deep by default.<p>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Control-r</td>
|
<td>Control-r</td>
|
||||||
<td>Rewind</td>
|
<td>Rewind 1</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Shift-Control-r</td>
|
<td>Control-Shift-r</td>
|
||||||
<td>Unwind</td>
|
<td>Rewind 10</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Control-Alt-r</td>
|
||||||
|
<td>Rewind all</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Control-y</td>
|
||||||
|
<td>Unwind 1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Control-Shift-y</td>
|
||||||
|
<td>Unwind 10</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Control-Alt-y</td>
|
||||||
|
<td>Unwind all</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Backquote (`)</td>
|
<td>Backquote (`)</td>
|
||||||
|
|
|
@ -1622,11 +1622,31 @@
|
||||||
<td>Alt + Left arrow</td>
|
<td>Alt + Left arrow</td>
|
||||||
<td>Cmd + Left arrow</td>
|
<td>Cmd + Left arrow</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Rewind by 10 states (pauses emulation)</td>
|
||||||
|
<td>Shift-Alt + Left arrow</td>
|
||||||
|
<td>Shift-Cmd + Left arrow</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Rewind all states (pauses emulation)</td>
|
||||||
|
<td>Alt + Down arrow</td>
|
||||||
|
<td>Cmd + Down arrow</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Unwind by one state (pauses emulation)</td>
|
<td>Unwind by one state (pauses emulation)</td>
|
||||||
<td>Alt + Right arrow</td>
|
<td>Alt + Right arrow</td>
|
||||||
<td>Cmd + Right arrow</td>
|
<td>Cmd + Right arrow</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Unwind by 10 states (pauses emulation)</td>
|
||||||
|
<td>Shift-Alt + Right arrow</td>
|
||||||
|
<td>Shift-Cmd + Right arrow</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Unwind all states (pauses emulation)</td>
|
||||||
|
<td>Alt + Up arrow</td>
|
||||||
|
<td>Cmd + Up arrow</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p><b>UI keys in Text Editing areas (cannot be remapped)</b></p>
|
<p><b>UI keys in Text Editing areas (cannot be remapped)</b></p>
|
||||||
|
|
|
@ -175,26 +175,22 @@ class LinkedObjectPool
|
||||||
moveToPrevious(); // if so, move to the previous node
|
moveToPrevious(); // if so, move to the previous node
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/**
|
/**
|
||||||
Convenience method to remove a single element from the active list at
|
Remove a single element from the active list at position of the iterator.
|
||||||
position of the iterator +- the offset.
|
|
||||||
*/
|
*/
|
||||||
void remove(const_iter i, Int32 offset = 0) {
|
void remove(const_iter i) {
|
||||||
myPool.splice(myPool.end(), myList,
|
myPool.splice(myPool.end(), myList, i);
|
||||||
offset >= 0 ? std::next(i, offset) : std::prev(i, -offset));
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
/**
|
/**
|
||||||
Convenience method to remove a single element from the active list by
|
Remove a single element from the active list by index, offset from
|
||||||
index, offset from the beginning of the list. (ie, '0' means first
|
the beginning of the list. (ie, '0' means first element, '1' is second,
|
||||||
element, '1' is second, and so on).
|
and so on).
|
||||||
*/
|
*/
|
||||||
void remove(uInt32 index) {
|
void remove(uInt32 index) {
|
||||||
myPool.splice(myPool.end(), myList, std::next(myList.begin(), index));
|
myPool.splice(myPool.end(), myList, std::next(myList.begin(), index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Remove range of elements from the beginning of the active list to
|
Remove range of elements from the beginning of the active list to
|
||||||
the 'current' node.
|
the 'current' node.
|
||||||
|
|
|
@ -130,38 +130,58 @@ bool RewindManager::addState(const string& message, bool continuous)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool RewindManager::rewindState()
|
uInt32 RewindManager::rewindState(uInt32 numStates)
|
||||||
{
|
{
|
||||||
|
uInt64 startCycles = myOSystem.console().tia().cycles();
|
||||||
|
uInt32 i;
|
||||||
|
string message;
|
||||||
|
|
||||||
|
for(i = 0; i < numStates; ++i)
|
||||||
|
{
|
||||||
if(!atFirst())
|
if(!atFirst())
|
||||||
{
|
{
|
||||||
if (!myLastContinuousAdd)
|
if(!myLastContinuousAdd)
|
||||||
// Set internal current iterator to previous state (back in time),
|
// Set internal current iterator to previous state (back in time),
|
||||||
// since we will now processed this state
|
// since we will now processed this state
|
||||||
myStateList.moveToPrevious();
|
myStateList.moveToPrevious();
|
||||||
myLastContinuousAdd = false;
|
myLastContinuousAdd = false;
|
||||||
|
|
||||||
//RewindState& lastState = myStateList.current();
|
|
||||||
|
|
||||||
RewindState& state = myStateList.current();
|
RewindState& state = myStateList.current();
|
||||||
Serializer& s = state.data;
|
Serializer& s = state.data;
|
||||||
string message = getMessage(state);
|
|
||||||
//cerr << "rewind " << state.count << endl;
|
//cerr << "rewind " << state.count << endl;
|
||||||
|
|
||||||
s.rewind(); // rewind Serializer internal buffers
|
s.rewind(); // rewind Serializer internal buffers
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i)
|
||||||
|
{
|
||||||
|
RewindState& state = myStateList.current();
|
||||||
|
Serializer& s = state.data;
|
||||||
|
|
||||||
myStateManager.loadState(s);
|
myStateManager.loadState(s);
|
||||||
myOSystem.console().tia().loadDisplay(s);
|
myOSystem.console().tia().loadDisplay(s);
|
||||||
|
|
||||||
// Show message indicating the rewind state
|
// Get message indicating the rewind state
|
||||||
myOSystem.frameBuffer().showMessage(message);
|
message = getMessage(startCycles, i);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
myOSystem.frameBuffer().showMessage("Rewind not possible");
|
else
|
||||||
return false;
|
message = "Rewind not possible";
|
||||||
|
|
||||||
|
myOSystem.frameBuffer().showMessage(message);
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool RewindManager::unwindState()
|
uInt32 RewindManager::unwindState(uInt32 numStates)
|
||||||
{
|
{
|
||||||
|
uInt64 startCycles = myOSystem.console().tia().cycles();
|
||||||
|
uInt32 i;
|
||||||
|
string message;
|
||||||
|
|
||||||
|
for(i = 0; i < numStates; ++i)
|
||||||
|
{
|
||||||
if(!atLast())
|
if(!atLast())
|
||||||
{
|
{
|
||||||
// Set internal current iterator to nextCycles state (forward in time),
|
// Set internal current iterator to nextCycles state (forward in time),
|
||||||
|
@ -170,19 +190,30 @@ bool RewindManager::unwindState()
|
||||||
|
|
||||||
RewindState& state = myStateList.current();
|
RewindState& state = myStateList.current();
|
||||||
Serializer& s = state.data;
|
Serializer& s = state.data;
|
||||||
string message = getMessage(state);
|
|
||||||
//cerr << "unwind " << state.count << endl;
|
//cerr << "unwind " << state.count << endl;
|
||||||
|
|
||||||
s.rewind(); // rewind Serializer internal buffers
|
s.rewind(); // rewind Serializer internal buffers
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i)
|
||||||
|
{
|
||||||
|
RewindState& state = myStateList.current();
|
||||||
|
Serializer& s = state.data;
|
||||||
|
|
||||||
myStateManager.loadState(s);
|
myStateManager.loadState(s);
|
||||||
myOSystem.console().tia().loadDisplay(s);
|
myOSystem.console().tia().loadDisplay(s);
|
||||||
|
|
||||||
// Show message indicating the rewind state
|
// Get message indicating the rewind state
|
||||||
|
message = getMessage(startCycles, i);
|
||||||
myOSystem.frameBuffer().showMessage(message);
|
myOSystem.frameBuffer().showMessage(message);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
myOSystem.frameBuffer().showMessage("Unwind not possible");
|
else
|
||||||
return false;
|
message = "Unwind not possible";
|
||||||
|
|
||||||
|
myOSystem.frameBuffer().showMessage(message);
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -191,8 +222,8 @@ void RewindManager::compressStates()
|
||||||
uInt64 currentCycles = myOSystem.console().tia().cycles();
|
uInt64 currentCycles = myOSystem.console().tia().cycles();
|
||||||
double expectedCycles = myInterval * myFactor * (1 + myFactor);
|
double expectedCycles = myInterval * myFactor * (1 + myFactor);
|
||||||
double maxError = 1;
|
double maxError = 1;
|
||||||
uInt32 removeIdx = 0;
|
|
||||||
uInt32 idx = myStateList.size() - 2;
|
uInt32 idx = myStateList.size() - 2;
|
||||||
|
Common::LinkedObjectPool<RewindState>::const_iter removeIter = myStateList.first();
|
||||||
|
|
||||||
//cerr << "idx: " << idx << endl;
|
//cerr << "idx: " << idx << endl;
|
||||||
// iterate from last but one to first but one
|
// iterate from last but one to first but one
|
||||||
|
@ -211,7 +242,7 @@ void RewindManager::compressStates()
|
||||||
if(error > maxError)
|
if(error > maxError)
|
||||||
{
|
{
|
||||||
maxError = error;
|
maxError = error;
|
||||||
removeIdx = idx;
|
removeIter = it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
--idx;
|
--idx;
|
||||||
|
@ -224,22 +255,23 @@ void RewindManager::compressStates()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myStateList.remove(removeIdx); // remove
|
myStateList.remove(removeIter); // remove
|
||||||
//cerr << "remove " << removeIdx << endl;
|
//cerr << "remove " << removeIdx << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string RewindManager::getMessage(RewindState& state)
|
string RewindManager::getMessage(Int64 startCycles, uInt32 numStates)
|
||||||
{
|
{
|
||||||
Int64 diff = myOSystem.console().tia().cycles() - state.cycles;
|
RewindState& state = myStateList.current();
|
||||||
|
Int64 diff = startCycles - state.cycles;
|
||||||
stringstream message;
|
stringstream message;
|
||||||
|
|
||||||
message << (diff >= 0 ? "Rewind" : "Unwind") << " " << getUnitString(diff);
|
message << (diff >= 0 ? "Rewind" : "Unwind") << " " << getUnitString(diff);
|
||||||
|
|
||||||
message << " [" << myStateList.currentIdx() << "/" << myStateList.size() << "]";
|
message << " [" << myStateList.currentIdx() << "/" << myStateList.size() << "]";
|
||||||
|
|
||||||
// add optional message
|
// add optional message
|
||||||
if(!state.message.empty())
|
if(numStates == 1 && !state.message.empty())
|
||||||
message << " (" << state.message << ")";
|
message << " (" << state.message << ")";
|
||||||
|
|
||||||
return message.str();
|
return message.str();
|
||||||
|
|
|
@ -99,6 +99,7 @@ class RewindManager
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Initializes state list and calculates compression factor.
|
||||||
*/
|
*/
|
||||||
void setup();
|
void setup();
|
||||||
|
|
||||||
|
@ -113,14 +114,20 @@ class RewindManager
|
||||||
/**
|
/**
|
||||||
Rewind one level of the state list, and display the message associated
|
Rewind one level of the state list, and display the message associated
|
||||||
with that state.
|
with that state.
|
||||||
|
|
||||||
|
@param numStates Number of states to rewind
|
||||||
|
@return Number of states to rewinded
|
||||||
*/
|
*/
|
||||||
bool rewindState();
|
uInt32 rewindState(uInt32 numStates = 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Unwind one level of the state list, and display the message associated
|
Unwind one level of the state list, and display the message associated
|
||||||
with that state.
|
with that state.
|
||||||
|
|
||||||
|
@param numStates Number of states to unwind
|
||||||
|
@return Number of states to unwinded
|
||||||
*/
|
*/
|
||||||
bool unwindState();
|
uInt32 unwindState(uInt32 numStates = 1);
|
||||||
|
|
||||||
bool atFirst() const { return myStateList.atFirst(); }
|
bool atFirst() const { return myStateList.atFirst(); }
|
||||||
bool atLast() const { return myStateList.atLast(); }
|
bool atLast() const { return myStateList.atLast(); }
|
||||||
|
@ -167,9 +174,17 @@ class RewindManager
|
||||||
// frequent (de)-allocations)
|
// frequent (de)-allocations)
|
||||||
Common::LinkedObjectPool<RewindState, INITIAL_SIZE> myStateList;
|
Common::LinkedObjectPool<RewindState, INITIAL_SIZE> myStateList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Remove a save state from the list
|
||||||
|
*/
|
||||||
void compressStates();
|
void compressStates();
|
||||||
|
|
||||||
string getMessage(RewindState& state);
|
/**
|
||||||
|
Get the message string for the rewind/unwind
|
||||||
|
|
||||||
|
@return The message
|
||||||
|
*/
|
||||||
|
string getMessage(Int64 startCycles, uInt32 numStates);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -142,17 +142,17 @@ void StateManager::toggleRewindMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool StateManager::rewindState()
|
bool StateManager::rewindState(uInt32 numStates)
|
||||||
{
|
{
|
||||||
RewindManager& r = myOSystem.state().rewindManager();
|
RewindManager& r = myOSystem.state().rewindManager();
|
||||||
return r.rewindState();
|
return r.rewindState(numStates);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool StateManager::unwindState()
|
bool StateManager::unwindState(uInt32 numStates)
|
||||||
{
|
{
|
||||||
RewindManager& r = myOSystem.state().rewindManager();
|
RewindManager& r = myOSystem.state().rewindManager();
|
||||||
return r.unwindState();
|
return r.unwindState(numStates);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -74,12 +74,12 @@ class StateManager
|
||||||
/**
|
/**
|
||||||
Rewinds one state; this uses the RewindManager for its functionality.
|
Rewinds one state; this uses the RewindManager for its functionality.
|
||||||
*/
|
*/
|
||||||
bool rewindState();
|
bool rewindState(uInt32 numStates = 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Unwinds one state; this uses the RewindManager for its functionality.
|
Unwinds one state; this uses the RewindManager for its functionality.
|
||||||
*/
|
*/
|
||||||
bool unwindState();
|
bool unwindState(uInt32 numStates = 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Updates the state of the system based on the currently active mode.
|
Updates the state of the system based on the currently active mode.
|
||||||
|
|
|
@ -526,7 +526,7 @@ void Debugger::updateRewindbuttons(const RewindManager& r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt16 Debugger::windStates(uInt16 states, bool unwind, string& message)
|
uInt16 Debugger::windStates(uInt16 numStates, bool unwind, string& message)
|
||||||
{
|
{
|
||||||
RewindManager& r = myOSystem.state().rewindManager();
|
RewindManager& r = myOSystem.state().rewindManager();
|
||||||
|
|
||||||
|
@ -534,13 +534,8 @@ uInt16 Debugger::windStates(uInt16 states, bool unwind, string& message)
|
||||||
|
|
||||||
unlockBankswitchState();
|
unlockBankswitchState();
|
||||||
|
|
||||||
uInt16 winds = 0;
|
|
||||||
uInt64 startCycles = myOSystem.console().tia().cycles();
|
uInt64 startCycles = myOSystem.console().tia().cycles();
|
||||||
for(uInt16 i = 0; i < states; ++i)
|
uInt16 winds = unwind ? r.unwindState(numStates) : r.rewindState(numStates);
|
||||||
if(unwind ? r.unwindState() : r.rewindState())
|
|
||||||
winds++;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
message = r.getUnitString(myOSystem.console().tia().cycles() - startCycles);
|
message = r.getUnitString(myOSystem.console().tia().cycles() - startCycles);
|
||||||
|
|
||||||
lockBankswitchState();
|
lockBankswitchState();
|
||||||
|
@ -550,15 +545,15 @@ uInt16 Debugger::windStates(uInt16 states, bool unwind, string& message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt16 Debugger::rewindStates(const uInt16 states, string& message)
|
uInt16 Debugger::rewindStates(const uInt16 numStates, string& message)
|
||||||
{
|
{
|
||||||
return windStates(states, false, message);
|
return windStates(numStates, false, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt16 Debugger::unwindStates(const uInt16 states, string& message)
|
uInt16 Debugger::unwindStates(const uInt16 numStates, string& message)
|
||||||
{
|
{
|
||||||
return windStates(states, true, message);
|
return windStates(numStates, true, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -262,8 +262,8 @@ class Debugger : public DialogContainer
|
||||||
int trace();
|
int trace();
|
||||||
void nextScanline(int lines);
|
void nextScanline(int lines);
|
||||||
void nextFrame(int frames);
|
void nextFrame(int frames);
|
||||||
uInt16 rewindStates(const uInt16 states, string& message);
|
uInt16 rewindStates(const uInt16 numStates, string& message);
|
||||||
uInt16 unwindStates(const uInt16 states, string& message);
|
uInt16 unwindStates(const uInt16 numStates, string& message);
|
||||||
|
|
||||||
void toggleBreakPoint(uInt16 bp);
|
void toggleBreakPoint(uInt16 bp);
|
||||||
|
|
||||||
|
@ -321,7 +321,7 @@ class Debugger : public DialogContainer
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// rewind/unwind n states
|
// rewind/unwind n states
|
||||||
uInt16 windStates(uInt16 states, bool unwind, string& message);
|
uInt16 windStates(uInt16 numStates, bool unwind, string& message);
|
||||||
// update the rewind/unwind button state
|
// update the rewind/unwind button state
|
||||||
void updateRewindbuttons(const RewindManager& r);
|
void updateRewindbuttons(const RewindManager& r);
|
||||||
|
|
||||||
|
|
|
@ -2177,7 +2177,6 @@ void DebuggerParser::executeWatch()
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// wrapper function for rewind/unwind commands
|
// wrapper function for rewind/unwind commands
|
||||||
// TODO: return and output (formatted) cycles
|
|
||||||
void DebuggerParser::executeWinds(bool unwind)
|
void DebuggerParser::executeWinds(bool unwind)
|
||||||
{
|
{
|
||||||
uInt16 states;
|
uInt16 states;
|
||||||
|
|
|
@ -97,8 +97,18 @@ void DebuggerDialog::handleKeyDown(StellaKey key, StellaMod mod)
|
||||||
switch(key)
|
switch(key)
|
||||||
{
|
{
|
||||||
case KBDK_R:
|
case KBDK_R:
|
||||||
if(!instance().eventHandler().kbdShift(mod))
|
if(instance().eventHandler().kbdAlt(mod))
|
||||||
|
doRewindAll();
|
||||||
|
else if(instance().eventHandler().kbdShift(mod))
|
||||||
|
doRewind10();
|
||||||
|
else
|
||||||
doRewind();
|
doRewind();
|
||||||
|
break;
|
||||||
|
case KBDK_Y:
|
||||||
|
if(instance().eventHandler().kbdAlt(mod))
|
||||||
|
doUnwindAll();
|
||||||
|
else if(instance().eventHandler().kbdShift(mod))
|
||||||
|
doUnwind10();
|
||||||
else
|
else
|
||||||
doUnwind();
|
doUnwind();
|
||||||
break;
|
break;
|
||||||
|
@ -212,6 +222,30 @@ void DebuggerDialog::doUnwind()
|
||||||
instance().debugger().parser().run("unwind");
|
instance().debugger().parser().run("unwind");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void DebuggerDialog::doRewind10()
|
||||||
|
{
|
||||||
|
instance().debugger().parser().run("rewind #10");
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void DebuggerDialog::doUnwind10()
|
||||||
|
{
|
||||||
|
instance().debugger().parser().run("unwind #10");
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void DebuggerDialog::doRewindAll()
|
||||||
|
{
|
||||||
|
instance().debugger().parser().run("rewind #1000");
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void DebuggerDialog::doUnwindAll()
|
||||||
|
{
|
||||||
|
instance().debugger().parser().run("unwind #1000");
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void DebuggerDialog::doExitDebugger()
|
void DebuggerDialog::doExitDebugger()
|
||||||
{
|
{
|
||||||
|
|
|
@ -84,6 +84,10 @@ class DebuggerDialog : public Dialog
|
||||||
void doAdvance();
|
void doAdvance();
|
||||||
void doRewind();
|
void doRewind();
|
||||||
void doUnwind();
|
void doUnwind();
|
||||||
|
void doRewind10();
|
||||||
|
void doUnwind10();
|
||||||
|
void doRewindAll();
|
||||||
|
void doUnwindAll();
|
||||||
void doExitDebugger();
|
void doExitDebugger();
|
||||||
void doExitRom();
|
void doExitRom();
|
||||||
|
|
||||||
|
|
|
@ -298,16 +298,28 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
|
||||||
{
|
{
|
||||||
switch(key)
|
switch(key)
|
||||||
{
|
{
|
||||||
case KBDK_LEFT: // Alt-left rewinds states
|
case KBDK_LEFT: // Alt-left(-shift) rewinds 1(10) states
|
||||||
myOSystem.frameBuffer().resetPauseDelay();
|
myOSystem.frameBuffer().resetPauseDelay();
|
||||||
setEventState(S_PAUSE);
|
setEventState(S_PAUSE);
|
||||||
myOSystem.state().rewindState();
|
myOSystem.state().rewindState((kbdShift(mod) && state) ? 10 : 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KBDK_RIGHT: // Alt-right unwinds states
|
case KBDK_RIGHT: // Alt-right(-shift) unwinds 1(10) states
|
||||||
myOSystem.frameBuffer().resetPauseDelay();
|
myOSystem.frameBuffer().resetPauseDelay();
|
||||||
setEventState(S_PAUSE);
|
setEventState(S_PAUSE);
|
||||||
myOSystem.state().unwindState();
|
myOSystem.state().unwindState((kbdShift(mod) && state) ? 10 : 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KBDK_DOWN: // Alt-down rewinds to start of list
|
||||||
|
myOSystem.frameBuffer().resetPauseDelay();
|
||||||
|
setEventState(S_PAUSE);
|
||||||
|
myOSystem.state().rewindState(1000);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KBDK_UP: // Alt-up rewinds to end of list
|
||||||
|
myOSystem.frameBuffer().resetPauseDelay();
|
||||||
|
setEventState(S_PAUSE);
|
||||||
|
myOSystem.state().unwindState(1000);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue