More inlining for performance.

This commit is contained in:
Christian Speckner 2019-03-02 00:08:22 +01:00
parent 2a9bfd6b23
commit d04b5dd64b
11 changed files with 273 additions and 276 deletions

View File

@ -18,10 +18,6 @@
#include "Ball.hxx"
#include "TIA.hxx"
enum Count: Int8 {
renderCounterOffset = -4
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Ball::Ball(uInt32 collisionMask)
: myCollisionMaskDisabled(collisionMask),
@ -169,48 +165,6 @@ void Ball::startMovement()
isMoving = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Ball::tick(bool isReceivingMclock)
{
if(myUseInvertedPhaseClock && myInvertedPhaseClock)
{
myInvertedPhaseClock = false;
return;
}
myIsVisible = myIsRendering && myRenderCounter >= 0;
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
bool starfieldEffect = isMoving && isReceivingMclock;
if (myCounter == 156) {
myIsRendering = true;
myRenderCounter = Count::renderCounterOffset;
uInt8 starfieldDelta = (myCounter + TIA::H_PIXEL - myLastMovementTick) % 4;
if (starfieldEffect && starfieldDelta == 3 && myWidth < 4) ++myRenderCounter;
switch (starfieldDelta) {
case 3:
myEffectiveWidth = myWidth == 1 ? 2 : myWidth;
break;
case 2:
myEffectiveWidth = 0;
break;
default:
myEffectiveWidth = myWidth;
break;
}
} else if (myIsRendering && ++myRenderCounter >= (starfieldEffect ? myEffectiveWidth : myWidth))
myIsRendering = false;
if (++myCounter >= TIA::H_PIXEL)
myCounter = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Ball::nextLine()
{
@ -274,7 +228,7 @@ uInt8 Ball::getPosition() const
// The result may be negative, so we add 160 and do the modulus -> 317 = 156 + TIA::H_PIXEL + 1
//
// Mind the sign of renderCounterOffset: it's defined negative above
return (317 - myCounter - Count::renderCounterOffset + myTIA->getPosition()) % TIA::H_PIXEL;
return (317 - myCounter - Count::renderCounterOffset + myTIA->getPosition()) % TIAConstants::H_PIXEL;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -283,7 +237,7 @@ void Ball::setPosition(uInt8 newPosition)
myTIA->flushLineCache();
// See getPosition for an explanation
myCounter = (317 - newPosition - Count::renderCounterOffset + myTIA->getPosition()) % TIA::H_PIXEL;
myCounter = (317 - newPosition - Count::renderCounterOffset + myTIA->getPosition()) % TIAConstants::H_PIXEL;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -20,6 +20,7 @@
#include "Serializable.hxx"
#include "bspf.hxx"
#include "TIAConstants.hxx"
class TIA;
@ -60,23 +61,6 @@ class Ball : public Serializable
void startMovement();
void movementTick(uInt32 clock, bool hblank)
{
myLastMovementTick = myCounter;
if (clock == myHmmClocks)
isMoving = false;
if(isMoving)
{
if (hblank) tick(false);
myInvertedPhaseClock = !hblank;
}
}
void tick(bool isReceivingMclock = true);
void nextLine();
bool isOn() const { return (collision & 0x8000); }
@ -98,6 +82,61 @@ class Ball : public Serializable
bool save(Serializer& out) const override;
bool load(Serializer& in) override;
void movementTick(uInt32 clock, bool hblank)
{
myLastMovementTick = myCounter;
if (clock == myHmmClocks)
isMoving = false;
if(isMoving)
{
if (hblank) tick(false);
myInvertedPhaseClock = !hblank;
}
}
void tick(bool isReceivingMclock = false)
{
if(myUseInvertedPhaseClock && myInvertedPhaseClock)
{
myInvertedPhaseClock = false;
return;
}
myIsVisible = myIsRendering && myRenderCounter >= 0;
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
bool starfieldEffect = isMoving && isReceivingMclock;
if (myCounter == 156) {
myIsRendering = true;
myRenderCounter = renderCounterOffset;
uInt8 starfieldDelta = (myCounter + TIAConstants::H_PIXEL - myLastMovementTick) % 4;
if (starfieldEffect && starfieldDelta == 3 && myWidth < 4) ++myRenderCounter;
switch (starfieldDelta) {
case 3:
myEffectiveWidth = myWidth == 1 ? 2 : myWidth;
break;
case 2:
myEffectiveWidth = 0;
break;
default:
myEffectiveWidth = myWidth;
break;
}
} else if (myIsRendering && ++myRenderCounter >= (starfieldEffect ? myEffectiveWidth : myWidth))
myIsRendering = false;
if (++myCounter >= TIAConstants::H_PIXEL)
myCounter = 0;
}
public:
uInt32 collision;
@ -108,6 +147,12 @@ class Ball : public Serializable
void updateEnabled();
void applyColors();
private:
enum Count: Int8 {
renderCounterOffset = -4
};
private:
uInt32 myCollisionMaskDisabled;

View File

@ -19,10 +19,6 @@
#include "DrawCounterDecodes.hxx"
#include "TIA.hxx"
enum Count: Int8 {
renderCounterOffset = -4
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Missile::Missile(uInt32 collisionMask)
: myCollisionMaskDisabled(collisionMask),
@ -163,53 +159,6 @@ void Missile::startMovement()
isMoving = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Missile::tick(uInt8 hclock, bool isReceivingMclock)
{
if(myUseInvertedPhaseClock && myInvertedPhaseClock)
{
myInvertedPhaseClock = false;
return;
}
myIsVisible =
myIsRendering &&
(myRenderCounter >= 0 || (isMoving && isReceivingMclock && myRenderCounter == -1 && myWidth < 4 && ((hclock + 1) % 4 == 3)));
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
if (myDecodes[myCounter] && !myResmp) {
myIsRendering = true;
myRenderCounter = Count::renderCounterOffset;
} else if (myIsRendering) {
if (myRenderCounter == -1) {
if (isMoving && isReceivingMclock) {
switch ((hclock + 1) % 4) {
case 3:
myEffectiveWidth = myWidth == 1 ? 2 : myWidth;
if (myWidth < 4) ++myRenderCounter;
break;
case 2:
myEffectiveWidth = 0;
break;
default:
myEffectiveWidth = myWidth;
break;
}
} else {
myEffectiveWidth = myWidth;
}
}
if (++myRenderCounter >= (isMoving ? myEffectiveWidth : myWidth)) myIsRendering = false;
}
if (++myCounter >= TIA::H_PIXEL) myCounter = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Missile::nextLine()
{
@ -289,7 +238,7 @@ uInt8 Missile::getPosition() const
// The result may be negative, so we add 160 and do the modulus
//
// Mind the sign of renderCounterOffset: it's defined negative above
return (317 - myCounter - Count::renderCounterOffset + myTIA->getPosition()) % TIA::H_PIXEL;
return (317 - myCounter - Count::renderCounterOffset + myTIA->getPosition()) % TIAConstants::H_PIXEL;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -298,7 +247,7 @@ void Missile::setPosition(uInt8 newPosition)
myTIA->flushLineCache();
// See getPosition for an explanation
myCounter = (317 - newPosition - Count::renderCounterOffset + myTIA->getPosition()) % TIA::H_PIXEL;
myCounter = (317 - newPosition - Count::renderCounterOffset + myTIA->getPosition()) % TIAConstants::H_PIXEL;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -21,6 +21,7 @@
#include "Serializable.hxx"
#include "bspf.hxx"
#include "Player.hxx"
#include "TIAConstants.hxx"
class TIA;
@ -48,19 +49,6 @@ class Missile : public Serializable
void startMovement();
void movementTick(uInt8 clock, uInt8 hclock, bool hblank)
{
if(clock == myHmmClocks) isMoving = false;
if (isMoving)
{
if (hblank) tick(hclock, false);
myInvertedPhaseClock = !hblank;
}
}
void tick(uInt8 hclock, bool isReceivingMclock = true);
void nextLine();
void setColor(uInt8 color);
@ -88,6 +76,63 @@ class Missile : public Serializable
bool save(Serializer& out) const override;
bool load(Serializer& in) override;
void movementTick(uInt8 clock, uInt8 hclock, bool hblank)
{
if(clock == myHmmClocks) isMoving = false;
if (isMoving)
{
if (hblank) tick(hclock, false);
myInvertedPhaseClock = !hblank;
}
}
void tick(uInt8 hclock, bool isReceivingMclock = false)
{
if(myUseInvertedPhaseClock && myInvertedPhaseClock)
{
myInvertedPhaseClock = false;
return;
}
myIsVisible =
myIsRendering &&
(myRenderCounter >= 0 || (isMoving && isReceivingMclock && myRenderCounter == -1 && myWidth < 4 && ((hclock + 1) % 4 == 3)));
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
if (myDecodes[myCounter] && !myResmp) {
myIsRendering = true;
myRenderCounter = renderCounterOffset;
} else if (myIsRendering) {
if (myRenderCounter == -1) {
if (isMoving && isReceivingMclock) {
switch ((hclock + 1) % 4) {
case 3:
myEffectiveWidth = myWidth == 1 ? 2 : myWidth;
if (myWidth < 4) ++myRenderCounter;
break;
case 2:
myEffectiveWidth = 0;
break;
default:
myEffectiveWidth = myWidth;
break;
}
} else {
myEffectiveWidth = myWidth;
}
}
if (++myRenderCounter >= (isMoving ? myEffectiveWidth : myWidth)) myIsRendering = false;
}
if (++myCounter >= TIAConstants::H_PIXEL) myCounter = 0;
}
public:
uInt32 collision;
@ -98,6 +143,12 @@ class Missile : public Serializable
void updateEnabled();
void applyColors();
private:
enum Count: Int8 {
renderCounterOffset = -4
};
private:
uInt32 myCollisionMaskDisabled;

View File

@ -19,10 +19,6 @@
#include "DrawCounterDecodes.hxx"
#include "TIA.hxx"
enum Count: Int8 {
renderCounterOffset = -5,
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Player::Player(uInt32 collisionMask)
: myCollisionMaskDisabled(collisionMask),
@ -106,7 +102,7 @@ void Player::nusiz(uInt8 value, bool hblank)
myDecodes != oldDecodes &&
myIsRendering &&
(myRenderCounter - Count::renderCounterOffset) < 2 &&
!myDecodes[(myCounter - myRenderCounter + Count::renderCounterOffset + TIA::H_PIXEL - 1) % TIA::H_PIXEL]
!myDecodes[(myCounter - myRenderCounter + Count::renderCounterOffset + TIAConstants::H_PIXEL - 1) % TIAConstants::H_PIXEL]
) {
myIsRendering = false;
}
@ -265,53 +261,6 @@ void Player::startMovement()
isMoving = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::tick()
{
if(myUseInvertedPhaseClock && myInvertedPhaseClock)
{
myInvertedPhaseClock = false;
return;
}
if (!myIsRendering || myRenderCounter < myRenderCounterTripPoint)
collision = myCollisionMaskDisabled;
else
collision = (myPattern & (1 << mySampleCounter)) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
if (myDecodes[myCounter]) {
myIsRendering = true;
mySampleCounter = 0;
myRenderCounter = Count::renderCounterOffset;
} else if (myIsRendering) {
++myRenderCounter;
switch (myDivider) {
case 1:
if (myRenderCounter > 0)
++mySampleCounter;
if (myRenderCounter >= 0 && myDividerChangeCounter >= 0 && myDividerChangeCounter-- == 0)
setDivider(myDividerPending);
break;
default:
if (myRenderCounter > 1 && (((myRenderCounter - 1) % myDivider) == 0))
++mySampleCounter;
if (myRenderCounter > 0 && myDividerChangeCounter >= 0 && myDividerChangeCounter-- == 0)
setDivider(myDividerPending);
break;
}
if (mySampleCounter > 7) myIsRendering = false;
}
if (++myCounter >= TIA::H_PIXEL) myCounter = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::nextLine()
{
@ -340,13 +289,13 @@ uInt8 Player::getRespClock() const
switch (myDivider)
{
case 1:
return (myCounter + TIA::H_PIXEL - 5) % TIA::H_PIXEL;
return (myCounter + TIAConstants::H_PIXEL - 5) % TIAConstants::H_PIXEL;
case 2:
return (myCounter + TIA::H_PIXEL - 9) % TIA::H_PIXEL;
return (myCounter + TIAConstants::H_PIXEL - 9) % TIAConstants::H_PIXEL;
case 4:
return (myCounter + TIA::H_PIXEL - 12) % TIA::H_PIXEL;
return (myCounter + TIAConstants::H_PIXEL - 12) % TIAConstants::H_PIXEL;
default:
throw runtime_error("invalid width");
@ -427,7 +376,7 @@ uInt8 Player::getPosition() const
// The result may be negative, so we add TIA::H_PIXEL and do the modulus -> 317 = 156 + TIA::H_PIXEL + 1
//
// Mind the sign of renderCounterOffset: it's defined negative above
return (317 - myCounter - Count::renderCounterOffset + shift + myTIA->getPosition()) % TIA::H_PIXEL;
return (317 - myCounter - Count::renderCounterOffset + shift + myTIA->getPosition()) % TIAConstants::H_PIXEL;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -438,7 +387,7 @@ void Player::setPosition(uInt8 newPosition)
const uInt8 shift = myDivider == 1 ? 0 : 1;
// See getPosition for an explanation
myCounter = (317 - newPosition - Count::renderCounterOffset + shift + myTIA->getPosition()) % TIA::H_PIXEL;
myCounter = (317 - newPosition - Count::renderCounterOffset + shift + myTIA->getPosition()) % TIAConstants::H_PIXEL;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -20,6 +20,7 @@
#include "bspf.hxx"
#include "Serializable.hxx"
#include "TIAConstants.hxx"
class TIA;
@ -61,20 +62,6 @@ class Player : public Serializable
void startMovement();
void movementTick(uInt32 clock, bool hblank)
{
if (clock == myHmmClocks)
isMoving = false;
if(isMoving)
{
if (hblank) tick();
myInvertedPhaseClock = !hblank;
}
}
void tick();
void nextLine();
uInt8 getClock() const { return myCounter; }
@ -100,6 +87,64 @@ class Player : public Serializable
bool save(Serializer& out) const override;
bool load(Serializer& in) override;
void movementTick(uInt32 clock, bool hblank)
{
if (clock == myHmmClocks)
isMoving = false;
if(isMoving)
{
if (hblank) tick();
myInvertedPhaseClock = !hblank;
}
}
void tick()
{
if(myUseInvertedPhaseClock && myInvertedPhaseClock)
{
myInvertedPhaseClock = false;
return;
}
if (!myIsRendering || myRenderCounter < myRenderCounterTripPoint)
collision = myCollisionMaskDisabled;
else
collision = (myPattern & (1 << mySampleCounter)) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
if (myDecodes[myCounter]) {
myIsRendering = true;
mySampleCounter = 0;
myRenderCounter = renderCounterOffset;
} else if (myIsRendering) {
++myRenderCounter;
switch (myDivider) {
case 1:
if (myRenderCounter > 0)
++mySampleCounter;
if (myRenderCounter >= 0 && myDividerChangeCounter >= 0 && myDividerChangeCounter-- == 0)
setDivider(myDividerPending);
break;
default:
if (myRenderCounter > 1 && (((myRenderCounter - 1) % myDivider) == 0))
++mySampleCounter;
if (myRenderCounter > 0 && myDividerChangeCounter >= 0 && myDividerChangeCounter-- == 0)
setDivider(myDividerPending);
break;
}
if (mySampleCounter > 7) myIsRendering = false;
}
if (++myCounter >= TIAConstants::H_PIXEL) myCounter = 0;
}
public:
uInt32 collision;
@ -111,6 +156,12 @@ class Player : public Serializable
void applyColors();
void setDivider(uInt8 divider);
private:
enum Count: Int8 {
renderCounterOffset = -5,
};
private:
uInt32 myCollisionMaskDisabled;

View File

@ -183,30 +183,6 @@ void Playfield::applyColorLoss()
applyColors();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Playfield::tick(uInt32 x)
{
myX = x;
if (myX == TIA::H_PIXEL / 2 || myX == 0) myRefp = myReflected;
if (x & 0x03) return;
uInt32 currentPixel;
if (myEffectivePattern == 0) {
currentPixel = 0;
} else if (x < TIA::H_PIXEL / 2) {
currentPixel = myEffectivePattern & (1 << (x >> 2));
} else if (myRefp) {
currentPixel = myEffectivePattern & (1 << (39 - (x >> 2)));
} else {
currentPixel = myEffectivePattern & (1 << ((x >> 2) - 20));
}
collision = currentPixel ? myCollisionMaskEnabled : myCollisionMaskDisabled;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Playfield::nextLine()
{
@ -249,10 +225,10 @@ void Playfield::applyColors()
uInt8 Playfield::getColor() const
{
if (!myDebugEnabled)
return myX < TIA::H_PIXEL / 2 ? myColorLeft : myColorRight;
return myX < TIAConstants::H_PIXEL / 2 ? myColorLeft : myColorRight;
else
{
if (myX < TIA::H_PIXEL / 2)
if (myX < TIAConstants::H_PIXEL / 2)
{
// left side:
if(myX < 16)
@ -265,16 +241,16 @@ uInt8 Playfield::getColor() const
// right side:
if(!myReflected)
{
if(myX < TIA::H_PIXEL / 2 + 16)
if(myX < TIAConstants::H_PIXEL / 2 + 16)
return myDebugColor - 2; // PF0
if(myX < TIA::H_PIXEL / 2 + 48)
if(myX < TIAConstants::H_PIXEL / 2 + 48)
return myDebugColor; // PF1
}
else
{
if(myX >= TIA::H_PIXEL - 16)
if(myX >= TIAConstants::H_PIXEL - 16)
return myDebugColor - 2; // PF0
if(myX >= TIA::H_PIXEL - 48)
if(myX >= TIAConstants::H_PIXEL - 48)
return myDebugColor; // PF1
}
}

View File

@ -20,6 +20,7 @@
#include "Serializable.hxx"
#include "bspf.hxx"
#include "TIAConstants.hxx"
class TIA;
@ -57,8 +58,6 @@ class Playfield : public Serializable
void applyColorLoss();
void tick(uInt32 x);
void nextLine();
bool isOn() const { return (collision & 0x8000); }
@ -70,6 +69,29 @@ class Playfield : public Serializable
bool save(Serializer& out) const override;
bool load(Serializer& in) override;
void tick(uInt32 x)
{
myX = x;
if (myX == TIAConstants::H_PIXEL / 2 || myX == 0) myRefp = myReflected;
if (x & 0x03) return;
uInt32 currentPixel;
if (myEffectivePattern == 0) {
currentPixel = 0;
} else if (x < TIAConstants::H_PIXEL / 2) {
currentPixel = myEffectivePattern & (1 << (x >> 2));
} else if (myRefp) {
currentPixel = myEffectivePattern & (1 << (39 - (x >> 2)));
} else {
currentPixel = myEffectivePattern & (1 << ((x >> 2) - 20));
}
collision = currentPixel ? myCollisionMaskEnabled : myCollisionMaskDisabled;
}
public:
uInt32 collision;

View File

@ -63,7 +63,7 @@ enum ResxCounter: uInt8 {
// This parameter still has room for tuning. If we go lower than 73, long005 will show
// a slight artifact (still have to crosscheck on real hardware), if we go lower than
// 70, the G.I. Joe will show an artifact (hole in roof).
static constexpr uInt8 resxLateHblankThreshold = TIA::H_CYCLES - 3;
static constexpr uInt8 resxLateHblankThreshold = TIAConstants::H_CYCLES - 3;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TIA::TIA(ConsoleIO& console, ConsoleTimingProvider timingProvider, Settings& settings)
@ -223,9 +223,9 @@ void TIA::reset()
setFixedColorPalette(mySettings.getString("tia.dbgcolors"));
// Blank the various framebuffers; they may contain graphical garbage
memset(myBackBuffer, 0, H_PIXEL * TIAConstants::frameBufferHeight);
memset(myFrontBuffer, 0, H_PIXEL * TIAConstants::frameBufferHeight);
memset(myFramebuffer, 0, H_PIXEL * TIAConstants::frameBufferHeight);
memset(myBackBuffer, 0, TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight);
memset(myFrontBuffer, 0, TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight);
memset(myFramebuffer, 0, TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight);
#ifdef DEBUGGER_SUPPORT
createAccessBase();
@ -830,9 +830,9 @@ bool TIA::saveDisplay(Serializer& out) const
{
try
{
out.putByteArray(myFramebuffer, H_PIXEL * TIAConstants::frameBufferHeight);
out.putByteArray(myBackBuffer, H_PIXEL * TIAConstants::frameBufferHeight);
out.putByteArray(myFrontBuffer, H_PIXEL * TIAConstants::frameBufferHeight);
out.putByteArray(myFramebuffer, TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight);
out.putByteArray(myBackBuffer, TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight);
out.putByteArray(myFrontBuffer, TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight);
out.putInt(myFramesSinceLastRender);
}
catch(...)
@ -850,9 +850,9 @@ bool TIA::loadDisplay(Serializer& in)
try
{
// Reset frame buffer pointer and data
in.getByteArray(myFramebuffer, H_PIXEL * TIAConstants::frameBufferHeight);
in.getByteArray(myBackBuffer, H_PIXEL * TIAConstants::frameBufferHeight);
in.getByteArray(myFrontBuffer, H_PIXEL * TIAConstants::frameBufferHeight);
in.getByteArray(myFramebuffer, TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight);
in.getByteArray(myBackBuffer, TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight);
in.getByteArray(myFrontBuffer, TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight);
myFramesSinceLastRender = in.getInt();
}
catch(...)
@ -879,7 +879,7 @@ void TIA::renderToFrameBuffer()
myFramesSinceLastRender = 0;
memcpy(myFramebuffer, myFrontBuffer, H_PIXEL * TIAConstants::frameBufferHeight);
memcpy(myFramebuffer, myFrontBuffer, TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight);
myFrameBufferScanlines = myFrontBufferScanlines;
}
@ -923,7 +923,7 @@ bool TIA::electronBeamPos(uInt32& x, uInt32& y) const
{
uInt8 clocks = clocksThisLine();
x = (clocks < H_BLANK_CLOCKS) ? 0 : clocks - H_BLANK_CLOCKS;
x = (clocks < TIAConstants::H_BLANK_CLOCKS) ? 0 : clocks - TIAConstants::H_BLANK_CLOCKS;
y = myFrameManager->getY();
return isRendering();
@ -1186,10 +1186,10 @@ void TIA::updateEmulation()
{
const uInt64 systemCycles = mySystem->cycles();
if (mySubClock > CYCLE_CLOCKS - 1)
if (mySubClock > TIAConstants::CYCLE_CLOCKS - 1)
throw runtime_error("subclock exceeds range");
const uInt32 cyclesToRun = CYCLE_CLOCKS * uInt32(systemCycles - myLastCycle) + mySubClock;
const uInt32 cyclesToRun = TIAConstants::CYCLE_CLOCKS * uInt32(systemCycles - myLastCycle) + mySubClock;
mySubClock = 0;
myLastCycle = systemCycles;
@ -1234,9 +1234,9 @@ void TIA::onFrameComplete()
// Blank out any extra lines not drawn this frame
const Int32 missingScanlines = myFrameManager->missingScanlines();
if (missingScanlines > 0)
memset(myBackBuffer + H_PIXEL * myFrameManager->getY(), 0, missingScanlines * H_PIXEL);
memset(myBackBuffer + TIAConstants::H_PIXEL * myFrameManager->getY(), 0, missingScanlines * TIAConstants::H_PIXEL);
memcpy(myFrontBuffer, myBackBuffer, H_PIXEL * TIAConstants::frameBufferHeight);
memcpy(myFrontBuffer, myBackBuffer, TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight);
myFrontBufferScanlines = scanlinesLastFrame();
@ -1246,9 +1246,9 @@ void TIA::onFrameComplete()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::onHalt()
{
mySubClock += (H_CLOCKS - myHctr) % H_CLOCKS;
mySystem->incrementCycles(mySubClock / CYCLE_CLOCKS);
mySubClock %= CYCLE_CLOCKS;
mySubClock += (TIAConstants::H_CLOCKS - myHctr) % TIAConstants::H_CLOCKS;
mySystem->incrementCycles(mySubClock / TIAConstants::CYCLE_CLOCKS);
mySubClock %= TIAConstants::CYCLE_CLOCKS;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1274,7 +1274,7 @@ void TIA::cycle(uInt32 colorClocks)
if (myCollisionUpdateRequired && !myFrameManager->vblank()) updateCollision();
}
if (++myHctr >= H_CLOCKS)
if (++myHctr >= TIAConstants::H_CLOCKS)
nextLine();
#ifdef SOUND_SUPPORT
@ -1319,23 +1319,23 @@ void TIA::tickHblank()
myExtendedHblank = false;
break;
case H_BLANK_CLOCKS - 1:
case TIAConstants::H_BLANK_CLOCKS - 1:
if (!myExtendedHblank) myHstate = HState::frame;
break;
case H_BLANK_CLOCKS + 7:
case TIAConstants::H_BLANK_CLOCKS + 7:
if (myExtendedHblank) myHstate = HState::frame;
break;
}
if (myExtendedHblank && myHctr > H_BLANK_CLOCKS - 1) myPlayfield.tick(myHctr - H_BLANK_CLOCKS - myHctrDelta);
if (myExtendedHblank && myHctr > TIAConstants::H_BLANK_CLOCKS - 1) myPlayfield.tick(myHctr - TIAConstants::H_BLANK_CLOCKS - myHctrDelta);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::tickHframe()
{
const uInt32 y = myFrameManager->getY();
const uInt32 x = myHctr - H_BLANK_CLOCKS - myHctrDelta;
const uInt32 x = myHctr - TIAConstants::H_BLANK_CLOCKS - myHctrDelta;
myCollisionUpdateRequired = true;
@ -1353,13 +1353,13 @@ void TIA::tickHframe()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::applyRsync()
{
const uInt32 x = myHctr > H_BLANK_CLOCKS ? myHctr - H_BLANK_CLOCKS : 0;
const uInt32 x = myHctr > TIAConstants::H_BLANK_CLOCKS ? myHctr - TIAConstants::H_BLANK_CLOCKS : 0;
myHctrDelta = H_CLOCKS - 3 - myHctr;
myHctrDelta = TIAConstants::H_CLOCKS - 3 - myHctr;
if (myFrameManager->isRendering())
memset(myBackBuffer + myFrameManager->getY() * H_PIXEL + x, 0, H_PIXEL - x);
memset(myBackBuffer + myFrameManager->getY() * TIAConstants::H_PIXEL + x, 0, TIAConstants::H_PIXEL - x);
myHctr = H_CLOCKS - 3;
myHctr = TIAConstants::H_CLOCKS - 3;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1398,7 +1398,7 @@ void TIA::cloneLastLine()
uInt8* buffer = myBackBuffer;
memcpy(buffer + y * H_PIXEL, buffer + (y-1) * H_PIXEL, H_PIXEL);
memcpy(buffer + y * TIAConstants::H_PIXEL, buffer + (y-1) * TIAConstants::H_PIXEL, TIAConstants::H_PIXEL);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1423,7 +1423,7 @@ void TIA::updateCollision()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::renderPixel(uInt32 x, uInt32 y)
{
if (x >= H_PIXEL) return;
if (x >= TIAConstants::H_PIXEL) return;
uInt8 color = 0;
@ -1475,7 +1475,7 @@ void TIA::renderPixel(uInt32 x, uInt32 y)
}
}
myBackBuffer[y * H_PIXEL + x] = color;
myBackBuffer[y * TIAConstants::H_PIXEL + x] = color;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1501,7 +1501,7 @@ void TIA::flushLineCache()
void TIA::clearHmoveComb()
{
if (myFrameManager->isRendering() && myHstate == HState::blank)
memset(myBackBuffer + myFrameManager->getY() * H_PIXEL, myColorHBlank, 8);
memset(myBackBuffer + myFrameManager->getY() * TIAConstants::H_PIXEL, myColorHBlank, 8);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -103,11 +103,6 @@ class TIA : public Device
HBLANK_WHITE = 0x0e
};
static constexpr uInt16
H_PIXEL = 160, H_CYCLES = 76, CYCLE_CLOCKS = 3,
H_CLOCKS = H_CYCLES * CYCLE_CLOCKS, // = 228
H_BLANK_CLOCKS = H_CLOCKS - H_PIXEL; // = 68
using ConsoleTimingProvider = std::function<ConsoleTiming()>;
public:
@ -252,7 +247,7 @@ class TIA : public Device
/**
Answers dimensional info about the framebuffer.
*/
uInt32 width() const { return H_PIXEL; }
uInt32 width() const { return TIAConstants::H_PIXEL; }
uInt32 height() const { return myFrameManager->height(); }
uInt32 ystart() const { return myFrameManager->ystart(); }
@ -494,7 +489,7 @@ class TIA : public Device
uInt8 getPosition() const {
uInt8 realHctr = myHctr - myHctrDelta;
return (realHctr < H_BLANK_CLOCKS) ? 0 : (realHctr - H_BLANK_CLOCKS);
return (realHctr < TIAConstants::H_BLANK_CLOCKS) ? 0 : (realHctr - TIAConstants::H_BLANK_CLOCKS);
}
/**
@ -750,12 +745,12 @@ class TIA : public Device
LatchedInput myInput1;
// Pointer to the internal color-index-based frame buffer
uInt8 myFramebuffer[H_PIXEL * TIAConstants::frameBufferHeight];
uInt8 myFramebuffer[TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight];
// The frame is rendered to the backbuffer and only copied to the framebuffer
// upon completion
uInt8 myBackBuffer[H_PIXEL * TIAConstants::frameBufferHeight];
uInt8 myFrontBuffer[H_PIXEL * TIAConstants::frameBufferHeight];
uInt8 myBackBuffer[TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight];
uInt8 myFrontBuffer[TIAConstants::H_PIXEL * TIAConstants::frameBufferHeight];
// We snapshot frame statistics when the back buffer is copied to the front buffer
// and when the front buffer is copied to the frame buffer

View File

@ -26,6 +26,11 @@ namespace TIAConstants {
constexpr uInt32 maxYStart = 64;
constexpr uInt32 minViewableHeight = 210, maxViewableHeight = 256;
constexpr uInt32 initialGarbageFrames = 10;
static constexpr uInt16
H_PIXEL = 160, H_CYCLES = 76, CYCLE_CLOCKS = 3,
H_CLOCKS = H_CYCLES * CYCLE_CLOCKS, // = 228
H_BLANK_CLOCKS = H_CLOCKS - H_PIXEL; // = 68
}
enum TIABit {