From d09ac569e569fac6763497022632430cfbde9f2f Mon Sep 17 00:00:00 2001 From: stephena Date: Wed, 4 Jun 2014 12:15:54 +0000 Subject: [PATCH] Finally have fullscreen/windowed mode switching working. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2904 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- src/common/FrameBufferSDL2.cxx | 57 +++++++++++++++++----------------- src/common/FrameBufferSDL2.hxx | 12 ++----- src/emucore/FrameBuffer.cxx | 33 +++++++------------- 3 files changed, 42 insertions(+), 60 deletions(-) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 732894eaa..6d4b2b049 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -38,7 +38,6 @@ FrameBufferSDL2::FrameBufferSDL2(OSystem& osystem) : FrameBuffer(osystem), myWindow(NULL), myRenderer(NULL), - myWindowFlags(0), myDirtyFlag(true), myDblBufferedFlag(true) { @@ -97,54 +96,54 @@ void FrameBufferSDL2::queryHardware(uInt32& w, uInt32& h, VariantList& renderers // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode, - bool fullscreen_toggle) + bool /*fullscreen_toggle*/) { -cerr << "fullscreen_toggle=" << fullscreen_toggle << endl; -#if 0 - uInt32 flags = enable ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0; - if(SDL_SetWindowFullscreen(myWindow, flags)) - myOSystem.settings().setValue("fullscreen", enable); -#endif - // If not initialized by this point, then immediately fail if(SDL_WasInit(SDL_INIT_VIDEO) == 0) return false; - // (Re)create window and renderer + // Always recreate renderer (some systems need this) if(myRenderer) { SDL_DestroyRenderer(myRenderer); myRenderer = NULL; } + // Don't re-create the window if its size hasn't changed, as it is + // wasteful, and causing flashing in fullscreen mode if(myWindow) { - SDL_DestroyWindow(myWindow); - myWindow = NULL; + int w, h; + SDL_GetWindowSize(myWindow, &w, &h); + if(w != mode.screen.w || h != mode.screen.h) + { + SDL_DestroyWindow(myWindow); + myWindow = NULL; + } } - // Window centering option - int pos = myOSystem.settings().getBool("center") - ? SDL_WINDOWPOS_CENTERED : SDL_WINDOWPOS_UNDEFINED; - myWindow = SDL_CreateWindow(title.c_str(), - pos, pos, mode.screen.w, mode.screen.h, - 0); - if(myWindow == NULL) + if(!myWindow) { - string msg = "ERROR: Unable to open SDL window: " + string(SDL_GetError()); - myOSystem.logMessage(msg, 0); - return false; + int pos = myOSystem.settings().getBool("center") + ? SDL_WINDOWPOS_CENTERED : SDL_WINDOWPOS_UNDEFINED; + myWindow = SDL_CreateWindow(title.c_str(), + pos, pos, mode.screen.w, mode.screen.h, + mode.fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + if(myWindow == NULL) + { + string msg = "ERROR: Unable to open SDL window: " + string(SDL_GetError()); + myOSystem.logMessage(msg, 0); + return false; + } } - // V'synced blits option Uint32 renderFlags = SDL_RENDERER_ACCELERATED; - if(myOSystem.settings().getBool("vsync")) + if(myOSystem.settings().getBool("vsync")) // V'synced blits option renderFlags |= SDL_RENDERER_PRESENTVSYNC; - // Render hint - const string& video = myOSystem.settings().getString("video"); + const string& video = myOSystem.settings().getString("video"); // Render hint if(video != "") SDL_SetHint(SDL_HINT_RENDER_DRIVER, video.c_str()); myRenderer = SDL_CreateRenderer(myWindow, -1, renderFlags); - if(myWindow == NULL) + if(myRenderer == NULL) { string msg = "ERROR: Unable to create SDL renderer: " + string(SDL_GetError()); myOSystem.logMessage(msg, 0); @@ -186,7 +185,7 @@ string FrameBufferSDL2::about() const void FrameBufferSDL2::invalidate() { myDirtyFlag = true; -// SDL_RenderClear(myRenderer); + SDL_RenderClear(myRenderer); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -216,7 +215,7 @@ void FrameBufferSDL2::postFrameUpdate() { if(myDirtyFlag) { - // Now show all changes made to the texture(s) + // Now show all changes made to the renderer SDL_RenderPresent(myRenderer); myDirtyFlag = false; } diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index 97982f3c9..ea00a8665 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -165,22 +165,16 @@ class FrameBufferSDL2 : public FrameBuffer SDL_Window* myWindow; SDL_Renderer* myRenderer; - // SDL initialization flags - // This is set by the base FrameBuffer class, and read by the derived classes - // If a FrameBuffer is successfully created, the derived classes must modify - // it to point to the actual flags used by the SDL_Surface - uInt32 myWindowFlags; - // Used by mapRGB (when palettes are created) SDL_PixelFormat* myPixelFormat; - // The depth of the texture buffer + // The depth of the render buffer uInt32 myDepth; - // Indicates that the texture has been modified, and should be redrawn + // Indicates that the renderer has been modified, and should be redrawn bool myDirtyFlag; - // Indicates whether the backend is using double buffering + // Indicates whether the render backend is using double buffering bool myDblBufferedFlag; }; diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index b8f90d564..dd020d800 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -192,16 +192,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, (myDesktopSize.w < width || myDesktopSize.h < height)) return kFailTooLarge; -// FIXSDL - remove size limitations here? - if(myOSystem.settings().getBool("fullscreen")) - { - if(myDesktopSize.w < width || myDesktopSize.h < height) - return kFailTooLarge; - - useFullscreen = true; - } - else - useFullscreen = false; + useFullscreen = myOSystem.settings().getBool("fullscreen"); #else // Make sure this mode is even possible // We only really need to worry about it in non-windowed environments, @@ -676,8 +667,6 @@ void FrameBuffer::stateChanged(EventHandler::State state) void FrameBuffer::setFullscreen(bool enable) { const VideoMode& mode = getSavedVidMode(enable); -cerr << "setFullscreen: " << enable << " " << mode << endl; - if(setVideoMode(myScreenTitle, mode, true)) { myImageRect = mode.image; @@ -897,34 +886,34 @@ void VideoMode::applyAspectCorrection(uInt32 aspect, bool stretch) { // Fullscreen mode stretching float stretchFactor = 1.0; - float scaleX = float(image.width()) / screen.w; - float scaleY = float(image.height()) / screen.h; + float scaleX = float(iw) / screen.w; + float scaleY = float(ih) / screen.h; // Scale to actual or integral factors if(stretch) { // Scale to full (non-integral) available space if(scaleX > scaleY) - stretchFactor = float(screen.w) / image.width(); + stretchFactor = float(screen.w) / iw; else - stretchFactor = float(screen.h) / image.height(); + stretchFactor = float(screen.h) / ih; } else { // Only scale to an integral amount if(scaleX > scaleY) { - int bw = image.width() / zoom; - stretchFactor = float(int(screen.w / bw) * bw) / image.width(); + int bw = iw / zoom; + stretchFactor = float(int(screen.w / bw) * bw) / iw; } else { - int bh = image.height() / zoom; - stretchFactor = float(int(screen.h / bh) * bh) / image.height(); + int bh = ih / zoom; + stretchFactor = float(int(screen.h / bh) * bh) / ih; } } - iw = (uInt32) (stretchFactor * image.width()); - ih = (uInt32) (stretchFactor * image.height()); + iw = (uInt32) (stretchFactor * iw); + ih = (uInt32) (stretchFactor * ih); } else {