[Scummvm-cvs-logs] scummvm master -> b95013dfe25d75d39c7deb69ee1a63f93a4a495f

djwillis John.Willis at Distant-earth.com
Thu Mar 24 22:25:36 CET 2011


This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
973e3e827e GP2X: Remove incorrect GP2XWiz define from the GP2X event code.
cf8dcf4549 GPH: Cleanup GPH backend and adapt to newer modular backend model.
16e28747c7 BACKENDS: Add GPH event and graphics files to the build.
0fb15847c6 SDL/POSIX: Update main guard to add OpenPandora.
b95013dfe2 OPENPANDORA: Refactor OpenPandora backend and move events and graphics into modular backend style.


Commit: 973e3e827e39fc81a4b62490d3f1a60e5bc56518
    https://github.com/scummvm/scummvm/commit/973e3e827e39fc81a4b62490d3f1a60e5bc56518
Author: David-John Willis (John.Willis at Distant-earth.com)
Date: 2011-03-24T14:24:04-07:00

Commit Message:
GP2X: Remove incorrect GP2XWiz define from the GP2X event code.

* My plan is to move all of the GPH devices into the GPH backend
  but for now this is just a merge mess from the GSoC-OpenGL branch.

Changed paths:
    backends/events/gp2xsdl/gp2xsdl-events.cpp
    backends/events/gp2xsdl/gp2xsdl-events.h



diff --git a/backends/events/gp2xsdl/gp2xsdl-events.cpp b/backends/events/gp2xsdl/gp2xsdl-events.cpp
index 184f1d9..91feb2b 100644
--- a/backends/events/gp2xsdl/gp2xsdl-events.cpp
+++ b/backends/events/gp2xsdl/gp2xsdl-events.cpp
@@ -25,7 +25,7 @@
 
 #include "common/scummsys.h"
 
-#if defined(GP2X) || defined(GP2XWIZ)
+#if defined(GP2X)
 
 #include "backends/events/gp2xsdl/gp2xsdl-events.h"
 #if defined(GP2X)
@@ -441,7 +441,7 @@ bool GP2XSdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event
 			_km.x_down_count = 0;
 		}
 #endif
