From 9e9957b664754fd83adc9dd02b464c04eb8b7e47 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 20 Dec 2020 13:39:28 -0330 Subject: [PATCH] Fix segfault when exceptions are thrown on errors. That was exactly the point of exceptions; to NOT crash the app! --- src/common/FBBackendSDL2.cxx | 5 ++--- src/emucore/FrameBuffer.cxx | 36 +++++++++++++++++++++++++++--------- src/emucore/FrameBuffer.hxx | 18 +++++++++++++----- src/emucore/OSystem.cxx | 21 ++++++++------------- 4 files changed, 50 insertions(+), 30 deletions(-) diff --git a/src/common/FBBackendSDL2.cxx b/src/common/FBBackendSDL2.cxx index 7095cc273..f2738be39 100644 --- a/src/common/FBBackendSDL2.cxx +++ b/src/common/FBBackendSDL2.cxx @@ -39,9 +39,8 @@ FBBackendSDL2::FBBackendSDL2(OSystem& osystem) if(SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { ostringstream buf; - buf << "ERROR: Couldn't initialize SDL: " << SDL_GetError() << endl; - Logger::error(buf.str()); - throw runtime_error("FATAL ERROR"); + buf << "ERROR: Couldn't initialize SDL: " << SDL_GetError(); + throw runtime_error(buf.str()); } Logger::debug("FBBackendSDL2::FBBackendSDL2 SDL_Init()"); diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 4b1d4a5ca..0866ecf58 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -31,6 +31,7 @@ #include "FBSurface.hxx" #include "TIASurface.hxx" #include "FrameBuffer.hxx" +#include "PaletteHandler.hxx" #include "StateManager.hxx" #include "RewindManager.hxx" @@ -78,8 +79,7 @@ void FrameBuffer::initialize() { // First create the platform-specific backend; it is needed before anything // else can be used - try { myBackend = MediaFactory::createVideoBackend(myOSystem); } - catch(const runtime_error& e) { throw e; } + myBackend = MediaFactory::createVideoBackend(myOSystem); // Get desktop resolution and supported renderers vector windowedDisplays; @@ -952,7 +952,7 @@ void FrameBuffer::stateChanged(EventHandlerState state) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string FrameBuffer::getDisplayKey() +string FrameBuffer::getDisplayKey() const { // save current window's display and position switch(myBufferType) @@ -974,7 +974,7 @@ string FrameBuffer::getDisplayKey() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string FrameBuffer::getPositionKey() +string FrameBuffer::getPositionKey() const { // save current window's display and position switch(myBufferType) @@ -996,13 +996,31 @@ string FrameBuffer::getPositionKey() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::saveCurrentWindowPosition() +void FrameBuffer::saveCurrentWindowPosition() const { - myOSystem.settings().setValue( - getDisplayKey(), myBackend->getCurrentDisplayIndex()); - if(myBackend->isCurrentWindowPositioned()) + if(myBackend) + { myOSystem.settings().setValue( - getPositionKey(), myBackend->getCurrentWindowPos()); + getDisplayKey(), myBackend->getCurrentDisplayIndex()); + if(myBackend->isCurrentWindowPositioned()) + myOSystem.settings().setValue( + getPositionKey(), myBackend->getCurrentWindowPos()); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FrameBuffer::saveConfig(Settings& settings) const +{ + // Save the last windowed position and display on system shutdown + saveCurrentWindowPosition(); + + if(myTIASurface) + { + Logger::debug("Saving TV effects options ..."); + tiaSurface().ntsc().saveConfig(settings); + Logger::debug("Saving palette settings..."); + tiaSurface().paletteHandler().saveConfig(settings); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 992b7b790..4cd658c19 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -291,12 +291,12 @@ class FrameBuffer uInt32 hidpiScaleFactor() const { return myHiDPIEnabled ? 2 : 1; } /** - These methods are used to load/save position and display of the - current window. + This method should be called to save the current settings of all + its subsystems. Note that the this may be called when the class + hasn't been fully initialized, so we first need to check if the + subsytems actually exist. */ - string getPositionKey(); - string getDisplayKey(); - void saveCurrentWindowPosition(); + void saveConfig(Settings& settings) const; #ifdef GUI_SUPPORT /** @@ -376,6 +376,14 @@ class FrameBuffer int scaleY(int y) const { return myBackend->scaleY(y); } private: + /** + These methods are used to load/save position and display of the + current window. + */ + string getPositionKey() const; + string getDisplayKey() const; + void saveCurrentWindowPosition() const; + /** Calls 'free()' on all surfaces that the framebuffer knows about. */ diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index a07a319a3..6d9ab16f0 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -50,7 +50,6 @@ #include "CartCreator.hxx" #include "FrameBuffer.hxx" #include "TIASurface.hxx" -#include "PaletteHandler.hxx" #include "TIAConstants.hxx" #include "Settings.hxx" #include "PropsSet.hxx" @@ -152,8 +151,9 @@ bool OSystem::create() myFrameBuffer = make_unique(*this); myFrameBuffer->initialize(); } - catch(...) + catch(const runtime_error& e) { + Logger::error(e.what()); return false; } @@ -258,20 +258,15 @@ void OSystem::loadConfig(const Settings::Options& options) void OSystem::saveConfig() { // Ask all subsystems to save their settings - if(myFrameBuffer) + if(myFrameBuffer && mySettings) + myFrameBuffer->saveConfig(settings()); + + if(mySettings) { - // Save the last windowed position and display on system shutdown - myFrameBuffer->saveCurrentWindowPosition(); - - Logger::debug("Saving TV effects options ..."); - myFrameBuffer->tiaSurface().ntsc().saveConfig(settings()); - Logger::debug("Saving palette settings..."); - myFrameBuffer->tiaSurface().paletteHandler().saveConfig(settings()); + Logger::debug("Saving config options ..."); + mySettings->save(); } - Logger::debug("Saving config options ..."); - mySettings->save(); - if(myPropSet && myPropSet->save(myPropertiesFile)) Logger::debug("Saving properties set ..."); }