diff --git a/Changes.txt b/Changes.txt index 9f6bc410d..732d82330 100644 --- a/Changes.txt +++ b/Changes.txt @@ -45,6 +45,8 @@ * Added another oddball TIA glitch option for score mode color. + * Enhanced TV jitter emulation (TODO: doc). + * Enhanced support for CDFJ+ bankswitching type. * Added 0FA0 bankswitching for Fotomania ROMs. diff --git a/docs/graphics/options_developer_video.png b/docs/graphics/options_developer_video.png index 02b2549ed..441f30c60 100644 Binary files a/docs/graphics/options_developer_video.png and b/docs/graphics/options_developer_video.png differ diff --git a/docs/index.html b/docs/index.html index b40a78e5a..e9d527f93 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1982,6 +1982,18 @@ Cmd + J + + Decrease TV jitter sensitivity + Shift-Control-Alt + J + Shift-Control-Cmd + J + + + + Increase TV jitter sensitivity + Control-Alt + J + Control-Cmd + J + + Decrease TV jitter roll time Shift-Control + J @@ -3812,10 +3824,13 @@
-<plr.|dev.>tv.jitter <1|0>
Enable TV jitter/roll effect, when there are too many or too few scanlines per frame. + +
-<plr.|dev.>tv.jitter_sense <1 - 10>
+ When TV jitter/roll effect is enabled, determines the sensitivy to varying frame timings.
-<plr.|dev.>tv.jitter_recovery <1 - 20>
- When TV jitter/roll effect is enabled, determines how long to delay recovery - time (recovery spread over multiple frames). + When TV jitter/roll effect is enabled, determines the recovery time for screen rolling + (recovery spread over multiple frames).
-<plr.|dev.>colorloss <1|0>
Enable/disable the PAL color-loss effect. @@ -4677,6 +4692,7 @@ + diff --git a/src/common/DevSettingsHandler.cxx b/src/common/DevSettingsHandler.cxx index 2b90144f3..bd70cfef3 100644 --- a/src/common/DevSettingsHandler.cxx +++ b/src/common/DevSettingsHandler.cxx @@ -78,6 +78,7 @@ void DevSettingsHandler::loadSettings(SettingsSet set) myColorLoss[set] = settings.getBool(prefix + "colorloss"); // Jitter myTVJitter[set] = settings.getBool(prefix + "tv.jitter"); + myTVJitterSense[set] = settings.getInt(prefix + "tv.jitter_sense"); myTVJitterRec[set] = settings.getInt(prefix + "tv.jitter_recovery"); // States @@ -148,6 +149,7 @@ void DevSettingsHandler::saveSettings(SettingsSet set) settings.setValue(prefix + "colorloss", myColorLoss[set]); // Jitter settings.setValue(prefix + "tv.jitter", myTVJitter[set]); + settings.setValue(prefix + "tv.jitter_sense", myTVJitterSense[set]); settings.setValue(prefix + "tv.jitter_recovery", myTVJitterRec[set]); // States @@ -200,6 +202,7 @@ void DevSettingsHandler::applySettings(SettingsSet set) { // TV Jitter myOSystem.console().tia().toggleJitter(myTVJitter[set] ? 1 : 0); + myOSystem.console().tia().setJitterSensitivity(myTVJitterSense[set]); myOSystem.console().tia().setJitterRecoveryFactor(myTVJitterRec[set]); // PAL color loss myOSystem.console().enableColorLoss(myColorLoss[set]); diff --git a/src/common/DevSettingsHandler.hxx b/src/common/DevSettingsHandler.hxx index 25145b6c9..8b602aea0 100644 --- a/src/common/DevSettingsHandler.hxx +++ b/src/common/DevSettingsHandler.hxx @@ -55,6 +55,7 @@ class DevSettingsHandler std::array myRandomizeCPU; std::array myColorLoss; std::array myTVJitter; + std::array myTVJitterSense; std::array myTVJitterRec; std::array myDebugColors; std::array myUndrivenPins; diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index a1ed83659..5c6f37d6b 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -700,8 +700,10 @@ PhysicalKeyboardHandler::DefaultCommonMapping = { { Event::DecreaseSpeed, KBDK_S, KBDM_SHIFT | KBDM_CTRL }, { Event::IncreaseSpeed, KBDK_S, KBDM_CTRL }, { Event::ToggleTurbo, KBDK_T, KBDM_CTRL }, - { Event::JitterDecrease, KBDK_J, KBDM_SHIFT | KBDM_CTRL }, - { Event::JitterIncrease, KBDK_J, KBDM_CTRL }, + { Event::JitterSenseDecrease, KBDK_J, KBDM_SHIFT | MOD3 | KBDM_CTRL }, + { Event::JitterSenseIncrease, KBDK_J, MOD3 | KBDM_CTRL }, + { Event::JitterRecDecrease, KBDK_J, KBDM_SHIFT | KBDM_CTRL }, + { Event::JitterRecIncrease, KBDK_J, KBDM_CTRL }, { Event::ToggleDeveloperSet, KBDK_D, MOD3 }, { Event::ToggleJitter, KBDK_J, MOD3 }, { Event::ToggleFrameStats, KBDK_L, MOD3 }, diff --git a/src/common/jsonDefinitions.hxx b/src/common/jsonDefinitions.hxx index 0d0f9a7ce..ee82567fc 100644 --- a/src/common/jsonDefinitions.hxx +++ b/src/common/jsonDefinitions.hxx @@ -361,8 +361,10 @@ NLOHMANN_JSON_SERIALIZE_ENUM(Event::Type, { {Event::TogglePhosphor, "TogglePhosphor"}, {Event::ToggleDeveloperSet, "ToggleDeveloperSet"}, {Event::ToggleInter, "ToggleInter"}, - {Event::JitterDecrease, "JitterDecrease"}, - {Event::JitterIncrease, "JitterIncrease"}, + {Event::JitterSenseDecrease, "JitterSenseDecrease"}, + {Event::JitterSenseIncrease, "JitterSenseIncrease"}, + {Event::JitterRecDecrease, "JitterRecDecrease"}, + {Event::JitterRecIncrease, "JitterRecIncrease"}, {Event::ToggleJitter, "ToggleJitter"}, {Event::VolumeDecrease, "VolumeDecrease"}, {Event::VolumeIncrease, "VolumeIncrease"}, diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 8d3801023..4d98ab731 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -1253,7 +1253,40 @@ void Console::toggleJitter(bool toggle) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Console::changeJitter(int direction) const +void Console::changeJitterSense(int direction) const +{ + const string prefix = myOSystem.settings().getBool("dev.settings") ? "dev." : "plr."; + int sensitivity = myOSystem.settings().getInt(prefix + "tv.jitter_sense"); + const bool enabled = direction ? sensitivity + direction > 0 : myTIA->toggleJitter(3); + + // if disabled, enable before first before increasing recovery + if(!myTIA->toggleJitter(3)) + direction = 0; + + sensitivity = BSPF::clamp(static_cast(sensitivity + direction), + JitterEmulation::MIN_SENSITIVITY, JitterEmulation::MAX_SENSITIVITY); + myOSystem.settings().setValue(prefix + "tv.jitter", enabled); + + if(enabled) + { + ostringstream val; + + myTIA->toggleJitter(1); + myTIA->setJitterSensitivity(sensitivity); + myOSystem.settings().setValue(prefix + "tv.jitter_sense", sensitivity); + val << sensitivity; + myOSystem.frameBuffer().showGaugeMessage("TV jitter sensitivity", val.str(), sensitivity, + 0, JitterEmulation::MAX_SENSITIVITY); + } + else + { + myTIA->toggleJitter(0); + myOSystem.frameBuffer().showTextMessage("TV scanline jitter disabled"); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Console::changeJitterRecovery(int direction) const { const string prefix = myOSystem.settings().getBool("dev.settings") ? "dev." : "plr."; int recovery = myOSystem.settings().getInt(prefix + "tv.jitter_recovery"); @@ -1263,7 +1296,8 @@ void Console::changeJitter(int direction) const if(!myTIA->toggleJitter(3)) direction = 0; - recovery = BSPF::clamp(recovery + direction, 1, 20); + recovery = BSPF::clamp(static_cast(recovery + direction), + JitterEmulation::MIN_RECOVERY, JitterEmulation::MAX_RECOVERY); myOSystem.settings().setValue(prefix + "tv.jitter", enabled); if(enabled) @@ -1274,7 +1308,8 @@ void Console::changeJitter(int direction) const myTIA->setJitterRecoveryFactor(recovery); myOSystem.settings().setValue(prefix + "tv.jitter_recovery", recovery); val << recovery; - myOSystem.frameBuffer().showGaugeMessage("TV jitter roll", val.str(), recovery, 0, 20); + myOSystem.frameBuffer().showGaugeMessage("TV jitter roll", val.str(), recovery, + 0, JitterEmulation::MAX_RECOVERY); } else { diff --git a/src/emucore/Console.hxx b/src/emucore/Console.hxx index 169ba2beb..128316672 100644 --- a/src/emucore/Console.hxx +++ b/src/emucore/Console.hxx @@ -357,10 +357,15 @@ class Console : public Serializable, public ConsoleIO */ void toggleJitter(bool toggle = true) const; + /** + Changes the TIA 'scanline jitter' sensitivity. + */ + void changeJitterSense(int direction = +1) const; + /** Changes the TIA 'scanline jitter' revcovery rate. */ - void changeJitter(int direction = +1) const; + void changeJitterRecovery(int direction = +1) const; /** * Update vcenter diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index 0a3fffbe4..db6ae19d9 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -116,7 +116,8 @@ class Event ScanlinesDecrease, ScanlinesIncrease, PreviousScanlineMask, NextScanlineMask, PhosphorDecrease, PhosphorIncrease, TogglePhosphor, ToggleInter, - ToggleDeveloperSet, JitterDecrease, JitterIncrease, ToggleJitter, + ToggleDeveloperSet, JitterRecDecrease, JitterRecIncrease, + JitterSenseDecrease, JitterSenseIncrease, ToggleJitter, VolumeDecrease, VolumeIncrease, SoundToggle, diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index e51163466..7ad4b6813 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -976,23 +976,39 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) if(pressed && !repeated) { myOSystem.console().toggleJitter(); - myGlobalKeyHandler->setSetting(GlobalKeyHandler::Setting::JITTER); + myGlobalKeyHandler->setSetting(GlobalKeyHandler::Setting::JITTER_SENSE); } return; - case Event::JitterDecrease: + case Event::JitterSenseDecrease: if(pressed) { - myOSystem.console().changeJitter(-1); - myGlobalKeyHandler->setSetting(GlobalKeyHandler::Setting::JITTER); + myOSystem.console().changeJitterSense(-1); + myGlobalKeyHandler->setSetting(GlobalKeyHandler::Setting::JITTER_SENSE); } return; - case Event::JitterIncrease: + case Event::JitterSenseIncrease: if(pressed) { - myOSystem.console().changeJitter(+1); - myGlobalKeyHandler->setSetting(GlobalKeyHandler::Setting::JITTER); + myOSystem.console().changeJitterSense(+1); + myGlobalKeyHandler->setSetting(GlobalKeyHandler::Setting::JITTER_SENSE); + } + return; + + case Event::JitterRecDecrease: + if(pressed) + { + myOSystem.console().changeJitterRecovery(-1); + myGlobalKeyHandler->setSetting(GlobalKeyHandler::Setting::JITTER_REC); + } + return; + + case Event::JitterRecIncrease: + if(pressed) + { + myOSystem.console().changeJitterRecovery(+1); + myGlobalKeyHandler->setSetting(GlobalKeyHandler::Setting::JITTER_REC); } return; @@ -3041,8 +3057,10 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { { { Event::ToggleFixedColors, "Toggle TIA 'Fixed Debug Colors' mode", "" }, { Event::ToggleColorLoss, "Toggle PAL color-loss effect", "" }, { Event::ToggleJitter, "Toggle TV scanline 'Jitter' effect", "" }, - { Event::JitterDecrease, "Decrease TV 'Jitter' roll", "" }, - { Event::JitterIncrease, "Increase TV 'Jitter' roll", "" }, + { Event::JitterSenseDecrease, "Decrease TV 'Jitter' sensitivity", "" }, + { Event::JitterSenseIncrease, "Increase TV 'Jitter' sensitivity", "" }, + { Event::JitterRecDecrease, "Decrease TV 'Jitter' roll", "" }, + { Event::JitterRecIncrease, "Increase TV 'Jitter' roll", "" }, // Combo { Event::Combo1, "Combo 1", "" }, @@ -3230,5 +3248,6 @@ const Event::EventSet EventHandler::DebugEvents = { Event::ToggleBLCollision, Event::ToggleBLBit, Event::TogglePFCollision, Event::TogglePFBit, Event::ToggleCollisions, Event::ToggleBits, Event::ToggleFixedColors, Event::ToggleColorLoss, - Event::ToggleJitter, Event::JitterDecrease,Event::JitterIncrease, + Event::ToggleJitter, Event::JitterSenseDecrease,Event::JitterSenseIncrease, + Event::JitterRecDecrease,Event::JitterRecIncrease, }; diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 2182e08e2..d85afa969 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -524,7 +524,7 @@ class EventHandler #else REFRESH_SIZE = 0, #endif - EMUL_ACTIONLIST_SIZE = 230 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE, + EMUL_ACTIONLIST_SIZE = 232 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE, MENU_ACTIONLIST_SIZE = 19 ; diff --git a/src/emucore/GlobalKeyHandler.cxx b/src/emucore/GlobalKeyHandler.cxx index 381b63f70..bf640b920 100644 --- a/src/emucore/GlobalKeyHandler.cxx +++ b/src/emucore/GlobalKeyHandler.cxx @@ -436,7 +436,8 @@ GlobalKeyHandler::SettingData GlobalKeyHandler::getSettingData(const Setting set {Setting::ALL_CX, {false, std::bind(&Console::toggleCollisions, &myOSystem.console(), _1)}}, // debug, not persisted {Setting::FIXED_COL, {false, std::bind(&Console::toggleFixedColors, &myOSystem.console(), _1)}}, // debug, not persisted {Setting::COLOR_LOSS, {false, std::bind(&Console::toggleColorLoss, &myOSystem.console(), _1)}}, - {Setting::JITTER, {true, std::bind(&Console::changeJitter, &myOSystem.console(), _1)}}, + {Setting::JITTER_SENSE, {true, std::bind(&Console::changeJitterSense, &myOSystem.console(), _1)}}, + {Setting::JITTER_REC, {true, std::bind(&Console::changeJitterRecovery, &myOSystem.console(), _1)}}, // *** Following functions are not used when cycling settings, but for "direct only" hotkeys *** {Setting::STATE, {true, std::bind(&StateManager::changeState, &myOSystem.state(), _1)}}, // temporary, not persisted {Setting::PALETTE_ATTRIBUTE, {true, std::bind(&PaletteHandler::changeCurrentAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), _1)}}, diff --git a/src/emucore/GlobalKeyHandler.hxx b/src/emucore/GlobalKeyHandler.hxx index 60cc6ab13..69615e17f 100644 --- a/src/emucore/GlobalKeyHandler.hxx +++ b/src/emucore/GlobalKeyHandler.hxx @@ -118,7 +118,8 @@ class GlobalKeyHandler ALL_CX, FIXED_COL, COLOR_LOSS, - JITTER, + JITTER_SENSE, + JITTER_REC, // *** Only used via direct hotkeys *** STATE, PALETTE_ATTRIBUTE, @@ -131,7 +132,7 @@ class GlobalKeyHandler START_INPUT_ADJ = DIGITAL_DEADZONE, END_INPUT_ADJ = MOUSE_RANGE, START_DEBUG_ADJ = DEVELOPER, - END_DEBUG_ADJ = JITTER, + END_DEBUG_ADJ = JITTER_REC, }; public: diff --git a/src/emucore/MindLink.cxx b/src/emucore/MindLink.cxx index e7464eb63..02ec5a79f 100644 --- a/src/emucore/MindLink.cxx +++ b/src/emucore/MindLink.cxx @@ -43,9 +43,9 @@ void MindLink::update() myEvent.get(Event::MouseButtonRightValue)) myMindlinkPos = myMindlinkPos | TRIGGER_VALUE; // starts game, calibration and reverse -#ifdef DEBUG_BUILD - cerr << std::hex << myMindlinkPos << endl; -#endif +//#ifdef DEBUG_BUILD +// cerr << std::hex << myMindlinkPos << endl; +//#endif myMindlinkShift = 1; // start transfer with least significant bit nextMindlinkBit(); diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index cb641c16b..91a56822f 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -25,6 +25,7 @@ #include "PaletteHandler.hxx" #include "Joystick.hxx" #include "Paddles.hxx" +#include "JitterEmulation.hxx" #ifdef DEBUGGER_SUPPORT #include "DebuggerDialog.hxx" @@ -225,7 +226,8 @@ Settings::Settings() setPermanent("plr.tiarandom", "false"); setPermanent("plr.colorloss", "false"); setPermanent("plr.tv.jitter", "true"); - setPermanent("plr.tv.jitter_recovery", "10"); + setPermanent("plr.tv.jitter_sense", JitterEmulation::PLR_SENSITIVITY); + setPermanent("plr.tv.jitter_recovery", JitterEmulation::PLR_RECOVERY); setPermanent("plr.debugcolors", "false"); setPermanent("plr.console", "2600"); // 7800 setPermanent("plr.timemachine", true); @@ -245,7 +247,8 @@ Settings::Settings() setPermanent("dev.tiarandom", "true"); setPermanent("dev.colorloss", "true"); setPermanent("dev.tv.jitter", "true"); - setPermanent("dev.tv.jitter_recovery", "2"); + setPermanent("dev.tv.jitter_sense", JitterEmulation::DEV_SENSITIVITY); + setPermanent("dev.tv.jitter_recovery", JitterEmulation::DEV_RECOVERY); setPermanent("dev.debugcolors", "false"); setPermanent("dev.tiadriven", "true"); setPermanent("dev.console", "2600"); // 7800 @@ -336,8 +339,13 @@ void Settings::validate() i = getInt("tv.filter"); if(i < 0 || i > 5) setValue("tv.filter", "0"); + i = getInt("dev.tv.jitter_sense"); + if(i < JitterEmulation::MIN_SENSITIVITY || i > JitterEmulation::MAX_SENSITIVITY) + setValue("dev.tv.jitter_sense", JitterEmulation::DEV_SENSITIVITY); + i = getInt("dev.tv.jitter_recovery"); - if(i < 1 || i > 20) setValue("dev.tv.jitter_recovery", "2"); + if(i < JitterEmulation::MIN_RECOVERY || i > JitterEmulation::MAX_RECOVERY) + setValue("dev.tv.jitter_recovery", JitterEmulation::DEV_RECOVERY); int size = getInt("dev.tm.size"); if(size < 20 || size > 1000) @@ -355,8 +363,12 @@ void Settings::validate() i = getInt("dev.tm.horizon"); if(i < 0 || i > 6) setValue("dev.tm.horizon", 1);*/ + i = getInt("plr.tv.jitter_sense"); + if(i < JitterEmulation::MIN_SENSITIVITY || i > JitterEmulation::MAX_SENSITIVITY) + setValue("plr.tv.jitter_sense", JitterEmulation::PLR_SENSITIVITY); + i = getInt("plr.tv.jitter_recovery"); - if(i < 1 || i > 20) setValue("plr.tv.jitter_recovery", "10"); + if(i < 1 || i > 20) setValue("plr.tv.jitter_recovery", JitterEmulation::PLR_RECOVERY); size = getInt("plr.tm.size"); if(size < 20 || size > 1000) @@ -713,6 +725,7 @@ void Settings::usage() const << " -plr.debugcolors <1|0> Enable debug colors\n" << " -plr.colorloss <1|0> Enable PAL color-loss effect\n" << " -plr.tv.jitter <1|0> Enable TV jitter effect\n" + << " -plr.tv.jitter_sense <1-10> Set TV jitter effect sensitivity\n" << " -plr.tv.jitter_recovery <1-20> Set recovery time for TV jitter effect\n" << " -plr.extaccess <1|0> Enable messages for external access\n" << endl @@ -729,8 +742,9 @@ void Settings::usage() const << " -dev.debugcolors <1|0> Enable debug colors\n" << " -dev.colorloss <1|0> Enable PAL color-loss effect\n" << " -dev.tv.jitter <1|0> Enable TV jitter effect\n" + << " -dev.tv.jitter_sense <1-10> Set TV jitter effect sensitivity\n" << " -dev.tv.jitter_recovery <1-20> Set recovery time for TV jitter effect\n" - << " -dev.tiadriven <1|0> Drive unused TIA pins randomly on a\n" + << " -dev.tiadriven <1|0> Drive unqused TIA pins randomly on a\n" << " read/peek\n" #ifdef DEBUGGER_SUPPORT << " -dev.rwportbreak <1|0> Debugger breaks on reads from write ports\n" diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index 4d73e85ee..4c61e197f 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -104,7 +104,8 @@ void TIA::setFrameManager(AbstractFrameManager* frameManager) ); myFrameManager->enableJitter(myEnableJitter); - myFrameManager->setJitterFactor(myJitterFactor); + myFrameManager->setJitterSensitivity(myJitterSensitivity); + myFrameManager->setJitterRecovery(myJitterRecovery); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -544,7 +545,7 @@ bool TIA::poke(uInt16 address, uInt8 value) break; case VSYNC: - myFrameManager->setVsync(value & 0x02); + myFrameManager->setVsync(value & 0x02, mySystem->cycles()); myShadowRegisters[address] = value; break; @@ -985,7 +986,8 @@ void TIA::applyDeveloperSettings() myTIAPinsDriven = devSettings ? mySettings.getBool("dev.tiadriven") : false; myEnableJitter = mySettings.getBool(devSettings ? "dev.tv.jitter" : "plr.tv.jitter"); - myJitterFactor = mySettings.getInt(devSettings ? "dev.tv.jitter_recovery" : "plr.tv.jitter_recovery"); + myJitterSensitivity = mySettings.getInt(devSettings ? "dev.tv.jitter_sense" : "plr.tv.jitter_sense"); + myJitterRecovery = mySettings.getInt(devSettings ? "dev.tv.jitter_recovery" : "plr.tv.jitter_recovery"); if(myFrameManager) enableColorLoss(mySettings.getBool(devSettings ? "dev.colorloss" : "plr.colorloss")); @@ -1281,12 +1283,20 @@ bool TIA::toggleJitter(uInt8 mode) return myEnableJitter; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TIA::setJitterSensitivity(Int32 sensitivity) +{ + myJitterSensitivity = sensitivity; + + if (myFrameManager) myFrameManager->setJitterSensitivity(sensitivity); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIA::setJitterRecoveryFactor(Int32 factor) { - myJitterFactor = factor; + myJitterRecovery = factor; - if (myFrameManager) myFrameManager->setJitterFactor(myJitterFactor); + if (myFrameManager) myFrameManager->setJitterRecovery(myJitterRecovery); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index 3959ea62f..3c80163a4 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -441,6 +441,7 @@ class TIA : public Device @return Whether the mode was enabled or disabled */ bool toggleJitter(uInt8 mode = 2); + void setJitterSensitivity(Int32 sensitivity); void setJitterRecoveryFactor(Int32 factor); /** @@ -977,7 +978,8 @@ class TIA : public Device * The frame manager can change during our lifetime, so we buffer those two. */ bool myEnableJitter{false}; - uInt8 myJitterFactor{0}; + uInt8 myJitterSensitivity{0}; + uInt8 myJitterRecovery{0}; static constexpr uInt16 TIA_SIZE = 0x40, TIA_MASK = TIA_SIZE - 1, diff --git a/src/emucore/tia/frame-manager/AbstractFrameManager.cxx b/src/emucore/tia/frame-manager/AbstractFrameManager.cxx index 0067a6a40..92dacfb55 100644 --- a/src/emucore/tia/frame-manager/AbstractFrameManager.cxx +++ b/src/emucore/tia/frame-manager/AbstractFrameManager.cxx @@ -72,13 +72,13 @@ void AbstractFrameManager::setVblank(bool vblank) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void AbstractFrameManager::setVsync(bool vsync) +void AbstractFrameManager::setVsync(bool vsync, uInt64 cycles) { if (vsync == myVsync) return; myVsync = vsync; - onSetVsync(); + onSetVsync(cycles); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/tia/frame-manager/AbstractFrameManager.hxx b/src/emucore/tia/frame-manager/AbstractFrameManager.hxx index 5327257f5..a69b5118c 100644 --- a/src/emucore/tia/frame-manager/AbstractFrameManager.hxx +++ b/src/emucore/tia/frame-manager/AbstractFrameManager.hxx @@ -67,7 +67,7 @@ class AbstractFrameManager : public Serializable /** * Called by TIA on VSYNC writes. */ - void setVsync(bool vsync); + void setVsync(bool vsync, uInt64 cycles); /** * Should the TIA render its frame? This is buffered in a flag for @@ -123,10 +123,15 @@ class AbstractFrameManager : public Serializable // required. All of these are irrelevant if nothing is displayed (during // autodetect). + /** + * The jitter sensitivity determines jitter simulation sensitivity to unstable video signals. + */ + virtual void setJitterSensitivity(uInt8 sensitivity) {} + /** * The jitter factor determines the time jitter simulation takes to recover. */ - virtual void setJitterFactor(uInt8 factor) {} + virtual void setJitterRecovery(uInt8 factor) {} /** * Is jitter simulation enabled? @@ -207,7 +212,7 @@ class AbstractFrameManager : public Serializable /** * Called if vsync changes. */ - virtual void onSetVsync() {} + virtual void onSetVsync(uInt64 cycles) {} /** * Called if the next line is signalled, after the internal bookkeeping has diff --git a/src/emucore/tia/frame-manager/FrameLayoutDetector.cxx b/src/emucore/tia/frame-manager/FrameLayoutDetector.cxx index ac01f0702..6861ff8bb 100644 --- a/src/emucore/tia/frame-manager/FrameLayoutDetector.cxx +++ b/src/emucore/tia/frame-manager/FrameLayoutDetector.cxx @@ -39,7 +39,7 @@ void FrameLayoutDetector::onReset() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameLayoutDetector::onSetVsync() +void FrameLayoutDetector::onSetVsync(uInt64) { if (myVsync) setState(State::waitForVsyncEnd); diff --git a/src/emucore/tia/frame-manager/FrameLayoutDetector.hxx b/src/emucore/tia/frame-manager/FrameLayoutDetector.hxx index 0d5c52a28..da72a0cf9 100644 --- a/src/emucore/tia/frame-manager/FrameLayoutDetector.hxx +++ b/src/emucore/tia/frame-manager/FrameLayoutDetector.hxx @@ -44,7 +44,7 @@ class FrameLayoutDetector: public AbstractFrameManager /** * Hook into vsync changes. */ - void onSetVsync() override; + void onSetVsync(uInt64) override; /** * Hook into reset. diff --git a/src/emucore/tia/frame-manager/FrameManager.cxx b/src/emucore/tia/frame-manager/FrameManager.cxx index 9eb86427a..0ab4369cc 100644 --- a/src/emucore/tia/frame-manager/FrameManager.cxx +++ b/src/emucore/tia/frame-manager/FrameManager.cxx @@ -114,10 +114,16 @@ void FrameManager::setAdjustVSize(Int32 adjustVSize) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameManager::onSetVsync() +void FrameManager::onSetVsync(uInt64 cycles) { - if (myState == State::waitForVsyncEnd) setState(State::waitForFrameStart); - else setState(State::waitForVsyncEnd); + if (myState == State::waitForVsyncEnd) { + myVsyncEnd = cycles; + setState(State::waitForFrameStart); + } + else { + myVsyncStart = cycles; + setState(State::waitForVsyncEnd); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -133,7 +139,7 @@ void FrameManager::setState(FrameManager::State state) notifyFrameComplete(); if (myTotalFrames > Metrics::initialGarbageFrames) - myJitterEmulation.frameComplete(myCurrentFrameFinalLines); + myJitterEmulation.frameComplete(myCurrentFrameFinalLines, myVsyncEnd - myVsyncStart); notifyFrameStart(); diff --git a/src/emucore/tia/frame-manager/FrameManager.hxx b/src/emucore/tia/frame-manager/FrameManager.hxx index f5b8eae4d..7ec51c903 100644 --- a/src/emucore/tia/frame-manager/FrameManager.hxx +++ b/src/emucore/tia/frame-manager/FrameManager.hxx @@ -47,8 +47,9 @@ class FrameManager: public AbstractFrameManager { FrameManager(); public: + void setJitterSensitivity(uInt8 sensitivity) override { myJitterEmulation.setSensitivity(sensitivity); } - void setJitterFactor(uInt8 factor) override { myJitterEmulation.setJitterFactor(factor); } + void setJitterRecovery(uInt8 factor) override { myJitterEmulation.setRecovery(factor); } bool jitterEnabled() const override { return myJitterEnabled; } @@ -78,7 +79,7 @@ class FrameManager: public AbstractFrameManager { void setLayout(FrameLayout mode) override { layout(mode); } - void onSetVsync() override; + void onSetVsync(uInt64 cycles) override; void onNextLine() override; @@ -122,6 +123,8 @@ class FrameManager: public AbstractFrameManager { Int32 myMaxVcenter{0}; Int32 myVSizeAdjust{0}; + uInt64 myVsyncStart{0}; + uInt64 myVsyncEnd{0}; bool myJitterEnabled{false}; JitterEmulation myJitterEmulation; diff --git a/src/emucore/tia/frame-manager/JitterEmulation.cxx b/src/emucore/tia/frame-manager/JitterEmulation.cxx index c9e08aa28..905dbe0c9 100644 --- a/src/emucore/tia/frame-manager/JitterEmulation.cxx +++ b/src/emucore/tia/frame-manager/JitterEmulation.cxx @@ -26,52 +26,103 @@ JitterEmulation::JitterEmulation() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void JitterEmulation::reset() { - myLastFrameScanlines = 0; - myStableFrameFinalLines = -1; - myStableFrames = 0; - myStabilizationCounter = 0; - myDestabilizationCounter = 0; - myJitter = 0; + setSensitivity(mySensitivity); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void JitterEmulation::frameComplete(uInt32 scanlineCount) +void JitterEmulation::setSensitivity(Int32 sensitivity) { - if (static_cast(scanlineCount) != myStableFrameFinalLines) { - if (myDestabilizationCounter++ > Metrics::framesUntilDestabilization) myStableFrameFinalLines = -1; + myLastFrameScanlines = myLastFrameVsyncCycles = myUnstableCount = myJitter = 0; + mySensitivity = BSPF::clamp(sensitivity, MIN_SENSITIVITY, MAX_SENSITIVITY); - if (scanlineCount == myLastFrameScanlines) { + const float factor = pow(static_cast(mySensitivity - MIN_SENSITIVITY) / (MAX_SENSITIVITY - MIN_SENSITIVITY), 1.5); - if (++myStabilizationCounter >= Metrics::framesForStableHeight) { - if (myStableFrameFinalLines > 0) updateJitter(scanlineCount - myStableFrameFinalLines); + myScanlineDelta = round(MAX_SCANLINE_DELTA - (MAX_SCANLINE_DELTA - MIN_SCANLINE_DELTA) * factor); + myVsyncCycles = round(MIN_VSYNC_CYCLES + (MAX_VSYNC_CYCLES - MIN_VSYNC_CYCLES) * factor); + myVsyncDelta1 = round(MAX_VSYNC_DELTA_1 - (MAX_VSYNC_DELTA_1 - MIN_VSYNC_DELTA_1) * factor); +#ifdef VSYNC_LINE_JITTER + myVsyncDelta2 = round(MIN_VSYNC_DELTA_2 + (MAX_VSYNC_DELTA_2 - MIN_VSYNC_DELTA_2) * factor); +#endif + myUnstableFrames = round(MAX_UNSTABLE_FRAMES - (MAX_UNSTABLE_FRAMES - MIN_UNSTABLE_FRAMES) * factor); + myJitterLines = round(MIN_JITTER_LINES + (MAX_JITTER_LINES - MIN_JITTER_LINES) * factor); + myVsyncLines = round(MIN_VSYNC_LINES + (MAX_VSYNC_LINES - MIN_VSYNC_LINES) * factor); +} - myStableFrameFinalLines = scanlineCount; - myDestabilizationCounter = 0; +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void JitterEmulation::frameComplete(Int32 scanlineCount, Int32 vsyncCycles) +{ +#ifdef DEBUG_BUILD + const int vsyncLines = round((vsyncCycles - 2) / 76.0); + cerr << "TV jitter " << myJitter << " - " << scanlineCount << ", " << vsyncCycles << ", " << vsyncLines << endl; +#endif + + // Check if current frame size is stable compared to previous frame + const bool scanlinesStable = scanlineCount == myLastFrameScanlines; + const bool vsyncCyclesStable = vsyncCycles >= myVsyncCycles; + // Handle inconsistency of vsync cycles and around half lines +#ifdef VSYNC_LINE_JITTER + const Int32 minLines = round((vsyncCycles - 2 - myVsyncDelta2) / 76.0); + const Int32 maxLines = round((vsyncCycles - 2 + myVsyncDelta2) / 76.0); + const Int32 minLastLines = round((myLastFrameVsyncCycles - 2 - myVsyncDelta2) / 76.0); + const Int32 maxLastLines = round((myLastFrameVsyncCycles - 2 + myVsyncDelta2) / 76.0); + const bool vsyncLinesStable = abs(vsyncCycles - myLastFrameVsyncCycles) < myVsyncDelta1 + && minLines == maxLastLines && maxLines == minLastLines; +#else + const bool vsyncLinesStable = abs(vsyncCycles - myLastFrameVsyncCycles) < myVsyncDelta1; +#endif + + if(!scanlinesStable || !vsyncCyclesStable || !vsyncLinesStable) + { + if(++myUnstableCount >= myUnstableFrames) + { + if(!scanlinesStable) + { + const Int32 scanlineDifference = scanlineCount - myLastFrameScanlines; + + if(abs(scanlineDifference) < myScanlineDelta + && abs(myJitter) < static_cast(myRandom.next() % myJitterLines)) + { + // Repeated invalid frames cause randomly repeated jitter + myJitter = std::max(std::min(scanlineDifference, myJitterLines), -myYStart); + } } + if(!vsyncCyclesStable) + { + // If VSYNC length is too low, the frame rolls permanently down, speed depending on missing cycles + const Int32 jitter = std::max( + std::min(round(scanlineCount * (1 - static_cast(vsyncCycles) / myVsyncCycles)), + myJitterLines), + myJitterRecovery + 1); // Roll at least one scanline + myJitter -= jitter; + // Limit jitter to -myYstart..scanlineCount + if(myJitter < -myYStart) + myJitter += 262; + } + if(!vsyncLinesStable) + { +#ifdef VSYNC_LINE_JITTER + myJitter += minLines > maxLastLines ? myVsyncLines : -myVsyncLines; +#else + myJitter += vsyncCycles > myLastFrameVsyncCycles ? myVsyncLines : -myVsyncLines; +#endif + } + myJitter = std::max(myJitter, -myYStart); } - else myStabilizationCounter = 0; } - else myDestabilizationCounter = 0; + else + { + myUnstableCount = 0; + + // Only recover during stable frames + if(myJitter > 0) + myJitter = std::max(myJitter - myJitterRecovery, 0); + else if(myJitter < 0) + myJitter = std::min(myJitter + myJitterRecovery, 0); + } myLastFrameScanlines = scanlineCount; - - if (myJitter > 0) myJitter = std::max(myJitter - myJitterFactor, 0); - if (myJitter < 0) myJitter = std::min(myJitter + myJitterFactor, 0); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void JitterEmulation::updateJitter(Int32 scanlineDifference) -{ - if (static_cast(abs(scanlineDifference)) < Metrics::minDeltaForJitter) return; - - Int32 jitter = std::min(scanlineDifference, Metrics::maxJitter); - jitter = std::max(jitter, -myYStart); - - if (jitter > 0) jitter += myJitterFactor; - if (jitter < 0) jitter -= myJitterFactor; - - if (abs(jitter) > abs(myJitter)) myJitter = jitter; + myLastFrameVsyncCycles = vsyncCycles; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -79,14 +130,13 @@ bool JitterEmulation::save(Serializer& out) const { try { - out.putInt(myLastFrameScanlines); - out.putInt(myStableFrameFinalLines); - out.putInt(myStableFrames); - out.putInt(myStabilizationCounter); - out.putInt(myDestabilizationCounter); - out.putInt(myJitter); - out.putInt(myJitterFactor); + out.putInt(mySensitivity); + out.putInt(myJitterRecovery); out.putInt(myYStart); + out.putInt(myLastFrameScanlines); + out.putInt(myLastFrameVsyncCycles); + out.putInt(myUnstableCount); + out.putInt(myJitter); } catch(...) { @@ -103,14 +153,13 @@ bool JitterEmulation::load(Serializer& in) { try { - myLastFrameScanlines = in.getInt(); - myStableFrameFinalLines = in.getInt(); - myStableFrames = in.getInt(); - myStabilizationCounter = in.getInt(); - myDestabilizationCounter = in.getInt(); - myJitter = in.getInt(); - myJitterFactor = in.getInt(); + mySensitivity = in.getInt(); + myJitterRecovery = in.getInt(); myYStart = in.getInt(); + myLastFrameScanlines = in.getInt(); + myLastFrameVsyncCycles = in.getInt(); + myUnstableCount = in.getInt(); + myJitter = in.getInt(); } catch (...) { @@ -118,6 +167,7 @@ bool JitterEmulation::load(Serializer& in) return false; } + setSensitivity(mySensitivity); return true; } diff --git a/src/emucore/tia/frame-manager/JitterEmulation.hxx b/src/emucore/tia/frame-manager/JitterEmulation.hxx index ebdee2559..0c6aa06b8 100644 --- a/src/emucore/tia/frame-manager/JitterEmulation.hxx +++ b/src/emucore/tia/frame-manager/JitterEmulation.hxx @@ -18,27 +18,38 @@ #ifndef TIA_JITTER_EMULATION #define TIA_JITTER_EMULATION +//#define VSYNC_LINE_JITTER // makes e.g. Alien jitter, but not on my TV (TJ) + #include "bspf.hxx" #include "Serializable.hxx" +#include "Random.hxx" -class JitterEmulation: public Serializable +class JitterEmulation : public Serializable { public: - JitterEmulation(); public: + // sensitivity: + static constexpr Int32 MIN_SENSITIVITY = 1; + static constexpr Int32 MAX_SENSITIVITY = 10; + static constexpr Int32 PLR_SENSITIVITY = 3; + static constexpr Int32 DEV_SENSITIVITY = 8; + // roll speed: + static constexpr Int32 MIN_RECOVERY = 1; + static constexpr Int32 MAX_RECOVERY = 20; + static constexpr Int32 PLR_RECOVERY = 10; + static constexpr Int32 DEV_RECOVERY = 2; + public: void reset(); + void setSensitivity(Int32 sensitivity); + void setRecovery(Int32 recoveryFactor) { myJitterRecovery = recoveryFactor; } + void setYStart(Int32 ystart) { myYStart = ystart; } - void frameComplete(uInt32 scanlineCount); - - void setJitterFactor(Int32 factor) { myJitterFactor = factor; } - + void frameComplete(Int32 scanlineCount, Int32 vsyncCycles); Int32 jitter() const { return myJitter; } - void setYStart(uInt32 ystart) { myYStart = ystart; } - /** * Save state. */ @@ -50,36 +61,48 @@ class JitterEmulation: public Serializable bool load(Serializer& in) override; private: - - void updateJitter(Int32 scanlineDifference); + // varying scanlines: + static constexpr Int32 MIN_SCANLINE_DELTA = 1; // was: 3 + static constexpr Int32 MAX_SCANLINE_DELTA = 5; + // varying VSYNC timing: + static constexpr Int32 MIN_VSYNC_CYCLES = 76 * 3 / 4; + static constexpr Int32 MAX_VSYNC_CYCLES = 76 * 3; + static constexpr Int32 MIN_VSYNC_DELTA_1 = 1; + static constexpr Int32 MAX_VSYNC_DELTA_1 = 76 / 3; +#ifdef VSYNC_LINE_JITTER + static constexpr Int32 MIN_VSYNC_DELTA_2 = 1; + static constexpr Int32 MAX_VSYNC_DELTA_2 = 10; +#endif + // threshold for jitter: + static constexpr Int32 MIN_UNSTABLE_FRAMES = 1; // was: 10 + static constexpr Int32 MAX_UNSTABLE_FRAMES = 10; + // resulting jitter: + static constexpr Int32 MIN_JITTER_LINES = 1; // was: 50 + static constexpr Int32 MAX_JITTER_LINES = 200; + static constexpr Int32 MIN_VSYNC_LINES = 1; + static constexpr Int32 MAX_VSYNC_LINES = 5; private: + Random myRandom; - uInt32 myLastFrameScanlines{0}; - - Int32 myStableFrameFinalLines{-1}; - - uInt32 myStableFrames{0}; - - uInt32 myStabilizationCounter{0}; - - uInt32 myDestabilizationCounter{0}; - + Int32 myLastFrameScanlines{0}; + Int32 myLastFrameVsyncCycles{0}; + Int32 myUnstableCount{0}; Int32 myJitter{0}; - - Int32 myJitterFactor{0}; - - uInt32 myYStart{0}; - - enum Metrics: uInt32 { - framesForStableHeight = 2, - framesUntilDestabilization = 10, - minDeltaForJitter = 3, - maxJitter = 50 - }; + Int32 myJitterRecovery{0}; + Int32 myYStart{0}; + Int32 mySensitivity{MIN_SENSITIVITY}; + Int32 myScanlineDelta{MAX_SCANLINE_DELTA}; + Int32 myVsyncCycles{MIN_VSYNC_CYCLES}; + Int32 myVsyncDelta1{MAX_VSYNC_DELTA_1}; +#ifdef VSYNC_LINE_JITTER + Int32 myVsyncDelta2{MIN_VSYNC_DELTA_2}; +#endif + Int32 myUnstableFrames{MAX_UNSTABLE_FRAMES}; + Int32 myJitterLines{MIN_JITTER_LINES}; + Int32 myVsyncLines{MIN_VSYNC_LINES}; private: - JitterEmulation(const JitterEmulation&) = delete; JitterEmulation(JitterEmulation&&) = delete; JitterEmulation& operator=(const JitterEmulation&) = delete; diff --git a/src/gui/DeveloperDialog.cxx b/src/gui/DeveloperDialog.cxx index fd22e69d9..3e1d5e975 100644 --- a/src/gui/DeveloperDialog.cxx +++ b/src/gui/DeveloperDialog.cxx @@ -33,6 +33,7 @@ #include "Font.hxx" #include "Console.hxx" #include "TIA.hxx" +#include "JitterEmulation.hxx" #include "OSystem.hxx" #include "EventHandler.hxx" #include "StateManager.hxx" @@ -372,21 +373,33 @@ void DeveloperDialog::addVideoTab(const GUI::Font& font) // TV jitter effect myTVJitterWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "Jitter/roll effect", kTVJitter); + ypos += lineHeight + VGAP; + myTVJitterWidget->setToolTip("Enable to emulate TV loss of sync.", Event::ToggleJitter); wid.push_back(myTVJitterWidget); + + myTVJitterSenseWidget = new SliderWidget(myTab, font, + myTVJitterWidget->getLeft() + CheckboxWidget::prefixSize(font), ypos - 1, + fontWidth * 9, lineHeight, + "Sensitivity ", 0, 0, fontWidth * 2); + myTVJitterSenseWidget->setMinValue(JitterEmulation::MIN_SENSITIVITY); + myTVJitterSenseWidget->setMaxValue(JitterEmulation::MAX_SENSITIVITY); + myTVJitterSenseWidget->setTickmarkIntervals(3); + myTVJitterSenseWidget->setToolTip("Define sensitivity to unstable frames.", + Event::JitterSenseDecrease, Event::JitterSenseIncrease); + wid.push_back(myTVJitterSenseWidget); + myTVJitterRecWidget = new SliderWidget(myTab, font, - myTVJitterWidget->getRight() + fontWidth * 3, ypos - 1, - "Recovery ", 0, kTVJitterChanged); - myTVJitterRecWidget->setMinValue(1); myTVJitterRecWidget->setMaxValue(20); + myTVJitterSenseWidget->getRight() + fontWidth * 2, ypos - 1, + fontWidth * 9, lineHeight, + "Recovery ", 0, 0, fontWidth * 2); + myTVJitterRecWidget->setMinValue(JitterEmulation::MIN_RECOVERY); + myTVJitterRecWidget->setMaxValue(JitterEmulation::MAX_RECOVERY); myTVJitterRecWidget->setTickmarkIntervals(5); myTVJitterRecWidget->setToolTip("Define speed of sync recovery.", - Event::JitterDecrease, Event::JitterIncrease); + Event::JitterRecDecrease, Event::JitterRecIncrease); wid.push_back(myTVJitterRecWidget); - myTVJitterRecLabelWidget = new StaticTextWidget(myTab, font, - myTVJitterRecWidget->getRight() + 4, - myTVJitterRecWidget->getTop() + 2, - 5 * fontWidth, fontHeight); - ypos += lineHeight + VGAP; + ypos += lineHeight + VGAP * 2; myColorLossWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "PAL color-loss"); @@ -728,6 +741,7 @@ void DeveloperDialog::getWidgetStates(SettingsSet set) myColorLoss[set] = myColorLossWidget->getState(); // Jitter myTVJitter[set] = myTVJitterWidget->getState(); + myTVJitterSense[set] = myTVJitterSenseWidget->getValue(); myTVJitterRec[set] = myTVJitterRecWidget->getValue(); // States @@ -777,9 +791,10 @@ void DeveloperDialog::setWidgetStates(SettingsSet set) myColorLossWidget->setState(myColorLoss[set]); // Jitter myTVJitterWidget->setState(myTVJitter[set]); + myTVJitterSenseWidget->setValue(myTVJitterSense[set]); myTVJitterRecWidget->setValue(myTVJitterRec[set]); - handleTVJitterChange(myTVJitterWidget->getState()); + handleTVJitterChange(); // States myTimeMachineWidget->setState(myTimeMachine[set]); @@ -931,6 +946,9 @@ void DeveloperDialog::setDefaults() case 2: // Video // Jitter myTVJitter[set] = true; + myTVJitterSense[set] = devSettings + ? JitterEmulation::DEV_SENSITIVITY + : JitterEmulation::PLR_SENSITIVITY; myTVJitterRec[set] = devSettings ? 2 : 10; // PAL color-loss effect myColorLoss[set] = devSettings ? true : false; @@ -997,11 +1015,7 @@ void DeveloperDialog::handleCommand(CommandSender* sender, int cmd, int data, in break; case kTVJitter: - handleTVJitterChange(myTVJitterWidget->getState()); - break; - - case kTVJitterChanged: - myTVJitterRecLabelWidget->setValue(myTVJitterRecWidget->getValue()); + handleTVJitterChange(); break; case kTimeMachine: @@ -1101,10 +1115,12 @@ void DeveloperDialog::handleSettings(bool devSettings) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void DeveloperDialog::handleTVJitterChange(bool enable) +void DeveloperDialog::handleTVJitterChange() { + bool enable = myTVJitterWidget->getState(); + + myTVJitterSenseWidget->setEnabled(enable); myTVJitterRecWidget->setEnabled(enable); - myTVJitterRecLabelWidget->setEnabled(enable); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/DeveloperDialog.hxx b/src/gui/DeveloperDialog.hxx index c94b2e473..2e900ef9c 100644 --- a/src/gui/DeveloperDialog.hxx +++ b/src/gui/DeveloperDialog.hxx @@ -60,7 +60,6 @@ class DeveloperDialog : public Dialog, DevSettingsHandler kConsole = 'DVco', kTIAType = 'DVtt', kTVJitter = 'DVjt', - kTVJitterChanged = 'DVjr', kTimeMachine = 'DTtm', kSizeChanged = 'DTsz', kUncompressedChanged = 'DTuc', @@ -125,6 +124,7 @@ class DeveloperDialog : public Dialog, DevSettingsHandler CheckboxWidget* myTVJitterWidget{nullptr}; SliderWidget* myTVJitterRecWidget{nullptr}; StaticTextWidget* myTVJitterRecLabelWidget{nullptr}; + SliderWidget* myTVJitterSenseWidget{nullptr}; CheckboxWidget* myColorLossWidget{nullptr}; CheckboxWidget* myDebugColorsWidget{nullptr}; std::array myDbgColour{nullptr}; @@ -160,7 +160,7 @@ class DeveloperDialog : public Dialog, DevSettingsHandler void setWidgetStates(SettingsSet set); void handleSettings(bool devSettings); - void handleTVJitterChange(bool enable); + void handleTVJitterChange(); void handleConsole(); void handleTia();
ItemBrief descriptionFor more information,
see Command Line
Jitter/roll effectEmulate screen roll with inconsistent scanline count-plr.tv.jitter
-dev.tv.jitter
(Jitter/roll) SensitivityDetermines sensitivity for screen rolling-plr.tv.jitter_sense
-dev.tv.jitter_sense
(Jitter/roll) RecoveryDetermines recovery time for screen rolling-plr.tv.jitter_recovery
-dev.tv.jitter_recovery
PAL color-lossUse PAL color-loss effect-plr.colorloss
-dev.colorloss
Debug colorsUse fixed debug colors-plr.debugcolors
-dev.debugcolors