[Scummvm-git-logs] scummvm master -> 89f1b1c96eaa8cbb4f4938bd6524cab6c15227c1

criezy criezy at scummvm.org
Sun Jul 8 17:54:56 CEST 2018


This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
8526c2c31a OSYSTEM: Add Stretch Mode API
812ce59ee4 SDL: Implement stretch mode API
adacb4fcfd BASE: Add command line stretch mode arg
89f1b1c96e GUI: Add Stretch Mode selection in Options dialog


Commit: 8526c2c31a07e57f7166047a87474bffd82e8a03
    https://github.com/scummvm/scummvm/commit/8526c2c31a07e57f7166047a87474bffd82e8a03
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2018-07-08T16:54:51+01:00

Commit Message:
OSYSTEM: Add Stretch Mode API

Changed paths:
    backends/graphics/graphics.h
    backends/modular-backend.cpp
    backends/modular-backend.h
    common/system.cpp
    common/system.h


diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index d5c36c1..e7be236 100644
--- a/backends/graphics/graphics.h
+++ b/backends/graphics/graphics.h
@@ -53,6 +53,13 @@ public:
 	};
 	virtual bool setShader(int id) { return false; }
 	virtual int getShader() const { return 0; }
+	virtual const OSystem::GraphicsMode *getSupportedStretchModes() const {
+		static const OSystem::GraphicsMode noStretchModes[] = {{"NONE", "Normal", 0}, {nullptr, nullptr, 0 }};
+		return noStretchModes;
+	}
+	virtual int getDefaultStretchMode() const { return 0; }
+	virtual bool setStretchMode(int mode) { return false; }
+	virtual int getStretchMode() const { return 0; }
 
 #ifdef USE_RGB_COLOR
 	virtual Graphics::PixelFormat getScreenFormat() const = 0;
diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp
index 944ddd5..2c6aaba 100644
--- a/backends/modular-backend.cpp
+++ b/backends/modular-backend.cpp
@@ -93,6 +93,22 @@ int ModularBackend::getShader() const {
 	return _graphicsManager->getShader();
 }
 
+const OSystem::GraphicsMode *ModularBackend::getSupportedStretchModes() const {
+	return _graphicsManager->getSupportedStretchModes();
+}
+
+int ModularBackend::getDefaultStretchMode() const {
+	return _graphicsManager->getDefaultStretchMode();
+}
+
+bool ModularBackend::setStretchMode(int mode) {
+	return _graphicsManager->setStretchMode(mode);
+}
+
+int ModularBackend::getStretchMode() const {
+	return _graphicsManager->getStretchMode();
+}
+
 void ModularBackend::resetGraphicsScale() {
 	_graphicsManager->resetGraphicsScale();
 }
diff --git a/backends/modular-backend.h b/backends/modular-backend.h
index fa34f29..ead559c 100644
--- a/backends/modular-backend.h
+++ b/backends/modular-backend.h
@@ -69,6 +69,10 @@ public:
 	virtual const GraphicsMode *getSupportedShaders() const override;
 	virtual int getShader() const override;
 	virtual bool setShader(int id) override;
+	virtual const GraphicsMode *getSupportedStretchModes() const override;
+	virtual int getDefaultStretchMode() const override;
+	virtual bool setStretchMode(int mode) override;
+	virtual int getStretchMode() const override;
 	virtual void resetGraphicsScale() override;
 #ifdef USE_RGB_COLOR
 	virtual Graphics::PixelFormat getScreenFormat() const override;
diff --git a/common/system.cpp b/common/system.cpp
index f4568c2..51f41ec 100644
--- a/common/system.cpp
+++ b/common/system.cpp
@@ -121,6 +121,27 @@ bool OSystem::setGraphicsMode(const char *name) {
 	return false;
 }
 
