From 6e157429b7a5a64af6265d075c88595df2d6fd79 Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Sun, 1 Oct 2017 16:23:22 -0500 Subject: BACKENDS: Fix window sizing of games that switch between multiple resolutions --- backends/graphics/graphics.h | 2 + backends/graphics/openglsdl/openglsdl-graphics.cpp | 17 ++--- backends/graphics/openglsdl/openglsdl-graphics.h | 5 +- backends/graphics/sdl/sdl-graphics.cpp | 89 +++++++++++++++++++++- backends/graphics/sdl/sdl-graphics.h | 14 +++- .../graphics/surfacesdl/surfacesdl-graphics.cpp | 45 +++++++---- backends/graphics/surfacesdl/surfacesdl-graphics.h | 2 + backends/modular-backend.cpp | 4 + backends/modular-backend.h | 1 + backends/platform/sdl/sdl-window.cpp | 29 ++++++- common/system.h | 13 ++++ engines/cine/cine.cpp | 6 ++ engines/dreamweb/stubs.cpp | 6 ++ engines/engine.cpp | 39 ++++------ engines/gob/gob.cpp | 8 ++ engines/util.h | 14 +++- graphics/mode.h | 50 ++++++++++++ 17 files changed, 287 insertions(+), 57 deletions(-) create mode 100644 graphics/mode.h diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h index 35f2fa1cb6..9f07d36190 100644 --- a/backends/graphics/graphics.h +++ b/backends/graphics/graphics.h @@ -27,6 +27,7 @@ #include "common/noncopyable.h" #include "common/keyboard.h" +#include "graphics/mode.h" #include "graphics/palette.h" /** @@ -58,6 +59,7 @@ public: virtual Common::List getSupportedFormats() const = 0; #endif virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) = 0; + virtual void initSizeHint(const Graphics::ModeList &modes) = 0; virtual int getScreenChangeID() const = 0; virtual void beginGFXTransaction() = 0; diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp index efc10a0d2c..73fc87a75f 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.cpp +++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -268,22 +268,19 @@ bool OpenGLSdlGraphicsManager::getFeatureState(OSystem::Feature f) { } } -bool OpenGLSdlGraphicsManager::setGraphicsMode(int mode) { +void OpenGLSdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFormat *format) { // HACK: This is stupid but the SurfaceSDL backend defaults to 2x. This // assures that the launcher (which requests 320x200) has a reasonable // size. It also makes small games have a reasonable size (i.e. at least // 640x400). We follow the same logic here until we have a better way to // give hints to our backend for that. - _graphicsScale = 2; - - return OpenGLGraphicsManager::setGraphicsMode(mode); -} - -void OpenGLSdlGraphicsManager::resetGraphicsScale() { - OpenGLGraphicsManager::resetGraphicsScale(); + if (w > 320) { + _graphicsScale = 1; + } else { + _graphicsScale = 2; + } - // HACK: See OpenGLSdlGraphicsManager::setGraphicsMode. - _graphicsScale = 1; + return OpenGLGraphicsManager::initSize(w, h, format); } #ifdef USE_RGB_COLOR diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h index 51edcb4363..c5003d867b 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.h +++ b/backends/graphics/openglsdl/openglsdl-graphics.h @@ -43,8 +43,7 @@ public: virtual void setFeatureState(OSystem::Feature f, bool enable); virtual bool getFeatureState(OSystem::Feature f); - virtual bool setGraphicsMode(int mode); - virtual void resetGraphicsScale(); + virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format) override; #ifdef USE_RGB_COLOR virtual Common::List getSupportedFormats() const; @@ -69,6 +68,8 @@ protected: virtual void refreshScreen(); virtual void *getProcAddress(const char *name) const; + virtual int getGraphicsModeScale(int mode) const override { return 1; } + private: bool setupMode(uint width, uint height); diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp index aa6087beae..a181582235 100644 --- a/backends/graphics/sdl/sdl-graphics.cpp +++ b/backends/graphics/sdl/sdl-graphics.cpp @@ -23,12 +23,14 @@ #include "backends/graphics/sdl/sdl-graphics.h" #include "backends/platform/sdl/sdl-sys.h" #include "backends/events/sdl/sdl-events.h" +#include "common/config-manager.h" #include "common/textconsole.h" +#include "graphics/scaler/aspect.h" SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *source, SdlWindow *window) : _eventSource(source), _window(window) #if SDL_VERSION_ATLEAST(2, 0, 0) - , _allowWindowSizeReset(false), _lastFlags(0) + , _allowWindowSizeReset(false), _hintedWidth(0), _hintedHeight(0), _lastFlags(0) #endif { } @@ -63,7 +65,7 @@ bool SdlGraphicsManager::setState(const State &state) { #ifdef USE_RGB_COLOR initSize(state.screenWidth, state.screenHeight, &state.pixelFormat); #else - initSize(state.screenWidth, state.screenHeight, 0); + initSize(state.screenWidth, state.screenHeight, nullptr); #endif setFeatureState(OSystem::kFeatureAspectRatioCorrection, state.aspectRatio); setFeatureState(OSystem::kFeatureFullscreenMode, state.fullscreen); @@ -76,8 +78,82 @@ bool SdlGraphicsManager::setState(const State &state) { } } +bool SdlGraphicsManager::defaultGraphicsModeConfig() const { + const Common::ConfigManager::Domain *transientDomain = ConfMan.getDomain(Common::ConfigManager::kTransientDomain); + if (transientDomain && transientDomain->contains("gfx_mode")) { + const Common::String &mode = transientDomain->getVal("gfx_mode"); + if (!mode.equalsIgnoreCase("normal") && !mode.equalsIgnoreCase("default")) { + return false; + } + } + + const Common::ConfigManager::Domain *gameDomain = ConfMan.getActiveDomain(); + if (gameDomain && gameDomain->contains("gfx_mode")) { + const Common::String &mode = gameDomain->getVal("gfx_mode"); + if (!mode.equalsIgnoreCase("normal") && !mode.equalsIgnoreCase("default")) { + return false; + } + } + + return true; +} + +int SdlGraphicsManager::getGraphicsModeIdByName(const Common::String &name) const { + const OSystem::GraphicsMode *mode = getSupportedGraphicsModes(); + while (mode && mode->name != nullptr) { + if (name.equalsIgnoreCase(mode->name)) { + return mode->id; + } + ++mode; + } + return -1; +} + +void SdlGraphicsManager::initSizeHint(const Graphics::ModeList &modes) { #if SDL_VERSION_ATLEAST(2, 0, 0) -bool SdlGraphicsManager::createOrUpdateWindow(const int width, const int height, const Uint32 flags) { + const bool useDefault = defaultGraphicsModeConfig(); + + int scale = getGraphicsModeScale(getGraphicsModeIdByName(ConfMan.get("gfx_mode"))); + if (scale == -1) { + warning("Unknown scaler; defaulting to 1"); + scale = 1; + } + + int16 bestWidth = 0, bestHeight = 0; + const Graphics::ModeList::const_iterator end = modes.end(); + for (Graphics::ModeList::const_iterator it = modes.begin(); it != end; ++it) { + int16 width = it->width, height = it->height; + + // TODO: Normalize AR correction by passing a PAR in the mode list + // instead of checking the dimensions here like this, since not all + // 320x200/640x400 uses are with non-square pixels (e.g. DreamWeb). + if (ConfMan.getBool("aspect_ratio")) { + if ((width == 320 && height == 200) || (width == 640 && height == 400)) { + height = real2Aspect(height); + } + } + + if (!useDefault || width <= 320) { + width *= scale; + height *= scale; + } + + if (bestWidth < width) { + bestWidth = width; + } + + if (bestHeight < height) { + bestHeight = height; + } + } + + _hintedWidth = bestWidth; + _hintedHeight = bestHeight; +#endif +} + +#if SDL_VERSION_ATLEAST(2, 0, 0) +bool SdlGraphicsManager::createOrUpdateWindow(int width, int height, const Uint32 flags) { if (!_window) { return false; } @@ -88,6 +164,13 @@ bool SdlGraphicsManager::createOrUpdateWindow(const int width, const int height, // size or pixel format of the internal game surface (since a user may have // resized the game window) if (!_window->getSDLWindow() || _lastFlags != flags || _allowWindowSizeReset) { + if (_hintedWidth) { + width = _hintedWidth; + } + if (_hintedHeight) { + height = _hintedHeight; + } + if (!_window->createOrUpdateWindow(width, height, flags)) { return false; } diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h index 937beef9b4..74ee2838ea 100644 --- a/backends/graphics/sdl/sdl-graphics.h +++ b/backends/graphics/sdl/sdl-graphics.h @@ -122,14 +122,26 @@ public: */ SdlWindow *getWindow() const { return _window; } + virtual void initSizeHint(const Graphics::ModeList &modes) override; + protected: + virtual int getGraphicsModeScale(int mode) const = 0; + + bool defaultGraphicsModeConfig() const; + int getGraphicsModeIdByName(const Common::String &name) const; + #if SDL_VERSION_ATLEAST(2, 0, 0) public: - void unlockWindowSize() { _allowWindowSizeReset = true; } + void unlockWindowSize() { + _allowWindowSizeReset = true; + _hintedWidth = 0; + _hintedHeight = 0; + } protected: Uint32 _lastFlags; bool _allowWindowSizeReset; + int _hintedWidth, _hintedHeight; bool createOrUpdateWindow(const int width, const int height, const Uint32 flags); #endif diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index de54145d5f..897cdcb352 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -598,19 +598,11 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() { } #endif -bool SurfaceSdlGraphicsManager::setGraphicsMode(int mode) { - Common::StackLock lock(_graphicsMutex); - - assert(_transactionMode == kTransactionActive); - - if (_oldVideoMode.setup && _oldVideoMode.mode == mode) - return true; - - int newScaleFactor = 1; - +int SurfaceSdlGraphicsManager::getGraphicsModeScale(int mode) const { + int scale; switch (mode) { case GFX_NORMAL: - newScaleFactor = 1; + scale = 1; break; #ifdef USE_SCALERS case GFX_DOUBLESIZE: @@ -623,18 +615,34 @@ bool SurfaceSdlGraphicsManager::setGraphicsMode(int mode) { #ifdef USE_HQ_SCALERS case GFX_HQ2X: #endif - newScaleFactor = 2; + scale = 2; break; case GFX_TRIPLESIZE: case GFX_ADVMAME3X: #ifdef USE_HQ_SCALERS case GFX_HQ3X: #endif - newScaleFactor = 3; + scale = 3; break; #endif - default: + scale = -1; + } + + return scale; +} + +bool SurfaceSdlGraphicsManager::setGraphicsMode(int mode) { + Common::StackLock lock(_graphicsMutex); + + assert(_transactionMode == kTransactionActive); + + if (_oldVideoMode.setup && _oldVideoMode.mode == mode) + return true; + + int newScaleFactor = getGraphicsModeScale(mode); + + if (newScaleFactor == -1) { warning("unknown gfx mode %d", mode); return false; } @@ -774,6 +782,15 @@ void SurfaceSdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFo return; #endif + if ((int)w != _videoMode.screenWidth || (int)h != _videoMode.screenHeight) { + const bool useDefault = defaultGraphicsModeConfig(); + if (useDefault && w > 320) { + resetGraphicsScale(); + } else { + setGraphicsMode(getGraphicsModeIdByName(ConfMan.get("gfx_mode"))); + } + } + _videoMode.screenWidth = w; _videoMode.screenHeight = h; diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h index e93cf410ea..62a4a38d3e 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.h +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h @@ -190,6 +190,8 @@ protected: /** Hardware screen */ SDL_Surface *_hwscreen; + virtual int getGraphicsModeScale(int mode) const override; + #if SDL_VERSION_ATLEAST(2, 0, 0) /* SDL2 features a different API for 2D graphics. We create a wrapper * around this API to keep the code paths as close as possible. */ diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp index 1dab18d54e..c9adbd3100 100644 --- a/backends/modular-backend.cpp +++ b/backends/modular-backend.cpp @@ -113,6 +113,10 @@ void ModularBackend::initSize(uint w, uint h, const Graphics::PixelFormat *forma _graphicsManager->initSize(w, h, format); } +void ModularBackend::initSizeHint(const Graphics::ModeList &modes) { + _graphicsManager->initSizeHint(modes); +} + int ModularBackend::getScreenChangeID() const { return _graphicsManager->getScreenChangeID(); } diff --git a/backends/modular-backend.h b/backends/modular-backend.h index d828c2dde6..982dbbfb02 100644 --- a/backends/modular-backend.h +++ b/backends/modular-backend.h @@ -75,6 +75,7 @@ public: virtual Common::List getSupportedFormats() const; #endif virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL); + virtual void initSizeHint(const Graphics::ModeList &modes) override; virtual int getScreenChangeID() const; virtual void beginGFXTransaction(); diff --git a/backends/platform/sdl/sdl-window.cpp b/backends/platform/sdl/sdl-window.cpp index 07ddc998ba..75cf813638 100644 --- a/backends/platform/sdl/sdl-window.cpp +++ b/backends/platform/sdl/sdl-window.cpp @@ -223,6 +223,33 @@ bool SdlWindow::createOrUpdateWindow(int width, int height, uint32 flags) { const uint32 oldNonUpdateableFlags = _lastFlags & ~updateableFlagsMask; const uint32 newNonUpdateableFlags = flags & ~updateableFlagsMask; + const uint32 fullscreenFlags = flags & fullscreenMask; + + // This is terrible, but there is no way in SDL to get information on the + // maximum bounds of a window with decoration, and SDL is too dumb to make + // sure the window's surface doesn't grow beyond the display bounds, which + // can easily happen with 3x scalers. There is a function in SDL to get the + // window decoration size, but it only exists starting in SDL 2.0.5, which + // is a buggy release on some platforms so we can't safely use 2.0.5+ + // features since some users replace the SDL dynamic library with 2.0.4, and + // the documentation says it only works on X11 anyway, which means it is + // basically worthless. So we'll just try to keep things closeish to the + // maximum for now. + SDL_DisplayMode displayMode; + SDL_GetDesktopDisplayMode(0, &displayMode); + if (!fullscreenFlags) { + displayMode.w -= 20; + displayMode.h -= 30; + } + + if (width > displayMode.w) { + width = displayMode.w; + } + + if (height > displayMode.h) { + height = displayMode.h; + } + if (!_window || oldNonUpdateableFlags != newNonUpdateableFlags) { destroyWindow(); _window = SDL_CreateWindow(_windowCaption.c_str(), _lastX, @@ -231,8 +258,6 @@ bool SdlWindow::createOrUpdateWindow(int width, int height, uint32 flags) { setupIcon(); } } else { - const uint32 fullscreenFlags = flags & fullscreenMask; - if (fullscreenFlags) { SDL_DisplayMode fullscreenMode; fullscreenMode.w = width; diff --git a/common/system.h b/common/system.h index 32f20daf8f..a7f084b455 100644 --- a/common/system.h +++ b/common/system.h @@ -27,6 +27,7 @@ #include "common/noncopyable.h" #include "common/list.h" // For OSystem::getSupportedFormats() #include "graphics/pixelformat.h" +#include "graphics/mode.h" namespace Audio { class Mixer; @@ -633,6 +634,18 @@ public: */ virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) = 0; + /** + * Send a list of graphics modes to the backend so it can make a decision + * about the best way to set up the display hardware. + * + * Engines that switch between different virtual screen sizes during a game + * should call this function prior to any call to initSize. Engines that use + * only a single screen size do not need to call this function. + * + * @param modes the list of graphics modes the engine will probably use. + */ + virtual void initSizeHint(const Graphics::ModeList &modes) = 0; + /** * Return an int value which is changed whenever any screen * parameters (like the resolution) change. That is, whenever a diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp index 777cbe279f..5ecf78d8b4 100644 --- a/engines/cine/cine.cpp +++ b/engines/cine/cine.cpp @@ -94,8 +94,14 @@ void CineEngine::syncSoundSettings() { } Common::Error CineEngine::run() { + Graphics::ModeList modes; + modes.push_back(Graphics::Mode(320, 200)); if (g_cine->getGameType() == GType_FW && (g_cine->getFeatures() & GF_CD)) { + modes.push_back(Graphics::Mode(640, 480)); + initGraphicsModes(modes); showSplashScreen(); + } else { + initGraphicsModes(modes); } // Initialize backend diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp index 4aa487d13f..401ecf038c 100644 --- a/engines/dreamweb/stubs.cpp +++ b/engines/dreamweb/stubs.cpp @@ -22,6 +22,7 @@ #include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" +#include "engines/util.h" #include "common/config-manager.h" #include "common/file.h" @@ -563,6 +564,11 @@ void DreamWebEngine::dreamweb() { break; } + Graphics::ModeList modes; + modes.push_back(Graphics::Mode(320, 200)); + modes.push_back(Graphics::Mode(640, 480)); + initGraphicsModes(modes); + allocateBuffers(); // setMouse diff --git a/engines/engine.cpp b/engines/engine.cpp index ae82692992..8f412ba911 100644 --- a/engines/engine.cpp +++ b/engines/engine.cpp @@ -32,6 +32,7 @@ #include "engines/engine.h" #include "engines/dialogs.h" +#include "engines/util.h" #include "common/config-manager.h" #include "common/events.h" @@ -195,35 +196,21 @@ void Engine::initializePath(const Common::FSNode &gamePath) { } void initCommonGFX() { - const Common::ConfigManager::Domain *transientDomain = ConfMan.getDomain(Common::ConfigManager::kTransientDomain); const Common::ConfigManager::Domain *gameDomain = ConfMan.getActiveDomain(); - assert(transientDomain); - - // Override global scaler with any game-specific define - if (ConfMan.hasKey("gfx_mode")) { - Common::String gfxMode = ConfMan.get("gfx_mode"); - g_system->setGraphicsMode(gfxMode.c_str()); - } - - // Note: The following code deals with the fullscreen / ASR settings. This - // is a bit tricky, because there are three ways the user can affect these - // settings: Via the config file, via the command line, and via in-game - // hotkeys. // Any global or command line settings already have been applied at the time - // we get here. Hence we only do something + // we get here, so we only do something if the game domain overrides those + // values + if (gameDomain) { + if (gameDomain->contains("aspect_ratio")) + g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, ConfMan.getBool("aspect_ratio")); - // (De)activate aspect-ratio correction as determined by the config settings - if (gameDomain && gameDomain->contains("aspect_ratio")) - g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, ConfMan.getBool("aspect_ratio")); + if (gameDomain->contains("fullscreen")) + g_system->setFeatureState(OSystem::kFeatureFullscreenMode, ConfMan.getBool("fullscreen")); - // (De)activate fullscreen mode as determined by the config settings - if (gameDomain && gameDomain->contains("fullscreen")) - g_system->setFeatureState(OSystem::kFeatureFullscreenMode, ConfMan.getBool("fullscreen")); - - // (De)activate filtering mode as determined by the config settings - if (gameDomain && gameDomain->contains("filtering")) - g_system->setFeatureState(OSystem::kFeatureFilteringMode, ConfMan.getBool("filtering")); + if (gameDomain->contains("filtering")) + g_system->setFeatureState(OSystem::kFeatureFilteringMode, ConfMan.getBool("filtering")); + } } // Please leave the splash screen in working order for your releases, even if they're commercial. @@ -285,6 +272,10 @@ void splashScreen() { splash = true; } +void initGraphicsModes(const Graphics::ModeList &modes) { + g_system->initSizeHint(modes); +} + void initGraphics(int width, int height, const Graphics::PixelFormat *format) { g_system->beginGFXTransaction(); diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index c9eaec9ef0..46f32a9f32 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -25,6 +25,7 @@ #include "backends/audiocd/audiocd.h" #include "base/plugins.h" #include "common/config-manager.h" +#include "engines/util.h" #include "audio/mididrv.h" #include "audio/mixer.h" @@ -708,6 +709,13 @@ Common::Error GobEngine::initGraphics() { _mode = 0x14; } + Graphics::ModeList modes; + modes.push_back(Graphics::Mode(_width, _height)); + if (getGameType() == kGameTypeLostInTime) { + modes.push_back(Graphics::Mode(640, 400)); + } + initGraphicsModes(modes); + _video->setSize(); _pixelFormat = g_system->getScreenFormat(); diff --git a/engines/util.h b/engines/util.h index fdac02f005..ccf28f2e22 100644 --- a/engines/util.h +++ b/engines/util.h @@ -23,9 +23,11 @@ #ifndef ENGINES_UTIL_H #define ENGINES_UTIL_H +#include "common/array.h" #include "common/scummsys.h" #include "common/list.h" #include "graphics/pixelformat.h" +#include "graphics/mode.h" /** * Setup the backend's graphics mode. @@ -33,7 +35,17 @@ void initCommonGFX(); /** - * Setup the backend's screen size and graphics mode. + * Sends a list of graphics modes to the backend so it can make a decision + * about the best way to set up the display hardware. + * + * Engines that switch between different virtual screen sizes during a game + * should call this function prior to any call to initGraphics. Engines that use + * only a single screen size do not need to call this function. + */ +void initGraphicsModes(const Graphics::ModeList &modes); + +/** + * Sets up the backend's screen size and graphics mode. * * Shows an various warnings on certain backend graphics * transaction failures (aspect switch, fullscreen switch, etc.). diff --git a/graphics/mode.h b/graphics/mode.h new file mode 100644 index 0000000000..bd8eb25e00 --- /dev/null +++ b/graphics/mode.h @@ -0,0 +1,50 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GRAPHICS_MODE_H +#define GRAPHICS_MODE_H + +#include "common/array.h" + +namespace Graphics { + +/** + * Represents a hardware video mode. + */ +struct Mode { + int16 width; ///< The width in pixels + int16 height; ///< The height in pixels + + Mode(const int16 w, const int16 h) : + width(w), + height(h) {} + + bool operator<(const Mode &other) const { + return width < other.width && height < other.height; + } +}; + +typedef Common::Array ModeList; + +} + +#endif -- cgit v1.2.3