aboutsummaryrefslogtreecommitdiff
path: root/backends/sdl
diff options
context:
space:
mode:
authorMax Horn2004-02-27 19:35:51 +0000
committerMax Horn2004-02-27 19:35:51 +0000
commit2671ca515e0d95e8fd2bc4cfe3b37271b037f17f (patch)
tree3c97251311d85b10b04732993adb63f41b7aeb36 /backends/sdl
parent751435d54f58f38d158432b9ea4700a5819148d1 (diff)
downloadscummvm-rg350-2671ca515e0d95e8fd2bc4cfe3b37271b037f17f.tar.gz
scummvm-rg350-2671ca515e0d95e8fd2bc4cfe3b37271b037f17f.tar.bz2
scummvm-rg350-2671ca515e0d95e8fd2bc4cfe3b37271b037f17f.zip
fix a recursive lock bug related to update_screen() (shouldn't have caused problems on most systems, but still was a bug); rewrite the code which switches the scaler mode to be slightly more efficient
svn-id: r13070
Diffstat (limited to 'backends/sdl')
-rw-r--r--backends/sdl/sdl-common.cpp155
-rw-r--r--backends/sdl/sdl-common.h6
-rw-r--r--backends/sdl/sdl.cpp25
3 files changed, 131 insertions, 55 deletions
diff --git a/backends/sdl/sdl-common.cpp b/backends/sdl/sdl-common.cpp
index dbc31be385..dbf7f2de9f 100644
--- a/backends/sdl/sdl-common.cpp
+++ b/backends/sdl/sdl-common.cpp
@@ -47,6 +47,34 @@
#define JOY_BUT_SPACE 4
#define JOY_BUT_F5 5
+static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
+ {"1x", "Normal (no scaling)", GFX_NORMAL},
+ {"2x", "2x", GFX_DOUBLESIZE},
+ {"3x", "3x", GFX_TRIPLESIZE},
+ {"2xsai", "2xSAI", GFX_2XSAI},
+ {"super2xsai", "Super2xSAI", GFX_SUPER2XSAI},
+ {"supereagle", "SuperEagle", GFX_SUPEREAGLE},
+ {"advmame2x", "AdvMAME2x", GFX_ADVMAME2X},
+ {"advmame3x", "AdvMAME3x", GFX_ADVMAME3X},
+ {"hq2x", "HQ2x", GFX_HQ2X},
+ {"hq3x", "HQ3x", GFX_HQ3X},
+ {"tv2x", "TV2x", GFX_TV2X},
+ {"dotmatrix", "DotMatrix", GFX_DOTMATRIX},
+ {0, 0, 0}
+};
+
+static const int s_gfxModeSwitchTable[][4] = {
+ { GFX_NORMAL, GFX_DOUBLESIZE, GFX_TRIPLESIZE, -1 },
+ { GFX_NORMAL, GFX_ADVMAME2X, GFX_ADVMAME3X, -1 },
+ { GFX_NORMAL, GFX_HQ2X, GFX_HQ3X, -1 },
+ { GFX_NORMAL, GFX_2XSAI, -1, -1 },
+ { GFX_NORMAL, GFX_SUPER2XSAI, -1, -1 },
+ { GFX_NORMAL, GFX_SUPEREAGLE, -1, -1 },
+ { GFX_NORMAL, GFX_TV2X, -1, -1 },
+ { GFX_NORMAL, GFX_DOTMATRIX, -1, -1 }
+ };
+
+
OSystem *OSystem_SDL_create() {
return OSystem_SDL_Common::create();
}
@@ -104,7 +132,7 @@ void OSystem_SDL_Common::set_timer(TimerProc callback, int timer) {
OSystem_SDL_Common::OSystem_SDL_Common()
: _screen(0), _screenWidth(0), _screenHeight(0),
_tmpscreen(0), _tmpScreenWidth(0), _overlayVisible(false),
- _cdrom(0), _modeChanged(false), _dirty_checksums(0),
+ _cdrom(0), _scaler_proc(0), _modeChanged(false), _dirty_checksums(0),
_mouseVisible(false), _mouseDrawn(false), _mouseData(0),
_mouseHotspotX(0), _mouseHotspotY(0),
_currentShakePos(0), _newShakePos(0),
@@ -668,17 +696,6 @@ bool OSystem_SDL_Common::poll_event(Event *event) {
// Ctrl-Alt-<key> will change the GFX mode
if ((b & (KBD_CTRL|KBD_ALT)) == (KBD_CTRL|KBD_ALT)) {
- static const int gfxModes[][4] = {
- { GFX_NORMAL, GFX_DOUBLESIZE, GFX_TRIPLESIZE, -1 },
- { GFX_NORMAL, GFX_ADVMAME2X, GFX_ADVMAME3X, -1 },
- { GFX_NORMAL, GFX_HQ2X, GFX_HQ3X, -1 },
- { GFX_NORMAL, GFX_2XSAI, -1, -1 },
- { GFX_NORMAL, GFX_SUPER2XSAI, -1, -1 },
- { GFX_NORMAL, GFX_SUPEREAGLE, -1, -1 },
- { GFX_NORMAL, GFX_TV2X, -1, -1 },
- { GFX_NORMAL, GFX_DOTMATRIX, -1, -1 }
- };
-
// FIXME EVIL HACK: This shouldn't be a static int, rather it
// should be a member variable. Furthermore, it shouldn't be
// set in this code, rather it should be set by load_gfx_mode().
@@ -688,8 +705,8 @@ bool OSystem_SDL_Common::poll_event(Event *event) {
// Try to figure out which gfx mode "group" we are in
// This is just a temporary hack until the proper solution
// (i.e. code in load_gfx_mode()) is in effect.
- for (int i = 0; i < ARRAYSIZE(gfxModes); i++) {
- if (gfxModes[i][1] == _mode || gfxModes[i][2] == _mode) {
+ for (int i = 0; i < ARRAYSIZE(s_gfxModeSwitchTable); i++) {
+ if (s_gfxModeSwitchTable[i][1] == _mode || s_gfxModeSwitchTable[i][2] == _mode) {
_scalerType = i;
break;
}
@@ -708,22 +725,22 @@ bool OSystem_SDL_Common::poll_event(Event *event) {
// TODO: Shall we 'wrap around' here?
if (ev.key.keysym.sym == '=' || ev.key.keysym.sym == '+' || ev.key.keysym.sym == '-') {
factor += (ev.key.keysym.sym == '-' ? -1 : +1);
- if (0 <= factor && factor < 4 && gfxModes[_scalerType][factor] >= 0) {
- setGraphicsMode(gfxModes[_scalerType][factor]);
+ if (0 <= factor && factor < 4 && s_gfxModeSwitchTable[_scalerType][factor] >= 0) {
+ setGraphicsMode(s_gfxModeSwitchTable[_scalerType][factor]);
}
break;
}
if ('1' <= ev.key.keysym.sym && ev.key.keysym.sym <= '9') {
_scalerType = ev.key.keysym.sym - '1';
- if (_scalerType >= ARRAYSIZE(gfxModes))
+ if (_scalerType >= ARRAYSIZE(s_gfxModeSwitchTable))
break;
- while (gfxModes[_scalerType][factor] < 0) {
+ while (s_gfxModeSwitchTable[_scalerType][factor] < 0) {
assert(factor > 0);
factor--;
}
- setGraphicsMode(gfxModes[_scalerType][factor]);
+ setGraphicsMode(s_gfxModeSwitchTable[_scalerType][factor]);
break;
}
}
@@ -1033,37 +1050,93 @@ void OSystem_SDL_Common::clearSoundCallback() {
SDL_CloseAudio();
}
-static const OSystem::GraphicsMode gfx_modes[] = {
- {"1x", "Normal (no scaling)", GFX_NORMAL},
- {"2x", "2x", GFX_DOUBLESIZE},
- {"3x", "3x", GFX_TRIPLESIZE},
- {"2xsai", "2xSAI", GFX_2XSAI},
- {"super2xsai", "Super2xSAI", GFX_SUPER2XSAI},
- {"supereagle", "SuperEagle", GFX_SUPEREAGLE},
- {"advmame2x", "AdvMAME2x", GFX_ADVMAME2X},
- {"advmame3x", "AdvMAME3x", GFX_ADVMAME3X},
- {"hq2x", "HQ2x", GFX_HQ2X},
- {"hq3x", "HQ3x", GFX_HQ3X},
- {"tv2x", "TV2x", GFX_TV2X},
- {"dotmatrix", "DotMatrix", GFX_DOTMATRIX},
- {0, 0, 0}
-};
-
const OSystem::GraphicsMode *OSystem_SDL_Common::getSupportedGraphicsModes() const {
- return gfx_modes;
+ return s_supportedGraphicsModes;
+}
+
+void OSystem_SDL_Common::update_screen() {
+ Common::StackLock lock(_graphicsMutex, this); // Lock the mutex until this function ends
+
+ intern_update_screen();
}
bool OSystem_SDL_Common::setGraphicsMode(int mode) {
Common::StackLock lock(_graphicsMutex, this);
- // FIXME! HACK, hard coded threshold, not good
- // Really should check the 'mode' against the list of supported
- // modes, and then decide whether to accept it.
- if (mode > 11)
+ int newScaleFactor = 1;
+ ScalerProc *newScalerProc;
+
+ switch(mode) {
+ case GFX_NORMAL:
+ newScaleFactor = 1;
+ newScalerProc = Normal1x;
+ break;
+ case GFX_DOUBLESIZE:
+ newScaleFactor = 2;
+ newScalerProc = Normal2x;
+ break;
+ case GFX_TRIPLESIZE:
+ newScaleFactor = 3;
+ newScalerProc = Normal3x;
+ break;
+
+ case GFX_2XSAI:
+ newScaleFactor = 2;
+ newScalerProc = _2xSaI;
+ break;
+ case GFX_SUPER2XSAI:
+ newScaleFactor = 2;
+ newScalerProc = Super2xSaI;
+ break;
+ case GFX_SUPEREAGLE:
+ newScaleFactor = 2;
+ newScalerProc = SuperEagle;
+ break;
+ case GFX_ADVMAME2X:
+ newScaleFactor = 2;
+ newScalerProc = AdvMame2x;
+ break;
+ case GFX_ADVMAME3X:
+ newScaleFactor = 3;
+ newScalerProc = AdvMame3x;
+ break;
+ case GFX_HQ2X:
+ newScaleFactor = 2;
+ newScalerProc = HQ2x;
+ break;
+ case GFX_HQ3X:
+ newScaleFactor = 3;
+ newScalerProc = HQ3x;
+ break;
+ case GFX_TV2X:
+ newScaleFactor = 2;
+ newScalerProc = TV2x;
+ break;
+ case GFX_DOTMATRIX:
+ newScaleFactor = 2;
+ newScalerProc = DotMatrix;
+ break;
+
+ default:
+ warning("unknown gfx mode %d", mode);
return false;
+ }
_mode = mode;
- hotswap_gfx_mode();
+
+ if (newScaleFactor != _scaleFactor) {
+ hotswap_gfx_mode();
+ } else {
+ _scaler_proc = newScalerProc;
+ _forceFull = true;
+
+ // Blit everything to the screen
+ intern_update_screen();
+
+ // Make sure that an EVENT_SCREEN_CHANGED gets sent later
+ _modeChanged = true;
+ }
+
return true;
}
diff --git a/backends/sdl/sdl-common.h b/backends/sdl/sdl-common.h
index 13ea005690..9a612d80b3 100644
--- a/backends/sdl/sdl-common.h
+++ b/backends/sdl/sdl-common.h
@@ -24,6 +24,7 @@
#include "common/stdafx.h"
#include "common/scummsys.h"
+#include "common/scaler.h"
#include "common/system.h"
#include "backends/intern.h"
@@ -45,7 +46,7 @@ public:
void move_screen(int dx, int dy, int height);
// Update the dirty areas of the screen
- void update_screen() = 0;
+ void update_screen();
// Either show or hide the mouse cursor
bool show_mouse(bool visible);
@@ -159,6 +160,7 @@ protected:
};
bool _forceFull; // Force full redraw on next update_screen
+ ScalerProc *_scaler_proc;
int _scaleFactor;
int _mode;
bool _full_screen;
@@ -233,6 +235,8 @@ protected:
void toggleMouseGrab();
+ virtual void intern_update_screen() = 0;
+
virtual void load_gfx_mode() = 0;
virtual void unload_gfx_mode() = 0;
virtual void hotswap_gfx_mode() = 0;
diff --git a/backends/sdl/sdl.cpp b/backends/sdl/sdl.cpp
index e43926ce3f..7b28f75552 100644
--- a/backends/sdl/sdl.cpp
+++ b/backends/sdl/sdl.cpp
@@ -21,7 +21,6 @@
*/
#include "sdl-common.h"
-#include "common/scaler.h"
#include "common/util.h"
class OSystem_SDL : public OSystem_SDL_Common {
@@ -29,13 +28,11 @@ public:
OSystem_SDL();
// Update the dirty areas of the screen
- void update_screen();
+ void intern_update_screen();
protected:
SDL_Surface *_hwscreen; // hardware screen
- ScalerProc *_scaler_proc;
-
virtual void load_gfx_mode();
virtual void unload_gfx_mode();
virtual bool save_screenshot(const char *filename);
@@ -49,7 +46,7 @@ OSystem_SDL_Common *OSystem_SDL_Common::create_intern() {
}
OSystem_SDL::OSystem_SDL()
- : _hwscreen(0), _scaler_proc(0)
+ : _hwscreen(0)
{
}
@@ -136,7 +133,7 @@ void OSystem_SDL::load_gfx_mode() {
// FIXME: We should be able to continue the game without
// shutting down or bringing up the debug console, but at
// this point we've already screwed up all our member vars.
- // We need to find a way to call SDL_VideoModeOK *before*
+ // We need to find a way to call SDL_SetVideoMode *before*
// that happens and revert to all the old settings if we
// can't pull off the switch to the new settings.
//
@@ -225,17 +222,15 @@ void OSystem_SDL::hotswap_gfx_mode() {
SDL_FreeSurface(old_tmpscreen);
// Blit everything to the screen
- update_screen();
+ intern_update_screen();
// Make sure that an EVENT_SCREEN_CHANGED gets sent later
_modeChanged = true;
}
-void OSystem_SDL::update_screen() {
+void OSystem_SDL::intern_update_screen() {
assert(_hwscreen != NULL);
- Common::StackLock lock(_graphicsMutex, this); // Lock the mutex until this function ends
-
// If the shake position changed, fill the dirty area with blackness
if (_currentShakePos != _newShakePos) {
SDL_Rect blackrect = {0, 0, _screenWidth * _scaleFactor, _newShakePos * _scaleFactor};
@@ -374,15 +369,19 @@ void OSystem_SDL::setFullscreenMode(bool enable) {
if (_full_screen != enable) {
assert(_hwscreen != 0);
_full_screen ^= true;
-#ifdef MACOSX
+#if defined(MACOSX) && !SDL_VERSION_ATLEAST(1, 2, 6)
// On OS X, SDL_WM_ToggleFullScreen is currently not implemented. Worse,
- // it still always returns -1. So we simply don't call it at all and
- // use hotswap_gfx_mode() directly to switch to fullscreen mode.
+ // before SDL 1.2.6 it always returned -1 (which would indicate a
+ // successful switch). So we simply don't call it at all and use
+ // hotswap_gfx_mode() directly to switch to fullscreen mode.
hotswap_gfx_mode();
#else
if (!SDL_WM_ToggleFullScreen(_hwscreen)) {
// if ToggleFullScreen fails, achieve the same effect with hotswap gfx mode
hotswap_gfx_mode();
+ } else {
+ // Make sure that an EVENT_SCREEN_CHANGED gets sent later
+ _modeChanged = true;
}
#endif
}