aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp8
-rw-r--r--backends/graphics/opengl/opengl-graphics.h5
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.cpp28
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp5
-rw-r--r--backends/platform/sdl/sdl.cpp58
-rw-r--r--backends/timer/default/default-timer.cpp17
6 files changed, 97 insertions, 24 deletions
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 57c2378649..40ef17e477 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -1245,12 +1245,16 @@ void OpenGLGraphicsManager::toggleAntialiasing() {
_transactionDetails.filterChanged = true;
}
-uint OpenGLGraphicsManager::getAspectRatio() {
+uint OpenGLGraphicsManager::getAspectRatio() const {
// In case we enable aspect ratio correction we force a 4/3 ratio.
+ // But just for 320x200 and 640x400 games, since other games do not need
+ // this.
// TODO: This makes OpenGL Normal behave like OpenGL Conserve, when aspect
// ratio correction is enabled, but it's better than the previous 4/3 mode
// mess at least...
- if (_videoMode.aspectRatioCorrection)
+ if (_videoMode.aspectRatioCorrection
+ && ((_videoMode.screenWidth == 320 && _videoMode.screenHeight == 200)
+ || (_videoMode.screenWidth == 640 && _videoMode.screenHeight == 400)))
return 13333;
else if (_videoMode.mode == OpenGL::GFX_NORMAL)
return _videoMode.hardwareWidth * 10000 / _videoMode.hardwareHeight;
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 8a110b2d5f..42cfbacc85 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -214,10 +214,7 @@ protected:
virtual void calculateDisplaySize(int &width, int &height);
virtual void refreshDisplaySize();
- /**
- * Returns the current target aspect ratio x 10000
- */
- virtual uint getAspectRatio();
+ uint getAspectRatio() const;
bool _formatBGR;
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 8ea95768df..84515732fe 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -313,14 +313,17 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() {
_videoMode.overlayWidth = _videoMode.hardwareWidth = _videoMode.screenWidth * scaleFactor;
_videoMode.overlayHeight = _videoMode.hardwareHeight = _videoMode.screenHeight * scaleFactor;
- int screenAspectRatio = _videoMode.screenWidth * 10000 / _videoMode.screenHeight;
- int desiredAspectRatio = getAspectRatio();
-
- // Do not downscale dimensions, only enlarge them if needed
- if (screenAspectRatio > desiredAspectRatio)
- _videoMode.hardwareHeight = (_videoMode.overlayWidth * 10000 + 5000) / desiredAspectRatio;
- else if (screenAspectRatio < desiredAspectRatio)
- _videoMode.hardwareWidth = (_videoMode.overlayHeight * desiredAspectRatio + 5000) / 10000;
+ // The only modes where we need to adapt the aspect ratio are 320x200
+ // and 640x400. That is since our aspect ratio correction in fact is
+ // only used to ensure that the original pixel size aspect for these
+ // modes is used.
+ // (Non-square pixels on old monitors vs square pixel on new ones).
+ if (_videoMode.aspectRatioCorrection
+ && ((_videoMode.screenWidth == 320 && _videoMode.screenHeight == 200)
+ || (_videoMode.screenWidth == 640 && _videoMode.screenHeight == 400)))
+ _videoMode.overlayHeight = _videoMode.hardwareHeight = 240 * scaleFactor;
+ else
+ _videoMode.overlayHeight = _videoMode.hardwareHeight = _videoMode.screenHeight * scaleFactor;
}
_screenResized = false;
@@ -640,10 +643,7 @@ void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height)
_videoMode.hardwareWidth = width;
_videoMode.hardwareHeight = height;
- if (_videoMode.mode != OpenGL::GFX_ORIGINAL) {
- _screenResized = true;
- calculateDisplaySize(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
- }
+ _screenResized = true;
int scale = MIN(_videoMode.hardwareWidth / _videoMode.screenWidth,
_videoMode.hardwareHeight / _videoMode.screenHeight);
@@ -653,10 +653,6 @@ void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height)
setScale(MAX(MIN(scale, 3), 1));
}
- if (_videoMode.mode == OpenGL::GFX_ORIGINAL) {
- calculateDisplaySize(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
- }
-
_transactionDetails.sizeChanged = true;
endGFXTransaction();
#ifdef USE_OSD
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 81c439e7e2..146200148a 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -249,7 +249,10 @@ void SurfaceSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable)
}
bool SurfaceSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
- assert(_transactionMode == kTransactionNone);
+ // We need to allow this to be called from within a transaction, since we
+ // currently use it to retreive the graphics state, when switching from
+ // SDL->OpenGL mode for example.
+ //assert(_transactionMode == kTransactionNone);
switch (f) {
case OSystem::kFeatureFullscreenMode:
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index 63871f5034..8dff5cec05 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -49,6 +49,7 @@
#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"
@@ -524,6 +525,22 @@ bool OSystem_SDL::setGraphicsMode(int mode) {
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) {
@@ -535,16 +552,55 @@ bool OSystem_SDL::setGraphicsMode(int mode) {
_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(_eventSource);
((OpenGLSdlGraphicsManager *)_graphicsManager)->initEventObserver();
_graphicsManager->beginGFXTransaction();
+
+ switchedManager = true;
}
_graphicsMode = mode;
- return _graphicsManager->setGraphicsMode(srcMode->id);
+
+ 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++;
diff --git a/backends/timer/default/default-timer.cpp b/backends/timer/default/default-timer.cpp
index efb3ec9ad9..e1aadb62b8 100644
--- a/backends/timer/default/default-timer.cpp
+++ b/backends/timer/default/default-timer.cpp
@@ -161,4 +161,21 @@ void DefaultTimerManager::removeTimerProc(TimerProc callback) {
slot = slot->next;
}
}
+
+ // We need to remove all names referencing the timer proc here.
+ //
+ // Else we run into troubles, when the client code removes and readds timer
+ // callbacks.
+ //
+ // Another issues occurs when one plays a game with ALSA as music driver,
+ // does RTL and starts a different engine game with ALSA as music driver.
+ // In this case the MPU401 code will add different timer procs with the
+ // same name, resulting in two different callbacks added with the same
+ // name and causing installTimerProc to error out.
+ // A good test case is running a SCUMM with ALSA output and then a KYRA
+ // game for example.
+ for (TimerSlotMap::iterator i = _callbacks.begin(), end = _callbacks.end(); i != end; ++i) {
+ if (i->_value == callback)
+ _callbacks.erase(i);
+ }
}