aboutsummaryrefslogtreecommitdiff
path: root/backends/platform
diff options
context:
space:
mode:
authorJohannes Schickel2013-08-18 16:56:34 +0200
committerJohannes Schickel2013-10-19 22:14:24 +0200
commit5ce830b97643fc76bdcafdbbe09e226519a9d2e6 (patch)
tree2081a1d9eff756823e3141aa019e141bb1e5f18c /backends/platform
parent46323074e77622e7d08fe20bfdcc459b8eba08a3 (diff)
downloadscummvm-rg350-5ce830b97643fc76bdcafdbbe09e226519a9d2e6.tar.gz
scummvm-rg350-5ce830b97643fc76bdcafdbbe09e226519a9d2e6.tar.bz2
scummvm-rg350-5ce830b97643fc76bdcafdbbe09e226519a9d2e6.zip
SDL: Add a OpenGL SDL backend and hook it into the SDL backend.
The hooking code is nearly exactly the old hooking code. Only the OpenGL SDL creation has been adapted since it uses a different constructor now.
Diffstat (limited to 'backends/platform')
-rw-r--r--backends/platform/sdl/sdl.cpp231
-rw-r--r--backends/platform/sdl/sdl.h19
2 files changed, 246 insertions, 4 deletions
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index 16fe88e990..1431e1fc5e 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -47,6 +47,10 @@
#include "backends/mutex/sdl/sdl-mutex.h"
#include "backends/timer/sdl/sdl-timer.h"
#include "backends/graphics/surfacesdl/surfacesdl-graphics.h"
+#ifdef USE_OPENGL
+#include "backends/graphics/openglsdl/openglsdl-graphics.h"
+#include "graphics/cursorman.h"
+#endif
#include "icons/scummvm.xpm"
@@ -60,6 +64,14 @@
OSystem_SDL::OSystem_SDL()
:
+#ifdef USE_OPENGL
+ _desktopWidth(0),
+ _desktopHeight(0),
+ _graphicsModes(0),
+ _graphicsMode(0),
+ _sdlModesCount(0),
+ _glModesCount(0),
+#endif
_inited(false),
_initedSDL(false),
_logger(0),
@@ -100,6 +112,10 @@ OSystem_SDL::~OSystem_SDL() {
delete _mutexManager;
_mutexManager = 0;
+#ifdef USE_OPENGL
+ delete[] _graphicsModes;
+#endif
+
delete _logger;
_logger = 0;
@@ -129,6 +145,11 @@ void OSystem_SDL::init() {
if (_taskbarManager == 0)
_taskbarManager = new Common::TaskbarManager();
#endif
+
+#ifdef USE_OPENGL
+ // Setup a list with both SDL and OpenGL graphics modes
+ setupGraphicsModes();
+#endif
}
void OSystem_SDL::initBackend() {
@@ -140,8 +161,46 @@ void OSystem_SDL::initBackend() {
if (_eventSource == 0)
_eventSource = new SdlEventSource();
+ int graphicsManagerType = 0;
+
+#ifdef USE_OPENGL
+ // Query the desktop resolution. We simply hope nothing tried to change
+ // the resolution so far.
+ const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
+ if (videoInfo && videoInfo->current_w > 0 && videoInfo->current_h > 0) {
+ _desktopWidth = videoInfo->current_w;
+ _desktopHeight = videoInfo->current_h;
+ }
+#endif
+
if (_graphicsManager == 0) {
- _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource);
+#ifdef USE_OPENGL
+ if (ConfMan.hasKey("gfx_mode")) {
+ Common::String gfxMode(ConfMan.get("gfx_mode"));
+ bool use_opengl = false;
+ const OSystem::GraphicsMode *mode = OpenGLSdlGraphicsManager::supportedGraphicsModes();
+ int i = 0;
+ while (mode->name) {
+ if (scumm_stricmp(mode->name, gfxMode.c_str()) == 0) {
+ _graphicsMode = i + _sdlModesCount;
+ use_opengl = true;
+ }
+
+ mode++;
+ ++i;
+ }
+
+ // If the gfx_mode is from OpenGL, create the OpenGL graphics manager
+ if (use_opengl) {
+ _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource);
+ graphicsManagerType = 1;
+ }
+ }
+#endif
+ if (_graphicsManager == 0) {
+ _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource);
+ graphicsManagerType = 0;
+ }
}
if (_savefileManager == 0)
@@ -183,7 +242,13 @@ void OSystem_SDL::initBackend() {
// so the virtual keyboard can be initialized, but we have to add the
// graphics manager as an event observer after initializing the event
// manager.
- ((SurfaceSdlGraphicsManager *)_graphicsManager)->initEventObserver();
+ if (graphicsManagerType == 0)
+ ((SurfaceSdlGraphicsManager *)_graphicsManager)->initEventObserver();
+#ifdef USE_OPENGL
+ else if (graphicsManagerType == 1)
+ ((OpenGLSdlGraphicsManager *)_graphicsManager)->initEventObserver();
+#endif
+
}
#if defined(USE_TASKBAR)
@@ -208,8 +273,9 @@ void OSystem_SDL::initSDL() {
if (ConfMan.hasKey("disable_sdl_parachute"))
sdlFlags |= SDL_INIT_NOPARACHUTE;
-#ifdef WEBOS
- // WebOS needs this flag or otherwise the application won't start
+#if defined(WEBOS) || defined(USE_OPENGL)
+ // WebOS needs this flag or otherwise the application won't start.
+ // OpenGL SDL needs this to query the desktop resolution on startup.
sdlFlags |= SDL_INIT_VIDEO;
#endif
@@ -478,3 +544,160 @@ Common::TimerManager *OSystem_SDL::getTimerManager() {
return _timerManager;
#endif
}
+
+#ifdef USE_OPENGL
+
+const OSystem::GraphicsMode *OSystem_SDL::getSupportedGraphicsModes() const {
+ return _graphicsModes;
+}
+
+int OSystem_SDL::getDefaultGraphicsMode() const {
+ // Return the default graphics mode from the current graphics manager
+ if (_graphicsMode < _sdlModesCount)
+ return _graphicsManager->getDefaultGraphicsMode();
+ else
+ return _graphicsManager->getDefaultGraphicsMode() + _sdlModesCount;
+}
+
+bool OSystem_SDL::setGraphicsMode(int mode) {
+ const OSystem::GraphicsMode *srcMode;
+ int i;
+
+ // Check if mode is from SDL or OpenGL
+ if (mode < _sdlModesCount) {
+ srcMode = SurfaceSdlGraphicsManager::supportedGraphicsModes();
+ i = 0;
+ } else {
+ srcMode = OpenGLSdlGraphicsManager::supportedGraphicsModes();
+ i = _sdlModesCount;
+ }
+
+ // Very hacky way to set up the old graphics manager state, in case we
+ // switch from SDL->OpenGL or OpenGL->SDL.
+ //
+ // This is a probably temporary workaround to fix bugs like #3368143
+ // "SDL/OpenGL: Crash when switching renderer backend".
+ const int screenWidth = _graphicsManager->getWidth();
+ const int screenHeight = _graphicsManager->getHeight();
+ const bool arState = _graphicsManager->getFeatureState(kFeatureAspectRatioCorrection);
+ const bool fullscreen = _graphicsManager->getFeatureState(kFeatureFullscreenMode);
+ const bool cursorPalette = _graphicsManager->getFeatureState(kFeatureCursorPalette);
+#ifdef USE_RGB_COLOR
+ const Graphics::PixelFormat pixelFormat = _graphicsManager->getScreenFormat();
+#endif
+
+ bool switchedManager = false;
+
+ // Loop through modes
+ while (srcMode->name) {
+ if (i == mode) {
+ // If the new mode and the current mode are not from the same graphics
+ // manager, delete and create the new mode graphics manager
+ if (_graphicsMode >= _sdlModesCount && mode < _sdlModesCount) {
+ debug(1, "switching to plain SDL graphics");
+ delete _graphicsManager;
+ _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource);
+ ((SurfaceSdlGraphicsManager *)_graphicsManager)->initEventObserver();
+ _graphicsManager->beginGFXTransaction();
+
+ switchedManager = true;
+ } else if (_graphicsMode < _sdlModesCount && mode >= _sdlModesCount) {
+ debug(1, "switching to OpenGL graphics");
+ delete _graphicsManager;
+ _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource);
+ ((OpenGLSdlGraphicsManager *)_graphicsManager)->initEventObserver();
+ _graphicsManager->beginGFXTransaction();
+
+ switchedManager = true;
+ }
+
+ _graphicsMode = mode;
+
+ if (switchedManager) {
+#ifdef USE_RGB_COLOR
+ _graphicsManager->initSize(screenWidth, screenHeight, &pixelFormat);
+#else
+ _graphicsManager->initSize(screenWidth, screenHeight, 0);
+#endif
+ _graphicsManager->setFeatureState(kFeatureAspectRatioCorrection, arState);
+ _graphicsManager->setFeatureState(kFeatureFullscreenMode, fullscreen);
+ _graphicsManager->setFeatureState(kFeatureCursorPalette, cursorPalette);
+
+ // Worst part about this right now, tell the cursor manager to
+ // resetup the cursor + cursor palette if necessarily
+
+ // First we need to try to setup the old state on the new manager...
+ if (_graphicsManager->endGFXTransaction() != kTransactionSuccess) {
+ // Oh my god if this failed the client code might just explode.
+ return false;
+ }
+
+ // Next setup the cursor again
+ CursorMan.pushCursor(0, 0, 0, 0, 0, 0);
+ CursorMan.popCursor();
+
+ // Next setup cursor palette if needed
+ if (cursorPalette) {
+ CursorMan.pushCursorPalette(0, 0, 0);
+ CursorMan.popCursorPalette();
+ }
+
+ _graphicsManager->beginGFXTransaction();
+ // Oh my god if this failed the client code might just explode.
+ return _graphicsManager->setGraphicsMode(srcMode->id);
+ } else {
+ return _graphicsManager->setGraphicsMode(srcMode->id);
+ }
+ }
+
+ i++;
+ srcMode++;
+ }
+
+ return false;
+}
+
+int OSystem_SDL::getGraphicsMode() const {
+ return _graphicsMode;
+}
+
+void OSystem_SDL::setupGraphicsModes() {
+ const OSystem::GraphicsMode *sdlGraphicsModes = SurfaceSdlGraphicsManager::supportedGraphicsModes();
+ const OSystem::GraphicsMode *openglGraphicsModes = OpenGLSdlGraphicsManager::supportedGraphicsModes();
+ _sdlModesCount = 0;
+ _glModesCount = 0;
+
+ // Count the number of graphics modes
+ const OSystem::GraphicsMode *srcMode = sdlGraphicsModes;
+ while (srcMode->name) {
+ _sdlModesCount++;
+ srcMode++;
+ }
+ srcMode = openglGraphicsModes;
+ while (srcMode->name) {
+ _glModesCount++;
+ srcMode++;
+ }
+
+ // Allocate enough space for merged array of modes
+ _graphicsModes = new OSystem::GraphicsMode[_glModesCount + _sdlModesCount + 1];
+
+ // Copy SDL graphics modes
+ memcpy((void *)_graphicsModes, sdlGraphicsModes, _sdlModesCount * sizeof(OSystem::GraphicsMode));
+
+ // Copy OpenGL graphics modes
+ memcpy((void *)(_graphicsModes + _sdlModesCount), openglGraphicsModes, _glModesCount * sizeof(OSystem::GraphicsMode));
+
+ // Set a null mode at the end
+ memset((void *)(_graphicsModes + _sdlModesCount + _glModesCount), 0, sizeof(OSystem::GraphicsMode));
+
+ // Set new internal ids for all modes
+ int i = 0;
+ OSystem::GraphicsMode *mode = _graphicsModes;
+ while (mode->name) {
+ mode->id = i++;
+ mode++;
+ }
+}
+
+#endif
diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h
index 0012e88c51..590354b699 100644
--- a/backends/platform/sdl/sdl.h
+++ b/backends/platform/sdl/sdl.h
@@ -104,6 +104,25 @@ protected:
// Logging
virtual Common::WriteStream *createLogFile() { return 0; }
Backends::Log::Log *_logger;
+
+#ifdef USE_OPENGL
+ int _desktopWidth, _desktopHeight;
+
+ OSystem::GraphicsMode *_graphicsModes;
+ int _graphicsMode;
+ int _sdlModesCount;
+ int _glModesCount;
+
+ /**
+ * Creates the merged graphics modes list
+ */
+ virtual void setupGraphicsModes();
+
+ virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
+ virtual int getDefaultGraphicsMode() const;
+ virtual bool setGraphicsMode(int mode);
+ virtual int getGraphicsMode() const;
+#endif
};
#endif