Inject FrameManager instance into TIA.

This commit is contained in:
Christian Speckner 2017-10-07 19:48:06 +02:00
parent a452d83b39
commit 47f528c4d3
6 changed files with 99 additions and 34 deletions

View File

@ -57,6 +57,7 @@
#include "Version.hxx" #include "Version.hxx"
#include "TIAConstants.hxx" #include "TIAConstants.hxx"
#include "FrameLayout.hxx" #include "FrameLayout.hxx"
#include "frame-manager/FrameManager.hxx"
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
#include "Debugger.hxx" #include "Debugger.hxx"
@ -88,8 +89,11 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
my6502 = make_unique<M6502>(myOSystem.settings()); my6502 = make_unique<M6502>(myOSystem.settings());
myRiot = make_unique<M6532>(*this, myOSystem.settings()); myRiot = make_unique<M6532>(*this, myOSystem.settings());
myTIA = make_unique<TIA>(*this, myOSystem.sound(), myOSystem.settings()); myTIA = make_unique<TIA>(*this, myOSystem.sound(), myOSystem.settings());
myFrameManager = make_unique<FrameManager>();
mySwitches = make_unique<Switches>(myEvent, myProperties); mySwitches = make_unique<Switches>(myEvent, myProperties);
myTIA->setFrameManager(myFrameManager.get());
// Construct the system and components // Construct the system and components
mySystem = make_unique<System>(osystem, *my6502, *myRiot, *myTIA, *myCart); mySystem = make_unique<System>(osystem, *my6502, *myRiot, *myTIA, *myCart);

View File

