diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 73a573271..156594f22 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -328,12 +328,16 @@ void Console::toggleFormat(int direction) void Console::toggleColorLoss() { bool colorloss = !myOSystem.settings().getBool("colorloss"); - myOSystem.settings().setValue("colorloss", colorloss); - myTIA->enableColorLoss(colorloss); - - string message = string("PAL color-loss ") + - (colorloss ? "enabled" : "disabled"); - myOSystem.frameBuffer().showMessage(message); + if(myTIA->enableColorLoss(colorloss)) + { + myOSystem.settings().setValue("colorloss", colorloss); + string message = string("PAL color-loss ") + + (colorloss ? "enabled" : "disabled"); + myOSystem.frameBuffer().showMessage(message); + } + else + myOSystem.frameBuffer().showMessage( + "PAL color-loss not available in non PAL modes"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/DefProps.hxx b/src/emucore/DefProps.hxx index 3b3c94bf8..9cde5b22b 100644 --- a/src/emucore/DefProps.hxx +++ b/src/emucore/DefProps.hxx @@ -718,7 +718,7 @@ static const char* DefProps[DEF_PROPS_SIZE][21] = { { "35ae903dff7389755ad4a07f2fb7400c", "", "", "Colored Wall Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "35b10a248a7e67493ec43aeb9743538c", "Dor-x", "", "Defender (Dor-x) (Hack)", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "35b43b54e83403bb3d71f519739a9549", "Parker Brothers, Dave Engman, Isabel Garret", "", "McDonald's (06-06-1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "35be55426c1fec32dfb503b4f0651572", "Men-A-Vision", "", "Air Raid (Men-A-Vision) (PAL)", "NTSC50 format", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "NTSC50", "", "", "YES", "" }, + { "35be55426c1fec32dfb503b4f0651572", "Men-A-Vision", "", "Air Raid (Men-A-Vision) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, { "35fa32256982774a4f134c3347882dff", "Retroactive", "", "Qb (V0.05) (Macintosh) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, { "360ba640f6810ec902b01a09cc8ab556", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (06-15-1983) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "360c0dcb11506e73bd0b77207c81bc62", "Digitel", "", "Enduro (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, diff --git a/src/emucore/StateManager.cxx b/src/emucore/StateManager.cxx index 7b4837264..1819979b6 100644 --- a/src/emucore/StateManager.cxx +++ b/src/emucore/StateManager.cxx @@ -28,7 +28,7 @@ #include "StateManager.hxx" -#define STATE_HEADER "04090600state" +#define STATE_HEADER "04090700state" #define MOVIE_HEADER "03030000movie" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/stella.pro b/src/emucore/stella.pro index cd904261b..3d1be8792 100644 --- a/src/emucore/stella.pro +++ b/src/emucore/stella.pro @@ -4261,9 +4261,7 @@ "Cartridge.MD5" "35be55426c1fec32dfb503b4f0651572" "Cartridge.Manufacturer" "Men-A-Vision" "Cartridge.Name" "Air Raid (Men-A-Vision) (PAL)" -"Cartridge.Note" "NTSC50 format" "Cartridge.Rarity" "Extremely Rare" -"Display.Format" "NTSC50" "Display.Phosphor" "YES" "" diff --git a/src/emucore/tia/Background.cxx b/src/emucore/tia/Background.cxx index ed3e127dc..47f9b3166 100644 --- a/src/emucore/tia/Background.cxx +++ b/src/emucore/tia/Background.cxx @@ -56,10 +56,24 @@ void Background::enableDebugColors(bool enabled) applyColors(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Background::applyColorLoss() +{ + myTIA->flushLineCache(); + applyColors(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Background::applyColors() { - myColor = myDebugEnabled ? myDebugColor : myObjectColor; + if (!myDebugEnabled) + { + if (myTIA->colorLossActive()) myObjectColor |= 0x01; + else myObjectColor &= 0xfe; + myColor = myObjectColor; + } + else + myColor = myDebugColor; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -95,6 +109,8 @@ bool Background::load(Serializer& in) myObjectColor = in.getByte(); myDebugColor = in.getByte(); myDebugEnabled = in.getBool(); + + applyColors(); } catch(...) { diff --git a/src/emucore/tia/Background.hxx b/src/emucore/tia/Background.hxx index 2d90994e2..455e7cd8b 100644 --- a/src/emucore/tia/Background.hxx +++ b/src/emucore/tia/Background.hxx @@ -29,9 +29,7 @@ class Background : public Serializable Background(); public: - void setTIA(TIA* tia) { - myTIA = tia; - } + void setTIA(TIA* tia) { myTIA = tia; } void reset(); @@ -39,6 +37,8 @@ class Background : public Serializable void setDebugColor(uInt8 color); void enableDebugColors(bool enabled); + void applyColorLoss(); + uInt8 getColor() const { return myColor; } /** diff --git a/src/emucore/tia/Ball.cxx b/src/emucore/tia/Ball.cxx index 92755a814..6cf421ced 100644 --- a/src/emucore/tia/Ball.cxx +++ b/src/emucore/tia/Ball.cxx @@ -51,7 +51,6 @@ void Ball::reset() myRenderCounter = 0; updateEnabled(); - applyColors(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -134,7 +133,6 @@ void Ball::setColor(uInt8 color) void Ball::setDebugColor(uInt8 color) { myTIA->flushLineCache(); - myDebugColor = color; applyColors(); } @@ -143,11 +141,17 @@ void Ball::setDebugColor(uInt8 color) void Ball::enableDebugColors(bool enabled) { myTIA->flushLineCache(); - myDebugEnabled = enabled; applyColors(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Ball::applyColorLoss() +{ + myTIA->flushLineCache(); + applyColors(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Ball::startMovement() { @@ -234,7 +238,14 @@ void Ball::updateEnabled() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Ball::applyColors() { - myColor = myDebugEnabled ? myDebugColor : myObjectColor; + if (!myDebugEnabled) + { + if (myTIA->colorLossActive()) myObjectColor |= 0x01; + else myObjectColor &= 0xfe; + myColor = myObjectColor; + } + else + myColor = myDebugColor; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -325,6 +336,8 @@ bool Ball::load(Serializer& in) myIsRendering = in.getBool(); myRenderCounter = in.getByte(); + + applyColors(); } catch(...) { diff --git a/src/emucore/tia/Ball.hxx b/src/emucore/tia/Ball.hxx index 0297aff27..1f6a8d575 100644 --- a/src/emucore/tia/Ball.hxx +++ b/src/emucore/tia/Ball.hxx @@ -31,9 +31,7 @@ class Ball : public Serializable public: - void setTIA(TIA* tia) { - myTIA = tia; - } + void setTIA(TIA* tia) { myTIA = tia; } void reset(); @@ -56,6 +54,8 @@ class Ball : public Serializable void setDebugColor(uInt8 color); void enableDebugColors(bool enabled); + void applyColorLoss(); + void startMovement(); bool movementTick(uInt32 clock, bool apply); diff --git a/src/emucore/tia/FrameManager.cxx b/src/emucore/tia/FrameManager.cxx index a1c3f4b66..ba857a23e 100644 --- a/src/emucore/tia/FrameManager.cxx +++ b/src/emucore/tia/FrameManager.cxx @@ -213,6 +213,7 @@ void FrameManager::finalizeFrame() { handleJitter(myCurrentFrameTotalLines - myCurrentFrameFinalLines); + myPreviousFrameFinalLines = myCurrentFrameFinalLines; myCurrentFrameFinalLines = myCurrentFrameTotalLines; myCurrentFrameTotalLines = 0; myTotalFrames++; @@ -349,6 +350,7 @@ bool FrameManager::save(Serializer& out) const out.putInt(myLineInState); out.putInt(myCurrentFrameTotalLines); out.putInt(myCurrentFrameFinalLines); + out.putInt(myPreviousFrameFinalLines); out.putInt(myVsyncLines); out.putDouble(myFrameRate); out.putInt(myY); out.putInt(myLastY); @@ -394,6 +396,7 @@ bool FrameManager::load(Serializer& in) myLineInState = in.getInt(); myCurrentFrameTotalLines = in.getInt(); myCurrentFrameFinalLines = in.getInt(); + myPreviousFrameFinalLines = in.getInt(); myVsyncLines = in.getInt(); myFrameRate = float(in.getDouble()); myY = in.getInt(); myLastY = in.getInt(); diff --git a/src/emucore/tia/FrameManager.hxx b/src/emucore/tia/FrameManager.hxx index 659446c81..1daa6d8a1 100644 --- a/src/emucore/tia/FrameManager.hxx +++ b/src/emucore/tia/FrameManager.hxx @@ -69,6 +69,10 @@ class FrameManager : public Serializable uInt32 missingScanlines() const; + bool scanlineCountTransitioned() const { + return (myPreviousFrameFinalLines & 0x1) != (myCurrentFrameFinalLines & 0x1); + } + uInt32 frameCount() const { return myTotalFrames; } float frameRate() const { return myFrameRate; } @@ -141,6 +145,7 @@ class FrameManager : public Serializable uInt32 myLineInState; uInt32 myCurrentFrameTotalLines; uInt32 myCurrentFrameFinalLines; + uInt32 myPreviousFrameFinalLines; uInt32 myVsyncLines; float myFrameRate; uInt32 myY, myLastY; diff --git a/src/emucore/tia/Missile.cxx b/src/emucore/tia/Missile.cxx index bea6a6b9e..0ff01acc0 100644 --- a/src/emucore/tia/Missile.cxx +++ b/src/emucore/tia/Missile.cxx @@ -230,10 +230,18 @@ void Missile::setDebugColor(uInt8 color) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Missile::enableDebugColors(bool enabled) { + myTIA->flushLineCache(); myDebugEnabled = enabled; applyColors(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Missile::applyColorLoss() +{ + myTIA->flushLineCache(); + applyColors(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Missile::updateEnabled() { @@ -243,7 +251,14 @@ void Missile::updateEnabled() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Missile::applyColors() { - myColor = myDebugEnabled ? myDebugColor : myObjectColor; + if (!myDebugEnabled) + { + if (myTIA->colorLossActive()) myObjectColor |= 0x01; + else myObjectColor &= 0xfe; + myColor = myObjectColor; + } + else + myColor = myDebugColor; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -334,6 +349,8 @@ bool Missile::load(Serializer& in) myColor = in.getByte(); myObjectColor = in.getByte(); myDebugColor = in.getByte(); myDebugEnabled = in.getBool(); + + applyColors(); } catch(...) { diff --git a/src/emucore/tia/Missile.hxx b/src/emucore/tia/Missile.hxx index cadf7208d..12bef6626 100644 --- a/src/emucore/tia/Missile.hxx +++ b/src/emucore/tia/Missile.hxx @@ -32,9 +32,7 @@ class Missile : public Serializable public: - void setTIA(TIA* tia) { - myTIA = tia; - } + void setTIA(TIA* tia) { myTIA = tia; } void reset(); @@ -59,6 +57,8 @@ class Missile : public Serializable void setDebugColor(uInt8 color); void enableDebugColors(bool enabled); + void applyColorLoss(); + void toggleCollisions(bool enabled); void toggleEnabled(bool enabled); diff --git a/src/emucore/tia/Player.cxx b/src/emucore/tia/Player.cxx index a9c7689d1..dcc6bd2e1 100644 --- a/src/emucore/tia/Player.cxx +++ b/src/emucore/tia/Player.cxx @@ -231,7 +231,6 @@ void Player::setColor(uInt8 color) void Player::setDebugColor(uInt8 color) { myTIA->flushLineCache(); - myDebugColor = color; applyColors(); } @@ -240,11 +239,17 @@ void Player::setDebugColor(uInt8 color) void Player::enableDebugColors(bool enabled) { myTIA->flushLineCache(); - myDebugEnabled = enabled; applyColors(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Player::applyColorLoss() +{ + myTIA->flushLineCache(); + applyColors(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Player::startMovement() { @@ -379,7 +384,14 @@ void Player::setDivider(uInt8 divider) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Player::applyColors() { - myColor = myDebugEnabled ? myDebugColor : myObjectColor; + if (!myDebugEnabled) + { + if (myTIA->colorLossActive()) myObjectColor |= 0x01; + else myObjectColor &= 0xfe; + myColor = myObjectColor; + } + else + myColor = myDebugColor; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -487,6 +499,8 @@ bool Player::load(Serializer& in) myIsReflected = in.getBool(); myIsDelaying = in.getBool(); + + applyColors(); } catch(...) { diff --git a/src/emucore/tia/Player.hxx b/src/emucore/tia/Player.hxx index 11ac11594..e2cca4ccf 100644 --- a/src/emucore/tia/Player.hxx +++ b/src/emucore/tia/Player.hxx @@ -30,9 +30,7 @@ class Player : public Serializable public: - void setTIA(TIA* tia) { - myTIA = tia; - } + void setTIA(TIA* tia) { myTIA = tia; } void reset(); @@ -57,6 +55,8 @@ class Player : public Serializable void setDebugColor(uInt8 color); void enableDebugColors(bool enabled); + void applyColorLoss(); + void startMovement(); bool movementTick(uInt32 clock, bool apply); diff --git a/src/emucore/tia/Playfield.cxx b/src/emucore/tia/Playfield.cxx index e7bc7d3b5..332da7de4 100644 --- a/src/emucore/tia/Playfield.cxx +++ b/src/emucore/tia/Playfield.cxx @@ -46,7 +46,6 @@ void Playfield::reset() collision = 0; - applyColors(); updatePattern(); } @@ -169,6 +168,13 @@ void Playfield::enableDebugColors(bool enabled) applyColors(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Playfield::applyColorLoss() +{ + myTIA->flushLineCache(); + applyColors(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Playfield::tick(uInt32 x) { @@ -203,12 +209,23 @@ void Playfield::applyColors() switch (myColorMode) { case ColorMode::normal: - myColorLeft = myColorRight = myObjectColor; + if (myTIA->colorLossActive()) + myColorLeft = myColorRight = myObjectColor |= 0x01; + else + myColorLeft = myColorRight = myObjectColor &= 0xfe; break; case ColorMode::score: - myColorLeft = myColorP0; - myColorRight = myColorP1; + if (myTIA->colorLossActive()) + { + myColorLeft = myColorP0 |= 0x01; + myColorRight = myColorP1 |= 0x01; + } + else + { + myColorLeft = myColorP0 &= 0xfe; + myColorRight = myColorP1 &= 0xfe; + } break; } } diff --git a/src/emucore/tia/Playfield.hxx b/src/emucore/tia/Playfield.hxx index 8e656b426..59aaa55f4 100644 --- a/src/emucore/tia/Playfield.hxx +++ b/src/emucore/tia/Playfield.hxx @@ -30,9 +30,7 @@ class Playfield : public Serializable public: - void setTIA(TIA* tia) { - myTIA = tia; - } + void setTIA(TIA* tia) { myTIA = tia; } void reset(); @@ -57,6 +55,8 @@ class Playfield : public Serializable void setDebugColor(uInt8 color); void enableDebugColors(bool enabled); + void applyColorLoss(); + void tick(uInt32 x); uInt8 getPixel(uInt8 colorIn) const { diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index 8786897c3..486f2baf8 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -118,6 +118,7 @@ void TIA::reset() myLinesSinceChange = 0; myCollisionUpdateRequired = false; myAutoFrameEnabled = false; + myColorLossEnabled = myColorLossActive = false; myColorHBlank = 0; myLastCycle = 0; mySubClock = 0; @@ -152,7 +153,8 @@ void TIA::reset() void TIA::frameReset() { clearBuffers(); - myAutoFrameEnabled = (mySettings.getInt("framerate") <= 0); + myAutoFrameEnabled = mySettings.getInt("framerate") <= 0; + enableColorLoss(mySettings.getBool("colorloss")); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -754,9 +756,30 @@ void TIA::update() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// TODO: stub -void TIA::enableColorLoss(bool enabled) +bool TIA::enableColorLoss(bool enabled) { + if (consoleTiming() != ConsoleTiming::pal) + return false; + + if(enabled) + { + myColorLossEnabled = true; + myColorLossActive = false; // will be determined each frame + } + else + { + myColorLossEnabled = myColorLossActive = false; + + myMissile0.applyColorLoss(); + myMissile1.applyColorLoss(); + myPlayer0.applyColorLoss(); + myPlayer1.applyColorLoss(); + myBall.applyColorLoss(); + myPlayfield.applyColorLoss(); + myBackground.applyColorLoss(); + } + + return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -876,12 +899,6 @@ bool TIA::toggleFixedColors(uInt8 mode) return on; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool TIA::usingFixedColors() const -{ - return myColorHBlank != 0x00; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool TIA::driveUnusedPinsRandom(uInt8 mode) { @@ -896,7 +913,6 @@ bool TIA::driveUnusedPinsRandom(uInt8 mode) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// TODO: stub bool TIA::toggleJitter(uInt8 mode) { switch (mode) { @@ -989,6 +1005,26 @@ void TIA::onFrameStart() for (uInt8 i = 0; i < 4; i++) updatePaddle(i); + + // Check for colour-loss emulation + if (myColorLossEnabled) + { + // Only activate it when necessary, since changing colours in + // the graphical object forces the TIA cached line to be flushed + if (myFrameManager.scanlineCountTransitioned()) + { + myColorLossActive = myFrameManager.scanlinesLastFrame() & 0x1; + +cerr << "change: " << myColorLossActive << endl; + myMissile0.applyColorLoss(); + myMissile1.applyColorLoss(); + myPlayer0.applyColorLoss(); + myPlayer1.applyColorLoss(); + myBall.applyColorLoss(); + myPlayfield.applyColorLoss(); + myBackground.applyColorLoss(); + } + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index 57c2ae6e1..e22155e84 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -198,7 +198,14 @@ class TIA : public Device @param enabled Whether to enable or disable PAL color-loss mode */ - void enableColorLoss(bool enabled); + bool enableColorLoss(bool enabled); + + /** + Answers whether colour-loss is applicable for the current frame. + + @return Colour-loss is active for this frame + */ + bool colorLossActive() const { return myColorLossActive; } /** Answers the current color clock we've gotten to on this scanline. @@ -273,7 +280,7 @@ class TIA : public Device @return Whether the mode was enabled or disabled */ bool toggleFixedColors(uInt8 mode = 2); - bool usingFixedColors() const; + bool usingFixedColors() const { return myColorHBlank != 0x00; } /** Enable/disable/query state of 'undriven/floating TIA pins'. @@ -488,7 +495,13 @@ class TIA : public Device // Automatic framerate correction based on number of scanlines bool myAutoFrameEnabled; - private: + // Indicates if color loss should be enabled or disabled. Color loss + // occurs on PAL-like systems when the previous frame contains an odd + // number of scanlines. + bool myColorLossEnabled; + bool myColorLossActive; + + private: TIA() = delete; TIA(const TIA&) = delete; TIA(TIA&&) = delete;