mirror of https://github.com/stella-emu/stella.git
Port main loop.
This commit is contained in:
parent
b6a2e266aa
commit
70dc29f077
|
@ -19,10 +19,10 @@
|
|||
|
||||
#include "TIA.hxx"
|
||||
#include "TIATypes.hxx"
|
||||
#include "M6502.hxx"
|
||||
|
||||
namespace TIA6502tsCore {
|
||||
|
||||
// TODO: stub
|
||||
TIA::TIA(Console& console, Sound& sound, Settings& settings)
|
||||
: myConsole(console),
|
||||
mySound(sound),
|
||||
|
@ -33,22 +33,60 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
|
|||
[this] () {onFrameComplete();}
|
||||
);
|
||||
|
||||
myCurrentFrameBuffer = make_ptr<uInt8[]>(160 * 320);
|
||||
myPreviousFrameBuffer = make_ptr<uInt8[]>(160 * 320);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
// TODO: stub
|
||||
void TIA::reset()
|
||||
{
|
||||
myHblankCtr = 0;
|
||||
myHctr = 0;
|
||||
myMovementInProgress = false;
|
||||
myExtendedHblank = false;
|
||||
myMovementClock = 0;
|
||||
myPriority = Priority::normal;
|
||||
myHstate = HState::blank;
|
||||
myIsFreshLine = true;
|
||||
myCollisionMask = 0;
|
||||
myLinesSinceChange = 0;
|
||||
myCollisionUpdateRequired = false;
|
||||
|
||||
myLastCycle = 0;
|
||||
|
||||
mySound.reset();
|
||||
myDelayQueue.reset();
|
||||
myFrameManager.reset();
|
||||
}
|
||||
|
||||
// TODO: stub
|
||||
void TIA::systemCyclesReset()
|
||||
{}
|
||||
{
|
||||
uInt32 cycles = mySystem->cycles();
|
||||
|
||||
myLastCycle -= cycles;
|
||||
mySound.adjustCycleCounter(-cycles);
|
||||
}
|
||||
|
||||
// TODO: stub
|
||||
void TIA::install(System& system)
|
||||
{}
|
||||
{
|
||||
installDelegate(system, *this);
|
||||
}
|
||||
|
||||
void TIA::installDelegate(System& system, Device& device)
|
||||
{
|
||||
// Remember which system I'm installed in
|
||||
mySystem = &system;
|
||||
|
||||
// All accesses are to the given device
|
||||
System::PageAccess access(&device, System::PA_READWRITE);
|
||||
|
||||
// We're installing in a 2600 system
|
||||
for(uInt32 i = 0; i < 8192; i += (1 << System::PAGE_SHIFT))
|
||||
if((i & 0x1080) == 0x0000)
|
||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
||||
}
|
||||
|
||||
|
||||
// TODO: stub
|
||||
bool TIA::save(Serializer& out) const
|
||||
|
@ -74,10 +112,6 @@ bool TIA::poke(uInt16 address, uInt8 value)
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO: stub
|
||||
void TIA::installDelegate(System& system, Device& device)
|
||||
{}
|
||||
|
||||
// TODO: stub
|
||||
void TIA::frameReset()
|
||||
{}
|
||||
|
@ -98,25 +132,22 @@ bool TIA::loadDisplay(Serializer& in)
|
|||
void TIA::update()
|
||||
{}
|
||||
|
||||
// TODO: stub
|
||||
uInt8* TIA::currentFrameBuffer() const
|
||||
{
|
||||
return 0;
|
||||
return myCurrentFrameBuffer.get();
|
||||
}
|
||||
|
||||
// TODO: stub
|
||||
uInt8* TIA::previousFrameBuffer() const
|
||||
{
|
||||
return 0;
|
||||
return myPreviousFrameBuffer.get();
|
||||
}
|
||||
|
||||
// TODO: stub
|
||||
uInt32 TIA::height() const
|
||||
{
|
||||
return 0;
|
||||
return myFrameManager.height();
|
||||
}
|
||||
|
||||
// TODO: stub
|
||||
uInt32 TIA::ystart() const
|
||||
{
|
||||
return 0;
|
||||
|
@ -138,10 +169,9 @@ void TIA::enableAutoFrame(bool enabled)
|
|||
void TIA::enableColorLoss(bool enabled)
|
||||
{}
|
||||
|
||||
// TODO: stub
|
||||
bool TIA::isPAL() const
|
||||
{
|
||||
return false;
|
||||
return myFrameManager.tvMode() == FrameManager::TvMode::pal;
|
||||
}
|
||||
|
||||
// TODO: stub
|
||||
|
@ -159,7 +189,7 @@ uInt32 TIA::scanlines() const
|
|||
// TODO: stub
|
||||
bool TIA::partialFrame() const
|
||||
{
|
||||
return false;
|
||||
return myFrameManager.isRendering();
|
||||
}
|
||||
|
||||
// TODO: stub
|
||||
|
@ -226,9 +256,109 @@ bool TIA::toggleJitter(uInt8 mode)
|
|||
void TIA::setJitterRecoveryFactor(Int32 f)
|
||||
{}
|
||||
|
||||
// TODO: stub
|
||||
void TIA::cycle(uInt32 colorClocks)
|
||||
{
|
||||
for (uInt32 i = 0; i < colorClocks; i++) {
|
||||
myDelayQueue.execute(
|
||||
[this] (uInt8 address, uInt8 value) {delayedWrite(address, value);}
|
||||
);
|
||||
|
||||
myCollisionUpdateRequired = false;
|
||||
|
||||
tickMovement();
|
||||
|
||||
if (myHstate == HState::blank)
|
||||
tickHblank();
|
||||
else
|
||||
tickHframe();
|
||||
|
||||
if (myCollisionUpdateRequired) updateCollision();
|
||||
}
|
||||
}
|
||||
|
||||
void TIA::tickMovement()
|
||||
{
|
||||
if (myMovementInProgress) return;
|
||||
|
||||
if ((myHctr & 0x03) == 0) {
|
||||
myLinesSinceChange = 0;
|
||||
|
||||
const bool apply = myHstate == HState::blank;
|
||||
|
||||
bool m = false;
|
||||
|
||||
// TODO: propagate movement to sprites
|
||||
|
||||
myMovementInProgress = m;
|
||||
myCollisionUpdateRequired = m;
|
||||
|
||||
myMovementClock++;
|
||||
}
|
||||
}
|
||||
|
||||
void TIA::tickHblank()
|
||||
{
|
||||
if (myIsFreshLine) {
|
||||
myHblankCtr = 0;
|
||||
myIsFreshLine = false;
|
||||
}
|
||||
|
||||
if (++myHblankCtr >= 68) myHstate = HState::frame;
|
||||
}
|
||||
|
||||
void TIA::tickHframe()
|
||||
{
|
||||
const uInt32 y = myFrameManager.currentLine();
|
||||
const bool lineNotCached = myLinesSinceChange < 2 || y == 0;
|
||||
const uInt32 x = myHctr - 68;
|
||||
|
||||
myCollisionUpdateRequired = lineNotCached;
|
||||
|
||||
// TODO: playfield tick
|
||||
|
||||
// TODO: render sprites
|
||||
|
||||
// TODO: tick sprites
|
||||
|
||||
if (myFrameManager.isRendering()) renderPixel(x, y, lineNotCached);
|
||||
|
||||
if (++myHctr >= 228) nextLine();
|
||||
}
|
||||
|
||||
void TIA::nextLine()
|
||||
{
|
||||
myHctr = 0;
|
||||
myLinesSinceChange++;
|
||||
|
||||
myHstate = HState::blank;
|
||||
myIsFreshLine = true;
|
||||
myExtendedHblank = false;
|
||||
|
||||
myFrameManager.nextLine();
|
||||
}
|
||||
|
||||
void TIA::updateCollision()
|
||||
{
|
||||
// TODO: update collision mask with sprite masks
|
||||
}
|
||||
|
||||
void TIA::renderPixel(uInt32 x, uInt32 y, bool lineNotCached)
|
||||
{
|
||||
if (lineNotCached) {
|
||||
uInt8 color = 0;
|
||||
|
||||
// TODO: determine color from sprites
|
||||
|
||||
myCurrentFrameBuffer.get()[y * 160 + x] = myFrameManager.vblank() ? 0 : color;
|
||||
} else {
|
||||
myCurrentFrameBuffer.get()[y * 160 + x] = myCurrentFrameBuffer.get()[(y-1) * 160 + x];
|
||||
}
|
||||
}
|
||||
|
||||
void TIA::onFrameComplete()
|
||||
{}
|
||||
{
|
||||
mySystem->m6502().stop();
|
||||
}
|
||||
|
||||
// TODO: stub
|
||||
void TIA::delayedWrite(uInt8 address, uInt8 value)
|
||||
|
|
|
@ -118,6 +118,26 @@ class TIA : public AbstractTIA {
|
|||
|
||||
private:
|
||||
|
||||
enum HState {blank, frame};
|
||||
|
||||
enum Priority {normal, inverted};
|
||||
|
||||
private:
|
||||
|
||||
void cycle(uInt32 colorClocks);
|
||||
|
||||
void tickMovement();
|
||||
|
||||
void tickHblank();
|
||||
|
||||
void tickHframe();
|
||||
|
||||
void updateCollision();
|
||||
|
||||
void renderPixel(uInt32 x, uInt32 y, bool lineNotCached);
|
||||
|
||||
void nextLine();
|
||||
|
||||
void onFrameComplete();
|
||||
|
||||
void delayedWrite(uInt8 address, uInt8 value);
|
||||
|
@ -125,15 +145,34 @@ class TIA : public AbstractTIA {
|
|||
private:
|
||||
|
||||
Console& myConsole;
|
||||
|
||||
Sound& mySound;
|
||||
|
||||
Settings& mySettings;
|
||||
|
||||
DelayQueue myDelayQueue;
|
||||
|
||||
FrameManager myFrameManager;
|
||||
|
||||
HState myHstate;
|
||||
bool myIsFreshLine;
|
||||
|
||||
uInt32 myHblankCtr;
|
||||
uInt32 myHctr;
|
||||
|
||||
bool myCollisionUpdateRequired;
|
||||
uInt32 myCollisionMask;
|
||||
|
||||
uInt32 myMovementClock;
|
||||
bool myMovementInProgress;
|
||||
bool myExtendedHblank;
|
||||
|
||||
uInt32 myLinesSinceChange;
|
||||
|
||||
Priority myPriority;
|
||||
|
||||
uInt32 myLastCycle;
|
||||
|
||||
BytePtr myCurrentFrameBuffer;
|
||||
BytePtr myPreviousFrameBuffer;
|
||||
|
||||
private:
|
||||
|
||||
TIA() = delete;
|
||||
|
|
Loading…
Reference in New Issue