added score mode glitch emulation TIA option (resolves #587)

This commit is contained in:
Thomas Jentzsch 2021-11-30 23:07:59 +01:00
parent a4059235fa
commit 2504f8600c
12 changed files with 95 additions and 27 deletions

View File

@ -24,6 +24,8 @@
* Added option to toggle autofire mode.
* Added another oddball TIA glitch option for score mode color.
-Have fun!

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -3723,8 +3723,8 @@
<td>When enabled, each external access (AtariVox/SaveKey EEPROM, PlusROM, Supercharger...)
is signalled by a message.</td>
</tr><tr>
<td><pre>-dev.tia.type &lt;standard|koolaidman|cosmicark|</br> pesco|quickstep|indy500|heman|custom&gt;</pre></td>
<td>Set emulated TIA type.</td>
<td><pre>-dev.tia.type &lt;standard|koolaidman|</br> cosmicark|pesco|quickstep|matchie|</br> indy500|heman|custom&gt;</pre></td>
<td>Set emulated TIA type. Only with 'custom' the following TIA options become relevant.</td>
</tr><tr>
<td><pre>-dev.tia.plinvphase &lt;1|0&gt;</pre></td>
<td>Enable/disable inverted HMOVE clock phase for players (Kool Aid Man glitch).</td>
@ -3740,6 +3740,9 @@
</tr><tr>
<td><pre>-dev.tia.delaypfcolor &lt;1|0&gt;</pre></td>
<td>Enable/disable playfield color delayed by one color clock (colored step borders in Quick Step!).</td>
</tr><tr>
<td><pre>-dev.tia.pfscoreglitch &lt;1|0&gt;</pre></td>
<td>Enable/disable earlier playfield score mode color color switch (center vertical line in Matchie).</td>
</tr><tr>
<td><pre>-dev.tia.delaybkcolor &lt;1|0&gt;</pre></td>
<td>Enable/disable background color delayed by one color clock (stray pixels in Indy 500 menu hack).</td>
@ -4570,10 +4573,10 @@
<tr><td>Inverted HMOVE clock...</td><td>Emulates the Kool-Aid Man
collision and Cosmic Ark stars glitches for the given objects.</td>
<td>-dev.tia.plinvphase</br>-dev.tia.msinvphase</br>-dev.tia.blinvphase</td></tr>
<tr><td>Delayed Playfield</td><td>Emulates playfield register changes delayed
<tr><td>Delayed Playfield</td><td>Emulates playfield changes moved
by one color clock. This e.g. causes glitches in Pesco (stray playfield
pixel) and Quick Step! (colored step borders).</td>
<td>-dev.tia.delaypfbits</br>-dev.tia.delaypfcolor</td></tr>
pixel), Quick Step! (colored step borders) and Matchie (vertical line at pixel 79).</td>
<td>-dev.tia.delaypfbits</br>-dev.tia.delaypfcolor</br>-dev.tia.pfscoreglitch</td></tr>
<tr><td>Delayed Background</td><td>Emulates background color register changes delayed
by one color clock. This causes stray pixel in the Indy 500 menu hack.</td>
<td>-dev.tia.delaybkcolor</td></tr>

View File

@ -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]);

View File

@ -70,6 +70,7 @@ class DevSettingsHandler
std::array<bool, numSets> myBlInvPhase;
std::array<bool, numSets> myPFBits;
std::array<bool, numSets> myPFColor;
std::array<bool, numSets> myPFScore;
std::array<bool, numSets> myBKColor;
std::array<bool, numSets> myPlSwap;
std::array<bool, numSets> myBlSwap;

View File

@ -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 <standard|custom| Selects a TIA type\n"
<< " koolaidman|\n"
<< " cosmicark|pesco|\n"
<< " quickstep|\n"
<< " quickstep|matchie|\n"
<< " indy500|heman|>\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;
}

View File

@ -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();

View File

@ -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)));

View File

@ -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)
{

View File

@ -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.

View File

@ -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);

View File

@ -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};