Add measured FPS to OSD, squash a bunch of minor bugs.

This commit is contained in:
Christian Speckner 2018-07-30 23:19:09 +02:00
parent de24815771
commit 3a5572d3b9
13 changed files with 113 additions and 75 deletions

View File

@ -17,7 +17,8 @@ MODULE_OBJS := \
src/common/StateManager.o \ src/common/StateManager.o \
src/common/ZipHandler.o \ src/common/ZipHandler.o \
src/common/AudioQueue.o \ src/common/AudioQueue.o \
src/common/AudioSettings.o src/common/AudioSettings.o \
src/common/FpsMeter.o
MODULE_DIRS += \ MODULE_DIRS += \
src/common src/common

View File

@ -157,6 +157,8 @@ void Debugger::quit(bool exitrom)
myOSystem.eventHandler().handleEvent(Event::LauncherMode, 1); myOSystem.eventHandler().handleEvent(Event::LauncherMode, 1);
else else
myOSystem.eventHandler().leaveDebugMode(); myOSystem.eventHandler().leaveDebugMode();
myOSystem.console().tia().clearPendingFrame();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -148,7 +148,6 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
// Note that this can be overridden if a format is forced // Note that this can be overridden if a format is forced
// For example, if a PAL ROM is forced to be NTSC, it will use NTSC-like // For example, if a PAL ROM is forced to be NTSC, it will use NTSC-like
// properties (60Hz, 262 scanlines, etc), but likely result in flicker // properties (60Hz, 262 scanlines, etc), but likely result in flicker
setTIAProperties();
if(myDisplayFormat == "NTSC") if(myDisplayFormat == "NTSC")
{ {
myCurrentFormat = 1; myCurrentFormat = 1;
@ -180,6 +179,8 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
myConsoleTiming = ConsoleTiming::secam; myConsoleTiming = ConsoleTiming::secam;
} }
setTIAProperties();
bool joyallow4 = myOSystem.settings().getBool("joyallow4"); bool joyallow4 = myOSystem.settings().getBool("joyallow4");
myOSystem.eventHandler().allowAllDirections(joyallow4); myOSystem.eventHandler().allowAllDirections(joyallow4);
@ -387,6 +388,7 @@ void Console::setFormat(uInt32 format)
myTIA->frameReset(); myTIA->frameReset();
initializeVideo(); // takes care of refreshing the screen initializeVideo(); // takes care of refreshing the screen
initializeAudio(); // ensure that audio synthesis is set up to match emulation speed initializeAudio(); // ensure that audio synthesis is set up to match emulation speed
myOSystem.resetFps(); // Reset FPS measurement
} }
myOSystem.frameBuffer().showMessage(message); myOSystem.frameBuffer().showMessage(message);
@ -975,7 +977,8 @@ void Console::generateColorLossPalette()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
float Console::getFramerate() const float Console::getFramerate() const
{ {
return myTIA->frameBufferFrameRate(); return
static_cast<float>(myEmulationTiming.linesPerSecond()) / myTIA->frameBufferScanlinesLastFrame();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -134,6 +134,12 @@ uInt32 EmulationTiming::cyclesPerSecond() const
return myCyclesPerSecond; return myCyclesPerSecond;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 EmulationTiming::linesPerSecond() const
{
return myLinesPerSecond;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 EmulationTiming::audioFragmentSize() const uInt32 EmulationTiming::audioFragmentSize() const
{ {
@ -181,7 +187,7 @@ void EmulationTiming::recalculate()
case ConsoleTiming::pal: case ConsoleTiming::pal:
case ConsoleTiming::secam: case ConsoleTiming::secam:
myCyclesPerSecond = uInt32(round(mySpeedFactor * 312 * 76 * 50) / 38); myAudioSampleRate = uInt32(round(mySpeedFactor * 312 * 76 * 50) / 38);
break; break;
default: default:
@ -204,4 +210,6 @@ void EmulationTiming::recalculate()
myPrebufferFragmentCount, myPrebufferFragmentCount,
discreteDivCeil(myMaxCyclesPerTimeslice * myAudioSampleRate, myAudioFragmentSize * myCyclesPerSecond) discreteDivCeil(myMaxCyclesPerTimeslice * myAudioSampleRate, myAudioFragmentSize * myCyclesPerSecond)
) + myAudioQueueExtraFragments; ) + myAudioQueueExtraFragments;
myLinesPerSecond = myCyclesPerSecond / 76;
} }

View File

@ -49,6 +49,8 @@ class EmulationTiming {
uInt32 cyclesPerFrame() const; uInt32 cyclesPerFrame() const;
uInt32 linesPerSecond() const;
uInt32 cyclesPerSecond() const; uInt32 cyclesPerSecond() const;
uInt32 audioFragmentSize() const; uInt32 audioFragmentSize() const;
@ -82,6 +84,7 @@ class EmulationTiming {
uInt32 myAudioSampleRate; uInt32 myAudioSampleRate;
uInt32 myAudioQueueCapacity; uInt32 myAudioQueueCapacity;
uInt32 myPrebufferFragmentCount; uInt32 myPrebufferFragmentCount;
uInt32 myLinesPerSecond;
float mySpeedFactor; float mySpeedFactor;

View File

@ -229,8 +229,8 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
// Create surfaces for TIA statistics and general messages // Create surfaces for TIA statistics and general messages
myStatsMsg.color = kColorInfo; myStatsMsg.color = kColorInfo;
myStatsMsg.w = font().getMaxCharWidth() * 30 + 3; myStatsMsg.w = font().getMaxCharWidth() * 40 + 3;
myStatsMsg.h = (font().getFontHeight() + 2) * 2; myStatsMsg.h = (font().getFontHeight() + 2) * 3;
if(!myStatsMsg.surface) if(!myStatsMsg.surface)
{ {
@ -361,7 +361,7 @@ void FrameBuffer::update(bool force)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::updateInEmulationMode() void FrameBuffer::updateInEmulationMode(float framesPerSecond)
{ {
// Update method that is specifically tailored to emulation mode // Update method that is specifically tailored to emulation mode
// Typically called from a thread, so it needs to be separate from // Typically called from a thread, so it needs to be separate from
@ -374,7 +374,7 @@ void FrameBuffer::updateInEmulationMode()
// Show frame statistics // Show frame statistics
if(myStatsMsg.enabled) if(myStatsMsg.enabled)
drawFrameStats(); drawFrameStats(framesPerSecond);
myLastScanlines = myOSystem.console().tia().frameBufferScanlinesLastFrame(); myLastScanlines = myOSystem.console().tia().frameBufferScanlinesLastFrame();
myPausedCount = 0; myPausedCount = 0;
@ -410,39 +410,50 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position,
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::drawFrameStats() void FrameBuffer::drawFrameStats(float framesPerSecond)
{ {
const ConsoleInfo& info = myOSystem.console().about(); const ConsoleInfo& info = myOSystem.console().about();
char msg[30];
uInt32 color; uInt32 color;
const int XPOS = 2, YPOS = 0; int xPos = 2, yPos = 0;
int xPos = XPOS; const int dy = font().getFontHeight() + 2;
ostringstream ss;
myStatsMsg.surface->invalidate(); myStatsMsg.surface->invalidate();
// draw scanlines // draw scanlines
color = myOSystem.console().tia().frameBufferScanlinesLastFrame() != myLastScanlines ? color = myOSystem.console().tia().frameBufferScanlinesLastFrame() != myLastScanlines ?
uInt32(kDbgColorRed) : myStatsMsg.color; uInt32(kDbgColorRed) : myStatsMsg.color;
std::snprintf(msg, 30, "%3u", myOSystem.console().tia().frameBufferScanlinesLastFrame());
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS, ss
<< myOSystem.console().tia().frameBufferScanlinesLastFrame()
<< " / "
<< std::fixed << std::setprecision(1) << myOSystem.console().getFramerate()
<< "Hz => "
<< info.DisplayFormat;
myStatsMsg.surface->drawString(font(), ss.str(), xPos, yPos,
myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor); myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor);
xPos += font().getStringWidth(msg);
// draw frequency yPos += dy;
std::snprintf(msg, 30, " => %s", info.DisplayFormat.c_str()); ss.str("");
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS,
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
xPos += font().getStringWidth(msg);
std::snprintf(msg, 30, " @ %5.2ffps", myOSystem.console().getFramerate()); ss
<< std::fixed << std::setprecision(1) << framesPerSecond
<< "fps @ "
<< std::fixed << std::setprecision(2) << 100 * myOSystem.settings().getFloat("speed")
<< "% speed";
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS, myStatsMsg.surface->drawString(font(), ss.str(), xPos, yPos,
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
// draw bankswitching type yPos += dy;
string bsinfo = info.BankSwitch + ss.str("");
(myOSystem.settings().getBool("dev.settings") ? "| Developer" : "");
myStatsMsg.surface->drawString(font(), bsinfo, XPOS, YPOS + font().getFontHeight(), ss << info.BankSwitch;
if (myOSystem.settings().getBool("dev.settings")) ss << "| Developer";
myStatsMsg.surface->drawString(font(), ss.str(), xPos, yPos,
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
myStatsMsg.surface->setDstPos(myImageRect.x() + 10, myImageRect.y() + 8); myStatsMsg.surface->setDstPos(myImageRect.x() + 10, myImageRect.y() + 8);

View File

@ -120,7 +120,7 @@ class FrameBuffer
/** /**
There is a dedicated update method for emulation mode. There is a dedicated update method for emulation mode.
*/ */
void updateInEmulationMode(); void updateInEmulationMode(float framesPerSecond);
/** /**
Shows a message onscreen. Shows a message onscreen.
@ -471,7 +471,7 @@ class FrameBuffer
private: private:
// Draws the frame stats overlay // Draws the frame stats overlay
void drawFrameStats(); void drawFrameStats(float framesPerSecond);
// Indicates the number of times the framebuffer was initialized // Indicates the number of times the framebuffer was initialized
uInt32 myInitializedCount; uInt32 myInitializedCount;

View File

@ -30,14 +30,13 @@
#include "CheatManager.hxx" #include "CheatManager.hxx"
#endif #endif
#include <chrono>
#include "FSNode.hxx" #include "FSNode.hxx"
#include "MD5.hxx" #include "MD5.hxx"
#include "Cart.hxx" #include "Cart.hxx"
#include "CartDetector.hxx" #include "CartDetector.hxx"
#include "FrameBuffer.hxx" #include "FrameBuffer.hxx"
#include "TIASurface.hxx" #include "TIASurface.hxx"
#include "TIAConstants.hxx"
#include "Settings.hxx" #include "Settings.hxx"
#include "PropsSet.hxx" #include "PropsSet.hxx"
#include "EventHandler.hxx" #include "EventHandler.hxx"
@ -60,10 +59,15 @@
using namespace std::chrono; using namespace std::chrono;
namespace {
constexpr uInt32 FPS_METER_QUEUE_SIZE = 100;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSystem::OSystem() OSystem::OSystem()
: myLauncherUsed(false), : myLauncherUsed(false),
myQuitLoop(false) myQuitLoop(false),
myFpsMeter(FPS_METER_QUEUE_SIZE)
{ {
// Get built-in features // Get built-in features
#ifdef SOUND_SUPPORT #ifdef SOUND_SUPPORT
@ -481,6 +485,12 @@ void OSystem::logMessage(const string& message, uInt8 level)
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::resetFps()
{
myFpsMeter.reset();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
unique_ptr<Console> OSystem::openConsole(const FilesystemNode& romfile, string& md5) unique_ptr<Console> OSystem::openConsole(const FilesystemNode& romfile, string& md5)
{ {
@ -651,7 +661,10 @@ double OSystem::dispatchEmulation(EmulationWorker& emulationWorker)
bool framePending = tia.newFramePending(); bool framePending = tia.newFramePending();
// ... and copy it to the frame buffer. It is important to do this before // ... and copy it to the frame buffer. It is important to do this before
// the worker is started to avoid racing. // the worker is started to avoid racing.
if (framePending) tia.renderToFrameBuffer(); if (framePending) {
myFpsMeter.render(tia.framesSinceLastRender());
tia.renderToFrameBuffer();
}
// Start emulation on a dedicated thread. It will do its own scheduling to sync 6507 and real time // Start emulation on a dedicated thread. It will do its own scheduling to sync 6507 and real time
// and will run until we stop the worker. // and will run until we stop the worker.
@ -665,7 +678,7 @@ double OSystem::dispatchEmulation(EmulationWorker& emulationWorker)
// Render the frame. This may block, but emulation will continue to run on the worker, so the // Render the frame. This may block, but emulation will continue to run on the worker, so the
// audio pipeline is kept fed :) // audio pipeline is kept fed :)
if (framePending) myFrameBuffer->updateInEmulationMode(); if (framePending) myFrameBuffer->updateInEmulationMode(myFpsMeter.fps());
// Stop the worker and wait until it has finished // Stop the worker and wait until it has finished
uInt64 totalCycles = emulationWorker.stop(); uInt64 totalCycles = emulationWorker.stop();
@ -691,11 +704,20 @@ void OSystem::mainLoop()
// The emulation worker // The emulation worker
EmulationWorker emulationWorker; EmulationWorker emulationWorker;
myFpsMeter.reset(TIAConstants::initialGarbageFrames);
for(;;) for(;;)
{ {
bool wasEmulation = myEventHandler->state() == EventHandlerState::EMULATION;
myEventHandler->poll(getTicks()); myEventHandler->poll(getTicks());
if(myQuitLoop) break; // Exit if the user wants to quit if(myQuitLoop) break; // Exit if the user wants to quit
if (!wasEmulation && myEventHandler->state() == EventHandlerState::EMULATION) {
myFpsMeter.reset();
virtualTime = high_resolution_clock::now();
}
double timesliceSeconds; double timesliceSeconds;
if (myEventHandler->state() == EventHandlerState::EMULATION) if (myEventHandler->state() == EventHandlerState::EMULATION)

View File

@ -40,9 +40,12 @@ class StateManager;
class VideoDialog; class VideoDialog;
class EmulationWorker; class EmulationWorker;
#include <chrono>
#include "FSNode.hxx" #include "FSNode.hxx"
#include "FrameBufferConstants.hxx" #include "FrameBufferConstants.hxx"
#include "EventHandlerConstants.hxx" #include "EventHandlerConstants.hxx"
#include "FpsMeter.hxx"
#include "bspf.hxx" #include "bspf.hxx"
#include "AudioSettings.hxx" #include "AudioSettings.hxx"
@ -367,6 +370,11 @@ class OSystem
*/ */
const string& logMessages() const { return myLogMessages; } const string& logMessages() const { return myLogMessages; }
/**
Reset FPS measurement.
*/
void resetFps();
public: public:
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// The following methods are system-specific and can be overrided in // The following methods are system-specific and can be overrided in
@ -510,6 +518,8 @@ class OSystem
string myFeatures; string myFeatures;
string myBuildInfo; string myBuildInfo;
FpsMeter myFpsMeter;
private: private:
/** /**
Creates the various framebuffers/renderers available in this system. Creates the various framebuffers/renderers available in this system.

View File

@ -181,10 +181,9 @@ void TIA::reset()
frameReset(); // Recalculate the size of the display frameReset(); // Recalculate the size of the display
} }
myFrontBufferFrameRate = myFrameBufferFrameRate = 0;
myFrontBufferScanlines = myFrameBufferScanlines = 0; myFrontBufferScanlines = myFrameBufferScanlines = 0;
myNewFramePending = false; myFramesSinceLastRender = 0;
// Must be done last, after all other items have reset // Must be done last, after all other items have reset
enableFixedColors(mySettings.getBool(mySettings.getBool("dev.settings") ? "dev.debugcolors" : "plr.debugcolors")); enableFixedColors(mySettings.getBool(mySettings.getBool("dev.settings") ? "dev.debugcolors" : "plr.debugcolors"));
@ -293,8 +292,6 @@ bool TIA::save(Serializer& out) const
out.putInt(myFrameBufferScanlines); out.putInt(myFrameBufferScanlines);
out.putInt(myFrontBufferScanlines); out.putInt(myFrontBufferScanlines);
out.putDouble(myFrameBufferFrameRate);
out.putDouble(myFrontBufferFrameRate);
} }
catch(...) catch(...)
{ {
@ -366,8 +363,6 @@ bool TIA::load(Serializer& in)
myFrameBufferScanlines = in.getInt(); myFrameBufferScanlines = in.getInt();
myFrontBufferScanlines = in.getInt(); myFrontBufferScanlines = in.getInt();
myFrameBufferFrameRate = in.getDouble();
myFrontBufferFrameRate = in.getDouble();
} }
catch(...) catch(...)
{ {
@ -799,7 +794,7 @@ bool TIA::saveDisplay(Serializer& out) const
out.putByteArray(myFramebuffer, 160* TIAConstants::frameBufferHeight); out.putByteArray(myFramebuffer, 160* TIAConstants::frameBufferHeight);
out.putByteArray(myBackBuffer, 160 * TIAConstants::frameBufferHeight); out.putByteArray(myBackBuffer, 160 * TIAConstants::frameBufferHeight);
out.putByteArray(myFrontBuffer, 160 * TIAConstants::frameBufferHeight); out.putByteArray(myFrontBuffer, 160 * TIAConstants::frameBufferHeight);
out.putBool(myNewFramePending); out.putInt(myFramesSinceLastRender);
} }
catch(...) catch(...)
{ {
@ -819,7 +814,7 @@ bool TIA::loadDisplay(Serializer& in)
in.getByteArray(myFramebuffer, 160 * TIAConstants::frameBufferHeight); in.getByteArray(myFramebuffer, 160 * TIAConstants::frameBufferHeight);
in.getByteArray(myBackBuffer, 160 * TIAConstants::frameBufferHeight); in.getByteArray(myBackBuffer, 160 * TIAConstants::frameBufferHeight);
in.getByteArray(myFrontBuffer, 160 * TIAConstants::frameBufferHeight); in.getByteArray(myFrontBuffer, 160 * TIAConstants::frameBufferHeight);
myNewFramePending = in.getBool(); myFramesSinceLastRender = in.getInt();
} }
catch(...) catch(...)
{ {
@ -841,11 +836,12 @@ void TIA::update(DispatchResult& result, uInt64 maxCycles)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::renderToFrameBuffer() void TIA::renderToFrameBuffer()
{ {
if (!myNewFramePending) return; if (myFramesSinceLastRender == 0) return;
myFramesSinceLastRender = 0;
memcpy(myFramebuffer, myFrontBuffer, 160 * TIAConstants::frameBufferHeight); memcpy(myFramebuffer, myFrontBuffer, 160 * TIAConstants::frameBufferHeight);
myFrameBufferFrameRate = myFrontBufferFrameRate;
myFrameBufferScanlines = myFrontBufferScanlines; myFrameBufferScanlines = myFrontBufferScanlines;
} }
@ -1198,10 +1194,9 @@ void TIA::onFrameComplete()
memcpy(myFrontBuffer, myBackBuffer, 160 * TIAConstants::frameBufferHeight); memcpy(myFrontBuffer, myBackBuffer, 160 * TIAConstants::frameBufferHeight);
myFrontBufferFrameRate = frameRate();
myFrontBufferScanlines = scanlinesLastFrame(); myFrontBufferScanlines = scanlinesLastFrame();
myNewFramePending = true; myFramesSinceLastRender++;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -207,7 +207,17 @@ class TIA : public Device
/** /**
Did we generate a new frame? Did we generate a new frame?
*/ */
bool newFramePending() { return myNewFramePending; } bool newFramePending() { return myFramesSinceLastRender > 0; }
/**
* Clear any pending frames.
*/
void clearPendingFrame() { myFramesSinceLastRender = 0; }
/**
The number of frames since we did last render to the front buffer.
*/
uInt32 framesSinceLastRender() { return myFramesSinceLastRender; }
/** /**
Render the pending frame to the framebuffer and clear the flag. Render the pending frame to the framebuffer and clear the flag.
@ -248,13 +258,6 @@ class TIA : public Device
*/ */
ConsoleTiming consoleTiming() const { return myConsole.timing(); } ConsoleTiming consoleTiming() const { return myConsole.timing(); }
float frameRate() const { return myFrameManager ? myFrameManager->frameRate() : 0; }
/**
The same, but for the frame in the frame buffer.
*/
float frameBufferFrameRate() const { return myFrameBufferFrameRate; }
/** /**
Enables/disables color-loss for PAL modes only. Enables/disables color-loss for PAL modes only.
@ -694,10 +697,9 @@ class TIA : public Device
// We snapshot frame statistics when the back buffer is copied to the front buffer // We snapshot frame statistics when the back buffer is copied to the front buffer
// and when the front buffer is copied to the frame buffer // and when the front buffer is copied to the frame buffer
uInt32 myFrontBufferScanlines, myFrameBufferScanlines; uInt32 myFrontBufferScanlines, myFrameBufferScanlines;
float myFrontBufferFrameRate, myFrameBufferFrameRate;
// Did we emit a frame? // Frames since the last time a frame was rendered to the render buffer
bool myNewFramePending; uInt32 myFramesSinceLastRender;
/** /**
* Setting this to true injects random values into undefined reads. * Setting this to true injects random values into undefined reads.

View File

@ -37,8 +37,6 @@ void AbstractFrameManager::reset()
myCurrentFrameFinalLines = 0; myCurrentFrameFinalLines = 0;
myPreviousFrameFinalLines = 0; myPreviousFrameFinalLines = 0;
myTotalFrames = 0; myTotalFrames = 0;
myFrameRate = 0;
myFrameRate = 60.0;
onReset(); onReset();
} }
@ -101,9 +99,6 @@ void AbstractFrameManager::notifyFrameComplete()
myTotalFrames++; myTotalFrames++;
if (myOnFrameComplete) myOnFrameComplete(); if (myOnFrameComplete) myOnFrameComplete();
myFrameRate = (layout() == FrameLayout::pal ? 15600.0 : 15720.0) /
myCurrentFrameFinalLines;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -130,7 +125,6 @@ bool AbstractFrameManager::save(Serializer& out) const
out.putInt(myPreviousFrameFinalLines); out.putInt(myPreviousFrameFinalLines);
out.putInt(myTotalFrames); out.putInt(myTotalFrames);
out.putInt(uInt32(myLayout)); out.putInt(uInt32(myLayout));
out.putDouble(myFrameRate);
return onSave(out); return onSave(out);
} }
@ -155,7 +149,6 @@ bool AbstractFrameManager::load(Serializer& in)
myPreviousFrameFinalLines = in.getInt(); myPreviousFrameFinalLines = in.getInt();
myTotalFrames = in.getInt(); myTotalFrames = in.getInt();
myLayout = FrameLayout(in.getInt()); myLayout = FrameLayout(in.getInt());
myFrameRate = float(in.getDouble());
return onLoad(in); return onLoad(in);
} }

View File

@ -107,13 +107,6 @@ class AbstractFrameManager : public Serializable
*/ */
FrameLayout layout() const { return myLayout; } FrameLayout layout() const { return myLayout; }
/**
* The current frame rate. This is calculated dynamically from the number of
* scanlines in the last frames and used to control sleep time in the
* dispatch loop.
*/
float frameRate() const { return myFrameRate; }
/** /**
* Save state. * Save state.
*/ */
@ -289,11 +282,6 @@ class AbstractFrameManager : public Serializable
*/ */
uInt32 myTotalFrames; uInt32 myTotalFrames;
/**
* Frame rate (see above.)
*/
float myFrameRate;
private: private:
/** /**