[Scummvm-git-logs] scummvm master -> c2ae54306f1b7c9d48a1a3a23e59b08b5438d768

sev- sev at scummvm.org
Wed Jun 23 19:30:00 UTC 2021


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

Summary:
0e6b9c2bb6 SDL: Begin refactoring the API for selecting scalers
7ed5984e2f SDL: Add some validation to setScaler()
da5d773924 BACKENDS: Add getDefaultScaler and getDefaultScaleFactor to OSystem
b2d41daabc GUI: Add improved scaler selection to the Options dialog
c2ae54306f BASE: Update scaler settings from old config files


Commit: 0e6b9c2bb6738dcf15d0dcc534aedacf8de78c1b
    https://github.com/scummvm/scummvm/commit/0e6b9c2bb6738dcf15d0dcc534aedacf8de78c1b
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-06-23T21:29:53+02:00

Commit Message:
SDL: Begin refactoring the API for selecting scalers

Changed paths:
    backends/base-backend.cpp
    backends/base-backend.h
    backends/graphics/graphics.h
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.h
    backends/modular-backend.cpp
    backends/modular-backend.h
    common/system.h
    test/null_osystem.cpp


diff --git a/backends/base-backend.cpp b/backends/base-backend.cpp
index 851075ec0e..4d434bf8d8 100644
--- a/backends/base-backend.cpp
+++ b/backends/base-backend.cpp
@@ -23,6 +23,7 @@
 #include "backends/base-backend.h"
 
 #include "graphics/pixelbuffer.h"
+#include "graphics/scalerplugin.h"
 
 #ifndef DISABLE_DEFAULT_EVENT_MANAGER
 #include "backends/events/default/default-events.h"
@@ -35,6 +36,21 @@
 
 #include "gui/message.h"
 
