Refactoring, convert TvMode to FrameLayout as per AtariAge thread.

This commit is contained in:
Stephen Anthony 2017-03-15 20:57:03 -02:30
parent 59a6f8f9d1
commit 3950f80a30
8 changed files with 67 additions and 64 deletions

View File

@ -55,8 +55,8 @@
#include "CommandMenu.hxx" #include "CommandMenu.hxx"
#include "Serializable.hxx" #include "Serializable.hxx"
#include "Version.hxx" #include "Version.hxx"
#include "TvMode.hxx"
#include "FrameManager.hxx" #include "FrameManager.hxx"
#include "FrameLayout.hxx"
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
#include "Debugger.hxx" #include "Debugger.hxx"
@ -125,9 +125,10 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
uInt8 linesNTSC = 0; uInt8 linesNTSC = 0;
mySystem->reset(true); // autodetect in reset enabled mySystem->reset(true); // autodetect in reset enabled
myTIA->autodetectTvMode(true); myTIA->autodetectLayout(true);
for(int i = 0; i < 60; ++i) { for(int i = 0; i < 60; ++i) {
if (i > initialGarbageFrames) myTIA->tvMode() == TvMode::pal ? linesPAL++ : linesNTSC++; if (i > initialGarbageFrames)
myTIA->frameLayout() == FrameLayout::pal ? linesPAL++ : linesNTSC++;
myTIA->update(); myTIA->update();
} }
@ -245,7 +246,7 @@ void Console::toggleFormat(int direction)
{ {
case 0: // auto-detect case 0: // auto-detect
myTIA->update(); myTIA->update();
myDisplayFormat = myTIA->tvMode() == TvMode::pal ? "PAL" : "NTSC"; myDisplayFormat = myTIA->frameLayout() == FrameLayout::pal ? "PAL" : "NTSC";
message = "Auto-detect mode: " + myDisplayFormat; message = "Auto-detect mode: " + myDisplayFormat;
saveformat = "AUTO"; saveformat = "AUTO";
break; break;
@ -571,7 +572,7 @@ void Console::setTIAProperties()
if(height != 0) if(height != 0)
height = BSPF::clamp(height, FrameManager::minViewableHeight, FrameManager::maxViewableHeight); height = BSPF::clamp(height, FrameManager::minViewableHeight, FrameManager::maxViewableHeight);
myTIA->autodetectTvMode(false); myTIA->autodetectLayout(false);
if(myDisplayFormat == "NTSC" || myDisplayFormat == "PAL60" || if(myDisplayFormat == "NTSC" || myDisplayFormat == "PAL60" ||
myDisplayFormat == "SECAM60") myDisplayFormat == "SECAM60")
@ -579,7 +580,7 @@ void Console::setTIAProperties()
// Assume we've got ~262 scanlines (NTSC-like format) // Assume we've got ~262 scanlines (NTSC-like format)
myFramerate = 60.0; myFramerate = 60.0;
myConsoleInfo.InitialFrameRate = "60"; myConsoleInfo.InitialFrameRate = "60";
myTIA->setTvMode(TvMode::ntsc); myTIA->setLayout(FrameLayout::ntsc);
} }
else else
{ {
@ -590,7 +591,7 @@ void Console::setTIAProperties()
// PAL ROMs normally need at least 250 lines // PAL ROMs normally need at least 250 lines
if (height != 0) height = std::max(height, 250u); if (height != 0) height = std::max(height, 250u);
myTIA->setTvMode(TvMode::pal); myTIA->setLayout(FrameLayout::pal);
} }
myTIA->setYStart(ystart); myTIA->setYStart(ystart);

View File

@ -15,11 +15,12 @@
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================ //============================================================================
#ifndef TIA_TYPES #ifndef FRAME_LAYOUT
#define TIA_TYPES #define FRAME_LAYOUT
enum TvMode { enum FrameLayout {
pal, ntsc ntsc, // ROM display has NTSC timings (~60Hz, ~262 scanlines, etc)
pal // ROM display has PAL timings (~50Hz, ~312 scanlines, etc)
}; };
#endif // TIA_TYPES #endif // FRAME_LAYOUT

View File

