aboutsummaryrefslogtreecommitdiff
path: root/backends/graphics/surfacesdl
diff options
context:
space:
mode:
authorJohannes Schickel2015-12-13 20:20:23 +0100
committerJohannes Schickel2015-12-13 21:30:25 +0100
commit5d48e211aa76a64c438457350a25f365cbdfdcd7 (patch)
treeaf0f04365ab50f6789b81b0b5e8499edd15d3242 /backends/graphics/surfacesdl
parent942d0fdad46d2105f1606ddea8cd9146acec70d8 (diff)
downloadscummvm-rg350-5d48e211aa76a64c438457350a25f365cbdfdcd7.tar.gz
scummvm-rg350-5d48e211aa76a64c438457350a25f365cbdfdcd7.tar.bz2
scummvm-rg350-5d48e211aa76a64c438457350a25f365cbdfdcd7.zip
SDL: Fix mouse emulation with SDL2.
The mouse emulation via keyboard (or other means) was broken with 079037b73990b6107e59c7f1cd971c3a1cc221d1.
Diffstat (limited to 'backends/graphics/surfacesdl')
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp74
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.h5
2 files changed, 43 insertions, 36 deletions
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 7d666bdbfa..b2da47110b 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -32,6 +32,7 @@
#include "common/textconsole.h"
#include "common/translation.h"
#include "common/util.h"
+#include "common/frac.h"
#ifdef USE_RGB_COLOR
#include "common/list.h"
#endif
@@ -125,7 +126,7 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
_hwscreen(0),
#if SDL_VERSION_ATLEAST(2, 0, 0)
_renderer(nullptr), _screenTexture(nullptr),
- _viewportX(0), _viewportY(0), _renderScaleX(1.0f), _renderScaleY(1.0f), _mouseScaleX(1.0f), _mouseScaleY(1.0f),
+ _viewport(), _windowWidth(1), _windowHeight(1),
#else
_originalBitsPerPixel(0),
#endif
@@ -890,9 +891,14 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
SDL_SetColorKey(_osdSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kOSDColorKey);
#endif
+#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->resetKeyboadEmulation(
_videoMode.screenWidth * _videoMode.scaleFactor - 1,
effectiveScreenHeight() - 1);
+#endif
// Distinguish 555 and 565 mode
if (_hwscreen->format->Rmask == 0x7C00)
@@ -1774,8 +1780,10 @@ void SurfaceSdlGraphicsManager::warpMouse(int x, int y) {
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
- x1 = (int)((x1 + _viewportX) * _renderScaleX);
- y1 = (int)((y1 + _viewportY) * _renderScaleY);
+ // 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);
@@ -2361,13 +2369,13 @@ void SurfaceSdlGraphicsManager::notifyVideoExpose() {
void SurfaceSdlGraphicsManager::transformMouseCoordinates(Common::Point &point) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
- // In fullscreen mode we can easily get coordinates outside the actual
- // screen area. For example, if black bars are added left/right we can end
- // up with negative x coordinates if the user moves the mouse inside the
- // black bar. Here, we post process the received cooridnates to give the
- // user the feeling the black bars do not exist.
- point.x = (int)((point.x + _viewportX) * _mouseScaleX);
- point.y = (int)((point.y + _viewportY) * _mouseScaleY);
+ // 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) {
@@ -2408,31 +2416,31 @@ SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height,
return nullptr;
}
- // We set the logical renderer size to the requested resolution in
- // fullscreen. This assures that SDL2 adds black bars if needed to prevent
- // stretching.
- if (isFullscreen && SDL_RenderSetLogicalSize(_renderer, width, height) < 0) {
- deinitializeRenderer();
- return nullptr;
- }
+ SDL_GetWindowSize(_window->getSDLWindow(), &_windowWidth, &_windowHeight);
+ // We expect full screen resolution as inputs coming from the event system.
+ _eventSource->resetKeyboadEmulation(_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(width) / height;
- // To provide smooth mouse handling in case black borders are added, we
- // obtain the actual window size and the internal renderer scaling.
- // Based on this we calculate scale factors to scale received mouse
- // coordinates into actual screen area coordinates.
- SDL_RenderGetScale(_renderer, &_renderScaleX, &_renderScaleY);
- int windowWidth = 1, windowHeight = 1;
- SDL_GetWindowSize(_window->getSDLWindow(), &windowWidth, &windowHeight);
+ _viewport.w = _windowWidth;
+ _viewport.h = _windowHeight;
- _mouseScaleX = (width * _renderScaleX) / windowWidth;
- _mouseScaleY = (height * _renderScaleY) / windowHeight;
+ // Adjust one dimension for mantaining the aspect ratio.
+ if (abs(outputAspect - desiredAspect) >= (int)(FRAC_ONE / 1000)) {
+ if (outputAspect < desiredAspect) {
+ _viewport.h = height * _windowWidth / width;
+ } else if (outputAspect > desiredAspect) {
+ _viewport.w = width * _windowHeight / height;
+ }
+ }
- // Obtain viewport top left coordinates to transform received coordinates
- // into visible area coordinates (i.e. including black borders).
- SDL_Rect viewport;
- SDL_RenderGetViewport(_renderer, &viewport);
- _viewportX = viewport.x;
- _viewportY = viewport.y;
+ _viewport.x = (_windowWidth - _viewport.w) / 2;
+ _viewport.y = (_windowHeight - _viewport.h) / 2;
_screenTexture = SDL_CreateTexture(_renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height);
if (!_screenTexture) {
@@ -2453,7 +2461,7 @@ void SurfaceSdlGraphicsManager::SDL_UpdateRects(SDL_Surface *screen, int numrect
SDL_UpdateTexture(_screenTexture, nullptr, screen->pixels, screen->pitch);
SDL_RenderClear(_renderer);
- SDL_RenderCopy(_renderer, _screenTexture, NULL, NULL);
+ 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 4d74ec575b..ac9844c849 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -171,9 +171,8 @@ protected:
* around this API to keep the code paths as close as possible. */
SDL_Renderer *_renderer;
SDL_Texture *_screenTexture;
- int _viewportX, _viewportY;
- float _renderScaleX, _renderScaleY;
- float _mouseScaleX, _mouseScaleY;
+ SDL_Rect _viewport;
+ int _windowWidth, _windowHeight;
void deinitializeRenderer();
SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);