diff options
author | Max Horn | 2004-02-27 19:35:51 +0000 |
---|---|---|
committer | Max Horn | 2004-02-27 19:35:51 +0000 |
commit | 2671ca515e0d95e8fd2bc4cfe3b37271b037f17f (patch) | |
tree | 3c97251311d85b10b04732993adb63f41b7aeb36 | |
parent | 751435d54f58f38d158432b9ea4700a5819148d1 (diff) | |
download | scummvm-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
-rw-r--r-- | backends/sdl/sdl-common.cpp | 155 | ||||
-rw-r--r-- | backends/sdl/sdl-common.h | 6 | ||||
-rw-r--r-- | backends/sdl/sdl.cpp | 25 |
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 } |