- 
+
 	} else if (ev.jaxis.axis == JOY_YAXIS) {
 #ifndef JOY_INVERT_Y
 		axis = -axis;
diff --git a/backends/events/gp2xsdl/gp2xsdl-events.h b/backends/events/gp2xsdl/gp2xsdl-events.h
index 8ea533d..5bf472d 100644
--- a/backends/events/gp2xsdl/gp2xsdl-events.h
+++ b/backends/events/gp2xsdl/gp2xsdl-events.h
@@ -29,7 +29,7 @@
 #include "backends/events/sdl/sdl-events.h"
 
 /**
- * SDL events manager for GP2X and GP2XWIZ
+ * SDL events manager for GP2X
  */
 class GP2XSdlEventSource : public SdlEventSource {
 public:


Commit: cf8dcf45494dcee0ef7b9655dcd656c518cc6d42
    https://github.com/scummvm/scummvm/commit/cf8dcf45494dcee0ef7b9655dcd656c518cc6d42
Author: David-John Willis (John.Willis at Distant-earth.com)
Date: 2011-03-24T14:24:05-07:00

Commit Message:
GPH: Cleanup GPH backend and adapt to newer modular backend model.

Changed paths:
  A backends/events/gph/gph-events.cpp
  A backends/events/gph/gph-events.h
  A backends/graphics/gph/gph-graphics.cpp
  A backends/graphics/gph/gph-graphics.h
  A backends/platform/gph/gph-backend.cpp
  R backends/platform/gph/gph-events.cpp
  R backends/platform/gph/gph-graphics.cpp
    backends/platform/gph/gph-main.cpp
    backends/platform/gph/gph-sdl.h
    backends/platform/gph/module.mk



diff --git a/backends/events/gph/gph-events.cpp b/backends/events/gph/gph-events.cpp
new file mode 100644
index 0000000..8a5bee9
--- /dev/null
+++ b/backends/events/gph/gph-events.cpp
@@ -0,0 +1,469 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+/*
+ * GPH: Device Specific Event Handling.
+ */
+
+#if defined(GP2XWIZ) || defined(CAANOO)
+
+#include "backends/events/gph/gph-events.h"
+#include "backends/graphics/gph/gph-graphics.h"
+#include "backends/platform/gph/gph-hw.h"
+
+#include "common/util.h"
+#include "common/events.h"
+
+#define JOY_DEADZONE 2200
+
+#define JOY_XAXIS 0
+#define JOY_YAXIS 1
+
+/* Quick default button states for modifiers. */
+int BUTTON_STATE_L					=	false;
+
+#if defined(CAANOO)
+
+	/* Caanoo: Main Joystick Button Mappings */
+	/* 		   The Caanoo has an analogue stick so no digital DPAD */
+	enum {
+		/* Joystick Buttons */
+		BUTTON_A			= 0,
+		BUTTON_X			= 1,
+		BUTTON_B			= 2,
+		BUTTON_Y			= 3,
+		BUTTON_L			= 4,
+		BUTTON_R			= 5,
+		BUTTON_HOME			= 6,	// Home
+		BUTTON_HOLD			= 7,	// Hold (on Power)
+		BUTTON_HELP			= 8,	// Help I
+		BUTTON_HELP2		= 9,	// Help II
+		BUTTON_CLICK		= 10	// Stick Click
+	};
+
+	enum {
+		/* Unused Joystick Buttons on the Caanoo */
+		BUTTON_VOLUP		= 51,
+		BUTTON_VOLDOWN		= 52,
+		BUTTON_UP			= 53,
+		BUTTON_UPLEFT		= 54,
+		BUTTON_LEFT			= 55,
+		BUTTON_DOWNLEFT		= 56,
+		BUTTON_DOWN			= 57,
+		BUTTON_DOWNRIGHT	= 58,
+		BUTTON_RIGHT		= 59,
+		BUTTON_UPRIGHT		= 60,
+		BUTTON_MENU			= 61,
+		BUTTON_SELECT		= 62
+	};
+
+#else
+
+	/* Wiz: Main Joystick Mappings */
+	enum {
+		/* DPAD */
+		BUTTON_UP			= 0,
+		BUTTON_UPLEFT		= 1,
+		BUTTON_LEFT			= 2,
+		BUTTON_DOWNLEFT		= 3,
+		BUTTON_DOWN			= 4,
+		BUTTON_DOWNRIGHT	= 5,
+		BUTTON_RIGHT		= 6,
+		BUTTON_UPRIGHT		= 7,
+		/* Joystick Buttons */
+		BUTTON_MENU			= 8,
+		BUTTON_SELECT		= 9,
+		BUTTON_L			= 10,
+		BUTTON_R			= 11,
+		BUTTON_A			= 12,
+		BUTTON_B			= 13,
+		BUTTON_X			= 14,
+		BUTTON_Y			= 15,
+		BUTTON_VOLUP		= 16,
+		BUTTON_VOLDOWN		= 17
+	};
+
+	enum {
+		/* Unused Joystick Buttons on the Wiz */
+		BUTTON_HOME			= 51,
+		BUTTON_HOLD			= 52,
+		BUTTON_CLICK		= 53,
+		BUTTON_HELP			= 54,
+		BUTTON_HELP2		= 55
+	};
+
+#endif
+
+enum {
+	/* Touchscreen TapMode */
+	TAPMODE_LEFT		= 0,
+	TAPMODE_RIGHT		= 1,
+	TAPMODE_HOVER		= 2
+};
+
+//GPHEventSource::GPHEventSource()
+//	: _buttonStateL(false){
+//}
+
+//void GPHEventSource::fillMouseEvent(Common::Event &event, int x, int y) {
+//	if (GPHGraphicsManager::_videoMode.mode == GFX_HALF && !GPHGraphicsManager::_overlayVisible){
+//		event.mouse.x = x*2;
+//		event.mouse.y = y*2;
+//	} else {
+//		event.mouse.x = x;
+//		event.mouse.y = y;
+//	}
+//
+//	// Update the "keyboard mouse" coords
+//	_km.x = x;
+//	_km.y = y;
+//
+//	// Adjust for the screen scaling
+//	if (!_overlayVisible) {
+//		event.mouse.x /= _videoMode.scaleFactor;
+//		event.mouse.y /= _videoMode.scaleFactor;
+//		if (_videoMode.aspectRatioCorrection)
+//			event.mouse.y = aspect2Real(event.mouse.y);
+//	}
+//}
+
+
+void GPHEventSource::moveStick() {
+	bool stickBtn[32];
+
+	memcpy(stickBtn, _stickBtn, sizeof(stickBtn));
+
+	if ((stickBtn[0])||(stickBtn[2])||(stickBtn[4])||(stickBtn[6]))
+		stickBtn[1] = stickBtn[3] = stickBtn[5] = stickBtn[7] = 0;
+
+	if ((stickBtn[1])||(stickBtn[2])||(stickBtn[3])) {
+		if (_km.x_down_count!=2) {
+			_km.x_vel = -1;
+			_km.x_down_count = 1;
+		} else
+			_km.x_vel = -4;
+	} else if ((stickBtn[5])||(stickBtn[6])||(stickBtn[7])) {
+		if (_km.x_down_count!=2) {
+			_km.x_vel = 1;
+			_km.x_down_count = 1;
+		} else
+			_km.x_vel = 4;
+	} else {
+		_km.x_vel = 0;
+		_km.x_down_count = 0;
+	}
+
+	if ((stickBtn[0])||(stickBtn[1])||(stickBtn[7])) {
+		if (_km.y_down_count!=2) {
+			_km.y_vel = -1;
+			_km.y_down_count = 1;
+		} else
+			_km.y_vel = -4;
+	} else if ((stickBtn[3])||(stickBtn[4])||(stickBtn[5])) {
+		if (_km.y_down_count!=2) {
+			_km.y_vel = 1;
+			_km.y_down_count = 1;
+		} else
+			_km.y_vel = 4;
+	} else {
+		_km.y_vel = 0;
+		_km.y_down_count = 0;
+	}
+}
+
+/* Custom handleMouseButtonDown/handleMouseButtonUp to deal with 'Tap Mode' for the touchscreen */
+
+bool GPHEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) {
+	if (ev.button.button == SDL_BUTTON_LEFT){
+		if (BUTTON_STATE_L == true) /* BUTTON_STATE_L = Left Trigger Held, force Right Click */
+			event.type = Common::EVENT_RBUTTONDOWN;
+		else if (GPH::tapmodeLevel == TAPMODE_LEFT) /* TAPMODE_LEFT = Left Click Tap Mode */
+			event.type = Common::EVENT_LBUTTONDOWN;
+		else if (GPH::tapmodeLevel == TAPMODE_RIGHT) /* TAPMODE_RIGHT = Right Click Tap Mode */
+			event.type = Common::EVENT_RBUTTONDOWN;
+		else if (GPH::tapmodeLevel == TAPMODE_HOVER) /* TAPMODE_HOVER = Hover (No Click) Tap Mode */
+			event.type = Common::EVENT_MOUSEMOVE;
+		else
+			event.type = Common::EVENT_LBUTTONDOWN; /* For normal mice etc. */
+	}
+	else if (ev.button.button == SDL_BUTTON_RIGHT)
+		event.type = Common::EVENT_RBUTTONDOWN;
+#if defined(SDL_BUTTON_WHEELUP) && defined(SDL_BUTTON_WHEELDOWN)
+	else if (ev.button.button == SDL_BUTTON_WHEELUP)
+		event.type = Common::EVENT_WHEELUP;
+	else if (ev.button.button == SDL_BUTTON_WHEELDOWN)
+		event.type = Common::EVENT_WHEELDOWN;
+#endif
+#if defined(SDL_BUTTON_MIDDLE)
+	else if (ev.button.button == SDL_BUTTON_MIDDLE)
+		event.type = Common::EVENT_MBUTTONDOWN;
+#endif
+	else
+		return false;
+
+	fillMouseEvent(event, ev.button.x, ev.button.y);
+
+	return true;
+}
+
+bool GPHEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
+	if (ev.button.button == SDL_BUTTON_LEFT){
+		if (BUTTON_STATE_L == true) /* BUTTON_STATE_L = Left Trigger Held, force Right Click */
+			event.type = Common::EVENT_RBUTTONUP;
+		else if (GPH::tapmodeLevel == TAPMODE_LEFT) /* TAPMODE_LEFT = Left Click Tap Mode */
+			event.type = Common::EVENT_LBUTTONUP;
+		else if (GPH::tapmodeLevel == TAPMODE_RIGHT) /* TAPMODE_RIGHT = Right Click Tap Mode */
+			event.type = Common::EVENT_RBUTTONUP;
+		else if (GPH::tapmodeLevel == TAPMODE_HOVER) /* TAPMODE_HOVER = Hover (No Click) Tap Mode */
+			event.type = Common::EVENT_MOUSEMOVE;
+		else
+			event.type = Common::EVENT_LBUTTONUP; /* For normal mice etc. */
+	}
+	else if (ev.button.button == SDL_BUTTON_RIGHT)
+		event.type = Common::EVENT_RBUTTONUP;
+#if defined(SDL_BUTTON_MIDDLE)
+	else if (ev.button.button == SDL_BUTTON_MIDDLE)
+		event.type = Common::EVENT_MBUTTONUP;
+#endif
+	else
+		return false;
+
+	fillMouseEvent(event, ev.button.x, ev.button.y);
+
+	return true;
+}
+
+/* Custom handleJoyButtonDown/handleJoyButtonUp to deal with the joystick buttons on GPH devices */
+
+bool GPHEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
+
+	_stickBtn[ev.jbutton.button] = 1;
+	event.kbd.flags = 0;
+
+	switch (ev.jbutton.button) {
+	case BUTTON_UP:
+	case BUTTON_UPLEFT:
+	case BUTTON_LEFT:
+	case BUTTON_DOWNLEFT:
+	case BUTTON_DOWN:
+	case BUTTON_DOWNRIGHT:
+	case BUTTON_RIGHT:
+	case BUTTON_UPRIGHT:
+		moveStick();
+		event.type = Common::EVENT_MOUSEMOVE;
+		fillMouseEvent(event, _km.x, _km.y);
+		break;
+	case BUTTON_B:
+	case BUTTON_CLICK:
+		event.type = Common::EVENT_LBUTTONDOWN;
+		fillMouseEvent(event, _km.x, _km.y);
+		break;
+	case BUTTON_X:
+		event.type = Common::EVENT_RBUTTONDOWN;
+		fillMouseEvent(event, _km.x, _km.y);
+		break;
+	case BUTTON_L:
+		BUTTON_STATE_L = true;
+		break;
+	case BUTTON_R:
+		event.type = Common::EVENT_KEYDOWN;
+		if (BUTTON_STATE_L == true) {
+#ifdef ENABLE_VKEYBD
+			event.kbd.keycode = Common::KEYCODE_F7;
+			event.kbd.ascii = mapKey(SDLK_F7, ev.key.keysym.mod, 0);
+#else
+			event.kbd.keycode = Common::KEYCODE_0;
+			event.kbd.ascii = mapKey(SDLK_0, ev.key.keysym.mod, 0);
+#endif
+		} else {
+			event.kbd.keycode = Common::KEYCODE_RETURN;
+			event.kbd.ascii = mapKey(SDLK_RETURN, ev.key.keysym.mod, 0);
+		}
+		break;
+	case BUTTON_SELECT:
+	case BUTTON_HOME:
+		event.type = Common::EVENT_KEYDOWN;
+		if (BUTTON_STATE_L == true) {
+			event.type = Common::EVENT_QUIT;
+		} else {
+			event.kbd.keycode = Common::KEYCODE_ESCAPE;
+			event.kbd.ascii = mapKey(SDLK_ESCAPE, ev.key.keysym.mod, 0);
+		}
+		break;
+	case BUTTON_A:
+		event.type = Common::EVENT_KEYDOWN;
+		if (BUTTON_STATE_L == true) {
+			event.type = Common::EVENT_PREDICTIVE_DIALOG;
+		} else {
+		event.kbd.keycode = Common::KEYCODE_PERIOD;
+		event.kbd.ascii = mapKey(SDLK_PERIOD, ev.key.keysym.mod, 0);
+		}
+		break;
+	case BUTTON_Y:
+		event.type = Common::EVENT_KEYDOWN;
+		if (BUTTON_STATE_L == true) {
+			GPH::ToggleTapMode();
+			if (GPH::tapmodeLevel == TAPMODE_LEFT) {
+				g_system->displayMessageOnOSD("Touchscreen 'Tap Mode' - Left Click");
+			} else if (GPH::tapmodeLevel == TAPMODE_RIGHT) {
+				g_system->displayMessageOnOSD("Touchscreen 'Tap Mode' - Right Click");
+			} else if (GPH::tapmodeLevel == TAPMODE_HOVER) {
+				g_system->displayMessageOnOSD("Touchscreen 'Tap Mode' - Hover (No Click)");
+			}
+		} else {
+			event.kbd.keycode = Common::KEYCODE_SPACE;
+			event.kbd.ascii = mapKey(SDLK_SPACE, ev.key.keysym.mod, 0);
+		}
+		break;
+	case BUTTON_MENU:
+	case BUTTON_HELP:
+		event.type = Common::EVENT_KEYDOWN;
+		if (BUTTON_STATE_L == true) {
+			event.type = Common::EVENT_MAINMENU;
+		} else {
+			event.kbd.keycode = Common::KEYCODE_F5;
+			event.kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
+		}
+		break;
+	case BUTTON_VOLUP:
+		WIZ_HW::mixerMoveVolume(2);
+		if (WIZ_HW::volumeLevel == 100) {
+			g_system->displayMessageOnOSD("Maximum Volume");
+		} else {
+			g_system->displayMessageOnOSD("Increasing Volume");
+		}
+		break;
+	case BUTTON_VOLDOWN:
+		WIZ_HW::mixerMoveVolume(1);
+		if (WIZ_HW::volumeLevel == 0) {
+			g_system->displayMessageOnOSD("Minimal Volume");
+		} else {
+			g_system->displayMessageOnOSD("Decreasing Volume");
+		}
+		break;
+	case BUTTON_HOLD:
+		event.type = Common::EVENT_QUIT;
+		break;
+	case BUTTON_HELP2:
+		GPH::ToggleTapMode();
+		if (GPH::tapmodeLevel == TAPMODE_LEFT) {
+			g_system->displayMessageOnOSD("Touchscreen 'Tap Mode': Left Click");
+		} else if (GPH::tapmodeLevel == TAPMODE_RIGHT) {
+			g_system->displayMessageOnOSD("Touchscreen 'Tap Mode': Right Click");
+		} else if (GPH::tapmodeLevel == TAPMODE_HOVER) {
+			g_system->displayMessageOnOSD("Touchscreen 'Tap Mode': Hover (No Click)");
+		}
+		break;
+	}
+	return true;
+}
+
+bool GPHEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
+
+	_stickBtn[ev.jbutton.button] = 0;
+	event.kbd.flags = 0;
+
+	switch (ev.jbutton.button) {
+	case BUTTON_UP:
+	case BUTTON_UPLEFT:
+	case BUTTON_LEFT:
+	case BUTTON_DOWNLEFT:
+	case BUTTON_DOWN:
+	case BUTTON_DOWNRIGHT:
+	case BUTTON_RIGHT:
+	case BUTTON_UPRIGHT:
+		moveStick();
+		event.type = Common::EVENT_MOUSEMOVE;
+		fillMouseEvent(event, _km.x, _km.y);
+		break;
+	case BUTTON_B:
+	case BUTTON_CLICK:
+		event.type = Common::EVENT_LBUTTONUP;
+		fillMouseEvent(event, _km.x, _km.y);
+		break;
+	case BUTTON_X:
+		event.type = Common::EVENT_RBUTTONUP;
+		fillMouseEvent(event, _km.x, _km.y);
+		break;
+	case BUTTON_L:
+		BUTTON_STATE_L = false;
+		break;
+	case BUTTON_SELECT:
+	case BUTTON_HOME:
+		event.type = Common::EVENT_KEYUP;
+		event.kbd.keycode = Common::KEYCODE_ESCAPE;
+		event.kbd.ascii = mapKey(SDLK_ESCAPE, ev.key.keysym.mod, 0);
+		break;
+	case BUTTON_A:
+		event.type = Common::EVENT_KEYUP;
+		event.kbd.keycode = Common::KEYCODE_PERIOD;
+		event.kbd.ascii = mapKey(SDLK_PERIOD, ev.key.keysym.mod, 0);
+		break;
+	case BUTTON_Y:
+		event.type = Common::EVENT_KEYUP;
+		event.kbd.keycode = Common::KEYCODE_SPACE;
+		event.kbd.ascii = mapKey(SDLK_SPACE, ev.key.keysym.mod, 0);
+		break;
+	case BUTTON_MENU:
+	case BUTTON_HELP:
+		event.type = Common::EVENT_KEYUP;
+		if (BUTTON_STATE_L == true) {
+			event.type = Common::EVENT_MAINMENU;
+		} else {
+			event.kbd.keycode = Common::KEYCODE_F5;
+			event.kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
+		}
+		break;
+	case BUTTON_R:
+		event.type = Common::EVENT_KEYUP;
+		if (BUTTON_STATE_L == true) {
+#ifdef ENABLE_VKEYBD
+			event.kbd.keycode = Common::KEYCODE_F7;
+			event.kbd.ascii = mapKey(SDLK_F7, ev.key.keysym.mod, 0);
+#else
+			event.kbd.keycode = Common::KEYCODE_0;
+			event.kbd.ascii = mapKey(SDLK_0, ev.key.keysym.mod, 0);
+#endif
+		} else {
+			event.kbd.keycode = Common::KEYCODE_RETURN;
+			event.kbd.ascii = mapKey(SDLK_RETURN, ev.key.keysym.mod, 0);
+		}
+		break;
+	case BUTTON_VOLUP:
+		break;
+	case BUTTON_VOLDOWN:
+		break;
+	case BUTTON_HOLD:
+		break;
+	case BUTTON_HELP2:
+		break;
+	}
+	return true;
+}
+
+bool GPHEventSource::remapKey(SDL_Event &ev,Common::Event &event) {
+	return false;
+}
+
+#endif
diff --git a/backends/events/gph/gph-events.h b/backends/events/gph/gph-events.h
new file mode 100644
index 0000000..f929a14
--- /dev/null
+++ b/backends/events/gph/gph-events.h
@@ -0,0 +1,61 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if !defined(BACKEND_EVENTS_GPH_H) && !defined(DISABLE_DEFAULT_EVENTMANAGER)
+#define BACKEND_EVENTS_GPH_H
+
+#include "backends/events/sdl/sdl-events.h"
+
+/*
+ * SDL Events manager for GPH devices.
+ */
+
+class GPHEventSource : public SdlEventSource {
+//public:
+//	GPHEventSource();
+
+protected:
+	bool _stickBtn[32];
+
+	/**
+	 * Button state for L button modifier
+	 */
+	bool _buttonStateL;
+
+	/**
+	 * Handles the stick movement
+	 */
+	void moveStick();
+
+	virtual bool handleKeyDown(SDL_Event &ev, Common::Event &event);
+	virtual bool handleJoyButtonDown(SDL_Event &ev, Common::Event &event);
+	virtual bool handleJoyButtonUp(SDL_Event &ev, Common::Event &event);
+	virtual bool handleMouseButtonDown(SDL_Event &ev, Common::Event &event);
+	virtual bool handleMouseButtonUp(SDL_Event &ev, Common::Event &event);
+	virtual bool handleJoyAxisMotion(SDL_Event &ev, Common::Event &event);
+
+//	void fillMouseEvent(Common::Event &event, int x, int y);
+	virtual bool remapKey(SDL_Event &ev, Common::Event &event);
+	virtual void SDLModToOSystemKeyFlags(SDLMod mod, Common::Event &event);
+};
+
+#endif /* BACKEND_EVENTS_GPH_H */
diff --git a/backends/graphics/gph/gph-graphics.cpp b/backends/graphics/gph/gph-graphics.cpp
new file mode 100644
index 0000000..2f971f8
--- /dev/null
+++ b/backends/graphics/gph/gph-graphics.cpp
@@ -0,0 +1,538 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#if defined(GP2XWIZ) || defined(CAANOO)
+
+#include "backends/graphics/gph/gph-graphics.h"
+#include "backends/events/gph/gph-events.h"
+#include "graphics/scaler/aspect.h"
+#include "common/mutex.h"
+
+static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
+	{"1x", "Standard", GFX_NORMAL},
+	{0, 0, 0}
+};
+
+GPHGraphicsManager::GPHGraphicsManager(SdlEventSource *boss)
+ : SdlGraphicsManager(boss) {
+}
+
+const OSystem::GraphicsMode *GPHGraphicsManager::getSupportedGraphicsModes() const {
+	return s_supportedGraphicsModes;
+}
+
+int GPHGraphicsManager::getDefaultGraphicsMode() const {
+	return GFX_NORMAL;
+}
+
+bool GPHGraphicsManager::setGraphicsMode(int mode) {
+	Common::StackLock lock(_graphicsMutex);
+
+	assert(_transactionMode == kTransactionActive);
+
+	if (_oldVideoMode.setup && _oldVideoMode.mode == mode)
+		return true;
+
+	int newScaleFactor = 1;
+
+	switch (mode) {
+	case GFX_NORMAL:
+		newScaleFactor = 1;
+		break;
+	case GFX_HALF:
+		newScaleFactor = 1;
+		break;
+	default:
+		warning("unknown gfx mode %d", mode);
+		return false;
+	}
+
+	_transactionDetails.normal1xScaler = (mode == GFX_NORMAL);
+	if (_oldVideoMode.setup && _oldVideoMode.scaleFactor != newScaleFactor)
+		_transactionDetails.needHotswap = true;
+
+	_transactionDetails.needUpdatescreen = true;
+
+	_videoMode.mode = mode;
+	_videoMode.scaleFactor = newScaleFactor;
+
+	return true;
+}
+
+void GPHGraphicsManager::setGraphicsModeIntern() {
+	Common::StackLock lock(_graphicsMutex);
+	ScalerProc *newScalerProc = 0;
+
+	switch (_videoMode.mode) {
+	case GFX_NORMAL:
+		newScalerProc = Normal1x;
+		break;
+	case GFX_HALF:
+		newScalerProc = DownscaleAllByHalf;
+		break;
+
+	default:
+		error("Unknown gfx mode %d", _videoMode.mode);
+	}
+
+	_scalerProc = newScalerProc;
+
+	if (!_screen || !_hwscreen)
+		return;
+
+	// Blit everything to the screen
+	_forceFull = true;
+
+	// Even if the old and new scale factors are the same, we may have a
+	// different scaler for the cursor now.
+	blitCursor();
+}
+
+void GPHGraphicsManager::initSize(uint w, uint h) {
+	assert(_transactionMode == kTransactionActive);
+
+	// Avoid redundant res changes
+	if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight)
+		return;
+
+	_videoMode.screenWidth = w;
+	_videoMode.screenHeight = h;
+	if (w > 320 || h > 240){
+		setGraphicsMode(GFX_HALF);
+		setGraphicsModeIntern();
+		_sdlEventSource->toggleMouseGrab();
+	}
+
+	_transactionDetails.sizeChanged = true;
+}
+
+void GPHGraphicsManager::drawMouse() {
+	if (!_mouseVisible || !_mouseSurface) {
+		_mouseBackup.x = _mouseBackup.y = _mouseBackup.w = _mouseBackup.h = 0;
+		return;
+	}
+
+	SDL_Rect dst;
+	int scale;
+	int width, height;
+	int hotX, hotY;
+
+	if (_videoMode.mode == GFX_HALF && !_overlayVisible){
+		dst.x = _mouseCurState.x/2;
+		dst.y = _mouseCurState.y/2;
+	} else {
+		dst.x = _mouseCurState.x;
+		dst.y = _mouseCurState.y;
+	}
+
+	if (!_overlayVisible) {
+		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 = _videoMode.overlayWidth;
+		height = _videoMode.overlayHeight;
+		dst.w = _mouseCurState.rW;
+		dst.h = _mouseCurState.rH;
+		hotX = _mouseCurState.rHotX;
+		hotY = _mouseCurState.rHotY;
+	}
+
+	// The mouse is undrawn using virtual coordinates, i.e. they may be
+	// scaled and aspect-ratio corrected.
+
+	_mouseBackup.x = dst.x - hotX;
+	_mouseBackup.y = dst.y - hotY;
+	_mouseBackup.w = dst.w;
+	_mouseBackup.h = dst.h;
+
+	// We draw the pre-scaled cursor image, so now we need to adjust for
+	// scaling, shake position and aspect ratio correction manually.
+
+	if (!_overlayVisible) {
+		dst.y += _currentShakePos;
+	}
+
+	if (_videoMode.aspectRatioCorrection && !_overlayVisible)
+		dst.y = real2Aspect(dst.y);
+
+	dst.x = scale * dst.x - _mouseCurState.rHotX;
+	dst.y = scale * dst.y - _mouseCurState.rHotY;
+	dst.w = _mouseCurState.rW;
+	dst.h = _mouseCurState.rH;
+
+	// Note that SDL_BlitSurface() and addDirtyRect() will both perform any
+	// clipping necessary
+
+	if (SDL_BlitSurface(_mouseSurface, NULL, _hwscreen, &dst) != 0)
+		error("SDL_BlitSurface failed: %s", SDL_GetError());
+
+	// The screen will be updated using real surface coordinates, i.e.
+	// they will not be scaled or aspect-ratio corrected.
+	addDirtyRect(dst.x, dst.y, dst.w, dst.h, true);
+}
+
+void GPHGraphicsManager::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 >= _videoMode.screenWidth || y >= _videoMode.screenHeight))
+		return;
+
+	if (_mouseBackup.w != 0 && _mouseBackup.h != 0){
+		if (_videoMode.mode == GFX_HALF && !_overlayVisible){
+			addDirtyRect(x*2, y*2, _mouseBackup.w*2, _mouseBackup.h*2);
+		} else {
+			addDirtyRect(x, y, _mouseBackup.w, _mouseBackup.h);
+		}
+	}
+}
+
+void GPHGraphicsManager::internUpdateScreen() {
+	SDL_Surface *srcSurf, *origSurf;
+	int height, width;
+	ScalerProc *scalerProc;
+	int scale1;
+
+#if defined (DEBUG)
+	assert(_hwscreen != NULL);
+	assert(_hwscreen->map->sw_data != NULL);
+#endif
+
+	// If the shake position changed, fill the dirty area with blackness
+	if (_currentShakePos != _newShakePos ||
+		(_mouseNeedsRedraw && _mouseBackup.y <= _currentShakePos)) {
+		SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _videoMode.scaleFactor, _newShakePos * _videoMode.scaleFactor};
+
+		if (_videoMode.aspectRatioCorrection && !_overlayVisible)
+			blackrect.h = real2Aspect(blackrect.h - 1) + 1;
+
+		SDL_FillRect(_hwscreen, &blackrect, 0);
+
+		_currentShakePos = _newShakePos;
+
+		_forceFull = true;
+	}
+
+	// Check whether the palette was changed in the meantime and update the
+	// screen surface accordingly.
+	if (_screen && _paletteDirtyEnd != 0) {
+		SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart,
+			_paletteDirtyStart,
+			_paletteDirtyEnd - _paletteDirtyStart);
+
+		_paletteDirtyEnd = 0;
+
+		_forceFull = true;
+	}
+
+#ifdef USE_OSD
+	// OSD visible (i.e. non-transparent)?
+	if (_osdAlpha != SDL_ALPHA_TRANSPARENT) {
+		// Updated alpha value
+		const int diff = SDL_GetTicks() - _osdFadeStartTime;
+		if (diff > 0) {
+			if (diff >= kOSDFadeOutDuration) {
+				// Back to full transparency
+				_osdAlpha = SDL_ALPHA_TRANSPARENT;
+			} else {
+				// Do a linear fade out...
+				const int startAlpha = SDL_ALPHA_TRANSPARENT + kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100;
+				_osdAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
+			}
+			SDL_SetAlpha(_osdSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, _osdAlpha);
+			_forceFull = true;
+		}
+	}
+#endif
+
+	if (!_overlayVisible) {
+		origSurf = _screen;
+		srcSurf = _tmpscreen;
+		width = _videoMode.screenWidth;
+		height = _videoMode.screenHeight;
+		scalerProc = _scalerProc;
+		scale1 = _videoMode.scaleFactor;
+	} else {
+		origSurf = _overlayscreen;
+		srcSurf = _tmpscreen2;
+		width = _videoMode.overlayWidth;
+		height = _videoMode.overlayHeight;
+		scalerProc = Normal1x;
+
+		scale1 = 1;
+	}
+
+	// Add the area covered by the mouse cursor to the list of dirty rects if
+	// we have to redraw the mouse.
+	if (_mouseNeedsRedraw)
+		undrawMouse();
+
+	// Force a full redraw if requested
+	if (_forceFull) {
+		_numDirtyRects = 1;
+		_dirtyRectList[0].x = 0;
+		_dirtyRectList[0].y = 0;
+		_dirtyRectList[0].w = width;
+		_dirtyRectList[0].h = height;
+	}
+
+	// Only draw anything if necessary
+	if (_numDirtyRects > 0 || _mouseNeedsRedraw) {
+		SDL_Rect *r;
+		SDL_Rect dst;
+		uint32 srcPitch, dstPitch;
+		SDL_Rect *lastRect = _dirtyRectList + _numDirtyRects;
+
+		for (r = _dirtyRectList; r != lastRect; ++r) {
+			dst = *r;
+			dst.x++;	// Shift rect by one since 2xSai needs to access the data around
+			dst.y++;	// any pixel to scale it, and we want to avoid mem access crashes.
+
+			if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)
+				error("SDL_BlitSurface failed: %s", SDL_GetError());
+		}
+
+		SDL_LockSurface(srcSurf);
+		SDL_LockSurface(_hwscreen);
+
+		srcPitch = srcSurf->pitch;
+		dstPitch = _hwscreen->pitch;
+
+		for (r = _dirtyRectList; r != lastRect; ++r) {
+			register int dst_y = r->y + _currentShakePos;
+			register int dst_h = 0;
+			register int dst_w = r->w;
+			register int orig_dst_y = 0;
+			register int dst_x = r->x;
+			register int src_y;
+			register int src_x;
+
+			if (dst_y < height) {
+				dst_h = r->h;
+				if (dst_h > height - dst_y)
+					dst_h = height - dst_y;
+
+				orig_dst_y = dst_y;
+				src_x = dst_x;
+				src_y = dst_y;
+
+				if (_videoMode.aspectRatioCorrection && !_overlayVisible)
+					dst_y = real2Aspect(dst_y);
+
+				assert(scalerProc != NULL);
+
+				if ((_videoMode.mode == GFX_HALF) && (scalerProc == DownscaleAllByHalf)) {
+					if (dst_x%2==1){
+						dst_x--;
+						dst_w++;
+					}
+					if (dst_y%2==1){
+						dst_y--;
+						dst_h++;
+					}
+					src_x = dst_x;
+					src_y = dst_y;
+					dst_x = dst_x / 2;
+					dst_y = dst_y / 2;
+
+					scalerProc((byte *)srcSurf->pixels + (src_x * 2 + 2) + (src_y + 1) * srcPitch, srcPitch,
+						   (byte *)_hwscreen->pixels + dst_x * 2 + dst_y * dstPitch, dstPitch, dst_w, dst_h);
+				} else {
+					scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
+					           (byte *)_hwscreen->pixels + r->x * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h);
+				}
+			}
+
+			if (_videoMode.mode == GFX_HALF && scalerProc == DownscaleAllByHalf){
+				r->w = r->w / 2;
+				r->h = dst_h / 2;
+			} else {
+				r->w = r->w;
+				r->h = dst_h;
+			}
+
+			r->x = dst_x;
+			r->y = dst_y;
+
+
+#ifdef USE_SCALERS
+			if (_videoMode.aspectRatioCorrection && 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.
+		if (_forceFull) {
+			_dirtyRectList[0].y = 0;
+			_dirtyRectList[0].h = (_videoMode.mode == GFX_HALF) ? effectiveScreenHeight()/2 : effectiveScreenHeight();
+		}
+
+		drawMouse();
+
+#ifdef USE_OSD
+		if (_osdAlpha != SDL_ALPHA_TRANSPARENT) {
+			SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0);
+		}
+#endif
+		// Finally, blit all our changes to the screen
+		SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
+	}
+
+	_numDirtyRects = 0;
+	_forceFull = false;
+	_mouseNeedsRedraw = false;
+}
+
+void GPHGraphicsManager::showOverlay() {
+	if (_videoMode.mode == GFX_HALF){
+		_mouseCurState.x = _mouseCurState.x / 2;
+		_mouseCurState.y = _mouseCurState.y / 2;
+	}
+	SdlGraphicsManager::showOverlay();
+}
+
+void GPHGraphicsManager::hideOverlay() {
+	if (_videoMode.mode == GFX_HALF){
+		_mouseCurState.x = _mouseCurState.x * 2;
+		_mouseCurState.y = _mouseCurState.y * 2;
+	}
+	SdlGraphicsManager::hideOverlay();
+}
+
+
+bool GPHGraphicsManager::loadGFXMode() {
+
+	/* Forcefully disable aspect ratio correction for games
+	   that start with a native 240px height resolution
+	   This corrects games with non-standard resolutions
+	   such as MM Nes (256x240).
+	*/
+
+	if(_videoMode.screenHeight == 240) {
+		_videoMode.aspectRatioCorrection = false;
+	}
+
+	fprintf(stdout, "Game ScreenMode = %d*%d\n", _videoMode.screenWidth, _videoMode.screenHeight);
+	if (_videoMode.screenWidth > 320 || _videoMode.screenHeight > 240) {
+		_videoMode.aspectRatioCorrection = false;
+		setGraphicsMode(GFX_HALF);
+		fprintf(stdout, "GraphicsMode set to HALF\n");
+	} else {
+		setGraphicsMode(GFX_NORMAL);
+		fprintf(stdout, "GraphicsMode set to NORMAL\n");
+	}
+
+	if ((_videoMode.mode == GFX_HALF) && !_overlayVisible) {
+		_videoMode.overlayWidth = _videoMode.screenWidth / 2;
+		_videoMode.overlayHeight = _videoMode.screenHeight / 2;
+		_videoMode.fullscreen = true;
+	} else {
+
+		_videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
+		_videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
+
+		if (_videoMode.aspectRatioCorrection)
+			_videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight);
+
+		_videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
+		_videoMode.hardwareHeight = effectiveScreenHeight();
+	}
+	return SdlGraphicsManager::loadGFXMode();
+}
+
+bool GPHGraphicsManager::hasFeature(OSystem::Feature f) {
+	return
+	    (f == OSystem::kFeatureAspectRatioCorrection) ||
+	    (f == OSystem::kFeatureCursorHasPalette);
+}
+
+void GPHGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
+	switch (f) {
+		case OSystem::kFeatureAspectRatioCorrection:
+		setAspectRatioCorrection(enable);
+		break;
+	default:
+		break;
+	}
+}
+
+bool GPHGraphicsManager::getFeatureState(OSystem::Feature f) {
+	assert(_transactionMode == kTransactionNone);
+
+	switch (f) {
+		case OSystem::kFeatureAspectRatioCorrection:
+		return _videoMode.aspectRatioCorrection;
+	default:
+		return false;
+	}
+}
+
+SdlGraphicsManager::MousePos* GPHGraphicsManager::getMouseCurState() {
+	return &_mouseCurState;
+}
+
+SdlGraphicsManager::VideoState* GPHGraphicsManager::getVideoMode() {
+	return &_videoMode;
+}
+
+void GPHGraphicsManager::warpMouse(int x, int y) {
+	if (_mouseCurState.x != x || _mouseCurState.y != y) {
+		if (_videoMode.mode == GFX_HALF && !_overlayVisible){
+			x = x / 2;
+			y = y / 2;
+		}
+	}
+	SdlGraphicsManager::warpMouse(x, y);
+}
+
+void GPHGraphicsManager::adjustMouseEvent(const Common::Event &event) {
+	if (!event.synthetic) {
+		Common::Event newEvent(event);
+		newEvent.synthetic = true;
+		if (!_overlayVisible) {
+			if (_videoMode.mode == GFX_HALF) {
+				newEvent.mouse.x *= 2;
+				newEvent.mouse.y *= 2;
+			}
+			newEvent.mouse.x /= _videoMode.scaleFactor;
+			newEvent.mouse.y /= _videoMode.scaleFactor;
+			if (_videoMode.aspectRatioCorrection)
+				newEvent.mouse.y = aspect2Real(newEvent.mouse.y);
+		}
+		g_system->getEventManager()->pushEvent(newEvent);
+	}
+}
+
+#endif
diff --git a/backends/graphics/gph/gph-graphics.h b/backends/graphics/gph/gph-graphics.h
new file mode 100644
index 0000000..6ba2b34
--- /dev/null
+++ b/backends/graphics/gph/gph-graphics.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_GPH_H
+#define BACKENDS_GRAPHICS_GPH_H
+
+#include "backends/graphics/sdl/sdl-graphics.h"
+#include "graphics/scaler/aspect.h"	// for aspect2Real 
+#include "graphics/scaler/downscaler.h"
+
+enum {
+	GFX_HALF = 12
+};
+
+class GPHGraphicsManager : public SdlGraphicsManager {
+public:
+	GPHGraphicsManager(SdlEventSource *boss);
+
+	bool hasFeature(OSystem::Feature f);
+	void setFeatureState(OSystem::Feature f, bool enable);
+	bool getFeatureState(OSystem::Feature f);
+	int getDefaultGraphicsMode() const;
+
+	void initSize(uint w, uint h);
+	const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
+	bool setGraphicsMode(const char *name);
+	bool setGraphicsMode(int mode);
+	void setGraphicsModeIntern();
+	void internUpdateScreen();
+	void showOverlay();
+	void hideOverlay();
+	bool loadGFXMode();
+	void drawMouse();
+	void undrawMouse();
+	virtual void warpMouse(int x, int y);
+
+	SdlGraphicsManager::MousePos *getMouseCurState();
+	SdlGraphicsManager::VideoState *getVideoMode();
+
+	virtual void adjustMouseEvent(const Common::Event &event);
+};
+
+#endif /* BACKENDS_GRAPHICS_GPH_H */
diff --git a/backends/platform/gph/gph-backend.cpp b/backends/platform/gph/gph-backend.cpp
new file mode 100644
index 0000000..0432974
--- /dev/null
+++ b/backends/platform/gph/gph-backend.cpp
@@ -0,0 +1,211 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "backends/platform/sdl/sdl-sys.h"
+
+// #include "backends/platform/gph/gph-options.h"
+#include "backends/platform/gph/gph-sdl.h"
+#include "backends/platform/gph/gph-hw.h"
+#include "backends/plugins/posix/posix-provider.h"
+#include "base/main.h"
+
+#include "common/archive.h"
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/events.h"
+#include "common/util.h"
+
+#include "common/file.h"
+#include "base/main.h"
+
+#include "backends/saves/default/default-saves.h"
+
+#include "backends/timer/default/default-timer.h"
+#include "audio/mixer_intern.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <time.h>	// for getTimeAndDate()
+
+/* Dump console info to files. */
+#define DUMP_STDOUT
+
+void OSystem_GPH::initBackend() {
+
+	// Create the events manager
+	if (_eventSource == 0)
+		_eventSource = new GPHEventSource();
+
+	// Create the graphics manager
+	if (_graphicsManager == 0) {
+		_graphicsManager = new GPHGraphicsManager(_eventSource);
+	}
+
+	/* Setup default save path to be workingdir/saves */
+
+	char savePath[PATH_MAX+1];
+	char workDirName[PATH_MAX+1];
+
+	if (getcwd(workDirName, PATH_MAX) == NULL) {
+		error("Could not obtain current working directory");
+	} else {
+		printf("Current working directory: %s\n", workDirName);
+	}
+
+	strcpy(savePath, workDirName);
+	strcat(savePath, "/saves");
+	printf("Current save directory: %s\n", savePath);
+	struct stat sb;
+	if (stat(savePath, &sb) == -1)
+		if (errno == ENOENT) // Create the dir if it does not exist
+			if (mkdir(savePath, 0755) != 0)
+				warning("mkdir for '%s' failed!", savePath);
+
+	_savefileManager = new DefaultSaveFileManager(savePath);
+
+	#ifdef DUMP_STDOUT
+		// The GP2X Wiz has a serial console on the breakout board but most users do not use this so we
+		// output all our STDOUT and STDERR to files for debug purposes.
+		char STDOUT_FILE[PATH_MAX+1];
+		char STDERR_FILE[PATH_MAX+1];
+
+		strcpy(STDOUT_FILE, workDirName);
+		strcpy(STDERR_FILE, workDirName);
+		strcat(STDOUT_FILE, "/scummvm.stdout.txt");
+		strcat(STDERR_FILE, "/scummvm.stderr.txt");
+
+		// Flush the output in case anything is queued
+		fclose(stdout);
+		fclose(stderr);
+
+		// Redirect standard input and standard output
+		FILE *newfp = freopen(STDOUT_FILE, "w", stdout);
+		if (newfp == NULL) {
+		#if !defined(stdout)
+			stdout = fopen(STDOUT_FILE, "w");
+		#else
+			newfp = fopen(STDOUT_FILE, "w");
+			if (newfp) {
+				*stdout = *newfp;
+			}
+		#endif
+		}
+
+		newfp = freopen(STDERR_FILE, "w", stderr);
+		if (newfp == NULL) {
+		#if !defined(stderr)
+			stderr = fopen(STDERR_FILE, "w");
+		#else
+			newfp = fopen(STDERR_FILE, "w");
+			if (newfp) {
+				*stderr = *newfp;
+			}
+		#endif
+		}
+
+		setbuf(stderr, NULL);
+		printf("%s\n", "Debug: STDOUT and STDERR redirected to text files.");
+	#endif /* DUMP_STDOUT */
+
+	/* Initialise any GP2X Wiz specific stuff we may want (Batt Status, scaler etc.) */
+	WIZ_HW::deviceInit();
+
+	/* Set Default hardware mixer volume to a preset level (VOLUME_INITIAL). This is done to 'reset' volume level if set by other apps. */
+	WIZ_HW::mixerMoveVolume(0);
+
+	/* Up default volume values as we use a seperate system level volume anyway. */
+	ConfMan.registerDefault("music_volume", 192);
+	ConfMan.registerDefault("sfx_volume", 192);
+	ConfMan.registerDefault("speech_volume", 192);
+
+	/* Trigger autosave every 4 minutes - On low batts 5 mins is about your warning time. */
+	ConfMan.registerDefault("autosave_period", 4 * 60);
+
+	/* Make sure that aspect ratio correction is enabled on the 1st run to stop users asking me what the 'wasted space' is ;-). */
+	ConfMan.registerDefault("aspect_ratio", true);
+
+	/* Make sure SDL knows that we have a joystick we want to use. */
+	ConfMan.setInt("joystick_num", 0);
+
+	/* Now setup any device specific user options (Left handed mode, that sort of thing). */
+	// GPH::setOptions();
+
+	printf("%s\n", "Passing to OSystem::SDL initBackend.");
+
+	/* Pass to POSIX method to do the heavy lifting */
+	OSystem_POSIX::initBackend();
+}
+
+void OSystem_GPH::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
+
+	/* Setup default extra data paths for engine data files and plugins */
+	char workDirName[PATH_MAX+1];
+
+	if (getcwd(workDirName, PATH_MAX) == NULL) {
+		error("Error: Could not obtain current working directory");
+	}
+
+	Common::FSNode workdirNode(workDirName);
+	if (workdirNode.exists() && workdirNode.isDirectory()) {
+		s.add("__GP2XWIZ_WORKDIR__", new Common::FSDirectory(workDirName), priority);
+	}
+
+	char enginedataPath[PATH_MAX+1];
+
+	strcpy(enginedataPath, workDirName);
+	strcat(enginedataPath, "/engine-data");
+
+	Common::FSNode engineNode(enginedataPath);
+	if (engineNode.exists() && engineNode.isDirectory()) {
+		s.add("__GP2XWIZ_ENGDATA__", new Common::FSDirectory(enginedataPath), priority);
+	}
+
+	char pluginsPath[PATH_MAX+1];
+
+	strcpy(pluginsPath, workDirName);
+	strcat(pluginsPath, "/plugins");
+
+	Common::FSNode pluginsNode(pluginsPath);
+	if (pluginsNode.exists() && pluginsNode.isDirectory()) {
+		s.add("__GP2XWIZ_PLUGINS__", new Common::FSDirectory(pluginsPath), priority);
+	}
+}
+
+void OSystem_GPH::quit() {
+
+	WIZ_HW::deviceDeinit();
+
+	#ifdef DUMP_STDOUT
+		printf("%s\n", "Debug: STDOUT and STDERR text files closed.");
+		fclose(stdout);
+		fclose(stderr);
+	#endif /* DUMP_STDOUT */
+
+	OSystem_SDL::quit();
+}
diff --git a/backends/platform/gph/gph-events.cpp b/backends/platform/gph/gph-events.cpp
deleted file mode 100644
index 2a6237c..0000000
--- a/backends/platform/gph/gph-events.cpp
+++ /dev/null
@@ -1,481 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-/*
- * GPH: Device Specific Event Handling.
- *
- */
-
-#include "backends/platform/gph/gph-sdl.h"
-#include "backends/platform/gph/gph-hw.h"
-#include "graphics/scaler/aspect.h"
-
-#include "common/util.h"
-#include "common/events.h"
-
-#define JOY_DEADZONE 2200
-
-#define JOY_XAXIS 0
-#define JOY_YAXIS 1
-
-/* Quick default button states for modifiers. */
-int BUTTON_STATE_L					=	false;
-
-#if defined(CAANOO)
-
-	/* Caanoo: Main Joystick Button Mappings */
-	/* 		   The Caanoo has an analogue stick so no digital DPAD */
-	enum {
-		/* Joystick Buttons */
-		BUTTON_A			= 0,
-		BUTTON_X			= 1,
-		BUTTON_B			= 2,
-		BUTTON_Y			= 3,
-		BUTTON_L			= 4,
-		BUTTON_R			= 5,
-		BUTTON_HOME			= 6,	// Home
-		BUTTON_HOLD			= 7,	// Hold (on Power)
-		BUTTON_HELP			= 8,	// Help I
-		BUTTON_HELP2		= 9,	// Help II
-		BUTTON_CLICK		= 10	// Stick Click
-	};
-
-	enum {
-		/* Unused Joystick Buttons on the Caanoo */
-		BUTTON_VOLUP		= 51,
-		BUTTON_VOLDOWN		= 52,
-		BUTTON_UP			= 53,
-		BUTTON_UPLEFT		= 54,
-		BUTTON_LEFT			= 55,
-		BUTTON_DOWNLEFT		= 56,
-		BUTTON_DOWN			= 57,
-		BUTTON_DOWNRIGHT	= 58,
-		BUTTON_RIGHT		= 59,
-		BUTTON_UPRIGHT		= 60,
-		BUTTON_MENU			= 61,
-		BUTTON_SELECT		= 62
-	};
-
-#else
-
-	/* Wiz: Main Joystick Mappings */
-	enum {
-		/* DPAD */
-		BUTTON_UP			= 0,
-		BUTTON_UPLEFT		= 1,
-		BUTTON_LEFT			= 2,
-		BUTTON_DOWNLEFT		= 3,
-		BUTTON_DOWN			= 4,
-		BUTTON_DOWNRIGHT	= 5,
-		BUTTON_RIGHT		= 6,
-		BUTTON_UPRIGHT		= 7,
-		/* Joystick Buttons */
-		BUTTON_MENU			= 8,
-		BUTTON_SELECT		= 9,
-		BUTTON_L			= 10,
-		BUTTON_R			= 11,
-		BUTTON_A			= 12,
-		BUTTON_B			= 13,
-		BUTTON_X			= 14,
-		BUTTON_Y			= 15,
-		BUTTON_VOLUP		= 16,
-		BUTTON_VOLDOWN		= 17
-	};
-
-	enum {
-		/* Unused Joystick Buttons on the Wiz */
-		BUTTON_HOME			= 51,
-		BUTTON_HOLD			= 52,
-		BUTTON_CLICK		= 53,
-		BUTTON_HELP			= 54,
-		BUTTON_HELP2		= 55
-	};
-
-#endif
-
-enum {
-	/* Touchscreen TapMode */
-	TAPMODE_LEFT		= 0,
-	TAPMODE_RIGHT		= 1,
-	TAPMODE_HOVER		= 2
-};
-
-static int mapKey(SDLKey key, SDLMod mod, Uint16 unicode) {
-	if (key >= SDLK_F1 && key <= SDLK_F9) {
-		return key - SDLK_F1 + Common::ASCII_F1;
-	} else if (key >= SDLK_KP0 && key <= SDLK_KP9) {
-		return key - SDLK_KP0 + '0';
-	} else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) {
-		return key;
-	} else if (unicode) {
-		return unicode;
-	} else if (key >= 'a' && key <= 'z' && (mod & KMOD_SHIFT)) {
-		return key & ~0x20;
-	} else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) {
-		return 0;
-	}
-	return key;
-}
-
-
-void OSystem_GPH::fillMouseEvent(Common::Event &event, int x, int y) {
-	if (_videoMode.mode == GFX_HALF && !_overlayVisible){
-		event.mouse.x = x*2;
-		event.mouse.y = y*2;
-	} else {
-		event.mouse.x = x;
-		event.mouse.y = y;
-	}
-
-	// Update the "keyboard mouse" coords
-	_km.x = x;
-	_km.y = y;
-
-	// Adjust for the screen scaling
-	if (!_overlayVisible) {
-		event.mouse.x /= _videoMode.scaleFactor;
-		event.mouse.y /= _videoMode.scaleFactor;
-		if (_videoMode.aspectRatioCorrection)
-			event.mouse.y = aspect2Real(event.mouse.y);
-	}
-}
-
-
-void OSystem_GPH::moveStick() {
-	bool stickBtn[32];
-
-	memcpy(stickBtn, _stickBtn, sizeof(stickBtn));
-
-	if ((stickBtn[0])||(stickBtn[2])||(stickBtn[4])||(stickBtn[6]))
-		stickBtn[1] = stickBtn[3] = stickBtn[5] = stickBtn[7] = 0;
-
-	if ((stickBtn[1])||(stickBtn[2])||(stickBtn[3])) {
-		if (_km.x_down_count!=2) {
-			_km.x_vel = -1;
-			_km.x_down_count = 1;
-		} else
-			_km.x_vel = -4;
-	} else if ((stickBtn[5])||(stickBtn[6])||(stickBtn[7])) {
-		if (_km.x_down_count!=2) {
-			_km.x_vel = 1;
-			_km.x_down_count = 1;
-		} else
-			_km.x_vel = 4;
-	} else {
-		_km.x_vel = 0;
-		_km.x_down_count = 0;
-	}
-
-	if ((stickBtn[0])||(stickBtn[1])||(stickBtn[7])) {
-		if (_km.y_down_count!=2) {
-			_km.y_vel = -1;
-			_km.y_down_count = 1;
-		} else
-			_km.y_vel = -4;
-	} else if ((stickBtn[3])||(stickBtn[4])||(stickBtn[5])) {
-		if (_km.y_down_count!=2) {
-			_km.y_vel = 1;
-			_km.y_down_count = 1;
-		} else
-			_km.y_vel = 4;
-	} else {
-		_km.y_vel = 0;
-		_km.y_down_count = 0;
-	}
-}
-
-/* Custom handleMouseButtonDown/handleMouseButtonUp to deal with 'Tap Mode' for the touchscreen */
-
-bool OSystem_GPH::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) {
-	if (ev.button.button == SDL_BUTTON_LEFT){
-		if (BUTTON_STATE_L == true) /* BUTTON_STATE_L = Left Trigger Held, force Right Click */
-			event.type = Common::EVENT_RBUTTONDOWN;
-		else if (GPH::tapmodeLevel == TAPMODE_LEFT) /* TAPMODE_LEFT = Left Click Tap Mode */
-			event.type = Common::EVENT_LBUTTONDOWN;
-		else if (GPH::tapmodeLevel == TAPMODE_RIGHT) /* TAPMODE_RIGHT = Right Click Tap Mode */
-			event.type = Common::EVENT_RBUTTONDOWN;
-		else if (GPH::tapmodeLevel == TAPMODE_HOVER) /* TAPMODE_HOVER = Hover (No Click) Tap Mode */
-			event.type = Common::EVENT_MOUSEMOVE;
-		else
-			event.type = Common::EVENT_LBUTTONDOWN; /* For normal mice etc. */
-	}
-	else if (ev.button.button == SDL_BUTTON_RIGHT)
-		event.type = Common::EVENT_RBUTTONDOWN;
-#if defined(SDL_BUTTON_WHEELUP) && defined(SDL_BUTTON_WHEELDOWN)
-	else if (ev.button.button == SDL_BUTTON_WHEELUP)
-		event.type = Common::EVENT_WHEELUP;
-	else if (ev.button.button == SDL_BUTTON_WHEELDOWN)
-		event.type = Common::EVENT_WHEELDOWN;
-#endif
-#if defined(SDL_BUTTON_MIDDLE)
-	else if (ev.button.button == SDL_BUTTON_MIDDLE)
-		event.type = Common::EVENT_MBUTTONDOWN;
-#endif
-	else
-		return false;
-
-	fillMouseEvent(event, ev.button.x, ev.button.y);
-
-	return true;
-}
-
-bool OSystem_GPH::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
-	if (ev.button.button == SDL_BUTTON_LEFT){
-		if (BUTTON_STATE_L == true) /* BUTTON_STATE_L = Left Trigger Held, force Right Click */
-			event.type = Common::EVENT_RBUTTONUP;
-		else if (GPH::tapmodeLevel == TAPMODE_LEFT) /* TAPMODE_LEFT = Left Click Tap Mode */
-			event.type = Common::EVENT_LBUTTONUP;
-		else if (GPH::tapmodeLevel == TAPMODE_RIGHT) /* TAPMODE_RIGHT = Right Click Tap Mode */
-			event.type = Common::EVENT_RBUTTONUP;
-		else if (GPH::tapmodeLevel == TAPMODE_HOVER) /* TAPMODE_HOVER = Hover (No Click) Tap Mode */
-			event.type = Common::EVENT_MOUSEMOVE;
-		else
-			event.type = Common::EVENT_LBUTTONUP; /* For normal mice etc. */
-	}
-	else if (ev.button.button == SDL_BUTTON_RIGHT)
-		event.type = Common::EVENT_RBUTTONUP;
-#if defined(SDL_BUTTON_MIDDLE)
-	else if (ev.button.button == SDL_BUTTON_MIDDLE)
-		event.type = Common::EVENT_MBUTTONUP;
-#endif
-	else
-		return false;
-
-	fillMouseEvent(event, ev.button.x, ev.button.y);
-
-	return true;
-}
-
-/* Custom handleJoyButtonDown/handleJoyButtonUp to deal with the joystick buttons on GPH devices */
-
-bool OSystem_GPH::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
-
-	_stickBtn[ev.jbutton.button] = 1;
-	event.kbd.flags = 0;
-
-	switch (ev.jbutton.button) {
-	case BUTTON_UP:
-	case BUTTON_UPLEFT:
-	case BUTTON_LEFT:
-	case BUTTON_DOWNLEFT:
-	case BUTTON_DOWN:
-	case BUTTON_DOWNRIGHT:
-	case BUTTON_RIGHT:
-	case BUTTON_UPRIGHT:
-		moveStick();
-		event.type = Common::EVENT_MOUSEMOVE;
-		fillMouseEvent(event, _km.x, _km.y);
-		break;
-	case BUTTON_B:
-	case BUTTON_CLICK:
-		event.type = Common::EVENT_LBUTTONDOWN;
-		fillMouseEvent(event, _km.x, _km.y);
-		break;
-	case BUTTON_X:
-		event.type = Common::EVENT_RBUTTONDOWN;
-		fillMouseEvent(event, _km.x, _km.y);
-		break;
-	case BUTTON_L:
-		BUTTON_STATE_L = true;
-		break;
-	case BUTTON_R:
-		event.type = Common::EVENT_KEYDOWN;
-		if (BUTTON_STATE_L == true) {
-#ifdef ENABLE_VKEYBD
-			event.kbd.keycode = Common::KEYCODE_F7;
-			event.kbd.ascii = mapKey(SDLK_F7, ev.key.keysym.mod, 0);
-#else
-			event.kbd.keycode = Common::KEYCODE_0;
-			event.kbd.ascii = mapKey(SDLK_0, ev.key.keysym.mod, 0);
-#endif
-		} else {
-			event.kbd.keycode = Common::KEYCODE_RETURN;
-			event.kbd.ascii = mapKey(SDLK_RETURN, ev.key.keysym.mod, 0);
-		}
-		break;
-	case BUTTON_SELECT:
-	case BUTTON_HOME:
-		event.type = Common::EVENT_KEYDOWN;
-		if (BUTTON_STATE_L == true) {
-			event.type = Common::EVENT_QUIT;
-		} else {
-			event.kbd.keycode = Common::KEYCODE_ESCAPE;
-			event.kbd.ascii = mapKey(SDLK_ESCAPE, ev.key.keysym.mod, 0);
-		}
-		break;
-	case BUTTON_A:
-		event.type = Common::EVENT_KEYDOWN;
-		if (BUTTON_STATE_L == true) {
-			event.type = Common::EVENT_PREDICTIVE_DIALOG;
-		} else {
-		event.kbd.keycode = Common::KEYCODE_PERIOD;
-		event.kbd.ascii = mapKey(SDLK_PERIOD, ev.key.keysym.mod, 0);
-		}
-		break;
-	case BUTTON_Y:
-		event.type = Common::EVENT_KEYDOWN;
-		if (BUTTON_STATE_L == true) {
-			GPH::ToggleTapMode();
-			if (GPH::tapmodeLevel == TAPMODE_LEFT) {
-				displayMessageOnOSD("Touchscreen 'Tap Mode' - Left Click");
-			} else if (GPH::tapmodeLevel == TAPMODE_RIGHT) {
-				displayMessageOnOSD("Touchscreen 'Tap Mode' - Right Click");
-			} else if (GPH::tapmodeLevel == TAPMODE_HOVER) {
-				displayMessageOnOSD("Touchscreen 'Tap Mode' - Hover (No Click)");
-			}
-		} else {
-			event.kbd.keycode = Common::KEYCODE_SPACE;
-			event.kbd.ascii = mapKey(SDLK_SPACE, ev.key.keysym.mod, 0);
-		}
-		break;
-	case BUTTON_MENU:
-	case BUTTON_HELP:
-		event.type = Common::EVENT_KEYDOWN;
-		if (BUTTON_STATE_L == true) {
-			event.type = Common::EVENT_MAINMENU;
-		} else {
-			event.kbd.keycode = Common::KEYCODE_F5;
-			event.kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
-		}
-		break;
-	case BUTTON_VOLUP:
-		WIZ_HW::mixerMoveVolume(2);
-		if (WIZ_HW::volumeLevel == 100) {
-			displayMessageOnOSD("Maximum Volume");
-		} else {
-			displayMessageOnOSD("Increasing Volume");
-		}
-		break;
-	case BUTTON_VOLDOWN:
-		WIZ_HW::mixerMoveVolume(1);
-		if (WIZ_HW::volumeLevel == 0) {
-			displayMessageOnOSD("Minimal Volume");
-		} else {
-			displayMessageOnOSD("Decreasing Volume");
-		}
-		break;
-	case BUTTON_HOLD:
-		event.type = Common::EVENT_QUIT;
-		break;
-	case BUTTON_HELP2:
-		GPH::ToggleTapMode();
-		if (GPH::tapmodeLevel == TAPMODE_LEFT) {
-			displayMessageOnOSD("Touchscreen 'Tap Mode': Left Click");
-		} else if (GPH::tapmodeLevel == TAPMODE_RIGHT) {
-			displayMessageOnOSD("Touchscreen 'Tap Mode': Right Click");
-		} else if (GPH::tapmodeLevel == TAPMODE_HOVER) {
-			displayMessageOnOSD("Touchscreen 'Tap Mode': Hover (No Click)");
-		}
-		break;
-	}
-	return true;
-}
-
-bool OSystem_GPH::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
-
-	_stickBtn[ev.jbutton.button] = 0;
-	event.kbd.flags = 0;
-
-	switch (ev.jbutton.button) {
-	case BUTTON_UP:
-	case BUTTON_UPLEFT:
-	case BUTTON_LEFT:
-	case BUTTON_DOWNLEFT:
-	case BUTTON_DOWN:
-	case BUTTON_DOWNRIGHT:
-	case BUTTON_RIGHT:
-	case BUTTON_UPRIGHT:
-		moveStick();
-		event.type = Common::EVENT_MOUSEMOVE;
-		fillMouseEvent(event, _km.x, _km.y);
-		break;
-	case BUTTON_B:
-	case BUTTON_CLICK:
-		event.type = Common::EVENT_LBUTTONUP;
-		fillMouseEvent(event, _km.x, _km.y);
-		break;
-	case BUTTON_X:
-		event.type = Common::EVENT_RBUTTONUP;
-		fillMouseEvent(event, _km.x, _km.y);
-		break;
-	case BUTTON_L:
-		BUTTON_STATE_L = false;
-		break;
-	case BUTTON_SELECT:
-	case BUTTON_HOME:
-		event.type = Common::EVENT_KEYUP;
-		event.kbd.keycode = Common::KEYCODE_ESCAPE;
-		event.kbd.ascii = mapKey(SDLK_ESCAPE, ev.key.keysym.mod, 0);
-		break;
-	case BUTTON_A:
-		event.type = Common::EVENT_KEYUP;
-		event.kbd.keycode = Common::KEYCODE_PERIOD;
-		event.kbd.ascii = mapKey(SDLK_PERIOD, ev.key.keysym.mod, 0);
-		break;
-	case BUTTON_Y:
-		event.type = Common::EVENT_KEYUP;
-		event.kbd.keycode = Common::KEYCODE_SPACE;
-		event.kbd.ascii = mapKey(SDLK_SPACE, ev.key.keysym.mod, 0);
-		break;
-	case BUTTON_MENU:
-	case BUTTON_HELP:
-		event.type = Common::EVENT_KEYUP;
-		if (BUTTON_STATE_L == true) {
-			event.type = Common::EVENT_MAINMENU;
-		} else {
-			event.kbd.keycode = Common::KEYCODE_F5;
-			event.kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
-		}
-		break;
-	case BUTTON_R:
-		event.type = Common::EVENT_KEYUP;
-		if (BUTTON_STATE_L == true) {
-#ifdef ENABLE_VKEYBD
-			event.kbd.keycode = Common::KEYCODE_F7;
-			event.kbd.ascii = mapKey(SDLK_F7, ev.key.keysym.mod, 0);
-#else
-			event.kbd.keycode = Common::KEYCODE_0;
-			event.kbd.ascii = mapKey(SDLK_0, ev.key.keysym.mod, 0);
-#endif
-		} else {
-			event.kbd.keycode = Common::KEYCODE_RETURN;
-			event.kbd.ascii = mapKey(SDLK_RETURN, ev.key.keysym.mod, 0);
-		}
-		break;
-	case BUTTON_VOLUP:
-		break;
-	case BUTTON_VOLDOWN:
-		break;
-	case BUTTON_HOLD:
-		break;
-	case BUTTON_HELP2:
-		break;
-	}
-	return true;
-}
-
-bool OSystem_GPH::remapKey(SDL_Event &ev,Common::Event &event) {
-	return false;
-}
diff --git a/backends/platform/gph/gph-graphics.cpp b/backends/platform/gph/gph-graphics.cpp
deleted file mode 100644
index 8fada7e..0000000
--- a/backends/platform/gph/gph-graphics.cpp
+++ /dev/null
@@ -1,470 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "backends/platform/gph/gph-sdl.h"
-
-#include "common/mutex.h"
-#include "graphics/font.h"
-#include "graphics/fontman.h"
-#include "graphics/scaler.h"
-#include "graphics/scaler/aspect.h"
-#include "graphics/scaler/downscaler.h"
-#include "graphics/surface.h"
-
-static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
-	{"1x", "Fullscreen", GFX_NORMAL},
-	{0, 0, 0}
-};
-
-const OSystem::GraphicsMode *OSystem_GPH::getSupportedGraphicsModes() const {
-	return s_supportedGraphicsModes;
-}
-
-int OSystem_GPH::getDefaultGraphicsMode() const {
-	return GFX_NORMAL;
-}
-
-bool OSystem_GPH::setGraphicsMode(int mode) {
-	Common::StackLock lock(_graphicsMutex);
-
-	assert(_transactionMode == kTransactionActive);
-
-	if (_oldVideoMode.setup && _oldVideoMode.mode == mode)
-		return true;
-
-	int newScaleFactor = 1;
-
-	switch (mode) {
-	case GFX_NORMAL:
-		newScaleFactor = 1;
-		break;
-	case GFX_HALF:
-		newScaleFactor = 1;
-		break;
-	default:
-		warning("unknown gfx mode %d", mode);
-		return false;
-	}
-
-	_transactionDetails.normal1xScaler = (mode == GFX_NORMAL);
-	if (_oldVideoMode.setup && _oldVideoMode.scaleFactor != newScaleFactor)
-		_transactionDetails.needHotswap = true;
-
-	_transactionDetails.needUpdatescreen = true;
-
-	_videoMode.mode = mode;
-	_videoMode.scaleFactor = newScaleFactor;
-
-	return true;
-}
-
-void OSystem_GPH::setGraphicsModeIntern() {
-	Common::StackLock lock(_graphicsMutex);
-	ScalerProc *newScalerProc = 0;
-
-	switch (_videoMode.mode) {
-	case GFX_NORMAL:
-		newScalerProc = Normal1x;
-		break;
-	case GFX_HALF:
-		newScalerProc = DownscaleAllByHalf;
-		break;
-
-	default:
-		error("Unknown gfx mode %d", _videoMode.mode);
-	}
-
-	_scalerProc = newScalerProc;
-
-	if (!_screen || !_hwscreen)
-		return;
-
-	// Blit everything to the screen
-	_forceFull = true;
-
-	// Even if the old and new scale factors are the same, we may have a
-	// different scaler for the cursor now.
-	blitCursor();
-}
-
-void OSystem_GPH::initSize(uint w, uint h) {
-	assert(_transactionMode == kTransactionActive);
-
-	// Avoid redundant res changes
-	if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight)
-		return;
-
-	_videoMode.screenWidth = w;
-	_videoMode.screenHeight = h;
-	if (w > 320 || h > 240){
-		setGraphicsMode(GFX_HALF);
-		setGraphicsModeIntern();
-		toggleMouseGrab();
-	}
-
-	_transactionDetails.sizeChanged = true;
-}
-
-bool OSystem_GPH::loadGFXMode() {
-	if (_videoMode.screenWidth > 320 || _videoMode.screenHeight > 240) {
-		_videoMode.aspectRatioCorrection = false;
-		setGraphicsMode(GFX_HALF);
-		printf("GFX_HALF\n");
-	} else {
-		setGraphicsMode(GFX_NORMAL);
-		printf("GFX_NORMAL\n");
-	}
-
-	if ((_videoMode.mode == GFX_HALF) && !_overlayVisible) {
-		_videoMode.overlayWidth = _videoMode.screenWidth / 2;
-		_videoMode.overlayHeight = _videoMode.screenHeight / 2;
-		_videoMode.fullscreen = true;
-	} else {
-
-		_videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
-		_videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
-
-		if (_videoMode.aspectRatioCorrection)
-			_videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight);
-
-		_videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
-		_videoMode.hardwareHeight = effectiveScreenHeight();
-	}
-	return OSystem_SDL::loadGFXMode();
-}
-
-void OSystem_GPH::drawMouse() {
-	if (!_mouseVisible || !_mouseSurface) {
-		_mouseBackup.x = _mouseBackup.y = _mouseBackup.w = _mouseBackup.h = 0;
-		return;
-	}
-
-	SDL_Rect dst;
-	int scale;
-	int width, height;
-	int hotX, hotY;
-
-	if (_videoMode.mode == GFX_HALF && !_overlayVisible){
-		dst.x = _mouseCurState.x/2;
-		dst.y = _mouseCurState.y/2;
-	} else {
-		dst.x = _mouseCurState.x;
-		dst.y = _mouseCurState.y;
-	}
-
-	if (!_overlayVisible) {
-		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 = _videoMode.overlayWidth;
-		height = _videoMode.overlayHeight;
-		dst.w = _mouseCurState.rW;
-		dst.h = _mouseCurState.rH;
-		hotX = _mouseCurState.rHotX;
-		hotY = _mouseCurState.rHotY;
-	}
-
-	// The mouse is undrawn using virtual coordinates, i.e. they may be
-	// scaled and aspect-ratio corrected.
-
-	_mouseBackup.x = dst.x - hotX;
-	_mouseBackup.y = dst.y - hotY;
-	_mouseBackup.w = dst.w;
-	_mouseBackup.h = dst.h;
-
-	// We draw the pre-scaled cursor image, so now we need to adjust for
-	// scaling, shake position and aspect ratio correction manually.
-
-	if (!_overlayVisible) {
-		dst.y += _currentShakePos;
-	}
-
-	if (_videoMode.aspectRatioCorrection && !_overlayVisible)
-		dst.y = real2Aspect(dst.y);
-
-	dst.x = scale * dst.x - _mouseCurState.rHotX;
-	dst.y = scale * dst.y - _mouseCurState.rHotY;
-	dst.w = _mouseCurState.rW;
-	dst.h = _mouseCurState.rH;
-
-	// Note that SDL_BlitSurface() and addDirtyRect() will both perform any
-	// clipping necessary
-
-	if (SDL_BlitSurface(_mouseSurface, NULL, _hwscreen, &dst) != 0)
-		error("SDL_BlitSurface failed: %s", SDL_GetError());
-
-	// The screen will be updated using real surface coordinates, i.e.
-	// they will not be scaled or aspect-ratio corrected.
-	addDirtyRect(dst.x, dst.y, dst.w, dst.h, true);
-}
-
-void OSystem_GPH::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 >= _videoMode.screenWidth || y >= _videoMode.screenHeight))
-		return;
-
-	if (_mouseBackup.w != 0 && _mouseBackup.h != 0){
-		if (_videoMode.mode == GFX_HALF && !_overlayVisible){
-			addDirtyRect(x*2, y*2, _mouseBackup.w*2, _mouseBackup.h*2);
-		} else {
-			addDirtyRect(x, y, _mouseBackup.w, _mouseBackup.h);
-		}
-	}
-}
-
-void OSystem_GPH::internUpdateScreen() {
-	SDL_Surface *srcSurf, *origSurf;
-	int height, width;
-	ScalerProc *scalerProc;
-	int scale1;
-
-#if defined (DEBUG)
-	assert(_hwscreen != NULL);
-	assert(_hwscreen->map->sw_data != NULL);
-#endif
-
-	// If the shake position changed, fill the dirty area with blackness
-	if (_currentShakePos != _newShakePos ||
-		(_mouseNeedsRedraw && _mouseBackup.y <= _currentShakePos)) {
-		SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _videoMode.scaleFactor, _newShakePos * _videoMode.scaleFactor};
-
-		if (_videoMode.aspectRatioCorrection && !_overlayVisible)
-			blackrect.h = real2Aspect(blackrect.h - 1) + 1;
-
-		SDL_FillRect(_hwscreen, &blackrect, 0);
-
-		_currentShakePos = _newShakePos;
-
-		_forceFull = true;
-	}
-
-	// Check whether the palette was changed in the meantime and update the
-	// screen surface accordingly.
-	if (_screen && _paletteDirtyEnd != 0) {
-		SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart,
-			_paletteDirtyStart,
-			_paletteDirtyEnd - _paletteDirtyStart);
-
-		_paletteDirtyEnd = 0;
-
-		_forceFull = true;
-	}
-
-#ifdef USE_OSD
-	// OSD visible (i.e. non-transparent)?
-	if (_osdAlpha != SDL_ALPHA_TRANSPARENT) {
-		// Updated alpha value
-		const int diff = SDL_GetTicks() - _osdFadeStartTime;
-		if (diff > 0) {
-			if (diff >= kOSDFadeOutDuration) {
-				// Back to full transparency
-				_osdAlpha = SDL_ALPHA_TRANSPARENT;
-			} else {
-				// Do a linear fade out...
-				const int startAlpha = SDL_ALPHA_TRANSPARENT + kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100;
-				_osdAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
-			}
-			SDL_SetAlpha(_osdSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, _osdAlpha);
-			_forceFull = true;
-		}
-	}
-#endif
-
-	if (!_overlayVisible) {
-		origSurf = _screen;
-		srcSurf = _tmpscreen;
-		width = _videoMode.screenWidth;
-		height = _videoMode.screenHeight;
-		scalerProc = _scalerProc;
-		scale1 = _videoMode.scaleFactor;
-	} else {
-		origSurf = _overlayscreen;
-		srcSurf = _tmpscreen2;
-		width = _videoMode.overlayWidth;
-		height = _videoMode.overlayHeight;
-		scalerProc = Normal1x;
-
-		scale1 = 1;
-	}
-
-	// Add the area covered by the mouse cursor to the list of dirty rects if
-	// we have to redraw the mouse.
-	if (_mouseNeedsRedraw)
-		undrawMouse();
-
-	// Force a full redraw if requested
-	if (_forceFull) {
-		_numDirtyRects = 1;
-		_dirtyRectList[0].x = 0;
-		_dirtyRectList[0].y = 0;
-		_dirtyRectList[0].w = width;
-		_dirtyRectList[0].h = height;
-	}
-
-	// Only draw anything if necessary
-	if (_numDirtyRects > 0 || _mouseNeedsRedraw) {
-		SDL_Rect *r;
-		SDL_Rect dst;
-		uint32 srcPitch, dstPitch;
-		SDL_Rect *lastRect = _dirtyRectList + _numDirtyRects;
-
-		for (r = _dirtyRectList; r != lastRect; ++r) {
-			dst = *r;
-			dst.x++;	// Shift rect by one since 2xSai needs to access the data around
-			dst.y++;	// any pixel to scale it, and we want to avoid mem access crashes.
-
-			if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)
-				error("SDL_BlitSurface failed: %s", SDL_GetError());
-		}
-
-		SDL_LockSurface(srcSurf);
-		SDL_LockSurface(_hwscreen);
-
-		srcPitch = srcSurf->pitch;
-		dstPitch = _hwscreen->pitch;
-
-		for (r = _dirtyRectList; r != lastRect; ++r) {
-			register int dst_y = r->y + _currentShakePos;
-			register int dst_h = 0;
-			register int dst_w = r->w;
-			register int orig_dst_y = 0;
-			register int dst_x = r->x;
-			register int src_y;
-			register int src_x;
-
-			if (dst_y < height) {
-				dst_h = r->h;
-				if (dst_h > height - dst_y)
-					dst_h = height - dst_y;
-
-				orig_dst_y = dst_y;
-				src_x = dst_x;
-				src_y = dst_y;
-
-				if (_videoMode.aspectRatioCorrection && !_overlayVisible)
-					dst_y = real2Aspect(dst_y);
-
-				assert(scalerProc != NULL);
-
-				if ((_videoMode.mode == GFX_HALF) && (scalerProc == DownscaleAllByHalf)) {
-					if (dst_x%2==1){
-						dst_x--;
-						dst_w++;
-					}
-					if (dst_y%2==1){
-						dst_y--;
-						dst_h++;
-					}
-					src_x = dst_x;
-					src_y = dst_y;
-					dst_x = dst_x / 2;
-					dst_y = dst_y / 2;
-
-					scalerProc((byte *)srcSurf->pixels + (src_x * 2 + 2) + (src_y + 1) * srcPitch, srcPitch,
-						   (byte *)_hwscreen->pixels + dst_x * 2 + dst_y * dstPitch, dstPitch, dst_w, dst_h);
-				} else {
-					scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
-					           (byte *)_hwscreen->pixels + r->x * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h);
-				}
-			}
-
-			if (_videoMode.mode == GFX_HALF && scalerProc == DownscaleAllByHalf){
-				r->w = r->w / 2;
-				r->h = dst_h / 2;
-			} else {
-				r->w = r->w;
-				r->h = dst_h;
-			}
-
-			r->x = dst_x;
-			r->y = dst_y;
-
-
-#ifdef USE_SCALERS
-			if (_videoMode.aspectRatioCorrection && 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.
-		if (_forceFull) {
-			_dirtyRectList[0].y = 0;
-			_dirtyRectList[0].h = (_videoMode.mode == GFX_HALF) ? effectiveScreenHeight()/2 : effectiveScreenHeight();
-		}
-
-		drawMouse();
-
-#ifdef USE_OSD
-		if (_osdAlpha != SDL_ALPHA_TRANSPARENT) {
-			SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0);
-		}
-#endif
-		// Finally, blit all our changes to the screen
-		SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
-	}
-
-	_numDirtyRects = 0;
-	_forceFull = false;
-	_mouseNeedsRedraw = false;
-}
-
-void OSystem_GPH::showOverlay() {
-	if (_videoMode.mode == GFX_HALF){
-		_mouseCurState.x = _mouseCurState.x / 2;
-		_mouseCurState.y = _mouseCurState.y / 2;
-	}
-	OSystem_SDL::showOverlay();
-}
-
-void OSystem_GPH::hideOverlay() {
-	if (_videoMode.mode == GFX_HALF){
-		_mouseCurState.x = _mouseCurState.x * 2;
-		_mouseCurState.y = _mouseCurState.y * 2;
-	}
-	OSystem_SDL::hideOverlay();
-}
-
-void OSystem_GPH::warpMouse(int x, int y) {
-	if (_mouseCurState.x != x || _mouseCurState.y != y) {
-		if (_videoMode.mode == GFX_HALF && !_overlayVisible){
-			x = x / 2;
-			y = y / 2;
-		}
-	}
-	OSystem_SDL::warpMouse(x, y);
-}
diff --git a/backends/platform/gph/gph-main.cpp b/backends/platform/gph/gph-main.cpp
index e711135..c7d691f 100644
--- a/backends/platform/gph/gph-main.cpp
+++ b/backends/platform/gph/gph-main.cpp
@@ -18,199 +18,34 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
- * $URL$
- * $Id$
- *
  */
 
