stella/src/emucore/tia/frame-manager/JitterEmulation.cxx

132 lines
3.7 KiB
C++

//============================================================================
//
// 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,
framesUntilDestabilization = 10,
minDeltaForJitter = 3,
maxJitter = 50
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
JitterEmulation::JitterEmulation() :
myYStart(0)
{}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void JitterEmulation::reset()
{
myLastFrameScanlines = 0;
myStableFrameFinalLines = -1;
myStableFrames = 0;
myStabilizationCounter = 0;
myDestabilizationCounter = 0;
myJitter = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void JitterEmulation::frameComplete(uInt32 scanlineCount)
{
if (scanlineCount != myStableFrameFinalLines) {
if (myDestabilizationCounter++ > Metrics::framesUntilDestabilization) myStableFrameFinalLines = -1;
if (scanlineCount == myLastFrameScanlines) {
if (++myStabilizationCounter >= Metrics::framesForStableHeight) {
if (myStableFrameFinalLines > 0) updateJitter(scanlineCount - myStableFrameFinalLines);
myStableFrameFinalLines = scanlineCount;
myDestabilizationCounter = 0;
}
}
else myStabilizationCounter = 0;
}
else myDestabilizationCounter = 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>(scanlineDifference, 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(myDestabilizationCounter);
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();
myDestabilizationCounter = in.getInt();
myJitter = in.getInt();
myJitterFactor = in.getInt();
myYStart = in.getInt();
}
catch (...)
{
cerr << "ERROR: JitterEmulation::load" << std::endl;
return false;
}
return true;
}