From 51f8d904d231a5743ff04ef8c5880385eb4fe237 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Tue, 29 Nov 2022 16:10:43 +0100 Subject: [PATCH] Revert "improved inlining in VS (I hope this doesn't break the code again)" This reverts commit 46f2b6aac0e75c49718ac85437566d598c79617c. --- src/emucore/tia/Ball.hxx | 150 ++++++++++++++++++---------------- src/emucore/tia/Missile.hxx | 128 +++++++++++++++-------------- src/emucore/tia/Player.hxx | 131 ++++++++++++++--------------- src/emucore/tia/Playfield.hxx | 55 +++++++------ 4 files changed, 244 insertions(+), 220 deletions(-) diff --git a/src/emucore/tia/Ball.hxx b/src/emucore/tia/Ball.hxx index 6750687c8..dd6cf8d1f 100644 --- a/src/emucore/tia/Ball.hxx +++ b/src/emucore/tia/Ball.hxx @@ -165,80 +165,14 @@ class Ball : public Serializable bool load(Serializer& in) override; /** - Process a single movement tick. Inline for performance. + Process a single movement tick. Inline for performance (implementation below). */ - FORCE_INLINE void movementTick(uInt32 clock, bool hblank) - { - myLastMovementTick = myCounter; - - // Stop movement once the number of clocks according to HMBL is reached - if (clock == myHmmClocks) - isMoving = false; - - if(isMoving) - { - // Process the tick if we are in hblank. Otherwise, the tick is either masked - // by an ordinary tick or merges two consecutive ticks into a single tick (inverted - // movement clock phase mode). - if (hblank) tick(false); - - // Track a tick outside hblank for later processing - myInvertedPhaseClock = !hblank; - } - } + FORCE_INLINE void movementTick(uInt32 clock, bool hblank); /** - Tick one color clock. Inline for performance. + Tick one color clock. Inline for performance (implementation below). */ - FORCE_INLINE void tick(bool isReceivingRegularClock = true) - { - // If we are in inverted movement clock phase mode and a movement tick occurred, it - // will supress the tick. - if(myUseInvertedPhaseClock && myInvertedPhaseClock) - { - myInvertedPhaseClock = false; - return; - } - - // Turn on the signal if the render counter reaches the threshold - mySignalActive = myIsRendering && myRenderCounter >= 0; - - // Consider enabled status and the signal to determine visibility (as represented - // by the collision mask) - collision = (mySignalActive && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled; - - // Regular clock pulse during movement -> starfield mode - const bool starfieldEffect = isMoving && isReceivingRegularClock; - - // Decode value that triggers rendering - if (myCounter == 156) { - myIsRendering = true; - myRenderCounter = renderCounterOffset; - - // What follows is an effective description of ball width in starfield mode. - const 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; - } + FORCE_INLINE void tick(bool isReceivingRegularClock = true); public: @@ -402,4 +336,80 @@ class Ball : public Serializable Ball& operator=(Ball&&) = delete; }; +// ############################################################################ +// Implementation +// ############################################################################ + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +FORCE_INLINE void Ball::movementTick(uInt32 clock, bool hblank) +{ + myLastMovementTick = myCounter; + + // Stop movement once the number of clocks according to HMBL is reached + if (clock == myHmmClocks) + isMoving = false; + + if(isMoving) + { + // Process the tick if we are in hblank. Otherwise, the tick is either masked + // by an ordinary tick or merges two consecutive ticks into a single tick (inverted + // movement clock phase mode). + if (hblank) tick(false); + + // Track a tick outside hblank for later processing + myInvertedPhaseClock = !hblank; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +FORCE_INLINE void Ball::tick(bool isReceivingRegularClock) +{ + // If we are in inverted movement clock phase mode and a movement tick occurred, it + // will supress the tick. + if(myUseInvertedPhaseClock && myInvertedPhaseClock) + { + myInvertedPhaseClock = false; + return; + } + + // Turn on the signal if the render counter reaches the threshold + mySignalActive = myIsRendering && myRenderCounter >= 0; + + // Consider enabled status and the signal to determine visibility (as represented + // by the collision mask) + collision = (mySignalActive && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled; + + // Regular clock pulse during movement -> starfield mode + const bool starfieldEffect = isMoving && isReceivingRegularClock; + + // Decode value that triggers rendering + if (myCounter == 156) { + myIsRendering = true; + myRenderCounter = renderCounterOffset; + + // What follows is an effective description of ball width in starfield mode. + const 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; +} + #endif // TIA_BALL diff --git a/src/emucore/tia/Missile.hxx b/src/emucore/tia/Missile.hxx index 6638ea937..a860bd23b 100644 --- a/src/emucore/tia/Missile.hxx +++ b/src/emucore/tia/Missile.hxx @@ -76,69 +76,9 @@ class Missile : public Serializable bool save(Serializer& out) const override; bool load(Serializer& in) override; - /** - Process a single movement tick. Inline for performance. - */ - FORCE_INLINE void movementTick(uInt8 clock, uInt8 hclock, bool hblank) - { - if(clock == myHmmClocks) isMoving = false; + FORCE_INLINE void movementTick(uInt8 clock, uInt8 hclock, bool hblank); - if (isMoving) - { - if (hblank) tick(hclock, false); - myInvertedPhaseClock = !hblank; - } - } - - /** - Tick one color clock. Inline for performance. - */ - FORCE_INLINE void tick(uInt8 hclock, bool isReceivingMclock = true) - { - 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; - myCopy = myDecodes[myCounter]; - } 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; - } + FORCE_INLINE void tick(uInt8 hclock, bool isReceivingMclock = true); public: @@ -196,4 +136,68 @@ class Missile : public Serializable Missile& operator=(Missile&&) = delete; }; +// ############################################################################ +// Implementation +// ############################################################################ + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +FORCE_INLINE void Missile::movementTick(uInt8 clock, uInt8 hclock, bool hblank) +{ + if(clock == myHmmClocks) isMoving = false; + + if (isMoving) + { + if (hblank) tick(hclock, false); + myInvertedPhaseClock = !hblank; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +FORCE_INLINE 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 = renderCounterOffset; + myCopy = myDecodes[myCounter]; + } 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; +} + #endif // TIA_MISSILE diff --git a/src/emucore/tia/Player.hxx b/src/emucore/tia/Player.hxx index b30b31d58..c42fed515 100644 --- a/src/emucore/tia/Player.hxx +++ b/src/emucore/tia/Player.hxx @@ -87,71 +87,9 @@ class Player : public Serializable bool save(Serializer& out) const override; bool load(Serializer& in) override; - /** - Process a single movement tick. Inline for performance. - */ - FORCE_INLINE void movementTick(uInt32 clock, bool hblank) - { - if (clock == myHmmClocks) - isMoving = false; - - if(isMoving) - { - if (hblank) tick(); - myInvertedPhaseClock = !hblank; - } - } - - /** - Tick one color clock. Inline for performance. - */ - FORCE_INLINE 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; - myCopy = myDecodes[myCounter]; - } 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; - } + FORCE_INLINE void movementTick(uInt32 clock, bool hblank); + FORCE_INLINE void tick(); public: @@ -214,4 +152,69 @@ class Player : public Serializable Player& operator=(Player&&) = delete; }; +// ############################################################################ +// Implementation +// ############################################################################ + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +FORCE_INLINE void Player::movementTick(uInt32 clock, bool hblank) +{ + if (clock == myHmmClocks) + isMoving = false; + + if(isMoving) + { + if (hblank) tick(); + myInvertedPhaseClock = !hblank; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +FORCE_INLINE 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 = renderCounterOffset; + myCopy = myDecodes[myCounter]; + } 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; +} + #endif // TIA_PLAYER diff --git a/src/emucore/tia/Playfield.hxx b/src/emucore/tia/Playfield.hxx index d9e416770..763712fe2 100644 --- a/src/emucore/tia/Playfield.hxx +++ b/src/emucore/tia/Playfield.hxx @@ -132,31 +132,9 @@ class Playfield : public Serializable bool load(Serializer& in) override; /** - Tick one color clock. Inline for performance. + Tick one color clock. Inline for performance (implementation below). */ - FORCE_INLINE void tick(uInt32 x) - { - myX = x; - - // Reflected flag is updated only at x = 0 or x = 79 - if (myX == TIAConstants::H_PIXEL / 2-1 || myX == 0) myRefp = myReflected; - - if (x & 0x03) return; - - uInt32 currentPixel; - - if (myEffectivePattern == 0) { - currentPixel = 0; - } else if (x < TIAConstants::H_PIXEL / 2 - 1) { - 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; - } + FORCE_INLINE void tick(uInt32 x); public: @@ -283,4 +261,33 @@ class Playfield : public Serializable Playfield& operator=(Playfield&&) = delete; }; +// ############################################################################ +// Implementation +// ############################################################################ + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +FORCE_INLINE void Playfield::tick(uInt32 x) +{ + myX = x; + + // Reflected flag is updated only at x = 0 or x = 79 + if (myX == TIAConstants::H_PIXEL / 2-1 || myX == 0) myRefp = myReflected; + + if (x & 0x03) return; + + uInt32 currentPixel; + + if (myEffectivePattern == 0) { + currentPixel = 0; + } else if (x < TIAConstants::H_PIXEL / 2 - 1) { + 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; +} + #endif // TIA_PLAYFIELD