-#include "backends/platform/sdl/sdl-sys.h"
-
-// #include "backends/platform/gph/gph-options.h"
 #include "backends/platform/gph/gph-sdl.h"
-#include "backends/platform/gph/gph-hw.h"
-#include "backends/plugins/posix/posix-provider.h"
+#include "backends/plugins/sdl/sdl-provider.h"
 #include "base/main.h"
 
-#include "common/archive.h"
-#include "common/config-manager.h"
-#include "common/debug.h"
-#include "common/events.h"
-#include "common/util.h"
-
-#include "common/file.h"
-#include "base/main.h"
-
-#include "backends/saves/default/default-saves.h"
-
-#include "backends/timer/default/default-timer.h"
-#include "audio/mixer_intern.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <time.h>	// for getTimeAndDate()
-
-/* Dump console info to files. */
-#define DUMP_STDOUT
+#if defined(GP2XWIZ) || defined(CAANOO)
 
 int main(int argc, char *argv[]) {
+
+	// Create our OSystem instance
 	g_system = new OSystem_GPH();
 	assert(g_system);
+
+	// Pre initialize the backend
+	((OSystem_GPH *)g_system)->init();
+
 #ifdef DYNAMIC_MODULES
-	PluginManager::instance().addPluginProvider(new POSIXPluginProvider());
+	PluginManager::instance().addPluginProvider(new SDLPluginProvider());
 #endif
 
 	// Invoke the actual ScummVM main entry point:
 	int res = scummvm_main(argc, argv);
-	g_system->quit();
-
-	return res;
-}
-
-void OSystem_GPH::initBackend() {
-
-	/* Setup default save path to be workingdir/saves */
-
-	char savePath[PATH_MAX+1];
-	char workDirName[PATH_MAX+1];
-
-	if (getcwd(workDirName, PATH_MAX) == NULL) {
-		error("Could not obtain current working directory");
-	} else {
-		printf("Current working directory: %s\n", workDirName);
-	}
-
-	strcpy(savePath, workDirName);
-	strcat(savePath, "/saves");
-	printf("Current save directory: %s\n", savePath);
-	struct stat sb;
-	if (stat(savePath, &sb) == -1)
-		if (errno == ENOENT) // Create the dir if it does not exist
-			if (mkdir(savePath, 0755) != 0)
-				warning("mkdir for '%s' failed!", savePath);
-
-	_savefile = new DefaultSaveFileManager(savePath);
-
-	#ifdef DUMP_STDOUT
-		// The GP2X Wiz has a serial console on the breakout board but most users do not use this so we
-		// output all our STDOUT and STDERR to files for debug purposes.
-		char STDOUT_FILE[PATH_MAX+1];
-		char STDERR_FILE[PATH_MAX+1];
-
-		strcpy(STDOUT_FILE, workDirName);
-		strcpy(STDERR_FILE, workDirName);
-		strcat(STDOUT_FILE, "/scummvm.stdout.txt");
-		strcat(STDERR_FILE, "/scummvm.stderr.txt");
-
-		// Flush the output in case anything is queued
-		fclose(stdout);
-		fclose(stderr);
-
-		// Redirect standard input and standard output
-		FILE *newfp = freopen(STDOUT_FILE, "w", stdout);
-		if (newfp == NULL) {
-		#if !defined(stdout)
-			stdout = fopen(STDOUT_FILE, "w");
-		#else
-			newfp = fopen(STDOUT_FILE, "w");
-			if (newfp) {
-				*stdout = *newfp;
-			}
-		#endif
-		}
-
-		newfp = freopen(STDERR_FILE, "w", stderr);
-		if (newfp == NULL) {
-		#if !defined(stderr)
-			stderr = fopen(STDERR_FILE, "w");
-		#else
-			newfp = fopen(STDERR_FILE, "w");
-			if (newfp) {
-				*stderr = *newfp;
-			}
-		#endif
-		}
 
-		setbuf(stderr, NULL);
-		printf("%s\n", "Debug: STDOUT and STDERR redirected to text files.");
-	#endif /* DUMP_STDOUT */
+	// Free OSystem
+	delete (OSystem_GPH *)g_system;
 
-	/* Initialise any GP2X Wiz specific stuff we may want (Batt Status, scaler etc.) */
-	WIZ_HW::deviceInit();
-
-	/* Set Default hardware mixer volume to a preset level (VOLUME_INITIAL). This is done to 'reset' volume level if set by other apps. */
-	WIZ_HW::mixerMoveVolume(0);
-
-	/* Up default volume values as we use a seperate system level volume anyway. */
-	ConfMan.registerDefault("music_volume", 192);
-	ConfMan.registerDefault("sfx_volume", 192);
-	ConfMan.registerDefault("speech_volume", 192);
-
-	/* Trigger autosave every 4 minutes - On low batts 5 mins is about your warning time. */
-	ConfMan.registerDefault("autosave_period", 4 * 60);
-
-	/* Make sure that aspect ratio correction is enabled on the 1st run to stop users asking me what the 'wasted space' is ;-). */
-	ConfMan.registerDefault("aspect_ratio", true);
-
-	/* Make sure SDL knows that we have a joystick we want to use. */
-	ConfMan.setInt("joystick_num", 0);
-
-	/* Now setup any device specific user options (Left handed mode, that sort of thing). */
-	// GPH::setOptions();
-
-	printf("%s\n", "Passing to OSystem::SDL initBackend.");
-
-	/* Pass to SDL backend to do the heavy lifting */
-	OSystem_SDL::initBackend();
-}
-
-void OSystem_GPH::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
-
-	/* Setup default extra data paths for engine data files and plugins */
-	char workDirName[PATH_MAX+1];
-
-	if (getcwd(workDirName, PATH_MAX) == NULL) {
-		error("Error: Could not obtain current working directory");
-	}
-
-	Common::FSNode workdirNode(workDirName);
-	if (workdirNode.exists() && workdirNode.isDirectory()) {
-		s.add("__GP2XWIZ_WORKDIR__", new Common::FSDirectory(workDirName), priority);
-	}
-
-	char enginedataPath[PATH_MAX+1];
-
-	strcpy(enginedataPath, workDirName);
-	strcat(enginedataPath, "/engine-data");
-
-	Common::FSNode engineNode(enginedataPath);
-	if (engineNode.exists() && engineNode.isDirectory()) {
-		s.add("__GP2XWIZ_ENGDATA__", new Common::FSDirectory(enginedataPath), priority);
-	}
-
-	char pluginsPath[PATH_MAX+1];
-
-	strcpy(pluginsPath, workDirName);
-	strcat(pluginsPath, "/plugins");
-
-	Common::FSNode pluginsNode(pluginsPath);
-	if (pluginsNode.exists() && pluginsNode.isDirectory()) {
-		s.add("__GP2XWIZ_PLUGINS__", new Common::FSDirectory(pluginsPath), priority);
-	}
+	return res;
 }
 
