Reenable jitter.

This commit is contained in:
Christian Speckner 2017-10-15 00:11:19 +02:00
parent 0e5525223b
commit 640da16a2a
6 changed files with 239 additions and 62 deletions

View File

@ -98,6 +98,13 @@ class FrameLayoutDetector: public AbstractFrameManager {
*/
uInt32 myLinesWaitingForVsyncToStart;
private:
FrameLayoutDetector(const FrameLayoutDetector&) = delete;
FrameLayoutDetector(FrameLayoutDetector&&) = delete;
FrameLayoutDetector& operator=(const FrameLayoutDetector&) = delete;
FrameLayoutDetector& operator=(FrameLayoutDetector&&) = delete;
};
#endif // TIA_FRAME_LAYOUT_DETECTOR

View File

@ -58,11 +58,15 @@ void FrameManager::onReset()
myStableFrameLines = -1;
myStableFrameHeightCountdown = 0;
myJitterEmulation.reset();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::onNextLine()
{
Int32 jitter;
State previousState = myState;
myLineInState++;
@ -83,7 +87,10 @@ void FrameManager::onNextLine()
break;
case State::waitForFrameStart:
if (myLineInState >= myYStart) setState(State::frame);
jitter =
(myJitterEnabled && myTotalFrames > Metrics::initialGarbageFrames) ? myJitterEmulation.jitter() : 0;
if (myLineInState >= (myYStart + jitter)) setState(State::frame);
break;
case State::frame:
@ -111,6 +118,13 @@ Int32 FrameManager::missingScanlines() const
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::setYstart(uInt32 ystart)
{
myYStart = ystart;
myJitterEmulation.setYStart(ystart);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::onSetVsync()
{
@ -128,7 +142,8 @@ void FrameManager::setState(FrameManager::State state)
switch (myState) {
case State::waitForFrameStart:
finalizeFrame();
notifyFrameComplete();
myJitterEmulation.frameComplete(myCurrentFrameFinalLines);
notifyFrameStart();
myVsyncLines = 0;
@ -146,45 +161,6 @@ void FrameManager::setState(FrameManager::State state)
updateIsRendering();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::finalizeFrame()
{
if (myCurrentFrameTotalLines != (uInt32)myStableFrameLines) {
if (myCurrentFrameTotalLines == myCurrentFrameFinalLines) {
if (++myStableFrameHeightCountdown >= Metrics::framesForStableHeight) {
if (myStableFrameLines >= 0) {
handleJitter(myCurrentFrameTotalLines - myStableFrameLines);
}
myStableFrameLines = myCurrentFrameTotalLines;
}
}
else myStableFrameHeightCountdown = 0;
}
notifyFrameComplete();
#ifdef TIA_FRAMEMANAGER_DEBUG_LOG
(cout << "frame complete @ " << myLineInState << " (" << myCurrentFrameFinalLines << " total)" << "\n").flush();
#endif // TIA_FRAMEMANAGER_DEBUG_LOG
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::handleJitter(Int32 scanlineDifference)
{
/*
if (
(uInt32)abs(scanlineDifference) < Metrics::minDeltaForJitter ||
!myJitterEnabled ||
myTotalFrames < Metrics::initialGarbageFrames
) return;
myVblankManager.setJitter(scanlineDifference);
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: kill this with fire once frame manager refactoring is complete
void FrameManager::onLayoutChange()
@ -219,16 +195,6 @@ void FrameManager::setFixedHeight(uInt32 height)
myHeight = myFixedHeight > 0 ? myFixedHeight : (myKernelLines + Metrics::visibleOverscan);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::enableJitter(bool enabled)
{
/*
myJitterEnabled = enabled;
if (!enabled) myVblankManager.setJitter(0);
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::updateIsRendering() {
myIsRendering = myState == State::frame;
@ -237,6 +203,8 @@ void FrameManager::updateIsRendering() {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameManager::onSave(Serializer& out) const
{
if (!myJitterEmulation.save(out)) return false;
out.putInt(uInt32(myState));
out.putInt(myLineInState);
out.putInt(myVsyncLines);
@ -261,6 +229,8 @@ bool FrameManager::onSave(Serializer& out) const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameManager::onLoad(Serializer& in)
{
if (!myJitterEmulation.load(in)) return false;
myState = State(in.getInt());
myLineInState = in.getInt();
myVsyncLines = in.getInt();

View File

@ -21,6 +21,7 @@
#include "AbstractFrameManager.hxx"
#include "TIAConstants.hxx"
#include "bspf.hxx"
#include "JitterEmulation.hxx"
class FrameManager: public AbstractFrameManager {
public:
@ -29,11 +30,11 @@ class FrameManager: public AbstractFrameManager {
public:
void setJitterFactor(uInt8 factor) override { }
void setJitterFactor(uInt8 factor) override { myJitterEmulation.setJitterFactor(factor); }
bool jitterEnabled() const override { return myJitterEnabled; }
void enableJitter(bool enabled) override;
void enableJitter(bool enabled) override { myJitterEnabled = enabled; }
uInt32 height() const override { return myHeight; };
@ -45,7 +46,7 @@ class FrameManager: public AbstractFrameManager {
Int32 missingScanlines() const override;
void setYstart(uInt32 ystart) override { myYStart = ystart; }
void setYstart(uInt32 ystart) override;
uInt32 ystart() const override { return myYStart; }
@ -80,12 +81,6 @@ class FrameManager: public AbstractFrameManager {
void setState(State state);
void finalizeFrame();
void nextLineInVsync();
void handleJitter(Int32 scanlineDifference);
void updateIsRendering();
private:
@ -108,6 +103,8 @@ class FrameManager: public AbstractFrameManager {
Int32 myStableFrameLines;
uInt8 myStableFrameHeightCountdown;
JitterEmulation myJitterEmulation;
private:
FrameManager(const FrameManager&) = delete;

View File

@ -0,0 +1,122 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include "JitterEmulation.hxx"
enum Metrics: uInt32 {
framesForStableHeight = 2,
minDeltaForJitter = 3,
maxJitter = 50
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
JitterEmulation::JitterEmulation() :
myYStart(0)
{}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void JitterEmulation::reset()
{
myLastFrameScanlines = 0;
myStableFrameFinalLines = 0;
myStableFrames = 0;
myStabilizationCounter = 0;
myJitter = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void JitterEmulation::frameComplete(uInt32 scanlineCount)
{
if (scanlineCount != myStableFrameFinalLines) {
if (scanlineCount == myLastFrameScanlines) {
if (++myStabilizationCounter >= Metrics::framesForStableHeight) {
if (myStableFrameFinalLines > 0) updateJitter(scanlineCount - myStableFrameFinalLines);
myStableFrameFinalLines = scanlineCount;
}
}
else myStabilizationCounter = 0;
}
myLastFrameScanlines = scanlineCount;
if (myJitter > 0) myJitter = std::max(myJitter - myJitterFactor, 0);
if (myJitter < 0) myJitter = std::min(myJitter + myJitterFactor, 0);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void JitterEmulation::updateJitter(Int32 scanlineDifference)
{
if ((uInt32)abs(scanlineDifference) < Metrics::minDeltaForJitter) return;
Int32 jitter = std::min<Int32>(jitter, Metrics::maxJitter);
jitter = std::max<Int32>(jitter, -myYStart);
if (jitter > 0) jitter += myJitterFactor;
if (jitter < 0) jitter -= myJitterFactor;
if (abs(jitter) > abs(myJitter)) myJitter = jitter;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool JitterEmulation::save(Serializer& out) const
{
try {
out.putString(name());
out.putInt(myLastFrameScanlines);
out.putInt(myStableFrameFinalLines);
out.putInt(myStableFrames);
out.putInt(myStabilizationCounter);
out.putInt(myJitter);
out.putInt(myJitterFactor);
out.putInt(myYStart);
}
catch(...) {
cerr << "ERROR: JitterEmulation::save" << std::endl;
return false;
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool JitterEmulation::load(Serializer& in)
{
try {
if (in.getString() != name()) return false;
myLastFrameScanlines = in.getInt();
myStableFrameFinalLines = in.getInt();
myStableFrames = in.getInt();
myStabilizationCounter = in.getInt();
myJitter = in.getInt();
myJitterFactor = in.getInt();
myYStart = in.getInt();
}
catch (...)
{
cerr << "ERROR: JitterEmulation::load" << std::endl;
return false;
}
return true;
}

View File

@ -0,0 +1,81 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef TIA_JITTER_EMULATION
#define TIA_JITTER_EMULATION
#include "bspf.hxx"
#include "Serializable.hxx"
class JitterEmulation: public Serializable {
public:
JitterEmulation();
public:
void reset();
void frameComplete(uInt32 scanlineCount);
void setJitterFactor(Int32 factor) { myJitterFactor = factor; }
Int32 jitter() const { return myJitter; }
void setYStart(uInt32 ystart) { myYStart = ystart; }
/**
* Save state.
*/
bool save(Serializer& out) const override;
/**
* Restore state.
*/
bool load(Serializer& in) override;
string name() const override { return "JitterEmulation"; }
private:
void updateJitter(Int32 scanlineDifference);
private:
uInt32 myLastFrameScanlines;
uInt32 myStableFrameFinalLines;
uInt32 myStableFrames;
uInt32 myStabilizationCounter;
Int32 myJitter;
Int32 myJitterFactor;
uInt32 myYStart;
private:
JitterEmulation(const JitterEmulation&) = delete;
JitterEmulation(JitterEmulation&&) = delete;
JitterEmulation& operator=(const JitterEmulation&) = delete;
JitterEmulation& operator=(JitterEmulation&&) = delete;
};
#endif // TIA_JITTER_EMULATION

View File

@ -2,10 +2,10 @@ MODULE := src/emucore/tia/frame-manager
MODULE_OBJS := \
src/emucore/tia/frame-manager/FrameManager.o \
src/emucore/tia/frame-manager/VblankManager.o \
src/emucore/tia/frame-manager/AbstractFrameManager.o \
src/emucore/tia/frame-manager/FrameLayoutDetector.o \
src/emucore/tia/frame-manager/YStartDetector.o
src/emucore/tia/frame-manager/YStartDetector.o \
src/emucore/tia/frame-manager/JitterEmulation.o
MODULE_DIRS += \
src/emucore/tia/frame-manager