@ -35,6 +35,7 @@ class Debugger;
#include "FrameBuffer.hxx" #include "FrameBuffer.hxx"
#include "Serializable.hxx" #include "Serializable.hxx"
#include "NTSCFilter.hxx" #include "NTSCFilter.hxx"
#include "frame-manager/AbstractFrameManager.hxx"
/** /**
Contains detailed info about a console. Contains detailed info about a console.
@ -360,6 +361,9 @@ class Console : public Serializable
// Pointer to the TIA object // Pointer to the TIA object
unique_ptr<TIA> myTIA; unique_ptr<TIA> myTIA;
// The frame manager instance that is used during emulation.
unique_ptr<AbstractFrameManager> myFrameManager;
// Pointer to the Cartridge (the debugger needs it) // Pointer to the Cartridge (the debugger needs it)
unique_ptr<Cartridge> myCart; unique_ptr<Cartridge> myCart;

View File

@ -69,6 +69,7 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
: myConsole(console), : myConsole(console),
mySound(sound), mySound(sound),
mySettings(settings), mySettings(settings),
myFrameManager(nullptr),
myPlayfield(~CollisionMask::playfield & 0x7FFF), myPlayfield(~CollisionMask::playfield & 0x7FFF),
myMissile0(~CollisionMask::missile0 & 0x7FFF), myMissile0(~CollisionMask::missile0 & 0x7FFF),
myMissile1(~CollisionMask::missile1 & 0x7FFF), myMissile1(~CollisionMask::missile1 & 0x7FFF),
@ -78,7 +79,28 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
mySpriteEnabledBits(0xFF), mySpriteEnabledBits(0xFF),
myCollisionsEnabledBits(0xFF) myCollisionsEnabledBits(0xFF)
{ {
myFrameManager = new FrameManager(); myTIAPinsDriven = mySettings.getBool("tiadriven");
myBackground.setTIA(this);
myPlayfield.setTIA(this);
myPlayer0.setTIA(this);
myPlayer1.setTIA(this);
myMissile0.setTIA(this);
myMissile1.setTIA(this);
myBall.setTIA(this);
myEnableJitter = mySettings.getBool("tv.jitter");
myJitterFactor = mySettings.getInt("tv.jitter_recovery");
reset();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::setFrameManager(AbstractFrameManager *frameManager)
{
clearFrameManager();
myFrameManager = frameManager;
myFrameManager->setHandlers( myFrameManager->setHandlers(
[this] () { [this] () {
@ -92,25 +114,18 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
} }
); );
myTIAPinsDriven = mySettings.getBool("tiadriven"); myFrameManager->enableJitter(myEnableJitter);
myFrameManager->setJitterFactor(myJitterFactor);
myBackground.setTIA(this);
myPlayfield.setTIA(this);
myPlayer0.setTIA(this);
myPlayer1.setTIA(this);
myMissile0.setTIA(this);
myMissile1.setTIA(this);
myBall.setTIA(this);
myFrameManager->enableJitter(mySettings.getBool("tv.jitter"));
myFrameManager->setJitterFactor(mySettings.getInt("tv.jitter_recovery"));
reset();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TIA::~TIA() { void TIA::clearFrameManager()
delete myFrameManager; {
if (!myFrameManager) return;
myFrameManager->clearHandlers();
myFrameManager = nullptr;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -152,7 +167,8 @@ void TIA::reset()
mySound.reset(); mySound.reset();
myDelayQueue.reset(); myDelayQueue.reset();
myFrameManager->reset();
if (myFrameManager) myFrameManager->reset();
myCyclesAtFrameStart = 0; myCyclesAtFrameStart = 0;
@ -914,7 +930,9 @@ bool TIA::toggleCollisions()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIA::enableFixedColors(bool enable) bool TIA::enableFixedColors(bool enable)
{ {
int layout = myFrameManager->layout() == FrameLayout::pal ? 1 : 0; int layout = 0;
if (myFrameManager) layout = myFrameManager->layout() == FrameLayout::pal ? 1 : 0;
myMissile0.setDebugColor(myFixedColorPalette[layout][FixedObject::M0]); myMissile0.setDebugColor(myFixedColorPalette[layout][FixedObject::M0]);
myMissile1.setDebugColor(myFixedColorPalette[layout][FixedObject::M1]); myMissile1.setDebugColor(myFixedColorPalette[layout][FixedObject::M1]);
myPlayer0.setDebugColor(myFixedColorPalette[layout][FixedObject::P0]); myPlayer0.setDebugColor(myFixedColorPalette[layout][FixedObject::P0]);
@ -999,22 +1017,32 @@ bool TIA::toggleJitter(uInt8 mode)
{ {
switch (mode) { switch (mode) {
case 0: case 0:
myFrameManager->enableJitter(false); myEnableJitter = false;
break; break;
case 1: case 1:
myFrameManager->enableJitter(true); myEnableJitter = true;
break; break;
case 2: case 2:
myFrameManager->enableJitter(!myFrameManager->jitterEnabled()); myEnableJitter = !myEnableJitter;
break; break;
default: default:
throw runtime_error("invalid argument for toggleJitter"); throw runtime_error("invalid argument for toggleJitter");
} }
return myFrameManager->jitterEnabled(); if (myFrameManager) myFrameManager->enableJitter(myEnableJitter);
return myEnableJitter;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::setJitterRecoveryFactor(Int32 factor)
{
myJitterFactor = factor;
if (myFrameManager) myFrameManager->setJitterFactor(myJitterFactor);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -101,9 +101,20 @@ class TIA : public Device
@param settings The settings object for this TIA device @param settings The settings object for this TIA device
*/ */
TIA(Console& console, Sound& sound, Settings& settings); TIA(Console& console, Sound& sound, Settings& settings);
virtual ~TIA();
virtual ~TIA() = default;
public: public:
/**
* Configure the frame manager.
*/
void setFrameManager(AbstractFrameManager *frameManager);
/**
* Clear the configured frame manager and deteach the lifecycle callbacks.
*/
void clearFrameManager();
/** /**
Reset device to its power-on state. Reset device to its power-on state.
*/ */
@ -360,7 +371,7 @@ class TIA : public Device
@return Whether the mode was enabled or disabled @return Whether the mode was enabled or disabled
*/ */
bool toggleJitter(uInt8 mode = 2); bool toggleJitter(uInt8 mode = 2);
void setJitterRecoveryFactor(Int32 factor) { myFrameManager->setJitterFactor(factor); } void setJitterRecoveryFactor(Int32 factor);
/** /**
This method should be called to update the TIA with a new scanline. This method should be called to update the TIA with a new scanline.
@ -731,10 +742,17 @@ class TIA : public Device
bool myColorLossActive; bool myColorLossActive;
/** /**
* System cycles at the end of the previous frame / beginning of next frame * System cycles at the end of the previous frame / beginning of next frame.
*/ */
uInt64 myCyclesAtFrameStart; uInt64 myCyclesAtFrameStart;
/**
* The frame manager can change during our lifetime, so we buffer those two.
*/
bool myEnableJitter;
uInt8 myJitterFactor;
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
// The arrays containing information about every byte of TIA // The arrays containing information about every byte of TIA
// indicating whether and how (RW) it is used. // indicating whether and how (RW) it is used.