-void OSystem_GPH::quit() {
-
-	WIZ_HW::deviceDeinit();
-
-	#ifdef DUMP_STDOUT
-		printf("%s\n", "Debug: STDOUT and STDERR text files closed.");
-		fclose(stdout);
-		fclose(stderr);
-	#endif /* DUMP_STDOUT */
-
-	OSystem_SDL::quit();
-}
+#endif
diff --git a/backends/platform/gph/gph-sdl.h b/backends/platform/gph/gph-sdl.h
index 136363f..ef696bc 100644
--- a/backends/platform/gph/gph-sdl.h
+++ b/backends/platform/gph/gph-sdl.h
@@ -18,20 +18,18 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
- * $URL$
- * $Id$
- *
  */
 
-#ifndef GPH_SDL_H
-#define GPH_SDL_H
+#ifndef GPH_H
+#define GPH_H
 
-#include "backends/platform/sdl/sdl.h"
+#if defined(GP2XWIZ) || defined(CAANOO)
 
-// FIXME: For now keep hacks in this header to save polluting the SDL backend.
-enum {
-    GFX_HALF = 12
-};
+#include "backends/base-backend.h"
+#include "backends/platform/sdl/sdl.h"
+#include "backends/platform/sdl/posix/posix.h"
+#include "backends/graphics/gph/gph-graphics.h"
+#include "backends/events/gph/gph-events.h"
 
 #define __GP2XWIZ__
 #define MIXER_DOUBLE_BUFFERING 1
