SDL: Begin refactoring the API for selecting scalers

This commit is contained in:
Cameron Cawley 2021-01-05 22:54:53 +00:00 committed by Eugene Sandulenko
parent 626206de7f
commit 0e6b9c2bb6
9 changed files with 154 additions and 158 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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 {

View file

@ -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;

View file

@ -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.

View file

@ -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) {
}