Rework dispatch loop.

This commit is contained in:
Christian Speckner 2018-01-31 20:44:39 +01:00
parent 7f83e776b2
commit 396dd637af
7 changed files with 43 additions and 77 deletions

View File

@ -41,6 +41,7 @@
"tuple": "cpp", "tuple": "cpp",
"type_traits": "cpp", "type_traits": "cpp",
"stdexcept": "cpp", "stdexcept": "cpp",
"fstream": "cpp" "fstream": "cpp",
"__locale": "cpp"
} }
} }

View File

@ -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
{ {

View File

@ -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.

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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.