aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorColin Snover2017-10-01 16:23:22 -0500
committerColin Snover2017-10-07 12:30:29 -0500
commit6e157429b7a5a64af6265d075c88595df2d6fd79 (patch)
tree6e16e359d2f427ff0aa17ae229780509595ee1b1 /backends
parent24f5d456195df3b65ed2876cbca2e2981f3d1a07 (diff)
downloadscummvm-rg350-6e157429b7a5a64af6265d075c88595df2d6fd79.tar.gz
scummvm-rg350-6e157429b7a5a64af6265d075c88595df2d6fd79.tar.bz2
scummvm-rg350-6e157429b7a5a64af6265d075c88595df2d6fd79.zip
BACKENDS: Fix window sizing of games that switch between multiple resolutions
Diffstat (limited to 'backends')
-rw-r--r--backends/graphics/graphics.h2
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.cpp17
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.h5
-rw-r--r--backends/graphics/sdl/sdl-graphics.cpp89
-rw-r--r--backends/graphics/sdl/sdl-graphics.h14
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp45
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.h2
-rw-r--r--backends/modular-backend.cpp4
-rw-r--r--backends/modular-backend.h1
-rw-r--r--backends/platform/sdl/sdl-window.cpp29
10 files changed, 176 insertions, 32 deletions
diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index 35f2fa1cb6..9f07d36190 100644
--- a/backends/graphics/graphics.h
+++ b/backends/graphics/graphics.h
@@ -27,6 +27,7 @@
#include "common/noncopyable.h"
#include "common/keyboard.h"
+#include "graphics/mode.h"
#include "graphics/palette.h"
/**
@@ -58,6 +59,7 @@ public:
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const = 0;
#endif
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) = 0;
+ virtual void initSizeHint(const Graphics::ModeList &modes) = 0;
virtual int getScreenChangeID() const = 0;
virtual void beginGFXTransaction() = 0;
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index efc10a0d2c..73fc87a75f 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -268,22 +268,19 @@ bool OpenGLSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
}
}
-bool OpenGLSdlGraphicsManager::setGraphicsMode(int mode) {
+void OpenGLSdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFormat *format) {
// HACK: This is stupid but the SurfaceSDL backend defaults to 2x. This
// assures that the launcher (which requests 320x200) has a reasonable
// size. It also makes small games have a reasonable size (i.e. at least
// 640x400). We follow the same logic here until we have a better way to
// give hints to our backend for that.
- _graphicsScale = 2;
-
- return OpenGLGraphicsManager::setGraphicsMode(mode);
-}
-
-void OpenGLSdlGraphicsManager::resetGraphicsScale() {
- OpenGLGraphicsManager::resetGraphicsScale();
+ if (w > 320) {
+ _graphicsScale = 1;
+ } else {
+ _graphicsScale = 2;
+ }
- // HACK: See OpenGLSdlGraphicsManager::setGraphicsMode.
- _graphicsScale = 1;
+ return OpenGLGraphicsManager::initSize(w, h, format);
}
#ifdef USE_RGB_COLOR
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h
index 51edcb4363..c5003d867b 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.h
+++ b/backends/graphics/openglsdl/openglsdl-graphics.h
@@ -43,8 +43,7 @@ public:
virtual void setFeatureState(OSystem::Feature f, bool enable);
virtual bool getFeatureState(OSystem::Feature f);
- virtual bool setGraphicsMode(int mode);
- virtual void resetGraphicsScale();
+ virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format) override;
#ifdef USE_RGB_COLOR
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
@@ -69,6 +68,8 @@ protected:
virtual void refreshScreen();
virtual void *getProcAddress(const char *name) const;
+ virtual int getGraphicsModeScale(int mode) const override { return 1; }
+
private:
bool setupMode(uint width, uint height);
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index aa6087beae..a181582235 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -23,12 +23,14 @@
#include "backends/graphics/sdl/sdl-graphics.h"
#include "backends/platform/sdl/sdl-sys.h"
#include "backends/events/sdl/sdl-events.h"
+#include "common/config-manager.h"
#include "common/textconsole.h"
+#include "graphics/scaler/aspect.h"
SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *source, SdlWindow *window)
: _eventSource(source), _window(window)
#if SDL_VERSION_ATLEAST(2, 0, 0)
- , _allowWindowSizeReset(false), _lastFlags(0)
+ , _allowWindowSizeReset(false), _hintedWidth(0), _hintedHeight(0), _lastFlags(0)
#endif
{
}
@@ -63,7 +65,7 @@ bool SdlGraphicsManager::setState(const State &state) {
#ifdef USE_RGB_COLOR
initSize(state.screenWidth, state.screenHeight, &state.pixelFormat);
#else
- initSize(state.screenWidth, state.screenHeight, 0);
+ initSize(state.screenWidth, state.screenHeight, nullptr);
#endif
setFeatureState(OSystem::kFeatureAspectRatioCorrection, state.aspectRatio);
setFeatureState(OSystem::kFeatureFullscreenMode, state.fullscreen);
@@ -76,8 +78,82 @@ bool SdlGraphicsManager::setState(const State &state) {
}
}
+bool SdlGraphicsManager::defaultGraphicsModeConfig() const {
+ const Common::ConfigManager::Domain *transientDomain = ConfMan.getDomain(Common::ConfigManager::kTransientDomain);
+ if (transientDomain && transientDomain->contains("gfx_mode")) {
+ const Common::String &mode = transientDomain->getVal("gfx_mode");
+ if (!mode.equalsIgnoreCase("normal") && !mode.equalsIgnoreCase("default")) {
+ return false;
+ }
+ }
+
+ const Common::ConfigManager::Domain *gameDomain = ConfMan.getActiveDomain();
+ if (gameDomain && gameDomain->contains("gfx_mode")) {
+ const Common::String &mode = gameDomain->getVal("gfx_mode");
+ if (!mode.equalsIgnoreCase("normal") && !mode.equalsIgnoreCase("default")) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+int SdlGraphicsManager::getGraphicsModeIdByName(const Common::String &name) const {
+ const OSystem::GraphicsMode *mode = getSupportedGraphicsModes();
+ while (mode && mode->name != nullptr) {
+ if (name.equalsIgnoreCase(mode->name)) {
+ return mode->id;
+ }
+ ++mode;
+ }
+ return -1;
+}
+
+void SdlGraphicsManager::initSizeHint(const Graphics::ModeList &modes) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
-bool SdlGraphicsManager::createOrUpdateWindow(const int width, const int height, const Uint32 flags) {
+ const bool useDefault = defaultGraphicsModeConfig();
+
+ int scale = getGraphicsModeScale(getGraphicsModeIdByName(ConfMan.get("gfx_mode")));
+ if (scale == -1) {
+ warning("Unknown scaler; defaulting to 1");
+ scale = 1;
+ }
+
+ int16 bestWidth = 0, bestHeight = 0;
+ const Graphics::ModeList::const_iterator end = modes.end();
+ for (Graphics::ModeList::const_iterator it = modes.begin(); it != end; ++it) {
+ int16 width = it->width, height = it->height;
+
+ // TODO: Normalize AR correction by passing a PAR in the mode list
+ // instead of checking the dimensions here like this, since not all
+ // 320x200/640x400 uses are with non-square pixels (e.g. DreamWeb).
+ if (ConfMan.getBool("aspect_ratio")) {
+ if ((width == 320 && height == 200) || (width == 640 && height == 400)) {
+ height = real2Aspect(height);
+ }
+ }
+
+ if (!useDefault || width <= 320) {
+ width *= scale;
+ height *= scale;
+ }
+
+ if (bestWidth < width) {
+ bestWidth = width;
+ }
+
+ if (bestHeight < height) {
+ bestHeight = height;
+ }
+ }
+
+ _hintedWidth = bestWidth;
+ _hintedHeight = bestHeight;
+#endif
+}
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+bool SdlGraphicsManager::createOrUpdateWindow(int width, int height, const Uint32 flags) {
if (!_window) {
return false;
}
@@ -88,6 +164,13 @@ bool SdlGraphicsManager::createOrUpdateWindow(const int width, const int height,
// size or pixel format of the internal game surface (since a user may have
// resized the game window)
if (!_window->getSDLWindow() || _lastFlags != flags || _allowWindowSizeReset) {
+ if (_hintedWidth) {
+ width = _hintedWidth;
+ }
+ if (_hintedHeight) {
+ height = _hintedHeight;
+ }
+
if (!_window->createOrUpdateWindow(width, height, flags)) {
return false;
}
diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h
index 937beef9b4..74ee2838ea 100644
--- a/backends/graphics/sdl/sdl-graphics.h
+++ b/backends/graphics/sdl/sdl-graphics.h
@@ -122,14 +122,26 @@ public:
*/
SdlWindow *getWindow() const { return _window; }
+ virtual void initSizeHint(const Graphics::ModeList &modes) override;
+
protected:
+ virtual int getGraphicsModeScale(int mode) const = 0;
+
+ bool defaultGraphicsModeConfig() const;
+ int getGraphicsModeIdByName(const Common::String &name) const;
+
#if SDL_VERSION_ATLEAST(2, 0, 0)
public:
- void unlockWindowSize() { _allowWindowSizeReset = true; }
+ void unlockWindowSize() {
+ _allowWindowSizeReset = true;
+ _hintedWidth = 0;
+ _hintedHeight = 0;
+ }
protected:
Uint32 _lastFlags;
bool _allowWindowSizeReset;
+ int _hintedWidth, _hintedHeight;
bool createOrUpdateWindow(const int width, const int height, const Uint32 flags);
#endif
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index de54145d5f..897cdcb352 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -598,19 +598,11 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() {
}
#endif
-bool SurfaceSdlGraphicsManager::setGraphicsMode(int mode) {
- Common::StackLock lock(_graphicsMutex);
-
- assert(_transactionMode == kTransactionActive);
-
- if (_oldVideoMode.setup && _oldVideoMode.mode == mode)
- return true;
-
- int newScaleFactor = 1;
-
+int SurfaceSdlGraphicsManager::getGraphicsModeScale(int mode) const {
+ int scale;
switch (mode) {
case GFX_NORMAL:
- newScaleFactor = 1;
+ scale = 1;
break;
#ifdef USE_SCALERS
case GFX_DOUBLESIZE:
@@ -623,18 +615,34 @@ bool SurfaceSdlGraphicsManager::setGraphicsMode(int mode) {
#ifdef USE_HQ_SCALERS
case GFX_HQ2X:
#endif
- newScaleFactor = 2;
+ scale = 2;
break;
case GFX_TRIPLESIZE:
case GFX_ADVMAME3X:
#ifdef USE_HQ_SCALERS
case GFX_HQ3X:
#endif
- newScaleFactor = 3;
+ scale = 3;
break;
#endif
-
default:
+ scale = -1;
+ }
+
+ return scale;
+}
+
+bool SurfaceSdlGraphicsManager::setGraphicsMode(int mode) {
+ Common::StackLock lock(_graphicsMutex);
+
+ assert(_transactionMode == kTransactionActive);
+
+ if (_oldVideoMode.setup && _oldVideoMode.mode == mode)
+ return true;
+
+ int newScaleFactor = getGraphicsModeScale(mode);
+
+ if (newScaleFactor == -1) {
warning("unknown gfx mode %d", mode);
return false;
}
@@ -774,6 +782,15 @@ void SurfaceSdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFo
return;
#endif
+ if ((int)w != _videoMode.screenWidth || (int)h != _videoMode.screenHeight) {
+ const bool useDefault = defaultGraphicsModeConfig();
+ if (useDefault && w > 320) {
+ resetGraphicsScale();
+ } else {
+ setGraphicsMode(getGraphicsModeIdByName(ConfMan.get("gfx_mode")));
+ }
+ }
+
_videoMode.screenWidth = w;
_videoMode.screenHeight = h;
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index e93cf410ea..62a4a38d3e 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -190,6 +190,8 @@ protected:
/** Hardware screen */
SDL_Surface *_hwscreen;
+ virtual int getGraphicsModeScale(int mode) const override;
+
#if SDL_VERSION_ATLEAST(2, 0, 0)
/* SDL2 features a different API for 2D graphics. We create a wrapper
* around this API to keep the code paths as close as possible. */
diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp
index 1dab18d54e..c9adbd3100 100644
--- a/backends/modular-backend.cpp
+++ b/backends/modular-backend.cpp
@@ -113,6 +113,10 @@ void ModularBackend::initSize(uint w, uint h, const Graphics::PixelFormat *forma
_graphicsManager->initSize(w, h, format);
}
+void ModularBackend::initSizeHint(const Graphics::ModeList &modes) {
+ _graphicsManager->initSizeHint(modes);
+}
+
int ModularBackend::getScreenChangeID() const {
return _graphicsManager->getScreenChangeID();
}
diff --git a/backends/modular-backend.h b/backends/modular-backend.h
index d828c2dde6..982dbbfb02 100644
--- a/backends/modular-backend.h
+++ b/backends/modular-backend.h
@@ -75,6 +75,7 @@ public:
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
#endif
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL);
+ virtual void initSizeHint(const Graphics::ModeList &modes) override;
virtual int getScreenChangeID() const;
virtual void beginGFXTransaction();
diff --git a/backends/platform/sdl/sdl-window.cpp b/backends/platform/sdl/sdl-window.cpp
index 07ddc998ba..75cf813638 100644
--- a/backends/platform/sdl/sdl-window.cpp
+++ b/backends/platform/sdl/sdl-window.cpp
@@ -223,6 +223,33 @@ bool SdlWindow::createOrUpdateWindow(int width, int height, uint32 flags) {
const uint32 oldNonUpdateableFlags = _lastFlags & ~updateableFlagsMask;
const uint32 newNonUpdateableFlags = flags & ~updateableFlagsMask;
+ const uint32 fullscreenFlags = flags & fullscreenMask;
+
+ // This is terrible, but there is no way in SDL to get information on the
+ // maximum bounds of a window with decoration, and SDL is too dumb to make
+ // sure the window's surface doesn't grow beyond the display bounds, which
+ // can easily happen with 3x scalers. There is a function in SDL to get the
+ // window decoration size, but it only exists starting in SDL 2.0.5, which
+ // is a buggy release on some platforms so we can't safely use 2.0.5+
+ // features since some users replace the SDL dynamic library with 2.0.4, and
+ // the documentation says it only works on X11 anyway, which means it is
+ // basically worthless. So we'll just try to keep things closeish to the
+ // maximum for now.
+ SDL_DisplayMode displayMode;
+ SDL_GetDesktopDisplayMode(0, &displayMode);
+ if (!fullscreenFlags) {
+ displayMode.w -= 20;
+ displayMode.h -= 30;
+ }
+
+ if (width > displayMode.w) {
+ width = displayMode.w;
+ }
+
+ if (height > displayMode.h) {
+ height = displayMode.h;
+ }
+
if (!_window || oldNonUpdateableFlags != newNonUpdateableFlags) {
destroyWindow();
_window = SDL_CreateWindow(_windowCaption.c_str(), _lastX,
@@ -231,8 +258,6 @@ bool SdlWindow::createOrUpdateWindow(int width, int height, uint32 flags) {
setupIcon();
}
} else {
- const uint32 fullscreenFlags = flags & fullscreenMask;
-
if (fullscreenFlags) {
SDL_DisplayMode fullscreenMode;
fullscreenMode.w = width;