mirror of https://github.com/stella-emu/stella.git
Finalize and start frames right after vsync -> stabilizes algorithm.
This commit is contained in:
parent
c0aa5c83f5
commit
3303f0560a
|
@ -29,7 +29,7 @@ enum Metrics: uInt32 {
|
|||
overscanNTSC = 30,
|
||||
overscanPAL = 36,
|
||||
vsync = 3,
|
||||
maxLinesVsync = 30,
|
||||
maxLinesVsync = 32,
|
||||
maxLinesVsyncDuringAutodetect = 100,
|
||||
visibleOverscan = 20,
|
||||
maxUnderscan = 10,
|
||||
|
@ -93,6 +93,8 @@ void FrameManager::reset()
|
|||
myStableVblankFrames = 0;
|
||||
myVblankViolated = false;
|
||||
myVsyncLines = 0;
|
||||
myY = 0;
|
||||
myFramePending = false;
|
||||
|
||||
if (myVblankMode != VblankMode::fixed) myVblankMode = VblankMode::floating;
|
||||
}
|
||||
|
@ -100,13 +102,15 @@ void FrameManager::reset()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameManager::nextLine()
|
||||
{
|
||||
State previousState = myState;
|
||||
|
||||
myCurrentFrameTotalLines++;
|
||||
myLineInState++;
|
||||
|
||||
switch (myState)
|
||||
{
|
||||
case State::waitForVsyncStart:
|
||||
if (Int32(myLineInState) >= Int32(myFrameLines - myCurrentFrameFinalLines) || !myCurrentFrameFinalLines)
|
||||
if ((myCurrentFrameTotalLines > myFrameLines - 3) || myTotalFrames == 0)
|
||||
myVsyncLines++;
|
||||
|
||||
if (myVsyncLines > vsyncLimit(myAutodetectTvMode)) setState(State::waitForFrameStart);
|
||||
|
@ -125,12 +129,14 @@ void FrameManager::nextLine()
|
|||
|
||||
case State::frame:
|
||||
if (myLineInState >= (myFixedHeight > 0 ? myFixedHeight : (myKernelLines + Metrics::visibleOverscan)))
|
||||
finalizeFrame();
|
||||
setState(State::waitForVsyncStart);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw runtime_error("frame manager: invalid state");
|
||||
}
|
||||
|
||||
if (myState == State::frame && previousState == State::frame) myY++;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -215,15 +221,11 @@ void FrameManager::setVsync(bool vsync)
|
|||
break;
|
||||
|
||||
case State::waitForVsyncEnd:
|
||||
if (!myVsync)
|
||||
setState(State::waitForFrameStart);
|
||||
if (!myVsync) setState(State::waitForFrameStart);
|
||||
break;
|
||||
|
||||
case State::frame:
|
||||
if (myVsync) {
|
||||
myCurrentFrameTotalLines++;
|
||||
finalizeFrame(State::waitForVsyncEnd);
|
||||
}
|
||||
if (myVsync) setState(State::waitForVsyncEnd);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -245,13 +247,17 @@ void FrameManager::setState(FrameManager::State state)
|
|||
|
||||
switch (myState) {
|
||||
case State::waitForFrameStart:
|
||||
if (myFramePending) finalizeFrame();
|
||||
if (myOnFrameStart) myOnFrameStart();
|
||||
myFramePending = true;
|
||||
|
||||
myVsyncLines = 0;
|
||||
myVblankViolated = false;
|
||||
break;
|
||||
|
||||
case State::frame:
|
||||
myVsyncLines = 0;
|
||||
if (myOnFrameStart) myOnFrameStart();
|
||||
myY = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -260,22 +266,18 @@ void FrameManager::setState(FrameManager::State state)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameManager::finalizeFrame(FrameManager::State state)
|
||||
void FrameManager::finalizeFrame()
|
||||
{
|
||||
myCurrentFrameFinalLines = myCurrentFrameTotalLines;
|
||||
myCurrentFrameTotalLines = 0;
|
||||
myTotalFrames++;
|
||||
|
||||
if (myOnFrameComplete) {
|
||||
myOnFrameComplete();
|
||||
}
|
||||
if (myOnFrameComplete) myOnFrameComplete();
|
||||
|
||||
#ifdef TIA_FRAMEMANAGER_DEBUG_LOG
|
||||
(cout << "frame complete @ " << myLineInState << " (" << myCurrentFrameFinalLines << " total)" << "\n").flush();
|
||||
#endif // TIA_FRAMEMANAGER_DEBUG_LOG
|
||||
|
||||
setState(state);
|
||||
|
||||
if (myAutodetectTvMode) updateAutodetectedTvMode();
|
||||
|
||||
myFrameRate = (myMode == TvMode::pal ? 15600.0 : 15720.0) /
|
||||
|
@ -322,6 +324,10 @@ void FrameManager::updateTvMode(TvMode mode)
|
|||
{
|
||||
if (mode == myMode) return;
|
||||
|
||||
#ifdef TIA_FRAMEMANAGER_DEBUG_LOG
|
||||
(cout << "TV mode switched to " << int(mode) << "\n").flush();
|
||||
#endif // TIA_FRAMEMANAGER_DEBUG_LOG
|
||||
|
||||
myMode = mode;
|
||||
|
||||
switch (myMode)
|
||||
|
@ -395,12 +401,6 @@ void FrameManager::setFixedHeight(uInt32 height)
|
|||
myFixedHeight = height;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 FrameManager::currentLine() const
|
||||
{
|
||||
return myState == State::frame ? myLineInState : 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 FrameManager::scanlines() const
|
||||
{
|
||||
|
|
|
@ -60,7 +60,10 @@ class FrameManager : public Serializable
|
|||
|
||||
void setFixedHeight(uInt32 height);
|
||||
|
||||
uInt32 currentLine() const;
|
||||
uInt32 getY() const
|
||||
{
|
||||
return myY;
|
||||
}
|
||||
|
||||
uInt32 scanlines() const;
|
||||
|
||||
|
@ -111,7 +114,7 @@ class FrameManager : public Serializable
|
|||
|
||||
void setState(State state);
|
||||
|
||||
void finalizeFrame(State state = State::waitForVsyncStart);
|
||||
void finalizeFrame();
|
||||
|
||||
void nextLineInVsync();
|
||||
|
||||
|
@ -128,6 +131,8 @@ class FrameManager : public Serializable
|
|||
uInt32 myCurrentFrameFinalLines;
|
||||
uInt32 myVsyncLines;
|
||||
float myFrameRate;
|
||||
uInt32 myY;
|
||||
bool myFramePending;
|
||||
|
||||
uInt32 myTotalFrames;
|
||||
uInt32 myFramesInMode;
|
||||
|
|
|
@ -925,12 +925,12 @@ void TIA::onFrameComplete()
|
|||
mySystem->m6502().stop();
|
||||
mySystem->resetCycles();
|
||||
|
||||
Int32 missingScanlines = myLastFrameHeight - myFrameManager.currentLine();
|
||||
Int32 missingScanlines = myLastFrameHeight - myFrameManager.getY();
|
||||
|
||||
if (missingScanlines > 0)
|
||||
memset(myCurrentFrameBuffer.get() + 160 * myFrameManager.currentLine(), 0, missingScanlines * 160);
|
||||
memset(myCurrentFrameBuffer.get() + 160 * myFrameManager.getY(), 0, missingScanlines * 160);
|
||||
|
||||
myLastFrameHeight = myFrameManager.currentLine();
|
||||
myLastFrameHeight = myFrameManager.getY();
|
||||
|
||||
// Recalculate framerate, attempting to auto-correct for scanline 'jumps'
|
||||
if(myAutoFrameEnabled)
|
||||
|
@ -1003,7 +1003,7 @@ void TIA::tickHblank()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TIA::tickHframe()
|
||||
{
|
||||
const uInt32 y = myFrameManager.currentLine();
|
||||
const uInt32 y = myFrameManager.getY();
|
||||
const bool lineNotCached = myLinesSinceChange < 2 || y == 0;
|
||||
const uInt32 x = myHctr - 68 + myXDelta;
|
||||
|
||||
|
@ -1027,7 +1027,7 @@ void TIA::applyRsync()
|
|||
|
||||
if (x > 0 && myFrameManager.isRendering()) {
|
||||
myXDelta = x - 157;
|
||||
memset(myCurrentFrameBuffer.get() + myFrameManager.currentLine() * 160 + x, 0, 160 - x);
|
||||
memset(myCurrentFrameBuffer.get() + myFrameManager.getY() * 160 + x, 0, 160 - x);
|
||||
}
|
||||
|
||||
myLinesSinceChange = 0;
|
||||
|
@ -1141,7 +1141,7 @@ void TIA::renderPixel(uInt32 x, uInt32 y, bool lineNotCached)
|
|||
void TIA::clearHmoveComb()
|
||||
{
|
||||
if (myFrameManager.isRendering() && myHstate == HState::blank)
|
||||
memset(myCurrentFrameBuffer.get() + myFrameManager.currentLine() * 160,
|
||||
memset(myCurrentFrameBuffer.get() + myFrameManager.getY() * 160,
|
||||
myColorHBlank, 8);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue