aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/events/sdl/sdl-events.cpp3
-rw-r--r--backends/graphics/graphics.h18
-rw-r--r--backends/graphics/null/null-graphics.h4
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp221
-rw-r--r--backends/graphics/opengl/opengl-graphics.h228
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.cpp82
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.h36
-rw-r--r--backends/graphics/sdl/sdl-graphics.cpp36
-rw-r--r--backends/graphics/sdl/sdl-graphics.h66
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp478
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.h165
-rw-r--r--backends/graphics/windowed.h313
-rw-r--r--backends/platform/sdl/sdl-window.cpp12
-rw-r--r--backends/platform/sdl/sdl-window.h9
14 files changed, 820 insertions, 851 deletions
diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index 2c6fe85232..db4aa21ef1 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -174,8 +174,7 @@ void SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
event.mouse.y = y;
if (_graphicsManager) {
- _graphicsManager->notifyMousePos(Common::Point(x, y));
- _graphicsManager->transformMouseCoordinates(event.mouse);
+ _graphicsManager->notifyMousePosition(event.mouse);
}
}
diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index bcd659ac11..cf33803cf5 100644
--- a/backends/graphics/graphics.h
+++ b/backends/graphics/graphics.h
@@ -38,9 +38,9 @@ class GraphicsManager : public PaletteManager {
public:
virtual ~GraphicsManager() {}
- virtual bool hasFeature(OSystem::Feature f) = 0;
+ virtual bool hasFeature(OSystem::Feature f) const = 0;
virtual void setFeatureState(OSystem::Feature f, bool enable) = 0;
- virtual bool getFeatureState(OSystem::Feature f) = 0;
+ virtual bool getFeatureState(OSystem::Feature f) const = 0;
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const = 0;
virtual int getDefaultGraphicsMode() const = 0;
@@ -65,10 +65,10 @@ public:
virtual void beginGFXTransaction() = 0;
virtual OSystem::TransactionError endGFXTransaction() = 0;
- virtual int16 getHeight() = 0;
- virtual int16 getWidth() = 0;
+ virtual int16 getHeight() const = 0;
+ virtual int16 getWidth() const = 0;
virtual void setPalette(const byte *colors, uint start, uint num) = 0;
- virtual void grabPalette(byte *colors, uint start, uint num) = 0;
+ virtual void grabPalette(byte *colors, uint start, uint num) const = 0;
virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) = 0;
virtual Graphics::Surface *lockScreen() = 0;
virtual void unlockScreen() = 0;
@@ -82,10 +82,10 @@ public:
virtual void hideOverlay() = 0;
virtual Graphics::PixelFormat getOverlayFormat() const = 0;
virtual void clearOverlay() = 0;
- virtual void grabOverlay(void *buf, int pitch) = 0;
- virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h)= 0;
- virtual int16 getOverlayHeight() = 0;
- virtual int16 getOverlayWidth() = 0;
+ virtual void grabOverlay(void *buf, int pitch) const = 0;
+ virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) = 0;
+ virtual int16 getOverlayHeight() const = 0;
+ virtual int16 getOverlayWidth() const = 0;
virtual bool showMouse(bool visible) = 0;
virtual void warpMouse(int x, int y) = 0;
diff --git a/backends/graphics/null/null-graphics.h b/backends/graphics/null/null-graphics.h
index 67306c29f3..a870a76b73 100644
--- a/backends/graphics/null/null-graphics.h
+++ b/backends/graphics/null/null-graphics.h
@@ -54,8 +54,8 @@ public:
void beginGFXTransaction() {}
OSystem::TransactionError endGFXTransaction() { return OSystem::kTransactionSuccess; }
- int16 getHeight() { return 0; }
- int16 getWidth() { return 0; }
+ int16 getHeight() const { return 0; }
+ int16 getWidth() const { return 0; }
void setPalette(const byte *colors, uint start, uint num) {}
void grabPalette(byte *colors, uint start, uint num) {}
void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {}
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 28ca110d91..d98dcda599 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -53,14 +53,12 @@ namespace OpenGL {
OpenGLGraphicsManager::OpenGLGraphicsManager()
: _currentState(), _oldState(), _transactionMode(kTransactionNone), _screenChangeID(1 << (sizeof(int) * 8 - 2)),
_pipeline(nullptr),
- _outputScreenWidth(0), _outputScreenHeight(0), _displayX(0), _displayY(0),
- _displayWidth(0), _displayHeight(0), _defaultFormat(), _defaultFormatAlpha(),
+ _defaultFormat(), _defaultFormatAlpha(),
_gameScreen(nullptr), _gameScreenShakeOffset(0), _overlay(nullptr),
- _overlayVisible(false), _cursor(nullptr),
- _cursorX(0), _cursorY(0), _cursorDisplayX(0),_cursorDisplayY(0), _cursorHotspotX(0), _cursorHotspotY(0),
+ _cursor(nullptr),
+ _cursorHotspotX(0), _cursorHotspotY(0),
_cursorHotspotXScaled(0), _cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0),
- _cursorKeyColor(0), _cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false),
- _forceRedraw(false)
+ _cursorKeyColor(0), _cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false)
#ifdef USE_OSD
, _osdMessageChangeRequest(false), _osdMessageAlpha(0), _osdMessageFadeStartTime(0), _osdMessageSurface(nullptr),
_osdIconSurface(nullptr)
@@ -83,7 +81,7 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
#endif
}
-bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) {
+bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) const {
switch (f) {
case OSystem::kFeatureAspectRatioCorrection:
case OSystem::kFeatureCursorPalette:
@@ -129,7 +127,7 @@ void OpenGLGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
}
}
-bool OpenGLGraphicsManager::getFeatureState(OSystem::Feature f) {
+bool OpenGLGraphicsManager::getFeatureState(OSystem::Feature f) const {
switch (f) {
case OSystem::kFeatureAspectRatioCorrection:
return _currentState.aspectRatioCorrection;
@@ -220,10 +218,9 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
#endif
do {
- uint requestedWidth = _currentState.gameWidth;
- uint requestedHeight = _currentState.gameHeight;
- const uint desiredAspect = getDesiredGameScreenAspect();
- requestedHeight = intToFrac(requestedWidth) / desiredAspect;
+ const uint desiredAspect = getDesiredGameAspectRatio();
+ const uint requestedWidth = _currentState.gameWidth;
+ const uint requestedHeight = intToFrac(requestedWidth) / desiredAspect;
if (!loadVideoMode(requestedWidth, requestedHeight,
#ifdef USE_RGB_COLOR
@@ -317,7 +314,7 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
// Update our display area and cursor scaling. This makes sure we pick up
// aspect ratio correction and game screen changes correctly.
- recalculateDisplayArea();
+ recalculateDisplayAreas();
recalculateCursorScaling();
// Something changed, so update the screen change ID.
@@ -347,11 +344,11 @@ void OpenGLGraphicsManager::initSize(uint width, uint height, const Graphics::Pi
_currentState.gameHeight = height;
}
-int16 OpenGLGraphicsManager::getWidth() {
+int16 OpenGLGraphicsManager::getWidth() const {
return _currentState.gameWidth;
}
-int16 OpenGLGraphicsManager::getHeight() {
+int16 OpenGLGraphicsManager::getHeight() const {
return _currentState.gameHeight;
}
@@ -392,6 +389,7 @@ void OpenGLGraphicsManager::updateScreen() {
// We only update the screen when there actually have been any changes.
if ( !_forceRedraw
+ && !_cursorNeedsRedraw
&& !_gameScreen->isDirty()
&& !(_overlayVisible && _overlay->isDirty())
&& !(_cursorVisible && _cursor && _cursor->isDirty())
@@ -401,7 +399,6 @@ void OpenGLGraphicsManager::updateScreen() {
) {
return;
}
- _forceRedraw = false;
// Update changes to textures.
_gameScreen->updateGLTexture();
@@ -420,14 +417,14 @@ void OpenGLGraphicsManager::updateScreen() {
_backBuffer.enableScissorTest(true);
}
- const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight();
+ const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_gameDrawRect.height() / _gameScreen->getHeight();
// First step: Draw the (virtual) game screen.
- g_context.getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _displayX, _displayY + shakeOffset, _displayWidth, _displayHeight);
+ g_context.getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top + shakeOffset, _gameDrawRect.width(), _gameDrawRect.height());
// Second step: Draw the overlay if visible.
if (_overlayVisible) {
- g_context.getActivePipeline()->drawTexture(_overlay->getGLTexture(), 0, 0, _outputScreenWidth, _outputScreenHeight);
+ g_context.getActivePipeline()->drawTexture(_overlay->getGLTexture(), 0, 0, _overlayDrawRect.width(), _overlayDrawRect.height());
}
// Third step: Draw the cursor if visible.
@@ -437,8 +434,8 @@ void OpenGLGraphicsManager::updateScreen() {
const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset;
g_context.getActivePipeline()->drawTexture(_cursor->getGLTexture(),
- _cursorDisplayX - _cursorHotspotXScaled,
- _cursorDisplayY - _cursorHotspotYScaled + cursorOffset,
+ _cursorX - _cursorHotspotXScaled,
+ _cursorY - _cursorHotspotYScaled + cursorOffset,
_cursorWidthScaled, _cursorHeightScaled);
}
@@ -464,8 +461,8 @@ void OpenGLGraphicsManager::updateScreen() {
// Set the OSD transparency.
g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, _osdMessageAlpha / 100.0f);
- int dstX = (_outputScreenWidth - _osdMessageSurface->getWidth()) / 2;
- int dstY = (_outputScreenHeight - _osdMessageSurface->getHeight()) / 2;
+ int dstX = (_windowWidth - _osdMessageSurface->getWidth()) / 2;
+ int dstY = (_windowHeight - _osdMessageSurface->getHeight()) / 2;
// Draw the OSD texture.
g_context.getActivePipeline()->drawTexture(_osdMessageSurface->getGLTexture(),
@@ -481,7 +478,7 @@ void OpenGLGraphicsManager::updateScreen() {
}
if (_osdIconSurface) {
- int dstX = _outputScreenWidth - _osdIconSurface->getWidth() - kOSDIconRightMargin;
+ int dstX = _windowWidth - _osdIconSurface->getWidth() - kOSDIconRightMargin;
int dstY = kOSDIconTopMargin;
// Draw the OSD icon texture.
@@ -490,6 +487,8 @@ void OpenGLGraphicsManager::updateScreen() {
}
#endif
+ _cursorNeedsRedraw = false;
+ _forceRedraw = false;
refreshScreen();
}
@@ -507,7 +506,7 @@ void OpenGLGraphicsManager::setFocusRectangle(const Common::Rect& rect) {
void OpenGLGraphicsManager::clearFocusRectangle() {
}
-int16 OpenGLGraphicsManager::getOverlayWidth() {
+int16 OpenGLGraphicsManager::getOverlayWidth() const {
if (_overlay) {
return _overlay->getWidth();
} else {
@@ -515,7 +514,7 @@ int16 OpenGLGraphicsManager::getOverlayWidth() {
}
}
-int16 OpenGLGraphicsManager::getOverlayHeight() {
+int16 OpenGLGraphicsManager::getOverlayHeight() const {
if (_overlay) {
return _overlay->getHeight();
} else {
@@ -523,22 +522,6 @@ int16 OpenGLGraphicsManager::getOverlayHeight() {
}
}
-void OpenGLGraphicsManager::showOverlay() {
- _overlayVisible = true;
- _forceRedraw = true;
-
- // Update cursor position.
- setMousePosition(_cursorX, _cursorY);
-}
-
-void OpenGLGraphicsManager::hideOverlay() {
- _overlayVisible = false;
- _forceRedraw = true;
-
- // Update cursor position.
- setMousePosition(_cursorX, _cursorY);
-}
-
Graphics::PixelFormat OpenGLGraphicsManager::getOverlayFormat() const {
return _overlay->getFormat();
}
@@ -551,7 +534,7 @@ void OpenGLGraphicsManager::clearOverlay() {
_overlay->fill(0);
}
-void OpenGLGraphicsManager::grabOverlay(void *buf, int pitch) {
+void OpenGLGraphicsManager::grabOverlay(void *buf, int pitch) const {
const Graphics::Surface *overlayData = _overlay->getSurface();
const byte *src = (const byte *)overlayData->getPixels();
@@ -568,7 +551,7 @@ bool OpenGLGraphicsManager::showMouse(bool visible) {
// In case the mouse cursor visibility changed we need to redraw the whole
// screen even when nothing else changed.
if (_cursorVisible != visible) {
- _forceRedraw = true;
+ _cursorNeedsRedraw = true;
}
bool last = _cursorVisible;
@@ -576,43 +559,6 @@ bool OpenGLGraphicsManager::showMouse(bool visible) {
return last;
}
-void OpenGLGraphicsManager::warpMouse(int x, int y) {
- int16 currentX = _cursorX;
- int16 currentY = _cursorY;
- adjustMousePosition(currentX, currentY);
-
- // Check whether the (virtual) coordinate actually changed. If not, then
- // simply do nothing. This avoids ugly "jittering" due to the actual
- // output screen having a bigger resolution than the virtual coordinates.
- if (currentX == x && currentY == y) {
- return;
- }
-
- // Scale the virtual coordinates into actual physical coordinates.
- if (_overlayVisible) {
- if (!_overlay) {
- return;
- }
-
- // It might be confusing that we actually have to handle something
- // here when the overlay is visible. This is because for very small
- // resolutions we have a minimal overlay size and have to adjust
- // for that.
- x = (x * _outputScreenWidth) / _overlay->getWidth();
- y = (y * _outputScreenHeight) / _overlay->getHeight();
- } else {
- if (!_gameScreen) {
- return;
- }
-
- x = (x * _outputScreenWidth) / _gameScreen->getWidth();
- y = (y * _outputScreenHeight) / _gameScreen->getHeight();
- }
-
- setMousePosition(x, y);
- setInternalMousePosition(x, y);
-}
-
namespace {
template<typename DstPixel, typename SrcPixel>
void applyColorKey(DstPixel *dst, const SrcPixel *src, uint w, uint h, uint dstPitch, uint srcPitch, SrcPixel keyColor, DstPixel alphaMask) {
@@ -720,7 +666,6 @@ void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int
updateCursorPalette();
}
- // Update the scaling.
recalculateCursorScaling();
}
@@ -765,8 +710,8 @@ void OpenGLGraphicsManager::osdMessageUpdateSurface() {
}
// Clip the rect
- width = MIN<uint>(width, _displayWidth);
- height = MIN<uint>(height, _displayHeight);
+ width = MIN<uint>(width, _gameDrawRect.width());
+ height = MIN<uint>(height, _gameDrawRect.height());
delete _osdMessageSurface;
_osdMessageSurface = nullptr;
@@ -849,16 +794,13 @@ void OpenGLGraphicsManager::setPalette(const byte *colors, uint start, uint num)
updateCursorPalette();
}
-void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) {
+void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) const {
assert(_gameScreen->hasPalette());
memcpy(colors, _gamePalette + start * 3, num * 3);
}
-void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
- _outputScreenWidth = width;
- _outputScreenHeight = height;
-
+void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height) {
// Setup backbuffer size.
_backBuffer.setDimensions(width, height);
@@ -873,7 +815,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
// anyway. Thus, it should not be a real issue for modern hardware.
if ( overlayWidth > (uint)g_context.maxTextureSize
|| overlayHeight > (uint)g_context.maxTextureSize) {
- const frac_t outputAspect = intToFrac(_outputScreenWidth) / _outputScreenHeight;
+ const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight;
if (outputAspect > (frac_t)FRAC_ONE) {
overlayWidth = g_context.maxTextureSize;
@@ -906,7 +848,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
_overlay->fill(0);
// Re-setup the scaling for the screen and cursor
- recalculateDisplayArea();
+ recalculateDisplayAreas();
recalculateCursorScaling();
// Something changed, so update the screen change ID.
@@ -960,8 +902,8 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
// Refresh the output screen dimensions if some are set up.
- if (_outputScreenWidth != 0 && _outputScreenHeight != 0) {
- setActualScreenSize(_outputScreenWidth, _outputScreenHeight);
+ if (_windowWidth != 0 && _windowHeight != 0) {
+ handleResize(_windowWidth, _windowHeight);
}
// TODO: Should we try to convert textures into one of those formats if
@@ -1031,46 +973,6 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
g_context.reset();
}
-void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {
- if (_overlayVisible) {
- // It might be confusing that we actually have to handle something
- // here when the overlay is visible. This is because for very small
- // resolutions we have a minimal overlay size and have to adjust
- // for that.
- // This can also happen when the overlay is smaller than the actual
- // display size because of texture size limitations.
- if (_overlay) {
- x = (x * _overlay->getWidth()) / _outputScreenWidth;
- y = (y * _overlay->getHeight()) / _outputScreenHeight;
- }
- } else if (_gameScreen) {
- const int16 width = _gameScreen->getWidth();
- const int16 height = _gameScreen->getHeight();
-
- x = (x * width) / (int)_outputScreenWidth;
- y = (y * height) / (int)_outputScreenHeight;
- }
-}
-
-void OpenGLGraphicsManager::setMousePosition(int x, int y) {
- // Whenever the mouse position changed we force a screen redraw to reflect
- // changes properly.
- if (_cursorX != x || _cursorY != y) {
- _forceRedraw = true;
- }
-
- _cursorX = x;
- _cursorY = y;
-
- if (_overlayVisible) {
- _cursorDisplayX = x;
- _cursorDisplayY = y;
- } else {
- _cursorDisplayX = _displayX + (x * _displayWidth) / _outputScreenWidth;
- _cursorDisplayY = _displayY + (y * _displayHeight) / _outputScreenHeight;
- }
-}
-
Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &format, bool wantAlpha) {
GLenum glIntFormat, glFormat, glType;
if (format.bytesPerPixel == 1) {
@@ -1191,51 +1093,34 @@ bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelF
}
}
-frac_t OpenGLGraphicsManager::getDesiredGameScreenAspect() const {
- const uint width = _currentState.gameWidth;
- const uint height = _currentState.gameHeight;
-
+bool OpenGLGraphicsManager::gameNeedsAspectRatioCorrection() const {
if (_currentState.aspectRatioCorrection) {
+ const uint width = getWidth();
+ const uint height = getHeight();
+
// In case we enable aspect ratio correction we force a 4/3 ratio.
// But just for 320x200 and 640x400 games, since other games do not need
// this.
- if ((width == 320 && height == 200) || (width == 640 && height == 400)) {
- return intToFrac(4) / 3;
- }
+ return (width == 320 && height == 200) || (width == 640 && height == 400);
}
- return intToFrac(width) / height;
+ return false;
}
-void OpenGLGraphicsManager::recalculateDisplayArea() {
- if (!_gameScreen || _outputScreenHeight == 0) {
+void OpenGLGraphicsManager::recalculateDisplayAreas() {
+ if (!_gameScreen) {
return;
}
- const frac_t outputAspect = intToFrac(_outputScreenWidth) / _outputScreenHeight;
- const frac_t desiredAspect = getDesiredGameScreenAspect();
-
- _displayWidth = _outputScreenWidth;
- _displayHeight = _outputScreenHeight;
-
- // Adjust one dimension for mantaining the aspect ratio.
- if (outputAspect < desiredAspect) {
- _displayHeight = intToFrac(_displayWidth) / desiredAspect;
- } else if (outputAspect > desiredAspect) {
- _displayWidth = fracToInt(_displayHeight * desiredAspect);
- }
-
- // We center the screen in the middle for now.
- _displayX = (_outputScreenWidth - _displayWidth ) / 2;
- _displayY = (_outputScreenHeight - _displayHeight) / 2;
+ WindowedGraphicsManager::recalculateDisplayAreas();
// Setup drawing limitation for game graphics.
// This involves some trickery because OpenGL's viewport coordinate system
// is upside down compared to ours.
- _backBuffer.setScissorBox(_displayX,
- _outputScreenHeight - _displayHeight - _displayY,
- _displayWidth,
- _displayHeight);
+ _backBuffer.setScissorBox(_gameDrawRect.left,
+ _windowHeight - _gameDrawRect.height() - _gameDrawRect.top,
+ _gameDrawRect.width(),
+ _gameDrawRect.height());
// Update the cursor position to adjust for new display area.
setMousePosition(_cursorX, _cursorY);
@@ -1272,8 +1157,8 @@ void OpenGLGraphicsManager::recalculateCursorScaling() {
// In case scaling is actually enabled we will scale the cursor according
// to the game screen.
if (!_cursorDontScale) {
- const frac_t screenScaleFactorX = intToFrac(_displayWidth) / _gameScreen->getWidth();
- const frac_t screenScaleFactorY = intToFrac(_displayHeight) / _gameScreen->getHeight();
+ const frac_t screenScaleFactorX = intToFrac(_gameDrawRect.width()) / _gameScreen->getWidth();
+ const frac_t screenScaleFactorY = intToFrac(_gameDrawRect.height()) / _gameScreen->getHeight();
_cursorHotspotXScaled = fracToInt(_cursorHotspotXScaled * screenScaleFactorX);
_cursorWidthScaled = fracToInt(_cursorWidthScaled * screenScaleFactorX);
@@ -1284,14 +1169,14 @@ void OpenGLGraphicsManager::recalculateCursorScaling() {
}
#ifdef USE_OSD
-const Graphics::Font *OpenGLGraphicsManager::getFontOSD() {
+const Graphics::Font *OpenGLGraphicsManager::getFontOSD() const {
return FontMan.getFontByUsage(Graphics::FontManager::kLocalizedFont);
}
#endif
bool OpenGLGraphicsManager::saveScreenshot(const Common::String &filename) const {
- const uint width = _outputScreenWidth;
- const uint height = _outputScreenHeight;
+ const uint width = _windowWidth;
+ const uint height = _windowHeight;
// A line of a BMP image must have a size divisible by 4.
// We calculate the padding bytes needed here.
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index cbf68d9cf1..92bb988a5e 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -25,7 +25,7 @@
#include "backends/graphics/opengl/opengl-sys.h"
#include "backends/graphics/opengl/framebuffer.h"
-#include "backends/graphics/graphics.h"
+#include "backends/graphics/windowed.h"
#include "common/frac.h"
#include "common/mutex.h"
@@ -53,74 +53,70 @@ enum {
GFX_OPENGL = 0
};
-class OpenGLGraphicsManager : virtual public GraphicsManager {
+class OpenGLGraphicsManager : virtual public WindowedGraphicsManager {
public:
OpenGLGraphicsManager();
virtual ~OpenGLGraphicsManager();
// GraphicsManager API
- virtual bool hasFeature(OSystem::Feature f);
- virtual void setFeatureState(OSystem::Feature f, bool enable);
- virtual bool getFeatureState(OSystem::Feature f);
+ virtual bool hasFeature(OSystem::Feature f) const override;
+ virtual void setFeatureState(OSystem::Feature f, bool enable) override;
+ virtual bool getFeatureState(OSystem::Feature f) const override;
- virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
- virtual int getDefaultGraphicsMode() const;
- virtual bool setGraphicsMode(int mode);
- virtual int getGraphicsMode() const;
+ virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
+ virtual int getDefaultGraphicsMode() const override;
+ virtual bool setGraphicsMode(int mode) override;
+ virtual int getGraphicsMode() const override;
- virtual void resetGraphicsScale() {}
+ virtual void resetGraphicsScale() override {}
#ifdef USE_RGB_COLOR
- virtual Graphics::PixelFormat getScreenFormat() const;
- virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const = 0;
+ virtual Graphics::PixelFormat getScreenFormat() const override;
+ virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override = 0;
#endif
- virtual void beginGFXTransaction();
- virtual OSystem::TransactionError endGFXTransaction();
+ virtual void beginGFXTransaction() override;
+ virtual OSystem::TransactionError endGFXTransaction() override;
- virtual int getScreenChangeID() const;
+ virtual int getScreenChangeID() const override;
- virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format);
+ virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format) override;
- virtual int16 getWidth();
- virtual int16 getHeight();
+ virtual int16 getWidth() const override;
+ virtual int16 getHeight() const override;
- virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h);
- virtual void fillScreen(uint32 col);
+ virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override;
+ virtual void fillScreen(uint32 col) override;
- virtual void setShakePos(int shakeOffset);
+ virtual void setShakePos(int shakeOffset) override;
- virtual void updateScreen();
+ virtual void updateScreen() override;
- virtual Graphics::Surface *lockScreen();
- virtual void unlockScreen();
+ virtual Graphics::Surface *lockScreen() override;
+ virtual void unlockScreen() override;
- virtual void setFocusRectangle(const Common::Rect& rect);
- virtual void clearFocusRectangle();
+ virtual void setFocusRectangle(const Common::Rect& rect) override;
+ virtual void clearFocusRectangle() override;
- virtual int16 getOverlayWidth();
- virtual int16 getOverlayHeight();
+ virtual int16 getOverlayWidth() const override;
+ virtual int16 getOverlayHeight() const override;
- virtual void showOverlay();
- virtual void hideOverlay();
+ virtual Graphics::PixelFormat getOverlayFormat() const override;
- virtual Graphics::PixelFormat getOverlayFormat() const;
+ virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
+ virtual void clearOverlay() override;
+ virtual void grabOverlay(void *buf, int pitch) const override;
- virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
- virtual void clearOverlay();
- virtual void grabOverlay(void *buf, int pitch);
+ virtual bool showMouse(bool visible) override;
+ virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) override;
+ virtual void setCursorPalette(const byte *colors, uint start, uint num) override;
- virtual bool showMouse(bool visible);
- virtual void warpMouse(int x, int y);
- virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
- virtual void setCursorPalette(const byte *colors, uint start, uint num);
-
- virtual void displayMessageOnOSD(const char *msg);
- virtual void displayActivityIconOnOSD(const Graphics::Surface *icon);
+ virtual void displayMessageOnOSD(const char *msg) override;
+ virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override;
// PaletteManager interface
- virtual void setPalette(const byte *colors, uint start, uint num);
- virtual void grabPalette(byte *colors, uint start, uint num);
+ virtual void setPalette(const byte *colors, uint start, uint num) override;
+ virtual void grabPalette(byte *colors, uint start, uint num) const override;
protected:
/**
@@ -129,15 +125,6 @@ protected:
bool isGLESContext() const { return g_context.type == kContextGLES || g_context.type == kContextGLES2; }
/**
- * Set up the actual screen size available for the OpenGL code to do any
- * drawing.
- *
- * @param width The width of the screen.
- * @param height The height of the screen.
- */
- void setActualScreenSize(uint width, uint height);
-
- /**
* Sets the OpenGL (ES) type the graphics manager shall work with.
*
* This needs to be called at least once (and before ever calling
@@ -167,33 +154,6 @@ protected:
void notifyContextDestroy();
/**
- * Adjust the physical mouse coordinates according to the currently visible screen.
- */
- void adjustMousePosition(int16 &x, int16 &y);
-
- /**
- * Set up the mouse position for graphics output.
- *
- * @param x X coordinate in physical coordinates.
- * @param y Y coordinate in physical coordinates.
- */
- void setMousePosition(int x, int y);
-
- /**
- * Query the mouse position in physical coordinates.
- */
- void getMousePosition(int16 &x, int16 &y) const { x = _cursorX; y = _cursorY; }
-
- /**
- * Set up the mouse position for the (event) system.
- *
- * @param x X coordinate in physical coordinates.
- * @param y Y coordinate in physical coordinates.
- */
- virtual void setInternalMousePosition(int x, int y) = 0;
-
-private:
- /**
* Create a surface with the specified pixel format.
*
* @param format The pixel format the Surface object should accept as
@@ -292,8 +252,7 @@ protected:
virtual void refreshScreen() = 0;
/**
- * Save a screenshot of the full display as BMP to the given file. This
- * uses Common::DumpFile for writing the screenshot.
+ * Saves a screenshot of the entire window, excluding window decorations.
*
* @param filename The output filename.
* @return true on success, false otherwise
@@ -334,7 +293,6 @@ protected:
*/
virtual void *getProcAddress(const char *name) const = 0;
-private:
/**
* Try to determine the internal parameters for a given pixel format.
*
@@ -342,49 +300,9 @@ private:
*/
bool getGLPixelFormat(const Graphics::PixelFormat &pixelFormat, GLenum &glIntFormat, GLenum &glFormat, GLenum &glType) const;
- //
- // Actual hardware screen
- //
-
- /**
- * The width of the physical output.
- */
- uint _outputScreenWidth;
-
- /**
- * The height of the physical output.
- */
- uint _outputScreenHeight;
-
- /**
- * @return The desired aspect of the game screen.
- */
- frac_t getDesiredGameScreenAspect() const;
-
- /**
- * Recalculates the area used to display the game screen.
- */
- void recalculateDisplayArea();
-
- /**
- * The X coordinate of the game screen.
- */
- uint _displayX;
-
- /**
- * The Y coordinate of the game screen.
- */
- uint _displayY;
-
- /**
- * The width of the game screen in physical coordinates.
- */
- uint _displayWidth;
-
- /**
- * The height of the game screen in physical coordinates.
- */
- uint _displayHeight;
+ virtual bool gameNeedsAspectRatioCorrection() const override;
+ virtual void recalculateDisplayAreas() override;
+ virtual void handleResizeImpl(const int width, const int height) override;
/**
* The default pixel format of the backend.
@@ -396,12 +314,8 @@ private:
*/
Graphics::PixelFormat _defaultFormatAlpha;
- //
- // Game screen
- //
-
/**
- * The virtual game screen.
+ * The rendering surface for the virtual game screen.
*/
Surface *_gameScreen;
@@ -420,15 +334,10 @@ private:
//
/**
- * The overlay screen.
+ * The rendering surface for the overlay.
*/
Surface *_overlay;
- /**
- * Whether the overlay is visible or not.
- */
- bool _overlayVisible;
-
//
// Cursor
//
@@ -439,37 +348,17 @@ private:
void updateCursorPalette();
/**
- * The cursor image.
+ * The rendering surface for the mouse cursor.
*/
Surface *_cursor;
/**
- * X coordinate of the cursor in physical coordinates.
- */
- int _cursorX;
-
- /**
- * Y coordinate of the cursor in physical coordinates.
- */
- int _cursorY;
-
- /**
- * X coordinate used for drawing the cursor.
- */
- int _cursorDisplayX;
-
- /**
- * Y coordinate used for drawing the cursor.
- */
- int _cursorDisplayY;
-
- /**
- * The X offset for the cursor hotspot in unscaled coordinates.
+ * The X offset for the cursor hotspot in unscaled game coordinates.
*/
int _cursorHotspotX;
/**
- * The Y offset for the cursor hotspot in unscaled coordinates.
+ * The Y offset for the cursor hotspot in unscaled game coordinates.
*/
int _cursorHotspotY;
@@ -480,22 +369,24 @@ private:
void recalculateCursorScaling();
/**
- * The X offset for the cursor hotspot in scaled coordinates.
+ * The X offset for the cursor hotspot in scaled game display area
+ * coordinates.
*/
int _cursorHotspotXScaled;
/**
- * The Y offset for the cursor hotspot in scaled coordinates.
+ * The Y offset for the cursor hotspot in scaled game display area
+ * coordinates.
*/
int _cursorHotspotYScaled;
/**
- * The width of the cursor scaled coordinates.
+ * The width of the cursor in scaled game display area coordinates.
*/
uint _cursorWidthScaled;
/**
- * The height of the cursor scaled coordinates.
+ * The height of the cursor in scaled game display area coordinates.
*/
uint _cursorHeightScaled;
@@ -524,15 +415,6 @@ private:
*/
byte _cursorPalette[3 * 256];
- //
- // Misc
- //
-
- /**
- * Whether the screen contents shall be forced to redrawn.
- */
- bool _forceRedraw;
-
#ifdef USE_OSD
//
// OSD
@@ -541,7 +423,7 @@ protected:
/**
* Returns the font used for on screen display
*/
- virtual const Graphics::Font *getFontOSD();
+ virtual const Graphics::Font *getFontOSD() const;
private:
/**
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 46940d74f2..c77e9dafc5 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -21,8 +21,10 @@
*/
#include "backends/graphics/openglsdl/openglsdl-graphics.h"
+#include "backends/graphics/opengl/texture.h"
#include "backends/events/sdl/sdl-events.h"
#include "backends/platform/sdl/sdl.h"
+#include "graphics/scaler/aspect.h"
#include "common/textconsole.h"
#include "common/config-manager.h"
@@ -35,7 +37,7 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
#if SDL_VERSION_ATLEAST(2, 0, 0)
_glContext(),
#else
- _lastVideoModeLoad(0), _hwScreen(nullptr),
+ _lastVideoModeLoad(0),
#endif
_graphicsScale(2), _ignoreLoadVideoMode(false), _gotResize(false), _wantsFullScreen(false), _ignoreResizeEvents(0),
_desiredFullscreenWidth(0), _desiredFullscreenHeight(0) {
@@ -52,14 +54,16 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
// Context version 1.4 is choosen arbitrarily based on what most shader
// extensions were written against.
-#define DEFAULT_GL_MAJOR 1
-#define DEFAULT_GL_MINOR 4
+ enum {
+ DEFAULT_GL_MAJOR = 1,
+ DEFAULT_GL_MINOR = 4,
-#define DEFAULT_GLES_MAJOR 1
-#define DEFAULT_GLES_MINOR 1
+ DEFAULT_GLES_MAJOR = 1,
+ DEFAULT_GLES_MINOR = 1,
-#define DEFAULT_GLES2_MAJOR 2
-#define DEFAULT_GLES2_MINOR 0
+ DEFAULT_GLES2_MAJOR = 2,
+ DEFAULT_GLES2_MINOR = 0
+ };
#if USE_FORCED_GL
glContextType = OpenGL::kContextGL;
@@ -127,12 +131,6 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
} else {
glContextType = OpenGL::kContextGL;
}
-#undef DEFAULT_GL_MAJOR
-#undef DEFAULT_GL_MINOR
-#undef DEFAULT_GLES_MAJOR
-#undef DEFAULT_GLES_MINOR
-#undef DEFAULT_GLES2_MAJOR
-#undef DEFAULT_GLES2_MINOR
#endif
setContextType(glContextType);
@@ -217,7 +215,7 @@ void OpenGLSdlGraphicsManager::deactivateManager() {
SdlGraphicsManager::deactivateManager();
}
-bool OpenGLSdlGraphicsManager::hasFeature(OSystem::Feature f) {
+bool OpenGLSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
switch (f) {
case OSystem::kFeatureFullscreenMode:
case OSystem::kFeatureIconifyWindow:
@@ -246,7 +244,7 @@ void OpenGLSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable)
}
}
-bool OpenGLSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
+bool OpenGLSdlGraphicsManager::getFeatureState(OSystem::Feature f) const {
switch (f) {
case OSystem::kFeatureFullscreenMode:
#if SDL_VERSION_ATLEAST(2, 0, 0)
@@ -344,7 +342,7 @@ void OpenGLSdlGraphicsManager::updateScreen() {
void OpenGLSdlGraphicsManager::notifyVideoExpose() {
}
-void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height) {
+void OpenGLSdlGraphicsManager::notifyResize(const int width, const int height) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
// We sometime get outdated resize events from SDL2. So check that the size we get
// is the actual current window size. If not ignore the resize.
@@ -354,11 +352,10 @@ void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height)
// causes a SDL_WINDOWEVENT_RESIZED event with the old resolution to be sent, and this
// event is processed after recreating the window at the new resolution.
int currentWidth, currentHeight;
- getWindowDimensions(&currentWidth, &currentHeight);
- if (width != (uint)currentWidth || height != (uint)currentHeight)
+ getWindowSizeFromSdl(&currentWidth, &currentHeight);
+ if (width != currentWidth || height != currentHeight)
return;
- setActualScreenSize(width, height);
- _eventSource->resetKeyboardEmulation(width - 1, height - 1);
+ handleResize(width, height);
#else
if (!_ignoreResizeEvents && _hwScreen && !(_hwScreen->flags & SDL_FULLSCREEN)) {
// We save that we handled a resize event here. We need to know this
@@ -373,18 +370,6 @@ void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height)
#endif
}
-void OpenGLSdlGraphicsManager::transformMouseCoordinates(Common::Point &point) {
- adjustMousePosition(point.x, point.y);
-}
-
-void OpenGLSdlGraphicsManager::notifyMousePos(Common::Point mouse) {
- setMousePosition(mouse.x, mouse.y);
-}
-
-void OpenGLSdlGraphicsManager::setInternalMousePosition(int x, int y) {
- _window->warpMouseInWindow(x, y);
-}
-
bool OpenGLSdlGraphicsManager::loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) {
// In some cases we might not want to load the requested video mode. This
// will assure that the window size is not altered.
@@ -422,6 +407,11 @@ void *OpenGLSdlGraphicsManager::getProcAddress(const char *name) const {
return SDL_GL_GetProcAddress(name);
}
+void OpenGLSdlGraphicsManager::handleResizeImpl(const int width, const int height) {
+ OpenGLGraphicsManager::handleResizeImpl(width, height);
+ SdlGraphicsManager::handleResizeImpl(width, height);
+}
+
bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
// In case we request a fullscreen mode we will use the mode the user
// has chosen last time or the biggest mode available.
@@ -517,9 +507,8 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
notifyContextCreate(rgba8888, rgba8888);
int actualWidth, actualHeight;
- getWindowDimensions(&actualWidth, &actualHeight);
- setActualScreenSize(actualWidth, actualHeight);
- _eventSource->resetKeyboardEmulation(actualWidth - 1, actualHeight - 1);
+ getWindowSizeFromSdl(&actualWidth, &actualHeight);
+ handleResize(actualWidth, actualHeight);
return true;
#else
// WORKAROUND: Working around infamous SDL bugs when switching
@@ -566,8 +555,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
if (_hwScreen) {
notifyContextCreate(rgba8888, rgba8888);
- setActualScreenSize(_hwScreen->w, _hwScreen->h);
- _eventSource->resetKeyboardEmulation(_hwScreen->w - 1, _hwScreen->h - 1);
+ handleResize(_hwScreen->w, _hwScreen->h);
}
// Ignore resize events (from SDL) for a few frames, if this isn't
@@ -580,20 +568,6 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
#endif
}
-void OpenGLSdlGraphicsManager::getWindowDimensions(int *width, int *height) {
-#if SDL_VERSION_ATLEAST(2, 0, 0)
- SDL_GetWindowSize(_window->getSDLWindow(), width, height);
-#else
- if (width) {
- *width = _hwScreen->w;
- }
-
- if (height) {
- *height = _hwScreen->h;
- }
-#endif
-}
-
bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
switch (event.type) {
case Common::EVENT_KEYUP:
@@ -707,7 +681,7 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
// current scale setting in case the user resized the
// window. Then we apply the direction change.
int windowWidth = 0, windowHeight = 0;
- getWindowDimensions(&windowWidth, &windowHeight);
+ getWindowSizeFromSdl(&windowWidth, &windowHeight);
_graphicsScale = MAX<int>(windowWidth / _lastRequestedWidth, windowHeight / _lastRequestedHeight);
_graphicsScale = MAX<int>(_graphicsScale + direction, 1);
@@ -725,7 +699,7 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
#ifdef USE_OSD
int windowWidth = 0, windowHeight = 0;
- getWindowDimensions(&windowWidth, &windowHeight);
+ getWindowSizeFromSdl(&windowWidth, &windowHeight);
const Common::String osdMsg = Common::String::format(_("Resolution: %dx%d"), windowWidth, windowHeight);
displayMessageOnOSD(osdMsg.c_str());
#endif
@@ -785,7 +759,7 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
}
}
-bool OpenGLSdlGraphicsManager::isHotkey(const Common::Event &event) {
+bool OpenGLSdlGraphicsManager::isHotkey(const Common::Event &event) const {
if (event.kbd.hasFlags(Common::KBD_ALT)) {
return event.kbd.keycode == Common::KEYCODE_RETURN
|| event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h
index c5003d867b..954c7215a4 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.h
+++ b/backends/graphics/openglsdl/openglsdl-graphics.h
@@ -36,38 +36,37 @@ public:
virtual ~OpenGLSdlGraphicsManager();
// GraphicsManager API
- virtual void activateManager();
- virtual void deactivateManager();
+ virtual void activateManager() override;
+ virtual void deactivateManager() override;
- virtual bool hasFeature(OSystem::Feature f);
- virtual void setFeatureState(OSystem::Feature f, bool enable);
- virtual bool getFeatureState(OSystem::Feature f);
+ virtual bool hasFeature(OSystem::Feature f) const override;
+ virtual void setFeatureState(OSystem::Feature f, bool enable) override;
+ virtual bool getFeatureState(OSystem::Feature f) const override;
virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format) override;
#ifdef USE_RGB_COLOR
- virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
+ virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
#endif
- virtual void updateScreen();
+ virtual void updateScreen() override;
// EventObserver API
- virtual bool notifyEvent(const Common::Event &event);
+ virtual bool notifyEvent(const Common::Event &event) override;
// SdlGraphicsManager API
- virtual void notifyVideoExpose();
- virtual void notifyResize(const uint width, const uint height);
- virtual void transformMouseCoordinates(Common::Point &point);
- virtual void notifyMousePos(Common::Point mouse);
+ virtual void notifyVideoExpose() override;
+ virtual void notifyResize(const int width, const int height) override;
protected:
- virtual void setInternalMousePosition(int x, int y);
+ virtual bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) override;
- virtual bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format);
+ virtual void refreshScreen() override;
- virtual void refreshScreen();
+ virtual void *getProcAddress(const char *name) const override;
+
+ virtual void handleResizeImpl(const int width, const int height) override;
- virtual void *getProcAddress(const char *name) const;
virtual int getGraphicsModeScale(int mode) const override { return 1; }
private:
@@ -78,11 +77,8 @@ private:
SDL_GLContext _glContext;
#else
uint32 _lastVideoModeLoad;
- SDL_Surface *_hwScreen;
#endif
- void getWindowDimensions(int *width, int *height);
-
uint _lastRequestedWidth;
uint _lastRequestedHeight;
uint _graphicsScale;
@@ -122,7 +118,7 @@ private:
uint _desiredFullscreenWidth;
uint _desiredFullscreenHeight;
- virtual bool isHotkey(const Common::Event &event);
+ bool isHotkey(const Common::Event &event) const;
};
#endif
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index a181582235..ea947c1073 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -28,15 +28,11 @@
#include "graphics/scaler/aspect.h"
SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *source, SdlWindow *window)
- : _eventSource(source), _window(window)
+ : _eventSource(source), _window(window), _hwScreen(nullptr)
#if SDL_VERSION_ATLEAST(2, 0, 0)
, _allowWindowSizeReset(false), _hintedWidth(0), _hintedHeight(0), _lastFlags(0)
#endif
- {
-}
-
-SdlGraphicsManager::~SdlGraphicsManager() {
-}
+{}
void SdlGraphicsManager::activateManager() {
_eventSource->setGraphicsManager(this);
@@ -46,7 +42,7 @@ void SdlGraphicsManager::deactivateManager() {
_eventSource->setGraphicsManager(0);
}
-SdlGraphicsManager::State SdlGraphicsManager::getState() {
+SdlGraphicsManager::State SdlGraphicsManager::getState() const {
State state;
state.screenWidth = getWidth();
@@ -152,6 +148,32 @@ void SdlGraphicsManager::initSizeHint(const Graphics::ModeList &modes) {
#endif
}
+void SdlGraphicsManager::notifyMousePosition(Common::Point &mouse) {
+ int showCursor;
+ if (_activeArea.drawRect.contains(mouse)) {
+ showCursor = SDL_DISABLE;
+ } else {
+ mouse.x = CLIP<int>(mouse.x, _activeArea.drawRect.left, _activeArea.drawRect.right - 1);
+ mouse.y = CLIP<int>(mouse.y, _activeArea.drawRect.top, _activeArea.drawRect.bottom - 1);
+
+ if (_window->mouseIsGrabbed()) {
+ setSystemMousePosition(mouse.x, mouse.y);
+ showCursor = SDL_DISABLE;
+ } else {
+ showCursor = SDL_ENABLE;
+ }
+ }
+
+ SDL_ShowCursor(showCursor);
+ setMousePosition(mouse.x, mouse.y);
+ mouse = convertWindowToVirtual(mouse.x, mouse.y);
+}
+
+void SdlGraphicsManager::handleResizeImpl(const int width, const int height) {
+ _eventSource->resetKeyboardEmulation(width - 1, height - 1);
+ _forceRedraw = true;
+}
+
#if SDL_VERSION_ATLEAST(2, 0, 0)
bool SdlGraphicsManager::createOrUpdateWindow(int width, int height, const Uint32 flags) {
if (!_window) {
diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h
index ce282d842d..886070aedb 100644
--- a/backends/graphics/sdl/sdl-graphics.h
+++ b/backends/graphics/sdl/sdl-graphics.h
@@ -23,7 +23,7 @@
#ifndef BACKENDS_GRAPHICS_SDL_SDLGRAPHICS_H
#define BACKENDS_GRAPHICS_SDL_SDLGRAPHICS_H
-#include "backends/graphics/graphics.h"
+#include "backends/graphics/windowed.h"
#include "backends/platform/sdl/sdl-window.h"
#include "common/rect.h"
@@ -32,13 +32,11 @@ class SdlEventSource;
/**
* Base class for a SDL based graphics manager.
- *
- * It features a few extra a few extra features required by SdlEventSource.
*/
-class SdlGraphicsManager : virtual public GraphicsManager {
+class SdlGraphicsManager : virtual public WindowedGraphicsManager {
public:
SdlGraphicsManager(SdlEventSource *source, SdlWindow *window);
- virtual ~SdlGraphicsManager();
+ virtual ~SdlGraphicsManager() {}
/**
* Makes this graphics manager active. That means it should be ready to
@@ -74,23 +72,20 @@ public:
* @param width Requested window width.
* @param height Requested window height.
*/
- virtual void notifyResize(const uint width, const uint height) {}
+ virtual void notifyResize(const int width, const int height) {}
/**
- * Transforms real screen coordinates into the current active screen
- * coordinates (may be either game screen or overlay).
+ * Notifies the graphics manager about a mouse position change.
*
- * @param point Mouse coordinates to transform.
- */
- virtual void transformMouseCoordinates(Common::Point &point) = 0;
-
- /**
- * Notifies the graphics manager about a position change according to the
- * real screen coordinates.
+ * The passed point *must* be converted from window coordinates to virtual
+ * coordinates in order for the event to be processed correctly by the game
+ * engine. Just use `convertWindowToVirtual` for this unless you need to do
+ * something special.
*
- * @param mouse Mouse position.
+ * @param mouse The mouse position in window coordinates, which must be
+ * converted synchronously to virtual coordinates.
*/
- virtual void notifyMousePos(Common::Point mouse) = 0;
+ virtual void notifyMousePosition(Common::Point &mouse);
/**
* A (subset) of the graphic manager's state. This is used when switching
@@ -108,17 +103,17 @@ public:
};
/**
- * Queries the current state of the graphic manager.
+ * Gets the current state of the graphics manager.
*/
- State getState();
+ State getState() const;
/**
- * Setup a basic state of the graphic manager.
+ * Sets up a basic state of the graphics manager.
*/
bool setState(const State &state);
/**
- * Queries the SDL window.
+ * @returns the SDL window.
*/
SdlWindow *getWindow() const { return _window; }
@@ -130,6 +125,34 @@ protected:
bool defaultGraphicsModeConfig() const;
int getGraphicsModeIdByName(const Common::String &name) const;
+ /**
+ * Gets the dimensions of the window directly from SDL instead of from the
+ * values stored by the graphics manager.
+ */
+ void getWindowSizeFromSdl(int *width, int *height) const {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ assert(_window);
+ SDL_GetWindowSize(_window->getSDLWindow(), width, height);
+#else
+ assert(_hwScreen);
+
+ if (width) {
+ *width = _hwScreen->w;
+ }
+
+ if (height) {
+ *height = _hwScreen->h;
+ }
+#endif
+ }
+
+ virtual void setSystemMousePosition(const int x, const int y) override {
+ assert(_window);
+ _window->warpMouseInWindow(x, y);
+ }
+
+ virtual void handleResizeImpl(const int width, const int height) override;
+
#if SDL_VERSION_ATLEAST(2, 0, 0)
public:
void unlockWindowSize() {
@@ -146,6 +169,7 @@ protected:
bool createOrUpdateWindow(const int width, const int height, const Uint32 flags);
#endif
+ SDL_Surface *_hwScreen;
SdlEventSource *_eventSource;
SdlWindow *_window;
};
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index fb9870910b..52104ffb7a 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -23,7 +23,6 @@
#include "common/scummsys.h"
#if defined(SDL_BACKEND)
-
#include "backends/graphics/surfacesdl/surfacesdl-graphics.h"
#include "backends/events/sdl/sdl-events.h"
#include "backends/platform/sdl/sdl.h"
@@ -133,10 +132,8 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
_osdMessageSurface(nullptr), _osdMessageAlpha(SDL_ALPHA_TRANSPARENT), _osdMessageFadeStartTime(0),
_osdIconSurface(nullptr),
#endif
- _hwscreen(0),
#if SDL_VERSION_ATLEAST(2, 0, 0)
_renderer(nullptr), _screenTexture(nullptr),
- _viewport(), _windowWidth(1), _windowHeight(1),
#endif
#if defined(WIN32) && !SDL_VERSION_ATLEAST(2, 0, 0)
_originalBitsPerPixel(0),
@@ -146,10 +143,9 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
_screenFormat(Graphics::PixelFormat::createFormatCLUT8()),
_cursorFormat(Graphics::PixelFormat::createFormatCLUT8()),
#endif
- _overlayVisible(false),
_overlayscreen(0), _tmpscreen2(0),
_scalerProc(0), _screenChangeCount(0),
- _mouseVisible(false), _mouseNeedsRedraw(false), _mouseData(0), _mouseSurface(0),
+ _mouseVisible(false), _mouseData(0), _mouseSurface(0),
_mouseOrigSurface(0), _cursorDontScale(false), _cursorPaletteDisabled(true),
_currentShakePos(0), _newShakePos(0),
_paletteDirtyStart(0), _paletteDirtyEnd(0),
@@ -247,7 +243,7 @@ void SurfaceSdlGraphicsManager::deactivateManager() {
SdlGraphicsManager::deactivateManager();
}
-bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) {
+bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
return
(f == OSystem::kFeatureFullscreenMode) ||
(f == OSystem::kFeatureAspectRatioCorrection) ||
@@ -284,7 +280,7 @@ void SurfaceSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable)
}
}
-bool SurfaceSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
+bool SurfaceSdlGraphicsManager::getFeatureState(OSystem::Feature f) const {
// We need to allow this to be called from within a transaction, since we
// currently use it to retreive the graphics state, when switching from
// SDL->OpenGL mode for example.
@@ -555,16 +551,16 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() {
Graphics::PixelFormat(2, 4, 4, 4, 4, 4, 8, 12, 0)
};
- if (_hwscreen) {
+ if (_hwScreen) {
// Get our currently set hardware format
- Graphics::PixelFormat hwFormat(_hwscreen->format->BytesPerPixel,
- 8 - _hwscreen->format->Rloss, 8 - _hwscreen->format->Gloss,
- 8 - _hwscreen->format->Bloss, 8 - _hwscreen->format->Aloss,
- _hwscreen->format->Rshift, _hwscreen->format->Gshift,
- _hwscreen->format->Bshift, _hwscreen->format->Ashift);
+ Graphics::PixelFormat hwFormat(_hwScreen->format->BytesPerPixel,
+ 8 - _hwScreen->format->Rloss, 8 - _hwScreen->format->Gloss,
+ 8 - _hwScreen->format->Bloss, 8 - _hwScreen->format->Aloss,
+ _hwScreen->format->Rshift, _hwScreen->format->Gshift,
+ _hwScreen->format->Bshift, _hwScreen->format->Ashift);
// Workaround to SDL not providing an accurate Aloss value on Mac OS X.
- if (_hwscreen->format->Amask == 0)
+ if (_hwScreen->format->Amask == 0)
hwFormat.aLoss = 8;
_supportedFormats.push_back(hwFormat);
@@ -579,7 +575,7 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() {
// Push some RGB formats
for (i = 0; i < ARRAYSIZE(RGBList); i++) {
- if (_hwscreen && (RGBList[i].bytesPerPixel > format.bytesPerPixel))
+ if (_hwScreen && (RGBList[i].bytesPerPixel > format.bytesPerPixel))
continue;
if (RGBList[i] != format)
_supportedFormats.push_back(RGBList[i]);
@@ -587,7 +583,7 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() {
// Push some BGR formats
for (i = 0; i < ARRAYSIZE(BGRList); i++) {
- if (_hwscreen && (BGRList[i].bytesPerPixel > format.bytesPerPixel))
+ if (_hwScreen && (BGRList[i].bytesPerPixel > format.bytesPerPixel))
continue;
if (BGRList[i] != format)
_supportedFormats.push_back(BGRList[i]);
@@ -722,11 +718,11 @@ void SurfaceSdlGraphicsManager::setGraphicsModeIntern() {
}
}
- if (!_screen || !_hwscreen)
+ if (!_screen || !_hwScreen)
return;
// Blit everything to the screen
- _forceFull = true;
+ _forceRedraw = true;
// Even if the old and new scale factors are the same, we may have a
// different scaler for the cursor now.
@@ -797,13 +793,6 @@ void SurfaceSdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFo
_transactionDetails.sizeChanged = true;
}
-int SurfaceSdlGraphicsManager::effectiveScreenHeight() const {
- return _videoMode.scaleFactor *
- (_videoMode.aspectRatioCorrection
- ? real2Aspect(_videoMode.screenHeight)
- : _videoMode.screenHeight);
-}
-
static void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &width, int &height) {
assert(&width != &height);
@@ -864,7 +853,7 @@ static void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &w
}
bool SurfaceSdlGraphicsManager::loadGFXMode() {
- _forceFull = true;
+ _forceRedraw = true;
#if !defined(__MAEMO__) && !defined(DINGUX) && !defined(GPH_DEVICE) && !defined(LINUXMOTO) && !defined(OPENPANDORA)
_videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
@@ -873,11 +862,14 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
if (_videoMode.screenHeight != 200 && _videoMode.screenHeight != 400)
_videoMode.aspectRatioCorrection = false;
- if (_videoMode.aspectRatioCorrection)
+ _videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
+ _videoMode.hardwareHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
+
+ if (_videoMode.aspectRatioCorrection) {
_videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight);
+ _videoMode.hardwareHeight = real2Aspect(_videoMode.hardwareHeight);
+ }
- _videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
- _videoMode.hardwareHeight = effectiveScreenHeight();
// On GPH devices ALL the _videoMode.hardware... are setup in GPHGraphicsManager::loadGFXMode()
#elif !defined(GPH_DEVICE)
_videoMode.hardwareWidth = _videoMode.overlayWidth;
@@ -924,7 +916,7 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
_displayDisabled = ConfMan.getBool("disable_display");
if (_displayDisabled) {
- _hwscreen = g_eventRec.getSurface(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
+ _hwScreen = g_eventRec.getSurface(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
} else
#endif
{
@@ -937,7 +929,7 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
}
#endif
- _hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16,
+ _hwScreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16,
_videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
);
}
@@ -946,9 +938,9 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
detectSupportedFormats();
#endif
- if (_hwscreen == NULL) {
+ if (_hwScreen == NULL) {
// DON'T use error(), as this tries to bring up the debug
- // console, which WON'T WORK now that _hwscreen is hosed.
+ // console, which WON'T WORK now that _hwScreen is hosed.
if (!_oldVideoMode.setup) {
warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
@@ -958,6 +950,10 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
}
}
+#if !SDL_VERSION_ATLEAST(2, 0, 0)
+ handleResize(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
+#endif
+
//
// Create the surface used for the graphics in 16 bit before scaling, and also the overlay
//
@@ -965,20 +961,20 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
// Need some extra bytes around when using 2xSaI
_tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3,
16,
- _hwscreen->format->Rmask,
- _hwscreen->format->Gmask,
- _hwscreen->format->Bmask,
- _hwscreen->format->Amask);
+ _hwScreen->format->Rmask,
+ _hwScreen->format->Gmask,
+ _hwScreen->format->Bmask,
+ _hwScreen->format->Amask);
if (_tmpscreen == NULL)
error("allocating _tmpscreen failed");
_overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight,
16,
- _hwscreen->format->Rmask,
- _hwscreen->format->Gmask,
- _hwscreen->format->Bmask,
- _hwscreen->format->Amask);
+ _hwScreen->format->Rmask,
+ _hwScreen->format->Gmask,
+ _hwScreen->format->Bmask,
+ _hwScreen->format->Amask);
if (_overlayscreen == NULL)
error("allocating _overlayscreen failed");
@@ -997,25 +993,16 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
_tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3,
16,
- _hwscreen->format->Rmask,
- _hwscreen->format->Gmask,
- _hwscreen->format->Bmask,
- _hwscreen->format->Amask);
+ _hwScreen->format->Rmask,
+ _hwScreen->format->Gmask,
+ _hwScreen->format->Bmask,
+ _hwScreen->format->Amask);
if (_tmpscreen2 == NULL)
error("allocating _tmpscreen2 failed");
-#if !SDL_VERSION_ATLEAST(2, 0, 0)
- // For SDL2 the output resolution might differ from the requested
- // resolution. We handle resetting the keyboard emulation properly inside
- // our SDL_SetVideoMode wrapper for SDL2.
- _eventSource->resetKeyboardEmulation(
- _videoMode.screenWidth * _videoMode.scaleFactor - 1,
- effectiveScreenHeight() - 1);
-#endif
-
// Distinguish 555 and 565 mode
- if (_hwscreen->format->Rmask == 0x7C00)
+ if (_hwScreen->format->Rmask == 0x7C00)
InitScalers(555);
else
InitScalers(565);
@@ -1033,9 +1020,9 @@ void SurfaceSdlGraphicsManager::unloadGFXMode() {
deinitializeRenderer();
#endif
- if (_hwscreen) {
- SDL_FreeSurface(_hwscreen);
- _hwscreen = NULL;
+ if (_hwScreen) {
+ SDL_FreeSurface(_hwScreen);
+ _hwScreen = NULL;
}
if (_tmpscreen) {
@@ -1087,9 +1074,9 @@ bool SurfaceSdlGraphicsManager::hotswapGFXMode() {
_overlayscreen = NULL;
// Release the HW screen surface
- if (_hwscreen) {
- SDL_FreeSurface(_hwscreen);
- _hwscreen = NULL;
+ if (_hwScreen) {
+ SDL_FreeSurface(_hwScreen);
+ _hwScreen = NULL;
}
if (_tmpscreen) {
SDL_FreeSurface(_tmpscreen);
@@ -1155,25 +1142,19 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
ScalerProc *scalerProc;
int scale1;
- // definitions not available for non-DEBUG here. (needed this to compile in SYMBIAN32 & linux?)
-#if defined(DEBUG) && !defined(WIN32) && !defined(_WIN32_WCE)
- assert(_hwscreen != NULL);
- assert(_hwscreen->map->sw_data != NULL);
-#endif
-
// If the shake position changed, fill the dirty area with blackness
if (_currentShakePos != _newShakePos ||
- (_mouseNeedsRedraw && _mouseBackup.y <= _currentShakePos)) {
+ (_cursorNeedsRedraw && _mouseBackup.y <= _currentShakePos)) {
SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _videoMode.scaleFactor), (Uint16)(_newShakePos * _videoMode.scaleFactor)};
if (_videoMode.aspectRatioCorrection && !_overlayVisible)
blackrect.h = real2Aspect(blackrect.h - 1) + 1;
- SDL_FillRect(_hwscreen, &blackrect, 0);
+ SDL_FillRect(_hwScreen, &blackrect, 0);
_currentShakePos = _newShakePos;
- _forceFull = true;
+ _forceRedraw = true;
}
// Check whether the palette was changed in the meantime and update the
@@ -1185,7 +1166,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
_paletteDirtyEnd = 0;
- _forceFull = true;
+ _forceRedraw = true;
}
if (!_overlayVisible) {
@@ -1207,7 +1188,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
// Add the area covered by the mouse cursor to the list of dirty rects if
// we have to redraw the mouse.
- if (_mouseNeedsRedraw)
+ if (_cursorNeedsRedraw)
undrawMouse();
#ifdef USE_OSD
@@ -1215,7 +1196,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
#endif
// Force a full redraw if requested
- if (_forceFull) {
+ if (_forceRedraw) {
_numDirtyRects = 1;
_dirtyRectList[0].x = 0;
_dirtyRectList[0].y = 0;
@@ -1224,7 +1205,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
}
// Only draw anything if necessary
- if (_numDirtyRects > 0 || _mouseNeedsRedraw) {
+ if (_numDirtyRects > 0 || _cursorNeedsRedraw) {
SDL_Rect *r;
SDL_Rect dst;
uint32 srcPitch, dstPitch;
@@ -1240,10 +1221,10 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
}
SDL_LockSurface(srcSurf);
- SDL_LockSurface(_hwscreen);
+ SDL_LockSurface(_hwScreen);
srcPitch = srcSurf->pitch;
- dstPitch = _hwscreen->pitch;
+ dstPitch = _hwScreen->pitch;
for (r = _dirtyRectList; r != lastRect; ++r) {
register int dst_y = r->y + _currentShakePos;
@@ -1268,7 +1249,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
assert(scalerProc != NULL);
scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
- (byte *)_hwscreen->pixels + rx1 * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h);
+ (byte *)_hwScreen->pixels + rx1 * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h);
}
r->x = rx1;
@@ -1278,17 +1259,17 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
#ifdef USE_SCALERS
if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible)
- r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1);
+ r->h = stretch200To240((uint8 *) _hwScreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1);
#endif
}
SDL_UnlockSurface(srcSurf);
- SDL_UnlockSurface(_hwscreen);
+ SDL_UnlockSurface(_hwScreen);
// Readjust the dirty rect list in case we are doing a full update.
// This is necessary if shaking is active.
- if (_forceFull) {
+ if (_forceRedraw) {
_dirtyRectList[0].y = 0;
- _dirtyRectList[0].h = effectiveScreenHeight();
+ _dirtyRectList[0].h = _videoMode.hardwareHeight;
}
drawMouse();
@@ -1318,18 +1299,18 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
y = real2Aspect(y);
if (h > 0 && w > 0) {
- SDL_LockSurface(_hwscreen);
+ SDL_LockSurface(_hwScreen);
// Use white as color for now.
- Uint32 rectColor = SDL_MapRGB(_hwscreen->format, 0xFF, 0xFF, 0xFF);
+ Uint32 rectColor = SDL_MapRGB(_hwScreen->format, 0xFF, 0xFF, 0xFF);
// First draw the top and bottom lines
// then draw the left and right lines
- if (_hwscreen->format->BytesPerPixel == 2) {
- uint16 *top = (uint16 *)((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 2);
- uint16 *bottom = (uint16 *)((byte *)_hwscreen->pixels + (y + h) * _hwscreen->pitch + x * 2);
- byte *left = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 2);
- byte *right = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + (x + w - 1) * 2);
+ if (_hwScreen->format->BytesPerPixel == 2) {
+ uint16 *top = (uint16 *)((byte *)_hwScreen->pixels + y * _hwScreen->pitch + x * 2);
+ uint16 *bottom = (uint16 *)((byte *)_hwScreen->pixels + (y + h) * _hwScreen->pitch + x * 2);
+ byte *left = ((byte *)_hwScreen->pixels + y * _hwScreen->pitch + x * 2);
+ byte *right = ((byte *)_hwScreen->pixels + y * _hwScreen->pitch + (x + w - 1) * 2);
while (w--) {
*top++ = rectColor;
@@ -1340,14 +1321,14 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
*(uint16 *)left = rectColor;
*(uint16 *)right = rectColor;
- left += _hwscreen->pitch;
- right += _hwscreen->pitch;
+ left += _hwScreen->pitch;
+ right += _hwScreen->pitch;
}
- } else if (_hwscreen->format->BytesPerPixel == 4) {
- uint32 *top = (uint32 *)((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 4);
- uint32 *bottom = (uint32 *)((byte *)_hwscreen->pixels + (y + h) * _hwscreen->pitch + x * 4);
- byte *left = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 4);
- byte *right = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + (x + w - 1) * 4);
+ } else if (_hwScreen->format->BytesPerPixel == 4) {
+ uint32 *top = (uint32 *)((byte *)_hwScreen->pixels + y * _hwScreen->pitch + x * 4);
+ uint32 *bottom = (uint32 *)((byte *)_hwScreen->pixels + (y + h) * _hwScreen->pitch + x * 4);
+ byte *left = ((byte *)_hwScreen->pixels + y * _hwScreen->pitch + x * 4);
+ byte *right = ((byte *)_hwScreen->pixels + y * _hwScreen->pitch + (x + w - 1) * 4);
while (w--) {
*top++ = rectColor;
@@ -1358,12 +1339,12 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
*(uint32 *)left = rectColor;
*(uint32 *)right = rectColor;
- left += _hwscreen->pitch;
- right += _hwscreen->pitch;
+ left += _hwScreen->pitch;
+ right += _hwScreen->pitch;
}
}
- SDL_UnlockSurface(_hwscreen);
+ SDL_UnlockSurface(_hwScreen);
}
}
}
@@ -1371,17 +1352,17 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
// Finally, blit all our changes to the screen
if (!_displayDisabled) {
- SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
+ SDL_UpdateRects(_hwScreen, _numDirtyRects, _dirtyRectList);
}
}
_numDirtyRects = 0;
- _forceFull = false;
- _mouseNeedsRedraw = false;
+ _forceRedraw = false;
+ _cursorNeedsRedraw = false;
}
bool SurfaceSdlGraphicsManager::saveScreenshot(const char *filename) {
- assert(_hwscreen != NULL);
+ assert(_hwScreen != NULL);
Common::StackLock lock(_graphicsMutex);
#ifdef USE_PNG
@@ -1391,12 +1372,12 @@ bool SurfaceSdlGraphicsManager::saveScreenshot(const char *filename) {
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
- SDL_Surface *rgbScreen = SDL_ConvertSurfaceFormat(_hwscreen, SDL_PIXELFORMAT_RGB24, 0);
+ SDL_Surface *rgbScreen = SDL_ConvertSurfaceFormat(_hwScreen, SDL_PIXELFORMAT_RGB24, 0);
#else
// This block of code was taken mostly as-is from SDL 1.2's SDL_SaveBMP_RW
SDL_Surface *rgbScreen = SDL_CreateRGBSurface(SDL_SWSURFACE,
- _hwscreen->w,
- _hwscreen->h,
+ _hwScreen->w,
+ _hwScreen->h,
24,
#ifdef SCUMM_LITTLE_ENDIAN
0x0000FF, 0x00FF00, 0xFF0000,
@@ -1411,9 +1392,9 @@ bool SurfaceSdlGraphicsManager::saveScreenshot(const char *filename) {
SDL_Rect bounds;
bounds.x = bounds.y = 0;
- bounds.w = _hwscreen->w;
- bounds.h = _hwscreen->h;
- if (SDL_LowerBlit(_hwscreen, &bounds, rgbScreen, &bounds) < 0) {
+ bounds.w = _hwScreen->w;
+ bounds.h = _hwScreen->h;
+ if (SDL_LowerBlit(_hwScreen, &bounds, rgbScreen, &bounds) < 0) {
SDL_FreeSurface(rgbScreen);
rgbScreen = nullptr;
}
@@ -1441,7 +1422,7 @@ bool SurfaceSdlGraphicsManager::saveScreenshot(const char *filename) {
return success;
#else
- return SDL_SaveBMP(_hwscreen, filename) == 0;
+ return SDL_SaveBMP(_hwScreen, filename) == 0;
#endif
}
@@ -1571,7 +1552,7 @@ void SurfaceSdlGraphicsManager::unlockScreen() {
SDL_UnlockSurface(_screen);
// Trigger a full screen update
- _forceFull = true;
+ _forceRedraw = true;
// Finally unlock the graphics mutex
g_system->unlockMutex(_graphicsMutex);
@@ -1585,11 +1566,11 @@ void SurfaceSdlGraphicsManager::fillScreen(uint32 col) {
}
void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool realCoordinates) {
- if (_forceFull)
+ if (_forceRedraw)
return;
if (_numDirtyRects == NUM_DIRTY_RECT) {
- _forceFull = true;
+ _forceRedraw = true;
return;
}
@@ -1608,8 +1589,8 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
if (!realCoordinates) {
x--;
y--;
- w+=2;
- h+=2;
+ w += 2;
+ h += 2;
}
// clip
@@ -1620,7 +1601,7 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
if (y < 0) {
h += y;
- y=0;
+ y = 0;
}
if (w > width - x) {
@@ -1638,7 +1619,7 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
#endif
if (w == width && h == height) {
- _forceFull = true;
+ _forceRedraw = true;
return;
}
@@ -1652,11 +1633,11 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
}
}
-int16 SurfaceSdlGraphicsManager::getHeight() {
+int16 SurfaceSdlGraphicsManager::getHeight() const {
return _videoMode.screenHeight;
}
-int16 SurfaceSdlGraphicsManager::getWidth() {
+int16 SurfaceSdlGraphicsManager::getWidth() const {
return _videoMode.screenWidth;
}
@@ -1697,7 +1678,7 @@ void SurfaceSdlGraphicsManager::setPalette(const byte *colors, uint start, uint
blitCursor();
}
-void SurfaceSdlGraphicsManager::grabPalette(byte *colors, uint start, uint num) {
+void SurfaceSdlGraphicsManager::grabPalette(byte *colors, uint start, uint num) const {
assert(colors);
#ifdef USE_RGB_COLOR
@@ -1777,56 +1758,7 @@ void SurfaceSdlGraphicsManager::clearFocusRectangle() {
#pragma mark --- Overlays ---
#pragma mark -
-void SurfaceSdlGraphicsManager::showOverlay() {
- assert(_transactionMode == kTransactionNone);
-
- int x, y;
-
- if (_overlayVisible)
- return;
-
- _overlayVisible = true;
-
- // Since resolution could change, put mouse to adjusted position
- // Fixes bug #1349059
- x = _mouseCurState.x * _videoMode.scaleFactor;
- if (_videoMode.aspectRatioCorrection)
- y = real2Aspect(_mouseCurState.y) * _videoMode.scaleFactor;
- else
- y = _mouseCurState.y * _videoMode.scaleFactor;
-
- warpMouse(x, y);
-
- clearOverlay();
-}
-
-void SurfaceSdlGraphicsManager::hideOverlay() {
- assert(_transactionMode == kTransactionNone);
-
- if (!_overlayVisible)
- return;
-
- int x, y;
-
- _overlayVisible = false;
-
- // Since resolution could change, put mouse to adjusted position
- // Fixes bug #1349059
- x = _mouseCurState.x / _videoMode.scaleFactor;
- y = _mouseCurState.y / _videoMode.scaleFactor;
- if (_videoMode.aspectRatioCorrection)
- y = aspect2Real(y);
-
- warpMouse(x, y);
-
- clearOverlay();
-
- _forceFull = true;
-}
-
void SurfaceSdlGraphicsManager::clearOverlay() {
- //assert(_transactionMode == kTransactionNone);
-
Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends
if (!_overlayVisible)
@@ -1854,10 +1786,10 @@ void SurfaceSdlGraphicsManager::clearOverlay() {
SDL_UnlockSurface(_tmpscreen);
SDL_UnlockSurface(_overlayscreen);
- _forceFull = true;
+ _forceRedraw = true;
}
-void SurfaceSdlGraphicsManager::grabOverlay(void *buf, int pitch) {
+void SurfaceSdlGraphicsManager::grabOverlay(void *buf, int pitch) const {
assert(_transactionMode == kTransactionNone);
if (_overlayscreen == NULL)
@@ -1937,56 +1869,11 @@ bool SurfaceSdlGraphicsManager::showMouse(bool visible) {
bool last = _mouseVisible;
_mouseVisible = visible;
- _mouseNeedsRedraw = true;
+ _cursorNeedsRedraw = true;
return last;
}
-void SurfaceSdlGraphicsManager::setMousePos(int x, int y) {
- if (x != _mouseCurState.x || y != _mouseCurState.y) {
- _mouseNeedsRedraw = true;
- _mouseCurState.x = x;
- _mouseCurState.y = y;
- }
-}
-
-void SurfaceSdlGraphicsManager::warpMouse(int x, int y) {
- // Don't change actual mouse position, when mouse is outside of our window (in case of windowed mode)
- if (!_window->hasMouseFocus()) {
- setMousePos(x, y); // but change game cursor position
- return;
- }
-
- int x1 = x, y1 = y;
- if (_videoMode.aspectRatioCorrection && !_overlayVisible)
- y1 = real2Aspect(y1);
-
- if (_mouseCurState.x != x || _mouseCurState.y != y) {
- if (!_overlayVisible) {
- x1 *= _videoMode.scaleFactor;
- y1 *= _videoMode.scaleFactor;
- }
-
-#if SDL_VERSION_ATLEAST(2, 0, 0)
- // Transform our coordinates in "virtual" output coordinate space into
- // actual output coordinate space.
- x1 = x1 * _windowWidth / _videoMode.hardwareWidth;
- y1 = y1 * _windowHeight / _videoMode.hardwareHeight;
-#endif
-
- _window->warpMouseInWindow(x1, y1);
-
- // SDL_WarpMouse() generates a mouse movement event, so
- // setMousePos() would be called eventually. However, the
- // cannon script in CoMI calls this function twice each time
- // the cannon is reloaded. Unless we update the mouse position
- // immediately the second call is ignored, causing the cannon
- // to change its aim.
-
- setMousePos(x, y);
- }
-}
-
void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
#ifdef USE_RGB_COLOR
if (!format)
@@ -2022,10 +1909,10 @@ void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h,
_mouseCurState.w + 2,
_mouseCurState.h + 2,
16,
- _hwscreen->format->Rmask,
- _hwscreen->format->Gmask,
- _hwscreen->format->Bmask,
- _hwscreen->format->Amask);
+ _hwScreen->format->Rmask,
+ _hwScreen->format->Gmask,
+ _hwScreen->format->Bmask,
+ _hwScreen->format->Amask);
if (_mouseOrigSurface == NULL)
error("allocating _mouseOrigSurface failed");
@@ -2057,7 +1944,7 @@ void SurfaceSdlGraphicsManager::blitCursor() {
if (!_mouseOrigSurface || !_mouseData)
return;
- _mouseNeedsRedraw = true;
+ _cursorNeedsRedraw = true;
w = _mouseCurState.w;
h = _mouseCurState.h;
@@ -2159,10 +2046,10 @@ void SurfaceSdlGraphicsManager::blitCursor() {
_mouseCurState.rW,
_mouseCurState.rH,
16,
- _hwscreen->format->Rmask,
- _hwscreen->format->Gmask,
- _hwscreen->format->Bmask,
- _hwscreen->format->Amask);
+ _hwScreen->format->Rmask,
+ _hwScreen->format->Gmask,
+ _hwScreen->format->Bmask,
+ _hwScreen->format->Amask);
if (_mouseSurface == NULL)
error("allocating _mouseSurface failed");
@@ -2245,8 +2132,10 @@ void SurfaceSdlGraphicsManager::drawMouse() {
int scale;
int hotX, hotY;
- dst.x = _mouseCurState.x;
- dst.y = _mouseCurState.y;
+ const Common::Point virtualCursor = convertWindowToVirtual(_cursorX, _cursorY);
+
+ dst.x = virtualCursor.x;
+ dst.y = virtualCursor.y;
if (!_overlayVisible) {
scale = _videoMode.scaleFactor;
@@ -2286,7 +2175,7 @@ void SurfaceSdlGraphicsManager::drawMouse() {
// Note that SDL_BlitSurface() and addDirtyRect() will both perform any
// clipping necessary
- if (SDL_BlitSurface(_mouseSurface, NULL, _hwscreen, &dst) != 0)
+ if (SDL_BlitSurface(_mouseSurface, NULL, _hwScreen, &dst) != 0)
error("SDL_BlitSurface failed: %s", SDL_GetError());
// The screen will be updated using real surface coordinates, i.e.
@@ -2335,14 +2224,14 @@ void SurfaceSdlGraphicsManager::displayMessageOnOSD(const char *msg) {
}
// Clip the rect
- if (width > _hwscreen->w)
- width = _hwscreen->w;
- if (height > _hwscreen->h)
- height = _hwscreen->h;
+ if (width > _hwScreen->w)
+ width = _hwScreen->w;
+ if (height > _hwScreen->h)
+ height = _hwScreen->h;
_osdMessageSurface = SDL_CreateRGBSurface(
SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCALPHA,
- width, height, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask
+ width, height, 16, _hwScreen->format->Rmask, _hwScreen->format->Gmask, _hwScreen->format->Bmask, _hwScreen->format->Amask
);
// Lock the surface
@@ -2379,8 +2268,8 @@ void SurfaceSdlGraphicsManager::displayMessageOnOSD(const char *msg) {
SDL_Rect SurfaceSdlGraphicsManager::getOSDMessageRect() const {
SDL_Rect rect;
- rect.x = (_hwscreen->w - _osdMessageSurface->w) / 2;
- rect.y = (_hwscreen->h - _osdMessageSurface->h) / 2;
+ rect.x = (_hwScreen->w - _osdMessageSurface->w) / 2;
+ rect.y = (_hwScreen->h - _osdMessageSurface->h) / 2;
rect.w = _osdMessageSurface->w;
rect.h = _osdMessageSurface->h;
return rect;
@@ -2393,7 +2282,7 @@ void SurfaceSdlGraphicsManager::displayActivityIconOnOSD(const Graphics::Surface
if (_osdIconSurface && !icon) {
// Force a redraw to clear the icon on the next update
- _forceFull = true;
+ _forceRedraw = true;
}
if (_osdIconSurface) {
@@ -2432,7 +2321,7 @@ void SurfaceSdlGraphicsManager::displayActivityIconOnOSD(const Graphics::Surface
SDL_Rect SurfaceSdlGraphicsManager::getOSDIconRect() const {
SDL_Rect dstRect;
- dstRect.x = _hwscreen->w - _osdIconSurface->w - 10;
+ dstRect.x = _hwScreen->w - _osdIconSurface->w - 10;
dstRect.y = 10;
dstRect.w = _osdIconSurface->w;
dstRect.h = _osdIconSurface->h;
@@ -2464,7 +2353,7 @@ void SurfaceSdlGraphicsManager::updateOSD() {
_osdMessageAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
}
SDL_SetAlpha(_osdMessageSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, _osdMessageAlpha);
- _forceFull = true;
+ _forceRedraw = true;
}
if (_osdMessageAlpha == SDL_ALPHA_TRANSPARENT) {
@@ -2474,26 +2363,30 @@ void SurfaceSdlGraphicsManager::updateOSD() {
if (_osdIconSurface) {
// Redraw the area below the icon for the transparent blit to give correct results.
- _forceFull = true;
+ _forceRedraw = true;
}
}
void SurfaceSdlGraphicsManager::drawOSD() {
if (_osdMessageSurface) {
SDL_Rect dstRect = getOSDMessageRect();
- SDL_BlitSurface(_osdMessageSurface, 0, _hwscreen, &dstRect);
+ SDL_BlitSurface(_osdMessageSurface, 0, _hwScreen, &dstRect);
}
if (_osdIconSurface) {
SDL_Rect dstRect = getOSDIconRect();
- SDL_BlitSurface(_osdIconSurface, 0, _hwscreen, &dstRect);
+ SDL_BlitSurface(_osdIconSurface, 0, _hwScreen, &dstRect);
}
}
#endif
-bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
+void SurfaceSdlGraphicsManager::handleResizeImpl(const int width, const int height) {
+ SdlGraphicsManager::handleResizeImpl(width, height);
+ recalculateDisplayAreas();
+}
+bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
// Ctrl-Alt-a toggles aspect ratio correction
if (key == 'a') {
beginGFXTransaction();
@@ -2505,13 +2398,13 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
message = Common::String::format("%s\n%d x %d -> %d x %d",
_("Enabled aspect ratio correction"),
_videoMode.screenWidth, _videoMode.screenHeight,
- _hwscreen->w, _hwscreen->h
+ _hwScreen->w, _hwScreen->h
);
else
message = Common::String::format("%s\n%d x %d -> %d x %d",
_("Disabled aspect ratio correction"),
_videoMode.screenWidth, _videoMode.screenHeight,
- _hwscreen->w, _hwscreen->h
+ _hwScreen->w, _hwScreen->h
);
displayMessageOnOSD(message.c_str());
#endif
@@ -2532,7 +2425,7 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
displayMessageOnOSD(_("Filtering disabled"));
}
#endif
- _forceFull = true;
+ _forceRedraw = true;
internUpdateScreen();
return true;
}
@@ -2542,12 +2435,19 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
int factor = _videoMode.scaleFactor - 1;
SDLKey sdlKey = (SDLKey)key;
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ bool sizeChanged = false;
+#endif
+
// Increase/decrease the scale factor
if (sdlKey == SDLK_EQUALS || sdlKey == SDLK_PLUS || sdlKey == SDLK_MINUS ||
sdlKey == SDLK_KP_PLUS || sdlKey == SDLK_KP_MINUS) {
factor += (sdlKey == SDLK_MINUS || sdlKey == SDLK_KP_MINUS) ? -1 : +1;
if (0 <= factor && factor <= 3) {
newMode = s_gfxModeSwitchTable[_scalerType][factor];
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ sizeChanged = true;
+#endif
}
}
@@ -2585,10 +2485,19 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
_("Active graphics filter:"),
newScalerName,
_videoMode.screenWidth, _videoMode.screenHeight,
- _hwscreen->w, _hwscreen->h);
+ _hwScreen->w, _hwScreen->h);
displayMessageOnOSD(message.c_str());
}
#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);
+ }
+#endif
+
internUpdateScreen();
return true;
@@ -2700,37 +2609,11 @@ bool SurfaceSdlGraphicsManager::notifyEvent(const Common::Event &event) {
}
void SurfaceSdlGraphicsManager::notifyVideoExpose() {
- _forceFull = true;
-}
-
-void SurfaceSdlGraphicsManager::notifyResize(const uint width, const uint height) {
-#if SDL_VERSION_ATLEAST(2, 0, 0)
- setWindowResolution(width, height);
-#endif
-}
-
-void SurfaceSdlGraphicsManager::transformMouseCoordinates(Common::Point &point) {
-#if SDL_VERSION_ATLEAST(2, 0, 0)
- // In SDL2 the actual output resolution might be different from what we
- // requested. Thus, we transform the coordinates from actual output
- // coordinate space into the "virtual" output coordinate space.
- // Please note that we ignore the possible existence of black bars here,
- // this avoids the feeling of stickyness to black bars.
- point.x = point.x * _videoMode.hardwareWidth / _windowWidth;
- point.y = point.y * _videoMode.hardwareHeight / _windowHeight;
-#endif
-
- if (!_overlayVisible) {
- point.x /= _videoMode.scaleFactor;
- point.y /= _videoMode.scaleFactor;
- if (_videoMode.aspectRatioCorrection)
- point.y = aspect2Real(point.y);
- }
+ _forceRedraw = true;
}
-void SurfaceSdlGraphicsManager::notifyMousePos(Common::Point mouse) {
- transformMouseCoordinates(mouse);
- setMousePos(mouse.x, mouse.y);
+void SurfaceSdlGraphicsManager::notifyResize(const int width, const int height) {
+ handleResize(width, height);
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
@@ -2742,39 +2625,6 @@ void SurfaceSdlGraphicsManager::deinitializeRenderer() {
_renderer = nullptr;
}
-void SurfaceSdlGraphicsManager::setWindowResolution(int width, int height) {
- _windowWidth = width;
- _windowHeight = height;
-
- // We expect full screen resolution as inputs coming from the event system.
- _eventSource->resetKeyboardEmulation(_windowWidth - 1, _windowHeight - 1);
-
- // Calculate the "viewport" for the actual area we draw in. In fullscreen
- // we can easily get a different resolution than what we requested. In
- // this case, we add black bars if necessary to assure the aspect ratio
- // is preserved.
- const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight;
- const frac_t desiredAspect = intToFrac(_videoMode.hardwareWidth) / _videoMode.hardwareHeight;
-
- _viewport.w = _windowWidth;
- _viewport.h = _windowHeight;
-
- // Adjust one dimension for mantaining the aspect ratio.
- if (abs(outputAspect - desiredAspect) >= (int)(FRAC_ONE / 1000)) {
- if (outputAspect < desiredAspect) {
- _viewport.h = _videoMode.hardwareHeight * _windowWidth / _videoMode.hardwareWidth;
- } else if (outputAspect > desiredAspect) {
- _viewport.w = _videoMode.hardwareWidth * _windowHeight / _videoMode.hardwareHeight;
- }
- }
-
- _viewport.x = (_windowWidth - _viewport.w) / 2;
- _viewport.y = (_windowHeight - _viewport.h) / 2;
-
- // Force a full redraw because we changed the viewport.
- _forceFull = true;
-}
-
void SurfaceSdlGraphicsManager::recreateScreenTexture() {
if (!_renderer)
return;
@@ -2807,8 +2657,8 @@ SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height,
return nullptr;
}
- SDL_GetWindowSize(_window->getSDLWindow(), &_windowWidth, &_windowHeight);
- setWindowResolution(_windowWidth, _windowHeight);
+ getWindowSizeFromSdl(&_windowWidth, &_windowHeight);
+ handleResize(_windowWidth, _windowHeight);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, _videoMode.filtering ? "linear" : "nearest");
@@ -2830,8 +2680,14 @@ SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height,
void SurfaceSdlGraphicsManager::SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects) {
SDL_UpdateTexture(_screenTexture, nullptr, screen->pixels, screen->pitch);
+ SDL_Rect viewport;
+ viewport.x = _activeArea.drawRect.left;
+ viewport.y = _activeArea.drawRect.top;
+ viewport.w = _activeArea.drawRect.width();
+ viewport.h = _activeArea.drawRect.height();
+
SDL_RenderClear(_renderer);
- SDL_RenderCopy(_renderer, _screenTexture, NULL, &_viewport);
+ SDL_RenderCopy(_renderer, _screenTexture, NULL, &viewport);
SDL_RenderPresent(_renderer);
}
#endif // SDL_VERSION_ATLEAST(2, 0, 0)
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 85f63cb61a..c1e49b953a 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -40,7 +40,6 @@
#endif
#if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
-// Uncomment this to enable the 'on screen display' code.
#define USE_OSD 1
#endif
@@ -80,76 +79,71 @@ public:
SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
virtual ~SurfaceSdlGraphicsManager();
- virtual void activateManager();
- virtual void deactivateManager();
+ virtual void activateManager() override;
+ virtual void deactivateManager() override;
- virtual bool hasFeature(OSystem::Feature f);
- virtual void setFeatureState(OSystem::Feature f, bool enable);
- virtual bool getFeatureState(OSystem::Feature f);
+ virtual bool hasFeature(OSystem::Feature f) const override;
+ virtual void setFeatureState(OSystem::Feature f, bool enable) override;
+ virtual bool getFeatureState(OSystem::Feature f) const override;
- virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
- virtual int getDefaultGraphicsMode() const;
- virtual bool setGraphicsMode(int mode);
- virtual int getGraphicsMode() const;
- virtual void resetGraphicsScale();
+ virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
+ virtual int getDefaultGraphicsMode() const override;
+ virtual bool setGraphicsMode(int mode) override;
+ virtual int getGraphicsMode() const override;
+ virtual void resetGraphicsScale() override;
#ifdef USE_RGB_COLOR
- virtual Graphics::PixelFormat getScreenFormat() const { return _screenFormat; }
- virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
+ virtual Graphics::PixelFormat getScreenFormat() const override { return _screenFormat; }
+ virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
#endif
- virtual const OSystem::GraphicsMode *getSupportedShaders() const;
- virtual int getShader() const;
- virtual bool setShader(int id);
- virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
- virtual int getScreenChangeID() const { return _screenChangeCount; }
+ virtual const OSystem::GraphicsMode *getSupportedShaders() const override;
+ virtual int getShader() const override;
+ virtual bool setShader(int id) override;
+ virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL) override;
+ virtual int getScreenChangeID() const override { return _screenChangeCount; }
- virtual void beginGFXTransaction();
- virtual OSystem::TransactionError endGFXTransaction();
+ virtual void beginGFXTransaction() override;
+ virtual OSystem::TransactionError endGFXTransaction() override;
- virtual int16 getHeight();
- virtual int16 getWidth();
+ virtual int16 getHeight() const override;
+ virtual int16 getWidth() const override;
protected:
// PaletteManager API
- virtual void setPalette(const byte *colors, uint start, uint num);
- virtual void grabPalette(byte *colors, uint start, uint num);
+ virtual void setPalette(const byte *colors, uint start, uint num) override;
+ virtual void grabPalette(byte *colors, uint start, uint num) const override;
public:
- virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h);
- virtual Graphics::Surface *lockScreen();
- virtual void unlockScreen();
- virtual void fillScreen(uint32 col);
- virtual void updateScreen();
- virtual void setShakePos(int shakeOffset);
- virtual void setFocusRectangle(const Common::Rect& rect);
- virtual void clearFocusRectangle();
-
- virtual void showOverlay();
- virtual void hideOverlay();
- virtual Graphics::PixelFormat getOverlayFormat() const { return _overlayFormat; }
- virtual void clearOverlay();
- virtual void grabOverlay(void *buf, int pitch);
- virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
- virtual int16 getOverlayHeight() { return _videoMode.overlayHeight; }
- virtual int16 getOverlayWidth() { return _videoMode.overlayWidth; }
-
- virtual bool showMouse(bool visible);
- virtual void warpMouse(int x, int y);
- virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
- virtual void setCursorPalette(const byte *colors, uint start, uint num);
+ virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override;
+ virtual Graphics::Surface *lockScreen() override;
+ virtual void unlockScreen() override;
+ virtual void fillScreen(uint32 col) override;
+ virtual void updateScreen() override;
+ virtual void setShakePos(int shakeOffset) override;
+ virtual void setFocusRectangle(const Common::Rect& rect) override;
+ virtual void clearFocusRectangle() override;
+
+ virtual Graphics::PixelFormat getOverlayFormat() const override { return _overlayFormat; }
+ virtual void clearOverlay() override;
+ virtual void grabOverlay(void *buf, int pitch) const override;
+ virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
+ virtual int16 getOverlayHeight() const override { return _videoMode.overlayHeight; }
+ virtual int16 getOverlayWidth() const override { return _videoMode.overlayWidth; }
+
+ virtual bool showMouse(bool visible) override;
+ virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) override;
+ virtual void setCursorPalette(const byte *colors, uint start, uint num) override;
#ifdef USE_OSD
- virtual void displayMessageOnOSD(const char *msg);
- virtual void displayActivityIconOnOSD(const Graphics::Surface *icon);
+ virtual void displayMessageOnOSD(const char *msg) override;
+ virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override;
#endif
// Override from Common::EventObserver
- bool notifyEvent(const Common::Event &event);
+ virtual bool notifyEvent(const Common::Event &event) override;
// SdlGraphicsManager interface
- virtual void notifyVideoExpose();
- virtual void notifyResize(const uint width, const uint height);
- virtual void transformMouseCoordinates(Common::Point &point);
- virtual void notifyMousePos(Common::Point mouse);
+ virtual void notifyVideoExpose() override;
+ virtual void notifyResize(const int width, const int height) override;
protected:
#ifdef USE_OSD
@@ -178,8 +172,11 @@ protected:
void drawOSD();
#endif
- /** Hardware screen */
- SDL_Surface *_hwscreen;
+ virtual bool gameNeedsAspectRatioCorrection() const override {
+ return _videoMode.aspectRatioCorrection;
+ }
+
+ virtual void handleResizeImpl(const int width, const int height) override;
virtual int getGraphicsModeScale(int mode) const override;
@@ -188,10 +185,7 @@ protected:
* around this API to keep the code paths as close as possible. */
SDL_Renderer *_renderer;
SDL_Texture *_screenTexture;
- SDL_Rect _viewport;
- int _windowWidth, _windowHeight;
void deinitializeRenderer();
- void setWindowResolution(int width, int height);
void recreateScreenTexture();
virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
@@ -218,7 +212,6 @@ protected:
SDL_Surface *_tmpscreen2;
SDL_Surface *_overlayscreen;
- bool _overlayVisible;
Graphics::PixelFormat _overlayFormat;
enum {
@@ -280,14 +273,11 @@ protected:
uint8 _originalBitsPerPixel;
#endif
- /** Force full redraw on next updateScreen */
- bool _forceFull;
-
ScalerProc *_scalerProc;
int _scalerType;
int _transactionMode;
- // Indicates whether it is needed to free _hwsurface in destructor
+ // Indicates whether it is needed to free _hwSurface in destructor
bool _displayDisabled;
bool _screenIsLocked;
@@ -308,10 +298,6 @@ protected:
int _numDirtyRects;
struct MousePos {
- // The mouse position, using either virtual (game) or real
- // (overlay) coordinates.
- int16 x, y;
-
// The size and hotspot of the original cursor image.
int16 w, h;
int16 hotX, hotY;
@@ -326,14 +312,13 @@ protected:
int16 vW, vH;
int16 vHotX, vHotY;
- MousePos() : x(0), y(0), w(0), h(0), hotX(0), hotY(0),
+ MousePos() : w(0), h(0), hotX(0), hotY(0),
rW(0), rH(0), rHotX(0), rHotY(0), vW(0), vH(0),
vHotX(0), vHotY(0)
{ }
};
bool _mouseVisible;
- bool _mouseNeedsRedraw;
byte *_mouseData;
SDL_Rect _mouseBackup;
MousePos _mouseCurState;
@@ -386,21 +371,45 @@ protected:
virtual void unloadGFXMode();
virtual bool hotswapGFXMode();
- virtual void setFullscreenMode(bool enable);
virtual void setAspectRatioCorrection(bool enable);
#if SDL_VERSION_ATLEAST(2, 0, 0)
- virtual void setFilteringMode(bool enable);
+ void setFilteringMode(bool enable);
#endif
- virtual int effectiveScreenHeight() const;
-
+ virtual bool saveScreenshot(const char *filename);
virtual void setGraphicsModeIntern();
- virtual bool handleScalerHotkeys(Common::KeyCode key);
- virtual bool isScalerHotkey(const Common::Event &event);
- virtual void setMousePos(int x, int y);
- virtual void toggleFullScreen();
- virtual bool saveScreenshot(const char *filename);
+private:
+ void setFullscreenMode(bool enable);
+ bool handleScalerHotkeys(Common::KeyCode key);
+ bool isScalerHotkey(const Common::Event &event);
+ void toggleFullScreen();
+
+ /**
+ * Converts the given point from the overlay's coordinate space to the
+ * game's coordinate space.
+ */
+ Common::Point convertOverlayToGame(const int x, const int y) const {
+ if (getOverlayWidth() == 0 || getOverlayHeight() == 0) {
+ error("convertOverlayToGame called without a valid overlay");
+ }
+
+ return Common::Point(x * getWidth() / getOverlayWidth(),
+ y * getHeight() / getOverlayHeight());
+ }
+
+ /**
+ * Converts the given point from the game's coordinate space to the
+ * overlay's coordinate space.
+ */
+ Common::Point convertGameToOverlay(const int x, const int y) const {
+ if (getWidth() == 0 || getHeight() == 0) {
+ error("convertGameToOverlay called without a valid overlay");
+ }
+
+ return Common::Point(x * getOverlayWidth() / getWidth(),
+ y * getOverlayHeight() / getHeight());
+ }
};
#endif
diff --git a/backends/graphics/windowed.h b/backends/graphics/windowed.h
new file mode 100644
index 0000000000..b3e5b832b3
--- /dev/null
+++ b/backends/graphics/windowed.h
@@ -0,0 +1,313 @@
+/* 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 BACKENDS_GRAPHICS_WINDOWED_H
+#define BACKENDS_GRAPHICS_WINDOWED_H
+
+#include "backends/graphics/graphics.h"
+#include "common/frac.h"
+#include "common/rect.h"
+#include "common/textconsole.h"
+#include "graphics/scaler/aspect.h"
+
+class WindowedGraphicsManager : virtual public GraphicsManager {
+public:
+ WindowedGraphicsManager() :
+ _windowWidth(0),
+ _windowHeight(0),
+ _overlayVisible(false),
+ _forceRedraw(false),
+ _cursorX(0),
+ _cursorY(0),
+ _cursorNeedsRedraw(false) {}
+
+ virtual void showOverlay() override {
+ if (_overlayVisible)
+ return;
+
+ _activeArea.drawRect = _overlayDrawRect;
+ _activeArea.width = getOverlayWidth();
+ _activeArea.height = getOverlayHeight();
+ _overlayVisible = true;
+ _forceRedraw = true;
+ }
+
+ virtual void hideOverlay() override {
+ if (!_overlayVisible)
+ return;
+
+ _activeArea.drawRect = _gameDrawRect;
+ _activeArea.width = getWidth();
+ _activeArea.height = getHeight();
+ _overlayVisible = false;
+ _forceRedraw = true;
+ }
+
+protected:
+ /**
+ * @returns whether or not the game screen must have aspect ratio correction
+ * applied for correct rendering.
+ */
+ virtual bool gameNeedsAspectRatioCorrection() const = 0;
+
+ /**
+ * Backend-specific implementation for updating internal surfaces that need
+ * to reflect the new window size.
+ */
+ virtual void handleResizeImpl(const int width, const int height) = 0;
+
+ /**
+ * Converts the given point from the active virtual screen's coordinate
+ * space to the window's coordinate space (i.e. game-to-window or
+ * overlay-to-window).
+ */
+ Common::Point convertVirtualToWindow(const int x, const int y) const {
+ const int targetX = _activeArea.drawRect.left;
+ const int targetY = _activeArea.drawRect.top;
+ const int targetWidth = _activeArea.drawRect.width();
+ const int targetHeight = _activeArea.drawRect.height();
+ const int sourceWidth = _activeArea.width;
+ const int sourceHeight = _activeArea.height;
+
+ if (sourceWidth == 0 || sourceHeight == 0) {
+ error("convertVirtualToWindow called without a valid draw rect");
+ }
+
+ return Common::Point(targetX + x * targetWidth / sourceWidth,
+ targetY + y * targetHeight / sourceHeight);
+ }
+
+ /**
+ * Converts the given point from the window's coordinate space to the
+ * active virtual screen's coordinate space (i.e. window-to-game or
+ * window-to-overlay).
+ */
+ Common::Point convertWindowToVirtual(int x, int y) const {
+ const int sourceX = _activeArea.drawRect.left;
+ const int sourceY = _activeArea.drawRect.top;
+ const int sourceMaxX = _activeArea.drawRect.right - 1;
+ const int sourceMaxY = _activeArea.drawRect.bottom - 1;
+ const int sourceWidth = _activeArea.drawRect.width();
+ const int sourceHeight = _activeArea.drawRect.height();
+ const int targetWidth = _activeArea.width;
+ const int targetHeight = _activeArea.height;
+
+ if (sourceWidth == 0 || sourceHeight == 0) {
+ error("convertWindowToVirtual called without a valid draw rect");
+ }
+
+ x = CLIP<int>(x, sourceX, sourceMaxX);
+ y = CLIP<int>(y, sourceY, sourceMaxY);
+
+ return Common::Point(((x - sourceX) * targetWidth) / sourceWidth,
+ ((y - sourceY) * targetHeight) / sourceHeight);
+ }
+
+ /**
+ * @returns the desired aspect ratio of the game surface.
+ */
+ frac_t getDesiredGameAspectRatio() const {
+ if (getHeight() == 0 || gameNeedsAspectRatioCorrection()) {
+ return intToFrac(4) / 3;
+ }
+
+ return intToFrac(getWidth()) / getHeight();
+ }
+
+ /**
+ * Called after the window has been updated with new dimensions.
+ *
+ * @param width The new width of the window, excluding window decoration.
+ * @param height The new height of the window, excluding window decoration.
+ */
+ void handleResize(const int width, const int height) {
+ _windowWidth = width;
+ _windowHeight = height;
+ handleResizeImpl(width, height);
+ }
+
+ /**
+ * Recalculates the display areas for the game and overlay surfaces within
+ * the window.
+ */
+ virtual void recalculateDisplayAreas() {
+ if (_windowHeight == 0) {
+ return;
+ }
+
+ const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight;
+
+ populateDisplayAreaDrawRect(getDesiredGameAspectRatio(), outputAspect, _gameDrawRect);
+
+ if (getOverlayHeight()) {
+ const frac_t overlayAspect = intToFrac(getOverlayWidth()) / getOverlayHeight();
+ populateDisplayAreaDrawRect(overlayAspect, outputAspect, _overlayDrawRect);
+ }
+
+ if (_overlayVisible) {
+ _activeArea.drawRect = _overlayDrawRect;
+ _activeArea.width = getOverlayWidth();
+ _activeArea.height = getOverlayHeight();
+ } else {
+ _activeArea.drawRect = _gameDrawRect;
+ _activeArea.width = getWidth();
+ _activeArea.height = getHeight();
+ }
+ }
+ /**
+ * Sets the position of the hardware mouse cursor in the host system,
+ * relative to the window.
+ *
+ * @param x X coordinate in window coordinates.
+ * @param y Y coordinate in window coordinates.
+ */
+ virtual void setSystemMousePosition(const int x, const int y) = 0;
+
+ /**
+ * Move ("warp") the mouse cursor to the specified position.
+ *
+ * @param x The new X position of the mouse in virtual screen coordinates.
+ * @param y The new Y position of the mouse in virtual screen coordinates.
+ */
+ void warpMouse(const int x, const int y) {
+ // Check active coordinate instead of window coordinate to avoid warping
+ // the mouse if it is still within the same virtual pixel
+ const Common::Point virtualCursor = convertWindowToVirtual(_cursorX, _cursorY);
+ if (virtualCursor.x != x || virtualCursor.y != y) {
+ // Warping the mouse in SDL generates a mouse movement event, so
+ // `setMousePosition` would be called eventually through the
+ // `notifyMousePosition` callback if we *only* set the system mouse
+ // position here. However, this can cause problems with some games.
+ // For example, the cannon script in CoMI calls to warp the mouse
+ // twice each time the cannon is reloaded, and unless we update the
+ // mouse position immediately, the second call is ignored, which
+ // causes the cannon to change its aim.
+ const Common::Point windowCursor = convertVirtualToWindow(x, y);
+ setMousePosition(windowCursor.x, windowCursor.y);
+ setSystemMousePosition(windowCursor.x, windowCursor.y);
+ }
+ }
+
+ /**
+ * Sets the position of the rendered mouse cursor in the window.
+ *
+ * @param x X coordinate in window coordinates.
+ * @param y Y coordinate in window coordinates.
+ */
+ void setMousePosition(int x, int y) {
+ if (_cursorX != x || _cursorY != y) {
+ _cursorNeedsRedraw = true;
+ }
+
+ _cursorX = x;
+ _cursorY = y;
+ }
+
+ /**
+ * The width of the window, excluding window decoration.
+ */
+ int _windowWidth;
+
+ /**
+ * The height of the window, excluding window decoration.
+ */
+ int _windowHeight;
+
+ /**
+ * Whether the overlay (i.e. launcher, including the out-of-game launcher)
+ * is visible or not.
+ */
+ bool _overlayVisible;
+
+ /**
+ * The scaled draw rectangle for the game surface within the window.
+ */
+ Common::Rect _gameDrawRect;
+
+ /**
+ * The scaled draw rectangle for the overlay (launcher) surface within the
+ * window.
+ */
+ Common::Rect _overlayDrawRect;
+
+ /**
+ * Data about the display area of a virtual screen.
+ */
+ struct DisplayArea {
+ /**
+ * The scaled area where the virtual screen is drawn within the window.
+ */
+ Common::Rect drawRect;
+
+ /**
+ * The width of the virtual screen's unscaled coordinate space.
+ */
+ int width;
+
+ /**
+ * The height of the virtual screen's unscaled coordinate space.
+ */
+ int height;
+ };
+
+ /**
+ * Display area information about the currently active virtual screen. This
+ * will be the overlay screen when the overlay is active, and the game
+ * screen otherwise.
+ */
+ DisplayArea _activeArea;
+
+ /**
+ * Whether the screen must be redrawn on the next frame.
+ */
+ bool _forceRedraw;
+
+ /**
+ * Whether the mouse cursor needs to be redrawn on the next frame.
+ */
+ bool _cursorNeedsRedraw;
+
+ /**
+ * The position of the mouse cursor, in window coordinates.
+ */
+ int _cursorX, _cursorY;
+
+private:
+ void populateDisplayAreaDrawRect(const frac_t inputAspect, const frac_t outputAspect, Common::Rect &drawRect) const {
+ int width = _windowWidth;
+ int height = _windowHeight;
+
+ // Maintain aspect ratios
+ if (outputAspect < inputAspect) {
+ height = intToFrac(width) / inputAspect;
+ } else if (outputAspect > inputAspect) {
+ width = fracToInt(height * inputAspect);
+ }
+
+ drawRect.left = (_windowWidth - width) / 2;
+ drawRect.top = (_windowHeight - height) / 2;
+ drawRect.setWidth(width);
+ drawRect.setHeight(height);
+ }
+};
+
+#endif
diff --git a/backends/platform/sdl/sdl-window.cpp b/backends/platform/sdl/sdl-window.cpp
index 16b978dca4..a550fbbd40 100644
--- a/backends/platform/sdl/sdl-window.cpp
+++ b/backends/platform/sdl/sdl-window.cpp
@@ -135,8 +135,10 @@ void SdlWindow::toggleMouseGrab() {
#else
if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) {
SDL_WM_GrabInput(SDL_GRAB_ON);
+ _inputGrabState = true;
} else {
SDL_WM_GrabInput(SDL_GRAB_OFF);
+ _inputGrabState = false;
}
#endif
}
@@ -154,13 +156,15 @@ bool SdlWindow::hasMouseFocus() const {
}
void SdlWindow::warpMouseInWindow(int x, int y) {
+ if (hasMouseFocus()) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
- if (_window && hasMouseFocus()) {
- SDL_WarpMouseInWindow(_window, x, y);
- }
+ if (_window) {
+ SDL_WarpMouseInWindow(_window, x, y);
+ }
#else
- SDL_WarpMouse(x, y);
+ SDL_WarpMouse(x, y);
#endif
+ }
}
void SdlWindow::iconifyWindow() {
diff --git a/backends/platform/sdl/sdl-window.h b/backends/platform/sdl/sdl-window.h
index fb7607be55..4f6d924411 100644
--- a/backends/platform/sdl/sdl-window.h
+++ b/backends/platform/sdl/sdl-window.h
@@ -56,7 +56,8 @@ public:
bool hasMouseFocus() const;
/**
- * Warp the mouse to the specified position in window coordinates.
+ * Warp the mouse to the specified position in window coordinates. The mouse
+ * will only be warped if the window is focused in the window manager.
*/
void warpMouseInWindow(int x, int y);
@@ -73,6 +74,11 @@ public:
*/
bool getSDLWMInformation(SDL_SysWMinfo *info) const;
+ bool mouseIsGrabbed() const { return _inputGrabState; }
+
+private:
+ bool _inputGrabState;
+
#if SDL_VERSION_ATLEAST(2, 0, 0)
public:
/**
@@ -108,7 +114,6 @@ private:
*/
int _lastX, _lastY;
- bool _inputGrabState;
Common::String _windowCaption;
#endif
};