mirror of https://github.com/stella-emu/stella.git
Rework dispatch loop.
This commit is contained in:
parent
7f83e776b2
commit
396dd637af
|
@ -41,6 +41,7 @@
|
|||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"fstream": "cpp"
|
||||
"fstream": "cpp",
|
||||
"__locale": "cpp"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -987,6 +987,12 @@ void Console::setFramerate(float framerate)
|
|||
// myOSystem.sound().setFrameRate(framerate);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
float Console::getFramerate() const
|
||||
{
|
||||
return myTIA->frameRate();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Console::toggleTIABit(TIABit bit, const string& bitname, bool show) const
|
||||
{
|
||||
|
|
|
@ -272,7 +272,7 @@ class Console : public Serializable
|
|||
Returns the framerate based on a number of factors
|
||||
(whether 'framerate' is set, what display format is in use, etc)
|
||||
*/
|
||||
float getFramerate() const { return myFramerate; }
|
||||
float getFramerate() const;
|
||||
|
||||
/**
|
||||
Toggles the TIA bit specified in the method name.
|
||||
|
|
|
@ -47,10 +47,7 @@ FrameBuffer::FrameBuffer(OSystem& osystem)
|
|||
myInitializedCount(0),
|
||||
myPausedCount(0),
|
||||
myStatsEnabled(false),
|
||||
myLastFrameRate(60),
|
||||
myCurrentModeList(nullptr),
|
||||
myTotalTime(0),
|
||||
myTotalFrames(0)
|
||||
myCurrentModeList(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -290,8 +287,7 @@ Int64 FrameBuffer::update()
|
|||
// Show frame statistics
|
||||
if(myStatsMsg.enabled)
|
||||
drawFrameStats();
|
||||
else
|
||||
myLastFrameRate = myOSystem.console().getFramerate();
|
||||
|
||||
myLastScanlines = myOSystem.console().tia().scanlinesLastFrame();
|
||||
myPausedCount = 0;
|
||||
break; // EventHandlerState::EMULATION
|
||||
|
@ -404,30 +400,7 @@ void FrameBuffer::drawFrameStats()
|
|||
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
||||
xPos += font().getStringWidth(msg);
|
||||
|
||||
// draw framerate
|
||||
float frameRate;
|
||||
/*if(myOSystem.settings().getInt("framerate") == 0)
|
||||
{
|
||||
// if 'Auto' is selected, draw the calculated framerate
|
||||
frameRate = myOSystem.console().getFramerate();
|
||||
}
|
||||
else*/
|
||||
{
|
||||
// if 'Auto' is not selected, draw the effective framerate
|
||||
const TimingInfo& ti = myOSystem.timingInfo();
|
||||
if(ti.totalFrames - myTotalFrames >= myLastFrameRate)
|
||||
{
|
||||
frameRate = 1000000.0 * (ti.totalFrames - myTotalFrames) / (ti.totalTime - myTotalTime);
|
||||
if(frameRate > myOSystem.console().getFramerate() + 1)
|
||||
frameRate = 1;
|
||||
myTotalFrames = ti.totalFrames;
|
||||
myTotalTime = ti.totalTime;
|
||||
}
|
||||
else
|
||||
frameRate = myLastFrameRate;
|
||||
}
|
||||
myLastFrameRate = frameRate;
|
||||
std::snprintf(msg, 30, " @ %5.2ffps", frameRate);
|
||||
std::snprintf(msg, 30, " @ %5.2ffps", myOSystem.console().getFramerate());
|
||||
myStatsMsg.surface->drawString(font(), msg, xPos, YPOS,
|
||||
myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
|
||||
|
||||
|
|
|
@ -517,7 +517,6 @@ class FrameBuffer
|
|||
Message myStatsMsg;
|
||||
bool myStatsEnabled;
|
||||
uInt32 myLastScanlines;
|
||||
float myLastFrameRate;
|
||||
|
||||
bool myGrabMouse;
|
||||
|
||||
|
@ -538,9 +537,6 @@ class FrameBuffer
|
|||
// Holds UI palette data (standard and classic colours)
|
||||
static uInt32 ourGUIColors[3][kNumColors-256];
|
||||
|
||||
uInt64 myTotalTime;
|
||||
uInt64 myTotalFrames;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
FrameBuffer() = delete;
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "CheatManager.hxx"
|
||||
#endif
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "FSNode.hxx"
|
||||
#include "MD5.hxx"
|
||||
#include "Cart.hxx"
|
||||
|
@ -58,6 +60,8 @@
|
|||
|
||||
#include "OSystem.hxx"
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
OSystem::OSystem()
|
||||
: myLauncherUsed(false),
|
||||
|
@ -615,52 +619,36 @@ uInt64 OSystem::getTicks() const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void OSystem::mainLoop()
|
||||
{
|
||||
if(mySettings->getString("timing") == "sleep")
|
||||
{
|
||||
// Sleep-based wait: good for CPU, bad for graphical sync
|
||||
bool busyWait = mySettings->getString("timing") != "sleep";
|
||||
time_point<high_resolution_clock> virtualTime = high_resolution_clock::now();
|
||||
|
||||
for(;;)
|
||||
{
|
||||
myTimingInfo.start = getTicks();
|
||||
myEventHandler->poll(myTimingInfo.start);
|
||||
if(myQuitLoop) break; // Exit if the user wants to quit
|
||||
myFrameBuffer->update();
|
||||
myTimingInfo.current = getTicks();
|
||||
myTimingInfo.virt += myTimePerFrame;
|
||||
|
||||
// Timestamps may periodically go out of sync, particularly on systems
|
||||
// that can have 'negative time' (ie, when the time seems to go backwards)
|
||||
// This normally results in having a very large delay time, so we check
|
||||
// for that and reset the timers when appropriate
|
||||
if((myTimingInfo.virt - myTimingInfo.current) > (myTimePerFrame << 1))
|
||||
{
|
||||
myTimingInfo.current = myTimingInfo.virt = getTicks();
|
||||
Int64 cycles = myFrameBuffer->update();
|
||||
duration<double> timeslice (
|
||||
(cycles >= 0) ?
|
||||
static_cast<double>(cycles) / static_cast<double>(76 * ((myConsole->timing() == ConsoleTiming::ntsc) ? (262 * 60) : (312 * 50))) :
|
||||
1. / 30.
|
||||
);
|
||||
|
||||
virtualTime += duration_cast<high_resolution_clock::duration>(timeslice);
|
||||
time_point<high_resolution_clock> now = high_resolution_clock::now();
|
||||
|
||||
if (duration_cast<duration<double>>(now - virtualTime).count() > 0.5)
|
||||
virtualTime = now;
|
||||
else if (virtualTime > now) {
|
||||
if (busyWait && cycles >= 0) {
|
||||
while (high_resolution_clock::now() < virtualTime);
|
||||
}
|
||||
else std::this_thread::sleep_until(virtualTime);
|
||||
}
|
||||
|
||||
if(myTimingInfo.current < myTimingInfo.virt)
|
||||
SDL_Delay(uInt32(myTimingInfo.virt - myTimingInfo.current) / 1000);
|
||||
|
||||
myTimingInfo.totalTime += (getTicks() - myTimingInfo.start);
|
||||
myTimingInfo.totalFrames++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Busy-wait: bad for CPU, good for graphical sync
|
||||
for(;;)
|
||||
{
|
||||
myTimingInfo.start = getTicks();
|
||||
myEventHandler->poll(myTimingInfo.start);
|
||||
if(myQuitLoop) break; // Exit if the user wants to quit
|
||||
myFrameBuffer->update();
|
||||
myTimingInfo.virt += myTimePerFrame;
|
||||
|
||||
while(getTicks() < myTimingInfo.virt)
|
||||
; // busy-wait
|
||||
|
||||
myTimingInfo.totalTime += (getTicks() - myTimingInfo.start);
|
||||
myTimingInfo.totalFrames++;
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup time
|
||||
#ifdef CHEATCODE_SUPPORT
|
||||
|
|
|
@ -237,6 +237,8 @@ class TIA : public Device
|
|||
*/
|
||||
void enableAutoFrame(bool enabled) { myAutoFrameEnabled = enabled; }
|
||||
|
||||
float frameRate() const { return myFrameManager ? myFrameManager->frameRate() : 0; }
|
||||
|
||||
/**
|
||||
Enables/disables color-loss for PAL modes only.
|
||||
|
||||
|
|
Loading…
Reference in New Issue