@@ -40,42 +38,13 @@ enum {
 	#define PATH_MAX 255
 #endif
 
-class OSystem_GPH : public OSystem_SDL {
+class OSystem_GPH : public OSystem_POSIX {
 public:
-	OSystem_GPH() {}
-
-	/* Graphics */
-    void initSize(uint w, uint h);
-    void setGraphicsModeIntern();
-    bool setGraphicsMode(int mode);
-    void internUpdateScreen();
-    const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
-	bool setGraphicsMode(const char *name);
-    int getDefaultGraphicsMode() const;
-    bool loadGFXMode();
-    void drawMouse();
-    void undrawMouse();
-    void showOverlay();
-    void hideOverlay();
-
-	/* Event Stuff */
-	void moveStick();
-	void fillMouseEvent(Common::Event&, int, int);
-	void warpMouse(int, int);
-	bool remapKey(SDL_Event&, Common::Event&);
-
 	/* Platform Setup Stuff */
 	void addSysArchivesToSearchSet(Common::SearchSet &s, int priority);
 	void initBackend();
 	void quit();
-
-protected:
-	bool _stickBtn[32];
-
-	bool handleMouseButtonDown(SDL_Event &ev, Common::Event &event);
-	bool handleMouseButtonUp(SDL_Event &ev, Common::Event &event);
-	bool handleJoyButtonDown(SDL_Event &ev, Common::Event &event);
-	bool handleJoyButtonUp(SDL_Event &ev, Common::Event &event);
 };
 
-#endif //GPH_SDL_H
+#endif
+#endif //GPH_H
diff --git a/backends/platform/gph/module.mk b/backends/platform/gph/module.mk
index f5567f5..a995149 100644
--- a/backends/platform/gph/module.mk
+++ b/backends/platform/gph/module.mk
@@ -1,10 +1,9 @@
 MODULE := backends/platform/gph
 
 MODULE_OBJS := \
-	gph-events.o \
-	gph-graphics.o \
-	gph-hw.o \
-	gph-main.o
+	gph-main.o \
+	gph-backend.o \
+	gph-hw.o
 
 # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
 MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))


