diff --git a/Changes.txt b/Changes.txt index bd42bb88b..6a2a0e1e1 100644 --- a/Changes.txt +++ b/Changes.txt @@ -24,6 +24,8 @@ * Added option to toggle autofire mode. + * Added another oddball TIA glitch option for score mode color. + -Have fun! diff --git a/docs/graphics/options_developer_tia.png b/docs/graphics/options_developer_tia.png index 0e4f73764..847f035db 100644 Binary files a/docs/graphics/options_developer_tia.png and b/docs/graphics/options_developer_tia.png differ diff --git a/docs/index.html b/docs/index.html index 8850786ed..0c8fa756d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3723,8 +3723,8 @@ When enabled, each external access (AtariVox/SaveKey EEPROM, PlusROM, Supercharger...) is signalled by a message. -
-dev.tia.type <standard|koolaidman|cosmicark|
pesco|quickstep|indy500|heman|custom>
- Set emulated TIA type. +
-dev.tia.type <standard|koolaidman|
cosmicark|pesco|quickstep|matchie|
indy500|heman|custom>
+ Set emulated TIA type. Only with 'custom' the following TIA options become relevant.
-dev.tia.plinvphase <1|0>
Enable/disable inverted HMOVE clock phase for players (Kool Aid Man glitch). @@ -3740,6 +3740,9 @@
-dev.tia.delaypfcolor <1|0>
Enable/disable playfield color delayed by one color clock (colored step borders in Quick Step!). + +
-dev.tia.pfscoreglitch <1|0>
+ Enable/disable earlier playfield score mode color color switch (center vertical line in Matchie).
-dev.tia.delaybkcolor <1|0>
Enable/disable background color delayed by one color clock (stray pixels in Indy 500 menu hack). @@ -4570,10 +4573,10 @@ Inverted HMOVE clock...Emulates the Kool-Aid Man collision and Cosmic Ark stars glitches for the given objects. -dev.tia.plinvphase
-dev.tia.msinvphase
-dev.tia.blinvphase - Delayed PlayfieldEmulates playfield register changes delayed + Delayed PlayfieldEmulates playfield changes moved by one color clock. This e.g. causes glitches in Pesco (stray playfield - pixel) and Quick Step! (colored step borders). - -dev.tia.delaypfbits
-dev.tia.delaypfcolor + pixel), Quick Step! (colored step borders) and Matchie (vertical line at pixel 79). + -dev.tia.delaypfbits
-dev.tia.delaypfcolor
-dev.tia.pfscoreglitch Delayed BackgroundEmulates background color register changes delayed by one color clock. This causes stray pixel in the Indy 500 menu hack. -dev.tia.delaybkcolor diff --git a/src/common/DevSettingsHandler.cxx b/src/common/DevSettingsHandler.cxx index 9b28ce149..fe3d52cd4 100644 --- a/src/common/DevSettingsHandler.cxx +++ b/src/common/DevSettingsHandler.cxx @@ -67,6 +67,7 @@ void DevSettingsHandler::loadSettings(SettingsSet set) myBlInvPhase[set] = devSettings ? settings.getBool("dev.tia.blinvphase") : false; myPFBits[set] = devSettings ? settings.getBool("dev.tia.delaypfbits") : false; myPFColor[set] = devSettings ? settings.getBool("dev.tia.delaypfcolor") : false; + myPFScore[set] = devSettings ? settings.getBool("dev.tia.pfscoreglitch") : false; myBKColor[set] = devSettings ? settings.getBool("dev.tia.delaybkcolor") : false; myPlSwap[set] = devSettings ? settings.getBool("dev.tia.delayplswap") : false; myBlSwap[set] = devSettings ? settings.getBool("dev.tia.delayblswap") : false; @@ -134,6 +135,7 @@ void DevSettingsHandler::saveSettings(SettingsSet set) settings.setValue("dev.tia.blinvphase", myBlInvPhase[set]); settings.setValue("dev.tia.delaypfbits", myPFBits[set]); settings.setValue("dev.tia.delaypfcolor", myPFColor[set]); + settings.setValue("dev.tia.pfscoreglitch", myPFScore[set]); settings.setValue("dev.tia.delaybkcolor", myBKColor[set]); settings.setValue("dev.tia.delayplswap", myPlSwap[set]); settings.setValue("dev.tia.delayblswap", myBlSwap[set]); @@ -187,6 +189,7 @@ void DevSettingsHandler::applySettings(SettingsSet set) myOSystem.console().tia().setBlInvertedPhaseClock(myBlInvPhase[set]); myOSystem.console().tia().setPFBitsDelay(myPFBits[set]); myOSystem.console().tia().setPFColorDelay(myPFColor[set]); + myOSystem.console().tia().setPFScoreGlitch(myPFScore[set]); myOSystem.console().tia().setBKColorDelay(myBKColor[set]); myOSystem.console().tia().setPlSwapDelay(myPlSwap[set]); myOSystem.console().tia().setBlSwapDelay(myBlSwap[set]); diff --git a/src/common/DevSettingsHandler.hxx b/src/common/DevSettingsHandler.hxx index 1d2ba73aa..1d683164c 100644 --- a/src/common/DevSettingsHandler.hxx +++ b/src/common/DevSettingsHandler.hxx @@ -70,6 +70,7 @@ class DevSettingsHandler std::array myBlInvPhase; std::array myPFBits; std::array myPFColor; + std::array myPFScore; std::array myBKColor; std::array myPlSwap; std::array myBlSwap; diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 804502a00..121725b7f 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -251,6 +251,7 @@ Settings::Settings() setPermanent("dev.tia.blinvphase", "true"); setPermanent("dev.tia.delaypfbits", "true"); setPermanent("dev.tia.delaypfcolor", "true"); + setPermanent("dev.tia.pfscoreglitch", "true"); setPermanent("dev.tia.delaybkcolor", "true"); setPermanent("dev.tia.delayplswap", "true"); setPermanent("dev.tia.delayblswap", "true"); @@ -745,17 +746,18 @@ void Settings::usage() const << " -dev.tia.type \n" - << " -dev.tia.plinvphase <1|0> Enable inverted HMOVE clock phase for players\n" - << " -dev.tia.msinvphase <1|0> Enable inverted HMOVE clock phase for\n" + << " -dev.tia.plinvphase <1|0> Enable inverted HMOVE clock phase for players\n" + << " -dev.tia.msinvphase <1|0> Enable inverted HMOVE clock phase for\n" << " missiles\n" - << " -dev.tia.blinvphase <1|0> Enable inverted HMOVE clock phase for ball\n" - << " -dev.tia.delaypfbits <1|0> Enable extra delay cycle for PF bits access\n" - << " -dev.tia.delaypfcolor <1|0> Enable extra delay cycle for PF color\n" - << " -dev.tia.delaybkcolor <1|0> Enable extra delay cycle for background color\n" - << " -dev.tia.delayplswap <1|0> Enable extra delay cycle for VDELP0/1 swap\n" - << " -dev.tia.delayblswap <1|0> Enable extra delay cycle for VDELBL swap\n" + << " -dev.tia.blinvphase <1|0> Enable inverted HMOVE clock phase for ball\n" + << " -dev.tia.delaypfbits <1|0> Enable extra delay cycle for PF bits access\n" + << " -dev.tia.delaypfcolor <1|0> Enable extra delay cycle for PF color\n" + << " -dev.tia.pfscoreglitch <1|0> Enable PF score mode color glitch\n" + << " -dev.tia.delaybkcolor <1|0> Enable extra delay cycle for background color\n" + << " -dev.tia.delayplswap <1|0> Enable extra delay cycle for VDELP0/1 swap\n" + << " -dev.tia.delayblswap <1|0> Enable extra delay cycle for VDELBL swap\n" << endl << std::flush; } diff --git a/src/emucore/tia/Playfield.cxx b/src/emucore/tia/Playfield.cxx index 67b2e328b..37fa633d4 100644 --- a/src/emucore/tia/Playfield.cxx +++ b/src/emucore/tia/Playfield.cxx @@ -41,6 +41,8 @@ void Playfield::reset() myColorLeft = myColorRight = 0; myColorP0 = myColorP1 = 0; myColorMode = ColorMode::normal; + myScoreGlitch = false; + myScoreHaste = 0; myDebugEnabled = false; collision = 0; @@ -107,6 +109,7 @@ void Playfield::ctrlpf(uInt8 value) myReflected = reflected; myColorMode = colorMode; + myScoreHaste = (myColorMode == ColorMode::score && myScoreGlitch) ? 1 : 0; applyColors(); } @@ -152,6 +155,13 @@ void Playfield::setColorP1(uInt8 color) applyColors(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Playfield::setScoreGlitch(bool enable) +{ + myScoreGlitch = enable; + myScoreHaste = (myColorMode == ColorMode::score && myScoreGlitch) ? 1 : 0; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Playfield::setDebugColor(uInt8 color) { @@ -222,10 +232,10 @@ void Playfield::applyColors() uInt8 Playfield::getColor() const { if (!myDebugEnabled) - return myX < TIAConstants::H_PIXEL / 2 ? myColorLeft : myColorRight; + return myX < uInt16(TIAConstants::H_PIXEL / 2 - myScoreHaste) ? myColorLeft : myColorRight; else { - if (myX < TIAConstants::H_PIXEL / 2) + if (myX < uInt16(TIAConstants::H_PIXEL / 2 - myScoreHaste)) { // left side: if(myX < 16) @@ -281,6 +291,7 @@ bool Playfield::save(Serializer& out) const out.putBool(myDebugEnabled); out.putByte(uInt8(myColorMode)); + out.putBool(myScoreGlitch); out.putInt(myPattern); out.putInt(myEffectivePattern); @@ -322,6 +333,8 @@ bool Playfield::load(Serializer& in) myDebugEnabled = in.getBool(); myColorMode = ColorMode(in.getByte()); + myScoreGlitch = in.getBool(); + myScoreHaste = myColorMode == ColorMode::score && myScoreGlitch ? 1 : 0; myPattern = in.getInt(); myEffectivePattern = in.getInt(); diff --git a/src/emucore/tia/Playfield.hxx b/src/emucore/tia/Playfield.hxx index 1420ba103..abc0163eb 100644 --- a/src/emucore/tia/Playfield.hxx +++ b/src/emucore/tia/Playfield.hxx @@ -89,6 +89,11 @@ class Playfield : public Serializable */ void setColorP1(uInt8 color); + /** + Set score mode color glitch. + */ + void setScoreGlitch(bool enable); + /** Set the color used in "debug colors" mode. */ @@ -144,7 +149,7 @@ class Playfield : public Serializable private: /** - Playfield mode. + Playfield color mode. */ enum class ColorMode: uInt8 {normal, score}; @@ -197,10 +202,20 @@ class Playfield : public Serializable bool myDebugEnabled{false}; /** - * Plafield mode. + * Playfield color mode. */ ColorMode myColorMode{ColorMode::normal}; + /** + * Score mode color glitch. + */ + bool myScoreGlitch{false}; + + /** + * Score mode color switch haste. + */ + uInt8 myScoreHaste{0}; + /** Pattern derifed from PF0, PF1, PF2 */ @@ -256,7 +271,7 @@ void Playfield::tick(uInt32 x) myX = x; // Reflected flag is updated only at x = 0 or x = 79 - if (myX == TIAConstants::H_PIXEL / 2 || myX == 0) myRefp = myReflected; + if (myX == TIAConstants::H_PIXEL / 2-1 || myX == 0) myRefp = myReflected; if (x & 0x03) return; @@ -264,7 +279,7 @@ void Playfield::tick(uInt32 x) if (myEffectivePattern == 0) { currentPixel = 0; - } else if (x < TIAConstants::H_PIXEL / 2) { + } else if (x < TIAConstants::H_PIXEL / 2 - 1) { currentPixel = myEffectivePattern & (1 << (x >> 2)); } else if (myRefp) { currentPixel = myEffectivePattern & (1 << (39 - (x >> 2))); diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index 9b0cb65e5..e908b6e36 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -957,6 +957,9 @@ void TIA::applyDeveloperSettings() setPFColorDelay(custom ? mySettings.getBool("dev.tia.delaypfcolor") : BSPF::equalsIgnoreCase("quickstep", mySettings.getString("dev.tia.type"))); + setPFScoreGlitch(custom + ? mySettings.getBool("dev.tia.pfscoreglitch") + : BSPF::equalsIgnoreCase("matchie", mySettings.getString("dev.tia.type"))); setBKColorDelay(custom ? mySettings.getBool("dev.tia.delaybkcolor") : BSPF::equalsIgnoreCase("indy500", mySettings.getString("dev.tia.type"))); @@ -972,6 +975,7 @@ void TIA::applyDeveloperSettings() setBlInvertedPhaseClock(false); setPFBitsDelay(false); setPFColorDelay(false); + myPlayfield.setScoreGlitch(false); setBKColorDelay(false); setPlSwapDelay(false); setBlSwapDelay(false); @@ -1661,6 +1665,12 @@ void TIA::setPFColorDelay(bool delayed) myPFColorDelay = delayed ? 1 : 0; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TIA::setPFScoreGlitch(bool enable) +{ + myPlayfield.setScoreGlitch(enable); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIA::setBKColorDelay(bool delayed) { diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index 59826edc4..9e595529f 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -457,6 +457,13 @@ class TIA : public Device */ void setPFColorDelay(bool delayed); + /** + Enables/disables score mode playfield color glitch + + @param enable Wether to enable color glitch + */ + void setPFScoreGlitch(bool enable); + /** Enables/disables delayed background colors. diff --git a/src/gui/DeveloperDialog.cxx b/src/gui/DeveloperDialog.cxx index fbd7d570a..d8f57380c 100644 --- a/src/gui/DeveloperDialog.cxx +++ b/src/gui/DeveloperDialog.cxx @@ -252,6 +252,7 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font) VarList::push_back(items, "Faulty Cosmic Ark stars", "cosmicark"); VarList::push_back(items, "Glitched Pesco", "pesco"); VarList::push_back(items, "Glitched Quick Step!", "quickstep"); + VarList::push_back(items, "Glitched Matchie line", "matchie"); VarList::push_back(items, "Glitched Indy 500 menu", "indy500"); VarList::push_back(items, "Glitched He-Man title", "heman"); VarList::push_back(items, "Custom", "custom"); @@ -273,12 +274,12 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font) "Players"); wid.push_back(myPlInvPhaseWidget); - myMsInvPhaseWidget = new CheckboxWidget(myTab, font, myPlInvPhaseWidget->getRight() + 20, ypos + 1, - "Missiles"); + myMsInvPhaseWidget = new CheckboxWidget(myTab, font, myPlInvPhaseWidget->getRight() + fontWidth() * 2.5, + ypos + 1, "Missiles"); wid.push_back(myMsInvPhaseWidget); - myBlInvPhaseWidget = new CheckboxWidget(myTab, font, myMsInvPhaseWidget->getRight() + 20, ypos + 1, - "Ball"); + myBlInvPhaseWidget = new CheckboxWidget(myTab, font, myMsInvPhaseWidget->getRight() + fontWidth() * 2.5, + ypos + 1, "Ball"); wid.push_back(myBlInvPhaseWidget); ypos += lineHeight + VGAP * 1; @@ -290,10 +291,14 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font) myPFBitsWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 3, ypos + 1, "Bits"); wid.push_back(myPFBitsWidget); - //ypos += lineHeight + VGAP * 1; - myPFColorWidget = new CheckboxWidget(myTab, font, myPFBitsWidget->getRight() + 20, ypos + 1, "Color"); + myPFColorWidget = new CheckboxWidget(myTab, font, myPFBitsWidget->getRight() + +fontWidth() * 2.5, + ypos + 1, "Color"); wid.push_back(myPFColorWidget); + + myPFScoreWidget = new CheckboxWidget(myTab, font, myPFColorWidget->getRight() + +fontWidth() * 2.5, + ypos + 1, "Score"); + wid.push_back(myPFScoreWidget); ypos += lineHeight + VGAP * 1; myBackgroundLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, @@ -316,7 +321,8 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font) myPlSwapWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 3, ypos + 1, "Players"); wid.push_back(myPlSwapWidget); - myBlSwapWidget = new CheckboxWidget(myTab, font, myPlSwapWidget->getRight() + 20, ypos + 1, "Ball"); + myBlSwapWidget = new CheckboxWidget(myTab, font, myPlSwapWidget->getRight() + fontWidth() * 2.5, + ypos + 1, "Ball"); wid.push_back(myBlSwapWidget); // Add items for tab 2 @@ -700,6 +706,7 @@ void DeveloperDialog::getWidgetStates(SettingsSet set) myBlInvPhase[set] = myBlInvPhaseWidget->getState(); myPFBits[set] = myPFBitsWidget->getState(); myPFColor[set] = myPFColorWidget->getState(); + myPFScore[set] = myPFScoreWidget->getState(); myBKColor[set] = myBKColorWidget->getState(); myPlSwap[set] = myPlSwapWidget->getState(); myBlSwap[set] = myBlSwapWidget->getState(); @@ -904,6 +911,7 @@ void DeveloperDialog::setDefaults() myBlInvPhase[set] = devSettings ? true : false; myPFBits[set] = devSettings ? true : false; myPFColor[set] = devSettings ? true : false; + myPFScore[set] = devSettings ? true : false; myBKColor[set] = devSettings ? true : false; myPlSwap[set] = devSettings ? true : false; myBlSwap[set] = devSettings ? true : false; @@ -1114,6 +1122,7 @@ void DeveloperDialog::handleTia() myBackgroundLabel->setEnabled(enable); myPFBitsWidget->setEnabled(enable); myPFColorWidget->setEnabled(enable); + myPFScoreWidget->setEnabled(enable); myBKColorWidget->setEnabled(enable); mySwapLabel->setEnabled(enable); myPlSwapWidget->setEnabled(enable); @@ -1128,6 +1137,7 @@ void DeveloperDialog::handleTia() myBlInvPhaseWidget->setState(myBlInvPhase[set]); myPFBitsWidget->setState(myPFBits[set]); myPFColorWidget->setState(myPFColor[set]); + myPFScoreWidget->setState(myPFScore[set]); myBKColorWidget->setState(myBKColor[set]); myPlSwapWidget->setState(myPlSwap[set]); myBlSwapWidget->setState(myBlSwap[set]); @@ -1139,6 +1149,7 @@ void DeveloperDialog::handleTia() myBlInvPhaseWidget->setState(false); myPFBitsWidget->setState(BSPF::equalsIgnoreCase("pesco", myTIATypeWidget->getSelectedTag().toString())); myPFColorWidget->setState(BSPF::equalsIgnoreCase("quickstep", myTIATypeWidget->getSelectedTag().toString())); + myPFScoreWidget->setState(BSPF::equalsIgnoreCase("matchie", myTIATypeWidget->getSelectedTag().toString())); myBKColorWidget->setState(BSPF::equalsIgnoreCase("indy500", myTIATypeWidget->getSelectedTag().toString())); myPlSwapWidget->setState(BSPF::equalsIgnoreCase("heman", myTIATypeWidget->getSelectedTag().toString())); myBlSwapWidget->setState(false); diff --git a/src/gui/DeveloperDialog.hxx b/src/gui/DeveloperDialog.hxx index 5779364f2..0489ee8f4 100644 --- a/src/gui/DeveloperDialog.hxx +++ b/src/gui/DeveloperDialog.hxx @@ -113,6 +113,7 @@ class DeveloperDialog : public Dialog, DevSettingsHandler StaticTextWidget* myPlayfieldLabel{nullptr}; CheckboxWidget* myPFBitsWidget{nullptr}; CheckboxWidget* myPFColorWidget{nullptr}; + CheckboxWidget* myPFScoreWidget{nullptr}; StaticTextWidget* myBackgroundLabel{nullptr}; CheckboxWidget* myBKColorWidget{nullptr}; StaticTextWidget* mySwapLabel{nullptr};