aboutsummaryrefslogtreecommitdiff
path: root/backends/wince
diff options
context:
space:
mode:
authorNicolas Bacca2004-01-26 08:20:26 +0000
committerNicolas Bacca2004-01-26 08:20:26 +0000
commitbf88c1eae54b3b90e1ca39f1547332bb8fc17fb7 (patch)
treeb1ffee18d5e45276af191c032088446e62024388 /backends/wince
parentcccecd0ee3dd4ef155aa21f75c364355f746ea13 (diff)
downloadscummvm-rg350-bf88c1eae54b3b90e1ca39f1547332bb8fc17fb7.tar.gz
scummvm-rg350-bf88c1eae54b3b90e1ca39f1547332bb8fc17fb7.tar.bz2
scummvm-rg350-bf88c1eae54b3b90e1ca39f1547332bb8fc17fb7.zip
New CE backend initial commit
svn-id: r12618
Diffstat (limited to 'backends/wince')
-rw-r--r--backends/wince/CEActions.cpp250
-rw-r--r--backends/wince/CEActions.h91
-rw-r--r--backends/wince/CEDevice.cpp118
-rw-r--r--backends/wince/CEDevice.h49
-rw-r--r--backends/wince/CEKeysDialog.cpp123
-rw-r--r--backends/wince/CEKeysDialog.h45
-rw-r--r--backends/wince/CELauncherDialog.cpp121
-rw-r--r--backends/wince/CELauncherDialog.h43
-rw-r--r--backends/wince/CEScaler.cpp76
-rw-r--r--backends/wince/CEScaler.h34
-rw-r--r--backends/wince/wince-sdl.cpp1146
-rw-r--r--backends/wince/wince-sdl.h125
12 files changed, 2221 insertions, 0 deletions
diff --git a/backends/wince/CEActions.cpp b/backends/wince/CEActions.cpp
new file mode 100644
index 0000000000..65ac639e51
--- /dev/null
+++ b/backends/wince/CEActions.cpp
@@ -0,0 +1,250 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+
+#include "stdafx.h"
+#include "CEActions.h"
+#include "KeysBuffer.h"
+
+#include "gui/message.h"
+
+#include "scumm/scumm.h"
+
+#include "common/config-manager.h"
+
+const String actionNames[] = {
+ "none",
+ "Pause",
+ "Save",
+ "Quit",
+ "Skip",
+ "Hide",
+ "Keyboard",
+ "Sound",
+ "Right click",
+ "Cursor",
+ "Free look"
+};
+
+CEActions* CEActions::Instance() {
+ return _instance;
+}
+
+String CEActions::actionName(ActionType action) {
+ return actionNames[action];
+}
+
+int CEActions::size() {
+ return ACTION_LAST - 1;
+}
+
+CEActions::CEActions(OSystem_WINCE3 *mainSystem, GameDetector &detector) :
+ _mainSystem(mainSystem), _mapping_active(false), _right_click_needed(false) {
+ int i;
+ bool is_simon = (strcmp(detector._targetName.c_str(), "simon") == 0);
+ bool is_sword1 = (detector._targetName == "sword1");
+ bool is_sword2 = (strcmp(detector._targetName.c_str(), "sword2") == 0);
+ bool is_queen = (detector._targetName == "queen");
+ bool is_sky = (detector._targetName == "sky");
+
+ for (i=0; i<ACTION_LAST; i++)
+ _action_mapping[i] = 0;
+
+ // See if a right click mapping could be needed
+ if (is_sword1 || is_sword2 || is_sky || is_queen || detector._targetName == "comi" ||
+ detector._targetName == "samnmax")
+ _right_click_needed = true;
+
+ // Initialize keys for different actions
+ // Pause
+ _key_action[ACTION_PAUSE].setAscii(VK_SPACE);
+ _action_enabled[ACTION_PAUSE] = true;
+ // Save
+ if (is_simon)
+ _action_enabled[ACTION_SAVE] = false;
+ else
+ if (is_queen) {
+ _action_enabled[ACTION_SAVE] = true;
+ _key_action[ACTION_SAVE].setAscii(282); // F1 key
+ }
+ else
+ if (is_sky) {
+ _action_enabled[ACTION_SAVE] = true;
+ _key_action[ACTION_SAVE].setAscii(63);
+ }
+ else {
+ _action_enabled[ACTION_SAVE] = true;
+ _key_action[ACTION_SAVE].setAscii(319); // F5 key
+ }
+ // Quit
+ _action_enabled[ACTION_QUIT] = true;
+ // Skip
+ _action_enabled[ACTION_SKIP] = true;
+ if (is_simon || is_sky || is_sword2 || is_queen || is_sword1)
+ _key_action[ACTION_SKIP].setAscii(VK_ESCAPE);
+ else
+ _key_action[ACTION_SKIP].setAscii(Scumm::KEY_ALL_SKIP);
+ // Hide
+ _action_enabled[ACTION_HIDE] = true;
+ // Keyboard
+ _action_enabled[ACTION_KEYBOARD] = true;
+ // Sound
+ _action_enabled[ACTION_SOUND] = true;
+ // RightClick
+ _action_enabled[ACTION_RIGHTCLICK] = true;
+ // Cursor
+ _action_enabled[ACTION_CURSOR] = true;
+ // Freelook
+ _action_enabled[ACTION_FREELOOK] = true;
+}
+
+
+CEActions::~CEActions() {
+}
+
+void CEActions::init(OSystem_WINCE3 *mainSystem, GameDetector &detector) {
+ _instance = new CEActions(mainSystem, detector);
+}
+
+bool CEActions::perform(ActionType action) {
+ switch (action) {
+ case ACTION_PAUSE:
+ case ACTION_SAVE:
+ case ACTION_SKIP:
+ KeysBuffer::Instance()->add(&_key_action[action]);
+ return true;
+ case ACTION_KEYBOARD:
+ _mainSystem->swap_panel();
+ return true;
+ case ACTION_HIDE:
+ _mainSystem->swap_panel_visibility();
+ return true;
+ case ACTION_SOUND:
+ _mainSystem->swap_sound_master();
+ return true;
+ case ACTION_RIGHTCLICK:
+ _mainSystem->add_right_click();
+ return true;
+ case ACTION_CURSOR:
+ _mainSystem->swap_mouse_visibility();
+ return true;
+ case ACTION_QUIT:
+ GUI::MessageDialog alert("Do you want to quit ?", "Yes", "No");
+ if (alert.runModal() == 1)
+ _mainSystem->quit();
+ return true;
+ }
+ return false;
+}
+
+bool CEActions::isActive(ActionType action) {
+ return false;
+}
+
+bool CEActions::isEnabled(ActionType action) {
+ return _action_enabled[action];
+}
+
+void CEActions::beginMapping(bool start) {
+ _mapping_active = start;
+}
+
+bool CEActions::mappingActive() {
+ return _mapping_active;
+}
+
+bool CEActions::performMapped(unsigned int keyCode, bool pushed) {
+ int i;
+
+ for (i=0; i<ACTION_LAST; i++) {
+ if (_action_mapping[i] == keyCode) {
+ if (pushed)
+ return perform((ActionType)(i + 1));
+ else
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool CEActions::loadMapping() {
+ const char *tempo;
+ int version;
+ int i;
+ version = ConfMan.getInt("CE_mapping_version");
+ if (version != ACTIONS_VERSION)
+ return false;
+ tempo = ConfMan.get("CE_mapping").c_str();
+ if (tempo && strlen(tempo)) {
+ for (i=0; i<ACTION_LAST; i++) {
+ char x[6];
+ int j;
+ memset(x, 0, sizeof(x));
+ memcpy(x, tempo + 5 * i, 4);
+ sscanf(x, "%x", &j);
+ _action_mapping[i] = j;
+ }
+ return true;
+ }
+ else
+ return false;
+}
+
+bool CEActions::saveMapping() {
+ char tempo[200];
+ int i;
+ tempo[0] = '\0';
+ ConfMan.set("CE_mapping_version", ACTIONS_VERSION);
+ for (i=0; i<ACTION_LAST; i++) {
+ char x[4];
+ sprintf(x, "%.4x ", _action_mapping[i]);
+ strcat(tempo, x);
+ }
+ ConfMan.set("CE_mapping", tempo);
+ ConfMan.flushToDisk();
+ return true;
+}
+
+unsigned int CEActions::getMapping(ActionType action) {
+ return _action_mapping[action - 1];
+}
+
+
+void CEActions::setMapping(ActionType action, unsigned int keyCode) {
+ int i;
+
+ for (i=0; i<ACTION_LAST; i++) {
+ if (_action_mapping[i] == keyCode)
+ _action_mapping[i] = 0;
+ }
+
+ _action_mapping[action - 1] = keyCode;
+}
+
+bool CEActions::needsRightClickMapping() {
+ if (!_right_click_needed)
+ return false;
+ else
+ return (_action_mapping[ACTION_RIGHTCLICK] == 0);
+}
+
+CEActions *CEActions::_instance = NULL; \ No newline at end of file
diff --git a/backends/wince/CEActions.h b/backends/wince/CEActions.h
new file mode 100644
index 0000000000..1ed38fe56f
--- /dev/null
+++ b/backends/wince/CEActions.h
@@ -0,0 +1,91 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef CEACTIONS
+#define CEACTIONS
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+
+
+#include "base/gameDetector.h"
+#include "wince-sdl.h"
+#include "Key.h"
+
+enum ActionType {
+ ACTION_NONE = 0,
+ ACTION_PAUSE,
+ ACTION_SAVE,
+ ACTION_QUIT,
+ ACTION_SKIP,
+ ACTION_HIDE,
+ ACTION_KEYBOARD,
+ ACTION_SOUND,
+ ACTION_RIGHTCLICK,
+ ACTION_CURSOR,
+ ACTION_FREELOOK,
+
+ ACTION_LAST
+};
+
+#define ACTIONS_VERSION 1
+
+class OSystem_WINCE3;
+
+class CEActions {
+ public:
+ static CEActions* Instance();
+ static void init(OSystem_WINCE3 *mainSystem, GameDetector &detector);
+
+ // Actions
+ bool perform(ActionType action);
+ bool isActive(ActionType action);
+ bool isEnabled(ActionType action);
+ String actionName(ActionType action);
+ int size();
+
+ // Mapping
+ void beginMapping(bool start);
+ bool mappingActive();
+ bool performMapped(unsigned int keyCode, bool pushed);
+ bool loadMapping();
+ bool saveMapping();
+ unsigned int getMapping(ActionType action);
+ void setMapping(ActionType action, unsigned int keyCode);
+
+ // Utility
+ bool needsRightClickMapping();
+
+ ~CEActions();
+ private:
+ CEActions(OSystem_WINCE3 *mainSystem, GameDetector &detector);
+ static CEActions* _instance;
+ OSystem_WINCE3 *_mainSystem;
+ Key _key_action[ACTION_LAST];
+ bool _action_active[ACTION_LAST];
+ bool _action_enabled[ACTION_LAST];
+ unsigned int _action_mapping[ACTION_LAST];
+ bool _mapping_active;
+ bool _right_click_needed;
+ };
+
+#endif \ No newline at end of file
diff --git a/backends/wince/CEDevice.cpp b/backends/wince/CEDevice.cpp
new file mode 100644
index 0000000000..68c559da59
--- /dev/null
+++ b/backends/wince/CEDevice.cpp
@@ -0,0 +1,118 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "stdafx.h"
+#include "CEDevice.h"
+
+bool CEDevice::_hasGAPIMapping = false;
+struct GXKeyList CEDevice::_portrait_keys = {0};
+
+#define KEY_CALENDAR 0xc1
+#define KEY_CONTACTS 0xc2
+#define KEY_INBOX 0xc3
+#define KEY_TASK 0xc4
+
+bool CEDevice::hasPocketPCResolution() {
+ return (GetSystemMetrics(SM_CXSCREEN) < 320 && GetSystemMetrics(SM_CXSCREEN) >= 240);
+}
+
+bool CEDevice::hasDesktopResolution() {
+ return (GetSystemMetrics(SM_CXSCREEN) >= 320);
+}
+
+bool CEDevice::hasWideResolution() {
+ return (GetSystemMetrics(SM_CXSCREEN) >= 640 && GetSystemMetrics(SM_CYSCREEN) >= 480);
+}
+
+bool CEDevice::hasSmartphoneResolution() {
+ return (GetSystemMetrics(SM_CXSCREEN) < 240);
+}
+
+bool CEDevice::enableHardwareKeyMapping() {
+ HINSTANCE GAPI_handle;
+ tGXVoidFunction GAPIOpenInput;
+ tGXGetDefaultKeys GAPIGetDefaultKeys;
+
+ _hasGAPIMapping = false;
+ GAPI_handle = LoadLibrary(TEXT("gx.dll"));
+ if (!GAPI_handle)
+ return false;
+ GAPIOpenInput = (tGXVoidFunction)GetProcAddress(GAPI_handle, TEXT("?GXOpenInput@@YAHXZ"));
+ if (!GAPIOpenInput)
+ return false;
+ GAPIGetDefaultKeys = (tGXGetDefaultKeys)GetProcAddress(GAPI_handle, TEXT("?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z"));
+ if (!GAPIGetDefaultKeys)
+ return false;
+ GAPIOpenInput();
+ _portrait_keys = GAPIGetDefaultKeys(GX_NORMALKEYS);
+ _hasGAPIMapping = true;
+ CloseHandle(GAPI_handle);
+ return true;
+}
+
+bool CEDevice::disableHardwareKeyMapping() {
+ HINSTANCE GAPI_handle;
+ tGXVoidFunction GAPICloseInput;
+
+ GAPI_handle = LoadLibrary(TEXT("gx.dll"));
+ if (!GAPI_handle)
+ return false;
+ GAPICloseInput = (tGXVoidFunction)GetProcAddress(GAPI_handle, TEXT("?GXCloseInput@@YAHXZ"));
+ if (!GAPICloseInput)
+ return false;
+ GAPICloseInput();
+ CloseHandle(GAPI_handle);
+ return true;
+}
+
+Common::String CEDevice::getKeyName(unsigned int keyCode) {
+ char key_name[10];
+
+ if (!keyCode)
+ return "No key";
+ if (keyCode == (unsigned int)_portrait_keys.vkA)
+ return "Button A";
+ if (keyCode == (unsigned int)_portrait_keys.vkB)
+ return "Button B";
+ if (keyCode == (unsigned int)_portrait_keys.vkC)
+ return "Button C";
+ if (keyCode == (unsigned int)_portrait_keys.vkStart)
+ return "Button Start";
+ if (keyCode == (unsigned int)_portrait_keys.vkUp)
+ return "Pad Up";
+ if (keyCode == (unsigned int)_portrait_keys.vkDown)
+ return "Pad Down";
+ if (keyCode == (unsigned int)_portrait_keys.vkLeft)
+ return "Pad Left";
+ if (keyCode == (unsigned int)_portrait_keys.vkRight)
+ return "Pad Right";
+ 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";
+
+ sprintf(key_name, "Key %.4x", keyCode);
+ return key_name;
+}
diff --git a/backends/wince/CEDevice.h b/backends/wince/CEDevice.h
new file mode 100644
index 0000000000..05558f6663
--- /dev/null
+++ b/backends/wince/CEDevice.h
@@ -0,0 +1,49 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#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 bool hasPocketPCResolution();
+ static bool hasDesktopResolution();
+ static bool hasWideResolution();
+ static bool hasSmartphoneResolution();
+ static bool enableHardwareKeyMapping();
+ static bool disableHardwareKeyMapping();
+ static Common::String getKeyName(unsigned int keyCode);
+ private:
+ static bool _hasGAPIMapping;
+ static struct GXKeyList _portrait_keys;
+ typedef int (*tGXVoidFunction)(void);
+ typedef struct GXKeyList (*tGXGetDefaultKeys)(int);
+
+};
+
+#endif \ No newline at end of file
diff --git a/backends/wince/CEKeysDialog.cpp b/backends/wince/CEKeysDialog.cpp
new file mode 100644
index 0000000000..0130ee0432
--- /dev/null
+++ b/backends/wince/CEKeysDialog.cpp
@@ -0,0 +1,123 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "stdafx.h"
+#include "CEKeysDialog.h"
+#include "CEActions.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(160, 20, "Map", kMapCmd, 'M'); // Map
+ addButton(160, 40, "OK", kOKCmd, 'O'); // OK
+ addButton(160, 60, "Cancel", kCloseCmd, 'C'); // Cancel
+
+ _actionsList = new ListWidget(this, 10, 20, 140, 90);
+ _actionsList->setNumberingMode(kListNumberingZero);
+
+ _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);
+
+ // Get actions names
+ Common::StringList l;
+
+ for (int i = 1; i < CEActions::Instance()->size(); i++)
+ l.push_back(CEActions::Instance()->actionName((ActionType)i));
+
+ _actionsList->setList(l);
+
+ _actionSelected = -1;
+ CEActions::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(CEActions::Instance()->getMapping((ActionType)(_actionsList->getSelected() + 1))).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() + 1;
+ sprintf(selection, "Associated key : %s", CEDevice::getKeyName(CEActions::Instance()->getMapping((ActionType)_actionSelected)).c_str());
+ _actionTitle->setLabel("Press the key to associate");
+ _keyMapping->setLabel(selection);
+ _keyMapping->draw();
+ CEActions::Instance()->beginMapping(true);
+ _actionsList->setEnabled(false);
+ }
+ _actionTitle->draw();
+ break;
+ case kOKCmd:
+ CEActions::Instance()->saveMapping();
+ close();
+ break;
+ case kCloseCmd:
+ CEActions::Instance()->loadMapping();
+ close();
+ break;
+ }
+}
+
+void CEKeysDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
+ if (modifiers == 0xff && CEActions::Instance()->mappingActive()) {
+ // GAPI key was selected
+ char selection[100];
+
+ CEActions::Instance()->setMapping((ActionType)_actionSelected, (ascii & 0xff));
+
+ sprintf(selection, "Associated key : %s", CEDevice::getKeyName(CEActions::Instance()->getMapping((ActionType)_actionSelected)).c_str());
+ _actionTitle->setLabel("Choose an action to map");
+ _keyMapping->setLabel(selection);
+ _keyMapping->draw();
+ _actionSelected = -1;
+ _actionsList->setEnabled(true);
+ CEActions::Instance()->beginMapping(false);
+ }
+}
diff --git a/backends/wince/CEKeysDialog.h b/backends/wince/CEKeysDialog.h
new file mode 100644
index 0000000000..6a8cd6bc74
--- /dev/null
+++ b/backends/wince/CEKeysDialog.h
@@ -0,0 +1,45 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#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 \ No newline at end of file
diff --git a/backends/wince/CELauncherDialog.cpp b/backends/wince/CELauncherDialog.cpp
new file mode 100644
index 0000000000..fc2d6d513f
--- /dev/null
+++ b/backends/wince/CELauncherDialog.cpp
@@ -0,0 +1,121 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "stdafx.h"
+#include "CELauncherDialog.h"
+
+#include "base/engine.h"
+
+#include "gui/browser.h"
+#include "gui/message.h"
+
+#include "common/config-manager.h"
+
+using namespace GUI;
+using namespace Common;
+
+
+CELauncherDialog::CELauncherDialog(GameDetector &detector) : GUI::LauncherDialog(detector) {
+}
+
+void CELauncherDialog::addCandidate(String &path, DetectedGameList &candidates) {
+ int idx = -1;
+ DetectedGame result;
+
+ if (candidates.isEmpty())
+ return;
+
+ if (candidates.size() == 1)
+ idx = 0;
+ else {
+ char candidateName[100];
+ 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].name) == 0) {
+ idx = i;
+ break;
+ }
+ }
+ }
+
+ 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.name);
+ 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.name, domain);
+ ConfMan.set("description", result.description, 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(FilesystemNode::kListFilesOnly);
+ DetectedGameList candidates(PluginManager::instance().detectGames(*files));
+ addCandidate(node->path(), candidates);
+ // Then recurse on the subdirectories
+ FSList *dirs = node->listDir(FilesystemNode::kListDirectoriesOnly);
+ for (FSList::ConstIterator 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() == 1 && _browser->runModal()) {
+ // Clear existing domains
+ ConfigManager::DomainMap &domains = (ConfigManager::DomainMap&)ConfMan.getGameDomains();
+ domains.clear();
+ ConfMan.flushToDisk();
+ automaticScanDirectory(_browser->getResult());
+ ConfMan.flushToDisk();
+ updateListing();
+ draw();
+ }
+ else
+ GUILauncherDialog::addGame();
+} \ No newline at end of file
diff --git a/backends/wince/CELauncherDialog.h b/backends/wince/CELauncherDialog.h
new file mode 100644
index 0000000000..c035ca4ec1
--- /dev/null
+++ b/backends/wince/CELauncherDialog.h
@@ -0,0 +1,43 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef CELAUNCHERDIALOG
+#define CELAUNCHERDIALOG
+
+#include "backends/fs/fs.h"
+
+#include "base/gameDetector.h"
+#include "base/plugins.h"
+
+#include "gui/launcher.h"
+
+class CELauncherDialog : public GUI::LauncherDialog {
+public:
+ CELauncherDialog(GameDetector &detector);
+protected:
+ void addGame();
+ void addCandidate(String &path, DetectedGameList &candidates);
+ void automaticScanDirectory(const FilesystemNode *node);
+};
+
+typedef GUI::LauncherDialog GUILauncherDialog;
+
+#endif \ No newline at end of file
diff --git a/backends/wince/CEScaler.cpp b/backends/wince/CEScaler.cpp
new file mode 100644
index 0000000000..5a2a51031d
--- /dev/null
+++ b/backends/wince/CEScaler.cpp
@@ -0,0 +1,76 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "stdafx.h"
+#include "CEScaler.h"
+
+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) = interpolate16_2<565, 3, 1>(color1, color2);
+ *(((uint16 *)work) + 1) = interpolate16_2<565, 1, 1>(color2, color3);
+ *(((uint16 *)work) + 2) = interpolate16_2<565, 1, 3>(color3, color4);
+
+ work += 3 * sizeof(uint16);
+ }
+ srcPtr += srcPitch;
+ dstPtr += dstPitch;
+ }
+}
+
+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--) {
+ i = 0;
+ work = dstPtr;
+
+ for (int i=0; i<width; i+=2) {
+ // Work with 2 pixels on a row and one below
+ uint16 color1 = *(((const uint16 *)srcPtr) + i);
+ uint16 color2 = *(((const uint16 *)srcPtr) + (i + 1));
+ uint16 color3 = *(((const uint16 *)srcPtr) + (i + srcPitch16));
+
+ *(((uint16 *)work) + 0) = interpolate16_3<565, 2, 1, 1>(color1, color2, color3);
+
+ work += 2 * sizeof(uint16);
+ }
+ srcPtr += 2 * srcPitch;
+ dstPtr += dstPitch;
+ }
+}
+
diff --git a/backends/wince/CEScaler.h b/backends/wince/CEScaler.h
new file mode 100644
index 0000000000..05c05abeb6
--- /dev/null
+++ b/backends/wince/CEScaler.h
@@ -0,0 +1,34 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef CESCALER
+#define CESCALER
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+#include "common/scaler.h"
+#include "common/scaler/intern.h"
+
+DECLARE_SCALER(PocketPCPortrait);
+DECLARE_SCALER(PocketPCHalf);
+
+#endif \ No newline at end of file
diff --git a/backends/wince/wince-sdl.cpp b/backends/wince/wince-sdl.cpp
new file mode 100644
index 0000000000..67574b6868
--- /dev/null
+++ b/backends/wince/wince-sdl.cpp
@@ -0,0 +1,1146 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "common/stdafx.h"
+#include "wince-sdl.h"
+
+#include "common/util.h"
+#include "base/gameDetector.h"
+#include "base/engine.h"
+#include "base/plugins.h"
+#include "common/timer.h"
+
+#include "common/config-manager.h"
+
+#include "scumm/scumm.h"
+
+#include "resource.h"
+
+#include "CEActions.h"
+#include "ItemAction.h"
+#include "CEKeysDialog.h"
+
+#include "gui/message.h"
+
+#include "sound/fmopl.h"
+
+
+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"
+
+// Given to the true main, needed for backend adaptation
+
+static GameDetector _gameDetector;
+
+// Static member inits
+
+bool OSystem_WINCE3::_soundMaster = true;
+OSystem::SoundProc OSystem_WINCE3::_originalSoundProc = NULL;
+
+// ********************************************************************************************
+
+// MAIN
+
+extern "C" int scummvm_main(GameDetector &gameDetector, int argc, char **argv);
+
+int SDL_main(int argc, char **argv) {
+ return scummvm_main(_gameDetector, argc, argv);
+}
+
+// ********************************************************************************************
+
+
+// ********************************************************************************************
+
+void drawError(char *error) {
+}
+
+bool isSmartphone(void) {
+ return false;
+}
+
+
+// ********************************************************************************************
+
+OSystem *OSystem_WINCE3_create(int gfx_mode) {
+ return OSystem_SDL_Common::create(gfx_mode);
+}
+
+OSystem *OSystem_WINCE3_create() {
+ return OSystem_SDL_Common::create(GFX_NORMAL);
+}
+
+
+OSystem_SDL_Common *OSystem_SDL_Common::create_intern() {
+ return new OSystem_WINCE3();
+}
+
+OSystem_WINCE3::OSystem_WINCE3()
+ : _hwscreen(0), _scaler_proc(0), _orientationLandscape(false), _newOrientation(false),
+ _panelInitialized(false), _forcePanelInvisible(false), _panelVisible(true),
+ _panelStateForced(false), _addRightClickDown(false), _addRightClickUp(false),
+ _forceHideMouse(false), _freeLook(false)
+{
+ CEDevice::enableHardwareKeyMapping();
+ create_toolbar();
+}
+
+void OSystem_WINCE3::swap_panel_visibility() {
+ if (!_forcePanelInvisible && !_panelStateForced) {
+ _panelVisible = !_panelVisible;
+ _toolbarHandler.setVisible(_panelVisible);
+ }
+}
+
+void OSystem_WINCE3::swap_panel() {
+ if (!_panelStateForced) {
+ if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD)
+ _toolbarHandler.setActive(NAME_MAIN_PANEL);
+ else
+ _toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
+ }
+}
+
+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() {
+ _addRightClickDown = true;
+}
+
+void OSystem_WINCE3::swap_mouse_visibility() {
+ _forceHideMouse = !_forceHideMouse;
+ if (_forceHideMouse)
+ undraw_mouse();
+}
+
+void OSystem_WINCE3::swap_freeLook() {
+ _freeLook = !_freeLook;
+}
+
+void OSystem_WINCE3::create_toolbar() {
+ PanelKeyboard *keyboard;
+
+ // Add the keyboard
+ keyboard = new PanelKeyboard(PANEL_KEYBOARD, _keysBuffer);
+ _toolbarHandler.add(NAME_PANEL_KEYBOARD, *keyboard);
+}
+
+void OSystem_WINCE3::private_sound_proc(void *param, byte *buf, int len) {
+ (*_originalSoundProc)(param, buf, len);
+ if (!_soundMaster)
+ memset(buf, 0, len);
+}
+
+bool OSystem_WINCE3::set_sound_proc(SoundProc proc, void *param, SoundFormat format) {
+ SDL_AudioSpec desired;
+ int thread_priority;
+
+ memset(&desired, 0, sizeof(desired));
+
+ _originalSoundProc = proc;
+ // See if the output frequency is forced by the game
+ if ((_gameDetector._game.features & Scumm::GF_DIGI_IMUSE) ||
+ _gameDetector._targetName == "queen" ||
+ strncmp(_gameDetector._targetName.c_str(), "sword", 5) == 0 ||
+ strncmp(_gameDetector._targetName.c_str(), "sky", 3) == 0)
+ desired.freq = SAMPLES_PER_SEC_NEW;
+ else {
+ if (ConfMan.getBool("CE_high_sample_rate"))
+ desired.freq = SAMPLES_PER_SEC_NEW;
+ else
+ desired.freq = SAMPLES_PER_SEC_OLD;
+ }
+ 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.get("CE_sound_thread_priority").isEmpty()) {
+#ifdef SH3
+ thread_priority = THREAD_PRIORITY_NORMAL;
+#else
+ thread_priority = THREAD_PRIORITY_ABOVE_NORMAL;
+#endif
+ }
+ else
+ thread_priority = ConfMan.getInt("CE_sound_thread_priority");
+
+ desired.thread_priority = thread_priority;
+
+ if (SDL_OpenAudio(&desired, NULL) != 0) {
+ return false;
+ }
+ SDL_PauseAudio(0);
+ return true;
+}
+
+void OSystem_WINCE3::update_game_settings() {
+ // Finish panel initialization
+ if (!_panelInitialized && _gameDetector._targetName.size()) {
+ Panel *panel;
+ _panelInitialized = true;
+ CEActions::init(this, _gameDetector);
+ // Add the main panel
+ panel = new Panel(10, 40);
+ panel->setBackground(IMAGE_PANEL);
+ // Save
+ panel->add(NAME_ITEM_OPTIONS, new ItemAction(ITEM_OPTIONS, ACTION_SAVE));
+ // Skip
+ panel->add(NAME_ITEM_SKIP, new ItemAction(ITEM_SKIP, ACTION_SKIP));
+ // sound
+ panel->add(NAME_ITEM_SOUND, new ItemSwitch(ITEM_SOUND_OFF, ITEM_SOUND_ON, &_soundMaster));
+ // portrait/landscape - screen dependant
+ if (_screenWidth <= 320)
+ panel->add(NAME_ITEM_ORIENTATION, new ItemSwitch(ITEM_VIEW_LANDSCAPE, ITEM_VIEW_PORTRAIT, &_newOrientation));
+ _toolbarHandler.add(NAME_MAIN_PANEL, *panel);
+ _toolbarHandler.setActive(NAME_MAIN_PANEL);
+
+ // Load key mapping
+ CEActions::Instance()->loadMapping();
+
+ // Some games need to map the right click button, signal it here if it wasn't done
+ if (CEActions::Instance()->needsRightClickMapping()) {
+ while (!CEActions::Instance()->getMapping(ACTION_RIGHTCLICK)) {
+ CEKeysDialog *keysDialog = new CEKeysDialog("Map right click action");
+ keysDialog->runModal();
+ if (!CEActions::Instance()->getMapping(ACTION_RIGHTCLICK)) {
+ GUI::MessageDialog alert("You must map a key to the 'Right Click' action to play this game");
+ alert.runModal();
+ }
+ }
+ }
+
+ // Extra warning for Zak Mc Kracken
+ if (strncmp(_gameDetector._targetName.c_str(), "zak", 3) == 0 &&
+ !CEActions::Instance()->getMapping(ACTION_HIDE)) {
+ GUI::MessageDialog alert("Don't forget to map a key to 'Hide Toolbar' action to see the whole inventory");
+ alert.runModal();
+ }
+
+ // Keyboard is active for Monkey 1 or 2
+ if (_gameDetector._targetName == "monkey2" || _gameDetector._targetName == "monkeyvga" ||
+ _gameDetector._targetName == "monkeyega") {
+ _monkeyKeyboard = true;
+ _toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
+ }
+ }
+}
+
+void OSystem_WINCE3::init_size(uint w, uint h) {
+ if (w == 320 && h == 200)
+ h = 240; // use the extra 40 pixels height for the toolbar
+ OSystem_SDL_Common::init_size(w, h);
+ update_game_settings();
+}
+
+void OSystem_WINCE3::load_gfx_mode() {
+ int displayWidth;
+ int displayHeight;
+
+ _full_screen = true; // forced
+ _forceFull = true;
+ _mode_flags |= DF_UPDATE_EXPAND_1_PIXEL;
+
+ _tmpscreen = NULL;
+ _tmpScreenWidth = (_screenWidth + 3);
+
+ _scaleFactorXm = -1;
+ _scaleFactorXd = -1;
+ _scaleFactorYm = -1;
+ _scaleFactorYd = -1;
+
+ _newOrientation = _orientationLandscape = ConfMan.getBool("CE_landscape");
+
+ if (CEDevice::hasPocketPCResolution()) {
+ if (!_orientationLandscape && _screenWidth == 320) {
+ _scaleFactorXm = 3;
+ _scaleFactorXd = 4;
+ _scaleFactorYm = 1;
+ _scaleFactorYd = 1;
+ _scaler_proc = PocketPCPortrait;
+ _mode_flags = 0;
+ }
+ if (_screenWidth == 640) {
+ _scaleFactorXm = 1;
+ _scaleFactorXd = 2;
+ _scaleFactorYm = 1;
+ _scaleFactorYd = 2;
+ _scaler_proc = PocketPCHalf;
+ _mode_flags = 0;
+ }
+ }
+
+ if (CEDevice::hasPocketPCResolution() && _orientationLandscape)
+ _mode = GFX_NORMAL;
+
+ if (_scaleFactorXm < 0) {
+ /* Standard scalers, from the SDL backend */
+ switch(_mode) {
+ case GFX_NORMAL:
+ _scaleFactor = 1;
+ _scaler_proc = Normal1x;
+ break;
+ case GFX_DOUBLESIZE:
+ _scaleFactor = 2;
+ _scaler_proc = Normal2x;
+ break;
+ case GFX_TRIPLESIZE:
+ _scaleFactor = 3;
+ _scaler_proc = Normal3x;
+ break;
+ case GFX_2XSAI:
+ _scaleFactor = 2;
+ _scaler_proc = _2xSaI;
+ break;
+ case GFX_SUPER2XSAI:
+ _scaleFactor = 2;
+ _scaler_proc = Super2xSaI;
+ break;
+ case GFX_SUPEREAGLE:
+ _scaleFactor = 2;
+ _scaler_proc = SuperEagle;
+ break;
+ case GFX_ADVMAME2X:
+ _scaleFactor = 2;
+ _scaler_proc = AdvMame2x;
+ break;
+ case GFX_ADVMAME3X:
+ _scaleFactor = 3;
+ _scaler_proc = AdvMame3x;
+ break;
+ case GFX_HQ2X:
+ _scaleFactor = 2;
+ _scaler_proc = HQ2x;
+ break;
+ case GFX_HQ3X:
+ _scaleFactor = 3;
+ _scaler_proc = HQ3x;
+ break;
+ case GFX_TV2X:
+ _scaleFactor = 2;
+ _scaler_proc = TV2x;
+ break;
+ case GFX_DOTMATRIX:
+ _scaleFactor = 2;
+ _scaler_proc = 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 > GetSystemMetrics(SM_CXSCREEN) &&
+ _scaleFactor * _screenWidth > GetSystemMetrics(SM_CYSCREEN))
+ || (_scaleFactor * _screenHeight > GetSystemMetrics(SM_CXSCREEN) &&
+ _scaleFactor * _screenHeight > GetSystemMetrics(SM_CYSCREEN))) {
+ _scaleFactor = 1;
+ _scaler_proc = Normal1x;
+ }
+
+ // Common scaler system was used
+ if (_scaleFactorXm < 0) {
+ _scaleFactorXm = _scaleFactor;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = _scaleFactor;
+ _scaleFactorYd = 1;
+ }
+
+ //
+ // 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;
+
+ if (!(displayWidth > GetSystemMetrics(SM_CXSCREEN))) { // no rotation
+ displayWidth = GetSystemMetrics(SM_CXSCREEN);
+ displayHeight = GetSystemMetrics(SM_CYSCREEN);
+ }
+
+ _hwscreen = SDL_SetVideoMode(displayWidth, displayHeight, 16, SDL_FULLSCREEN | SDL_SWSURFACE);
+ 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);
+
+ // Need some extra bytes around when using 2xSaI
+ uint16 *tmp_screen = (uint16 *)calloc(_tmpScreenWidth * (_screenHeight + 3), sizeof(uint16));
+ _tmpscreen = SDL_CreateRGBSurfaceFrom(tmp_screen,
+ _tmpScreenWidth, _screenHeight + 3, 16, _tmpScreenWidth * 2,
+ _hwscreen->format->Rmask,
+ _hwscreen->format->Gmask,
+ _hwscreen->format->Bmask,
+ _hwscreen->format->Amask);
+
+ if (_tmpscreen == NULL)
+ error("_tmpscreen failed");
+
+ // 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::unload_gfx_mode() {
+ if (_screen) {
+ SDL_FreeSurface(_screen);
+ _screen = NULL;
+ }
+
+ if (_hwscreen) {
+ SDL_FreeSurface(_hwscreen);
+ _hwscreen = NULL;
+ }
+
+ if (_tmpscreen) {
+ free(_tmpscreen->pixels);
+ SDL_FreeSurface(_tmpscreen);
+ _tmpscreen = NULL;
+ }
+}
+
+void OSystem_WINCE3::hotswap_gfx_mode() {
+ if (!_screen)
+ return;
+
+ // Keep around the old _screen & _tmpscreen so we can restore the screen data
+ // after the mode switch.
+ SDL_Surface *old_screen = _screen;
+ SDL_Surface *old_tmpscreen = _tmpscreen;
+
+ // Release the HW screen surface
+ SDL_FreeSurface(_hwscreen);
+
+ // Setup the new GFX mode
+ load_gfx_mode();
+
+ // 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);
+
+ // Free the old surfaces
+ SDL_FreeSurface(old_screen);
+ free(old_tmpscreen->pixels);
+ SDL_FreeSurface(old_tmpscreen);
+
+ // Blit everything to the screen
+ update_screen();
+
+ // 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 && 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::update_screen() {
+ assert(_hwscreen != NULL);
+
+ Common::StackLock lock(_graphicsMutex, this); // Lock the mutex until this function ends
+
+ 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.
+ draw_mouse();
+
+ // 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;
+ }
+
+ // Force a full redraw if requested
+ if (_forceFull) {
+ _num_dirty_rects = 1;
+
+ _dirty_rect_list[0].x = 0;
+ _dirty_rect_list[0].y = 0;
+ _dirty_rect_list[0].w = _screenWidth;
+ _dirty_rect_list[0].h = _screenHeight;
+
+ _toolbarHandler.forceRedraw();
+ }
+
+ // Only draw anything if necessary
+ if (_num_dirty_rects > 0) {
+
+ SDL_Rect *r;
+ SDL_Rect dst;
+ uint32 srcPitch, dstPitch;
+ SDL_Rect *last_rect = _dirty_rect_list + _num_dirty_rects;
+
+ if (_scaler_proc == Normal1x && !_adjustAspectRatio) {
+ SDL_Surface *target = _overlayVisible ? _tmpscreen : _screen;
+ for (r = _dirty_rect_list; r != last_rect; ++r) {
+ dst = *r;
+
+ if (_overlayVisible) {
+ // FIXME: I don't understand why this is necessary...
+ dst.x--;
+ dst.y--;
+ }
+ dst.y += _currentShakePos;
+ if (SDL_BlitSurface(target, r, _hwscreen, &dst) != 0)
+ error("SDL_BlitSurface failed: %s", SDL_GetError());
+ }
+ } else {
+ if (!_overlayVisible) {
+ for (r = _dirty_rect_list; 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(_screen, r, _tmpscreen, &dst) != 0)
+ error("SDL_BlitSurface failed: %s", SDL_GetError());
+ }
+ }
+
+ SDL_LockSurface(_tmpscreen);
+ SDL_LockSurface(_hwscreen);
+
+ srcPitch = _tmpscreen->pitch;
+ dstPitch = _hwscreen->pitch;
+
+ for (r = _dirty_rect_list; r != last_rect; ++r) {
+ register int dst_y = r->y + _currentShakePos;
+ register int dst_h = 0;
+ register int orig_dst_y = 0;
+
+ 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);
+ }
+
+ _scaler_proc((byte *)_tmpscreen->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);
+ }
+
+ r->x *= _scaleFactorXm;
+ r->x /= _scaleFactorXd;
+ r->y = dst_y;
+ r->w *= _scaleFactorXm;
+ r->w *= _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(_tmpscreen);
+ 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) {
+ _dirty_rect_list[0].y = 0;
+ _dirty_rect_list[0].h = (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactorYm / _scaleFactorYd;
+ }
+ }
+ // FIXME
+ // Add the toolbar if needed
+ SDL_Rect toolbar_rect[1];
+ //if (_toolbarHandler.draw(_tmpscreen, &toolbar_rect[0]) && !_forceFull) {
+ if (_toolbarHandler.draw(_tmpscreen, &toolbar_rect[0])) {
+ // It can be drawn, scale it
+ uint32 srcPitch, dstPitch;
+
+ SDL_LockSurface(_tmpscreen);
+ SDL_LockSurface(_hwscreen);
+ srcPitch = _tmpscreen->pitch;
+ dstPitch = _hwscreen->pitch;
+ _scaler_proc((byte *)_tmpscreen->pixels + (toolbar_rect[0].x * 2 + 2) + (toolbar_rect[0].y + 1) * srcPitch, srcPitch,
+ (byte *)_hwscreen->pixels + (toolbar_rect[0].x * 2 * _scaleFactorXm / _scaleFactorXd) + toolbar_rect[0].y * dstPitch, dstPitch, toolbar_rect[0].w, toolbar_rect[0].h);
+ SDL_UnlockSurface(_tmpscreen);
+ SDL_UnlockSurface(_hwscreen);
+ // And blit it
+ SDL_UpdateRects(_hwscreen, 1, toolbar_rect);
+ }
+ // Finally, blit all our changes to the screen
+ if (_num_dirty_rects > 0)
+ SDL_UpdateRects(_hwscreen, _num_dirty_rects, _dirty_rect_list);
+
+ _num_dirty_rects = 0;
+ _forceFull = false;
+}
+
+uint32 OSystem_WINCE3::property(int param, Property *value) {
+
+ Common::StackLock lock(_graphicsMutex, this); // Lock the mutex until this function ends
+
+ if (param == PROP_TOGGLE_FULLSCREEN) {
+ // FIXME
+ assert(_hwscreen != 0);
+ _full_screen ^= true;
+ if (!SDL_WM_ToggleFullScreen(_hwscreen)) {
+ // if ToggleFullScreen fails, achieve the same effect with hotswap gfx mode
+ hotswap_gfx_mode();
+ }
+ return 1;
+ } else if (param == PROP_SET_GFX_MODE) {
+ if (value->gfx_mode > 11) // FIXME! HACK, hard coded threshold, not good
+ return 0;
+
+ _mode = value->gfx_mode;
+ hotswap_gfx_mode();
+
+ return 1;
+ } else if (param == PROP_TOGGLE_ASPECT_RATIO) {
+ if (_screenHeight == 200) {
+ assert(_hwscreen != 0);
+ _adjustAspectRatio ^= true;
+ hotswap_gfx_mode();
+ }
+ return 1;
+ } else if (param == PROP_TOGGLE_VIRTUAL_KEYBOARD) {
+ if (value->show_keyboard) {
+ _panelStateForced = true;
+ _saveToolbarState = _toolbarHandler.visible();
+ _saveActiveToolbar = _toolbarHandler.activeName();
+ _toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
+ _toolbarHandler.setVisible(true);
+ }
+ else {
+ _panelStateForced = false;
+ _toolbarHandler.setActive(_saveActiveToolbar);
+ _toolbarHandler.setVisible(_saveToolbarState);
+ }
+ return 1;
+ } else if (param == PROP_HAS_SCALER) {
+ switch(value->gfx_mode) {
+ case GFX_NORMAL:
+ return 1;
+ case GFX_DOUBLESIZE:
+ case GFX_2XSAI:
+ case GFX_SUPER2XSAI:
+ case GFX_SUPEREAGLE:
+ case GFX_ADVMAME2X:
+ case GFX_HQ2X:
+ case GFX_TV2X:
+ case GFX_DOTMATRIX:
+ return (CEDevice::hasWideResolution());
+ default:
+ return 0;
+ }
+ } else if (param == PROP_GET_FMOPL_ENV_BITS) { // imuse FM quality
+ if (ConfMan.getBool("CE_FM_high_quality"))
+ return FMOPL_ENV_BITS_HQ;
+ else
+ return FMOPL_ENV_BITS_LQ;
+ } else if (param == PROP_GET_FMOPL_EG_ENT) { // imuse FM quality
+ if (ConfMan.getBool("CE_FM_high_quality"))
+ return FMOPL_EG_ENT_HQ;
+ else
+ return FMOPL_EG_ENT_LQ;
+ }
+
+ return OSystem_SDL_Common::property(param, value);
+}
+
+bool OSystem_WINCE3::save_screenshot(const char *filename) {
+ assert(_hwscreen != NULL);
+
+ Common::StackLock lock(_graphicsMutex, this); // 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 (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::draw_mouse() {
+ // FIXME
+ if (!(_toolbarHandler.visible() && _mouseCurState.y >= 200) && !_forceHideMouse)
+ OSystem_SDL_Common::draw_mouse();
+}
+
+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
+ event.mouse.x *= _scaleFactorXd;
+ event.mouse.x /= _scaleFactorXm;
+ event.mouse.y *= _scaleFactorYd;
+ event.mouse.x /= _scaleFactorYm;
+}
+
+void OSystem_WINCE3::warp_mouse(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.
+
+ set_mouse_pos(x, y);
+ }
+}
+
+void OSystem_WINCE3::add_dirty_rect(int x, int y, int w, int h) {
+ if (_scaler_proc == PocketPCPortrait) {
+ // Align on a 4 bytes boundary for the Portrait mode
+ if (x != 0) {
+ while (x % 4) {
+ x--;
+ w++;
+ }
+ }
+ while (w % 4) w++;
+ }
+
+ OSystem_SDL_Common::add_dirty_rect(x, y, w, h);
+}
+
+// FIXME
+// Remove useless mappings
+
+bool OSystem_WINCE3::poll_event(Event *event) {
+ SDL_Event ev;
+ byte b = 0;
+ Event temp_event;
+
+ // Check if the keys queue is empty
+ Key *key = _keysBuffer->Instance()->get();
+ if (key) {
+ event->kbd.flags = key->flags();
+ event->kbd.ascii = key->ascii();
+ event->kbd.keycode = key->keycode();
+ if (key->pushed())
+ event->event_code = EVENT_KEYDOWN;
+ else
+ event->event_code = EVENT_KEYUP;
+ return true;
+ }
+
+ // Check if a right click event must be generated
+ if (_addRightClickDown || _addRightClickUp) {
+ event->event_code = (_addRightClickDown ? EVENT_RBUTTONDOWN : EVENT_RBUTTONUP);
+ event->mouse.x = _mouseCurState.x;
+ event->mouse.y = _mouseCurState.y;
+
+ if (_addRightClickDown) {
+ _addRightClickDown = false;
+ _addRightClickUp = true;
+ }
+ else {
+ _addRightClickUp = false;
+ }
+
+ return true;
+ }
+
+ kbd_mouse();
+
+ // If the screen mode changed, send an EVENT_SCREEN_CHANGED
+ if (_modeChanged) {
+ _modeChanged = false;
+ event->event_code = EVENT_SCREEN_CHANGED;
+ return true;
+ }
+
+ while(SDL_PollEvent(&ev)) {
+ switch(ev.type) {
+ case SDL_KEYDOWN:
+
+ if (ev.key.keysym.mod & KMOD_SHIFT)
+ b |= KBD_SHIFT;
+ if (ev.key.keysym.mod & KMOD_CTRL)
+ b |= KBD_CTRL;
+ if (ev.key.keysym.mod & KMOD_ALT)
+ b |= KBD_ALT;
+ event->kbd.flags = b;
+
+ // Alt-Return toggles full screen mode
+ if (b == KBD_ALT && ev.key.keysym.sym == SDLK_RETURN) {
+ property(PROP_TOGGLE_FULLSCREEN, NULL);
+ break;
+ }
+
+ if (b == KBD_ALT && ev.key.keysym.sym == 's') {
+ char filename[20];
+
+ for (int n = 0;; n++) {
+ SDL_RWops *file;
+
+ sprintf(filename, "scummvm%05d.bmp", n);
+ file = SDL_RWFromFile(filename, "r");
+ if (!file)
+ break;
+ SDL_RWclose(file);
+ }
+ if (save_screenshot(filename))
+ printf("Saved '%s'\n", filename);
+ else
+ printf("Could not save screenshot!\n");
+ break;
+ }
+
+ // Ctrl-m toggles mouse capture
+ if (b == KBD_CTRL && ev.key.keysym.sym == 'm') {
+ property(PROP_TOGGLE_MOUSE_GRAB, NULL);
+ break;
+ }
+
+ // Ctrl-z and Alt-X quit
+ if ((b == KBD_CTRL && ev.key.keysym.sym == 'z') || (b == KBD_ALT && ev.key.keysym.sym == 'x')) {
+ event->event_code = EVENT_QUIT;
+ return true;
+ }
+
+ // Ctrl-Alt-<key> will change the GFX mode
+ if ((b & (KBD_CTRL|KBD_ALT)) == (KBD_CTRL|KBD_ALT)) {
+ static const int gfxModes[][4] = {
+ { GFX_NORMAL, GFX_DOUBLESIZE, GFX_TRIPLESIZE, -1 },
+ { GFX_NORMAL, GFX_ADVMAME2X, GFX_ADVMAME3X, -1 },
+ { GFX_NORMAL, GFX_HQ2X, GFX_HQ3X, -1 },
+ { GFX_NORMAL, GFX_2XSAI, -1, -1 },
+ { GFX_NORMAL, GFX_SUPER2XSAI, -1, -1 },
+ { GFX_NORMAL, GFX_SUPEREAGLE, -1, -1 },
+ { GFX_NORMAL, GFX_TV2X, -1, -1 },
+ { GFX_NORMAL, GFX_DOTMATRIX, -1, -1 }
+ };
+
+ // FIXME EVIL HACK: This shouldn't be a static int, rather it
+ // should be a member variable. Furthermore, it shouldn't be
+ // set in this code, rather it should be set by load_gfx_mode().
+ // But for now this quick&dirty hack works.
+ static int _scalerType = 0;
+ if (_mode != GFX_NORMAL) {
+ // Try to figure out which gfx mode "group" we are in
+ // This is just a temporary hack until the proper solution
+ // (i.e. code in load_gfx_mode()) is in effect.
+ for (int i = 0; i < ARRAYSIZE(gfxModes); i++) {
+ if (gfxModes[i][1] == _mode || gfxModes[i][2] == _mode) {
+ _scalerType = i;
+ break;
+ }
+ }
+ }
+
+
+ Property prop;
+ int factor = _scaleFactor - 1;
+
+ // Ctrl-Alt-a toggles aspect ratio correction
+ if (ev.key.keysym.sym == 'a') {
+ property(PROP_TOGGLE_ASPECT_RATIO, NULL);
+ break;
+ }
+
+ // Increase/decrease the scale factor
+ // TODO: Shall we 'wrap around' here?
+ if (ev.key.keysym.sym == '=' || ev.key.keysym.sym == '+' || ev.key.keysym.sym == '-') {
+ factor += (ev.key.keysym.sym == '-' ? -1 : +1);
+ if (0 <= factor && factor < 4 && gfxModes[_scalerType][factor] >= 0) {
+ prop.gfx_mode = gfxModes[_scalerType][factor];
+ property(PROP_SET_GFX_MODE, &prop);
+ }
+ break;
+ }
+
+ if ('1' <= ev.key.keysym.sym && ev.key.keysym.sym <= '9') {
+ _scalerType = ev.key.keysym.sym - '1';
+ if (_scalerType >= ARRAYSIZE(gfxModes))
+ break;
+
+ while (gfxModes[_scalerType][factor] < 0) {
+ assert(factor > 0);
+ factor--;
+ }
+ prop.gfx_mode = gfxModes[_scalerType][factor];
+ property(PROP_SET_GFX_MODE, &prop);
+ break;
+ }
+ }
+
+ // Check mapping
+ if (CEActions::Instance()->mappingActive()) {
+ event->event_code = EVENT_KEYDOWN;
+ event->kbd.ascii = (ev.key.keysym.sym ? ev.key.keysym.sym : ev.key.keysym.unicode);
+ event->kbd.flags = 0xff;
+ return true;
+ }
+ else
+ if (CEActions::Instance()->performMapped((ev.key.keysym.sym ? ev.key.keysym.sym : ev.key.keysym.unicode), true))
+ return true;
+
+ event->event_code = 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);
+
+ switch(ev.key.keysym.sym) {
+ case SDLK_LEFT:
+ km.x_vel = -1;
+ km.x_down_count = 1;
+ break;
+ case SDLK_RIGHT:
+ km.x_vel = 1;
+ km.x_down_count = 1;
+ break;
+ case SDLK_UP:
+ km.y_vel = -1;
+ km.y_down_count = 1;
+ break;
+ case SDLK_DOWN:
+ km.y_vel = 1;
+ km.y_down_count = 1;
+ break;
+ default:
+ break;
+ }
+
+ return true;
+
+ case SDL_KEYUP:
+ // Check mapping
+ if (CEActions::Instance()->mappingActive()) {
+ event->event_code = EVENT_KEYUP;
+ event->kbd.ascii = (ev.key.keysym.sym ? ev.key.keysym.sym : ev.key.keysym.unicode);
+ event->kbd.flags = 0xff;
+ return true;
+ }
+ else
+ if (CEActions::Instance()->performMapped((ev.key.keysym.sym ? ev.key.keysym.sym : ev.key.keysym.unicode), false))
+ return true;
+
+ event->event_code = 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);
+
+ switch(ev.key.keysym.sym) {
+ case SDLK_LEFT:
+ if (km.x_vel < 0) {
+ km.x_vel = 0;
+ km.x_down_count = 0;
+ }
+ break;
+ case SDLK_RIGHT:
+ if (km.x_vel > 0) {
+ km.x_vel = 0;
+ km.x_down_count = 0;
+ }
+ break;
+ case SDLK_UP:
+ if (km.y_vel < 0) {
+ km.y_vel = 0;
+ km.y_down_count = 0;
+ }
+ break;
+ case SDLK_DOWN:
+ if (km.y_vel > 0) {
+ km.y_vel = 0;
+ km.y_down_count = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+
+ case SDL_MOUSEMOTION:
+ event->event_code = EVENT_MOUSEMOVE;
+ fillMouseEvent(*event, ev.motion.x, ev.motion.y);
+ set_mouse_pos(event->mouse.x, event->mouse.y);
+ return true;
+
+ case SDL_MOUSEBUTTONDOWN:
+ if (ev.button.button == SDL_BUTTON_LEFT)
+ temp_event.event_code = EVENT_LBUTTONDOWN;
+ else if (ev.button.button == SDL_BUTTON_RIGHT)
+ temp_event.event_code = EVENT_RBUTTONDOWN;
+ else
+ break;
+
+ fillMouseEvent(temp_event, ev.button.x, ev.button.y);
+
+ if (_toolbarHandler.action(temp_event.mouse.x, temp_event.mouse.y, true)) {
+ if (!_toolbarHandler.drawn())
+ update_screen();
+ if (_newOrientation != _orientationLandscape) {
+ _orientationLandscape = _newOrientation;
+ ConfMan.set("CE_landscape", _orientationLandscape);
+ ConfMan.flushToDisk();
+ hotswap_gfx_mode();
+ }
+ }
+ else {
+ if (!_freeLook)
+ memcpy(event, &temp_event, sizeof(Event));
+ }
+
+ return true;
+
+ case SDL_MOUSEBUTTONUP:
+ if (ev.button.button == SDL_BUTTON_LEFT)
+ temp_event.event_code = EVENT_LBUTTONUP;
+ else if (ev.button.button == SDL_BUTTON_RIGHT)
+ temp_event.event_code = EVENT_RBUTTONUP;
+ else
+ break;
+
+ fillMouseEvent(temp_event, ev.button.x, ev.button.y);
+
+ if (_toolbarHandler.action(temp_event.mouse.x, temp_event.mouse.y, false)) {
+ if (!_toolbarHandler.drawn())
+ update_screen();
+ }
+ else {
+ if (!_freeLook)
+ memcpy(event, &temp_event, sizeof(Event));
+ }
+
+ return true;
+
+ case SDL_VIDEOEXPOSE:
+ _forceFull = true;
+ break;
+
+ case SDL_QUIT:
+ event->event_code = EVENT_QUIT;
+ CEDevice::disableHardwareKeyMapping();
+ return true;
+ }
+ }
+ return false;
+}
+
+void OSystem_WINCE3::quit() {
+ CEDevice::disableHardwareKeyMapping();
+ OSystem_SDL_Common::quit();
+} \ No newline at end of file
diff --git a/backends/wince/wince-sdl.h b/backends/wince/wince-sdl.h
new file mode 100644
index 0000000000..420d017b76
--- /dev/null
+++ b/backends/wince/wince-sdl.h
@@ -0,0 +1,125 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef WINCE_SDL_H
+#define WINCE_SDL_H
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+#include "common/scaler.h"
+#include "backends/intern.h"
+#include "backends/sdl/sdl-common.h"
+
+#include "CEgui.h"
+#include "CEkeys.h"
+#include "CEDevice.h"
+#include "CEScaler.h"
+
+#include <SDL.h>
+
+class OSystem_WINCE3 : public OSystem_SDL_Common {
+public:
+ OSystem_WINCE3();
+
+ // Update the dirty areas of the screen
+ void update_screen();
+
+ // Set a parameter
+ uint32 property(int param, Property *value);
+
+ void init_size(uint w, uint h);
+
+ // Overloaded from SDL_Common (toolbar handling)
+ bool poll_event(Event *event);
+ // Overloaded from SDL_Common (toolbar handling)
+ void draw_mouse();
+ // 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 add_dirty_rect(int x, int y, int w, int h);
+ // Overloaded from SDL_Common (new scaler handling)
+ void warp_mouse(int x, int y);
+ // Overloaded from SDL_Commmon
+ void quit();
+ // Overloaded from SDL_Commmon (master volume and sample rate subtleties)
+ bool set_sound_proc(SoundProc proc, void *param, SoundFormat format);
+
+ // GUI and action stuff
+ void swap_panel_visibility();
+ void swap_panel();
+ void swap_sound_master();
+ void add_right_click();
+ void swap_mouse_visibility();
+ void swap_freeLook();
+
+protected:
+ SDL_Surface *_hwscreen; // hardware screen
+
+ ScalerProc *_scaler_proc;
+
+ virtual void load_gfx_mode();
+ virtual void unload_gfx_mode();
+ virtual bool save_screenshot(const char *filename);
+ void hotswap_gfx_mode();
+
+
+private:
+
+ static void private_sound_proc(void *param, byte *buf, int len);
+ static SoundProc _originalSoundProc;
+
+ void create_toolbar();
+ void update_game_settings();
+ void update_keyboard();
+
+ CEKEYS::KeysBuffer *_keysBuffer;
+ CEGUI::ToolbarHandler _toolbarHandler;
+
+ bool _freeLook; // freeLook mode (do not send mouse button events)
+
+ bool _forceHideMouse; // force invisible mouse cursor
+
+ bool _addRightClickDown; // add a right click event (button pushed)
+ bool _addRightClickUp; // add a right click event (button released)
+
+ 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
+ bool _orientationLandscape; // current orientation
+ bool _newOrientation; // new orientation
+
+ bool _saveToolbarState; // save visibility when forced
+ String _saveActiveToolbar; // save active toolbar when forced
+
+ int _scaleFactorXm;
+ int _scaleFactorXd;
+ int _scaleFactorYm;
+ int _scaleFactorYd;
+};
+
+#endif \ No newline at end of file