mirror of https://github.com/stella-emu/stella.git
Documentation, minor simplificationsDocumentation, minor simplifications.
This commit is contained in:
parent
4f31166e11
commit
12afce8c0d
|
@ -18,6 +18,9 @@
|
|||
#include "FrameLayoutDetector.hxx"
|
||||
#include "TIAConstants.hxx"
|
||||
|
||||
/**
|
||||
* Misc. numeric constants used in the algorithm.
|
||||
*/
|
||||
enum Metrics: uInt32 {
|
||||
frameLinesNTSC = 262,
|
||||
frameLinesPAL = 312,
|
||||
|
@ -28,6 +31,7 @@ enum Metrics: uInt32 {
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameLayout FrameLayoutDetector::detectedLayout() const{
|
||||
// We choose the mode that was detected for the majority of frames.
|
||||
return myPalFrames > myNtscFrames ? FrameLayout::pal : FrameLayout::ntsc;
|
||||
}
|
||||
|
||||
|
@ -55,6 +59,8 @@ void FrameLayoutDetector::onNextLine()
|
|||
|
||||
switch (myState) {
|
||||
case State::waitForVsyncStart:
|
||||
// We start counting the number of "lines spent while waiting for vsync start" from
|
||||
// the "ideal" frame size (corrected by the three scanlines spent in vsync).
|
||||
if (myCurrentFrameTotalLines > frameLines - 3 || myTotalFrames == 0)
|
||||
myLinesWaitingForVsync++;
|
||||
|
||||
|
@ -78,15 +84,13 @@ void FrameLayoutDetector::setState(State state)
|
|||
if (state == myState) return;
|
||||
|
||||
myState = state;
|
||||
myLinesWaitingForVsync = 0;
|
||||
|
||||
switch (myState) {
|
||||
case State::waitForVsyncEnd:
|
||||
myLinesWaitingForVsync = 0;
|
||||
break;
|
||||
|
||||
case State::waitForVsyncStart:
|
||||
myLinesWaitingForVsync = 0;
|
||||
|
||||
finalizeFrame();
|
||||
notifyFrameStart();
|
||||
break;
|
||||
|
@ -103,19 +107,25 @@ void FrameLayoutDetector::finalizeFrame()
|
|||
|
||||
if (myTotalFrames <= Metrics::initialGarbageFrames) return;
|
||||
|
||||
// Calculate the delta between scanline count and the sweet spot for the respective
|
||||
// frame layouts
|
||||
const uInt32
|
||||
deltaNTSC = abs(Int32(myCurrentFrameFinalLines) - Int32(frameLinesNTSC)),
|
||||
deltaPAL = abs(Int32(myCurrentFrameFinalLines) - Int32(frameLinesPAL));
|
||||
|
||||
// Does the scanline count fall into one of our tolerance windows? -> use it
|
||||
if (std::min(deltaNTSC, deltaPAL) <= Metrics::tvModeDetectionTolerance)
|
||||
layout(deltaNTSC <= deltaPAL ? FrameLayout::ntsc : FrameLayout::pal);
|
||||
else if (
|
||||
// If scanline count is odd and lies between the PAL and NTSC windows we assume
|
||||
// it is NTSC (it would cause color loss on PAL CRTs)
|
||||
(myCurrentFrameFinalLines < frameLinesPAL) &&
|
||||
(myCurrentFrameFinalLines > frameLinesNTSC) &&
|
||||
(myCurrentFrameFinalLines % 2)
|
||||
)
|
||||
layout(FrameLayout::ntsc);
|
||||
else
|
||||
// Take the nearest layout if all else fails
|
||||
layout(deltaNTSC <= deltaPAL ? FrameLayout::ntsc : FrameLayout::pal);
|
||||
|
||||
switch (layout()) {
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
#include "AbstractFrameManager.hxx"
|
||||
#include "FrameLayout.hxx"
|
||||
|
||||
/**
|
||||
* This frame manager performs frame layout autodetection. It counts the scanlines
|
||||
* in each frame and assigns guesses the frame layout from this.
|
||||
*/
|
||||
class FrameLayoutDetector: public AbstractFrameManager {
|
||||
public:
|
||||
|
||||
|
@ -28,36 +32,70 @@ class FrameLayoutDetector: public AbstractFrameManager {
|
|||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Return the detected frame layout.
|
||||
*/
|
||||
FrameLayout detectedLayout() const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Hook into vsync changes.
|
||||
*/
|
||||
void onSetVsync() override;
|
||||
|
||||
/**
|
||||
* Hook into reset.
|
||||
*/
|
||||
void onReset() override;
|
||||
|
||||
/**
|
||||
* Hook into line changes.
|
||||
*/
|
||||
void onNextLine() override;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* This frame manager only tracks frame boundaries, so we have only two states.
|
||||
*/
|
||||
enum State {
|
||||
// Wait for VSYNC to be enabled.
|
||||
waitForVsyncStart,
|
||||
|
||||
// Wait for VSYNC to be disabled.
|
||||
waitForVsyncEnd
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Change state and change internal state accordingly.
|
||||
*/
|
||||
void setState(State state);
|
||||
|
||||
/**
|
||||
* Finalize the current frame and guess frame layout from the scanline count.
|
||||
*/
|
||||
void finalizeFrame();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* The current state.
|
||||
*/
|
||||
State myState;
|
||||
|
||||
/**
|
||||
* The total number of frames detected as the respective frame layout.
|
||||
*/
|
||||
uInt32 myNtscFrames, myPalFrames;
|
||||
|
||||
/**
|
||||
* We count the number of scanlines we spend waiting for vsync to be
|
||||
* toggled. If a threshold is exceeded, we force the transition.
|
||||
*/
|
||||
uInt32 myLinesWaitingForVsync;
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue