mirror of https://github.com/stella-emu/stella.git
Fix timing glitch, port missiles.
This commit is contained in:
parent
c8dc5e2db9
commit
baecc4e3a1
|
@ -0,0 +1,91 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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$
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
// namespace TIA6502tsCore
|
||||||
|
|
||||||
|
#include "DrawCounterDecodes.hxx"
|
||||||
|
|
||||||
|
namespace TIA6502tsCore {
|
||||||
|
|
||||||
|
const uInt8* const* DrawCounterDecodes::playerDecodes() const {
|
||||||
|
return myPlayerDecodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uInt8* const* DrawCounterDecodes::missileDecodes() const {
|
||||||
|
return myMissileDecodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawCounterDecodes DrawCounterDecodes::myInstance;
|
||||||
|
|
||||||
|
DrawCounterDecodes& DrawCounterDecodes::DrawCounterDecodes::get()
|
||||||
|
{
|
||||||
|
return myInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawCounterDecodes::DrawCounterDecodes()
|
||||||
|
{
|
||||||
|
myDecodes0 = new uInt8[160];
|
||||||
|
myDecodes1 = new uInt8[160];
|
||||||
|
myDecodes2 = new uInt8[160];
|
||||||
|
myDecodes3 = new uInt8[160];
|
||||||
|
myDecodes4 = new uInt8[160];
|
||||||
|
myDecodes6 = new uInt8[160];
|
||||||
|
myDecodesWide = new uInt8[160];
|
||||||
|
|
||||||
|
for (uInt8 *decodes : {myDecodes0, myDecodes1, myDecodes2, myDecodes3, myDecodes4, myDecodes6}) {
|
||||||
|
memset(decodes, 0, 160);
|
||||||
|
decodes[156] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(myDecodesWide, 0, 160);
|
||||||
|
myDecodesWide[157] = 1;
|
||||||
|
|
||||||
|
myDecodes1[12] = 1;
|
||||||
|
myDecodes2[28] = 1;
|
||||||
|
myDecodes3[12] = myDecodes3[28] = 1;
|
||||||
|
myDecodes4[60] = 1;
|
||||||
|
myDecodes6[28] = myDecodes6[60] = 1;
|
||||||
|
|
||||||
|
myPlayerDecodes[0] = myDecodes0;
|
||||||
|
myPlayerDecodes[1] = myDecodes1;
|
||||||
|
myPlayerDecodes[2] = myDecodes2;
|
||||||
|
myPlayerDecodes[3] = myDecodes3;
|
||||||
|
myPlayerDecodes[4] = myDecodes4;
|
||||||
|
myPlayerDecodes[5] = myDecodesWide;
|
||||||
|
myPlayerDecodes[6] = myDecodes6;
|
||||||
|
myPlayerDecodes[7] = myDecodesWide;
|
||||||
|
|
||||||
|
myMissileDecodes[0] = myDecodes0;
|
||||||
|
myMissileDecodes[1] = myDecodes1;
|
||||||
|
myMissileDecodes[2] = myDecodes2;
|
||||||
|
myMissileDecodes[3] = myDecodes3;
|
||||||
|
myMissileDecodes[4] = myDecodes4;
|
||||||
|
myMissileDecodes[5] = myDecodes0;
|
||||||
|
myMissileDecodes[6] = myDecodes6;
|
||||||
|
myMissileDecodes[7] = myDecodes0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawCounterDecodes::~DrawCounterDecodes()
|
||||||
|
{
|
||||||
|
for (uInt8 *decodes : {myDecodes0, myDecodes1, myDecodes2, myDecodes3, myDecodes4, myDecodes6, myDecodesWide}) {
|
||||||
|
delete[] decodes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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_DRAW_COUNTER_DECODES
|
||||||
|
#define TIA_6502TS_CORE_DRAW_COUNTER_DECODES
|
||||||
|
|
||||||
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
namespace TIA6502tsCore {
|
||||||
|
|
||||||
|
class DrawCounterDecodes {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
const uInt8* const* playerDecodes() const;
|
||||||
|
|
||||||
|
const uInt8* const* missileDecodes() const;
|
||||||
|
|
||||||
|
static DrawCounterDecodes& get();
|
||||||
|
|
||||||
|
~DrawCounterDecodes();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
DrawCounterDecodes();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uInt8 *myPlayerDecodes[8];
|
||||||
|
|
||||||
|
uInt8 *myMissileDecodes[8];
|
||||||
|
|
||||||
|
uInt8 *myDecodes0, *myDecodes1, *myDecodes2, *myDecodes3, *myDecodes4, *myDecodes6, *myDecodesWide;
|
||||||
|
|
||||||
|
static DrawCounterDecodes myInstance;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
DrawCounterDecodes(const DrawCounterDecodes&) = delete;
|
||||||
|
DrawCounterDecodes(DrawCounterDecodes&&) = delete;
|
||||||
|
DrawCounterDecodes& operator=(const DrawCounterDecodes&) = delete;
|
||||||
|
DrawCounterDecodes& operator=(DrawCounterDecodes&&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace TIA6502tsCore
|
||||||
|
|
||||||
|
#endif // TIA_6502TS_CORE_DRAW_COUNTER_DECODES
|
|
@ -0,0 +1,121 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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 "Missile.hxx"
|
||||||
|
#include "DrawCounterDecodes.hxx"
|
||||||
|
|
||||||
|
enum Count {
|
||||||
|
renderCounterOffset = -4
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace TIA6502tsCore {
|
||||||
|
|
||||||
|
uInt8 Missile::myWidths[4] = {1, 2, 4, 8};
|
||||||
|
|
||||||
|
Missile::Missile(uInt32 collisionMask)
|
||||||
|
: myCollisionMask(collisionMask)
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Missile::reset()
|
||||||
|
{
|
||||||
|
myDecodes = DrawCounterDecodes::get().missileDecodes()[0];
|
||||||
|
myEnabled = false;
|
||||||
|
myEnam = false;
|
||||||
|
myResmp = 0;
|
||||||
|
myHmmClocks = 0;
|
||||||
|
myCounter = 0;
|
||||||
|
myIsMoving = false;
|
||||||
|
myWidth = 1;
|
||||||
|
myIsRendering = false;
|
||||||
|
myRenderCounter = 0;
|
||||||
|
myColor = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Missile::enam(uInt8 value)
|
||||||
|
{
|
||||||
|
myEnam = (value & 0x02) > 0;
|
||||||
|
myEnabled = myEnam && (myResmp == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Missile::hmm(uInt8 value)
|
||||||
|
{
|
||||||
|
myHmmClocks = (value >> 4) ^ 0x08;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Missile::resm(bool hblank)
|
||||||
|
{
|
||||||
|
myCounter = hblank ? 159 : 157;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Missile::nusiz(uInt8 value)
|
||||||
|
{
|
||||||
|
myWidth = myWidths[(value & 0x30) >> 4];
|
||||||
|
myDecodes = DrawCounterDecodes::get().missileDecodes()[value & 0x07];
|
||||||
|
|
||||||
|
if (myIsRendering && myRenderCounter >= myWidth)
|
||||||
|
myIsRendering = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Missile::startMovement()
|
||||||
|
{
|
||||||
|
myIsMoving = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Missile::movementTick(uInt32 clock, bool apply)
|
||||||
|
{
|
||||||
|
if (clock == myHmmClocks) myIsMoving = false;
|
||||||
|
|
||||||
|
if (myIsMoving && apply) {
|
||||||
|
render();
|
||||||
|
tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
return myIsMoving;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Missile::render()
|
||||||
|
{
|
||||||
|
collision = (myIsRendering && myRenderCounter >= 0 && myEnabled) ? 0 : myCollisionMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Missile::tick()
|
||||||
|
{
|
||||||
|
if (myDecodes[myCounter]) {
|
||||||
|
myIsRendering = true;
|
||||||
|
myRenderCounter = Count::renderCounterOffset;
|
||||||
|
} else if (myIsRendering && ++myRenderCounter >= myWidth) {
|
||||||
|
myIsRendering = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++myCounter >= 160) myCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Missile::setColor(uInt8 color)
|
||||||
|
{
|
||||||
|
myColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
uInt8 Missile::getPixel(uInt8 colorIn) const
|
||||||
|
{
|
||||||
|
return collision ? colorIn : myColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace TIA6502tsCore
|
|
@ -0,0 +1,94 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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_MISSILE
|
||||||
|
#define TIA_6502TS_CORE_MISSILE
|
||||||
|
|
||||||
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
namespace TIA6502tsCore {
|
||||||
|
|
||||||
|
class Missile {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Missile(uInt32 collisionMask);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
void enam(uInt8 value);
|
||||||
|
|
||||||
|
void hmm(uInt8 value);
|
||||||
|
|
||||||
|
void resm(bool hblank);
|
||||||
|
|
||||||
|
// TODO: resmp
|
||||||
|
|
||||||
|
void nusiz(uInt8 value);
|
||||||
|
|
||||||
|
void startMovement();
|
||||||
|
|
||||||
|
bool movementTick(uInt32 clock, bool apply);
|
||||||
|
|
||||||
|
void render();
|
||||||
|
|
||||||
|
void tick();
|
||||||
|
|
||||||
|
void setColor(uInt8 color);
|
||||||
|
|
||||||
|
uInt8 getPixel(uInt8 colorIn) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
uInt32 collision;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uInt32 myCollisionMask;
|
||||||
|
|
||||||
|
bool myEnabled;
|
||||||
|
bool myEnam;
|
||||||
|
uInt8 myResmp;
|
||||||
|
|
||||||
|
uInt32 myHmmClocks;
|
||||||
|
uInt8 myCounter;
|
||||||
|
bool myIsMoving;
|
||||||
|
uInt8 myWidth;
|
||||||
|
|
||||||
|
bool myIsRendering;
|
||||||
|
Int8 myRenderCounter;
|
||||||
|
|
||||||
|
const uInt8 *myDecodes;
|
||||||
|
static uInt8 myWidths[4];
|
||||||
|
|
||||||
|
uInt8 myColor;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Missile(const Missile&) = delete;
|
||||||
|
Missile(Missile&&) = delete;
|
||||||
|
Missile& operator=(const Missile&) = delete;
|
||||||
|
Missile& operator=(Missile&&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace TIA6502tsCore
|
||||||
|
|
||||||
|
#endif // TIA_6502TS_CORE_MISSILE
|
|
@ -48,11 +48,17 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
|
||||||
mySound(sound),
|
mySound(sound),
|
||||||
mySettings(settings),
|
mySettings(settings),
|
||||||
myDelayQueue(10, 20),
|
myDelayQueue(10, 20),
|
||||||
myPlayfield(CollisionMask::playfield)
|
myPlayfield(CollisionMask::playfield),
|
||||||
|
myMissile0(CollisionMask::missile0),
|
||||||
|
myMissile1(CollisionMask::missile1)
|
||||||
{
|
{
|
||||||
myFrameManager.setHandlers(
|
myFrameManager.setHandlers(
|
||||||
[this] () {onFrameStart();},
|
[this] () {
|
||||||
[this] () {onFrameComplete();}
|
myCurrentFrameBuffer.swap(myPreviousFrameBuffer);
|
||||||
|
},
|
||||||
|
[this] () {
|
||||||
|
mySystem->m6502().stop();
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
myCurrentFrameBuffer = make_ptr<uInt8[]>(160 * 320);
|
myCurrentFrameBuffer = make_ptr<uInt8[]>(160 * 320);
|
||||||
|
@ -74,10 +80,13 @@ void TIA::reset()
|
||||||
myCollisionMask = 0;
|
myCollisionMask = 0;
|
||||||
myLinesSinceChange = 0;
|
myLinesSinceChange = 0;
|
||||||
myCollisionUpdateRequired = false;
|
myCollisionUpdateRequired = false;
|
||||||
|
myColorBk = 0;
|
||||||
|
|
||||||
myLastCycle = 0;
|
myLastCycle = 0;
|
||||||
|
|
||||||
myPlayfield.reset();
|
myPlayfield.reset();
|
||||||
|
myMissile0.reset();
|
||||||
|
myMissile1.reset();
|
||||||
|
|
||||||
mySound.reset();
|
mySound.reset();
|
||||||
myDelayQueue.reset();
|
myDelayQueue.reset();
|
||||||
|
@ -139,7 +148,7 @@ bool TIA::poke(uInt16 address, uInt8 value)
|
||||||
|
|
||||||
switch (address) {
|
switch (address) {
|
||||||
case WSYNC:
|
case WSYNC:
|
||||||
mySystem->incrementCycles((227 - myHctr) / 3);
|
mySystem->incrementCycles((227 - myHctr) / 3 + 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VSYNC:
|
case VSYNC:
|
||||||
|
@ -157,17 +166,32 @@ bool TIA::poke(uInt16 address, uInt8 value)
|
||||||
case AUDC0:
|
case AUDC0:
|
||||||
case AUDC1:
|
case AUDC1:
|
||||||
mySound.set(address, value, mySystem->cycles());
|
mySound.set(address, value, mySystem->cycles());
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HMOVE:
|
||||||
|
myDelayQueue.push(HMOVE, value, Delay::hmove);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COLUBK:
|
||||||
|
myColorBk = value & 0xFE;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COLUP0:
|
case COLUP0:
|
||||||
myLinesSinceChange = 0;
|
myLinesSinceChange = 0;
|
||||||
myPlayfield.setColorP0(value & 0xFE);
|
value &= 0xFE;
|
||||||
|
myPlayfield.setColorP0(value);
|
||||||
|
myMissile0.setColor(value);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COLUP1:
|
case COLUP1:
|
||||||
myLinesSinceChange = 0;
|
myLinesSinceChange = 0;
|
||||||
myPlayfield.setColorP1(value & 0xFE);
|
value &= 0xFE;
|
||||||
|
myPlayfield.setColorP1(value);
|
||||||
|
myMissile1.setColor(value);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -197,6 +221,57 @@ bool TIA::poke(uInt16 address, uInt8 value)
|
||||||
case PF2:
|
case PF2:
|
||||||
myDelayQueue.push(PF2, value, Delay::pf);
|
myDelayQueue.push(PF2, value, Delay::pf);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENAM0:
|
||||||
|
myLinesSinceChange = 0;
|
||||||
|
myMissile0.enam(value);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENAM1:
|
||||||
|
myLinesSinceChange = 0;
|
||||||
|
myMissile1.enam(value);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RESM0:
|
||||||
|
myLinesSinceChange = 0;
|
||||||
|
myMissile0.resm(myHstate == HState::blank);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RESM1:
|
||||||
|
myLinesSinceChange = 0;
|
||||||
|
myMissile1.resm(myHstate == HState::blank);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NUSIZ0:
|
||||||
|
myLinesSinceChange = 0;
|
||||||
|
myMissile0.nusiz(value);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NUSIZ1:
|
||||||
|
myLinesSinceChange = 0;
|
||||||
|
myMissile1.nusiz(value);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HMM0:
|
||||||
|
myDelayQueue.push(HMM0, value, Delay::hmm);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HMM1:
|
||||||
|
myDelayQueue.push(HMM1, value, Delay::hmm);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HMCLR:
|
||||||
|
myDelayQueue.push(HMCLR, value, Delay::hmclr);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,7 +454,7 @@ void TIA::cycle(uInt32 colorClocks)
|
||||||
|
|
||||||
void TIA::tickMovement()
|
void TIA::tickMovement()
|
||||||
{
|
{
|
||||||
if (myMovementInProgress) return;
|
if (!myMovementInProgress) return;
|
||||||
|
|
||||||
if ((myHctr & 0x03) == 0) {
|
if ((myHctr & 0x03) == 0) {
|
||||||
myLinesSinceChange = 0;
|
myLinesSinceChange = 0;
|
||||||
|
@ -388,7 +463,8 @@ void TIA::tickMovement()
|
||||||
|
|
||||||
bool m = false;
|
bool m = false;
|
||||||
|
|
||||||
// TODO: propagate movement to sprites
|
m = myMissile0.movementTick(myMovementClock, apply) || m;
|
||||||
|
m = myMissile1.movementTick(myMovementClock, apply) || m;
|
||||||
|
|
||||||
myMovementInProgress = m;
|
myMovementInProgress = m;
|
||||||
myCollisionUpdateRequired = m;
|
myCollisionUpdateRequired = m;
|
||||||
|
@ -419,15 +495,28 @@ void TIA::tickHframe()
|
||||||
|
|
||||||
myPlayfield.tick(x);
|
myPlayfield.tick(x);
|
||||||
|
|
||||||
// TODO: render sprites
|
if (lineNotCached)
|
||||||
|
renderSprites(x);
|
||||||
|
|
||||||
// TODO: tick sprites
|
tickSprites();
|
||||||
|
|
||||||
if (myFrameManager.isRendering()) renderPixel(x, y, lineNotCached);
|
if (myFrameManager.isRendering()) renderPixel(x, y, lineNotCached);
|
||||||
|
|
||||||
if (++myHctr >= 228) nextLine();
|
if (++myHctr >= 228) nextLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TIA::renderSprites(uInt32 x)
|
||||||
|
{
|
||||||
|
myMissile0.render();
|
||||||
|
myMissile1.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIA::tickSprites()
|
||||||
|
{
|
||||||
|
myMissile0.tick();
|
||||||
|
myMissile1.tick();
|
||||||
|
}
|
||||||
|
|
||||||
void TIA::nextLine()
|
void TIA::nextLine()
|
||||||
{
|
{
|
||||||
myHctr = 0;
|
myHctr = 0;
|
||||||
|
@ -448,11 +537,15 @@ void TIA::updateCollision()
|
||||||
void TIA::renderPixel(uInt32 x, uInt32 y, bool lineNotCached)
|
void TIA::renderPixel(uInt32 x, uInt32 y, bool lineNotCached)
|
||||||
{
|
{
|
||||||
if (lineNotCached) {
|
if (lineNotCached) {
|
||||||
uInt8 color = 0;
|
uInt8 color = myColorBk;
|
||||||
|
|
||||||
if (myPriority == Priority::normal) {
|
if (myPriority == Priority::normal) {
|
||||||
color = myPlayfield.getPixel(color);
|
color = myPlayfield.getPixel(color);
|
||||||
|
color = myMissile1.getPixel(color);
|
||||||
|
color = myMissile0.getPixel(color);
|
||||||
} else {
|
} else {
|
||||||
|
color = myMissile1.getPixel(color);
|
||||||
|
color = myMissile0.getPixel(color);
|
||||||
color = myPlayfield.getPixel(color);
|
color = myPlayfield.getPixel(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,19 +555,32 @@ void TIA::renderPixel(uInt32 x, uInt32 y, bool lineNotCached)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TIA::onFrameComplete()
|
void TIA::clearHmoveComb()
|
||||||
{
|
{
|
||||||
mySystem->m6502().stop();
|
if (myFrameManager.isRendering() && myHstate == HState::blank)
|
||||||
}
|
memset(myCurrentFrameBuffer.get() + myFrameManager.currentLine() * 160, 0, 8);
|
||||||
|
|
||||||
void TIA::onFrameStart()
|
|
||||||
{
|
|
||||||
myCurrentFrameBuffer.swap(myPreviousFrameBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TIA::delayedWrite(uInt8 address, uInt8 value)
|
void TIA::delayedWrite(uInt8 address, uInt8 value)
|
||||||
{
|
{
|
||||||
switch (address) {
|
switch (address) {
|
||||||
|
case HMOVE:
|
||||||
|
myLinesSinceChange = 0;
|
||||||
|
|
||||||
|
myMovementClock = 0;
|
||||||
|
myMovementInProgress = true;
|
||||||
|
|
||||||
|
if (!myExtendedHblank) {
|
||||||
|
myHblankCtr -= 8;
|
||||||
|
clearHmoveComb();
|
||||||
|
myExtendedHblank = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
myMissile0.startMovement();
|
||||||
|
myMissile1.startMovement();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case PF0:
|
case PF0:
|
||||||
myLinesSinceChange = 0;
|
myLinesSinceChange = 0;
|
||||||
myPlayfield.pf0(value);
|
myPlayfield.pf0(value);
|
||||||
|
@ -491,6 +597,25 @@ void TIA::delayedWrite(uInt8 address, uInt8 value)
|
||||||
myLinesSinceChange = 0;
|
myLinesSinceChange = 0;
|
||||||
myPlayfield.pf2(value);
|
myPlayfield.pf2(value);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HMM0:
|
||||||
|
myLinesSinceChange = 0;
|
||||||
|
myMissile0.hmm(value);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HMM1:
|
||||||
|
myLinesSinceChange = 0;
|
||||||
|
myMissile1.hmm(value);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HMCLR:
|
||||||
|
myLinesSinceChange = 0;
|
||||||
|
myMissile0.hmm(0);
|
||||||
|
myMissile1.hmm(0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "DelayQueue.hxx"
|
#include "DelayQueue.hxx"
|
||||||
#include "FrameManager.hxx"
|
#include "FrameManager.hxx"
|
||||||
#include "Playfield.hxx"
|
#include "Playfield.hxx"
|
||||||
|
#include "Missile.hxx"
|
||||||
|
|
||||||
class Console;
|
class Console;
|
||||||
|
|
||||||
|
@ -137,8 +138,14 @@ class TIA : public AbstractTIA {
|
||||||
|
|
||||||
void updateCollision();
|
void updateCollision();
|
||||||
|
|
||||||
|
void renderSprites(uInt32 x);
|
||||||
|
|
||||||
|
void tickSprites();
|
||||||
|
|
||||||
void renderPixel(uInt32 x, uInt32 y, bool lineNotCached);
|
void renderPixel(uInt32 x, uInt32 y, bool lineNotCached);
|
||||||
|
|
||||||
|
void clearHmoveComb();
|
||||||
|
|
||||||
void nextLine();
|
void nextLine();
|
||||||
|
|
||||||
void onFrameComplete();
|
void onFrameComplete();
|
||||||
|
@ -159,8 +166,8 @@ class TIA : public AbstractTIA {
|
||||||
HState myHstate;
|
HState myHstate;
|
||||||
bool myIsFreshLine;
|
bool myIsFreshLine;
|
||||||
|
|
||||||
uInt32 myHblankCtr;
|
Int32 myHblankCtr;
|
||||||
uInt32 myHctr;
|
Int32 myHctr;
|
||||||
|
|
||||||
bool myCollisionUpdateRequired;
|
bool myCollisionUpdateRequired;
|
||||||
uInt32 myCollisionMask;
|
uInt32 myCollisionMask;
|
||||||
|
@ -175,10 +182,14 @@ class TIA : public AbstractTIA {
|
||||||
|
|
||||||
uInt32 myLastCycle;
|
uInt32 myLastCycle;
|
||||||
|
|
||||||
|
uInt8 myColorBk;
|
||||||
|
|
||||||
BytePtr myCurrentFrameBuffer;
|
BytePtr myCurrentFrameBuffer;
|
||||||
BytePtr myPreviousFrameBuffer;
|
BytePtr myPreviousFrameBuffer;
|
||||||
|
|
||||||
Playfield myPlayfield;
|
Playfield myPlayfield;
|
||||||
|
Missile myMissile0;
|
||||||
|
Missile myMissile1;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,9 @@ MODULE_OBJS := \
|
||||||
src/emucore/tia/core_6502ts/DelayQueueMember.o \
|
src/emucore/tia/core_6502ts/DelayQueueMember.o \
|
||||||
src/emucore/tia/core_6502ts/DelayQueue.o \
|
src/emucore/tia/core_6502ts/DelayQueue.o \
|
||||||
src/emucore/tia/core_6502ts/FrameManager.o \
|
src/emucore/tia/core_6502ts/FrameManager.o \
|
||||||
src/emucore/tia/core_6502ts/Playfield.o
|
src/emucore/tia/core_6502ts/Playfield.o \
|
||||||
|
src/emucore/tia/core_6502ts/DrawCounterDecodes.o \
|
||||||
|
src/emucore/tia/core_6502ts/Missile.o
|
||||||
|
|
||||||
|
|
||||||
MODULE_DIRS += \
|
MODULE_DIRS += \
|
||||||
|
|
Loading…
Reference in New Issue