Make sure that every frame draws all scanlines in the height of the window.

If the ROM doesn't reach that far, blank out all further scanlines.

Optimize FrameManager::height() method.
This commit is contained in:
Stephen Anthony 2017-03-11 16:53:04 -03:30
parent 4a71e48a07
commit 68f9831061
4 changed files with 26 additions and 16 deletions

View File

@ -56,6 +56,7 @@ uInt8 FrameManager::initialGarbageFrames()
FrameManager::FrameManager() FrameManager::FrameManager()
: myMode(TvMode::pal), : myMode(TvMode::pal),
myAutodetectTvMode(true), myAutodetectTvMode(true),
myHeight(0),
myFixedHeight(0) myFixedHeight(0)
{ {
updateTvMode(TvMode::ntsc); updateTvMode(TvMode::ntsc);
@ -120,8 +121,11 @@ void FrameManager::nextLine()
break; break;
case State::frame: case State::frame:
if (myLineInState >= (myFixedHeight > 0 ? myFixedHeight : (myKernelLines + Metrics::visibleOverscan))) if (myLineInState >= myHeight)
{
myLastY = ystart() + myY; // Last line drawn in this frame
setState(State::waitForVsyncStart); setState(State::waitForVsyncStart);
}
break; break;
default: default:
@ -131,6 +135,15 @@ void FrameManager::nextLine()
if (myState == State::frame && previousState == State::frame) myY++; if (myState == State::frame && previousState == State::frame) myY++;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameManager::missingScanlines() const
{
if (myLastY == ystart() + myY)
return 0;
else
return myHeight - myY;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::setVsync(bool vsync) void FrameManager::setVsync(bool vsync)
{ {
@ -278,6 +291,7 @@ 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
myVblankManager.setVblankLines(myVblankLines); myVblankManager.setVblankLines(myVblankLines);
} }
@ -294,9 +308,10 @@ void FrameManager::setVblank(bool vblank)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameManager::height() const void FrameManager::setFixedHeight(uInt32 height)
{ {
return myFixedHeight > 0 ? myFixedHeight : (myKernelLines + Metrics::visibleOverscan); myFixedHeight = height;
myHeight = myFixedHeight > 0 ? myFixedHeight : (myKernelLines + Metrics::visibleOverscan);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -57,9 +57,9 @@ class FrameManager : public Serializable
bool vsync() const { return myVsync; } bool vsync() const { return myVsync; }
uInt32 height() const; uInt32 height() const { return myHeight; }
void setFixedHeight(uInt32 height) { myFixedHeight = height; } void setFixedHeight(uInt32 height);
uInt32 getY() const { return myY; } uInt32 getY() const { return myY; }
@ -67,6 +67,8 @@ class FrameManager : public Serializable
uInt32 scanlinesLastFrame() const { return myCurrentFrameFinalLines; } uInt32 scanlinesLastFrame() const { return myCurrentFrameFinalLines; }
uInt32 missingScanlines() const;
uInt32 frameCount() const { return myTotalFrames; } uInt32 frameCount() const { return myTotalFrames; }
float frameRate() const { return myFrameRate; } float frameRate() const { return myFrameRate; }
@ -135,7 +137,7 @@ class FrameManager : public Serializable
uInt32 myCurrentFrameFinalLines; uInt32 myCurrentFrameFinalLines;
uInt32 myVsyncLines; uInt32 myVsyncLines;
float myFrameRate; float myFrameRate;
uInt32 myY; uInt32 myY, myLastY;
bool myFramePending; bool myFramePending;
uInt32 myTotalFrames; uInt32 myTotalFrames;
@ -148,6 +150,7 @@ class FrameManager : public Serializable
uInt32 myKernelLines; uInt32 myKernelLines;
uInt32 myOverscanLines; uInt32 myOverscanLines;
uInt32 myFrameLines; uInt32 myFrameLines;
uInt32 myHeight;
uInt32 myFixedHeight; uInt32 myFixedHeight;
private: private:

View File

@ -117,7 +117,6 @@ void TIA::reset()
myLastCycle = 0; myLastCycle = 0;
mySubClock = 0; mySubClock = 0;
myXDelta = 0; myXDelta = 0;
myLastFrameHeight[0] = myLastFrameHeight[1] = 0;
myBackground.reset(); myBackground.reset();
myPlayfield.reset(); myPlayfield.reset();
@ -827,10 +826,6 @@ void TIA::updateEmulation()
void TIA::swapBuffers() void TIA::swapBuffers()
{ {
myCurrentFrameBuffer.swap(myPreviousFrameBuffer); myCurrentFrameBuffer.swap(myPreviousFrameBuffer);
uInt32 tmp = myLastFrameHeight[0];
myLastFrameHeight[0] = myLastFrameHeight[1];
myLastFrameHeight[1] = tmp;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -853,13 +848,11 @@ void TIA::onFrameComplete()
mySystem->m6502().stop(); mySystem->m6502().stop();
mySystem->resetCycles(); mySystem->resetCycles();
const Int32 missingScanlines = myLastFrameHeight[0] - myFrameManager.getY(); // Blank out any extra lines not drawn this frame
const uInt32 missingScanlines = myFrameManager.missingScanlines();
if (missingScanlines > 0) if (missingScanlines > 0)
memset(myCurrentFrameBuffer.get() + 160 * myFrameManager.getY(), 0, missingScanlines * 160); memset(myCurrentFrameBuffer.get() + 160 * myFrameManager.getY(), 0, missingScanlines * 160);
myLastFrameHeight[0] = myFrameManager.getY();
// Recalculate framerate, attempting to auto-correct for scanline 'jumps' // Recalculate framerate, attempting to auto-correct for scanline 'jumps'
if(myAutoFrameEnabled) if(myAutoFrameEnabled)
myConsole.setFramerate(myFrameManager.frameRate()); myConsole.setFramerate(myFrameManager.frameRate());

View File

@ -445,7 +445,6 @@ class TIA : public Device
// Pointer to the current and previous frame buffers // Pointer to the current and previous frame buffers
BytePtr myCurrentFrameBuffer; BytePtr myCurrentFrameBuffer;
BytePtr myPreviousFrameBuffer; BytePtr myPreviousFrameBuffer;
uInt32 myLastFrameHeight[2];
Background myBackground; Background myBackground;
Playfield myPlayfield; Playfield myPlayfield;