mirror of https://github.com/stella-emu/stella.git
Add ball.
This commit is contained in:
parent
95c1d2b08c
commit
d02c985a91
|
@ -0,0 +1,153 @@
|
|||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2016 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include "Ball.hxx"
|
||||
|
||||
enum Count: Int8 {
|
||||
renderCounterOffset = -4
|
||||
};
|
||||
|
||||
namespace TIA6502tsCore {
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Ball::Ball(uInt32 collisionMask)
|
||||
: myCollisionMask(collisionMask)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::reset()
|
||||
{
|
||||
myColor = 0;
|
||||
collision = myCollisionMask;
|
||||
myEnabledOld = false;
|
||||
myEnabledNew = false;
|
||||
myEnabled = false;
|
||||
myHmmClocks = 0;
|
||||
myCounter = 0;
|
||||
myIsMoving = false;
|
||||
myWidth = 1;
|
||||
myIsRendering = false;
|
||||
myRenderCounter = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::enabl(uInt8 value)
|
||||
{
|
||||
myEnabledNew = (value & 0x02) > 0;
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::hmbl(uInt8 value)
|
||||
{
|
||||
myHmmClocks = (value >> 4) ^ 0x08;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::resbl(bool hblank)
|
||||
{
|
||||
myCounter = hblank ? 159 : 157;
|
||||
|
||||
if (!hblank) {
|
||||
myIsRendering = true;
|
||||
myRenderCounter = Count::renderCounterOffset;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::ctrlpf(uInt8 value)
|
||||
{
|
||||
static constexpr uInt8 ourWidths[] = {1, 2, 4, 8};
|
||||
|
||||
myWidth = ourWidths[(value & 0x30) >> 4];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::vdelbl(uInt8 value)
|
||||
{
|
||||
myIsDelaying = (value & 0x01) > 0;
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::setColor(uInt8 color)
|
||||
{
|
||||
myColor = color;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::startMovement()
|
||||
{
|
||||
myIsMoving = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Ball::movementTick(uInt32 clock, bool apply)
|
||||
{
|
||||
if (clock == myHmmClocks) myIsMoving = false;
|
||||
|
||||
if (myIsMoving && apply) {
|
||||
render();
|
||||
tick();
|
||||
}
|
||||
|
||||
return myIsMoving;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::render()
|
||||
{
|
||||
collision = (myIsRendering && myRenderCounter >= 0 && myEnabled) ? 0 : myCollisionMask;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::tick()
|
||||
{
|
||||
if (myCounter == 156) {
|
||||
myIsRendering = true;
|
||||
myRenderCounter = Count::renderCounterOffset;
|
||||
}
|
||||
else if (myIsRendering && ++myRenderCounter >= myWidth)
|
||||
myIsRendering = false;
|
||||
|
||||
if (++myCounter >= 160)
|
||||
myCounter = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 Ball::getPixel(uInt8 colorIn) const
|
||||
{
|
||||
return collision > 0 ? colorIn : myColor;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::shuffleStatus()
|
||||
{
|
||||
myEnabledOld = myEnabledNew;
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Ball::updateEnabled()
|
||||
{
|
||||
myEnabled = myIsDelaying ? myEnabledOld : myEnabledNew;
|
||||
}
|
||||
|
||||
} // namespace TIA6502tsCore
|
|
@ -0,0 +1,99 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2016 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifndef TIA_6502TS_CORE_BALL
|
||||
#define TIA_6502TS_CORE_BALL
|
||||
|
||||
#include "bspf.hxx"
|
||||
|
||||
namespace TIA6502tsCore {
|
||||
|
||||
class Ball
|
||||
{
|
||||
public:
|
||||
|
||||
Ball(uInt32 collisionMask);
|
||||
|
||||
public:
|
||||
|
||||
void reset();
|
||||
|
||||
void enabl(uInt8 value);
|
||||
|
||||
void hmbl(uInt8 value);
|
||||
|
||||
void resbl(bool hblank);
|
||||
|
||||
void ctrlpf(uInt8 value);
|
||||
|
||||
void vdelbl(uInt8 value);
|
||||
|
||||
void setColor(uInt8 color);
|
||||
|
||||
void startMovement();
|
||||
|
||||
bool movementTick(uInt32 clock, bool apply);
|
||||
|
||||
void render();
|
||||
|
||||
void tick();
|
||||
|
||||
uInt8 getPixel(uInt8 colorIn) const;
|
||||
|
||||
void shuffleStatus();
|
||||
|
||||
public:
|
||||
|
||||
uInt32 collision;
|
||||
|
||||
private:
|
||||
|
||||
void updateEnabled();
|
||||
|
||||
private:
|
||||
|
||||
uInt32 myCollisionMask;
|
||||
|
||||
uInt8 myColor;
|
||||
|
||||
bool myEnabledOld;
|
||||
bool myEnabledNew;
|
||||
bool myEnabled;
|
||||
bool myIsDelaying;
|
||||
|
||||
uInt8 myHmmClocks;
|
||||
uInt8 myCounter;
|
||||
bool myIsMoving;
|
||||
uInt8 myWidth;
|
||||
|
||||
bool myIsRendering;
|
||||
Int8 myRenderCounter;
|
||||
|
||||
private:
|
||||
|
||||
Ball() = delete;
|
||||
Ball(const Ball&) = delete;
|
||||
Ball(Ball&&) = delete;
|
||||
Ball& operator=(const Ball&) = delete;
|
||||
Ball& operator=(Ball&&);
|
||||
};
|
||||
|
||||
} // namespace TIA6502tsCore
|
||||
|
||||
#endif // TIA_6502TS_CORE_BALL
|
|
@ -47,6 +47,7 @@ void Missile::reset()
|
|||
myIsRendering = false;
|
||||
myRenderCounter = 0;
|
||||
myColor = 0;
|
||||
collision = myCollisionMask;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -48,6 +48,7 @@ void Player::reset()
|
|||
myPattern = 0;
|
||||
myIsReflected = 0;
|
||||
myIsDelaying = false;
|
||||
collision = myCollisionMask;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -58,7 +58,8 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
|
|||
myMissile0(CollisionMask::missile0),
|
||||
myMissile1(CollisionMask::missile1),
|
||||
myPlayer0(CollisionMask::player0),
|
||||
myPlayer1(CollisionMask::player1)
|
||||
myPlayer1(CollisionMask::player1),
|
||||
myBall(CollisionMask::ball)
|
||||
{
|
||||
myFrameManager.setHandlers(
|
||||
[this] () {
|
||||
|
@ -98,6 +99,7 @@ void TIA::reset()
|
|||
myMissile1.reset();
|
||||
myPlayer0.reset();
|
||||
myPlayer1.reset();
|
||||
myBall.reset();
|
||||
|
||||
mySound.reset();
|
||||
myDelayQueue.reset();
|
||||
|
@ -217,11 +219,14 @@ bool TIA::poke(uInt16 address, uInt8 value)
|
|||
myLinesSinceChange = 0;
|
||||
myPriority = (value & 0x04) ? Priority::inverted : Priority::normal;
|
||||
myPlayfield.ctrlpf(value);
|
||||
myBall.ctrlpf(value);
|
||||
break;
|
||||
|
||||
case COLUPF:
|
||||
myLinesSinceChange = 0;
|
||||
myPlayfield.setColor(value & 0xFE);
|
||||
value &= 0xFE;
|
||||
myPlayfield.setColor(value);
|
||||
myBall.setColor(value);
|
||||
break;
|
||||
|
||||
case PF0:
|
||||
|
@ -286,8 +291,10 @@ bool TIA::poke(uInt16 address, uInt8 value)
|
|||
break;
|
||||
|
||||
case GRP1:
|
||||
myLinesSinceChange = 0;
|
||||
myDelayQueue.push(GRP1, value, Delay::grp);
|
||||
myDelayQueue.push(DummyRegisters::shuffleP0, 0, Delay::shufflePlayer);
|
||||
myBall.shuffleStatus();
|
||||
break;
|
||||
|
||||
case RESP0:
|
||||
|
@ -327,6 +334,25 @@ bool TIA::poke(uInt16 address, uInt8 value)
|
|||
case HMP1:
|
||||
myDelayQueue.push(HMP1, value, Delay::hmp);
|
||||
break;
|
||||
|
||||
case ENABL:
|
||||
myLinesSinceChange = 0;
|
||||
myBall.enabl(value);
|
||||
break;
|
||||
|
||||
case RESBL:
|
||||
myLinesSinceChange = 0;
|
||||
myBall.resbl(myHstate == HState::blank);
|
||||
break;
|
||||
|
||||
case VDELBL:
|
||||
myLinesSinceChange = 0;
|
||||
myBall.vdelbl(value);
|
||||
break;
|
||||
|
||||
case HMBL:
|
||||
myDelayQueue.push(HMBL, value, Delay::hmbl);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -556,6 +582,7 @@ void TIA::tickMovement()
|
|||
m = myMissile1.movementTick(myMovementClock, apply) || m;
|
||||
m = myPlayer0.movementTick(myMovementClock, apply) || m;
|
||||
m = myPlayer1.movementTick(myMovementClock, apply) || m;
|
||||
m = myBall.movementTick(myMovementClock, apply) || m;
|
||||
|
||||
myMovementInProgress = m;
|
||||
myCollisionUpdateRequired = m;
|
||||
|
@ -605,7 +632,7 @@ void TIA::renderSprites()
|
|||
myPlayer1.render();
|
||||
myMissile0.render();
|
||||
myMissile1.render();
|
||||
|
||||
myBall.render();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -615,6 +642,7 @@ void TIA::tickSprites()
|
|||
myMissile1.tick();
|
||||
myPlayer0.tick();
|
||||
myPlayer1.tick();
|
||||
myBall.tick();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -644,6 +672,7 @@ void TIA::renderPixel(uInt32 x, uInt32 y, bool lineNotCached)
|
|||
|
||||
if (myPriority == Priority::normal) {
|
||||
color = myPlayfield.getPixel(color);
|
||||
color = myBall.getPixel(color);
|
||||
color = myMissile1.getPixel(color);
|
||||
color = myPlayer1.getPixel(color);
|
||||
color = myMissile0.getPixel(color);
|
||||
|
@ -654,6 +683,7 @@ void TIA::renderPixel(uInt32 x, uInt32 y, bool lineNotCached)
|
|||
color = myMissile0.getPixel(color);
|
||||
color = myPlayer0.getPixel(color);
|
||||
color = myPlayfield.getPixel(color);
|
||||
color = myBall.getPixel(color);
|
||||
}
|
||||
|
||||
myCurrentFrameBuffer.get()[y * 160 + x] = myFrameManager.vblank() ? 0 : color;
|
||||
|
@ -690,6 +720,7 @@ void TIA::delayedWrite(uInt8 address, uInt8 value)
|
|||
myMissile1.startMovement();
|
||||
myPlayer0.startMovement();
|
||||
myPlayer1.startMovement();
|
||||
myBall.startMovement();
|
||||
break;
|
||||
|
||||
case PF0:
|
||||
|
@ -723,6 +754,7 @@ void TIA::delayedWrite(uInt8 address, uInt8 value)
|
|||
myMissile1.hmm(0);
|
||||
myPlayer0.hmp(0);
|
||||
myPlayer1.hmp(0);
|
||||
myBall.hmbl(0);
|
||||
break;
|
||||
|
||||
case GRP0:
|
||||
|
@ -754,6 +786,11 @@ void TIA::delayedWrite(uInt8 address, uInt8 value)
|
|||
myLinesSinceChange = 0;
|
||||
myPlayer1.hmp(value);
|
||||
break;
|
||||
|
||||
case HMBL:
|
||||
myLinesSinceChange = 0;
|
||||
myBall.hmbl(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "Playfield.hxx"
|
||||
#include "Missile.hxx"
|
||||
#include "Player.hxx"
|
||||
#include "Ball.hxx"
|
||||
|
||||
class Console;
|
||||
|
||||
|
@ -192,6 +193,7 @@ class TIA : public AbstractTIA
|
|||
Missile myMissile1;
|
||||
Player myPlayer0;
|
||||
Player myPlayer1;
|
||||
Ball myBall;
|
||||
|
||||
private:
|
||||
TIA() = delete;
|
||||
|
|
|
@ -8,8 +8,8 @@ MODULE_OBJS := \
|
|||
src/emucore/tia/core_6502ts/Playfield.o \
|
||||
src/emucore/tia/core_6502ts/DrawCounterDecodes.o \
|
||||
src/emucore/tia/core_6502ts/Missile.o \
|
||||
src/emucore/tia/core_6502ts/Player.o
|
||||
|
||||
src/emucore/tia/core_6502ts/Player.o \
|
||||
src/emucore/tia/core_6502ts/Ball.o
|
||||
|
||||
MODULE_DIRS += \
|
||||
src/emucore/tia/core_6502ts
|
||||
|
|
Loading…
Reference in New Issue