View File

@ -20,9 +20,9 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AbstractFrameManager::AbstractFrameManager() : AbstractFrameManager::AbstractFrameManager() :
myLayout(FrameLayout::pal), myLayout(FrameLayout::pal),
myOnFrameStart(0), myOnFrameStart(nullptr),
myOnFrameComplete(0), myOnFrameComplete(nullptr),
myOnRenderingStart(0) myOnRenderingStart(nullptr)
{ {
layout(FrameLayout::ntsc); layout(FrameLayout::ntsc);
reset(); reset();
@ -63,6 +63,12 @@ void AbstractFrameManager::setHandlers(
myOnRenderingStart = renderingStartCallback; myOnRenderingStart = renderingStartCallback;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AbstractFrameManager::clearHandlers()
{
myOnFrameStart = myOnFrameComplete = myOnRenderingStart = nullptr;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AbstractFrameManager::setVblank(bool vblank) void AbstractFrameManager::setVblank(bool vblank)
{ {

View File

@ -44,6 +44,11 @@ class AbstractFrameManager : public Serializable
callback renderingStartCallback callback renderingStartCallback
); );
/**
* Clear the configured handler callbacks.
*/
void clearHandlers();
/** /**
* Reset. * Reset.
*/ */
@ -151,7 +156,7 @@ class AbstractFrameManager : public Serializable
/** /**
* Frame height. * Frame height.
*/ */
virtual uInt32 height() { return 0; } virtual uInt32 height() const { return 0; }
/** /**
* Configure a fixed frame height (the default is determined by the frame * Configure a fixed frame height (the default is determined by the frame
@ -162,13 +167,13 @@ class AbstractFrameManager : public Serializable
/** /**
* The current y coordinate (valid only during rendering). * The current y coordinate (valid only during rendering).
*/ */
virtual uInt32 getY() { return 0; } virtual uInt32 getY() const { return 0; }
/** /**
* The current number of scanlines in the current frame (including invisible * The current number of scanlines in the current frame (including invisible
* lines). * lines).
*/ */
virtual uInt32 scanlines() { return 0; } virtual uInt32 scanlines() const { return 0; }
/** /**
* Configure the ystart value. * Configure the ystart value.
@ -178,12 +183,12 @@ class AbstractFrameManager : public Serializable
/** /**
* The configured ystart value. * The configured ystart value.
*/ */
virtual uInt32 ystart() { return 0; } virtual uInt32 ystart() const { return 0; }
/** /**
* TODO: this looks pretty weird --- does this actually work? * TODO: this looks pretty weird --- does this actually work?
*/ */
virtual bool ystartIsAuto(uInt32 line) { return false; } virtual bool ystartIsAuto(uInt32 line) const { return false; }
/** /**
* TODO: this has to go * TODO: this has to go