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

View File

@ -35,6 +35,7 @@ class Debugger;
#include "FrameBuffer.hxx"
#include "Serializable.hxx"
#include "NTSCFilter.hxx"
#include "frame-manager/AbstractFrameManager.hxx"
/**
Contains detailed info about a console.
@ -360,6 +361,9 @@ class Console : public Serializable
// Pointer to the TIA object
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)
unique_ptr<Cartridge> myCart;

View File

@ -69,6 +69,7 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
: myConsole(console),
mySound(sound),
mySettings(settings),
myFrameManager(nullptr),
myPlayfield(~CollisionMask::playfield & 0x7FFF),
myMissile0(~CollisionMask::missile0 & 0x7FFF),
myMissile1(~CollisionMask::missile1 & 0x7FFF),
@ -78,7 +79,28 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
mySpriteEnabledBits(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(
[this] () {
@ -92,25 +114,18 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
}
);
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);
myFrameManager->enableJitter(mySettings.getBool("tv.jitter"));
myFrameManager->setJitterFactor(mySettings.getInt("tv.jitter_recovery"));
reset();
myFrameManager->enableJitter(myEnableJitter);
myFrameManager->setJitterFactor(myJitterFactor);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TIA::~TIA() {
delete myFrameManager;
void TIA::clearFrameManager()
{
if (!myFrameManager) return;
myFrameManager->clearHandlers();
myFrameManager = nullptr;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -152,7 +167,8 @@ void TIA::reset()
mySound.reset();
myDelayQueue.reset();
myFrameManager->reset();
if (myFrameManager) myFrameManager->reset();
myCyclesAtFrameStart = 0;
@ -914,7 +930,9 @@ bool TIA::toggleCollisions()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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]);
myMissile1.setDebugColor(myFixedColorPalette[layout][FixedObject::M1]);
myPlayer0.setDebugColor(myFixedColorPalette[layout][FixedObject::P0]);
@ -999,22 +1017,32 @@ bool TIA::toggleJitter(uInt8 mode)
{
switch (mode) {
case 0:
myFrameManager->enableJitter(false);
myEnableJitter = false;
break;
case 1:
myFrameManager->enableJitter(true);
myEnableJitter = true;
break;
case 2:
myFrameManager->enableJitter(!myFrameManager->jitterEnabled());
myEnableJitter = !myEnableJitter;
break;
default:
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
*/
TIA(Console& console, Sound& sound, Settings& settings);
virtual ~TIA();
virtual ~TIA() = default;
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.
*/
@ -360,7 +371,7 @@ class TIA : public Device
@return Whether the mode was enabled or disabled
*/
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.
@ -731,10 +742,17 @@ class TIA : public Device
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;
/**
* The frame manager can change during our lifetime, so we buffer those two.
*/
bool myEnableJitter;
uInt8 myJitterFactor;
#ifdef DEBUGGER_SUPPORT
// The arrays containing information about every byte of TIA
// indicating whether and how (RW) it is used.

View File

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

View File

@ -44,6 +44,11 @@ class AbstractFrameManager : public Serializable
callback renderingStartCallback
);
/**
* Clear the configured handler callbacks.
*/
void clearHandlers();
/**
* Reset.
*/
@ -151,7 +156,7 @@ class AbstractFrameManager : public Serializable
/**
* 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
@ -162,13 +167,13 @@ class AbstractFrameManager : public Serializable
/**
* 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
* lines).
*/
virtual uInt32 scanlines() { return 0; }
virtual uInt32 scanlines() const { return 0; }
/**
* Configure the ystart value.
@ -178,12 +183,12 @@ class AbstractFrameManager : public Serializable
/**
* The configured ystart value.
*/
virtual uInt32 ystart() { return 0; }
virtual uInt32 ystart() const { return 0; }
/**
* 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