From 8f2123a5bf37264fc99630fd22975678a8837b32 Mon Sep 17 00:00:00 2001 From: stephena Date: Mon, 2 Jun 2014 14:34:12 +0000 Subject: [PATCH] Aspect ratio correction is now properly applied to the TIA in windowed and (simulated) fullscreen mode. Fullscreen mode is now simulated in that it creates a window that matches what would appear in fullscreen. The next thing to do is actually have the backend create this fullscreen mode correctly. Changed 'gl_fsscale' to 'tia.fsfill' to more properly indicate what the option does. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2894 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- docs/index.html | 4 +- src/common/FrameBufferSDL2.cxx | 20 ++--- src/common/FrameBufferSDL2.hxx | 8 +- src/emucore/FrameBuffer.cxx | 134 ++++++++++++++------------------- src/emucore/FrameBuffer.hxx | 25 +++--- src/emucore/Settings.cxx | 10 +-- src/gui/VideoDialog.cxx | 4 +- 7 files changed, 91 insertions(+), 114 deletions(-) diff --git a/docs/index.html b/docs/index.html index 00118c262..ad4f97572 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1837,8 +1837,8 @@ -
FIXSDL-gl_fsscale <1|0>
- OpenGL mode only. Stretch TIA image completely while in fullscreen mode +
-tia.fsfill <1|0>
+ Stretch TIA image completely while in fullscreen mode (vs. an integral stretch which won't necessarily completely fill the screen). diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 26b22b65c..732894eaa 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -96,8 +96,16 @@ void FrameBufferSDL2::queryHardware(uInt32& w, uInt32& h, VariantList& renderers } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) +bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode, + 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; @@ -118,7 +126,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) int pos = myOSystem.settings().getBool("center") ? SDL_WINDOWPOS_CENTERED : SDL_WINDOWPOS_UNDEFINED; myWindow = SDL_CreateWindow(title.c_str(), - pos, pos, mode.image.width(), mode.image.height(), + pos, pos, mode.screen.w, mode.screen.h, 0); if(myWindow == NULL) { @@ -193,14 +201,6 @@ void FrameBufferSDL2::grabMouse(bool grab) //FIXSDL SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBufferSDL2::enableFullscreen(bool enable) -{ - uInt32 flags = enable ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0; - if(SDL_SetWindowFullscreen(myWindow, flags)) - myOSystem.settings().setValue("fullscreen", enable); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FrameBufferSDL2::fullScreen() const { diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index 2b6c011f7..97982f3c9 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -121,12 +121,8 @@ class FrameBufferSDL2 : public FrameBuffer @return False on any errors, else true */ - bool setVideoMode(const string& title, const VideoMode& mode); - - /** - Enables/disables fullscreen mode. - */ - void enableFullscreen(bool enable); + bool setVideoMode(const string& title, const VideoMode& mode, + bool fullscreen_toggle); /** This method is called to invalidate the contents of the entire diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 0cdd572e8..b8f90d564 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -193,7 +193,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, return kFailTooLarge; // FIXSDL - remove size limitations here? - if(myOSystem.settings().getString("fullscreen") == "1") + if(myOSystem.settings().getBool("fullscreen")) { if(myDesktopSize.w < width || myDesktopSize.h < height) return kFailTooLarge; @@ -216,12 +216,13 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, // Initialize video subsystem (make sure we get a valid mode) string pre_about = about(); const VideoMode& mode = getSavedVidMode(useFullscreen); - myImageRect = mode.image; - myScreenSize = mode.screen; - if(width <= (uInt32)myScreenSize.w && height <= (uInt32)myScreenSize.h) + if(width <= (uInt32)mode.screen.w && height <= (uInt32)mode.screen.h) { if(setVideoMode(myScreenTitle, mode)) { + myImageRect = mode.image; + myScreenSize = mode.screen; + // Inform TIA surface about new mode if(myOSystem.eventHandler().state() != EventHandler::S_LAUNCHER && myOSystem.eventHandler().state() != EventHandler::S_DEBUGGER) @@ -523,9 +524,6 @@ inline void FrameBuffer::drawMessage() inline void FrameBuffer::drawTIA() { myTIASurface->render(); - - // Let postFrameUpdate() know that a change has been made -//FIXSDL invalidate(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -646,20 +644,20 @@ void FrameBuffer::resetSurfaces() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::setPalette(const uInt32* palette) +void FrameBuffer::setPalette(const uInt32* raw_palette) { // Set palette for normal fill for(int i = 0; i < 256; ++i) { - Uint8 r = (palette[i] >> 16) & 0xff; - Uint8 g = (palette[i] >> 8) & 0xff; - Uint8 b = palette[i] & 0xff; + Uint8 r = (raw_palette[i] >> 16) & 0xff; + Uint8 g = (raw_palette[i] >> 8) & 0xff; + Uint8 b = raw_palette[i] & 0xff; myPalette[i] = mapRGB(r, g, b); } // Let the TIA surface know about the new palette - myTIASurface->setPalette(myPalette, palette); + myTIASurface->setPalette(myPalette, raw_palette); myRedrawEntireFrame = true; } @@ -677,26 +675,24 @@ void FrameBuffer::stateChanged(EventHandler::State state) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBuffer::setFullscreen(bool enable) { -cerr << "setFullscreen: " << enable << endl; -enableFullscreen(enable); + const VideoMode& mode = getSavedVidMode(enable); +cerr << "setFullscreen: " << enable << " " << mode << endl; + if(setVideoMode(myScreenTitle, mode, true)) + { + myImageRect = mode.image; + myScreenSize = mode.screen; + // Inform TIA surface about new mode + if(myOSystem.eventHandler().state() != EventHandler::S_LAUNCHER && + myOSystem.eventHandler().state() != EventHandler::S_DEBUGGER) + myTIASurface->initialize(myOSystem.console(), mode); -#if 0 //FIXSDL -#ifdef WINDOWED_SUPPORT - // '-1' means fullscreen mode is completely disabled - bool full = enable && myOSystem.settings().getString("fullscreen") != "-1"; - setHint(kFullScreen, full); - - // Do a dummy call to getSavedVidMode to set up the modelists - // and have it point to the correct 'current' mode - getSavedVidMode(); - - // Do a mode change to the 'current' mode by not passing a '+1' or '-1' - // to changeVidMode() - changeVidMode(0); -#endif -#endif + // Did we get the requested fullscreen state? + myOSystem.settings().setValue("fullscreen", fullScreen()); + resetSurfaces(); + setCursorState(); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -725,14 +721,13 @@ bool FrameBuffer::changeWindowedVidMode(int direction) return false; const VideoMode& mode = myCurrentModeList->current(); - myImageRect = mode.image; - myScreenSize = mode.screen; if(setVideoMode(myScreenTitle, mode)) { + myImageRect = mode.image; + myScreenSize = mode.screen; + // Inform TIA surface about new mode - if(myOSystem.eventHandler().state() != EventHandler::S_LAUNCHER && - myOSystem.eventHandler().state() != EventHandler::S_DEBUGGER) - myTIASurface->initialize(myOSystem.console(), mode); + myTIASurface->initialize(myOSystem.console(), mode); resetSurfaces(); showMessage(mode.description); @@ -824,11 +819,10 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight) } // TIA fullscreen mode - // GUI::Size screen(myDesktopWidth, myDesktopHeight); - myFullscreenModeList.add( - VideoMode(baseWidth, baseHeight, myDesktopSize.w, myDesktopSize.h, true) - ); - + VideoMode mode(baseWidth*maxZoom, baseHeight*maxZoom, + myDesktopSize.w, myDesktopSize.h, true); + mode.applyAspectCorrection(aspect, myOSystem.settings().getBool("tia.fsfill")); + myFullscreenModeList.add(mode); } else // UI mode { @@ -840,12 +834,6 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight) VideoMode(baseWidth, baseHeight, myDesktopSize.w, myDesktopSize.h, true) ); } - -#if 0 //FIXSDL -cerr << "Windowed modes:\n" << myWindowedModeList << endl - << "Fullscreen modes:\n" << myFullscreenModeList << endl - << endl; -#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -899,54 +887,48 @@ VideoMode::VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void VideoMode::applyAspectCorrection(uInt32 aspect, uInt32 stretch) +void VideoMode::applyAspectCorrection(uInt32 aspect, bool stretch) { // Width is modified by aspect ratio; other factors may be applied below uInt32 iw = (uInt32)(float(image.width() * aspect) / 100.0); uInt32 ih = image.height(); - if(stretch) + if(fullscreen) { -#if 0 // Fullscreen mode stretching - if(fullScreen() && - (mode.image_w < mode.screen_w) && (mode.image_h < mode.screen_h)) - { - float stretchFactor = 1.0; - float scaleX = float(mode.image_w) / mode.screen_w; - float scaleY = float(mode.image_h) / mode.screen_h; + float stretchFactor = 1.0; + float scaleX = float(image.width()) / screen.w; + float scaleY = float(image.height()) / screen.h; - // Scale to actual or integral factors - if(myOSystem.settings().getBool("gl_fsscale")) + // Scale to actual or integral factors + if(stretch) + { + // Scale to full (non-integral) available space + if(scaleX > scaleY) + stretchFactor = float(screen.w) / image.width(); + else + stretchFactor = float(screen.h) / image.height(); + } + else + { + // Only scale to an integral amount + if(scaleX > scaleY) { - // Scale to full (non-integral) available space - if(scaleX > scaleY) - stretchFactor = float(mode.screen_w) / mode.image_w; - else - stretchFactor = float(mode.screen_h) / mode.image_h; + int bw = image.width() / zoom; + stretchFactor = float(int(screen.w / bw) * bw) / image.width(); } else { - // Only scale to an integral amount - if(scaleX > scaleY) - { - int bw = mode.image_w / mode.gfxmode.zoom; - stretchFactor = float(int(mode.screen_w / bw) * bw) / mode.image_w; - } - else - { - int bh = mode.image_h / mode.gfxmode.zoom; - stretchFactor = float(int(mode.screen_h / bh) * bh) / mode.image_h; - } + int bh = image.height() / zoom; + stretchFactor = float(int(screen.h / bh) * bh) / image.height(); } - mode.image_w = (Uint16) (stretchFactor * mode.image_w); - mode.image_h = (Uint16) (stretchFactor * mode.image_h); } -#endif + iw = (uInt32) (stretchFactor * image.width()); + ih = (uInt32) (stretchFactor * image.height()); } else { - // In non-stretch mode, the screen size changes to match the image width + // In windowed mode, the screen size changes to match the image width // Height is never modified in this mode screen.w = iw; } diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 21ebcb4f4..be66fa7a0 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -108,14 +108,14 @@ class VideoMode friend ostream& operator<<(ostream& os, const VideoMode& vm) { - os << "image=" << vm.image << " screen=" << vm.screen << endl - << "full= " << vm.fullscreen << " zoom=" << vm.zoom + os << "image=" << vm.image << " screen=" << vm.screen + << " full= " << vm.fullscreen << " zoom=" << vm.zoom << " desc=" << vm.description; return os; } private: - void applyAspectCorrection(uInt32 aspect, uInt32 stretch = false); + void applyAspectCorrection(uInt32 aspect, bool stretch = false); }; /** @@ -303,9 +303,9 @@ class FrameBuffer /** Set up the TIA/emulation palette for a screen of any depth > 8. - @param palette The array of colors + @param palette The array of colors in R/G/B format */ - void setPalette(const uInt32* palette); + void setPalette(const uInt32* raw_palette); /** Informs the Framebuffer of a change in EventHandler state. @@ -375,16 +375,15 @@ class FrameBuffer @param title The title for the created window @param mode The video mode to use + @param fullscreen_toggle Indicate whether this video mode change is + due to a fullscreen/windowed toggle or not; some backends + can use this information to perform a more optimized mode + change + @return False on any errors, else true */ - virtual bool setVideoMode(const string& title, const VideoMode& mode) = 0; - - /** - Enables/disables fullscreen mode. - - @param enable Set the fullscreen mode to this value - */ - virtual void enableFullscreen(bool enable) = 0; + virtual bool setVideoMode(const string& title, const VideoMode& mode, + bool fullscreen_toggle = false) = 0; /** This method is called to invalidate the contents of the entire diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index e4f2f83f6..aabf8c84c 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -53,7 +53,7 @@ Settings::Settings(OSystem& osystem) setInternal("tia.inter", "false"); setInternal("tia.aspectn", "90"); setInternal("tia.aspectp", "100"); - setInternal("gl_fsscale", "false"); //FIXSDL - deprecated + setInternal("tia.fsfill", "false"); // TV filtering options setInternal("tv.filter", "0"); @@ -341,7 +341,7 @@ void Settings::usage() << endl << " -video Type is one of the following:\n" #ifdef BSPF_WINDOWS - << " direct3d Direct3D 9/11 acceleration\n" + << " direct3d Direct3D acceleration\n" #endif << " opengl OpenGL acceleration\n" << " opengles2 OpenGLES 2 acceleration\n" @@ -368,9 +368,9 @@ void Settings::usage() #endif << " -tia.zoom Use the specified zoom level (windowed mode) for TIA image\n" << " -tia.inter <1|0> Enable interpolated (smooth) scaling for TIA image\n" - << " -tia.aspectn Scale the TIA width by the given percentage in NTSC mode\n" - << " -tia.aspectp Scale the TIA width by the given percentage in PAL mode\n" - << " -gl_fsscale <1|0> Stretch GL image in fullscreen emulation mode to max/integer scale\n" + << " -tia.aspectn Scale TIA width by the given percentage in NTSC mode\n" + << " -tia.aspectp Scale TIA width by the given percentage in PAL mode\n" + << " -tia.fsfill <1|0> Stretch TIA image to fill fullscreen mode\n" << endl << " -tv.filter <0-5> Set TV effects off (0) or to specified mode (1-5)\n" << " -tv.scanlines <0-100> Set scanline intensity to percentage (0 disables completely)\n" diff --git a/src/gui/VideoDialog.cxx b/src/gui/VideoDialog.cxx index 96fbe2905..29a2a8f60 100644 --- a/src/gui/VideoDialog.cxx +++ b/src/gui/VideoDialog.cxx @@ -353,7 +353,7 @@ void VideoDialog::loadConfig() myFullscreen->setState(instance().settings().getBool("fullscreen")); // Fullscreen stretch setting - myUseStretch->setState(instance().settings().getBool("tia.fs_stretch")); + myUseStretch->setState(instance().settings().getBool("tia.fsfill")); // Use sync to vertical blank myUseVSync->setState(instance().settings().getBool("vsync")); @@ -433,7 +433,7 @@ void VideoDialog::saveConfig() instance().console().toggleColorLoss(myColorLoss->getState()); // Fullscreen stretch setting - instance().settings().setValue("tia,fs_stretch", myUseStretch->getState()); + instance().settings().setValue("tia.fsfill", myUseStretch->getState()); // Use sync to vertical blank instance().settings().setValue("vsync", myUseVSync->getState());