+bool BaseBackend::setScaler(const char *name, int factor) {
+	if (!name)
+		return false;
+
+	const PluginList &scalerPlugins = ScalerMan.getPlugins();
+
+	for (uint scalerIndex = 0; scalerIndex < scalerPlugins.size(); scalerIndex++) {
+		if (!scumm_stricmp(scalerPlugins[scalerIndex]->get<ScalerPluginObject>().getName(), name)) {
+			return setScaler(scalerIndex, factor);
+		}
+	}
+
+	return false;
+}
+
 void BaseBackend::displayMessageOnOSD(const Common::U32String &msg) {
 	// Display the message for 1.5 seconds
 	GUI::TimedMessageDialog dialog(msg, 1500);
diff --git a/backends/base-backend.h b/backends/base-backend.h
index 6269834d84..230531b4d1 100644
--- a/backends/base-backend.h
+++ b/backends/base-backend.h
@@ -34,6 +34,8 @@ class BaseBackend : public OSystem {
 public:
 	virtual void initBackend() override;
 
+	using OSystem::setScaler;
+	virtual bool setScaler(const char *name, int factor) override final;
 	virtual void displayMessageOnOSD(const Common::U32String &msg) override;
 	virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override {}
 	virtual void fillScreen(uint32 col) override;
diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index 6523e5914f..1385038aa6 100644
--- a/backends/graphics/graphics.h
+++ b/backends/graphics/graphics.h
@@ -63,6 +63,8 @@ public:
 	virtual int getDefaultStretchMode() const { return 0; }
 	virtual bool setStretchMode(int mode) { return false; }
 	virtual int getStretchMode() const { return 0; }
+	virtual bool setScaler(uint mode, int factor) { return false; }
+	virtual uint getScaler() const { return 0; }
 
 #ifdef USE_RGB_COLOR
 	virtual Graphics::PixelFormat getScreenFormat() const = 0;
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 4c63dd6596..37f9f00476 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -57,15 +57,11 @@
 #define SDL_FULLSCREEN  0x40000000
 #endif
 
-struct GraphicsModeData {
-	const char *pluginName;
-	uint scaleFactor;
+static OSystem::GraphicsMode s_supportedGraphicsModes[] = {
+	{"surfacesdl", _s("SDL Surface"), GFX_SURFACESDL},
+	{0, 0, 0}
 };
 
-static Common::Array<OSystem::GraphicsMode> *s_supportedGraphicsModes = NULL;
-static Common::Array<GraphicsModeData> *s_supportedGraphicsModesData = NULL;
-static int s_defaultGraphicsMode;
-
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 const OSystem::GraphicsMode s_supportedStretchModes[] = {
 	{"center", _s("Center"), STRETCH_CENTER},
@@ -77,10 +73,6 @@ const OSystem::GraphicsMode s_supportedStretchModes[] = {
 };
 #endif
 
-static void initGraphicsModes();
-
-DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Normal (no scaling)", "lowres")
-
 AspectRatio::AspectRatio(int w, int h) {
 	// TODO : Validation and so on...
 	// Currently, we just ensure the program don't instantiate non-supported aspect ratios
@@ -160,7 +152,6 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
 #endif
 
 	_scalerPlugin = NULL;
-	_scalerIndex = 0;
 	_maxExtraPixels = ScalerMan.getMaxExtraPixels();
 
 	_videoMode.fullscreen = ConfMan.getBool("fullscreen");
@@ -169,11 +160,12 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
 	_videoMode.stretchMode = STRETCH_FIT;
 #endif
 
-	if (!s_supportedGraphicsModes)
-		initGraphicsModes();
-
-	_videoMode.mode = s_defaultGraphicsMode;
-	_videoMode.scaleFactor = getGraphicsModeScale(_videoMode.mode);
+	_videoMode.scalerIndex = 0;
+#ifdef USE_SCALERS
+	_videoMode.scaleFactor = 2;
+#else
+	_videoMode.scaleFactor = 1;
+#endif
 }
 
 SurfaceSdlGraphicsManager::~SurfaceSdlGraphicsManager() {
@@ -190,21 +182,14 @@ SurfaceSdlGraphicsManager::~SurfaceSdlGraphicsManager() {
 	free(_currentPalette);
 	free(_cursorPalette);
 	delete[] _mouseData;
-
-	for (uint i = 0; i < s_supportedGraphicsModes->size() - 1; ++i) {
-		OSystem::GraphicsMode &gm = (*s_supportedGraphicsModes)[i];
-		free(const_cast<char *>(gm.name));
-		free(const_cast<char *>(gm.description));
-	}
-	delete s_supportedGraphicsModes;
-	delete s_supportedGraphicsModesData;
-	s_supportedGraphicsModes = NULL;
-	s_supportedGraphicsModesData = NULL;
 }
 
 bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
 	return
 		(f == OSystem::kFeatureFullscreenMode) ||
+#ifdef USE_SCALERS
+		(f == OSystem::kFeatureScalers) ||
+#endif
 #ifdef USE_ASPECT
 		(f == OSystem::kFeatureAspectRatioCorrection) ||
 #endif
@@ -265,48 +250,20 @@ bool SurfaceSdlGraphicsManager::getFeatureState(OSystem::Feature f) const {
 	}
 }
 
-static void initGraphicsModes() {
-	s_supportedGraphicsModes = new Common::Array<OSystem::GraphicsMode>;
-	s_supportedGraphicsModesData = new Common::Array<GraphicsModeData>;
-	const PluginList &plugins = ScalerMan.getPlugins();
-	OSystem::GraphicsMode gm;
-	GraphicsModeData gmd;
-	// 0 should be the normal1x mode
-	s_defaultGraphicsMode = 0;
-	for (uint i = 0; i < plugins.size(); ++i) {
-		ScalerPluginObject &plugin = plugins[i]->get<ScalerPluginObject>();
-		const Common::Array<uint> &factors = plugin.getFactors();
-		const char *name = plugin.getName();
-		const char *prettyName = plugin.getPrettyName();
-		gmd.pluginName = name;
-		for (uint j = 0; j < factors.size(); ++j) {
-			Common::String n1 = Common::String::format("%s%dx", name, factors[j]);
-			Common::String n2 = Common::String::format("%s%dx", prettyName, factors[j]);
-			gm.name = scumm_strdup(n1.c_str());
-			gm.description = scumm_strdup(n2.c_str());
-			gm.id = s_supportedGraphicsModes->size();
-
-			// if normal2x exists, it is the default
-			if (strcmp(gm.name, "normal2x") == 0)
-				s_defaultGraphicsMode = gm.id;
-
-			s_supportedGraphicsModes->push_back(gm);
-			gmd.scaleFactor = factors[j];
-			s_supportedGraphicsModesData->push_back(gmd);
-		}
-	}
-	gm.name = 0;
-	gm.description = 0;
-	gm.id = 0;
-	s_supportedGraphicsModes->push_back(gm);
-}
-
 const OSystem::GraphicsMode *SurfaceSdlGraphicsManager::getSupportedGraphicsModes() const {
-	return s_supportedGraphicsModes->begin();
+	return s_supportedGraphicsModes;
 }
 
 int SurfaceSdlGraphicsManager::getDefaultGraphicsMode() const {
-	return s_defaultGraphicsMode;
+	return GFX_SURFACESDL;
+}
+
+bool SurfaceSdlGraphicsManager::setGraphicsMode(int mode, uint flags) {
+	return (mode == GFX_SURFACESDL);
+}
+
+int SurfaceSdlGraphicsManager::getGraphicsMode() const {
+	return GFX_SURFACESDL;
 }
 
 void SurfaceSdlGraphicsManager::beginGFXTransaction() {
@@ -344,10 +301,10 @@ OSystem::TransactionError SurfaceSdlGraphicsManager::endGFXTransaction() {
 			errors |= OSystem::kTransactionAspectRatioFailed;
 
 			_videoMode.aspectRatioCorrection = _oldVideoMode.aspectRatioCorrection;
-		} else if (_videoMode.mode != _oldVideoMode.mode) {
+		} else if (_videoMode.scalerIndex != _oldVideoMode.scalerIndex) {
 			errors |= OSystem::kTransactionModeSwitchFailed;
 
-			_videoMode.mode = _oldVideoMode.mode;
+			_videoMode.scalerIndex = _oldVideoMode.scalerIndex;
 			_videoMode.scaleFactor = _oldVideoMode.scaleFactor;
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 		} else if (_videoMode.stretchMode != _oldVideoMode.stretchMode) {
@@ -377,7 +334,8 @@ OSystem::TransactionError SurfaceSdlGraphicsManager::endGFXTransaction() {
 
 		if (_videoMode.fullscreen == _oldVideoMode.fullscreen &&
 			_videoMode.aspectRatioCorrection == _oldVideoMode.aspectRatioCorrection &&
-			_videoMode.mode == _oldVideoMode.mode &&
+			_videoMode.scalerIndex == _oldVideoMode.scalerIndex &&
+			_videoMode.scaleFactor == _oldVideoMode.scaleFactor &&
 			_videoMode.filtering == _oldVideoMode.filtering &&
 			_videoMode.screenWidth == _oldVideoMode.screenWidth &&
 			_videoMode.screenHeight == _oldVideoMode.screenHeight) {
@@ -595,46 +553,25 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() {
 #endif
 
 int SurfaceSdlGraphicsManager::getGraphicsModeScale(int mode) const {
-	if (mode < 0 || mode >= (int)s_supportedGraphicsModes->size())
-		return -1;
-
-	return (*s_supportedGraphicsModesData)[mode].scaleFactor;
+	// TODO: I'm not 100% sure this is correct...
+	return _videoMode.scaleFactor;
 }
 
-bool SurfaceSdlGraphicsManager::setGraphicsMode(int mode, uint flags) {
+bool SurfaceSdlGraphicsManager::setScaler(uint mode, int factor) {
 	Common::StackLock lock(_graphicsMutex);
 
 	assert(_transactionMode == kTransactionActive);
 
-	if (_oldVideoMode.setup && _oldVideoMode.mode == mode)
+	if (_oldVideoMode.setup && _oldVideoMode.scalerIndex == mode && _oldVideoMode.scaleFactor == factor)
 		return true;
 
-	int newScaleFactor;
-
-	if (mode < 0 || mode >= (int)s_supportedGraphicsModes->size()) {
-		warning("unknown gfx mode %d", mode);
-		return false;
-	}
-
-	const char *name = (*s_supportedGraphicsModesData)[mode].pluginName;
-	newScaleFactor = (*s_supportedGraphicsModesData)[mode].scaleFactor;
-
-	// Find which plugin corresponds to the desired mode and set
-	// _scalerIndex accordingly. _scalerPlugin will be updated later.
-	while (strcmp(name, _scalerPlugins[_scalerIndex]->get<ScalerPluginObject>().getName()) != 0) {
-		_scalerIndex++;
-		if (_scalerIndex >= _scalerPlugins.size()) {
-			_scalerIndex = 0;
-		}
-	}
-
-	if (_oldVideoMode.setup && _oldVideoMode.scaleFactor != newScaleFactor)
+	if (_oldVideoMode.setup && _oldVideoMode.scaleFactor != factor)
 		_transactionDetails.needHotswap = true;
 
 	_transactionDetails.needUpdatescreen = true;
 
-	_videoMode.mode = mode;
-	_videoMode.scaleFactor = newScaleFactor;
+	_videoMode.scalerIndex = mode;
+	_videoMode.scaleFactor = factor;
 
 	return true;
 }
@@ -646,8 +583,8 @@ void SurfaceSdlGraphicsManager::setGraphicsModeIntern() {
 		return;
 
 
-	// If the _scalerIndex has changed, change scaler plugins
-	if (&_scalerPlugins[_scalerIndex]->get<ScalerPluginObject>() != _scalerPlugin
+	// If the scalerIndex has changed, change scaler plugins
+	if (&_scalerPlugins[_videoMode.scalerIndex]->get<ScalerPluginObject>() != _scalerPlugin
 #ifdef USE_RGB_COLOR
 		|| _transactionDetails.formatChanged
 #endif
@@ -656,7 +593,7 @@ void SurfaceSdlGraphicsManager::setGraphicsModeIntern() {
 		if (_scalerPlugin)
 			_scalerPlugin->deinitialize();
 
-		_scalerPlugin = &_scalerPlugins[_scalerIndex]->get<ScalerPluginObject>();
+		_scalerPlugin = &_scalerPlugins[_videoMode.scalerIndex]->get<ScalerPluginObject>();
 		_scalerPlugin->initialize(format);
 	}
 
@@ -677,9 +614,9 @@ void SurfaceSdlGraphicsManager::setGraphicsModeIntern() {
 	blitCursor();
 }
 
-int SurfaceSdlGraphicsManager::getGraphicsMode() const {
+uint SurfaceSdlGraphicsManager::getScaler() const {
 	assert(_transactionMode == kTransactionNone);
-	return _videoMode.mode;
+	return _videoMode.scalerIndex;
 }
 
 #if SDL_VERSION_ATLEAST(2, 0, 0)
@@ -2409,57 +2346,37 @@ void SurfaceSdlGraphicsManager::handleResizeImpl(const int width, const int heig
 	recalculateDisplayAreas();
 }
 
-/**
- * Finds what the graphics mode should be using factor and plugin
- *
- * @param plugin      The scaler plugin to match
- * @param factor      The scale factor to match
- * @return            The graphics mode
- */
-int findGraphicsMode(uint factor, ScalerPluginObject &plugin) {
-	for (uint i = 0; i < s_supportedGraphicsModesData->size(); ++i) {
-		if (strcmp((*s_supportedGraphicsModesData)[i].pluginName, plugin.getName()) == 0
-				&& (*s_supportedGraphicsModesData)[i].scaleFactor == factor) {
-			return i;
-		}
-	}
-	return -1;
-}
-
-void SurfaceSdlGraphicsManager::handleScalerHotkeys(int factor) {
+void SurfaceSdlGraphicsManager::handleScalerHotkeys(uint mode, int factor) {
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 	bool sizeChanged = _videoMode.scaleFactor != factor;
 #endif
 
-	int newMode = findGraphicsMode(factor, _scalerPlugins[_scalerIndex]->get<ScalerPluginObject>());
-	if (newMode >= 0) {
-		beginGFXTransaction();
-			setGraphicsMode(newMode);
-		endGFXTransaction();
+	beginGFXTransaction();
+		setScaler(mode, factor);
+	endGFXTransaction();
 #ifdef USE_OSD
-		const char *newScalerName = _scalerPlugin->getPrettyName();
-		if (newScalerName) {
-			const Common::U32String message = Common::U32String::format(
-				"%S %s%d\n%d x %d -> %d x %d",
-				_("Active graphics filter:").c_str(),
-				newScalerName,
-				_scalerPlugin->getFactor(),
-				_videoMode.screenWidth, _videoMode.screenHeight,
-				_hwScreen->w, _hwScreen->h);
-			displayMessageOnOSD(message);
-		}
+	const char *newScalerName = _scalerPlugin->getPrettyName();
+	if (newScalerName) {
+		const Common::U32String message = Common::U32String::format(
+			"%S %s%d\n%d x %d -> %d x %d",
+			_("Active graphics filter:").c_str(),
+			newScalerName,
+			_scalerPlugin->getFactor(),
+			_videoMode.screenWidth, _videoMode.screenHeight,
+			_hwScreen->w, _hwScreen->h);
+		displayMessageOnOSD(message);
+	}
 #endif
 
 #if SDL_VERSION_ATLEAST(2, 0, 0)
-		if (sizeChanged) {
-			// Forcibly resizing the window here since a user switching scaler
-			// size will not normally cause the window to update
-			_window->createOrUpdateWindow(_hwScreen->w, _hwScreen->h, _lastFlags);
-		}
+	if (sizeChanged) {
+		// Forcibly resizing the window here since a user switching scaler
+		// size will not normally cause the window to update
+		_window->createOrUpdateWindow(_hwScreen->w, _hwScreen->h, _lastFlags);
+	}
 #endif
 
-		internUpdateScreen();
-	}
+	internUpdateScreen();
 }
 
 bool SurfaceSdlGraphicsManager::notifyEvent(const Common::Event &event) {
@@ -2539,30 +2456,33 @@ bool SurfaceSdlGraphicsManager::notifyEvent(const Common::Event &event) {
 #endif
 
 	case kActionIncreaseScaleFactor:
-		handleScalerHotkeys(_scalerPlugin->increaseFactor());
+		handleScalerHotkeys(_videoMode.scalerIndex, _scalerPlugin->increaseFactor());
 		return true;
 
 	case kActionDecreaseScaleFactor:
-		handleScalerHotkeys(_scalerPlugin->decreaseFactor());
+		handleScalerHotkeys(_videoMode.scalerIndex, _scalerPlugin->decreaseFactor());
 		return true;
 
-	case kActionNextScaleFilter:
-		_scalerIndex++;
-		if (_scalerIndex >= _scalerPlugins.size()) {
-			_scalerIndex = 0;
+	case kActionNextScaleFilter: {
+		uint scalerIndex =  _videoMode.scalerIndex + 1;
+		if (scalerIndex >= _scalerPlugins.size()) {
+			scalerIndex = 0;
 		}
 
-		handleScalerHotkeys(_scalerPlugins[_scalerIndex]->get<ScalerPluginObject>().getFactor());
+		handleScalerHotkeys(scalerIndex, _scalerPlugins[scalerIndex]->get<ScalerPluginObject>().getFactor());
 		return true;
+	}
 
-	case kActionPreviousScaleFilter:
-		if (_scalerIndex == 0) {
-			_scalerIndex = _scalerPlugins.size();
+	case kActionPreviousScaleFilter: {
+		uint scalerIndex =  _videoMode.scalerIndex;
+		if (scalerIndex == 0) {
+			scalerIndex = _scalerPlugins.size();
 		}
-		_scalerIndex--;
+		scalerIndex--;
 
-		handleScalerHotkeys(_scalerPlugins[_scalerIndex]->get<ScalerPluginObject>().getFactor());
+		handleScalerHotkeys(scalerIndex, _scalerPlugins[scalerIndex]->get<ScalerPluginObject>().getFactor());
 		return true;
+	}
 
 	default:
 		return SdlGraphicsManager::notifyEvent(event);
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index f7688fee48..30c41b2ef7 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -40,6 +40,10 @@
 #define USE_SDL_DEBUG_FOCUSRECT
 #endif
 
+enum {
+	GFX_SURFACESDL = 0
+};
+
 
 class AspectRatio {
 	int _kw, _kh;
@@ -69,6 +73,8 @@ public:
 	virtual int getDefaultGraphicsMode() const override;
 	virtual bool setGraphicsMode(int mode, uint flags = OSystem::kGfxModeNoFlags) override;
 	virtual int getGraphicsMode() const override;
+	virtual bool setScaler(uint mode, int factor) override;
+	virtual uint getScaler() const override;
 #ifdef USE_RGB_COLOR
 	virtual Graphics::PixelFormat getScreenFormat() const override { return _screenFormat; }
 	virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
@@ -256,7 +262,7 @@ protected:
 		int stretchMode;
 #endif
 
-		int mode;
+		uint scalerIndex;
 		int scaleFactor;
 
 		int screenWidth, screenHeight;
@@ -277,7 +283,7 @@ protected:
 			stretchMode = 0;
 #endif
 
-			mode = 0;
+			scalerIndex = 0;
 			scaleFactor = 0;
 
 			screenWidth = 0;
@@ -317,7 +323,6 @@ protected:
 
 	const PluginList &_scalerPlugins;
 	ScalerPluginObject *_scalerPlugin;
-	uint _scalerIndex;
 	uint _maxExtraPixels;
 	uint _extraPixels;
 
@@ -416,7 +421,7 @@ protected:
 
 private:
 	void setFullscreenMode(bool enable);
-	void handleScalerHotkeys(int factor);
+	void handleScalerHotkeys(uint mode, int factor);
 
 	/**
 	 * Converts the given point from the overlay's coordinate space to the
diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp
index 6eaeb8f607..c548284bfb 100644
--- a/backends/modular-backend.cpp
+++ b/backends/modular-backend.cpp
@@ -108,6 +108,14 @@ int ModularGraphicsBackend::getStretchMode() const {
 	return _graphicsManager->getStretchMode();
 }
 
+bool ModularGraphicsBackend::setScaler(uint mode, int factor) {
+	return _graphicsManager->setScaler(mode, factor);
+}
+
+uint ModularGraphicsBackend::getScaler() const {
+	return _graphicsManager->getScaler();
+}
+
 #ifdef USE_RGB_COLOR
 
 Graphics::PixelFormat ModularGraphicsBackend::getScreenFormat() const {
diff --git a/backends/modular-backend.h b/backends/modular-backend.h
index b9079e764c..97b231ad6e 100644
--- a/backends/modular-backend.h
+++ b/backends/modular-backend.h
@@ -76,6 +76,8 @@ public:
 	virtual int getDefaultStretchMode() const override final;
 	virtual bool setStretchMode(int mode) override final;
 	virtual int getStretchMode() const override final;
+	virtual bool setScaler(uint mode, int factor) override final;
+	virtual uint getScaler() const override final;
 #ifdef USE_RGB_COLOR
 	virtual Graphics::PixelFormat getScreenFormat() const override final;
 	virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override final;
diff --git a/common/system.h b/common/system.h
index 2abca223f8..af59539a20 100644
--- a/common/system.h
+++ b/common/system.h
@@ -486,6 +486,11 @@ public:
 		*/
 		kFeatureJoystickDeadzone,
 
+		/**
+		* Scalers.
+		*/
+		kFeatureScalers,
+
 		/**
 		* Shaders.
 		*/
@@ -861,6 +866,38 @@ public:
 	 */
 	virtual int getStretchMode() const { return 0; }
 
+	/**
+	 * Switch to the specified scaler.
+	 *
+	 * If switching to the new mode fails, this method returns false.
+	 *
+	 * @param mode ID of the new scaler.
+	 * @param factor The scale factor to use
+	 *
+	 * @return True if the switch was successful, false otherwise.
+	 */
+	virtual bool setScaler(uint mode, int factor) { return false; }
+
+	/**
+	 * Switch to the scaler with the given name.
+	 *
+	 * If @p name is unknown, or if switching to the new mode fails,
+	 * this method returns false.
+	 *
+	 * @param name Name of the new scaler.
+	 * @param factor The scale factor to use
+	 *
+	 * @return True if the switch was successful, false otherwise.
+	 */
+	virtual bool setScaler(const char *name, int factor) { return false; }
+
+	/**
+	 * Determine which stretch mode is currently active.
+	 *
+	 * @return ID of the active stretch mode.
+	 */
+	virtual uint getScaler() const { return 0; }
+
 
 	/**
 	 * Set the size and color format of the virtual screen.
diff --git a/test/null_osystem.cpp b/test/null_osystem.cpp
index 134a399b8e..7fd0e0329c 100644
--- a/test/null_osystem.cpp
+++ b/test/null_osystem.cpp
@@ -7,6 +7,10 @@ void Common::install_null_g_system() {
 	g_system = OSystem_NULL_create();
 }
 
+bool BaseBackend::setScaler(const char *name, int factor) {
+	return false;
+}
+
 void BaseBackend::displayMessageOnOSD(const Common::U32String &msg) {
 }
 


Commit: 7ed5984e2f4398614858ff98f4f93a737e57135f
    https://github.com/scummvm/scummvm/commit/7ed5984e2f4398614858ff98f4f93a737e57135f
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-06-23T21:29:53+02:00

Commit Message:
SDL: Add some validation to setScaler()

Changed paths:
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    graphics/scalerplugin.h


diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 37f9f00476..ef37850899 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -565,13 +565,21 @@ bool SurfaceSdlGraphicsManager::setScaler(uint mode, int factor) {
 	if (_oldVideoMode.setup && _oldVideoMode.scalerIndex == mode && _oldVideoMode.scaleFactor == factor)
 		return true;
 
-	if (_oldVideoMode.setup && _oldVideoMode.scaleFactor != factor)
+	int newFactor;
+	if (_scalerPlugins[mode]->get<ScalerPluginObject>().hasFactor(factor))
+		newFactor = factor;
+	else if (_scalerPlugins[mode]->get<ScalerPluginObject>().hasFactor(_oldVideoMode.scaleFactor))
+		newFactor = _oldVideoMode.scaleFactor;
+	else
+		newFactor = _scalerPlugins[mode]->get<ScalerPluginObject>().getFactor();
+
+	if (_oldVideoMode.setup && _oldVideoMode.scaleFactor != newFactor)
 		_transactionDetails.needHotswap = true;
 
 	_transactionDetails.needUpdatescreen = true;
 
 	_videoMode.scalerIndex = mode;
-	_videoMode.scaleFactor = factor;
+	_videoMode.scaleFactor = newFactor;
 
 	return true;
 }
diff --git a/graphics/scalerplugin.h b/graphics/scalerplugin.h
index 44b446f364..996e68db0e 100644
--- a/graphics/scalerplugin.h
+++ b/graphics/scalerplugin.h
@@ -75,6 +75,16 @@ public:
 
 	virtual const Common::Array<uint> &getFactors() const { return _factors; }
 
+	virtual bool hasFactor(uint factor) {
+		const Common::Array<uint> &factors = getFactors();
+		for (Common::Array<uint>::const_iterator it = factors.begin(); it != factors.end(); it++) {
+			if ((*it) == factor)
+				return true;
+		}
+
+		return false;
+	}
+
 	/**
 	 * Set the scaling factor.
 	 * Intended to be used with GUI to set a known valid factor.


Commit: da5d773924285bccf342d76a47cc43bc64bb24eb
    https://github.com/scummvm/scummvm/commit/da5d773924285bccf342d76a47cc43bc64bb24eb
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-06-23T21:29:53+02:00

Commit Message:
BACKENDS: Add getDefaultScaler and getDefaultScaleFactor to OSystem

Changed paths:
    backends/base-backend.cpp
    backends/graphics/graphics.h
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.h
    backends/modular-backend.cpp
    backends/modular-backend.h
    base/plugins.cpp
    common/system.h
    graphics/scalerplugin.h


diff --git a/backends/base-backend.cpp b/backends/base-backend.cpp
index 4d434bf8d8..560510e068 100644
--- a/backends/base-backend.cpp
+++ b/backends/base-backend.cpp
@@ -40,6 +40,9 @@ bool BaseBackend::setScaler(const char *name, int factor) {
 	if (!name)
 		return false;
 
+	if (!scumm_stricmp(name, "default"))
+		return setScaler(getDefaultScaler(), factor);
+
 	const PluginList &scalerPlugins = ScalerMan.getPlugins();
 
 	for (uint scalerIndex = 0; scalerIndex < scalerPlugins.size(); scalerIndex++) {
diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index 1385038aa6..f6f297571c 100644
--- a/backends/graphics/graphics.h
+++ b/backends/graphics/graphics.h
@@ -63,6 +63,8 @@ public:
 	virtual int getDefaultStretchMode() const { return 0; }
 	virtual bool setStretchMode(int mode) { return false; }
 	virtual int getStretchMode() const { return 0; }
+	virtual uint getDefaultScaler() const { return 0; }
+	virtual int getDefaultScaleFactor() const { return 1; }
 	virtual bool setScaler(uint mode, int factor) { return false; }
 	virtual uint getScaler() const { return 0; }
 
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index ef37850899..008e2999f3 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -160,12 +160,8 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
 	_videoMode.stretchMode = STRETCH_FIT;
 #endif
 
-	_videoMode.scalerIndex = 0;
-#ifdef USE_SCALERS
-	_videoMode.scaleFactor = 2;
-#else
-	_videoMode.scaleFactor = 1;
-#endif
+	_videoMode.scalerIndex = getDefaultScaler();
+	_videoMode.scaleFactor = getDefaultScaleFactor();
 }
 
 SurfaceSdlGraphicsManager::~SurfaceSdlGraphicsManager() {
@@ -557,6 +553,18 @@ int SurfaceSdlGraphicsManager::getGraphicsModeScale(int mode) const {
 	return _videoMode.scaleFactor;
 }
 
+uint SurfaceSdlGraphicsManager::getDefaultScaler() const {
+	return ScalerMan.findScalerPluginIndex("normal");
+}
+
+int SurfaceSdlGraphicsManager::getDefaultScaleFactor() const {
+#ifdef USE_SCALERS
+	return 2;
+#else
+	return 1;
+#endif
+}
+
 bool SurfaceSdlGraphicsManager::setScaler(uint mode, int factor) {
 	Common::StackLock lock(_graphicsMutex);
 
@@ -566,7 +574,9 @@ bool SurfaceSdlGraphicsManager::setScaler(uint mode, int factor) {
 		return true;
 
 	int newFactor;
-	if (_scalerPlugins[mode]->get<ScalerPluginObject>().hasFactor(factor))
+	if (factor == -1)
+		newFactor = getDefaultScaleFactor();
+	else if (_scalerPlugins[mode]->get<ScalerPluginObject>().hasFactor(factor))
 		newFactor = factor;
 	else if (_scalerPlugins[mode]->get<ScalerPluginObject>().hasFactor(_oldVideoMode.scaleFactor))
 		newFactor = _oldVideoMode.scaleFactor;
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 30c41b2ef7..061a87f331 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -73,6 +73,8 @@ public:
 	virtual int getDefaultGraphicsMode() const override;
 	virtual bool setGraphicsMode(int mode, uint flags = OSystem::kGfxModeNoFlags) override;
 	virtual int getGraphicsMode() const override;
+	virtual uint getDefaultScaler() const override;
+	virtual int getDefaultScaleFactor() const override;
 	virtual bool setScaler(uint mode, int factor) override;
 	virtual uint getScaler() const override;
 #ifdef USE_RGB_COLOR
diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp
index c548284bfb..e0ac0ffe04 100644
--- a/backends/modular-backend.cpp
+++ b/backends/modular-backend.cpp
@@ -108,6 +108,14 @@ int ModularGraphicsBackend::getStretchMode() const {
 	return _graphicsManager->getStretchMode();
 }
 
+uint ModularGraphicsBackend::getDefaultScaler() const {
+	return _graphicsManager->getDefaultScaler();
+}
+
+int ModularGraphicsBackend::getDefaultScaleFactor() const {
+	return _graphicsManager->getDefaultScaleFactor();
+}
+
 bool ModularGraphicsBackend::setScaler(uint mode, int factor) {
 	return _graphicsManager->setScaler(mode, factor);
 }
diff --git a/backends/modular-backend.h b/backends/modular-backend.h
index 97b231ad6e..db22cfe29a 100644
--- a/backends/modular-backend.h
+++ b/backends/modular-backend.h
@@ -76,6 +76,8 @@ public:
 	virtual int getDefaultStretchMode() const override final;
 	virtual bool setStretchMode(int mode) override final;
 	virtual int getStretchMode() const override final;
+	virtual uint getDefaultScaler() const override final;
+	virtual int getDefaultScaleFactor() const override final;
 	virtual bool setScaler(uint mode, int factor) override final;
 	virtual uint getScaler() const override final;
 #ifdef USE_RGB_COLOR
diff --git a/base/plugins.cpp b/base/plugins.cpp
index af804a8e59..04baf89243 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -1023,3 +1023,17 @@ Plugin *ScalerManager::findScalerPlugin(const char *name) const {
 
 	return 0;
 }
+
+uint ScalerManager::findScalerPluginIndex(const char *name) const {
+	const PluginList &plugins = getPlugins();
+	uint index = 0;
+
+	for (PluginList::const_iterator i = plugins.begin(); i != plugins.end(); ++i) {
+		if (!strcmp((*i)->get<ScalerPluginObject>().getName(), name)) {
+			return index;
+		}
+		index++;
+	}
+
+	return 0;
+}
diff --git a/common/system.h b/common/system.h
index af59539a20..99445b1dc6 100644
--- a/common/system.h
+++ b/common/system.h
@@ -866,6 +866,28 @@ public:
 	 */
 	virtual int getStretchMode() const { return 0; }
 
+	/**
+	 * Return the ID of the 'default' scaler.
+	 *
+	 * This mode is set by the client code when no user overrides
+	 * are present (i.e. if no custom scaler is selected using the
+	 * command line or a config file).
+	 *
+	 * @return ID of the 'default' scaler.
+	 */
+	virtual uint getDefaultScaler() const { return 0; }
+
+	/**
+	 * Return the 'default' scale factor.
+	 *
+	 * This mode is set by the client code when no user overrides
+	 * are present (i.e. if no custom shader mode is selected using
+	 * the command line or a config file).
+	 *
+	 * @return The 'default' scale factor.
+	 */
+	virtual int getDefaultScaleFactor() const { return 1; }
+
 	/**
 	 * Switch to the specified scaler.
 	 *
diff --git a/graphics/scalerplugin.h b/graphics/scalerplugin.h
index 996e68db0e..4a3d6cf8ec 100644
--- a/graphics/scalerplugin.h
+++ b/graphics/scalerplugin.h
@@ -225,6 +225,11 @@ public:
 	 * Search the scaler plugins for a special plugin based on its name.
 	 */
 	Plugin *findScalerPlugin(const char *name) const;
+
+	/**
+	 * Search the scaler plugins for a special plugin based on its name.
+	 */
+	uint findScalerPluginIndex(const char *name) const;
 };
 
 /** Convenience shortcut for accessing singleton */


Commit: b2d41daabcea8a5d0a57c4afdf654c0bd5859fcb
    https://github.com/scummvm/scummvm/commit/b2d41daabcea8a5d0a57c4afdf654c0bd5859fcb
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-06-23T21:29:53+02:00

Commit Message:
GUI: Add improved scaler selection to the Options dialog

Changed paths:
    base/commandLine.cpp
    base/main.cpp
    engines/engine.cpp
    gui/ThemeEngine.h
    gui/editgamedialog.cpp
    gui/options.cpp
    gui/options.h
    gui/themes/default.inc
    gui/themes/residualvm.zip
    gui/themes/residualvm/THEMERC
    gui/themes/residualvm/residualvm_layout.stx
    gui/themes/residualvm/residualvm_layout_lowres.stx
    gui/themes/scummclassic.zip
    gui/themes/scummclassic/THEMERC
    gui/themes/scummclassic/classic_layout.stx
    gui/themes/scummclassic/classic_layout_lowres.stx
    gui/themes/scummmodern.zip
    gui/themes/scummmodern/THEMERC
    gui/themes/scummmodern/scummmodern_layout.stx
    gui/themes/scummmodern/scummmodern_layout_lowres.stx
    gui/themes/scummremastered.zip
    gui/themes/scummremastered/THEMERC
    gui/themes/scummremastered/remastered_layout.stx
    gui/themes/scummremastered/remastered_layout_lowres.stx


diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 1fe8bb6af4..553dccb7ca 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -103,10 +103,11 @@ static const char HELP_STRING[] =
 	"  -x, --save-slot[=NUM]    Save game slot to load (default: autosave)\n"
 	"  -f, --fullscreen         Force full-screen mode\n"
 	"  -F, --no-fullscreen      Force windowed mode\n"
-	"  -g, --gfx-mode=MODE      Select graphics scaler (1x,2x,3x,2xsai,super2xsai,\n"
-	"                           supereagle,advmame2x,advmame3x,hq2x,hq3x,tv2x,\n"
-	"                           dotmatrix)\n"
+	"  -g, --gfx-mode=MODE      Select graphics mode\n"
 	"  --stretch-mode=MODE      Select stretch mode (center, integral, fit, stretch)\n"
+	"  --scaler=MODE            Select graphics scaler (normal,hq,edge,advmame,sai,\n"
+	"                           supersai,supereagle,pm,dotmatrix,tv2x)\n"
+	"  --scale-factor=FACTOR    Factor to scale the graphics by\n"
 	"  --filtering              Force filtered graphics mode\n"
 	"  --no-filtering           Force unfiltered graphics mode\n"
 #ifdef USE_OPENGL
@@ -248,6 +249,8 @@ void registerDefaults() {
 	ConfMan.registerDefault("render_mode", "default");
 	ConfMan.registerDefault("desired_screen_aspect_ratio", "auto");
 	ConfMan.registerDefault("stretch_mode", "default");
+	ConfMan.registerDefault("scaler", "default");
+	ConfMan.registerDefault("scale_factor", -1);
 	ConfMan.registerDefault("shader", "default");
 	ConfMan.registerDefault("show_fps", false);
 	ConfMan.registerDefault("dirtyrects", true);
@@ -663,6 +666,12 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
 			DO_LONG_OPTION("stretch-mode")
 			END_OPTION
 
+			DO_LONG_OPTION("scaler")
+			END_OPTION
+
+			DO_LONG_OPTION_INT("scale-factor")
+			END_OPTION
+
 			DO_LONG_OPTION("shader")
 			END_OPTION
 
diff --git a/base/main.cpp b/base/main.cpp
index 6229c5ae85..cb466f969f 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -343,6 +343,7 @@ static void setupGraphics(OSystem &system) {
 		system.setGraphicsMode(ConfMan.get("gfx_mode").c_str());
 		system.setStretchMode(ConfMan.get("stretch_mode").c_str());
 		system.setShader(ConfMan.get("shader").c_str());
+		system.setScaler(ConfMan.get("scaler").c_str(), ConfMan.getInt("scale_factor"));
 
 		system.initSize(320, 200);
 
diff --git a/engines/engine.cpp b/engines/engine.cpp
index a279734dce..45d69a4012 100644
--- a/engines/engine.cpp
+++ b/engines/engine.cpp
@@ -215,6 +215,9 @@ void initCommonGFX() {
 		if (gameDomain->contains("stretch_mode"))
 			g_system->setStretchMode(ConfMan.get("stretch_mode").c_str());
 
+		if (gameDomain->contains("scaler") || gameDomain->contains("scale_factor"))
+			g_system->setScaler(ConfMan.get("scaler").c_str(), ConfMan.getInt("scale_factor"));
+
 		if (gameDomain->contains("shader"))
 			g_system->setShader(ConfMan.get("shader").c_str());
 	}
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index 2db54cb9b5..38cd57b98c 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -37,7 +37,7 @@
 #include "graphics/pixelformat.h"
 
 
-#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.46"
+#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.47"
 
 class OSystem;
 
diff --git a/gui/editgamedialog.cpp b/gui/editgamedialog.cpp
index 304a701c10..9df5c3579e 100644
--- a/gui/editgamedialog.cpp
+++ b/gui/editgamedialog.cpp
@@ -411,6 +411,8 @@ void EditGameDialog::open() {
 	e = ConfMan.hasKey("gfx_mode", _domain) ||
 		ConfMan.hasKey("render_mode", _domain) ||
 		ConfMan.hasKey("stretch_mode", _domain) ||
+		ConfMan.hasKey("scaler", _domain) ||
+		ConfMan.hasKey("scale_factor", _domain) ||
 		ConfMan.hasKey("aspect_ratio", _domain) ||
 		ConfMan.hasKey("fullscreen", _domain) ||
 		ConfMan.hasKey("vsync", _domain) ||
diff --git a/gui/options.cpp b/gui/options.cpp
index 482b45c060..3c84708ba7 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -64,6 +64,7 @@
 #endif
 
 #include "graphics/renderer.h"
+#include "graphics/scalerplugin.h"
 
 namespace GUI {
 
@@ -90,6 +91,7 @@ enum {
 	kKbdMouseSpeedChanged	= 'kmsc',
 	kJoystickDeadzoneChanged= 'jodc',
 	kGraphicsTabContainerReflowCmd = 'gtcr',
+	kScalerPopUpCmd			= 'scPU',
 	kFullscreenToggled		= 'oful'
 };
 
@@ -185,6 +187,9 @@ void OptionsDialog::init() {
 	_renderModePopUpDesc = nullptr;
 	_stretchPopUp = nullptr;
 	_stretchPopUpDesc = nullptr;
+	_scalerPopUp = nullptr;
+	_scalerPopUpDesc = nullptr;
+	_scaleFactorPopUp = nullptr;
 	_fullscreenCheckbox = nullptr;
 	_filteringCheckbox = nullptr;
 	_aspectCheckbox = nullptr;
@@ -350,6 +355,37 @@ void OptionsDialog::build() {
 			_stretchPopUp->setVisible(false);
 		}
 
+		_scalerPopUp->setSelected(0);
+		_scaleFactorPopUp->setSelected(0);
+
+		if (g_system->hasFeature(OSystem::kFeatureScalers)) {
+			if (ConfMan.hasKey("scaler", _domain)) {
+				const PluginList &scalerPlugins = ScalerMan.getPlugins();
+				Common::String scaler(ConfMan.get("scaler", _domain));
+
+				for (uint scalerIndex = 0; scalerIndex < scalerPlugins.size(); scalerIndex++) {
+					if (scumm_stricmp(scalerPlugins[scalerIndex]->get<ScalerPluginObject>().getName(), scaler.c_str()) != 0)
+						continue;
+
+					_scalerPopUp->setSelectedTag(scalerIndex);
+					updateScaleFactors(scalerIndex);
+
+					if (ConfMan.hasKey("scale_factor", _domain)) {
+						int scaleFactor = ConfMan.getInt("scale_factor", _domain);
+						if (scalerPlugins[scalerIndex]->get<ScalerPluginObject>().hasFactor(scaleFactor))
+							_scaleFactorPopUp->setSelectedTag(scaleFactor);
+					}
+
+					break;
+				}
+
+			}
+		} else {
+			_scalerPopUpDesc->setVisible(false);
+			_scalerPopUp->setVisible(false);
+			_scaleFactorPopUp->setVisible(false);
+		}
+
 		// Fullscreen setting
 		if (g_system->hasFeature(OSystem::kFeatureFullscreenMode)) {
 			_fullscreenCheckbox->setState(ConfMan.getBool("fullscreen", _domain));
@@ -587,6 +623,31 @@ void OptionsDialog::apply() {
 					graphicsModeChanged = true;
 			}
 
+			isSet = false;
+			const PluginList &scalerPlugins = ScalerMan.getPlugins();
+			if ((int32)_scalerPopUp->getSelectedTag() >= 0) {
+				const char *name = scalerPlugins[_scalerPopUp->getSelectedTag()]->get<ScalerPluginObject>().getName();
+				if (ConfMan.get("scaler", _domain) != name)
+					graphicsModeChanged = true;
+				ConfMan.set("scaler", name, _domain);
+
+				int factor = _scaleFactorPopUp->getSelectedTag();
+				if (ConfMan.getInt("scale_factor", _domain) != factor)
+					graphicsModeChanged = true;
+				ConfMan.setInt("scale_factor", factor, _domain);
+				isSet = true;
+			}
+			if (!isSet) {
+				ConfMan.removeKey("scaler", _domain);
+				ConfMan.removeKey("scale_factor", _domain);
+
+				uint defaultScaler = g_system->getDefaultScaler();
+				if (g_system->getScaler() != defaultScaler)
+					graphicsModeChanged = true;
+				else if (scalerPlugins[defaultScaler]->get<ScalerPluginObject>().getFactor() != g_system->getDefaultScaleFactor())
+					graphicsModeChanged = true;
+			}
+
 			if (_rendererTypePopUp->getSelectedTag() > 0) {
 				Graphics::RendererType selected = (Graphics::RendererType) _rendererTypePopUp->getSelectedTag();
 				ConfMan.set("renderer", Graphics::getRendererTypeCode(selected), _domain);
@@ -607,6 +668,8 @@ void OptionsDialog::apply() {
 			ConfMan.removeKey("aspect_ratio", _domain);
 			ConfMan.removeKey("gfx_mode", _domain);
 			ConfMan.removeKey("stretch_mode", _domain);
+			ConfMan.removeKey("scaler", _domain);
+			ConfMan.removeKey("scale_factor", _domain);
 			ConfMan.removeKey("render_mode", _domain);
 			ConfMan.removeKey("renderer", _domain);
 			ConfMan.removeKey("antialiasing", _domain);
@@ -647,6 +710,7 @@ void OptionsDialog::apply() {
 		g_system->beginGFXTransaction();
 		g_system->setGraphicsMode(ConfMan.get("gfx_mode", _domain).c_str());
 		g_system->setStretchMode(ConfMan.get("stretch_mode", _domain).c_str());
+		g_system->setScaler(ConfMan.get("scaler", _domain).c_str(), ConfMan.getInt("scale_factor", _domain));
 
 		if (ConfMan.hasKey("aspect_ratio"))
 			g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, ConfMan.getBool("aspect_ratio", _domain));
@@ -967,6 +1031,10 @@ void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
 	case kGraphicsTabContainerReflowCmd:
 		setupGraphicsTab();
 		break;
+	case kScalerPopUpCmd:
+		updateScaleFactors(data);
+		g_gui.scheduleTopDialogRedraw();
+		break;
 	case kApplyCmd:
 		apply();
 		break;
@@ -1007,6 +1075,9 @@ void OptionsDialog::setGraphicSettingsState(bool enabled) {
 	_renderModePopUp->setEnabled(enabled);
 	_stretchPopUpDesc->setEnabled(enabled);
 	_stretchPopUp->setEnabled(enabled);
+	_scalerPopUpDesc->setEnabled(enabled);
+	_scalerPopUp->setEnabled(enabled);
+	_scaleFactorPopUp->setEnabled(enabled);
 	_vsyncCheckbox->setEnabled(enabled);
 	_filteringCheckbox->setEnabled(enabled);
 	_rendererTypePopUpDesc->setEnabled(enabled);
@@ -1353,6 +1424,20 @@ void OptionsDialog::addGraphicControls(GuiObject *boss, const Common::String &pr
 		sm++;
 	}
 
+	// The Scaler popup
+	const PluginList &scalerPlugins = ScalerMan.getPlugins();
+	_scalerPopUpDesc = new StaticTextWidget(boss, prefix + "grScalerPopupDesc", _("Scaler:"));
+	_scalerPopUp = new PopUpWidget(boss, prefix + "grScalerPopup", Common::U32String(), kScalerPopUpCmd);
+
+	_scalerPopUp->appendEntry(_("<default>"));
+	_scalerPopUp->appendEntry(Common::U32String());
+	for (uint scalerIndex = 0; scalerIndex < scalerPlugins.size(); scalerIndex++) {
+		_scalerPopUp->appendEntry(_c(scalerPlugins[scalerIndex]->get<ScalerPluginObject>().getPrettyName(), context), scalerIndex);
+	}
+
+	_scaleFactorPopUp = new PopUpWidget(boss, prefix + "grScaleFactorPopup");
+	updateScaleFactors(_scalerPopUp->getSelectedTag());
+
 	// Fullscreen checkbox
 	_fullscreenCheckbox = new CheckboxWidget(boss, prefix + "grFullscreenCheckbox", _("Fullscreen mode"), Common::U32String(), kFullscreenToggled);
 
@@ -1722,6 +1807,33 @@ void OptionsDialog::setupGraphicsTab() {
 	_aspectCheckbox->setVisible(true);
 	_renderModePopUpDesc->setVisible(true);
 	_renderModePopUp->setVisible(true);
+
+	if (g_system->hasFeature(OSystem::kFeatureScalers)) {
+		_scalerPopUpDesc->setVisible(true);
+		_scalerPopUp->setVisible(true);
+		_scaleFactorPopUp->setVisible(true);
+	} else {
+		_scalerPopUpDesc->setVisible(false);
+		_scalerPopUp->setVisible(false);
+		_scaleFactorPopUp->setVisible(false);
+	}
+}
+
+void OptionsDialog::updateScaleFactors(uint32 tag) {
+	if ((int32)tag >= 0) {
+		const PluginList &scalerPlugins = ScalerMan.getPlugins();
+		const Common::Array<uint> &factors = scalerPlugins[tag]->get<ScalerPluginObject>().getFactors();
+
+		_scaleFactorPopUp->clearEntries();
+		for (Common::Array<uint>::const_iterator it = factors.begin(); it != factors.end(); it++) {
+			_scaleFactorPopUp->appendEntry(Common::U32String::format("%dx", (*it)), (*it));
+		}
+		_scaleFactorPopUp->setSelectedTag(scalerPlugins[tag]->get<ScalerPluginObject>().getFactor());
+	} else {
+		_scaleFactorPopUp->clearEntries();
+		_scaleFactorPopUp->appendEntry(_("<default>"));
+		_scaleFactorPopUp->setSelected(0);
+	}
 }
 
 #pragma mark -
diff --git a/gui/options.h b/gui/options.h
index a2af96d97c..156a8c762f 100644
--- a/gui/options.h
+++ b/gui/options.h
@@ -112,6 +112,7 @@ protected:
 	void setSubtitleSettingsState(bool enabled);
 
 	virtual void setupGraphicsTab();
+	void updateScaleFactors(uint32 tag);
 
 	bool loadMusicDeviceSetting(PopUpWidget *popup, Common::String setting, MusicType preferredType = MT_AUTO);
 	void saveMusicDeviceSetting(PopUpWidget *popup, Common::String setting);
@@ -152,6 +153,8 @@ private:
 	PopUpWidget *_gfxPopUp;
 	StaticTextWidget *_stretchPopUpDesc;
 	PopUpWidget *_stretchPopUp;
+	StaticTextWidget *_scalerPopUpDesc;
+	PopUpWidget *_scalerPopUp, *_scaleFactorPopUp;
 	CheckboxWidget *_fullscreenCheckbox;
 	CheckboxWidget *_filteringCheckbox;
 	CheckboxWidget *_aspectCheckbox;
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index ce339e9657..99ca9239d1 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -1703,6 +1703,17 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "type='PopUp' "
 "/>"
 "</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' align='center'>"
+"<widget name='grScalerPopupDesc' "
+"type='OptionsLabel' "
+"/>"
+"<widget name='grScalerPopup' "
+"type='PopUp' "
+"/>"
+"<widget name='grScaleFactorPopup' "
+"type='PopUp' "
+"/>"
+"</layout>"
 "<widget name='grAspectCheckbox' "
 "type='Checkbox' "
 "/>"
@@ -3532,6 +3543,17 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
 "type='PopUp' "
 "/>"
 "</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' align='center'>"
+"<widget name='grScalerPopupDesc' "
+"type='OptionsLabel' "
+"/>"
+"<widget name='grScalerPopup' "
+"type='PopUp' "
+"/>"
+"<widget name='grScaleFactorPopup' "
+"type='PopUp' "
+"/>"
+"</layout>"
 "<widget name='grAspectCheckbox' "
 "type='Checkbox' "
 "/>"
diff --git a/gui/themes/residualvm.zip b/gui/themes/residualvm.zip
index 3a147828a6..1373f44636 100644
Binary files a/gui/themes/residualvm.zip and b/gui/themes/residualvm.zip differ
diff --git a/gui/themes/residualvm/THEMERC b/gui/themes/residualvm/THEMERC
index 4a7b14f50c..cf724c376a 100644
--- a/gui/themes/residualvm/THEMERC
+++ b/gui/themes/residualvm/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.8.46:ResidualVM Modern Theme:No Author]
+[SCUMMVM_STX0.8.47:ResidualVM Modern Theme:No Author]
diff --git a/gui/themes/residualvm/residualvm_layout.stx b/gui/themes/residualvm/residualvm_layout.stx
index 5ae7adc21c..c93237e8c1 100644
--- a/gui/themes/residualvm/residualvm_layout.stx
+++ b/gui/themes/residualvm/residualvm_layout.stx
@@ -347,6 +347,17 @@
 						type = 'PopUp'
 				/>
 			</layout>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
+				<widget name = 'grScalerPopupDesc'
+						type = 'OptionsLabel'
+				/>
+				<widget name = 'grScalerPopup'
+						type = 'PopUp'
+				/>
+				<widget name = 'grScaleFactorPopup'
+						type = 'PopUp'
+				/>
+			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'
 			/>
diff --git a/gui/themes/residualvm/residualvm_layout_lowres.stx b/gui/themes/residualvm/residualvm_layout_lowres.stx
index 672ca184a1..c41d1f8670 100644
--- a/gui/themes/residualvm/residualvm_layout_lowres.stx
+++ b/gui/themes/residualvm/residualvm_layout_lowres.stx
@@ -329,6 +329,17 @@
 						type = 'PopUp'
 				/>
 			</layout>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' align = 'center'>
+				<widget name = 'grScalerPopupDesc'
+						type = 'OptionsLabel'
+				/>
+				<widget name = 'grScalerPopup'
+						type = 'PopUp'
+				/>
+				<widget name = 'grScaleFactorPopup'
+						type = 'PopUp'
+				/>
+			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'
 			/>
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index eeba51f236..1c042b5757 100644
Binary files a/gui/themes/scummclassic.zip and b/gui/themes/scummclassic.zip differ
diff --git a/gui/themes/scummclassic/THEMERC b/gui/themes/scummclassic/THEMERC
index effd352ba9..1168571bad 100644
--- a/gui/themes/scummclassic/THEMERC
+++ b/gui/themes/scummclassic/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.8.46:ScummVM Classic Theme:No Author]
+[SCUMMVM_STX0.8.47:ScummVM Classic Theme:No Author]
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index 341ece4036..44951a4338 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -333,6 +333,17 @@
 						type = 'PopUp'
 				/>
 			</layout>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
+				<widget name = 'grScalerPopupDesc'
+						type = 'OptionsLabel'
+				/>
+				<widget name = 'grScalerPopup'
+						type = 'PopUp'
+				/>
+				<widget name = 'grScaleFactorPopup'
+						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 beb7e3ef41..c889eb1f72 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -329,6 +329,17 @@
 						type = 'PopUp'
 				/>
 			</layout>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' align = 'center'>
+				<widget name = 'grScalerPopupDesc'
+						type = 'OptionsLabel'
+				/>
+				<widget name = 'grScalerPopup'
+						type = 'PopUp'
+				/>
+				<widget name = 'grScaleFactorPopup'
+						type = 'PopUp'
+				/>
+			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'
 			/>
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index 63641955b3..1f54ab59fa 100644
Binary files a/gui/themes/scummmodern.zip and b/gui/themes/scummmodern.zip differ
diff --git a/gui/themes/scummmodern/THEMERC b/gui/themes/scummmodern/THEMERC
index cca3a45e7b..e9b67c543b 100644
--- a/gui/themes/scummmodern/THEMERC
+++ b/gui/themes/scummmodern/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.8.46:ScummVM Modern Theme:No Author]
+[SCUMMVM_STX0.8.47:ScummVM Modern Theme:No Author]
diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx
index 5ae7adc21c..c93237e8c1 100644
--- a/gui/themes/scummmodern/scummmodern_layout.stx
+++ b/gui/themes/scummmodern/scummmodern_layout.stx
@@ -347,6 +347,17 @@
 						type = 'PopUp'
 				/>
 			</layout>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
+				<widget name = 'grScalerPopupDesc'
+						type = 'OptionsLabel'
+				/>
+				<widget name = 'grScalerPopup'
+						type = 'PopUp'
+				/>
+				<widget name = 'grScaleFactorPopup'
+						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 672ca184a1..c41d1f8670 100644
--- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx
+++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
@@ -329,6 +329,17 @@
 						type = 'PopUp'
 				/>
 			</layout>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' align = 'center'>
+				<widget name = 'grScalerPopupDesc'
+						type = 'OptionsLabel'
+				/>
+				<widget name = 'grScalerPopup'
+						type = 'PopUp'
+				/>
+				<widget name = 'grScaleFactorPopup'
+						type = 'PopUp'
+				/>
+			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'
 			/>
diff --git a/gui/themes/scummremastered.zip b/gui/themes/scummremastered.zip
index 35b7048e72..90cc62a86e 100644
Binary files a/gui/themes/scummremastered.zip and b/gui/themes/scummremastered.zip differ
diff --git a/gui/themes/scummremastered/THEMERC b/gui/themes/scummremastered/THEMERC
index c3e5b418a4..1272ed64de 100644
--- a/gui/themes/scummremastered/THEMERC
+++ b/gui/themes/scummremastered/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.8.46:ScummVM Modern Theme Remastered:No Author]
+[SCUMMVM_STX0.8.47:ScummVM Modern Theme Remastered:No Author]
diff --git a/gui/themes/scummremastered/remastered_layout.stx b/gui/themes/scummremastered/remastered_layout.stx
index 0694882ff8..277dd6f3c3 100644
--- a/gui/themes/scummremastered/remastered_layout.stx
+++ b/gui/themes/scummremastered/remastered_layout.stx
@@ -349,6 +349,17 @@
 						type = 'PopUp'
 				/>
 			</layout>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
+				<widget name = 'grScalerPopupDesc'
+						type = 'OptionsLabel'
+				/>
+				<widget name = 'grScalerPopup'
+						type = 'PopUp'
+				/>
+				<widget name = 'grScaleFactorPopup'
+						type = 'PopUp'
+				/>
+			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'
 			/>
diff --git a/gui/themes/scummremastered/remastered_layout_lowres.stx b/gui/themes/scummremastered/remastered_layout_lowres.stx
index c05368635d..4292b8b7ec 100644
--- a/gui/themes/scummremastered/remastered_layout_lowres.stx
+++ b/gui/themes/scummremastered/remastered_layout_lowres.stx
@@ -331,6 +331,17 @@
 						type = 'PopUp'
 				/>
 			</layout>
+			<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' align = 'center'>
+				<widget name = 'grScalerPopupDesc'
+						type = 'OptionsLabel'
+				/>
+				<widget name = 'grScalerPopup'
+						type = 'PopUp'
+				/>
+				<widget name = 'grScaleFactorPopup'
+						type = 'PopUp'
+				/>
+			</layout>
 			<widget name = 'grAspectCheckbox'
 					type = 'Checkbox'
 			/>


Commit: c2ae54306f1b7c9d48a1a3a23e59b08b5438d768
    https://github.com/scummvm/scummvm/commit/c2ae54306f1b7c9d48a1a3a23e59b08b5438d768
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-06-23T21:29:53+02:00

Commit Message:
BASE: Update scaler settings from old config files

Changed paths:
    backends/platform/sdl/sdl.cpp
    base/plugins.cpp
    graphics/scalerplugin.h


diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index 5a927564d6..b024f61594 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -72,22 +72,6 @@
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 #include <SDL_clipboard.h>
 #endif
-struct LegacyGraphicsMode {
-	const char *name;
-	const char *oldName;
-};
-
-// Table for using old names for scalers in the configuration
-// to keep compatibility with old config files.
-static const LegacyGraphicsMode s_legacyGraphicsModes[] = {
-	{ "supereagle2x", "supereagle" },
-	{ "dotmatrix2x", "dotmatrix" },
-	{ "sai2x", "2xsai" },
-	{ "normal1x", "1x" },
-	{ "normal2x", "2x" },
-	{ "normal3x", "3x" },
-	{ "supersai2x", "super2xsai" },
-};
 
 OSystem_SDL::OSystem_SDL()
 	:
@@ -253,30 +237,7 @@ void OSystem_SDL::initBackend() {
 	}
 
 	// Search for legacy gfx_mode and replace it
-	if (ConfMan.hasKey("gfx_mode")) {
-		Common::String gfxMode(ConfMan.get("gfx_mode"));
-		for (uint i = 0; i < ARRAYSIZE(s_legacyGraphicsModes); ++i) {
-			if (gfxMode == s_legacyGraphicsModes[i].oldName) {
-				ConfMan.set("gfx_mode", s_legacyGraphicsModes[i].name);
-				break;
-			}
-		}
-	}
-	// Look in all game domains as well
-#if 0
-	Common::ConfigManager::DomainMap &dm = ConfMan.getGameDomains();
-	for (Common::ConfigManager::DomainMap::iterator domain = dm.begin(); domain != dm.end(); ++domain) {
-		Common::ConfigManager::Domain::const_iterator gm = domain->_value.find("gfx_mode");
-		if (gm != domain->_value.end()) {
-			for (uint i = 0; i < ARRAYSIZE(s_legacyGraphicsModes); ++i) {
-				if (gm->_value == s_legacyGraphicsModes[i].oldName) {
-					gm->_value = s_legacyGraphicsModes[i].name;
-					break;
-				}
-			}
-		}
-	}
-#endif
+	ScalerMan.updateOldSettings();
 
 	if (_graphicsManager == 0) {
 #ifdef USE_OPENGL
diff --git a/base/plugins.cpp b/base/plugins.cpp
index 04baf89243..c6f9973008 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -1037,3 +1037,68 @@ uint ScalerManager::findScalerPluginIndex(const char *name) const {
 
 	return 0;
 }
+
+struct LegacyGraphicsMode {
+	const char *oldName;
+	const char *newName;
+	uint factor;
+};
+
+// Table for using old names for scalers in the configuration
+// to keep compatibiblity with old config files.
+static const LegacyGraphicsMode s_legacyGraphicsModes[] = {
+	{ "1x", "normal", 1 },
+	{ "2x", "normal", 2 },
+	{ "3x", "normal", 3 },
+	{ "normal1x", "normal", 1 },
+	{ "normal2x", "normal", 2 },
+	{ "normal3x", "normal", 3 },
+	{ "normal4x", "normal", 4 },
+	{ "hq2x", "hq", 2 },
+	{ "hq3x", "hq", 3 },
+	{ "edge2x", "edge", 2 },
+	{ "edge3x", "edge", 3 },
+	{ "advmame2x", "advmame", 2 },
+	{ "advmame3x", "advmame", 3 },
+	{ "advmame4x", "advmame", 4 },
+	{ "2xsai", "sai", 2 },
+	{ "sai2x", "sai", 2 },
+	{ "super2xsai", "supersai", 2 },
+	{ "supersai2x", "supersai", 2 },
+	{ "supereagle", "supereagle", 2 },
+	{ "supereagle2x", "supereagle", 2 },
+	{ "pm2x", "pm", 2 },
+	{ "dotmatrix", "dotmatrix", 2 },
+	{ "dotmatrix2x", "dotmatrix", 2 },
+	{ "tv2x", "tv", 2 }
+};
+
+void ScalerManager::updateOldSettings() {
+	// Search for legacy gfx_mode and replace it
+	if (ConfMan.hasKey("gfx_mode")) {
+		Common::String gfxMode(ConfMan.get("gfx_mode"));
+		for (uint i = 0; i < ARRAYSIZE(s_legacyGraphicsModes); ++i) {
+			if (gfxMode == s_legacyGraphicsModes[i].oldName) {
+				ConfMan.set("scaler", s_legacyGraphicsModes[i].newName);
+				ConfMan.setInt("scale_factor", s_legacyGraphicsModes[i].factor);
+				break;
+			}
+		}
+	}
+
+	// Look in all game domains as well
+	for (Common::ConfigManager::DomainMap::iterator domain = ConfMan.beginGameDomains(); domain != ConfMan.endGameDomains(); ++domain) {
+		if (domain->_value.contains("gfx_mode")) {
+			Common::String gfxMode(domain->_value.getVal("gfx_mode"));
+			for (uint i = 0; i < ARRAYSIZE(s_legacyGraphicsModes); ++i) {
+				if (gfxMode == s_legacyGraphicsModes[i].oldName) {
+					warning("%s: %s -> %s@%dx", domain->_value.getDomainComment().c_str(), s_legacyGraphicsModes[i].oldName, s_legacyGraphicsModes[i].newName, s_legacyGraphicsModes[i].factor);
+					domain->_value.setVal("scaler", s_legacyGraphicsModes[i].newName);
+					domain->_value.setVal("scale_factor", Common::String::format("%i", s_legacyGraphicsModes[i].factor));
+					domain->_value.erase("gfx_mode");
+					break;
+				}
+			}
+		}
+	}
+}
diff --git a/graphics/scalerplugin.h b/graphics/scalerplugin.h
index 4a3d6cf8ec..2fb10bc785 100644
--- a/graphics/scalerplugin.h
+++ b/graphics/scalerplugin.h
@@ -230,6 +230,11 @@ public:
 	 * Search the scaler plugins for a special plugin based on its name.
 	 */
 	uint findScalerPluginIndex(const char *name) const;
+
+	/**
+	 * Update scaler settings from older versions of ScummVM.
+	 */
+	void updateOldSettings();
 };
 
 /** Convenience shortcut for accessing singleton */




More information about the Scummvm-git-logs mailing list