diff options
| author | Kostas Nakos | 2006-07-01 08:13:46 +0000 |
|---|---|---|
| committer | Kostas Nakos | 2006-07-01 08:13:46 +0000 |
| commit | 6a8749ace05649fdf69593c76a75c322f34a5bfa (patch) | |
| tree | da214254c9ca56ded22af377fe0763ad73dd7bb5 /backends/platform/wince | |
| parent | 294dcea3ef063ee4ec95f3f418af4534445da1c6 (diff) | |
| download | scummvm-rg350-6a8749ace05649fdf69593c76a75c322f34a5bfa.tar.gz scummvm-rg350-6a8749ace05649fdf69593c76a75c322f34a5bfa.tar.bz2 scummvm-rg350-6a8749ace05649fdf69593c76a75c322f34a5bfa.zip | |
move ce port to its new home
svn-id: r23366
Diffstat (limited to 'backends/platform/wince')
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 Binary files differnew file mode 100644 index 0000000000..cc9c68d778 --- /dev/null +++ b/backends/platform/wince/icons/scumm_icon.ico diff --git a/backends/platform/wince/images/Action.bmp b/backends/platform/wince/images/Action.bmp Binary files differnew file mode 100644 index 0000000000..4985512cf4 --- /dev/null +++ b/backends/platform/wince/images/Action.bmp diff --git a/backends/platform/wince/images/DiskwFolder.bmp b/backends/platform/wince/images/DiskwFolder.bmp Binary files differnew file mode 100644 index 0000000000..82b4019930 --- /dev/null +++ b/backends/platform/wince/images/DiskwFolder.bmp diff --git a/backends/platform/wince/images/MonkeyLandscape.bmp b/backends/platform/wince/images/MonkeyLandscape.bmp Binary files differnew file mode 100644 index 0000000000..70f6ed69e7 --- /dev/null +++ b/backends/platform/wince/images/MonkeyLandscape.bmp diff --git a/backends/platform/wince/images/MonkeyPortrait.bmp b/backends/platform/wince/images/MonkeyPortrait.bmp Binary files differnew file mode 100644 index 0000000000..00619c2985 --- /dev/null +++ b/backends/platform/wince/images/MonkeyPortrait.bmp diff --git a/backends/platform/wince/images/SoundOff.bmp b/backends/platform/wince/images/SoundOff.bmp Binary files differnew file mode 100644 index 0000000000..2f7b26deaf --- /dev/null +++ b/backends/platform/wince/images/SoundOff.bmp diff --git a/backends/platform/wince/images/SoundOn.bmp b/backends/platform/wince/images/SoundOn.bmp Binary files differnew file mode 100644 index 0000000000..2988b87224 --- /dev/null +++ b/backends/platform/wince/images/SoundOn.bmp diff --git a/backends/platform/wince/images/bindkeys.bmp b/backends/platform/wince/images/bindkeys.bmp Binary files differnew file mode 100644 index 0000000000..8a6cfc9347 --- /dev/null +++ b/backends/platform/wince/images/bindkeys.bmp diff --git a/backends/platform/wince/images/keyboard.bmp b/backends/platform/wince/images/keyboard.bmp Binary files differnew file mode 100644 index 0000000000..aac79d00e5 --- /dev/null +++ b/backends/platform/wince/images/keyboard.bmp diff --git a/backends/platform/wince/images/panelbig.bmp b/backends/platform/wince/images/panelbig.bmp Binary files differnew file mode 100644 index 0000000000..4d10f255ad --- /dev/null +++ b/backends/platform/wince/images/panelbig.bmp 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 |
