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

fingolfin max at quendi.de
Tue Mar 8 13:15:28 CET 2011


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

Summary:
aa452d3aeb WINCE: Make scummvm compile and run again for WinCE platform (patch #3202337)


Commit: aa452d3aeb3e2506c7386554d5dfbe852b8ae475
    https://github.com/scummvm/scummvm/commit/aa452d3aeb3e2506c7386554d5dfbe852b8ae475
Author: Max Horn (max at quendi.de)
Date: 2011-03-08T03:53:41-08:00

Commit Message:
WINCE: Make scummvm compile and run again for WinCE platform (patch #3202337)

Changed paths:
  A backends/events/wincesdl/wincesdl-events.cpp
  A backends/events/wincesdl/wincesdl-events.h
  A backends/graphics/wincesdl/wincesdl-graphics.cpp
  A backends/graphics/wincesdl/wincesdl-graphics.h
  A backends/mixer/wincesdl/wincesdl-mixer.cpp
  A backends/mixer/wincesdl/wincesdl-mixer.h
    backends/graphics/sdl/sdl-graphics.cpp
    backends/module.mk
    backends/platform/wince/CEActionsPocket.cpp
    backends/platform/wince/CEActionsSmartphone.cpp
    backends/platform/wince/CEDevice.cpp
    backends/platform/wince/CEDevice.h
    backends/platform/wince/wince-sdl.cpp
    backends/platform/wince/wince-sdl.h



diff --git a/backends/events/wincesdl/wincesdl-events.cpp b/backends/events/wincesdl/wincesdl-events.cpp
new file mode 100644
index 0000000..86b2fd6
--- /dev/null
+++ b/backends/events/wincesdl/wincesdl-events.cpp
@@ -0,0 +1,327 @@
+/* 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 "common/scummsys.h"
+
+#ifdef _WIN32_WCE
+
+#include "common/config-manager.h"
+
+#include "backends/events/wincesdl/wincesdl-events.h"
+#include "backends/graphics/wincesdl/wincesdl-graphics.h"
+#include "backends/platform/wince/CEActionsPocket.h"
+#include "backends/platform/wince/CEActionsSmartphone.h"
+#include "backends/platform/wince/CEDevice.h"
+
+#include "backends/platform/sdl/sdl.h"
+
+WINCESdlEventSource::WINCESdlEventSource()
+	: _tapTime(0), _closeClick(false), _rbutton(false),
+	_freeLook(false) {
+}
+
+void WINCESdlEventSource::fillMouseEvent(Common::Event &event, int x, int y) {
+	event.mouse.x = x;
+	event.mouse.y = y;
+
+	// Update the "keyboard mouse" coords
+	_km.x = event.mouse.x;
+	_km.y = event.mouse.y;
+
+	// Adjust for the screen scaling
+	if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_zoomDown)
+		event.mouse.y += 240;
+
+	event.mouse.x = event.mouse.x * ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_scaleFactorXd / ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_scaleFactorXm;
+	event.mouse.y = event.mouse.y * ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_scaleFactorYd / ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_scaleFactorYm;
+}
+
+bool WINCESdlEventSource::pollEvent(Common::Event &event) {
+	SDL_Event ev;
+	ev.type = SDL_NOEVENT;
+	DWORD currentTime;
+	bool keyEvent = false;
+	int deltaX, deltaY;
+
+	memset(&event, 0, sizeof(Common::Event));
+
+	handleKbdMouse();
+
+	// If the screen changed, send an Common::EVENT_SCREEN_CHANGED
+	int screenID = ((OSystem_SDL *)g_system)->getGraphicsManager()->getScreenChangeID();
+	if (screenID != _lastScreenID) {
+		_lastScreenID = screenID;
+		event.type = Common::EVENT_SCREEN_CHANGED;
+		return true;
+	}
+
+	CEDevice::wakeUp();
+
+	currentTime = GetTickCount();
+
+	while (SDL_PollEvent(&ev)) {
+		switch (ev.type) {
+		case SDL_KEYDOWN:
+			debug(1, "Key down %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));
+			// KMOD_RESERVED is used if the key has been injected by an external buffer
+			if (ev.key.keysym.mod != KMOD_RESERVED && !GUI::Actions::Instance()->mappingActive()) {
+				keyEvent = true;
+				((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed = ev.key.keysym.sym;
+				((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeatTime = currentTime;
+				((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeat = 0;
+
+				if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, true))
+					return true;
+			}
+
+			if (GUI_Actions::Instance()->mappingActive())
+				event.kbd.flags = 0xFF;
+			else if (ev.key.keysym.sym == SDLK_PAUSE) {
+				((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed = 0;
+				event.type = Common::EVENT_PREDICTIVE_DIALOG;
+				return true;
+			} 			event.type = Common::EVENT_KEYDOWN;
+			if (!GUI::Actions::Instance()->mappingActive())
+				event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
+			else
+				event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive());
+			event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive());
+
+			if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
+				event.kbd.ascii ^= 0x20;
+				event.kbd.flags = Common::KBD_SHIFT;
+			}
+
+			return true;
+
+		case SDL_KEYUP:
+			debug(1, "Key up %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));
+			// KMOD_RESERVED is used if the key has been injected by an external buffer
+			if (ev.key.keysym.mod != KMOD_RESERVED && !GUI::Actions::Instance()->mappingActive()) {
+				keyEvent = true;
+				((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed = 0;
+
+				if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, false))
+					return true;
+			}
+
+			if (GUI_Actions::Instance()->mappingActive())
+				event.kbd.flags = 0xFF;
+			else if (ev.key.keysym.sym == SDLK_PAUSE) {
+				((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed = 0;
+				return false;	// chew up the show agi dialog key up event
+			}
+
+			event.type = Common::EVENT_KEYUP;
+			if (!GUI::Actions::Instance()->mappingActive())
+				event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
+			else
+				event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive());
+			event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive());
+
+			if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
+				event.kbd.ascii ^= 0x20;
+				event.kbd.flags = Common::KBD_SHIFT;
+			}
+
+			return true;
+
+		case SDL_MOUSEMOTION:
+			event.type = Common::EVENT_MOUSEMOVE;
+			fillMouseEvent(event, ev.motion.x, ev.motion.y);
+			((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->setMousePos(event.mouse.x, event.mouse.y);
+
+			return true;
+
+		case SDL_MOUSEBUTTONDOWN:
+			if (ev.button.button == SDL_BUTTON_LEFT)
+				event.type = Common::EVENT_LBUTTONDOWN;
+			else if (ev.button.button == SDL_BUTTON_RIGHT)
+				event.type = Common::EVENT_RBUTTONDOWN;
+			else
+				break;
+			fillMouseEvent(event, ev.button.x, ev.button.y);
+
+
+			if (event.mouse.x > _tapX)
+				deltaX = event.mouse.x - _tapX;
+			else
+				deltaX = _tapX - event.mouse.x;
+			if (event.mouse.y > _tapY)
+				deltaY = event.mouse.y - _tapY;
+			else
+				deltaY = _tapY - event.mouse.y;
+			_closeClick = (deltaX <= 5 && deltaY <= 5);
+
+			if (!_isSmartphone) {
+				// handle double-taps
+				if (_tapTime) {		// second tap
+					if (_closeClick && (GetTickCount() - _tapTime < 1000)) {
+						if ( event.mouse.y <= 20 &&
+								((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_panelInitialized) {
+							// top of screen (show panel)
+							((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_panel_visibility();
+						} else if (!((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_noDoubleTapRMB) {
+							// right click
+							event.type = Common::EVENT_RBUTTONDOWN;
+							_rbutton = true;
+						}
+					}
+					_tapTime = 0;
+				} else {
+					_tapTime = GetTickCount();
+					_tapX = event.mouse.x;
+					_tapY = event.mouse.y;
+				}
+			}
+
+			if (_freeLook && !_closeClick) {
+				_rbutton = false;
+				_tapTime = 0;
+				_tapX = event.mouse.x;
+				_tapY = event.mouse.y;
+				event.type = Common::EVENT_MOUSEMOVE;
+				((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->setMousePos(event.mouse.x, event.mouse.y);
+			}
+
+
+			if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHandler.action(event.mouse.x, event.mouse.y, true)) {
+				if (!((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHandler.drawn()) {
+					((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHighDrawn = false;
+					((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->internUpdateScreen();
+				}
+				if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_newOrientation != ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_orientationLandscape){
+					((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_orientationLandscape = ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_newOrientation;
+					((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHighDrawn = false;
+					ConfMan.setInt("landscape", ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_orientationLandscape);
+					ConfMan.flushToDisk();
+					((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->hotswapGFXMode();
+				}
+				return false;
+			}
+
+			return true;
+
+		case SDL_MOUSEBUTTONUP:
+			if (ev.button.button == SDL_BUTTON_LEFT)
+				event.type = Common::EVENT_LBUTTONUP;
+			else if (ev.button.button == SDL_BUTTON_RIGHT)
+				event.type = Common::EVENT_RBUTTONUP;
+			else
+				break;
+
+			if (_rbutton) {
+				event.type = Common::EVENT_RBUTTONUP;
+				_rbutton = false;
+			}
+
+			fillMouseEvent(event, ev.button.x, ev.button.y);
+
+			if (_freeLook && !_closeClick) {
+				_tapX = event.mouse.x;
+				_tapY = event.mouse.y;
+				event.type = Common::EVENT_MOUSEMOVE;
+				((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->setMousePos(event.mouse.x, event.mouse.y);
+			}
+
+			if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHandler.action(event.mouse.x, event.mouse.y, false)) {
+				if (!((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHandler.drawn()) {
+					((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHighDrawn = false;
+					((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->internUpdateScreen();
+				}
+				return false;
+
+			}
+			return true;
+
+		case SDL_VIDEOEXPOSE:
+			// HACK: Send a fake event, handled by SdlGraphicsManager
+			event.type = (Common::EventType)OSystem_SDL::kSdlEventExpose;
+			break;
+
+		case SDL_QUIT:
+			event.type = Common::EVENT_QUIT;
+			return true;
+
+		case SDL_ACTIVEEVENT:
+			if (ev.active.state & SDL_APPMOUSEFOCUS)
+				debug(2, "%s mouse focus.", ev.active.gain ? "Got" : "Lost");
+			if (ev.active.state & SDL_APPINPUTFOCUS)
+				debug(2, "%s input focus.", ev.active.gain ? "Got" : "Lost");
+			if (ev.active.state & SDL_APPACTIVE)
+				debug(2, "%s total focus.", ev.active.gain ? "Got" : "Lost");
+			if (ev.active.state & SDL_APPINPUTFOCUS) {
+				((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_hasfocus = ev.active.gain;
+				SDL_PauseAudio(!((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_hasfocus);
+				if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_hasfocus) {
+					event.type = (Common::EventType)OSystem_SDL::kSdlEventExpose;
+				}
+			}
+			break;
+		}
+	}
+
+	// Simulate repeated key for backend
+	if (!keyEvent && ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed && (int)currentTime > ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeatTime + ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeatTrigger) {
+		((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeatTime = currentTime;
+		((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeat++;
+		GUI_Actions::Instance()->performMapped(((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed, true);
+	}
+
+	return false;
+}
+
+int WINCESdlEventSource::mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode, bool unfilter) {
+	if (GUI::Actions::Instance()->mappingActive())
+		return key;
+
+	if (unfilter) {
+		switch (key) {
+		case SDLK_ESCAPE:
+			return SDLK_BACKSPACE;
+		case SDLK_F8:
+			return SDLK_ASTERISK;
+		case SDLK_F9:
+			return SDLK_HASH;
+		default:
+			return key;
+		}
+	}
+
+	if (key >= SDLK_KP0 && key <= SDLK_KP9) {
+		return key - SDLK_KP0 + '0';
+	} else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) {
+		return key;
+	} else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) {
+		return 0;
+	}
+	return key;
+}
+
+void WINCESdlEventSource::swap_freeLook() {
+	_freeLook = !_freeLook;
+}
+
+#endif /* _WIN32_WCE */
diff --git a/backends/events/wincesdl/wincesdl-events.h b/backends/events/wincesdl/wincesdl-events.h
new file mode 100644
index 0000000..4c5b194
--- /dev/null
+++ b/backends/events/wincesdl/wincesdl-events.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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef BACKENDS_EVENTS_SDL_WINCE_H
+#define BACKENDS_EVENTS_SDL_WINCE_H
+
+#include "backends/events/sdl/sdl-events.h"
+
+extern bool _isSmartphone;
+
+class WINCESdlEventSource : public SdlEventSource {
+public:
+	WINCESdlEventSource();
+
+	void loadDeviceConfiguration();
+
+	// Overloaded from SDL backend (toolbar handling)
+	bool pollEvent(Common::Event &event);
+	// Overloaded from SDL backend (mouse and new scaler handling)
+	void fillMouseEvent(Common::Event &event, int x, int y);
+
+	void swap_freeLook();
+
+protected:
+
+private:
+	int mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode, bool unfilter);
+
+	// Keyboard tap
+	int _tapX;
+	int _tapY;
+	long _tapTime;
+
+	bool _closeClick;			// flag when taps are spatially close together
+	bool _rbutton;				// double tap -> right button simulation
+	bool _freeLook;				// freeLook mode (do not send mouse button events)
+
+};
+
+#endif /* BACKENDS_EVENTS_SDL_WINCE_H */
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index d8b686e..7d36786 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -161,13 +161,6 @@ SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *sdlEventSource)
 
 	_graphicsMutex = g_system->createMutex();
 
-#ifdef _WIN32_WCE
-	if (ConfMan.hasKey("use_GDI") && ConfMan.getBool("use_GDI")) {
-		SDL_VideoInit("windib", 0);
-		sdlFlags ^= SDL_INIT_VIDEO;
-	}
-#endif
-
 	SDL_ShowCursor(SDL_DISABLE);
 
 	memset(&_oldVideoMode, 0, sizeof(_oldVideoMode));
