[Scummvm-git-logs] scummvm master -> 488353480fe108078bd53f42749582c059f945cf
bluegr
noreply at scummvm.org
Sat Sep 28 23:10:42 UTC 2024
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
488353480f SDL, COMMON: Support screen rotation
Commit: 488353480fe108078bd53f42749582c059f945cf
https://github.com/scummvm/scummvm/commit/488353480fe108078bd53f42749582c059f945cf
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2024-09-29T02:10:39+03:00
Commit Message:
SDL, COMMON: Support screen rotation
Changed paths:
A common/rotationmode.cpp
A common/rotationmode.h
backends/graphics/graphics.h
backends/graphics/ios/renderbuffer.cpp
backends/graphics/ios/renderbuffer.h
backends/graphics/opengl/framebuffer.cpp
backends/graphics/opengl/framebuffer.h
backends/graphics/opengl/opengl-graphics.cpp
backends/graphics/opengl/pipelines/libretro.cpp
backends/graphics/opengl/texture.cpp
backends/graphics/openglsdl/openglsdl-graphics.cpp
backends/graphics/sdl/sdl-graphics.cpp
backends/graphics/sdl/sdl-graphics.h
backends/graphics/surfacesdl/surfacesdl-graphics.cpp
backends/graphics/windowed.h
common/module.mk
common/system.h
gui/options.cpp
gui/options.h
gui/themes/common/highres_layout.stx
gui/themes/common/lowres_layout.stx
gui/themes/default.inc
gui/themes/residualvm.zip
gui/themes/scummclassic.zip
gui/themes/scummclassic/classic_layout.stx
gui/themes/scummclassic/classic_layout_lowres.stx
gui/themes/scummmodern.zip
gui/themes/scummremastered.zip
diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index 463ec7d133d..b4a200cd8a5 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 @@ public:
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/ios/renderbuffer.cpp b/backends/graphics/ios/renderbuffer.cpp
index 9e568ad358f..b4d2e08cc6a 100644
--- a/backends/graphics/ios/renderbuffer.cpp
+++ b/backends/graphics/ios/renderbuffer.cpp
@@ -53,7 +53,7 @@ void RenderbufferTarget::activateInternal() {
}
}
-bool RenderbufferTarget::setSize(uint width, uint height) {
+bool RenderbufferTarget::setSize(uint width, uint height, Common::RotationMode rotation) {
// Set viewport dimensions.
_viewport[0] = 0;
_viewport[1] = 0;
diff --git a/backends/graphics/ios/renderbuffer.h b/backends/graphics/ios/renderbuffer.h
index 0047f9c2f1c..758672d7757 100644
--- a/backends/graphics/ios/renderbuffer.h
+++ b/backends/graphics/ios/renderbuffer.h
@@ -40,7 +40,7 @@ public:
/**
* Set size of the render target.
*/
- bool setSize(uint width, uint height) override;
+ bool setSize(uint width, uint height, Common::RotationMode rotation) override;
protected:
void activateInternal() override;
diff --git a/backends/graphics/opengl/framebuffer.cpp b/backends/graphics/opengl/framebuffer.cpp
index 3b2b3efe04d..16b61b407ac 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 53ef00960db..f9bb5825d44 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 @@ public:
/**
* 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 @@ public:
/**
* 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 @@ public:
/**
* 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 101d6519409..0f89cce524f 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 9c20a1eef23..635dcf8b5a8 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 a7ca8ff73ae..4c36455569d 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 c9f0844a8ae..528886e2fb2 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 72adec5fa88..516c421c63d 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 Common::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<int16>(mouse.x, 0, _windowWidth - 1);
- mouse.y = CLIP<int16>(mouse.y, 0, _windowHeight - 1);
+ switch (getRotationMode()) {
+ case Common::kRotationNormal:
+ break;
+ case Common::kRotation90: {
+ int x0 = mouse.x, y0 = mouse.y;
+ mouse.x = CLIP<int16>(y0, 0, _windowHeight - 1);
+ mouse.y = CLIP<int16>(_windowWidth - 1 - x0, 0, _windowWidth - 1);
+ break;
+ }
+ case Common::kRotation180: {
+ mouse.x = CLIP<int16>(_windowWidth - 1 - mouse.x, 0, _windowWidth - 1);
+ mouse.y = CLIP<int16>(_windowHeight - 1 - mouse.y, 0, _windowHeight - 1);
+ break;
+ }
+ case Common::kRotation270: {
+ int x0 = mouse.x, y0 = mouse.y;
+ mouse.x = CLIP<int16>(_windowHeight - 1 - y0, 0, _windowHeight - 1);
+ mouse.y = CLIP<int16>(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 6774a96830d..6c978a9e129 100644
--- a/backends/graphics/sdl/sdl-graphics.h
+++ b/backends/graphics/sdl/sdl-graphics.h
@@ -91,6 +91,8 @@ public:
*/
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 aacb0641692..840fee5a82e 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 9f4500b2d1c..e39177c8bdf 100644
--- a/backends/graphics/windowed.h
+++ b/backends/graphics/windowed.h
@@ -408,6 +408,17 @@ protected:
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 @@ private:
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 @@ private:
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 a98010d1c22..315ef171341 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/rotationmode.cpp b/common/rotationmode.cpp
new file mode 100644
index 00000000000..7ca36ab2c2e
--- /dev/null
+++ b/common/rotationmode.cpp
@@ -0,0 +1,46 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/rotationmode.h"
+
+#include "common/gui_options.h"
+#include "common/str.h"
+#include "common/translation.h"
+
+
+namespace Common {
+
+
+const RotationModeDescription g_rotationModes[] = {
+ { _s("No rotation"), kRotationNormal },
+ { _s("Clockwise"), kRotation90 },
+ { _s("180 degress"), kRotation180 },
+ { _s("Counter-clockwise"), kRotation270 },
+ { nullptr, kRotationNormal}
+};
+
+RotationMode parseRotationMode(int val) {
+ if ((val % 90) != 0 || val < 0 || val > 270)
+ return kRotationNormal;
+
+ return static_cast<RotationMode>(val);
+}
+}
diff --git a/common/rotationmode.h b/common/rotationmode.h
new file mode 100644
index 00000000000..15d31035e94
--- /dev/null
+++ b/common/rotationmode.h
@@ -0,0 +1,62 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef COMMON_ROTATIONMODE_H
+#define COMMON_ROTATIONMODE_H
+
+#include "common/scummsys.h"
+
+namespace Common {
+
+/**
+ * @defgroup common_rotationmode Rotation modes
+ * @ingroup common
+ *
+ * @brief API for rotation modes.
+ *
+ * @{
+ */
+
+class String;
+
+/**
+ * List of rotation modes.
+ *
+ */
+enum RotationMode {
+ kRotationNormal = 0,
+ kRotation90 = 90,
+ kRotation180 = 180,
+ kRotation270 = 270,
+};
+
+struct RotationModeDescription {
+ const char *description;
+ RotationMode id;
+};
+
+extern const RotationModeDescription g_rotationModes[];
+
+extern RotationMode parseRotationMode(int val);
+
+}
+
+#endif
diff --git a/common/system.h b/common/system.h
index f3bba6a62f7..0c3949cd43b 100644
--- a/common/system.h
+++ b/common/system.h
@@ -628,6 +628,11 @@ public:
* 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 6de2cf21ab8..d000413fae8 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(_("<default>"));
+ _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 2fa503ccd6f..f88638e0a70 100644
--- a/gui/options.h
+++ b/gui/options.h
@@ -170,6 +170,8 @@ private:
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 ad47197531e..945f33fa142 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -760,6 +760,14 @@
type = 'PopUp'
/>
</layout>
+ <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
+ <widget name = 'grRotationModePopupDesc'
+ type = 'OptionsLabel'
+ />
+ <widget name = 'grRotationModePopup'
+ type = 'PopUp'
+ />
+ </layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
<widget name = 'grStretchModePopupDesc'
type = 'OptionsLabel'
diff --git a/gui/themes/common/lowres_layout.stx b/gui/themes/common/lowres_layout.stx
index 4b85e9af246..c59daa0e8e5 100644
--- a/gui/themes/common/lowres_layout.stx
+++ b/gui/themes/common/lowres_layout.stx
@@ -600,6 +600,14 @@
type = 'PopUp'
/>
</layout>
+ <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' align = 'center'>
+ <widget name = 'grRotationModePopupDesc'
+ type = 'OptionsLabel'
+ />
+ <widget name = 'grRotationModePopup'
+ type = 'PopUp'
+ />
+ </layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' align = 'center'>
<widget name = 'grStretchModePopupDesc'
type = 'OptionsLabel'
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index 689bf34a29b..59e76bfa97a 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -1829,6 +1829,14 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
"/>"
"</layout>"
"<layout type='horizontal' padding='0,0,0,0' spacing='10' align='center'>"
+"<widget name='grRotationModePopupDesc' "
+"type='OptionsLabel' "
+"/>"
+"<widget name='grRotationModePopup' "
+"type='PopUp' "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' align='center'>"
"<widget name='grStretchModePopupDesc' "
"type='OptionsLabel' "
"/>"
@@ -4219,6 +4227,14 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
"/>"
"</layout>"
"<layout type='horizontal' padding='0,0,0,0' spacing='6' align='center'>"
+"<widget name='grRotationModePopupDesc' "
+"type='OptionsLabel' "
+"/>"
+"<widget name='grRotationModePopup' "
+"type='PopUp' "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' align='center'>"
"<widget name='grStretchModePopupDesc' "
"type='OptionsLabel' "
"/>"
diff --git a/gui/themes/residualvm.zip b/gui/themes/residualvm.zip
index 0882c25147b..bad63cc4c23 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 397150d76fd..acf1f00f761 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 3554aebd31e..dc9f9c54c68 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -438,6 +438,14 @@
type = 'PopUp'
/>
</layout>
+ <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
+ <widget name = 'grRotationModePopupDesc'
+ type = 'OptionsLabel'
+ />
+ <widget name = 'grRotationModePopup'
+ type = 'PopUp'
+ />
+ </layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
<widget name = 'grStretchModePopupDesc'
type = 'OptionsLabel'
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index a509bbd77ed..4b6e659ac73 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -445,6 +445,14 @@
type = 'PopUp'
/>
</layout>
+ <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' align = 'center'>
+ <widget name = 'grRotationModePopupDesc'
+ type = 'OptionsLabel'
+ />
+ <widget name = 'grRotationModePopup'
+ type = 'PopUp'
+ />
+ </layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' align = 'center'>
<widget name = 'grStretchModePopupDesc'
type = 'OptionsLabel'
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index 30e28f8bcb8..6be0f764629 100644
Binary files a/gui/themes/scummmodern.zip and b/gui/themes/scummmodern.zip differ
diff --git a/gui/themes/scummremastered.zip b/gui/themes/scummremastered.zip
index 0ff105c4af0..2d95e797a17 100644
Binary files a/gui/themes/scummremastered.zip and b/gui/themes/scummremastered.zip differ
More information about the Scummvm-git-logs
mailing list