diff options
author | John Willis | 2009-02-12 09:52:31 +0000 |
---|---|---|
committer | John Willis | 2009-02-12 09:52:31 +0000 |
commit | 521cc089110501c456844a4bc5963bd6d8e4df5c (patch) | |
tree | 78ab3126b2da4db27862cee65160c4d8816d4fd7 /backends | |
parent | 5f634212aa97bd3d5b6e31b45352b5cb985ef636 (diff) | |
download | scummvm-rg350-521cc089110501c456844a4bc5963bd6d8e4df5c.tar.gz scummvm-rg350-521cc089110501c456844a4bc5963bd6d8e4df5c.tar.bz2 scummvm-rg350-521cc089110501c456844a4bc5963bd6d8e4df5c.zip |
Cleanup of the GP2X backend. It's been sat on my HDD for a while and it really should be in SVN.
svn-id: r36278
Diffstat (limited to 'backends')
-rwxr-xr-x | backends/platform/gp2x/build/bundle.sh | 3 | ||||
-rw-r--r-- | backends/platform/gp2x/events.cpp | 69 | ||||
-rw-r--r-- | backends/platform/gp2x/gp2x-common.h | 107 | ||||
-rw-r--r-- | backends/platform/gp2x/gp2x-hw.cpp | 57 | ||||
-rw-r--r-- | backends/platform/gp2x/gp2x.cpp | 248 | ||||
-rw-r--r-- | backends/platform/gp2x/graphics.cpp | 634 | ||||
-rw-r--r-- | backends/platform/gp2x/module.mk | 12 |
7 files changed, 717 insertions, 413 deletions
diff --git a/backends/platform/gp2x/build/bundle.sh b/backends/platform/gp2x/build/bundle.sh index 9824c9b451..8d48dcfb06 100755 --- a/backends/platform/gp2x/build/bundle.sh +++ b/backends/platform/gp2x/build/bundle.sh @@ -27,8 +27,7 @@ cp ../../../../README ./scummvm-gp2x-`date '+%Y-%m-%d'`/ cp ../../../../COPYING ./scummvm-gp2x-`date '+%Y-%m-%d'`/ cp ../../../../COPYRIGHT ./scummvm-gp2x-`date '+%Y-%m-%d'`/ cp ../../../../NEWS ./scummvm-gp2x-`date '+%Y-%m-%d'`/ -cp ../../../../gui/themes/modern.ini ./scummvm-gp2x-`date '+%Y-%m-%d'`/ -cp ../../../../gui/themes/modern.zip ./scummvm-gp2x-`date '+%Y-%m-%d'`/ +cp ../../../../gui/themes/scummmodern.zip ./scummvm-gp2x-`date '+%Y-%m-%d'`/ cp ../../../../dists/pred.dic ./scummvm-gp2x-`date '+%Y-%m-%d'`/ cp ../../../../dists/engine-data/* ./scummvm-gp2x-`date '+%Y-%m-%d'`/engine-data diff --git a/backends/platform/gp2x/events.cpp b/backends/platform/gp2x/events.cpp index bf3e331edd..1c0fb398db 100644 --- a/backends/platform/gp2x/events.cpp +++ b/backends/platform/gp2x/events.cpp @@ -30,6 +30,7 @@ #include "backends/platform/gp2x/gp2x-common.h" #include "backends/platform/gp2x/gp2x-hw.h" +#include "backends/keymapper/keymapper.h" #include "common/util.h" #include "common/events.h" @@ -90,9 +91,9 @@ void OSystem_GP2X::fillMouseEvent(Common::Event &event, int x, int y) { // Adjust for the screen scaling if (!_overlayVisible) { - event.mouse.x /= _scaleFactor; - event.mouse.y /= _scaleFactor; - if (_adjustAspectRatio) + event.mouse.x /= _videoMode.scaleFactor; + event.mouse.y /= _videoMode.scaleFactor; + if (_videoMode.aspectRatio) event.mouse.y = aspect2Real(event.mouse.y); } } @@ -161,7 +162,7 @@ void OSystem_GP2X::handleKbdMouse() { _km.y_down_count = 1; } - SDL_WarpMouse(_km.x, _km.y); + SDL_WarpMouse((Uint16)_km.x, (Uint16)_km.y); } } } @@ -257,7 +258,6 @@ bool OSystem_GP2X::pollEvent(Common::Event &event) { if (_modeChanged) { _modeChanged = false; event.type = Common::EVENT_SCREEN_CHANGED; - _screenChangeCount++; return true; } @@ -593,3 +593,62 @@ bool OSystem_GP2X::remapKey(SDL_Event &ev,Common::Event &event) { return false; } +void OSystem_GP2X::setupKeymapper() { +#ifdef ENABLE_KEYMAPPER + using namespace Common; + Keymapper *mapper = getEventManager()->getKeymapper(); + + HardwareKeySet *keySet = new HardwareKeySet(); + keySet->addHardwareKey(new HardwareKey( "a", KeyState(KEYCODE_a), "a", kActionKeyType )); + keySet->addHardwareKey(new HardwareKey( "s", KeyState(KEYCODE_s), "s", kActionKeyType )); + keySet->addHardwareKey(new HardwareKey( "d", KeyState(KEYCODE_d), "d", kActionKeyType )); + keySet->addHardwareKey(new HardwareKey( "f", KeyState(KEYCODE_f), "f", kActionKeyType )); + keySet->addHardwareKey(new HardwareKey( "n", KeyState(KEYCODE_n), "n (vk)", kTriggerLeftKeyType, kVirtualKeyboardActionType )); + keySet->addHardwareKey(new HardwareKey( "m", KeyState(KEYCODE_m), "m (remap)", kTriggerRightKeyType, kKeyRemapActionType )); + keySet->addHardwareKey(new HardwareKey( "[", KeyState(KEYCODE_LEFTBRACKET), "[ (select)", kSelectKeyType )); + keySet->addHardwareKey(new HardwareKey( "]", KeyState(KEYCODE_RIGHTBRACKET), "] (start)", kStartKeyType )); + mapper->registerHardwareKeySet(keySet); + + Keymap *globalMap = new Keymap("global"); + Keymap *guiMap = new Keymap("gui"); + Action *act; + Event evt ; + + act = new Action(globalMap, "MENU", "Menu", kGenericActionType, kSelectKeyType); + act->addKeyEvent(KeyState(KEYCODE_F5, ASCII_F5, 0)); + + act = new Action(globalMap, "SKCT", "Skip", kGenericActionType, kActionKeyType); + act->addKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0)); + + act = new Action(globalMap, "PAUS", "Pause", kGenericActionType, kStartKeyType); + act->addKeyEvent(KeyState(KEYCODE_SPACE, ' ', 0)); + + act = new Action(globalMap, "SKLI", "Skip line", kGenericActionType, kActionKeyType); + act->addKeyEvent(KeyState(KEYCODE_PERIOD, '.', 0)); + + act = new Action(globalMap, "VIRT", "Display keyboard", kVirtualKeyboardActionType); + act->addKeyEvent(KeyState(KEYCODE_F6, ASCII_F6, 0)); + + act = new Action(globalMap, "REMP", "Remap keys", kKeyRemapActionType); + act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0)); + + mapper->addGlobalKeymap(globalMap); + + act = new Action(guiMap, "CLOS", "Close", kGenericActionType, kStartKeyType); + act->addKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0)); + + act = new Action(guiMap, "CLIK", "Mouse click"); + act->addLeftClickEvent(); + + act = new Action(guiMap, "VIRT", "Display keyboard", kVirtualKeyboardActionType); + act->addKeyEvent(KeyState(KEYCODE_F6, ASCII_F6, 0)); + + act = new Action(guiMap, "REMP", "Remap keys", kKeyRemapActionType); + act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0)); + + mapper->addGlobalKeymap(guiMap); + + mapper->pushKeymap("global"); +#endif +} + diff --git a/backends/platform/gp2x/gp2x-common.h b/backends/platform/gp2x/gp2x-common.h index 14c62edf87..7341b0646f 100644 --- a/backends/platform/gp2x/gp2x-common.h +++ b/backends/platform/gp2x/gp2x-common.h @@ -26,21 +26,21 @@ #ifndef GP2X_COMMON_H #define GP2X_COMMON_H -#define __GP2X__ -#define USE_OSD +#include <SDL.h> +#include <SDL_gp2x.h> #include "backends/base-backend.h" #include "graphics/scaler.h" -#include <SDL.h> -#include <SDL_gp2x.h> +#define __GP2X__ +#define USE_OSD +/* #define DISABLE_SCALERS */ +#define MIXER_DOUBLE_BUFFERING 1 namespace Audio { class MixerImpl; } -//#define DISABLE_SCALERS - enum { GFX_NORMAL = 0, GFX_DOUBLESIZE = 1, @@ -65,11 +65,12 @@ public: virtual void initBackend(); void beginGFXTransaction(void); - void endGFXTransaction(void); + TransactionError endGFXTransaction(void); // Set the size of the video bitmap. // Typically, 320x200 void initSize(uint w, uint h); + int getScreenChangeID() const { return _screenChangeCount; } // Set colors of the palette @@ -106,7 +107,7 @@ public: void disableCursorPalette(bool disable) { _cursorPaletteDisabled = disable; blitCursor(); - }; + } // Shaking is used in SCUMM. Set current shake position. void setShakePos(int shake_pos); @@ -121,9 +122,15 @@ public: // Returns true if an event was retrieved. virtual bool pollEvent(Common::Event &event); // overloaded by CE backend + // Sets up the keymapper with the backends hardware key set + void setupKeymapper(); + // Set function that generates samples void setupMixer(); static void mixCallback(void *s, byte *samples, int len); + + void closeMixer(); + virtual Audio::Mixer *getMixer(); // Poll CD status @@ -152,6 +159,7 @@ public: void deleteMutex(MutexRef mutex); // Overlay + Graphics::PixelFormat getOverlayFormat() const { return _overlayFormat; } void showOverlay(); void hideOverlay(); void clearOverlay(); @@ -159,8 +167,8 @@ public: void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); int16 getHeight(); int16 getWidth(); - int16 getOverlayHeight() { return _overlayHeight; } - int16 getOverlayWidth() { return _overlayWidth; } + int16 getOverlayHeight() { return _videoMode.overlayHeight; } + int16 getOverlayWidth() { return _videoMode.overlayWidth; } const GraphicsMode *getSupportedGraphicsModes() const; int getDefaultGraphicsMode() const; @@ -176,6 +184,11 @@ public: void displayMessageOnOSD(const char *msg); virtual Common::SaveFileManager *getSavefileManager(); + virtual FilesystemFactory *getFilesystemFactory(); + virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0); + + virtual Common::SeekableReadStream *createConfigReadStream(); + virtual Common::WriteStream *createConfigWriteStream(); protected: bool _inited; @@ -195,7 +208,6 @@ protected: // unseen game screen SDL_Surface *_screen; - int _screenWidth, _screenHeight; // temporary screen (for scalers) SDL_Surface *_tmpscreen; @@ -203,8 +215,8 @@ protected: // overlay SDL_Surface *_overlayscreen; - int _overlayWidth, _overlayHeight; bool _overlayVisible; + Graphics::PixelFormat _overlayFormat; // Audio int _samplesPerSec; @@ -215,42 +227,44 @@ protected: uint32 _cdEndTime, _cdStopTime; enum { - DF_WANT_RECT_OPTIM = 1 << 0, - DF_UPDATE_EXPAND_1_PIXEL = 1 << 1 + DF_WANT_RECT_OPTIM = 1 << 0 }; enum { kTransactionNone = 0, - kTransactionCommit = 1, - kTransactionActive = 2 + kTransactionActive = 1, + kTransactionRollback = 2 }; struct TransactionDetails { - int mode; - bool modeChanged; - int w; - int h; bool sizeChanged; - bool fs; - bool fsChanged; - bool ar; - bool arChanged; bool needHotswap; bool needUpdatescreen; - bool needUnload; - bool needToggle; bool normal1xScaler; }; TransactionDetails _transactionDetails; + struct VideoState { + bool setup; + + bool fullscreen; + bool aspectRatio; + + int mode; + int scaleFactor; + + int screenWidth, screenHeight; + int overlayWidth, overlayHeight; + }; + VideoState _videoMode, _oldVideoMode; + + virtual void setGraphicsModeIntern(); // overloaded by CE backend + /** Force full redraw on next updateScreen */ bool _forceFull; ScalerProc *_scalerProc; int _scalerType; - int _scaleFactor; - int _mode; int _transactionMode; - bool _fullscreen; bool _screenIsLocked; Graphics::Surface _framebuffer; @@ -352,32 +366,50 @@ protected: */ MutexRef _graphicsMutex; - Common::SaveFileManager *_savefile; - FilesystemFactory *getFilesystemFactory(); +#ifdef MIXER_DOUBLE_BUFFERING + SDL_mutex *_soundMutex; + SDL_cond *_soundCond; + SDL_Thread *_soundThread; + bool _soundThreadIsRunning; + bool _soundThreadShouldQuit; + + byte _activeSoundBuf; + uint _soundBufSize; + byte *_soundBuffers[2]; + void mixerProducerThread(); + static int SDLCALL mixerProducerThreadEntry(void *arg); + void initThreadedMixer(Audio::MixerImpl *mixer, uint bufSize); + void deinitThreadedMixer(); +#endif + + FilesystemFactory *_fsFactory; + Common::SaveFileManager *_savefile; Audio::MixerImpl *_mixer; SDL_TimerID _timerID; Common::TimerManager *_timer; +protected: void addDirtyRgnAuto(const byte *buf); void makeChecksums(const byte *buf); virtual void addDirtyRect(int x, int y, int w, int h, bool realCoordinates = false); void drawMouse(); - virtual void undrawMouse(); - virtual void blitCursor(); + void undrawMouse(); + void blitCursor(); /** Set the position of the virtual mouse cursor. */ void setMousePos(int x, int y); void fillMouseEvent(Common::Event &event, int x, int y); + void toggleMouseGrab(); void internUpdateScreen(); - void loadGFXMode(); + bool loadGFXMode(); void unloadGFXMode(); - void hotswapGFXMode(); + bool hotswapGFXMode(); void setFullscreenMode(bool enable); void setAspectRatioCorrection(bool enable); @@ -386,7 +418,10 @@ protected: bool saveScreenshot(const char *filename); - int effectiveScreenHeight() const { return (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor; } + int effectiveScreenHeight() const { + return (_videoMode.aspectRatio ? real2Aspect(_videoMode.screenHeight) : _videoMode.screenHeight) + * _videoMode.scaleFactor; + } void setupIcon(); void handleKbdMouse(); diff --git a/backends/platform/gp2x/gp2x-hw.cpp b/backends/platform/gp2x/gp2x-hw.cpp index 6e0e5215ef..fe02e029f7 100644 --- a/backends/platform/gp2x/gp2x-hw.cpp +++ b/backends/platform/gp2x/gp2x-hw.cpp @@ -213,60 +213,3 @@ void gp2x_video_wait_vsync(void) MEM_REG[0x2846>>1]=(MEM_REG[0x2846>>1] | 0x20) & ~2; while (!(MEM_REG[0x2846>>1] & 2)); } - -//char GP2X_get_battery_level() { - // Returns string of level in English for use in displayMessageOnOSD() to show battery level. - // - //if (gp2x_dev[1] == -1) - //{ - // warning("Error occured getting voltage status"); - // return "Unable to read battery level."; - //} - // - //int i; - //int battval; - //unsigned short cbv; - //int v; - // - //battval = 0; - //for (i = 0; i < 1000; i ++) - //{ - // if (read (gp2x_dev[1], &cbv, 2) == 2) - // battval += cbv; - // if (gp2x_joystick_read() & GP2X_START) - // { - // needexit = 1; - // break; - // } - //} - //if (needexit) break; - // - //battval /= 1000; - - // Do a very rough translation - //if (battval > 1016) v = 37; - //else if (battval > 974) v = 33; - //else if (battval > 943) v = 32; - //else if (battval > 915) v = 31; - //else if (battval > 896) v = 30; - //else if (battval > 837) v = 29; - //else if (battval > 815) v = 28; - //else if (battval > 788) v = 27; - //else if (battval > 745) v = 26; - //else if (battval > 708) v = 25; - //else if (battval > 678) v = 24; - //else if (battval > 649) v = 23; - //else if (battval > 605) v = 22; - //else if (battval > 573) v = 21; - //else if (battval > 534) v = 20; - //else if (battval > 496) v = 19; - //else if (battval > 448) v = 18; - //else v = 17; - - //gp2x_printf (NULL, 0, 0, "Voltage: ~%d.%dV (%s)", v/10, v%10, v>26?"Battery Full" : v>24?"Battery Medium" : "Battery Empty"); - //gp2x_video_RGB_flip(0); - //} - //close (gp2x_dev[1]); - - //return "Voltage: ~%d.%dV (%s)", v/10, v%10, v>26?"Battery Full" : v>24?"Battery Medium" : "Battery Empty"; -//} diff --git a/backends/platform/gp2x/gp2x.cpp b/backends/platform/gp2x/gp2x.cpp index 5701a27c35..039f72e02f 100644 --- a/backends/platform/gp2x/gp2x.cpp +++ b/backends/platform/gp2x/gp2x.cpp @@ -31,16 +31,20 @@ #include "backends/platform/gp2x/gp2x-common.h" #include "backends/platform/gp2x/gp2x-hw.h" #include "backends/platform/gp2x/gp2x-mem.h" +#include "common/archive.h" #include "common/config-manager.h" + +#include "common/events.h" +#include "common/util.h" + #include "common/debug.h" #include "common/file.h" -#include "common/util.h" #include "base/main.h" -#include "backends/saves/default/default-saves.h" +#include "backends/saves/posix/posix-saves.h" + #include "backends/timer/default/default-timer.h" #include "backends/plugins/posix/posix-provider.h" -#include "backends/fs/posix/posix-fs-factory.h" // for getFilesystemFactory() #include "sound/mixer_intern.h" #include <stdio.h> @@ -49,20 +53,18 @@ #include <limits.h> #include <errno.h> #include <sys/stat.h> -#include <time.h> // for getTimeAndDate() +#include <time.h> // for getTimeAndDate() // Disable for normal serial logging. #define DUMP_STDOUT -#if defined(HAVE_CONFIG_H) -#include "config.h" -#endif - #define SAMPLES_PER_SEC 11025 //#define SAMPLES_PER_SEC 22050 //#define SAMPLES_PER_SEC 44100 +#define DEFAULT_CONFIG_FILE ".scummvmrc" +#include "backends/fs/posix/posix-fs-factory.h" static Uint32 timer_handler(Uint32 interval, void *param) { ((DefaultTimerManager *)param)->handler(); @@ -107,8 +109,6 @@ void OSystem_GP2X::initBackend() { error("Could not initialize SDL: %s", SDL_GetError()); } - SDL_ShowCursor(SDL_DISABLE); - // Setup default save path to be workingdir/saves #ifndef PATH_MAX #define PATH_MAX 255 @@ -192,6 +192,10 @@ void OSystem_GP2X::initBackend() { setbuf(stderr, NULL); /* No buffering */ #endif // DUMP_STDOUT + _graphicsMutex = createMutex(); + + SDL_ShowCursor(SDL_DISABLE); + // Setup other defaults. ConfMan.registerDefault("aspect_ratio", true); @@ -200,14 +204,15 @@ void OSystem_GP2X::initBackend() { ConfMan.registerDefault("speech_volume", 220); ConfMan.registerDefault("autosave_period", 3 * 60); // Trigger autosave every 3 minutes - On low batts 4 mins is about your warning time. - _graphicsMutex = createMutex(); + memset(&_oldVideoMode, 0, sizeof(_oldVideoMode)); + memset(&_videoMode, 0, sizeof(_videoMode)); + memset(&_transactionDetails, 0, sizeof(_transactionDetails)); _cksumValid = false; - _mode = GFX_NORMAL; - _scaleFactor = 0; + _videoMode.mode = GFX_NORMAL; + _videoMode.scaleFactor = 1; _scalerProc = Normal1x; - _fullscreen = true; - _adjustAspectRatio = ConfMan.getBool("aspect_ratio"); + _videoMode.aspectRatio = ConfMan.getBool("aspect_ratio"); _scalerType = 0; _modeFlags = 0; _adjustZoomOnMouse = false; @@ -221,7 +226,7 @@ void OSystem_GP2X::initBackend() { // Create the savefile manager, if none exists yet (we check for this to // allow subclasses to provide their own). if (_savefile == 0) { - _savefile = new DefaultSaveFileManager(savePath); + _savefile = new POSIXSaveFileManager(); } // Create and hook up the mixer, if none exists yet (we check for this to @@ -230,16 +235,21 @@ void OSystem_GP2X::initBackend() { setupMixer(); } + // Setup the keymapper with backend's set of keys + // NOTE: must be done before creating TimerManager + // to avoid race conditions in creating EventManager + setupKeymapper(); + // Create and hook up the timer manager, if none exists yet (we check for // this to allow subclasses to provide their own). if (_timer == 0) { - // TODO: We could implement a custom SDLTimerManager by using + // Note: We could implement a custom SDLTimerManager by using // SDL_AddTimer. That might yield better timer resolution, but it would // also change the semantics of a timer: Right now, ScummVM timers // *never* run in parallel, due to the way they are implemented. If we // switched to SDL_AddTimer, each timer might run in a separate thread. - // Unfortunately, not all our code is prepared for that, so we can't just - // switch. But it's a long term goal to do just that! + // However, not all our code is prepared for that, so we can't just + // switch. Still, it's a potential future change to keep in mind. _timer = new DefaultTimerManager(); _timerID = SDL_AddTimer(10, &timer_handler, _timer); @@ -278,8 +288,7 @@ void OSystem_GP2X::initBackend() { OSystem_GP2X::OSystem_GP2X() : _osdSurface(0), _osdAlpha(SDL_ALPHA_TRANSPARENT), _osdFadeStartTime(0), - _hwscreen(0), _screen(0), _screenWidth(0), _screenHeight(0), - _tmpscreen(0), _overlayWidth(0), _overlayHeight(0), + _hwscreen(0), _screen(0), _tmpscreen(0), _overlayVisible(false), _overlayscreen(0), _tmpscreen2(0), _samplesPerSec(0), @@ -289,9 +298,15 @@ OSystem_GP2X::OSystem_GP2X() _joystick(0), _currentShakePos(0), _newShakePos(0), _paletteDirtyStart(0), _paletteDirtyEnd(0), +#ifdef MIXER_DOUBLE_BUFFERING + _soundMutex(0), _soundCond(0), _soundThread(0), + _soundThreadIsRunning(false), _soundThreadShouldQuit(false), +#endif + _fsFactory(0), _savefile(0), _mixer(0), _timer(0), + _screenIsLocked(false), _graphicsMutex(0), _transactionMode(kTransactionNone) { // allocate palette storage @@ -305,11 +320,12 @@ OSystem_GP2X::OSystem_GP2X() memset(&_mouseCurState, 0, sizeof(_mouseCurState)); _inited = false; + _fsFactory = new POSIXFilesystemFactory(); } OSystem_GP2X::~OSystem_GP2X() { SDL_RemoveTimer(_timerID); - SDL_CloseAudio(); + closeMixer(); free(_dirtyChecksums); free(_currentPalette); @@ -317,12 +333,13 @@ OSystem_GP2X::~OSystem_GP2X() { free(_mouseData); delete _savefile; - delete _mixer; delete _timer; } uint32 OSystem_GP2X::getMillis() { - return SDL_GetTicks(); + uint32 millis = SDL_GetTicks(); + getEventManager()->processMillis(millis); + return millis; } void OSystem_GP2X::delayMillis(uint msecs) { @@ -345,12 +362,54 @@ Common::SaveFileManager *OSystem_GP2X::getSavefileManager() { } FilesystemFactory *OSystem_GP2X::getFilesystemFactory() { - return &POSIXFilesystemFactory::instance(); + assert(_fsFactory); + return _fsFactory; +} + +void OSystem_GP2X::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) { + +#ifdef DATA_PATH + // Add the global DATA_PATH to the directory search list + // FIXME: We use depth = 4 for now, to match the old code. May want to change that + Common::FSNode dataNode(DATA_PATH); + if (dataNode.exists() && dataNode.isDirectory()) { + s.add(DATA_PATH, new Common::FSDirectory(dataNode, 4), priority); + } +#endif + +#if defined(MACOSX) || defined(IPHONE) + // Get URL of the Resource directory of the .app bundle + CFURLRef fileUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); + if (fileUrl) { + // Try to convert the URL to an absolute path + UInt8 buf[MAXPATHLEN]; + if (CFURLGetFileSystemRepresentation(fileUrl, true, buf, sizeof(buf))) { + // Success: Add it to the search path + Common::String bundlePath((const char *)buf); + s.add("__OSX_BUNDLE__", new Common::FSDirectory(bundlePath), priority); + } + CFRelease(fileUrl); + } + +#endif + +} + +static Common::String getDefaultConfigFileName() { + char configFile[MAXPATHLEN]; + strcpy(configFile, DEFAULT_CONFIG_FILE); + return configFile; +} + +Common::SeekableReadStream *OSystem_GP2X::createConfigReadStream() { + Common::FSNode file(getDefaultConfigFileName()); + return file.createReadStream(); } -//void OSystem_GP2X::setTimerCallback(TimerProc callback, int timer) { -// SDL_SetTimer(timer, (SDL_TimerCallback) callback); -//} +Common::WriteStream *OSystem_GP2X::createConfigWriteStream() { + Common::FSNode file(getDefaultConfigFileName()); + return file.createWriteStream(); +} bool OSystem_GP2X::hasFeature(Feature f) { return @@ -387,10 +446,8 @@ bool OSystem_GP2X::getFeatureState(Feature f) { switch (f) { case kFeatureFullscreenMode: return false; - //case kFeatureFullscreenMode: - // return _fullscreen; case kFeatureAspectRatioCorrection: - return _adjustAspectRatio; + return _videoMode.aspectRatio; case kFeatureAutoComputeDirtyRects: return _modeFlags & DF_WANT_RECT_OPTIM; default: @@ -408,7 +465,7 @@ void OSystem_GP2X::quit() { GP2X_device_deinit(); SDL_RemoveTimer(_timerID); - SDL_CloseAudio(); + closeMixer(); free(_dirtyChecksums); free(_currentPalette); @@ -416,9 +473,8 @@ void OSystem_GP2X::quit() { free(_mouseData); delete _savefile; - delete _mixer; delete _timer; - + SDL_ShowCursor(SDL_ENABLE); SDL_Quit(); delete getEventManager(); @@ -446,20 +502,114 @@ void OSystem_GP2X::deleteMutex(MutexRef mutex) { #pragma mark --- Audio --- #pragma mark - +#ifdef MIXER_DOUBLE_BUFFERING + +void OSystem_GP2X::mixerProducerThread() { + byte nextSoundBuffer; + + SDL_LockMutex(_soundMutex); + while (true) { + // Wait till we are allowed to produce data + SDL_CondWait(_soundCond, _soundMutex); + + if (_soundThreadShouldQuit) + break; + + // Generate samples and put them into the next buffer + nextSoundBuffer = _activeSoundBuf ^ 1; + _mixer->mixCallback(_soundBuffers[nextSoundBuffer], _soundBufSize); + + // Swap buffers + _activeSoundBuf = nextSoundBuffer; + } + SDL_UnlockMutex(_soundMutex); +} + +int SDLCALL OSystem_GP2X::mixerProducerThreadEntry(void *arg) { + OSystem_GP2X *this_ = (OSystem_GP2X *)arg; + assert(this_); + this_->mixerProducerThread(); + return 0; +} + + +void OSystem_GP2X::initThreadedMixer(Audio::MixerImpl *mixer, uint bufSize) { + _soundThreadIsRunning = false; + _soundThreadShouldQuit = false; + + // Create mutex and condition variable + _soundMutex = SDL_CreateMutex(); + _soundCond = SDL_CreateCond(); + + // Create two sound buffers + _activeSoundBuf = 0; + _soundBufSize = bufSize; + _soundBuffers[0] = (byte *)calloc(1, bufSize); + _soundBuffers[1] = (byte *)calloc(1, bufSize); + + _soundThreadIsRunning = true; + + // Finally start the thread + _soundThread = SDL_CreateThread(mixerProducerThreadEntry, this); +} + +void OSystem_GP2X::deinitThreadedMixer() { + // Kill thread?? _soundThread + + if (_soundThreadIsRunning) { + // Signal the producer thread to end, and wait for it to actually finish. + _soundThreadShouldQuit = true; + SDL_CondBroadcast(_soundCond); + SDL_WaitThread(_soundThread, NULL); + + // Kill the mutex & cond variables. + // Attention: AT this point, the mixer callback must not be running + // anymore, else we will crash! + SDL_DestroyMutex(_soundMutex); + SDL_DestroyCond(_soundCond); + + _soundThreadIsRunning = false; + + free(_soundBuffers[0]); + free(_soundBuffers[1]); + } +} + + +void OSystem_GP2X::mixCallback(void *arg, byte *samples, int len) { + OSystem_GP2X *this_ = (OSystem_GP2X *)arg; + assert(this_); + assert(this_->_mixer); + + assert((int)this_->_soundBufSize == len); + + // Lock mutex, to ensure our data is not overwritten by the producer thread + SDL_LockMutex(this_->_soundMutex); + + // Copy data from the current sound buffer + memcpy(samples, this_->_soundBuffers[this_->_activeSoundBuf], len); + + // Unlock mutex and wake up the produced thread + SDL_UnlockMutex(this_->_soundMutex); + SDL_CondSignal(this_->_soundCond); +} + +#else + void OSystem_GP2X::mixCallback(void *sys, byte *samples, int len) { OSystem_GP2X *this_ = (OSystem_GP2X *)sys; assert(this_); + assert(this_->_mixer); - if (this_->_mixer) - this_->_mixer->mixCallback(samples, len); + this_->_mixer->mixCallback(samples, len); } +#endif + void OSystem_GP2X::setupMixer() { SDL_AudioSpec desired; SDL_AudioSpec obtained; - //memset(&desired, 0, sizeof(desired)); - // Determine the desired output sampling frequency. _samplesPerSec = 0; if (ConfMan.hasKey("output_rate")) @@ -467,7 +617,6 @@ void OSystem_GP2X::setupMixer() { if (_samplesPerSec <= 0) _samplesPerSec = SAMPLES_PER_SEC; - //Quick EVIL Hack - DJWillis _samplesPerSec = 11025; @@ -507,10 +656,31 @@ void OSystem_GP2X::setupMixer() { // Tell the mixer that we are ready and start the sound processing _mixer->setOutputRate(_samplesPerSec); _mixer->setReady(true); + +#ifdef MIXER_DOUBLE_BUFFERING + initThreadedMixer(_mixer, obtained.samples * 4); +#endif + + // start the sound system SDL_PauseAudio(0); } } +void OSystem_GP2X::closeMixer() { + if (_mixer) + _mixer->setReady(false); + + SDL_CloseAudio(); + + delete _mixer; + _mixer = 0; + +#ifdef MIXER_DOUBLE_BUFFERING + deinitThreadedMixer(); +#endif + +} + Audio::Mixer *OSystem_GP2X::getMixer() { assert(_mixer); return _mixer; diff --git a/backends/platform/gp2x/graphics.cpp b/backends/platform/gp2x/graphics.cpp index 7fa0fddeb1..775c3afb73 100644 --- a/backends/platform/gp2x/graphics.cpp +++ b/backends/platform/gp2x/graphics.cpp @@ -70,116 +70,246 @@ int OSystem_GP2X::getDefaultGraphicsMode() const { } void OSystem_GP2X::beginGFXTransaction(void) { - assert (_transactionMode == kTransactionNone); + assert(_transactionMode == kTransactionNone); _transactionMode = kTransactionActive; - _transactionDetails.modeChanged = false; _transactionDetails.sizeChanged = false; - _transactionDetails.arChanged = false; - _transactionDetails.fsChanged = false; _transactionDetails.needHotswap = false; _transactionDetails.needUpdatescreen = false; - _transactionDetails.needUnload = false; _transactionDetails.normal1xScaler = false; + + _oldVideoMode = _videoMode; } -void OSystem_GP2X::endGFXTransaction(void) { - // for each engine we run initCommonGFX() as first thing in the transaction - // and initSize() is called later. If user runs launcher at 320x200 with - // 2x overlay, setting to Nomral1x sclaler in that case will be suppressed - // and backend is forced to 2x - // - // This leads to bad results such as 1280x960 window for 640x480 engines. - // To prevent that we rerun setGraphicsMode() if there was 1x scaler request - if (_transactionDetails.normal1xScaler) - setGraphicsMode(GFX_NORMAL); +OSystem::TransactionError OSystem_GP2X::endGFXTransaction(void) { + int errors = kTransactionSuccess; + + assert(_transactionMode != kTransactionNone); - assert (_transactionMode == kTransactionActive); + if (_transactionMode == kTransactionRollback) { + if (_videoMode.fullscreen != _oldVideoMode.fullscreen) { + errors |= kTransactionFullscreenFailed; - _transactionMode = kTransactionCommit; - if (_transactionDetails.modeChanged) - setGraphicsMode(_transactionDetails.mode); + _videoMode.fullscreen = _oldVideoMode.fullscreen; + } else if (_videoMode.aspectRatio != _oldVideoMode.aspectRatio) { + errors |= kTransactionAspectRatioFailed; - if (_transactionDetails.sizeChanged) - initSize(_transactionDetails.w, _transactionDetails.h); + _videoMode.aspectRatio = _oldVideoMode.aspectRatio; + } else if (_videoMode.mode != _oldVideoMode.mode) { + errors |= kTransactionModeSwitchFailed; + + _videoMode.mode = _oldVideoMode.mode; + _videoMode.scaleFactor = _oldVideoMode.scaleFactor; + } else if (_videoMode.screenWidth != _oldVideoMode.screenWidth || _videoMode.screenHeight != _oldVideoMode.screenHeight) { + errors |= kTransactionSizeChangeFailed; + + _videoMode.screenWidth = _oldVideoMode.screenWidth; + _videoMode.screenHeight = _oldVideoMode.screenHeight; + _videoMode.overlayWidth = _oldVideoMode.overlayWidth; + _videoMode.overlayHeight = _oldVideoMode.overlayHeight; + } - if (_transactionDetails.arChanged) - setAspectRatioCorrection(_transactionDetails.ar); + if (_videoMode.fullscreen == _oldVideoMode.fullscreen && + _videoMode.aspectRatio == _oldVideoMode.aspectRatio && + _videoMode.mode == _oldVideoMode.mode && + _videoMode.screenWidth == _oldVideoMode.screenWidth && + _videoMode.screenHeight == _oldVideoMode.screenHeight) { + + // Our new video mode would now be exactly the same as the + // old one. Since we still can not assume SDL_SetVideoMode + // to be working fine, we need to invalidate the old video + // mode, so loadGFXMode would error out properly. + _oldVideoMode.setup = false; + } + } - if (_transactionDetails.needUnload) { + if (_transactionDetails.sizeChanged) { unloadGFXMode(); - loadGFXMode(); - clearOverlay(); - } else { - if (!_transactionDetails.fsChanged) { - if (_transactionDetails.needHotswap) - hotswapGFXMode(); - else if (_transactionDetails.needUpdatescreen) + if (!loadGFXMode()) { + if (_oldVideoMode.setup) { + _transactionMode = kTransactionRollback; + errors |= endGFXTransaction(); + } + } else { + setGraphicsModeIntern(); + clearOverlay(); + + _videoMode.setup = true; + _modeChanged = true; + // OSystem_SDL::pollEvent used to update the screen change count, + // but actually it gives problems when a video mode was changed + // but OSystem_SDL::pollEvent was not called. This for example + // caused a crash under certain circumstances when doing an RTL. + // To fix this issue we update the screen change count right here. + _screenChangeCount++; + } + } else if (_transactionDetails.needHotswap) { + setGraphicsModeIntern(); + if (!hotswapGFXMode()) { + if (_oldVideoMode.setup) { + _transactionMode = kTransactionRollback; + errors |= endGFXTransaction(); + } + } else { + _videoMode.setup = true; + _modeChanged = true; + // OSystem_SDL::pollEvent used to update the screen change count, + // but actually it gives problems when a video mode was changed + // but OSystem_SDL::pollEvent was not called. This for example + // caused a crash under certain circumstances when doing an RTL. + // To fix this issue we update the screen change count right here. + _screenChangeCount++; + + if (_transactionDetails.needUpdatescreen) internUpdateScreen(); } + } else if (_transactionDetails.needUpdatescreen) { + setGraphicsModeIntern(); + internUpdateScreen(); } - if (_transactionDetails.fsChanged) - setFullscreenMode(_transactionDetails.fs); - _transactionMode = kTransactionNone; + return (TransactionError)errors; } bool OSystem_GP2X::setGraphicsMode(int mode) { Common::StackLock lock(_graphicsMutex); + assert(_transactionMode == kTransactionActive); + + if (_oldVideoMode.setup && _oldVideoMode.mode == mode) + return true; + int newScaleFactor = 1; - ScalerProc *newScalerProc; - mode = GFX_NORMAL; - newScaleFactor = 1; - newScalerProc = Normal1x; + switch(mode) { + case GFX_NORMAL: + newScaleFactor = 1; + break; +#ifndef DISABLE_SCALERS + case GFX_DOUBLESIZE: + newScaleFactor = 2; + break; + case GFX_TRIPLESIZE: + newScaleFactor = 3; + break; + + case GFX_2XSAI: + newScaleFactor = 2; + break; + case GFX_SUPER2XSAI: + newScaleFactor = 2; + break; + case GFX_SUPEREAGLE: + newScaleFactor = 2; + break; + case GFX_ADVMAME2X: + newScaleFactor = 2; + break; + case GFX_ADVMAME3X: + newScaleFactor = 3; + break; +#ifndef DISABLE_HQ_SCALERS + case GFX_HQ2X: + newScaleFactor = 2; + break; + case GFX_HQ3X: + newScaleFactor = 3; + break; +#endif + case GFX_TV2X: + newScaleFactor = 2; + break; + case GFX_DOTMATRIX: + newScaleFactor = 2; + break; +#endif // DISABLE_SCALERS + + default: + warning("unknown gfx mode %d", mode); + return false; + } _transactionDetails.normal1xScaler = (mode == GFX_NORMAL); + if (_oldVideoMode.setup && _oldVideoMode.scaleFactor != newScaleFactor) + _transactionDetails.needHotswap = true; - _mode = mode; - _scalerProc = newScalerProc; + _transactionDetails.needUpdatescreen = true; - if (_transactionMode == kTransactionActive) { - _transactionDetails.mode = mode; - _transactionDetails.modeChanged = true; + _videoMode.mode = mode; + _videoMode.scaleFactor = newScaleFactor; - if (newScaleFactor != _scaleFactor) { - _transactionDetails.needHotswap = true; - _scaleFactor = newScaleFactor; - } + return true; +} - _transactionDetails.needUpdatescreen = true; - return true; - } +void OSystem_GP2X::setGraphicsModeIntern() { + Common::StackLock lock(_graphicsMutex); + ScalerProc *newScalerProc = 0; - // NOTE: This should not be executed at transaction commit - // Otherwise there is some unsolicited setGraphicsMode() call - // which should be properly removed - if (newScaleFactor != _scaleFactor) { - assert(_transactionMode != kTransactionCommit); + switch (_videoMode.mode) { + case GFX_NORMAL: + newScalerProc = Normal1x; + break; +#ifndef DISABLE_SCALERS + case GFX_DOUBLESIZE: + newScalerProc = Normal2x; + break; + case GFX_TRIPLESIZE: + newScalerProc = Normal3x; + break; + + case GFX_2XSAI: + newScalerProc = _2xSaI; + break; + case GFX_SUPER2XSAI: + newScalerProc = Super2xSaI; + break; + case GFX_SUPEREAGLE: + newScalerProc = SuperEagle; + break; + case GFX_ADVMAME2X: + newScalerProc = AdvMame2x; + break; + case GFX_ADVMAME3X: + newScalerProc = AdvMame3x; + break; +#ifndef DISABLE_HQ_SCALERS + case GFX_HQ2X: + newScalerProc = HQ2x; + break; + case GFX_HQ3X: + newScalerProc = HQ3x; + break; +#endif + case GFX_TV2X: + newScalerProc = TV2x; + break; + case GFX_DOTMATRIX: + newScalerProc = DotMatrix; + break; +#endif // DISABLE_SCALERS - _scaleFactor = newScaleFactor; - hotswapGFXMode(); + default: + error("Unknown gfx mode %d", _videoMode.mode); } - // Determine the "scaler type", i.e. essentially an index into the - // s_gfxModeSwitchTable array defined in events.cpp. - if (_mode != GFX_NORMAL) { + _scalerProc = newScalerProc; + + if (_videoMode.mode != GFX_NORMAL) { for (int i = 0; i < ARRAYSIZE(s_gfxModeSwitchTable); i++) { - if (s_gfxModeSwitchTable[i][1] == _mode || s_gfxModeSwitchTable[i][2] == _mode) { + if (s_gfxModeSwitchTable[i][1] == _videoMode.mode || s_gfxModeSwitchTable[i][2] == _videoMode.mode) { _scalerType = i; break; } } } - if (!_screen) - return true; + if (!_screen || !_hwscreen) + return; // Blit everything to the screen _forceFull = true; @@ -187,101 +317,79 @@ bool OSystem_GP2X::setGraphicsMode(int mode) { // Even if the old and new scale factors are the same, we may have a // different scaler for the cursor now. blitCursor(); - - if (_transactionMode != kTransactionCommit) - internUpdateScreen(); - - // Make sure that an Common::EVENT_SCREEN_CHANGED gets sent later - _modeChanged = true; - - return true; } int OSystem_GP2X::getGraphicsMode() const { assert (_transactionMode == kTransactionNone); - return _mode; + return _videoMode.mode; } void OSystem_GP2X::initSize(uint w, uint h){ + assert(_transactionMode == kTransactionActive); + // Avoid redundant res changes - if ((int)w == _screenWidth && (int)h == _screenHeight && - _transactionMode != kTransactionCommit) + if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight) return; - _screenWidth = w; - _screenHeight = h; + _videoMode.screenWidth = w; + _videoMode.screenHeight = h; - _cksumNum = (_screenWidth * _screenHeight / (8 * 8)); + _cksumNum = (w * h / (8 * 8)); - if (_transactionMode == kTransactionActive) { - _transactionDetails.w = w; - _transactionDetails.h = h; - _transactionDetails.sizeChanged = true; - - _transactionDetails.needUnload = true; - - return; - } + _transactionDetails.sizeChanged = true; free(_dirtyChecksums); _dirtyChecksums = (uint32 *)calloc(_cksumNum * 2, sizeof(uint32)); - - if (_transactionMode != kTransactionCommit) { - unloadGFXMode(); - loadGFXMode(); - - // if initSize() gets called in the middle, overlay is not transparent - clearOverlay(); - } } -void OSystem_GP2X::loadGFXMode() { +bool OSystem_GP2X::loadGFXMode() { assert(_inited); _forceFull = true; - _modeFlags |= DF_UPDATE_EXPAND_1_PIXEL; int hwW, hwH; - _overlayWidth = _screenWidth * _scaleFactor; - _overlayHeight = _screenHeight * _scaleFactor; + _videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor; + _videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor; - if (_screenHeight != 200) - _adjustAspectRatio = false; + if (_videoMode.screenHeight != 200 && _videoMode.screenHeight != 400) + _videoMode.aspectRatio = false; - if (_adjustAspectRatio) - _overlayHeight = real2Aspect(_overlayHeight); + if (_videoMode.aspectRatio) + _videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight); - hwW = _screenWidth * _scaleFactor; + hwW = _videoMode.screenWidth * _videoMode.scaleFactor; hwH = effectiveScreenHeight(); // // Create the surface that contains the 8 bit game data // - _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth, _screenHeight, 8, 0, 0, 0, 0); + _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0); if (_screen == NULL) error("allocating _screen failed"); // - // Create the surface that contains the graphics in 16 bit mode + // Create the surface that contains the scaled graphics in 16 bit mode // - // FIXME: Hack for GP2X SDL querks. - if (_screenWidth <= 320) { - _hwscreen = SDL_SetVideoMode(320, 240, 16, SDL_FULLSCREEN|SDL_SWSURFACE); - } else { - _hwscreen = SDL_SetVideoMode(_screenWidth, _screenHeight, 16, SDL_FULLSCREEN|SDL_SWSURFACE); - } - + _hwscreen = SDL_SetVideoMode(hwW, hwH, 16, + _videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE + ); if (_hwscreen == NULL) { - warning("SDL_SetVideoMode says we can't switch to that mode"); - quit(); + // DON'T use error(), as this tries to bring up the debug + // console, which WON'T WORK now that _hwscreen is hosed. + + if (!_oldVideoMode.setup) { + warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError()); + quit(); + } else { + return false; + } } // GP2X Specific, must be called after any SDL_SetVideoMode to ensure the hardware cursor is off. // Note: On the GP2X SDL_SetVideoMode recalls SDL_Init(). SDL_ShowCursor(SDL_DISABLE); - // // Create the surface used for the graphics in 16 bit before scaling, and also the overlay // @@ -293,7 +401,7 @@ void OSystem_GP2X::loadGFXMode() { InitScalers(565); // Need some extra bytes around when using 2xSaI - _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth + 3, _screenHeight + 3, + _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, @@ -303,7 +411,7 @@ void OSystem_GP2X::loadGFXMode() { if (_tmpscreen == NULL) error("allocating _tmpscreen failed"); - _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth, _overlayHeight, + _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, @@ -313,7 +421,19 @@ void OSystem_GP2X::loadGFXMode() { if (_overlayscreen == NULL) error("allocating _overlayscreen failed"); - _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth + 3, _overlayHeight + 3, + _overlayFormat.bytesPerPixel = _overlayscreen->format->BytesPerPixel; + + _overlayFormat.rLoss = _overlayscreen->format->Rloss; + _overlayFormat.gLoss = _overlayscreen->format->Gloss; + _overlayFormat.bLoss = _overlayscreen->format->Bloss; + _overlayFormat.aLoss = _overlayscreen->format->Aloss; + + _overlayFormat.rShift = _overlayscreen->format->Rshift; + _overlayFormat.gShift = _overlayscreen->format->Gshift; + _overlayFormat.bShift = _overlayscreen->format->Bshift; + _overlayFormat.aShift = _overlayscreen->format->Ashift; + + _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, @@ -336,10 +456,12 @@ void OSystem_GP2X::loadGFXMode() { SDL_SetColorKey(_osdSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kOSDColorKey); // keyboard cursor control, some other better place for it? - _km.x_max = _screenWidth * _scaleFactor - 1; + _km.x_max = _videoMode.screenWidth * _videoMode.scaleFactor - 1; _km.y_max = effectiveScreenHeight() - 1; _km.delay_time = 25; _km.last_time = 0; + + return true; } void OSystem_GP2X::unloadGFXMode() { @@ -372,28 +494,38 @@ void OSystem_GP2X::unloadGFXMode() { SDL_FreeSurface(_osdSurface); _osdSurface = NULL; } + DestroyScalers(); } -void OSystem_GP2X::hotswapGFXMode() { +bool OSystem_GP2X::hotswapGFXMode() { if (!_screen) - return; + return false; // Keep around the old _screen & _overlayscreen so we can restore the screen data // after the mode switch. SDL_Surface *old_screen = _screen; SDL_Surface *old_overlayscreen = _overlayscreen; + _screen = NULL; + _overlayscreen = NULL; // Release the HW screen surface - SDL_FreeSurface(_hwscreen); + SDL_FreeSurface(_hwscreen); _hwscreen = NULL; - SDL_FreeSurface(_tmpscreen); - SDL_FreeSurface(_tmpscreen2); + SDL_FreeSurface(_tmpscreen); _tmpscreen = NULL; + SDL_FreeSurface(_tmpscreen2); _tmpscreen2 = NULL; // Release the OSD surface - SDL_FreeSurface(_osdSurface); + SDL_FreeSurface(_osdSurface); _osdSurface = NULL; // Setup the new GFX mode - loadGFXMode(); + if (!loadGFXMode()) { + unloadGFXMode(); + + _screen = old_screen; + _overlayscreen = old_overlayscreen; + + return false; + } // reset palette SDL_SetColors(_screen, _currentPalette, 0, 256); @@ -412,8 +544,7 @@ void OSystem_GP2X::hotswapGFXMode() { // Blit everything to the screen internUpdateScreen(); - // Make sure that an Common::EVENT_SCREEN_CHANGED gets sent later - _modeChanged = true; + return true; } void OSystem_GP2X::updateScreen() { @@ -437,9 +568,9 @@ void OSystem_GP2X::internUpdateScreen() { // If the shake position changed, fill the dirty area with blackness if (_currentShakePos != _newShakePos) { - SDL_Rect blackrect = {0, 0, _screenWidth * _scaleFactor, _newShakePos * _scaleFactor}; + SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _videoMode.scaleFactor, _newShakePos * _videoMode.scaleFactor}; - if (_adjustAspectRatio && !_overlayVisible) + if (_videoMode.aspectRatio && !_overlayVisible) blackrect.h = real2Aspect(blackrect.h - 1) + 1; SDL_FillRect(_hwscreen, &blackrect, 0); @@ -481,15 +612,15 @@ void OSystem_GP2X::internUpdateScreen() { if (!_overlayVisible) { origSurf = _screen; srcSurf = _tmpscreen; - width = _screenWidth; - height = _screenHeight; + width = _videoMode.screenWidth; + height = _videoMode.screenHeight; scalerProc = _scalerProc; - scale1 = _scaleFactor; + scale1 = _videoMode.scaleFactor; } else { origSurf = _overlayscreen; srcSurf = _tmpscreen2; - width = _overlayWidth; - height = _overlayHeight; + width = _videoMode.overlayWidth; + height = _videoMode.overlayHeight; scalerProc = Normal1x; scale1 = 1; @@ -513,15 +644,6 @@ void OSystem_GP2X::internUpdateScreen() { uint32 srcPitch, dstPitch; SDL_Rect *lastRect = _dirtyRectList + _numDirtyRects; - if (scalerProc == Normal1x && !_adjustAspectRatio && 0) { - for (r = _dirtyRectList; r != lastRect; ++r) { - dst = *r; - - dst.y += _currentShakePos; - if (SDL_BlitSurface(origSurf, r, _hwscreen, &dst) != 0) - error("SDL_BlitSurface failed: %s", SDL_GetError()); - } - } else { for (r = _dirtyRectList; r != lastRect; ++r) { dst = *r; dst.x++; // Shift rect by one since 2xSai needs to acces the data around @@ -551,7 +673,7 @@ void OSystem_GP2X::internUpdateScreen() { orig_dst_y = dst_y; dst_y = dst_y * scale1; - if (_adjustAspectRatio && !_overlayVisible) + if (_videoMode.aspectRatio && !_overlayVisible) dst_y = real2Aspect(dst_y); assert(scalerProc != NULL); @@ -565,13 +687,12 @@ void OSystem_GP2X::internUpdateScreen() { r->h = dst_h * scale1; #ifndef DISABLE_SCALERS - if (_adjustAspectRatio && orig_dst_y < height && !_overlayVisible) + if (_videoMode.aspectRatio && orig_dst_y < height && !_overlayVisible) r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1); #endif } SDL_UnlockSurface(srcSurf); SDL_UnlockSurface(_hwscreen); - } // Readjust the dirty rect list in case we are doing a full update. // This is necessary if shaking is active. @@ -608,62 +729,28 @@ bool OSystem_GP2X::saveScreenshot(const char *filename) { void OSystem_GP2X::setFullscreenMode(bool enable) { Common::StackLock lock(_graphicsMutex); - if (_fullscreen != enable || _transactionMode == kTransactionCommit) { - assert(_hwscreen != 0); - _fullscreen = enable; - - if (_transactionMode == kTransactionActive) { - _transactionDetails.fs = enable; - _transactionDetails.fsChanged = true; - - _transactionDetails.needHotswap = true; - - return; - } - -#if (defined(MACOSX) && !SDL_VERSION_ATLEAST(1, 2, 6)) || defined(__MAEMO__) - // On OS X, SDL_WM_ToggleFullScreen is currently not implemented. Worse, - // 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 - // hotswapGFXMode() directly to switch to fullscreen mode. - hotswapGFXMode(); -#else - if (!SDL_WM_ToggleFullScreen(_hwscreen)) { - // if ToggleFullScreen fails, achieve the same effect with hotswap gfx mode - hotswapGFXMode(); - } else { - // Blit everything to the screen - internUpdateScreen(); + if (_oldVideoMode.setup && _oldVideoMode.fullscreen == enable) + return; - // Make sure that an Common::EVENT_SCREEN_CHANGED gets sent later - _modeChanged = true; - } -#endif + if (_transactionMode == kTransactionActive) { + _videoMode.fullscreen = enable; + _transactionDetails.needHotswap = true; } } void OSystem_GP2X::setAspectRatioCorrection(bool enable) { - if ((_screenHeight == 200 && _adjustAspectRatio != enable) || - _transactionMode == kTransactionCommit) { + if ((_videoMode.screenHeight == 200 && _videoMode.aspectRatio != enable) || + _transactionMode == kTransactionActive) { + Common::StackLock lock(_graphicsMutex); - //assert(_hwscreen != 0); - _adjustAspectRatio = enable; + if (_oldVideoMode.setup && _oldVideoMode.aspectRatio == enable) + return; if (_transactionMode == kTransactionActive) { - _transactionDetails.ar = enable; - _transactionDetails.arChanged = true; - + _videoMode.aspectRatio = enable; _transactionDetails.needHotswap = true; - - return; - } else { - if (_transactionMode != kTransactionCommit) - hotswapGFXMode(); } - - // Make sure that an Common::EVENT_SCREEN_CHANGED gets sent later - _modeChanged = true; } } @@ -693,8 +780,8 @@ void OSystem_GP2X::copyRectToScreen(const byte *src, int pitch, int x, int y, in // assert(h > 0 && y + h <= _screenHeight); // assert(w > 0 && x + w <= _screenWidth); - if (((long)src & 3) == 0 && pitch == _screenWidth && x == 0 && y == 0 && - w == _screenWidth && h == _screenHeight && _modeFlags & DF_WANT_RECT_OPTIM) { + if (((long)src & 3) == 0 && pitch == _videoMode.screenWidth && x == 0 && y == 0 && + w == _videoMode.screenWidth && h == _videoMode.screenHeight && _modeFlags & DF_WANT_RECT_OPTIM) { /* Special, optimized case for full screen updates. * It tries to determine what areas were actually changed, * and just updates those, on the actual display. */ @@ -713,12 +800,12 @@ void OSystem_GP2X::copyRectToScreen(const byte *src, int pitch, int x, int y, in y = 0; } - if (w > _screenWidth - x) { - w = _screenWidth - x; + if (w > _videoMode.screenWidth - x) { + w = _videoMode.screenWidth - x; } - if (h > _screenHeight - y) { - h = _screenHeight - y; + if (h > _videoMode.screenHeight - y) { + h = _videoMode.screenHeight - y; } if (w <= 0 || h <= 0) @@ -732,15 +819,15 @@ void OSystem_GP2X::copyRectToScreen(const byte *src, int pitch, int x, int y, in if (SDL_LockSurface(_screen) == -1) error("SDL_LockSurface failed: %s", SDL_GetError()); - byte *dst = (byte *)_screen->pixels + y * _screenWidth + x; + byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x; - if (_screenWidth == pitch && pitch == w) { + if (_videoMode.screenWidth == pitch && pitch == w) { memcpy(dst, src, h*w); } else { do { memcpy(dst, src, w); src += pitch; - dst += _screenWidth; + dst += _videoMode.screenWidth; } while (--h); } @@ -800,16 +887,16 @@ void OSystem_GP2X::addDirtyRect(int x, int y, int w, int h, bool realCoordinates int height, width; if (!_overlayVisible && !realCoordinates) { - width = _screenWidth; - height = _screenHeight; + width = _videoMode.screenWidth; + height = _videoMode.screenHeight; } else { - width = _overlayWidth; - height = _overlayHeight; + width = _videoMode.overlayWidth; + height = _videoMode.overlayHeight; } // Extend the dirty region by 1 pixel for scalers // that "smear" the screen, e.g. 2xSAI - if ((_modeFlags & DF_UPDATE_EXPAND_1_PIXEL) && !realCoordinates) { + if (!realCoordinates) { x--; y--; w+=2; @@ -835,7 +922,7 @@ void OSystem_GP2X::addDirtyRect(int x, int y, int w, int h, bool realCoordinates h = height - y; } - if (_adjustAspectRatio && !_overlayVisible && !realCoordinates) { + if (_videoMode.aspectRatio && !_overlayVisible && !realCoordinates) { makeRectStretchable(x, y, w, h); } @@ -858,14 +945,14 @@ void OSystem_GP2X::makeChecksums(const byte *buf) { assert(buf); uint32 *sums = _dirtyChecksums; uint x,y; - const uint last_x = (uint)_screenWidth / 8; - const uint last_y = (uint)_screenHeight / 8; + const uint last_x = (uint)_videoMode.screenWidth / 8; + const uint last_y = (uint)_videoMode.screenHeight / 8; const uint BASE = 65521; /* largest prime smaller than 65536 */ /* the 8x8 blocks in buf are enumerated starting in the top left corner and * reading each line at a time from left to right */ - for (y = 0; y != last_y; y++, buf += _screenWidth * (8 - 1)) + for (y = 0; y != last_y; y++, buf += _videoMode.screenWidth * (8 - 1)) for (x = 0; x != last_x; x++, buf += 8) { // Adler32 checksum algorithm (from RFC1950, used by gzip and zlib). // This computes the Adler32 checksum of a 8x8 pixel block. Note @@ -881,7 +968,7 @@ void OSystem_GP2X::makeChecksums(const byte *buf) { s1 += ptr[subX]; s2 += s1; } - ptr += _screenWidth; + ptr += _videoMode.screenWidth; } s1 %= BASE; @@ -911,8 +998,8 @@ void OSystem_GP2X::addDirtyRgnAuto(const byte *buf) { int x, y, w; uint32 *ck = _dirtyChecksums; - for (y = 0; y != _screenHeight / 8; y++) { - for (x = 0; x != _screenWidth / 8; x++, ck++) { + for (y = 0; y != _videoMode.screenHeight / 8; y++) { + for (x = 0; x != _videoMode.screenWidth / 8; x++, ck++) { if (ck[0] != ck[_cksumNum]) { /* found a dirty 8x8 block, now go as far to the right as possible, and at the same time, unmark the dirty status by setting old to new. */ @@ -920,7 +1007,7 @@ void OSystem_GP2X::addDirtyRgnAuto(const byte *buf) { do { ck[w + _cksumNum] = ck[w]; w++; - } while (x + w != _screenWidth / 8 && ck[w] != ck[w + _cksumNum]); + } while (x + w != _videoMode.screenWidth / 8 && ck[w] != ck[w + _cksumNum]); addDirtyRect(x * 8, y * 8, w * 8, 8); @@ -937,11 +1024,11 @@ void OSystem_GP2X::addDirtyRgnAuto(const byte *buf) { } int16 OSystem_GP2X::getHeight() { - return _screenHeight; + return _videoMode.screenHeight; } int16 OSystem_GP2X::getWidth() { - return _screenWidth; + return _videoMode.screenWidth; } void OSystem_GP2X::setPalette(const byte *colors, uint start, uint num) { @@ -1026,11 +1113,11 @@ void OSystem_GP2X::showOverlay() { // Since resolution could change, put mouse to adjusted position // Fixes bug #1349059 - x = _mouseCurState.x * _scaleFactor; - if (_adjustAspectRatio) - y = real2Aspect(_mouseCurState.y) * _scaleFactor; + x = _mouseCurState.x * _videoMode.scaleFactor; + if (_videoMode.aspectRatio) + y = real2Aspect(_mouseCurState.y) * _videoMode.scaleFactor; else - y = _mouseCurState.y * _scaleFactor; + y = _mouseCurState.y * _videoMode.scaleFactor; warpMouse(x, y); @@ -1049,9 +1136,9 @@ void OSystem_GP2X::hideOverlay() { // Since resolution could change, put mouse to adjusted position // Fixes bug #1349059 - x = _mouseCurState.x / _scaleFactor; - y = _mouseCurState.y / _scaleFactor; - if (_adjustAspectRatio) + x = _mouseCurState.x / _videoMode.scaleFactor; + y = _mouseCurState.y / _videoMode.scaleFactor; + if (_videoMode.aspectRatio) y = aspect2Real(y); warpMouse(x, y); @@ -1073,20 +1160,20 @@ void OSystem_GP2X::clearOverlay() { SDL_Rect src, dst; src.x = src.y = 0; dst.x = dst.y = 1; - src.w = dst.w = _screenWidth; - src.h = dst.h = _screenHeight; + src.w = dst.w = _videoMode.screenWidth; + src.h = dst.h = _videoMode.screenHeight; if (SDL_BlitSurface(_screen, &src, _tmpscreen, &dst) != 0) error("SDL_BlitSurface failed: %s", SDL_GetError()); SDL_LockSurface(_tmpscreen); SDL_LockSurface(_overlayscreen); _scalerProc((byte *)(_tmpscreen->pixels) + _tmpscreen->pitch + 2, _tmpscreen->pitch, - (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _screenWidth, _screenHeight); + (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _videoMode.screenWidth, _videoMode.screenHeight); #ifndef DISABLE_SCALERS - if (_adjustAspectRatio) + if (_videoMode.aspectRatio) stretch200To240((uint8 *)_overlayscreen->pixels, _overlayscreen->pitch, - _overlayWidth, _screenHeight * _scaleFactor, 0, 0, 0); + _videoMode.overlayWidth, _videoMode.screenHeight * _videoMode.scaleFactor, 0, 0, 0); #endif SDL_UnlockSurface(_tmpscreen); SDL_UnlockSurface(_overlayscreen); @@ -1104,9 +1191,9 @@ void OSystem_GP2X::grabOverlay(OverlayColor *buf, int pitch) { error("SDL_LockSurface failed: %s", SDL_GetError()); byte *src = (byte *)_overlayscreen->pixels; - int h = _overlayHeight; + int h = _videoMode.overlayHeight; do { - memcpy(buf, src, _overlayWidth * 2); + memcpy(buf, src, _videoMode.overlayWidth * 2); src += _overlayscreen->pitch; buf += pitch; } while (--h); @@ -1132,12 +1219,12 @@ void OSystem_GP2X::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, y = 0; } - if (w > _overlayWidth - x) { - w = _overlayWidth - x; + if (w > _videoMode.overlayWidth - x) { + w = _videoMode.overlayWidth - x; } - if (h > _overlayHeight - y) { - h = _overlayHeight - y; + if (h > _videoMode.overlayHeight - y) { + h = _videoMode.overlayHeight - y; } if (w <= 0 || h <= 0) @@ -1190,7 +1277,7 @@ void OSystem_GP2X::warpMouse(int x, int y) { if (_mouseCurState.x != x || _mouseCurState.y != y) { if (!_overlayVisible) - SDL_WarpMouse(x * _scaleFactor, y1 * _scaleFactor); + SDL_WarpMouse(x * _videoMode.scaleFactor, y1 * _videoMode.scaleFactor); else SDL_WarpMouse(x, y1); @@ -1293,7 +1380,7 @@ void OSystem_GP2X::blitCursor() { int rW, rH; - if (_cursorTargetScale >= _scaleFactor) { + if (_cursorTargetScale >= _videoMode.scaleFactor) { // The cursor target scale is greater or equal to the scale at // which the rest of the screen is drawn. We do not downscale // the cursor image, we draw it at its original size. It will @@ -1306,22 +1393,22 @@ void OSystem_GP2X::blitCursor() { // The virtual dimensions may be larger than the original. - _mouseCurState.vW = w * _cursorTargetScale / _scaleFactor; - _mouseCurState.vH = h * _cursorTargetScale / _scaleFactor; + _mouseCurState.vW = w * _cursorTargetScale / _videoMode.scaleFactor; + _mouseCurState.vH = h * _cursorTargetScale / _videoMode.scaleFactor; _mouseCurState.vHotX = _mouseCurState.hotX * _cursorTargetScale / - _scaleFactor; + _videoMode.scaleFactor; _mouseCurState.vHotY = _mouseCurState.hotY * _cursorTargetScale / - _scaleFactor; + _videoMode.scaleFactor; } else { // The cursor target scale is smaller than the scale at which // the rest of the screen is drawn. We scale up the cursor // image to make it appear correct. - rW = w * _scaleFactor / _cursorTargetScale; - rH = h * _scaleFactor / _cursorTargetScale; - _mouseCurState.rHotX = _mouseCurState.hotX * _scaleFactor / + rW = w * _videoMode.scaleFactor / _cursorTargetScale; + rH = h * _videoMode.scaleFactor / _cursorTargetScale; + _mouseCurState.rHotX = _mouseCurState.hotX * _videoMode.scaleFactor / _cursorTargetScale; - _mouseCurState.rHotY = _mouseCurState.hotY * _scaleFactor / + _mouseCurState.rHotY = _mouseCurState.hotY * _videoMode.scaleFactor / _cursorTargetScale; // The virtual dimensions will be the same as the original. @@ -1333,7 +1420,8 @@ void OSystem_GP2X::blitCursor() { } int rH1 = rH; // store original to pass to aspect-correction function later - if (_adjustAspectRatio && _cursorTargetScale == 1) { + + if (_videoMode.aspectRatio && _cursorTargetScale == 1) { rH = real2Aspect(rH - 1) + 1; _mouseCurState.rHotY = real2Aspect(_mouseCurState.rHotY); } @@ -1368,16 +1456,16 @@ void OSystem_GP2X::blitCursor() { // the game. This only works well with the non-blurring scalers so we // actually only use the 1x, 1.5x, 2x and AdvMame scalers. - if (_cursorTargetScale == 1 && (_mode == GFX_DOUBLESIZE || _mode == GFX_TRIPLESIZE)) + if (_cursorTargetScale == 1 && (_videoMode.mode == GFX_DOUBLESIZE || _videoMode.mode == GFX_TRIPLESIZE)) scalerProc = _scalerProc; else - scalerProc = scalersMagn[_cursorTargetScale - 1][_scaleFactor - 1]; + scalerProc = scalersMagn[_cursorTargetScale - 1][_videoMode.scaleFactor - 1]; scalerProc((byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2, _mouseOrigSurface->pitch, (byte *)_mouseSurface->pixels, _mouseSurface->pitch, _mouseCurState.w, _mouseCurState.h); - if (_adjustAspectRatio && _cursorTargetScale == 1) + if (_videoMode.aspectRatio && _cursorTargetScale == 1) cursorStretch200To240((uint8 *)_mouseSurface->pixels, _mouseSurface->pitch, rW, rH1, 0, 0, 0); SDL_UnlockSurface(_mouseSurface); @@ -1404,13 +1492,20 @@ static int cursorStretch200To240(uint8 *buf, uint32 pitch, int width, int height return 1 + maxDstY - srcY; } +void OSystem_GP2X::toggleMouseGrab() { + if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) + SDL_WM_GrabInput(SDL_GRAB_ON); + else + SDL_WM_GrabInput(SDL_GRAB_OFF); +} + void OSystem_GP2X::undrawMouse() { const int x = _mouseBackup.x; const int y = _mouseBackup.y; // When we switch bigger overlay off mouse jumps. Argh! // This is intended to prevent undrawing offscreen mouse - if (!_overlayVisible && (x >= _screenWidth || y >= _screenHeight)) { + if (!_overlayVisible && (x >= _videoMode.screenWidth || y >= _videoMode.screenHeight)) { return; } @@ -1432,14 +1527,14 @@ void OSystem_GP2X::drawMouse() { int tmpScreenWidth, tmpScreenHeight; // Temp vars to ensure we zoom to the LCD resolution or greater. - tmpScreenWidth = _screenWidth; - tmpScreenHeight = _screenHeight; + tmpScreenWidth = _videoMode.screenWidth; + tmpScreenHeight = _videoMode.screenHeight; - if (_screenHeight <= 240) { + if (_videoMode.screenHeight <= 240) { tmpScreenHeight = 240; } - if (_screenWidth <= 320) { + if (_videoMode.screenWidth <= 320) { tmpScreenWidth = 320; } @@ -1447,17 +1542,17 @@ void OSystem_GP2X::drawMouse() { dst.y = _mouseCurState.y; if (!_overlayVisible) { - scale = _scaleFactor; - width = _screenWidth; - height = _screenHeight; + scale = _videoMode.scaleFactor; + width = _videoMode.screenWidth; + height = _videoMode.screenHeight; dst.w = _mouseCurState.vW; dst.h = _mouseCurState.vH; hotX = _mouseCurState.vHotX; hotY = _mouseCurState.vHotY; } else { scale = 1; - width = _overlayWidth; - height = _overlayHeight; + width = _videoMode.overlayWidth; + height = _videoMode.overlayHeight; dst.w = _mouseCurState.rW; dst.h = _mouseCurState.rH; hotX = _mouseCurState.rHotX; @@ -1479,7 +1574,7 @@ void OSystem_GP2X::drawMouse() { dst.y += _currentShakePos; } - if (_adjustAspectRatio && !_overlayVisible) + if (_videoMode.aspectRatio && !_overlayVisible) dst.y = real2Aspect(dst.y); dst.x = scale * dst.x - _mouseCurState.rHotX; @@ -1633,17 +1728,18 @@ void OSystem_GP2X::displayMessageOnOSD(const char *msg) { void OSystem_GP2X::handleScalerHotkeys(const SDL_KeyboardEvent &key) { // Ctrl-Alt-a toggles aspect ratio correction if (key.keysym.sym == 'a') { - setFeatureState(kFeatureAspectRatioCorrection, !_adjustAspectRatio); - + beginGFXTransaction(); + setFeatureState(kFeatureAspectRatioCorrection, !_videoMode.aspectRatio); + endGFXTransaction(); char buffer[128]; - if (_adjustAspectRatio) + if (_videoMode.aspectRatio) sprintf(buffer, "Enabled aspect ratio correction\n%d x %d -> %d x %d", - _screenWidth, _screenHeight, + _videoMode.screenWidth, _videoMode.screenHeight, _hwscreen->w, _hwscreen->h ); else sprintf(buffer, "Disabled aspect ratio correction\n%d x %d -> %d x %d", - _screenWidth, _screenHeight, + _videoMode.screenWidth, _videoMode.screenHeight, _hwscreen->w, _hwscreen->h ); displayMessageOnOSD(buffer); @@ -1653,7 +1749,7 @@ void OSystem_GP2X::handleScalerHotkeys(const SDL_KeyboardEvent &key) { } int newMode = -1; - int factor = _scaleFactor - 1; + int factor = _videoMode.scaleFactor - 1; // Increase/decrease the scale factor if (key.keysym.sym == SDLK_EQUALS || key.keysym.sym == SDLK_PLUS || key.keysym.sym == SDLK_MINUS || @@ -1679,13 +1775,15 @@ void OSystem_GP2X::handleScalerHotkeys(const SDL_KeyboardEvent &key) { } if (newMode >= 0) { - setGraphicsMode(newMode); + beginGFXTransaction(); + setGraphicsMode(newMode); + endGFXTransaction(); if (_osdSurface) { const char *newScalerName = 0; const GraphicsMode *g = getSupportedGraphicsModes(); while (g->name) { - if (g->id == _mode) { + if (g->id == _videoMode.mode) { newScalerName = g->description; break; } @@ -1695,7 +1793,7 @@ void OSystem_GP2X::handleScalerHotkeys(const SDL_KeyboardEvent &key) { char buffer[128]; sprintf(buffer, "Active graphics filter: %s\n%d x %d -> %d x %d", newScalerName, - _screenWidth, _screenHeight, + _videoMode.screenWidth, _videoMode.screenHeight, _hwscreen->w, _hwscreen->h ); displayMessageOnOSD(buffer); diff --git a/backends/platform/gp2x/module.mk b/backends/platform/gp2x/module.mk index 0d771e2579..58dfd24ee6 100644 --- a/backends/platform/gp2x/module.mk +++ b/backends/platform/gp2x/module.mk @@ -1,16 +1,16 @@ MODULE := backends/platform/gp2x MODULE_OBJS := \ - gp2x-hw.o \ - gp2x-mem.o \ + gp2x-hw.o \ + gp2x-mem.o \ events.o \ graphics.o \ - gp2x.o - # gp2x-options.o - # overload_help.o + gp2x.o \ +# gp2x-options.o \ +# overload_help.o \ MODULE_DIRS += \ backends/platform/gp2x/ -# We don't use the common.rules here on purpose +# We don't use the rules.mk here on purpose OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) |