diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h index 463ec7d133d9d..b4a200cd8a503 100644 --- a/backends/graphics/graphics.h +++ b/backends/graphics/graphics.h @@ -25,6 +25,7 @@ #include "common/system.h" #include "common/noncopyable.h" #include "common/keyboard.h" +#include "common/rotationmode.h" #include "graphics/mode.h" #include "graphics/paletteman.h" @@ -59,6 +60,7 @@ class GraphicsManager : public PaletteManager { virtual int getDefaultStretchMode() const { return 0; } virtual bool setStretchMode(int mode) { return false; } virtual int getStretchMode() const { return 0; } + virtual Common::RotationMode getRotationMode() const { return Common::kRotationNormal; } virtual uint getDefaultScaler() const { return 0; } virtual uint getDefaultScaleFactor() const { return 1; } virtual bool setScaler(uint mode, int factor) { return false; } diff --git a/backends/graphics/opengl/framebuffer.cpp b/backends/graphics/opengl/framebuffer.cpp index 3b2b3efe04db6..16b61b407ac42 100644 --- a/backends/graphics/opengl/framebuffer.cpp +++ b/backends/graphics/opengl/framebuffer.cpp @@ -23,6 +23,7 @@ #include "backends/graphics/opengl/pipelines/pipeline.h" #include "backends/graphics/opengl/texture.h" #include "graphics/opengl/debug.h" +#include "common/rotationmode.h" namespace OpenGL { @@ -188,7 +189,7 @@ void Backbuffer::activateInternal() { #endif } -bool Backbuffer::setSize(uint width, uint height) { +bool Backbuffer::setSize(uint width, uint height, Common::RotationMode rotation) { // Set viewport dimensions. _viewport[0] = 0; _viewport[1] = 0; @@ -216,6 +217,41 @@ bool Backbuffer::setSize(uint width, uint height) { _projectionMatrix(3, 2) = 0.0f; _projectionMatrix(3, 3) = 1.0f; + switch (rotation) { + default: + _projectionMatrix(0, 0) = 2.0f / width; + _projectionMatrix(0, 1) = 0.0f; + _projectionMatrix(1, 0) = 0.0f; + _projectionMatrix(1, 1) = -2.0f / height; + _projectionMatrix(3, 0) = -1.0f; + _projectionMatrix(3, 1) = 1.0f; + break; + case Common::kRotation90: + _projectionMatrix(0, 0) = 0.0f; + _projectionMatrix(0, 1) = -2.0f / height; + _projectionMatrix(1, 0) = -2.0f / width; + _projectionMatrix(1, 1) = 0.0f; + _projectionMatrix(3, 0) = 1.0f; + _projectionMatrix(3, 1) = 1.0f; + break; + case Common::kRotation180: + _projectionMatrix(0, 0) = -2.0f / width; + _projectionMatrix(0, 1) = 0.0f; + _projectionMatrix(1, 0) = 0.0f; + _projectionMatrix(1, 1) = 2.0f / height; + _projectionMatrix(3, 0) = 1.0f; + _projectionMatrix(3, 1) = -1.0f; + break; + case Common::kRotation270: + _projectionMatrix(0, 0) = 0.0f; + _projectionMatrix(0, 1) = 2.0f / height; + _projectionMatrix(1, 0) = 2.0f / width; + _projectionMatrix(1, 1) = 0.0f; + _projectionMatrix(3, 0) = -1.0f; + _projectionMatrix(3, 1) = -1.0f; + break; + } + // Directly apply changes when we are active. if (isActive()) { applyViewport(); @@ -268,7 +304,7 @@ void TextureTarget::create() { _needUpdate = true; } -bool TextureTarget::setSize(uint width, uint height) { +bool TextureTarget::setSize(uint width, uint height, Common::RotationMode rotation) { if (!_texture->setSize(width, height)) { return false; } diff --git a/backends/graphics/opengl/framebuffer.h b/backends/graphics/opengl/framebuffer.h index 53ef00960db0a..f9bb5825d4477 100644 --- a/backends/graphics/opengl/framebuffer.h +++ b/backends/graphics/opengl/framebuffer.h @@ -26,6 +26,8 @@ #include "math/matrix4.h" +#include "common/rotationmode.h" + namespace OpenGL { class Pipeline; @@ -147,7 +149,7 @@ class Framebuffer { /** * Set the size of the target buffer. */ - virtual bool setSize(uint width, uint height) = 0; + virtual bool setSize(uint width, uint height, Common::RotationMode rotation) = 0; /** * Accessor to activate framebuffer for pipeline. @@ -183,7 +185,7 @@ class Backbuffer : public Framebuffer { /** * Set the size of the back buffer. */ - bool setSize(uint width, uint height) override; + bool setSize(uint width, uint height, Common::RotationMode rotation) override; protected: void activateInternal() override; @@ -216,7 +218,7 @@ class TextureTarget : public Framebuffer { /** * Set size of the texture target. */ - bool setSize(uint width, uint height) override; + bool setSize(uint width, uint height, Common::RotationMode rotation) override; /** * Query pointer to underlying GL texture. diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp index 101d651940966..0f89cce524fd3 100644 --- a/backends/graphics/opengl/opengl-graphics.cpp +++ b/backends/graphics/opengl/opengl-graphics.cpp @@ -633,6 +633,15 @@ void OpenGLGraphicsManager::renderCursor() { } void OpenGLGraphicsManager::updateScreen() { + int rotation = getRotationMode(); + int rotatedWidth = _windowWidth; + int rotatedHeight = _windowHeight; + + if (rotation == Common::kRotation90 || rotation == Common::kRotation270) { + rotatedWidth = _windowHeight; + rotatedHeight = _windowWidth; + } + if (!_gameScreen || !_pipeline) { return; } @@ -726,8 +735,8 @@ void OpenGLGraphicsManager::updateScreen() { // Third step: Draw the overlay if visible. if (_overlayVisible) { - int dstX = (_windowWidth - _overlayDrawRect.width()) / 2; - int dstY = (_windowHeight - _overlayDrawRect.height()) / 2; + int dstX = (rotatedWidth - _overlayDrawRect.width()) / 2; + int dstY = (rotatedHeight - _overlayDrawRect.height()) / 2; _targetBuffer->enableBlend(Framebuffer::kBlendModeTraditionalTransparency); _pipeline->drawTexture(_overlay->getGLTexture(), dstX, dstY, _overlayDrawRect.width(), _overlayDrawRect.height()); } @@ -762,8 +771,8 @@ void OpenGLGraphicsManager::updateScreen() { // Set the OSD transparency. _pipeline->setColor(1.0f, 1.0f, 1.0f, _osdMessageAlpha / 100.0f); - int dstX = (_windowWidth - _osdMessageSurface->getWidth()) / 2; - int dstY = (_windowHeight - _osdMessageSurface->getHeight()) / 2; + int dstX = (rotatedWidth - _osdMessageSurface->getWidth()) / 2; + int dstY = (rotatedHeight - _osdMessageSurface->getHeight()) / 2; // Draw the OSD texture. _pipeline->drawTexture(_osdMessageSurface->getGLTexture(), @@ -783,7 +792,7 @@ void OpenGLGraphicsManager::updateScreen() { } if (_osdIconSurface) { - int dstX = _windowWidth - _osdIconSurface->getWidth() - kOSDIconRightMargin; + int dstX = rotatedWidth - _osdIconSurface->getWidth() - kOSDIconRightMargin; int dstY = kOSDIconTopMargin; // Draw the OSD icon texture. @@ -1267,11 +1276,22 @@ void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) cons void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height) { // Setup backbuffer size. - _targetBuffer->setSize(width, height); + _targetBuffer->setSize(width, height, getRotationMode()); + int rotation = getRotationMode(); uint overlayWidth = width; uint overlayHeight = height; + int rotatedWidth = _windowWidth; + int rotatedHeight = _windowHeight; + + if (rotation == Common::kRotation90 || rotation == Common::kRotation270) { + overlayWidth = height; + overlayHeight = width; + rotatedWidth = _windowHeight; + rotatedHeight = _windowWidth; + } + // WORKAROUND: We can only support surfaces up to the maximum supported // texture size. Thus, in case we encounter a physical size bigger than // this maximum texture size we will simply use an overlay as big as @@ -1280,7 +1300,7 @@ void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height) // anyway. Thus, it should not be a real issue for modern hardware. if ( overlayWidth > (uint)OpenGLContext.maxTextureSize || overlayHeight > (uint)OpenGLContext.maxTextureSize) { - const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight; + const frac_t outputAspect = intToFrac(rotatedWidth) / rotatedHeight; if (outputAspect > (frac_t)FRAC_ONE) { overlayWidth = OpenGLContext.maxTextureSize; @@ -1648,10 +1668,21 @@ void OpenGLGraphicsManager::recalculateDisplayAreas() { // Setup drawing limitation for game graphics. // This involves some trickery because OpenGL's viewport coordinate system // is upside down compared to ours. - _targetBuffer->setScissorBox(_gameDrawRect.left, - _windowHeight - _gameDrawRect.height() - _gameDrawRect.top, - _gameDrawRect.width(), - _gameDrawRect.height()); + switch (getRotationMode()) { + case Common::kRotation90: + case Common::kRotation180: + _targetBuffer->setScissorBox(_gameDrawRect.top, + _gameDrawRect.left, + _gameDrawRect.height(), + _gameDrawRect.width()); + break; + default: + _targetBuffer->setScissorBox(_gameDrawRect.left, + _windowHeight - _gameDrawRect.height() - _gameDrawRect.top, + _gameDrawRect.width(), + _gameDrawRect.height()); + } + _shakeOffsetScaled = Common::Point(_gameScreenShakeXOffset * _gameDrawRect.width() / (int)_currentState.gameWidth, _gameScreenShakeYOffset * _gameDrawRect.height() / (int)_currentState.gameHeight); diff --git a/backends/graphics/opengl/pipelines/libretro.cpp b/backends/graphics/opengl/pipelines/libretro.cpp index 9c20a1eef2355..635dcf8b5a8f2 100644 --- a/backends/graphics/opengl/pipelines/libretro.cpp +++ b/backends/graphics/opengl/pipelines/libretro.cpp @@ -663,7 +663,7 @@ bool LibRetroPipeline::setupFBOs() { pass.shaderPass->applyScale(sourceW, sourceH, viewportW, viewportH, &sourceW, &sourceH); // Resize FBO to fit the output of the pass. - if (!pass.target->setSize((uint)sourceW, (uint)sourceH)) { + if (!pass.target->setSize((uint)sourceW, (uint)sourceH, Common::kRotationNormal)) { return false; } diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp index a7ca8ff73ae4e..4c36455569d19 100644 --- a/backends/graphics/opengl/texture.cpp +++ b/backends/graphics/opengl/texture.cpp @@ -756,7 +756,7 @@ void TextureCLUT8GPU::enableLinearFiltering(bool enable) { void TextureCLUT8GPU::allocate(uint width, uint height) { // Assure the texture can contain our user data. _clut8Texture.setSize(width, height); - _target->setSize(width, height); + _target->setSize(width, height, Common::kRotationNormal); // In case the needed texture dimension changed we will reinitialize the // texture data buffer. diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp index c9f0844a8ae66..528886e2fb23d 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.cpp +++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -216,6 +216,7 @@ bool OpenGLSdlGraphicsManager::hasFeature(OSystem::Feature f) const { case OSystem::kFeatureVSync: #if SDL_VERSION_ATLEAST(2, 0, 0) case OSystem::kFeatureFullscreenToggleKeepsContext: + case OSystem::kFeatureRotationMode: #endif return true; @@ -242,6 +243,10 @@ void OpenGLSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) } break; + case OSystem::kFeatureRotationMode: + notifyResize(getWindowWidth(), getWindowHeight()); + break; + default: OpenGLGraphicsManager::setFeatureState(f, enable); } diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp index 72adec5fa888c..d0b3a12f95f86 100644 --- a/backends/graphics/sdl/sdl-graphics.cpp +++ b/backends/graphics/sdl/sdl-graphics.cpp @@ -85,6 +85,14 @@ SdlGraphicsManager::State SdlGraphicsManager::getState() const { return state; } +Common::RotationMode SdlGraphicsManager::getRotationMode() const { +#if SDL_VERSION_ATLEAST(2, 0, 0) + return Common::parseRotationMode(ConfMan.getInt("rotation_mode")); +#else + return kRotationNormal; +#endif +} + bool SdlGraphicsManager::setState(const State &state) { beginGFXTransaction(); #ifdef USE_RGB_COLOR @@ -218,8 +226,27 @@ bool SdlGraphicsManager::lockMouse(bool lock) { } bool SdlGraphicsManager::notifyMousePosition(Common::Point &mouse) { - mouse.x = CLIP(mouse.x, 0, _windowWidth - 1); - mouse.y = CLIP(mouse.y, 0, _windowHeight - 1); + switch (getRotationMode()) { + case Common::kRotationNormal: + break; + case Common::kRotation90: { + int x0 = mouse.x, y0 = mouse.y; + mouse.x = CLIP(y0, 0, _windowHeight - 1); + mouse.y = CLIP(_windowWidth - 1 - x0, 0, _windowWidth - 1); + break; + } + case Common::kRotation180: { + mouse.x = CLIP(_windowWidth - 1 - mouse.x, 0, _windowWidth - 1); + mouse.y = CLIP(_windowHeight - 1 - mouse.y, 0, _windowHeight - 1); + break; + } + case Common::kRotation270: { + int x0 = mouse.x, y0 = mouse.y; + mouse.x = CLIP(_windowHeight - 1 - y0, 0, _windowHeight - 1); + mouse.y = CLIP(x0, 0, _windowWidth - 1); + break; + } + } bool showCursor = false; // Currently on macOS we need to scale the events for HiDPI screen, but on @@ -300,6 +327,13 @@ bool SdlGraphicsManager::createOrUpdateWindow(int width, int height, const Uint3 if (!_window) { return false; } + Common::RotationMode rotation = getRotationMode(); + + if (rotation == Common::kRotation90 || rotation == Common::kRotation270) { + int w = width, h = height; + width = h; + height = w; + } // width *=3; // height *=3; diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h index 6774a96830d75..6c978a9e12937 100644 --- a/backends/graphics/sdl/sdl-graphics.h +++ b/backends/graphics/sdl/sdl-graphics.h @@ -91,6 +91,8 @@ class SdlGraphicsManager : virtual public WindowedGraphicsManager, public Common */ virtual bool notifyMousePosition(Common::Point &mouse); + Common::RotationMode getRotationMode() const override; + virtual bool showMouse(bool visible) override; bool lockMouse(bool lock) override; diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index aacb06416924b..840fee5a82eb0 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -215,6 +215,7 @@ bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) const { #if SDL_VERSION_ATLEAST(2, 0, 0) (f == OSystem::kFeatureFullscreenToggleKeepsContext) || (f == OSystem::kFeatureStretchMode) || + (f == OSystem::kFeatureRotationMode) || (f == OSystem::kFeatureVSync) || #endif (f == OSystem::kFeatureCursorPalette) || @@ -247,6 +248,9 @@ void SurfaceSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) if (enable) _window->iconifyWindow(); break; + case OSystem::kFeatureRotationMode: + notifyResize(getWindowWidth(), getWindowHeight()); + break; default: break; } @@ -2908,11 +2912,27 @@ void SurfaceSdlGraphicsManager::SDL_UpdateRects(SDL_Surface *screen, int numrect Common::Rect &drawRect = (_overlayVisible) ? _overlayDrawRect : _gameDrawRect; viewport.x = drawRect.left; viewport.y = drawRect.top; +#if SDL_VERSION_ATLEAST(2, 0, 0) + int rotation = getRotationMode(); + int rotangle = 0; + if (rotation == Common::kRotation90 || rotation == Common::kRotation270) { + int delta = (drawRect.width() - drawRect.height()) / 2; + viewport.x = drawRect.top - delta; + viewport.y = drawRect.left + delta; + } + rotangle = rotation; +#endif viewport.w = drawRect.width(); viewport.h = drawRect.height(); SDL_RenderClear(_renderer); - SDL_RenderCopy(_renderer, _screenTexture, nullptr, &viewport); +#if SDL_VERSION_ATLEAST(2, 0, 0) + if (rotangle != 0) + SDL_RenderCopyEx(_renderer, _screenTexture, nullptr, &viewport, rotangle, nullptr, SDL_FLIP_NONE); + else +#endif + SDL_RenderCopy(_renderer, _screenTexture, nullptr, &viewport); + SDL_RenderPresent(_renderer); } diff --git a/backends/graphics/windowed.h b/backends/graphics/windowed.h index 9f4500b2d1cb2..e39177c8bdf4f 100644 --- a/backends/graphics/windowed.h +++ b/backends/graphics/windowed.h @@ -408,6 +408,17 @@ class WindowedGraphicsManager : virtual public GraphicsManager { private: void populateDisplayAreaDrawRect(const frac_t displayAspect, int originalWidth, int originalHeight, Common::Rect &drawRect) const { int mode = getStretchMode(); + Common::RotationMode rotation = getRotationMode(); + int rotatedWindowWidth; + int rotatedWindowHeight; + + if (rotation == Common::kRotation90 || rotation == Common::kRotation270) { + rotatedWindowWidth = _windowHeight; + rotatedWindowHeight = _windowWidth; + } else { + rotatedWindowWidth = _windowWidth; + rotatedWindowHeight = _windowHeight; + } // Mode Center = use original size, or divide by an integral amount if window is smaller than game surface // Mode Integral = scale by an integral amount. // Mode Fit = scale to fit the window while respecting the aspect ratio @@ -418,30 +429,30 @@ class WindowedGraphicsManager : virtual public GraphicsManager { if (mode == STRETCH_CENTER || mode == STRETCH_INTEGRAL || mode == STRETCH_INTEGRAL_AR) { width = originalWidth; height = intToFrac(width) / displayAspect; - if (width > _windowWidth || height > _windowHeight) { - int fac = 1 + MAX((width - 1) / _windowWidth, (height - 1) / _windowHeight); + if (width > rotatedWindowWidth || height > rotatedWindowHeight) { + int fac = 1 + MAX((width - 1) / rotatedWindowWidth, (height - 1) / rotatedWindowHeight); width /= fac; height /= fac; } else if (mode == STRETCH_INTEGRAL) { - int fac = MIN(_windowWidth / width, _windowHeight / height); + int fac = MIN(rotatedWindowWidth / width, rotatedWindowHeight / height); width *= fac; height *= fac; } else if (mode == STRETCH_INTEGRAL_AR) { int targetHeight = height; - int horizontalFac = _windowWidth / width; + int horizontalFac = rotatedWindowWidth / width; do { width = originalWidth * horizontalFac; int verticalFac = (targetHeight * horizontalFac + originalHeight / 2) / originalHeight; height = originalHeight * verticalFac; --horizontalFac; - } while (horizontalFac > 0 && height > _windowHeight); - if (height > _windowHeight) + } while (horizontalFac > 0 && height > rotatedWindowHeight); + if (height > rotatedWindowHeight) height = targetHeight; } } else { - frac_t windowAspect = intToFrac(_windowWidth) / _windowHeight; - width = _windowWidth; - height = _windowHeight; + frac_t windowAspect = intToFrac(rotatedWindowWidth) / rotatedWindowHeight; + width = rotatedWindowWidth; + height = rotatedWindowHeight; if (mode == STRETCH_FIT_FORCE_ASPECT) { frac_t ratio = intToFrac(4) / 3; if (windowAspect < ratio) @@ -460,26 +471,26 @@ class WindowedGraphicsManager : virtual public GraphicsManager { switch (_screenAlign & SCREEN_ALIGN_XMASK) { default: case SCREEN_ALIGN_CENTER: - alignX = ((_windowWidth - width) / 2); + alignX = ((rotatedWindowWidth - width) / 2); break; case SCREEN_ALIGN_LEFT: alignX = 0; break; case SCREEN_ALIGN_RIGHT: - alignX = (_windowWidth - width); + alignX = (rotatedWindowWidth - width); break; } switch (_screenAlign & SCREEN_ALIGN_YMASK) { default: case SCREEN_ALIGN_MIDDLE: - alignY = ((_windowHeight - height) / 2); + alignY = ((rotatedWindowHeight - height) / 2); break; case SCREEN_ALIGN_TOP: alignY = 0; break; case SCREEN_ALIGN_BOTTOM: - alignY = (_windowHeight - height); + alignY = (rotatedWindowHeight - height); break; } diff --git a/common/module.mk b/common/module.mk index a98010d1c22f8..315ef17134169 100644 --- a/common/module.mk +++ b/common/module.mk @@ -30,6 +30,7 @@ MODULE_OBJS := \ random.o \ rational.o \ rendermode.o \ + rotationmode.o \ str.o \ stream.o \ streamdebug.o \ diff --git a/common/system.h b/common/system.h index f3bba6a62f77d..0c3949cd43b2d 100644 --- a/common/system.h +++ b/common/system.h @@ -628,6 +628,11 @@ class OSystem : Common::NonCopyable { * Covers a wide range of platforms, Apple Macs, XBox 360, PS3, and more */ kFeatureCpuAltivec, + + /** + * Graphics code is able to rotate the screen + */ + kFeatureRotationMode, }; /** diff --git a/gui/options.cpp b/gui/options.cpp index 6de2cf21ab89e..d000413fae825 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -38,6 +38,7 @@ #include "common/config-manager.h" #include "common/gui_options.h" #include "common/rendermode.h" +#include "common/rotationmode.h" #include "common/savefile.h" #include "common/system.h" #include "common/textconsole.h" @@ -205,6 +206,8 @@ void OptionsDialog::init() { _gfxPopUpDesc = nullptr; _renderModePopUp = nullptr; _renderModePopUpDesc = nullptr; + _rotationModePopUp = nullptr; + _rotationModePopUpDesc = nullptr; _stretchPopUp = nullptr; _stretchPopUpDesc = nullptr; _scalerPopUp = nullptr; @@ -343,6 +346,21 @@ void OptionsDialog::build() { _renderModePopUp->setSelectedTag(sel); } + if (g_system->hasFeature(OSystem::kFeatureRotationMode)) { + _rotationModePopUp->setSelected(0); + + if (ConfMan.hasKey("rotation_mode", _domain)) { + const Common::RotationModeDescription *p = Common::g_rotationModes; + const Common::RotationMode rotationMode = Common::parseRotationMode(ConfMan.getInt("rotation_mode", _domain)); + int sel = 0; + for (int i = 0; p->description; ++p, ++i) { + if (rotationMode == p->id) + sel = p->id; + } + _rotationModePopUp->setSelectedTag(sel); + } + } + // Fullscreen setting if (g_system->hasFeature(OSystem::kFeatureFullscreenMode)) { _fullscreenCheckbox->setState(ConfMan.getBool("fullscreen", _domain)); @@ -660,6 +678,17 @@ void OptionsDialog::apply() { } } + if (g_system->hasFeature(OSystem::kFeatureRotationMode)) { + if ((int32)_rotationModePopUp->getSelectedTag() >= 0) { + int rotationModeCode = ((Common::RotationMode)_rotationModePopUp->getSelectedTag()); + if (_rotationModePopUp->getSelectedTag() == 0 || ConfMan.getInt("rotation_mode", _domain) != rotationModeCode) { + ConfMan.setInt("rotation_mode", rotationModeCode, _domain); + _rotationModePopUpDesc->setFontColor(ThemeEngine::FontColor::kFontColorNormal); + } + g_system->setFeatureState(OSystem::kFeatureRotationMode, true); + } + } + if (g_system->hasFeature(OSystem::kFeatureStretchMode)) { isSet = false; if ((int32)_stretchPopUp->getSelectedTag() >= 0) { @@ -1232,6 +1261,10 @@ void OptionsDialog::setGraphicSettingsState(bool enabled) { _gfxPopUp->setEnabled(enabled); _renderModePopUpDesc->setEnabled(enabled); _renderModePopUp->setEnabled(enabled); + if (_rotationModePopUp) { + _rotationModePopUpDesc->setEnabled(enabled); + _rotationModePopUp->setEnabled(enabled); + } if (_rendererTypePopUp) { _rendererTypePopUpDesc->setEnabled(enabled); @@ -1628,6 +1661,21 @@ void OptionsDialog::addGraphicControls(GuiObject *boss, const Common::String &pr updateScaleFactors(_scalerPopUp->getSelectedTag()); } + if (g_system->hasFeature(OSystem::kFeatureRotationMode)) { + const Common::RotationModeDescription *rotm = Common::g_rotationModes; + _rotationModePopUpDesc = new StaticTextWidget(boss, prefix + "grRotationModePopupDesc", _("Rotation mode:")); + if (ConfMan.isKeyTemporary("rotation_mode")) + _rotationModePopUpDesc->setFontColor(ThemeEngine::FontColor::kFontColorOverride); + _rotationModePopUp = new PopUpWidget(boss, prefix + "grRotationModePopup"); + + _rotationModePopUp->appendEntry(_("")); + _rotationModePopUp->appendEntry(Common::U32String()); + while (rotm->description) { + _rotationModePopUp->appendEntry(_c(rotm->description, context), rotm->id); + rotm++; + } + } + if (!g_gui.useLowResGUI()) _shaderButton = new ButtonWidget(boss, prefix + "grShaderButton", _("Shader:"), _("Specifies path to the shader used for scaling the game screen"), kChooseShaderCmd); else @@ -2046,6 +2094,10 @@ void OptionsDialog::setupGraphicsTab() { _stretchPopUpDesc->setVisible(true); _stretchPopUp->setVisible(true); } + if (g_system->hasFeature(OSystem::kFeatureRotationMode)) { + _rotationModePopUpDesc->setVisible(true); + _rotationModePopUp->setVisible(true); + } _fullscreenCheckbox->setVisible(true); if (g_system->hasFeature(OSystem::kFeatureFilteringMode)) _filteringCheckbox->setVisible(true); diff --git a/gui/options.h b/gui/options.h index 2fa503ccd6fa5..f88638e0a7083 100644 --- a/gui/options.h +++ b/gui/options.h @@ -170,6 +170,8 @@ class OptionsDialog : public Dialog { PopUpWidget *_antiAliasPopUp; StaticTextWidget *_renderModePopUpDesc; PopUpWidget *_renderModePopUp; + StaticTextWidget *_rotationModePopUpDesc; + PopUpWidget *_rotationModePopUp; // // Audio controls diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx index ad47197531ebe..945f33fa14244 100644 --- a/gui/themes/common/highres_layout.stx +++ b/gui/themes/common/highres_layout.stx @@ -760,6 +760,14 @@ type = 'PopUp' /> + + + + + + + + " "" "" +"" +"" +"" +"" "" @@ -4219,6 +4227,14 @@ const char *defaultXML1 = "" "/>" "" "" +"" +"" +"" +"" "" diff --git a/gui/themes/residualvm.zip b/gui/themes/residualvm.zip index 0882c25147bd7..bad63cc4c23ce 100644 Binary files a/gui/themes/residualvm.zip and b/gui/themes/residualvm.zip differ diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip index 397150d76fd98..acf1f00f76129 100644 Binary files a/gui/themes/scummclassic.zip and b/gui/themes/scummclassic.zip differ diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx index 3554aebd31e6e..dc9f9c54c6823 100644 --- a/gui/themes/scummclassic/classic_layout.stx +++ b/gui/themes/scummclassic/classic_layout.stx @@ -438,6 +438,14 @@ type = 'PopUp' /> + + + + + + + +