aboutsummaryrefslogtreecommitdiff
path: root/backends/graphics/surfacesdl
diff options
context:
space:
mode:
Diffstat (limited to 'backends/graphics/surfacesdl')
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp125
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.h16
2 files changed, 126 insertions, 15 deletions
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 7f3c99fcea..9cb14525ee 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -116,13 +116,19 @@ static AspectRatio getDesiredAspectRatio() {
}
#endif
-SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource)
+SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window)
:
- SdlGraphicsManager(sdlEventSource),
+ SdlGraphicsManager(sdlEventSource, window),
#ifdef USE_OSD
_osdSurface(0), _osdAlpha(SDL_ALPHA_TRANSPARENT), _osdFadeStartTime(0),
#endif
- _hwscreen(0), _screen(0), _tmpscreen(0),
+ _hwscreen(0),
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ _renderer(nullptr), _screenTexture(nullptr),
+#else
+ _originalBitsPerPixel(0),
+#endif
+ _screen(0), _tmpscreen(0),
#ifdef USE_RGB_COLOR
_screenFormat(Graphics::PixelFormat::createFormatCLUT8()),
_cursorFormat(Graphics::PixelFormat::createFormatCLUT8()),
@@ -235,7 +241,7 @@ void SurfaceSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable)
break;
case OSystem::kFeatureIconifyWindow:
if (enable)
- SDL_WM_IconifyWindow();
+ _window->iconifyWindow();
break;
default:
break;
@@ -681,12 +687,22 @@ static void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &w
const int w = width;
const int h = height;
+ int bestW = 0, bestH = 0;
+ uint bestMetric = (uint)-1; // Metric is wasted space
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ const int numModes = SDL_GetNumDisplayModes(0);
+ SDL_DisplayMode modeData, *mode = &modeData;
+ for (int i = 0; i < numModes; ++i) {
+ if (SDL_GetDisplayMode(0, i, &modeData)) {
+ continue;
+ }
+#else
SDL_Rect const* const*availableModes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_SWSURFACE); //TODO : Maybe specify a pixel format
assert(availableModes);
- const SDL_Rect *bestMode = NULL;
- uint bestMetric = (uint)-1; // Metric is wasted space
while (const SDL_Rect *mode = *availableModes++) {
+#endif
if (mode->w < w)
continue;
if (mode->h < h)
@@ -699,15 +715,23 @@ static void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &w
continue;
bestMetric = metric;
- bestMode = mode;
+ bestW = mode->w;
+ bestH = mode->h;
+
+ // Make editors a bit more happy by having the same amount of closing as
+ // opening curley braces.
+#if SDL_VERSION_ATLEAST(2, 0, 0)
}
+#else
+ }
+#endif
- if (!bestMode) {
+ if (!bestW || !bestH) {
warning("Unable to enforce the desired aspect ratio");
return;
}
- width = bestMode->w;
- height = bestMode->h;
+ width = bestW;
+ height = bestH;
}
bool SurfaceSdlGraphicsManager::loadGFXMode() {
@@ -774,7 +798,15 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
_hwscreen = g_eventRec.getSurface(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
} else
#endif
- {
+ {
+ // Save the original bpp to be able to restore the video mode on unload
+#if !SDL_VERSION_ATLEAST(2, 0, 0)
+ if (_originalBitsPerPixel == 0) {
+ const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
+ _originalBitsPerPixel = videoInfo->vfmt->BitsPerPixel;
+ }
+#endif
+
_hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16,
_videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
);
@@ -876,6 +908,10 @@ void SurfaceSdlGraphicsManager::unloadGFXMode() {
_screen = NULL;
}
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ deinitializeRenderer();
+#endif
+
if (_hwscreen) {
SDL_FreeSurface(_hwscreen);
_hwscreen = NULL;
@@ -903,6 +939,13 @@ void SurfaceSdlGraphicsManager::unloadGFXMode() {
}
#endif
DestroyScalers();
+
+#if !SDL_VERSION_ATLEAST(2, 0, 0)
+ // Reset video mode to original
+ // This will ensure that any new graphic manager will use the initial BPP when listing available modes
+ if (_originalBitsPerPixel != 0)
+ SDL_SetVideoMode(_videoMode.screenWidth, _videoMode.screenHeight, _originalBitsPerPixel, _videoMode.fullscreen ? (SDL_FULLSCREEN | SDL_SWSURFACE) : SDL_SWSURFACE);
+#endif
}
bool SurfaceSdlGraphicsManager::hotswapGFXMode() {
@@ -1443,6 +1486,9 @@ void SurfaceSdlGraphicsManager::setPalette(const byte *colors, uint start, uint
base[i].r = b[0];
base[i].g = b[1];
base[i].b = b[2];
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ base[i].a = 255;
+#endif
}
if (start < _paletteDirtyStart)
@@ -1481,6 +1527,9 @@ void SurfaceSdlGraphicsManager::setCursorPalette(const byte *colors, uint start,
base[i].r = b[0];
base[i].g = b[1];
base[i].b = b[2];
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ base[i].a = 255;
+#endif
}
_cursorPaletteDisabled = false;
@@ -1710,7 +1759,7 @@ void SurfaceSdlGraphicsManager::warpMouse(int x, int y) {
int y1 = y;
// Don't change actual mouse position, when mouse is outside of our window (in case of windowed mode)
- if (!(SDL_GetAppState( ) & SDL_APPMOUSEFOCUS)) {
+ if (!_window->hasMouseFocus()) {
setMousePos(x, y); // but change game cursor position
return;
}
@@ -1720,9 +1769,9 @@ void SurfaceSdlGraphicsManager::warpMouse(int x, int y) {
if (_mouseCurState.x != x || _mouseCurState.y != y) {
if (!_overlayVisible)
- SDL_WarpMouse(x * _videoMode.scaleFactor, y1 * _videoMode.scaleFactor);
+ _window->warpMouseInWindow(x * _videoMode.scaleFactor, y1 * _videoMode.scaleFactor);
else
- SDL_WarpMouse(x, y1);
+ _window->warpMouseInWindow(x, y1);
// SDL_WarpMouse() generates a mouse movement event, so
// setMousePos() would be called eventually. However, the
@@ -2317,4 +2366,52 @@ void SurfaceSdlGraphicsManager::notifyMousePos(Common::Point mouse) {
setMousePos(mouse.x, mouse.y);
}
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+void SurfaceSdlGraphicsManager::deinitializeRenderer() {
+ SDL_DestroyTexture(_screenTexture);
+ _screenTexture = nullptr;
+
+ SDL_DestroyRenderer(_renderer);
+ _renderer = nullptr;
+
+ _window->destroyWindow();
+}
+
+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)) {
+ return nullptr;
+ }
+
+ _renderer = SDL_CreateRenderer(_window->getSDLWindow(), -1, 0);
+ if (!_renderer) {
+ deinitializeRenderer();
+ return nullptr;
+ }
+
+ _screenTexture = SDL_CreateTexture(_renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height);
+ if (!_screenTexture) {
+ deinitializeRenderer();
+ return nullptr;
+ }
+
+ SDL_Surface *screen = SDL_CreateRGBSurface(0, width, height, 16, 0xF800, 0x7E0, 0x1F, 0);
+ if (!screen) {
+ deinitializeRenderer();
+ return nullptr;
+ } else {
+ return screen;
+ }
+}
+
+void SurfaceSdlGraphicsManager::SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects) {
+ SDL_UpdateTexture(_screenTexture, nullptr, screen->pixels, screen->pitch);
+
+ SDL_RenderClear(_renderer);
+ SDL_RenderCopy(_renderer, _screenTexture, NULL, NULL);
+ SDL_RenderPresent(_renderer);
+}
+#endif // SDL_VERSION_ATLEAST(2, 0, 0)
+
#endif
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 49bd66b3e5..2431ce8664 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -77,7 +77,7 @@ public:
*/
class SurfaceSdlGraphicsManager : public SdlGraphicsManager, public Common::EventObserver {
public:
- SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource);
+ SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
virtual ~SurfaceSdlGraphicsManager();
virtual void activateManager();
@@ -166,6 +166,17 @@ protected:
/** Hardware screen */
SDL_Surface *_hwscreen;
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ /* SDL2 features a different API for 2D graphics. We create a wrapper
+ * around this API to keep the code paths as close as possible. */
+ SDL_Renderer *_renderer;
+ SDL_Texture *_screenTexture;
+ void deinitializeRenderer();
+
+ SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
+ void SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects);
+#endif
+
/** Unseen game screen */
SDL_Surface *_screen;
#ifdef USE_RGB_COLOR
@@ -225,6 +236,9 @@ protected:
};
VideoState _videoMode, _oldVideoMode;
+ // Original BPP to restore the video mode on unload
+ uint8 _originalBitsPerPixel;
+
/** Force full redraw on next updateScreen */
bool _forceFull;