mirror of https://github.com/stella-emu/stella.git
Add measured FPS to OSD, squash a bunch of minor bugs.
This commit is contained in:
parent
de24815771
commit
3a5572d3b9
|
@ -17,7 +17,8 @@ MODULE_OBJS := \
|
|||
src/common/StateManager.o \
|
||||
src/common/ZipHandler.o \
|
||||
src/common/AudioQueue.o \
|
||||
src/common/AudioSettings.o
|
||||
src/common/AudioSettings.o \
|
||||
src/common/FpsMeter.o
|
||||
|
||||
MODULE_DIRS += \
|
||||
src/common
|
||||
|
|
|
@ -157,6 +157,8 @@ void Debugger::quit(bool exitrom)
|
|||
myOSystem.eventHandler().handleEvent(Event::LauncherMode, 1);
|
||||
else
|
||||
myOSystem.eventHandler().leaveDebugMode();
|
||||
|
||||
myOSystem.console().tia().clearPendingFrame();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -148,7 +148,6 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
|
|||
// 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
|
||||
// properties (60Hz, 262 scanlines, etc), but likely result in flicker
|
||||
setTIAProperties();
|
||||
if(myDisplayFormat == "NTSC")
|
||||
{
|
||||
myCurrentFormat = 1;
|
||||
|
@ -180,6 +179,8 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
|
|||
myConsoleTiming = ConsoleTiming::secam;
|
||||
}
|
||||
|
||||
setTIAProperties();
|
||||
|
||||
bool joyallow4 = myOSystem.settings().getBool("joyallow4");
|
||||
myOSystem.eventHandler().allowAllDirections(joyallow4);
|
||||
|
||||
|
@ -387,6 +388,7 @@ void Console::setFormat(uInt32 format)
|
|||
myTIA->frameReset();
|
||||
initializeVideo(); // takes care of refreshing the screen
|
||||
initializeAudio(); // ensure that audio synthesis is set up to match emulation speed
|
||||
myOSystem.resetFps(); // Reset FPS measurement
|
||||
}
|
||||
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
|
@ -975,7 +977,8 @@ void Console::generateColorLossPalette()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
float Console::getFramerate() const
|
||||
{
|
||||
return myTIA->frameBufferFrameRate();
|
||||
return
|
||||
static_cast<float>(myEmulationTiming.linesPerSecond()) / myTIA->frameBufferScanlinesLastFrame();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -134,6 +134,12 @@ uInt32 EmulationTiming::cyclesPerSecond() const
|
|||
return myCyclesPerSecond;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 EmulationTiming::linesPerSecond() const
|
||||
{
|
||||
return myLinesPerSecond;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 EmulationTiming::audioFragmentSize() const
|
||||
{
|
||||
|
@ -181,7 +187,7 @@ void EmulationTiming::recalculate()
|
|||
|
||||
case ConsoleTiming::pal:
|
||||
case ConsoleTiming::secam:
|
||||
myCyclesPerSecond = uInt32(round(mySpeedFactor * 312 * 76 * 50) / 38);
|
||||
myAudioSampleRate = uInt32(round(mySpeedFactor * 312 * 76 * 50) / 38);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -204,4 +210,6 @@ void EmulationTiming::recalculate()
|
|||
myPrebufferFragmentCount,
|
||||
discreteDivCeil(myMaxCyclesPerTimeslice * myAudioSampleRate, myAudioFragmentSize * myCyclesPerSecond)
|
||||
) + myAudioQueueExtraFragments;
|
||||
|
||||
myLinesPerSecond = myCyclesPerSecond / 76;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ class EmulationTiming {
|
|||
|
||||
uInt32 cyclesPerFrame() const;
|
||||
|
||||
uInt32 linesPerSecond() const;
|
||||
|
||||
uInt32 cyclesPerSecond() const;
|
||||
|
||||
uInt32 audioFragmentSize() const;
|
||||
|
@ -82,6 +84,7 @@ class EmulationTiming {
|
|||
uInt32 myAudioSampleRate;
|
||||
uInt32 myAudioQueueCapacity;
|
||||
uInt32 myPrebufferFragmentCount;
|
||||
uInt32 myLinesPerSecond;
|
||||
|
||||
float mySpeedFactor;
|
||||
|
||||
|
|
|
@ -229,8 +229,8 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
|
|||
|
||||
// Create surfaces for TIA statistics and general messages
|
||||
myStatsMsg.color = kColorInfo;
|
||||
myStatsMsg.w = font().getMaxCharWidth() * 30 + 3;
|
||||
myStatsMsg.h = (font().getFontHeight() + 2) * 2;
|
||||
myStatsMsg.w = font().getMaxCharWidth() * 40 + 3;
|
||||
myStatsMsg.h = (font().getFontHeight() + 2) * 3;
|
||||
|
||||
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
|
||||
// Typically called from a thread, so it needs to be separate from
|
||||
|
@ -374,7 +374,7 @@ void FrameBuffer::updateInEmulationMode()
|
|||
|
||||
// Show frame statistics
|
||||
if(myStatsMsg.enabled)
|
||||
drawFrameStats();
|
||||
drawFrameStats(framesPerSecond);
|
||||
|
||||
myLastScanlines = myOSystem.console().tia().frameBufferScanlinesLastFrame();
|
||||
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();
|
||||
char msg[30];
|
||||
uInt32 color;
|
||||
const int XPOS = 2, YPOS = 0;
|
||||
int xPos = XPOS;
|
||||
int xPos = 2, yPos = 0;
|
||||
const int dy = font().getFontHeight() + 2;
|
||||
|
||||
ostringstream ss;
|
||||
|
||||
myStatsMsg.surface->invalidate();
|
||||
|
||||
// draw scanlines
|
||||
color = myOSystem.console().tia().frameBufferScanlinesLastFrame() != myLastScanlines ?
|
||||
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);
|
||||
xPos += font().getStringWidth(msg);
|
||||
|
||||
// draw frequency
|
||||
std::snprintf(msg, 30, " => %s", info.DisplayFormat.c_str());
|
||||
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS,
|
||||
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
||||
xPos += font().getStringWidth(msg);
|
||||
yPos += dy;
|
||||
ss.str("");
|
||||
|
||||
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);
|
||||
|
||||
// draw bankswitching type
|
||||
string bsinfo = info.BankSwitch +
|
||||
(myOSystem.settings().getBool("dev.settings") ? "| Developer" : "");
|
||||
myStatsMsg.surface->drawString(font(), bsinfo, XPOS, YPOS + font().getFontHeight(),
|
||||
yPos += dy;
|
||||
ss.str("");
|
||||
|
||||
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.surface->setDstPos(myImageRect.x() + 10, myImageRect.y() + 8);
|
||||
|
|
|
@ -120,7 +120,7 @@ class FrameBuffer
|
|||
/**
|
||||
There is a dedicated update method for emulation mode.
|
||||
*/
|
||||
void updateInEmulationMode();
|
||||
void updateInEmulationMode(float framesPerSecond);
|
||||
|
||||
/**
|
||||
Shows a message onscreen.
|
||||
|
@ -471,7 +471,7 @@ class FrameBuffer
|
|||
|
||||
private:
|
||||
// Draws the frame stats overlay
|
||||
void drawFrameStats();
|
||||
void drawFrameStats(float framesPerSecond);
|
||||
|
||||
// Indicates the number of times the framebuffer was initialized
|
||||
uInt32 myInitializedCount;
|
||||
|
|
|
@ -30,14 +30,13 @@
|
|||
#include "CheatManager.hxx"
|
||||
#endif
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "FSNode.hxx"
|
||||
#include "MD5.hxx"
|
||||
#include "Cart.hxx"
|
||||
#include "CartDetector.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "TIASurface.hxx"
|
||||
#include "TIAConstants.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "PropsSet.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
|
@ -60,10 +59,15 @@
|
|||
|
||||
using namespace std::chrono;
|
||||
|
||||
namespace {
|
||||
constexpr uInt32 FPS_METER_QUEUE_SIZE = 100;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
OSystem::OSystem()
|
||||
: myLauncherUsed(false),
|
||||
myQuitLoop(false)
|
||||
myQuitLoop(false),
|
||||
myFpsMeter(FPS_METER_QUEUE_SIZE)
|
||||
{
|
||||
// Get built-in features
|
||||
#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)
|
||||
{
|
||||
|
@ -651,7 +661,10 @@ double OSystem::dispatchEmulation(EmulationWorker& emulationWorker)
|
|||
bool framePending = tia.newFramePending();
|
||||
// ... and copy it to the frame buffer. It is important to do this before
|
||||
// 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
|
||||
// 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
|
||||
// audio pipeline is kept fed :)
|
||||
if (framePending) myFrameBuffer->updateInEmulationMode();
|
||||
if (framePending) myFrameBuffer->updateInEmulationMode(myFpsMeter.fps());
|
||||
|
||||
// Stop the worker and wait until it has finished
|
||||
uInt64 totalCycles = emulationWorker.stop();
|
||||
|
@ -691,11 +704,20 @@ void OSystem::mainLoop()
|
|||
// The emulation worker
|
||||
EmulationWorker emulationWorker;
|
||||
|
||||
myFpsMeter.reset(TIAConstants::initialGarbageFrames);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
bool wasEmulation = myEventHandler->state() == EventHandlerState::EMULATION;
|
||||
|
||||
myEventHandler->poll(getTicks());
|
||||
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;
|
||||
|
||||
if (myEventHandler->state() == EventHandlerState::EMULATION)
|
||||
|
|
|
@ -40,9 +40,12 @@ class StateManager;
|
|||
class VideoDialog;
|
||||
class EmulationWorker;
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "FSNode.hxx"
|
||||
#include "FrameBufferConstants.hxx"
|
||||
#include "EventHandlerConstants.hxx"
|
||||
#include "FpsMeter.hxx"
|
||||
#include "bspf.hxx"
|
||||
#include "AudioSettings.hxx"
|
||||
|
||||
|
@ -367,6 +370,11 @@ class OSystem
|
|||
*/
|
||||
const string& logMessages() const { return myLogMessages; }
|
||||
|
||||
/**
|
||||
Reset FPS measurement.
|
||||
*/
|
||||
void resetFps();
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// The following methods are system-specific and can be overrided in
|
||||
|
@ -510,6 +518,8 @@ class OSystem
|
|||
string myFeatures;
|
||||
string myBuildInfo;
|
||||
|
||||
FpsMeter myFpsMeter;
|
||||
|
||||
private:
|
||||
/**
|
||||
Creates the various framebuffers/renderers available in this system.
|
||||
|
|
|
@ -181,10 +181,9 @@ void TIA::reset()
|
|||
frameReset(); // Recalculate the size of the display
|
||||
}
|
||||
|
||||
myFrontBufferFrameRate = myFrameBufferFrameRate = 0;
|
||||
myFrontBufferScanlines = myFrameBufferScanlines = 0;
|
||||
|
||||
myNewFramePending = false;
|
||||
myFramesSinceLastRender = 0;
|
||||
|
||||
// Must be done last, after all other items have reset
|
||||
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(myFrontBufferScanlines);
|
||||
out.putDouble(myFrameBufferFrameRate);
|
||||
out.putDouble(myFrontBufferFrameRate);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -366,8 +363,6 @@ bool TIA::load(Serializer& in)
|
|||
|
||||
myFrameBufferScanlines = in.getInt();
|
||||
myFrontBufferScanlines = in.getInt();
|
||||
myFrameBufferFrameRate = in.getDouble();
|
||||
myFrontBufferFrameRate = in.getDouble();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -799,7 +794,7 @@ bool TIA::saveDisplay(Serializer& out) const
|
|||
out.putByteArray(myFramebuffer, 160* TIAConstants::frameBufferHeight);
|
||||
out.putByteArray(myBackBuffer, 160 * TIAConstants::frameBufferHeight);
|
||||
out.putByteArray(myFrontBuffer, 160 * TIAConstants::frameBufferHeight);
|
||||
out.putBool(myNewFramePending);
|
||||
out.putInt(myFramesSinceLastRender);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -819,7 +814,7 @@ bool TIA::loadDisplay(Serializer& in)
|
|||
in.getByteArray(myFramebuffer, 160 * TIAConstants::frameBufferHeight);
|
||||
in.getByteArray(myBackBuffer, 160 * TIAConstants::frameBufferHeight);
|
||||
in.getByteArray(myFrontBuffer, 160 * TIAConstants::frameBufferHeight);
|
||||
myNewFramePending = in.getBool();
|
||||
myFramesSinceLastRender = in.getInt();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -841,11 +836,12 @@ void TIA::update(DispatchResult& result, uInt64 maxCycles)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TIA::renderToFrameBuffer()
|
||||
{
|
||||
if (!myNewFramePending) return;
|
||||
if (myFramesSinceLastRender == 0) return;
|
||||
|
||||
myFramesSinceLastRender = 0;
|
||||
|
||||
memcpy(myFramebuffer, myFrontBuffer, 160 * TIAConstants::frameBufferHeight);
|
||||
|
||||
myFrameBufferFrameRate = myFrontBufferFrameRate;
|
||||
myFrameBufferScanlines = myFrontBufferScanlines;
|
||||
}
|
||||
|
||||
|
@ -1198,10 +1194,9 @@ void TIA::onFrameComplete()
|
|||
|
||||
memcpy(myFrontBuffer, myBackBuffer, 160 * TIAConstants::frameBufferHeight);
|
||||
|
||||
myFrontBufferFrameRate = frameRate();
|
||||
myFrontBufferScanlines = scanlinesLastFrame();
|
||||
|
||||
myNewFramePending = true;
|
||||
myFramesSinceLastRender++;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -207,7 +207,17 @@ class TIA : public Device
|
|||
/**
|
||||
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.
|
||||
|
@ -248,13 +258,6 @@ class TIA : public Device
|
|||
*/
|
||||
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.
|
||||
|
||||
|
@ -694,10 +697,9 @@ class TIA : public Device
|
|||
// 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
|
||||
uInt32 myFrontBufferScanlines, myFrameBufferScanlines;
|
||||
float myFrontBufferFrameRate, myFrameBufferFrameRate;
|
||||
|
||||
// Did we emit a frame?
|
||||
bool myNewFramePending;
|
||||
// Frames since the last time a frame was rendered to the render buffer
|
||||
uInt32 myFramesSinceLastRender;
|
||||
|
||||
/**
|
||||
* Setting this to true injects random values into undefined reads.
|
||||
|
|
|
@ -37,8 +37,6 @@ void AbstractFrameManager::reset()
|
|||
myCurrentFrameFinalLines = 0;
|
||||
myPreviousFrameFinalLines = 0;
|
||||
myTotalFrames = 0;
|
||||
myFrameRate = 0;
|
||||
myFrameRate = 60.0;
|
||||
|
||||
onReset();
|
||||
}
|
||||
|
@ -101,9 +99,6 @@ void AbstractFrameManager::notifyFrameComplete()
|
|||
myTotalFrames++;
|
||||
|
||||
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(myTotalFrames);
|
||||
out.putInt(uInt32(myLayout));
|
||||
out.putDouble(myFrameRate);
|
||||
|
||||
return onSave(out);
|
||||
}
|
||||
|
@ -155,7 +149,6 @@ bool AbstractFrameManager::load(Serializer& in)
|
|||
myPreviousFrameFinalLines = in.getInt();
|
||||
myTotalFrames = in.getInt();
|
||||
myLayout = FrameLayout(in.getInt());
|
||||
myFrameRate = float(in.getDouble());
|
||||
|
||||
return onLoad(in);
|
||||
}
|
||||
|
|
|
@ -107,13 +107,6 @@ class AbstractFrameManager : public Serializable
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
|
@ -289,11 +282,6 @@ class AbstractFrameManager : public Serializable
|
|||
*/
|
||||
uInt32 myTotalFrames;
|
||||
|
||||
/**
|
||||
* Frame rate (see above.)
|
||||
*/
|
||||
float myFrameRate;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue