aboutsummaryrefslogtreecommitdiff
path: root/backends/graphics/surfacesdl
diff options
context:
space:
mode:
authorThierry Crozat2018-05-12 19:57:21 +0100
committerThierry Crozat2018-07-08 16:54:51 +0100
commit812ce59ee44d669d2b17a1c1602f9364900b9479 (patch)
treed1a7b66bc186a5c892c67e281a502a997246f369 /backends/graphics/surfacesdl
parent8526c2c31a07e57f7166047a87474bffd82e8a03 (diff)
downloadscummvm-rg350-812ce59ee44d669d2b17a1c1602f9364900b9479.tar.gz
scummvm-rg350-812ce59ee44d669d2b17a1c1602f9364900b9479.tar.bz2
scummvm-rg350-812ce59ee44d669d2b17a1c1602f9364900b9479.zip
SDL: Implement stretch mode API
Four modes are supported: - Use original size with no scaling - Scale by an integral amount as much as possible but not bigger than the window. - Scale to fit the window while respecting the aspect ratio. There may be black bars on the left and right, or on the top and bottom, but not both. This is the default, and the old behaviour. - Scale and stretch to fit the window. In this mode the aspecy ratio is not respected and there is no black bars. The mode is controled by the "scaling_mode" value (between 0 and 3) in the config file. Also add Crtl-Alt-s hotkey to cycle through scaling modes
Diffstat (limited to 'backends/graphics/surfacesdl')
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp101
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.h11
2 files changed, 112 insertions, 0 deletions
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index fd6e2bd400..654dbd7c97 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -71,6 +71,16 @@ static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
{0, 0, 0}
};
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+const OSystem::GraphicsMode s_supportedStretchModes[] = {
+ {"center", _s("Center"), STRETCH_CENTER},
+ {"pixel-perfect", _s("Pixel-perfect scaling"), STRETCH_INTEGRAL},
+ {"fit", _s("Fit to window"), STRETCH_FIT},
+ {"stretch", _s("Stretch to window"), STRETCH_STRETCH},
+ {nullptr, nullptr, 0}
+};
+#endif
+
DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Normal (no scaling)", "lowres")
// Table of the cursor scalers [scaleFactor - 1]
@@ -196,6 +206,7 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
#if SDL_VERSION_ATLEAST(2, 0, 0)
_videoMode.filtering = ConfMan.getBool("filtering");
+ _videoMode.stretchMode = STRETCH_FIT;
#endif
// the default backend has no shaders
@@ -323,6 +334,7 @@ void SurfaceSdlGraphicsManager::beginGFXTransaction() {
_transactionDetails.needHotswap = false;
_transactionDetails.needUpdatescreen = false;
+ _transactionDetails.needDisplayResize = false;
#if SDL_VERSION_ATLEAST(2, 0, 0)
_transactionDetails.needTextureUpdate = false;
@@ -354,6 +366,10 @@ OSystem::TransactionError SurfaceSdlGraphicsManager::endGFXTransaction() {
_videoMode.mode = _oldVideoMode.mode;
_videoMode.scaleFactor = _oldVideoMode.scaleFactor;
#if SDL_VERSION_ATLEAST(2, 0, 0)
+ } else if (_videoMode.stretchMode != _oldVideoMode.stretchMode) {
+ errors |= OSystem::kTransactionStretchModeSwitchFailed;
+
+ _videoMode.stretchMode = _oldVideoMode.stretchMode;
} else if (_videoMode.filtering != _oldVideoMode.filtering) {
errors |= OSystem::kTransactionFilteringFailed;
@@ -431,6 +447,8 @@ OSystem::TransactionError SurfaceSdlGraphicsManager::endGFXTransaction() {
// To fix this issue we update the screen change count right here.
_screenChangeCount++;
+ if (_transactionDetails.needDisplayResize)
+ recalculateDisplayAreas();
if (_transactionDetails.needUpdatescreen)
internUpdateScreen();
}
@@ -438,10 +456,14 @@ OSystem::TransactionError SurfaceSdlGraphicsManager::endGFXTransaction() {
} else if (_transactionDetails.needTextureUpdate) {
setGraphicsModeIntern();
recreateScreenTexture();
+ if (_transactionDetails.needDisplayResize)
+ recalculateDisplayAreas();
internUpdateScreen();
#endif
} else if (_transactionDetails.needUpdatescreen) {
setGraphicsModeIntern();
+ if (_transactionDetails.needDisplayResize)
+ recalculateDisplayAreas();
internUpdateScreen();
}
@@ -745,6 +767,51 @@ bool SurfaceSdlGraphicsManager::setShader(int id) {
return true;
}
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+const OSystem::GraphicsMode *SurfaceSdlGraphicsManager::getSupportedStretchModes() const {
+ return s_supportedStretchModes;
+}
+
+int SurfaceSdlGraphicsManager::getDefaultStretchMode() const {
+ return STRETCH_FIT;
+}
+
+bool SurfaceSdlGraphicsManager::setStretchMode(int mode) {
+ Common::StackLock lock(_graphicsMutex);
+
+ assert(_transactionMode == kTransactionActive);
+
+ if (_oldVideoMode.setup && _oldVideoMode.stretchMode == mode)
+ return true;
+
+ // Check this is a valid mode
+ const OSystem::GraphicsMode *sm = s_supportedStretchModes;
+ bool found = false;
+ while (sm->name) {
+ if (sm->id == mode) {
+ found = true;
+ break;
+ }
+ sm++;
+ }
+ if (!found) {
+ warning("unknown stretch mode %d", mode);
+ return false;
+ }
+
+ _transactionDetails.needUpdatescreen = true;
+ _transactionDetails.needDisplayResize = true;
+
+ _videoMode.stretchMode = mode;
+
+ return true;
+}
+
+int SurfaceSdlGraphicsManager::getStretchMode() const {
+ return _videoMode.stretchMode;
+}
+#endif
+
void SurfaceSdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFormat *format) {
assert(_transactionMode == kTransactionActive);
@@ -2485,6 +2552,38 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
}
#endif
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ // Ctrl+Alt+s cycles through scaling mode (0 to 3)
+ if (key == 's') {
+ int index = 0;
+ const OSystem::GraphicsMode *sm = s_supportedStretchModes;
+ while (sm->name) {
+ if (sm->id == _videoMode.stretchMode)
+ break;
+ sm++;
+ index++;
+ }
+ index++;
+ if (!s_supportedStretchModes[index].name)
+ index = 0;
+
+ beginGFXTransaction();
+ setStretchMode(s_supportedStretchModes[index].id);
+ endGFXTransaction();
+
+#ifdef USE_OSD
+ Common::String message = Common::String::format("%s: %s",
+ _("Stretch mode"),
+ _(s_supportedStretchModes[index].description)
+ );
+ displayMessageOnOSD(message.c_str());
+#endif
+ _forceRedraw = true;
+ internUpdateScreen();
+ return true;
+ }
+#endif
+
int newMode = -1;
int factor = _videoMode.scaleFactor - 1;
SDLKey sdlKey = (SDLKey)key;
@@ -2575,6 +2674,8 @@ bool SurfaceSdlGraphicsManager::isScalerHotkey(const Common::Event &event) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (event.kbd.keycode == 'f')
return true;
+ if (event.kbd.keycode == 's')
+ return true;
#endif
return (isScaleKey || event.kbd.keycode == 'a');
}
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 9e8e75772d..6e7fec4823 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -98,6 +98,12 @@ public:
virtual const OSystem::GraphicsMode *getSupportedShaders() const override;
virtual int getShader() const override;
virtual bool setShader(int id) override;
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ virtual const OSystem::GraphicsMode *getSupportedStretchModes() const override;
+ virtual int getDefaultStretchMode() const override;
+ virtual bool setStretchMode(int mode) override;
+ virtual int getStretchMode() const override;
+#endif
virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL) override;
virtual int getScreenChangeID() const override { return _screenChangeCount; }
@@ -174,6 +180,9 @@ protected:
virtual bool gameNeedsAspectRatioCorrection() const override {
return _videoMode.aspectRatioCorrection;
}
+ virtual int getGameRenderScale() const override {
+ return _videoMode.scaleFactor;
+ }
virtual void handleResizeImpl(const int width, const int height) override;
@@ -225,6 +234,7 @@ protected:
bool needUpdatescreen;
#if SDL_VERSION_ATLEAST(2, 0, 0)
bool needTextureUpdate;
+ bool needDisplayResize;
#endif
#ifdef USE_RGB_COLOR
bool formatChanged;
@@ -241,6 +251,7 @@ protected:
#if SDL_VERSION_ATLEAST(2, 0, 0)
bool filtering;
+ int stretchMode;
#endif
int mode;