+bool OSystem::setStretchMode(const char *name) {
+	if (!name)
+		return false;
+
+	// Special case for the 'default' filter
+	if (!scumm_stricmp(name, "default")) {
+		return setStretchMode(getDefaultStretchMode());
+	}
+
+	const GraphicsMode *sm = getSupportedStretchModes();
+
+	while (sm->name) {
+		if (!scumm_stricmp(sm->name, name)) {
+			return setStretchMode(sm->id);
+		}
+		sm++;
+	}
+
+	return false;
+}
+
 void OSystem::fatalError() {
 	quit();
 	exit(1);
diff --git a/common/system.h b/common/system.h
index 8866a4d..158e75c 100644
--- a/common/system.h
+++ b/common/system.h
@@ -607,6 +607,56 @@ public:
 	virtual int getShader() const { return 0; }
 
 	/**
+	 * Retrieve a list of all stretch modes supported by this backend.
+	 * It is completely up to the backend maintainer to decide what is
+	 * appropriate here and what not.
+	 * The list is terminated by an all-zero entry.
+	 * @return a list of supported stretch modes
+	 */
+	virtual const GraphicsMode *getSupportedStretchModes() const {
+		static const GraphicsMode noStretchModes[] = {{"NONE", "Normal", 0}, {nullptr, nullptr, 0 }};
+		return noStretchModes;
+	}
+
+	/**
+	 * Return the ID of the 'default' stretch mode. What exactly this means
+	 * is up to the backend. This mode is set by the client code when no user
+	 * overrides are present (i.e. if no custom stretch mode is selected via
+	 * the command line or a config file).
+	 *
+	 * @return the ID of the 'default' graphics mode
+	 */
+	virtual int getDefaultStretchMode() const { return 0; }
+
+	/**
+	 * Switch to the specified stretch mode. If switching to the new mode
+	 * failed, this method returns false.
+	 *
+	 * @param mode	the ID of the new graphics mode
+	 * @return true if the switch was successful, false otherwise
+	 */
+	virtual bool setStretchMode(int mode) { return false; }
+
+	/**
+	 * Switch to the stretch mode with the given name. If 'name' is unknown,
+	 * or if switching to the new mode failed, this method returns false.
+	 *
+	 * @param name	the name of the new stretch mode
+	 * @return true if the switch was successful, false otherwise
+	 * @note This is implemented via the setStretchMode(int) method, as well
+	 *       as getSupportedStretchModes() and getDefaultStretchMode().
+	 *       In particular, backends do not have to overload this!
+	 */
+	bool setStretchMode(const char *name);
+
+	/**
+	 * Determine which stretch mode is currently active.
+	 * @return the ID of the active stretch mode
+	 */
+	virtual int getStretchMode() const { return 0; }
+
+
+	/**
 	 * Set the size and color format of the virtual screen. Typical sizes include:
 	 *  - 320x200 (e.g. for most SCUMM games, and Simon)
 	 *  - 320x240 (e.g. for FM-TOWN SCUMM games)
@@ -695,7 +745,8 @@ public:
 		kTransactionModeSwitchFailed = (1 << 2),	/**< Failed switching the GFX graphics mode (setGraphicsMode) */
 		kTransactionSizeChangeFailed = (1 << 3),	/**< Failed switching the screen dimensions (initSize) */
 		kTransactionFormatNotSupported = (1 << 4),	/**< Failed setting the color format */
-		kTransactionFilteringFailed = (1 << 5)		/**< Failed setting the filtering mode */
+		kTransactionFilteringFailed = (1 << 5),		/**< Failed setting the filtering mode */
+		kTransactionStretchModeSwitchFailed = (1 << 6)	/**< Failed setting the stretch mode */
 	};
 
 	/**


Commit: 812ce59ee44d669d2b17a1c1602f9364900b9479
    https://github.com/scummvm/scummvm/commit/812ce59ee44d669d2b17a1c1602f9364900b9479
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2018-07-08T16:54:51+01:00

Commit Message:
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

Changed paths:
    README
    backends/graphics/openglsdl/openglsdl-graphics.cpp
    backends/graphics/openglsdl/openglsdl-graphics.h
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.h
    backends/graphics/windowed.h


diff --git a/README b/README
index 7008118..9c0b25b 100644
--- a/README
+++ b/README
@@ -1718,6 +1718,7 @@ other games.
                              stretches the image to use 320x240 pixels
                              instead, or a multiple thereof
     Ctrl-Alt f             - Enable/disable graphics filtering
+    Ctrl-Alt s             - Cycle through scaling modes
     Alt-Enter              - Toggles full screen/windowed
     Alt-s                  - Make a screenshot (SDL backend only)
     Ctrl-F7                - Open virtual keyboard (if enabled)
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 3209905..8dcc558 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -39,7 +39,7 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 #else
       _lastVideoModeLoad(0),
 #endif
-      _graphicsScale(2), _ignoreLoadVideoMode(false), _gotResize(false), _wantsFullScreen(false), _ignoreResizeEvents(0),
+      _graphicsScale(2), _stretchMode(STRETCH_FIT), _ignoreLoadVideoMode(false), _gotResize(false), _wantsFullScreen(false), _ignoreResizeEvents(0),
       _desiredFullscreenWidth(0), _desiredFullscreenHeight(0) {
 	// Setup OpenGL attributes for SDL
 	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
@@ -266,6 +266,54 @@ bool OpenGLSdlGraphicsManager::getFeatureState(OSystem::Feature f) const {
 	}
 }
 
+namespace {
+const OSystem::GraphicsMode sdlGlStretchModes[] = {
+	{"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}
+};
+
+} // End of anonymous namespace
+
+const OSystem::GraphicsMode *OpenGLSdlGraphicsManager::getSupportedStretchModes() const {
+	return sdlGlStretchModes;
+}
+
+int OpenGLSdlGraphicsManager::getDefaultStretchMode() const {
+	return STRETCH_FIT;
+}
+
+bool OpenGLSdlGraphicsManager::setStretchMode(int mode) {
+	assert(getTransactionMode() != kTransactionNone);
+
+	if (mode == _stretchMode)
+		return true;
+
+	// Check this is a valid mode
+	const OSystem::GraphicsMode *sm = sdlGlStretchModes;
+	bool found = false;
+	while (sm->name) {
+		if (sm->id == mode) {
+			found = true;
+			break;
+		}
+		sm++;
+	}
+	if (!found) {
+		warning("unknown stretch mode %d", mode);
+		return false;
+	}
+
+	_stretchMode = mode;
+	return true;
+}
+
+int OpenGLSdlGraphicsManager::getStretchMode() const {
+	return _stretchMode;
+}
+
 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
@@ -735,7 +783,7 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
 
 				// Ctrl+Alt+f toggles filtering on/off
 				beginGFXTransaction();
-				setFeatureState(OSystem::kFeatureFilteringMode, !getFeatureState(OSystem::kFeatureFilteringMode));
+					setFeatureState(OSystem::kFeatureFilteringMode, !getFeatureState(OSystem::kFeatureFilteringMode));
 				endGFXTransaction();
 
 				// Make sure we do not ignore the next resize. This
@@ -751,6 +799,34 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
 #endif
 
 				return true;
+			} else if (event.kbd.keycode == Common::KEYCODE_s) {
+				// Never try to resize the window when changing the scaling mode.
+				_ignoreLoadVideoMode = true;
+
+				// Ctrl+Alt+s cycles through stretch mode
+				int index = 0;
+				const OSystem::GraphicsMode *sm = sdlGlStretchModes;
+				while (sm->name) {
+					if (sm->id == _stretchMode)
+						break;
+					sm++;
+					index++;
+				}
+				index++;
+				if (!sdlGlStretchModes[index].name)
+					index = 0;
+				beginGFXTransaction();
+				setStretchMode(sdlGlStretchModes[index].id);
+				endGFXTransaction();
+
+#ifdef USE_OSD
+				Common::String message = Common::String::format("%s: %s",
+					_("Stretch mode"),
+					_(sdlGlStretchModes[index].description)
+					);
+				displayMessageOnOSD(message.c_str());
+#endif
+				return true;
 			}
 		}
 		// Fall through
@@ -769,7 +845,8 @@ bool OpenGLSdlGraphicsManager::isHotkey(const Common::Event &event) const {
 		return    event.kbd.keycode == Common::KEYCODE_PLUS || event.kbd.keycode == Common::KEYCODE_MINUS
 		       || event.kbd.keycode == Common::KEYCODE_KP_PLUS || event.kbd.keycode == Common::KEYCODE_KP_MINUS
 		       || event.kbd.keycode == Common::KEYCODE_a
-		       || event.kbd.keycode == Common::KEYCODE_f;
+		       || event.kbd.keycode == Common::KEYCODE_f
+		       || event.kbd.keycode == Common::KEYCODE_s;
 	}
 
 	return false;
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h
index 954c721..b6ea496 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.h
+++ b/backends/graphics/openglsdl/openglsdl-graphics.h
@@ -43,6 +43,11 @@ public:
 	virtual void setFeatureState(OSystem::Feature f, bool enable) override;
 	virtual bool getFeatureState(OSystem::Feature f) const override;
 
+	virtual const OSystem::GraphicsMode *getSupportedStretchModes() const override;
+	virtual int getDefaultStretchMode() const override;
+	virtual bool setStretchMode(int mode) override;
+	virtual int getStretchMode() const override;
+
 	virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format) override;
 
 #ifdef USE_RGB_COLOR
@@ -82,6 +87,7 @@ private:
 	uint _lastRequestedWidth;
 	uint _lastRequestedHeight;
 	uint _graphicsScale;
+	int _stretchMode;
 	bool _ignoreLoadVideoMode;
 	bool _gotResize;
 
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index fd6e2bd..654dbd7 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 9e8e757..6e7fec4 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;
diff --git a/backends/graphics/windowed.h b/backends/graphics/windowed.h
index 8a0bddf..4732ea9 100644
--- a/backends/graphics/windowed.h
+++ b/backends/graphics/windowed.h
@@ -26,9 +26,17 @@
 #include "backends/graphics/graphics.h"
 #include "common/frac.h"
 #include "common/rect.h"
+#include "common/config-manager.h"
 #include "common/textconsole.h"
 #include "graphics/scaler/aspect.h"
 
+enum {
+	STRETCH_CENTER = 0,
+	STRETCH_INTEGRAL = 1,
+	STRETCH_FIT = 2,
+	STRETCH_STRETCH = 3
+};
+
 class WindowedGraphicsManager : virtual public GraphicsManager {
 public:
 	WindowedGraphicsManager() :
@@ -136,6 +144,13 @@ protected:
 	}
 
 	/**
+	 * @returns the scale used between the game size and the surface on which it is rendered.
+	 */
+	virtual int getGameRenderScale() const {
+		return 1;
+	}
+
+	/**
 	 * Called after the window has been updated with new dimensions.
 	 *
 	 * @param width The new width of the window, excluding window decoration.
@@ -156,13 +171,11 @@ protected:
 			return;
 		}
 
-		const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight;
-
-		populateDisplayAreaDrawRect(getDesiredGameAspectRatio(), outputAspect, _gameDrawRect);
+		populateDisplayAreaDrawRect(getDesiredGameAspectRatio(), getWidth() * getGameRenderScale(), _gameDrawRect);
 
 		if (getOverlayHeight()) {
 			const frac_t overlayAspect = intToFrac(getOverlayWidth()) / getOverlayHeight();
-			populateDisplayAreaDrawRect(overlayAspect, outputAspect, _overlayDrawRect);
+			populateDisplayAreaDrawRect(overlayAspect, getOverlayWidth(), _overlayDrawRect);
 		}
 
 		if (_overlayVisible) {
@@ -316,15 +329,36 @@ protected:
 	int _cursorX, _cursorY;
 
 private:
-	void populateDisplayAreaDrawRect(const frac_t inputAspect, const frac_t outputAspect, Common::Rect &drawRect) const {
-		int width = _windowWidth;
-		int height = _windowHeight;
-
-		// Maintain aspect ratios
-		if (outputAspect < inputAspect) {
-			height = intToFrac(width) / inputAspect;
-		} else if (outputAspect > inputAspect) {
-			width = fracToInt(height * inputAspect);
+	void populateDisplayAreaDrawRect(const frac_t displayAspect, int originalWidth, Common::Rect &drawRect) const {
+		int mode = getStretchMode();
+		// Mode Center   = use original size, or divide by an integral amount if window is smaller than game surface
+		// Mode Integral = scale by an integral amount.
+		// Mode Fit      = scale to fit the window while respecting the aspect ratio
+		// Mode Stretch  = scale and stretch to fit the window without respecting the aspect ratio
+
+		int width = 0, height = 0;
+		if (mode == STRETCH_CENTER || mode == STRETCH_INTEGRAL) {
+			width = originalWidth;
+			height = intToFrac(width) / displayAspect;
+			if (width > _windowWidth || height > _windowHeight) {
+				int fac = 1 + MAX((width - 1) / _windowWidth, (height - 1) / _windowHeight);
+				width /= fac;
+				height /= fac;
+			} else if (mode == STRETCH_INTEGRAL) {
+				int fac = MIN(_windowWidth / width, _windowHeight / height);
+				width *= fac;
+				height *= fac;
+			}
+		} else {
+			frac_t windowAspect = intToFrac(_windowWidth) / _windowHeight;
+			width = _windowWidth;
+			height = _windowHeight;
+			if (mode != STRETCH_STRETCH) {
+				if (windowAspect < displayAspect)
+					height = intToFrac(width) / displayAspect;
+				else if (windowAspect > displayAspect)
+					width = fracToInt(height * displayAspect);
+			}
 		}
 
 		drawRect.left = (_windowWidth - width) / 2;


Commit: adacb4fcfd743aa3980b3e08c62578f32de2d0b3
    https://github.com/scummvm/scummvm/commit/adacb4fcfd743aa3980b3e08c62578f32de2d0b3
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2018-07-08T16:54:51+01:00

Commit Message:
BASE: Add command line stretch mode arg

Changed paths:
    README
    base/commandLine.cpp
    base/main.cpp


diff --git a/README b/README
index 9c0b25b..2dd1cb4 100644
--- a/README
+++ b/README
@@ -1527,6 +1527,7 @@ arguments -- see the next section.
   -f, --fullscreen         Force full-screen mode
   -F, --no-fullscreen      Force windowed mode
   -g, --gfx-mode=MODE      Select graphics scaler (see also section 5.3)
+  --stretch-mode=MODE      Select stretch mode (center, integral, fit, stretch)
   --filtering              Force filtered graphics mode
   --no-filtering           Force unfiltered graphics mode
 
diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 96548b9..a54f444 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -93,6 +93,7 @@ static const char HELP_STRING[] =
 	"  -g, --gfx-mode=MODE      Select graphics scaler (1x,2x,3x,2xsai,super2xsai,\n"
 	"                           supereagle,advmame2x,advmame3x,hq2x,hq3x,tv2x,\n"
 	"                           dotmatrix)\n"
+	"  --stretch-mode=MODE      Select stretch mode (center, integral, fit, stretch)"
 	"  --filtering              Force filtered graphics mode\n"
 	"  --no-filtering           Force unfiltered graphics mode\n"
 	"  --gui-theme=THEME        Select GUI theme\n"
@@ -213,6 +214,7 @@ void registerDefaults() {
 	ConfMan.registerDefault("gfx_mode", "normal");
 	ConfMan.registerDefault("render_mode", "default");
 	ConfMan.registerDefault("desired_screen_aspect_ratio", "auto");
+	ConfMan.registerDefault("stretch_mode", "default");
 
 	// Sound & Music
 	ConfMan.registerDefault("music_volume", 192);
@@ -509,6 +511,9 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
 			DO_OPTION('g', "gfx-mode")
 			END_OPTION
 
+			DO_LONG_OPTION("stretch-mode")
+			END_OPTION
+
 			DO_OPTION_INT('m', "music-volume")
 			END_OPTION
 
diff --git a/base/main.cpp b/base/main.cpp
index cbf2e23..c43b865 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -296,6 +296,8 @@ static void setupGraphics(OSystem &system) {
 			system.setFeatureState(OSystem::kFeatureFullscreenMode, ConfMan.getBool("fullscreen"));
 		if (ConfMan.hasKey("filtering"))
 			system.setFeatureState(OSystem::kFeatureFilteringMode, ConfMan.getBool("filtering"));
+		if (ConfMan.hasKey("stretch_mode"))
+			system.setStretchMode(ConfMan.get("stretch_mode").c_str());
 	system.endGFXTransaction();
 
 	// When starting up launcher for the first time, the user might have specified


Commit: 89f1b1c96eaa8cbb4f4938bd6524cab6c15227c1
    https://github.com/scummvm/scummvm/commit/89f1b1c96eaa8cbb4f4938bd6524cab6c15227c1
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2018-07-08T16:54:51+01:00

Commit Message:
GUI: Add Stretch Mode selection in Options dialog

Changed paths:
    backends/graphics/openglsdl/openglsdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    common/system.h
    engines/engine.cpp
    gui/options.cpp
    gui/options.h
    gui/themes/default.inc
    gui/themes/scummclassic.zip
    gui/themes/scummclassic/classic_layout.stx
    gui/themes/scummclassic/classic_layout_lowres.stx
    gui/themes/scummmodern.zip
    gui/themes/scummmodern/scummmodern_layout.stx
    gui/themes/scummmodern/scummmodern_layout_lowres.stx


diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 8dcc558..ef3b25e 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -218,6 +218,7 @@ void OpenGLSdlGraphicsManager::deactivateManager() {
 bool OpenGLSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
 	switch (f) {
 	case OSystem::kFeatureFullscreenMode:
+	case OSystem::kFeatureStretchMode:
 	case OSystem::kFeatureIconifyWindow:
 		return true;
 
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 654dbd7..1ca8902 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -256,6 +256,7 @@ bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
 		(f == OSystem::kFeatureAspectRatioCorrection) ||
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 		(f == OSystem::kFeatureFilteringMode) ||
+		(f == OSystem::kFeatureStretchMode) ||
 #endif
 		(f == OSystem::kFeatureCursorPalette) ||
 		(f == OSystem::kFeatureIconifyWindow);
diff --git a/common/system.h b/common/system.h
index 158e75c..7caf73a 100644
--- a/common/system.h
+++ b/common/system.h
@@ -263,6 +263,11 @@ public:
 		kFeatureFilteringMode,
 
 		/**
+		 * Indicate if stretch modes are supported by the backend.
+		 */
+		kFeatureStretchMode,
+
+		/**
 		 * Determine whether a virtual keyboard is too be shown or not.
 		 * This would mostly be implemented by backends for hand held devices,
 		 * like PocketPC, Palms, Symbian phones like the P800, Zaurus, etc.
diff --git a/engines/engine.cpp b/engines/engine.cpp
index 99f2713..77ca54f 100644
--- a/engines/engine.cpp
+++ b/engines/engine.cpp
@@ -329,6 +329,15 @@ void initGraphics(int width, int height, const Graphics::PixelFormat *format) {
 		dialog.runModal();
 	}
 
+	if (gfxError & OSystem::kTransactionStretchModeSwitchFailed) {
+		Common::String message = _("Could not switch to stretch mode: '");
+		message += ConfMan.get("stretch_mode");
+		message += "'.";
+
+		GUI::MessageDialog dialog(message);
+		dialog.runModal();
+	}
+
 	if (gfxError & OSystem::kTransactionAspectRatioFailed) {
 		GUI::MessageDialog dialog(_("Could not apply aspect ratio setting."));
 		dialog.runModal();
diff --git a/gui/options.cpp b/gui/options.cpp
index 6083a2c..bee161e 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -154,6 +154,8 @@ void OptionsDialog::init() {
 	_gfxPopUpDesc = 0;
 	_renderModePopUp = 0;
 	_renderModePopUpDesc = 0;
+	_stretchPopUp = 0;
+	_stretchPopUpDesc = 0;
 	_fullscreenCheckbox = 0;
 	_filteringCheckbox = 0;
 	_aspectCheckbox = 0;
@@ -285,6 +287,25 @@ void OptionsDialog::build() {
 			_renderModePopUp->setSelectedTag(sel);
 		}
 
+		_stretchPopUp->setSelected(0);
+
+		if (g_system->hasFeature(OSystem::kFeatureStretchMode)) {
+			if (ConfMan.hasKey("stretch_mode", _domain)) {
+				const OSystem::GraphicsMode *sm = g_system->getSupportedStretchModes();
+				Common::String stretchMode(ConfMan.get("stretch_mode", _domain));
+				int stretchCount = 1;
+				while (sm->name) {
+					stretchCount++;
+					if (scumm_stricmp(sm->name, stretchMode.c_str()) == 0)
+						_stretchPopUp->setSelected(stretchCount);
+					sm++;
+				}
+			}
+		} else {
+			_stretchPopUpDesc->setVisible(false);
+			_stretchPopUp->setVisible(false);
+		}
+
 #ifdef GUI_ONLY_FULLSCREEN
 		_fullscreenCheckbox->setState(true);
 		_fullscreenCheckbox->setEnabled(false);
@@ -470,6 +491,23 @@ void OptionsDialog::apply() {
 
 			if ((int32)_renderModePopUp->getSelectedTag() >= 0)
 				ConfMan.set("render_mode", Common::getRenderModeCode((Common::RenderMode)_renderModePopUp->getSelectedTag()), _domain);
+
+			isSet = false;
+			if ((int32)_stretchPopUp->getSelectedTag() >= 0) {
+				const OSystem::GraphicsMode *sm = g_system->getSupportedStretchModes();
+				while (sm->name) {
+					if (sm->id == (int)_stretchPopUp->getSelectedTag()) {
+						if (ConfMan.get("stretch_mode", _domain) != sm->name)
+							graphicsModeChanged = true;
+						ConfMan.set("stretch_mode", sm->name, _domain);
+						isSet = true;
+						break;
+					}
+					sm++;
+				}
+			}
+			if (!isSet)
+				ConfMan.removeKey("stretch_mode", _domain);
 		} else {
 			ConfMan.removeKey("fullscreen", _domain);
 			ConfMan.removeKey("filtering", _domain);
@@ -484,6 +522,8 @@ void OptionsDialog::apply() {
 		g_system->beginGFXTransaction();
 		g_system->setGraphicsMode(ConfMan.get("gfx_mode", _domain).c_str());
 
+		if (ConfMan.hasKey("stretch_mode"))
+			g_system->setStretchMode(ConfMan.get("stretch_mode", _domain).c_str());
 		if (ConfMan.hasKey("aspect_ratio"))
 			g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, ConfMan.getBool("aspect_ratio", _domain));
 		if (ConfMan.hasKey("fullscreen"))
@@ -519,7 +559,20 @@ void OptionsDialog::apply() {
 					gm++;
 				}
 				message += "\n";
-				message += _("the video mode could not be changed.");
+				message += _("the video mode could not be changed");
+			}
+
+			if (gfxError & OSystem::kTransactionStretchModeSwitchFailed) {
+				const OSystem::GraphicsMode *sm = g_system->getSupportedStretchModes();
+				while (sm->name) {
+					if (sm->id == g_system->getStretchMode()) {
+						ConfMan.set("stretch_mode", sm->name, _domain);
+						break;
+					}
+					sm++;
+				}
+				message += "\n";
+				message += _("the stretch mode could not be changed");
 			}
 
 			if (gfxError & OSystem::kTransactionAspectRatioFailed) {
@@ -805,6 +858,8 @@ void OptionsDialog::setGraphicSettingsState(bool enabled) {
 	_gfxPopUp->setEnabled(enabled);
 	_renderModePopUpDesc->setEnabled(enabled);
 	_renderModePopUp->setEnabled(enabled);
+	_stretchPopUpDesc->setEnabled(enabled);
+	_stretchPopUp->setEnabled(enabled);
 	_filteringCheckbox->setEnabled(enabled);
 #ifndef GUI_ENABLE_KEYSDIALOG
 #ifndef GUI_ONLY_FULLSCREEN
@@ -1014,6 +1069,18 @@ void OptionsDialog::addGraphicControls(GuiObject *boss, const Common::String &pr
 			_renderModePopUp->appendEntry(_c(rm->description, context), rm->id);
 	}
 
+	// The Stretch mode popup
+	const OSystem::GraphicsMode *sm = g_system->getSupportedStretchModes();
+	_stretchPopUpDesc = new StaticTextWidget(boss, prefix + "grStretchModePopupDesc", _("Stretch mode:"));
+	_stretchPopUp = new PopUpWidget(boss, prefix + "grStretchModePopup");
+
+	_stretchPopUp->appendEntry(_("<default>"));
+	_stretchPopUp->appendEntry("");
+	while (sm->name) {
+		_stretchPopUp->appendEntry(_c(sm->description, context), sm->id);
+		sm++;
+	}
+
 	// Fullscreen checkbox
 	_fullscreenCheckbox = new CheckboxWidget(boss, prefix + "grFullscreenCheckbox", _("Fullscreen mode"));
 
diff --git a/gui/options.h b/gui/options.h
index bc58d7a..a2dec89 100644
--- a/gui/options.h
+++ b/gui/options.h
@@ -138,6 +138,8 @@ private:
 	bool _enableGraphicSettings;
 	StaticTextWidget *_gfxPopUpDesc;
 	PopUpWidget *_gfxPopUp;
+	StaticTextWidget *_stretchPopUpDesc;
+	PopUpWidget *_stretchPopUp;
 	CheckboxWidget *_fullscreenCheckbox;
 	CheckboxWidget *_filteringCheckbox;
 	CheckboxWidget *_aspectCheckbox;
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index fe48acd..098c873 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -866,6 +866,14 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "type='PopUp' "
 "/>"
 "</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
+"<widget name='grStretchModePopupDesc' "
+"type='OptionsLabel' "
+"/>"
+"<widget name='grStretchModePopup' "
+"type='PopUp' "
+"/>"
+"</layout>"
 "<widget name='grAspectCheckbox' "
 "type='Checkbox' "
 "/>"
@@ -2447,6 +2455,14 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "type='PopUp' "
 "/>"
 "</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
+"<widget name='grStretchModePopupDesc' "
+"type='OptionsLabel' "
+"/>"
+"<widget name='grStretchModePopup' "
+"type='PopUp' "
+"/>"
+"</layout>"
 "<widget name='grAspectCheckbox' "
 "type='Checkbox' "
 "/>"
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index 4f7e3ce..8b5b52f 100644
Binary files a/gui/themes/scummclassic.zip and b/gui/themes/scummclassic.zip differ
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index e3411dc..23f8aca 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -292,6 +292,14 @@
 						type = 'PopUp'
 				/>
 			</layout>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
+				<widget name = 'grStretchModePopupDesc'
+						type = 'OptionsLabel'
+				/>
+				<widget name = 'grStretchModePopup'
+						type = 'PopUp'
+				/>
+			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'
 			/>
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index 4b710b8..ae3a6ee 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -289,6 +289,14 @@
 						type = 'PopUp'
 				/>
 			</layout>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
+				<widget name = 'grStretchModePopupDesc'
+						type = 'OptionsLabel'
+				/>
+				<widget name = 'grStretchModePopup'
+						type = 'PopUp'
+				/>
+			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'
 			/>
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index fae746b..de7c587 100644
Binary files a/gui/themes/scummmodern.zip and b/gui/themes/scummmodern.zip differ
diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx
index 34b66e2..5cf22f9 100644
--- a/gui/themes/scummmodern/scummmodern_layout.stx
+++ b/gui/themes/scummmodern/scummmodern_layout.stx
@@ -306,6 +306,14 @@
 						type = 'PopUp'
 				/>
 			</layout>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
+				<widget name = 'grStretchModePopupDesc'
+						type = 'OptionsLabel'
+				/>
+				<widget name = 'grStretchModePopup'
+						type = 'PopUp'
+				/>
+			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'
 			/>
diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
index 506a975..651efb4 100644
--- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx
+++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
@@ -287,6 +287,14 @@
 						type = 'PopUp'
 				/>
 			</layout>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
+				<widget name = 'grStretchModePopupDesc'
+						type = 'OptionsLabel'
+				/>
+				<widget name = 'grStretchModePopup'
+						type = 'PopUp'
+				/>
+			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'
 			/>





More information about the Scummvm-git-logs mailing list