Commit: 16e28747c7cfd00ccb4cd44493f15bb38faff958
    https://github.com/scummvm/scummvm/commit/16e28747c7cfd00ccb4cd44493f15bb38faff958
Author: David-John Willis (John.Willis at Distant-earth.com)
Date: 2011-03-24T14:24:05-07:00

Commit Message:
BACKENDS: Add GPH event and graphics files to the build.

Changed paths:
    backends/module.mk



diff --git a/backends/module.mk b/backends/module.mk
index 484f804..c8e0342 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -8,6 +8,7 @@ MODULE_OBJS := \
 	events/default/default-events.o \
 	events/dinguxsdl/dinguxsdl-events.o \
 	events/gp2xsdl/gp2xsdl-events.o \
+	events/gph/gph-events.o \
 	events/linuxmotosdl/linuxmotosdl-events.o \
 	events/samsungtvsdl/samsungtvsdl-events.o \
 	events/sdl/sdl-events.o \
@@ -21,6 +22,7 @@ MODULE_OBJS := \
 	fs/windows/windows-fs-factory.o \
 	graphics/dinguxsdl/dinguxsdl-graphics.o \
 	graphics/gp2xsdl/gp2xsdl-graphics.o \
+	graphics/gph/gph-graphics.o \
 	graphics/linuxmotosdl/linuxmotosdl-graphics.o \
 	graphics/opengl/glerrorcheck.o \
 	graphics/opengl/gltexture.o \


Commit: 0fb15847c6c195945b186aad9cc29dead154078a
    https://github.com/scummvm/scummvm/commit/0fb15847c6c195945b186aad9cc29dead154078a
Author: David-John Willis (John.Willis at Distant-earth.com)
Date: 2011-03-24T14:24:05-07:00

Commit Message:
SDL/POSIX: Update main guard to add OpenPandora.

 - Also mention GPH_DEVICE not each backend on it's own.

Changed paths:
    backends/platform/sdl/posix/posix-main.cpp



diff --git a/backends/platform/sdl/posix/posix-main.cpp b/backends/platform/sdl/posix/posix-main.cpp
index 10ed43f..72777e1 100644
--- a/backends/platform/sdl/posix/posix-main.cpp
+++ b/backends/platform/sdl/posix/posix-main.cpp
@@ -25,7 +25,7 @@
 
 #include "common/scummsys.h"
 
-#if defined(UNIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(LINUXMOTO) && !defined(GP2XWIZ) && !defined(GP2X) && !defined(DINGUX)
+#if defined(UNIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA)
 
 #include "backends/platform/sdl/posix/posix.h"
 #include "backends/plugins/sdl/sdl-provider.h"


Commit: b95013dfe25d75d39c7deb69ee1a63f93a4a495f
    https://github.com/scummvm/scummvm/commit/b95013dfe25d75d39c7deb69ee1a63f93a4a495f
Author: David-John Willis (John.Willis at Distant-earth.com)
Date: 2011-03-24T14:24:05-07:00

Commit Message:
OPENPANDORA: Refactor OpenPandora backend and move events and graphics into modular backend style.

Changed paths:
  A backends/events/openpandora/op-events.cpp
  A backends/events/openpandora/op-events.h
  A backends/graphics/openpandora/op-graphics.cpp
  A backends/graphics/openpandora/op-graphics.h
  A backends/platform/openpandora/op-backend.cpp
  R backends/platform/openpandora/op-events.cpp
  R backends/platform/openpandora/op-graphics.cpp
    backends/module.mk
    backends/platform/openpandora/module.mk
    backends/platform/openpandora/op-main.cpp
    backends/platform/openpandora/op-sdl.h



