aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorJohn Willis2009-02-12 09:52:31 +0000
committerJohn Willis2009-02-12 09:52:31 +0000
commit521cc089110501c456844a4bc5963bd6d8e4df5c (patch)
tree78ab3126b2da4db27862cee65160c4d8816d4fd7 /backends
parent5f634212aa97bd3d5b6e31b45352b5cb985ef636 (diff)
downloadscummvm-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-xbackends/platform/gp2x/build/bundle.sh3
-rw-r--r--backends/platform/gp2x/events.cpp69
-rw-r--r--backends/platform/gp2x/gp2x-common.h107
-rw-r--r--backends/platform/gp2x/gp2x-hw.cpp57
-rw-r--r--backends/platform/gp2x/gp2x.cpp248
-rw-r--r--backends/platform/gp2x/graphics.cpp634
-rw-r--r--backends/platform/gp2x/module.mk12
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)