Fix PAL autodetection:

* Be more tolerant when waiting for vsync during TV mode autodetect.
  * Count PAL and NTSC frames during autodetect, use the mode with
    more statistics.
This commit is contained in:
Christian Speckner 2017-01-13 09:14:44 +01:00
parent 2ccb559138
commit 0a8b1debfc
3 changed files with 32 additions and 8 deletions

View File

@ -54,6 +54,7 @@
#include "Serializable.hxx"
#include "Version.hxx"
#include "TvMode.hxx"
#include "FrameManager.hxx"
#ifdef DEBUGGER_SUPPORT
#include "Debugger.hxx"
@ -116,11 +117,20 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
// The 'fastscbios' option must be changed before the system is reset
bool fastscbios = myOSystem.settings().getBool("fastscbios");
myOSystem.settings().setValue("fastscbios", true);
uInt8 initialGarbageFrames = FrameManager::initialGarbageFrames();
uInt8 linesPAL = 0;
uInt8 linesNTSC = 0;
mySystem->reset(true); // autodetect in reset enabled
myTIA->autodetectTvMode(true);
for(int i = 0; i < 80; ++i)
for(int i = 0; i < 60; ++i) {
if (i > initialGarbageFrames) myTIA->tvMode() == TvMode::pal ? linesPAL++ : linesNTSC++;
myTIA->update();
myDisplayFormat = myTIA->tvMode() == TvMode::pal ? "PAL" : "NTSC";
}
myDisplayFormat = linesPAL > linesNTSC ? "PAL" : "NTSC";
if(myProperties.get(Display_Format) == "AUTO")
{
autodetected = "*";

View File

@ -29,11 +29,12 @@ enum Metrics: uInt32 {
overscanNTSC = 30,
overscanPAL = 36,
vsync = 3,
vsyncLimit = 30,
maxLinesVsync = 30,
maxLinesVsyncDuringAutodetect = 100,
visibleOverscan = 20,
maxUnderscan = 10,
tvModeDetectionTolerance = 20,
initialGarbageFrames = 20,
initialGarbageFrames = 10,
framesForModeConfirmation = 5,
maxVblankViolations = 2,
minStableVblankFrames = 1
@ -43,6 +44,16 @@ static constexpr uInt32
frameLinesNTSC = Metrics::vsync + Metrics::vblankNTSC + Metrics::kernelNTSC + Metrics::overscanNTSC,
frameLinesPAL = Metrics::vsync + Metrics::vblankPAL + Metrics::kernelPAL + Metrics::overscanPAL;
inline static uInt32 vsyncLimit(bool autodetect) {
return autodetect ? maxLinesVsyncDuringAutodetect : maxLinesVsync;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 FrameManager::initialGarbageFrames()
{
return Metrics::initialGarbageFrames;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameManager::FrameManager()
: myMode(TvMode::pal),
@ -95,15 +106,15 @@ void FrameManager::nextLine()
switch (myState)
{
case State::waitForVsyncStart:
if (Int32(myLineInState) > Int32(myFrameLines - myCurrentFrameFinalLines) || !myCurrentFrameFinalLines)
if (Int32(myLineInState) >= Int32(myFrameLines - myCurrentFrameFinalLines) || !myCurrentFrameFinalLines)
myVsyncLines++;
if (myVsyncLines > Metrics::vsyncLimit) setState(State::waitForFrameStart);
if (myVsyncLines > vsyncLimit(myAutodetectTvMode)) setState(State::waitForFrameStart);
break;
case State::waitForVsyncEnd:
if (++myVsyncLines > Metrics::vsyncLimit)
if (++myVsyncLines > vsyncLimit(myAutodetectTvMode))
setState(State::waitForFrameStart);
break;
@ -131,7 +142,7 @@ void FrameManager::nextLineInVsync()
case VblankMode::floating:
if (shouldTransition) {
if (myTotalFrames > initialGarbageFrames && myLineInState == myLastVblankLines)
if (myTotalFrames > Metrics::initialGarbageFrames && myLineInState == myLastVblankLines)
myStableVblankFrames++;
else
myStableVblankFrames = 0;

View File

@ -35,6 +35,9 @@ class FrameManager : public Serializable
FrameManager();
public:
static uInt8 initialGarbageFrames();
void setHandlers(callback frameStartCallback, callback frameCompletionCallback);
void reset();