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
This commit is contained in:
parent
751435d54f
commit
2671ca515e
3 changed files with 131 additions and 55 deletions
|
@ -47,6 +47,34 @@
|
||||||
#define JOY_BUT_SPACE 4
|
#define JOY_BUT_SPACE 4
|
||||||
#define JOY_BUT_F5 5
|
#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() {
|
OSystem *OSystem_SDL_create() {
|
||||||
return OSystem_SDL_Common::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()
|
OSystem_SDL_Common::OSystem_SDL_Common()
|
||||||
: _screen(0), _screenWidth(0), _screenHeight(0),
|
: _screen(0), _screenWidth(0), _screenHeight(0),
|
||||||
_tmpscreen(0), _tmpScreenWidth(0), _overlayVisible(false),
|
_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),
|
_mouseVisible(false), _mouseDrawn(false), _mouseData(0),
|
||||||
_mouseHotspotX(0), _mouseHotspotY(0),
|
_mouseHotspotX(0), _mouseHotspotY(0),
|
||||||
_currentShakePos(0), _newShakePos(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
|
// Ctrl-Alt-<key> will change the GFX mode
|
||||||
if ((b & (KBD_CTRL|KBD_ALT)) == (KBD_CTRL|KBD_ALT)) {
|
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
|
// FIXME EVIL HACK: This shouldn't be a static int, rather it
|
||||||
// should be a member variable. Furthermore, it shouldn't be
|
// should be a member variable. Furthermore, it shouldn't be
|
||||||
// set in this code, rather it should be set by load_gfx_mode().
|
// 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
|
// Try to figure out which gfx mode "group" we are in
|
||||||
// This is just a temporary hack until the proper solution
|
// This is just a temporary hack until the proper solution
|
||||||
// (i.e. code in load_gfx_mode()) is in effect.
|
// (i.e. code in load_gfx_mode()) is in effect.
|
||||||
for (int i = 0; i < ARRAYSIZE(gfxModes); i++) {
|
for (int i = 0; i < ARRAYSIZE(s_gfxModeSwitchTable); i++) {
|
||||||
if (gfxModes[i][1] == _mode || gfxModes[i][2] == _mode) {
|
if (s_gfxModeSwitchTable[i][1] == _mode || s_gfxModeSwitchTable[i][2] == _mode) {
|
||||||
_scalerType = i;
|
_scalerType = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -708,22 +725,22 @@ bool OSystem_SDL_Common::poll_event(Event *event) {
|
||||||
// TODO: Shall we 'wrap around' here?
|
// TODO: Shall we 'wrap around' here?
|
||||||
if (ev.key.keysym.sym == '=' || ev.key.keysym.sym == '+' || ev.key.keysym.sym == '-') {
|
if (ev.key.keysym.sym == '=' || ev.key.keysym.sym == '+' || ev.key.keysym.sym == '-') {
|
||||||
factor += (ev.key.keysym.sym == '-' ? -1 : +1);
|
factor += (ev.key.keysym.sym == '-' ? -1 : +1);
|
||||||
if (0 <= factor && factor < 4 && gfxModes[_scalerType][factor] >= 0) {
|
if (0 <= factor && factor < 4 && s_gfxModeSwitchTable[_scalerType][factor] >= 0) {
|
||||||
setGraphicsMode(gfxModes[_scalerType][factor]);
|
setGraphicsMode(s_gfxModeSwitchTable[_scalerType][factor]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('1' <= ev.key.keysym.sym && ev.key.keysym.sym <= '9') {
|
if ('1' <= ev.key.keysym.sym && ev.key.keysym.sym <= '9') {
|
||||||
_scalerType = ev.key.keysym.sym - '1';
|
_scalerType = ev.key.keysym.sym - '1';
|
||||||
if (_scalerType >= ARRAYSIZE(gfxModes))
|
if (_scalerType >= ARRAYSIZE(s_gfxModeSwitchTable))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
while (gfxModes[_scalerType][factor] < 0) {
|
while (s_gfxModeSwitchTable[_scalerType][factor] < 0) {
|
||||||
assert(factor > 0);
|
assert(factor > 0);
|
||||||
factor--;
|
factor--;
|
||||||
}
|
}
|
||||||
setGraphicsMode(gfxModes[_scalerType][factor]);
|
setGraphicsMode(s_gfxModeSwitchTable[_scalerType][factor]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1033,37 +1050,93 @@ void OSystem_SDL_Common::clearSoundCallback() {
|
||||||
SDL_CloseAudio();
|
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 {
|
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) {
|
bool OSystem_SDL_Common::setGraphicsMode(int mode) {
|
||||||
Common::StackLock lock(_graphicsMutex, this);
|
Common::StackLock lock(_graphicsMutex, this);
|
||||||
|
|
||||||
// FIXME! HACK, hard coded threshold, not good
|
int newScaleFactor = 1;
|
||||||
// Really should check the 'mode' against the list of supported
|
ScalerProc *newScalerProc;
|
||||||
// modes, and then decide whether to accept it.
|
|
||||||
if (mode > 11)
|
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;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
|
|
||||||
|
if (newScaleFactor != _scaleFactor) {
|
||||||
hotswap_gfx_mode();
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "common/stdafx.h"
|
#include "common/stdafx.h"
|
||||||
#include "common/scummsys.h"
|
#include "common/scummsys.h"
|
||||||
|
#include "common/scaler.h"
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
#include "backends/intern.h"
|
#include "backends/intern.h"
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ public:
|
||||||
void move_screen(int dx, int dy, int height);
|
void move_screen(int dx, int dy, int height);
|
||||||
|
|
||||||
// Update the dirty areas of the screen
|
// Update the dirty areas of the screen
|
||||||
void update_screen() = 0;
|
void update_screen();
|
||||||
|
|
||||||
// Either show or hide the mouse cursor
|
// Either show or hide the mouse cursor
|
||||||
bool show_mouse(bool visible);
|
bool show_mouse(bool visible);
|
||||||
|
@ -159,6 +160,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
bool _forceFull; // Force full redraw on next update_screen
|
bool _forceFull; // Force full redraw on next update_screen
|
||||||
|
ScalerProc *_scaler_proc;
|
||||||
int _scaleFactor;
|
int _scaleFactor;
|
||||||
int _mode;
|
int _mode;
|
||||||
bool _full_screen;
|
bool _full_screen;
|
||||||
|
@ -233,6 +235,8 @@ protected:
|
||||||
void toggleMouseGrab();
|
void toggleMouseGrab();
|
||||||
|
|
||||||
|
|
||||||
|
virtual void intern_update_screen() = 0;
|
||||||
|
|
||||||
virtual void load_gfx_mode() = 0;
|
virtual void load_gfx_mode() = 0;
|
||||||
virtual void unload_gfx_mode() = 0;
|
virtual void unload_gfx_mode() = 0;
|
||||||
virtual void hotswap_gfx_mode() = 0;
|
virtual void hotswap_gfx_mode() = 0;
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sdl-common.h"
|
#include "sdl-common.h"
|
||||||
#include "common/scaler.h"
|
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
|
||||||
class OSystem_SDL : public OSystem_SDL_Common {
|
class OSystem_SDL : public OSystem_SDL_Common {
|
||||||
|
@ -29,13 +28,11 @@ public:
|
||||||
OSystem_SDL();
|
OSystem_SDL();
|
||||||
|
|
||||||
// Update the dirty areas of the screen
|
// Update the dirty areas of the screen
|
||||||
void update_screen();
|
void intern_update_screen();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SDL_Surface *_hwscreen; // hardware screen
|
SDL_Surface *_hwscreen; // hardware screen
|
||||||
|
|
||||||
ScalerProc *_scaler_proc;
|
|
||||||
|
|
||||||
virtual void load_gfx_mode();
|
virtual void load_gfx_mode();
|
||||||
virtual void unload_gfx_mode();
|
virtual void unload_gfx_mode();
|
||||||
virtual bool save_screenshot(const char *filename);
|
virtual bool save_screenshot(const char *filename);
|
||||||
|
@ -49,7 +46,7 @@ OSystem_SDL_Common *OSystem_SDL_Common::create_intern() {
|
||||||
}
|
}
|
||||||
|
|
||||||
OSystem_SDL::OSystem_SDL()
|
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
|
// FIXME: We should be able to continue the game without
|
||||||
// shutting down or bringing up the debug console, but at
|
// shutting down or bringing up the debug console, but at
|
||||||
// this point we've already screwed up all our member vars.
|
// 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
|
// that happens and revert to all the old settings if we
|
||||||
// can't pull off the switch to the new settings.
|
// can't pull off the switch to the new settings.
|
||||||
//
|
//
|
||||||
|
@ -225,17 +222,15 @@ void OSystem_SDL::hotswap_gfx_mode() {
|
||||||
SDL_FreeSurface(old_tmpscreen);
|
SDL_FreeSurface(old_tmpscreen);
|
||||||
|
|
||||||
// Blit everything to the screen
|
// Blit everything to the screen
|
||||||
update_screen();
|
intern_update_screen();
|
||||||
|
|
||||||
// Make sure that an EVENT_SCREEN_CHANGED gets sent later
|
// Make sure that an EVENT_SCREEN_CHANGED gets sent later
|
||||||
_modeChanged = true;
|
_modeChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_SDL::update_screen() {
|
void OSystem_SDL::intern_update_screen() {
|
||||||
assert(_hwscreen != NULL);
|
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 the shake position changed, fill the dirty area with blackness
|
||||||
if (_currentShakePos != _newShakePos) {
|
if (_currentShakePos != _newShakePos) {
|
||||||
SDL_Rect blackrect = {0, 0, _screenWidth * _scaleFactor, _newShakePos * _scaleFactor};
|
SDL_Rect blackrect = {0, 0, _screenWidth * _scaleFactor, _newShakePos * _scaleFactor};
|
||||||
|
@ -374,15 +369,19 @@ void OSystem_SDL::setFullscreenMode(bool enable) {
|
||||||
if (_full_screen != enable) {
|
if (_full_screen != enable) {
|
||||||
assert(_hwscreen != 0);
|
assert(_hwscreen != 0);
|
||||||
_full_screen ^= true;
|
_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,
|
// 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
|
// before SDL 1.2.6 it always returned -1 (which would indicate a
|
||||||
// use hotswap_gfx_mode() directly to switch to fullscreen mode.
|
// 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();
|
hotswap_gfx_mode();
|
||||||
#else
|
#else
|
||||||
if (!SDL_WM_ToggleFullScreen(_hwscreen)) {
|
if (!SDL_WM_ToggleFullScreen(_hwscreen)) {
|
||||||
// if ToggleFullScreen fails, achieve the same effect with hotswap gfx mode
|
// if ToggleFullScreen fails, achieve the same effect with hotswap gfx mode
|
||||||
hotswap_gfx_mode();
|
hotswap_gfx_mode();
|
||||||
|
} else {
|
||||||
|
// Make sure that an EVENT_SCREEN_CHANGED gets sent later
|
||||||
|
_modeChanged = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue