diff --git a/docs/graphics/options_developer_states.png b/docs/graphics/options_developer_states.png
index ac09d4d2f..04e4563f8 100644
Binary files a/docs/graphics/options_developer_states.png and b/docs/graphics/options_developer_states.png differ
diff --git a/docs/index.html b/docs/index.html
index 6d53dfff4..d7d340e30 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -2484,11 +2484,11 @@
-<plr.|dev.>rewind <1|0> |
Enables continuous rewind |
- -<plr.|dev.>rewind.size <100 - 1000> |
+ -<plr.|dev.>rewind.size <20 - 1000> |
Defines the rewind buffer size. |
- -<plr.|dev.>rewind.uncompressed <100 - 1000> |
+ -<plr.|dev.>rewind.uncompressed <0 - 1000> |
Defines the uncompressed rewind buffer size. Must be <= rewind buffer size. |
diff --git a/src/common/RewindManager.cxx b/src/common/RewindManager.cxx
index 1f8fb1807..06be2bec4 100644
--- a/src/common/RewindManager.cxx
+++ b/src/common/RewindManager.cxx
@@ -24,7 +24,7 @@
#include "RewindManager.hxx"
-static int count = 1;
+//static int count = 1;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RewindManager::RewindManager(OSystem& system, StateManager& statemgr)
: myOSystem(system),
@@ -36,18 +36,13 @@ RewindManager::RewindManager(OSystem& system, StateManager& statemgr)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RewindManager::setup()
{
- /*static const int NUM_INTERVALS = 6;
- // TODO: check for intervals shorter than 1 frame (adjust horizon too!)
- const uInt32 INTERVAL_CYCLES[NUM_INTERVALS] = { 76, 76 * 50, 76 * 262, 76 * 262 * 10,
- 76 * 262 * 60, 76 * 262 * 60 * 10 };
- static const int NUM_HORIZONS = 7;
- const uInt64 HORIZON_CYCLES[NUM_HORIZONS] = { 76 * 262, 76 * 262 * 10, 76 * 262 * 60, 76 * 262 * 60 * 10,
- 76 * 262 * 60 * 60, 76 * 262 * 60 * 60 * 10, uInt64(76) * 262 * 60 * 60 * 60 };*/
- bool devSettings = myOSystem.settings().getBool("dev.settings");
- string prefix = devSettings ? "dev." : "plr.";
+ string prefix = myOSystem.settings().getBool("dev.settings") ? "dev." : "plr.";
- mySize = MAX_SIZE; // myOSystem.settings().getInt(prefix + "rewind.size");
- myUncompressed = MAX_SIZE / 4; // myOSystem.settings().getInt(prefix + "rewind.uncompressed");
+ mySize = myOSystem.settings().getInt(prefix + "rewind.size");
+ if(mySize != myStateList.capacity())
+ myStateList.resize(mySize);
+
+ myUncompressed = myOSystem.settings().getInt(prefix + "rewind.uncompressed");
myInterval = INTERVAL_CYCLES[0];
for(int i = 0; i < NUM_INTERVALS; ++i)
@@ -89,7 +84,7 @@ void RewindManager::setup()
else
maxFactor = myFactor;
}
-cerr << "factor " << myFactor << endl;
+//cerr << "factor " << myFactor << endl;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -122,8 +117,8 @@ bool RewindManager::addState(const string& message, bool continuous)
{
state.message = message;
state.cycle = myOSystem.console().tia().cycles();
- state.count = count++;
-cerr << "add " << state.count << endl;
+ //state.count = count++;
+//cerr << "add " << state.count << endl;
return true;
}
return false;
@@ -143,7 +138,7 @@ bool RewindManager::rewindState()
RewindState& state = myStateList.current();
Serializer& s = state.data;
string message = getMessage(state, lastState);
-cerr << "rewind " << state.count << endl;
+//cerr << "rewind " << state.count << endl;
s.rewind(); // rewind Serializer internal buffers
myStateManager.loadState(s);
@@ -169,7 +164,7 @@ bool RewindManager::unwindState()
RewindState& state = myStateList.current();
Serializer& s = state.data;
string message = getMessage(state, state);
-cerr << "unwind " << state.count << endl;
+//cerr << "unwind " << state.count << endl;
s.rewind(); // rewind Serializer internal buffers
myStateManager.loadState(s);
@@ -222,14 +217,14 @@ void RewindManager::compressStates()
}
if (maxDelta < 1)
{
- // the horizon is getting too big
+ // the horizon is getting too big (can happen after changing settings)
myStateList.remove(1); // remove oldest but one
-cerr << "remove oldest + 1" << endl;
+//cerr << "remove oldest + 1" << endl;
}
else
{
myStateList.remove(removeIdx); // remove
-cerr << "remove " << removeIdx << endl;
+//cerr << "remove " << removeIdx << endl;
}
}
@@ -259,8 +254,7 @@ string RewindManager::getUnitString(Int64 cycles)
// TODO: do we need hours here? don't think so
const Int32 NUM_UNITS = 5;
const string UNIT_NAMES[NUM_UNITS] = { "cycle", "scanline", "frame", "second", "minute" };
- const Int64 UNIT_CYCLES[NUM_UNITS + 1] = { 1, 76, 76 * scanlines, freq,
- freq * 60, Int64(1) << 62 };
+ const Int64 UNIT_CYCLES[NUM_UNITS + 1] = { 1, 76, 76 * scanlines, freq, freq * 60, Int64(1) << 62 };
stringstream result;
Int32 i;
@@ -280,4 +274,3 @@ string RewindManager::getUnitString(Int64 cycles)
return result.str();
}
-
diff --git a/src/common/RewindManager.hxx b/src/common/RewindManager.hxx
index 920acf49e..a531c1c9c 100644
--- a/src/common/RewindManager.hxx
+++ b/src/common/RewindManager.hxx
@@ -134,7 +134,7 @@ class RewindManager
private:
// Maximum number of states to save
- static constexpr uInt32 MAX_SIZE = 20; // TODO: use a parameter here and allow user to define size in UI
+ static constexpr uInt32 INITIAL_SIZE = 100;
OSystem& myOSystem;
StateManager& myStateManager;
@@ -149,7 +149,7 @@ class RewindManager
Serializer data;
string message;
uInt64 cycle;
- int count; // TODO - remove this
+ //int count; // TODO - remove this
// We do nothing on object instantiation or copy
// The goal of LinkedObjectPool is to not do any allocations at all
@@ -158,13 +158,13 @@ class RewindManager
// Output object info; used for debugging only
friend ostream& operator<<(ostream& os, const RewindState& s) {
- return os << "msg: " << s.message << " cycle: " << s.cycle << " count: " << s.count;
+ return os << "msg: " << s.message << " cycle: " << s.cycle; // << " count: " << s.count;
}
};
// The linked-list to store states (internally it takes care of reducing
// frequent (de)-allocations)
- Common::LinkedObjectPool myStateList;
+ Common::LinkedObjectPool myStateList;
void compressStates();
diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx
index 665a79888..38f462bbe 100644
--- a/src/debugger/Debugger.cxx
+++ b/src/debugger/Debugger.cxx
@@ -615,8 +615,9 @@ void Debugger::setStartState()
// Lock the bus each time the debugger is entered, so we don't disturb anything
lockBankswitchState();
- // Save initial state and add it to the rewind list
- saveOldState("enter debugger");
+ // Save initial state and add it to the rewind list (except when in currently rewinding)
+ RewindManager& r = myOSystem.state().rewindManager();
+ saveOldState(r.atLast() ? "enter debugger" : "");
// Set the 're-disassemble' flag, but don't do it until the next scheduled time
myDialog->rom().invalidate(false);
diff --git a/src/gui/DeveloperDialog.cxx b/src/gui/DeveloperDialog.cxx
index 2e1d1a651..88b6ca927 100644
--- a/src/gui/DeveloperDialog.cxx
+++ b/src/gui/DeveloperDialog.cxx
@@ -189,7 +189,8 @@ void DeveloperDialog::addVideoTab(const GUI::Font& font)
ypos += lineHeight + VGAP * 1;
// TV jitter effect
- myTVJitterWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "Jitter/roll effect", kTVJitter);
+ myTVJitterWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
+ "Jitter/roll effect", kTVJitter);
wid.push_back(myTVJitterWidget);
myTVJitterRecWidget = new SliderWidget(myTab, font,
myTVJitterWidget->getRight() + fontWidth * 3, ypos - 1,
@@ -198,18 +199,21 @@ void DeveloperDialog::addVideoTab(const GUI::Font& font)
myTVJitterRecWidget->setMinValue(1); myTVJitterRecWidget->setMaxValue(20);
wid.push_back(myTVJitterRecWidget);
myTVJitterRecLabelWidget = new StaticTextWidget(myTab, font,
- myTVJitterRecWidget->getRight() + 4, myTVJitterRecWidget->getTop() + 2,
+ myTVJitterRecWidget->getRight() + 4,
+ myTVJitterRecWidget->getTop() + 2,
5 * fontWidth, fontHeight, "", kTextAlignLeft);
myTVJitterRecLabelWidget->setFlags(WIDGET_CLEARBG);
wid.push_back(myTVJitterRecLabelWidget);
ypos += lineHeight + VGAP;
- myColorLossWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "PAL color-loss");
+ myColorLossWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
+ "PAL color-loss");
wid.push_back(myColorLossWidget);
ypos += lineHeight + VGAP;
// debug colors
- myDebugColorsWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "Debug colors (*)");
+ myDebugColorsWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
+ "Debug colors (*)");
wid.push_back(myDebugColorsWidget);
ypos += lineHeight + VGAP + 2;
@@ -258,12 +262,12 @@ void DeveloperDialog::addVideoTab(const GUI::Font& font)
void DeveloperDialog::addStatesTab(const GUI::Font& font)
{
const string INTERVALS[NUM_INTERVALS] = {
- "1 frame",
- "3 frames",
+ " 1 frame",
+ " 3 frames",
"10 frames",
"30 frames",
- "1 second",
- "3 seconds",
+ " 1 second",
+ " 3 seconds",
"10 seconds"
};
const string INT_SETTINGS[NUM_INTERVALS] = {
@@ -276,14 +280,14 @@ void DeveloperDialog::addStatesTab(const GUI::Font& font)
"10s"
};
const string HORIZONS[NUM_HORIZONS] = {
- "~3 seconds",
- "~10 seconds",
- "~30 seconds",
- "~1 minute",
- "~3 minutes",
- "~10 minutes",
- "~30 minutes",
- "~60 minutes"
+ " 3 seconds",
+ "10 seconds",
+ "30 seconds",
+ " 1 minute",
+ " 3 minutes",
+ "10 minutes",
+ "30 minutes",
+ "60 minutes"
};
const string HOR_SETTINGS[NUM_HORIZONS] = {
"3s",
@@ -325,7 +329,7 @@ void DeveloperDialog::addStatesTab(const GUI::Font& font)
int sWidth = font.getMaxCharWidth() * 8;
myStateSizeWidget = new SliderWidget(myTab, font, HBORDER + INDENT * 2, ypos - 1, sWidth, lineHeight,
"Buffer size (*) ", 0, kSizeChanged);
- myStateSizeWidget->setMinValue(100);
+ myStateSizeWidget->setMinValue(20);
myStateSizeWidget->setMaxValue(1000);
myStateSizeWidget->setStepValue(20);
wid.push_back(myStateSizeWidget);
@@ -346,7 +350,7 @@ void DeveloperDialog::addStatesTab(const GUI::Font& font)
items.clear();
for(int i = 0; i < NUM_INTERVALS; ++i)
VarList::push_back(items, INTERVALS[i], INT_SETTINGS[i]);
- int pwidth = font.getStringWidth("~10 seconds");
+ int pwidth = font.getStringWidth("10 seconds");
myStateIntervalWidget = new PopUpWidget(myTab, font, HBORDER + INDENT * 2, ypos, pwidth,
lineHeight, items, "Interval ", 0, kIntervalChanged);
wid.push_back(myStateIntervalWidget);
@@ -356,7 +360,7 @@ void DeveloperDialog::addStatesTab(const GUI::Font& font)
for(int i = 0; i < NUM_HORIZONS; ++i)
VarList::push_back(items, HORIZONS[i], HOR_SETTINGS[i]);
myStateHorizonWidget = new PopUpWidget(myTab, font, HBORDER + INDENT * 2, ypos, pwidth,
- lineHeight, items, "Horizon ", 0, kHorizonChanged);
+ lineHeight, items, "Horizon ~ ", 0, kHorizonChanged);
wid.push_back(myStateHorizonWidget);
// Add message concerning usage
@@ -519,7 +523,6 @@ void DeveloperDialog::loadSettings(SettingsSet set)
myUncompressed[set] = instance().settings().getInt(prefix + "rewind.uncompressed");
myStateInterval[set] = instance().settings().getString(prefix + "rewind.interval");
myStateHorizon[set] = instance().settings().getString(prefix + "rewind.horizon");
-
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -710,9 +713,6 @@ void DeveloperDialog::saveConfig()
instance().console().tia().setFixedColorPalette(dbgcolors))
instance().settings().setValue("tia.dbgcolors", dbgcolors);
- // Finally, issue a complete framebuffer re-initialization
- //instance().createFrameBuffer();
-
// update RewindManager
instance().state().rewindManager().setup();
instance().state().setRewindMode(myContinuousRewindWidget->getState() ?
@@ -967,11 +967,17 @@ void DeveloperDialog::handleSize()
{
uInt32 size = myStateSizeWidget->getValue();
uInt32 uncompressed = myUncompressedWidget->getValue();
- uInt32 interval = myStateIntervalWidget->getSelected();
- uInt32 horizon = myStateHorizonWidget->getSelected();
+ Int32 interval = myStateIntervalWidget->getSelected();
+ Int32 horizon = myStateHorizonWidget->getSelected();
bool found = false;
Int32 i;
+ // handle illegal values
+ if(interval == -1)
+ interval = 0;
+ if(horizon == -1)
+ horizon = 0;
+
myStateSizeLabelWidget->setValue(size);
// adapt horizon and interval
do
@@ -1012,11 +1018,17 @@ void DeveloperDialog::handleInterval()
{
uInt32 size = myStateSizeWidget->getValue();
uInt32 uncompressed = myUncompressedWidget->getValue();
- uInt32 interval = myStateIntervalWidget->getSelected();
- uInt32 horizon = myStateHorizonWidget->getSelected();
+ Int32 interval = myStateIntervalWidget->getSelected();
+ Int32 horizon = myStateHorizonWidget->getSelected();
bool found = false;
Int32 i;
+ // handle illegal values
+ if(interval == -1)
+ interval = 0;
+ if(horizon == -1)
+ horizon = 0;
+
// adapt horizon and size
do
{
@@ -1044,17 +1056,23 @@ void DeveloperDialog::handleHorizon()
{
uInt32 size = myStateSizeWidget->getValue();
uInt32 uncompressed = myUncompressedWidget->getValue();
- uInt32 interval = myStateIntervalWidget->getSelected();
- uInt32 horizon = myStateHorizonWidget->getSelected();
+ Int32 interval = myStateIntervalWidget->getSelected();
+ Int32 horizon = myStateHorizonWidget->getSelected();
bool found = false;
Int32 i;
+ // handle illegal values
+ if(interval == -1)
+ interval = 0;
+ if(horizon == -1)
+ horizon = 0;
+
// adapt interval and size
do
{
for(i = interval; i >= 0; --i)
{
- if(size * instance().state().rewindManager().INTERVAL_CYCLES[i]
+ if(uInt64(size) * instance().state().rewindManager().INTERVAL_CYCLES[i]
<= instance().state().rewindManager().HORIZON_CYCLES[horizon])
{
found = true;
diff --git a/src/gui/DeveloperDialog.hxx b/src/gui/DeveloperDialog.hxx
index bbc28f002..db0388eb4 100644
--- a/src/gui/DeveloperDialog.hxx
+++ b/src/gui/DeveloperDialog.hxx
@@ -152,7 +152,6 @@ class DeveloperDialog : public Dialog
bool myContinuousRewind[2];
int myStateSize[2];
int myUncompressed[2];
- //int myStateInterval[2];
string myStateInterval[2];
string myStateHorizon[2];
@@ -182,8 +181,9 @@ class DeveloperDialog : public Dialog
void handleUncompressed();
void handleInterval();
void handleHorizon();
-
+#ifdef DEBUGGER_SUPPORT
void handleFontSize();
+#endif
// Following constructors and assignment operators not supported
DeveloperDialog() = delete;