aboutsummaryrefslogtreecommitdiff
path: root/backends/wince
diff options
context:
space:
mode:
authorNicolas Bacca2003-01-26 21:42:32 +0000
committerNicolas Bacca2003-01-26 21:42:32 +0000
commita6f7fabc462017d5f96d3609dd45328fb67d3dc8 (patch)
treeb47bc4fc805544a5617c88530f1a2108df5ce402 /backends/wince
parent0662e36fef6fa618aadba3a4692b583deb1ea25f (diff)
downloadscummvm-rg350-a6f7fabc462017d5f96d3609dd45328fb67d3dc8.tar.gz
scummvm-rg350-a6f7fabc462017d5f96d3609dd45328fb67d3dc8.tar.bz2
scummvm-rg350-a6f7fabc462017d5f96d3609dd45328fb67d3dc8.zip
Global Windows CE routines
svn-id: r6556
Diffstat (limited to 'backends/wince')
-rw-r--r--backends/wince/wince.cpp1728
1 files changed, 1728 insertions, 0 deletions
diff --git a/backends/wince/wince.cpp b/backends/wince/wince.cpp
new file mode 100644
index 0000000000..f2b6ff155c
--- /dev/null
+++ b/backends/wince/wince.cpp
@@ -0,0 +1,1728 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001/2002 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 "wince.h"
+
+#if _WIN32_WCE >= 300
+
+#include <Aygshell.h>
+
+#else
+
+// Put in include file
+
+typedef enum tagSIPSTATE
+{
+ SIP_UP = 0,
+ SIP_DOWN,
+ SIP_FORCEDOWN,
+ SIP_UNCHANGED,
+ SIP_INPUTDIALOG,
+} SIPSTATE;
+
+#define SHFS_SHOWTASKBAR 0x0001
+#define SHFS_HIDETASKBAR 0x0002
+#define SHFS_SHOWSIPBUTTON 0x0004
+#define SHFS_HIDESIPBUTTON 0x0008
+#define SHFS_SHOWSTARTICON 0x0010
+#define SHFS_HIDESTARTICON 0x0020
+
+typedef struct
+{
+ DWORD cbSize;
+ HWND hwndLastFocus;
+ UINT fSipUp :1;
+ UINT fSipOnDeactivation :1;
+ UINT fActive :1;
+ UINT fReserved :29;
+} SHACTIVATEINFO, *PSHACTIVATEINFO;
+
+#endif
+
+
+#define CURRENT_KEYS_VERSION 3
+
+typedef int (*tTimeCallback)(int);
+typedef void SoundProc(void *param, byte *buf, int len);
+
+// Dynamically linked Aygshell
+typedef BOOL (*tSHFullScreen)(HWND,DWORD);
+//typedef BOOL (WINSHELLAPI *tSHHandleWMSettingChange)(HWND,WPARAM,LPARAM,SHACTIVATEINFO*);
+typedef BOOL (*tSHSipPreference)(HWND,SIPSTATE);
+typedef BOOL (*tSHCreateMenuBar)(void*);
+
+/*
+// Dynamically linked SDLAudio
+typedef void (*tSDL_AudioQuit)(void);
+typedef int (*tSDL_Init)(Uint32);
+typedef void (*tSDL_PauseAudio)(int);
+typedef int (*tSDL_OpenAudio)(SDL_AudioSpec*, SDL_AudioSpec*);
+*/
+
+// GAPI "emulation"
+typedef struct pseudoGAPI {
+ const TCHAR *device;
+ void *buffer;
+ int xWidth;
+ int yHeight;
+ int xPitch;
+ int yPitch;
+ int BPP;
+ int format;
+} pseudoGAPI;
+
+typedef struct {
+ int x, y, w, h;
+} dirty_square;
+
+#define AddDirtyRect(xi,yi,wi,hi) \
+ if (num_of_dirty_square < MAX_NUMBER_OF_DIRTY_SQUARES) { \
+ if (smartphone) { /* Align dirty rect for smartphone */ \
+ register int offsetX = xi % 3; \
+ register int offsetY = yi % 8; \
+ register int newX = (xi < 3 ? 0 : xi - offsetX); \
+ register int newY = (yi < 8 ? 0 : yi - offsetY); \
+ ds[num_of_dirty_square].x = newX; \
+ ds[num_of_dirty_square].y = newY; \
+ ds[num_of_dirty_square].w = wi + offsetX; \
+ ds[num_of_dirty_square].h = hi + offsetY; \
+ } \
+ else { \
+ ds[num_of_dirty_square].x = xi; \
+ ds[num_of_dirty_square].y = yi; \
+ ds[num_of_dirty_square].w = wi; \
+ ds[num_of_dirty_square].h = hi; \
+ } \
+ num_of_dirty_square++; \
+ }
+
+
+/* Hardcode the video buffer for some devices for which there is no GAPI */
+/* and no GameX support */
+
+pseudoGAPI availablePseudoGAPI[] = {
+ { TEXT("HP, Jornada 710"),
+ (void*)0x82200000,
+ 640,
+ 240,
+ 2,
+ 1280,
+ 16,
+ 0xA8
+ },
+ { TEXT("HP, Jornada 720"),
+ (void*)0x82200000,
+ 640,
+ 240,
+ 2,
+ 1280,
+ 16,
+ 0xA8
+ },
+ { TEXT("Compaq iPAQ H3600"), /* this is just a test for my device :) */
+ (void*)0xAC05029E,
+ 240,
+ 320,
+ 640,
+ -2,
+ 16,
+ 0xA8
+ },
+ { 0, 0, 0, 0, 0, 0, 0, 0 }
+};
+
+int _pseudoGAPI_device;
+
+int _thread_priority;
+
+bool canCacheGAPIBuffer;
+
+
+extern char noGAPI;
+
+
+
+extern float _screen_factor;
+
+/* Default SDLAUDIO */
+
+/*
+
+void defaultSDL_AudioQuit() {
+}
+
+int defaultSDL_Init(Uint32 flags) {
+ return 0;
+}
+
+void defaultSDL_PauseAudio(int pause) {
+}
+
+int defaultSDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) {
+ return 0;
+}
+
+*/
+
+/* Default AYGSHELL */
+
+BOOL defaultSHFullScreen(HWND handle, DWORD action) {
+ if ((action & SHFS_HIDETASKBAR) != 0 || (action & SHFS_SHOWTASKBAR) != 0) {
+ // Hide taskbar, WinCE 2.x style - from EasyCE
+ HKEY hKey=0;
+ DWORD dwValue = 0;
+ unsigned long lSize = sizeof( DWORD );
+ DWORD dwType = REG_DWORD;
+ MSG msg;
+
+
+ RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("\\software\\microsoft\\shell"), 0, KEY_ALL_ACCESS, &hKey );
+ RegQueryValueEx( hKey, TEXT("TBOpt"), 0, &dwType, (BYTE*)&dwValue, &lSize );
+ if ((action & SHFS_SHOWTASKBAR) != 0)
+ dwValue &= 0xFFFFFFFF - 8;// reset bit to show taskbar
+ else dwValue |= 8; // set bit to hide taskbar
+ RegSetValueEx( hKey, TEXT("TBOpt"), 0, REG_DWORD, (BYTE*)&dwValue, lSize );
+ msg.hwnd = FindWindow( TEXT("HHTaskBar"), NULL );
+ SendMessage( msg.hwnd, WM_COMMAND, 0x03EA, 0 );
+ if (handle)
+ SetForegroundWindow( handle );
+ }
+
+ return TRUE;
+}
+
+/*
+BOOL WINSHELLAPI defaultSHHandleWMSettingChange(HWND handle, WPARAM param1, LPARAM param2, SHACTIVATEINFO *info) {
+ return TRUE;
+}
+*/
+
+BOOL defaultSHSipPreference(HWND handle, SIPSTATE state) {
+ return TRUE;
+}
+
+/* Default GAPI */
+
+int defaultGXOpenDisplay(HWND hWnd, DWORD dwFlags) {
+ return GAPI_SIMU;
+}
+
+int defaultGXCloseDisplay() {
+ return 0;
+}
+
+
+void* defaultGXBeginDraw() {
+ return availablePseudoGAPI[_pseudoGAPI_device].buffer;
+}
+
+int defaultGXEndDraw() {
+ return 0;
+}
+
+int defaultGXOpenInput() {
+ return 0;
+}
+
+int defaultGXCloseInput() {
+ return 0;
+}
+
+GXDisplayProperties defaultGXGetDisplayProperties() {
+ GXDisplayProperties result;
+
+ result.cxWidth = availablePseudoGAPI[_pseudoGAPI_device].xWidth;
+ result.cyHeight = availablePseudoGAPI[_pseudoGAPI_device].yHeight;
+ result.cbxPitch = availablePseudoGAPI[_pseudoGAPI_device].xPitch;
+ result.cbyPitch = availablePseudoGAPI[_pseudoGAPI_device].yPitch;
+ result.cBPP = availablePseudoGAPI[_pseudoGAPI_device].BPP;
+ result.ffFormat = availablePseudoGAPI[_pseudoGAPI_device].format;
+
+ return result;
+}
+
+GXKeyList defaultGXGetDefaultKeys(int options) {
+ GXKeyList result;
+
+ memset(&result, 0xff, sizeof(result));
+
+ return result;
+}
+
+int defaultGXSuspend() {
+ return 0;
+}
+
+int defaultGXResume() {
+ return 0;
+}
+
+/* GAMEX GAPI emulation */
+
+#ifdef GAMEX
+
+GameX *gameX;
+
+int gameXGXOpenDisplay(HWND hWnd, DWORD dwFlags) {
+ gameX = new GameX();
+ if (!gameX || !gameX->OpenGraphics() || !gameX->GetFBAddress()) {
+ //MessageBox(NULL, TEXT("Couldn't initialize GameX. Reverting to GDI graphics"), TEXT("PocketScumm rendering"), MB_OK);
+ noGAPI = 1;
+ }
+ return 0;
+}
+
+int gameXGXCloseDisplay() {
+ gameX->CloseGraphics();
+ delete gameX;
+ return 0;
+}
+
+
+void* gameXGXBeginDraw() {
+ gameX->BeginDraw();
+ return (gameX->GetFBAddress());
+}
+
+int gameXGXEndDraw() {
+ return gameX->EndDraw();
+}
+
+int gameXGXOpenInput() {
+ return 0;
+}
+
+int gameXGXCloseInput() {
+ return 0;
+}
+
+GXDisplayProperties gameXGXGetDisplayProperties() {
+ GXDisplayProperties result;
+
+ result.cBPP = gameX->GetFBBpp();
+ if (result.cBPP == 16)
+ result.cbxPitch = 2;
+ else
+ result.cbxPitch = 1;
+ result.cbyPitch = gameX->GetFBModulo();
+
+ return result;
+}
+
+GXKeyList gameXGXGetDefaultKeys(int options) {
+ GXKeyList result;
+
+ memset(&result, 0xff, sizeof(result));
+
+ return result;
+}
+
+int gameXGXSuspend() {
+ return 0;
+}
+
+int gameXGXResume() {
+ return 0;
+}
+
+#endif
+
+GameDetector detector;
+Engine *engine;
+bool is_simon;
+NewGui *g_gui;
+extern Scumm *g_scumm;
+//extern SimonState *g_simon;
+//OSystem *g_system;
+//SoundMixer *g_mixer;
+Config *g_config;
+tTimeCallback timer_callback;
+int timer_interval;
+
+tSHFullScreen dynamicSHFullScreen = NULL;
+//tSHHandleWMSettingChange dynamicSHHandleWMSettingChange = NULL;
+tSHSipPreference dynamicSHSipPreference = NULL;
+tSHCreateMenuBar dynamicSHCreateMenuBar = NULL;
+tGXOpenInput dynamicGXOpenInput = NULL;
+tGXGetDefaultKeys dynamicGXGetDefaultKeys = NULL;
+tGXCloseDisplay dynamicGXCloseDisplay = NULL;
+tGXCloseInput dynamicGXCloseInput = NULL;
+tGXSuspend dynamicGXSuspend = NULL;
+tGXResume dynamicGXResume = NULL;
+tGXGetDisplayProperties dynamicGXGetDisplayProperties = NULL;
+tGXOpenDisplay dynamicGXOpenDisplay = NULL;
+tGXEndDraw dynamicGXEndDrawInternal = NULL;
+tGXBeginDraw dynamicGXBeginDrawInternal = NULL;
+tGXEndDraw dynamicGXEndDraw = NULL;
+tGXBeginDraw dynamicGXBeginDraw = NULL;
+
+
+extern void Cls();
+
+extern BOOL isPrescanning();
+extern void changeScanPath();
+extern void startScan();
+extern void endScanPath();
+extern void abortScanPath();
+
+void load_key_mapping();
+void keypad_init();
+
+extern void Cls();
+
+extern BOOL isPrescanning();
+extern void changeScanPath();
+extern void startScan();
+extern void endScanPath();
+extern void abortScanPath();
+
+void keypad_init();
+
+/************* WinCE Specifics *****************/
+byte veryFastMode;
+
+bool sound_activated, terminated;
+HWND hWnd_MainMenu;
+HWND hWnd_Window;
+
+void drawAllToolbar(bool);
+void redrawSoundItem();
+
+extern bool toolbar_drawn;
+extern bool draw_keyboard;
+bool hide_toolbar;
+bool hide_cursor;
+bool save_hide_toolbar;
+bool keyboard_override;
+
+bool _get_key_mapping;
+static char _directory[MAX_PATH];
+bool select_game;
+bool need_GAPI;
+
+bool gfx_mode_switch;
+
+dirty_square ds[MAX_NUMBER_OF_DIRTY_SQUARES];
+int num_of_dirty_square;
+
+
+SoundProc *real_soundproc;
+
+extern void startFindGame();
+extern void displayGameInfo();
+extern bool loadGameSettings(void);
+extern void setFindGameDlgHandle(HWND);
+extern void getSelectedGame(int, char*, TCHAR*);
+extern void runGame(char*);
+
+extern void palette_update();
+
+extern void own_soundProc(void *buffer, byte *samples, int len);
+
+extern int chooseGame(void);
+
+//#define SHMenuBar_GetMenu(hWndMB,ID_MENU) (HMENU)SendMessage((hWndMB), SHCMBM_GETSUBMENU, (WPARAM)0, (LPARAM)ID_MENU)
+
+/* Monkey Island 1 and 2 keyboard stuff (copy protection) */
+bool monkey_keyboard;
+
+bool new_audio_rate;
+
+bool closing = false;
+
+/* Check platform */
+bool smartphone = false;
+
+void close_GAPI() {
+ g_config->setBool("Sound", sound_activated, "wince");
+ g_config->setInt("DisplayMode", GetScreenMode(), "wince");
+ g_config->flush();
+ dynamicSHFullScreen(hWnd_Window, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON);
+ dynamicGXCloseInput();
+ dynamicGXCloseDisplay();
+ SDL_AudioQuit();
+ UpdateWindow(hWnd_Window);
+ closing = true;
+}
+
+void do_quit() {
+ close_GAPI();
+ exit(1);
+}
+
+void Error(LPCTSTR msg)
+{
+ OutputDebugString(msg);
+ MessageBox(HWND_DESKTOP, msg, TEXT("Error"), MB_ICONSTOP);
+ exit(1);
+}
+
+void Warning(LPCTSTR msg)
+{
+ OutputDebugString(msg);
+ MessageBox(HWND_DESKTOP, msg, TEXT("Error"), MB_ICONSTOP);
+}
+
+int mapKey(int key) {
+ if (key>=VK_F1 && key<=VK_F9) {
+ return key - VK_F1 + 315;
+ }
+ return key;
+}
+
+
+#define IMPORT(Handle,Variable,Type,Function, Replace) \
+ Variable = (Type)GetProcAddress(Handle, TEXT(Function)); \
+ if (!Variable) { \
+ if (Replace) { \
+ Variable = Replace; \
+ } \
+ else { \
+ MessageBox(NULL, TEXT(Function), TEXT("Error importing DLL function"), MB_OK); \
+ exit(1); \
+ } \
+ }
+
+
+void* dynamicGXBeginDrawCached() {
+ static bool checked = false;
+ static void* buffer;
+
+ if (!checked) {
+ checked = true;
+ canCacheGAPIBuffer = !dynamicGXIsDisplayDRAMBuffer();
+ if (canCacheGAPIBuffer) {
+ buffer = dynamicGXBeginDrawInternal();
+ return buffer;
+ }
+ else {
+ dynamicGXBeginDraw = dynamicGXBeginDrawInternal;
+ return dynamicGXBeginDrawInternal();
+ }
+ }
+
+ return buffer;
+}
+
+int dynamicGXEndDrawCached() {
+ if (!canCacheGAPIBuffer)
+ return dynamicGXEndDrawInternal();
+
+ return 1;
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
+{
+
+ TCHAR directory[MAX_PATH];
+ char game_name[100];
+ bool sound;
+ int version;
+ int result;
+
+ HMODULE aygshell_handle;
+ //HMODULE SDLAudio_handle;
+ HMODULE GAPI_handle;
+
+ // Check platform
+ smartphone = (GetSystemMetrics(SM_CXSCREEN) < 320 && GetSystemMetrics(SM_CYSCREEN) < 320);
+
+ hide_toolbar = false;
+ noGAPI = 0;
+
+ g_config = new Config("scummvm.ini", "scummvm");
+ g_config->set_writing(true);
+
+ // See if we're running on a Windows CE version supporting aygshell
+ aygshell_handle = LoadLibrary(TEXT("aygshell.dll"));
+ if (aygshell_handle) {
+ IMPORT(aygshell_handle, dynamicSHFullScreen, tSHFullScreen, "SHFullScreen", defaultSHFullScreen)
+ IMPORT(aygshell_handle, dynamicSHSipPreference, tSHSipPreference, "SHSipPreference", NULL)
+ if (smartphone)
+ IMPORT(aygshell_handle, dynamicSHCreateMenuBar, tSHCreateMenuBar, "SHCreateMenuBar", NULL)
+ // This function doesn't seem to be implemented on my 3630 !
+ //IMPORT(aygshell_handle, dynamicSHHandleWMSettingChange, tSHHandleWMSettingChange, "SHHandleWMSettingChange")
+
+ } else {
+ dynamicSHFullScreen = defaultSHFullScreen;
+ dynamicSHSipPreference = defaultSHSipPreference;
+ //dynamicSHHandleWMSettingChange = defaultSHHandleWMSettingChange;
+ }
+
+ // See if GX.dll is present
+ GAPI_handle = LoadLibrary(TEXT("gx.dll"));
+ if (GAPI_handle) {
+ IMPORT(GAPI_handle, dynamicGXOpenInput, tGXOpenInput, "?GXOpenInput@@YAHXZ", NULL)
+ IMPORT(GAPI_handle, dynamicGXGetDefaultKeys, tGXGetDefaultKeys, "?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z", NULL)
+ IMPORT(GAPI_handle, dynamicGXCloseDisplay, tGXCloseDisplay, "?GXCloseDisplay@@YAHXZ", NULL)
+ IMPORT(GAPI_handle, dynamicGXCloseInput, tGXCloseInput, "?GXCloseInput@@YAHXZ", NULL)
+ IMPORT(GAPI_handle, dynamicGXSuspend, tGXSuspend, "?GXSuspend@@YAHXZ", NULL)
+ IMPORT(GAPI_handle, dynamicGXResume, tGXResume, "?GXResume@@YAHXZ", NULL)
+ IMPORT(GAPI_handle, dynamicGXGetDisplayProperties, tGXGetDisplayProperties, "?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ", NULL)
+ IMPORT(GAPI_handle, dynamicGXOpenDisplay, tGXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z", NULL)
+ IMPORT(GAPI_handle, dynamicGXEndDrawInternal, tGXEndDraw, "?GXEndDraw@@YAHXZ", NULL)
+ IMPORT(GAPI_handle, dynamicGXBeginDrawInternal, tGXBeginDraw, "?GXBeginDraw@@YAPAXXZ", NULL)
+ IMPORT(GAPI_handle, dynamicGXIsDisplayDRAMBuffer, tGXIsDisplayDRAMBuffer, "?GXIsDisplayDRAMBuffer@@YAHXZ", NULL);
+ dynamicGXBeginDraw = dynamicGXBeginDrawCached;
+ dynamicGXEndDraw = dynamicGXEndDrawCached;
+ gfx_mode_switch = !smartphone;
+ } else {
+
+#ifndef GAMEX
+
+ TCHAR oeminfo[MAX_PATH];
+ int i = 0;
+
+ SystemParametersInfo(SPI_GETOEMINFO, sizeof(oeminfo), oeminfo, 0);
+
+ while (availablePseudoGAPI[i].device) {
+ if (!_tcsncmp(oeminfo, availablePseudoGAPI[i].device, _tcslen(availablePseudoGAPI[i].device))) {
+ _pseudoGAPI_device = i;
+ break;
+ }
+ i++;
+ }
+
+ if (!availablePseudoGAPI[i].device) {
+ noGAPI = 1;
+ }
+ else {
+ FILE *test;
+
+ test = fopen("NoDirectVideo", "r");
+ if (test) {
+ noGAPI = 1;
+ fclose(test);
+ }
+ else
+ if (g_config->getBool("NoDirectVideo", false, "wince"))
+ noGAPI = 1;
+ }
+
+ dynamicGXOpenInput = defaultGXOpenInput;
+ dynamicGXGetDefaultKeys = defaultGXGetDefaultKeys;
+ dynamicGXCloseDisplay = defaultGXCloseDisplay;
+ dynamicGXCloseInput = defaultGXCloseInput;
+ dynamicGXSuspend = defaultGXSuspend;
+ dynamicGXResume = defaultGXResume;
+ dynamicGXGetDisplayProperties = defaultGXGetDisplayProperties;
+ dynamicGXOpenDisplay = defaultGXOpenDisplay;
+ dynamicGXEndDraw = defaultGXEndDraw;
+ dynamicGXBeginDraw = defaultGXBeginDraw;
+
+#else
+ dynamicGXOpenInput = gameXGXOpenInput;
+ dynamicGXGetDefaultKeys = gameXGXGetDefaultKeys;
+ dynamicGXCloseDisplay = gameXGXCloseDisplay;
+ dynamicGXCloseInput = gameXGXCloseInput;
+ dynamicGXSuspend = gameXGXSuspend;
+ dynamicGXResume = gameXGXResume;
+ dynamicGXGetDisplayProperties = gameXGXGetDisplayProperties;
+ dynamicGXOpenDisplay = gameXGXOpenDisplay;
+ dynamicGXEndDraw = gameXGXEndDraw;
+ dynamicGXBeginDraw = gameXGXBeginDraw;
+
+ FILE *test;
+
+ test = fopen("NoGameX", "r");
+ if (test) {
+ noGAPI = 1;
+ fclose(test);
+ }
+ else
+ if (g_config->getBool("NoGameX", false, "wince"))
+ noGAPI = 1;
+
+#endif
+
+ gfx_mode_switch = false;
+ }
+
+ sound = g_config->getBool("Sound", true, "wince");
+ if (sound)
+ sound_activated = sound;
+ else
+ sound_activated = true;
+
+ _thread_priority = g_config->getInt("SoundThreadPriority", -1, "wince");
+ if (_thread_priority < 0) {
+#ifdef SH3
+ _thread_priority = THREAD_PRIORITY_NORMAL;
+#else
+ //_thread_priority = THREAD_PRIORITY_ABOVE_NORMAL;
+ _thread_priority = THREAD_PRIORITY_NORMAL;
+
+#endif
+ g_config->setInt("SoundThreadPriority", _thread_priority, "wince");
+ g_config->flush();
+ }
+
+ select_game = true;
+ need_GAPI = !smartphone;
+
+ /* Create the main window */
+ WNDCLASS wcex;
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = (WNDPROC)OSystem_WINCE3::WndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hInstance;
+ wcex.hIcon = 0;
+ wcex.hCursor = NULL;
+ wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+ wcex.lpszMenuName = 0;
+ wcex.lpszClassName = TEXT("ScummVM");
+ if (!RegisterClass(&wcex))
+ Error(TEXT("Cannot register window class!"));
+
+ hWnd_Window = CreateWindow(TEXT("ScummVM"), TEXT("ScummVM"), WS_VISIBLE,
+ 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, GetModuleHandle(NULL), NULL);
+
+ ShowWindow(hWnd_Window, SW_SHOW);
+ UpdateWindow(hWnd_Window);
+
+ if (smartphone) {
+ if (SmartphoneInitialMenu(hInstance, hWnd_Window, game_name, directory))
+ return 0;
+ need_GAPI = true;
+ }
+
+ if (GraphicsOn(hWnd_Window, gfx_mode_switch)) { // open GAPI in Portrait mode
+
+ MessageBox(NULL, TEXT("Couldn't initialize display !"), TEXT("PocketSCUMM error"), MB_OK);
+
+ return 0;
+
+ }
+ GAPIKeysInit();
+ Cls();
+
+ // Hide taskbar
+ SetWindowPos(hWnd_Window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+ SetForegroundWindow(hWnd_Window);
+ dynamicSHFullScreen(hWnd_Window, SHFS_HIDESIPBUTTON | SHFS_HIDETASKBAR | SHFS_HIDESTARTICON);
+
+ if (!smartphone) {
+
+ result = chooseGame();
+
+ if (result < 0)
+ return 0;
+
+ getSelectedGame(result, game_name, directory);
+ }
+
+ WideCharToMultiByte(CP_ACP, 0, directory, wcslen(directory) + 1, _directory, sizeof(_directory), NULL, NULL);
+ strcat(_directory, "\\");
+
+ runGame(game_name);
+
+ return 0;
+}
+
+void runGame(char *game_name) {
+ int argc = 4;
+ char* argv[4];
+ char argdir[MAX_PATH];
+ char music[100];
+ bool no_music;
+
+ select_game = false;
+
+ argv[0] = NULL;
+ sprintf(argdir, "-p%s", _directory);
+ argv[1] = argdir;
+
+
+ no_music = g_config->getBool("NoMusic", false, "wince");
+ //sprintf(music, "-e%s", (no_music ? "null" : "wince"));
+ sprintf(music, "-e%s", (no_music ? "null" : "adlib"));
+
+ //sprintf(music, "-enull");
+
+ argv[2] = music;
+ argv[3] = game_name;
+
+ if (!argv[3])
+ return;
+
+ // No default toolbar for zak256
+ /*
+ if (strcmp(game_name, "zak256") == 0)
+ hide_toolbar = true;
+ */
+
+ // Keyboard activated for Monkey Island 2 and Monkey 1 floppy
+ if (strcmp(game_name, "monkey2") == 0 ||
+ strcmp(game_name, "monkeyvga") == 0) {
+ draw_keyboard = true;
+ monkey_keyboard = true;
+ }
+
+ //new_audio_rate = (strcmp(game_name, "dig") == 0 || strcmp(game_name, "monkey") == 0);
+ new_audio_rate = (strcmp(game_name, "dig") == 0 || strcmp(game_name, "ft") == 0);
+
+ detector.parseCommandLine(argc, argv);
+
+ if (detector.detectMain())
+ //return (-1);
+ return;
+
+ OSystem *system = detector.createSystem();
+
+ //g_system = system;
+ g_gui = new NewGui(system);
+
+ /* Start the engine */
+
+ is_simon = (detector._gameId >= GID_SIMON_FIRST);
+
+ if (smartphone || detector._gameId == GID_SAMNMAX || detector._gameId == GID_FT || detector._gameId == GID_DIG)
+ hide_cursor = FALSE;
+ else
+ hide_cursor = TRUE;
+
+ engine = Engine::createFromDetector(&detector, system);
+
+ keypad_init();
+ load_key_mapping();
+
+ engine->go();
+
+ //return 0;
+}
+
+
+
+LRESULT CALLBACK OSystem_WINCE3::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static SHACTIVATEINFO sai;
+
+ OSystem_WINCE3 *wm = NULL;
+
+ if (!select_game)
+ wm = (OSystem_WINCE3*)GetWindowLong(hWnd, GWL_USERDATA);
+
+ if (!select_game && monkey_keyboard && (
+ g_scumm->_vars[g_scumm->VAR_ROOM] != 108 && // monkey 2
+ g_scumm->_vars[g_scumm->VAR_ROOM] != 90)) { // monkey 1 floppy
+ monkey_keyboard = false;
+ draw_keyboard = false;
+ toolbar_drawn = false;
+ }
+
+ if (smartphone) {
+ if (SmartphoneWndProc(hWnd, message, wParam, lParam, wm))
+ return 0;
+ }
+ else
+ if (PPCWndProc(hWnd, message, wParam, lParam, wm))
+ return 0;
+
+ switch (message)
+ {
+ case WM_CREATE:
+
+ memset(&sai, 0, sizeof(sai));
+ if (need_GAPI)
+ dynamicSHSipPreference(hWnd, SIP_FORCEDOWN);
+// SHSipPreference(hWnd, SIP_INPUTDIALOG);
+
+ return 0;
+
+ case WM_DESTROY:
+ case WM_CLOSE:
+ if (need_GAPI)
+ GraphicsOff();
+ PostQuitMessage(0);
+ break;
+
+ case WM_ERASEBKGND:
+ {
+
+ if (!need_GAPI) {
+ RECT rc;
+ HDC hDC;
+ GetClientRect(hWnd, &rc);
+ hDC = GetDC(hWnd);
+ FillRect(hDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH));
+ ReleaseDC(hWnd, hDC);
+ }
+ }
+ return 1;
+
+ case WM_PAINT:
+ {
+ HDC hDC;
+ PAINTSTRUCT ps;
+
+ if (!need_GAPI)
+ return DefWindowProc(hWnd, message, wParam, lParam);
+
+ hDC = BeginPaint (hWnd, &ps);
+ EndPaint (hWnd, &ps);
+
+ if (!hide_toolbar)
+ toolbar_drawn = false;
+
+ /*
+ if(!GetScreenMode()) {
+ SHSipPreference(hWnd, SIP_UP);
+ } else {
+ SHSipPreference(hWnd, SIP_FORCEDOWN);
+ }
+ */
+ dynamicSHSipPreference(hWnd, SIP_FORCEDOWN);
+ }
+// SHSipPreference(hWnd, SIP_UP); /* Hack! */
+ /* It does not happen often but I don't want to see tooltip traces */
+ if (!select_game)
+ wm->update_screen();
+ return 0;
+
+ case WM_ACTIVATE:
+ case WM_SETFOCUS:
+ if (!need_GAPI) {
+ SetFocus(hWnd);
+ break;
+ }
+ GraphicsResume();
+ if (!hide_toolbar)
+ toolbar_drawn = false;
+// SHHandleWMActivate(hWnd, wParam, lParam, &sai, SHA_INPUTDIALOG);
+
+ dynamicSHSipPreference(hWnd, SIP_FORCEDOWN);
+ dynamicSHFullScreen(hWnd, SHFS_HIDETASKBAR);
+ MoveWindow(hWnd, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), TRUE);
+ SetCapture(hWnd);
+
+ /*
+ if (LOWORD(wParam) == WA_ACTIVE) {
+ if (GetScreenMode()) {
+ SHSipPreference(hWnd, SIP_FORCEDOWN);
+ SHFullScreen(hWnd, SHFS_HIDETASKBAR);
+ MoveWindow(hWnd, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), TRUE);
+ SetCapture(hWnd);
+ }
+ else {
+ SHFullScreen(hWnd, SHFS_SHOWTASKBAR);
+ MoveWindow(hWnd, 0, 0, GetSystemMetrics(SM_CYSCREEN), GetSystemMetrics(SM_CXSCREEN), TRUE);
+ }
+ }
+ */
+
+ return 0;
+
+ case WM_HIBERNATE:
+ case WM_KILLFOCUS:
+ GraphicsSuspend();
+ if (!hide_toolbar)
+ toolbar_drawn = false;
+ return 0;
+
+ case WM_SETTINGCHANGE:
+ //not implemented ?
+ //dynamicSHHandleWMSettingChange(hWnd, wParam, lParam, &sai);
+ if (!hide_toolbar)
+ toolbar_drawn = false;
+ return 0;
+
+ case WM_COMMAND:
+ return 0;
+
+ case WM_TIMER:
+ timer_callback(timer_interval);
+ break;
+ default:
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+ return 0;
+}
+
+/*************** Specific config support ***********/
+
+void load_key_mapping() {
+// unsigned char actions[TOTAL_ACTIONS];
+ unsigned int actions_keys[TOTAL_ACTIONS];
+ const char *current;
+ int version;
+ int i;
+
+ memset(actions_keys, 0, sizeof(actions_keys));
+
+ version = g_config->getInt("KeysVersion", 0, "wince");
+
+ memset(actions_keys, 0, TOTAL_ACTIONS);
+
+ current = g_config->get("ActionKeys", "wince");
+ if (current && version == CURRENT_KEYS_VERSION) {
+ for (i=0; i<TOTAL_ACTIONS; i++) {
+ char x[6];
+ int j;
+
+ memset(x, 0, sizeof(x));
+ memcpy(x, current + 5 * i, 4);
+ sscanf(x, "%x", &j);
+ actions_keys[i] = j;
+ }
+ }
+ setActionKeys(actions_keys);
+
+ /*
+ memset(actions, 0, TOTAL_ACTIONS);
+
+ actions[0] = ACTION_PAUSE;
+ actions[1] = ACTION_SAVE;
+ actions[2] = ACTION_BOSS;
+ actions[3] = ACTION_SKIP;
+ actions[4] = ACTION_HIDE;
+
+ current = g_config->get("ActionTypes", "wince");
+ if (current && version) {
+ for (i=0; i<TOTAL_ACTIONS; i++) {
+ char x[6];
+ int j;
+
+ memset(x, 0, sizeof(x));
+ memcpy(x, current + 3 * i, 2);
+ sscanf(x, "%x", &j);
+ actions[i] = j;
+ }
+ }
+ setActionTypes(actions);
+ */
+
+ if (!version || version != CURRENT_KEYS_VERSION) {
+ g_config->setInt("KeysVersion", CURRENT_KEYS_VERSION, "wince");
+ g_config->flush();
+ }
+}
+
+void save_key_mapping() {
+ char tempo[1024];
+ const unsigned int *work_keys;
+// const unsigned char *work;
+ int i;
+
+ tempo[0] = '\0';
+ work_keys = getActionKeys();
+ for (i=0; i<TOTAL_ACTIONS; i++) {
+ char x[4];
+ sprintf(x, "%.4x ", work_keys[i]);
+ strcat(tempo, x);
+ }
+ g_config->set("ActionKeys", tempo, "wince");
+
+/*
+ tempo[0] = '\0';
+
+ work = getActionTypes();
+ for (i=0; i<TOTAL_ACTIONS; i++) {
+ char x[3];
+ sprintf(x, "%.2x ", work[i]);
+ strcat(tempo, x);
+ }
+ g_config->set("ActionTypes", tempo, "wince");
+*/
+
+ g_config->flush();
+}
+
+/*************** Hardware keys support ***********/
+
+void OSystem_WINCE3::addEventKeyPressed(int ascii_code) {
+ _event.event_code = EVENT_KEYDOWN;
+ _event.kbd.ascii = ascii_code;
+}
+
+void OSystem_WINCE3::addEventRightButtonClicked() {
+ OSystem_WINCE3* system;
+ system = (OSystem_WINCE3*)g_scumm->_system;
+
+ system->addEventKeyPressed(9);
+}
+
+void action_right_click() {
+ OSystem_WINCE3* system;
+ system = (OSystem_WINCE3*)g_scumm->_system;
+
+ system->addEventRightButtonClicked();
+}
+
+void action_pause() {
+ OSystem_WINCE3* system;
+ system = (OSystem_WINCE3*)g_scumm->_system;
+
+ system->addEventKeyPressed(mapKey(VK_SPACE));
+}
+
+void action_save() {
+ OSystem_WINCE3* system;
+ system = (OSystem_WINCE3*)g_scumm->_system;
+
+ /*if (GetScreenMode()) {*/
+ /*
+ draw_keyboard = true;
+ if (!hide_toolbar)
+ toolbar_drawn = false;
+ */
+ /*}*/
+ if (g_scumm->_features & GF_OLD256)
+ system->addEventKeyPressed(319);
+ else
+ system->addEventKeyPressed(g_scumm->_vars[g_scumm->VAR_SAVELOADDIALOG_KEY]);
+}
+
+void action_quit() {
+ do_quit();
+}
+
+void action_boss() {
+ SHELLEXECUTEINFO se;
+
+ g_config->setBool("Sound", sound_activated, "wince");
+ g_config->setInt("DisplayMode", GetScreenMode(), "wince");
+ g_config->flush();
+ sound_activated = false;
+ toolbar_drawn = false;
+ hide_toolbar = true;
+ Cls();
+ g_scumm->_saveLoadSlot = 0;
+ g_scumm->_saveLoadCompatible = false;
+ g_scumm->_saveLoadFlag = 1;
+ strcpy(g_scumm->_saveLoadName, "BOSS");
+ g_scumm->saveState(g_scumm->_saveLoadSlot, g_scumm->_saveLoadCompatible);
+ dynamicGXCloseInput();
+ dynamicGXCloseDisplay();
+ SDL_AudioQuit();
+ memset(&se, 0, sizeof(se));
+ se.cbSize = sizeof(se);
+ se.hwnd = NULL;
+ se.lpFile = TEXT("tasks.exe");
+ se.lpVerb = TEXT("open");
+ se.lpDirectory = TEXT("\\windows");
+ ShellExecuteEx(&se);
+ exit(1);
+}
+
+void action_skip() {
+ OSystem_WINCE3* system;
+ system = (OSystem_WINCE3*)g_scumm->_system;
+
+ if (is_simon) {
+ ((SimonState*)engine)->_exit_cutscene = true;
+ return;
+ }
+
+ if (g_scumm->vm.cutScenePtr[g_scumm->vm.cutSceneStackPointer] || g_scumm->_insaneState)
+ system->addEventKeyPressed(g_scumm->_vars[g_scumm->VAR_CUTSCENEEXIT_KEY]);
+ else
+ system->addEventKeyPressed(g_scumm->_vars[g_scumm->VAR_TALKSTOP_KEY]);
+}
+
+void do_hide(bool hide_state) {
+ hide_toolbar = hide_state;
+ if (hide_toolbar)
+ RestoreScreenGeometry();
+ else
+ LimitScreenGeometry();
+ Cls();
+ num_of_dirty_square = MAX_NUMBER_OF_DIRTY_SQUARES;
+ toolbar_drawn = hide_toolbar;
+ g_scumm->_system->update_screen();
+}
+
+void action_hide() {
+ do_hide(!hide_toolbar);
+}
+
+void action_keyboard() {
+ /*if (GetScreenMode()) {*/
+ draw_keyboard = !draw_keyboard;
+ if (!hide_toolbar)
+ toolbar_drawn = false;
+ /*}*/
+}
+
+void action_sound() {
+ sound_activated = !sound_activated;
+}
+
+void action_cursoronoff() {
+ hide_cursor = !hide_cursor;
+}
+
+void action_subtitleonoff() {
+ g_scumm->_noSubtitles = !g_scumm->_noSubtitles;
+}
+
+void keypad_init() {
+ static pAction actions[TOTAL_ACTIONS] =
+ { NULL, action_pause, action_save, action_quit, action_skip, action_hide,
+ action_keyboard, action_sound, action_right_click, action_cursoronoff,
+ action_subtitleonoff, action_boss
+ };
+
+ GAPIKeysInitActions(actions);
+
+}
+
+void keypad_close() {
+ dynamicGXCloseInput();
+}
+
+void force_keyboard(bool activate) {
+
+if (activate) {
+ save_hide_toolbar = hide_toolbar;
+ if (save_hide_toolbar) {
+ // Display the keyboard while the dialog is running
+ do_hide(false);
+ }
+ if (!draw_keyboard) {
+ keyboard_override = true;
+ draw_keyboard = true;
+ toolbar_drawn = false;
+ }
+}
+else {
+ if (save_hide_toolbar) {
+ do_hide(true);
+ save_hide_toolbar = false;
+ }
+ if (keyboard_override) {
+ keyboard_override = false;
+ draw_keyboard = false;
+ toolbar_drawn = false;
+ }
+}
+}
+
+/************* OSystem Main **********************/
+OSystem *OSystem_WINCE3::create(int gfx_mode, bool full_screen) {
+ const char *display_mode;
+ OSystem_WINCE3 *syst = new OSystem_WINCE3();
+ syst->_mode = gfx_mode;
+ syst->_full_screen = full_screen;
+ syst->_event.event_code = -1;
+ syst->_start_time = GetTickCount();
+
+ /* Retrieve the handle of this module */
+ syst->hInst = GetModuleHandle(NULL);
+
+ syst->hWnd = hWnd_Window;
+ SetWindowLong(syst->hWnd, GWL_USERDATA, (long)syst);
+
+ // Mini SDL init
+
+ if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER)==-1) {
+ exit(1);
+ }
+
+ reducePortraitGeometry();
+
+ if (smartphone || ((noGAPI || !gfx_mode_switch) && GetSystemMetrics(SM_CXSCREEN) < 320))
+ SetScreenMode(1);
+
+ Cls();
+ drawWait();
+
+ // Set mode, portrait or landscape
+ display_mode = g_config->get("DisplayMode", "wince");
+
+ if (display_mode && !(noGAPI || !gfx_mode_switch))
+ SetScreenMode(atoi(display_mode));
+
+ return syst;
+}
+
+OSystem *OSystem_WINCE3_create() {
+ return OSystem_WINCE3::create(0, 0);
+}
+
+void OSystem_WINCE3::set_timer(int timer, int (*callback)(int)) {
+ SetTimer(hWnd, 1, timer, NULL);
+ timer_interval = timer;
+ timer_callback = callback;
+}
+
+void OSystem_WINCE3::set_palette(const byte *colors, uint start, uint num) {
+ const byte *b = colors;
+ uint i;
+ for(i=0;i!=num;i++) {
+ SetPalEntry(i + start, b[0], b[1], b[2]);
+ b += 4;
+ }
+
+ palette_update();
+
+ num_of_dirty_square = MAX_NUMBER_OF_DIRTY_SQUARES;
+}
+
+void OSystem_WINCE3::load_gfx_mode() {
+ force_full = true;
+
+ _gfx_buf = (byte*)malloc((320 * 240) * sizeof(byte));
+ _overlay_buf = (byte*)malloc((320 * 240) * sizeof(uint16));
+ //_ms_backup = (byte*)malloc((40 * 40 * 3) * sizeof(byte));
+ _ms_backup = (byte*)malloc((40 * 40 * 3) * sizeof(uint16));
+}
+
+void OSystem_WINCE3::unload_gfx_mode() {
+ // FIXME: Free the _gfx_buf here
+}
+
+void OSystem_WINCE3::init_size(uint w, uint h) {
+ load_gfx_mode();
+ SetScreenGeometry(w, h);
+ LimitScreenGeometry();
+ _screenWidth = w;
+ _screenHeight = h;
+ num_of_dirty_square = MAX_NUMBER_OF_DIRTY_SQUARES;
+}
+
+void OSystem_WINCE3::copy_rect(const byte *buf, int pitch, int x, int y, int w, int h) {
+ byte *dst;
+
+ if (!hide_cursor && _mouse_drawn)
+ undraw_mouse();
+
+ AddDirtyRect(x, y, w, h);
+
+ dst = _gfx_buf + y * 320 + x;
+ do {
+ memcpy(dst, buf, w);
+ dst += 320;
+ buf += pitch;
+ } while (--h);
+
+}
+
+void OSystem_WINCE3::update_screen() {
+
+ if (!hide_cursor)
+ draw_mouse();
+
+ if (_overlay_visible) {
+ Set_565((int16*)_overlay_buf, 320, 0, 0, 320, 200);
+ checkToolbar();
+ }
+ else {
+ if (num_of_dirty_square >= MAX_NUMBER_OF_DIRTY_SQUARES) {
+ Blt(_gfx_buf); // global redraw
+ num_of_dirty_square = 0;
+ }
+ else {
+ int i;
+ for (i=0; i<num_of_dirty_square; i++) {
+ if (smartphone)
+ Blt_part(_gfx_buf + (320 * ds[i].y) + ds[i].x, ds[i].x * 2 / 3, ds[i].y * 7 / 8, ds[i].w, ds[i].h, 320, true);
+ else
+ Blt_part(_gfx_buf + (320 * ds[i].y) + ds[i].x, ((GetScreenMode() || GetSystemMetrics(SM_CXSCREEN) >= 320) ? ds[i].x : ds[i].x * 3/4), ds[i].y, ds[i].w, ds[i].h, 320, true);
+ }
+ num_of_dirty_square = 0;
+ }
+ }
+}
+
+bool OSystem_WINCE3::show_mouse(bool visible) {
+ if (_mouse_visible == visible)
+ return visible;
+
+ bool last = _mouse_visible;
+ _mouse_visible = visible;
+
+ return last;
+}
+
+// From X11 port
+
+void OSystem_WINCE3::draw_mouse() {
+ if (_mouse_drawn || !_mouse_visible)
+ return;
+ _mouse_drawn = true;
+
+ int xdraw = _ms_cur.x - _ms_hotspot_x;
+ int ydraw = _ms_cur.y - _ms_hotspot_y;
+ int w = _ms_cur.w;
+ int h = _ms_cur.h;
+ int real_w;
+ int real_h;
+ int real_h_2;
+
+ byte *dst;
+ byte *dst2;
+ const byte *buf = _ms_buf;
+ byte *bak = _ms_backup;
+
+ assert(w <= 40 && h <= 40);
+
+ if (ydraw < 0) {
+ real_h = h + ydraw;
+ buf += (-ydraw) * w;
+ ydraw = 0;
+ } else {
+ real_h = (ydraw + h) > 200 ? (200 - ydraw) : h;
+ }
+ if (xdraw < 0) {
+ real_w = w + xdraw;
+ buf += (-xdraw);
+ xdraw = 0;
+ } else {
+ real_w = (xdraw + w) > 320 ? (320 - xdraw) : w;
+ }
+
+ if (_overlay_visible)
+ dst = (byte*)_overlay_buf + (ydraw * 320 * sizeof(uint16)) + (xdraw * sizeof(uint16));
+ else
+ dst = _gfx_buf + (ydraw * 320) + xdraw;
+ dst2 = dst;
+
+ if ((real_h == 0) || (real_w == 0)) {
+ _mouse_drawn = false;
+ return;
+ }
+
+ AddDirtyRect(xdraw, ydraw, real_w, real_h);
+ _ms_old.x = xdraw;
+ _ms_old.y = ydraw;
+ _ms_old.w = real_w;
+ _ms_old.h = real_h;
+
+ if (!_overlay_visible) {
+
+ real_h_2 = real_h;
+ while (real_h_2 > 0) {
+ memcpy(bak, dst, real_w);
+ bak += 40;
+ dst += 320;
+ real_h_2--;
+ }
+ while (real_h > 0) {
+ int width = real_w;
+ while (width > 0) {
+ byte color = *buf;
+ if (color != 0xFF) {
+ *dst2 = color;
+ }
+ buf++;
+ dst2++;
+ width--;
+ }
+ buf += w - real_w;
+ dst2 += 320 - real_w;
+ real_h--;
+ }
+ }
+ else {
+ real_h_2 = real_h;
+ while (real_h_2 > 0) {
+ memcpy(bak, dst, real_w * sizeof(uint16));
+ bak += 40 * sizeof(uint16);
+ dst += 320 * sizeof(uint16);
+ real_h_2--;
+ }
+ while (real_h > 0) {
+ int width = real_w;
+ while (width > 0) {
+ byte color = *buf;
+ if (color != 0xFF) {
+ uint16 x = getColor565(color);
+ memcpy(dst2, &x, sizeof(uint16));
+ }
+ buf++;
+ dst2 += sizeof(uint16);
+ width--;
+ }
+ buf += w - real_w;
+ dst2 += (320 - real_w) * sizeof(uint16);
+ real_h--;
+ }
+ }
+}
+
+void OSystem_WINCE3::undraw_mouse() {
+ byte *dst;
+
+ if (!_mouse_drawn)
+ return;
+ _mouse_drawn = false;
+
+ int old_h = _ms_old.h;
+
+ AddDirtyRect(_ms_old.x, _ms_old.y, _ms_old.w, _ms_old.h);
+
+ if (_overlay_visible)
+ dst = (byte*)_overlay_buf + (_ms_old.y * 320 * sizeof(uint16)) + (_ms_old.x * sizeof(uint16));
+ else
+ dst = _gfx_buf + (_ms_old.y * 320) + _ms_old.x;
+ byte *bak = _ms_backup;
+
+ if (!_overlay_visible) {
+
+ while (old_h > 0) {
+ memcpy(dst, bak, _ms_old.w);
+ bak += 40;
+ dst += 320;
+ old_h--;
+ }
+ }
+ else {
+ while (old_h > 0) {
+ memcpy(dst, bak, _ms_old.w * sizeof(uint16));
+ bak += 40 * sizeof(uint16);
+ dst += 320 * sizeof(uint16);
+ old_h--;
+ }
+ }
+}
+
+
+void OSystem_WINCE3::warp_mouse(int x, int y) {
+}
+
+void OSystem_WINCE3::set_mouse_pos(int x, int y) {
+ if (x != _ms_cur.x || y != _ms_cur.y) {
+ _ms_cur.x = x;
+ _ms_cur.y = y;
+ }
+}
+
+void OSystem_WINCE3::set_mouse_cursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y) {
+ _ms_cur.w = w;
+ _ms_cur.h = h;
+
+ _ms_hotspot_x = hotspot_x;
+ _ms_hotspot_y = hotspot_y;
+
+ _ms_buf = (byte*)buf;
+
+ // Refresh mouse cursor
+
+ if (!hide_cursor) {
+ undraw_mouse();
+ draw_mouse();
+ }
+}
+
+void OSystem_WINCE3::set_shake_pos(int shake_pos) {;}
+
+uint32 OSystem_WINCE3::get_msecs() {
+ return GetTickCount() - _start_time;
+}
+
+void OSystem_WINCE3::delay_msecs(uint msecs) {
+ //handleMessage();
+ Sleep(msecs);
+}
+
+void *OSystem_WINCE3::create_thread(ThreadProc *proc, void *param) {
+ // needed for emulated MIDI support (Sam'n'Max)
+ HANDLE handle;
+ handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)proc, param, 0, NULL);
+ SetThreadPriority(handle, THREAD_PRIORITY_NORMAL);
+ return handle;
+}
+
+int mapKey(int key, byte mod)
+{
+ if (key>=VK_F1 && key<=VK_F9) {
+ return key - VK_F1 + 315;
+ }
+ return key;
+}
+
+bool OSystem_WINCE3::poll_event(Event *event) {
+
+ for (;;) {
+ MSG msg;
+
+ _event.event_code = -1;
+
+ if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ return false;
+
+ if (msg.message==WM_QUIT) {
+ terminated=true;
+ do_quit();
+ return false;
+ }
+
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+
+ *event = _event;
+
+ return true;
+ }
+
+ return false;
+}
+
+void own_soundProc(void *buffer, byte *samples, int len) {
+
+ (*real_soundproc)(buffer, samples, len);
+
+ if (!sound_activated)
+ memset(samples, 0, len);
+}
+
+bool OSystem_WINCE3::set_sound_proc(void *param, SoundProc *proc, byte format) {
+ SDL_AudioSpec desired;
+
+ /* only one format supported at the moment */
+
+ real_soundproc = proc;
+ desired.freq = (new_audio_rate ? SAMPLES_PER_SEC_NEW : SAMPLES_PER_SEC_OLD);
+ desired.format = AUDIO_S16SYS;
+ desired.channels = 2;
+ desired.samples = 128;
+ desired.callback = own_soundProc;
+ desired.userdata = param;
+ desired.thread_priority = _thread_priority;
+
+ if (SDL_OpenAudio(&desired, NULL) != 0) {
+ return false;
+ }
+ SDL_PauseAudio(0);
+
+ return true;
+}
+
+/* Hotswap graphics modes */
+void OSystem_WINCE3::get_320x200_image(byte *buf) {;}
+void OSystem_WINCE3::hotswap_gfx_mode() {;}
+uint32 OSystem_WINCE3::property(int param, Property *value) {
+ switch(param) {
+
+ case PROP_TOGGLE_FULLSCREEN:
+ return 1;
+
+ case PROP_SET_WINDOW_CAPTION:
+ return 1;
+
+ case PROP_OPEN_CD:
+ break;
+
+ case PROP_SET_GFX_MODE:
+ return 1;
+
+ case PROP_SHOW_DEFAULT_CURSOR:
+ break;
+
+ case PROP_GET_SAMPLE_RATE:
+ return (new_audio_rate ? SAMPLES_PER_SEC_NEW : SAMPLES_PER_SEC_OLD);
+ }
+
+ return 0;
+}
+
+void OSystem_WINCE3::quit() {
+ unload_gfx_mode();
+ do_quit();
+}
+
+/* CDRom Audio */
+void OSystem_WINCE3::stop_cdrom() {;}
+void OSystem_WINCE3::play_cdrom(int track, int num_loops, int start_frame, int end_frame) {
+ /* Reset sync count */
+ g_scumm->_vars[g_scumm->VAR_MI1_TIMER] = 0;
+}
+
+bool OSystem_WINCE3::poll_cdrom() {return 0;}
+void OSystem_WINCE3::update_cdrom() {;}
+
+//void ScummDebugger::attach(Scumm *s) {;}
+
+/* Mutex stuff */
+void* OSystem_WINCE3::create_mutex() {
+ return (void*)CreateMutex(NULL, FALSE, NULL);
+}
+void OSystem_WINCE3::lock_mutex(void *handle) {
+ WaitForSingleObject((HANDLE)handle, INFINITE);
+}
+
+void OSystem_WINCE3::unlock_mutex(void *handle) {
+ ReleaseMutex((HANDLE)handle);
+}
+
+void OSystem_WINCE3::delete_mutex(void *handle) {
+ CloseHandle((HANDLE)handle);
+}
+
+/* Overlay stuff */
+
+void OSystem_WINCE3::show_overlay() {
+ undraw_mouse();
+ _overlay_visible = true;
+ clear_overlay();
+
+}
+
+void OSystem_WINCE3::hide_overlay() {
+ undraw_mouse();
+ _overlay_visible = false;
+ toolbar_drawn = false;
+ num_of_dirty_square = MAX_NUMBER_OF_DIRTY_SQUARES;
+}
+
+void OSystem_WINCE3::clear_overlay() {
+
+ if (!_overlay_visible)
+ return;
+
+ Blt(_gfx_buf);
+}
+
+void OSystem_WINCE3::grab_overlay(int16 *buf, int pitch) {
+ //FIXME : it'd be better with a REAL surface :)
+ //Blt(_gfx_buf);
+ Get_565(_gfx_buf, buf, pitch, 0, 0, 320, 200);
+ memcpy(_overlay_buf, buf, 320 * 200 * sizeof(int16));
+}
+
+void OSystem_WINCE3::copy_rect_overlay(const int16 *buf, int pitch, int x, int y, int w, int h) {
+ int i;
+
+ UBYTE *dest = _overlay_buf;
+ dest += y * 320 * sizeof(int16);
+ for (i=0; i<h; i++) {
+ memcpy(dest + (x * sizeof(int16)), buf, w * 2);
+ dest += 320 * sizeof(int16);
+ buf += pitch;
+ }
+}
+
+void OSystem_WINCE3::move_screen(int dx, int dy, int height) {
+ // FIXME : to be implemented
+}
+
+/* NECESSARY operators redefinition */
+
+
+void *operator new(size_t size) {
+ return calloc(size, 1);
+}
+
+void operator delete(void *ptr) {
+ free(ptr);
+}
+