Refactoring: remove framerate from OSystem and Console.

This commit is contained in:
Christian Speckner 2018-02-03 01:01:02 +01:00
parent 396dd637af
commit cb89d09c7f
9 changed files with 16 additions and 176 deletions

View File

@ -222,7 +222,7 @@ void SoundSDL2::adjustVolume(Int8 direction)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL2::processFragment(Int16* stream, uInt32 length) void SoundSDL2::processFragment(Int16* stream, uInt32 length)
{ {
if (myUnderrun && myAudioQueue->size() > myFragmentBufferSize) { if (myUnderrun && myAudioQueue->size() > 0) {
myUnderrun = false; myUnderrun = false;
myCurrentFragment = myAudioQueue->dequeue(myCurrentFragment); myCurrentFragment = myAudioQueue->dequeue(myCurrentFragment);
myFragmentIndex = 0; myFragmentIndex = 0;

View File

@ -72,7 +72,7 @@
namespace { namespace {
constexpr uInt8 YSTART_EXTRA = 2; constexpr uInt8 YSTART_EXTRA = 2;
constexpr uInt8 AUDIO_QUEUE_CAPACITY_FRAGMENTS = 20; constexpr uInt8 AUDIO_QUEUE_CAPACITY_FRAGMENTS = 30;
constexpr uInt8 AUDIO_QUEUE_HALF_FRAMES_PER_FRAGMENT = 1; constexpr uInt8 AUDIO_QUEUE_HALF_FRAMES_PER_FRAGMENT = 1;
} }
@ -84,7 +84,6 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
myProperties(props), myProperties(props),
myCart(std::move(cart)), myCart(std::move(cart)),
myDisplayFormat(""), // Unknown TV format @ start myDisplayFormat(""), // Unknown TV format @ start
myFramerate(0.0), // Unknown framerate @ start
myCurrentFormat(0), // Unknown format @ start, myCurrentFormat(0), // Unknown format @ start,
myAutodetectedYstart(0), myAutodetectedYstart(0),
myUserPaletteDefined(false), myUserPaletteDefined(false),
@ -149,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
// The TIA will self-adjust the framerate if necessary
setTIAProperties(); setTIAProperties();
if(myDisplayFormat == "NTSC") if(myDisplayFormat == "NTSC")
{ {
@ -551,39 +549,14 @@ FBInitStatus Console::initializeVideo(bool full)
} }
setPalette(myOSystem.settings().getString("palette")); setPalette(myOSystem.settings().getString("palette"));
// Set the correct framerate based on the format of the ROM
// This can be overridden by changing the framerate in the
// VideoDialog box or on the commandline, but it can't be saved
// (ie, framerate is now determined based on number of scanlines).
int framerate = myOSystem.settings().getInt("framerate");
if(framerate > 0) myFramerate = float(framerate);
myOSystem.setFramerate(myFramerate);
// Make sure auto-frame calculation is only enabled when necessary
myTIA->enableAutoFrame(framerate <= 0);
return fbstatus; return fbstatus;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::initializeAudio() void Console::initializeAudio()
{ {
// Initialize the sound interface.
// The # of channels can be overridden in the AudioDialog box or on
// the commandline, but it can't be saved.
int framerate = myOSystem.settings().getInt("framerate");
if(framerate > 0) myFramerate = float(framerate);
myOSystem.sound().close(); myOSystem.sound().close();
// SND_TODO Communicate channels to TIA
// const string& sound = myProperties.get(Cartridge_Sound);
// myOSystem.sound().setChannels(sound == "STEREO" ? 2 : 1);
myOSystem.sound().open(myAudioQueue); myOSystem.sound().open(myAudioQueue);
// Make sure auto-frame calculation is only enabled when necessary
myTIA->enableAutoFrame(framerate <= 0);
} }
/* Original frying research and code by Fred Quimby. /* Original frying research and code by Fred Quimby.
@ -713,16 +686,11 @@ void Console::setTIAProperties()
myDisplayFormat == "SECAM60") myDisplayFormat == "SECAM60")
{ {
// Assume we've got ~262 scanlines (NTSC-like format) // Assume we've got ~262 scanlines (NTSC-like format)
myFramerate = 60.0;
myConsoleInfo.InitialFrameRate = "60";
myTIA->setLayout(FrameLayout::ntsc); myTIA->setLayout(FrameLayout::ntsc);
} }
else else
{ {
// Assume we've got ~312 scanlines (PAL-like format) // Assume we've got ~312 scanlines (PAL-like format)
myFramerate = 50.0;
myConsoleInfo.InitialFrameRate = "50";
// PAL ROMs normally need at least 250 lines // PAL ROMs normally need at least 250 lines
if (height != 0) height = std::max(height, 250u); if (height != 0) height = std::max(height, 250u);
@ -979,14 +947,6 @@ void Console::generateColorLossPalette()
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::setFramerate(float framerate)
{
myFramerate = framerate;
myOSystem.setFramerate(framerate);
// myOSystem.sound().setFrameRate(framerate);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
float Console::getFramerate() const float Console::getFramerate() const
{ {

View File

@ -50,7 +50,6 @@ struct ConsoleInfo
string Control0; string Control0;
string Control1; string Control1;
string DisplayFormat; string DisplayFormat;
string InitialFrameRate;
}; };
/** /**
@ -263,14 +262,7 @@ class Console : public Serializable
void changeHeight(int direction); void changeHeight(int direction);
/** /**
Sets the framerate of the console, which in turn communicates Returns the current framerate.
this to all applicable subsystems.
*/
void setFramerate(float framerate);
/**
Returns the framerate based on a number of factors
(whether 'framerate' is set, what display format is in use, etc)
*/ */
float getFramerate() const; float getFramerate() const;
@ -405,9 +397,6 @@ class Console : public Serializable
// The currently defined display format (NTSC/PAL/SECAM) // The currently defined display format (NTSC/PAL/SECAM)
string myDisplayFormat; string myDisplayFormat;
// The currently defined display framerate
float myFramerate;
// Display format currently in use // Display format currently in use
uInt32 myCurrentFormat; uInt32 myCurrentFormat;
@ -424,6 +413,8 @@ class Console : public Serializable
// Contains timing information for this console // Contains timing information for this console
ConsoleTiming myConsoleTiming; ConsoleTiming myConsoleTiming;
uInt32 myFramerate;
// Table of RGB values for NTSC, PAL and SECAM // Table of RGB values for NTSC, PAL and SECAM
static uInt32 ourNTSCPalette[256]; static uInt32 ourNTSCPalette[256];
static uInt32 ourPALPalette[256]; static uInt32 ourPALPalette[256];

View File

@ -721,8 +721,7 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
myDesktopSize.w, myDesktopSize.h); myDesktopSize.w, myDesktopSize.h);
// Aspect ratio // Aspect ratio
bool ntsc = myOSystem.console().about().InitialFrameRate == "60"; uInt32 aspect = myOSystem.settings().getInt(myOSystem.console().timing() == ConsoleTiming::ntsc ?
uInt32 aspect = myOSystem.settings().getInt(ntsc ?
"tia.aspectn" : "tia.aspectp"); "tia.aspectn" : "tia.aspectp");
// Figure our the smallest zoom level we can use // Figure our the smallest zoom level we can use

View File

@ -17,11 +17,6 @@
#include <cassert> #include <cassert>
#include <ctime>
#ifdef HAVE_GETTIMEOFDAY
#include <sys/time.h>
#endif
#include "bspf.hxx" #include "bspf.hxx"
#include "MediaFactory.hxx" #include "MediaFactory.hxx"
@ -67,9 +62,6 @@ OSystem::OSystem()
: myLauncherUsed(false), : myLauncherUsed(false),
myQuitLoop(false) myQuitLoop(false)
{ {
// Calculate startup time
myMillisAtStart = uInt32(time(nullptr) * 1000);
// Get built-in features // Get built-in features
#ifdef SOUND_SUPPORT #ifdef SOUND_SUPPORT
myFeatures += "Sound "; myFeatures += "Sound ";
@ -237,16 +229,6 @@ void OSystem::setConfigFile(const string& file)
myConfigFile = FilesystemNode(file).getPath(); myConfigFile = FilesystemNode(file).getPath();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::setFramerate(float framerate)
{
if(framerate > 0.0)
{
myDisplayFrameRate = framerate;
myTimePerFrame = uInt32(1000000.0 / myDisplayFrameRate);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBInitStatus OSystem::createFrameBuffer() FBInitStatus OSystem::createFrameBuffer()
{ {
@ -362,9 +344,6 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum,
<< getROMInfo(*myConsole) << endl; << getROMInfo(*myConsole) << endl;
logMessage(buf.str(), 1); logMessage(buf.str(), 1);
// Update the timing info for a new console run
resetLoopTiming();
myFrameBuffer->setCursorState(); myFrameBuffer->setCursorState();
// Also check if certain virtual buttons should be held down // Also check if certain virtual buttons should be held down
@ -404,8 +383,6 @@ bool OSystem::createLauncher(const string& startdir)
myLauncher->reStack(); myLauncher->reStack();
myFrameBuffer->setCursorState(); myFrameBuffer->setCursorState();
setFramerate(30);
resetLoopTiming();
status = true; status = true;
} }
else else
@ -575,15 +552,6 @@ string OSystem::getROMInfo(const Console& console)
return buf.str(); return buf.str();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::resetLoopTiming()
{
myTimingInfo.start = myTimingInfo.virt = getTicks();
myTimingInfo.current = 0;
myTimingInfo.totalTime = 0;
myTimingInfo.totalFrames = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::validatePath(string& path, const string& setting, void OSystem::validatePath(string& path, const string& setting,
const string& defaultpath) const string& defaultpath)
@ -601,19 +569,13 @@ void OSystem::validatePath(string& path, const string& setting,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt64 OSystem::getTicks() const uInt64 OSystem::getTicks() const
{ {
#ifdef HAVE_GETTIMEOFDAY return duration_cast<duration<uInt64, std::ratio<1, 1000000> > >(system_clock::now().time_since_epoch()).count();
// Gettimeofday natively refers to the UNIX epoch (a set time in the past) }
timeval now;
gettimeofday(&now, nullptr);
return uInt64(now.tv_sec) * 1000000 + now.tv_usec; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#else float OSystem::frameRate() const
// We use SDL_GetTicks, but add in the time when the application was {
// initialized. This is necessary, since SDL_GetTicks only measures how return myConsole ? myConsole->getFramerate() : 0;
// long SDL has been running, which can be the same between multiple runs
// of the application.
return uInt64(SDL_GetTicks() + myMillisAtStart) * 1000;
#endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -625,7 +587,7 @@ void OSystem::mainLoop()
for(;;) for(;;)
{ {
myEventHandler->poll(myTimingInfo.start); myEventHandler->poll(getTicks());
if(myQuitLoop) break; // Exit if the user wants to quit if(myQuitLoop) break; // Exit if the user wants to quit
Int64 cycles = myFrameBuffer->update(); Int64 cycles = myFrameBuffer->update();
@ -646,8 +608,6 @@ void OSystem::mainLoop()
} }
else std::this_thread::sleep_until(virtualTime); else std::this_thread::sleep_until(virtualTime);
} }
myTimingInfo.totalFrames++;
} }
// Cleanup time // Cleanup time

View File

@ -44,14 +44,6 @@ class VideoDialog;
#include "EventHandlerConstants.hxx" #include "EventHandlerConstants.hxx"
#include "bspf.hxx" #include "bspf.hxx"
struct TimingInfo {
uInt64 start;
uInt64 current;
uInt64 virt;
uInt64 totalTime;
uInt64 totalFrames;
};
/** /**
This class provides an interface for accessing operating system specific This class provides an interface for accessing operating system specific
functions. It also comprises an overall parent object, to which all the functions. It also comprises an overall parent object, to which all the
@ -207,26 +199,11 @@ class OSystem
CheatManager& cheat() const { return *myCheatManager; } CheatManager& cheat() const { return *myCheatManager; }
#endif #endif
/**
Set the framerate for the video system. It's placed in this class since
the mainLoop() method is defined here.
@param framerate The video framerate to use
*/
virtual void setFramerate(float framerate);
/** /**
Set all config file paths for the OSystem. Set all config file paths for the OSystem.
*/ */
void setConfigPaths(); void setConfigPaths();
/**
Get the current framerate for the video system.
@return The video framerate currently in use
*/
float frameRate() const { return myDisplayFrameRate; }
/** /**
Return the default full/complete directory name for storing data. Return the default full/complete directory name for storing data.
*/ */
@ -377,12 +354,6 @@ class OSystem
*/ */
const string& logMessages() const { return myLogMessages; } const string& logMessages() const { return myLogMessages; }
/**
Return timing information (start time of console, current
number of frames rendered, etc.
*/
const TimingInfo& timingInfo() const { return myTimingInfo; }
public: public:
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// The following methods are system-specific and can be overrided in // The following methods are system-specific and can be overrided in
@ -400,6 +371,8 @@ class OSystem
*/ */
virtual uInt64 getTicks() const; virtual uInt64 getTicks() const;
float frameRate() const;
/** /**
This method runs the main loop. Since different platforms This method runs the main loop. Since different platforms
may use different timing methods and/or algorithms, this method can may use different timing methods and/or algorithms, this method can
@ -492,15 +465,6 @@ class OSystem
// The list of log messages // The list of log messages
string myLogMessages; string myLogMessages;
// Number of times per second to iterate through the main loop
float myDisplayFrameRate;
// Time per frame for a video update, based on the current framerate
uInt32 myTimePerFrame;
// The time (in milliseconds) from the UNIX epoch when the application starts
uInt32 myMillisAtStart;
// Indicates whether to stop the main loop // Indicates whether to stop the main loop
bool myQuitLoop; bool myQuitLoop;
@ -523,9 +487,6 @@ class OSystem
string myFeatures; string myFeatures;
string myBuildInfo; string myBuildInfo;
// Indicates whether the main processing loop should proceed
TimingInfo myTimingInfo;
private: private:
/** /**
Creates the various framebuffers/renderers available in this system. Creates the various framebuffers/renderers available in this system.
@ -577,12 +538,6 @@ class OSystem
*/ */
string getROMInfo(const Console& console); string getROMInfo(const Console& console);
/**
Initializes the timing so that the mainloop is reset to its
initial values.
*/
void resetLoopTiming();
/** /**
Validate the directory name, and create it if necessary. Validate the directory name, and create it if necessary.
Also, update the settings with the new name. For now, validation Also, update the settings with the new name. For now, validation

View File

@ -144,7 +144,6 @@ void TIA::reset()
myCollisionMask = 0; myCollisionMask = 0;
myLinesSinceChange = 0; myLinesSinceChange = 0;
myCollisionUpdateRequired = false; myCollisionUpdateRequired = false;
myAutoFrameEnabled = false;
myColorLossEnabled = myColorLossActive = false; myColorLossEnabled = myColorLossActive = false;
myColorHBlank = 0; myColorHBlank = 0;
myLastCycle = 0; myLastCycle = 0;
@ -190,7 +189,6 @@ void TIA::reset()
void TIA::frameReset() void TIA::frameReset()
{ {
memset(myFramebuffer, 0, 160 * TIAConstants::frameBufferHeight); memset(myFramebuffer, 0, 160 * TIAConstants::frameBufferHeight);
myAutoFrameEnabled = mySettings.getInt("framerate") <= 0;
enableColorLoss(mySettings.getBool("dev.settings") ? "dev.colorloss" : "plr.colorloss"); enableColorLoss(mySettings.getBool("dev.settings") ? "dev.colorloss" : "plr.colorloss");
} }
@ -277,8 +275,6 @@ bool TIA::save(Serializer& out) const
out.putDouble(myTimestamp); out.putDouble(myTimestamp);
out.putBool(myAutoFrameEnabled);
out.putByteArray(myShadowRegisters, 64); out.putByteArray(myShadowRegisters, 64);
out.putLong(myCyclesAtFrameStart); out.putLong(myCyclesAtFrameStart);
@ -347,8 +343,6 @@ bool TIA::load(Serializer& in)
myTimestamp = in.getDouble(); myTimestamp = in.getDouble();
myAutoFrameEnabled = in.getBool();
in.getByteArray(myShadowRegisters, 64); in.getByteArray(myShadowRegisters, 64);
myCyclesAtFrameStart = in.getLong(); myCyclesAtFrameStart = in.getLong();
@ -1157,10 +1151,6 @@ void TIA::onFrameComplete()
const Int32 missingScanlines = myFrameManager->missingScanlines(); const Int32 missingScanlines = myFrameManager->missingScanlines();
if (missingScanlines > 0) if (missingScanlines > 0)
memset(myFramebuffer + 160 * myFrameManager->getY(), 0, missingScanlines * 160); memset(myFramebuffer + 160 * myFrameManager->getY(), 0, missingScanlines * 160);
// Recalculate framerate, attempting to auto-correct for scanline 'jumps'
if(myAutoFrameEnabled)
myConsole.setFramerate(myFrameManager->frameRate());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -229,14 +229,6 @@ class TIA : public Device
*/ */
ConsoleTiming consoleTiming() const { return myConsole.timing(); } ConsoleTiming consoleTiming() const { return myConsole.timing(); }
/**
Enables/disables auto-frame calculation. If enabled, the TIA
re-adjusts the framerate at regular intervals.
@param enabled Whether to enable or disable all auto-frame calculation
*/
void enableAutoFrame(bool enabled) { myAutoFrameEnabled = enabled; }
float frameRate() const { return myFrameManager ? myFrameManager->frameRate() : 0; } float frameRate() const { return myFrameManager ? myFrameManager->frameRate() : 0; }
/** /**
@ -760,11 +752,6 @@ class TIA : public Device
*/ */
uInt8 myShadowRegisters[64]; uInt8 myShadowRegisters[64];
/**
* Automatic framerate correction based on number of scanlines.
*/
bool myAutoFrameEnabled;
/** /**
* Indicates if color loss should be enabled or disabled. Color loss * Indicates if color loss should be enabled or disabled. Color loss
* occurs on PAL-like systems when the previous frame contains an odd * occurs on PAL-like systems when the previous frame contains an odd

View File

@ -410,9 +410,7 @@ void VideoDialog::saveConfig()
instance().settings().setValue("framerate", f); instance().settings().setValue("framerate", f);
if(instance().hasConsole()) if(instance().hasConsole())
{ {
// Make sure auto-frame calculation is only enabled when necessary // instance().console().setFramerate(float(f));
instance().console().tia().enableAutoFrame(f <= 0);
instance().console().setFramerate(float(f));
} }
// Fullscreen // Fullscreen