From 6fc3863ef9cfc29c28835fa5af99afc1ee06201e Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 17 May 2019 22:19:27 +0200 Subject: [PATCH] make Stella remember the last window position (now Center option makes a difference!) --- src/common/FrameBufferSDL2.cxx | 68 ++++++++++++++++++++++++---------- src/common/FrameBufferSDL2.hxx | 29 ++++++++++----- src/emucore/FrameBuffer.cxx | 3 +- src/emucore/FrameBuffer.hxx | 32 ++++++++++++---- src/emucore/OSystem.cxx | 5 +++ src/emucore/Settings.cxx | 5 ++- 6 files changed, 104 insertions(+), 38 deletions(-) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index ec882ddb8..541545e6c 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -31,7 +31,8 @@ FrameBufferSDL2::FrameBufferSDL2(OSystem& osystem) : FrameBuffer(osystem), myWindow(nullptr), - myRenderer(nullptr) + myRenderer(nullptr), + myCenter(false) { ASSERT_MAIN_THREAD; @@ -88,11 +89,11 @@ void FrameBufferSDL2::queryHardware(vector& fullscreenRes, ASSERT_MAIN_THREAD; // Get number of displays (for most systems, this will be '1') - int maxDisplays = SDL_GetNumVideoDisplays(); + myNumDisplays = SDL_GetNumVideoDisplays(); // First get the maximum fullscreen desktop resolution SDL_DisplayMode display; - for(int i = 0; i < maxDisplays; ++i) + for(int i = 0; i < myNumDisplays; ++i) { SDL_GetDesktopDisplayMode(i, &display); fullscreenRes.emplace_back(display.w, display.h); @@ -102,14 +103,14 @@ void FrameBufferSDL2::queryHardware(vector& fullscreenRes, // Try to take into account taskbars, etc, if available #if SDL_VERSION_ATLEAST(2,0,5) SDL_Rect r; - for(int i = 0; i < maxDisplays; ++i) + for(int i = 0; i < myNumDisplays; ++i) { // Display bounds minus dock SDL_GetDisplayUsableBounds(i, &r); // Requires SDL-2.0.5 or higher windowedRes.emplace_back(r.w, r.h); } #else - for(int i = 0; i < maxDisplays; ++i) + for(int i = 0; i < myNumDisplays; ++i) { SDL_GetDesktopDisplayMode(i, &display); windowedRes.emplace_back(display.w, display.h); @@ -162,6 +163,27 @@ Int32 FrameBufferSDL2::getCurrentDisplayIndex() return SDL_GetWindowDisplayIndex(myWindow); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FrameBufferSDL2::getCurrentWindowPos(int& x, int&y) +{ + ASSERT_MAIN_THREAD; + + if (myCenter || + !myWindow || (SDL_GetWindowFlags(myWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP)) + { + // restore to last saved window position + x = myOSystem.settings().getInt("pos.x"); + y = myOSystem.settings().getInt("pos.y"); + } + else + { + // save current window position + SDL_GetWindowPosition(myWindow, &x, &y); + myOSystem.settings().setValue("pos.x", x); + myOSystem.settings().setValue("pos.y", y); + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) { @@ -171,15 +193,8 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) if(SDL_WasInit(SDL_INIT_VIDEO) == 0) return false; - // Always recreate renderer (some systems need this) - if(myRenderer) - { - SDL_DestroyRenderer(myRenderer); - myRenderer = nullptr; - } - Int32 displayIndex = mode.fsIndex; - if(displayIndex == -1) + if (displayIndex == -1) { // windowed mode if (myWindow) @@ -187,16 +202,27 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) // Show it on same screen as the previous window displayIndex = SDL_GetWindowDisplayIndex(myWindow); } - if(displayIndex < 0) + if (displayIndex < 0) { - // fallback to the first screen - displayIndex = 0; + // fallback to the last used screen if still existing + displayIndex = std::min(myNumDisplays, myOSystem.settings().getInt("display")); } } - uInt32 pos = myOSystem.settings().getBool("center") - ? SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex) - : SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex); + // get current windows position + int posX, posY; + getCurrentWindowPos(posX, posY); + + // Always recreate renderer (some systems need this) + if(myRenderer) + { + SDL_DestroyRenderer(myRenderer); + myRenderer = nullptr; + } + + myCenter = myOSystem.settings().getBool("center"); + if (myCenter) + posX = posY = SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex); uInt32 flags = mode.fsIndex != -1 ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0; // macOS seems to have issues with destroying the window, and wants to @@ -221,6 +247,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) { // Even though window size stayed the same, the title may have changed SDL_SetWindowTitle(myWindow, title.c_str()); + SDL_SetWindowPosition(myWindow, posX, posY); } #else // macOS wants to *never* re-create the window @@ -236,7 +263,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) #endif else { - myWindow = SDL_CreateWindow(title.c_str(), pos, pos, + myWindow = SDL_CreateWindow(title.c_str(), posX, posY, mode.screen.w, mode.screen.h, flags); if(myWindow == nullptr) { @@ -311,6 +338,7 @@ void FrameBufferSDL2::invalidate() { ASSERT_MAIN_THREAD; + SDL_RenderClear(myRenderer); } diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index 8aed202ab..568bdc4ef 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -97,6 +97,23 @@ class FrameBufferSDL2 : public FrameBuffer */ void readPixels(uInt8* buffer, uInt32 pitch, const Common::Rect& rect) const override; + /** + This method is called to query the video hardware for the index + of the display the current window is displayed on + + @return the current display index or a negative value if no + window is displayed + */ + Int32 getCurrentDisplayIndex() override; + + /** + This method is called to query the current window position. + + @param x The x-position retrieved + @param y The y-position retrieved + */ + void getCurrentWindowPos(int& x, int& y) override; + /** Clear the frame buffer */ @@ -119,15 +136,6 @@ class FrameBufferSDL2 : public FrameBuffer vector& windowedRes, VariantList& renderers) override; - /** - This method is called to query the video hardware for the index - of the display the current window is displayed on - - @return the current display index or a negative value if no - window is displayed - */ - Int32 getCurrentDisplayIndex() override; - /** This method is called to change to the given video mode. @@ -184,6 +192,9 @@ class FrameBufferSDL2 : public FrameBuffer // Used by mapRGB (when palettes are created) SDL_PixelFormat* myPixelFormat; + // center setting of curent window + bool myCenter; + private: // Following constructors and assignment operators not supported FrameBufferSDL2() = delete; diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 895862343..86c6b6901 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -55,7 +55,8 @@ FrameBuffer::FrameBuffer(OSystem& osystem) myGrabMouse(false), myHiDPIAllowed(false), myHiDPIEnabled(false), - myCurrentModeList(nullptr) + myCurrentModeList(nullptr), + myNumDisplays(1) { } diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 965bc445b..6c236989e 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -335,6 +335,23 @@ class FrameBuffer */ virtual void readPixels(uInt8* buffer, uInt32 pitch, const Common::Rect& rect) const = 0; + /** + This method is called to query the video hardware for the index + of the display the current window is displayed on + + @return the current display index or a negative value if no + window is displayed + */ + virtual Int32 getCurrentDisplayIndex() = 0; + + /** + This method is called to query the current window position. + + @param x The x-position retrieved + @param y The y-position retrieved + */ + virtual void getCurrentWindowPos(int& x, int& y) = 0; + /** Clear the framebuffer. */ @@ -354,8 +371,6 @@ class FrameBuffer vector& windowedRes, VariantList& renderers) = 0; - virtual Int32 getCurrentDisplayIndex() = 0; - /** This method is called to change to the given video mode. @@ -497,6 +512,14 @@ class FrameBuffer // Title of the main window/screen string myScreenTitle; + // Number of displays + int myNumDisplays; + + // The resolution of the attached displays in fullscreen mode + // The primary display is typically the first in the array + // Windowed modes use myDesktopSize directly + vector myFullscreenDisplays; + private: // Draws the frame stats overlay void drawFrameStats(float framesPerSecond); @@ -522,11 +545,6 @@ class FrameBuffer // Maximum absolute dimensions of the desktop area Common::Size myAbsDesktopSize; - // The resolution of the attached displays in fullscreen mode - // The primary display is typically the first in the array - // Windowed modes use myDesktopSize directly - vector myFullscreenDisplays; - // Supported renderers VariantList myRenderers; diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 879299ab1..f1283a757 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -233,6 +233,11 @@ void OSystem::loadConfig(const Settings::Options& options) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void OSystem::saveConfig() { + // Save the current window position and display on system shutdown + int x, y; + myFrameBuffer->getCurrentWindowPos(x, y); + settings().setValue("display", myFrameBuffer->getCurrentDisplayIndex()); + // Ask all subsystems to save their settings if(myFrameBuffer) { diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index af85bcc49..78c88891e 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -37,7 +37,10 @@ Settings::Settings() setPermanent("video", ""); setPermanent("speed", "1.0"); setPermanent("vsync", "true"); - setPermanent("center", "false"); + setPermanent("center", "true"); + setPermanent("pos.x", 50); + setPermanent("pos.y", 50); + setPermanent("display", 0); setPermanent("palette", "standard"); setPermanent("uimessages", "true");