aboutsummaryrefslogtreecommitdiff
path: root/backends/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'backends/graphics')
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp41
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.h2
2 files changed, 42 insertions, 1 deletions
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 9cb14525ee..e45773e5d7 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -125,6 +125,7 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
_hwscreen(0),
#if SDL_VERSION_ATLEAST(2, 0, 0)
_renderer(nullptr), _screenTexture(nullptr),
+ _viewportX(0), _viewportY(0), _mouseScaleX(1.0f), _mouseScaleY(1.0f),
#else
_originalBitsPerPixel(0),
#endif
@@ -2353,6 +2354,16 @@ 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);
+#endif
+
if (!_overlayVisible) {
point.x /= _videoMode.scaleFactor;
point.y /= _videoMode.scaleFactor;
@@ -2380,7 +2391,8 @@ void SurfaceSdlGraphicsManager::deinitializeRenderer() {
SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) {
deinitializeRenderer();
- if (!_window->createWindow(width, height, (flags & SDL_FULLSCREEN) ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)) {
+ const bool isFullscreen = (flags & SDL_FULLSCREEN) != 0;
+ if (!_window->createWindow(width, height, isFullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)) {
return nullptr;
}
@@ -2390,6 +2402,33 @@ 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;
+ }
+
+ // 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.
+ float scaleX = 0, scaleY = 0;
+ SDL_RenderGetScale(_renderer, &scaleX, &scaleY);
+ int windowWidth = 1, windowHeight = 1;
+ SDL_GetWindowSize(_window->getSDLWindow(), &windowWidth, &windowHeight);
+
+ _mouseScaleX = (width * scaleX) / windowWidth;
+ _mouseScaleY = (height * scaleY) / windowHeight;
+
+ // 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;
+
_screenTexture = SDL_CreateTexture(_renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height);
if (!_screenTexture) {
deinitializeRenderer();
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 2431ce8664..07ff4e5926 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -171,6 +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 _mouseScaleX, _mouseScaleY;
void deinitializeRenderer();
SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);