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;