diff --git a/backends/events/openpandora/op-events.cpp b/backends/events/openpandora/op-events.cpp
new file mode 100644
index 0000000..381cbf8
--- /dev/null
+++ b/backends/events/openpandora/op-events.cpp
@@ -0,0 +1,186 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+/*
+ * OpenPandora: Device Specific Event Handling.
+ *
+ */
+
+#if defined(OPENPANDORA)
+
+#include "backends/events/openpandora/op-events.h"
+#include "backends/graphics/openpandora/op-graphics.h"
+#include "backends/platform/openpandora/op-sdl.h"
+#include "backends/platform/openpandora/op-options.h"
+
+/* Quick default button states for modifiers. */
+int BUTTON_STATE_L					=	false;
+
+enum {
+	/* Touchscreen TapMode */
+	TAPMODE_LEFT		= 0,
+	TAPMODE_RIGHT		= 1,
+	TAPMODE_HOVER		= 2
+};
+
+OPEventSource::OPEventSource()
+	: _buttonStateL(false){
+}
+
+/* On the OpenPandora by default the ABXY and L/R Trigger buttons are returned by SDL as
+   (A): SDLK_HOME (B): SDLK_END (X): SDLK_PAGEDOWN (Y): SDLK_PAGEUP (L): SDLK_RSHIFT (R): SDLK_RCTRL
+*/
+
+bool OPEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
+
+	if (ev.type == SDL_KEYDOWN) {
+		switch (ev.key.keysym.sym) {
+		case SDLK_HOME:
+			event.type = Common::EVENT_LBUTTONDOWN;
+			fillMouseEvent(event, _km.x, _km.y);
+			return true;
+			break;
+		case SDLK_END:
+			event.type = Common::EVENT_RBUTTONDOWN;
+			fillMouseEvent(event, _km.x, _km.y);
+			return true;
+			break;
+		case SDLK_PAGEDOWN:
+			event.type = Common::EVENT_MAINMENU;
+			return true;
+			break;
+		case SDLK_PAGEUP:
+			OP::ToggleTapMode();
+			if (OP::tapmodeLevel == TAPMODE_LEFT) {
+				g_system->displayMessageOnOSD("Touchscreen 'Tap Mode' - Left Click");
+			} else if (OP::tapmodeLevel == TAPMODE_RIGHT) {
+				g_system->displayMessageOnOSD("Touchscreen 'Tap Mode' - Right Click");
+			} else if (OP::tapmodeLevel == TAPMODE_HOVER) {
+				g_system->displayMessageOnOSD("Touchscreen 'Tap Mode' - Hover (No Click)");
+			}
+			break;
+		case SDLK_RSHIFT:
+			BUTTON_STATE_L = true;
+			break;
+		case SDLK_RCTRL:
+			break;
+		default:
+			return false;
+			break;
+		}
+		return false;
+	} else {
+		switch (ev.key.keysym.sym) {
+		case SDLK_HOME:
+			event.type = Common::EVENT_LBUTTONUP;
+			fillMouseEvent(event, _km.x, _km.y);
+			return true;
+			break;
+		case SDLK_END:
+			event.type = Common::EVENT_RBUTTONUP;
+			fillMouseEvent(event, _km.x, _km.y);
+			return true;
+			break;
+		case SDLK_PAGEDOWN:
+			event.type = Common::EVENT_MAINMENU;
+			return true;
+			break;
+		case SDLK_PAGEUP:
+			break;
+		case SDLK_RSHIFT:
+			BUTTON_STATE_L = false;
+			break;
+		case SDLK_RCTRL:
+			break;
+		default:
+			return false;
+			break;
+		}
+		return false;
+	}
+	return false;
+}
+
+/* Custom handleMouseButtonDown/handleMouseButtonUp to deal with 'Tap Mode' for the touchscreen */
+
+bool OPEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) {
+	if (ev.button.button == SDL_BUTTON_LEFT){
+		if (BUTTON_STATE_L == true) /* BUTTON_STATE_L = Left Trigger Held, force Right Click */
+			event.type = Common::EVENT_RBUTTONDOWN;
+		else if (OP::tapmodeLevel == TAPMODE_LEFT) /* TAPMODE_LEFT = Left Click Tap Mode */
+			event.type = Common::EVENT_LBUTTONDOWN;
+		else if (OP::tapmodeLevel == TAPMODE_RIGHT) /* TAPMODE_RIGHT = Right Click Tap Mode */
+			event.type = Common::EVENT_RBUTTONDOWN;
+		else if (OP::tapmodeLevel == TAPMODE_HOVER) /* TAPMODE_HOVER = Hover (No Click) Tap Mode */
+			event.type = Common::EVENT_MOUSEMOVE;
+		else
+			event.type = Common::EVENT_LBUTTONDOWN; /* For normal mice etc. */
+	}
+	else if (ev.button.button == SDL_BUTTON_RIGHT)
+		event.type = Common::EVENT_RBUTTONDOWN;
+#if defined(SDL_BUTTON_WHEELUP) && defined(SDL_BUTTON_WHEELDOWN)
+	else if (ev.button.button == SDL_BUTTON_WHEELUP)
+		event.type = Common::EVENT_WHEELUP;
+	else if (ev.button.button == SDL_BUTTON_WHEELDOWN)
+		event.type = Common::EVENT_WHEELDOWN;
+#endif
+#if defined(SDL_BUTTON_MIDDLE)
+	else if (ev.button.button == SDL_BUTTON_MIDDLE)
+		event.type = Common::EVENT_MBUTTONDOWN;
+#endif
+	else
+		return false;
+
+	fillMouseEvent(event, ev.button.x, ev.button.y);
+
+	return true;
+}
+
+bool OPEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
+	if (ev.button.button == SDL_BUTTON_LEFT){
+		if (BUTTON_STATE_L == true) /* BUTTON_STATE_L = Left Trigger Held, force Right Click */
+			event.type = Common::EVENT_RBUTTONUP;
+		else if (OP::tapmodeLevel == TAPMODE_LEFT) /* TAPMODE_LEFT = Left Click Tap Mode */
+			event.type = Common::EVENT_LBUTTONUP;
+		else if (OP::tapmodeLevel == TAPMODE_RIGHT) /* TAPMODE_RIGHT = Right Click Tap Mode */
+			event.type = Common::EVENT_RBUTTONUP;
+		else if (OP::tapmodeLevel == TAPMODE_HOVER) /* TAPMODE_HOVER = Hover (No Click) Tap Mode */
+			event.type = Common::EVENT_MOUSEMOVE;
+		else
+			event.type = Common::EVENT_LBUTTONUP; /* For normal mice etc. */
+	}
+	else if (ev.button.button == SDL_BUTTON_RIGHT)
+		event.type = Common::EVENT_RBUTTONUP;
+#if defined(SDL_BUTTON_MIDDLE)
+	else if (ev.button.button == SDL_BUTTON_MIDDLE)
+		event.type = Common::EVENT_MBUTTONUP;
+#endif
+	else
+		return false;
+
+	fillMouseEvent(event, ev.button.x, ev.button.y);
+
+	return true;
+}
+#endif
diff --git a/backends/events/openpandora/op-events.h b/backends/events/openpandora/op-events.h
new file mode 100644
index 0000000..4b13ef2
--- /dev/null
+++ b/backends/events/openpandora/op-events.h
@@ -0,0 +1,46 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if !defined(BACKEND_EVENTS_OP_H) && !defined(DISABLE_DEFAULT_EVENTMANAGER)
+#define BACKEND_EVENTS_OP_H
+
+#include "backends/events/sdl/sdl-events.h"
+
+/**
+ * Events manager for the OpenPandora.
+ */
+class OPEventSource : public SdlEventSource {
+public:
+	OPEventSource();
+
+protected:
+	/** Button state for L button modifier */
+	bool _buttonStateL;
+
+	bool remapKey(SDL_Event &ev, Common::Event &event);
+
+//private:
+	bool handleMouseButtonDown(SDL_Event &ev, Common::Event &event);
+	bool handleMouseButtonUp(SDL_Event &ev, Common::Event &event);
+};
+
+#endif /* BACKEND_EVENTS_OP_H */
diff --git a/backends/graphics/openpandora/op-graphics.cpp b/backends/graphics/openpandora/op-graphics.cpp
new file mode 100644
index 0000000..ab6974b
--- /dev/null
+++ b/backends/graphics/openpandora/op-graphics.cpp
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#if defined(OPENPANDORA)
+
+#include "backends/graphics/openpandora/op-graphics.h"
+#include "backends/events/openpandora/op-events.h"
+#include "backends/platform/openpandora/op-sdl.h"
+#include "common/mutex.h"
+#include "common/translation.h"
+#include "common/util.h"
+
+#include "graphics/scaler/aspect.h"
+#include "graphics/surface.h"
+
+OPGraphicsManager::OPGraphicsManager(SdlEventSource *boss)
+	: SdlGraphicsManager(boss) {
+}
+
+bool OPGraphicsManager::loadGFXMode() {
+	/* FIXME: For now we just cheat and set the overlay to 640*480 not 800*480 and let SDL
+	   deal with the boarders (it saves cleaning up the overlay when the game screen is
+	   smaller than the overlay ;)
+	*/
+	_videoMode.overlayWidth = 640;
+	_videoMode.overlayHeight = 480;
+	_videoMode.fullscreen = true;
+
+	if (_videoMode.screenHeight != 200 && _videoMode.screenHeight != 400)
+		_videoMode.aspectRatioCorrection = false;
+
+	return SdlGraphicsManager::loadGFXMode();
+}
+
+#endif
diff --git a/backends/graphics/openpandora/op-graphics.h b/backends/graphics/openpandora/op-graphics.h
new file mode 100644
index 0000000..b0d4298
--- /dev/null
+++ b/backends/graphics/openpandora/op-graphics.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_OP_H
+#define BACKENDS_GRAPHICS_OP_H
+
+#include "backends/graphics/sdl/sdl-graphics.h"
+#include "graphics/scaler/aspect.h"	// for aspect2Real
+#include "graphics/scaler/downscaler.h"
+
+enum {
+	GFX_HALF = 12
+};
+
+class OPGraphicsManager : public SdlGraphicsManager {
+public:
+	OPGraphicsManager(SdlEventSource *boss);
+
+	bool hasFeature(OSystem::Feature f);
+	void setFeatureState(OSystem::Feature f, bool enable);
+	bool getFeatureState(OSystem::Feature f);
+	int getDefaultGraphicsMode() const;
+
+	void initSize(uint w, uint h);
+	const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
+	bool setGraphicsMode(const char *name);
+	bool setGraphicsMode(int mode);
+	void setGraphicsModeIntern();
+	void internUpdateScreen();
+	void showOverlay();
+	void hideOverlay();
+	bool loadGFXMode();
+	void drawMouse();
+	void undrawMouse();
+	virtual void warpMouse(int x, int y);
+
+	SdlGraphicsManager::MousePos *getMouseCurState();
+	SdlGraphicsManager::VideoState *getVideoMode();
+
+	virtual void adjustMouseEvent(const Common::Event &event);
+};
+
+#endif /* BACKENDS_GRAPHICS_OP_H */
diff --git a/backends/module.mk b/backends/module.mk
index c8e0342..c562aea 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -10,6 +10,7 @@ MODULE_OBJS := \
 	events/gp2xsdl/gp2xsdl-events.o \
 	events/gph/gph-events.o \
 	events/linuxmotosdl/linuxmotosdl-events.o \
+	events/openpandora/op-events.o \
 	events/samsungtvsdl/samsungtvsdl-events.o \
 	events/sdl/sdl-events.o \
 	events/symbiansdl/symbiansdl-events.o \
@@ -28,6 +29,7 @@ MODULE_OBJS := \
 	graphics/opengl/gltexture.o \
 	graphics/opengl/opengl-graphics.o \
 	graphics/openglsdl/openglsdl-graphics.o \
+	graphics/openpandora/op-graphics.o \
 	graphics/sdl/sdl-graphics.o \
 	graphics/symbiansdl/symbiansdl-graphics.o \
 	graphics/wincesdl/wincesdl-graphics.o \
diff --git a/backends/platform/openpandora/module.mk b/backends/platform/openpandora/module.mk
index 1e5f6bc..8e60b87 100755
--- a/backends/platform/openpandora/module.mk
+++ b/backends/platform/openpandora/module.mk
@@ -1,9 +1,8 @@
 MODULE := backends/platform/openpandora
 
 MODULE_OBJS := \
-	op-graphics.o \
-	op-events.o \
 	op-options.o \
+	op-backend.o \
 	op-main.o
 
 MODULE_DIRS += \
diff --git a/backends/platform/openpandora/op-backend.cpp b/backends/platform/openpandora/op-backend.cpp
new file mode 100644
index 0000000..5b33392
--- /dev/null
+++ b/backends/platform/openpandora/op-backend.cpp
@@ -0,0 +1,273 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "backends/platform/openpandora/op-sdl.h"
+#include "base/main.h"
+
+#include "backends/saves/default/default-saves.h"
+
+#include "common/archive.h"
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/events.h"
+#include "common/util.h"
+
+#include "common/file.h"
+#include "base/main.h"
+
+#include "backends/saves/default/default-saves.h"
+
+#include "backends/timer/default/default-timer.h"
+#include "audio/mixer_intern.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <time.h>	// for getTimeAndDate()
+
+/* Dump console info to files. */
+#define DUMP_STDOUT
+
+static SDL_Cursor *hiddenCursor;
+
+static Uint32 timer_handler(Uint32 interval, void *param) {
+	((DefaultTimerManager *)param)->handler();
+	return interval;
+}
+
+void OSystem_OP::initBackend() {
+
+	assert(!_inited);
+
+//	int joystick_num = ConfMan.getInt("joystick_num");
+//	uint32 sdlFlags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
+//
+//	if (ConfMan.hasKey("disable_sdl_parachute"))
+//		sdlFlags |= SDL_INIT_NOPARACHUTE;
+//
+//	if (joystick_num > -1)
+//		sdlFlags |= SDL_INIT_JOYSTICK;
+//
+//	if (SDL_Init(sdlFlags) == -1) {
+//		error("Could not initialize SDL: %s", SDL_GetError());
+//	}
+//
+
+	/* Setup default save path to be workingdir/saves */
+
+	char savePath[PATH_MAX+1];
+	char workDirName[PATH_MAX+1];
+
+	if (getcwd(workDirName, PATH_MAX) == NULL) {
+		error("Could not obtain current working directory.");
+	} else {
+		printf("Current working directory: %s\n", workDirName);
+	}
+
+	strcpy(savePath, workDirName);
+	strcat(savePath, "/../saves");
+	printf("Current save directory: %s\n", savePath);
+	struct stat sb;
+	if (stat(savePath, &sb) == -1)
+		if (errno == ENOENT) // Create the dir if it does not exist
+			if (mkdir(savePath, 0755) != 0)
+				warning("mkdir for '%s' failed!", savePath);
+
+//	_savefileManager = new DefaultSaveFileManager(savePath);
+
+	#ifdef DUMP_STDOUT
+		// The OpenPandora has a serial console on the EXT connection but most users do not use this so we
+		// output all our STDOUT and STDERR to files for debug purposes.
+		char STDOUT_FILE[PATH_MAX+1];
+		char STDERR_FILE[PATH_MAX+1];
+
+		strcpy(STDOUT_FILE, workDirName);
+		strcpy(STDERR_FILE, workDirName);
+		strcat(STDOUT_FILE, "/scummvm.stdout.txt");
+		strcat(STDERR_FILE, "/scummvm.stderr.txt");
+
+		// Flush the output in case anything is queued
+		fclose(stdout);
+		fclose(stderr);
+
+		// Redirect standard input and standard output
+		FILE *newfp = freopen(STDOUT_FILE, "w", stdout);
+		if (newfp == NULL) {
+		#if !defined(stdout)
+			stdout = fopen(STDOUT_FILE, "w");
+		#else
+			newfp = fopen(STDOUT_FILE, "w");
+			if (newfp) {
+				*stdout = *newfp;
+			}
+		#endif
+		}
+
+		newfp = freopen(STDERR_FILE, "w", stderr);
+		if (newfp == NULL) {
+		#if !defined(stderr)
+			stderr = fopen(STDERR_FILE, "w");
+		#else
+			newfp = fopen(STDERR_FILE, "w");
+			if (newfp) {
+				*stderr = *newfp;
+			}
+		#endif
+		}
+
+		setbuf(stderr, NULL);
+		printf("%s\n", "Debug: STDOUT and STDERR redirected to text files.");
+	#endif /* DUMP_STDOUT */
+
+	/* Trigger autosave every 4 minutes. */
+	ConfMan.registerDefault("autosave_period", 4 * 60);
+
+	ConfMan.registerDefault("fullscreen", true);
+
+	/* Make sure that aspect ratio correction is enabled on the 1st run to stop
+	   users asking me what the 'wasted space' at the bottom is ;-). */
+	ConfMan.registerDefault("aspect_ratio", true);
+
+	/* Make sure SDL knows that we have a joystick we want to use. */
+	ConfMan.setInt("joystick_num", 0);
+
+	// Create the events manager
+	if (_eventSource == 0)
+		_eventSource = new OPEventSource();
+
+	// Create the graphics manager
+	if (_graphicsManager == 0)
+		_graphicsManager = new OPGraphicsManager(_eventSource);
+
+//	_graphicsMutex = createMutex();
+
+	// Invoke parent implementation of this method
+	OSystem_POSIX::initBackend();
+
+	_inited = true;
+}
+
+
+
+	// enable joystick
+//	if (joystick_num > -1 && SDL_NumJoysticks() > 0) {
+//		printf("Using joystick: %s\n", SDL_JoystickName(0));
+//		_joystick = SDL_JoystickOpen(joystick_num);
+//	}
+//
+//	setupMixer();
+
+	// 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.
+	// 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);
+
+void OSystem_OP::initSDL() {
+	// Check if SDL has not been initialized
+	if (!_initedSDL) {
+
+		uint32 sdlFlags = SDL_INIT_EVENTTHREAD;
+		if (ConfMan.hasKey("disable_sdl_parachute"))
+			sdlFlags |= SDL_INIT_NOPARACHUTE;
+
+		// Initialize SDL (SDL Subsystems are initiliazed in the corresponding sdl managers)
+		if (SDL_Init(sdlFlags) == -1)
+			error("Could not initialize SDL: %s", SDL_GetError());
+
+    	uint8_t hiddenCursorData = 0;
+
+    	hiddenCursor = SDL_CreateCursor(&hiddenCursorData, &hiddenCursorData, 8, 1, 0, 0);
+
+		/* On the OpenPandora we need to work around an SDL assumption that
+		   returns relative mouse coordinates when you get to the screen
+		   edges using the touchscreen. The workaround is to set a blank
+		   SDL cursor and not disable it (Hackish I know).
+
+		   The root issues likes in the Windows Manager GRAB code in SDL.
+		   That is why the issue is not seen on framebuffer devices like the
+		   GP2X (there is no X window manager ;)).
+		*/
+		SDL_ShowCursor(SDL_ENABLE);
+		SDL_SetCursor(hiddenCursor);
+		SDL_EnableUNICODE(1);
+
+//		memset(&_oldVideoMode, 0, sizeof(_oldVideoMode));
+//		memset(&_videoMode, 0, sizeof(_videoMode));
+//		memset(&_transactionDetails, 0, sizeof(_transactionDetails));
+
+//		_videoMode.mode = GFX_DOUBLESIZE;
+//		_videoMode.scaleFactor = 2;
+//		_videoMode.aspectRatioCorrection = ConfMan.getBool("aspect_ratio");
+//		_scalerProc = Normal2x;
+//		_scalerType = 0;
+
+//		_videoMode.fullscreen = true;
+
+		_initedSDL = true;
+	}
+}
+
+void OSystem_OP::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
+
+	/* Setup default extra data paths for engine data files and plugins */
+
+	char workDirName[PATH_MAX+1];
+
+	if (getcwd(workDirName, PATH_MAX) == NULL) {
+		error("Error: Could not obtain current working directory.");
+	}
+
+	char enginedataPath[PATH_MAX+1];
+
+	strcpy(enginedataPath, workDirName);
+	strcat(enginedataPath, "/../data");
+	printf("Default engine data directory: %s\n", enginedataPath);
+
+	Common::FSNode engineNode(enginedataPath);
+	if (engineNode.exists() && engineNode.isDirectory()) {
+		s.add("__OP_ENGDATA__", new Common::FSDirectory(enginedataPath), priority);
+	}
+}
+
+void OSystem_OP::quit() {
+
+	SDL_FreeCursor(hiddenCursor);
+
+	#ifdef DUMP_STDOUT
+		printf("%s\n", "Debug: STDOUT and STDERR text files closed.");
+		fclose(stdout);
+		fclose(stderr);
+	#endif /* DUMP_STDOUT */
+
+	OSystem_POSIX::quit();
+}
diff --git a/backends/platform/openpandora/op-events.cpp b/backends/platform/openpandora/op-events.cpp
deleted file mode 100644
index 24283aa..0000000
--- a/backends/platform/openpandora/op-events.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-/*
- * OpenPandora: Device Specific Event Handling.
- *
- */
-
-#include "backends/platform/openpandora/op-sdl.h"
-#include "backends/platform/openpandora/op-options.h"
-
-/* Quick default button states for modifiers. */
-int BUTTON_STATE_L					=	false;
-
-enum {
-	/* Touchscreen TapMode */
-	TAPMODE_LEFT		= 0,
-	TAPMODE_RIGHT		= 1,
-	TAPMODE_HOVER		= 2
-};
-
-/* On the OpenPandora by default the ABXY and L/R Trigger buttons are returned by SDL as
-   (A): SDLK_HOME (B): SDLK_END (X): SDLK_PAGEDOWN (Y): SDLK_PAGEUP (L): SDLK_RSHIFT (R): SDLK_RCTRL
-*/
-
-bool OSystem_OP::handleKeyDown(SDL_Event &ev, Common::Event &event) {
-	switch (ev.key.keysym.sym) {
-	case SDLK_HOME:
-		event.type = Common::EVENT_LBUTTONDOWN;
-		fillMouseEvent(event, _km.x, _km.y);
-		return true;
-		break;
-	case SDLK_END:
-		event.type = Common::EVENT_RBUTTONDOWN;
-		fillMouseEvent(event, _km.x, _km.y);
-		return true;
-		break;
-	case SDLK_PAGEDOWN:
-		event.type = Common::EVENT_MAINMENU;
-		return true;
-		break;
-	case SDLK_PAGEUP:
-		OP::ToggleTapMode();
-		if (OP::tapmodeLevel == TAPMODE_LEFT) {
-			displayMessageOnOSD("Touchscreen 'Tap Mode' - Left Click");
-		} else if (OP::tapmodeLevel == TAPMODE_RIGHT) {
-			displayMessageOnOSD("Touchscreen 'Tap Mode' - Right Click");
-		} else if (OP::tapmodeLevel == TAPMODE_HOVER) {
-			displayMessageOnOSD("Touchscreen 'Tap Mode' - Hover (No Click)");
-		}
-		break;
-	case SDLK_RSHIFT:
-		BUTTON_STATE_L = true;
-		break;
-	case SDLK_RCTRL:
-		break;
-	default:
-		return OSystem_SDL::handleKeyDown(ev, event);
-		break;
-	}
-	return false;
-}
-
-bool OSystem_OP::handleKeyUp(SDL_Event &ev, Common::Event &event) {
-	switch (ev.key.keysym.sym) {
-	case SDLK_HOME:
-		event.type = Common::EVENT_LBUTTONUP;
-		fillMouseEvent(event, _km.x, _km.y);
-		return true;
-		break;
-	case SDLK_END:
-		event.type = Common::EVENT_RBUTTONUP;
-		fillMouseEvent(event, _km.x, _km.y);
-		return true;
-		break;
-	case SDLK_PAGEDOWN:
-		event.type = Common::EVENT_MAINMENU;
-		return true;
-		break;
-	case SDLK_PAGEUP:
-		break;
-	case SDLK_RSHIFT:
-		BUTTON_STATE_L = false;
-		break;
-	case SDLK_RCTRL:
-		break;
-	default:
-		return OSystem_SDL::handleKeyUp(ev, event);
-		break;
-	}
-	return false;
-}
-
-/* Custom handleMouseButtonDown/handleMouseButtonUp to deal with 'Tap Mode' for the touchscreen */
-
-bool OSystem_OP::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) {
-	if (ev.button.button == SDL_BUTTON_LEFT){
-		if (BUTTON_STATE_L == true) /* BUTTON_STATE_L = Left Trigger Held, force Right Click */
-			event.type = Common::EVENT_RBUTTONDOWN;
-		else if (OP::tapmodeLevel == TAPMODE_LEFT) /* TAPMODE_LEFT = Left Click Tap Mode */
-			event.type = Common::EVENT_LBUTTONDOWN;
-		else if (OP::tapmodeLevel == TAPMODE_RIGHT) /* TAPMODE_RIGHT = Right Click Tap Mode */
-			event.type = Common::EVENT_RBUTTONDOWN;
-		else if (OP::tapmodeLevel == TAPMODE_HOVER) /* TAPMODE_HOVER = Hover (No Click) Tap Mode */
-			event.type = Common::EVENT_MOUSEMOVE;
-		else
-			event.type = Common::EVENT_LBUTTONDOWN; /* For normal mice etc. */
-	}
-	else if (ev.button.button == SDL_BUTTON_RIGHT)
-		event.type = Common::EVENT_RBUTTONDOWN;
-#if defined(SDL_BUTTON_WHEELUP) && defined(SDL_BUTTON_WHEELDOWN)
-	else if (ev.button.button == SDL_BUTTON_WHEELUP)
-		event.type = Common::EVENT_WHEELUP;
-	else if (ev.button.button == SDL_BUTTON_WHEELDOWN)
-		event.type = Common::EVENT_WHEELDOWN;
-#endif
-#if defined(SDL_BUTTON_MIDDLE)
-	else if (ev.button.button == SDL_BUTTON_MIDDLE)
-		event.type = Common::EVENT_MBUTTONDOWN;
-#endif
-	else
-		return false;
-
-	fillMouseEvent(event, ev.button.x, ev.button.y);
-
-	return true;
-}
-
-bool OSystem_OP::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
-	if (ev.button.button == SDL_BUTTON_LEFT){
-		if (BUTTON_STATE_L == true) /* BUTTON_STATE_L = Left Trigger Held, force Right Click */
-			event.type = Common::EVENT_RBUTTONUP;
-		else if (OP::tapmodeLevel == TAPMODE_LEFT) /* TAPMODE_LEFT = Left Click Tap Mode */
-			event.type = Common::EVENT_LBUTTONUP;
-		else if (OP::tapmodeLevel == TAPMODE_RIGHT) /* TAPMODE_RIGHT = Right Click Tap Mode */
-			event.type = Common::EVENT_RBUTTONUP;
-		else if (OP::tapmodeLevel == TAPMODE_HOVER) /* TAPMODE_HOVER = Hover (No Click) Tap Mode */
-			event.type = Common::EVENT_MOUSEMOVE;
-		else
-			event.type = Common::EVENT_LBUTTONUP; /* For normal mice etc. */
-	}
-	else if (ev.button.button == SDL_BUTTON_RIGHT)
-		event.type = Common::EVENT_RBUTTONUP;
-#if defined(SDL_BUTTON_MIDDLE)
-	else if (ev.button.button == SDL_BUTTON_MIDDLE)
-		event.type = Common::EVENT_MBUTTONUP;
-#endif
-	else
-		return false;
-
-	fillMouseEvent(event, ev.button.x, ev.button.y);
-
-	return true;
-}
diff --git a/backends/platform/openpandora/op-graphics.cpp b/backends/platform/openpandora/op-graphics.cpp
deleted file mode 100644
index ef95f52..0000000
--- a/backends/platform/openpandora/op-graphics.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "backends/platform/openpandora/op-sdl.h"
-#include "common/mutex.h"
-#include "common/translation.h"
-#include "common/util.h"
-
-#include "graphics/scaler/aspect.h"
-#include "graphics/surface.h"
-
-bool OSystem_OP::loadGFXMode() {
-	/* FIXME: For now we just cheat and set the overlay to 640*480 not 800*480 and let SDL
-	   deal with the boarders (it saves cleaning up the overlay when the game screen is
-	   smaller than the overlay ;)
-	*/
-	_videoMode.overlayWidth = 640;
-	_videoMode.overlayHeight = 480;
-	_videoMode.fullscreen = true;
-
-	if (_videoMode.screenHeight != 200 && _videoMode.screenHeight != 400)
-		_videoMode.aspectRatioCorrection = false;
-
-	OSystem_SDL::loadGFXMode();
-
-	return true;
-
-}
diff --git a/backends/platform/openpandora/op-main.cpp b/backends/platform/openpandora/op-main.cpp
index 6e64bad..ab777fe 100644
--- a/backends/platform/openpandora/op-main.cpp
+++ b/backends/platform/openpandora/op-main.cpp
@@ -18,250 +18,36 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
- * $URL$
- * $Id$
- *
  */
 
