diff options
Diffstat (limited to 'backends/platform/sdl')
-rw-r--r-- | backends/platform/sdl/sdl.cpp | 231 | ||||
-rw-r--r-- | backends/platform/sdl/sdl.h | 19 |
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 |