mirror of https://github.com/stella-emu/stella.git
Frame manager fixes
* Don't wait until next line before starting frame after vblank is deactivated -> fixes white line on top of time pilot * Make ystart match stella 4 conventions
This commit is contained in:
parent
bf014c8e70
commit
8f93704559
|
@ -297,7 +297,12 @@ uInt32 FrameManager::ystart() const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameManager::setVblank(bool vblank)
|
||||
{
|
||||
myVblankManager.setVblank(vblank);
|
||||
if (myState == State::waitForFrameStart) {
|
||||
if (myVblankManager.setVblankDuringVblank(vblank, myTotalFrames <= Metrics::initialGarbageFrames)) {
|
||||
setState(State::frame);
|
||||
}
|
||||
} else
|
||||
myVblankManager.setVblank(vblank);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -835,6 +835,11 @@ void TIA::onFrameStart()
|
|||
{
|
||||
swapBuffers();
|
||||
|
||||
const Int32 x = myHctr - 68;
|
||||
|
||||
if (x > 0)
|
||||
memset(myCurrentFrameBuffer.get() + 160 * myFrameManager.getY(), 0, x);
|
||||
|
||||
for (uInt8 i = 0; i < 4; i++)
|
||||
updatePaddle(i);
|
||||
}
|
||||
|
@ -845,7 +850,7 @@ void TIA::onFrameComplete()
|
|||
mySystem->m6502().stop();
|
||||
mySystem->resetCycles();
|
||||
|
||||
Int32 missingScanlines = myLastFrameHeight[0] - myFrameManager.getY();
|
||||
const Int32 missingScanlines = myLastFrameHeight[0] - myFrameManager.getY();
|
||||
|
||||
if (missingScanlines > 0)
|
||||
memset(myCurrentFrameBuffer.get() + 160 * myFrameManager.getY(), 0, missingScanlines * 160);
|
||||
|
|
|
@ -44,6 +44,7 @@ void VblankManager::reset()
|
|||
myStableVblankFrames = 0;
|
||||
myVblankViolated = false;
|
||||
myLastVblankLines = 0;
|
||||
myIsRunning = false;
|
||||
|
||||
if (myMode != VblankMode::fixed) myMode = VblankMode::floating;
|
||||
}
|
||||
|
@ -52,13 +53,63 @@ void VblankManager::reset()
|
|||
void VblankManager::start()
|
||||
{
|
||||
myCurrentLine = 0;
|
||||
myIsRunning = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool VblankManager::nextLine(bool isGarbageFrame)
|
||||
{
|
||||
if (!myIsRunning) return false;
|
||||
|
||||
myCurrentLine++;
|
||||
|
||||
const bool transition =
|
||||
myMode == VblankMode::fixed ? (myCurrentLine >= myYstart) : shouldTransition(isGarbageFrame);
|
||||
|
||||
if (transition) myIsRunning = false;
|
||||
|
||||
return transition;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void VblankManager::setVblankLines(uInt32 vblankLines)
|
||||
{
|
||||
myVblankLines = vblankLines;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void VblankManager::setYstart(uInt32 ystart)
|
||||
{
|
||||
if (ystart == myYstart) return;
|
||||
|
||||
myYstart = ystart;
|
||||
|
||||
myMode = ystart ? VblankMode::fixed : VblankMode::floating;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void VblankManager::setVblank(bool vblank)
|
||||
{
|
||||
myVblank = vblank;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool VblankManager::setVblankDuringVblank(bool vblank, bool isGarbageFrame)
|
||||
{
|
||||
const bool oldVblank = myVblank;
|
||||
|
||||
myVblank = vblank;
|
||||
if (!myIsRunning || vblank || oldVblank == myVblank) return false;
|
||||
|
||||
const bool transition = shouldTransition(isGarbageFrame);
|
||||
if (transition) myIsRunning = false;
|
||||
|
||||
return transition;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool VblankManager::shouldTransition(bool isGarbageFrame)
|
||||
{
|
||||
bool shouldTransition = myCurrentLine >= (myVblank ? myVblankLines : myVblankLines - Metrics::maxUnderscan);
|
||||
bool transition = false;
|
||||
|
||||
|
@ -114,42 +165,14 @@ bool VblankManager::nextLine(bool isGarbageFrame)
|
|||
|
||||
break;
|
||||
|
||||
case VblankMode::fixed:
|
||||
if (myCurrentLine > myYstart) transition = true;
|
||||
default:
|
||||
transition = false;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return transition;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void VblankManager::setVblankLines(uInt32 vblankLines)
|
||||
{
|
||||
myVblankLines = vblankLines;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void VblankManager::setYstart(uInt32 ystart)
|
||||
{
|
||||
if (ystart == myYstart) return;
|
||||
|
||||
myYstart = ystart;
|
||||
|
||||
myMode = ystart ? VblankMode::fixed : VblankMode::floating;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void VblankManager::setVblank(bool vblank)
|
||||
{
|
||||
#ifdef TIA_VBLANK_MANAGER_DEBUG_LOG
|
||||
if (myVblank != vblank)
|
||||
(cout << "vblank " << myVblank << " -> " << vblank << ": state " << int(myState) << " @ " << myLineInState << "\n").flush();
|
||||
#endif
|
||||
|
||||
myVblank = vblank;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// TODO: implement this once the class is finalized
|
||||
bool VblankManager::save(Serializer& out) const
|
||||
|
|
|
@ -42,6 +42,8 @@ class VblankManager : public Serializable
|
|||
|
||||
void setVblank(bool vblank);
|
||||
|
||||
bool setVblankDuringVblank(bool vblank, bool isGarbageFrame);
|
||||
|
||||
bool vblank() const { return myVblank; }
|
||||
|
||||
uInt32 currentLine() const {return myCurrentLine; };
|
||||
|
@ -61,6 +63,10 @@ class VblankManager : public Serializable
|
|||
fixed
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
bool shouldTransition(bool isGarbageFrame);
|
||||
|
||||
private:
|
||||
|
||||
uInt32 myVblankLines;
|
||||
|
@ -75,6 +81,8 @@ class VblankManager : public Serializable
|
|||
uInt8 myStableVblankFrames;
|
||||
bool myVblankViolated;
|
||||
|
||||
bool myIsRunning;
|
||||
|
||||
private:
|
||||
|
||||
VblankManager(const VblankManager&) = delete;
|
||||
|
|
Loading…
Reference in New Issue