Re-activate PAL colour-loss effect.

- Only activates in PAL-like modes (PAL and PAL60)
This commit is contained in:
Stephen Anthony 2017-05-12 16:29:46 -02:30
parent 1c9343e0e4
commit fb5daa483b
18 changed files with 187 additions and 51 deletions

View File

@ -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");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },

View File

@ -28,7 +28,7 @@
#include "StateManager.hxx"
#define STATE_HEADER "04090600state"
#define STATE_HEADER "04090700state"
#define MOVIE_HEADER "03030000movie"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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