aboutsummaryrefslogtreecommitdiff
path: root/backends/platform
diff options
context:
space:
mode:
Diffstat (limited to 'backends/platform')
-rw-r--r--backends/platform/wince/CEActionsPocket.cpp307
-rw-r--r--backends/platform/wince/CEActionsPocket.h91
-rw-r--r--backends/platform/wince/CEActionsSmartphone.cpp238
-rw-r--r--backends/platform/wince/CEActionsSmartphone.h82
-rw-r--r--backends/platform/wince/CEDevice.cpp198
-rw-r--r--backends/platform/wince/CEDevice.h46
-rw-r--r--backends/platform/wince/CEException.cpp156
-rw-r--r--backends/platform/wince/CEException.h34
-rw-r--r--backends/platform/wince/CEKeysDialog.cpp125
-rw-r--r--backends/platform/wince/CEKeysDialog.h46
-rw-r--r--backends/platform/wince/CELauncherDialog.cpp176
-rw-r--r--backends/platform/wince/CELauncherDialog.h42
-rw-r--r--backends/platform/wince/CEScaler.cpp213
-rw-r--r--backends/platform/wince/CEScaler.h42
-rw-r--r--backends/platform/wince/CEgui/CEGUI.h27
-rw-r--r--backends/platform/wince/CEgui/GUIElement.cpp125
-rw-r--r--backends/platform/wince/CEgui/GUIElement.h65
-rw-r--r--backends/platform/wince/CEgui/ItemAction.cpp48
-rw-r--r--backends/platform/wince/CEgui/ItemAction.h44
-rw-r--r--backends/platform/wince/CEgui/ItemSwitch.cpp93
-rw-r--r--backends/platform/wince/CEgui/ItemSwitch.h53
-rw-r--r--backends/platform/wince/CEgui/Panel.cpp83
-rw-r--r--backends/platform/wince/CEgui/Panel.h60
-rw-r--r--backends/platform/wince/CEgui/PanelItem.cpp45
-rw-r--r--backends/platform/wince/CEgui/PanelItem.h48
-rw-r--r--backends/platform/wince/CEgui/PanelKeyboard.cpp88
-rw-r--r--backends/platform/wince/CEgui/PanelKeyboard.h48
-rw-r--r--backends/platform/wince/CEgui/SDL_ImageResource.cpp83
-rw-r--r--backends/platform/wince/CEgui/SDL_ImageResource.h46
-rw-r--r--backends/platform/wince/CEgui/Toolbar.cpp36
-rw-r--r--backends/platform/wince/CEgui/Toolbar.h49
-rw-r--r--backends/platform/wince/CEgui/ToolbarHandler.cpp125
-rw-r--r--backends/platform/wince/CEgui/ToolbarHandler.h65
-rw-r--r--backends/platform/wince/CEkeys/CEKeys.h24
-rw-r--r--backends/platform/wince/CEkeys/EventsBuffer.cpp75
-rw-r--r--backends/platform/wince/CEkeys/EventsBuffer.h47
-rw-r--r--backends/platform/wince/PocketSCUMM.rc145
-rw-r--r--backends/platform/wince/README-WinCE506
-rw-r--r--backends/platform/wince/icons/scumm_icon.icobin0 -> 3638 bytes
-rw-r--r--backends/platform/wince/images/Action.bmpbin0 -> 2102 bytes
-rw-r--r--backends/platform/wince/images/DiskwFolder.bmpbin0 -> 2102 bytes
-rw-r--r--backends/platform/wince/images/MonkeyLandscape.bmpbin0 -> 630 bytes
-rw-r--r--backends/platform/wince/images/MonkeyPortrait.bmpbin0 -> 630 bytes
-rw-r--r--backends/platform/wince/images/SoundOff.bmpbin0 -> 2102 bytes
-rw-r--r--backends/platform/wince/images/SoundOn.bmpbin0 -> 2102 bytes
-rw-r--r--backends/platform/wince/images/bindkeys.bmpbin0 -> 2102 bytes
-rw-r--r--backends/platform/wince/images/keyboard.bmpbin0 -> 38454 bytes
-rw-r--r--backends/platform/wince/images/panelbig.bmpbin0 -> 13878 bytes
-rw-r--r--backends/platform/wince/missing/assert.h9
-rw-r--r--backends/platform/wince/missing/conio.h2
-rw-r--r--backends/platform/wince/missing/dir.h1
-rw-r--r--backends/platform/wince/missing/direct.h1
-rw-r--r--backends/platform/wince/missing/dirent.h52
-rw-r--r--backends/platform/wince/missing/errno.h1
-rw-r--r--backends/platform/wince/missing/fcntl.h1
-rw-r--r--backends/platform/wince/missing/io.h15
-rw-r--r--backends/platform/wince/missing/missing.cpp644
-rw-r--r--backends/platform/wince/missing/signal.h3
-rw-r--r--backends/platform/wince/missing/sys/stat.h23
-rw-r--r--backends/platform/wince/missing/sys/time.h10
-rw-r--r--backends/platform/wince/missing/sys/types.h5
-rw-r--r--backends/platform/wince/missing/time.h24
-rw-r--r--backends/platform/wince/missing/unistd.h1
-rw-r--r--backends/platform/wince/newres.h55
-rw-r--r--backends/platform/wince/ozone.h40
-rw-r--r--backends/platform/wince/portdefs.h73
-rw-r--r--backends/platform/wince/resource.h39
-rw-r--r--backends/platform/wince/wince-sdl.cpp2272
-rw-r--r--backends/platform/wince/wince-sdl.h237
69 files changed, 7332 insertions, 0 deletions
diff --git a/backends/platform/wince/CEActionsPocket.cpp b/backends/platform/wince/CEActionsPocket.cpp
new file mode 100644
index 0000000000..ee76245ef3
--- /dev/null
+++ b/backends/platform/wince/CEActionsPocket.cpp
@@ -0,0 +1,307 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "CEActionsPocket.h"
+#include "EventsBuffer.h"
+
+#include "gui/message.h"
+
+#include "scumm/scumm.h"
+
+#include "common/config-manager.h"
+
+#include "gui/KeysDialog.h"
+
+#ifdef _WIN32_WCE
+#define KEY_ALL_SKIP 3457
+#endif
+
+const String pocketActionNames[] = {
+ "Pause",
+ "Save",
+ "Quit",
+ "Skip",
+ "Hide",
+ "Keyboard",
+ "Sound",
+ "Right click",
+ "Cursor",
+ "Free look",
+ "Zoom up",
+ "Zoom down",
+ "FT Cheat",
+ "Bind Keys",
+ "Up",
+ "Down",
+ "Left",
+ "Right",
+ "Left Click",
+};
+
+void CEActionsPocket::init() {
+ _instance = new CEActionsPocket(ConfMan.get("gameid"));
+}
+
+
+String CEActionsPocket::actionName(GUI::ActionType action) {
+ return pocketActionNames[action];
+}
+
+int CEActionsPocket::size() {
+ return POCKET_ACTION_LAST;
+}
+
+String CEActionsPocket::domain() {
+ return ConfMan.kApplicationDomain;
+}
+
+int CEActionsPocket::version() {
+ return POCKET_ACTION_VERSION;
+}
+
+CEActionsPocket::CEActionsPocket(const Common::String &gameid) :
+GUI::Actions()
+{
+ int i;
+
+ _right_click_needed = false;
+ _hide_toolbar_needed = false;
+ _zoom_needed = false;
+
+ for (i=0; i<POCKET_ACTION_LAST; i++) {
+ _action_mapping[i] = 0;
+ _action_enabled[i] = false;
+ }
+
+ // apply some default settings for emulated mouse
+ _action_enabled[POCKET_ACTION_LEFTCLICK] = true;
+ _action_enabled[POCKET_ACTION_UP] = true;
+ _action_enabled[POCKET_ACTION_DOWN] = true;
+ _action_enabled[POCKET_ACTION_LEFT] = true;
+ _action_enabled[POCKET_ACTION_RIGHT] = true;
+ _action_mapping[POCKET_ACTION_LEFTCLICK] = VK_RETURN;
+ _action_mapping[POCKET_ACTION_UP] = 0x111;
+ _action_mapping[POCKET_ACTION_DOWN] = 0x112;
+ _action_mapping[POCKET_ACTION_LEFT] = 0x114;
+ _action_mapping[POCKET_ACTION_RIGHT] = 0x113;
+}
+
+void CEActionsPocket::initInstanceMain(OSystem *mainSystem) {
+ // Nothing generic to do for Pocket PC
+ _CESystem = static_cast<OSystem_WINCE3*>(mainSystem);
+ GUI_Actions::initInstanceMain(mainSystem);
+}
+
+void CEActionsPocket::initInstanceGame() {
+ String gameid(ConfMan.get("gameid"));
+ bool is_simon = (strncmp(gameid.c_str(), "simon", 5) == 0);
+ bool is_sword1 = (gameid == "sword1");
+ bool is_sword2 = (strcmp(gameid.c_str(), "sword2") == 0);
+ bool is_queen = (gameid == "queen");
+ bool is_sky = (gameid == "sky");
+ bool is_comi = (strncmp(gameid.c_str(), "comi", 4) == 0);
+ bool is_gob = (strncmp(gameid.c_str(), "gob", 3) == 0);
+ bool is_ite = ((strncmp(gameid.c_str(), "ite", 3) == 0) ||
+ (strncmp(gameid.c_str(), "ihnm", 4) == 0));
+ bool is_kyra = (gameid == "kyra1");
+
+ GUI_Actions::initInstanceGame();
+
+ // See if a right click mapping could be needed
+ if (is_sword1 || is_sword2 || is_sky || is_queen || is_comi || is_gob ||
+ gameid == "samnmax")
+ _right_click_needed = true;
+
+ // See if a "hide toolbar" mapping could be needed
+ if (is_sword1 || is_sword2 || is_comi)
+ _hide_toolbar_needed = true;
+
+ // Initialize keys for different actions
+ // Pause
+ _key_action[POCKET_ACTION_PAUSE].setAscii(VK_SPACE);
+ _action_enabled[POCKET_ACTION_PAUSE] = true;
+ // Save
+ if (is_simon || is_sword2 || is_gob || is_kyra)
+ _action_enabled[POCKET_ACTION_SAVE] = false;
+ else
+ if (is_queen || is_ite) {
+ _action_enabled[POCKET_ACTION_SAVE] = true;
+ _key_action[POCKET_ACTION_SAVE].setAscii(286); // F5 key for FOTAQ & ITE
+ }
+ else
+ if (is_sky) {
+ _action_enabled[POCKET_ACTION_SAVE] = true;
+ _key_action[POCKET_ACTION_SAVE].setAscii(63);
+ }
+ else {
+ _action_enabled[POCKET_ACTION_SAVE] = true;
+ _key_action[POCKET_ACTION_SAVE].setAscii(319); // F5 key
+ }
+ // Quit
+ _action_enabled[POCKET_ACTION_QUIT] = true;
+ // Skip
+ _action_enabled[POCKET_ACTION_SKIP] = true;
+ if (is_simon || is_sky || is_sword2 || is_queen || is_sword1 || is_gob || is_ite || is_kyra)
+ _key_action[POCKET_ACTION_SKIP].setAscii(VK_ESCAPE);
+ else
+ _key_action[POCKET_ACTION_SKIP].setAscii(KEY_ALL_SKIP);
+ // Hide
+ _action_enabled[POCKET_ACTION_HIDE] = true;
+ // Keyboard
+ _action_enabled[POCKET_ACTION_KEYBOARD] = true;
+ // Sound
+ _action_enabled[POCKET_ACTION_SOUND] = true;
+ // RightClick
+ _action_enabled[POCKET_ACTION_RIGHTCLICK] = true;
+ // Cursor
+ _action_enabled[POCKET_ACTION_CURSOR] = true;
+ // Freelook
+ _action_enabled[POCKET_ACTION_FREELOOK] = true;
+ // Zoom
+ if (is_sword1 || is_sword2 || is_comi) {
+ _zoom_needed = true;
+ _action_enabled[POCKET_ACTION_ZOOM_UP] = true;
+ _action_enabled[POCKET_ACTION_ZOOM_DOWN] = true;
+ }
+ // FT Cheat
+ _action_enabled[POCKET_ACTION_FT_CHEAT] = true;
+ _key_action[POCKET_ACTION_FT_CHEAT].setAscii(86); // shift-V
+ // Key bind method
+ _action_enabled[POCKET_ACTION_BINDKEYS] = true;
+}
+
+
+CEActionsPocket::~CEActionsPocket() {
+}
+
+bool CEActionsPocket::perform(GUI::ActionType action, bool pushed) {
+ static bool keydialogrunning = false;
+
+ if (!pushed) {
+ switch(action) {
+ case POCKET_ACTION_RIGHTCLICK:
+ _CESystem->add_right_click(false);
+ return true;
+ case POCKET_ACTION_LEFTCLICK:
+ _CESystem->add_left_click(false);
+ return true;
+ case POCKET_ACTION_PAUSE:
+ case POCKET_ACTION_SAVE:
+ case POCKET_ACTION_SKIP:
+ case POCKET_ACTION_FT_CHEAT:
+ EventsBuffer::simulateKey(&_key_action[action], false);
+ return true;
+
+ }
+ return false;
+ }
+
+ switch (action) {
+ case POCKET_ACTION_PAUSE:
+ case POCKET_ACTION_SAVE:
+ case POCKET_ACTION_SKIP:
+ case POCKET_ACTION_FT_CHEAT:
+ EventsBuffer::simulateKey(&_key_action[action], true);
+ return true;
+ case POCKET_ACTION_KEYBOARD:
+ _CESystem->swap_panel();
+ return true;
+ case POCKET_ACTION_HIDE:
+ _CESystem->swap_panel_visibility();
+ return true;
+ case POCKET_ACTION_SOUND:
+ _CESystem->swap_sound_master();
+ return true;
+ case POCKET_ACTION_RIGHTCLICK:
+ _CESystem->add_right_click(true);
+ return true;
+ case POCKET_ACTION_CURSOR:
+ _CESystem->swap_mouse_visibility();
+ return true;
+ case POCKET_ACTION_FREELOOK:
+ _CESystem->swap_freeLook();
+ return true;
+ case POCKET_ACTION_ZOOM_UP:
+ _CESystem->swap_zoom_up();
+ return true;
+ case POCKET_ACTION_ZOOM_DOWN:
+ _CESystem->swap_zoom_down();
+ return true;
+ case POCKET_ACTION_LEFTCLICK:
+ _CESystem->add_left_click(true);
+ return true;
+ case POCKET_ACTION_UP:
+ _CESystem->move_cursor_up();
+ return true;
+ case POCKET_ACTION_DOWN:
+ _CESystem->move_cursor_down();
+ return true;
+ case POCKET_ACTION_LEFT:
+ _CESystem->move_cursor_left();
+ return true;
+ case POCKET_ACTION_RIGHT:
+ _CESystem->move_cursor_right();
+ return true;
+ case POCKET_ACTION_QUIT:
+ {
+ GUI::MessageDialog alert("Do you want to quit ?", "Yes", "No");
+ if (alert.runModal() == GUI::kMessageOK)
+ _mainSystem->quit();
+ return true;
+ }
+ case POCKET_ACTION_BINDKEYS:
+ if (!keydialogrunning) {
+ keydialogrunning = true;
+ GUI::KeysDialog *keysDialog = new GUI::KeysDialog();
+ keysDialog->runModal();
+ delete keysDialog;
+ keydialogrunning = false;
+ }
+ return true;
+ }
+ return false;
+}
+
+bool CEActionsPocket::needsRightClickMapping() {
+ if (!_right_click_needed)
+ return false;
+ else
+ return (_action_mapping[POCKET_ACTION_RIGHTCLICK] == 0);
+}
+
+bool CEActionsPocket::needsHideToolbarMapping() {
+ if (!_hide_toolbar_needed)
+ return false;
+ else
+ return (_action_mapping[POCKET_ACTION_HIDE] == 0);
+}
+
+
+bool CEActionsPocket::needsZoomMapping() {
+ if (!_zoom_needed)
+ return false;
+ else
+ return (_action_mapping[POCKET_ACTION_ZOOM_UP] == 0 || _action_mapping[POCKET_ACTION_ZOOM_DOWN] == 0);
+}
+
diff --git a/backends/platform/wince/CEActionsPocket.h b/backends/platform/wince/CEActionsPocket.h
new file mode 100644
index 0000000000..f3d8f482cb
--- /dev/null
+++ b/backends/platform/wince/CEActionsPocket.h
@@ -0,0 +1,91 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEACTIONSPOCKET
+#define CEACTIONSPOCKET
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+
+
+#include "wince-sdl.h"
+#include "gui/Key.h"
+
+#include "gui/Actions.h"
+
+#define POCKET_ACTION_VERSION 4
+
+enum pocketActionType {
+ POCKET_ACTION_PAUSE = 0,
+ POCKET_ACTION_SAVE,
+ POCKET_ACTION_QUIT,
+ POCKET_ACTION_SKIP,
+ POCKET_ACTION_HIDE,
+ POCKET_ACTION_KEYBOARD,
+ POCKET_ACTION_SOUND,
+ POCKET_ACTION_RIGHTCLICK,
+ POCKET_ACTION_CURSOR,
+ POCKET_ACTION_FREELOOK,
+ POCKET_ACTION_ZOOM_UP,
+ POCKET_ACTION_ZOOM_DOWN,
+ POCKET_ACTION_FT_CHEAT,
+ POCKET_ACTION_BINDKEYS,
+ POCKET_ACTION_UP,
+ POCKET_ACTION_DOWN,
+ POCKET_ACTION_LEFT,
+ POCKET_ACTION_RIGHT,
+ POCKET_ACTION_LEFTCLICK,
+
+ POCKET_ACTION_LAST
+};
+
+class CEActionsPocket : public GUI::Actions {
+ public:
+ // Actions
+ bool perform(GUI::ActionType action, bool pushed = true);
+ String actionName(GUI::ActionType action);
+ int size();
+
+ static void init();
+ void initInstanceMain(OSystem *mainSystem);
+ void initInstanceGame();
+
+ // Action domain
+ String domain();
+ int version();
+
+ // Utility
+ bool needsRightClickMapping();
+ bool needsHideToolbarMapping();
+ bool needsZoomMapping();
+
+ ~CEActionsPocket();
+ private:
+ CEActionsPocket(const Common::String &gameid);
+ bool _right_click_needed;
+ bool _hide_toolbar_needed;
+ bool _zoom_needed;
+ OSystem_WINCE3 *_CESystem;
+ };
+
+#endif
diff --git a/backends/platform/wince/CEActionsSmartphone.cpp b/backends/platform/wince/CEActionsSmartphone.cpp
new file mode 100644
index 0000000000..4ee4963f66
--- /dev/null
+++ b/backends/platform/wince/CEActionsSmartphone.cpp
@@ -0,0 +1,238 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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$
+ *
+ */
+
+//#define SIMU_SMARTPHONE 1
+
+//#ifdef WIN32_PLATFORM_WFSP
+
+#include "common/stdafx.h"
+#include "CEActionsSmartphone.h"
+#include "EventsBuffer.h"
+
+#include "gui/message.h"
+
+#include "scumm/scumm.h"
+
+#include "common/config-manager.h"
+
+#include "gui/KeysDialog.h"
+
+#ifdef _WIN32_WCE
+#define KEY_ALL_SKIP 3457
+#endif
+
+const String smartphoneActionNames[] = {
+ "Up",
+ "Down",
+ "Left",
+ "Right",
+ "Left Click",
+ "Right Click",
+ "Save",
+ "Skip",
+ "Zone",
+ "FT Cheat",
+ "Bind Keys",
+ "Keyboard",
+ "Rotate"
+};
+
+#ifdef SIMU_SMARTPHONE
+const int ACTIONS_SMARTPHONE_DEFAULT[] = { 0x111, 0x112, 0x114, 0x113, 0x11a, 0x11b, VK_LWIN, VK_ESCAPE, VK_F8, 0, VK_RETURN, 0, 0 };
+#else
+const int ACTIONS_SMARTPHONE_DEFAULT[] = { '4', '6', '8', '2', 0x11a, 0x11b, '0', VK_ESCAPE, '9', 0, VK_RETURN, 0, 0 };
+#endif
+
+void CEActionsSmartphone::init() {
+ _instance = new CEActionsSmartphone();
+}
+
+
+String CEActionsSmartphone::actionName(GUI::ActionType action) {
+ return smartphoneActionNames[action];
+}
+
+int CEActionsSmartphone::size() {
+ return SMARTPHONE_ACTION_LAST;
+}
+
+String CEActionsSmartphone::domain() {
+ return ConfMan.kApplicationDomain;
+}
+
+int CEActionsSmartphone::version() {
+ return SMARTPHONE_ACTION_VERSION;
+}
+
+CEActionsSmartphone::CEActionsSmartphone()
+: GUI::Actions() {
+ int i;
+
+ for (i=0; i<SMARTPHONE_ACTION_LAST; i++) {
+ _action_mapping[i] = ACTIONS_SMARTPHONE_DEFAULT[i];
+ _action_enabled[i] = false;
+ }
+
+}
+
+void CEActionsSmartphone::initInstanceMain(OSystem *mainSystem) {
+ _CESystem = static_cast<OSystem_WINCE3*>(mainSystem);
+
+ GUI_Actions::initInstanceMain(mainSystem);
+ // Mouse Up
+ _action_enabled[SMARTPHONE_ACTION_UP] = true;
+ // Mouse Down
+ _action_enabled[SMARTPHONE_ACTION_DOWN] = true;
+ // Mouse Left
+ _action_enabled[SMARTPHONE_ACTION_LEFT] = true;
+ // Mouse Right
+ _action_enabled[SMARTPHONE_ACTION_RIGHT] = true;
+ // Left Click
+ _action_enabled[SMARTPHONE_ACTION_LEFTCLICK] = true;
+ // Right Click
+ _action_enabled[SMARTPHONE_ACTION_RIGHTCLICK] = true;
+ // Show virtual keyboard
+ _action_enabled[SMARTPHONE_ACTION_KEYBOARD] = true;
+ // Rotate display
+ _action_enabled[SMARTPHONE_ACTION_ROTATE] = true;
+}
+
+void CEActionsSmartphone::initInstanceGame() {
+ String gameid(ConfMan.get("gameid"));
+ bool is_simon = (strncmp(gameid.c_str(), "simon", 5) == 0);
+ bool is_sky = (gameid == "sky");
+ bool is_queen = (gameid == "queen");
+ bool is_gob = (strncmp(gameid.c_str(), "gob", 3) == 0);
+ bool is_ite = ((strncmp(gameid.c_str(), "ite", 3) == 0) ||
+ (strncmp(gameid.c_str(), "ihnm", 4) == 0));
+
+ GUI_Actions::initInstanceGame();
+
+ // See if a right click mapping could be needed
+ if (is_sky || gameid == "samnmax" || is_gob)
+ _right_click_needed = true;
+
+ // Initialize keys for different actions
+ // Save
+ if (is_simon || is_gob)
+ _action_enabled[SMARTPHONE_ACTION_SAVE] = false;
+ else
+ if (is_queen || is_ite) {
+ _action_enabled[SMARTPHONE_ACTION_SAVE] = true;
+ _key_action[SMARTPHONE_ACTION_SAVE].setAscii(286); // F1 key for FOTAQ and ITE
+ }
+ else
+ if (is_sky) {
+ _action_enabled[SMARTPHONE_ACTION_SAVE] = true;
+ _key_action[SMARTPHONE_ACTION_SAVE].setAscii(63);
+ }
+ else {
+ _action_enabled[SMARTPHONE_ACTION_SAVE] = true;
+ _key_action[SMARTPHONE_ACTION_SAVE].setAscii(319); // F5 key
+ }
+ // Skip
+ _action_enabled[SMARTPHONE_ACTION_SKIP] = true;
+ if (is_simon || is_sky || is_gob || is_ite)
+ _key_action[SMARTPHONE_ACTION_SKIP].setAscii(VK_ESCAPE);
+ else
+ _key_action[SMARTPHONE_ACTION_SKIP].setAscii(KEY_ALL_SKIP);
+ // Zone
+ _action_enabled[SMARTPHONE_ACTION_ZONE] = true;
+ // FT Cheat
+ _action_enabled[SMARTPHONE_ACTION_FT_CHEAT] = true;
+ _key_action[SMARTPHONE_ACTION_FT_CHEAT].setAscii(86); // shift-V
+ // Bind keys
+ _action_enabled[SMARTPHONE_ACTION_BINDKEYS] = true;
+}
+
+
+CEActionsSmartphone::~CEActionsSmartphone() {
+}
+
+bool CEActionsSmartphone::perform(GUI::ActionType action, bool pushed) {
+ static bool keydialogrunning = false;
+
+ if (!pushed) {
+ switch (action) {
+ case SMARTPHONE_ACTION_RIGHTCLICK:
+ _CESystem->add_right_click(false);
+ return true;
+ case SMARTPHONE_ACTION_LEFTCLICK:
+ _CESystem->add_left_click(false);
+ return true;
+ case SMARTPHONE_ACTION_SAVE:
+ case SMARTPHONE_ACTION_SKIP:
+ case SMARTPHONE_ACTION_FT_CHEAT:
+ EventsBuffer::simulateKey(&_key_action[action], false);
+ return true;
+ }
+ return false;
+ }
+
+ switch (action) {
+ case SMARTPHONE_ACTION_SAVE:
+ case SMARTPHONE_ACTION_SKIP:
+ case SMARTPHONE_ACTION_FT_CHEAT:
+ EventsBuffer::simulateKey(&_key_action[action], true);
+ return true;
+ case SMARTPHONE_ACTION_RIGHTCLICK:
+ _CESystem->add_right_click(true);
+ return true;
+ case SMARTPHONE_ACTION_LEFTCLICK:
+ _CESystem->add_left_click(true);
+ return true;
+ case SMARTPHONE_ACTION_UP:
+ _CESystem->move_cursor_up();
+ return true;
+ case SMARTPHONE_ACTION_DOWN:
+ _CESystem->move_cursor_down();
+ return true;
+ case SMARTPHONE_ACTION_LEFT:
+ _CESystem->move_cursor_left();
+ return true;
+ case SMARTPHONE_ACTION_RIGHT:
+ _CESystem->move_cursor_right();
+ return true;
+ case SMARTPHONE_ACTION_ZONE:
+ _CESystem->switch_zone();
+ return true;
+ case SMARTPHONE_ACTION_BINDKEYS:
+ if (!keydialogrunning) {
+ keydialogrunning = true;
+ GUI::KeysDialog *keysDialog = new GUI::KeysDialog();
+ keysDialog->runModal();
+ delete keysDialog;
+ keydialogrunning = false;
+ }
+ return true;
+ case SMARTPHONE_ACTION_KEYBOARD:
+ _CESystem->swap_smartphone_keyboard();
+ return true;
+ case SMARTPHONE_ACTION_ROTATE:
+ _CESystem->smartphone_rotate_display();
+ return true;
+ }
+
+ return false;
+}
+
+//#endif
diff --git a/backends/platform/wince/CEActionsSmartphone.h b/backends/platform/wince/CEActionsSmartphone.h
new file mode 100644
index 0000000000..b100680d9d
--- /dev/null
+++ b/backends/platform/wince/CEActionsSmartphone.h
@@ -0,0 +1,82 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEACTIONSSMARTPHONE
+#define CEACTIONSSMARTPHONE
+
+//#ifdef WIN32_PLATFORM_WFSP
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+
+
+#include "wince-sdl.h"
+#include "gui/Key.h"
+
+#include "gui/Actions.h"
+
+#define SMARTPHONE_ACTION_VERSION 4
+
+enum smartphoneActionType {
+ SMARTPHONE_ACTION_UP = 0,
+ SMARTPHONE_ACTION_DOWN,
+ SMARTPHONE_ACTION_LEFT,
+ SMARTPHONE_ACTION_RIGHT,
+ SMARTPHONE_ACTION_LEFTCLICK,
+ SMARTPHONE_ACTION_RIGHTCLICK,
+ SMARTPHONE_ACTION_SAVE,
+ SMARTPHONE_ACTION_SKIP,
+ SMARTPHONE_ACTION_ZONE,
+ SMARTPHONE_ACTION_FT_CHEAT,
+ SMARTPHONE_ACTION_BINDKEYS,
+ SMARTPHONE_ACTION_KEYBOARD,
+ SMARTPHONE_ACTION_ROTATE,
+
+ SMARTPHONE_ACTION_LAST
+};
+
+
+class CEActionsSmartphone : public GUI::Actions {
+ public:
+ // Actions
+ bool perform(GUI::ActionType action, bool pushed = true);
+ String actionName(GUI::ActionType action);
+ int size();
+ static void init();
+ void initInstanceMain(OSystem *mainSystem);
+ void initInstanceGame();
+
+ // Action domain
+ String domain();
+ int version();
+
+ ~CEActionsSmartphone();
+ private:
+ CEActionsSmartphone();
+ bool _right_click_needed;
+ OSystem_WINCE3 *_CESystem;
+ };
+
+#endif
+
+//#endif
diff --git a/backends/platform/wince/CEDevice.cpp b/backends/platform/wince/CEDevice.cpp
new file mode 100644
index 0000000000..ddf1e9df96
--- /dev/null
+++ b/backends/platform/wince/CEDevice.cpp
@@ -0,0 +1,198 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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$
+ *
+ */
+
+//#define SIMU_SMARTPHONE 1
+//#define SIMU_SMARTPHONE_2005 1
+
+#include "common/stdafx.h"
+#include "CEDevice.h"
+
+#include <SDL.h>
+
+#include "wince-sdl.h"
+
+#define KEY_CALENDAR 0xc1
+#define KEY_CONTACTS 0xc2
+#define KEY_INBOX 0xc3
+#define KEY_TASK 0xc4
+
+//#ifdef WIN32_PLATFORM_WFSP
+const char* SMARTPHONE_KEYS_NAME[] = {
+ "1", "2", "3","4", "5", "6", "7", "8", "9", "*", "0", "#",
+ "Home", "Back", "Up", "Down", "Left", "Right", "Action", "Hang up", "Call",
+ "Soft 1", "Soft 2", "Power", "Volume Up" ,"Volume Down", "Record", "None",
+ 0
+};
+
+// Old mapping from the previous (non SDL) version. To be forgotten.
+/*
+const int SMARTPHONE_KEYS_MAPPING[] = {
+ '1', '2', '3', '4', '5', '6', '7', '8', '9', VK_F8, '0', VK_F9,
+ VK_LWIN, VK_ESCAPE, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_RETURN, VK_F4, VK_F3,
+ VK_F1, VK_F2, VK_F18, VK_F6, VK_F7, VK_F10, 0xff, 0
+};
+*/
+
+// FIXME : Home and Record are not mapped
+const int SMARTPHONE_KEYS_MAPPING[] = {
+ '1', '2', '3', '4', '5', '6', '7', '8', '9', VK_F9, '0', VK_F10,
+ 0xFF, VK_ESCAPE, 0x113, 0x114, 0x111, 0x112, VK_RETURN, 0x11D, 0x11C,
+ 0x11A, 0x11B, 0x11D, 0x11F, 0x120, 0xFF, 0
+};
+
+static void (WINAPI* _SHIdleTimerReset)(void) = NULL;
+static HANDLE (WINAPI* _SetPowerRequirement)(PVOID,int,ULONG,PVOID,ULONG) = NULL;
+static DWORD (WINAPI* _ReleasePowerRequirement)(HANDLE) = NULL;
+static HANDLE _hPowerManagement = NULL;
+static DWORD _lastTime = 0;
+
+#define TIMER_TRIGGER 9000
+
+//#endif
+
+// Power management code borrowed from MoDaCo & Betaplayer. Thanks !
+void CEDevice::init() {
+ HINSTANCE dll = LoadLibrary(TEXT("aygshell.dll"));
+ if (dll) {
+ *(FARPROC*)&_SHIdleTimerReset = GetProcAddress(dll, MAKEINTRESOURCE(2006));
+ }
+ dll = LoadLibrary(TEXT("coredll.dll"));
+ if (dll) {
+ *(FARPROC*)&_SetPowerRequirement = GetProcAddress(dll, TEXT("SetPowerRequirement"));
+ *(FARPROC*)&_ReleasePowerRequirement = GetProcAddress(dll, TEXT("ReleasePowerRequirement"));
+
+ }
+ if (_SetPowerRequirement)
+ _hPowerManagement = _SetPowerRequirement(TEXT("BKL1:"), 0, 1, NULL, 0);
+ _lastTime = GetTickCount();
+}
+
+void CEDevice::end() {
+ if (_ReleasePowerRequirement && _hPowerManagement) {
+ _ReleasePowerRequirement(_hPowerManagement);
+ }
+}
+
+void CEDevice::wakeUp() {
+ DWORD currentTime = GetTickCount();
+ if (currentTime > _lastTime + TIMER_TRIGGER) {
+ _lastTime = currentTime;
+ SystemIdleTimerReset();
+ if (_SHIdleTimerReset)
+ _SHIdleTimerReset();
+ }
+}
+
+bool CEDevice::hasPocketPCResolution() {
+#ifdef SIMU_SMARTPHONE
+#ifndef SIMU_SMARTPHONE_2005
+ return false;
+#else
+ return true;
+#endif
+#else
+ if (OSystem_WINCE3::isOzone() && hasWideResolution())
+ return true;
+ return (OSystem_WINCE3::getScreenWidth() < 320 && OSystem_WINCE3::getScreenWidth() >= 240);
+#endif
+}
+
+bool CEDevice::hasDesktopResolution() {
+#ifdef SIMU_SMARTPHONE
+ return false;
+#else
+ if (OSystem_WINCE3::isOzone() && hasWideResolution())
+ return true;
+ return (OSystem_WINCE3::getScreenWidth() >= 320);
+#endif
+}
+
+bool CEDevice::hasWideResolution() {
+#ifdef SIMU_SMARTPHONE
+ return false;
+#else
+ return (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640);
+#endif
+}
+
+bool CEDevice::hasSmartphoneResolution() {
+#ifdef SIMU_SMARTPHONE
+#ifndef SIMU_SMARTPHONE_2005
+ return true;
+#else
+ return false;
+#endif
+#else
+ return (OSystem_WINCE3::getScreenWidth() < 240);
+#endif
+}
+
+bool CEDevice::isSmartphone() {
+#ifdef SIMU_SMARTPHONE
+ return true;
+#else
+ TCHAR platformType[100];
+ BOOL result = SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(platformType), platformType, 0);
+ if (!result && GetLastError() == ERROR_ACCESS_DENIED)
+ return true;
+ return (wcsnicmp(platformType, TEXT("SmartPhone"), 10) == 0);
+#endif
+}
+
+Common::String CEDevice::getKeyName(unsigned int keyCode) {
+ char key_name[10];
+
+ if (!keyCode)
+ return "No key";
+
+ if (keyCode == KEY_CALENDAR)
+ return "Button Calendar";
+ if (keyCode == KEY_CONTACTS)
+ return "Button Contacts";
+ if (keyCode == KEY_INBOX)
+ return "Button Inbox";
+ if (keyCode == KEY_TASK)
+ return "Button Tasks";
+ if (keyCode == SDLK_F1)
+ return "F1 (hard 1)";
+ if (keyCode == SDLK_F2)
+ return "F2 (hard 2)";
+ if (keyCode == SDLK_F3)
+ return "F3 (hard 3)";
+ if (keyCode == SDLK_F4)
+ return "F4 (hard 4)";
+
+//#ifdef WIN32_PLATFORM_WFSP
+ if (hasSmartphoneResolution()) {
+ int i = 0;
+ while (SMARTPHONE_KEYS_MAPPING[i]) {
+ if (keyCode == SMARTPHONE_KEYS_MAPPING[i])
+ return SMARTPHONE_KEYS_NAME[i];
+ i++;
+ }
+ }
+//#endif
+
+ sprintf(key_name, "Key %.4x", keyCode);
+ return key_name;
+}
+
diff --git a/backends/platform/wince/CEDevice.h b/backends/platform/wince/CEDevice.h
new file mode 100644
index 0000000000..07753413e4
--- /dev/null
+++ b/backends/platform/wince/CEDevice.h
@@ -0,0 +1,46 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEDEVICE
+#define CEDEVICE
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+#include "common/str.h"
+
+#include <gx.h>
+
+class CEDevice {
+ public:
+ static void init();
+ static void end();
+ static void wakeUp();
+ static bool hasPocketPCResolution();
+ static bool hasDesktopResolution();
+ static bool hasWideResolution();
+ static bool hasSmartphoneResolution();
+ static bool isSmartphone();
+ static Common::String getKeyName(unsigned int keyCode);
+};
+
+#endif
diff --git a/backends/platform/wince/CEException.cpp b/backends/platform/wince/CEException.cpp
new file mode 100644
index 0000000000..283d87882a
--- /dev/null
+++ b/backends/platform/wince/CEException.cpp
@@ -0,0 +1,156 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 "CEException.h"
+
+void CEException::writeString(HANDLE file, char *data) {
+ DWORD dummy;
+ WriteFile(file, data, strlen(data), &dummy, NULL);
+ WriteFile(file, "\r\n", 2, &dummy, NULL);
+}
+
+void CEException::writeBreak(HANDLE file) {
+ char tempo[100];
+ int i;
+
+ memset(tempo, 0, sizeof(tempo));
+ for (i=0; i<40; i++)
+ tempo[i] = '-';
+ writeString(file, tempo);
+}
+
+void CEException::dumpContext(HANDLE file, HANDLE hProcess, CONTEXT *context) {
+ char tempo[200];
+ unsigned char memoryDump[100];
+ DWORD size;
+ unsigned int i;
+
+#ifdef ARM
+ writeBreak(file);
+ writeString(file, "Context dump");
+ sprintf(tempo, "R0=%.8x R1=%.8x R2=%.8x R3=%.8x R4=%.8x", context->R0, context->R1,
+ context->R2, context->R3, context->R4);
+ writeString(file, tempo);
+ sprintf(tempo, "R5=%.8x R6=%.8x R7=%.8x R8=%.8x R9=%.8x", context->R5, context->R6,
+ context->R7, context->R8, context->R9);
+ writeString(file, tempo);
+ sprintf(tempo, "R10=%.8x R11=%.8x R12=%.8x", context->R10, context->R11,
+ context->R12);
+ writeString(file, tempo);
+ sprintf(tempo, "Sp=%.8x Lr=%.8x Pc=%.8x Psr=%.8x", context->Sp, context->Lr,
+ context->Pc, context->Psr);
+ writeString(file, tempo);
+ writeBreak(file);
+
+ sprintf(tempo, "Memory dump at %.8x", context->Pc - (sizeof(memoryDump) / 2));
+ writeString(file, tempo);
+ if (ReadProcessMemory(hProcess, (LPCVOID)(context->Pc - (sizeof(memoryDump) / 2)), memoryDump, sizeof(memoryDump), &size)) {
+ for (i=0; i<size; i+=8) {
+ int j;
+ char digit[3];
+ int max;
+ max = size - i;
+ if (max > 8)
+ max = 8;
+ tempo[0] = '\0';
+ for (j=0; j<max; j++) {
+ sprintf(digit, "%.2x ", memoryDump[i + j]);
+ strcat(tempo, digit);
+ }
+ writeString(file, tempo);
+ }
+ }
+#else
+ writeBreak(file);
+ writeString(file, "Context dump only available on ARM devices");
+#endif
+}
+
+void CEException::dumpException(HANDLE file, EXCEPTION_RECORD *exceptionRecord) {
+ char tempo[200];
+ char exceptionName[50];
+ unsigned int i;
+#if (_WIN32_WCE >= 300)
+ writeBreak(file);
+ switch(exceptionRecord->ExceptionCode) {
+ case EXCEPTION_ACCESS_VIOLATION :
+ strcpy(exceptionName, "Access Violation");
+ break;
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED :
+ strcpy(exceptionName, "Array Bounds Exceeded");
+ break;
+ case EXCEPTION_DATATYPE_MISALIGNMENT :
+ strcpy(exceptionName, "Datatype Misalignment");
+ break;
+ case EXCEPTION_IN_PAGE_ERROR :
+ strcpy(exceptionName, "In Page Error");
+ break;
+ case EXCEPTION_INT_DIVIDE_BY_ZERO :
+ strcpy(exceptionName, "Int Divide By Zero");
+ break;
+ case EXCEPTION_INT_OVERFLOW :
+ strcpy(exceptionName, "Int Overflow");
+ break;
+ case EXCEPTION_STACK_OVERFLOW :
+ strcpy(exceptionName, "Stack Overflow");
+ break;
+ default:
+ sprintf(exceptionName, "%.8x", exceptionRecord->ExceptionCode);
+ break;
+ }
+ sprintf(tempo, "Exception %s Flags %.8x Address %.8x", exceptionName, exceptionRecord->ExceptionFlags,
+ exceptionRecord->ExceptionAddress);
+ writeString(file, tempo);
+ if (exceptionRecord->NumberParameters) {
+ for (i=0; i<exceptionRecord->NumberParameters; i++) {
+ sprintf(tempo, "Parameter %d %.8x", i, exceptionRecord->ExceptionInformation[i]);
+ writeString(file, tempo);
+ }
+ }
+ if (exceptionRecord->ExceptionRecord)
+ dumpException(file, exceptionRecord->ExceptionRecord);
+#else
+ writeBreak(file);
+ writeString(file, "Cannot get exception information on this CE version");
+#endif
+}
+
+bool CEException::writeException(TCHAR *path, EXCEPTION_POINTERS *exceptionPointers) {
+ HANDLE dumpFile;
+ TCHAR dumpFileName[MAX_PATH];
+ SYSTEMTIME systemTime;
+
+ GetSystemTime(&systemTime);
+ wsprintf(dumpFileName, TEXT("%s_%.2d_%.2d_%.4d_%.2d_%.2d_%.2d.txt"),
+ path, systemTime.wDay, systemTime.wMonth, systemTime.wYear,
+ systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
+ dumpFile = CreateFile(dumpFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (dumpFile == INVALID_HANDLE_VALUE)
+ return false;
+
+ dumpException(dumpFile, exceptionPointers->ExceptionRecord);
+ dumpContext(dumpFile, GetCurrentProcess(), exceptionPointers->ContextRecord);
+
+ CloseHandle(dumpFile);
+
+ return true;
+}
diff --git a/backends/platform/wince/CEException.h b/backends/platform/wince/CEException.h
new file mode 100644
index 0000000000..0d4bb747ca
--- /dev/null
+++ b/backends/platform/wince/CEException.h
@@ -0,0 +1,34 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 <windows.h>
+
+class CEException {
+public:
+ static bool writeException(TCHAR *path, EXCEPTION_POINTERS *exceptionPointers);
+private:
+ static void writeString(HANDLE file, char *data);
+ static void writeBreak(HANDLE file);
+ static void dumpContext(HANDLE file, HANDLE hProcess, CONTEXT *context);
+ static void dumpException(HANDLE file, EXCEPTION_RECORD *exceptionRecord);
+
+};
diff --git a/backends/platform/wince/CEKeysDialog.cpp b/backends/platform/wince/CEKeysDialog.cpp
new file mode 100644
index 0000000000..737a33577c
--- /dev/null
+++ b/backends/platform/wince/CEKeysDialog.cpp
@@ -0,0 +1,125 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "CEKeysDialog.h"
+#include "CEDevice.h"
+#include "gui/Actions.h"
+
+using GUI::ListWidget;
+using GUI::kListNumberingZero;
+using GUI::WIDGET_CLEARBG;
+using GUI::kListSelectionChangedCmd;
+using GUI::kCloseCmd;
+using GUI::StaticTextWidget;
+using GUI::kTextAlignCenter;
+using GUI::CommandSender;
+
+enum {
+ kMapCmd = 'map ',
+ kOKCmd = 'ok '
+};
+
+
+CEKeysDialog::CEKeysDialog(const Common::String &title)
+ : GUI::Dialog(30, 20, 260, 160) {
+ addButton(this, 160, 20, "Map", kMapCmd, 'M'); // Map
+ addButton(this, 160, 40, "OK", kOKCmd, 'O'); // OK
+ addButton(this, 160, 60, "Cancel", kCloseCmd, 'C'); // Cancel
+
+ _actionTitle = new StaticTextWidget(this, 10, 120, 240, 16, title, kTextAlignCenter);
+ _keyMapping = new StaticTextWidget(this, 10, 140, 240, 16, "", kTextAlignCenter);
+
+ _actionTitle->setFlags(WIDGET_CLEARBG);
+ _keyMapping->setFlags(WIDGET_CLEARBG);
+
+ _actionsList = new ListWidget(this, "Actions List");
+ _actionsList->setNumberingMode(kListNumberingZero);
+
+ // Get actions names
+ Common::StringList l;
+
+ for (int i = 0; i < GUI_Actions::Instance()->size(); i++)
+ l.push_back(GUI_Actions::Instance()->actionName((GUI::ActionType)i));
+
+ _actionsList->setList(l);
+
+ _actionSelected = -1;
+ GUI_Actions::Instance()->beginMapping(false);
+}
+
+void CEKeysDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
+ switch(cmd) {
+
+ case kListSelectionChangedCmd:
+ if (_actionsList->getSelected() >= 0) {
+ char selection[100];
+
+ sprintf(selection, "Associated key : %s", CEDevice::getKeyName(GUI_Actions::Instance()->getMapping((GUI::ActionType)(_actionsList->getSelected()))).c_str());
+ _keyMapping->setLabel(selection);
+ _keyMapping->draw();
+ }
+ break;
+ case kMapCmd:
+ if (_actionsList->getSelected() < 0) {
+ _actionTitle->setLabel("Please select an action");
+ }
+ else {
+ char selection[100];
+
+ _actionSelected = _actionsList->getSelected();
+ sprintf(selection, "Associated key : %s", CEDevice::getKeyName(GUI_Actions::Instance()->getMapping((GUI::ActionType)_actionSelected)).c_str());
+ _actionTitle->setLabel("Press the key to associate");
+ _keyMapping->setLabel(selection);
+ _keyMapping->draw();
+ GUI_Actions::Instance()->beginMapping(true);
+ _actionsList->setEnabled(false);
+ }
+ _actionTitle->draw();
+ break;
+ case kOKCmd:
+ GUI_Actions::Instance()->saveMapping();
+ close();
+ break;
+ case kCloseCmd:
+ GUI_Actions::Instance()->loadMapping();
+ close();
+ break;
+ }
+}
+
+void CEKeysDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
+ if (modifiers == 0xff && GUI_Actions::Instance()->mappingActive()) {
+ // GAPI key was selected
+ char selection[100];
+
+ GUI_Actions::Instance()->setMapping((GUI::ActionType)_actionSelected, ascii);
+
+ sprintf(selection, "Associated key : %s", CEDevice::getKeyName(GUI_Actions::Instance()->getMapping((GUI::ActionType)_actionSelected)).c_str());
+ _actionTitle->setLabel("Choose an action to map");
+ _keyMapping->setLabel(selection);
+ _keyMapping->draw();
+ _actionSelected = -1;
+ _actionsList->setEnabled(true);
+ GUI_Actions::Instance()->beginMapping(false);
+ }
+}
diff --git a/backends/platform/wince/CEKeysDialog.h b/backends/platform/wince/CEKeysDialog.h
new file mode 100644
index 0000000000..37566bf431
--- /dev/null
+++ b/backends/platform/wince/CEKeysDialog.h
@@ -0,0 +1,46 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEKEYSDIALOG
+#define CEKEYSDIALOG
+
+#include "gui/newgui.h"
+#include "gui/dialog.h"
+#include "gui/ListWidget.h"
+#include "common/str.h"
+
+class CEKeysDialog : public GUI::Dialog {
+public:
+ CEKeysDialog(const Common::String &title = "Choose an action to map");
+
+ virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
+ virtual void handleKeyDown(uint16 ascii, int keycode, int modifiers);
+
+protected:
+
+ GUI::ListWidget *_actionsList;
+ GUI::StaticTextWidget *_actionTitle;
+ GUI::StaticTextWidget *_keyMapping;
+ int _actionSelected;
+};
+
+#endif
diff --git a/backends/platform/wince/CELauncherDialog.cpp b/backends/platform/wince/CELauncherDialog.cpp
new file mode 100644
index 0000000000..3a5dfb6459
--- /dev/null
+++ b/backends/platform/wince/CELauncherDialog.cpp
@@ -0,0 +1,176 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+
+#include "wince-sdl.h"
+
+#include "CELauncherDialog.h"
+
+#include "base/engine.h"
+
+#include "gui/newgui.h"
+#include "gui/widget.h"
+#include "gui/browser.h"
+#include "gui/message.h"
+
+#include "common/config-manager.h"
+
+using namespace GUI;
+using namespace Common;
+
+class CEAboutDialog : public Dialog {
+public:
+ CEAboutDialog::CEAboutDialog()
+ : Dialog(10, 60, 300, 77) {
+ char tempo[100];
+
+ addButton(this,(_w - kButtonWidth) / 2, 45, "OK", kCloseCmd, '\r'); // Close dialog - FIXME
+
+ Common::String videoDriver("Using SDL driver ");
+ SDL_VideoDriverName(tempo, sizeof(tempo));
+ videoDriver += tempo;
+ new StaticTextWidget(this, 0, 10, _w, kLineHeight, videoDriver, kTextAlignCenter);
+ Common::String displayInfos("Display ");
+ sprintf(tempo, "%dx%d (real %dx%d)", GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), OSystem_WINCE3::getScreenWidth(), OSystem_WINCE3::getScreenHeight());
+ displayInfos += tempo;
+ new StaticTextWidget(this, 0, 20, _w, kLineHeight, displayInfos, kTextAlignCenter);
+ }
+};
+
+class CEConflictDialog : public Dialog {
+public:
+ CEConflictDialog::CEConflictDialog(const Common::String &name)
+ : Dialog(10, 60, 300, 77) {
+
+ addButton(this,(_w - kButtonWidth) / 2, 45, "OK", kCloseCmd, '\r'); // Close dialog - FIXME
+
+ Common::String conflict("Too many matches for directory ");
+ conflict += name;
+ new StaticTextWidget(this, 0, 10, _w, kLineHeight, conflict, kTextAlignCenter);
+ new StaticTextWidget(this, 0, 20, _w, kLineHeight, "Please fix this :)", kTextAlignCenter);
+ }
+};
+
+
+CELauncherDialog::CELauncherDialog() : GUI::LauncherDialog() {
+}
+
+void CELauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
+ LauncherDialog::handleCommand(sender, cmd, data);
+ if (cmd == 'ABOU') {
+ CEAboutDialog about;
+ about.runModal();
+ }
+}
+
+void CELauncherDialog::addCandidate(String &path, DetectedGameList &candidates) {
+ int idx = -1;
+ DetectedGame result;
+
+ if (candidates.empty())
+ return;
+
+ if (candidates.size() == 1)
+ idx = 0;
+ else {
+ char candidateName[100];
+ unsigned int i;
+ for (i=path.size() - 2; i && path[i] != '\\'; i--);
+ strcpy(candidateName, &path[i + 1]);
+ candidateName[strlen(candidateName) - 1] = '\0';
+ for (i=0; i<candidates.size(); i++) {
+ if (scumm_stricmp(candidateName, candidates[i].description.c_str()) == 0) {
+ idx = i;
+ break;
+ }
+ }
+ if (idx == -1) {
+ CEConflictDialog conflict(candidateName);
+ conflict.runModal();
+ }
+ }
+
+ if (idx < 0)
+ return;
+
+ // FIXME : factor that
+ result = candidates[idx];
+
+ // The auto detector or the user made a choice.
+ // Pick a domain name which does not yet exist (after all, we
+ // are *adding* a game to the config, not replacing).
+ String domain(result.gameid);
+ if (ConfMan.hasGameDomain(domain)) {
+ char suffix = 'a';
+ domain += suffix;
+ while (ConfMan.hasGameDomain(domain)) {
+ assert(suffix < 'z');
+ domain.deleteLastChar();
+ suffix++;
+ domain += suffix;
+ }
+ ConfMan.set("gameid", result.description, domain);
+ ConfMan.set("description", result.description, domain);
+ } else
+ ConfMan.addGameDomain(domain);
+
+ ConfMan.set("path", path, domain);
+
+ // Set language if specified
+ if (result.language != Common::UNK_LANG)
+ ConfMan.set("language", Common::getLanguageCode(result.language), domain);
+
+ // Set platform if specified
+ if (result.platform != Common::kPlatformUnknown)
+ ConfMan.set("platform", Common::getPlatformCode(result.platform), domain);
+}
+
+void CELauncherDialog::automaticScanDirectory(const FilesystemNode &node) {
+ // First check if we have a recognized game in the current directory
+ FSList files;
+ node.listDir(files, FilesystemNode::kListFilesOnly);
+ DetectedGameList candidates(PluginManager::instance().detectGames(files));
+ addCandidate(node.path(), candidates);
+ // Then recurse on the subdirectories
+ FSList dirs;
+ node.listDir(dirs, FilesystemNode::kListDirectoriesOnly);
+ for (FSList::const_iterator currentDir = dirs.begin(); currentDir != dirs.end(); ++currentDir)
+ automaticScanDirectory(*currentDir);
+
+}
+
+void CELauncherDialog::addGame() {
+ MessageDialog alert("Do you want to perform an automatic scan ?", "Yes", "No");
+ if (alert.runModal() == kMessageOK && _browser->runModal() > 0) {
+ // Clear existing domains
+ ConfigManager::DomainMap &domains = (ConfigManager::DomainMap&)ConfMan.getGameDomains();
+ domains.clear();
+ ConfMan.flushToDisk();
+ automaticScanDirectory(_browser->getResult());
+ ConfMan.flushToDisk();
+ updateListing();
+ draw();
+ }
+ else
+ GUILauncherDialog::addGame();
+}
diff --git a/backends/platform/wince/CELauncherDialog.h b/backends/platform/wince/CELauncherDialog.h
new file mode 100644
index 0000000000..e2d85da8dc
--- /dev/null
+++ b/backends/platform/wince/CELauncherDialog.h
@@ -0,0 +1,42 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CELAUNCHERDIALOG
+#define CELAUNCHERDIALOG
+
+#include "base/plugins.h"
+#include "common/fs.h"
+#include "gui/launcher.h"
+
+class CELauncherDialog : public GUI::LauncherDialog {
+public:
+ CELauncherDialog();
+ virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
+protected:
+ void addGame();
+ void addCandidate(String &path, DetectedGameList &candidates);
+ void automaticScanDirectory(const FilesystemNode &node);
+};
+
+typedef GUI::LauncherDialog GUILauncherDialog;
+
+#endif
diff --git a/backends/platform/wince/CEScaler.cpp b/backends/platform/wince/CEScaler.cpp
new file mode 100644
index 0000000000..86fe2a7104
--- /dev/null
+++ b/backends/platform/wince/CEScaler.cpp
@@ -0,0 +1,213 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 "graphics/scaler/intern.h"
+#include "common/stdafx.h"
+#include "CEScaler.h"
+
+int redblueMasks[] = { 0x7C1F, 0xF81F };
+int greenMasks[] = { 0x03E0, 0x07E0 };
+
+static int maskUsed;
+
+void initCEScaler(void) {
+ if (gBitFormat == 555)
+ maskUsed = 0;
+ else
+ maskUsed = 1;
+}
+
+static inline uint16 CEinterpolate16_4(uint16 p1, uint16 p2, uint16 p3, uint16 p4)
+{
+ return ((((p1 & redblueMasks[maskUsed]) + (p2 & redblueMasks[maskUsed]) + (p3 & redblueMasks[maskUsed]) + (p4 & redblueMasks[maskUsed])) / 4) & redblueMasks[maskUsed]) |
+ ((((p1 & greenMasks[maskUsed]) + (p2 & greenMasks[maskUsed]) + (p3 & greenMasks[maskUsed]) + (p4 & greenMasks[maskUsed])) / 4) & greenMasks[maskUsed]);
+}
+
+static inline uint16 CEinterpolate16_2(uint16 p1, int w1, uint16 p2, int w2) {
+ return ((((p1 & redblueMasks[maskUsed]) * w1 + (p2 & redblueMasks[maskUsed]) * w2) / (w1 + w2)) & redblueMasks[maskUsed]) |
+ ((((p1 & greenMasks[maskUsed]) * w1 + (p2 & greenMasks[maskUsed]) * w2) / (w1 + w2)) & greenMasks[maskUsed]);
+}
+
+void PocketPCPortrait(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
+ uint8 *work;
+ int i;
+
+ while (height--) {
+ i = 0;
+ work = dstPtr;
+
+ for (int i=0; i<width; i+=4) {
+ // Work with 4 pixels
+ uint16 color1 = *(((const uint16 *)srcPtr) + i);
+ uint16 color2 = *(((const uint16 *)srcPtr) + (i + 1));
+ uint16 color3 = *(((const uint16 *)srcPtr) + (i + 2));
+ uint16 color4 = *(((const uint16 *)srcPtr) + (i + 3));
+
+ *(((uint16 *)work) + 0) = CEinterpolate16_2(color1, 3, color2, 1);
+ *(((uint16 *)work) + 1) = CEinterpolate16_2(color2, 1, color3, 1);
+ *(((uint16 *)work) + 2) = CEinterpolate16_2(color3, 1, color4, 3);
+
+ work += 3 * sizeof(uint16);
+ }
+ srcPtr += srcPitch;
+ dstPtr += dstPitch;
+ }
+}
+
+void PocketPCLandscapeAspect(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
+
+#define RB(x) ((x & redblueMasks[maskUsed])<<8)
+#define G(x) ((x & greenMasks[maskUsed])<<3)
+
+#define P20(x) (((x)>>2)-((x)>>4))
+#define P40(x) (((x)>>1)-((x)>>3))
+#define P60(x) (((x)>>1)+((x)>>3))
+#define P80(x) (((x)>>1)+((x)>>2)+((x)>>4))
+
+#define MAKEPIXEL(rb,g) ((((rb)>>8) & redblueMasks[maskUsed] | ((g)>>3) & greenMasks[maskUsed]))
+
+ int i,j;
+ unsigned int p1;
+ unsigned int p2;
+ uint16 * inbuf;
+ uint16 * outbuf;
+ inbuf=(uint16 *)srcPtr;
+ outbuf=(uint16 *)dstPtr;
+
+ uint16 srcPitch16 = (uint16)(srcPitch / sizeof(uint16));
+ uint16 dstPitch16 = (uint16)(dstPitch / sizeof(uint16));
+
+ for (i=0; i<((height)/6); i++) {
+ for (j=0; j<width; j++) {
+ p1=*((uint16*)inbuf+j);
+ inbuf+=srcPitch16;
+ *((uint16*)outbuf+j)=p1;
+ outbuf+=dstPitch16;
+ p2=*((uint16*)inbuf+j);
+ inbuf+=srcPitch16;
+ *((uint16*)outbuf+j)=MAKEPIXEL(P20(RB(p1))+P80(RB(p2)),P20(G(p1))+P80(G(p2)));
+ outbuf+=dstPitch16;
+ p1=p2;
+ p2=*((uint16*)inbuf+j);
+ inbuf+=srcPitch16;
+ *((uint16*)outbuf+j)=MAKEPIXEL(P40(RB(p1))+P60(RB(p2)),P40(G(p1))+P60(G(p2)));
+ outbuf+=dstPitch16;
+ p1=p2;
+ p2=*((uint16*)inbuf+j);
+ inbuf+=srcPitch16;
+ *((uint16*)outbuf+j)=MAKEPIXEL(P60(RB(p1))+P40(RB(p2)),P60(G(p1))+P40(G(p2)));
+ outbuf+=dstPitch16;
+ p1=p2;
+ p2=*((uint16*)inbuf+j);
+ *((uint16*)outbuf+j)=MAKEPIXEL(P80(RB(p1))+P20(RB(p2)),P80(G(p1))+P20(G(p2)));
+ outbuf+=dstPitch16;
+ *((uint16*)outbuf+j)=p2;
+ inbuf=inbuf-srcPitch16*4;
+ outbuf=outbuf-dstPitch16*5;
+ }
+ inbuf=inbuf+srcPitch16*5;
+ outbuf=outbuf+dstPitch16*6;
+ }
+}
+
+
+void PocketPCHalf(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
+ uint8 *work;
+ int i;
+ uint16 srcPitch16 = (uint16)(srcPitch / sizeof(uint16));
+
+ while ((height-=2) >= 0) {
+ i = 0;
+ work = dstPtr;
+
+ for (int i=0; i<width; i+=2) {
+ // Another lame filter attempt :)
+ uint16 color1 = *(((const uint16 *)srcPtr) + i);
+ uint16 color2 = *(((const uint16 *)srcPtr) + (i + 1));
+ uint16 color3 = *(((const uint16 *)srcPtr) + (i + srcPitch16));
+ uint16 color4 = *(((const uint16 *)srcPtr) + (i + srcPitch16 + 1));
+ *(((uint16 *)work) + 0) = CEinterpolate16_4(color1, color2, color3, color4);
+
+ work += sizeof(uint16);
+ }
+ srcPtr += 2 * srcPitch;
+ dstPtr += dstPitch;
+ }
+}
+
+
+void PocketPCHalfZoom(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
+ uint8 *work;
+ int i;
+ uint16 srcPitch16 = (uint16)(srcPitch / sizeof(uint16));
+
+ if (!height)
+ return;
+
+ while (height--) {
+ i = 0;
+ work = dstPtr;
+
+ for (int i=0; i<width; i+=2) {
+ uint16 color1 = *(((const uint16 *)srcPtr) + i);
+ uint16 color2 = *(((const uint16 *)srcPtr) + (i + 1));
+ *(((uint16 *)work) + 0) = CEinterpolate16_2(color1, 1, color2, 1);
+
+ work += sizeof(uint16);
+ }
+ srcPtr += srcPitch;
+ dstPtr += dstPitch;
+ }
+}
+
+//#ifdef WIN32_PLATFORM_WFSP
+void SmartphoneLandscape(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
+ uint8 *work;
+ int i;
+ int line = 0;
+
+ while (height--) {
+ i = 0;
+ work = dstPtr;
+
+ for (int i=0; i<width; i+=3) {
+ // Filter 2/3
+ uint16 color1 = *(((const uint16 *)srcPtr) + i);
+ uint16 color2 = *(((const uint16 *)srcPtr) + (i + 1));
+ uint16 color3 = *(((const uint16 *)srcPtr) + (i + 2));
+
+ *(((uint16 *)work) + 0) = CEinterpolate16_2(color1, 3, color2, 1);
+ *(((uint16 *)work) + 1) = CEinterpolate16_2(color2, 1, color3, 1);
+
+ work += 2 * sizeof(uint16);
+ }
+ srcPtr += srcPitch;
+ dstPtr += dstPitch;
+ line++;
+ if (line == 7) {
+ line = 0;
+ srcPtr += srcPitch;
+ height--;
+ }
+ }
+}
+//#endif
+
diff --git a/backends/platform/wince/CEScaler.h b/backends/platform/wince/CEScaler.h
new file mode 100644
index 0000000000..9ff10c632f
--- /dev/null
+++ b/backends/platform/wince/CEScaler.h
@@ -0,0 +1,42 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CESCALER
+#define CESCALER
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+#include "graphics/scaler.h"
+#include "graphics/scaler/intern.h"
+
+DECLARE_SCALER(PocketPCPortrait);
+DECLARE_SCALER(PocketPCLandscapeAspect);
+DECLARE_SCALER(PocketPCHalf);
+DECLARE_SCALER(PocketPCHalfZoom);
+//#ifdef WIN32_PLATFORM_WFSP
+DECLARE_SCALER(SmartphoneLandscape);
+//#endif
+
+void initCEScaler(void);
+
+#endif
diff --git a/backends/platform/wince/CEgui/CEGUI.h b/backends/platform/wince/CEgui/CEGUI.h
new file mode 100644
index 0000000000..1b5d5197f2
--- /dev/null
+++ b/backends/platform/wince/CEgui/CEGUI.h
@@ -0,0 +1,27 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 "ToolbarHandler.h"
+#include "Panel.h"
+#include "ItemSwitch.h"
+#include "PanelKeyboard.h"
+
diff --git a/backends/platform/wince/CEgui/GUIElement.cpp b/backends/platform/wince/CEgui/GUIElement.cpp
new file mode 100644
index 0000000000..520c17e11d
--- /dev/null
+++ b/backends/platform/wince/CEgui/GUIElement.cpp
@@ -0,0 +1,125 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "Toolbar.h"
+
+#include "SDL_ImageResource.h"
+
+namespace CEGUI {
+
+ GUIElement::GUIElement(int x, int y, int width, int height) :
+ _background(0), _drawn(false), _visible(true), _x(x), _y(y), _width(width), _height(height)
+ {
+ }
+
+ bool GUIElement::setBackground(WORD backgroundReference) {
+ _background = new SDL_ImageResource();
+ if (!_background->load(backgroundReference)) {
+ delete _background;
+ _background = NULL;
+ return false;
+ }
+ if (!_height && !_width) {
+ _height = _background->height();
+ _width = _background->width();
+ }
+ else
+ if (_background->height() != _height || _background->width() != _width) {
+ delete _background;
+ _background = NULL;
+ return false;
+ }
+ return true;
+ }
+
+ void GUIElement::move(int x, int y) {
+ _x = x;
+ _y = y;
+ }
+
+ bool GUIElement::draw(SDL_Surface *surface) {
+ if (_background && !_drawn && _visible) {
+ SDL_Rect rect;
+
+ rect.x = _x;
+ rect.y = _y;
+ rect.w = _width;
+ rect.h = _height;
+
+ SDL_BlitSurface(_background->get(), NULL, surface, &rect);
+
+ _drawn = true;
+
+ return true;
+ }
+ else
+ return false;
+ }
+
+ bool GUIElement::checkInside(int x, int y) {
+ if (x >= _x && x <= _x + _width && y >= _y && y <= _y + _height)
+ return true;
+ else
+ return false;
+ }
+
+ void GUIElement::setVisible(bool visibility) {
+ if (visibility && !_visible)
+ _drawn = false;
+ _visible = visibility;
+ }
+
+ bool GUIElement::visible() {
+ return _visible;
+ }
+
+ void GUIElement::forceRedraw() {
+ _drawn = false;
+ }
+
+ bool GUIElement::drawn() {
+ return _drawn;
+ }
+
+ int GUIElement::x() {
+ return _x;
+ }
+
+ int GUIElement::y() {
+ return _y;
+ }
+
+ int GUIElement::width() {
+ return _width;
+ }
+
+ int GUIElement::height() {
+ return _height;
+ }
+
+ GUIElement::~GUIElement() {
+ if (_background)
+ delete _background;
+ }
+
+}
diff --git a/backends/platform/wince/CEgui/GUIElement.h b/backends/platform/wince/CEgui/GUIElement.h
new file mode 100644
index 0000000000..eef84043b3
--- /dev/null
+++ b/backends/platform/wince/CEgui/GUIElement.h
@@ -0,0 +1,65 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEGUI_GUIELEMENT
+#define CEGUI_GUIELEMENT
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+
+#include "SDL.h"
+
+#include "SDL_ImageResource.h"
+
+namespace CEGUI {
+
+ class GUIElement {
+ public:
+ bool setBackground(WORD backgroundReference);
+ void setVisible(bool visibility);
+ virtual void forceRedraw();
+ virtual bool draw(SDL_Surface *surface);
+ virtual ~GUIElement();
+ void move(int x, int y);
+ int width();
+ int height();
+ int x();
+ int y();
+ virtual bool action(int x, int y, bool pushed) = 0;
+ bool visible();
+ bool drawn();
+ protected:
+ GUIElement(int x = 0, int y = 0, int width = 0, int height = 0);
+ bool checkInside(int x, int y);
+ bool _visible;
+ SDL_ImageResource *_background;
+ int _x;
+ int _y;
+ bool _drawn;
+ private:
+ int _width;
+ int _height;
+ };
+}
+
+#endif
diff --git a/backends/platform/wince/CEgui/ItemAction.cpp b/backends/platform/wince/CEgui/ItemAction.cpp
new file mode 100644
index 0000000000..9bc9db65bb
--- /dev/null
+++ b/backends/platform/wince/CEgui/ItemAction.cpp
@@ -0,0 +1,48 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "ItemAction.h"
+
+namespace CEGUI {
+
+ ItemAction::ItemAction(WORD reference, GUI::ActionType action) :
+ PanelItem(reference) {
+ _action = action;
+ if (!GUI::Actions::Instance()->isEnabled(_action))
+ _visible = false;
+ }
+
+
+ ItemAction::~ItemAction() {
+ }
+
+ bool ItemAction::action(int x, int y, bool pushed) {
+
+ if (checkInside(x, y) && _visible && pushed) {
+ GUI::Actions::Instance()->perform(_action);
+ return true;
+ }
+ else
+ return false;
+ }
+}
diff --git a/backends/platform/wince/CEgui/ItemAction.h b/backends/platform/wince/CEgui/ItemAction.h
new file mode 100644
index 0000000000..97202e14a1
--- /dev/null
+++ b/backends/platform/wince/CEgui/ItemAction.h
@@ -0,0 +1,44 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEGUI_ITEMACTION
+#define CEGUI_ITEMACTION
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+
+#include "gui/Actions.h"
+#include "CEgui/PanelItem.h"
+namespace CEGUI {
+
+ class ItemAction : public PanelItem {
+ public:
+ ItemAction(WORD reference, GUI::ActionType action);
+ virtual ~ItemAction();
+ virtual bool action(int x, int y, bool pushed);
+ private:
+ GUI::ActionType _action;
+ };
+}
+
+#endif
diff --git a/backends/platform/wince/CEgui/ItemSwitch.cpp b/backends/platform/wince/CEgui/ItemSwitch.cpp
new file mode 100644
index 0000000000..7498463871
--- /dev/null
+++ b/backends/platform/wince/CEgui/ItemSwitch.cpp
@@ -0,0 +1,93 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "ItemSwitch.h"
+
+namespace CEGUI {
+
+ void ItemSwitch::init(WORD referenceTrue, WORD referenceFalse) {
+ _backgroundTrue = _background;
+ _backgroundFalse = new SDL_ImageResource();
+ if (!_backgroundFalse->load(referenceFalse)) {
+ delete _backgroundFalse;
+ delete _background;
+ _background = NULL;
+ _backgroundFalse = NULL;
+ }
+ }
+
+ ItemSwitch::ItemSwitch(WORD referenceTrue, WORD referenceFalse, bool *item) :
+ PanelItem(referenceTrue) {
+ init(referenceTrue, referenceFalse);
+ _item = item;
+ _itemmax = -1;
+ if (!*_item)
+ _background = _backgroundFalse;
+ }
+
+ ItemSwitch::ItemSwitch(WORD referenceTrue, WORD referenceFalse, int *item, int max) :
+ PanelItem(referenceTrue) {
+ init(referenceTrue, referenceFalse);
+ _itemmultiple = item;
+ _itemmax = max;
+ if (!*item)
+ _background = _backgroundFalse;
+ }
+
+ ItemSwitch::~ItemSwitch() {
+ if (_backgroundFalse)
+ delete _backgroundFalse;
+ }
+
+ bool ItemSwitch::action(int x, int y, bool pushed) {
+
+ if (checkInside(x, y) && _visible && pushed) {
+ if (_itemmax <= 0) {
+ *_item = !*_item;
+ if (*_item)
+ _background = _backgroundTrue;
+ else
+ _background = _backgroundFalse;
+
+ if (_panel)
+ _panel->forceRedraw();
+
+ return true;
+ } else {
+ *_itemmultiple = *_itemmultiple + 1;
+ if (*_itemmultiple > _itemmax)
+ *_itemmultiple = 0;
+ if (*_itemmultiple)
+ _background = _backgroundTrue;
+ else
+ _background = _backgroundFalse;
+
+ if (_panel)
+ _panel->forceRedraw();
+
+ return true;
+ }
+ } else
+ return false;
+ }
+}
diff --git a/backends/platform/wince/CEgui/ItemSwitch.h b/backends/platform/wince/CEgui/ItemSwitch.h
new file mode 100644
index 0000000000..60a96c4894
--- /dev/null
+++ b/backends/platform/wince/CEgui/ItemSwitch.h
@@ -0,0 +1,53 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEGUI_ITEMSWITCH
+#define CEGUI_ITEMSWITCH
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+
+#include "Panel.h"
+#include "EventsBuffer.h"
+
+using GUI::Key;
+
+namespace CEGUI {
+
+ class ItemSwitch : public PanelItem {
+ public:
+ ItemSwitch(WORD referenceTrue, WORD referenceFalse, bool *item);
+ ItemSwitch(WORD referenceTrue, WORD referenceFalse, int *item, int max);
+ virtual ~ItemSwitch();
+ virtual bool action(int x, int y, bool pushed);
+ private:
+ void init(WORD referenceTrue, WORD referenceFalse);
+ bool *_item;
+ static bool _itemdummy;
+ int *_itemmultiple, _itemmax;
+ SDL_ImageResource *_backgroundTrue;
+ SDL_ImageResource *_backgroundFalse;
+ };
+}
+
+#endif
diff --git a/backends/platform/wince/CEgui/Panel.cpp b/backends/platform/wince/CEgui/Panel.cpp
new file mode 100644
index 0000000000..8b49b5d3a7
--- /dev/null
+++ b/backends/platform/wince/CEgui/Panel.cpp
@@ -0,0 +1,83 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "Panel.h"
+
+namespace CEGUI {
+
+ Panel::Panel(int interleave_first, int interleave) : Toolbar()
+ {
+ _interleave = interleave;
+ _currentItem = interleave_first;
+ }
+
+
+ bool Panel::add(const String &name, const PanelItem *item) {
+ _itemsMap[name] = (PanelItem*)item;
+ _itemsMap[name]->move(_currentItem, _y + 10);
+ _itemsMap[name]->setPanel(this);
+ _currentItem += _interleave;
+
+ return true;
+ }
+
+ bool Panel::draw(SDL_Surface *surface) {
+ ItemMap::const_iterator iterator;
+ if (!_drawn && _visible) {
+ GUIElement::draw(surface);
+ for (iterator = _itemsMap.begin(); iterator != _itemsMap.end(); ++iterator) {
+ ((GUIElement*)(iterator->_value))->draw(surface);
+ }
+ return true;
+ }
+ else
+ return false;
+ }
+
+ void Panel::forceRedraw() {
+ ItemMap::const_iterator iterator;
+ GUIElement::forceRedraw();
+ for (iterator = _itemsMap.begin(); iterator != _itemsMap.end(); ++iterator)
+ ((GUIElement*)(iterator->_value))->forceRedraw();
+ }
+
+ bool Panel::action(int x, int y, bool pushed) {
+ ItemMap::const_iterator iterator;
+ bool result = false;
+ if (!_visible || !checkInside(x, y))
+ return false;
+
+ for (iterator = _itemsMap.begin(); !result && iterator != _itemsMap.end(); ++iterator)
+ result = ((GUIElement*)(iterator->_value))->action(x, y, pushed);
+ return result;
+ }
+
+ void Panel::clear() {
+ _itemsMap.clear();
+ }
+
+ Panel::~Panel() {
+ _itemsMap.clear();
+ }
+}
+
diff --git a/backends/platform/wince/CEgui/Panel.h b/backends/platform/wince/CEgui/Panel.h
new file mode 100644
index 0000000000..8c4f4b3c7f
--- /dev/null
+++ b/backends/platform/wince/CEgui/Panel.h
@@ -0,0 +1,60 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEGUI_PANEL
+#define CEGUI_PANEL
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+#include "common/hashmap.h"
+#include "common/str.h"
+#include "common/config-manager.h"
+
+#include "PanelItem.h"
+#include "Toolbar.h"
+
+using Common::String;
+using Common::HashMap;
+
+namespace CEGUI {
+
+ class Panel : public Toolbar {
+ public:
+ Panel(int interleave_first, int interleave);
+ virtual bool draw(SDL_Surface *surface);
+ virtual ~Panel();
+ bool add(const String &name, const PanelItem *item);
+ void clear();
+ virtual void forceRedraw();
+ virtual bool action(int x, int y, bool pushed);
+ private:
+
+ typedef HashMap<String, PanelItem*, Common::IgnoreCase_Hash , Common::IgnoreCase_EqualTo> ItemMap;
+
+ ItemMap _itemsMap;
+ int _interleave;
+ int _currentItem;
+ };
+}
+
+#endif
diff --git a/backends/platform/wince/CEgui/PanelItem.cpp b/backends/platform/wince/CEgui/PanelItem.cpp
new file mode 100644
index 0000000000..762fac1047
--- /dev/null
+++ b/backends/platform/wince/CEgui/PanelItem.cpp
@@ -0,0 +1,45 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "PanelItem.h"
+
+namespace CEGUI {
+
+ PanelItem::PanelItem(WORD reference) : GUIElement() {
+ setBackground(reference);
+ _panel = NULL;
+ }
+
+
+ PanelItem::~PanelItem() {
+ }
+
+ bool PanelItem::action(int x, int y, bool pushed) {
+ return false;
+ }
+
+ void PanelItem::setPanel(Panel *panel) {
+ _panel = panel;
+ }
+}
+
diff --git a/backends/platform/wince/CEgui/PanelItem.h b/backends/platform/wince/CEgui/PanelItem.h
new file mode 100644
index 0000000000..638a9303d1
--- /dev/null
+++ b/backends/platform/wince/CEgui/PanelItem.h
@@ -0,0 +1,48 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEGUI_PANELITEM
+#define CEGUI_PANELITEM
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+
+#include "Toolbar.h"
+
+namespace CEGUI {
+
+ class Panel;
+
+ class PanelItem : public GUIElement {
+ friend class Panel;
+ public:
+ PanelItem(WORD reference);
+ virtual ~PanelItem();
+ virtual bool action(int x, int y, bool pushed);
+ protected:
+ void setPanel(Panel *panel);
+ Panel *_panel;
+ };
+}
+
+#endif
diff --git a/backends/platform/wince/CEgui/PanelKeyboard.cpp b/backends/platform/wince/CEgui/PanelKeyboard.cpp
new file mode 100644
index 0000000000..b554fb3b71
--- /dev/null
+++ b/backends/platform/wince/CEgui/PanelKeyboard.cpp
@@ -0,0 +1,88 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "PanelKeyboard.h"
+
+namespace CEGUI {
+
+ const char KEYBOARD_MAPPING_ALPHA_HIGH[] = {"abcdefghijklm"};
+ const char KEYBOARD_MAPPING_NUMERIC_HIGH[] = {"12345"};
+ const char KEYBOARD_MAPPING_ALPHA_LOW[] = {"nopqrstuvwxyz"};
+ const char KEYBOARD_MAPPING_NUMERIC_LOW[] = {"67890"};
+
+ PanelKeyboard::PanelKeyboard(WORD reference) : Toolbar() {
+ setBackground(reference);
+ }
+
+
+ PanelKeyboard::~PanelKeyboard() {
+ }
+
+ bool PanelKeyboard::action(int x, int y, bool pushed) {
+
+ if (checkInside(x, y)) {
+ char keyAscii = 0;
+ char keyCode = 0;
+ if (x < 185) {
+ // Alpha selection
+ if (y <= _y + 20)
+ keyAscii = KEYBOARD_MAPPING_ALPHA_HIGH[((x + 10) / 14) - 1];
+ else
+ keyAscii = KEYBOARD_MAPPING_ALPHA_LOW[((x + 10) / 14) - 1];
+ keyCode = tolower(keyAscii);
+ }
+ else
+ if (x >= 186 && x <= 255) {
+ // Numeric selection
+ if (y <= _y + 20)
+ keyAscii = KEYBOARD_MAPPING_NUMERIC_HIGH[((x - 187 + 10) / 14) - 1];
+ else
+ keyAscii = KEYBOARD_MAPPING_NUMERIC_LOW[((x - 187 + 10) / 14) - 1];
+ keyCode = keyAscii;
+ }
+ else
+ if (x >= 302 && x <= 316 && y < _y + 20) {
+ // Backspace
+ keyAscii = VK_BACK;
+ keyCode = keyAscii;
+ }
+ else
+ if (x >= 302 && x <= 316 && y >= _y + 20) {
+ // Enter
+ keyAscii = 13;
+ keyCode = 10;
+ }
+
+ if (keyAscii != 0) {
+ _key.setAscii(keyAscii);
+ _key.setKeycode(tolower(keyAscii));
+ return EventsBuffer::simulateKey(&_key, pushed);
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+ }
+}
+
diff --git a/backends/platform/wince/CEgui/PanelKeyboard.h b/backends/platform/wince/CEgui/PanelKeyboard.h
new file mode 100644
index 0000000000..2f53d0afa3
--- /dev/null
+++ b/backends/platform/wince/CEgui/PanelKeyboard.h
@@ -0,0 +1,48 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEGUI_PANELKEYBOARD
+#define CEGUI_PANELKEYBOARD
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+
+#include "Toolbar.h"
+#include "EventsBuffer.h"
+
+using GUI::Key;
+using CEKEYS::EventsBuffer;
+
+namespace CEGUI {
+
+ class PanelKeyboard : public Toolbar {
+ public:
+ PanelKeyboard(WORD reference);
+ virtual ~PanelKeyboard();
+ virtual bool action(int x, int y, bool pushed);
+ private:
+ Key _key;
+ };
+}
+
+#endif
diff --git a/backends/platform/wince/CEgui/SDL_ImageResource.cpp b/backends/platform/wince/CEgui/SDL_ImageResource.cpp
new file mode 100644
index 0000000000..0261d11684
--- /dev/null
+++ b/backends/platform/wince/CEgui/SDL_ImageResource.cpp
@@ -0,0 +1,83 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "SDL_ImageResource.h"
+
+namespace CEGUI {
+
+ SDL_ImageResource::SDL_ImageResource() :
+ _surface(0)
+ {
+ }
+
+ SDL_Surface* SDL_ImageResource::load(WORD resourceID) {
+ HRSRC resource;
+ HGLOBAL resourceGlobal;
+ LPVOID resourcePointer;
+ DWORD resourceSize;
+ SDL_RWops *surfaceData;
+ HMODULE moduleHandle;
+
+ moduleHandle = GetModuleHandle(NULL);
+ resource = FindResource(moduleHandle, MAKEINTRESOURCE(resourceID), TEXT("BINARY"));
+ if (!resource)
+ return NULL;
+ resourceSize = SizeofResource(moduleHandle, resource);
+ if (!resourceSize)
+ return NULL;
+ resourceGlobal = LoadResource(moduleHandle, resource);
+ if (!resourceGlobal)
+ return NULL;
+ resourcePointer = LockResource(resourceGlobal);
+ if (!resourcePointer)
+ return NULL;
+
+ surfaceData = SDL_RWFromMem(resourcePointer, resourceSize);
+ if (!surfaceData)
+ return NULL;
+ _surface = SDL_LoadBMP_RW(surfaceData, 1);
+
+ return _surface;
+ };
+
+ SDL_Surface* SDL_ImageResource::get() {
+ return _surface;
+ }
+
+ int SDL_ImageResource::height() {
+ if (_surface)
+ return _surface->h;
+ return 0;
+ }
+
+ int SDL_ImageResource::width() {
+ if (_surface)
+ return _surface->w;
+ return 0;
+ }
+
+ SDL_ImageResource::~SDL_ImageResource() {
+ if (_surface)
+ SDL_FreeSurface(_surface);
+ }
+}
diff --git a/backends/platform/wince/CEgui/SDL_ImageResource.h b/backends/platform/wince/CEgui/SDL_ImageResource.h
new file mode 100644
index 0000000000..0c46497de8
--- /dev/null
+++ b/backends/platform/wince/CEgui/SDL_ImageResource.h
@@ -0,0 +1,46 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEGUI_SDL_IMAGERESOURCE
+#define CEGUI_SDL_IMAGERESOURCE
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+
+#include "SDL.h"
+
+namespace CEGUI {
+ class SDL_ImageResource {
+ public:
+ SDL_ImageResource();
+ SDL_Surface* load(WORD resourceID);
+ SDL_Surface* get();
+ int height();
+ int width();
+ virtual ~SDL_ImageResource();
+ private:
+ SDL_Surface *_surface;
+ };
+}
+
+#endif
diff --git a/backends/platform/wince/CEgui/Toolbar.cpp b/backends/platform/wince/CEgui/Toolbar.cpp
new file mode 100644
index 0000000000..03859ab392
--- /dev/null
+++ b/backends/platform/wince/CEgui/Toolbar.cpp
@@ -0,0 +1,36 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "Toolbar.h"
+
+namespace CEGUI {
+
+ // Not to be drawn on game screen !
+ Toolbar::Toolbar() : GUIElement(0, 0, 320, 40)
+ {
+ }
+
+
+ Toolbar::~Toolbar() {
+ }
+}
diff --git a/backends/platform/wince/CEgui/Toolbar.h b/backends/platform/wince/CEgui/Toolbar.h
new file mode 100644
index 0000000000..ae97c1c8d5
--- /dev/null
+++ b/backends/platform/wince/CEgui/Toolbar.h
@@ -0,0 +1,49 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEGUI_TOOLBAR
+#define CEGUI_TOOLBAR
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+
+//#include "common/map.h"
+#include "common/str.h"
+
+#include "GUIElement.h"
+
+
+
+namespace CEGUI {
+
+ class Toolbar : public GUIElement {
+ public:
+ virtual ~Toolbar();
+ virtual bool action(int x, int y, bool pushed) = 0;
+ protected:
+ Toolbar();
+
+ };
+}
+
+#endif
diff --git a/backends/platform/wince/CEgui/ToolbarHandler.cpp b/backends/platform/wince/CEgui/ToolbarHandler.cpp
new file mode 100644
index 0000000000..1470479478
--- /dev/null
+++ b/backends/platform/wince/CEgui/ToolbarHandler.cpp
@@ -0,0 +1,125 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "ToolbarHandler.h"
+
+namespace CEGUI {
+
+ ToolbarHandler::ToolbarHandler():
+ _current(""), _active(NULL) {
+ }
+
+
+ bool ToolbarHandler::add(const String &name, const Toolbar &toolbar) {
+ _toolbarMap[name] = (Toolbar*)&toolbar;
+
+ if (!_active) {
+ _active = &((Toolbar&)toolbar);
+ _current = name;
+ }
+
+ return true;
+ }
+
+ String ToolbarHandler::activeName() {
+ return _current;
+ }
+
+ bool ToolbarHandler::setActive(const String &name) {
+ if (!_toolbarMap.contains(name))
+ return false;
+ if (_current == name)
+ return true;
+ _current = name;
+ _active = _toolbarMap[name];
+ _active->forceRedraw();
+ return true;
+ }
+
+ bool ToolbarHandler::action(int x, int y, bool pushed) {
+ if (_active && _active->visible()) {
+ // FIXME !
+ if (_offset > 240)
+ return _active->action(x / 2, (y - _offset) / 2, pushed);
+ else
+ return _active->action(x, y - _offset, pushed);
+ }
+ else
+ return false;
+ }
+
+ void ToolbarHandler::setVisible(bool visible) {
+ if (_active)
+ _active->setVisible(visible);
+ }
+
+ bool ToolbarHandler::visible() {
+ if (_active)
+ return _active->visible();
+ else
+ return false;
+ }
+
+ void ToolbarHandler::forceRedraw() {
+ if (_active)
+ _active->forceRedraw();
+ }
+
+ bool ToolbarHandler::drawn() {
+ if (_active)
+ return _active->drawn();
+ else
+ return false;
+ }
+
+ bool ToolbarHandler::draw(SDL_Surface *surface, SDL_Rect *rect) {
+ if (_active) {
+ bool result = _active->draw(surface);
+ if (result) {
+ rect->x = _active->x();
+ rect->y = _active->y();
+ rect->w = _active->width();
+ rect->h = _active->height();
+ }
+ return result;
+ }
+ else
+ return false;
+ }
+
+ void ToolbarHandler::setOffset(int offset) {
+ _offset = offset;
+ }
+
+ int ToolbarHandler::getOffset() {
+ return _offset;
+ }
+
+ Toolbar* ToolbarHandler::active() {
+ return _active;
+ }
+
+ ToolbarHandler::~ToolbarHandler() {
+ _toolbarMap.clear();
+ }
+}
diff --git a/backends/platform/wince/CEgui/ToolbarHandler.h b/backends/platform/wince/CEgui/ToolbarHandler.h
new file mode 100644
index 0000000000..376d536dd4
--- /dev/null
+++ b/backends/platform/wince/CEgui/ToolbarHandler.h
@@ -0,0 +1,65 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEGUI_TOOLBARHANDLER
+#define CEGUI_TOOLBARHANDLER
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+#include "common/str.h"
+#include "common/hashmap.h"
+#include "common/config-manager.h"
+
+#include "Toolbar.h"
+
+using Common::String;
+using Common::HashMap;
+
+namespace CEGUI {
+
+ class ToolbarHandler {
+ public:
+ ToolbarHandler();
+ bool add(const String &name, const Toolbar &toolbar);
+ bool setActive(const String &name);
+ bool action(int x, int y, bool pushed);
+ void setVisible(bool visible);
+ bool visible();
+ String activeName();
+ void forceRedraw();
+ void setOffset(int offset);
+ int getOffset();
+ bool draw(SDL_Surface *surface, SDL_Rect *rect);
+ bool drawn();
+ Toolbar *active();
+ virtual ~ToolbarHandler();
+ private:
+
+ HashMap<String, Toolbar*, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _toolbarMap;
+ String _current;
+ Toolbar *_active;
+ int _offset;
+ };
+}
+
+#endif
diff --git a/backends/platform/wince/CEkeys/CEKeys.h b/backends/platform/wince/CEkeys/CEKeys.h
new file mode 100644
index 0000000000..2b191b137f
--- /dev/null
+++ b/backends/platform/wince/CEkeys/CEKeys.h
@@ -0,0 +1,24 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 "EventsBuffer.h"
+
diff --git a/backends/platform/wince/CEkeys/EventsBuffer.cpp b/backends/platform/wince/CEkeys/EventsBuffer.cpp
new file mode 100644
index 0000000000..f89b851280
--- /dev/null
+++ b/backends/platform/wince/CEkeys/EventsBuffer.cpp
@@ -0,0 +1,75 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "EventsBuffer.h"
+
+namespace CEKEYS {
+
+ bool EventsBuffer::simulateKey(GUI::Key *key, bool pushed) {
+ SDL_Event ev = {0};
+
+ if (!key->keycode())
+ key->setKeycode(key->ascii());
+
+ if (!key->ascii())
+ key->setAscii(key->keycode());
+
+ ev.type = (pushed ? SDL_KEYDOWN : SDL_KEYUP);
+ ev.key.keysym.mod = (SDLMod)key->flags();
+ ev.key.keysym.sym = (SDLKey)key->keycode();
+ ev.key.keysym.unicode = key->keycode();
+ ev.key.keysym.mod = KMOD_RESERVED;
+ return (SDL_PushEvent(&ev) == 0);
+ }
+
+ bool EventsBuffer::simulateMouseMove(int x, int y) {
+ SDL_Event ev = {0};
+
+ ev.type = SDL_MOUSEMOTION;
+ ev.motion.x = x;
+ ev.motion.y = y;
+ return (SDL_PushEvent(&ev) == 0);
+ }
+
+ bool EventsBuffer::simulateMouseLeftClick(int x, int y, bool pushed) {
+ SDL_Event ev = {0};
+
+ ev.type = (pushed ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP);
+ ev.button.button = SDL_BUTTON_LEFT;
+ ev.button.x = x;
+ ev.button.y = y;
+ return (SDL_PushEvent(&ev) == 0);
+ }
+
+ bool EventsBuffer::simulateMouseRightClick(int x, int y, bool pushed) {
+ SDL_Event ev = {0};
+
+ ev.type = (pushed ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP);
+ ev.button.button = SDL_BUTTON_RIGHT;
+ ev.button.x = x;
+ ev.button.y = y;
+ return (SDL_PushEvent(&ev) == 0);
+ }
+}
+
+
diff --git a/backends/platform/wince/CEkeys/EventsBuffer.h b/backends/platform/wince/CEkeys/EventsBuffer.h
new file mode 100644
index 0000000000..eacc00fe75
--- /dev/null
+++ b/backends/platform/wince/CEkeys/EventsBuffer.h
@@ -0,0 +1,47 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 CEKEYS_EVENTSBUFFER
+#define CEKEYS_EVENTSBUFFER
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+#include "common/list.h"
+
+#include <SDL.h>
+
+#include "gui/Key.h"
+
+namespace CEKEYS {
+
+ class EventsBuffer {
+ public:
+ static bool simulateKey(GUI::Key *key, bool pushed);
+ static bool simulateMouseMove(int x, int y);
+ static bool simulateMouseLeftClick(int x, int y, bool pushed);
+ static bool simulateMouseRightClick(int x, int y, bool pushed);
+
+ };
+}
+
+#endif
diff --git a/backends/platform/wince/PocketSCUMM.rc b/backends/platform/wince/PocketSCUMM.rc
new file mode 100644
index 0000000000..c11547bc08
--- /dev/null
+++ b/backends/platform/wince/PocketSCUMM.rc
@@ -0,0 +1,145 @@
+//Microsoft eMbedded Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "newres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// French (France) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
+#ifdef _WIN32
+LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_POCKETSCUMM ICON DISCARDABLE "icons/scumm_icon.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""newres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menubar
+//
+
+IDR_SMARTFON_MENUBAR_GAMES MENU DISCARDABLE
+BEGIN
+ POPUP "Games"
+ BEGIN
+ POPUP "Play"
+ BEGIN
+ MENUITEM SEPARATOR
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "Scan", IDM_SMARTFON_SCAN
+ MENUITEM SEPARATOR
+ MENUITEM "Quit", IDM_SMARTFON_QUIT
+ END
+ POPUP "Options"
+ BEGIN
+ POPUP "Keys Mapping"
+ BEGIN
+ MENUITEM SEPARATOR
+ END
+ MENUITEM "Sound", IDM_SMARTFON_SOUND
+ MENUITEM "Help", IDM_SMARTFON_HELP
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Data
+//
+
+IDR_SMARTFON_MENUBAR_GAMES SHMENUBAR DISCARDABLE
+BEGIN
+ IDR_SMARTFON_MENUBAR_GAMES, 2,
+ I_IMAGENONE, ID_MENU_GAMES, TBSTATE_ENABLED,
+ TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_CAP_MENUITEM40002, 0, 0,
+ I_IMAGENONE, ID_MENU_OPTIONS, TBSTATE_ENABLED,
+ TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_CAP_OPTIONS, 0, 1,
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// BINARY
+//
+
+PANEL_GENERIC BINARY DISCARDABLE "images\\panelbig.bmp"
+PANEL_KEYBOARD BINARY DISCARDABLE "images\\keyboard.bmp"
+ITEM_SKIP BINARY DISCARDABLE "images\\Action.bmp"
+ITEM_OPTIONS BINARY DISCARDABLE "images\\DiskwFolder.bmp"
+ITEM_SOUND_ON BINARY DISCARDABLE "images\\SoundOn.bmp"
+ITEM_SOUND_OFF BINARY DISCARDABLE "images\\SoundOff.bmp"
+ITEM_VIEW_PORTRAIT BINARY DISCARDABLE "images\\MonkeyPortrait.bmp"
+ITEM_VIEW_LANDSCAPE BINARY DISCARDABLE "images\\MonkeyLandscape.bmp"
+ITEM_BINDKEYS BINARY DISCARDABLE "images\\bindkeys.bmp"
+HI_RES_AWARE CEUX {1}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_CAP_MENUITEM40002 "Games"
+ IDS_CAP_OPTIONS "Options"
+END
+
+#endif // French (France) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/backends/platform/wince/README-WinCE b/backends/platform/wince/README-WinCE
new file mode 100644
index 0000000000..b1fc585e22
--- /dev/null
+++ b/backends/platform/wince/README-WinCE
@@ -0,0 +1,506 @@
+ScummVM Windows CE FAQ
+Last updated: 2006-06-20
+Release version: 0.9.0
+------------------------------------------------------------------------
+
+This document is intended to give common answers to specific ScummVM
+issues on Windows CE, in 3 sections
+ * "General questions" : browse this section to get started and see
+ general issues
+ * "Game specific questions" : lists some common game specific issues
+ * "Support and links" : how to get support if you're still puzzled
+
+------------------------------------------------------------------------
+General questions
+------------------------------------------------------------------------
+
+Which devices are supported ?
+-----------------------------
+
+Official build
+--------------
+
+The official build is based on the ARM architecture and should work with any
+Pocket PC 2000, Pocket PC 2002, Pocket PC 2003, Pocket PC 2003 SE, Smartphone
+2002, Smartphone 2003 or Windows Mobile based device.
+
+Support for old ARM architectures (Handheld PCs, Palm Size PCs) and other CPUs
+(MIPS, SH3) is discontinued. Feel free to generate builds for these
+architectures and contact me to include them on ScummVM website.
+
+Full support
+------------
+
+* ARM based Windows Mobile handhelds with QVGA resolution (240x320) slower
+ than 200 MHz (PocketPC platform)
+
+All AdLib first generation games should work properly on these devices.
+Sam'n'Max will be a bit too slow to be played with music.
+More recent games (The Dig, Curse of Monkey Island, Broken Sword series)
+and all VGA games will probably be too slow to be enjoyable.
+
+* ARM based Windows Mobile handhelds with QVGA resolution (240x320) faster
+ than 200 MHz
+
+All games should work properly on these devices.
+VGA games will be resized and the font gets hard to read in this case (be sure
+to install the talkie version the game :p)
+
+* ARM based Windows Mobile handhelds with VGA resolution (640x480)
+
+All non VGA games should work properly on these devices. They can be resized
+with different scalers (not all desktop scalers are supported due to Embedded
+Visual C++ very personal interpretation of the C++ standard).
+VGA games will be displayed in true VGA mode, which can takes a lot of memory
+and slow down the game (especially during scrollings). It will get better in
+the next releases or with faster devices.
+
+* Windows Mobile Smartphones (176x220 or 240x320)
+
+Early support is provided for all 320x200 games.
+The font can get hard to read (you should prefer talkie games, or wear glasses)
+
+* Support for Windows Mobile 5 is experimental but should work. "Flipping" devices
+such as the HTC Wizard or HTC Universal work only in portait (closed) mode for the
+moment.
+
+Partial / Discontinued support
+------------------------------
+
+Support for the following devices is not complete, not working properly or
+discontinued because the device is now obsolete. Feel free to contribute and
+improve the port for your favorite device, or use the last release built with
+the previous port architecture (0.5.1) which was less resource hungry and
+supported more exotic devices.
+
+* "Paletted" devices (non "true color")
+
+These devices will be supported through the GDI layer which will slow down the
+games a lot. You can try to disable the music/sound effects to get a better
+game experience.
+
+* "Mono" devices
+
+I don't even think anything will be displayed on these devices :) you can try
+and report your success ...
+
+* MIPS/SH3 devices with QVGA resolution (240x320), "true color"
+
+Some devices may be a bit too slow, especially if direct screen access (GAPI)
+is not supported on these devices.
+
+* ARM/MIPS/SH3 devices with VGA resolution (640x480) (Palm Size PC / Handheld
+ PC platform)
+
+True VGA games will probably be too slow to run properly on these devices even
+if they can support them ...
+
+* ARM/MIPS/SH3 devices with desktop resolution (800x600) (Handheld PC platform)
+
+No, there will never be ANY scaler supporting 800x600 resolution, because
+320x200 games CANNOT be resized to a 800x600 by a simple operation.
+
+And the device will probably be too slow to perform any kind of graphic
+transform anyway :)
+
+How do I install ScummVM for Windows CE ?
+-----------------------------------------
+
+If the current release includes a .EXE installer, ScummVM for Windows CE
+will be installed without hassle.
+Otherwise, you'll unzip the release on your desktop computer, and copy
+all files on your device.
+
+If you're using a Pocket PC 2000 operating system, be sure to have GAPI
+installed - it's available on Microsoft website http://www.microsoft.com
+
+How do I install a game ?
+-------------------------
+
+You'll at least need to copy all the data files from your game, in a
+sub-directory of your game directory.
+
+You'll need to put the data files in a directory named after ScummVM game
+name (see "Supported Game" section in ScummVM readme) for the games having
+"generic" data files (.LFL files). Recent games can be put in any directory.
+
+You can compress the multimedia files (sound/video) as described in the
+ScummVM readme.
+
+You can compress the audio tracks of Loom or Monkey Island 1 as described in
+the ScummVM readme. If you are running these games on a slow device with Ogg
+Vorbis compression, it's recommended to sample the files to 11 kHz (this sample
+rate is not supported by other versions of ScummVM).
+
+If you need more details, you can check SirDave's mini-manual online available
+at: http://forums.scummvm.org/viewtopic.php?t=936
+and at: http://www.pocketmatrix.com/forums/viewtopic.php?t=8606
+
+How do I run a game ?
+---------------------
+
+If it's the first time you're running ScummVM for Windows CE, have installed or
+removed games, you need to rescan your game directory.
+ * Select Scan, tap the root directory of your games, and tap "Yes" to begin
+ an automatic scan of the installed games.
+
+Usually all games are detected and you can start playing right away. If your
+game is not detected check its directory name and your data files.
+
+To play a game, tap on its name then tap the "Play" button or double tap its
+name.
+
+How do I play a game on a Pocket PC or Handheld PC device ?
+-----------------------------------------------------------
+
+The stylus is your mouse cursor, and a tap is a left mouse button click.
+
+As the Pocket PC lacks some keys, a toolbar is displayed at the bottom of the
+screen to make the most common functions just a tap away
+ * The disk icon opens ScummVM options menu to save your game, or change your
+ current game settings.
+ * The movie icon skips a non interactive sequence, the current dialog or
+ behaves like the ESC key on a regular keyboard
+ * The sound icon turns all sound effects and music off and on
+ * The key icon allow you to map a key action to a device button.
+ * The monkey icon switches between portrait, landscape and inverse landscape
+ mode.
+
+You can map additional actions on your device hardware buttons using the
+"Options" / "Key" menu in the ScummVM options menu. To associate an action to
+a key, tap the action, then the "Map" button and press the hardware key.
+The following actions are available
+ * Pause : pause the game
+ * Save : open ScummVM option menu
+ * Quit : quit ScummVM (without saving, be careful when using it)
+ * Skip : skip a non interactive sequence, the current dialog or
+ behaves like the ESC key on a regular keyboard
+ * Hide : hide or display the toolbar
+ - YOU MUST HIDE THE TOOLBAR TO SCROLL THROUGH THE INVENTORY IN ZAK -
+ * Keyboard : hide or display the virtual keyboard
+ - YOU MUST DISPLAY THE KEYBOARD TO FIGHT IN INDIANA JONES 3 -
+ * Sound : turns all sound effects and music off and on
+ * Right click : acts as a right mouse button click
+ - YOU MUST MAP THIS ACTION TO PLAY THE FOLLOWING GAMES -
+ - SAM & MAX, BENEATH A STEEL SKY, CURSE OF MONKEY ISLAND -
+ * Cursor : hide or display the mouse cursor
+ * Free look : go in or out of free-look mode. In this mode, you can tap
+ the screen to look for interesting locations without walking.
+ * Zoom up : magnify the upper part of the screen for 640x480 games
+ rendered on a 320x240 device.
+ * Zoom down : magnify the lower part of the screen for 640x480 games
+ rendered on a 320x240 device.
+ * FT Cheat : win a Full Throttle action sequence
+ * Bind keys : map a key action to a device button
+ * Up,Down,Left:
+ Right, : emulate mouse/stylus behavior
+ Left Click :
+
+If you start a game when a Right click mapping is necessary, ScummVM will ask
+you to map one of your hardware key to this action before playing. Just press
+the key you want to map if you see this message.
+
+How do I hide the toolbar ?
+----------------------------
+
+A shortcut is available to hide the toolbar directly from the game screen from
+release 0.8.0. Double tapping the stylus at the top of the screen will switch
+between a visible toolbar panel, a virtual keyboard, and an invisible panel.
+If any part of the screen is obscured by the toolbar (like the load/save game
+dialogs) you can use the invisible panel mode to get to it. For 320x200 games
+on QVGA Pocket PCs, when the panel is hidden the game screen is resized to
+320x240 for better gaming experience.
+
+How do I play a game on a Microsoft Smartphone device ?
+-------------------------------------------------------
+
+When playing on a Smartphone, the cursor and mouse buttons are emulated by
+a set of default keys :
+ 4 Move up
+ 6 Move down
+ 8 Move left
+ 2 Move right
+ Hotkey 1 Left mouse button click
+ Hotkey 2 Right mouse button click
+ Return/Action Open the key mapping menu
+
+Note that this means that the input will be "inversed" on a 240x320 (Windows
+Mobile 2005) Smartphone. You'll have to remap the keys.
+
+A few options are also emulated by a set of default keys :
+
+ 0 Options menu
+ Back Skip
+ # Zone option
+
+The cursor will move faster if you keep the key down. You can tweak this
+behaviour in the configuration file described below.
+
+The "Zone" key is a *very* valuable addition allowing you to jump quickly
+between three screen zones : the game zone, the verbs zone and the inventory
+zone. When you switch to a zone the cursor will be reset to its former location
+in this zone.
+
+There are two more actions available for mapping:
+ - Keyboard: Shows hides a virtual keyboard which can be use whenever text
+ input is required in a game, or a dialog.
+ - Rotate : Flips the screen orientation between normal and inverse landscape.
+
+You can change the keys mapping during the game in the key mapping menu.
+
+Note that you'll need to push the Action button (center of the pad) to quit
+a Simon game.
+
+How can I apply a ScummVM command line option (f.e. to change the language)
+---------------------------------------------------------------------------
+
+See the section regarding the configuration file (scummvm.ini) in ScummVM
+README file - the same keywords apply.
+
+Some parameters are specific to this port :
+
+game specific section (f.e. [monkey2]) - performance options
+
+high_sample_rate bool Desktop quality (22 kHz) sound output if set.
+ 11 kHz otherwise.
+ The default is 11 kHz.
+ If you have a fast device, you can set this to
+ true to enjoy better sound effects and music.
+FM_high_quality bool Desktop quality FM synthesis if set. Lower
+ quality otherwise. The default is low quality.
+ You can change this if you have a fast device.
+sound_thread_priority int Set the priority of the sound thread
+ (given to SetThreadPriority API)
+Smush_force_redraw int Force a Smush frame redraw every X missed
+ frames. Mainly used for Full Throttle action
+ sequences. Setting it lower gives more
+ priority to screen redraws. Setting it higher
+ gives more priority to stylus/keyboard input.
+ The default is 30.
+
+game specific section (f.e. [monkey2]) - game options
+
+landscape int 0: Portrait, 1: Landscape, 2: Inverse Landscape
+
+[scummvm] section - keys definition
+
+You usually do not wish to modify these values directly, as they are set
+by the option dialog, and are only given here for reference.
+
+action_mapping_version int Mapping version linked to ScummVM version.
+action_mapping string Hex codes describing the key associated to
+ each different action.
+
+[scummvm] section - mouse emulation tuning
+
+You can tweak these parameters to customize how the cursor is handled.
+
+repeatTrigger int Number of milliseconds a key must be held to
+ consider being repeated.
+
+repeatX int Number of key repeat events before changing
+ horizontal cursor behaviour.
+stepX1 int Horizontal cursor offset value when the key is
+ not repeated.
+stepX2 int Horizontal cursor offset value when the key is
+ repeated less than repeatX.
+stepX3 int Horizontal cursor offset value when the key is
+ repeated more than repeatX.
+
+
+repeatY int Number of key repeat events before changing
+ vertical cursor behaviour.
+stepY1 int Vertical cursor offset value when the key is
+ not repeated.
+stepY2 int Horizontal cursor offset value when the key is
+ repeated less than repeatY.
+stepY3 int Vertical cursor offset value when the key is
+ repeated more than repeatY.
+
+Game xxx is too slow on my device
+---------------------------------
+
+Even if it shouldn't happen (this port is running almost correctly on a
+80 / 120 MHz first generation SPV phone), you can try some things :
+
+ * Disable sound in the engine (see the global README)
+ * Play with the priority of the sound thread (change the
+ sound_thread_priority value - the higher the lower priority)
+
+And don't forget to report your progress in the ScummVM forum !
+
+------------------------------------------------------------------------
+Game specific questions
+------------------------------------------------------------------------
+
+--------------------------
+-- Beneath a Steel Sky --
+--------------------------
+
+Introduction movie is too slow or never ends ...
+-------------------------------------------------
+
+Skip it :)
+
+How can I open the inventory in Beneath a Steel Sky ?
+---------------------------------------------------
+
+Tap the top of the screen. Check your stylus calibration if you still cannot
+open it.
+
+How can I use an item in Beneath a Steel Sky ?
+----------------------------------------------
+
+You need to map the right click button (see the General Questions section).
+
+----------------------------
+-- Curse of Monkey Island --
+----------------------------
+
+How can I open the inventory in Curse of Monkey Island ?
+------------------------------------------------------
+
+You need to map the right click button (see the General Questions section).
+
+I'm experiencing random crashes ...
+------------------------------------
+
+This game has high memory requirements, and may crash sometimes on low
+memory devices. Continue your game with the latest automatically saved
+game and everything should be fine.
+You can consider removing the music and voice files (VOXDISK.BUN, MUSDISK.BUN)
+to lower these requirements.
+
+Sound synchronization is lost in Curse of Monkey Island videos
+--------------------------------------------------------------
+
+This is a port bug which is very noticeable in VGA mode. It can probably be
+fixed with a faster blitting routine or a faster device.
+
+--------------------
+-- Full Throttle --
+--------------------
+
+I'm experiencing random crashes ...
+------------------------------------
+
+This game has high memory requirements, and may crash sometimes on low
+memory devices. Continue your game with the latest automatically saved
+game and everything should be fine.
+You can consider removing the voice file (MONSTER.SOU) and disable the
+music to lower these requirements.
+
+----------------------------------------
+-- Indiana Jones and the Last Crusade --
+----------------------------------------
+
+How can I fight in Indiana Jones and the Last Crusade ?
+-----------------------------------------------------
+
+You need to map the keyboard button (see the General Questions section).
+
+---------------
+-- Sam & Max --
+---------------
+
+How can I change the current action ?
+-------------------------------------
+
+You need to map the right click button (see the General Questions section).
+
+How can I exit a mini game ?
+----------------------------
+
+Use the skip toolbar icon (see the General Questions section).
+
+-------------------
+-- Simon 1 and 2 --
+--------------------
+
+How can I save or quit in Simon ?
+--------------------------------
+
+"Use" (use the use verb :p) the postcard. The ScummVM option dialog is disabled
+in Simon games.
+
+On Smartphone, you'll need to push the Action button (center of the pad) to
+quit the game.
+
+-------------
+-- The Dig --
+-------------
+
+I'm experiencing random crashes ...
+------------------------------------
+
+This game has high memory requirements, and may crash sometimes on low
+memory devices. Continue your game with the latest automatically saved
+game and everything should be fine.
+You can consider removing the music and voice files (VOXDISK.BUN, MUSDISK.BUN)
+to lower these requirements.
+
+--------------------
+-- Zak Mc Kracken --
+--------------------
+
+How can I scroll through my inventory items in Zak Mc Kracken ?
+-------------------------------------------------------------
+
+You need to map the hide toolbar button (see the General Questions section) or
+double tap at the top of the screen (from 0.8.0+)
+
+--------------------
+-- Broken Sword 2 --
+--------------------
+
+I've installed the movies pack but they are not playing
+-------------------------------------------------------
+
+MPEG 2 playback takes too much memory in the current release, and may prevent
+movies from playing in VGA mode. This may get better in the next releases.
+
+----------------
+-- Gobliiins --
+----------------
+
+Cursor is grabled after loading a game
+--------------------------------------
+
+Due to a bug in 0.8.0, you'll have to tap the stylus somewhere on the game
+screen between 2 letters when entering a code. Otherwise the cursor will get
+garbled.
+
+This has not been retested for 0.8.1 but should be fixed.
+
+------------------------------------------------------------------------
+Support
+------------------------------------------------------------------------
+
+Help, I've read everything and ...
+-----------------------------------
+
+Luckily, as there is a huge variety of Windows Mobile devices, a specific forum
+is dedicated to this ScummVM port. You can ask your question on the WinCE
+ScummVM forum available at http://forums.scummvm.org/viewforum.php?f=6
+
+Some older questions and very nice tutorials are still available on the historic
+PocketMatrix forum at http://www.pocketmatrix.com/forums/viewforum.php?f=20
+where the community is always glad to help and have dealt with all my bugs for more
+than three years now :)
+
+I think I found a bug, ScummVM crashes in ...
+---------------------------------------------
+
+See the "Reporting Bugs" section in ScummVM readme.
+
+If you have a Pocket PC or Handheld PC, be sure to include its resolution (obtained
+on the second dialog displayed on the "About" menu) in your bug report.
+
+If you cannot reproduce this bug on another ScummVM version, you can cross
+post your bug report on ScummVM forums.
+
+------------------------------------------------------------------------
+Good Luck and Happy Adventuring!
+The ScummVM team.
+http://www.scummvm.org/
+------------------------------------------------------------------------
diff --git a/backends/platform/wince/icons/scumm_icon.ico b/backends/platform/wince/icons/scumm_icon.ico
new file mode 100644
index 0000000000..cc9c68d778
--- /dev/null
+++ b/backends/platform/wince/icons/scumm_icon.ico
Binary files differ
diff --git a/backends/platform/wince/images/Action.bmp b/backends/platform/wince/images/Action.bmp
new file mode 100644
index 0000000000..4985512cf4
--- /dev/null
+++ b/backends/platform/wince/images/Action.bmp
Binary files differ
diff --git a/backends/platform/wince/images/DiskwFolder.bmp b/backends/platform/wince/images/DiskwFolder.bmp
new file mode 100644
index 0000000000..82b4019930
--- /dev/null
+++ b/backends/platform/wince/images/DiskwFolder.bmp
Binary files differ
diff --git a/backends/platform/wince/images/MonkeyLandscape.bmp b/backends/platform/wince/images/MonkeyLandscape.bmp
new file mode 100644
index 0000000000..70f6ed69e7
--- /dev/null
+++ b/backends/platform/wince/images/MonkeyLandscape.bmp
Binary files differ
diff --git a/backends/platform/wince/images/MonkeyPortrait.bmp b/backends/platform/wince/images/MonkeyPortrait.bmp
new file mode 100644
index 0000000000..00619c2985
--- /dev/null
+++ b/backends/platform/wince/images/MonkeyPortrait.bmp
Binary files differ
diff --git a/backends/platform/wince/images/SoundOff.bmp b/backends/platform/wince/images/SoundOff.bmp
new file mode 100644
index 0000000000..2f7b26deaf
--- /dev/null
+++ b/backends/platform/wince/images/SoundOff.bmp
Binary files differ
diff --git a/backends/platform/wince/images/SoundOn.bmp b/backends/platform/wince/images/SoundOn.bmp
new file mode 100644
index 0000000000..2988b87224
--- /dev/null
+++ b/backends/platform/wince/images/SoundOn.bmp
Binary files differ
diff --git a/backends/platform/wince/images/bindkeys.bmp b/backends/platform/wince/images/bindkeys.bmp
new file mode 100644
index 0000000000..8a6cfc9347
--- /dev/null
+++ b/backends/platform/wince/images/bindkeys.bmp
Binary files differ
diff --git a/backends/platform/wince/images/keyboard.bmp b/backends/platform/wince/images/keyboard.bmp
new file mode 100644
index 0000000000..aac79d00e5
--- /dev/null
+++ b/backends/platform/wince/images/keyboard.bmp
Binary files differ
diff --git a/backends/platform/wince/images/panelbig.bmp b/backends/platform/wince/images/panelbig.bmp
new file mode 100644
index 0000000000..4d10f255ad
--- /dev/null
+++ b/backends/platform/wince/images/panelbig.bmp
Binary files differ
diff --git a/backends/platform/wince/missing/assert.h b/backends/platform/wince/missing/assert.h
new file mode 100644
index 0000000000..0a9dc23bb8
--- /dev/null
+++ b/backends/platform/wince/missing/assert.h
@@ -0,0 +1,9 @@
+/* Header is not present in Windows CE SDK */
+
+// defined in common/util.h
+void CDECL _declspec(noreturn) error(const char *s, ...);
+
+#define assert(e) ((e) ? 0 : (::error("Assertion failed " #e " (%s, %d)", __FILE__, __LINE__)))
+
+#define abort() ::error("Abort (%s, %d)", __FILE__, __LINE__)
+
diff --git a/backends/platform/wince/missing/conio.h b/backends/platform/wince/missing/conio.h
new file mode 100644
index 0000000000..0cb5c297ea
--- /dev/null
+++ b/backends/platform/wince/missing/conio.h
@@ -0,0 +1,2 @@
+/* Header is not present in Windows CE SDK */
+
diff --git a/backends/platform/wince/missing/dir.h b/backends/platform/wince/missing/dir.h
new file mode 100644
index 0000000000..7ee9f5e5ba
--- /dev/null
+++ b/backends/platform/wince/missing/dir.h
@@ -0,0 +1 @@
+/* Header is not present in Windows CE SDK */
diff --git a/backends/platform/wince/missing/direct.h b/backends/platform/wince/missing/direct.h
new file mode 100644
index 0000000000..7ee9f5e5ba
--- /dev/null
+++ b/backends/platform/wince/missing/direct.h
@@ -0,0 +1 @@
+/* Header is not present in Windows CE SDK */
diff --git a/backends/platform/wince/missing/dirent.h b/backends/platform/wince/missing/dirent.h
new file mode 100644
index 0000000000..82dd0b2ee7
--- /dev/null
+++ b/backends/platform/wince/missing/dirent.h
@@ -0,0 +1,52 @@
+/* Header is not present in Windows CE SDK */
+/* It would not be a bad idea to take this thing from gcc distro and port
+ it properly. For now only required part is ported. */
+
+struct dirent
+{
+ long d_ino; /* Always zero. */
+ unsigned short d_reclen; /* Always zero. */
+ unsigned short d_namlen; /* Length of name in d_name. */
+ char* d_name; /* File name. */
+ /* NOTE: The name in the dirent structure points to the name in the
+ * finddata_t structure in the DIR. */
+};
+
+/*
+ * This is an internal data structure. Good programmers will not use it
+ * except as an argument to one of the functions below.
+ */
+typedef struct
+{
+ /* disk transfer area for this dir */
+/* struct _finddata_t dd_dta; */
+
+ /* dirent struct to return from dir (NOTE: this makes this thread
+ * safe as long as only one thread uses a particular DIR struct at
+ * a time) */
+ struct dirent dd_dir;
+
+ /* _findnext handle */
+ long dd_handle;
+
+ /*
+ * Status of search:
+ * 0 = not started yet (next entry to read is first entry)
+ * -1 = off the end
+ * positive = 0 based index of next entry
+ */
+ short dd_stat;
+
+ /* given path for dir with search pattern (struct is extended) */
+ char dd_name[1];
+} DIR;
+
+
+DIR* opendir (const char*);
+struct dirent* readdir (DIR*);
+int closedir (DIR*);
+/*
+void rewinddir (DIR*);
+long telldir (DIR*);
+void seekdir (DIR*, long);
+*/
diff --git a/backends/platform/wince/missing/errno.h b/backends/platform/wince/missing/errno.h
new file mode 100644
index 0000000000..7ee9f5e5ba
--- /dev/null
+++ b/backends/platform/wince/missing/errno.h
@@ -0,0 +1 @@
+/* Header is not present in Windows CE SDK */
diff --git a/backends/platform/wince/missing/fcntl.h b/backends/platform/wince/missing/fcntl.h
new file mode 100644
index 0000000000..7ee9f5e5ba
--- /dev/null
+++ b/backends/platform/wince/missing/fcntl.h
@@ -0,0 +1 @@
+/* Header is not present in Windows CE SDK */
diff --git a/backends/platform/wince/missing/io.h b/backends/platform/wince/missing/io.h
new file mode 100644
index 0000000000..a7b74c71b7
--- /dev/null
+++ b/backends/platform/wince/missing/io.h
@@ -0,0 +1,15 @@
+/* Header is not present in Windows CE SDK */
+
+/* This stuff will live here until port configuration file is in place */
+#define stricmp _stricmp
+#define strdup _strdup
+#define _HEAPOK 0
+#define _heapchk() 0
+
+#ifndef _FILE_DEFINED
+ typedef void FILE;
+ #define _FILE_DEFINED
+#endif
+FILE* wce_fopen(const char* fname, const char* fmode);
+#define fopen wce_fopen
+
diff --git a/backends/platform/wince/missing/missing.cpp b/backends/platform/wince/missing/missing.cpp
new file mode 100644
index 0000000000..e85babc13f
--- /dev/null
+++ b/backends/platform/wince/missing/missing.cpp
@@ -0,0 +1,644 @@
+/* MISSING.C
+ Implementation for standard and semi-standard C library calls missing in WinCE
+ environment.
+ by Vasyl Tsvirkunov
+*/
+
+#include <windows.h>
+#include <tchar.h>
+#include <string.h>
+#include <stdlib.h>
+#include "sys/stat.h"
+#include "sys/time.h"
+#include "time.h"
+#include "dirent.h"
+
+/* forward declaration */
+
+#if _WIN32_WCE < 300
+
+#define _STDAFX_H
+#include "portdefs.h"
+
+#else
+
+char *strdup(const char *strSource);
+
+#endif
+
+/* Limited dirent implementation. Used by UI.C and DEVICES.C */
+static WIN32_FIND_DATA wfd;
+
+DIR* opendir(const char* fname)
+{
+ DIR* pdir;
+ char fnameMask[MAX_PATH+1];
+ TCHAR fnameUnc[MAX_PATH+1];
+ char nameFound[MAX_PATH+1];
+
+ if(fname == NULL)
+ return NULL;
+
+ strcpy(fnameMask, fname);
+ if(!strlen(fnameMask) || fnameMask[strlen(fnameMask)-1] != '\\')
+ strncat(fnameMask, "\\", MAX_PATH-strlen(fnameMask)-1);
+ strncat(fnameMask, "*.*", MAX_PATH-strlen(fnameMask)-4);
+
+ pdir = (DIR*)malloc(sizeof(DIR)+strlen(fname));
+ pdir->dd_dir.d_ino = 0;
+ pdir->dd_dir.d_reclen = 0;
+ pdir->dd_dir.d_name = 0;
+ pdir->dd_dir.d_namlen = 0;
+
+ pdir->dd_handle = 0;
+ pdir->dd_stat = 0;
+ strcpy(pdir->dd_name, fname); /* it has exactly enough space for fname and nul char */
+
+ MultiByteToWideChar(CP_ACP, 0, fnameMask, -1, fnameUnc, MAX_PATH);
+ if((pdir->dd_handle = (long)FindFirstFile(fnameUnc, &wfd)) == (long)INVALID_HANDLE_VALUE)
+ {
+ free(pdir);
+ return NULL;
+ }
+ else
+ {
+ WideCharToMultiByte(CP_ACP, 0, wfd.cFileName, -1, nameFound, MAX_PATH, NULL, NULL);
+
+ pdir->dd_dir.d_name = strdup(nameFound);
+ pdir->dd_dir.d_namlen = strlen(nameFound);
+ }
+ return pdir;
+}
+
+struct dirent* readdir(DIR* dir)
+{
+ char nameFound[MAX_PATH+1];
+ static struct dirent dummy;
+
+ if(dir->dd_stat == 0)
+ {
+ dummy.d_name = ".";
+ dummy.d_namlen = 1;
+ dir->dd_stat ++;
+ return &dummy;
+ }
+ else if(dir->dd_stat == 1)
+ {
+ dummy.d_name = "..";
+ dummy.d_namlen = 2;
+ dir->dd_stat ++;
+ return &dummy;
+ }
+ else if(dir->dd_stat == 2)
+ {
+ dir->dd_stat++;
+ return &dir->dd_dir;
+ }
+ else
+ {
+ if(FindNextFile((HANDLE)dir->dd_handle, &wfd) == 0)
+ {
+ dir->dd_stat = -1;
+ return NULL;
+ }
+ WideCharToMultiByte(CP_ACP, 0, wfd.cFileName, -1, nameFound, MAX_PATH, NULL, NULL);
+
+ if(dir->dd_dir.d_name)
+ free(dir->dd_dir.d_name);
+
+ dir->dd_dir.d_name = strdup(nameFound);
+ dir->dd_dir.d_namlen = strlen(nameFound);
+
+ dir->dd_stat ++;
+
+ return &dir->dd_dir;
+ }
+}
+
+int closedir(DIR* dir)
+{
+ if(dir == NULL)
+ return 0;
+
+ if(dir->dd_handle)
+ FindClose((HANDLE)dir->dd_handle);
+
+ if(dir->dd_dir.d_name)
+ free(dir->dd_dir.d_name);
+ free(dir);
+ return 1;
+}
+
+/* Very limited implementation of stat. Used by UI.C, MEMORY-P.C (latter is not critical) */
+int stat(const char *fname, struct stat *ss)
+{
+ TCHAR fnameUnc[MAX_PATH+1];
+ HANDLE handle;
+ int len;
+
+ if(fname == NULL || ss == NULL)
+ return -1;
+
+ /* Special case (dummy on WinCE) */
+ len = strlen(fname);
+ if(len >= 2 && fname[len-1] == '.' && fname[len-2] == '.' &&
+ (len == 2 || fname[len-3] == '\\'))
+ {
+ /* That's everything implemented so far */
+ memset(ss, 0, sizeof(struct stat));
+ ss->st_size = 1024;
+ ss->st_mode |= S_IFDIR;
+ return 0;
+ }
+
+ MultiByteToWideChar(CP_ACP, 0, fname, -1, fnameUnc, MAX_PATH);
+ handle = FindFirstFile(fnameUnc, &wfd);
+ if(handle == INVALID_HANDLE_VALUE)
+ return -1;
+ else
+ {
+ /* That's everything implemented so far */
+ memset(ss, 0, sizeof(struct stat));
+ ss->st_size = wfd.nFileSizeLow;
+ if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ ss->st_mode |= S_IFDIR;
+
+ FindClose(handle);
+ }
+ return 0;
+}
+
+/* Remove file by name */
+int remove(const char* path)
+{
+ TCHAR pathUnc[MAX_PATH+1];
+ MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);
+ return !DeleteFile(pathUnc);
+}
+
+/* in our case unlink is the same as remove */
+int unlink(const char* path)
+{
+ return remove(path);
+}
+
+/* Make directory, Unix style */
+void mkdir(char* dirname, int mode)
+{
+ char path[MAX_PATH+1];
+ TCHAR pathUnc[MAX_PATH+1];
+ char* ptr;
+ strncpy(path, dirname, MAX_PATH);
+ if(*path == '/')
+ *path = '\\';
+ /* Run through the string and attempt creating all subdirs on the path */
+ for(ptr = path+1; *ptr; ptr ++)
+ {
+ if(*ptr == '\\' || *ptr == '/')
+ {
+ *ptr = 0;
+ MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);
+ CreateDirectory(pathUnc, 0);
+ *ptr = '\\';
+ }
+ }
+ MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);
+ CreateDirectory(pathUnc, 0);
+}
+
+/* Used in DEVICES.C and UI.C for some purpose. Not critical in this port */
+int system(const char* path) { return 0; }
+
+#if 0
+
+char *tmpnam(char *string)
+{
+ TCHAR pTemp[MAX_PATH+1];
+ static char buffer[MAX_PATH+1];
+ GetTempFileName(TEXT("."), TEXT("A8_"), 0, pTemp);
+ WideCharToMultiByte(CP_ACP, 0, pTemp, -1, buffer, MAX_PATH, NULL, NULL);
+
+ if(string)
+ {
+ strcpy(string, buffer);
+ return string;
+ }
+ else
+ return buffer;
+}
+
+FILE *tmpfile()
+{
+ TCHAR pTemp[MAX_PATH+1];
+ if(!GetTempFileName(TEXT("."), TEXT("A8_"), 0, pTemp))
+ return _wfopen(pTemp, TEXT("w+b"));
+ else
+ return 0;
+}
+
+#endif
+
+void rewind(FILE *stream)
+{
+ fseek(stream, 0, SEEK_SET);
+}
+
+
+#if _WIN32_WCE < 300
+
+int isalnum(int c) {
+ return ((c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z') ||
+ (c >= '0' && c <= '9'));
+}
+
+char *_strdup(const char *strSource)
+#else
+char *strdup(const char *strSource)
+#endif
+{
+ char* buffer;
+ buffer = (char*)malloc(strlen(strSource)+1);
+ if(buffer)
+ strcpy(buffer, strSource);
+ return buffer;
+}
+
+/* Used in UI.C */
+char cwd[MAX_PATH+1] = "";
+char *getcwd(char *buffer, int maxlen)
+{
+ TCHAR fileUnc[MAX_PATH+1];
+ char* plast;
+
+ if(cwd[0] == 0)
+ {
+ GetModuleFileName(NULL, fileUnc, MAX_PATH);
+ WideCharToMultiByte(CP_ACP, 0, fileUnc, -1, cwd, MAX_PATH, NULL, NULL);
+ plast = strrchr(cwd, '\\');
+ if(plast)
+ *plast = 0;
+ /* Special trick to keep start menu clean... */
+ if(_stricmp(cwd, "\\windows\\start menu") == 0)
+ strcpy(cwd, "\\Apps");
+ }
+ if(buffer)
+ strncpy(buffer, cwd, maxlen);
+ return cwd;
+}
+
+void GetCurrentDirectory(int len, char *buf)
+{
+ getcwd(buf,len);
+};
+
+/* Limited implementation of time.h. time_t formula is possibly incorrect. */
+time_t time(time_t* res)
+{
+ time_t t;
+ SYSTEMTIME st;
+ GetLocalTime(&st);
+
+ t = (time_t)(((((((st.wYear-1970)*12+st.wMonth)*31+st.wDay)*7+st.wDayOfWeek)*24+st.wHour)*60+st.wMinute)*60+st.wSecond);
+
+ if(res)
+ *res = t;
+ return t;
+}
+
+struct tm* localtime(time_t* timer)
+{
+ static struct tm tmLocalTime;
+ unsigned long rem = *timer;
+
+ tmLocalTime.tm_sec = (short)(rem % 60);
+ rem /= 60;
+ tmLocalTime.tm_min = (short)(rem % 60);
+ rem /= 60;
+ tmLocalTime.tm_hour = (short)(rem % 24);
+ rem /= 24;
+ tmLocalTime.tm_mday = (short)(rem % 7);
+ rem /= 7;
+ tmLocalTime.tm_mday = (short)(rem % 31);
+ rem /= 31;
+ tmLocalTime.tm_mon = (short)(rem % 12);
+ rem /= 12;
+ tmLocalTime.tm_year = (short)(rem+1970);
+
+ return &tmLocalTime;
+}
+
+/* Very limited implementation of sys/time.h */
+void gettimeofday(struct timeval* tp, void* dummy)
+{
+ DWORD dt = GetTickCount();
+ tp->tv_sec = dt/1000;
+ tp->tv_usec = dt*1000;
+}
+
+void usleep(long usec)
+{
+ long msec = usec/1000;
+ if(msec <= 0)
+ Sleep(0);
+ else
+ Sleep(msec);
+}
+
+/*
+Windows CE fopen has non-standard behavior -- not
+fully qualified paths refer to root folder rather
+than current folder (concept not implemented in CE).
+*/
+#undef fopen
+
+FILE* wce_fopen(const char* fname, const char* fmode)
+{
+ char fullname[MAX_PATH+1];
+
+ if(!fname || fname[0] == '\0')
+ return NULL;
+ if(fname[0] != '\\' && fname[0] != '/')
+ {
+ getcwd(fullname, MAX_PATH);
+ strncat(fullname, "\\", MAX_PATH-strlen(fullname)-1);
+ strncat(fullname, fname, MAX_PATH-strlen(fullname)-strlen(fname));
+ return fopen(fullname, fmode);
+ }
+ else
+ return fopen(fname, fmode);
+}
+
+/* This may provide for better sync mechanism */
+unsigned int clock()
+{
+ return GetTickCount();
+}
+
+/* And why do people use this? */
+#if _WIN32_WCE >= 300
+void abort()
+{
+ exit(1);
+}
+#endif
+
+/*
+IMHO, no project should use this one, it is not portable at all. This implementation
+at least allows some projects to work.
+*/
+char* getenv(char* name)
+{
+ static char buffer[MAX_PATH+1];
+ if(strcmp(name, "HOME") == 0 || strcmp(name, "HOMEDIR") == 0)
+ {
+ getcwd(buffer, MAX_PATH);
+ return buffer;
+ }
+ else
+ return "";
+}
+
+void *bsearch(const void *key, const void *base, size_t nmemb,
+ size_t size, int (*compar)(const void *, const void *)) {
+ size_t i;
+
+ for (i=0; i<nmemb; i++)
+ if (compar(key, (void*)((size_t)base + size * i)) == 0)
+ return (void*)((size_t)base + size * i);
+ return NULL;
+}
+
+#if _WIN32_WCE < 300 || defined(_TEST_HPC_STDIO)
+
+void *calloc(size_t n, size_t s) {
+ void *result = malloc(n * s);
+ if (result)
+ memset(result, 0, n * s);
+
+ return result;
+}
+
+char *strpbrk(const char *s, const char *accept) {
+ int i;
+
+ if (!s || !accept)
+ return NULL;
+
+ for (i=0; i<strlen(s); i++) {
+ int j;
+ for (j=0; j<strlen(accept); j++)
+ if (s[i] == accept[j])
+ return (char*)&s[i];
+ }
+
+ return NULL;
+}
+
+#ifndef _TEST_HPC_STDIO
+
+int isdigit(int c) {
+ return (c >='0' && c <= '9');
+}
+
+int isprint(int c) {
+ return (c >= ' ' && c <= '~');
+}
+
+int isspace(int c) {
+ return (c == ' ');
+}
+
+#endif
+
+#ifndef WIN32_PLATFORM_HPCPRO
+
+
+int printf(const char *format, ...) {
+ // useless anyway :)
+ return 0;
+}
+
+FILE *fopen(const char *path, const char *mode) {
+ TCHAR tempo[MAX_PATH];
+ HANDLE result;
+ bool writeAccess = (mode[0] == 'W' || mode[0] == 'w');
+
+ MultiByteToWideChar(CP_ACP, 0, path, strlen(path) + 1, tempo, sizeof(tempo));
+
+ result = CreateFile(tempo, ( writeAccess ? GENERIC_WRITE : GENERIC_READ), 0, NULL, (writeAccess ? CREATE_ALWAYS : OPEN_EXISTING), FILE_ATTRIBUTE_NORMAL, NULL);
+ if (result == INVALID_HANDLE_VALUE)
+ return NULL;
+ else
+ return (FILE*)result;
+}
+
+FILE * _wfopen(const TCHAR *path, const TCHAR *mode) {
+ HANDLE result;
+ bool writeAccess = (mode[0] == 'W' || mode[0] == 'w');
+ result = CreateFile(path, ( writeAccess ? GENERIC_WRITE : GENERIC_READ), 0, NULL, (writeAccess ? CREATE_ALWAYS : OPEN_EXISTING), FILE_ATTRIBUTE_NORMAL, NULL);
+ if (result == INVALID_HANDLE_VALUE)
+ return NULL;
+ else
+ return (FILE*)result;
+}
+
+FILE *_wfreopen(const TCHAR *path, const TCHAR *mode, FILE *stream) {
+ fclose(stream);
+ stream = _wfopen(path, mode);
+ return stream;
+}
+
+int fclose(FILE *stream) {
+ CloseHandle((HANDLE)stream);
+ return 1;
+}
+
+int fseek(FILE *stream, long offset, int whence) {
+ SetFilePointer((HANDLE)stream, offset, NULL, (whence == SEEK_CUR ? FILE_CURRENT : whence == SEEK_END ? FILE_END : FILE_BEGIN));
+ return 0;
+}
+
+long ftell(FILE *stream) {
+ return (SetFilePointer((HANDLE)stream, 0, NULL, FILE_CURRENT));
+}
+
+size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
+ DWORD sizeWritten;
+
+ WriteFile((HANDLE)stream, ptr, size * nmemb, &sizeWritten, NULL);
+
+ if (size != 0)
+ return sizeWritten / size;
+ else
+ return 0;
+}
+
+size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) {
+ DWORD sizeRead;
+
+ ReadFile((HANDLE)stream, ptr, size * nmemb, &sizeRead, NULL);
+
+ if (size != 0)
+ return sizeRead / size;
+ else
+ return 0;
+}
+
+int fgetc(FILE *stream) {
+ unsigned char c;
+ if (fread(&c, 1, 1, stream) != 1)
+ return -1;
+ else
+ return c;
+}
+
+char *fgets(char *s, int size, FILE *stream) {
+ int i = 0;
+ char tempo[1];
+
+ memset(s, 0, size);
+ while (fread(tempo, 1, 1, stream)) {
+ //if (tempo[0] == '\r')
+ // break;
+ if (tempo[0] == '\r')
+ continue;
+ s[i++] = tempo[0];
+ if (tempo[0] == '\n')
+ break;
+ if (i == size)
+ break;
+ }
+ if (!i)
+ return NULL;
+ else
+ return s;
+}
+
+int feof(FILE *stream) {
+ DWORD fileSize;
+ DWORD filePos;
+ fileSize = GetFileSize((HANDLE)stream, NULL);
+ filePos = SetFilePointer((HANDLE)stream, 0, 0, FILE_CURRENT);
+ return (filePos == 0xFFFFFFFF || filePos > (fileSize - 1));
+}
+
+int ferror(FILE *stream) {
+ return 0; // FIXME !
+}
+
+int fprintf(FILE *stream, const char *format, ...) {
+ char buf[1024];
+ va_list va;
+
+ va_start(va, format);
+ vsnprintf(buf, 1024, format, va);
+ va_end(va);
+
+ if (buf[strlen(buf) - 1] == '\n') {
+ int i = strlen(buf) - 1;
+ buf[i] = '\r';
+ buf[i + 1] = '\n';
+ buf[i + 2] = 0;
+ }
+
+ return fwrite(buf, 1, strlen(buf), stream);
+}
+
+FILE* _getstdfilex(int) {
+ return NULL;
+}
+
+void clearerr(FILE *stream) {
+}
+
+int fflush(FILE *stream) {
+ return 0;
+}
+
+#endif
+
+int stricmp( const char *string1, const char *string2 ) {
+ char src[4096];
+ char dest[4096];
+ int i;
+
+ for (i=0; i<strlen(string1); i++)
+ if (string1[i] >= 'A' && string1[i] <= 'Z')
+ src[i] = string1[i] + 32;
+ else
+ src[i] = string1[i];
+ src[i] = 0;
+
+ for (i=0; i<strlen(string2); i++)
+ if (string2[i] >= 'A' && string2[i] <= 'Z')
+ dest[i] = string2[i] + 32;
+ else
+ dest[i] = string2[i];
+ dest[i] = 0;
+
+ return strcmp(src, dest);
+}
+
+char *strrchr(const char *s, int c) {
+ int i;
+
+ for (i = strlen(s) - 1; i > 0; i--)
+ if (s[i] == c)
+ return (char*)(s + i);
+
+ return NULL;
+}
+
+long int strtol(const char *nptr, char **endptr, int base) {
+ // not correct but that's all we are using
+
+ long int result;
+ sscanf(nptr, "%ld", &result);
+ return result;
+}
+
+
+#endif
+
+
diff --git a/backends/platform/wince/missing/signal.h b/backends/platform/wince/missing/signal.h
new file mode 100644
index 0000000000..128d6bf1db
--- /dev/null
+++ b/backends/platform/wince/missing/signal.h
@@ -0,0 +1,3 @@
+/* Header is not present in Windows CE SDK */
+/* Functionality is not critical -- Pocket PC devices do not have Ctrl+C */
+#define signal(a,b)
diff --git a/backends/platform/wince/missing/sys/stat.h b/backends/platform/wince/missing/sys/stat.h
new file mode 100644
index 0000000000..d9eef1318d
--- /dev/null
+++ b/backends/platform/wince/missing/sys/stat.h
@@ -0,0 +1,23 @@
+/* Header is not present in Windows CE SDK */
+
+#include <sys/types.h>
+
+struct stat {
+ _dev_t st_dev;
+ _ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ _dev_t st_rdev;
+ _off_t st_size;
+ time_t st_atime;
+ time_t st_mtime;
+ time_t st_ctime;
+};
+
+
+#define _S_IFDIR 0040000 /* directory */
+#define S_IFDIR _S_IFDIR
+
+int stat(const char *, struct stat *);
diff --git a/backends/platform/wince/missing/sys/time.h b/backends/platform/wince/missing/sys/time.h
new file mode 100644
index 0000000000..ded29bb009
--- /dev/null
+++ b/backends/platform/wince/missing/sys/time.h
@@ -0,0 +1,10 @@
+/* Header is not present in Windows CE SDK */
+
+struct timeval
+{
+ int tv_sec;
+ int tv_usec;
+};
+
+void gettimeofday(struct timeval* tp, void* dummy);
+void usleep(long usec);
diff --git a/backends/platform/wince/missing/sys/types.h b/backends/platform/wince/missing/sys/types.h
new file mode 100644
index 0000000000..b6c05e3958
--- /dev/null
+++ b/backends/platform/wince/missing/sys/types.h
@@ -0,0 +1,5 @@
+/* Header is not present in Windows CE SDK */
+
+typedef unsigned short _ino_t;
+typedef unsigned int _dev_t;
+typedef long _off_t;
diff --git a/backends/platform/wince/missing/time.h b/backends/platform/wince/missing/time.h
new file mode 100644
index 0000000000..40c2894dca
--- /dev/null
+++ b/backends/platform/wince/missing/time.h
@@ -0,0 +1,24 @@
+/* Header is not present in Windows CE SDK */
+
+#ifndef A800_TIME_H
+#define A800_TIME_H
+
+#include <stdlib.h>
+
+struct tm
+{
+ short tm_year;
+ short tm_mon;
+ short tm_mday;
+ short tm_wday;
+ short tm_hour;
+ short tm_min;
+ short tm_sec;
+};
+
+time_t time(time_t* dummy);
+struct tm* localtime(time_t* dummy);
+
+unsigned int clock();
+
+#endif
diff --git a/backends/platform/wince/missing/unistd.h b/backends/platform/wince/missing/unistd.h
new file mode 100644
index 0000000000..7ee9f5e5ba
--- /dev/null
+++ b/backends/platform/wince/missing/unistd.h
@@ -0,0 +1 @@
+/* Header is not present in Windows CE SDK */
diff --git a/backends/platform/wince/newres.h b/backends/platform/wince/newres.h
new file mode 100644
index 0000000000..092f99d77d
--- /dev/null
+++ b/backends/platform/wince/newres.h
@@ -0,0 +1,55 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+// PARTICULAR PURPOSE.
+//
+// This is "Sample Code" and is distributable subject to the terms of the
+// end user license agreement.
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef __NEWRES_H__
+#define __NEWRES_H__
+
+#include "windows.h"
+
+#if !defined(UNDER_CE)
+#define UNDER_CE _WIN32_WCE
+#endif
+
+#if defined(_WIN32_WCE)
+ #if !defined(WCEOLE_ENABLE_DIALOGEX)
+ #define DIALOGEX DIALOG DISCARDABLE
+ #endif
+ #include <commctrl.h>
+ #define SHMENUBAR RCDATA
+ #if defined(WIN32_PLATFORM_WFSP) && (_WIN32_WCE >= 300)
+ #include <aygshell.h>
+ #define AFXCE_IDR_SCRATCH_SHMENU 28700
+ #else
+ #define I_IMAGENONE (-2)
+ #define NOMENU 0xFFFF
+ #define IDS_SHNEW 1
+
+ #define IDM_SHAREDNEW 10
+ #define IDM_SHAREDNEWDEFAULT 11
+ #endif // _WIN32_WCE_PSPC
+ #define AFXCE_IDD_SAVEMODIFIEDDLG 28701
+#endif // _WIN32_WCE
+
+#ifdef RC_INVOKED
+#ifndef _INC_WINDOWS
+#define _INC_WINDOWS
+ #include "winuser.h" // extract from windows header
+#if _WIN32_WCE >= 300
+ #include "winver.h"
+#endif
+#endif
+#endif
+
+#ifdef IDC_STATIC
+#undef IDC_STATIC
+#endif
+#define IDC_STATIC (-1)
+
+#endif //__NEWRES_H__
diff --git a/backends/platform/wince/ozone.h b/backends/platform/wince/ozone.h
new file mode 100644
index 0000000000..45de0bbb97
--- /dev/null
+++ b/backends/platform/wince/ozone.h
@@ -0,0 +1,40 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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$
+ *
+ */
+
+#define GETRAWFRAMEBUFFER 0x00020001
+
+#define FORMAT_565 1
+#define FORMAT_555 2
+#define FORMAT_OTHER 3
+
+#if defined(_WIN32_WCE) && _WIN32_WCE <= 300
+typedef struct _RawFrameBufferInfo
+{
+ WORD wFormat;
+ WORD wBPP;
+ VOID *pFramePointer;
+ int cxStride;
+ int cyStride;
+ int cxPixels;
+ int cyPixels;
+} RawFrameBufferInfo;
+#endif
diff --git a/backends/platform/wince/portdefs.h b/backends/platform/wince/portdefs.h
new file mode 100644
index 0000000000..c82e3159f4
--- /dev/null
+++ b/backends/platform/wince/portdefs.h
@@ -0,0 +1,73 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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$
+ *
+ */
+
+// Missing string/stdlib/assert declarations for WinCE 2.xx
+
+#if _WIN32_WCE < 300
+
+#define _HEAPOK 0
+
+void *calloc(size_t n, size_t s);
+int isalnum(int c);
+int isdigit(int c);
+int isprint(int c);
+int isspace(int c);
+char *strrchr(const char *s, int c);
+char *strdup(const char *s);
+int _stricmp( const char *string1, const char *string2 );
+int stricmp( const char *string1, const char *string2 );
+void assert( void* expression );
+void assert( int expression );
+long int strtol(const char *nptr, char **endptr, int base);
+char *_strdup(const char *s);
+char *strpbrk(const char *s, const char *accept);
+
+#endif
+
+#ifdef _WIN32_WCE
+
+void *bsearch(const void *, const void *, size_t, size_t, int (*x) (const void *, const void *));
+char *getcwd(char *buf, int size);
+void GetCurrentDirectory(int len, char *buf);
+#define INVALID_FILE_ATTRIBUTES 0xbadc0de
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <io.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <conio.h>
+#include <malloc.h>
+#include <assert.h>
+#include <mmsystem.h>
+#include <ctype.h>
+#include <Winuser.h>
+#include <direct.h>
+#include <time.h>
+
+void drawError(char*);
+
+#define vsnprintf _vsnprintf
+typedef int ptrdiff_t;
+
+#endif
diff --git a/backends/platform/wince/resource.h b/backends/platform/wince/resource.h
new file mode 100644
index 0000000000..94eb3c12f0
--- /dev/null
+++ b/backends/platform/wince/resource.h
@@ -0,0 +1,39 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft eMbedded Visual C++ generated include file.
+// Used by PocketSCUMM.rc
+//
+#define IDI_POCKETSCUMM 101
+#define IDR_SMARTFON_MENUBAR_GAMES 102
+#define IDR_SMARTFON_MENUBAR_OPTIONS 103
+#define IDB_LOGO 106
+#define IMAGE_PANEL 109
+#define PANEL_GENERIC 109
+#define IMAGE_KEYBOARD 110
+#define PANEL_KEYBOARD 110
+#define ITEM_SKIP 114
+#define ITEM_OPTIONS 115
+#define ITEM_SOUND_ON 118
+#define ITEM_SOUND_OFF 119
+#define ITEM_VIEW_PORTRAIT 120
+#define ITEM_VIEW_LANDSCAPE 122
+#define ITEM_BINDKEYS 125
+#define IDS_CAP_MENUITEM40002 40003
+#define ID_MENU_GAMES 40006
+#define IDM_SMARTFON_SCAN 40007
+#define IDM_SMARTFON_QUIT 40009
+#define IDS_CAP_OPTIONS 40015
+#define ID_MENU_OPTIONS 40016
+#define IDM_SMARTFON_MUSIC 40017
+#define IDM_SMARTFON_SOUND 40017
+#define IDM_SMARTFON_HELP 40021
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 126
+#define _APS_NEXT_COMMAND_VALUE 40022
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp
new file mode 100644
index 0000000000..b1ad143679
--- /dev/null
+++ b/backends/platform/wince/wince-sdl.cpp
@@ -0,0 +1,2272 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "wince-sdl.h"
+
+#include "common/util.h"
+#include "base/engine.h"
+#include "base/main.h"
+#include "base/plugins.h"
+#include "common/timer.h"
+
+#include "common/config-manager.h"
+
+#include "scumm/scumm.h"
+
+#include "resource.h"
+
+#include "gui/Actions.h"
+#include "CEActionsPocket.h"
+#include "CEActionsSmartphone.h"
+#include "ItemAction.h"
+#include "gui/KeysDialog.h"
+
+#include "gui/message.h"
+
+#include "sound/fmopl.h"
+
+#include "ozone.h"
+#include "CEException.h"
+
+#ifdef USE_VORBIS
+#ifndef USE_TREMOR
+#include <vorbis/vorbisfile.h>
+#else
+#include <tremor/ivorbisfile.h>
+#endif
+#endif
+
+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"
+
+// Given to the true main, needed for backend adaptation
+
+static FILE *stdout_file;
+static FILE *stderr_file;
+
+// Static member inits
+
+bool OSystem_WINCE3::_soundMaster = true;
+OSystem::SoundProc OSystem_WINCE3::_originalSoundProc = NULL;
+
+bool _isSmartphone = false;
+bool _hasSmartphoneResolution = false;
+
+// Graphics mode consts
+
+// Low end devices 240x320
+
+static const OSystem::GraphicsMode s_supportedGraphicsModesLow[] = {
+ {"1x", "Normal (no scaling)", GFX_NORMAL},
+ {0, 0, 0}
+};
+
+// High end device 480x640
+
+static const OSystem::GraphicsMode s_supportedGraphicsModesHigh[] = {
+ {"1x", "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}
+};
+
+
+// ********************************************************************************************
+
+bool isSmartphone() {
+ //return _isSmartphone;
+ return _hasSmartphoneResolution;
+}
+
+// ********************************************************************************************
+
+// MAIN
+
+int handleException(EXCEPTION_POINTERS *exceptionPointers) {
+ CEException::writeException(TEXT("\\scummvmCrash"), exceptionPointers);
+ drawError("Unrecoverable exception occurred - see crash dump in latest \\scummvmCrash file");
+ fclose(stdout_file);
+ fclose(stderr_file);
+ CEDevice::end();
+ SDL_Quit();
+ exit(0);
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+OSystem *OSystem_WINCE3_create() {
+ return new OSystem_WINCE3();
+}
+
+int SDL_main(int argc, char **argv) {
+ CEDevice::init();
+ OSystem_WINCE3::initScreenInfos();
+ /* Sanity check */
+//#ifndef WIN32_PLATFORM_WFSP
+// if (CEDevice::hasSmartphoneResolution()) {
+// MessageBox(NULL, TEXT("This build was not compiled with Smartphone support"), TEXT("ScummVM error"), MB_OK | MB_ICONERROR);
+// return 0;
+// }
+//#endif
+ /* Avoid print problems - this file will be put in RAM anyway */
+ stdout_file = fopen("\\scummvm_stdout.txt", "w");
+ stderr_file = fopen("\\scummvm_stderr.txt", "w");
+
+ int res = 0;
+
+#ifndef DEBUG
+ __try {
+#endif
+ g_system = OSystem_WINCE3_create();
+ assert(g_system);
+
+ // Invoke the actual ScummVM main entry point:
+ res = scummvm_main(argc, argv);
+ g_system->quit(); // TODO: Consider removing / replacing this!
+#ifndef DEBUG
+ }
+ __except (handleException(GetExceptionInformation())) {
+ }
+#endif
+
+ return res;
+}
+
+// ********************************************************************************************
+
+
+// ********************************************************************************************
+
+void pumpMessages() {
+ MSG msg;
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+}
+
+void drawError(char *error) {
+ TCHAR errorUnicode[200];
+ MultiByteToWideChar(CP_ACP, 0, error, strlen(error) + 1, errorUnicode, sizeof(errorUnicode));
+ pumpMessages();
+ MessageBox(GetActiveWindow(), errorUnicode, TEXT("ScummVM error"), MB_OK | MB_ICONERROR);
+ pumpMessages();
+}
+
+// ********************************************************************************************
+
+void OSystem_WINCE3::initBackend()
+{
+ // Initialize global key mapping
+ GUI::Actions::init();
+ GUI_Actions::Instance()->initInstanceMain(this);
+ GUI_Actions::Instance()->loadMapping();
+
+ loadDeviceConfiguration();
+}
+
+int OSystem_WINCE3::getScreenWidth() {
+ return _platformScreenWidth;
+}
+
+int OSystem_WINCE3::getScreenHeight() {
+ return _platformScreenHeight;
+}
+
+void OSystem_WINCE3::initScreenInfos() {
+ /*
+ // Check if we're running Ozone
+ int result;
+ RawFrameBufferInfo frameBufferInfo;
+ HDC hdc = GetDC(NULL);
+ result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *)&frameBufferInfo);
+ ReleaseDC(NULL, hdc);
+ _isOzone = (result > 0);
+ // And obtain the real screen size
+ _platformScreenWidth = (result > 0 ? frameBufferInfo.cxPixels : GetSystemMetrics(SM_CXSCREEN));
+ _platformScreenHeight = (result > 0 ? frameBufferInfo.cyPixels : GetSystemMetrics(SM_CYSCREEN));
+ */
+
+ // sdl port ensures that we use correctly full screen
+ _isOzone = 0;
+ _platformScreenWidth = GetSystemMetrics(SM_CXSCREEN);
+ _platformScreenHeight = GetSystemMetrics(SM_CYSCREEN);
+}
+
+bool OSystem_WINCE3::isOzone() {
+ return _isOzone;
+}
+
+// ********************************************************************************************
+
+
+OSystem_WINCE3::OSystem_WINCE3() : OSystem_SDL(),
+ _orientationLandscape(0), _newOrientation(0), _panelInitialized(false),
+ _panelVisible(true), _panelStateForced(false), _forceHideMouse(false),
+ _freeLook(false), _forcePanelInvisible(false), _toolbarHighDrawn(false), _zoomUp(false), _zoomDown(false),
+ _scalersChanged(false), _monkeyKeyboard(false), _lastKeyPressed(0), _tapTime(0),
+ _saveToolbarState(false), _saveActiveToolbar(NAME_MAIN_PANEL), _rbutton(false),
+ _usesEmulatedMouse(false)
+{
+ _isSmartphone = CEDevice::isSmartphone();
+ _hasSmartphoneResolution = CEDevice::hasSmartphoneResolution() || CEDevice::isSmartphone();
+ memset(&_mouseCurState, 0, sizeof(_mouseCurState));
+ if (_isSmartphone) {
+ _mouseCurState.x = 20;
+ _mouseCurState.y = 20;
+ }
+ if (_hasSmartphoneResolution) _panelVisible = false; // init correctly in smartphones
+ create_toolbar();
+
+
+ // Mouse backup (temporary code)
+ _mouseBackupOld = (byte*)malloc(MAX_MOUSE_W * MAX_MOUSE_H * MAX_SCALING * 2);
+ _mouseBackupToolbar = (uint16*)malloc(MAX_MOUSE_W * MAX_MOUSE_H * MAX_SCALING * 2);
+}
+
+void OSystem_WINCE3::swap_panel_visibility() {
+ //if (!_forcePanelInvisible && !_panelStateForced) {
+ 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);
+
+ if (_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 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 (_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);
+ 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();
+}
+
+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 = PocketPCHalf;
+ _zoomUp = false;
+ }
+ else
+ {
+ // only active if running on a PocketPC
+ if (_scalerProc != PocketPCHalf && _scalerProc != PocketPCHalfZoom)
+ return;
+ if (_scalerProc == PocketPCHalf) {
+ _saveToolbarZoom = _toolbarHandler.visible();
+ _toolbarHandler.setVisible(false);
+ // set zoom scaler
+ _scaleFactorYd = 1;
+ _scalerProc = PocketPCHalfZoom;
+ }
+ else
+ _zoomDown = false;
+
+ _zoomUp = true;
+ }
+ // redraw whole screen
+ addDirtyRect(0, 0, 640, 480);
+ internUpdateScreen();
+}
+
+void OSystem_WINCE3::swap_zoom_down() {
+ if (_zoomDown) {
+ // restore visibility
+ _toolbarHandler.setVisible(_saveToolbarZoom);
+ // restore scaler
+ _scaleFactorYd = 2;
+ _scalerProc = PocketPCHalf;
+ _zoomDown = false;
+ }
+ else
+ {
+ // only active if running on a PocketPC
+ if (_scalerProc != PocketPCHalf && _scalerProc != PocketPCHalfZoom)
+ return;
+ if (_scalerProc == PocketPCHalf) {
+ _saveToolbarZoom = _toolbarHandler.visible();
+ _toolbarHandler.setVisible(false);
+ // set zoom scaler
+ _scaleFactorYd = 1;
+ _scalerProc = PocketPCHalfZoom;
+ }
+ else
+ _zoomUp = false;
+
+ _zoomDown = true;
+ }
+ // redraw whole screen
+ addDirtyRect(0, 0, 640, 480);
+ internUpdateScreen();
+}
+
+//#ifdef WIN32_PLATFORM_WFSP
+// 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 > 240)
+ y = 240;
+
+ 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 > 320)
+ x = 320;
+
+ 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++;
+ if (_currentZone >= TOTAL_ZONES)
+ _currentZone = 0;
+
+ EventsBuffer::simulateMouseMove(_mouseXZone[_currentZone], _mouseYZone[_currentZone]);
+}
+//#endif
+
+
+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::private_sound_proc(void *param, byte *buf, int len) {
+ (*_originalSoundProc)(param, 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;
+
+ 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
+
+void OSystem_WINCE3::get_sample_rate() {
+ // 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" ||
+ strncmp(gameid.c_str(), "sword", 5) == 0 || strncmp(gameid.c_str(), "sky", 3) == 0)
+ _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
+}
+
+int OSystem_WINCE3::getOutputSampleRate() const {
+ return _sampleRate;
+}
+
+void OSystem_WINCE3::setWindowCaption(const char *caption) {
+ check_mappings(); // called here to initialize virtual keys handling
+ //update_game_settings();
+ get_sample_rate(); // called here to initialize mixer
+}
+
+bool OSystem_WINCE3::openCD(int drive) {
+ return false;
+}
+
+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 == kFeatureAutoComputeDirtyRects || 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;
+ default:
+ OSystem_SDL::setFeatureState(f, enable);
+ }
+}
+
+bool OSystem_WINCE3::getFeatureState(Feature f) {
+ switch(f) {
+ case kFeatureFullscreenMode:
+ return false;
+ case kFeatureVirtualKeyboard:
+ return (_panelStateForced);
+ }
+ return OSystem_SDL::getFeatureState(f);
+}
+
+bool OSystem_WINCE3::setSoundCallback(SoundProc proc, void *param) {
+ SDL_AudioSpec desired;
+ int thread_priority;
+
+ memset(&desired, 0, sizeof(desired));
+
+ _originalSoundProc = proc;
+ desired.freq = _sampleRate;
+ desired.format = AUDIO_S16SYS;
+ desired.channels = 2;
+ //desired.samples = 2048;
+ desired.samples = 128;
+ desired.callback = private_sound_proc;
+ desired.userdata = param;
+
+ // Add sound thread priority
+ if (!ConfMan.hasKey("sound_thread_priority")) {
+#ifdef SH3
+ thread_priority = THREAD_PRIORITY_NORMAL;
+#else
+ thread_priority = THREAD_PRIORITY_ABOVE_NORMAL;
+#endif
+ }
+ else
+ thread_priority = ConfMan.getInt("sound_thread_priority");
+
+ desired.thread_priority = thread_priority;
+
+ if (SDL_OpenAudio(&desired, NULL) != 0) {
+ return false;
+ }
+ SDL_PauseAudio(0);
+ return true;
+}
+
+void OSystem_WINCE3::check_mappings() {
+ CEActionsPocket *instance;
+
+ Common::String gameid(ConfMan.get("gameid"));
+
+ if (gameid.empty() || GUI_Actions::Instance()->initialized())
+ return;
+
+ GUI_Actions::Instance()->initInstanceGame();
+ instance = (CEActionsPocket*)GUI_Actions::Instance();
+
+ // Some games need to map the right click button, signal it here if it wasn't done
+ if (instance->needsRightClickMapping()) {
+ GUI::KeysDialog *keysDialog = new GUI::KeysDialog("Map right click action");
+ while (!instance->getMapping(POCKET_ACTION_RIGHTCLICK)) {
+ keysDialog->runModal();
+ if (!instance->getMapping(POCKET_ACTION_RIGHTCLICK)) {
+ GUI::MessageDialog alert("You must map a key to the 'Right Click' action to play this game");
+ alert.runModal();
+ }
+ }
+ delete keysDialog;
+ }
+
+ // Map the "hide toolbar" action if needed
+ if (instance->needsHideToolbarMapping()) {
+ GUI::KeysDialog *keysDialog = new GUI::KeysDialog("Map hide toolbar action");
+ while (!instance->getMapping(POCKET_ACTION_HIDE)) {
+ keysDialog->runModal();
+ if (!instance->getMapping(POCKET_ACTION_HIDE)) {
+ GUI::MessageDialog alert("You must map a key to the 'Hide toolbar' action to play this game");
+ alert.runModal();
+ }
+ }
+ delete keysDialog;
+ }
+
+ // Map the "zoom" actions if needed
+ if (instance->needsZoomMapping()) {
+ GUI::KeysDialog *keysDialog = new GUI::KeysDialog("Map Zoom Up action (optional)");
+ keysDialog->runModal();
+ delete keysDialog;
+ keysDialog = new GUI::KeysDialog("Map Zoom Down action (optional)");
+ keysDialog->runModal();
+ delete keysDialog;
+ }
+
+ // Extra warning for Zak Mc Kracken
+ if (strncmp(gameid.c_str(), "zak", 3) == 0 &&
+ !GUI_Actions::Instance()->getMapping(POCKET_ACTION_HIDE)) {
+ GUI::MessageDialog alert("Don't forget to map a key to 'Hide Toolbar' action to see the whole inventory");
+ alert.runModal();
+ }
+
+}
+
+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 (_screenWidth <= 320 && (isOzone() || !CEDevice::hasDesktopResolution())) {
+ if (ConfMan.hasKey("landscape"))
+ if (ConfMan.get("landscape")[0] > 57) {
+ _newOrientation = _orientationLandscape = ConfMan.getBool("landscape");
+ //ConfMan.removeKey("landscape", String::emptyString);
+ 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);
+
+ // Keyboard is active for Monkey 1 or 2 initial copy-protection
+ if (strncmp(gameid.c_str(), "monkey", 6) == 0) {
+ _monkeyKeyboard = true;
+ _toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
+ }
+
+ if (_mode == GFX_NORMAL && ConfMan.hasKey("landscape") && ConfMan.getInt("landscape")) {
+ setGraphicsMode(GFX_NORMAL);
+ hotswapGFXMode();
+ }
+
+ if (_hasSmartphoneResolution)
+ panel->setVisible(false);
+
+ _saveToolbarState = true;
+
+ // Set Smush Force Redraw rate for Full Throttle
+ if (!ConfMan.hasKey("Smush_force_redraw")) {
+ ConfMan.setInt("Smush_force_redraw", 30);
+ ConfMan.flushToDisk();
+ }
+ }
+
+ get_sample_rate();
+}
+
+void OSystem_WINCE3::initSize(uint w, uint h) {
+
+ if (_hasSmartphoneResolution && h == 240)
+ h = 200; // mainly for the launcher
+
+ if (_isSmartphone && !ConfMan.hasKey("landscape"))
+ {
+ ConfMan.setInt("landscape", 1);
+ ConfMan.flushToDisk();
+ }
+
+ switch (_transactionMode) {
+ case kTransactionActive:
+ _transactionDetails.w = w;
+ _transactionDetails.h = h;
+ _transactionDetails.sizeChanged = true;
+ _transactionDetails.needUnload = true;
+ return;
+ case kTransactionCommit:
+ break;
+ default:
+ break;
+ }
+
+ if (w == 320 && h == 200 && !_hasSmartphoneResolution)
+ h = 240; // use the extra 40 pixels height for the toolbar
+
+ 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) _screenWidth || h != (uint) _screenHeight)
+ _scalersChanged = false;
+
+ _overlayWidth = w;
+ _overlayHeight = h;
+
+ OSystem_SDL::initSize(w, h);
+
+ if (_scalersChanged) {
+ unloadGFXMode();
+ loadGFXMode();
+ _scalersChanged = false;
+ }
+
+ update_game_settings();
+}
+
+
+int OSystem_WINCE3::getDefaultGraphicsMode() const {
+ return GFX_NORMAL;
+}
+
+bool OSystem_WINCE3::update_scalers() {
+
+ if (_mode != GFX_NORMAL)
+ return false;
+
+ if (CEDevice::hasPocketPCResolution()) {
+ if (!_orientationLandscape && (_screenWidth == 320 || !_screenWidth)) {
+ _scaleFactorXm = 3;
+ _scaleFactorXd = 4;
+ _scaleFactorYm = 1;
+ _scaleFactorYd = 1;
+ _scalerProc = PocketPCPortrait;
+ _modeFlags = 0;
+ }
+ if ( _orientationLandscape && (_screenWidth == 320 || !_screenWidth)) {
+ if (!_panelVisible && !_hasSmartphoneResolution && !_overlayVisible) {
+ _scaleFactorXm = 1;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = 6;
+ _scaleFactorYd = 5;
+ _scalerProc = PocketPCLandscapeAspect;
+ _modeFlags = 0;
+ } else {
+ _scaleFactorXm = 1;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = 1;
+ _scaleFactorYd = 1;
+ _scalerProc = Normal1x;
+ _modeFlags = 0;
+ }
+ }
+ if (_screenWidth == 640 && !(isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) {
+ _scaleFactorXm = 1;
+ _scaleFactorXd = 2;
+ _scaleFactorYm = 1;
+ _scaleFactorYd = 2;
+ _scalerProc = PocketPCHalf;
+ _modeFlags = 0;
+ }
+ if (_screenWidth == 640 && (isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) {
+ _scaleFactorXm = 1;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = 1;
+ _scaleFactorYd = 1;
+ _scalerProc = Normal1x;
+ _modeFlags = 0;
+ }
+
+ return true;
+ }
+
+//#ifdef WIN32_PLATFORM_WFSP
+ if (CEDevice::hasSmartphoneResolution()) {
+ if (_screenWidth > 320)
+ error("Game resolution not supported on Smartphone");
+ _scaleFactorXm = 2;
+ _scaleFactorXd = 3;
+ _scaleFactorYm = 7;
+ _scaleFactorYd = 8;
+ _scalerProc = SmartphoneLandscape;
+ _modeFlags = 0;
+ initZones();
+ return true;
+ }
+//#endif
+
+ return false;
+}
+
+bool OSystem_WINCE3::setGraphicsMode(int mode) {
+
+ switch (_transactionMode) {
+ case kTransactionActive:
+ _transactionDetails.mode = mode;
+ _transactionDetails.modeChanged = true;
+ return true;
+ case kTransactionCommit:
+ break;
+ default:
+ break;
+ }
+
+ 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.removeKey("landscape", String::emptyString);
+ ConfMan.setInt("landscape", _orientationLandscape);
+ } else
+ _newOrientation = _orientationLandscape = ConfMan.getInt("landscape");
+ else
+ _newOrientation = _orientationLandscape = 0;
+
+ update_scalers();
+
+ // FIXME
+ if (isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640) && mode)
+ _scaleFactorXm = -1;
+
+ if (CEDevice::hasPocketPCResolution() && !CEDevice::hasWideResolution() && _orientationLandscape)
+ _mode = GFX_NORMAL;
+ else
+ _mode = mode;
+
+ if (_scaleFactorXm < 0) {
+ /* Standard scalers, from the SDL backend */
+ switch(_mode) {
+ case GFX_NORMAL:
+ _scaleFactor = 1;
+ _scalerProc = Normal1x;
+ break;
+ case GFX_DOUBLESIZE:
+ _scaleFactor = 2;
+ _scalerProc = Normal2x;
+ break;
+ case GFX_TRIPLESIZE:
+ _scaleFactor = 3;
+ _scalerProc = Normal3x;
+ break;
+ case GFX_2XSAI:
+ _scaleFactor = 2;
+ _scalerProc = _2xSaI;
+ break;
+ case GFX_SUPER2XSAI:
+ _scaleFactor = 2;
+ _scalerProc = Super2xSaI;
+ break;
+ case GFX_SUPEREAGLE:
+ _scaleFactor = 2;
+ _scalerProc = SuperEagle;
+ break;
+ case GFX_ADVMAME2X:
+ _scaleFactor = 2;
+ _scalerProc = AdvMame2x;
+ break;
+ case GFX_ADVMAME3X:
+ _scaleFactor = 3;
+ _scalerProc = AdvMame3x;
+ break;
+ case GFX_HQ2X:
+ _scaleFactor = 2;
+ _scalerProc = HQ2x;
+ break;
+ case GFX_HQ3X:
+ _scaleFactor = 3;
+ _scalerProc = HQ3x;
+ break;
+ case GFX_TV2X:
+ _scaleFactor = 2;
+ _scalerProc = TV2x;
+ break;
+ case GFX_DOTMATRIX:
+ _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 (_scaleFactor && ((_scaleFactor * _screenWidth > getScreenWidth() &&
+ _scaleFactor * _screenWidth > getScreenHeight())
+ || (_scaleFactor * _screenHeight > getScreenWidth() &&
+ _scaleFactor * _screenHeight > getScreenHeight()))) {
+ _scaleFactor = 1;
+ _scalerProc = Normal1x;
+ }
+
+ // Common scaler system was used
+ if (_scaleFactorXm < 0) {
+ _scaleFactorXm = _scaleFactor;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = _scaleFactor;
+ _scaleFactorYd = 1;
+ }
+
+ _forceFull = true;
+
+ if (oldScaleFactorXm != _scaleFactorXm ||
+ oldScaleFactorXd != _scaleFactorXd ||
+ oldScaleFactorYm != _scaleFactorYm ||
+ oldScaleFactorYd != _scaleFactorYd) {
+ _scalersChanged = true;
+ }
+ else
+ _scalersChanged = false;
+
+
+ return true;
+
+}
+
+void OSystem_WINCE3::loadGFXMode() {
+ int displayWidth;
+ int displayHeight;
+ unsigned int flags = SDL_FULLSCREEN | SDL_SWSURFACE;
+
+ _fullscreen = true; // forced
+ _forceFull = true;
+ _modeFlags |= DF_UPDATE_EXPAND_1_PIXEL;
+
+ _tmpscreen = NULL;
+
+ // Recompute scalers if necessary
+ update_scalers();
+
+ //
+ // Create the surface that contains the 8 bit game data
+ _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth, _screenHeight, 8, 0, 0, 0, 0);
+ if (_screen == NULL)
+ error("_screen failed");
+
+ //
+ // Create the surface that contains the scaled graphics in 16 bit mode
+ //
+
+ // Always use full screen mode to have a "clean screen"
+ displayWidth = _screenWidth * _scaleFactorXm / _scaleFactorXd;
+ displayHeight = _screenHeight * _scaleFactorYm / _scaleFactorYd;
+
+ // FIXME
+ if (displayWidth <= GetSystemMetrics(SM_CXSCREEN)) { // no rotation
+ displayWidth = GetSystemMetrics(SM_CXSCREEN);
+ displayHeight = GetSystemMetrics(SM_CYSCREEN);
+ } else if (displayHeight > GetSystemMetrics(SM_CXSCREEN)) // rotating, clip height
+ displayHeight = GetSystemMetrics(SM_CXSCREEN);
+
+ if (_orientationLandscape == 2) flags |= SDL_FLIPVIDEO;
+ _hwscreen = SDL_SetVideoMode(displayWidth, displayHeight, 16, flags);
+
+ if (_hwscreen == NULL) {
+ // DON'T use error(), as this tries to bring up the debug
+ // console, which WON'T WORK now that _hwscreen is hosed.
+
+ // FIXME: We should be able to continue the game without
+ // shutting down or bringing up the debug console, but at
+ // this point we've already screwed up all our member vars.
+ // We need to find a way to call SDL_VideoModeOK *before*
+ // that happens and revert to all the old settings if we
+ // can't pull off the switch to the new settings.
+ //
+ // Fingolfin says: the "easy" way to do that is not to modify
+ // the member vars before we are sure everything is fine. Think
+ // of "transactions, commit, rollback" style... we use local vars
+ // in place of the member vars, do everything etc. etc.. In case
+ // of a failure, rollback is trivial. Only if everything worked fine
+ // do we "commit" the changed values to the member vars.
+ warning("SDL_SetVideoMode says we can't switch to that mode");
+ quit();
+ }
+
+ //
+ // 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);
+ initCEScaler();
+
+ // Need some extra bytes around when using 2xSaI
+ _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ _screenWidth + 3,
+ _screenHeight + 3,
+ 16,
+ _hwscreen->format->Rmask,
+ _hwscreen->format->Gmask,
+ _hwscreen->format->Bmask,
+ _hwscreen->format->Amask);
+
+ if (_tmpscreen == NULL)
+ error("_tmpscreen failed");
+
+
+
+ // Overlay
+ if (CEDevice::hasDesktopResolution()) {
+ _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth * _scaleFactorXm / _scaleFactorXd, _overlayHeight * _scaleFactorYm / _scaleFactorYd, 16, 0, 0, 0, 0);
+ if (_overlayscreen == NULL)
+ error("_overlayscreen failed");
+ _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth * _scaleFactorXm / _scaleFactorXd + 3, _overlayHeight * _scaleFactorYm / _scaleFactorYd + 3, 16, 0, 0, 0, 0);
+ if (_tmpscreen2 == NULL)
+ error("_tmpscreen2 failed");
+ } else {
+ _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth, _overlayHeight, 16, 0, 0, 0, 0);
+ if (_overlayscreen == NULL)
+ error("_overlayscreen failed");
+ _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth + 3, _overlayHeight + 3, 16, 0, 0, 0, 0);
+ if (_tmpscreen2 == NULL)
+ error("_tmpscreen2 failed");
+ }
+
+ // Toolbar
+ uint16 *toolbar_screen = (uint16 *)calloc(320 * 40, sizeof(uint16));
+ _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");
+
+ if (_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");
+ }
+ else
+ _toolbarHigh = NULL;
+
+
+ // keyboard cursor control, some other better place for it?
+ _km.x_max = _screenWidth * _scaleFactorXm / _scaleFactorXd - 1;
+ _km.y_max = _screenHeight * _scaleFactorXm / _scaleFactorXd - 1;
+ _km.delay_time = 25;
+ _km.last_time = 0;
+}
+
+void OSystem_WINCE3::unloadGFXMode() {
+ if (_screen) {
+ SDL_FreeSurface(_screen);
+ _screen = NULL;
+ }
+
+ if (_hwscreen) {
+ SDL_FreeSurface(_hwscreen);
+ _hwscreen = NULL;
+ }
+
+ if (_tmpscreen) {
+ SDL_FreeSurface(_tmpscreen);
+ _tmpscreen = NULL;
+ }
+}
+
+void OSystem_WINCE3::hotswapGFXMode() {
+ if (!_screen)
+ return;
+
+ // 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
+ loadGFXMode();
+
+ // 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 to the screen
+ internUpdateScreen();
+
+ // Make sure that an EVENT_SCREEN_CHANGED gets sent later
+ _modeChanged = true;
+}
+
+void OSystem_WINCE3::update_keyboard() {
+ // Update the forced keyboard for Monkey Island copy protection
+ if (_monkeyKeyboard && !_isSmartphone)
+ if (!_panelVisible || _toolbarHandler.activeName() != NAME_PANEL_KEYBOARD)
+ swap_panel();
+ if (_monkeyKeyboard && Scumm::g_scumm->VAR_ROOM != 0xff && Scumm::g_scumm && Scumm::g_scumm->VAR(Scumm::g_scumm->VAR_ROOM) != 108 &&
+ Scumm::g_scumm->VAR(Scumm::g_scumm->VAR_ROOM) != 90) {
+ // Switch back to the normal panel now that the keyboard is not used anymore
+ _monkeyKeyboard = false;
+ _toolbarHandler.setActive(NAME_MAIN_PANEL);
+ }
+}
+
+void OSystem_WINCE3::internUpdateScreen() {
+ SDL_Surface *srcSurf, *origSurf;
+ static bool old_overlayVisible = false;
+ assert(_hwscreen != NULL);
+
+ update_keyboard();
+
+ // If the shake position changed, fill the dirty area with blackness
+ if (_currentShakePos != _newShakePos) {
+ SDL_Rect blackrect = {0, 0, _screenWidth * _scaleFactorXm / _scaleFactorXd, _newShakePos * _scaleFactorYm / _scaleFactorYd};
+
+ if (_adjustAspectRatio)
+ 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 = _screenHeight / 2;
+ _dirtyRectList[0].w = _screenWidth;
+ if (!_zoomUp && !_zoomDown)
+ _dirtyRectList[0].h = _screenHeight;
+ else
+ _dirtyRectList[0].h = _screenHeight / 2;
+
+ _toolbarHandler.forceRedraw();
+ }
+ //else
+ // undrawMouse();
+
+ // Only draw anything if necessary
+ if (_numDirtyRects > 0) {
+
+ SDL_Rect *r;
+ SDL_Rect dst;
+ uint32 srcPitch, dstPitch;
+ SDL_Rect *last_rect = _dirtyRectList + _numDirtyRects;
+ bool toolbarVisible = _toolbarHandler.visible();
+ int toolbarOffset = _toolbarHandler.getOffset();
+
+ if (_scalerProc == Normal1x && !_adjustAspectRatio && 0) {
+ for (r = _dirtyRectList; r != last_rect; ++r) {
+ dst = *r;
+
+ // Check if the toolbar is overwritten
+ if (!_forceFull && toolbarVisible && r->y + r->h >= toolbarOffset) {
+ _toolbarHandler.forceRedraw();
+ }
+
+ if (_overlayVisible) {
+ // FIXME: I don't understand why this is necessary...
+ dst.x--;
+ dst.y--;
+ }
+ dst.y += _currentShakePos;
+ if (SDL_BlitSurface(origSurf, r, _hwscreen, &dst) != 0)
+ error("SDL_BlitSurface failed: %s", SDL_GetError());
+ }
+ } else {
+ for (r = _dirtyRectList; r != last_rect; ++r) {
+ dst = *r;
+ dst.x++; // Shift rect by one since 2xSai needs to acces the data around
+ dst.y++; // any pixel to scale it, and we want to avoid mem access crashes.
+ if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)
+ error("SDL_BlitSurface failed: %s", SDL_GetError());
+ }
+
+ SDL_LockSurface(srcSurf);
+ SDL_LockSurface(_hwscreen);
+
+ srcPitch = srcSurf->pitch;
+ dstPitch = _hwscreen->pitch;
+
+ for (r = _dirtyRectList; r != last_rect; ++r) {
+ register int dst_y = r->y + _currentShakePos;
+ register int dst_h = 0;
+ register int orig_dst_y = 0;
+
+ // Check if the toolbar is overwritten
+ if (!_forceFull && toolbarVisible && r->y + r->h >= toolbarOffset) {
+ _toolbarHandler.forceRedraw();
+ }
+
+ if (dst_y < _screenHeight) {
+ dst_h = r->h;
+ if (dst_h > _screenHeight - dst_y)
+ dst_h = _screenHeight - dst_y;
+
+ dst_y *= _scaleFactorYm;
+ dst_y /= _scaleFactorYd;
+
+ if (_adjustAspectRatio) {
+ orig_dst_y = dst_y;
+ dst_y = real2Aspect(dst_y);
+ }
+
+ // clip inside platform screen (landscape,bottom only)
+ if (_orientationLandscape && !_zoomDown && dst_y+dst_h > _screenHeight)
+ dst_h = _screenHeight - dst_y;
+
+ if (!_zoomDown)
+ _scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
+ (byte *)_hwscreen->pixels + (r->x * 2 * _scaleFactorXm / _scaleFactorXd) + dst_y * dstPitch, dstPitch, r->w, dst_h);
+ else {
+ _scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
+ (byte *)_hwscreen->pixels + (r->x * 2 * _scaleFactorXm / _scaleFactorXd) + (dst_y - 240) * dstPitch, dstPitch, r->w, dst_h);
+ }
+
+ }
+
+ r->x = r->x * _scaleFactorXm / _scaleFactorXd;
+ if (!_zoomDown)
+ r->y = dst_y;
+ else
+ r->y = dst_y - 240;
+ r->w = r->w * _scaleFactorXm / _scaleFactorXd;
+ r->h = dst_h * _scaleFactorYm / _scaleFactorYd;
+
+ /*if (_adjustAspectRatio && orig_dst_y / _scaleFactor < _screenHeight)
+ r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
+ */
+ }
+ SDL_UnlockSurface(srcSurf);
+ SDL_UnlockSurface(_hwscreen);
+ }
+
+ // Readjust the dirty rect list in case we are doing a full update.
+ // This is necessary if shaking is active.
+ if (_forceFull) {
+ _dirtyRectList[0].y = 0;
+ _dirtyRectList[0].h = (_adjustAspectRatio ? 240 : (_zoomUp || _zoomDown ? _screenHeight / 2 : _screenHeight)) * _scaleFactorYm / _scaleFactorYd;
+ if (_orientationLandscape)
+ {
+ if (_dirtyRectList[0].h > _platformScreenWidth)
+ _dirtyRectList[0].h = _platformScreenWidth; // clip
+ } else {
+ if (_dirtyRectList[0].h > _platformScreenHeight)
+ _dirtyRectList[0].h = _platformScreenHeight; // clip
+ }
+ }
+ }
+ // 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;
+
+ if (_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;
+ }
+ else
+ _toolbarHighDrawn = false;
+ 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;
+ _scalerProc((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
+ }
+
+
+ //drawMouse();
+
+ // Finally, blit all our changes to the screen
+ if (_numDirtyRects > 0)
+ SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
+
+ _numDirtyRects = 0;
+ _forceFull = false;
+}
+
+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;
+}
+
+// FIXME
+// Reuse static or proper mapping
+
+static int mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode)
+{
+ if (GUI::Actions::Instance()->mappingActive())
+ return key;
+
+ if (key >= SDLK_F1 && key <= SDLK_F9) {
+ return key - SDLK_F1 + 315;
+ } else if (key >= SDLK_KP0 && key <= SDLK_KP9) {
+ return key - SDLK_KP0 + '0';
+ } else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) {
+ return key;
+ } else if (unicode) {
+ return unicode;
+ } else if (key >= 'a' && key <= 'z' && mod & KMOD_SHIFT) {
+ return key & ~0x20;
+ } else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) {
+ return 0;
+ }
+ return key;
+}
+
+void OSystem_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 > _overlayWidth - x) {
+ w = _overlayWidth - x;
+ }
+
+ if (h > _overlayHeight - y) {
+ h = _overlayHeight - y;
+ }
+
+ if (w <= 0 || h <= 0)
+ return;
+
+ // Mark the modified region as dirty
+ _cksumValid = false;
+ 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
+
+ if (((long)src & 3) == 0 && pitch == _screenWidth && x == 0 && y == 0 &&
+ w == _screenWidth && h == _screenHeight && _modeFlags & DF_WANT_RECT_OPTIM) {
+ /* Special, optimized case for full screen updates.
+ * It tries to determine what areas were actually changed,
+ * and just updates those, on the actual display. */
+ addDirtyRgnAuto(src);
+ } else {
+ /* Clip the coordinates */
+ if (x < 0) {
+ w += x;
+ src -= x;
+ x = 0;
+ }
+
+ if (y < 0) {
+ h += y;
+ src -= y * pitch;
+ y = 0;
+ }
+
+ if (w > _screenWidth - x) {
+ w = _screenWidth - x;
+ }
+
+ if (h > _screenHeight - y) {
+ h = _screenHeight - y;
+ }
+
+ if (w <= 0 || h <= 0)
+ return;
+
+ _cksumValid = false;
+ 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 * _screenWidth + x;
+
+ if (_screenWidth == pitch && pitch == w) {
+ memcpy(dst, src, h*w);
+ } else {
+ do {
+ memcpy(dst, src, w);
+ src += pitch;
+ dst += _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, byte keycolor, int cursorTargetScale) {
+
+ undrawMouse();
+ if (w == 0 || h == 0)
+ return;
+
+ assert(w <= MAX_MOUSE_W);
+ assert(h <= MAX_MOUSE_H);
+ _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);
+}
+
+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 (_mouseDrawn || !_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
+
+ // 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 > _screenWidth - x)
+ w = _screenWidth - x;
+ if (h > _screenHeight - y)
+ h = _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 * _screenWidth + x;
+ while (h > 0) {
+ int 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 += MAX_MOUSE_W - w;
+ dst += _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) {
+ int width = w;
+ while (width > 0) {
+ *bak++ = *(uint16 *)dst;
+ color = *src++;
+ if (color != 0xFF) // 0xFF = transparent, don't draw
+ *(uint16 *)dst = RGBToColor(_currentPalette[color].r, _currentPalette[color].g, _currentPalette[color].b);
+ dst += 2;
+ width--;
+ }
+ src += _mouseCurState.w - w;
+ bak += MAX_MOUSE_W - w;
+ dst += _overlayscreen->pitch - w * 2;
+ h--;
+ }
+ }
+
+ SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);
+
+ // Finally, set the flag to indicate the mouse has been drawn
+ _mouseDrawn = true;
+}
+
+void OSystem_WINCE3::undrawMouse() {
+ assert (_transactionMode == kTransactionNone || _transactionMode == kTransactionCommit);
+
+ if (!_mouseDrawn)
+ return;
+ _mouseDrawn = false;
+
+ 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 addjust 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 > _screenWidth - old_mouse_x)
+ old_mouse_w = _screenWidth - old_mouse_x;
+ if (old_mouse_h > _screenHeight - old_mouse_y)
+ old_mouse_h = _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 x, 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 * _screenWidth + old_mouse_x;
+ for (y = 0; y < old_mouse_h; ++y, bak += MAX_MOUSE_W, dst += _screenWidth) {
+ for (x = 0; x < old_mouse_w; ++x) {
+ dst[x] = bak[x];
+ }
+ }
+
+ } 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 += MAX_MOUSE_W, dst += _overlayscreen->pitch) {
+ for (x = 0; x < old_mouse_w; ++x) {
+ *((uint16 *)dst + x) = bak[x];
+ }
+ }
+ }
+
+ addDirtyRect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h);
+
+ SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);
+}
+
+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;
+
+ // 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) {
+ int width = w;
+ while (width > 0) {
+ *bak++ = *dst;
+ color = *src++;
+ if (color != _mouseKeyColor) // transparent color
+ *dst = 0xFFFF;
+ dst++;
+ width--;
+ }
+ src += _mouseCurState.w - w;
+ bak += MAX_MOUSE_W - w;
+ dst += surf->w - w;
+ h--;
+ }
+ } else { // restore bg
+ for (int y = 0; y < h; ++y, bak += MAX_MOUSE_W, dst += surf->w)
+ for (int x = 0; x < w; ++x)
+ dst[x] = bak[x];
+ }
+
+ SDL_UnlockSurface(surf);
+}
+
+void OSystem_WINCE3::blitCursor() {
+}
+
+void OSystem_WINCE3::showOverlay() {
+ assert (_transactionMode == kTransactionNone);
+
+ undrawMouse();
+
+ _overlayVisible = true;
+ clearOverlay();
+}
+
+void OSystem_WINCE3::hideOverlay() {
+ assert (_transactionMode == kTransactionNone);
+
+ undrawMouse();
+
+ _overlayVisible = false;
+ clearOverlay();
+ _forceFull = true;
+}
+
+void OSystem_WINCE3::drawMouse() {
+ // FIXME
+ if (!(_toolbarHandler.visible() && _mouseCurState.y >= _toolbarHandler.getOffset()) && !_forceHideMouse)
+ internDrawMouse();
+}
+
+void OSystem_WINCE3::fillMouseEvent(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) {
+
+ // Align on boundaries
+ if (_scaleFactorXd > 1) {
+ while (x % _scaleFactorXd) {
+ x--;
+ w++;
+ }
+ while (w % _scaleFactorXd) w++;
+ }
+
+ if (_scaleFactorYd > 1) {
+ while (y % _scaleFactorYd) {
+ y--;
+ h++;
+ }
+ while (h % _scaleFactorYd) h++;
+ }
+
+ if (_scalerProc == PocketPCHalfZoom) {
+ // Restrict rect if we're zooming
+ if (_zoomUp) {
+ if (y + h >= 240) {
+ if (y >= 240)
+ return;
+ else
+ h = 240 - y;
+ }
+ }
+ else
+ if (_zoomDown) {
+ if (y + h >= 240) {
+ if (y < 240) {
+ h = 240 - y;
+ y = 240;
+ }
+ }
+ else
+ return;
+ }
+ }
+
+ OSystem_SDL::addDirtyRect(x, y, w, h, false);
+}
+
+// FIXME
+// See if some SDL mapping can be useful for HPCs
+
+bool OSystem_WINCE3::pollEvent(Event &event) {
+ SDL_Event ev;
+ byte b = 0;
+ Event temp_event;
+ DWORD currentTime;
+ bool keyEvent = false;
+
+ memset(&temp_event, 0, sizeof(Event));
+ memset(&event, 0, sizeof(Event));
+
+ handleKbdMouse();
+
+ // If the screen mode changed, send an EVENT_SCREEN_CHANGED
+ if (_modeChanged) {
+ _modeChanged = false;
+ event.type = EVENT_SCREEN_CHANGED;
+ return true;
+ }
+
+ CEDevice::wakeUp();
+
+ //if (_isSmartphone)
+ currentTime = GetTickCount();
+
+ while(SDL_PollEvent(&ev)) {
+ switch(ev.type) {
+ case SDL_KEYDOWN:
+ // KMOD_RESERVED is used if the key has been injected by an external buffer
+ if (ev.key.keysym.mod != KMOD_RESERVED) {
+ //if (_isSmartphone) {
+ 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;
+ }
+
+ event.type = EVENT_KEYDOWN;
+ event.kbd.keycode = ev.key.keysym.sym;
+ event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode);
+
+ if (GUI_Actions::Instance()->mappingActive())
+ event.kbd.flags = 0xFF;
+
+ return true;
+
+ case SDL_KEYUP:
+ // KMOD_RESERVED is used if the key has been injected by an external buffer
+ if (ev.key.keysym.mod != KMOD_RESERVED) {
+ //if (_isSmartphone) {
+ keyEvent = true;
+ _lastKeyPressed = 0;
+ //}
+
+ if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, false))
+ return true;
+ }
+
+ event.type = EVENT_KEYUP;
+ event.kbd.keycode = ev.key.keysym.sym;
+ event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode);
+
+ if (GUI_Actions::Instance()->mappingActive())
+ event.kbd.flags = 0xFF;
+
+ return true;
+
+ case SDL_MOUSEMOTION:
+ event.type = 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)
+ temp_event.type = EVENT_LBUTTONDOWN;
+ else if (ev.button.button == SDL_BUTTON_RIGHT)
+ temp_event.type = EVENT_RBUTTONDOWN;
+ else
+ break;
+
+ fillMouseEvent(temp_event, ev.button.x, ev.button.y);
+
+ if (!_isSmartphone) {
+ // Already tap initiated ?
+ if (_tapTime) {
+ int deltaX;
+ int deltaY;
+ if (temp_event.mouse.x > _tapX)
+ deltaX = temp_event.mouse.x - _tapX;
+ else
+ deltaX = _tapX - temp_event.mouse.x;
+ if (temp_event.mouse.y > _tapY)
+ deltaY = temp_event.mouse.y - _tapY;
+ else
+ deltaY = _tapY - temp_event.mouse.y;
+ if (deltaX <= 5 && deltaY <= 5 && (GetTickCount() - _tapTime < 1000)) {
+ if (temp_event.mouse.y <= 20 && _panelInitialized) { // panel double tap?
+ swap_panel_visibility();
+ } else { // simulate right click
+ temp_event.type = EVENT_RBUTTONDOWN;
+ _rbutton = true;
+ }
+ }
+ _tapTime = 0;
+ } else {
+ _tapTime = GetTickCount();
+ _tapX = temp_event.mouse.x;
+ _tapY = temp_event.mouse.y;
+ }
+ }
+
+ if (_toolbarHandler.action(temp_event.mouse.x, temp_event.mouse.y, true)) {
+ if (!_toolbarHandler.drawn())
+ internUpdateScreen();
+ if (_newOrientation != _orientationLandscape && _mode == GFX_NORMAL) {
+ _orientationLandscape = _newOrientation;
+ ConfMan.setInt("landscape", _orientationLandscape);
+ ConfMan.flushToDisk();
+ setGraphicsMode(GFX_NORMAL);
+ hotswapGFXMode();
+ }
+ }
+ else {
+ if (!_freeLook)
+ memcpy(&event, &temp_event, sizeof(Event));
+ }
+
+ return true;
+
+ case SDL_MOUSEBUTTONUP:
+ if (ev.button.button == SDL_BUTTON_LEFT)
+ temp_event.type = EVENT_LBUTTONUP;
+ else if (ev.button.button == SDL_BUTTON_RIGHT)
+ temp_event.type = EVENT_RBUTTONUP;
+ else
+ break;
+
+ if (_rbutton) {
+ temp_event.type = EVENT_RBUTTONUP;
+ _rbutton = false;
+ }
+
+ fillMouseEvent(temp_event, ev.button.x, ev.button.y);
+
+ if (_toolbarHandler.action(temp_event.mouse.x, temp_event.mouse.y, false)) {
+ if (!_toolbarHandler.drawn())
+ internUpdateScreen();
+ }
+ else {
+ if (!_freeLook)
+ memcpy(&event, &temp_event, sizeof(Event));
+ }
+
+ return true;
+
+ case SDL_VIDEOEXPOSE:
+ _forceFull = true;
+ break;
+
+ case SDL_QUIT:
+ event.type = EVENT_QUIT;
+ return true;
+ }
+ }
+
+ // Simulate repeated key for Smartphones
+
+ if (!keyEvent) {
+ //if (_isSmartphone) {
+ if (_lastKeyPressed) {
+ if (currentTime > _keyRepeatTime + _keyRepeatTrigger) {
+ _keyRepeatTime = currentTime;
+ _keyRepeat++;
+ GUI_Actions::Instance()->performMapped(_lastKeyPressed, true);
+ }
+ }
+ //}
+ }
+
+ return false;
+}
+
+void OSystem_WINCE3::quit() {
+ fclose(stdout_file);
+ fclose(stderr_file);
+ if (gDebugLevel <= 0) {
+ DeleteFile(TEXT("\\scummvm_stdout.txt"));
+ DeleteFile(TEXT("\\scummvm_stderr.txt"));
+ }
+ CEDevice::end();
+ OSystem_SDL::quit();
+}
+
+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
new file mode 100644
index 0000000000..ae1d252f2d
--- /dev/null
+++ b/backends/platform/wince/wince-sdl.h
@@ -0,0 +1,237 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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 WINCE_SDL_H
+#define WINCE_SDL_H
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+#include "graphics/scaler.h"
+#include "backends/intern.h"
+#include "backends/platform/sdl/sdl-common.h"
+
+#include "CEgui.h"
+#include "CEkeys.h"
+#include "CEDevice.h"
+#include "CEScaler.h"
+
+#include <SDL.h>
+
+
+
+#define TOTAL_ZONES 3
+
+class OSystem_WINCE3 : public OSystem_SDL {
+public:
+ OSystem_WINCE3();
+
+ // Update the dirty areas of the screen
+ void internUpdateScreen();
+
+ void initSize(uint w, uint h);
+
+ void initBackend();
+
+ // Overloaded from SDL_Common (toolbar handling)
+ bool pollEvent(Event &event);
+ // Overloaded from SDL_Common (toolbar handling)
+ void drawMouse();
+ // Overloaded from SDL_Common (mouse and new scaler handling)
+ void fillMouseEvent(Event &event, int x, int y);
+ // Overloaded from SDL_Common (new scaler handling)
+ void addDirtyRect(int x, int y, int w, int h, bool mouseRect = false);
+ // Overloaded from SDL_Common (new scaler handling)
+ void warpMouse(int x, int y);
+ // Overloaded from SDL_Commmon
+ void quit();
+ // Overloaded from SDL_Commmon (master volume and sample rate subtleties)
+ bool setSoundCallback(SoundProc proc, void *param);
+
+ // Overloaded from SDL_Common (FIXME)
+ void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale); // overloaded by CE backend
+ void undrawMouse();
+ void blitCursor();
+ 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();
+
+ // 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:
+ void loadGFXMode();
+ void unloadGFXMode();
+ void hotswapGFXMode();
+ bool saveScreenshot(const char *filename);
+
+
+ const GraphicsMode *getSupportedGraphicsModes() const;
+ bool setGraphicsMode(int mode);
+ //int getGraphicsMode() const;
+ int getDefaultGraphicsMode() const;
+
+ void setWindowCaption(const char *caption);
+ bool openCD(int drive);
+ int getOutputSampleRate() const;
+
+ bool hasFeature(Feature f);
+ void setFeatureState(Feature f, bool enable);
+ bool getFeatureState(Feature f);
+
+ void internDrawMouse();
+ void drawToolbarMouse(SDL_Surface *surf, bool draw);
+
+private:
+
+#ifdef USE_VORBIS
+ bool checkOggHighSampleRate();
+#endif
+
+ static void private_sound_proc(void *param, byte *buf, int len);
+ static SoundProc _originalSoundProc;
+
+ bool update_scalers();
+ void create_toolbar();
+ void update_game_settings();
+ void check_mappings();
+ void update_keyboard();
+ void get_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
+
+ uint16 _sampleRate; // current audio sample rate
+
+ 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 _monkeyKeyboard; // forced keyboard for Monkey Island copy protection
+ 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 _rbutton; // double tap -> right button simulation
+
+ bool _usesEmulatedMouse; // emulated mousemove ever been used in this session
+
+ int _scaleFactorXm; // scaler X *
+ int _scaleFactorXd; // scaler X /
+ int _scaleFactorYm; // scaler Y *
+ int _scaleFactorYd; // scaler Y /
+ bool _scalersChanged;
+
+ 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;
+
+ // 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;
+
+ typedef struct zoneDesc {
+ int x;
+ int y;
+ int width;
+ int height;
+ } zoneDesc;
+
+ static zoneDesc _zones[TOTAL_ZONES];
+};
+
+#endif