@ -54,12 +54,12 @@ uInt8 FrameManager::initialGarbageFrames()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameManager::FrameManager() FrameManager::FrameManager()
: myMode(TvMode::pal), : myLayout(FrameLayout::pal),
myAutodetectTvMode(true), myAutodetectLayout(true),
myHeight(0), myHeight(0),
myFixedHeight(0) myFixedHeight(0)
{ {
updateTvMode(TvMode::ntsc); updateLayout(FrameLayout::ntsc);
reset(); reset();
} }
@ -105,12 +105,12 @@ void FrameManager::nextLine()
if ((myCurrentFrameTotalLines > myFrameLines - 3) || myTotalFrames == 0) if ((myCurrentFrameTotalLines > myFrameLines - 3) || myTotalFrames == 0)
myVsyncLines++; myVsyncLines++;
if (myVsyncLines > vsyncLimit(myAutodetectTvMode)) setState(State::waitForFrameStart); if (myVsyncLines > vsyncLimit(myAutodetectLayout)) setState(State::waitForFrameStart);
break; break;
case State::waitForVsyncEnd: case State::waitForVsyncEnd:
if (++myVsyncLines > vsyncLimit(myAutodetectTvMode)) if (++myVsyncLines > vsyncLimit(myAutodetectLayout))
setState(State::waitForFrameStart); setState(State::waitForFrameStart);
break; break;
@ -220,39 +220,39 @@ void FrameManager::finalizeFrame()
(cout << "frame complete @ " << myLineInState << " (" << myCurrentFrameFinalLines << " total)" << "\n").flush(); (cout << "frame complete @ " << myLineInState << " (" << myCurrentFrameFinalLines << " total)" << "\n").flush();
#endif // TIA_FRAMEMANAGER_DEBUG_LOG #endif // TIA_FRAMEMANAGER_DEBUG_LOG
if (myAutodetectTvMode) updateAutodetectedTvMode(); if (myAutodetectLayout) updateAutodetectedLayout();
myFrameRate = (myMode == TvMode::pal ? 15600.0 : 15720.0) / myFrameRate = (myLayout == FrameLayout::pal ? 15600.0 : 15720.0) /
myCurrentFrameFinalLines; myCurrentFrameFinalLines;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::updateAutodetectedTvMode() void FrameManager::updateAutodetectedLayout()
{ {
if (myTotalFrames <= Metrics::initialGarbageFrames) { if (myTotalFrames <= Metrics::initialGarbageFrames) {
return; return;
} }
const TvMode oldMode = myMode; const FrameLayout oldLayout = myLayout;
const uInt32 const uInt32
deltaNTSC = abs(Int32(myCurrentFrameFinalLines) - Int32(frameLinesNTSC)), deltaNTSC = abs(Int32(myCurrentFrameFinalLines) - Int32(frameLinesNTSC)),
deltaPAL = abs(Int32(myCurrentFrameFinalLines) - Int32(frameLinesPAL)); deltaPAL = abs(Int32(myCurrentFrameFinalLines) - Int32(frameLinesPAL));
if (std::min(deltaNTSC, deltaPAL) <= Metrics::tvModeDetectionTolerance) if (std::min(deltaNTSC, deltaPAL) <= Metrics::tvModeDetectionTolerance)
updateTvMode(deltaNTSC <= deltaPAL ? TvMode::ntsc : TvMode::pal); updateLayout(deltaNTSC <= deltaPAL ? FrameLayout::ntsc : FrameLayout::pal);
else if (!myModeConfirmed) { else if (!myModeConfirmed) {
if ( if (
(myCurrentFrameFinalLines < frameLinesPAL) && (myCurrentFrameFinalLines < frameLinesPAL) &&
(myCurrentFrameFinalLines > frameLinesNTSC) && (myCurrentFrameFinalLines > frameLinesNTSC) &&
(myCurrentFrameFinalLines % 2) (myCurrentFrameFinalLines % 2)
) )
updateTvMode(TvMode::ntsc); updateLayout(FrameLayout::ntsc);
else else
updateTvMode(deltaNTSC <= deltaPAL ? TvMode::ntsc : TvMode::pal); updateLayout(deltaNTSC <= deltaPAL ? FrameLayout::ntsc : FrameLayout::pal);
} }
if (oldMode == myMode) if (oldLayout == myLayout)
myFramesInMode++; myFramesInMode++;
else else
myFramesInMode = 0; myFramesInMode = 0;
@ -262,28 +262,28 @@ void FrameManager::updateAutodetectedTvMode()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::updateTvMode(TvMode mode) void FrameManager::updateLayout(FrameLayout layout)
{ {
if (mode == myMode) return; if (layout == myLayout) return;
#ifdef TIA_FRAMEMANAGER_DEBUG_LOG #ifdef TIA_FRAMEMANAGER_DEBUG_LOG
(cout << "TV mode switched to " << int(mode) << "\n").flush(); (cout << "TV mode switched to " << int(mode) << "\n").flush();
#endif // TIA_FRAMEMANAGER_DEBUG_LOG #endif // TIA_FRAMEMANAGER_DEBUG_LOG
myMode = mode; myLayout = layout;
switch (myMode) switch (myLayout)
{ {
case TvMode::ntsc: case FrameLayout::ntsc:
myVblankLines = Metrics::vblankNTSC; myVblankLines = Metrics::vblankNTSC;
myKernelLines = Metrics::kernelNTSC; myKernelLines = Metrics::kernelNTSC;
myOverscanLines = Metrics::overscanNTSC; myOverscanLines = Metrics::overscanNTSC;
break; break;
case TvMode::pal: case FrameLayout::pal:
myVblankLines = Metrics::vblankPAL; myVblankLines = Metrics::vblankPAL;
myKernelLines = Metrics::kernelPAL; myKernelLines = Metrics::kernelPAL;
myOverscanLines = Metrics::overscanPAL; myOverscanLines = Metrics::overscanPAL;
break; break;
default: default:
@ -291,7 +291,8 @@ void FrameManager::updateTvMode(TvMode mode)
} }
myFrameLines = Metrics::vsync + myVblankLines + myKernelLines + myOverscanLines; myFrameLines = Metrics::vsync + myVblankLines + myKernelLines + myOverscanLines;
setFixedHeight(myFixedHeight); // update since myKernelLines may have changed if (myFixedHeight == 0)
myHeight = myKernelLines + Metrics::visibleOverscan;
myVblankManager.setVblankLines(myVblankLines); myVblankManager.setVblankLines(myVblankLines);
} }

View File

@ -22,7 +22,7 @@
#include "VblankManager.hxx" #include "VblankManager.hxx"
#include "Serializable.hxx" #include "Serializable.hxx"
#include "TvMode.hxx" #include "FrameLayout.hxx"
#include "bspf.hxx" #include "bspf.hxx"
class FrameManager : public Serializable class FrameManager : public Serializable
@ -51,7 +51,7 @@ class FrameManager : public Serializable
bool isRendering() const { return myState == State::frame; } bool isRendering() const { return myState == State::frame; }
TvMode tvMode() const { return myMode; } FrameLayout layout() const { return myLayout; }
bool vblank() const { return myVblankManager.vblank(); } bool vblank() const { return myVblankManager.vblank(); }
@ -78,9 +78,9 @@ class FrameManager : public Serializable
uInt32 ystart() const { return myVblankManager.ystart(); } uInt32 ystart() const { return myVblankManager.ystart(); }
bool ystartIsAuto(uInt32 line) const { return myVblankManager.ystartIsAuto(line); } bool ystartIsAuto(uInt32 line) const { return myVblankManager.ystartIsAuto(line); }
void autodetectTvMode(bool toggle) { myAutodetectTvMode = toggle; } void autodetectLayout(bool toggle) { myAutodetectLayout = toggle; }
void setTvMode(TvMode mode) { if (!myAutodetectTvMode) updateTvMode(mode); } void setLayout(FrameLayout mode) { if (!myAutodetectLayout) updateLayout(mode); }
/** /**
Serializable methods (see that class for more information). Serializable methods (see that class for more information).
@ -112,9 +112,9 @@ class FrameManager : public Serializable
private: private:
void updateTvMode(TvMode mode); void updateLayout(FrameLayout mode);
void updateAutodetectedTvMode(); void updateAutodetectedLayout();
void setState(State state); void setState(State state);
@ -129,8 +129,8 @@ class FrameManager : public Serializable
VblankManager myVblankManager; VblankManager myVblankManager;
TvMode myMode; FrameLayout myLayout;
bool myAutodetectTvMode; bool myAutodetectLayout;
State myState; State myState;
uInt32 myLineInState; uInt32 myLineInState;
uInt32 myCurrentFrameTotalLines; uInt32 myCurrentFrameTotalLines;

View File

@ -42,7 +42,7 @@ void PaddleReader::reset(double timestamp)
myValue = 0; myValue = 0;
myTimestamp = timestamp; myTimestamp = timestamp;
setTvMode(TvMode::ntsc); setLayout(FrameLayout::ntsc);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -71,10 +71,10 @@ uInt8 PaddleReader::inpt(double timestamp)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaddleReader::update(double value, double timestamp, TvMode tvMode) void PaddleReader::update(double value, double timestamp, FrameLayout layout)
{ {
if (tvMode != myTvMode) { if (layout != myLayout) {
setTvMode(tvMode); setLayout(layout);
} }
if (value != myValue) { if (value != myValue) {
@ -84,11 +84,11 @@ void PaddleReader::update(double value, double timestamp, TvMode tvMode)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaddleReader::setTvMode(TvMode mode) void PaddleReader::setLayout(FrameLayout layout)
{ {
myTvMode = mode; myLayout = layout;
myClockFreq = myTvMode == TvMode::ntsc ? 60 * 228 * 262 : 50 * 228 * 312; myClockFreq = myLayout == FrameLayout::ntsc ? 60 * 228 * 262 : 50 * 228 * 312;
myUThresh = USUPP * (1. - exp(-TRIPPOINT_LINES * 228 / myClockFreq / (RPOT + R0) / C)); myUThresh = USUPP * (1. - exp(-TRIPPOINT_LINES * 228 / myClockFreq / (RPOT + R0) / C));
} }

View File

@ -19,7 +19,7 @@
#define TIA_PADDLE_READER #define TIA_PADDLE_READER
#include "bspf.hxx" #include "bspf.hxx"
#include "TvMode.hxx" #include "FrameLayout.hxx"
#include "Serializable.hxx" #include "Serializable.hxx"
class PaddleReader : public Serializable class PaddleReader : public Serializable
@ -37,7 +37,7 @@ class PaddleReader : public Serializable
uInt8 inpt(double timestamp); uInt8 inpt(double timestamp);
void update(double value, double timestamp, TvMode tvMode); void update(double value, double timestamp, FrameLayout layout);
/** /**
Serializable methods (see that class for more information). Serializable methods (see that class for more information).
@ -48,7 +48,7 @@ class PaddleReader : public Serializable
private: private:
void setTvMode(TvMode mode); void setLayout(FrameLayout layout);
void updateCharge(double timestamp); void updateCharge(double timestamp);
@ -60,7 +60,7 @@ class PaddleReader : public Serializable
double myValue; double myValue;
double myTimestamp; double myTimestamp;
TvMode myTvMode; FrameLayout myLayout;
double myClockFreq; double myClockFreq;
bool myIsDumped; bool myIsDumped;

View File

@ -735,7 +735,7 @@ bool TIA::toggleFixedColors(uInt8 mode)
// Otherwise, flip the state // Otherwise, flip the state
bool on = (mode == 0 || mode == 1) ? bool(mode) : myColorHBlank == 0; bool on = (mode == 0 || mode == 1) ? bool(mode) : myColorHBlank == 0;
bool pal = myFrameManager.tvMode() == TvMode::pal; bool pal = myFrameManager.layout() == FrameLayout::pal;
myMissile0.setDebugColor(pal ? M0ColorPAL : M0ColorNTSC); myMissile0.setDebugColor(pal ? M0ColorPAL : M0ColorNTSC);
myMissile1.setDebugColor(pal ? M1ColorPAL : M1ColorNTSC); myMissile1.setDebugColor(pal ? M1ColorPAL : M1ColorNTSC);
myPlayer0.setDebugColor(pal ? P0ColorPAL : P0ColorNTSC); myPlayer0.setDebugColor(pal ? P0ColorPAL : P0ColorNTSC);
@ -1226,7 +1226,7 @@ void TIA::updatePaddle(uInt8 idx)
myPaddleReaders[idx].update( myPaddleReaders[idx].update(
(resistance == Controller::maximumResistance ? -1 : double(resistance)) / MAX_RESISTANCE, (resistance == Controller::maximumResistance ? -1 : double(resistance)) / MAX_RESISTANCE,
myTimestamp, myTimestamp,
myFrameManager.tvMode() myFrameManager.layout()
); );
} }

View File

@ -26,6 +26,7 @@
#include "TIATypes.hxx" #include "TIATypes.hxx"
#include "DelayQueue.hxx" #include "DelayQueue.hxx"
#include "FrameManager.hxx" #include "FrameManager.hxx"
#include "FrameLayout.hxx"
#include "Background.hxx" #include "Background.hxx"
#include "Playfield.hxx" #include "Playfield.hxx"
#include "Missile.hxx" #include "Missile.hxx"
@ -33,7 +34,6 @@
#include "Ball.hxx" #include "Ball.hxx"
#include "LatchedInput.hxx" #include "LatchedInput.hxx"
#include "PaddleReader.hxx" #include "PaddleReader.hxx"
#include "TvMode.hxx"
class Console; class Console;
@ -170,9 +170,9 @@ class TIA : public Device
void setHeight(uInt32 height) { myFrameManager.setFixedHeight(height); } void setHeight(uInt32 height) { myFrameManager.setFixedHeight(height); }
void setYStart(uInt32 ystart) { myFrameManager.setYstart(ystart); } void setYStart(uInt32 ystart) { myFrameManager.setYstart(ystart); }
void autodetectTvMode(bool toggle) { myFrameManager.autodetectTvMode(toggle); } void autodetectLayout(bool toggle) { myFrameManager.autodetectLayout(toggle); }
void setTvMode(TvMode mode) { myFrameManager.setTvMode(mode); } void setLayout(FrameLayout layout) { myFrameManager.setLayout(layout); }
TvMode tvMode() const { return myFrameManager.tvMode(); } FrameLayout frameLayout() const { return myFrameManager.layout(); }
/** /**
Enables/disables auto-frame calculation. If enabled, the TIA Enables/disables auto-frame calculation. If enabled, the TIA