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