diff --git a/backends/graphics/wincesdl/wincesdl-graphics.cpp b/backends/graphics/wincesdl/wincesdl-graphics.cpp
new file mode 100644
index 0000000..ad1a8e7
--- /dev/null
+++ b/backends/graphics/wincesdl/wincesdl-graphics.cpp
@@ -0,0 +1,1638 @@
+/* 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 "common/scummsys.h"
+
+#ifdef _WIN32_WCE
+
+#include "common/system.h"
+#include "common/translation.h"
+#include "common/mutex.h"
+
+#include "graphics/scaler/downscaler.h"
+#include "graphics/scaler/aspect.h"
+#include "backends/graphics/wincesdl/wincesdl-graphics.h"
+#include "backends/events/wincesdl/wincesdl-events.h"
+#include "backends/platform/wince/wince-sdl.h"
+
+#include "backends/platform/wince/resource.h"
+#include "backends/platform/wince/CEActionsPocket.h"
+#include "backends/platform/wince/CEActionsSmartphone.h"
+#include "backends/platform/wince/CEDevice.h"
+#include "backends/platform/wince/CEScaler.h"
+#include "backends/platform/wince/CEgui/ItemAction.h"
+
+WINCESdlGraphicsManager::WINCESdlGraphicsManager(SdlEventSource *sdlEventSource)
+	: SdlGraphicsManager(sdlEventSource),
+	_panelInitialized(false), _noDoubleTapRMB(false),
+	_toolbarHighDrawn(false), _newOrientation(0), _orientationLandscape(0),
+	_panelVisible(true), _saveActiveToolbar(NAME_MAIN_PANEL), _panelStateForced(false),
+	_canBeAspectScaled(false), _scalersChanged(false), _saveToolbarState(false),
+	_mouseBackupOld(NULL), _mouseBackupDim(0), _mouseBackupToolbar(NULL),
+	_usesEmulatedMouse(false), _forceHideMouse(false), _hasfocus(true),
+	_zoomUp(false), _zoomDown(false) {
+	memset(&_mouseCurState, 0, sizeof(_mouseCurState));
+	if (_isSmartphone) {
+		_mouseCurState.x = 20;
+		_mouseCurState.y = 20;
+	}
+
+	loadDeviceConfigurationElement("repeatTrigger", _keyRepeatTrigger, 200);
+	loadDeviceConfigurationElement("repeatX", _repeatX, 4);
+	loadDeviceConfigurationElement("repeatY", _repeatY, 4);
+	loadDeviceConfigurationElement("stepX1", _stepX1, 2);
+	loadDeviceConfigurationElement("stepX2", _stepX2, 10);
+	loadDeviceConfigurationElement("stepX3", _stepX3, 40);
+	loadDeviceConfigurationElement("stepY1", _stepY1, 2);
+	loadDeviceConfigurationElement("stepY2", _stepY2, 10);
+	loadDeviceConfigurationElement("stepY3", _stepY3, 20);
+	ConfMan.flushToDisk();
+
+	_isSmartphone = CEDevice::isSmartphone();
+
+	// Query SDL for screen size and init screen dependent stuff
+	OSystem_WINCE3::initScreenInfos();
+	create_toolbar();
+	_hasSmartphoneResolution = CEDevice::hasSmartphoneResolution() || CEDevice::isSmartphone();
+	if (_hasSmartphoneResolution)
+		_panelVisible = false;	// init correctly in smartphones
+
+	_screen = NULL;
+}
+
+// Graphics mode consts
+
+// Low end devices 240x320
+
+static const OSystem::GraphicsMode s_supportedGraphicsModesLow[] = {
+	{"1x", _s("Normal (no scaling)"), GFX_NORMAL},
+	{0, 0, 0}
+};
+
+// High end device 480x640
+
+static const OSystem::GraphicsMode s_supportedGraphicsModesHigh[] = {
+	{"1x", _s("Normal (no scaling)"), GFX_NORMAL},
+	{"2x", "2x", GFX_DOUBLESIZE},
+#ifndef _MSC_VER // EVC breaks template functions, and I'm tired of fixing them :)
+	{"2xsai", "2xSAI", GFX_2XSAI},
+	{"super2xsai", "Super2xSAI", GFX_SUPER2XSAI},
+	{"supereagle", "SuperEagle", GFX_SUPEREAGLE},
+#endif
+	{"advmame2x", "AdvMAME2x", GFX_ADVMAME2X},
+#ifndef _MSC_VER
+	{"hq2x", "HQ2x", GFX_HQ2X},
+	{"tv2x", "TV2x", GFX_TV2X},
+#endif
+	{"dotmatrix", "DotMatrix", GFX_DOTMATRIX},
+	{0, 0, 0}
+};
+
+const OSystem::GraphicsMode *WINCESdlGraphicsManager::getSupportedGraphicsModes() const {
+	if (CEDevice::hasWideResolution())
+		return s_supportedGraphicsModesHigh;
+	else
+		return s_supportedGraphicsModesLow;
+}
+
+bool WINCESdlGraphicsManager::hasFeature(OSystem::Feature f) {
+	return (f == OSystem::kFeatureVirtualKeyboard);
+}
+
+void WINCESdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
+	switch (f) {
+	case OSystem::kFeatureFullscreenMode:
+		return;
+
+	case OSystem::kFeatureVirtualKeyboard:
+		if (_hasSmartphoneResolution)
+			return;
+		_toolbarHighDrawn = false;
+		if (enable) {
+			_panelStateForced = true;
+			if (!_toolbarHandler.visible()) swap_panel_visibility();
+			//_saveToolbarState = _toolbarHandler.visible();
+			_saveActiveToolbar = _toolbarHandler.activeName();
+			_toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
+			_toolbarHandler.setVisible(true);
+		} else
+			if (_panelStateForced) {
+				_panelStateForced = false;
+				_toolbarHandler.setActive(_saveActiveToolbar);
+				//_toolbarHandler.setVisible(_saveToolbarState);
+			}
+		return;
+
+	case OSystem::kFeatureDisableKeyFiltering:
+		if (_hasSmartphoneResolution) {
+			GUI::Actions::Instance()->beginMapping(enable);
+		}
+		return;
+
+	default:
+		SdlGraphicsManager::setFeatureState(f, enable);
+	}
+}
+
+bool WINCESdlGraphicsManager::getFeatureState(OSystem::Feature f) {
+	switch (f) {
+	case OSystem::kFeatureFullscreenMode:
+		return false;
+	case OSystem::kFeatureVirtualKeyboard:
+		return (_panelStateForced);
+	default:
+		return SdlGraphicsManager::getFeatureState(f);
+	}
+}
+
+int WINCESdlGraphicsManager::getDefaultGraphicsMode() const {
+	return GFX_NORMAL;
+}
+
+void WINCESdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFormat *format) {
+	if (_hasSmartphoneResolution && h == 240)
+		h = 200;  // mainly for the launcher
+
+	if (_isSmartphone && !ConfMan.hasKey("landscape")) {
+		ConfMan.setInt("landscape", 1);
+		ConfMan.flushToDisk();
+	}
+
+	_canBeAspectScaled = false;
+	if (w == 320 && h == 200 && !_hasSmartphoneResolution) {
+		_canBeAspectScaled = true;
+		h = 240; // use the extra 40 pixels height for the toolbar
+	}
+
+	if (h == 400)	// touche engine fixup
+		h += 80;
+
+	if (!_hasSmartphoneResolution) {
+		if (h == 240)
+			_toolbarHandler.setOffset(200);
+		else
+			_toolbarHandler.setOffset(400);
+	} else {
+		if (h == 240)
+			_toolbarHandler.setOffset(200);
+		else	// 176x220
+			_toolbarHandler.setOffset(0);
+	}
+
+	if (w != (uint) _videoMode.screenWidth || h != (uint) _videoMode.screenHeight)
+		_scalersChanged = false;
+
+	_videoMode.overlayWidth = w;
+	_videoMode.overlayHeight = h;
+
+	SdlGraphicsManager::initSize(w, h, format);
+
+	if (_scalersChanged) {
+		unloadGFXMode();
+		loadGFXMode();
+		_scalersChanged = false;
+	}
+
+	update_game_settings();
+}
+
+void WINCESdlGraphicsManager::loadDeviceConfigurationElement(Common::String element, int &value, int defaultValue) {
+	value = ConfMan.getInt(element, ConfMan.kApplicationDomain);
+	if (!value) {
+		value = defaultValue;
+		ConfMan.setInt(element, value, ConfMan.kApplicationDomain);
+	}
+}
+
+void WINCESdlGraphicsManager::move_cursor_up() {
+	int x, y;
+	_usesEmulatedMouse = true;
+	retrieve_mouse_location(x, y);
+	if (_keyRepeat > _repeatY)
+		y -= _stepY3;
+	else if (_keyRepeat)
+		y -= _stepY2;
+	else
+		y -= _stepY1;
+
+	if (y < 0)
+		y = 0;
+
+	EventsBuffer::simulateMouseMove(x, y);
+}
+
+void WINCESdlGraphicsManager::move_cursor_down() {
+	int x, y;
+	_usesEmulatedMouse = true;
+	retrieve_mouse_location(x, y);
+	if (_keyRepeat > _repeatY)
+		y += _stepY3;
+	else if (_keyRepeat)
+		y += _stepY2;
+	else
+		y += _stepY1;
+
+	if (y > _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd)
+		y = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd;
+
+	EventsBuffer::simulateMouseMove(x, y);
+}
+
+void WINCESdlGraphicsManager::move_cursor_left() {
+	int x, y;
+	_usesEmulatedMouse = true;
+	retrieve_mouse_location(x, y);
+	if (_keyRepeat > _repeatX)
+		x -= _stepX3;
+	else if (_keyRepeat)
+		x -= _stepX2;
+	else
+		x -= _stepX1;
+
+	if (x < 0)
+		x = 0;
+
+	EventsBuffer::simulateMouseMove(x, y);
+}
+
+void WINCESdlGraphicsManager::move_cursor_right() {
+	int x, y;
+	_usesEmulatedMouse = true;
+	retrieve_mouse_location(x, y);
+	if (_keyRepeat > _repeatX)
+		x += _stepX3;
+	else if (_keyRepeat)
+		x += _stepX2;
+	else
+		x += _stepX1;
+
+	if (x > _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd)
+		x = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd;
+
+	EventsBuffer::simulateMouseMove(x, y);
+}
+
+void WINCESdlGraphicsManager::retrieve_mouse_location(int &x, int &y) {
+	x = _mouseCurState.x;
+	y = _mouseCurState.y;
+
+	x = x * _scaleFactorXm / _scaleFactorXd;
+	y = y * _scaleFactorYm / _scaleFactorYd;
+
+	if (_zoomDown)
+		y -= 240;
+}
+
+void WINCESdlGraphicsManager::switch_zone() {
+	int x, y;
+	int i;
+	retrieve_mouse_location(x, y);
+
+	for (i = 0; i < TOTAL_ZONES; i++)
+		if (x >= _zones[i].x && y >= _zones[i].y &&
+			x <= _zones[i].x + _zones[i].width && y <= _zones[i].y + _zones[i].height) {
+				_mouseXZone[i] = x;
+				_mouseYZone[i] = y;
+				break;
+		}
+	_currentZone = i + 1;
+	if (_currentZone >= TOTAL_ZONES)
+		_currentZone = 0;
+
+	EventsBuffer::simulateMouseMove(_mouseXZone[_currentZone], _mouseYZone[_currentZone]);
+}
+
+void WINCESdlGraphicsManager::add_right_click(bool pushed) {
+	int x, y;
+	retrieve_mouse_location(x, y);
+	EventsBuffer::simulateMouseRightClick(x, y, pushed);
+}
+
+void WINCESdlGraphicsManager::add_left_click(bool pushed) {
+	int x, y;
+	retrieve_mouse_location(x, y);
+	EventsBuffer::simulateMouseLeftClick(x, y, pushed);
+}
+
+bool WINCESdlGraphicsManager::update_scalers() {
+	_videoMode.aspectRatioCorrection = false;
+
+	if (CEDevice::hasPocketPCResolution()) {
+		if (_videoMode.mode != GFX_NORMAL)
+			return false;
+
+		if ((!_orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth))
+			|| CEDevice::hasSquareQVGAResolution() ) {
+			if (OSystem_WINCE3::getScreenWidth() != 320) {
+				_scaleFactorXm = 3;
+				_scaleFactorXd = 4;
+				_scaleFactorYm = 1;
+				_scaleFactorYd = 1;
+				_scalerProc = DownscaleHorizByThreeQuarters;
+			} else {
+				_scaleFactorXm = 1;
+				_scaleFactorXd = 1;
+				_scaleFactorYm = 1;
+				_scaleFactorYd = 1;
+				_scalerProc = Normal1x;
+			}
+		} else if ( _orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth)) {
+			if (!_panelVisible && !_hasSmartphoneResolution  && !_overlayVisible && _canBeAspectScaled) {
+				_scaleFactorXm = 1;
+				_scaleFactorXd = 1;
+				_scaleFactorYm = 6;
+				_scaleFactorYd = 5;
+				_scalerProc = Normal1xAspect;
+				_videoMode.aspectRatioCorrection = true;
+			} else {
+				_scaleFactorXm = 1;
+				_scaleFactorXd = 1;
+				_scaleFactorYm = 1;
+				_scaleFactorYd = 1;
+				_scalerProc = Normal1x;
+			}
+		} else if (_videoMode.screenWidth == 640 && !(OSystem_WINCE3::isOzone() && (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640))) {
+			_scaleFactorXm = 1;
+			_scaleFactorXd = 2;
+			_scaleFactorYm = 1;
+			_scaleFactorYd = 2;
+			_scalerProc = DownscaleAllByHalf;
+		} else if (_videoMode.screenWidth == 640 && (OSystem_WINCE3::isOzone() && (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640))) {
+			_scaleFactorXm = 1;
+			_scaleFactorXd = 1;
+			_scaleFactorYm = 1;
+			_scaleFactorYd = 1;
+			_scalerProc = Normal1x;
+		}
+
+		return true;
+	} else if (CEDevice::hasWideResolution()) {
+#ifdef USE_ARM_SCALER_ASM
+		if ( _videoMode.mode == GFX_DOUBLESIZE && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth) ) {
+			if ( !_panelVisible && !_overlayVisible && _canBeAspectScaled ) {
+				_scaleFactorXm = 2;
+				_scaleFactorXd = 1;
+				_scaleFactorYm = 12;
+				_scaleFactorYd = 5;
+				_scalerProc = Normal2xAspect;
+				_videoMode.aspectRatioCorrection = true;
+			} else if ( (_panelVisible || _overlayVisible) && _canBeAspectScaled ) {
+				_scaleFactorXm = 2;
+				_scaleFactorXd = 1;
+				_scaleFactorYm = 2;
+				_scaleFactorYd = 1;
+				_scalerProc = Normal2x;
+			}
+			return true;
+		}
+#endif
+	} else if (CEDevice::hasSmartphoneResolution()) {
+		if (_videoMode.mode != GFX_NORMAL)
+			return false;
+
+		if (_videoMode.screenWidth > 320)
+			error("Game resolution not supported on Smartphone");
+#ifdef ARM
+		_scaleFactorXm = 11;
+		_scaleFactorXd = 16;
+#else
+		_scaleFactorXm = 2;
+		_scaleFactorXd = 3;
+#endif
+		_scaleFactorYm = 7;
+		_scaleFactorYd = 8;
+		_scalerProc = SmartphoneLandscape;
+		initZones();
+		return true;
+	}
+
+	return false;
+}
+
+void WINCESdlGraphicsManager::update_game_settings() {
+	Common::String gameid(ConfMan.get("gameid"));
+
+	// Finish panel initialization
+	if (!_panelInitialized && !gameid.empty()) {
+		CEGUI::Panel *panel;
+		_panelInitialized = true;
+		// Add the main panel
+		panel = new CEGUI::Panel(0, 32);
+		panel->setBackground(IMAGE_PANEL);
+
+		// Save
+		panel->add(NAME_ITEM_OPTIONS, new CEGUI::ItemAction(ITEM_OPTIONS, POCKET_ACTION_SAVE));
+		// Skip
+		panel->add(NAME_ITEM_SKIP, new CEGUI::ItemAction(ITEM_SKIP, POCKET_ACTION_SKIP));
+		// sound
+//__XXX__		panel->add(NAME_ITEM_SOUND, new CEGUI::ItemSwitch(ITEM_SOUND_OFF, ITEM_SOUND_ON, &_soundMaster));
+		panel->add(NAME_ITEM_SOUND, new CEGUI::ItemSwitch(ITEM_SOUND_OFF, ITEM_SOUND_ON, &OSystem_WINCE3::_soundMaster));
+
+		// bind keys
+		panel->add(NAME_ITEM_BINDKEYS, new CEGUI::ItemAction(ITEM_BINDKEYS, POCKET_ACTION_BINDKEYS));
+		// portrait/landscape - screen dependent
+		// FIXME : will still display the portrait/landscape icon when using a scaler (but will be disabled)
+		if (ConfMan.hasKey("landscape")) {
+			if (ConfMan.get("landscape")[0] > 57) {
+				_newOrientation = _orientationLandscape = ConfMan.getBool("landscape");
+				//ConfMan.removeKey("landscape", "");
+				ConfMan.setInt("landscape", _orientationLandscape);
+			} else
+				_newOrientation = _orientationLandscape = ConfMan.getInt("landscape");
+		} else {
+			_newOrientation = _orientationLandscape = 0;
+		}
+		panel->add(NAME_ITEM_ORIENTATION, new CEGUI::ItemSwitch(ITEM_VIEW_LANDSCAPE, ITEM_VIEW_PORTRAIT, &_newOrientation, 2));
+		_toolbarHandler.add(NAME_MAIN_PANEL, *panel);
+		_toolbarHandler.setActive(NAME_MAIN_PANEL);
+		_toolbarHandler.setVisible(true);
+
+		if (_videoMode.mode == GFX_NORMAL && ConfMan.hasKey("landscape") && ConfMan.getInt("landscape")) {
+			setGraphicsMode(GFX_NORMAL);
+			hotswapGFXMode();
+		}
+
+		if (_hasSmartphoneResolution)
+			panel->setVisible(false);
+
+		_saveToolbarState = true;
+	}
+
+	if (ConfMan.hasKey("no_doubletap_rightclick"))
+		_noDoubleTapRMB = ConfMan.getBool("no_doubletap_rightclick");
+}
+
+void WINCESdlGraphicsManager::internUpdateScreen() {
+	SDL_Surface *srcSurf, *origSurf;
+	static bool old_overlayVisible = false;
+	int numRectsOut = 0;
+	int16 routx, routy, routw, routh, stretch, shakestretch;
+
+	assert(_hwscreen != NULL);
+
+	// bail if the application is minimized, be nice to OS
+	if (!_hasfocus) {
+		Sleep(20);
+		return;
+	}
+
+	// If the shake position changed, fill the dirty area with blackness
+	if (_currentShakePos != _newShakePos) {
+		SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd, _newShakePos * _scaleFactorYm / _scaleFactorYd};
+		if (_videoMode.aspectRatioCorrection)
+			blackrect.h = real2Aspect(blackrect.h - 1) + 1;
+		SDL_FillRect(_hwscreen, &blackrect, 0);
+		_currentShakePos = _newShakePos;
+		_forceFull = true;
+	}
+
+	// Make sure the mouse is drawn, if it should be drawn.
+	drawMouse();
+
+	// Check whether the palette was changed in the meantime and update the
+	// screen surface accordingly.
+	if (_paletteDirtyEnd != 0) {
+		SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart, _paletteDirtyStart, _paletteDirtyEnd - _paletteDirtyStart);
+		_paletteDirtyEnd = 0;
+		_forceFull = true;
+	}
+
+	if (!_overlayVisible) {
+		origSurf = _screen;
+		srcSurf = _tmpscreen;
+	} else {
+		origSurf = _overlayscreen;
+		srcSurf = _tmpscreen2;
+	}
+
+	if (old_overlayVisible != _overlayVisible) {
+		old_overlayVisible = _overlayVisible;
+		update_scalers();
+	}
+
+	// Force a full redraw if requested
+	if (_forceFull) {
+		_numDirtyRects = 1;
+
+		_dirtyRectList[0].x = 0;
+		if (!_zoomDown)
+			_dirtyRectList[0].y = 0;
+		else
+			_dirtyRectList[0].y = _videoMode.screenHeight / 2;
+		_dirtyRectList[0].w = _videoMode.screenWidth;
+		if (!_zoomUp && !_zoomDown)
+			_dirtyRectList[0].h = _videoMode.screenHeight;
+		else
+			_dirtyRectList[0].h = _videoMode.screenHeight / 2;
+
+		_toolbarHandler.forceRedraw();
+	}
+
+	// Only draw anything if necessary
+	if (_numDirtyRects > 0) {
+
+		SDL_Rect *r, *rout;
+		SDL_Rect dst;
+		uint32 srcPitch, dstPitch;
+		SDL_Rect *last_rect = _dirtyRectList + _numDirtyRects;
+		bool toolbarVisible = _toolbarHandler.visible();
+		int toolbarOffset = _toolbarHandler.getOffset();
+
+		for (r = _dirtyRectList; r != last_rect; ++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.
+					// NOTE: This is also known as BLACK MAGIC, copied from the sdl backend
+			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, rout = _dirtyRectOut; r != last_rect; ++r) {
+
+			// always clamp to enclosing, downsampled-grid-aligned rect in the downscaled image
+			if (_scaleFactorXd != 1) {
+				stretch = r->x % _scaleFactorXd;
+				r->x -= stretch;
+				r->w += stretch;
+				r->w = (r->x + r->w + _scaleFactorXd - 1) / _scaleFactorXd * _scaleFactorXd - r->x;
+			}
+			if (_scaleFactorYd != 1) {
+				stretch = r->y % _scaleFactorYd;
+				r->y -= stretch;
+				r->h += stretch;
+				r->h = (r->y + r->h + _scaleFactorYd - 1) / _scaleFactorYd * _scaleFactorYd - r->y;
+			}
+
+			// transform
+			shakestretch = _currentShakePos * _scaleFactorYm / _scaleFactorYd;
+			routx = r->x * _scaleFactorXm / _scaleFactorXd;					// locate position in scaled screen
+			routy = r->y * _scaleFactorYm / _scaleFactorYd + shakestretch;	// adjust for shake offset
+			routw = r->w * _scaleFactorXm / _scaleFactorXd;
+			routh = r->h * _scaleFactorYm / _scaleFactorYd - shakestretch;
+
+			// clipping destination rectangle inside device screen (more strict, also more tricky but more stable)
+			// note that all current scalers do not make dst rect exceed left/right, unless chosen badly (FIXME)
+			if (_zoomDown)	routy -= 240;			// adjust for zoom position
+			if (routy + routh < 0)	continue;
+			if (routy < 0) {
+				routh += routy;
+				r->y -= routy * _scaleFactorYd / _scaleFactorYm;
+				routy = 0;
+				r->h = routh * _scaleFactorYd / _scaleFactorYm;
+			}
+			if (_orientationLandscape) {
+				if (routy > OSystem_WINCE3::getScreenWidth())	continue;
+				if (routy + routh > OSystem_WINCE3::getScreenWidth()) {
+					routh = OSystem_WINCE3::getScreenWidth() - routy;
+					r->h = routh * _scaleFactorYd / _scaleFactorYm;
+				}
+			} else {
+				if (routy > OSystem_WINCE3::getScreenHeight())	continue;
+				if (routy + routh > OSystem_WINCE3::getScreenHeight()) {
+					routh = OSystem_WINCE3::getScreenHeight() - routy;
+					r->h = routh * _scaleFactorYd / _scaleFactorYm;
+				}
+			}
+
+			// check if the toolbar is overwritten
+			if (toolbarVisible && r->y + r->h >= toolbarOffset)
+				_toolbarHandler.forceRedraw();
+
+			// blit it (with added voodoo from the sdl backend, shifting the source rect again)
+			_scalerProc(	(byte *)srcSurf->pixels + (r->x * 2 + 2)+ (r->y + 1) * srcPitch, srcPitch,
+					(byte *)_hwscreen->pixels + routx * 2 + routy * dstPitch, dstPitch,
+					r->w, r->h - _currentShakePos);
+
+			// add this rect to output
+			rout->x = routx;	rout->y = routy - shakestretch;
+			rout->w = routw;	rout->h = routh + shakestretch;
+			numRectsOut++;
+			rout++;
+
+		}
+		SDL_UnlockSurface(srcSurf);
+		SDL_UnlockSurface(_hwscreen);
+	}
+	// Add the toolbar if needed
+	SDL_Rect toolbar_rect[1];
+	if (_panelVisible && _toolbarHandler.draw(_toolbarLow, &toolbar_rect[0])) {
+		// It can be drawn, scale it
+		uint32 srcPitch, dstPitch;
+		SDL_Surface *toolbarSurface;
+		ScalerProc *toolbarScaler;
+
+		if (_videoMode.screenHeight > 240) {
+			if (!_toolbarHighDrawn) {
+				// Resize the toolbar
+				SDL_LockSurface(_toolbarLow);
+				SDL_LockSurface(_toolbarHigh);
+				Normal2x((byte*)_toolbarLow->pixels, _toolbarLow->pitch, (byte*)_toolbarHigh->pixels, _toolbarHigh->pitch, toolbar_rect[0].w, toolbar_rect[0].h);
+				SDL_UnlockSurface(_toolbarHigh);
+				SDL_UnlockSurface(_toolbarLow);
+				_toolbarHighDrawn = true;
+			}
+			toolbar_rect[0].w *= 2;
+			toolbar_rect[0].h *= 2;
+			toolbarSurface = _toolbarHigh;
+		}
+		else
+			toolbarSurface = _toolbarLow;
+
+		drawToolbarMouse(toolbarSurface, true);		// draw toolbar mouse if applicable
+
+		// Apply the appropriate scaler
+		SDL_LockSurface(toolbarSurface);
+		SDL_LockSurface(_hwscreen);
+		srcPitch = toolbarSurface->pitch;
+		dstPitch = _hwscreen->pitch;
+
+		toolbarScaler = _scalerProc;
+		if (_videoMode.scaleFactor == 2)
+			toolbarScaler = Normal2x;
+		else if (_videoMode.scaleFactor == 3)
+			toolbarScaler = Normal3x;
+		toolbarScaler((byte *)toolbarSurface->pixels, srcPitch,
+					(byte *)_hwscreen->pixels + (_toolbarHandler.getOffset() * _scaleFactorYm / _scaleFactorYd * dstPitch),
+					dstPitch, toolbar_rect[0].w, toolbar_rect[0].h);
+		SDL_UnlockSurface(toolbarSurface);
+		SDL_UnlockSurface(_hwscreen);
+
+		// And blit it
+		toolbar_rect[0].y = _toolbarHandler.getOffset();
+		toolbar_rect[0].x = toolbar_rect[0].x * _scaleFactorXm / _scaleFactorXd;
+		toolbar_rect[0].y = toolbar_rect[0].y * _scaleFactorYm / _scaleFactorYd;
+		toolbar_rect[0].w = toolbar_rect[0].w * _scaleFactorXm / _scaleFactorXd;
+		toolbar_rect[0].h = toolbar_rect[0].h * _scaleFactorYm / _scaleFactorYd;
+
+		SDL_UpdateRects(_hwscreen, 1, toolbar_rect);
+
+		drawToolbarMouse(toolbarSurface, false);	// undraw toolbar mouse
+	}
+
+	// Finally, blit all our changes to the screen
+	if (numRectsOut > 0)
+		SDL_UpdateRects(_hwscreen, numRectsOut, _dirtyRectOut);
+
+	_numDirtyRects = 0;
+	_forceFull = false;
+}
+
+bool WINCESdlGraphicsManager::setGraphicsMode(int mode) {
+
+	Common::StackLock lock(_graphicsMutex);
+	int oldScaleFactorXm = _scaleFactorXm;
+	int oldScaleFactorXd = _scaleFactorXd;
+	int oldScaleFactorYm = _scaleFactorYm;
+	int oldScaleFactorYd = _scaleFactorYd;
+
+	_scaleFactorXm = -1;
+	_scaleFactorXd = -1;
+	_scaleFactorYm = -1;
+	_scaleFactorYd = -1;
+
+	if (ConfMan.hasKey("landscape"))
+		if (ConfMan.get("landscape")[0] > 57) {
+			_newOrientation = _orientationLandscape = ConfMan.getBool("landscape");
+			ConfMan.setInt("landscape", _orientationLandscape);
+		} else
+			_newOrientation = _orientationLandscape = ConfMan.getInt("landscape");
+	else
+		_newOrientation = _orientationLandscape = 0;
+
+	if (OSystem_WINCE3::isOzone() && (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640) && mode)
+		_scaleFactorXm = -1;
+
+	if (CEDevice::hasPocketPCResolution() && !CEDevice::hasWideResolution() && _orientationLandscape)
+		_videoMode.mode = GFX_NORMAL;
+	else
+		_videoMode.mode = mode;
+
+	if (_scaleFactorXm < 0) {
+		/* Standard scalers, from the SDL backend */
+		switch (_videoMode.mode) {
+		case GFX_NORMAL:
+			_videoMode.scaleFactor = 1;
+			_scalerProc = Normal1x;
+			break;
+		case GFX_DOUBLESIZE:
+			_videoMode.scaleFactor = 2;
+			_scalerProc = Normal2x;
+			break;
+		case GFX_TRIPLESIZE:
+			_videoMode.scaleFactor = 3;
+			_scalerProc = Normal3x;
+			break;
+		case GFX_2XSAI:
+			_videoMode.scaleFactor = 2;
+			_scalerProc = _2xSaI;
+			break;
+		case GFX_SUPER2XSAI:
+			_videoMode.scaleFactor = 2;
+			_scalerProc = Super2xSaI;
+			break;
+		case GFX_SUPEREAGLE:
+			_videoMode.scaleFactor = 2;
+			_scalerProc = SuperEagle;
+			break;
+		case GFX_ADVMAME2X:
+			_videoMode.scaleFactor = 2;
+			_scalerProc = AdvMame2x;
+			break;
+		case GFX_ADVMAME3X:
+			_videoMode.scaleFactor = 3;
+			_scalerProc = AdvMame3x;
+			break;
+#ifdef USE_HQ_SCALERS
+		case GFX_HQ2X:
+			_videoMode.scaleFactor = 2;
+			_scalerProc = HQ2x;
+			break;
+		case GFX_HQ3X:
+			_videoMode.scaleFactor = 3;
+			_scalerProc = HQ3x;
+			break;
+#endif
+		case GFX_TV2X:
+			_videoMode.scaleFactor = 2;
+			_scalerProc = TV2x;
+			break;
+		case GFX_DOTMATRIX:
+			_videoMode.scaleFactor = 2;
+			_scalerProc = DotMatrix;
+			break;
+
+		default:
+			error("unknown gfx mode %d", mode);
+		}
+	}
+
+	// Check if the scaler can be accepted, if not get back to normal scaler
+	if (_videoMode.scaleFactor && ((_videoMode.scaleFactor * _videoMode.screenWidth > OSystem_WINCE3::getScreenWidth() && _videoMode.scaleFactor * _videoMode.screenWidth > OSystem_WINCE3::getScreenHeight())
+		 || (_videoMode.scaleFactor * _videoMode.screenHeight > OSystem_WINCE3::getScreenWidth() &&	_videoMode.scaleFactor * _videoMode.screenHeight > OSystem_WINCE3::getScreenHeight()))) {
+				_videoMode.scaleFactor = 1;
+				_scalerProc = Normal1x;
+	}
+
+	// Common scaler system was used
+	if (_scaleFactorXm < 0) {
+		_scaleFactorXm = _videoMode.scaleFactor;
+		_scaleFactorXd = 1;
+		_scaleFactorYm = _videoMode.scaleFactor;
+		_scaleFactorYd = 1;
+	}
+
+	_forceFull = true;
+
+	if (oldScaleFactorXm != _scaleFactorXm ||
+		oldScaleFactorXd != _scaleFactorXd ||
+		oldScaleFactorYm != _scaleFactorYm ||
+		oldScaleFactorYd != _scaleFactorYd) {
+		_scalersChanged = true;
+	}
+	else
+		_scalersChanged = false;
+
+
+	return true;
+
+}
+
+bool WINCESdlGraphicsManager::loadGFXMode() {
+	int displayWidth;
+	int displayHeight;
+	unsigned int flags = SDL_FULLSCREEN | SDL_SWSURFACE;
+
+	_videoMode.fullscreen = true; // forced
+	_forceFull = true;
+
+	_tmpscreen = NULL;
+
+	// Recompute scalers if necessary
+	update_scalers();
+
+	// Create the surface that contains the 8 bit game data
+	_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
+	if (_screen == NULL)
+		error("_screen failed (%s)", SDL_GetError());
+
+	// Create the surface that contains the scaled graphics in 16 bit mode
+	// Always use full screen mode to have a "clean screen"
+	if (!_videoMode.aspectRatioCorrection) {
+		displayWidth = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd;
+		displayHeight = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd;
+	} else {
+		displayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
+		displayHeight = _videoMode.screenHeight* _videoMode.scaleFactor;
+	}
+
+	switch (_orientationLandscape) {
+		case 1:
+			flags |= SDL_LANDSCVIDEO;
+			break;
+		case 2:
+			flags |= SDL_INVLNDVIDEO;
+			break;
+		default:
+			flags |= SDL_PORTRTVIDEO;
+	}
+	_hwscreen = SDL_SetVideoMode(displayWidth, displayHeight, 16, flags);
+
+	if (_hwscreen == NULL) {
+		warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
+		g_system->quit();
+	}
+
+	// see what orientation sdl finally accepted
+	if (_hwscreen->flags & SDL_PORTRTVIDEO)
+		_orientationLandscape = _newOrientation	= 0;
+	else if (_hwscreen->flags & SDL_LANDSCVIDEO)
+		_orientationLandscape = _newOrientation	= 1;
+	else
+		_orientationLandscape = _newOrientation	= 2;
+
+	// Create the surface used for the graphics in 16 bit before scaling, and also the overlay
+	// Distinguish 555 and 565 mode
+	if (_hwscreen->format->Rmask == 0x7C00)
+		InitScalers(555);
+	else
+		InitScalers(565);
+	_overlayFormat.bytesPerPixel = _hwscreen->format->BytesPerPixel;
+	_overlayFormat.rLoss = _hwscreen->format->Rloss;
+	_overlayFormat.gLoss = _hwscreen->format->Gloss;
+	_overlayFormat.bLoss = _hwscreen->format->Bloss;
+	_overlayFormat.aLoss = _hwscreen->format->Aloss;
+	_overlayFormat.rShift = _hwscreen->format->Rshift;
+	_overlayFormat.gShift = _hwscreen->format->Gshift;
+	_overlayFormat.bShift = _hwscreen->format->Bshift;
+	_overlayFormat.aShift = _hwscreen->format->Ashift;
+
+	// Need some extra bytes around when using 2xSaI
+	_tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
+
+	if (_tmpscreen == NULL)
+		error("_tmpscreen creation failed (%s)", SDL_GetError());
+
+	// Overlay
+	if (CEDevice::hasDesktopResolution()) {
+		_overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd, 16, 0, 0, 0, 0);
+		if (_overlayscreen == NULL)
+			error("_overlayscreen failed (%s)", SDL_GetError());
+		_tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd + 3, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd + 3, 16, 0, 0, 0, 0);
+		if (_tmpscreen2 == NULL)
+			error("_tmpscreen2 failed (%s)", SDL_GetError());
+	} else {
+		_overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight, 16, 0, 0, 0, 0);
+		if (_overlayscreen == NULL)
+			error("_overlayscreen failed (%s)", SDL_GetError());
+		_tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3, 16, 0, 0, 0, 0);
+		if (_tmpscreen2 == NULL)
+			error("_tmpscreen2 failed (%s)", SDL_GetError());
+	}
+
+	// Toolbar
+	_toolbarHighDrawn = false;
+	uint16 *toolbar_screen = (uint16 *)calloc(320 * 40, sizeof(uint16));	// *not* leaking memory here
+	_toolbarLow = SDL_CreateRGBSurfaceFrom(toolbar_screen, 320, 40, 16, 320 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
+
+	if (_toolbarLow == NULL)
+		error("_toolbarLow failed (%s)", SDL_GetError());
+
+	if (_videoMode.screenHeight > 240) {
+		uint16 *toolbar_screen_high = (uint16 *)calloc(640 * 80, sizeof(uint16));
+		_toolbarHigh = SDL_CreateRGBSurfaceFrom(toolbar_screen_high, 640, 80, 16, 640 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
+
+		if (_toolbarHigh == NULL)
+			error("_toolbarHigh failed (%s)", SDL_GetError());
+	} else
+		_toolbarHigh = NULL;
+
+	// keyboard cursor control, some other better place for it?
+	_sdlEventSource->resetKeyboadEmulation(_videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd - 1, _videoMode.screenHeight * _scaleFactorXm / _scaleFactorXd - 1);
+
+	return true;
+}
+
+void WINCESdlGraphicsManager::unloadGFXMode() {
+	if (_screen) {
+		SDL_FreeSurface(_screen);
+		_screen = NULL;
+	}
+
+	if (_hwscreen) {
+		SDL_FreeSurface(_hwscreen);
+		_hwscreen = NULL;
+	}
+
+	if (_tmpscreen) {
+		SDL_FreeSurface(_tmpscreen);
+		_tmpscreen = NULL;
+	}
+}
+
+bool WINCESdlGraphicsManager::hotswapGFXMode() {
+	if (!_screen)
+		return false;
+
+	// Keep around the old _screen & _tmpscreen so we can restore the screen data
+	// after the mode switch. (also for the overlay)
+	SDL_Surface *old_screen = _screen;
+	SDL_Surface *old_tmpscreen = _tmpscreen;
+	SDL_Surface *old_overlayscreen = _overlayscreen;
+	SDL_Surface *old_tmpscreen2 = _tmpscreen2;
+
+	// Release the HW screen surface
+	SDL_FreeSurface(_hwscreen);
+
+	// Release toolbars
+	free(_toolbarLow->pixels);
+	SDL_FreeSurface(_toolbarLow);
+	if (_toolbarHigh) {
+		free(_toolbarHigh->pixels);
+		SDL_FreeSurface(_toolbarHigh);
+	}
+
+	// Setup the new GFX mode
+	if (!loadGFXMode()) {
+		unloadGFXMode();
+
+		_screen = old_screen;
+		_overlayscreen = old_overlayscreen;
+
+		return false;
+	}
+
+	// reset palette
+	SDL_SetColors(_screen, _currentPalette, 0, 256);
+
+	// Restore old screen content
+	SDL_BlitSurface(old_screen, NULL, _screen, NULL);
+	SDL_BlitSurface(old_tmpscreen, NULL, _tmpscreen, NULL);
+	if (_overlayVisible) {
+		SDL_BlitSurface(old_overlayscreen, NULL, _overlayscreen, NULL);
+		SDL_BlitSurface(old_tmpscreen2, NULL, _tmpscreen2, NULL);
+	}
+
+	// Free the old surfaces
+	SDL_FreeSurface(old_screen);
+	SDL_FreeSurface(old_tmpscreen);
+	SDL_FreeSurface(old_overlayscreen);
+	SDL_FreeSurface(old_tmpscreen2);
+
+	// Blit everything back to the screen
+	_toolbarHighDrawn = false;
+	internUpdateScreen();
+
+	// Make sure that a Common::EVENT_SCREEN_CHANGED gets sent later -> FIXME this crashes when no game has been loaded.
+//	_modeChanged = true;
+
+	return true;
+}
+
+bool WINCESdlGraphicsManager::saveScreenshot(const char *filename) {
+	assert(_hwscreen != NULL);
+
+	Common::StackLock lock(_graphicsMutex);	// Lock the mutex until this function ends
+	SDL_SaveBMP(_hwscreen, filename);
+	return true;
+}
+
+void WINCESdlGraphicsManager::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
+	assert (_transactionMode == kTransactionNone);
+
+	if (_overlayscreen == NULL)
+		return;
+
+	// Clip the coordinates
+	if (x < 0) {
+		w += x;
+		buf -= x;
+		x = 0;
+	}
+
+	if (y < 0) {
+		h += y; buf -= y * pitch;
+		y = 0;
+	}
+
+	if (w > _videoMode.overlayWidth - x) {
+		w = _videoMode.overlayWidth - x;
+	}
+
+	if (h > _videoMode.overlayHeight - y) {
+		h = _videoMode.overlayHeight - y;
+	}
+
+	if (w <= 0 || h <= 0)
+		return;
+
+	// Mark the modified region as dirty
+	addDirtyRect(x, y, w, h);
+
+	undrawMouse();
+
+	if (SDL_LockSurface(_overlayscreen) == -1)
+		error("SDL_LockSurface failed: %s", SDL_GetError());
+
+	byte *dst = (byte *)_overlayscreen->pixels + y * _overlayscreen->pitch + x * 2;
+	do {
+		memcpy(dst, buf, w * 2);
+		dst += _overlayscreen->pitch;
+		buf += pitch;
+	} while (--h);
+
+	SDL_UnlockSurface(_overlayscreen);
+}
+
+void WINCESdlGraphicsManager::copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) {
+	assert (_transactionMode == kTransactionNone);
+	assert(src);
+
+	if (_screen == NULL)
+		return;
+
+	Common::StackLock lock(_graphicsMutex);	// Lock the mutex until this function ends
+
+	/* Clip the coordinates */
+	if (x < 0) {
+		w += x;
+		src -= x;
+		x = 0;
+	}
+
+	if (y < 0) {
+		h += y;
+		src -= y * pitch;
+		y = 0;
+	}
+
+	if (w > _videoMode.screenWidth - x) {
+		w = _videoMode.screenWidth - x;
+	}
+
+	if (h > _videoMode.screenHeight - y) {
+		h = _videoMode.screenHeight - y;
+	}
+
+	if (w <= 0 || h <= 0)
+		return;
+
+	addDirtyRect(x, y, w, h);
+
+	undrawMouse();
+
+	// Try to lock the screen surface
+	if (SDL_LockSurface(_screen) == -1)
+		error("SDL_LockSurface failed: %s", SDL_GetError());
+
+	byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
+
+	if (_videoMode.screenWidth == pitch && pitch == w) {
+		memcpy(dst, src, h*w);
+	} else {
+		do {
+			memcpy(dst, src, w);
+			src += pitch;
+			dst += _videoMode.screenWidth;
+		} while (--h);
+	}
+
+	// Unlock the screen surface
+	SDL_UnlockSurface(_screen);
+}
+
+void WINCESdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
+
+	undrawMouse();
+	if (w == 0 || h == 0)
+		return;
+
+	_mouseCurState.w = w;
+	_mouseCurState.h = h;
+
+	_mouseHotspotX = hotspot_x;
+	_mouseHotspotY = hotspot_y;
+
+	_mouseKeyColor = keycolor;
+
+	free(_mouseData);
+
+	_mouseData = (byte *) malloc(w * h);
+	memcpy(_mouseData, buf, w * h);
+
+	if (w > _mouseBackupDim || h > _mouseBackupDim) {
+		// mouse has been undrawn, adjust sprite backup area
+		free(_mouseBackupOld);
+		free(_mouseBackupToolbar);
+		uint16 tmp = (w > h) ? w : h;
+		_mouseBackupOld = (byte *) malloc(tmp * tmp * 2);	// can hold 8bpp (playfield) or 16bpp (overlay) data
+		_mouseBackupToolbar = (uint16 *) malloc(tmp * tmp * 2); // 16 bpp
+		_mouseBackupDim = tmp;
+	}
+}
+
+void WINCESdlGraphicsManager::adjustMouseEvent(const Common::Event &event) {
+	if (!event.synthetic) {
+		Common::Event newEvent(event);
+		newEvent.synthetic = true;
+		if (!_overlayVisible) {
+			/*
+			newEvent.mouse.x = newEvent.mouse.x * _scaleFactorXd / _scaleFactorXm;
+			newEvent.mouse.y = newEvent.mouse.y * _scaleFactorYd / _scaleFactorYm;
+			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);
+	}
+}
+
+void WINCESdlGraphicsManager::setMousePos(int x, int y) {
+	if (x != _mouseCurState.x || y != _mouseCurState.y) {
+		undrawMouse();
+		_mouseCurState.x = x;
+		_mouseCurState.y = y;
+		updateScreen();
+	}
+}
+
+Graphics::Surface *WINCESdlGraphicsManager::lockScreen() {
+	// Make sure mouse pointer is not painted over the playfield at the time of locking
+	undrawMouse();
+	return SdlGraphicsManager::lockScreen();
+}
+
+void WINCESdlGraphicsManager::showOverlay() {
+	assert (_transactionMode == kTransactionNone);
+
+	if (_overlayVisible)
+		return;
+
+	undrawMouse();
+	_overlayVisible = true;
+	update_scalers();
+	clearOverlay();
+}
+
+void WINCESdlGraphicsManager::hideOverlay() {
+	assert (_transactionMode == kTransactionNone);
+
+	if (!_overlayVisible)
+		return;
+
+	undrawMouse();
+	_overlayVisible = false;
+	clearOverlay();
+	_forceFull = true;
+}
+
+void WINCESdlGraphicsManager::blitCursor() {
+}
+
+void WINCESdlGraphicsManager::drawToolbarMouse(SDL_Surface *surf, bool draw) {
+
+	if (!_mouseData || !_usesEmulatedMouse)
+		return;
+
+	int x = _mouseCurState.x - _mouseHotspotX;
+	int y = _mouseCurState.y - _mouseHotspotY - _toolbarHandler.getOffset();
+	int w = _mouseCurState.w;
+	int h = _mouseCurState.h;
+	byte color;
+	const byte *src = _mouseData;
+	int width;
+
+	// clip
+	if (x < 0) {
+		w += x;
+		src -= x;
+		x = 0;
+	}
+	if (y < 0) {
+		h += y;
+		src -= y * _mouseCurState.w;
+		y = 0;
+	}
+	if (w > surf->w - x)
+		w = surf->w - x;
+	if (h > surf->h - y)
+		h = surf->h - y;
+	if (w <= 0 || h <= 0)
+		return;
+
+	if (SDL_LockSurface(surf) == -1)
+		error("SDL_LockSurface failed at internDrawToolbarMouse: %s", SDL_GetError());
+
+	uint16 *bak = _mouseBackupToolbar;	// toolbar surfaces are 16bpp
+	uint16 *dst;
+	dst = (uint16 *)surf->pixels + y * surf->w + x;
+
+	if (draw) {		// blit it
+		while (h > 0) {
+			width = w;
+			while (width > 0) {
+				*bak++ = *dst;
+				color = *src++;
+				if (color != _mouseKeyColor)	// transparent color
+					*dst = 0xFFFF;
+				dst++;
+				width--;
+			}
+			src += _mouseCurState.w - w;
+			bak += _mouseBackupDim - w;
+			dst += surf->w - w;
+			h--;
+		}
+	} else {		// restore bg
+		for (y = 0; y < h; ++y, bak += _mouseBackupDim, dst += surf->w)
+			memcpy(dst, bak, w << 1);
+	}
+
+	SDL_UnlockSurface(surf);
+}
+
+void WINCESdlGraphicsManager::warpMouse(int x, int y) {
+	if (_mouseCurState.x != x || _mouseCurState.y != y) {
+		SDL_WarpMouse(x * _scaleFactorXm / _scaleFactorXd, y * _scaleFactorYm / _scaleFactorYd);
+
+		// SDL_WarpMouse() generates a mouse movement event, so
+		// set_mouse_pos() would be called eventually. However, the
+		// cannon script in CoMI calls this function twice each time
+		// the cannon is reloaded. Unless we update the mouse position
+		// immediately the second call is ignored, causing the cannon
+		// to change its aim.
+
+		setMousePos(x, y);
+	}
+}
+
+void WINCESdlGraphicsManager::unlockScreen() {
+	SdlGraphicsManager::unlockScreen();
+}
+
+void WINCESdlGraphicsManager::internDrawMouse() {
+	if (!_mouseNeedsRedraw || !_mouseVisible || !_mouseData)
+		return;
+
+	int x = _mouseCurState.x - _mouseHotspotX;
+	int y = _mouseCurState.y - _mouseHotspotY;
+	int w = _mouseCurState.w;
+	int h = _mouseCurState.h;
+	byte color;
+	const byte *src = _mouseData;		// Image representing the mouse
+	int width;
+
+	// clip the mouse rect, and adjust the src pointer accordingly
+	if (x < 0) {
+		w += x;
+		src -= x;
+		x = 0;
+	}
+	if (y < 0) {
+		h += y;
+		src -= y * _mouseCurState.w;
+		y = 0;
+	}
+
+	if (w > _videoMode.screenWidth - x)
+		w = _videoMode.screenWidth - x;
+	if (h > _videoMode.screenHeight - y)
+		h = _videoMode.screenHeight - y;
+
+	// Quick check to see if anything has to be drawn at all
+	if (w <= 0 || h <= 0)
+		return;
+
+	// Draw the mouse cursor; backup the covered area in "bak"
+	if (SDL_LockSurface(_overlayVisible ? _overlayscreen : _screen) == -1)
+		error("SDL_LockSurface failed: %s", SDL_GetError());
+
+	// Mark as dirty
+	addDirtyRect(x, y, w, h);
+
+	if (!_overlayVisible) {
+		byte *bak = _mouseBackupOld;		// Surface used to backup the area obscured by the mouse
+		byte *dst;					// Surface we are drawing into
+
+		dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
+		while (h > 0) {
+			width = w;
+			while (width > 0) {
+				*bak++ = *dst;
+				color = *src++;
+				if (color != _mouseKeyColor)	// transparent, don't draw
+					*dst = color;
+				dst++;
+				width--;
+			}
+			src += _mouseCurState.w - w;
+			bak += _mouseBackupDim - w;
+			dst += _videoMode.screenWidth - w;
+			h--;
+		}
+
+	} else {
+		uint16 *bak = (uint16 *)_mouseBackupOld;	// Surface used to backup the area obscured by the mouse
+		byte *dst;					// Surface we are drawing into
+
+		dst = (byte *)_overlayscreen->pixels + (y + 1) * _overlayscreen->pitch + (x + 1) * 2;
+		while (h > 0) {
+			width = w;
+			while (width > 0) {
+				*bak++ = *(uint16 *)dst;
+				color = *src++;
+				if (color != 0xFF)	// 0xFF = transparent, don't draw
+					*(uint16 *)dst = SDL_MapRGB(_overlayscreen->format, _currentPalette[color].r, _currentPalette[color].g, _currentPalette[color].b);
+				dst += 2;
+				width--;
+			}
+			src += _mouseCurState.w - w;
+			bak += _mouseBackupDim - w;
+			dst += _overlayscreen->pitch - w * 2;
+			h--;
+		}
+	}
+
+	SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);
+
+	// Finally, set the flag to indicate the mouse has been drawn
+	_mouseNeedsRedraw = false;
+}
+
+void WINCESdlGraphicsManager::undrawMouse() {
+	assert (_transactionMode == kTransactionNone);
+
+	if (_mouseNeedsRedraw)
+		return;
+
+	int old_mouse_x = _mouseCurState.x - _mouseHotspotX;
+	int old_mouse_y = _mouseCurState.y - _mouseHotspotY;
+	int old_mouse_w = _mouseCurState.w;
+	int old_mouse_h = _mouseCurState.h;
+
+	// clip the mouse rect, and adjust the src pointer accordingly
+	if (old_mouse_x < 0) {
+		old_mouse_w += old_mouse_x;
+		old_mouse_x = 0;
+	}
+	if (old_mouse_y < 0) {
+		old_mouse_h += old_mouse_y;
+		old_mouse_y = 0;
+	}
+
+	if (old_mouse_w > _videoMode.screenWidth - old_mouse_x)
+		old_mouse_w = _videoMode.screenWidth - old_mouse_x;
+	if (old_mouse_h > _videoMode.screenHeight - old_mouse_y)
+		old_mouse_h = _videoMode.screenHeight - old_mouse_y;
+
+	// Quick check to see if anything has to be drawn at all
+	if (old_mouse_w <= 0 || old_mouse_h <= 0)
+		return;
+
+
+	if (SDL_LockSurface(_overlayVisible ? _overlayscreen : _screen) == -1)
+		error("SDL_LockSurface failed: %s", SDL_GetError());
+
+	int y;
+	if (!_overlayVisible) {
+		byte *dst, *bak = _mouseBackupOld;
+
+		// No need to do clipping here, since drawMouse() did that already
+		dst = (byte *)_screen->pixels + old_mouse_y * _videoMode.screenWidth + old_mouse_x;
+		for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _videoMode.screenWidth)
+			memcpy(dst, bak, old_mouse_w);
+	} else {
+		byte *dst;
+		uint16 *bak = (uint16 *)_mouseBackupOld;
+
+		// No need to do clipping here, since drawMouse() did that already
+		dst = (byte *)_overlayscreen->pixels + (old_mouse_y + 1) * _overlayscreen->pitch + (old_mouse_x + 1) * 2;
+		for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _overlayscreen->pitch)
+			memcpy(dst, bak, old_mouse_w << 1);
+	}
+
+	addDirtyRect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h);
+
+	SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);
+
+	_mouseNeedsRedraw = true;
+}
+
+void WINCESdlGraphicsManager::drawMouse() {
+	if (!(_toolbarHandler.visible() && _mouseCurState.y >= _toolbarHandler.getOffset() && !_usesEmulatedMouse) && !_forceHideMouse)
+		internDrawMouse();
+}
+
+bool WINCESdlGraphicsManager::showMouse(bool visible) {
+	if (_mouseVisible == visible)
+		return visible;
+
+	if (visible == false)
+		undrawMouse();
+
+	bool last = _mouseVisible;
+	_mouseVisible = visible;
+	_mouseNeedsRedraw = true;
+
+	return last;
+}
+
+void WINCESdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool mouseRect) {
+
+	if (_forceFull || _paletteDirtyEnd)
+		return;
+
+	SdlGraphicsManager::addDirtyRect(x, y, w, h, false);
+}
+
+void WINCESdlGraphicsManager::swap_panel_visibility() {
+	//if (!_forcePanelInvisible && !_panelStateForced) {
+		if (_zoomDown || _zoomUp)	return;
+
+		if (_panelVisible) {
+			if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD)
+				_panelVisible = !_panelVisible;
+			else
+				_toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
+		} else {
+			_toolbarHandler.setActive(NAME_MAIN_PANEL);
+			_panelVisible = !_panelVisible;
+		}
+		_toolbarHandler.setVisible(_panelVisible);
+		_toolbarHighDrawn = false;
+
+		if (_videoMode.screenHeight > 240)
+			addDirtyRect(0, 400, 640, 80);
+		else
+			addDirtyRect(0, 200, 320, 40);
+
+		if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible)
+			internUpdateScreen();
+		else {
+			update_scalers();
+			hotswapGFXMode();
+		}
+	//}
+}
+
+void WINCESdlGraphicsManager::swap_panel() {
+	_toolbarHighDrawn = false;
+	//if (!_panelStateForced) {
+		if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible)
+			_toolbarHandler.setActive(NAME_MAIN_PANEL);
+		else
+			_toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
+
+		if (_videoMode.screenHeight > 240)
+			addDirtyRect(0, 400, 640, 80);
+		else
+			addDirtyRect(0, 200, 320, 40);
+
+		_toolbarHandler.setVisible(true);
+		if (!_panelVisible) {
+			_panelVisible = true;
+			update_scalers();
+			hotswapGFXMode();
+		}
+	//}
+}
+
+void WINCESdlGraphicsManager::swap_smartphone_keyboard() {
+	_toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
+	_panelVisible = !_panelVisible;
+	_toolbarHandler.setVisible(_panelVisible);
+	if (_videoMode.screenHeight > 240)
+		addDirtyRect(0, 0, 640, 80);
+	else
+		addDirtyRect(0, 0, 320, 40);
+	internUpdateScreen();
+}
+
+void WINCESdlGraphicsManager::swap_zoom_up() {
+	if (_zoomUp) {
+		// restore visibility
+		_toolbarHandler.setVisible(_saveToolbarZoom);
+		// restore scaler
+		_scaleFactorYd = 2;
+		_scalerProc = DownscaleAllByHalf;
+		_zoomUp = false;
+		_zoomDown = false;
+	} else {
+		// only active if running on a PocketPC
+		if (_scalerProc != DownscaleAllByHalf && _scalerProc != DownscaleHorizByHalf)
+			return;
+		if (_scalerProc == DownscaleAllByHalf) {
+			_saveToolbarZoom = _toolbarHandler.visible();
+			_toolbarHandler.setVisible(false);
+			// set zoom scaler
+			_scaleFactorYd = 1;
+			_scalerProc = DownscaleHorizByHalf;
+		}
+
+		_zoomDown = false;
+		_zoomUp = true;
+	}
+	// redraw whole screen
+	addDirtyRect(0, 0, 640, 480);
+	internUpdateScreen();
+}
+
+void WINCESdlGraphicsManager::swap_zoom_down() {
+	if (_zoomDown) {
+		// restore visibility
+		_toolbarHandler.setVisible(_saveToolbarZoom);
+		// restore scaler
+		_scaleFactorYd = 2;
+		_scalerProc = DownscaleAllByHalf;
+		_zoomDown = false;
+		_zoomUp = false;
+	} else {
+		// only active if running on a PocketPC
+		if (_scalerProc != DownscaleAllByHalf && _scalerProc != DownscaleHorizByHalf)
+			return;
+		if (_scalerProc == DownscaleAllByHalf) {
+			_saveToolbarZoom = _toolbarHandler.visible();
+			_toolbarHandler.setVisible(false);
+			// set zoom scaler
+			_scaleFactorYd = 1;
+			_scalerProc = DownscaleHorizByHalf;
+		}
+
+		_zoomUp = false;
+		_zoomDown = true;
+	}
+	// redraw whole screen
+	addDirtyRect(0, 0, 640, 480);
+	internUpdateScreen();
+}
+
+void WINCESdlGraphicsManager::swap_mouse_visibility() {
+	_forceHideMouse = !_forceHideMouse;
+	if (_forceHideMouse)
+		undrawMouse();
+}
+
+// Smartphone actions
+void WINCESdlGraphicsManager::initZones() {
+	int i;
+
+	_currentZone = 0;
+	for (i = 0; i < TOTAL_ZONES; i++) {
+		_mouseXZone[i] = (_zones[i].x + (_zones[i].width / 2)) * _scaleFactorXm / _scaleFactorXd;
+		_mouseYZone[i] = (_zones[i].y + (_zones[i].height / 2)) * _scaleFactorYm / _scaleFactorYd;
+	}
+}
+
+void WINCESdlGraphicsManager::smartphone_rotate_display() {
+	_orientationLandscape = _newOrientation = _orientationLandscape == 1 ? 2 : 1;
+	ConfMan.setInt("landscape", _orientationLandscape);
+	ConfMan.flushToDisk();
+	hotswapGFXMode();
+}
+
+void WINCESdlGraphicsManager::create_toolbar() {
+	CEGUI::PanelKeyboard *keyboard;
+
+	// Add the keyboard
+	keyboard = new CEGUI::PanelKeyboard(PANEL_KEYBOARD);
+	_toolbarHandler.add(NAME_PANEL_KEYBOARD, *keyboard);
+	_toolbarHandler.setVisible(false);
+}
+
+WINCESdlGraphicsManager::zoneDesc WINCESdlGraphicsManager::_zones[TOTAL_ZONES] = {
+	{ 0, 0, 320, 145 },
+	{ 0, 145, 150, 55 },
+	{ 150, 145, 170, 55 }
+};
+
+#endif /* _WIN32_WCE */
+
diff --git a/backends/graphics/wincesdl/wincesdl-graphics.h b/backends/graphics/wincesdl/wincesdl-graphics.h
new file mode 100644
index 0000000..76b623d
--- /dev/null
+++ b/backends/graphics/wincesdl/wincesdl-graphics.h
@@ -0,0 +1,206 @@
+/* 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$
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_WINCE_SDL_H
+#define BACKENDS_GRAPHICS_WINCE_SDL_H
+
+#include "backends/graphics/sdl/sdl-graphics.h"
+#include "backends/platform/wince/CEgui/CEGUI.h"
+
+// Internal GUI names
+#define NAME_MAIN_PANEL			"MainPanel"
+#define NAME_PANEL_KEYBOARD		"Keyboard"
+#define NAME_ITEM_OPTIONS		"Options"
+#define NAME_ITEM_SKIP			"Skip"
+#define NAME_ITEM_SOUND			"Sound"
+#define NAME_ITEM_ORIENTATION	"Orientation"
+#define NAME_ITEM_BINDKEYS		"Bindkeys"
+
+#define TOTAL_ZONES 3
+
+extern bool _hasSmartphoneResolution;
+
+class WINCESdlGraphicsManager : public SdlGraphicsManager {
+public:
+	WINCESdlGraphicsManager(SdlEventSource *sdlEventSource);
+
+	const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
+	void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
+
+	bool hasFeature(OSystem::Feature f);
+	void setFeatureState(OSystem::Feature f, bool enable);
+	bool getFeatureState(OSystem::Feature f);
+
+	int getDefaultGraphicsMode() const;
+	bool setGraphicsMode(int mode);
+	bool loadGFXMode();
+	void unloadGFXMode();
+	bool hotswapGFXMode();
+
+	// Overloaded from SDL backend (toolbar handling)
+	void drawMouse();
+	// Overloaded from SDL backend (new scaler handling)
+	void addDirtyRect(int x, int y, int w, int h, bool mouseRect = false);
+	// Overloaded from SDL backend (new scaler handling)
+	void warpMouse(int x, int y);
+
+	// Update the dirty areas of the screen
+	void internUpdateScreen();
+	bool saveScreenshot(const char *filename);
+
+	// Overloaded from SDL_Common (FIXME)
+	void internDrawMouse();
+	void undrawMouse();
+	bool showMouse(bool visible);
+	void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // overloaded by CE backend
+	void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
+	void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); // overloaded by CE backend (FIXME)
+	Graphics::Surface *lockScreen();
+	void unlockScreen();
+	void blitCursor();
+	void showOverlay();
+	void hideOverlay();
+	void setMousePos(int x, int y);
+
+	// GUI and action stuff
+	void swap_panel_visibility();
+	void swap_panel();
+	void swap_smartphone_keyboard();
+	void swap_zoom_up();
+	void swap_zoom_down();
+	void swap_mouse_visibility();
+
+
+//#ifdef WIN32_PLATFORM_WFSP
+	void move_cursor_up();
+	void move_cursor_down();
+	void move_cursor_left();
+	void move_cursor_right();
+
+	void retrieve_mouse_location(int &x, int &y);
+	void switch_zone();
+
+	void add_right_click(bool pushed);
+	void add_left_click(bool pushed);
+
+	void initZones();
+	void smartphone_rotate_display();
+//#endif
+
+	bool _panelInitialized;	// only initialize the toolbar once
+	bool _noDoubleTapRMB;	// disable double tap -> rmb click
+
+	CEGUI::ToolbarHandler _toolbarHandler;
+
+	bool _toolbarHighDrawn;		// cache toolbar 640x80
+	int _newOrientation;		// new orientation
+	int _orientationLandscape;	// current orientation
+
+	int _scaleFactorXm;		// scaler X *
+	int _scaleFactorXd;		// scaler X /
+	int _scaleFactorYm;		// scaler Y *
+	int _scaleFactorYd;		// scaler Y /
+
+	bool _hasfocus;			// scummvm has the top window
+
+	bool hasPocketPCResolution();
+	bool hasDesktopResolution();
+	bool hasSquareQVGAResolution();
+	bool hasWideResolution() const;
+
+	MousePos _mouseCurState;
+
+	bool _zoomUp;			// zooming up mode
+	bool _zoomDown;			// zooming down mode
+
+	bool _usesEmulatedMouse;	// emulated mousemove ever been used in this session
+
+	int _mouseXZone[TOTAL_ZONES];
+	int _mouseYZone[TOTAL_ZONES];
+	int _currentZone;
+
+	// Smartphone specific variables
+	int _lastKeyPressed;		// last key pressed
+	int _keyRepeat;				// number of time the last key was repeated
+	int _keyRepeatTime;			// elapsed time since the key was pressed
+	int _keyRepeatTrigger;		// minimum time to consider the key was repeated
+
+	struct zoneDesc {
+		int x;
+		int y;
+		int width;
+		int height;
+	};
+
+	static zoneDesc _zones[TOTAL_ZONES];
+
+protected:
+	virtual void adjustMouseEvent(const Common::Event &event);
+
+private:
+	bool update_scalers();
+	void update_game_settings();
+	void drawToolbarMouse(SDL_Surface *surf, bool draw);
+
+	void create_toolbar();
+	bool _panelVisible;			// panel visibility
+	bool _panelStateForced;		// panel visibility forced by external call
+	String _saveActiveToolbar;	// save active toolbar when forced
+
+	bool _canBeAspectScaled;	// game screen size allows for aspect scaling
+
+	SDL_Rect _dirtyRectOut[NUM_DIRTY_RECT];
+	bool _scalersChanged;
+
+	bool isOzone();
+
+	bool _saveToolbarState;		// save visibility when forced
+	bool _saveToolbarZoom;		// save visibility when zooming
+
+	SDL_Surface *_toolbarLow;	// toolbar 320x40
+	SDL_Surface *_toolbarHigh;	// toolbar 640x80
+
+	// Mouse
+	int	_mouseHotspotX, _mouseHotspotY;
+	byte *_mouseBackupOld;
+	uint16 *_mouseBackupToolbar;
+	uint16 _mouseBackupDim;
+
+	bool _forceHideMouse;		// force invisible mouse cursor
+
+	// Smartphone specific variables
+	void loadDeviceConfigurationElement(Common::String element, int &value, int defaultValue);
+	int _repeatX;				// repeat trigger for left and right cursor moves
+	int _repeatY;				// repeat trigger for up and down cursor moves
+	int _stepX1;				// offset for left and right cursor moves (slowest)
+	int _stepX2;				// offset for left and right cursor moves (faster)
+	int _stepX3;				// offset for left and right cursor moves (fastest)
+	int _stepY1;				// offset for up and down cursor moves (slowest)
+	int _stepY2;				// offset for up and down cursor moves (faster)
+	int _stepY3;				// offset for up and down cursor moves (fastest)
+};
+
+#endif /* BACKENDS_GRAPHICS_WINCE_SDL_H */
+
diff --git a/backends/mixer/wincesdl/wincesdl-mixer.cpp b/backends/mixer/wincesdl/wincesdl-mixer.cpp
new file mode 100644
index 0000000..fb8a7d1
--- /dev/null
+++ b/backends/mixer/wincesdl/wincesdl-mixer.cpp
@@ -0,0 +1,183 @@
+/* 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$
+ *
+ */
+
+#ifdef _WIN32_WCE
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "common/config-manager.h"
+#include "backends/platform/wince/wince-sdl.h"
+#include "backends/mixer/wincesdl/wincesdl-mixer.h"
+#include "common/system.h"
+
+#ifdef USE_VORBIS
+#ifndef USE_TREMOR
+#include <vorbis/vorbisfile.h>
+#else
+#include <tremor/ivorbisfile.h>
+#endif
+#endif
+
+#define SAMPLES_PER_SEC_OLD 11025
+#define SAMPLES_PER_SEC_NEW 22050
+
+WINCESdlMixerManager::WINCESdlMixerManager() {
+
+}
+
+WINCESdlMixerManager::~WINCESdlMixerManager() {
+
+}
+
+void WINCESdlMixerManager::init() {
+	SDL_AudioSpec desired;
+	int thread_priority;
+
+	uint32 sampleRate = compute_sample_rate();
+	if (sampleRate == 0)
+		warning("OSystem_WINCE3::setupMixer called with sample rate 0 - audio will not work");
+	else if (_mixer && _mixer->getOutputRate() == sampleRate) {
+		debug(1, "Skipping sound mixer re-init: samplerate is good");
+		return;
+	}
+
+	memset(&desired, 0, sizeof(desired));
+	desired.freq = sampleRate;
+	desired.format = AUDIO_S16SYS;
+	desired.channels = 2;
+	desired.samples = 128;
+	desired.callback = private_sound_proc;
+	desired.userdata = this;
+
+	// Create the mixer instance
+	if (_mixer == 0)
+		_mixer = new Audio::MixerImpl(g_system, sampleRate);
+
+	// Add sound thread priority
+	if (!ConfMan.hasKey("sound_thread_priority"))
+		thread_priority = THREAD_PRIORITY_NORMAL;
+	else
+		thread_priority = ConfMan.getInt("sound_thread_priority");
+
+	desired.thread_priority = thread_priority;
+
+	SDL_CloseAudio();
+	if (SDL_OpenAudio(&desired, NULL) != 0) {
+		warning("Could not open audio device: %s", SDL_GetError());
+		_mixer->setReady(false);
+
+	} else {
+		debug(1, "Sound opened OK, mixing at %d Hz", sampleRate);
+
+		// Re-create mixer to match the output rate
+		int vol1 = _mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);
+		int vol2 = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
+		int vol3 = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
+		int vol4 = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
+		delete _mixer;
+		_mixer = new Audio::MixerImpl(g_system, sampleRate);
+		_mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, vol1);
+		_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol2);
+		_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, vol3);
+		_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, vol4);
+		_mixer->setReady(true);
+		SDL_PauseAudio(0);
+	}
+}
+
+void WINCESdlMixerManager::private_sound_proc(void *param, byte *buf, int len) {
+	WINCESdlMixerManager *this_ = (WINCESdlMixerManager *)param;
+	assert(this_);
+
+	if (this_->_mixer)
+		this_->_mixer->mixCallback(buf, len);
+	if (!OSystem_WINCE3::_soundMaster)
+		memset(buf, 0, len);
+}
+
+uint32 WINCESdlMixerManager::compute_sample_rate() {
+	uint32 sampleRate;
+
+	// Force at least medium quality FM synthesis for FOTAQ
+	Common::String gameid(ConfMan.get("gameid"));
+	if (gameid == "queen") {
+		if (!((ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) ||
+			(ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")))) {
+			ConfMan.setBool("FM_medium_quality", true);
+			ConfMan.flushToDisk();
+		}
+	}
+	// See if the output frequency is forced by the game
+	if (gameid == "ft" || gameid == "dig" || gameid == "comi" || gameid == "queen" || gameid == "sword" || gameid == "agi")
+			sampleRate = SAMPLES_PER_SEC_NEW;
+	else {
+		if (ConfMan.hasKey("high_sample_rate") && ConfMan.getBool("high_sample_rate"))
+			sampleRate = SAMPLES_PER_SEC_NEW;
+		else
+			sampleRate = SAMPLES_PER_SEC_OLD;
+	}
+
+#ifdef USE_VORBIS
+	// Modify the sample rate on the fly if OGG is involved
+	if (sampleRate == SAMPLES_PER_SEC_OLD)
+		if (checkOggHighSampleRate())
+			 sampleRate = SAMPLES_PER_SEC_NEW;
+#endif
+
+	return sampleRate;
+}
+
+#ifdef USE_VORBIS
+bool WINCESdlMixerManager::checkOggHighSampleRate() {
+	char trackFile[255];
+	FILE *testFile;
+	OggVorbis_File *test_ov_file = new OggVorbis_File;
+
+	// FIXME: The following sprintf assumes that "path" is always
+	// terminated by a path separator. This is *not* true in general.
+	// This code really should check for the path separator, or even
+	// better, use the FSNode API.
+	sprintf(trackFile, "%sTrack1.ogg", ConfMan.get("path").c_str());
+	// Check if we have an OGG audio track
+	testFile = fopen(trackFile, "rb");
+	if (testFile) {
+		if (!ov_open(testFile, test_ov_file, NULL, 0)) {
+			bool highSampleRate = (ov_info(test_ov_file, -1)->rate == 22050);
+			ov_clear(test_ov_file);
+			delete test_ov_file;
+			return highSampleRate;
+		}
+	}
+
+	// Do not test for OGG samples - too big and too slow anyway :)
+
+	delete test_ov_file;
+	return false;
+}
+#endif
+
+#endif
+
diff --git a/backends/mixer/wincesdl/wincesdl-mixer.h b/backends/mixer/wincesdl/wincesdl-mixer.h
new file mode 100644
index 0000000..6c2f1ef
--- /dev/null
+++ b/backends/mixer/wincesdl/wincesdl-mixer.h
@@ -0,0 +1,53 @@
+/* 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$
+ *
+ */
+
+#ifndef BACKENDS_MIXER_WINCE_SDL_H
+#define BACKENDS_MIXER_WINCE_SDL_H
+
+#include "backends/mixer/sdl/sdl-mixer.h"
+
+/**
+ * SDL mixer manager for WinCE
+ */
+class WINCESdlMixerManager : public SdlMixerManager {
+public:
+	WINCESdlMixerManager();
+	virtual ~WINCESdlMixerManager();
+
+	virtual void init();
+
+private:
+
+#ifdef USE_VORBIS
+	bool checkOggHighSampleRate();
+#endif
+
+	static void private_sound_proc(void *param, byte *buf, int len);
+	uint32 compute_sample_rate();
+
+};
+
+#endif
+
diff --git a/backends/module.mk b/backends/module.mk
index 5a8a63c..484f804 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -12,6 +12,7 @@ MODULE_OBJS := \
 	events/samsungtvsdl/samsungtvsdl-events.o \
 	events/sdl/sdl-events.o \
 	events/symbiansdl/symbiansdl-events.o \
+	events/wincesdl/wincesdl-events.o \
 	fs/abstract-fs.o \
 	fs/stdiostream.o \
 	fs/amigaos4/amigaos4-fs-factory.o \
@@ -27,6 +28,7 @@ MODULE_OBJS := \
 	graphics/openglsdl/openglsdl-graphics.o \
 	graphics/sdl/sdl-graphics.o \
 	graphics/symbiansdl/symbiansdl-graphics.o \
+	graphics/wincesdl/wincesdl-graphics.o \
 	keymapper/action.o \
 	keymapper/keymap.o \
 	keymapper/keymapper.o \
@@ -44,6 +46,7 @@ MODULE_OBJS := \
 	mixer/doublebuffersdl/doublebuffersdl-mixer.o \
 	mixer/sdl/sdl-mixer.o \
 	mixer/symbiansdl/symbiansdl-mixer.o \
+	mixer/wincesdl/wincesdl-mixer.o \
 	mutex/sdl/sdl-mutex.o \
 	plugins/elf/elf-loader.o \
 	plugins/elf/mips-loader.o \
diff --git a/backends/platform/wince/CEActionsPocket.cpp b/backends/platform/wince/CEActionsPocket.cpp
index 99d0be2..b3ac104 100644
--- a/backends/platform/wince/CEActionsPocket.cpp
+++ b/backends/platform/wince/CEActionsPocket.cpp
@@ -239,10 +239,12 @@ bool CEActionsPocket::perform(GUI::ActionType action, bool pushed) {
 	if (!pushed) {
 		switch (action) {
 		case POCKET_ACTION_RIGHTCLICK:
-			_CESystem->add_right_click(false);
+			//_CESystem->add_right_click(false);
+			((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_right_click(false);
 			return true;
 		case POCKET_ACTION_LEFTCLICK:
-			_CESystem->add_left_click(false);
+			//_CESystem->add_left_click(false);
+			((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_left_click(false);
 			return true;
 		case POCKET_ACTION_PAUSE:
 		case POCKET_ACTION_SAVE:
@@ -272,43 +274,55 @@ bool CEActionsPocket::perform(GUI::ActionType action, bool pushed) {
 		EventsBuffer::simulateKey(&_key_action[action], true);
 		return true;
 	case POCKET_ACTION_KEYBOARD:
-		_CESystem->swap_panel();
+		//_CESystem->swap_panel();
+		((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_panel();
 		return true;
 	case POCKET_ACTION_HIDE:
-		_CESystem->swap_panel_visibility();
+		//_CESystem->swap_panel_visibility();
+		((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_panel_visibility();
 		return true;
 	case POCKET_ACTION_SOUND:
 		_CESystem->swap_sound_master();
 		return true;
 	case POCKET_ACTION_RIGHTCLICK:
-		_CESystem->add_right_click(true);
+		//_CESystem->add_right_click(true);
+		((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_right_click(true);
 		return true;
 	case POCKET_ACTION_CURSOR:
-		_CESystem->swap_mouse_visibility();
+		//_CESystem->swap_mouse_visibility();
+		((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_mouse_visibility();
 		return true;
 	case POCKET_ACTION_FREELOOK:
-		_CESystem->swap_freeLook();
+		//_CESystem->swap_freeLook();
+		((WINCESdlEventSource *)((OSystem_SDL *)g_system)->getEventManager())->swap_freeLook();
 		return true;
 	case POCKET_ACTION_ZOOM_UP:
-		_CESystem->swap_zoom_up();
+		//_CESystem->swap_zoom_up();
+		((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_zoom_up();
 		return true;
 	case POCKET_ACTION_ZOOM_DOWN:
-		_CESystem->swap_zoom_down();
+		//_CESystem->swap_zoom_down();
+		((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_zoom_down();
 		return true;
 	case POCKET_ACTION_LEFTCLICK:
-		_CESystem->add_left_click(true);
+		//_CESystem->add_left_click(true);
+		((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_left_click(true);
 		return true;
 	case POCKET_ACTION_UP:
-		_CESystem->move_cursor_up();
+		//_CESystem->move_cursor_up();
+		((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_up();
 		return true;
 	case POCKET_ACTION_DOWN:
-		_CESystem->move_cursor_down();
+		//_CESystem->move_cursor_down();
+		((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_down();
 		return true;
 	case POCKET_ACTION_LEFT:
-		_CESystem->move_cursor_left();
+		//_CESystem->move_cursor_left();
+		((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_left();
 		return true;
 	case POCKET_ACTION_RIGHT:
-		_CESystem->move_cursor_right();
+		//_CESystem->move_cursor_right();
+		((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_right();
 		return true;
 	case POCKET_ACTION_QUIT:
 		if (!quitdialog) {
diff --git a/backends/platform/wince/CEActionsSmartphone.cpp b/backends/platform/wince/CEActionsSmartphone.cpp
index 5c7feb4..a868429 100644
--- a/backends/platform/wince/CEActionsSmartphone.cpp
+++ b/backends/platform/wince/CEActionsSmartphone.cpp
@@ -205,10 +205,12 @@ bool CEActionsSmartphone::perform(GUI::ActionType action, bool pushed) {
 	if (!pushed) {
 		switch (action) {
 			case SMARTPHONE_ACTION_RIGHTCLICK:
-				_CESystem->add_right_click(false);
+				//_CESystem->add_right_click(false);
+				((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_right_click(false);
 				return true;
 			case SMARTPHONE_ACTION_LEFTCLICK:
-				_CESystem->add_left_click(false);
+				//_CESystem->add_left_click(false);
+				((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_left_click(false);
 				return true;
 			case SMARTPHONE_ACTION_SAVE:
 			case SMARTPHONE_ACTION_SKIP:
@@ -235,25 +237,32 @@ bool CEActionsSmartphone::perform(GUI::ActionType action, bool pushed) {
 			EventsBuffer::simulateKey(&_key_action[action], true);
 			return true;
 		case SMARTPHONE_ACTION_RIGHTCLICK:
-			_CESystem->add_right_click(true);
+			//_CESystem->add_right_click(true);
+			((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_right_click(true);
 			return true;
 		case SMARTPHONE_ACTION_LEFTCLICK:
-			_CESystem->add_left_click(true);
+			//_CESystem->add_left_click(true);
+			((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_left_click(true);
 			return true;
 		case SMARTPHONE_ACTION_UP:
-			_CESystem->move_cursor_up();
+			//_CESystem->move_cursor_up();
+			((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_up();
 			return true;
 		case SMARTPHONE_ACTION_DOWN:
-			_CESystem->move_cursor_down();
+			//_CESystem->move_cursor_down();
+			((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_down();
 			return true;
 		case SMARTPHONE_ACTION_LEFT:
-			_CESystem->move_cursor_left();
+			//_CESystem->move_cursor_left();
+			((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_left();
 			return true;
 		case SMARTPHONE_ACTION_RIGHT:
-			_CESystem->move_cursor_right();
+			//_CESystem->move_cursor_right();
+			((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_right();
 			return true;
 		case SMARTPHONE_ACTION_ZONE:
-			_CESystem->switch_zone();
+			//_CESystem->switch_zone();
+			((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->switch_zone();
 			return true;
 		case SMARTPHONE_ACTION_BINDKEYS:
 			if (!keydialogrunning) {
@@ -265,10 +274,12 @@ bool CEActionsSmartphone::perform(GUI::ActionType action, bool pushed) {
 			}
 			return true;
 		case SMARTPHONE_ACTION_KEYBOARD:
-			_CESystem->swap_smartphone_keyboard();
+			//_CESystem->swap_smartphone_keyboard();
+			((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_smartphone_keyboard();
 			return true;
 		case SMARTPHONE_ACTION_ROTATE:
-			_CESystem->smartphone_rotate_display();
+			//_CESystem->smartphone_rotate_display();
+			((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->smartphone_rotate_display();
 			return true;
 		case SMARTPHONE_ACTION_QUIT:
 			if (!quitdialog) {
diff --git a/backends/platform/wince/CEDevice.cpp b/backends/platform/wince/CEDevice.cpp
index d94ce6c..3686944 100644
--- a/backends/platform/wince/CEDevice.cpp
+++ b/backends/platform/wince/CEDevice.cpp
@@ -44,7 +44,7 @@ extern "C" void WINAPI SystemIdleTimerReset(void);
 
 #define TIMER_TRIGGER 9000
 
-DWORD CEDevice::reg_access(TCHAR *key, TCHAR *val, DWORD data) {
+DWORD CEDevice::reg_access(const TCHAR *key, const TCHAR *val, DWORD data) {
 	HKEY regkey;
 	DWORD tmpval, cbdata;
 
@@ -70,7 +70,7 @@ DWORD CEDevice::reg_access(TCHAR *key, TCHAR *val, DWORD data) {
 void CEDevice::backlight_xchg() {
 	HANDLE h;
 
-	REG_bat = reg_access(TEXT("ControlPanel\\BackLight"), TEXT("BatteryTimeout"), REG_bat);
+	REG_bat = reg_access(TEXT("ControlPanel\\BackLight"), (const TCHAR*)TEXT("BatteryTimeout"), REG_bat);
 	REG_ac = reg_access(TEXT("ControlPanel\\BackLight"), TEXT("ACTimeout"), REG_ac);
 	REG_disp = reg_access(TEXT("ControlPanel\\Power"), TEXT("Display"), REG_disp);
 
@@ -127,6 +127,10 @@ bool CEDevice::hasSquareQVGAResolution() {
 	return (OSystem_WINCE3::getScreenWidth() == 240 && OSystem_WINCE3::getScreenHeight() == 240);
 }
 
+bool CEDevice::hasWideResolution() {
+	return (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640);
+}
+
 bool CEDevice::hasPocketPCResolution() {
 	if (OSystem_WINCE3::isOzone() && hasWideResolution())
 		return true;
@@ -139,10 +143,6 @@ bool CEDevice::hasDesktopResolution() {
 	return (OSystem_WINCE3::getScreenWidth() > 320);
 }
 
-bool CEDevice::hasWideResolution() {
-	return (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640);
-}
-
 bool CEDevice::hasSmartphoneResolution() {
 	return (OSystem_WINCE3::getScreenWidth() < 240);
 }
diff --git a/backends/platform/wince/CEDevice.h b/backends/platform/wince/CEDevice.h
index b2b20d0..24dffca 100644
--- a/backends/platform/wince/CEDevice.h
+++ b/backends/platform/wince/CEDevice.h
@@ -43,7 +43,7 @@ public:
 	static bool isSmartphone();
 
 private:
-	static DWORD reg_access(TCHAR *key, TCHAR *val, DWORD data);
+	static DWORD reg_access(const TCHAR *key, const TCHAR *val, DWORD data);
 	static void backlight_xchg();
 };
 
diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp
index ade90b2..45aa635 100644
--- a/backends/platform/wince/wince-sdl.cpp
+++ b/backends/platform/wince/wince-sdl.cpp
@@ -23,6 +23,7 @@
  *
  */
 
+
 // Disable symbol overrides so that we can use system headers.
 #define FORBIDDEN_SYMBOL_ALLOW_ALL
 
@@ -43,13 +44,12 @@
 #include "audio/mixer_intern.h"
 #include "audio/fmopl.h"
 
-#include "backends/timer/default/default-timer.h"
+#include "backends/timer/sdl/sdl-timer.h"
 
 #include "gui/Actions.h"
 #include "gui/KeysDialog.h"
 #include "gui/message.h"
 
-#include "backends/platform/wince/resource.h"
 #include "backends/platform/wince/CEActionsPocket.h"
 #include "backends/platform/wince/CEActionsSmartphone.h"
 #include "backends/platform/wince/CEgui/ItemAction.h"
@@ -60,13 +60,9 @@
 #include "backends/platform/wince/CEException.h"
 #include "backends/platform/wince/CEScaler.h"
 
-#ifdef USE_VORBIS
-#ifndef USE_TREMOR
-#include <vorbis/vorbisfile.h>
-#else
-#include <tremor/ivorbisfile.h>
-#endif
-#endif
+#include "backends/graphics/wincesdl/wincesdl-graphics.h"
+#include "backends/events/wincesdl/wincesdl-events.h"
+#include "backends/mixer/wincesdl/wincesdl-mixer.h"
 
 #ifdef DYNAMIC_MODULES
 #include "backends/plugins/win32/win32-provider.h"
@@ -76,23 +72,10 @@
 extern "C" _CRTIMP FILE* __cdecl   _wfreopen (const wchar_t*, const wchar_t*, FILE*);
 #endif
 
-#define SAMPLES_PER_SEC_OLD 11025
-#define SAMPLES_PER_SEC_NEW 22050
-
 using namespace CEGUI;
 
 // ********************************************************************************************
 
-// Internal GUI names
-
-#define NAME_MAIN_PANEL			"MainPanel"
-#define NAME_PANEL_KEYBOARD		"Keyboard"
-#define NAME_ITEM_OPTIONS		"Options"
-#define NAME_ITEM_SKIP			"Skip"
-#define NAME_ITEM_SOUND			"Sound"
-#define NAME_ITEM_ORIENTATION	"Orientation"
-#define NAME_ITEM_BINDKEYS		"Bindkeys"
-
 // stdin/err redirection
 #define STDOUT_FNAME "\\scummvm_stdout.txt"
 #define STDERR_FNAME "\\scummvm_stderr.txt"
@@ -106,34 +89,6 @@ bool OSystem_WINCE3::_soundMaster = true;
 bool _isSmartphone = false;
 bool _hasSmartphoneResolution = false;
 
-// Graphics mode consts
-
-// Low end devices 240x320
-
-static const OSystem::GraphicsMode s_supportedGraphicsModesLow[] = {
-	{"1x", _s("Normal (no scaling)"), GFX_NORMAL},
-	{0, 0, 0}
-};
-
-// High end device 480x640
-
-static const OSystem::GraphicsMode s_supportedGraphicsModesHigh[] = {
-	{"1x", _s("Normal (no scaling)"), GFX_NORMAL},
-	{"2x", "2x", GFX_DOUBLESIZE},
-#ifndef _MSC_VER // EVC breaks template functions, and I'm tired of fixing them :)
-	{"2xsai", "2xSAI", GFX_2XSAI},
-	{"super2xsai", "Super2xSAI", GFX_SUPER2XSAI},
-	{"supereagle", "SuperEagle", GFX_SUPEREAGLE},
-#endif
-	{"advmame2x", "AdvMAME2x", GFX_ADVMAME2X},
-#ifndef _MSC_VER
-	{"hq2x", "HQ2x", GFX_HQ2X},
-	{"tv2x", "TV2x", GFX_TV2X},
-#endif
-	{"dotmatrix", "DotMatrix", GFX_DOTMATRIX},
-	{0, 0, 0}
-};
-
 #define DEFAULT_CONFIG_FILE "scummvm.ini"
 
 // ********************************************************************************************
@@ -380,7 +335,6 @@ int dynamic_modules_main(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR szCmdLine, int
 
 // ********************************************************************************************
 
-
 // ********************************************************************************************
 
 void pumpMessages() {
@@ -407,28 +361,33 @@ static Uint32 timer_handler_wrapper(Uint32 interval) {
 }
 
 void OSystem_WINCE3::initBackend() {
-	// Instantiate our own sound mixer
-	// mixer init is rerun when a game engine is selected.
-	setupMixer();
+
+	assert(!_inited);
+
+	// Create the backend custom managers
+	if (_eventSource == 0)
+		_eventSource = new WINCESdlEventSource();
+
+	if (_mixerManager == 0) {
+		_mixerManager = new WINCESdlMixerManager();
+
+		// Setup and start mixer
+		_mixerManager->init();
+	}
+
+	if (_graphicsManager == 0)
+		_graphicsManager = new WINCESdlGraphicsManager(_eventSource);
 
 	// Create the timer. CE SDL does not support multiple timers (SDL_AddTimer).
 	// We work around this by using the SetTimer function, since we only use
 	// one timer in scummvm (for the time being)
 	_timer = _int_timer = new DefaultTimerManager();
-	_timerID = NULL;	// OSystem_SDL will call removetimer with this, it's ok
+	//_timerID = NULL;	// OSystem_SDL will call removetimer with this, it's ok
 	SDL_SetTimer(10, &timer_handler_wrapper);
 
 	// Chain init
 	OSystem_SDL::initBackend();
 
-	// Query SDL for screen size and init screen dependent stuff
-	OSystem_WINCE3::initScreenInfos();
-	_isSmartphone = CEDevice::isSmartphone();
-	create_toolbar();
-	_hasSmartphoneResolution = CEDevice::hasSmartphoneResolution() || CEDevice::isSmartphone();
-	if (_hasSmartphoneResolution)
-		_panelVisible = false;	// init correctly in smartphones
-
 	// Initialize global key mapping
 	GUI::Actions::init();
 	GUI_Actions::Instance()->initInstanceMain(this);
@@ -437,17 +396,16 @@ void OSystem_WINCE3::initBackend() {
 		GUI_Actions::Instance()->saveMapping();	// write defaults
 	}
 
-	loadDeviceConfiguration();
+	// Call parent implementation of this method
+	//OSystem_SDL::initBackend();
+
+	_inited = true;
 }
 
 int OSystem_WINCE3::getScreenWidth() {
 	return _platformScreenWidth;
 }
 
-int OSystem_WINCE3::getScreenHeight() {
-	return _platformScreenHeight;
-}
-
 void OSystem_WINCE3::initScreenInfos() {
 	// sdl port ensures that we use correctly full screen
 	_isOzone = 0;
@@ -457,6 +415,10 @@ void OSystem_WINCE3::initScreenInfos() {
 	_platformScreenHeight = r[0]->h;
 }
 
+int OSystem_WINCE3::getScreenHeight() {
+	return _platformScreenHeight;
+}
+
 bool OSystem_WINCE3::isOzone() {
 	return _isOzone;
 }
@@ -473,496 +435,38 @@ Common::String OSystem_WINCE3::getDefaultConfigFileName() {
 
 
 OSystem_WINCE3::OSystem_WINCE3() : OSystem_SDL(),
-	_orientationLandscape(0), _newOrientation(0), _panelInitialized(false), _canBeAspectScaled(false),
-	_panelVisible(true), _panelStateForced(false), _forceHideMouse(false), _unfilteredkeys(false),
-	_freeLook(false), _forcePanelInvisible(false), _toolbarHighDrawn(false), _zoomUp(false), _zoomDown(false),
-	_scalersChanged(false), _lastKeyPressed(0), _tapTime(0), _closeClick(false), _noDoubleTapRMB(false),
-	_saveToolbarState(false), _saveActiveToolbar(NAME_MAIN_PANEL), _rbutton(false), _hasfocus(true),
-	_usesEmulatedMouse(false), _mouseBackupOld(NULL), _mouseBackupToolbar(NULL), _mouseBackupDim(0)
+	_forcePanelInvisible(false)
 {
-	memset(&_mouseCurState, 0, sizeof(_mouseCurState));
-	if (_isSmartphone) {
-		_mouseCurState.x = 20;
-		_mouseCurState.y = 20;
-	}
-
+	// Initialze File System Factory
+	_fsFactory = new WindowsFilesystemFactory();
 	_mixer = 0;
-	_screen = NULL;
 }
 
-void OSystem_WINCE3::swap_panel_visibility() {
-	//if (!_forcePanelInvisible && !_panelStateForced) {
-		if (_zoomDown || _zoomUp)	return;
-
-		if (_panelVisible) {
-			if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD)
-				_panelVisible = !_panelVisible;
-			else
-				_toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
-		} else {
-			_toolbarHandler.setActive(NAME_MAIN_PANEL);
-			_panelVisible = !_panelVisible;
-		}
-		_toolbarHandler.setVisible(_panelVisible);
-		_toolbarHighDrawn = false;
-
-		if (_videoMode.screenHeight > 240)
-			addDirtyRect(0, 400, 640, 80);
-		else
-			addDirtyRect(0, 200, 320, 40);
-
-		if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible)
-			internUpdateScreen();
-		else {
-			update_scalers();
-			hotswapGFXMode();
-		}
-	//}
+OSystem_WINCE3::~OSystem_WINCE3() {
+	delete _fsFactory;
+	delete _mixer;
 }
 
-void OSystem_WINCE3::swap_panel() {
-	_toolbarHighDrawn = false;
-	//if (!_panelStateForced) {
-		if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible)
-			_toolbarHandler.setActive(NAME_MAIN_PANEL);
-		else
-			_toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
-
-		if (_videoMode.screenHeight > 240)
-			addDirtyRect(0, 400, 640, 80);
-		else
-			addDirtyRect(0, 200, 320, 40);
-
-		_toolbarHandler.setVisible(true);
-		if (!_panelVisible) {
-			_panelVisible = true;
-			update_scalers();
-			hotswapGFXMode();
-		}
-	//}
-}
-
-void OSystem_WINCE3::swap_smartphone_keyboard() {
-	_toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
-	_panelVisible = !_panelVisible;
-	_toolbarHandler.setVisible(_panelVisible);
-	if (_videoMode.screenHeight > 240)
-		addDirtyRect(0, 0, 640, 80);
-	else
-		addDirtyRect(0, 0, 320, 40);
-	internUpdateScreen();
-}
-
-void OSystem_WINCE3::smartphone_rotate_display() {
-	_orientationLandscape = _newOrientation = _orientationLandscape == 1 ? 2 : 1;
-	ConfMan.setInt("landscape", _orientationLandscape);
-	ConfMan.flushToDisk();
-	hotswapGFXMode();
+FilesystemFactory *OSystem_WINCE3::getFilesystemFactory() {
+	return _fsFactory;
 }
 
 void OSystem_WINCE3::swap_sound_master() {
 	_soundMaster = !_soundMaster;
-	if (_toolbarHandler.activeName() == NAME_MAIN_PANEL)
-		_toolbarHandler.forceRedraw(); // redraw sound icon
-}
-
-void OSystem_WINCE3::add_right_click(bool pushed) {
-	int x, y;
-	retrieve_mouse_location(x, y);
-	EventsBuffer::simulateMouseRightClick(x, y, pushed);
-}
 
-void OSystem_WINCE3::swap_mouse_visibility() {
-	_forceHideMouse = !_forceHideMouse;
-	if (_forceHideMouse)
-		undrawMouse();
-}
-
-void OSystem_WINCE3::swap_freeLook() {
-	_freeLook = !_freeLook;
-}
-
-void OSystem_WINCE3::swap_zoom_up() {
-	if (_zoomUp) {
-		// restore visibility
-		_toolbarHandler.setVisible(_saveToolbarZoom);
-		// restore scaler
-		_scaleFactorYd = 2;
-		_scalerProc = DownscaleAllByHalf;
-		_zoomUp = false;
-		_zoomDown = false;
-	} else {
-		// only active if running on a PocketPC
-		if (_scalerProc != DownscaleAllByHalf && _scalerProc != DownscaleHorizByHalf)
-			return;
-		if (_scalerProc == DownscaleAllByHalf) {
-			_saveToolbarZoom = _toolbarHandler.visible();
-			_toolbarHandler.setVisible(false);
-			// set zoom scaler
-			_scaleFactorYd = 1;
-			_scalerProc = DownscaleHorizByHalf;
-		}
+	//WINCESdlGraphicsManager _graphicsManager
 
-		_zoomDown = false;
-		_zoomUp = true;
-	}
-	// redraw whole screen
-	addDirtyRect(0, 0, 640, 480);
-	internUpdateScreen();
+	if (((WINCESdlGraphicsManager*)_graphicsManager)->_toolbarHandler.activeName() == NAME_MAIN_PANEL)
+		((WINCESdlGraphicsManager*)_graphicsManager)->_toolbarHandler.forceRedraw(); // redraw sound icon
 }
 
-void OSystem_WINCE3::swap_zoom_down() {
-	if (_zoomDown) {
-		// restore visibility
-		_toolbarHandler.setVisible(_saveToolbarZoom);
-		// restore scaler
-		_scaleFactorYd = 2;
-		_scalerProc = DownscaleAllByHalf;
-		_zoomDown = false;
-		_zoomUp = false;
-	} else {
-		// only active if running on a PocketPC
-		if (_scalerProc != DownscaleAllByHalf && _scalerProc != DownscaleHorizByHalf)
-			return;
-		if (_scalerProc == DownscaleAllByHalf) {
-			_saveToolbarZoom = _toolbarHandler.visible();
-			_toolbarHandler.setVisible(false);
-			// set zoom scaler
-			_scaleFactorYd = 1;
-			_scalerProc = DownscaleHorizByHalf;
-		}
-
-		_zoomUp = false;
-		_zoomDown = true;
-	}
-	// redraw whole screen
-	addDirtyRect(0, 0, 640, 480);
-	internUpdateScreen();
-}
-
-// Smartphone actions
-void OSystem_WINCE3::initZones() {
-	int i;
-
-	_currentZone = 0;
-	for (i = 0; i < TOTAL_ZONES; i++) {
-		_mouseXZone[i] = (_zones[i].x + (_zones[i].width / 2)) * _scaleFactorXm / _scaleFactorXd;
-		_mouseYZone[i] = (_zones[i].y + (_zones[i].height / 2)) * _scaleFactorYm / _scaleFactorYd;
-	}
-}
-
-void OSystem_WINCE3::loadDeviceConfigurationElement(String element, int &value, int defaultValue) {
-	value = ConfMan.getInt(element, ConfMan.kApplicationDomain);
-	if (!value) {
-		value = defaultValue;
-		ConfMan.setInt(element, value, ConfMan.kApplicationDomain);
-	}
-}
-
-void OSystem_WINCE3::loadDeviceConfiguration() {
-	loadDeviceConfigurationElement("repeatTrigger", _keyRepeatTrigger, 200);
-	loadDeviceConfigurationElement("repeatX", _repeatX, 4);
-	loadDeviceConfigurationElement("repeatY", _repeatY, 4);
-	loadDeviceConfigurationElement("stepX1", _stepX1, 2);
-	loadDeviceConfigurationElement("stepX2", _stepX2, 10);
-	loadDeviceConfigurationElement("stepX3", _stepX3, 40);
-	loadDeviceConfigurationElement("stepY1", _stepY1, 2);
-	loadDeviceConfigurationElement("stepY2", _stepY2, 10);
-	loadDeviceConfigurationElement("stepY3", _stepY3, 20);
-	ConfMan.flushToDisk();
-}
-
-void OSystem_WINCE3::add_left_click(bool pushed) {
-	int x, y;
-	retrieve_mouse_location(x, y);
-	EventsBuffer::simulateMouseLeftClick(x, y, pushed);
-}
-
-void OSystem_WINCE3::move_cursor_up() {
-	int x, y;
-	_usesEmulatedMouse = true;
-	retrieve_mouse_location(x, y);
-	if (_keyRepeat > _repeatY)
-		y -= _stepY3;
-	else if (_keyRepeat)
-		y -= _stepY2;
-	else
-		y -= _stepY1;
-
-	if (y < 0)
-		y = 0;
-
-	EventsBuffer::simulateMouseMove(x, y);
-}
-
-void OSystem_WINCE3::move_cursor_down() {
-	int x, y;
-	_usesEmulatedMouse = true;
-	retrieve_mouse_location(x, y);
-	if (_keyRepeat > _repeatY)
-		y += _stepY3;
-	else if (_keyRepeat)
-		y += _stepY2;
-	else
-		y += _stepY1;
-
-	if (y > _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd)
-		y = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd;
-
-	EventsBuffer::simulateMouseMove(x, y);
-}
-
-void OSystem_WINCE3::move_cursor_left() {
-	int x, y;
-	_usesEmulatedMouse = true;
-	retrieve_mouse_location(x, y);
-	if (_keyRepeat > _repeatX)
-		x -= _stepX3;
-	else if (_keyRepeat)
-		x -= _stepX2;
-	else
-		x -= _stepX1;
-
-	if (x < 0)
-		x = 0;
-
-	EventsBuffer::simulateMouseMove(x, y);
-}
-
-void OSystem_WINCE3::move_cursor_right() {
-	int x, y;
-	_usesEmulatedMouse = true;
-	retrieve_mouse_location(x, y);
-	if (_keyRepeat > _repeatX)
-		x += _stepX3;
-	else if (_keyRepeat)
-		x += _stepX2;
-	else
-		x += _stepX1;
-
-	if (x > _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd)
-		x = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd;
-
-	EventsBuffer::simulateMouseMove(x, y);
-}
-
-void OSystem_WINCE3::switch_zone() {
-	int x, y;
-	int i;
-	retrieve_mouse_location(x, y);
-
-	for (i = 0; i < TOTAL_ZONES; i++)
-		if (x >= _zones[i].x && y >= _zones[i].y &&
-			x <= _zones[i].x + _zones[i].width && y <= _zones[i].y + _zones[i].height) {
-				_mouseXZone[i] = x;
-				_mouseYZone[i] = y;
-				break;
-		}
-	_currentZone = i + 1;
-	if (_currentZone >= TOTAL_ZONES)
-		_currentZone = 0;
-
-	EventsBuffer::simulateMouseMove(_mouseXZone[_currentZone], _mouseYZone[_currentZone]);
-}
-
-void OSystem_WINCE3::create_toolbar() {
-	PanelKeyboard *keyboard;
-
-	// Add the keyboard
-	keyboard = new PanelKeyboard(PANEL_KEYBOARD);
-	_toolbarHandler.add(NAME_PANEL_KEYBOARD, *keyboard);
-	_toolbarHandler.setVisible(false);
-}
-
-void OSystem_WINCE3::setupMixer() {
-	SDL_AudioSpec desired;
-	int thread_priority;
-
-	uint32 sampleRate = compute_sample_rate();
-	if (sampleRate == 0)
-		warning("OSystem_WINCE3::setupMixer called with sample rate 0 - audio will not work");
-	else if (_mixer && _mixer->getOutputRate() == sampleRate) {
-		debug(1, "Skipping sound mixer re-init: samplerate is good");
-		return;
-	}
-
-	memset(&desired, 0, sizeof(desired));
-	desired.freq = sampleRate;
-	desired.format = AUDIO_S16SYS;
-	desired.channels = 2;
-	desired.samples = 128;
-	desired.callback = private_sound_proc;
-	desired.userdata = this;
-
-	// Create the mixer instance
-	if (_mixer == 0)
-		_mixer = new Audio::MixerImpl(this, sampleRate);
-
-	// Add sound thread priority
-	if (!ConfMan.hasKey("sound_thread_priority"))
-		thread_priority = THREAD_PRIORITY_NORMAL;
-	else
-		thread_priority = ConfMan.getInt("sound_thread_priority");
-
-	desired.thread_priority = thread_priority;
-
-	SDL_CloseAudio();
-	if (SDL_OpenAudio(&desired, NULL) != 0) {
-		warning("Could not open audio device: %s", SDL_GetError());
-		_mixer->setReady(false);
-
-	} else {
-		debug(1, "Sound opened OK, mixing at %d Hz", sampleRate);
-
-		// Re-create mixer to match the output rate
-		int vol1 = _mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);
-		int vol2 = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
-		int vol3 = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
-		int vol4 = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
-		delete _mixer;
-		_mixer = new Audio::MixerImpl(this, sampleRate);
-		_mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, vol1);
-		_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol2);
-		_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, vol3);
-		_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, vol4);
-		_mixer->setReady(true);
-		SDL_PauseAudio(0);
-	}
-}
-
-void OSystem_WINCE3::private_sound_proc(void *param, byte *buf, int len) {
-	OSystem_WINCE3 *this_ = (OSystem_WINCE3 *)param;
-	assert(this_);
-
-	if (this_->_mixer)
-		this_->_mixer->mixCallback(buf, len);
-	if (!_soundMaster)
-		memset(buf, 0, len);
-}
-
-#ifdef USE_VORBIS
-bool OSystem_WINCE3::checkOggHighSampleRate() {
-	char trackFile[255];
-	FILE *testFile;
-	OggVorbis_File *test_ov_file = new OggVorbis_File;
-
-	// FIXME: The following sprintf assumes that "path" is always
-	// terminated by a path separator. This is *not* true in general.
-	// This code really should check for the path separator, or even
-	// better, use the FSNode API.
-	sprintf(trackFile, "%sTrack1.ogg", ConfMan.get("path").c_str());
-	// Check if we have an OGG audio track
-	testFile = fopen(trackFile, "rb");
-	if (testFile) {
-		if (!ov_open(testFile, test_ov_file, NULL, 0)) {
-			bool highSampleRate = (ov_info(test_ov_file, -1)->rate == 22050);
-			ov_clear(test_ov_file);
-			delete test_ov_file;
-			return highSampleRate;
-		}
-	}
-
-	// Do not test for OGG samples - too big and too slow anyway :)
-
-	delete test_ov_file;
-	return false;
-}
-#endif
-
-uint32 OSystem_WINCE3::compute_sample_rate() {
-	uint32 sampleRate;
-
-	// Force at least medium quality FM synthesis for FOTAQ
-	Common::String gameid(ConfMan.get("gameid"));
-	if (gameid == "queen") {
-		if (!((ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) ||
-			(ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")))) {
-			ConfMan.setBool("FM_medium_quality", true);
-			ConfMan.flushToDisk();
-		}
-	}
-	// See if the output frequency is forced by the game
-	if (gameid == "ft" || gameid == "dig" || gameid == "comi" || gameid == "queen" || gameid == "sword" || gameid == "agi")
-			sampleRate = SAMPLES_PER_SEC_NEW;
-	else {
-		if (ConfMan.hasKey("high_sample_rate") && ConfMan.getBool("high_sample_rate"))
-			sampleRate = SAMPLES_PER_SEC_NEW;
-		else
-			sampleRate = SAMPLES_PER_SEC_OLD;
-	}
-
-#ifdef USE_VORBIS
-	// Modify the sample rate on the fly if OGG is involved
-	if (sampleRate == SAMPLES_PER_SEC_OLD)
-		if (checkOggHighSampleRate())
-			 sampleRate = SAMPLES_PER_SEC_NEW;
-#endif
-
-	return sampleRate;
-}
 
 void OSystem_WINCE3::engineInit() {
 	check_mappings(); // called here to initialize virtual keys handling
 
 	//update_game_settings();
 	// finalize mixer init
-	setupMixer();
-}
-
-const OSystem::GraphicsMode *OSystem_WINCE3::getSupportedGraphicsModes() const {
-	if (CEDevice::hasWideResolution())
-		return s_supportedGraphicsModesHigh;
-	else
-		return s_supportedGraphicsModesLow;
-}
-
-bool OSystem_WINCE3::hasFeature(Feature f) {
-	return (f == kFeatureVirtualKeyboard);
-}
-
-void OSystem_WINCE3::setFeatureState(Feature f, bool enable) {
-	switch (f) {
-	case kFeatureFullscreenMode:
-		return;
-
-	case kFeatureVirtualKeyboard:
-		if (_hasSmartphoneResolution)
-			return;
-		_toolbarHighDrawn = false;
-		if (enable) {
-			_panelStateForced = true;
-			if (!_toolbarHandler.visible()) swap_panel_visibility();
-			//_saveToolbarState = _toolbarHandler.visible();
-			_saveActiveToolbar = _toolbarHandler.activeName();
-			_toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
-			_toolbarHandler.setVisible(true);
-		} else
-			if (_panelStateForced) {
-				_panelStateForced = false;
-				_toolbarHandler.setActive(_saveActiveToolbar);
-				//_toolbarHandler.setVisible(_saveToolbarState);
-			}
-		return;
-
-	case kFeatureDisableKeyFiltering:
-		if (_hasSmartphoneResolution)
-			_unfilteredkeys = enable;
-		return;
-
-	default:
-		OSystem_SDL::setFeatureState(f, enable);
-	}
-}
-
-bool OSystem_WINCE3::getFeatureState(Feature f) {
-	switch (f) {
-	case kFeatureFullscreenMode:
-		return false;
-	case kFeatureVirtualKeyboard:
-		return (_panelStateForced);
-	default:
-		return OSystem_SDL::getFeatureState(f);
-	}
+	_mixerManager->init();
 }
 
 void OSystem_WINCE3::check_mappings() {
@@ -1021,1465 +525,32 @@ void OSystem_WINCE3::check_mappings() {
 
 }
 
-void OSystem_WINCE3::update_game_settings() {
-	Common::String gameid(ConfMan.get("gameid"));
-
-	// Finish panel initialization
-	if (!_panelInitialized && !gameid.empty()) {
-		Panel *panel;
-		_panelInitialized = true;
-		// Add the main panel
-		panel = new Panel(0, 32);
-		panel->setBackground(IMAGE_PANEL);
-		// Save
-		panel->add(NAME_ITEM_OPTIONS, new ItemAction(ITEM_OPTIONS, POCKET_ACTION_SAVE));
-		// Skip
-		panel->add(NAME_ITEM_SKIP, new ItemAction(ITEM_SKIP, POCKET_ACTION_SKIP));
-		// sound
-		panel->add(NAME_ITEM_SOUND, new ItemSwitch(ITEM_SOUND_OFF, ITEM_SOUND_ON, &_soundMaster));
-		// bind keys
-		panel->add(NAME_ITEM_BINDKEYS, new ItemAction(ITEM_BINDKEYS, POCKET_ACTION_BINDKEYS));
-		// portrait/landscape - screen dependent
-		// FIXME : will still display the portrait/landscape icon when using a scaler (but will be disabled)
-		if (ConfMan.hasKey("landscape")) {
-			if (ConfMan.get("landscape")[0] > 57) {
-				_newOrientation = _orientationLandscape = ConfMan.getBool("landscape");
-				//ConfMan.removeKey("landscape", "");
-				ConfMan.setInt("landscape", _orientationLandscape);
-			} else
-				_newOrientation = _orientationLandscape = ConfMan.getInt("landscape");
-		} else {
-			_newOrientation = _orientationLandscape = 0;
-		}
-		panel->add(NAME_ITEM_ORIENTATION, new ItemSwitch(ITEM_VIEW_LANDSCAPE, ITEM_VIEW_PORTRAIT, &_newOrientation, 2));
-		_toolbarHandler.add(NAME_MAIN_PANEL, *panel);
-		_toolbarHandler.setActive(NAME_MAIN_PANEL);
-		_toolbarHandler.setVisible(true);
-
-		if (_videoMode.mode == GFX_NORMAL && ConfMan.hasKey("landscape") && ConfMan.getInt("landscape")) {
-			setGraphicsMode(GFX_NORMAL);
-			hotswapGFXMode();
-		}
-
-		if (_hasSmartphoneResolution)
-			panel->setVisible(false);
-
-		_saveToolbarState = true;
-	}
-
-	if (ConfMan.hasKey("no_doubletap_rightclick"))
-		_noDoubleTapRMB = ConfMan.getBool("no_doubletap_rightclick");
-}
-
-void OSystem_WINCE3::initSize(uint w, uint h, const Graphics::PixelFormat *format) {
-	if (_hasSmartphoneResolution && h == 240)
-		h = 200;  // mainly for the launcher
-
-	if (_isSmartphone && !ConfMan.hasKey("landscape")) {
-		ConfMan.setInt("landscape", 1);
-		ConfMan.flushToDisk();
-	}
-
-	_canBeAspectScaled = false;
-	if (w == 320 && h == 200 && !_hasSmartphoneResolution) {
-		_canBeAspectScaled = true;
-		h = 240; // use the extra 40 pixels height for the toolbar
-	}
-
-	if (h == 400)	// touche engine fixup
-		h += 80;
-
-	if (!_hasSmartphoneResolution) {
-		if (h == 240)
-			_toolbarHandler.setOffset(200);
-		else
-			_toolbarHandler.setOffset(400);
-	} else {
-		if (h == 240)
-			_toolbarHandler.setOffset(200);
-		else	// 176x220
-			_toolbarHandler.setOffset(0);
-	}
-
-	if (w != (uint) _videoMode.screenWidth || h != (uint) _videoMode.screenHeight)
-		_scalersChanged = false;
-
-	_videoMode.overlayWidth = w;
-	_videoMode.overlayHeight = h;
-
-	OSystem_SDL::initSize(w, h, format);
-
-	if (_scalersChanged) {
-		unloadGFXMode();
-		loadGFXMode();
-		_scalersChanged = false;
-	}
-
-	update_game_settings();
-}
-
-
-int OSystem_WINCE3::getDefaultGraphicsMode() const {
-	return GFX_NORMAL;
-}
-
 void OSystem_WINCE3::setGraphicsModeIntern() {
 	// Scalers have been pre-selected for the desired mode.
 	// No further tuning required.
 }
 
-bool OSystem_WINCE3::update_scalers() {
-	_videoMode.aspectRatioCorrection = false;
-
-	if (CEDevice::hasPocketPCResolution()) {
-		if (_videoMode.mode != GFX_NORMAL)
-			return false;
-
-		if ((!_orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth))
-			|| CEDevice::hasSquareQVGAResolution() ) {
-			if (getScreenWidth() != 320) {
-				_scaleFactorXm = 3;
-				_scaleFactorXd = 4;
-				_scaleFactorYm = 1;
-				_scaleFactorYd = 1;
-				_scalerProc = DownscaleHorizByThreeQuarters;
-			} else {
-				_scaleFactorXm = 1;
-				_scaleFactorXd = 1;
-				_scaleFactorYm = 1;
-				_scaleFactorYd = 1;
-				_scalerProc = Normal1x;
-			}
-		} else if ( _orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth)) {
-			if (!_panelVisible && !_hasSmartphoneResolution  && !_overlayVisible && _canBeAspectScaled) {
-				_scaleFactorXm = 1;
-				_scaleFactorXd = 1;
-				_scaleFactorYm = 6;
-				_scaleFactorYd = 5;
-				_scalerProc = Normal1xAspect;
-				_videoMode.aspectRatioCorrection = true;
-			} else {
-				_scaleFactorXm = 1;
-				_scaleFactorXd = 1;
-				_scaleFactorYm = 1;
-				_scaleFactorYd = 1;
-				_scalerProc = Normal1x;
-			}
-		} else if (_videoMode.screenWidth == 640 && !(isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) {
-			_scaleFactorXm = 1;
-			_scaleFactorXd = 2;
-			_scaleFactorYm = 1;
-			_scaleFactorYd = 2;
-			_scalerProc = DownscaleAllByHalf;
-		} else if (_videoMode.screenWidth == 640 && (isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) {
-			_scaleFactorXm = 1;
-			_scaleFactorXd = 1;
-			_scaleFactorYm = 1;
-			_scaleFactorYd = 1;
-			_scalerProc = Normal1x;
-		}
-
-		return true;
-	} else if (CEDevice::hasWideResolution()) {
-#ifdef USE_ARM_SCALER_ASM
-		if ( _videoMode.mode == GFX_DOUBLESIZE && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth) ) {
-			if ( !_panelVisible && !_overlayVisible && _canBeAspectScaled ) {
-				_scaleFactorXm = 2;
-				_scaleFactorXd = 1;
-				_scaleFactorYm = 12;
-				_scaleFactorYd = 5;
-				_scalerProc = Normal2xAspect;
-				_videoMode.aspectRatioCorrection = true;
-			} else if ( (_panelVisible || _overlayVisible) && _canBeAspectScaled ) {
-				_scaleFactorXm = 2;
-				_scaleFactorXd = 1;
-				_scaleFactorYm = 2;
-				_scaleFactorYd = 1;
-				_scalerProc = Normal2x;
-			}
-			return true;
-		}
-#endif
-	} else if (CEDevice::hasSmartphoneResolution()) {
-		if (_videoMode.mode != GFX_NORMAL)
-			return false;
-
-		if (_videoMode.screenWidth > 320)
-			error("Game resolution not supported on Smartphone");
-#ifdef ARM
-		_scaleFactorXm = 11;
-		_scaleFactorXd = 16;
-#else
-		_scaleFactorXm = 2;
-		_scaleFactorXd = 3;
-#endif
-		_scaleFactorYm = 7;
-		_scaleFactorYd = 8;
-		_scalerProc = SmartphoneLandscape;
-		initZones();
-		return true;
-	}
-
-	return false;
-}
-
-bool OSystem_WINCE3::setGraphicsMode(int mode) {
-
-	Common::StackLock lock(_graphicsMutex);
-	int oldScaleFactorXm = _scaleFactorXm;
-	int oldScaleFactorXd = _scaleFactorXd;
-	int oldScaleFactorYm = _scaleFactorYm;
-	int oldScaleFactorYd = _scaleFactorYd;
-
-	_scaleFactorXm = -1;
-	_scaleFactorXd = -1;
-	_scaleFactorYm = -1;
-	_scaleFactorYd = -1;
-
-	if (ConfMan.hasKey("landscape"))
-		if (ConfMan.get("landscape")[0] > 57) {
-			_newOrientation = _orientationLandscape = ConfMan.getBool("landscape");
-			ConfMan.setInt("landscape", _orientationLandscape);
-		} else
-			_newOrientation = _orientationLandscape = ConfMan.getInt("landscape");
-	else
-		_newOrientation = _orientationLandscape = 0;
-
-	if (isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640) && mode)
-		_scaleFactorXm = -1;
+void OSystem_WINCE3::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;
 
-	if (CEDevice::hasPocketPCResolution() && !CEDevice::hasWideResolution() && _orientationLandscape)
-		_videoMode.mode = GFX_NORMAL;
-	else
-		_videoMode.mode = mode;
-
-	if (_scaleFactorXm < 0) {
-		/* Standard scalers, from the SDL backend */
-		switch (_videoMode.mode) {
-		case GFX_NORMAL:
-			_videoMode.scaleFactor = 1;
-			_scalerProc = Normal1x;
-			break;
-		case GFX_DOUBLESIZE:
-			_videoMode.scaleFactor = 2;
-			_scalerProc = Normal2x;
-			break;
-		case GFX_TRIPLESIZE:
-			_videoMode.scaleFactor = 3;
-			_scalerProc = Normal3x;
-			break;
-		case GFX_2XSAI:
-			_videoMode.scaleFactor = 2;
-			_scalerProc = _2xSaI;
-			break;
-		case GFX_SUPER2XSAI:
-			_videoMode.scaleFactor = 2;
-			_scalerProc = Super2xSaI;
-			break;
-		case GFX_SUPEREAGLE:
-			_videoMode.scaleFactor = 2;
-			_scalerProc = SuperEagle;
-			break;
-		case GFX_ADVMAME2X:
-			_videoMode.scaleFactor = 2;
-			_scalerProc = AdvMame2x;
-			break;
-		case GFX_ADVMAME3X:
-			_videoMode.scaleFactor = 3;
-			_scalerProc = AdvMame3x;
-			break;
-#ifdef USE_HQ_SCALERS
-		case GFX_HQ2X:
-			_videoMode.scaleFactor = 2;
-			_scalerProc = HQ2x;
-			break;
-		case GFX_HQ3X:
-			_videoMode.scaleFactor = 3;
-			_scalerProc = HQ3x;
-			break;
-#endif
-		case GFX_TV2X:
-			_videoMode.scaleFactor = 2;
-			_scalerProc = TV2x;
-			break;
-		case GFX_DOTMATRIX:
-			_videoMode.scaleFactor = 2;
-			_scalerProc = DotMatrix;
-			break;
-
-		default:
-			error("unknown gfx mode %d", mode);
+		if (ConfMan.hasKey("use_GDI") && ConfMan.getBool("use_GDI")) {
+			SDL_VideoInit("windib", 0);
+			sdlFlags ^= SDL_INIT_VIDEO;
 		}
-	}
-
-	// Check if the scaler can be accepted, if not get back to normal scaler
-	if (_videoMode.scaleFactor && ((_videoMode.scaleFactor * _videoMode.screenWidth > getScreenWidth() && _videoMode.scaleFactor * _videoMode.screenWidth > getScreenHeight())
-		 || (_videoMode.scaleFactor * _videoMode.screenHeight > getScreenWidth() &&	_videoMode.scaleFactor * _videoMode.screenHeight > getScreenHeight()))) {
-				_videoMode.scaleFactor = 1;
-				_scalerProc = Normal1x;
-	}
-
-	// Common scaler system was used
-	if (_scaleFactorXm < 0) {
-		_scaleFactorXm = _videoMode.scaleFactor;
-		_scaleFactorXd = 1;
-		_scaleFactorYm = _videoMode.scaleFactor;
-		_scaleFactorYd = 1;
-	}
-
-	_forceFull = true;
-
-	if (oldScaleFactorXm != _scaleFactorXm ||
-		oldScaleFactorXd != _scaleFactorXd ||
-		oldScaleFactorYm != _scaleFactorYm ||
-		oldScaleFactorYd != _scaleFactorYd) {
-		_scalersChanged = true;
-	}
-	else
-		_scalersChanged = false;
-
-
-	return true;
-
-}
-
-bool OSystem_WINCE3::loadGFXMode() {
-	int displayWidth;
-	int displayHeight;
-	unsigned int flags = SDL_FULLSCREEN | SDL_SWSURFACE;
-
-	_videoMode.fullscreen = true; // forced
-	_forceFull = true;
-
-	_tmpscreen = NULL;
-
-	// Recompute scalers if necessary
-	update_scalers();
-
-	// Create the surface that contains the 8 bit game data
-	_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
-	if (_screen == NULL)
-		error("_screen failed (%s)", SDL_GetError());
-
-	// Create the surface that contains the scaled graphics in 16 bit mode
-	// Always use full screen mode to have a "clean screen"
-	if (!_videoMode.aspectRatioCorrection) {
-		displayWidth = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd;
-		displayHeight = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd;
-	} else {
-		displayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
-		displayHeight = _videoMode.screenHeight* _videoMode.scaleFactor;
-	}
-
-	switch (_orientationLandscape) {
-		case 1:
-			flags |= SDL_LANDSCVIDEO;
-			break;
-		case 2:
-			flags |= SDL_INVLNDVIDEO;
-			break;
-		default:
-			flags |= SDL_PORTRTVIDEO;
-	}
-	_hwscreen = SDL_SetVideoMode(displayWidth, displayHeight, 16, flags);
-
-	if (_hwscreen == NULL) {
-		warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
-		quit();
-	}
-
-	// see what orientation sdl finally accepted
-	if (_hwscreen->flags & SDL_PORTRTVIDEO)
-		_orientationLandscape = _newOrientation	= 0;
-	else if (_hwscreen->flags & SDL_LANDSCVIDEO)
-		_orientationLandscape = _newOrientation	= 1;
-	else
-		_orientationLandscape = _newOrientation	= 2;
 
-	// Create the surface used for the graphics in 16 bit before scaling, and also the overlay
-	// Distinguish 555 and 565 mode
-	if (_hwscreen->format->Rmask == 0x7C00)
-		InitScalers(555);
-	else
-		InitScalers(565);
-	_overlayFormat.bytesPerPixel = _hwscreen->format->BytesPerPixel;
-	_overlayFormat.rLoss = _hwscreen->format->Rloss;
-	_overlayFormat.gLoss = _hwscreen->format->Gloss;
-	_overlayFormat.bLoss = _hwscreen->format->Bloss;
-	_overlayFormat.aLoss = _hwscreen->format->Aloss;
-	_overlayFormat.rShift = _hwscreen->format->Rshift;
-	_overlayFormat.gShift = _hwscreen->format->Gshift;
-	_overlayFormat.bShift = _hwscreen->format->Bshift;
-	_overlayFormat.aShift = _hwscreen->format->Ashift;
-
-	// Need some extra bytes around when using 2xSaI
-	_tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
-
-	if (_tmpscreen == NULL)
-		error("_tmpscreen creation failed (%s)", SDL_GetError());
-
-	// Overlay
-	if (CEDevice::hasDesktopResolution()) {
-		_overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd, 16, 0, 0, 0, 0);
-		if (_overlayscreen == NULL)
-			error("_overlayscreen failed (%s)", SDL_GetError());
-		_tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd + 3, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd + 3, 16, 0, 0, 0, 0);
-		if (_tmpscreen2 == NULL)
-			error("_tmpscreen2 failed (%s)", SDL_GetError());
-	} else {
-		_overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight, 16, 0, 0, 0, 0);
-		if (_overlayscreen == NULL)
-			error("_overlayscreen failed (%s)", SDL_GetError());
-		_tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3, 16, 0, 0, 0, 0);
-		if (_tmpscreen2 == NULL)
-			error("_tmpscreen2 failed (%s)", SDL_GetError());
-	}
-
-	// Toolbar
-	_toolbarHighDrawn = false;
-	uint16 *toolbar_screen = (uint16 *)calloc(320 * 40, sizeof(uint16));	// *not* leaking memory here
-	_toolbarLow = SDL_CreateRGBSurfaceFrom(toolbar_screen, 320, 40, 16, 320 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
-
-	if (_toolbarLow == NULL)
-		error("_toolbarLow failed (%s)", SDL_GetError());
-
-	if (_videoMode.screenHeight > 240) {
-		uint16 *toolbar_screen = (uint16 *)calloc(640 * 80, sizeof(uint16));
-		_toolbarHigh = SDL_CreateRGBSurfaceFrom(toolbar_screen, 640, 80, 16, 640 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
-
-		if (_toolbarHigh == NULL)
-			error("_toolbarHigh failed (%s)", SDL_GetError());
-	} else
-		_toolbarHigh = NULL;
-
-
-	// keyboard cursor control, some other better place for it?
-	_km.x_max = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd - 1;
-	_km.y_max = _videoMode.screenHeight * _scaleFactorXm / _scaleFactorXd - 1;
-	_km.delay_time = 25;
-	_km.last_time = 0;
-
-	return true;
-}
-
-void OSystem_WINCE3::unloadGFXMode() {
-	if (_screen) {
-		SDL_FreeSurface(_screen);
-		_screen = NULL;
-	}
-
-	if (_hwscreen) {
-		SDL_FreeSurface(_hwscreen);
-		_hwscreen = NULL;
-	}
+		// Initialize SDL (SDL Subsystems are initiliazed in the corresponding sdl managers)
+		if (SDL_Init(sdlFlags) == -1)
+			error("Could not initialize SDL: %s", SDL_GetError());
 
-	if (_tmpscreen) {
-		SDL_FreeSurface(_tmpscreen);
-		_tmpscreen = NULL;
-	}
-}
-
-bool OSystem_WINCE3::hotswapGFXMode() {
-	if (!_screen)
-		return false;
-
-	// Keep around the old _screen & _tmpscreen so we can restore the screen data
-	// after the mode switch. (also for the overlay)
-	SDL_Surface *old_screen = _screen;
-	SDL_Surface *old_tmpscreen = _tmpscreen;
-	SDL_Surface *old_overlayscreen = _overlayscreen;
-	SDL_Surface *old_tmpscreen2 = _tmpscreen2;
-
-	// Release the HW screen surface
-	SDL_FreeSurface(_hwscreen);
-
-	// Release toolbars
-	free(_toolbarLow->pixels);
-	SDL_FreeSurface(_toolbarLow);
-	if (_toolbarHigh) {
-		free(_toolbarHigh->pixels);
-		SDL_FreeSurface(_toolbarHigh);
-	}
+		// Enable unicode support if possible
+		SDL_EnableUNICODE(1);
 
-	// Setup the new GFX mode
-	if (!loadGFXMode()) {
-		unloadGFXMode();
-
-		_screen = old_screen;
-		_overlayscreen = old_overlayscreen;
-
-		return false;
+		_initedSDL = true;
 	}
-
-	// reset palette
-	SDL_SetColors(_screen, _currentPalette, 0, 256);
-
-	// Restore old screen content
-	SDL_BlitSurface(old_screen, NULL, _screen, NULL);
-	SDL_BlitSurface(old_tmpscreen, NULL, _tmpscreen, NULL);
-	if (_overlayVisible) {
-		SDL_BlitSurface(old_overlayscreen, NULL, _overlayscreen, NULL);
-		SDL_BlitSurface(old_tmpscreen2, NULL, _tmpscreen2, NULL);
-	}
-
-	// Free the old surfaces
-	SDL_FreeSurface(old_screen);
-	SDL_FreeSurface(old_tmpscreen);
-	SDL_FreeSurface(old_overlayscreen);
-	SDL_FreeSurface(old_tmpscreen2);
-
-	// Blit everything back to the screen
-	_toolbarHighDrawn = false;
-	internUpdateScreen();
-
-	// Make sure that a Common::EVENT_SCREEN_CHANGED gets sent later -> FIXME this crashes when no game has been loaded.
-//	_modeChanged = true;
-
-	return true;
-}
-
-void OSystem_WINCE3::internUpdateScreen() {
-	SDL_Surface *srcSurf, *origSurf;
-	static bool old_overlayVisible = false;
-	int numRectsOut = 0;
-	int16 routx, routy, routw, routh, stretch, shakestretch;
-
-	assert(_hwscreen != NULL);
-
-	// bail if the application is minimized, be nice to OS
-	if (!_hasfocus) {
-		Sleep(20);
-		return;
-	}
-
-	// If the shake position changed, fill the dirty area with blackness
-	if (_currentShakePos != _newShakePos) {
-		SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd, _newShakePos * _scaleFactorYm / _scaleFactorYd};
-		if (_videoMode.aspectRatioCorrection)
-			blackrect.h = real2Aspect(blackrect.h - 1) + 1;
-		SDL_FillRect(_hwscreen, &blackrect, 0);
-		_currentShakePos = _newShakePos;
-		_forceFull = true;
-	}
-
-	// Make sure the mouse is drawn, if it should be drawn.
-	drawMouse();
-
-	// Check whether the palette was changed in the meantime and update the
-	// screen surface accordingly.
-	if (_paletteDirtyEnd != 0) {
-		SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart, _paletteDirtyStart, _paletteDirtyEnd - _paletteDirtyStart);
-		_paletteDirtyEnd = 0;
-		_forceFull = true;
-	}
-
-	if (!_overlayVisible) {
-		origSurf = _screen;
-		srcSurf = _tmpscreen;
-	} else {
-		origSurf = _overlayscreen;
-		srcSurf = _tmpscreen2;
-	}
-
-	if (old_overlayVisible != _overlayVisible) {
-		old_overlayVisible = _overlayVisible;
-		update_scalers();
-	}
-
-	// Force a full redraw if requested
-	if (_forceFull) {
-		_numDirtyRects = 1;
-
-		_dirtyRectList[0].x = 0;
-		if (!_zoomDown)
-			_dirtyRectList[0].y = 0;
-		else
-			_dirtyRectList[0].y = _videoMode.screenHeight / 2;
-		_dirtyRectList[0].w = _videoMode.screenWidth;
-		if (!_zoomUp && !_zoomDown)
-			_dirtyRectList[0].h = _videoMode.screenHeight;
-		else
-			_dirtyRectList[0].h = _videoMode.screenHeight / 2;
-
-		_toolbarHandler.forceRedraw();
-	}
-
-	// Only draw anything if necessary
-	if (_numDirtyRects > 0) {
-
-		SDL_Rect *r, *rout;
-		SDL_Rect dst;
-		uint32 srcPitch, dstPitch;
-		SDL_Rect *last_rect = _dirtyRectList + _numDirtyRects;
-		bool toolbarVisible = _toolbarHandler.visible();
-		int toolbarOffset = _toolbarHandler.getOffset();
-
-		for (r = _dirtyRectList; r != last_rect; ++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.
-					// NOTE: This is also known as BLACK MAGIC, copied from the sdl backend
-			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, rout = _dirtyRectOut; r != last_rect; ++r) {
-
-			// always clamp to enclosing, downsampled-grid-aligned rect in the downscaled image
-			if (_scaleFactorXd != 1) {
-				stretch = r->x % _scaleFactorXd;
-				r->x -= stretch;
-				r->w += stretch;
-				r->w = (r->x + r->w + _scaleFactorXd - 1) / _scaleFactorXd * _scaleFactorXd - r->x;
-			}
-			if (_scaleFactorYd != 1) {
-				stretch = r->y % _scaleFactorYd;
-				r->y -= stretch;
-				r->h += stretch;
-				r->h = (r->y + r->h + _scaleFactorYd - 1) / _scaleFactorYd * _scaleFactorYd - r->y;
-			}
-
-			// transform
-			shakestretch = _currentShakePos * _scaleFactorYm / _scaleFactorYd;
-			routx = r->x * _scaleFactorXm / _scaleFactorXd;					// locate position in scaled screen
-			routy = r->y * _scaleFactorYm / _scaleFactorYd + shakestretch;	// adjust for shake offset
-			routw = r->w * _scaleFactorXm / _scaleFactorXd;
-			routh = r->h * _scaleFactorYm / _scaleFactorYd - shakestretch;
-
-			// clipping destination rectangle inside device screen (more strict, also more tricky but more stable)
-			// note that all current scalers do not make dst rect exceed left/right, unless chosen badly (FIXME)
-			if (_zoomDown)	routy -= 240;			// adjust for zoom position
-			if (routy + routh < 0)	continue;
-			if (routy < 0) {
-				routh += routy;
-				r->y -= routy * _scaleFactorYd / _scaleFactorYm;
-				routy = 0;
-				r->h = routh * _scaleFactorYd / _scaleFactorYm;
-			}
-			if (_orientationLandscape) {
-				if (routy > _platformScreenWidth)	continue;
-				if (routy + routh > _platformScreenWidth) {
-					routh = _platformScreenWidth - routy;
-					r->h = routh * _scaleFactorYd / _scaleFactorYm;
-				}
-			} else {
-				if (routy > _platformScreenHeight)	continue;
-				if (routy + routh > _platformScreenHeight) {
-					routh = _platformScreenHeight - routy;
-					r->h = routh * _scaleFactorYd / _scaleFactorYm;
-				}
-			}
-
-			// check if the toolbar is overwritten
-			if (toolbarVisible && r->y + r->h >= toolbarOffset)
-				_toolbarHandler.forceRedraw();
-
-			// blit it (with added voodoo from the sdl backend, shifting the source rect again)
-			_scalerProc(	(byte *)srcSurf->pixels + (r->x * 2 + 2)+ (r->y + 1) * srcPitch, srcPitch,
-					(byte *)_hwscreen->pixels + routx * 2 + routy * dstPitch, dstPitch,
-					r->w, r->h - _currentShakePos);
-
-			// add this rect to output
-			rout->x = routx;	rout->y = routy - shakestretch;
-			rout->w = routw;	rout->h = routh + shakestretch;
-			numRectsOut++;
-			rout++;
-
-		}
-		SDL_UnlockSurface(srcSurf);
-		SDL_UnlockSurface(_hwscreen);
-	}
-	// Add the toolbar if needed
-	SDL_Rect toolbar_rect[1];
-	if (_panelVisible && _toolbarHandler.draw(_toolbarLow, &toolbar_rect[0])) {
-		// It can be drawn, scale it
-		uint32 srcPitch, dstPitch;
-		SDL_Surface *toolbarSurface;
-		ScalerProc *toolbarScaler;
-
-		if (_videoMode.screenHeight > 240) {
-			if (!_toolbarHighDrawn) {
-				// Resize the toolbar
-				SDL_LockSurface(_toolbarLow);
-				SDL_LockSurface(_toolbarHigh);
-				Normal2x((byte*)_toolbarLow->pixels, _toolbarLow->pitch, (byte*)_toolbarHigh->pixels, _toolbarHigh->pitch, toolbar_rect[0].w, toolbar_rect[0].h);
-				SDL_UnlockSurface(_toolbarHigh);
-				SDL_UnlockSurface(_toolbarLow);
-				_toolbarHighDrawn = true;
-			}
-			toolbar_rect[0].w *= 2;
-			toolbar_rect[0].h *= 2;
-			toolbarSurface = _toolbarHigh;
-		}
-		else
-			toolbarSurface = _toolbarLow;
-
-		drawToolbarMouse(toolbarSurface, true);		// draw toolbar mouse if applicable
-
-		// Apply the appropriate scaler
-		SDL_LockSurface(toolbarSurface);
-		SDL_LockSurface(_hwscreen);
-		srcPitch = toolbarSurface->pitch;
-		dstPitch = _hwscreen->pitch;
-
-		toolbarScaler = _scalerProc;
-		if (_videoMode.scaleFactor == 2)
-			toolbarScaler = Normal2x;
-		else if (_videoMode.scaleFactor == 3)
-			toolbarScaler = Normal3x;
-		toolbarScaler((byte *)toolbarSurface->pixels, srcPitch,
-					(byte *)_hwscreen->pixels + (_toolbarHandler.getOffset() * _scaleFactorYm / _scaleFactorYd * dstPitch),
-					dstPitch, toolbar_rect[0].w, toolbar_rect[0].h);
-		SDL_UnlockSurface(toolbarSurface);
-		SDL_UnlockSurface(_hwscreen);
-
-		// And blit it
-		toolbar_rect[0].y = _toolbarHandler.getOffset();
-		toolbar_rect[0].x = toolbar_rect[0].x * _scaleFactorXm / _scaleFactorXd;
-		toolbar_rect[0].y = toolbar_rect[0].y * _scaleFactorYm / _scaleFactorYd;
-		toolbar_rect[0].w = toolbar_rect[0].w * _scaleFactorXm / _scaleFactorXd;
-		toolbar_rect[0].h = toolbar_rect[0].h * _scaleFactorYm / _scaleFactorYd;
-
-		SDL_UpdateRects(_hwscreen, 1, toolbar_rect);
-
-		drawToolbarMouse(toolbarSurface, false);	// undraw toolbar mouse
-	}
-
-	// Finally, blit all our changes to the screen
-	if (numRectsOut > 0)
-		SDL_UpdateRects(_hwscreen, numRectsOut, _dirtyRectOut);
-
-	_numDirtyRects = 0;
-	_forceFull = false;
-}
-
-Graphics::Surface *OSystem_WINCE3::lockScreen() {
-	// Make sure mouse pointer is not painted over the playfield at the time of locking
-	undrawMouse();
-	return OSystem_SDL::lockScreen();
-}
-
-void OSystem_WINCE3::unlockScreen() {
-	OSystem_SDL::unlockScreen();
-}
-
-bool OSystem_WINCE3::saveScreenshot(const char *filename) {
-	assert(_hwscreen != NULL);
-
-	Common::StackLock lock(_graphicsMutex);	// Lock the mutex until this function ends
-	SDL_SaveBMP(_hwscreen, filename);
-	return true;
-}
-
-void OSystem_WINCE3::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
-	assert (_transactionMode == kTransactionNone);
-
-	if (_overlayscreen == NULL)
-		return;
-
-	// Clip the coordinates
-	if (x < 0) {
-		w += x;
-		buf -= x;
-		x = 0;
-	}
-
-	if (y < 0) {
-		h += y; buf -= y * pitch;
-		y = 0;
-	}
-
-	if (w > _videoMode.overlayWidth - x) {
-		w = _videoMode.overlayWidth - x;
-	}
-
-	if (h > _videoMode.overlayHeight - y) {
-		h = _videoMode.overlayHeight - y;
-	}
-
-	if (w <= 0 || h <= 0)
-		return;
-
-	// Mark the modified region as dirty
-	addDirtyRect(x, y, w, h);
-
-	undrawMouse();
-
-	if (SDL_LockSurface(_overlayscreen) == -1)
-		error("SDL_LockSurface failed: %s", SDL_GetError());
-
-	byte *dst = (byte *)_overlayscreen->pixels + y * _overlayscreen->pitch + x * 2;
-	do {
-		memcpy(dst, buf, w * 2);
-		dst += _overlayscreen->pitch;
-		buf += pitch;
-	} while (--h);
-
-	SDL_UnlockSurface(_overlayscreen);
-}
-
-void OSystem_WINCE3::copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) {
-	assert (_transactionMode == kTransactionNone);
-	assert(src);
-
-	if (_screen == NULL)
-		return;
-
-	Common::StackLock lock(_graphicsMutex);	// Lock the mutex until this function ends
-
-	/* Clip the coordinates */
-	if (x < 0) {
-		w += x;
-		src -= x;
-		x = 0;
-	}
-
-	if (y < 0) {
-		h += y;
-		src -= y * pitch;
-		y = 0;
-	}
-
-	if (w > _videoMode.screenWidth - x) {
-		w = _videoMode.screenWidth - x;
-	}
-
-	if (h > _videoMode.screenHeight - y) {
-		h = _videoMode.screenHeight - y;
-	}
-
-	if (w <= 0 || h <= 0)
-		return;
-
-	addDirtyRect(x, y, w, h);
-
-	undrawMouse();
-
-	// Try to lock the screen surface
-	if (SDL_LockSurface(_screen) == -1)
-		error("SDL_LockSurface failed: %s", SDL_GetError());
-
-	byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
-
-	if (_videoMode.screenWidth == pitch && pitch == w) {
-		memcpy(dst, src, h*w);
-	} else {
-		do {
-			memcpy(dst, src, w);
-			src += pitch;
-			dst += _videoMode.screenWidth;
-		} while (--h);
-	}
-
-	// Unlock the screen surface
-	SDL_UnlockSurface(_screen);
-}
-
-void OSystem_WINCE3::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
-
-	undrawMouse();
-	if (w == 0 || h == 0)
-		return;
-
-	_mouseCurState.w = w;
-	_mouseCurState.h = h;
-
-	_mouseHotspotX = hotspot_x;
-	_mouseHotspotY = hotspot_y;
-
-	_mouseKeyColor = keycolor;
-
-	free(_mouseData);
-
-	_mouseData = (byte *) malloc(w * h);
-	memcpy(_mouseData, buf, w * h);
-
-	if (w > _mouseBackupDim || h > _mouseBackupDim) {
-		// mouse has been undrawn, adjust sprite backup area
-		free(_mouseBackupOld);
-		free(_mouseBackupToolbar);
-		uint16 tmp = (w > h) ? w : h;
-		_mouseBackupOld = (byte *) malloc(tmp * tmp * 2);	// can hold 8bpp (playfield) or 16bpp (overlay) data
-		_mouseBackupToolbar = (uint16 *) malloc(tmp * tmp * 2); // 16 bpp
-		_mouseBackupDim = tmp;
-	}
-}
-
-void OSystem_WINCE3::setMousePos(int x, int y) {
-	if (x != _mouseCurState.x || y != _mouseCurState.y) {
-		undrawMouse();
-		_mouseCurState.x = x;
-		_mouseCurState.y = y;
-		updateScreen();
-	}
-}
-
-
-void OSystem_WINCE3::internDrawMouse() {
-	if (!_mouseNeedsRedraw || !_mouseVisible || !_mouseData)
-		return;
-
-	int x = _mouseCurState.x - _mouseHotspotX;
-	int y = _mouseCurState.y - _mouseHotspotY;
-	int w = _mouseCurState.w;
-	int h = _mouseCurState.h;
-	byte color;
-	const byte *src = _mouseData;		// Image representing the mouse
-	int width;
-
-	// clip the mouse rect, and adjust the src pointer accordingly
-	if (x < 0) {
-		w += x;
-		src -= x;
-		x = 0;
-	}
-	if (y < 0) {
-		h += y;
-		src -= y * _mouseCurState.w;
-		y = 0;
-	}
-
-	if (w > _videoMode.screenWidth - x)
-		w = _videoMode.screenWidth - x;
-	if (h > _videoMode.screenHeight - y)
-		h = _videoMode.screenHeight - y;
-
-	// Quick check to see if anything has to be drawn at all
-	if (w <= 0 || h <= 0)
-		return;
-
-	// Draw the mouse cursor; backup the covered area in "bak"
-	if (SDL_LockSurface(_overlayVisible ? _overlayscreen : _screen) == -1)
-		error("SDL_LockSurface failed: %s", SDL_GetError());
-
-	// Mark as dirty
-	addDirtyRect(x, y, w, h);
-
-	if (!_overlayVisible) {
-		byte *bak = _mouseBackupOld;		// Surface used to backup the area obscured by the mouse
-		byte *dst;					// Surface we are drawing into
-
-		dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
-		while (h > 0) {
-			width = w;
-			while (width > 0) {
-				*bak++ = *dst;
-				color = *src++;
-				if (color != _mouseKeyColor)	// transparent, don't draw
-					*dst = color;
-				dst++;
-				width--;
-			}
-			src += _mouseCurState.w - w;
-			bak += _mouseBackupDim - w;
-			dst += _videoMode.screenWidth - w;
-			h--;
-		}
-
-	} else {
-		uint16 *bak = (uint16 *)_mouseBackupOld;	// Surface used to backup the area obscured by the mouse
-		byte *dst;					// Surface we are drawing into
-
-		dst = (byte *)_overlayscreen->pixels + (y + 1) * _overlayscreen->pitch + (x + 1) * 2;
-		while (h > 0) {
-			width = w;
-			while (width > 0) {
-				*bak++ = *(uint16 *)dst;
-				color = *src++;
-				if (color != 0xFF)	// 0xFF = transparent, don't draw
-					*(uint16 *)dst = SDL_MapRGB(_overlayscreen->format, _currentPalette[color].r, _currentPalette[color].g, _currentPalette[color].b);
-				dst += 2;
-				width--;
-			}
-			src += _mouseCurState.w - w;
-			bak += _mouseBackupDim - w;
-			dst += _overlayscreen->pitch - w * 2;
-			h--;
-		}
-	}
-
-	SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);
-
-	// Finally, set the flag to indicate the mouse has been drawn
-	_mouseNeedsRedraw = false;
-}
-
-void OSystem_WINCE3::undrawMouse() {
-	assert (_transactionMode == kTransactionNone);
-
-	if (_mouseNeedsRedraw)
-		return;
-
-	int old_mouse_x = _mouseCurState.x - _mouseHotspotX;
-	int old_mouse_y = _mouseCurState.y - _mouseHotspotY;
-	int old_mouse_w = _mouseCurState.w;
-	int old_mouse_h = _mouseCurState.h;
-
-	// clip the mouse rect, and adjust the src pointer accordingly
-	if (old_mouse_x < 0) {
-		old_mouse_w += old_mouse_x;
-		old_mouse_x = 0;
-	}
-	if (old_mouse_y < 0) {
-		old_mouse_h += old_mouse_y;
-		old_mouse_y = 0;
-	}
-
-	if (old_mouse_w > _videoMode.screenWidth - old_mouse_x)
-		old_mouse_w = _videoMode.screenWidth - old_mouse_x;
-	if (old_mouse_h > _videoMode.screenHeight - old_mouse_y)
-		old_mouse_h = _videoMode.screenHeight - old_mouse_y;
-
-	// Quick check to see if anything has to be drawn at all
-	if (old_mouse_w <= 0 || old_mouse_h <= 0)
-		return;
-
-
-	if (SDL_LockSurface(_overlayVisible ? _overlayscreen : _screen) == -1)
-		error("SDL_LockSurface failed: %s", SDL_GetError());
-
-	int y;
-	if (!_overlayVisible) {
-		byte *dst, *bak = _mouseBackupOld;
-
-		// No need to do clipping here, since drawMouse() did that already
-		dst = (byte *)_screen->pixels + old_mouse_y * _videoMode.screenWidth + old_mouse_x;
-		for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _videoMode.screenWidth)
-			memcpy(dst, bak, old_mouse_w);
-	} else {
-		byte *dst;
-		uint16 *bak = (uint16 *)_mouseBackupOld;
-
-		// No need to do clipping here, since drawMouse() did that already
-		dst = (byte *)_overlayscreen->pixels + (old_mouse_y + 1) * _overlayscreen->pitch + (old_mouse_x + 1) * 2;
-		for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _overlayscreen->pitch)
-			memcpy(dst, bak, old_mouse_w << 1);
-	}
-
-	addDirtyRect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h);
-
-	SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);
-
-	_mouseNeedsRedraw = true;
-}
-
-bool OSystem_WINCE3::showMouse(bool visible) {
-	if (_mouseVisible == visible)
-		return visible;
-
-	if (visible == false)
-		undrawMouse();
-
-	bool last = _mouseVisible;
-	_mouseVisible = visible;
-	_mouseNeedsRedraw = true;
-
-	return last;
-}
-
-void OSystem_WINCE3::drawToolbarMouse(SDL_Surface *surf, bool draw) {
-
-	if (!_mouseData || !_usesEmulatedMouse)
-		return;
-
-	int x = _mouseCurState.x - _mouseHotspotX;
-	int y = _mouseCurState.y - _mouseHotspotY - _toolbarHandler.getOffset();
-	int w = _mouseCurState.w;
-	int h = _mouseCurState.h;
-	byte color;
-	const byte *src = _mouseData;
-	int width;
-
-	// clip
-	if (x < 0) {
-		w += x;
-		src -= x;
-		x = 0;
-	}
-	if (y < 0) {
-		h += y;
-		src -= y * _mouseCurState.w;
-		y = 0;
-	}
-	if (w > surf->w - x)
-		w = surf->w - x;
-	if (h > surf->h - y)
-		h = surf->h - y;
-	if (w <= 0 || h <= 0)
-		return;
-
-	if (SDL_LockSurface(surf) == -1)
-		error("SDL_LockSurface failed at internDrawToolbarMouse: %s", SDL_GetError());
-
-	uint16 *bak = _mouseBackupToolbar;	// toolbar surfaces are 16bpp
-	uint16 *dst;
-	dst = (uint16 *)surf->pixels + y * surf->w + x;
-
-	if (draw) {		// blit it
-		while (h > 0) {
-			width = w;
-			while (width > 0) {
-				*bak++ = *dst;
-				color = *src++;
-				if (color != _mouseKeyColor)	// transparent color
-					*dst = 0xFFFF;
-				dst++;
-				width--;
-			}
-			src += _mouseCurState.w - w;
-			bak += _mouseBackupDim - w;
-			dst += surf->w - w;
-			h--;
-		}
-	} else {		// restore bg
-		for (y = 0; y < h; ++y, bak += _mouseBackupDim, dst += surf->w)
-			memcpy(dst, bak, w << 1);
-	}
-
-	SDL_UnlockSurface(surf);
-}
-
-void OSystem_WINCE3::blitCursor() {
-}
-
-void OSystem_WINCE3::showOverlay() {
-	assert (_transactionMode == kTransactionNone);
-
-	if (_overlayVisible)
-		return;
-
-	undrawMouse();
-	_overlayVisible = true;
-	update_scalers();
-	clearOverlay();
-}
-
-void OSystem_WINCE3::hideOverlay() {
-	assert (_transactionMode == kTransactionNone);
-
-	if (!_overlayVisible)
-		return;
-
-	undrawMouse();
-	_overlayVisible = false;
-	clearOverlay();
-	_forceFull = true;
-}
-
-void OSystem_WINCE3::drawMouse() {
-	if (!(_toolbarHandler.visible() && _mouseCurState.y >= _toolbarHandler.getOffset() && !_usesEmulatedMouse) && !_forceHideMouse)
-		internDrawMouse();
-}
-
-void OSystem_WINCE3::fillMouseEvent(Common::Event &event, int x, int y) {
-	event.mouse.x = x;
-	event.mouse.y = y;
-
-	// Update the "keyboard mouse" coords
-	_km.x = event.mouse.x;
-	_km.y = event.mouse.y;
-
-	// Adjust for the screen scaling
-	if (_zoomDown)
-		event.mouse.y += 240;
-
-	event.mouse.x = event.mouse.x * _scaleFactorXd / _scaleFactorXm;
-	event.mouse.y = event.mouse.y * _scaleFactorYd / _scaleFactorYm;
-}
-
-void OSystem_WINCE3::retrieve_mouse_location(int &x, int &y) {
-	x = _mouseCurState.x;
-	y = _mouseCurState.y;
-
-	x = x * _scaleFactorXm / _scaleFactorXd;
-	y = y * _scaleFactorYm / _scaleFactorYd;
-
-	if (_zoomDown)
-		y -= 240;
-}
-
-void OSystem_WINCE3::warpMouse(int x, int y) {
-	if (_mouseCurState.x != x || _mouseCurState.y != y) {
-		SDL_WarpMouse(x * _scaleFactorXm / _scaleFactorXd, y * _scaleFactorYm / _scaleFactorYd);
-
-		// SDL_WarpMouse() generates a mouse movement event, so
-		// set_mouse_pos() would be called eventually. However, the
-		// cannon script in CoMI calls this function twice each time
-		// the cannon is reloaded. Unless we update the mouse position
-		// immediately the second call is ignored, causing the cannon
-		// to change its aim.
-
-		setMousePos(x, y);
-	}
-}
-
-void OSystem_WINCE3::addDirtyRect(int x, int y, int w, int h, bool mouseRect) {
-
-	if (_forceFull || _paletteDirtyEnd)
-		return;
-
-	OSystem_SDL::addDirtyRect(x, y, w, h, false);
-}
-
-static int mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode, bool unfilter) {
-	if (GUI::Actions::Instance()->mappingActive())
-		return key;
-
-	if (unfilter) {
-		switch (key) {
-		case SDLK_ESCAPE:
-			return SDLK_BACKSPACE;
-		case SDLK_F8:
-			return SDLK_ASTERISK;
-		case SDLK_F9:
-			return SDLK_HASH;
-		default:
-			return key;
-		}
-	}
-
-	if (key >= SDLK_KP0 && key <= SDLK_KP9) {
-		return key - SDLK_KP0 + '0';
-	} else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) {
-		return key;
-	} else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) {
-		return 0;
-	}
-	return key;
-}
-
-bool OSystem_WINCE3::pollEvent(Common::Event &event) {
-	SDL_Event ev;
-	ev.type = SDL_NOEVENT;
-	DWORD currentTime;
-	bool keyEvent = false;
-	int deltaX, deltaY;
-
-	memset(&event, 0, sizeof(Common::Event));
-
-	handleKbdMouse();
-
-	// If the screen mode changed, send an Common::EVENT_SCREEN_CHANGED
-	if (_modeChanged) {
-		_modeChanged = false;
-		event.type = Common::EVENT_SCREEN_CHANGED;
-		_screenChangeCount++;
-		return true;
-	}
-
-	CEDevice::wakeUp();
-
-	currentTime = GetTickCount();
-
-	while (SDL_PollEvent(&ev)) {
-		switch (ev.type) {
-		case SDL_KEYDOWN:
-			debug(1, "Key down %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));
-			// KMOD_RESERVED is used if the key has been injected by an external buffer
-			if (ev.key.keysym.mod != KMOD_RESERVED && !_unfilteredkeys) {
-				keyEvent = true;
-				_lastKeyPressed = ev.key.keysym.sym;
-				_keyRepeatTime = currentTime;
-				_keyRepeat = 0;
-
-				if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, true))
-					return true;
-			}
-
-			if (GUI_Actions::Instance()->mappingActive())
-				event.kbd.flags = 0xFF;
-			else if (ev.key.keysym.sym == SDLK_PAUSE) {
-				_lastKeyPressed = 0;
-				event.type = Common::EVENT_PREDICTIVE_DIALOG;
-				return true;
-			} 			event.type = Common::EVENT_KEYDOWN;
-			if (!_unfilteredkeys)
-				event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
-			else
-				event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
-			event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
-
-			if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
-				event.kbd.ascii ^= 0x20;
-				event.kbd.flags = Common::KBD_SHIFT;
-			}
-
-			return true;
-
-		case SDL_KEYUP:
-			debug(1, "Key up %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));
-			// KMOD_RESERVED is used if the key has been injected by an external buffer
-			if (ev.key.keysym.mod != KMOD_RESERVED && !_unfilteredkeys) {
-				keyEvent = true;
-				_lastKeyPressed = 0;
-
-				if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, false))
-					return true;
-			}
-
-			if (GUI_Actions::Instance()->mappingActive())
-				event.kbd.flags = 0xFF;
-			else if (ev.key.keysym.sym == SDLK_PAUSE) {
-				_lastKeyPressed = 0;
-				return false;	// chew up the show agi dialog key up event
-			}
-
-			event.type = Common::EVENT_KEYUP;
-			if (!_unfilteredkeys)
-				event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
-			else
-				event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
-			event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
-
-			if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
-				event.kbd.ascii ^= 0x20;
-				event.kbd.flags = Common::KBD_SHIFT;
-			}
-
-			return true;
-
-		case SDL_MOUSEMOTION:
-			event.type = Common::EVENT_MOUSEMOVE;
-			fillMouseEvent(event, ev.motion.x, ev.motion.y);
-			setMousePos(event.mouse.x, event.mouse.y);
-			return true;
-
-		case SDL_MOUSEBUTTONDOWN:
-			if (ev.button.button == SDL_BUTTON_LEFT)
-				event.type = Common::EVENT_LBUTTONDOWN;
-			else if (ev.button.button == SDL_BUTTON_RIGHT)
-				event.type = Common::EVENT_RBUTTONDOWN;
-			else
-				break;
-			fillMouseEvent(event, ev.button.x, ev.button.y);
-
-
-			if (event.mouse.x > _tapX)
-				deltaX = event.mouse.x - _tapX;
-			else
-				deltaX = _tapX - event.mouse.x;
-			if (event.mouse.y > _tapY)
-				deltaY = event.mouse.y - _tapY;
-			else
-				deltaY = _tapY - event.mouse.y;
-			_closeClick = (deltaX <= 5 && deltaY <= 5);
-
-			if (!_isSmartphone) {
-				// handle double-taps
-				if (_tapTime) {		// second tap
-					if (_closeClick && (GetTickCount() - _tapTime < 1000)) {
-						if (event.mouse.y <= 20 && _panelInitialized) {		// top of screen (show panel)
-							swap_panel_visibility();
-						} else if (!_noDoubleTapRMB) {		// right click
-							event.type = Common::EVENT_RBUTTONDOWN;
-							_rbutton = true;
-						}
-					}
-					_tapTime = 0;
-				} else {
-					_tapTime = GetTickCount();
-					_tapX = event.mouse.x;
-					_tapY = event.mouse.y;
-				}
-			}
-
-			if (_freeLook && !_closeClick) {
-				_rbutton = false;
-				_tapTime = 0;
-				_tapX = event.mouse.x;
-				_tapY = event.mouse.y;
-				event.type = Common::EVENT_MOUSEMOVE;
-				setMousePos(event.mouse.x, event.mouse.y);
-			}
-
-
-			if (_toolbarHandler.action(event.mouse.x, event.mouse.y, true)) {
-				if (!_toolbarHandler.drawn()) {
-					_toolbarHighDrawn = false;
-					internUpdateScreen();
-				}
-				if (_newOrientation != _orientationLandscape){
-					_orientationLandscape = _newOrientation;
-					_toolbarHighDrawn = false;
-					ConfMan.setInt("landscape", _orientationLandscape);
-					ConfMan.flushToDisk();
-					hotswapGFXMode();
-				}
-				return false;
-			}
-
-			return true;
-
-		case SDL_MOUSEBUTTONUP:
-			if (ev.button.button == SDL_BUTTON_LEFT)
-				event.type = Common::EVENT_LBUTTONUP;
-			else if (ev.button.button == SDL_BUTTON_RIGHT)
-				event.type = Common::EVENT_RBUTTONUP;
-			else
-				break;
-
-			if (_rbutton) {
-				event.type = Common::EVENT_RBUTTONUP;
-				_rbutton = false;
-			}
-
-			fillMouseEvent(event, ev.button.x, ev.button.y);
-
-			if (_freeLook && !_closeClick) {
-				_tapX = event.mouse.x;
-				_tapY = event.mouse.y;
-				event.type = Common::EVENT_MOUSEMOVE;
-				setMousePos(event.mouse.x, event.mouse.y);
-			}
-
-			if (_toolbarHandler.action(event.mouse.x, event.mouse.y, false)) {
-				if (!_toolbarHandler.drawn()) {
-					_toolbarHighDrawn = false;
-					internUpdateScreen();
-				}
-				return false;
-
-			}
-			return true;
-
-		case SDL_VIDEOEXPOSE:
-			_forceFull = true;
-			break;
-
-		case SDL_QUIT:
-			event.type = Common::EVENT_QUIT;
-			return true;
-
-		case SDL_ACTIVEEVENT:
-			if (ev.active.state & SDL_APPMOUSEFOCUS)
-				debug(2, "%s mouse focus.", ev.active.gain ? "Got" : "Lost");
-			if (ev.active.state & SDL_APPINPUTFOCUS)
-				debug(2, "%s input focus.", ev.active.gain ? "Got" : "Lost");
-			if (ev.active.state & SDL_APPACTIVE)
-				debug(2, "%s total focus.", ev.active.gain ? "Got" : "Lost");
-			if (ev.active.state & SDL_APPINPUTFOCUS) {
-				_hasfocus = ev.active.gain;
-				SDL_PauseAudio(!_hasfocus);
-				_forceFull |= _hasfocus;
-			}
-			break;
-		}
-	}
-
-	// Simulate repeated key for backend
-	if (!keyEvent && _lastKeyPressed && currentTime > _keyRepeatTime + _keyRepeatTrigger) {
-		_keyRepeatTime = currentTime;
-		_keyRepeat++;
-		GUI_Actions::Instance()->performMapped(_lastKeyPressed, true);
-	}
-
-	return false;
 }
 
 void OSystem_WINCE3::quit() {
@@ -2508,8 +579,3 @@ void OSystem_WINCE3::getTimeAndDate(TimeDate &t) const {
 int OSystem_WINCE3::_platformScreenWidth;
 int OSystem_WINCE3::_platformScreenHeight;
 bool OSystem_WINCE3::_isOzone;
-OSystem_WINCE3::zoneDesc OSystem_WINCE3::_zones[TOTAL_ZONES] = {
-	{ 0, 0, 320, 145 },
-	{ 0, 145, 150, 55 },
-	{ 150, 145, 170, 55 }
-};
diff --git a/backends/platform/wince/wince-sdl.h b/backends/platform/wince/wince-sdl.h
index 6cc6e53..34672f8 100644
--- a/backends/platform/wince/wince-sdl.h
+++ b/backends/platform/wince/wince-sdl.h
@@ -35,7 +35,10 @@
 #include "backends/platform/wince/CEkeys/CEKeys.h"
 #include "backends/platform/wince/CEDevice.h"
 
-#define TOTAL_ZONES 3
+#include "backends/graphics/wincesdl/wincesdl-graphics.h"
+#include "backends/events/wincesdl/wincesdl-events.h"
+#include "backends/timer/default/default-timer.h"
+#include "backends/fs/windows/windows-fs-factory.h"
 
 // defines used for implementing the raw frame buffer access method (2003+)
 #define GETRAWFRAMEBUFFER   0x00020001
@@ -46,202 +49,45 @@
 class OSystem_WINCE3 : public OSystem_SDL {
 public:
 	OSystem_WINCE3();
-
-	// Update the dirty areas of the screen
-	void internUpdateScreen();
+	virtual ~OSystem_WINCE3();
 
 	void setGraphicsModeIntern();
-	void initSize(uint w, uint h, const Graphics::PixelFormat *format);
 	void initBackend();
 
-	// Overloaded from SDL backend (toolbar handling)
-	bool pollEvent(Common::Event &event);
-	// Overloaded from SDL backend (toolbar handling)
-	void drawMouse();
-	// Overloaded from SDL backend (mouse and new scaler handling)
-	void fillMouseEvent(Common::Event &event, int x, int y);
-	// Overloaded from SDL backend (new scaler handling)
-	void addDirtyRect(int x, int y, int w, int h, bool mouseRect = false);
-	// Overloaded from SDL backend (new scaler handling)
-	void warpMouse(int x, int y);
 	// Overloaded from SDL backend
 	void quit();
-	// Overloaded from SDL backend (master volume and sample rate subtleties)
-	void setupMixer();
 	// Overloaded from OSystem
 	void engineInit();
 	void getTimeAndDate(TimeDate &t) const;
 
 	virtual Common::String getDefaultConfigFileName();
+	virtual FilesystemFactory *getFilesystemFactory();
 
-
-	// Overloaded from SDL_Common (FIXME)
-	void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // overloaded by CE backend
-	void undrawMouse();
-	void blitCursor();
-	bool showMouse(bool visible);
-	void setMousePos(int x, int y);
-	void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); // overloaded by CE backend (FIXME)
-	void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
-	void showOverlay();
-	void hideOverlay();
-	Graphics::Surface *lockScreen();
-	void unlockScreen();
-
-	// GUI and action stuff
-	void swap_panel_visibility();
-	void swap_panel();
 	void swap_sound_master();
-	void add_right_click(bool pushed);
-	void swap_mouse_visibility();
-	void swap_freeLook();
-	void swap_zoom_up();
-	void swap_zoom_down();
-	void swap_smartphone_keyboard();
-
-//#ifdef WIN32_PLATFORM_WFSP
-	// Smartphone actions
-
-	void initZones();
-	void loadDeviceConfigurationElement(String element, int &value, int defaultValue);
-	void loadDeviceConfiguration();
-	void add_left_click(bool pushed);
-	void move_cursor_up();
-	void move_cursor_down();
-	void move_cursor_left();
-	void move_cursor_right();
-	void switch_zone();
-	void smartphone_rotate_display();
-//#endif
 
 	static int getScreenWidth();
 	static int getScreenHeight();
 	static void initScreenInfos();
 	static bool isOzone();
 
-protected:
-	bool loadGFXMode();
-	void unloadGFXMode();
-	bool hotswapGFXMode();
-	bool saveScreenshot(const char *filename);
-
-
-	const GraphicsMode *getSupportedGraphicsModes() const;
-	bool setGraphicsMode(int mode);
-	//int getGraphicsMode() const;
-	int getDefaultGraphicsMode() const;
-
-	bool hasFeature(Feature f);
-	void setFeatureState(Feature f, bool enable);
-	bool getFeatureState(Feature f);
+	static bool _soundMaster;	// turn off sound after all calculations
+								// static since needed by the SDL callback
 
-	void internDrawMouse();
-	void drawToolbarMouse(SDL_Surface *surf, bool draw);
+protected:
+	void initSDL();
+	Audio::MixerImpl *_mixer;
+	DefaultTimerManager *_timer;
+	FilesystemFactory *_fsFactory;
 
 private:
-
-#ifdef USE_VORBIS
-	bool checkOggHighSampleRate();
-#endif
-
-	static void private_sound_proc(void *param, byte *buf, int len);
-
-	bool update_scalers();
-	void create_toolbar();
-	void update_game_settings();
 	void check_mappings();
-	uint32 compute_sample_rate();
-
-	void retrieve_mouse_location(int &x, int &y);
-
-	CEGUI::ToolbarHandler _toolbarHandler;
-
-	SDL_Surface *_toolbarLow;	// toolbar 320x40
-	SDL_Surface *_toolbarHigh;	// toolbar 640x80
-	bool _toolbarHighDrawn;		// cache toolbar 640x80
-
-	bool _freeLook;			// freeLook mode (do not send mouse button events)
-
-	bool _forceHideMouse;		// force invisible mouse cursor
 
 	bool _forcePanelInvisible;	// force panel visibility for some cases
-	bool _panelVisible;		// panel visibility
-	bool _panelStateForced;		// panel visibility forced by external call
-
-	bool _panelInitialized;		// only initialize the toolbar once
-
-	bool _unfilteredkeys;		// discard key mapping temporarily (agi pred. dialog)
-	static bool _soundMaster;	// turn off sound after all calculations
-								// static since needed by the SDL callback
-	int _orientationLandscape;	// current orientation
-	int _newOrientation;		// new orientation
-
-	bool _saveToolbarState;		// save visibility when forced
-	String _saveActiveToolbar;	// save active toolbar when forced
-
-	bool _saveToolbarZoom;		// save visibility when zooming
-	bool _zoomUp;			// zooming up mode
-	bool _zoomDown;			// zooming down mode
-
-	bool _noDoubleTapRMB;	// disable double tap -> rmb click
-	bool _rbutton;			// double tap -> right button simulation
-	bool _closeClick;		// flag when taps are spatially close together
-
-	bool _usesEmulatedMouse;	// emulated mousemove ever been used in this session
-
-	bool _canBeAspectScaled;	// game screen size allows for aspect scaling
-
-	int _scaleFactorXm;		// scaler X *
-	int _scaleFactorXd;		// scaler X /
-	int _scaleFactorYm;		// scaler Y *
-	int _scaleFactorYd;		// scaler Y /
-	SDL_Rect _dirtyRectOut[NUM_DIRTY_RECT];
-	bool _scalersChanged;
-	bool _hasfocus;			// scummvm has the top window
 
 	static int _platformScreenWidth;
 	static int _platformScreenHeight;
 	static bool _isOzone;		// true if running on Windows 2003 SE
 
-	// Keyboard tap
-	int _tapX;
-	int _tapY;
-	long _tapTime;
-
-	// Mouse
-	int	_mouseHotspotX, _mouseHotspotY;
-	byte *_mouseBackupOld;
-	uint16 *_mouseBackupToolbar;
-	uint16 _mouseBackupDim;
-
-	// Smartphone specific variables
-
-	int _lastKeyPressed;			// last key pressed
-	int _keyRepeat;				// number of time the last key was repeated
-	int _keyRepeatTime;			// elapsed time since the key was pressed
-	int _keyRepeatTrigger;			// minimum time to consider the key was repeated
-
-	int _repeatX;				// repeat trigger for left and right cursor moves
-	int _repeatY;				// repeat trigger for up and down cursor moves
-	int _stepX1;				// offset for left and right cursor moves (slowest)
-	int _stepX2;				// offset for left and right cursor moves (faster)
-	int _stepX3;				// offset for left and right cursor moves (fastest)
-	int _stepY1;				// offset for up and down cursor moves (slowest)
-	int _stepY2;				// offset for up and down cursor moves (faster)
-	int _stepY3;				// offset for up and down cursor moves (fastest)
-
-	int _mouseXZone[TOTAL_ZONES];
-	int _mouseYZone[TOTAL_ZONES];
-	int _currentZone;
-
-	struct zoneDesc {
-		int x;
-		int y;
-		int width;
-		int height;
-	};
-
-	static zoneDesc _zones[TOTAL_ZONES];
 };
 
 #endif






More information about the Scummvm-git-logs mailing list