From cb89d09c7fcd6f36d570eee609875130fb9ae369 Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Sat, 3 Feb 2018 01:01:02 +0100 Subject: [PATCH] Refactoring: remove framerate from OSystem and Console. --- src/common/SoundSDL2.cxx | 2 +- src/emucore/Console.cxx | 42 +---------------------------- src/emucore/Console.hxx | 15 +++-------- src/emucore/FrameBuffer.cxx | 3 +-- src/emucore/OSystem.cxx | 54 +++++-------------------------------- src/emucore/OSystem.hxx | 49 ++------------------------------- src/emucore/tia/TIA.cxx | 10 ------- src/emucore/tia/TIA.hxx | 13 --------- src/gui/VideoDialog.cxx | 4 +-- 9 files changed, 16 insertions(+), 176 deletions(-) diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index f6923daea..cefcdfa67 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -222,7 +222,7 @@ void SoundSDL2::adjustVolume(Int8 direction) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void SoundSDL2::processFragment(Int16* stream, uInt32 length) { - if (myUnderrun && myAudioQueue->size() > myFragmentBufferSize) { + if (myUnderrun && myAudioQueue->size() > 0) { myUnderrun = false; myCurrentFragment = myAudioQueue->dequeue(myCurrentFragment); myFragmentIndex = 0; diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 7b08d4383..b8306b54b 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -72,7 +72,7 @@ namespace { 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; } @@ -84,7 +84,6 @@ Console::Console(OSystem& osystem, unique_ptr& cart, myProperties(props), myCart(std::move(cart)), myDisplayFormat(""), // Unknown TV format @ start - myFramerate(0.0), // Unknown framerate @ start myCurrentFormat(0), // Unknown format @ start, myAutodetectedYstart(0), myUserPaletteDefined(false), @@ -149,7 +148,6 @@ Console::Console(OSystem& osystem, unique_ptr& 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 - // The TIA will self-adjust the framerate if necessary setTIAProperties(); if(myDisplayFormat == "NTSC") { @@ -551,39 +549,14 @@ FBInitStatus Console::initializeVideo(bool full) } 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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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(); - - // SND_TODO Communicate channels to TIA - // const string& sound = myProperties.get(Cartridge_Sound); - // myOSystem.sound().setChannels(sound == "STEREO" ? 2 : 1); - 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. @@ -713,16 +686,11 @@ void Console::setTIAProperties() myDisplayFormat == "SECAM60") { // Assume we've got ~262 scanlines (NTSC-like format) - myFramerate = 60.0; - myConsoleInfo.InitialFrameRate = "60"; myTIA->setLayout(FrameLayout::ntsc); } else { // Assume we've got ~312 scanlines (PAL-like format) - myFramerate = 50.0; - myConsoleInfo.InitialFrameRate = "50"; - // PAL ROMs normally need at least 250 lines 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 { diff --git a/src/emucore/Console.hxx b/src/emucore/Console.hxx index cd6daab86..d3b1082f8 100644 --- a/src/emucore/Console.hxx +++ b/src/emucore/Console.hxx @@ -50,7 +50,6 @@ struct ConsoleInfo string Control0; string Control1; string DisplayFormat; - string InitialFrameRate; }; /** @@ -263,14 +262,7 @@ class Console : public Serializable void changeHeight(int direction); /** - Sets the framerate of the console, which in turn communicates - 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) + Returns the current framerate. */ float getFramerate() const; @@ -405,9 +397,6 @@ class Console : public Serializable // The currently defined display format (NTSC/PAL/SECAM) string myDisplayFormat; - // The currently defined display framerate - float myFramerate; - // Display format currently in use uInt32 myCurrentFormat; @@ -424,6 +413,8 @@ class Console : public Serializable // Contains timing information for this console ConsoleTiming myConsoleTiming; + uInt32 myFramerate; + // Table of RGB values for NTSC, PAL and SECAM static uInt32 ourNTSCPalette[256]; static uInt32 ourPALPalette[256]; diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 1876559a9..3f84a39d7 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -721,8 +721,7 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight) myDesktopSize.w, myDesktopSize.h); // Aspect ratio - bool ntsc = myOSystem.console().about().InitialFrameRate == "60"; - uInt32 aspect = myOSystem.settings().getInt(ntsc ? + uInt32 aspect = myOSystem.settings().getInt(myOSystem.console().timing() == ConsoleTiming::ntsc ? "tia.aspectn" : "tia.aspectp"); // Figure our the smallest zoom level we can use diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 9b9206cff..26ba9ed9d 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -17,11 +17,6 @@ #include -#include -#ifdef HAVE_GETTIMEOFDAY - #include -#endif - #include "bspf.hxx" #include "MediaFactory.hxx" @@ -67,9 +62,6 @@ OSystem::OSystem() : myLauncherUsed(false), myQuitLoop(false) { - // Calculate startup time - myMillisAtStart = uInt32(time(nullptr) * 1000); - // Get built-in features #ifdef SOUND_SUPPORT myFeatures += "Sound "; @@ -237,16 +229,6 @@ void OSystem::setConfigFile(const string& file) myConfigFile = FilesystemNode(file).getPath(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void OSystem::setFramerate(float framerate) -{ - if(framerate > 0.0) - { - myDisplayFrameRate = framerate; - myTimePerFrame = uInt32(1000000.0 / myDisplayFrameRate); - } -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FBInitStatus OSystem::createFrameBuffer() { @@ -362,9 +344,6 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum, << getROMInfo(*myConsole) << endl; logMessage(buf.str(), 1); - // Update the timing info for a new console run - resetLoopTiming(); - myFrameBuffer->setCursorState(); // Also check if certain virtual buttons should be held down @@ -404,8 +383,6 @@ bool OSystem::createLauncher(const string& startdir) myLauncher->reStack(); myFrameBuffer->setCursorState(); - setFramerate(30); - resetLoopTiming(); status = true; } else @@ -575,15 +552,6 @@ string OSystem::getROMInfo(const Console& console) 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, const string& defaultpath) @@ -601,19 +569,13 @@ void OSystem::validatePath(string& path, const string& setting, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt64 OSystem::getTicks() const { -#ifdef HAVE_GETTIMEOFDAY - // Gettimeofday natively refers to the UNIX epoch (a set time in the past) - timeval now; - gettimeofday(&now, nullptr); + return duration_cast > >(system_clock::now().time_since_epoch()).count(); +} - return uInt64(now.tv_sec) * 1000000 + now.tv_usec; -#else - // We use SDL_GetTicks, but add in the time when the application was - // initialized. This is necessary, since SDL_GetTicks only measures how - // long SDL has been running, which can be the same between multiple runs - // of the application. - return uInt64(SDL_GetTicks() + myMillisAtStart) * 1000; -#endif +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +float OSystem::frameRate() const +{ + return myConsole ? myConsole->getFramerate() : 0; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -625,7 +587,7 @@ void OSystem::mainLoop() for(;;) { - myEventHandler->poll(myTimingInfo.start); + myEventHandler->poll(getTicks()); if(myQuitLoop) break; // Exit if the user wants to quit Int64 cycles = myFrameBuffer->update(); @@ -646,8 +608,6 @@ void OSystem::mainLoop() } else std::this_thread::sleep_until(virtualTime); } - - myTimingInfo.totalFrames++; } // Cleanup time diff --git a/src/emucore/OSystem.hxx b/src/emucore/OSystem.hxx index 24d690e59..04a733481 100644 --- a/src/emucore/OSystem.hxx +++ b/src/emucore/OSystem.hxx @@ -44,14 +44,6 @@ class VideoDialog; #include "EventHandlerConstants.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 functions. It also comprises an overall parent object, to which all the @@ -207,26 +199,11 @@ class OSystem CheatManager& cheat() const { return *myCheatManager; } #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. */ 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. */ @@ -377,12 +354,6 @@ class OSystem */ 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: ////////////////////////////////////////////////////////////////////// // The following methods are system-specific and can be overrided in @@ -400,6 +371,8 @@ class OSystem */ virtual uInt64 getTicks() const; + float frameRate() const; + /** This method runs the main loop. Since different platforms may use different timing methods and/or algorithms, this method can @@ -492,15 +465,6 @@ class OSystem // The list of log messages 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 bool myQuitLoop; @@ -523,9 +487,6 @@ class OSystem string myFeatures; string myBuildInfo; - // Indicates whether the main processing loop should proceed - TimingInfo myTimingInfo; - private: /** Creates the various framebuffers/renderers available in this system. @@ -577,12 +538,6 @@ class OSystem */ 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. Also, update the settings with the new name. For now, validation diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index 3d8363a68..e58e4dcc5 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -144,7 +144,6 @@ void TIA::reset() myCollisionMask = 0; myLinesSinceChange = 0; myCollisionUpdateRequired = false; - myAutoFrameEnabled = false; myColorLossEnabled = myColorLossActive = false; myColorHBlank = 0; myLastCycle = 0; @@ -190,7 +189,6 @@ void TIA::reset() void TIA::frameReset() { memset(myFramebuffer, 0, 160 * TIAConstants::frameBufferHeight); - myAutoFrameEnabled = mySettings.getInt("framerate") <= 0; enableColorLoss(mySettings.getBool("dev.settings") ? "dev.colorloss" : "plr.colorloss"); } @@ -277,8 +275,6 @@ bool TIA::save(Serializer& out) const out.putDouble(myTimestamp); - out.putBool(myAutoFrameEnabled); - out.putByteArray(myShadowRegisters, 64); out.putLong(myCyclesAtFrameStart); @@ -347,8 +343,6 @@ bool TIA::load(Serializer& in) myTimestamp = in.getDouble(); - myAutoFrameEnabled = in.getBool(); - in.getByteArray(myShadowRegisters, 64); myCyclesAtFrameStart = in.getLong(); @@ -1157,10 +1151,6 @@ void TIA::onFrameComplete() const Int32 missingScanlines = myFrameManager->missingScanlines(); if (missingScanlines > 0) memset(myFramebuffer + 160 * myFrameManager->getY(), 0, missingScanlines * 160); - - // Recalculate framerate, attempting to auto-correct for scanline 'jumps' - if(myAutoFrameEnabled) - myConsole.setFramerate(myFrameManager->frameRate()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index 7cbf94872..9ab8350c6 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -229,14 +229,6 @@ class TIA : public Device */ 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; } /** @@ -760,11 +752,6 @@ class TIA : public Device */ uInt8 myShadowRegisters[64]; - /** - * Automatic framerate correction based on number of scanlines. - */ - bool myAutoFrameEnabled; - /** * Indicates if color loss should be enabled or disabled. Color loss * occurs on PAL-like systems when the previous frame contains an odd diff --git a/src/gui/VideoDialog.cxx b/src/gui/VideoDialog.cxx index 007e663ec..0ef087592 100644 --- a/src/gui/VideoDialog.cxx +++ b/src/gui/VideoDialog.cxx @@ -410,9 +410,7 @@ void VideoDialog::saveConfig() instance().settings().setValue("framerate", f); if(instance().hasConsole()) { - // Make sure auto-frame calculation is only enabled when necessary - instance().console().tia().enableAutoFrame(f <= 0); - instance().console().setFramerate(float(f)); + // instance().console().setFramerate(float(f)); } // Fullscreen