-// Disable symbol overrides so that we can use system headers.
-#define FORBIDDEN_SYMBOL_ALLOW_ALL
 
 #include "backends/platform/sdl/sdl-sys.h"
-
 #include "backends/platform/openpandora/op-sdl.h"
 #include "backends/plugins/posix/posix-provider.h"
 #include "base/main.h"
 
-#include "common/archive.h"
-#include "common/config-manager.h"
-#include "common/debug.h"
-#include "common/events.h"
-#include "common/util.h"
-
-#include "common/file.h"
-#include "base/main.h"
-
-#include "backends/saves/default/default-saves.h"
-
-#include "backends/timer/default/default-timer.h"
-#include "audio/mixer_intern.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <time.h>	// for getTimeAndDate()
-
-/* Dump console info to files. */
-#define DUMP_STDOUT
-
-static SDL_Cursor *hiddenCursor;
+#if defined(OPENPANDORA)
 
 int main(int argc, char *argv[]) {
+
+	// Create our OSystem instance
 	g_system = new OSystem_OP();
 	assert(g_system);
 
+	// Pre initialize the backend
+	//((OSystem_OP *)g_system)->init();
+
 #ifdef DYNAMIC_MODULES
 	PluginManager::instance().addPluginProvider(new POSIXPluginProvider());
 #endif
 
 	// Invoke the actual ScummVM main entry point:
 	int res = scummvm_main(argc, argv);
-	g_system->quit();
-
-	return res;
-}
-
-static Uint32 timer_handler(Uint32 interval, void *param) {
-	((DefaultTimerManager *)param)->handler();
-	return interval;
-}
-
-void OSystem_OP::initBackend() {
-
-	assert(!_inited);
-
-    uint8_t hiddenCursorData = 0;
-
-	int joystick_num = ConfMan.getInt("joystick_num");
-	uint32 sdlFlags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
-
-	if (ConfMan.hasKey("disable_sdl_parachute"))
-		sdlFlags |= SDL_INIT_NOPARACHUTE;
-
-	if (joystick_num > -1)
-		sdlFlags |= SDL_INIT_JOYSTICK;
-
-	if (SDL_Init(sdlFlags) == -1) {
-		error("Could not initialize SDL: %s", SDL_GetError());
-	}
-
-    hiddenCursor = SDL_CreateCursor(&hiddenCursorData, &hiddenCursorData, 8, 1, 0, 0);
-
-	/* Setup default save path to be workingdir/saves */
-
-	char savePath[PATH_MAX+1];
-	char workDirName[PATH_MAX+1];
-
-	if (getcwd(workDirName, PATH_MAX) == NULL) {
-		error("Could not obtain current working directory.");
-	} else {
-		printf("Current working directory: %s\n", workDirName);
-	}
-
-	strcpy(savePath, workDirName);
-	strcat(savePath, "/../saves");
-	printf("Current save directory: %s\n", savePath);
-	struct stat sb;
-	if (stat(savePath, &sb) == -1)
-		if (errno == ENOENT) // Create the dir if it does not exist
-			if (mkdir(savePath, 0755) != 0)
-				warning("mkdir for '%s' failed!", savePath);
-
-	_savefile = new DefaultSaveFileManager(savePath);
-
-	#ifdef DUMP_STDOUT
-		// The OpenPandora has a serial console on the EXT connection but most users do not use this so we
-		// output all our STDOUT and STDERR to files for debug purposes.
-		char STDOUT_FILE[PATH_MAX+1];
-		char STDERR_FILE[PATH_MAX+1];
-
-		strcpy(STDOUT_FILE, workDirName);
-		strcpy(STDERR_FILE, workDirName);
-		strcat(STDOUT_FILE, "/scummvm.stdout.txt");
-		strcat(STDERR_FILE, "/scummvm.stderr.txt");
-
-		// Flush the output in case anything is queued
-		fclose(stdout);
-		fclose(stderr);
 
-		// Redirect standard input and standard output
-		FILE *newfp = freopen(STDOUT_FILE, "w", stdout);
-		if (newfp == NULL) {
-		#if !defined(stdout)
-			stdout = fopen(STDOUT_FILE, "w");
-		#else
-			newfp = fopen(STDOUT_FILE, "w");
-			if (newfp) {
-				*stdout = *newfp;
-			}
-		#endif
-		}
+	// Free OSystem
+	delete (OSystem_OP *)g_system;
 
-		newfp = freopen(STDERR_FILE, "w", stderr);
-		if (newfp == NULL) {
-		#if !defined(stderr)
-			stderr = fopen(STDERR_FILE, "w");
-		#else
-			newfp = fopen(STDERR_FILE, "w");
-			if (newfp) {
-				*stderr = *newfp;
-			}
-		#endif
-		}
-
-		setbuf(stderr, NULL);
-		printf("%s\n", "Debug: STDOUT and STDERR redirected to text files.");
-	#endif /* DUMP_STDOUT */
-
-	/* Trigger autosave every 4 minutes. */
-	ConfMan.registerDefault("autosave_period", 4 * 60);
-
-	ConfMan.registerDefault("fullscreen", true);
-
-	/* Make sure that aspect ratio correction is enabled on the 1st run to stop
-	   users asking me what the 'wasted space' at the bottom is ;-). */
-	ConfMan.registerDefault("aspect_ratio", true);
-
-	/* Make sure SDL knows that we have a joystick we want to use. */
-	ConfMan.setInt("joystick_num", 0);
-
-	_graphicsMutex = createMutex();
-
-	/* On the OpenPandora we need to work around an SDL assumption that
-	   returns relative mouse coordinates when you get to the screen
-	   edges using the touchscreen. The workaround is to set a blank
-	   SDL cursor and not disable it (Hackish I know).
-
-	   The root issues likes in the Windows Manager GRAB code in SDL.
-	   That is why the issue is not seen on framebuffer devices like the
-	   GP2X (there is no X window manager ;)).
-	*/
-	SDL_ShowCursor(SDL_ENABLE);
-	SDL_SetCursor(hiddenCursor);
-
-	// Enable unicode support if possible
-	SDL_EnableUNICODE(1);
-
-	memset(&_oldVideoMode, 0, sizeof(_oldVideoMode));
-	memset(&_videoMode, 0, sizeof(_videoMode));
-	memset(&_transactionDetails, 0, sizeof(_transactionDetails));
-
-	_videoMode.mode = GFX_DOUBLESIZE;
-	_videoMode.scaleFactor = 2;
-	_videoMode.aspectRatioCorrection = ConfMan.getBool("aspect_ratio");
-	_scalerProc = Normal2x;
-	_scalerType = 0;
-
-	_videoMode.fullscreen = true;
-
-	// enable joystick
-	if (joystick_num > -1 && SDL_NumJoysticks() > 0) {
-		printf("Using joystick: %s\n", SDL_JoystickName(0));
-		_joystick = SDL_JoystickOpen(joystick_num);
-	}
-
-	setupMixer();
-
-	// 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.
-	// 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);
-
-	// Invoke parent implementation of this method
-	OSystem::initBackend();
-
-	_inited = true;
-}
-
-void OSystem_OP::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
-
-	/* Setup default extra data paths for engine data files and plugins */
-
-	char workDirName[PATH_MAX+1];
-
-	if (getcwd(workDirName, PATH_MAX) == NULL) {
-		error("Error: Could not obtain current working directory.");
-	}
-
-	char enginedataPath[PATH_MAX+1];
-
-	strcpy(enginedataPath, workDirName);
-	strcat(enginedataPath, "/../data");
-	printf("Default engine data directory: %s\n", enginedataPath);
-
-	Common::FSNode engineNode(enginedataPath);
-	if (engineNode.exists() && engineNode.isDirectory()) {
-		s.add("__OP_ENGDATA__", new Common::FSDirectory(enginedataPath), priority);
-	}
+	return res;
 }
 
-void OSystem_OP::quit() {
-
-	SDL_FreeCursor(hiddenCursor);
-
-	#ifdef DUMP_STDOUT
-		printf("%s\n", "Debug: STDOUT and STDERR text files closed.");
-		fclose(stdout);
-		fclose(stderr);
-	#endif /* DUMP_STDOUT */
-
-	OSystem_SDL::quit();
-}
+#endif
diff --git a/backends/platform/openpandora/op-sdl.h b/backends/platform/openpandora/op-sdl.h
index 8561b42..93c82ca 100644
--- a/backends/platform/openpandora/op-sdl.h
+++ b/backends/platform/openpandora/op-sdl.h
@@ -18,15 +18,18 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
- * $URL$
- * $Id$
- *
  */
 
 #ifndef OP_SDL_H
 #define OP_SDL_H
 
+#if defined(OPENPANDORA)
+
+#include "backends/base-backend.h"
 #include "backends/platform/sdl/sdl.h"
+#include "backends/platform/sdl/posix/posix.h"
+#include "backends/events/openpandora/op-events.h"
+#include "backends/graphics/openpandora/op-graphics.h"
 
 #define __OPENPANDORA__
 #define MIXER_DOUBLE_BUFFERING 1
@@ -35,25 +38,18 @@
 	#define PATH_MAX 255
 #endif
 
-class OSystem_OP : public OSystem_SDL {
+class OSystem_OP : public OSystem_POSIX {
 public:
 	OSystem_OP() {}
 
-	/* Events */
-	bool handleKeyDown(SDL_Event &ev, Common::Event &event);
-	bool handleKeyUp(SDL_Event &ev, Common::Event &event);
-	bool handleMouseButtonDown(SDL_Event &ev, Common::Event &event);
-	bool handleMouseButtonUp(SDL_Event &ev, Common::Event &event);
-
-	/* Graphics */
-	bool loadGFXMode();
-
 	/* Platform Setup Stuff */
 	void addSysArchivesToSearchSet(Common::SearchSet &s, int priority);
 	void initBackend();
+	void initSDL();
 	void quit();
 
 protected:
 
 };
 #endif
+#endif //OP_SDL_H






More information about the Scummvm-git-logs mailing list