2007-05-30 21:56:52 +00:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
2004-01-26 08:20:26 +00:00
|
|
|
*
|
|
|
|
* 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
|
2005-10-18 01:30:26 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2004-01-26 08:20:26 +00:00
|
|
|
*
|
2006-02-11 12:47:47 +00:00
|
|
|
* $URL$
|
|
|
|
* $Id$
|
2004-01-26 08:20:26 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2007-04-07 22:15:16 +00:00
|
|
|
#include "backends/platform/wince/wince-sdl.h"
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-04-07 22:15:16 +00:00
|
|
|
#include "common/config-manager.h"
|
|
|
|
#include "common/events.h"
|
2004-01-26 08:20:26 +00:00
|
|
|
#include "common/util.h"
|
2007-04-07 22:15:16 +00:00
|
|
|
#include "common/timer.h"
|
|
|
|
|
2006-09-23 00:42:35 +00:00
|
|
|
#include "engines/engine.h"
|
2007-04-07 22:15:16 +00:00
|
|
|
|
2006-04-02 00:08:22 +00:00
|
|
|
#include "base/main.h"
|
2004-01-26 08:20:26 +00:00
|
|
|
#include "base/plugins.h"
|
2007-04-07 22:15:16 +00:00
|
|
|
|
2008-06-28 15:28:29 +00:00
|
|
|
#include "sound/mixer_intern.h"
|
2007-04-07 22:15:16 +00:00
|
|
|
#include "sound/fmopl.h"
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-01-11 21:53:30 +00:00
|
|
|
#include "backends/timer/default/default-timer.h"
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2005-07-05 20:22:56 +00:00
|
|
|
#include "gui/Actions.h"
|
|
|
|
#include "gui/KeysDialog.h"
|
2004-01-26 08:20:26 +00:00
|
|
|
#include "gui/message.h"
|
|
|
|
|
2007-11-13 19:49:01 +00:00
|
|
|
#include "backends/platform/wince/resource.h"
|
2007-04-07 22:15:16 +00:00
|
|
|
#include "backends/platform/wince/CEActionsPocket.h"
|
|
|
|
#include "backends/platform/wince/CEActionsSmartphone.h"
|
|
|
|
#include "backends/platform/wince/CEgui/ItemAction.h"
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-04-07 22:15:16 +00:00
|
|
|
#include "backends/platform/wince/CEException.h"
|
2004-05-30 13:24:51 +00:00
|
|
|
|
2004-01-26 22:38:08 +00:00
|
|
|
#ifdef USE_VORBIS
|
2006-06-06 19:31:49 +00:00
|
|
|
#ifndef USE_TREMOR
|
2004-01-26 22:38:08 +00:00
|
|
|
#include <vorbis/vorbisfile.h>
|
2006-06-06 19:31:49 +00:00
|
|
|
#else
|
|
|
|
#include <tremor/ivorbisfile.h>
|
|
|
|
#endif
|
2004-01-26 22:38:08 +00:00
|
|
|
#endif
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-10-28 18:36:04 +00:00
|
|
|
#ifdef DYNAMIC_MODULES
|
|
|
|
#include "backends/plugins/win32/win32-provider.h"
|
|
|
|
#endif
|
|
|
|
|
2006-10-09 11:42:12 +00:00
|
|
|
#ifdef __GNUC__
|
|
|
|
extern "C" _CRTIMP FILE* __cdecl _wfreopen (const wchar_t*, const wchar_t*, FILE*);
|
|
|
|
#endif
|
|
|
|
|
2008-01-22 14:16:02 +00:00
|
|
|
#define SAMPLES_PER_SEC_OLD 11025
|
|
|
|
#define SAMPLES_PER_SEC_NEW 22050
|
|
|
|
|
2005-07-30 21:11:48 +00:00
|
|
|
using namespace CEGUI;
|
2004-01-26 08:20:26 +00:00
|
|
|
|
|
|
|
// ********************************************************************************************
|
|
|
|
|
|
|
|
// 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"
|
2008-12-18 08:06:08 +00:00
|
|
|
#define NAME_ITEM_ORIENTATION "Orientation"
|
2006-06-10 11:16:43 +00:00
|
|
|
#define NAME_ITEM_BINDKEYS "Bindkeys"
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-05-01 13:15:34 +00:00
|
|
|
// stdin/err redirection
|
|
|
|
#define STDOUT_FNAME "\\scummvm_stdout.txt"
|
|
|
|
#define STDERR_FNAME "\\scummvm_stderr.txt"
|
|
|
|
static FILE *stdout_file = NULL, *stderr_file = NULL;
|
|
|
|
static char stdout_fname[MAX_PATH], stderr_fname[MAX_PATH];
|
2004-01-26 08:20:26 +00:00
|
|
|
|
|
|
|
// Static member inits
|
2006-11-12 11:47:43 +00:00
|
|
|
typedef void (*SoundProc)(void *param, byte *buf, int len);
|
2004-01-26 08:20:26 +00:00
|
|
|
bool OSystem_WINCE3::_soundMaster = true;
|
|
|
|
|
2004-12-21 00:31:58 +00:00
|
|
|
bool _isSmartphone = false;
|
2005-10-16 22:52:46 +00:00
|
|
|
bool _hasSmartphoneResolution = false;
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2004-05-30 13:24:51 +00:00
|
|
|
// Graphics mode consts
|
|
|
|
|
|
|
|
// Low end devices 240x320
|
|
|
|
|
|
|
|
static const OSystem::GraphicsMode s_supportedGraphicsModesLow[] = {
|
|
|
|
{"1x", "Normal (no scaling)", GFX_NORMAL},
|
|
|
|
{0, 0, 0}
|
|
|
|
};
|
|
|
|
|
|
|
|
// High end device 480x640
|
|
|
|
|
|
|
|
static const OSystem::GraphicsMode s_supportedGraphicsModesHigh[] = {
|
|
|
|
{"1x", "Normal (no scaling)", GFX_NORMAL},
|
|
|
|
{"2x", "2x", GFX_DOUBLESIZE},
|
|
|
|
#ifndef _MSC_VER // EVC breaks template functions, and I'm tired of fixing them :)
|
|
|
|
{"2xsai", "2xSAI", GFX_2XSAI},
|
|
|
|
{"super2xsai", "Super2xSAI", GFX_SUPER2XSAI},
|
|
|
|
{"supereagle", "SuperEagle", GFX_SUPEREAGLE},
|
|
|
|
#endif
|
|
|
|
{"advmame2x", "AdvMAME2x", GFX_ADVMAME2X},
|
|
|
|
#ifndef _MSC_VER
|
|
|
|
{"hq2x", "HQ2x", GFX_HQ2X},
|
|
|
|
{"tv2x", "TV2x", GFX_TV2X},
|
|
|
|
#endif
|
|
|
|
{"dotmatrix", "DotMatrix", GFX_DOTMATRIX},
|
|
|
|
{0, 0, 0}
|
|
|
|
};
|
|
|
|
|
2008-12-18 08:06:08 +00:00
|
|
|
#define DEFAULT_CONFIG_FILE "scummvm.ini"
|
2004-05-30 13:24:51 +00:00
|
|
|
|
2004-12-21 00:31:58 +00:00
|
|
|
// ********************************************************************************************
|
|
|
|
|
|
|
|
bool isSmartphone() {
|
2005-10-16 22:52:46 +00:00
|
|
|
//return _isSmartphone;
|
|
|
|
return _hasSmartphoneResolution;
|
2004-12-21 00:31:58 +00:00
|
|
|
}
|
|
|
|
|
2007-05-01 13:15:34 +00:00
|
|
|
const TCHAR *ASCIItoUnicode(const char *str) {
|
|
|
|
static TCHAR ustr[MAX_PATH]; // size good enough
|
|
|
|
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, str, strlen(str) + 1, ustr, sizeof(ustr) / sizeof(TCHAR));
|
|
|
|
return ustr;
|
|
|
|
}
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
// MAIN
|
2006-10-08 18:15:18 +00:00
|
|
|
#ifndef __GNUC__
|
2005-01-28 23:45:53 +00:00
|
|
|
int handleException(EXCEPTION_POINTERS *exceptionPointers) {
|
2004-05-30 13:24:51 +00:00
|
|
|
CEException::writeException(TEXT("\\scummvmCrash"), exceptionPointers);
|
|
|
|
drawError("Unrecoverable exception occurred - see crash dump in latest \\scummvmCrash file");
|
2004-12-21 00:31:58 +00:00
|
|
|
fclose(stdout_file);
|
|
|
|
fclose(stderr_file);
|
|
|
|
CEDevice::end();
|
|
|
|
SDL_Quit();
|
|
|
|
exit(0);
|
2005-01-28 23:45:53 +00:00
|
|
|
return EXCEPTION_EXECUTE_HANDLER;
|
2004-05-30 13:24:51 +00:00
|
|
|
}
|
2006-10-08 18:15:18 +00:00
|
|
|
#endif
|
2004-05-30 13:24:51 +00:00
|
|
|
|
2006-06-06 19:31:49 +00:00
|
|
|
OSystem *OSystem_WINCE3_create() {
|
|
|
|
return new OSystem_WINCE3();
|
|
|
|
}
|
|
|
|
|
2007-10-28 18:36:04 +00:00
|
|
|
extern "C" char *getcwd(char *buf, int size);
|
2004-01-26 08:20:26 +00:00
|
|
|
int SDL_main(int argc, char **argv) {
|
2007-05-01 13:15:34 +00:00
|
|
|
FILE *newfp = NULL;
|
2006-10-08 18:15:18 +00:00
|
|
|
#ifdef __GNUC__
|
|
|
|
// Due to incomplete crt0.o implementation, we go through the constructor function
|
|
|
|
// list provided by the linker and init all of them
|
|
|
|
// thanks to joostp and DJWillis
|
|
|
|
extern void (*__CTOR_LIST__)() ;
|
|
|
|
void (**constructor)() = &__CTOR_LIST__ ;
|
|
|
|
constructor++ ;
|
2008-01-27 19:47:41 +00:00
|
|
|
while (*constructor) {
|
2006-10-08 18:15:18 +00:00
|
|
|
(*constructor)() ;
|
|
|
|
constructor++ ;
|
|
|
|
}
|
|
|
|
#endif
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2004-12-21 00:31:58 +00:00
|
|
|
CEDevice::init();
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2007-05-01 13:15:34 +00:00
|
|
|
/* Redirect standard input and standard output */
|
|
|
|
strcpy(stdout_fname, getcwd(NULL, MAX_PATH));
|
|
|
|
strcpy(stderr_fname, getcwd(NULL, MAX_PATH));
|
|
|
|
strcat(stdout_fname, STDOUT_FNAME);
|
|
|
|
strcat(stderr_fname, STDERR_FNAME);
|
2006-10-09 11:42:12 +00:00
|
|
|
#ifndef __GNUC__
|
2007-05-01 13:15:34 +00:00
|
|
|
stdout_file = fopen(stdout_fname, "w");
|
|
|
|
stderr_file = fopen(stderr_fname, "w");
|
2006-10-09 11:42:12 +00:00
|
|
|
#else
|
2007-05-01 13:15:34 +00:00
|
|
|
stdout_file = newfp = _wfreopen(ASCIItoUnicode(stdout_fname), TEXT("w"), stdout);
|
2006-10-09 11:42:12 +00:00
|
|
|
if (newfp == NULL) {
|
|
|
|
#if !defined(stdout)
|
2007-05-01 13:15:34 +00:00
|
|
|
stdout = fopen(stdout_fname, "w");
|
2006-10-09 11:42:12 +00:00
|
|
|
stdout_file = stdout;
|
|
|
|
#else
|
2007-05-01 13:15:34 +00:00
|
|
|
newfp = fopen(stdout_fname, "w");
|
2006-10-09 11:42:12 +00:00
|
|
|
if (newfp) {
|
2007-10-28 18:36:04 +00:00
|
|
|
//*stdout = *newfp;
|
2006-10-09 11:42:12 +00:00
|
|
|
stdout_file = stdout;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
2007-05-01 13:15:34 +00:00
|
|
|
stderr_file = newfp = _wfreopen(ASCIItoUnicode(stderr_fname), TEXT("w"), stderr);
|
2006-10-09 11:42:12 +00:00
|
|
|
if (newfp == NULL) {
|
|
|
|
#if !defined(stderr)
|
2007-05-01 13:15:34 +00:00
|
|
|
stderr = fopen(stderr_fname, "w");
|
2006-10-09 11:42:12 +00:00
|
|
|
stderr_file = stderr;
|
|
|
|
#else
|
2007-05-01 13:15:34 +00:00
|
|
|
newfp = fopen(stderr_fname, "w");
|
2006-10-09 11:42:12 +00:00
|
|
|
if (newfp) {
|
2007-10-28 18:36:04 +00:00
|
|
|
//*stderr = *newfp;
|
2006-10-09 11:42:12 +00:00
|
|
|
stderr_file = stderr;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2007-10-28 18:36:04 +00:00
|
|
|
#ifdef DYNAMIC_MODULES
|
|
|
|
PluginManager::instance().addPluginProvider(new Win32PluginProvider());
|
|
|
|
#endif
|
|
|
|
|
2006-04-02 14:31:23 +00:00
|
|
|
|
2007-10-28 18:36:04 +00:00
|
|
|
int res = 0;
|
2006-10-08 18:15:18 +00:00
|
|
|
#if !defined(DEBUG) && !defined(__GNUC__)
|
2004-05-30 13:24:51 +00:00
|
|
|
__try {
|
2006-06-06 19:31:49 +00:00
|
|
|
#endif
|
2006-04-02 14:16:31 +00:00
|
|
|
g_system = OSystem_WINCE3_create();
|
|
|
|
assert(g_system);
|
2006-04-02 14:31:23 +00:00
|
|
|
|
|
|
|
// Invoke the actual ScummVM main entry point:
|
|
|
|
res = scummvm_main(argc, argv);
|
|
|
|
g_system->quit(); // TODO: Consider removing / replacing this!
|
2006-10-08 18:15:18 +00:00
|
|
|
#if !defined(DEBUG) && !defined(__GNUC__)
|
2004-05-30 13:24:51 +00:00
|
|
|
}
|
|
|
|
__except (handleException(GetExceptionInformation())) {
|
|
|
|
}
|
2006-06-06 19:31:49 +00:00
|
|
|
#endif
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2006-04-02 14:31:23 +00:00
|
|
|
return res;
|
2005-07-30 21:11:48 +00:00
|
|
|
}
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2007-10-28 18:36:04 +00:00
|
|
|
#ifdef DYNAMIC_MODULES
|
|
|
|
|
|
|
|
/* This is the OS startup code in the case of a plugin-enabled build.
|
|
|
|
* It contains copied and slightly modified parts of SDL's win32/ce startup functions.
|
|
|
|
* We copy these here because the calling stub already has a WinMain procedure
|
|
|
|
* which overrides SDL's one and hence we essentially re-implement the startup procedure.
|
|
|
|
* Note also that this has to be here and not in the stub because SDL is statically
|
|
|
|
* linked in the scummvm.dll archive.
|
|
|
|
* Take a look at the comments in stub.cpp as well.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int console_main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
int n;
|
|
|
|
char *bufp, *appname;
|
|
|
|
|
|
|
|
appname = argv[0];
|
|
|
|
if ( (bufp=strrchr(argv[0], '\\')) != NULL )
|
|
|
|
appname = bufp + 1;
|
|
|
|
else if ( (bufp=strrchr(argv[0], '/')) != NULL )
|
|
|
|
appname = bufp + 1;
|
|
|
|
|
|
|
|
if ( (bufp=strrchr(appname, '.')) == NULL )
|
|
|
|
n = strlen(appname);
|
|
|
|
else
|
|
|
|
n = (bufp-appname);
|
|
|
|
|
|
|
|
bufp = (char *) alloca(n + 1);
|
|
|
|
strncpy(bufp, appname, n);
|
|
|
|
bufp[n] = '\0';
|
|
|
|
appname = bufp;
|
|
|
|
|
|
|
|
if ( SDL_Init(SDL_INIT_NOPARACHUTE) < 0 ) {
|
|
|
|
error("WinMain() error: %d", SDL_GetError());
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_SetModuleHandle(GetModuleHandle(NULL));
|
|
|
|
|
|
|
|
// Run the application main() code
|
|
|
|
SDL_main(argc, argv);
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ParseCommandLine(char *cmdline, char **argv)
|
|
|
|
{
|
|
|
|
char *bufp;
|
|
|
|
int argc;
|
|
|
|
|
|
|
|
argc = 0;
|
|
|
|
for (bufp = cmdline; *bufp;) {
|
2008-01-27 19:47:41 +00:00
|
|
|
// Skip leading whitespace
|
2007-10-28 18:36:04 +00:00
|
|
|
while (isspace(*bufp))
|
|
|
|
++bufp;
|
|
|
|
|
|
|
|
// Skip over argument
|
|
|
|
if (*bufp == '"') {
|
|
|
|
++bufp;
|
|
|
|
if (*bufp) {
|
|
|
|
if (argv)
|
|
|
|
argv[argc] = bufp;
|
|
|
|
++argc;
|
|
|
|
}
|
|
|
|
// Skip over word
|
|
|
|
while (*bufp && (*bufp != '"'))
|
|
|
|
++bufp;
|
|
|
|
} else {
|
|
|
|
if (*bufp) {
|
|
|
|
if (argv)
|
|
|
|
argv[argc] = bufp;
|
|
|
|
++argc;
|
|
|
|
}
|
|
|
|
// Skip over word
|
|
|
|
while (*bufp && ! isspace(*bufp))
|
|
|
|
++bufp;
|
|
|
|
}
|
|
|
|
if (*bufp) {
|
|
|
|
if (argv)
|
|
|
|
*bufp = '\0';
|
|
|
|
++bufp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (argv)
|
|
|
|
argv[argc] = NULL;
|
|
|
|
|
|
|
|
return(argc);
|
|
|
|
}
|
|
|
|
|
|
|
|
int dynamic_modules_main(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR szCmdLine, int sw) {
|
|
|
|
HINSTANCE handle;
|
|
|
|
char **argv;
|
|
|
|
int argc;
|
|
|
|
char *cmdline;
|
|
|
|
wchar_t *bufp;
|
|
|
|
int nLen;
|
|
|
|
|
|
|
|
if (wcsncmp(szCmdLine, TEXT("\\"), 1)) {
|
|
|
|
nLen = wcslen(szCmdLine)+128+1;
|
|
|
|
bufp = (wchar_t *) alloca(nLen*2);
|
|
|
|
wcscpy (bufp, TEXT("\""));
|
|
|
|
GetModuleFileName(NULL, bufp+1, 128-3);
|
|
|
|
wcscpy (bufp+wcslen(bufp), TEXT("\" "));
|
|
|
|
wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen-wcslen(bufp));
|
|
|
|
} else
|
|
|
|
bufp = szCmdLine;
|
|
|
|
|
|
|
|
nLen = wcslen(bufp)+1;
|
|
|
|
cmdline = (char *) alloca(nLen);
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL);
|
|
|
|
|
|
|
|
// Parse command line into argv and argc
|
|
|
|
argc = ParseCommandLine(cmdline, NULL);
|
|
|
|
argv = (char **) alloca((argc+1)*(sizeof *argv));
|
|
|
|
ParseCommandLine(cmdline, argv);
|
|
|
|
|
2008-12-18 08:06:08 +00:00
|
|
|
// fix gdb-emulator combo
|
2007-10-28 18:36:04 +00:00
|
|
|
while (argc > 1 && !strstr(argv[0], ".exe")) {
|
|
|
|
OutputDebugString(TEXT("SDL: gdb argv[0] fixup\n"));
|
|
|
|
*(argv[1]-1) = ' ';
|
|
|
|
int i;
|
|
|
|
for (i=1; i<argc; i++)
|
|
|
|
argv[i] = argv[i+1];
|
|
|
|
argc--;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run the main program (after a little SDL initialization)
|
|
|
|
return(console_main(argc, argv));
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
// ********************************************************************************************
|
|
|
|
|
|
|
|
|
|
|
|
// ********************************************************************************************
|
|
|
|
|
2004-05-09 15:02:10 +00:00
|
|
|
void pumpMessages() {
|
|
|
|
MSG msg;
|
|
|
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
|
|
|
TranslateMessage(&msg);
|
|
|
|
DispatchMessage(&msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
void drawError(char *error) {
|
2004-05-09 15:02:10 +00:00
|
|
|
TCHAR errorUnicode[200];
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, error, strlen(error) + 1, errorUnicode, sizeof(errorUnicode));
|
|
|
|
pumpMessages();
|
|
|
|
MessageBox(GetActiveWindow(), errorUnicode, TEXT("ScummVM error"), MB_OK | MB_ICONERROR);
|
|
|
|
pumpMessages();
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ********************************************************************************************
|
2007-01-11 21:53:30 +00:00
|
|
|
static DefaultTimerManager *_int_timer = NULL;
|
|
|
|
static Uint32 timer_handler_wrapper(Uint32 interval) {
|
|
|
|
_int_timer->handler();
|
|
|
|
return interval;
|
|
|
|
}
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2006-06-06 19:31:49 +00:00
|
|
|
void OSystem_WINCE3::initBackend()
|
|
|
|
{
|
2006-11-12 11:47:43 +00:00
|
|
|
// Instantiate our own sound mixer
|
|
|
|
// mixer init is postponed until a game engine is selected.
|
2008-06-29 14:40:41 +00:00
|
|
|
if (_mixer == 0)
|
|
|
|
_mixer = new Audio::MixerImpl(this);
|
2006-11-12 11:47:43 +00:00
|
|
|
|
2007-01-11 21:53:30 +00:00
|
|
|
// Create the timer. CE SDL does not support multiple timers (SDL_AddTimer).
|
|
|
|
// We work around this by using the SetTimer function, since we only use
|
|
|
|
// one timer in scummvm (for the time being)
|
|
|
|
_timer = _int_timer = new DefaultTimerManager();
|
|
|
|
_timerID = NULL; // OSystem_SDL will call removetimer with this, it's ok
|
|
|
|
SDL_SetTimer(10, &timer_handler_wrapper);
|
|
|
|
|
2006-11-12 11:47:43 +00:00
|
|
|
// Chain init
|
|
|
|
OSystem_SDL::initBackend();
|
2007-05-27 19:05:51 +00:00
|
|
|
|
|
|
|
// Query SDL for screen size and init screen dependent stuff
|
|
|
|
OSystem_WINCE3::initScreenInfos();
|
|
|
|
_isSmartphone = CEDevice::isSmartphone();
|
|
|
|
create_toolbar();
|
|
|
|
_hasSmartphoneResolution = CEDevice::hasSmartphoneResolution() || CEDevice::isSmartphone();
|
|
|
|
if (_hasSmartphoneResolution) _panelVisible = false; // init correctly in smartphones
|
|
|
|
|
|
|
|
// Initialize global key mapping
|
|
|
|
GUI::Actions::init();
|
|
|
|
GUI_Actions::Instance()->initInstanceMain(this);
|
|
|
|
if (!GUI_Actions::Instance()->loadMapping()) { // error during loading means not present/wrong version
|
|
|
|
warning("Setting default action mappings.");
|
|
|
|
GUI_Actions::Instance()->saveMapping(); // write defaults
|
|
|
|
}
|
|
|
|
|
|
|
|
loadDeviceConfiguration();
|
2006-06-06 19:31:49 +00:00
|
|
|
}
|
|
|
|
|
2004-05-30 13:24:51 +00:00
|
|
|
int OSystem_WINCE3::getScreenWidth() {
|
|
|
|
return _platformScreenWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
int OSystem_WINCE3::getScreenHeight() {
|
|
|
|
return _platformScreenHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::initScreenInfos() {
|
2006-06-10 11:16:43 +00:00
|
|
|
// sdl port ensures that we use correctly full screen
|
|
|
|
_isOzone = 0;
|
2007-05-27 19:05:51 +00:00
|
|
|
SDL_Rect **r;
|
|
|
|
r = SDL_ListModes(NULL, 0);
|
|
|
|
_platformScreenWidth = r[0]->w;
|
|
|
|
_platformScreenHeight = r[0]->h;
|
2004-05-30 13:24:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool OSystem_WINCE3::isOzone() {
|
|
|
|
return _isOzone;
|
|
|
|
}
|
|
|
|
|
2008-12-18 08:06:08 +00:00
|
|
|
static Common::String getDefaultConfigFileName() {
|
|
|
|
char configFile[MAXPATHLEN];
|
|
|
|
strcpy(configFile, getcwd(NULL, MAX_PATH));
|
|
|
|
strcat(configFile, "\\");
|
|
|
|
strcat(configFile, DEFAULT_CONFIG_FILE);
|
2009-01-01 15:06:43 +00:00
|
|
|
return configFile;
|
2008-12-18 08:06:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Common::SeekableReadStream *OSystem_WINCE3::openConfigFileForReading() {
|
|
|
|
Common::FSNode file(getDefaultConfigFileName());
|
|
|
|
return file.openForReading();
|
|
|
|
}
|
|
|
|
|
|
|
|
Common::WriteStream *OSystem_WINCE3::openConfigFileForWriting() {
|
|
|
|
Common::FSNode file(getDefaultConfigFileName());
|
|
|
|
return file.openForWriting();
|
|
|
|
}
|
|
|
|
|
2004-05-30 13:24:51 +00:00
|
|
|
// ********************************************************************************************
|
|
|
|
|
|
|
|
|
2005-07-30 21:11:48 +00:00
|
|
|
OSystem_WINCE3::OSystem_WINCE3() : OSystem_SDL(),
|
2006-06-10 11:16:43 +00:00
|
|
|
_orientationLandscape(0), _newOrientation(0), _panelInitialized(false),
|
2007-06-03 19:29:13 +00:00
|
|
|
_panelVisible(true), _panelStateForced(false), _forceHideMouse(false), _unfilteredkeys(false),
|
2005-01-04 23:00:03 +00:00
|
|
|
_freeLook(false), _forcePanelInvisible(false), _toolbarHighDrawn(false), _zoomUp(false), _zoomDown(false),
|
2008-08-25 08:48:46 +00:00
|
|
|
_scalersChanged(false), _lastKeyPressed(0), _tapTime(0), _closeClick(false), _noDoubleTapRMB(false),
|
2007-04-28 17:48:58 +00:00
|
|
|
_saveToolbarState(false), _saveActiveToolbar(NAME_MAIN_PANEL), _rbutton(false), _hasfocus(true),
|
2007-02-12 17:25:36 +00:00
|
|
|
_usesEmulatedMouse(false), _mouseBackupOld(NULL), _mouseBackupToolbar(NULL), _mouseBackupDim(0)
|
2004-01-26 08:20:26 +00:00
|
|
|
{
|
2004-12-21 00:31:58 +00:00
|
|
|
memset(&_mouseCurState, 0, sizeof(_mouseCurState));
|
|
|
|
if (_isSmartphone) {
|
|
|
|
_mouseCurState.x = 20;
|
|
|
|
_mouseCurState.y = 20;
|
|
|
|
}
|
|
|
|
|
2006-11-12 11:47:43 +00:00
|
|
|
_mixer = 0;
|
2007-04-28 17:48:58 +00:00
|
|
|
_screen = NULL;
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::swap_panel_visibility() {
|
2006-06-10 11:16:43 +00:00
|
|
|
//if (!_forcePanelInvisible && !_panelStateForced) {
|
2007-04-30 20:31:56 +00:00
|
|
|
if (_zoomDown || _zoomUp) return;
|
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
if (_panelVisible) {
|
|
|
|
if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD)
|
|
|
|
_panelVisible = !_panelVisible;
|
|
|
|
else
|
|
|
|
_toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
_toolbarHandler.setActive(NAME_MAIN_PANEL);
|
|
|
|
_panelVisible = !_panelVisible;
|
|
|
|
}
|
2004-01-26 08:20:26 +00:00
|
|
|
_toolbarHandler.setVisible(_panelVisible);
|
2007-04-30 20:31:56 +00:00
|
|
|
_toolbarHighDrawn = false;
|
2006-06-10 11:16:43 +00:00
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (_videoMode.screenHeight > 240)
|
2004-12-11 00:41:31 +00:00
|
|
|
addDirtyRect(0, 400, 640, 80);
|
2004-01-28 01:12:48 +00:00
|
|
|
else
|
2004-12-11 00:41:31 +00:00
|
|
|
addDirtyRect(0, 200, 320, 40);
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible)
|
|
|
|
internUpdateScreen();
|
|
|
|
else {
|
|
|
|
update_scalers();
|
|
|
|
hotswapGFXMode();
|
|
|
|
}
|
|
|
|
//}
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::swap_panel() {
|
2004-05-09 15:02:10 +00:00
|
|
|
_toolbarHighDrawn = false;
|
2006-06-10 11:16:43 +00:00
|
|
|
//if (!_panelStateForced) {
|
|
|
|
if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible)
|
2004-01-26 08:20:26 +00:00
|
|
|
_toolbarHandler.setActive(NAME_MAIN_PANEL);
|
|
|
|
else
|
|
|
|
_toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
|
2006-06-10 11:16:43 +00:00
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (_videoMode.screenHeight > 240)
|
2006-06-10 11:16:43 +00:00
|
|
|
addDirtyRect(0, 400, 640, 80);
|
|
|
|
else
|
|
|
|
addDirtyRect(0, 200, 320, 40);
|
|
|
|
|
|
|
|
_toolbarHandler.setVisible(true);
|
|
|
|
if (!_panelVisible) {
|
|
|
|
_panelVisible = true;
|
|
|
|
update_scalers();
|
|
|
|
hotswapGFXMode();
|
|
|
|
}
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::swap_smartphone_keyboard() {
|
|
|
|
_toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
|
|
|
|
_panelVisible = !_panelVisible;
|
|
|
|
_toolbarHandler.setVisible(_panelVisible);
|
2008-12-10 20:46:19 +00:00
|
|
|
if (_videoMode.screenHeight > 240)
|
2007-05-01 14:02:52 +00:00
|
|
|
addDirtyRect(0, 0, 640, 80);
|
|
|
|
else
|
|
|
|
addDirtyRect(0, 0, 320, 40);
|
2006-06-10 11:16:43 +00:00
|
|
|
internUpdateScreen();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::smartphone_rotate_display() {
|
|
|
|
_orientationLandscape = _newOrientation = _orientationLandscape == 1 ? 2 : 1;
|
|
|
|
ConfMan.setInt("landscape", _orientationLandscape);
|
|
|
|
ConfMan.flushToDisk();
|
|
|
|
hotswapGFXMode();
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::swap_sound_master() {
|
|
|
|
_soundMaster = !_soundMaster;
|
|
|
|
if (_toolbarHandler.activeName() == NAME_MAIN_PANEL)
|
|
|
|
_toolbarHandler.forceRedraw(); // redraw sound icon
|
|
|
|
}
|
|
|
|
|
2004-12-21 00:31:58 +00:00
|
|
|
void OSystem_WINCE3::add_right_click(bool pushed) {
|
2004-05-09 15:02:10 +00:00
|
|
|
int x, y;
|
|
|
|
retrieve_mouse_location(x, y);
|
2004-12-21 00:31:58 +00:00
|
|
|
EventsBuffer::simulateMouseRightClick(x, y, pushed);
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::swap_mouse_visibility() {
|
|
|
|
_forceHideMouse = !_forceHideMouse;
|
|
|
|
if (_forceHideMouse)
|
2004-12-11 00:41:31 +00:00
|
|
|
undrawMouse();
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::swap_freeLook() {
|
|
|
|
_freeLook = !_freeLook;
|
|
|
|
}
|
|
|
|
|
2005-07-30 21:11:48 +00:00
|
|
|
void OSystem_WINCE3::swap_zoom_up() {
|
2004-05-09 15:02:10 +00:00
|
|
|
if (_zoomUp) {
|
|
|
|
// restore visibility
|
|
|
|
_toolbarHandler.setVisible(_saveToolbarZoom);
|
|
|
|
// restore scaler
|
|
|
|
_scaleFactorYd = 2;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = PocketPCHalf;
|
2004-05-09 15:02:10 +00:00
|
|
|
_zoomUp = false;
|
2007-04-30 20:31:56 +00:00
|
|
|
_zoomDown = false;
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// only active if running on a PocketPC
|
2004-12-11 00:41:31 +00:00
|
|
|
if (_scalerProc != PocketPCHalf && _scalerProc != PocketPCHalfZoom)
|
2004-05-09 15:02:10 +00:00
|
|
|
return;
|
2004-12-11 00:41:31 +00:00
|
|
|
if (_scalerProc == PocketPCHalf) {
|
2004-05-09 15:02:10 +00:00
|
|
|
_saveToolbarZoom = _toolbarHandler.visible();
|
|
|
|
_toolbarHandler.setVisible(false);
|
|
|
|
// set zoom scaler
|
|
|
|
_scaleFactorYd = 1;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = PocketPCHalfZoom;
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2007-04-30 20:31:56 +00:00
|
|
|
_zoomDown = false;
|
2004-05-09 15:02:10 +00:00
|
|
|
_zoomUp = true;
|
|
|
|
}
|
|
|
|
// redraw whole screen
|
2004-12-11 00:41:31 +00:00
|
|
|
addDirtyRect(0, 0, 640, 480);
|
2004-05-09 15:02:10 +00:00
|
|
|
internUpdateScreen();
|
|
|
|
}
|
|
|
|
|
2005-07-30 21:11:48 +00:00
|
|
|
void OSystem_WINCE3::swap_zoom_down() {
|
2004-05-09 15:02:10 +00:00
|
|
|
if (_zoomDown) {
|
|
|
|
// restore visibility
|
|
|
|
_toolbarHandler.setVisible(_saveToolbarZoom);
|
|
|
|
// restore scaler
|
|
|
|
_scaleFactorYd = 2;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = PocketPCHalf;
|
2004-05-09 15:02:10 +00:00
|
|
|
_zoomDown = false;
|
2007-04-30 20:31:56 +00:00
|
|
|
_zoomUp = false;
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// only active if running on a PocketPC
|
2004-12-11 00:41:31 +00:00
|
|
|
if (_scalerProc != PocketPCHalf && _scalerProc != PocketPCHalfZoom)
|
2004-05-09 15:02:10 +00:00
|
|
|
return;
|
2004-12-11 00:41:31 +00:00
|
|
|
if (_scalerProc == PocketPCHalf) {
|
2004-05-09 15:02:10 +00:00
|
|
|
_saveToolbarZoom = _toolbarHandler.visible();
|
|
|
|
_toolbarHandler.setVisible(false);
|
|
|
|
// set zoom scaler
|
|
|
|
_scaleFactorYd = 1;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = PocketPCHalfZoom;
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
|
|
|
|
2007-04-30 20:31:56 +00:00
|
|
|
_zoomUp = false;
|
2004-05-09 15:02:10 +00:00
|
|
|
_zoomDown = true;
|
|
|
|
}
|
|
|
|
// redraw whole screen
|
2004-12-11 00:41:31 +00:00
|
|
|
addDirtyRect(0, 0, 640, 480);
|
2004-05-09 15:02:10 +00:00
|
|
|
internUpdateScreen();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Smartphone actions
|
2004-12-23 01:15:27 +00:00
|
|
|
void OSystem_WINCE3::initZones() {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
_currentZone = 0;
|
|
|
|
for (i=0; i<TOTAL_ZONES; i++) {
|
2005-01-28 23:45:53 +00:00
|
|
|
_mouseXZone[i] = (_zones[i].x + (_zones[i].width / 2)) * _scaleFactorXm / _scaleFactorXd;
|
|
|
|
_mouseYZone[i] = (_zones[i].y + (_zones[i].height / 2)) * _scaleFactorYm / _scaleFactorYd;
|
2004-12-23 01:15:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
void OSystem_WINCE3::loadDeviceConfigurationElement(String element, int &value, int defaultValue) {
|
|
|
|
value = ConfMan.getInt(element, ConfMan.kApplicationDomain);
|
2004-12-21 00:31:58 +00:00
|
|
|
if (!value) {
|
|
|
|
value = defaultValue;
|
2006-06-10 11:16:43 +00:00
|
|
|
ConfMan.setInt(element, value, ConfMan.kApplicationDomain);
|
2004-12-21 00:31:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
void OSystem_WINCE3::loadDeviceConfiguration() {
|
|
|
|
loadDeviceConfigurationElement("repeatTrigger", _keyRepeatTrigger, 200);
|
|
|
|
loadDeviceConfigurationElement("repeatX", _repeatX, 4);
|
|
|
|
loadDeviceConfigurationElement("repeatY", _repeatY, 4);
|
|
|
|
loadDeviceConfigurationElement("stepX1", _stepX1, 2);
|
|
|
|
loadDeviceConfigurationElement("stepX2", _stepX2, 10);
|
|
|
|
loadDeviceConfigurationElement("stepX3", _stepX3, 40);
|
|
|
|
loadDeviceConfigurationElement("stepY1", _stepY1, 2);
|
|
|
|
loadDeviceConfigurationElement("stepY2", _stepY2, 10);
|
|
|
|
loadDeviceConfigurationElement("stepY3", _stepY3, 20);
|
2004-12-21 00:31:58 +00:00
|
|
|
ConfMan.flushToDisk();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::add_left_click(bool pushed) {
|
|
|
|
int x, y;
|
|
|
|
retrieve_mouse_location(x, y);
|
|
|
|
EventsBuffer::simulateMouseLeftClick(x, y, pushed);
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::move_cursor_up() {
|
2004-12-21 00:31:58 +00:00
|
|
|
int x,y;
|
2006-06-10 11:16:43 +00:00
|
|
|
_usesEmulatedMouse = true;
|
2004-12-21 00:31:58 +00:00
|
|
|
retrieve_mouse_location(x, y);
|
|
|
|
if (_keyRepeat > _repeatY)
|
|
|
|
y -= _stepY3;
|
|
|
|
else
|
|
|
|
if (_keyRepeat)
|
|
|
|
y -= _stepY2;
|
|
|
|
else
|
|
|
|
y -= _stepY1;
|
|
|
|
|
|
|
|
if (y < 0)
|
|
|
|
y = 0;
|
|
|
|
|
|
|
|
EventsBuffer::simulateMouseMove(x, y);
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::move_cursor_down() {
|
2004-12-21 00:31:58 +00:00
|
|
|
int x,y;
|
2006-06-10 11:16:43 +00:00
|
|
|
_usesEmulatedMouse = true;
|
2004-12-21 00:31:58 +00:00
|
|
|
retrieve_mouse_location(x, y);
|
|
|
|
if (_keyRepeat > _repeatY)
|
|
|
|
y += _stepY3;
|
|
|
|
else
|
|
|
|
if (_keyRepeat)
|
|
|
|
y += _stepY2;
|
|
|
|
else
|
|
|
|
y += _stepY1;
|
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (y > _videoMode.screenHeight*_scaleFactorYm/_scaleFactorYd)
|
|
|
|
y = _videoMode.screenHeight*_scaleFactorYm/_scaleFactorYd;
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2005-07-30 21:11:48 +00:00
|
|
|
EventsBuffer::simulateMouseMove(x, y);
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::move_cursor_left() {
|
2004-12-21 00:31:58 +00:00
|
|
|
int x,y;
|
2006-06-10 11:16:43 +00:00
|
|
|
_usesEmulatedMouse = true;
|
2004-12-21 00:31:58 +00:00
|
|
|
retrieve_mouse_location(x, y);
|
|
|
|
if (_keyRepeat > _repeatX)
|
|
|
|
x -= _stepX3;
|
|
|
|
else
|
|
|
|
if (_keyRepeat)
|
2005-07-30 21:11:48 +00:00
|
|
|
x -= _stepX2;
|
2004-12-21 00:31:58 +00:00
|
|
|
else
|
|
|
|
x -= _stepX1;
|
|
|
|
|
|
|
|
if (x < 0)
|
|
|
|
x = 0;
|
|
|
|
|
|
|
|
EventsBuffer::simulateMouseMove(x, y);
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::move_cursor_right() {
|
2004-12-21 00:31:58 +00:00
|
|
|
int x,y;
|
2006-06-10 11:16:43 +00:00
|
|
|
_usesEmulatedMouse = true;
|
2004-12-21 00:31:58 +00:00
|
|
|
retrieve_mouse_location(x, y);
|
|
|
|
if (_keyRepeat > _repeatX)
|
|
|
|
x += _stepX3;
|
|
|
|
else
|
|
|
|
if (_keyRepeat)
|
|
|
|
x += _stepX2;
|
|
|
|
else
|
|
|
|
x += _stepX1;
|
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (x > _videoMode.screenWidth*_scaleFactorXm/_scaleFactorXd)
|
|
|
|
x = _videoMode.screenWidth*_scaleFactorXm/_scaleFactorXd;
|
2004-12-21 00:31:58 +00:00
|
|
|
|
|
|
|
EventsBuffer::simulateMouseMove(x, y);
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::switch_zone() {
|
2004-12-23 01:15:27 +00:00
|
|
|
int x,y;
|
|
|
|
int i;
|
|
|
|
retrieve_mouse_location(x, y);
|
|
|
|
|
|
|
|
for (i=0; i<TOTAL_ZONES; i++)
|
|
|
|
if (x >= _zones[i].x && y >= _zones[i].y &&
|
2006-08-18 21:00:41 +00:00
|
|
|
x <= _zones[i].x + _zones[i].width && y <= _zones[i].y + _zones[i].height) {
|
2004-12-23 01:15:27 +00:00
|
|
|
_mouseXZone[i] = x;
|
|
|
|
_mouseYZone[i] = y;
|
|
|
|
break;
|
|
|
|
}
|
2006-08-18 21:00:41 +00:00
|
|
|
_currentZone = i + 1;
|
2004-12-23 01:15:27 +00:00
|
|
|
if (_currentZone >= TOTAL_ZONES)
|
|
|
|
_currentZone = 0;
|
|
|
|
|
|
|
|
EventsBuffer::simulateMouseMove(_mouseXZone[_currentZone], _mouseYZone[_currentZone]);
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
void OSystem_WINCE3::create_toolbar() {
|
|
|
|
PanelKeyboard *keyboard;
|
|
|
|
|
|
|
|
// Add the keyboard
|
2006-06-10 11:16:43 +00:00
|
|
|
keyboard = new PanelKeyboard(PANEL_KEYBOARD);
|
|
|
|
_toolbarHandler.add(NAME_PANEL_KEYBOARD, *keyboard);
|
|
|
|
_toolbarHandler.setVisible(false);
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
2008-06-29 14:40:41 +00:00
|
|
|
void OSystem_WINCE3::setupMixer() {
|
2006-11-12 11:47:43 +00:00
|
|
|
SDL_AudioSpec desired;
|
|
|
|
int thread_priority;
|
|
|
|
|
|
|
|
if (_sampleRate == 0)
|
|
|
|
warning("setSoundCallback called with 0 _sampleRate. Audio will not work.");
|
|
|
|
|
|
|
|
memset(&desired, 0, sizeof(desired));
|
|
|
|
|
|
|
|
desired.freq = _sampleRate;
|
|
|
|
desired.format = AUDIO_S16SYS;
|
|
|
|
desired.channels = 2;
|
|
|
|
desired.samples = 128;
|
|
|
|
desired.callback = private_sound_proc;
|
2008-06-28 15:28:29 +00:00
|
|
|
desired.userdata = this;
|
|
|
|
|
|
|
|
// Create the mixer instance
|
2008-06-29 14:40:41 +00:00
|
|
|
if (_mixer == 0)
|
|
|
|
_mixer = new Audio::MixerImpl(this);
|
2006-11-12 11:47:43 +00:00
|
|
|
|
|
|
|
// Add sound thread priority
|
2008-06-28 15:28:29 +00:00
|
|
|
if (!ConfMan.hasKey("sound_thread_priority"))
|
2006-11-12 11:47:43 +00:00
|
|
|
thread_priority = THREAD_PRIORITY_NORMAL;
|
|
|
|
else
|
|
|
|
thread_priority = ConfMan.getInt("sound_thread_priority");
|
|
|
|
|
|
|
|
desired.thread_priority = thread_priority;
|
|
|
|
|
2007-02-18 11:46:39 +00:00
|
|
|
SDL_CloseAudio();
|
2006-11-12 11:47:43 +00:00
|
|
|
if (SDL_OpenAudio(&desired, NULL) != 0) {
|
|
|
|
warning("Could not open audio device: %s", SDL_GetError());
|
2008-06-28 15:28:29 +00:00
|
|
|
_mixer->setReady(false);
|
|
|
|
|
|
|
|
} else {
|
2007-05-12 22:33:13 +00:00
|
|
|
debug(1, "Sound opened OK, mixing at %d Hz", _sampleRate);
|
2008-06-28 15:28:29 +00:00
|
|
|
|
2008-06-29 14:40:41 +00:00
|
|
|
// Re-create mixer to match the output rate
|
2008-08-13 15:16:38 +00:00
|
|
|
int vol1 = _mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);
|
|
|
|
int vol2 = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
|
|
|
|
int vol3 = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
|
|
|
|
int vol4 = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
|
2008-06-29 14:40:41 +00:00
|
|
|
delete(_mixer);
|
|
|
|
_mixer = new Audio::MixerImpl(this);
|
2008-08-13 15:16:38 +00:00
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, vol1);
|
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol2);
|
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, vol3);
|
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, vol4);
|
2008-06-28 15:28:29 +00:00
|
|
|
_mixer->setOutputRate(_sampleRate);
|
|
|
|
_mixer->setReady(true);
|
|
|
|
SDL_PauseAudio(0);
|
|
|
|
}
|
2006-11-12 11:47:43 +00:00
|
|
|
}
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
void OSystem_WINCE3::private_sound_proc(void *param, byte *buf, int len) {
|
2008-06-28 15:28:29 +00:00
|
|
|
OSystem_WINCE3 *this_ = (OSystem_WINCE3 *)param;
|
|
|
|
assert(this_);
|
|
|
|
|
|
|
|
if (this_->_mixer)
|
|
|
|
this_->_mixer->mixCallback(buf, len);
|
2004-01-26 08:20:26 +00:00
|
|
|
if (!_soundMaster)
|
|
|
|
memset(buf, 0, len);
|
|
|
|
}
|
|
|
|
|
2004-01-26 22:38:08 +00:00
|
|
|
#ifdef USE_VORBIS
|
|
|
|
bool OSystem_WINCE3::checkOggHighSampleRate() {
|
|
|
|
char trackFile[255];
|
|
|
|
FILE *testFile;
|
|
|
|
OggVorbis_File *test_ov_file = new OggVorbis_File;
|
|
|
|
|
|
|
|
sprintf(trackFile,"%sTrack1.ogg", ConfMan.get("path").c_str());
|
|
|
|
// Check if we have an OGG audio track
|
|
|
|
testFile = fopen(trackFile, "rb");
|
|
|
|
if (testFile) {
|
|
|
|
if (!ov_open(testFile, test_ov_file, NULL, 0)) {
|
|
|
|
bool highSampleRate = (ov_info(test_ov_file, -1)->rate == 22050);
|
|
|
|
ov_clear(test_ov_file);
|
2006-10-08 18:15:18 +00:00
|
|
|
delete test_ov_file;
|
2004-01-26 22:38:08 +00:00
|
|
|
return highSampleRate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do not test for OGG samples - too big and too slow anyway :)
|
|
|
|
|
2006-10-08 18:15:18 +00:00
|
|
|
delete test_ov_file;
|
2004-01-26 22:38:08 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2008-06-28 15:28:29 +00:00
|
|
|
void OSystem_WINCE3::compute_sample_rate() {
|
2005-01-28 23:45:53 +00:00
|
|
|
// Force at least medium quality FM synthesis for FOTAQ
|
2006-04-15 17:39:14 +00:00
|
|
|
Common::String gameid(ConfMan.get("gameid"));
|
2006-04-12 19:04:10 +00:00
|
|
|
if (gameid == "queen") {
|
2005-01-28 23:45:53 +00:00
|
|
|
if (!((ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) ||
|
|
|
|
(ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")))) {
|
2006-06-06 19:31:49 +00:00
|
|
|
ConfMan.setBool("FM_medium_quality", true);
|
2005-01-28 23:45:53 +00:00
|
|
|
ConfMan.flushToDisk();
|
|
|
|
}
|
|
|
|
}
|
2004-01-26 08:20:26 +00:00
|
|
|
// See if the output frequency is forced by the game
|
2007-02-26 18:09:41 +00:00
|
|
|
if (gameid == "ft" || gameid == "dig" || gameid == "comi" || gameid == "queen" || gameid == "sword" || gameid == "agi")
|
2004-01-26 22:38:08 +00:00
|
|
|
_sampleRate = SAMPLES_PER_SEC_NEW;
|
2004-01-26 08:20:26 +00:00
|
|
|
else {
|
2004-05-09 15:02:10 +00:00
|
|
|
if (ConfMan.hasKey("high_sample_rate") && ConfMan.getBool("high_sample_rate"))
|
2004-01-26 22:38:08 +00:00
|
|
|
_sampleRate = SAMPLES_PER_SEC_NEW;
|
2004-01-26 08:20:26 +00:00
|
|
|
else
|
2004-01-26 22:38:08 +00:00
|
|
|
_sampleRate = SAMPLES_PER_SEC_OLD;
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
2004-01-26 22:38:08 +00:00
|
|
|
|
|
|
|
#ifdef USE_VORBIS
|
2006-11-12 21:06:56 +00:00
|
|
|
// Modify the sample rate on the fly if OGG is involved
|
|
|
|
if (_sampleRate == SAMPLES_PER_SEC_OLD)
|
|
|
|
if (checkOggHighSampleRate())
|
|
|
|
_sampleRate = SAMPLES_PER_SEC_NEW;
|
2004-01-26 22:38:08 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2004-05-09 15:02:10 +00:00
|
|
|
int OSystem_WINCE3::getOutputSampleRate() const {
|
|
|
|
return _sampleRate;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::setWindowCaption(const char *caption) {
|
|
|
|
check_mappings(); // called here to initialize virtual keys handling
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2004-05-09 15:02:10 +00:00
|
|
|
//update_game_settings();
|
2006-11-12 11:47:43 +00:00
|
|
|
// finalize mixer init
|
2008-06-28 15:28:29 +00:00
|
|
|
compute_sample_rate();
|
|
|
|
setupMixer();
|
2006-11-12 21:06:56 +00:00
|
|
|
|
|
|
|
// handle the actual event
|
|
|
|
OSystem_SDL::setWindowCaption(caption);
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool OSystem_WINCE3::openCD(int drive) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2004-05-30 13:24:51 +00:00
|
|
|
const OSystem::GraphicsMode *OSystem_WINCE3::getSupportedGraphicsModes() const {
|
|
|
|
if (CEDevice::hasWideResolution())
|
|
|
|
return s_supportedGraphicsModesHigh;
|
|
|
|
else
|
|
|
|
return s_supportedGraphicsModesLow;
|
|
|
|
}
|
2004-05-09 15:02:10 +00:00
|
|
|
|
|
|
|
bool OSystem_WINCE3::hasFeature(Feature f) {
|
2006-11-12 21:06:56 +00:00
|
|
|
return (f == kFeatureAutoComputeDirtyRects || f == kFeatureVirtualKeyboard);
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::setFeatureState(Feature f, bool enable) {
|
|
|
|
switch(f) {
|
|
|
|
case kFeatureFullscreenMode:
|
|
|
|
return;
|
2007-06-03 19:29:13 +00:00
|
|
|
|
2004-05-09 15:02:10 +00:00
|
|
|
case kFeatureVirtualKeyboard:
|
2005-10-16 22:52:46 +00:00
|
|
|
if (_hasSmartphoneResolution)
|
2004-12-21 00:31:58 +00:00
|
|
|
return;
|
2004-05-09 15:02:10 +00:00
|
|
|
_toolbarHighDrawn = false;
|
|
|
|
if (enable) {
|
|
|
|
_panelStateForced = true;
|
2006-06-10 11:16:43 +00:00
|
|
|
if (!_toolbarHandler.visible()) swap_panel_visibility();
|
|
|
|
//_saveToolbarState = _toolbarHandler.visible();
|
2004-05-09 15:02:10 +00:00
|
|
|
_saveActiveToolbar = _toolbarHandler.activeName();
|
|
|
|
_toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
|
|
|
|
_toolbarHandler.setVisible(true);
|
|
|
|
}
|
2008-01-27 19:47:41 +00:00
|
|
|
else
|
2006-06-10 11:16:43 +00:00
|
|
|
if (_panelStateForced) {
|
|
|
|
_panelStateForced = false;
|
|
|
|
_toolbarHandler.setActive(_saveActiveToolbar);
|
|
|
|
//_toolbarHandler.setVisible(_saveToolbarState);
|
|
|
|
}
|
2004-05-09 15:02:10 +00:00
|
|
|
return;
|
2007-06-03 19:29:13 +00:00
|
|
|
|
|
|
|
case kFeatureDisableKeyFiltering:
|
|
|
|
if (_hasSmartphoneResolution)
|
|
|
|
_unfilteredkeys = enable;
|
|
|
|
return;
|
|
|
|
|
2004-05-09 15:02:10 +00:00
|
|
|
default:
|
|
|
|
OSystem_SDL::setFeatureState(f, enable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OSystem_WINCE3::getFeatureState(Feature f) {
|
|
|
|
switch(f) {
|
|
|
|
case kFeatureFullscreenMode:
|
|
|
|
return false;
|
|
|
|
case kFeatureVirtualKeyboard:
|
|
|
|
return (_panelStateForced);
|
|
|
|
}
|
|
|
|
return OSystem_SDL::getFeatureState(f);
|
|
|
|
}
|
|
|
|
|
2004-01-28 01:12:48 +00:00
|
|
|
void OSystem_WINCE3::check_mappings() {
|
2007-11-13 19:49:01 +00:00
|
|
|
CEActionsPocket *instance;
|
2004-05-09 15:02:10 +00:00
|
|
|
|
2007-11-13 19:49:01 +00:00
|
|
|
Common::String gameid(ConfMan.get("gameid"));
|
2006-04-12 19:04:10 +00:00
|
|
|
|
2007-11-13 19:49:01 +00:00
|
|
|
if (gameid.empty() || GUI_Actions::Instance()->initialized())
|
|
|
|
return;
|
2004-05-09 15:02:10 +00:00
|
|
|
|
2007-11-13 19:49:01 +00:00
|
|
|
GUI_Actions::Instance()->initInstanceGame();
|
|
|
|
instance = (CEActionsPocket*)GUI_Actions::Instance();
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-11-13 19:49:01 +00:00
|
|
|
// Some games need to map the right click button, signal it here if it wasn't done
|
|
|
|
if (instance->needsRightClickMapping()) {
|
|
|
|
GUI::KeysDialog *keysDialog = new GUI::KeysDialog("Map right click action");
|
|
|
|
while (!instance->getMapping(POCKET_ACTION_RIGHTCLICK)) {
|
|
|
|
keysDialog->runModal();
|
|
|
|
if (!instance->getMapping(POCKET_ACTION_RIGHTCLICK)) {
|
|
|
|
GUI::MessageDialog alert("You must map a key to the 'Right Click' action to play this game");
|
|
|
|
alert.runModal();
|
2004-01-28 01:12:48 +00:00
|
|
|
}
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
2007-11-13 19:49:01 +00:00
|
|
|
delete keysDialog;
|
|
|
|
}
|
2004-05-09 15:02:10 +00:00
|
|
|
|
2007-11-13 19:49:01 +00:00
|
|
|
// Map the "hide toolbar" action if needed
|
|
|
|
if (instance->needsHideToolbarMapping()) {
|
|
|
|
GUI::KeysDialog *keysDialog = new GUI::KeysDialog("Map hide toolbar action");
|
|
|
|
while (!instance->getMapping(POCKET_ACTION_HIDE)) {
|
2004-05-09 15:02:10 +00:00
|
|
|
keysDialog->runModal();
|
2007-11-13 19:49:01 +00:00
|
|
|
if (!instance->getMapping(POCKET_ACTION_HIDE)) {
|
|
|
|
GUI::MessageDialog alert("You must map a key to the 'Hide toolbar' action to play this game");
|
|
|
|
alert.runModal();
|
|
|
|
}
|
2004-01-28 01:12:48 +00:00
|
|
|
}
|
2007-11-13 19:49:01 +00:00
|
|
|
delete keysDialog;
|
|
|
|
}
|
2004-01-28 01:12:48 +00:00
|
|
|
|
2007-11-13 19:49:01 +00:00
|
|
|
// Map the "zoom" actions if needed
|
|
|
|
if (instance->needsZoomMapping()) {
|
|
|
|
GUI::KeysDialog *keysDialog = new GUI::KeysDialog("Map Zoom Up action (optional)");
|
|
|
|
keysDialog->runModal();
|
|
|
|
delete keysDialog;
|
|
|
|
keysDialog = new GUI::KeysDialog("Map Zoom Down action (optional)");
|
|
|
|
keysDialog->runModal();
|
|
|
|
delete keysDialog;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Extra warning for Zak Mc Kracken
|
|
|
|
if (strncmp(gameid.c_str(), "zak", 3) == 0 &&
|
|
|
|
!GUI_Actions::Instance()->getMapping(POCKET_ACTION_HIDE)) {
|
|
|
|
GUI::MessageDialog alert("Don't forget to map a key to 'Hide Toolbar' action to see the whole inventory");
|
|
|
|
alert.runModal();
|
|
|
|
}
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2004-01-28 01:12:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::update_game_settings() {
|
2006-04-15 17:39:14 +00:00
|
|
|
Common::String gameid(ConfMan.get("gameid"));
|
2006-04-12 19:04:10 +00:00
|
|
|
|
2004-01-28 01:12:48 +00:00
|
|
|
// Finish panel initialization
|
2006-04-15 17:39:14 +00:00
|
|
|
if (!_panelInitialized && !gameid.empty()) {
|
2004-01-28 01:12:48 +00:00
|
|
|
Panel *panel;
|
2005-07-30 21:11:48 +00:00
|
|
|
_panelInitialized = true;
|
2004-01-28 01:12:48 +00:00
|
|
|
// Add the main panel
|
2006-06-10 11:16:43 +00:00
|
|
|
panel = new Panel(0, 32);
|
2004-01-28 01:12:48 +00:00
|
|
|
panel->setBackground(IMAGE_PANEL);
|
|
|
|
// Save
|
2004-05-09 15:02:10 +00:00
|
|
|
panel->add(NAME_ITEM_OPTIONS, new ItemAction(ITEM_OPTIONS, POCKET_ACTION_SAVE));
|
2004-01-28 01:12:48 +00:00
|
|
|
// Skip
|
2004-05-09 15:02:10 +00:00
|
|
|
panel->add(NAME_ITEM_SKIP, new ItemAction(ITEM_SKIP, POCKET_ACTION_SKIP));
|
2004-01-28 01:12:48 +00:00
|
|
|
// sound
|
2005-07-30 21:11:48 +00:00
|
|
|
panel->add(NAME_ITEM_SOUND, new ItemSwitch(ITEM_SOUND_OFF, ITEM_SOUND_ON, &_soundMaster));
|
2006-06-10 11:16:43 +00:00
|
|
|
// bind keys
|
|
|
|
panel->add(NAME_ITEM_BINDKEYS, new ItemAction(ITEM_BINDKEYS, POCKET_ACTION_BINDKEYS));
|
|
|
|
// portrait/landscape - screen dependent
|
2004-12-21 00:31:58 +00:00
|
|
|
// FIXME : will still display the portrait/landscape icon when using a scaler (but will be disabled)
|
2007-04-28 17:48:58 +00:00
|
|
|
if (ConfMan.hasKey("landscape"))
|
|
|
|
if (ConfMan.get("landscape")[0] > 57) {
|
|
|
|
_newOrientation = _orientationLandscape = ConfMan.getBool("landscape");
|
|
|
|
//ConfMan.removeKey("landscape", "");
|
|
|
|
ConfMan.setInt("landscape", _orientationLandscape);
|
|
|
|
} else
|
|
|
|
_newOrientation = _orientationLandscape = ConfMan.getInt("landscape");
|
|
|
|
else
|
|
|
|
_newOrientation = _orientationLandscape = 0;
|
|
|
|
panel->add(NAME_ITEM_ORIENTATION, new ItemSwitch(ITEM_VIEW_LANDSCAPE, ITEM_VIEW_PORTRAIT, &_newOrientation, 2));
|
2004-01-28 01:12:48 +00:00
|
|
|
_toolbarHandler.add(NAME_MAIN_PANEL, *panel);
|
|
|
|
_toolbarHandler.setActive(NAME_MAIN_PANEL);
|
2005-10-16 22:52:46 +00:00
|
|
|
_toolbarHandler.setVisible(true);
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (_videoMode.mode == GFX_NORMAL && ConfMan.hasKey("landscape") && ConfMan.getInt("landscape")) {
|
2004-05-09 15:02:10 +00:00
|
|
|
setGraphicsMode(GFX_NORMAL);
|
2004-12-11 00:41:31 +00:00
|
|
|
hotswapGFXMode();
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2005-10-16 22:52:46 +00:00
|
|
|
if (_hasSmartphoneResolution)
|
2004-12-21 00:31:58 +00:00
|
|
|
panel->setVisible(false);
|
2005-03-26 13:24:53 +00:00
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
_saveToolbarState = true;
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2008-08-25 08:48:46 +00:00
|
|
|
if (ConfMan.hasKey("no_doubletap_rightclick"))
|
|
|
|
_noDoubleTapRMB = ConfMan.getBool("no_doubletap_rightclick");
|
|
|
|
|
2008-06-28 15:28:29 +00:00
|
|
|
compute_sample_rate();
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
2006-05-17 23:52:45 +00:00
|
|
|
void OSystem_WINCE3::initSize(uint w, uint h) {
|
2005-10-16 22:52:46 +00:00
|
|
|
if (_hasSmartphoneResolution && h == 240)
|
2005-03-15 09:43:38 +00:00
|
|
|
h = 200; // mainly for the launcher
|
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
if (_isSmartphone && !ConfMan.hasKey("landscape"))
|
|
|
|
{
|
|
|
|
ConfMan.setInt("landscape", 1);
|
|
|
|
ConfMan.flushToDisk();
|
|
|
|
}
|
|
|
|
|
2005-10-16 22:52:46 +00:00
|
|
|
if (w == 320 && h == 200 && !_hasSmartphoneResolution)
|
2004-01-26 08:20:26 +00:00
|
|
|
h = 240; // use the extra 40 pixels height for the toolbar
|
2004-01-28 01:12:48 +00:00
|
|
|
|
2007-04-30 21:12:57 +00:00
|
|
|
if (h == 400) // touche engine fixup
|
|
|
|
h += 80;
|
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
if (!_hasSmartphoneResolution)
|
2004-12-21 00:31:58 +00:00
|
|
|
if (h == 240)
|
|
|
|
_toolbarHandler.setOffset(200);
|
|
|
|
else
|
2005-07-30 21:11:48 +00:00
|
|
|
_toolbarHandler.setOffset(400);
|
2006-06-10 11:16:43 +00:00
|
|
|
else
|
|
|
|
if (h == 240)
|
|
|
|
_toolbarHandler.setOffset(200);
|
|
|
|
else // 176x220
|
|
|
|
_toolbarHandler.setOffset(0);
|
2004-01-28 01:12:48 +00:00
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (w != (uint) _videoMode.screenWidth || h != (uint) _videoMode.screenHeight)
|
2004-05-30 13:24:51 +00:00
|
|
|
_scalersChanged = false;
|
2004-01-28 01:12:48 +00:00
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.overlayWidth = w;
|
|
|
|
_videoMode.overlayHeight = h;
|
2006-06-06 19:31:49 +00:00
|
|
|
|
2006-05-17 23:52:45 +00:00
|
|
|
OSystem_SDL::initSize(w, h);
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2004-05-30 13:24:51 +00:00
|
|
|
if (_scalersChanged) {
|
2004-12-11 00:41:31 +00:00
|
|
|
unloadGFXMode();
|
|
|
|
loadGFXMode();
|
2004-05-30 13:24:51 +00:00
|
|
|
_scalersChanged = false;
|
|
|
|
}
|
|
|
|
|
2005-07-30 21:11:48 +00:00
|
|
|
update_game_settings();
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
2005-10-16 22:52:46 +00:00
|
|
|
|
2004-05-09 15:02:10 +00:00
|
|
|
int OSystem_WINCE3::getDefaultGraphicsMode() const {
|
2005-07-30 21:11:48 +00:00
|
|
|
return GFX_NORMAL;
|
2004-05-09 15:02:10 +00:00
|
|
|
}
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2004-05-09 15:02:10 +00:00
|
|
|
bool OSystem_WINCE3::update_scalers() {
|
2008-12-10 20:46:19 +00:00
|
|
|
if (_videoMode.mode != GFX_NORMAL)
|
2004-12-11 00:41:31 +00:00
|
|
|
return false;
|
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.aspectRatio = false;
|
2006-08-25 06:30:18 +00:00
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
if (CEDevice::hasPocketPCResolution()) {
|
2008-12-10 20:46:19 +00:00
|
|
|
if ( (!_orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth))
|
2007-05-01 15:19:11 +00:00
|
|
|
|| CEDevice::hasSquareQVGAResolution() ) {
|
2007-05-27 19:05:51 +00:00
|
|
|
if (getScreenWidth() != 320) {
|
|
|
|
_scaleFactorXm = 3;
|
|
|
|
_scaleFactorXd = 4;
|
|
|
|
_scaleFactorYm = 1;
|
|
|
|
_scaleFactorYd = 1;
|
|
|
|
_scalerProc = PocketPCPortrait;
|
|
|
|
_modeFlags = 0;
|
|
|
|
} else {
|
|
|
|
_scaleFactorXm = 1;
|
|
|
|
_scaleFactorXd = 1;
|
|
|
|
_scaleFactorYm = 1;
|
|
|
|
_scaleFactorYd = 1;
|
|
|
|
_scalerProc = Normal1x;
|
|
|
|
_modeFlags = 0;
|
|
|
|
}
|
2008-12-10 20:46:19 +00:00
|
|
|
} else if ( _orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth)) {
|
|
|
|
Common::String gameid(ConfMan.get("gameid")); // consider removing this check and start honoring the _videoMode.aspectRatio flag
|
2006-07-26 20:09:12 +00:00
|
|
|
if (!_panelVisible && !_hasSmartphoneResolution && !_overlayVisible && !(strncmp(gameid.c_str(), "zak", 3) == 0)) {
|
2006-06-10 11:16:43 +00:00
|
|
|
_scaleFactorXm = 1;
|
|
|
|
_scaleFactorXd = 1;
|
|
|
|
_scaleFactorYm = 6;
|
|
|
|
_scaleFactorYd = 5;
|
|
|
|
_scalerProc = PocketPCLandscapeAspect;
|
|
|
|
_modeFlags = 0;
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.aspectRatio = true;
|
2006-06-10 11:16:43 +00:00
|
|
|
} else {
|
|
|
|
_scaleFactorXm = 1;
|
|
|
|
_scaleFactorXd = 1;
|
|
|
|
_scaleFactorYm = 1;
|
|
|
|
_scaleFactorYd = 1;
|
|
|
|
_scalerProc = Normal1x;
|
|
|
|
_modeFlags = 0;
|
|
|
|
}
|
2008-12-10 20:46:19 +00:00
|
|
|
} else if (_videoMode.screenWidth == 640 && !(isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) {
|
2004-01-26 08:20:26 +00:00
|
|
|
_scaleFactorXm = 1;
|
|
|
|
_scaleFactorXd = 2;
|
|
|
|
_scaleFactorYm = 1;
|
|
|
|
_scaleFactorYd = 2;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = PocketPCHalf;
|
|
|
|
_modeFlags = 0;
|
2008-12-10 20:46:19 +00:00
|
|
|
} else if (_videoMode.screenWidth == 640 && (isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) {
|
2004-05-30 13:24:51 +00:00
|
|
|
_scaleFactorXm = 1;
|
|
|
|
_scaleFactorXd = 1;
|
|
|
|
_scaleFactorYm = 1;
|
|
|
|
_scaleFactorYd = 1;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = Normal1x;
|
|
|
|
_modeFlags = 0;
|
2004-05-30 13:24:51 +00:00
|
|
|
}
|
2004-05-09 15:02:10 +00:00
|
|
|
|
|
|
|
return true;
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
2007-05-01 15:19:11 +00:00
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
if (CEDevice::hasSmartphoneResolution()) {
|
2008-12-10 20:46:19 +00:00
|
|
|
if (_videoMode.screenWidth > 320)
|
2004-05-09 15:02:10 +00:00
|
|
|
error("Game resolution not supported on Smartphone");
|
|
|
|
_scaleFactorXm = 2;
|
|
|
|
_scaleFactorXd = 3;
|
|
|
|
_scaleFactorYm = 7;
|
|
|
|
_scaleFactorYd = 8;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = SmartphoneLandscape;
|
|
|
|
_modeFlags = 0;
|
2005-01-28 23:45:53 +00:00
|
|
|
initZones();
|
2004-05-09 15:02:10 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OSystem_WINCE3::setGraphicsMode(int mode) {
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2004-05-09 15:02:10 +00:00
|
|
|
Common::StackLock lock(_graphicsMutex);
|
2004-05-30 13:24:51 +00:00
|
|
|
int oldScaleFactorXm = _scaleFactorXm;
|
|
|
|
int oldScaleFactorXd = _scaleFactorXd;
|
|
|
|
int oldScaleFactorYm = _scaleFactorYm;
|
|
|
|
int oldScaleFactorYd = _scaleFactorYd;
|
2004-05-09 15:02:10 +00:00
|
|
|
|
|
|
|
_scaleFactorXm = -1;
|
|
|
|
_scaleFactorXd = -1;
|
2005-07-30 21:11:48 +00:00
|
|
|
_scaleFactorYm = -1;
|
|
|
|
_scaleFactorYd = -1;
|
2004-05-09 15:02:10 +00:00
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
if (ConfMan.hasKey("landscape"))
|
|
|
|
if (ConfMan.get("landscape")[0] > 57) {
|
|
|
|
_newOrientation = _orientationLandscape = ConfMan.getBool("landscape");
|
|
|
|
ConfMan.setInt("landscape", _orientationLandscape);
|
|
|
|
} else
|
|
|
|
_newOrientation = _orientationLandscape = ConfMan.getInt("landscape");
|
|
|
|
else
|
|
|
|
_newOrientation = _orientationLandscape = 0;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2004-05-09 15:02:10 +00:00
|
|
|
update_scalers();
|
2004-12-11 00:41:31 +00:00
|
|
|
|
|
|
|
if (isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640) && mode)
|
|
|
|
_scaleFactorXm = -1;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2004-05-30 13:24:51 +00:00
|
|
|
if (CEDevice::hasPocketPCResolution() && !CEDevice::hasWideResolution() && _orientationLandscape)
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.mode = GFX_NORMAL;
|
2004-05-30 13:24:51 +00:00
|
|
|
else
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.mode = mode;
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2005-07-30 21:11:48 +00:00
|
|
|
if (_scaleFactorXm < 0) {
|
2004-01-26 08:20:26 +00:00
|
|
|
/* Standard scalers, from the SDL backend */
|
2008-12-10 20:46:19 +00:00
|
|
|
switch(_videoMode.mode) {
|
2005-07-30 21:11:48 +00:00
|
|
|
case GFX_NORMAL:
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.scaleFactor = 1;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = Normal1x;
|
2004-01-26 08:20:26 +00:00
|
|
|
break;
|
2005-07-30 21:11:48 +00:00
|
|
|
case GFX_DOUBLESIZE:
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.scaleFactor = 2;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = Normal2x;
|
2004-01-26 08:20:26 +00:00
|
|
|
break;
|
|
|
|
case GFX_TRIPLESIZE:
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.scaleFactor = 3;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = Normal3x;
|
2004-01-26 08:20:26 +00:00
|
|
|
break;
|
|
|
|
case GFX_2XSAI:
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.scaleFactor = 2;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = _2xSaI;
|
2004-01-26 08:20:26 +00:00
|
|
|
break;
|
|
|
|
case GFX_SUPER2XSAI:
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.scaleFactor = 2;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = Super2xSaI;
|
2004-01-26 08:20:26 +00:00
|
|
|
break;
|
|
|
|
case GFX_SUPEREAGLE:
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.scaleFactor = 2;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = SuperEagle;
|
2004-01-26 08:20:26 +00:00
|
|
|
break;
|
|
|
|
case GFX_ADVMAME2X:
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.scaleFactor = 2;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = AdvMame2x;
|
2004-01-26 08:20:26 +00:00
|
|
|
break;
|
|
|
|
case GFX_ADVMAME3X:
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.scaleFactor = 3;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = AdvMame3x;
|
2004-01-26 08:20:26 +00:00
|
|
|
break;
|
2007-02-04 17:45:00 +00:00
|
|
|
#ifndef DISABLE_HQ_SCALERS
|
2004-01-26 08:20:26 +00:00
|
|
|
case GFX_HQ2X:
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.scaleFactor = 2;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = HQ2x;
|
2004-01-26 08:20:26 +00:00
|
|
|
break;
|
|
|
|
case GFX_HQ3X:
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.scaleFactor = 3;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = HQ3x;
|
2004-01-26 08:20:26 +00:00
|
|
|
break;
|
2007-02-04 17:45:00 +00:00
|
|
|
#endif
|
2004-01-26 08:20:26 +00:00
|
|
|
case GFX_TV2X:
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.scaleFactor = 2;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = TV2x;
|
2004-01-26 08:20:26 +00:00
|
|
|
break;
|
|
|
|
case GFX_DOTMATRIX:
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.scaleFactor = 2;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = DotMatrix;
|
2004-01-26 08:20:26 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2008-12-10 20:46:19 +00:00
|
|
|
error("unknown gfx mode %d", mode);
|
2005-07-30 21:11:48 +00:00
|
|
|
}
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check if the scaler can be accepted, if not get back to normal scaler
|
2008-12-10 20:46:19 +00:00
|
|
|
if (_videoMode.scaleFactor && ((_videoMode.scaleFactor * _videoMode.screenWidth > getScreenWidth() && _videoMode.scaleFactor * _videoMode.screenWidth > getScreenHeight())
|
|
|
|
|| (_videoMode.scaleFactor * _videoMode.screenHeight > getScreenWidth() && _videoMode.scaleFactor * _videoMode.screenHeight > getScreenHeight()))) {
|
|
|
|
_videoMode.scaleFactor = 1;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc = Normal1x;
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Common scaler system was used
|
|
|
|
if (_scaleFactorXm < 0) {
|
2008-12-10 20:46:19 +00:00
|
|
|
_scaleFactorXm = _videoMode.scaleFactor;
|
2004-01-26 08:20:26 +00:00
|
|
|
_scaleFactorXd = 1;
|
2008-12-10 20:46:19 +00:00
|
|
|
_scaleFactorYm = _videoMode.scaleFactor;
|
2004-01-26 08:20:26 +00:00
|
|
|
_scaleFactorYd = 1;
|
|
|
|
}
|
|
|
|
|
2004-05-09 15:02:10 +00:00
|
|
|
_forceFull = true;
|
|
|
|
|
2004-05-30 13:24:51 +00:00
|
|
|
if (oldScaleFactorXm != _scaleFactorXm ||
|
|
|
|
oldScaleFactorXd != _scaleFactorXd ||
|
|
|
|
oldScaleFactorYm != _scaleFactorYm ||
|
|
|
|
oldScaleFactorYd != _scaleFactorYd) {
|
|
|
|
_scalersChanged = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
_scalersChanged = false;
|
|
|
|
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2004-05-09 15:02:10 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-12-04 08:10:32 +00:00
|
|
|
bool OSystem_WINCE3::loadGFXMode() {
|
2004-05-09 15:02:10 +00:00
|
|
|
int displayWidth;
|
|
|
|
int displayHeight;
|
2006-06-10 11:16:43 +00:00
|
|
|
unsigned int flags = SDL_FULLSCREEN | SDL_SWSURFACE;
|
2004-05-09 15:02:10 +00:00
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
_videoMode.fullscreen = true; // forced
|
2004-05-09 15:02:10 +00:00
|
|
|
_forceFull = true;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2004-05-09 15:02:10 +00:00
|
|
|
_tmpscreen = NULL;
|
|
|
|
|
|
|
|
// Recompute scalers if necessary
|
|
|
|
update_scalers();
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
// Create the surface that contains the 8 bit game data
|
2008-12-10 20:46:19 +00:00
|
|
|
_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
|
2004-01-26 08:20:26 +00:00
|
|
|
if (_screen == NULL)
|
2007-05-05 09:31:48 +00:00
|
|
|
error("_screen failed (%s)", SDL_GetError());
|
2004-01-26 08:20:26 +00:00
|
|
|
|
|
|
|
// Create the surface that contains the scaled graphics in 16 bit mode
|
|
|
|
// Always use full screen mode to have a "clean screen"
|
2008-12-10 20:46:19 +00:00
|
|
|
if (!_videoMode.aspectRatio) {
|
|
|
|
displayWidth = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd;
|
|
|
|
displayHeight = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd;
|
2007-04-28 17:48:58 +00:00
|
|
|
} else {
|
2008-12-10 20:46:19 +00:00
|
|
|
displayWidth = _videoMode.screenWidth;
|
|
|
|
displayHeight = _videoMode.screenHeight;
|
2007-04-28 17:48:58 +00:00
|
|
|
}
|
2007-04-30 21:12:57 +00:00
|
|
|
|
2007-04-28 17:48:58 +00:00
|
|
|
switch (_orientationLandscape) {
|
|
|
|
case 1:
|
|
|
|
flags |= SDL_LANDSCVIDEO;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
flags |= SDL_INVLNDVIDEO;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
flags |= SDL_PORTRTVIDEO;
|
|
|
|
}
|
2006-06-10 11:16:43 +00:00
|
|
|
_hwscreen = SDL_SetVideoMode(displayWidth, displayHeight, 16, flags);
|
2005-07-30 21:11:48 +00:00
|
|
|
|
|
|
|
if (_hwscreen == NULL) {
|
2007-05-05 09:31:48 +00:00
|
|
|
warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
|
2005-07-30 21:11:48 +00:00
|
|
|
quit();
|
2009-01-01 15:06:43 +00:00
|
|
|
}
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-04-28 17:48:58 +00:00
|
|
|
// see what orientation sdl finally accepted
|
|
|
|
if (_hwscreen->flags & SDL_PORTRTVIDEO)
|
|
|
|
_orientationLandscape = _newOrientation = 0;
|
|
|
|
else if (_hwscreen->flags & SDL_LANDSCVIDEO)
|
|
|
|
_orientationLandscape = _newOrientation = 1;
|
|
|
|
else
|
|
|
|
_orientationLandscape = _newOrientation = 2;
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-04-28 17:48:58 +00:00
|
|
|
// Create the surface used for the graphics in 16 bit before scaling, and also the overlay
|
2004-01-26 08:20:26 +00:00
|
|
|
// Distinguish 555 and 565 mode
|
|
|
|
if (_hwscreen->format->Rmask == 0x7C00)
|
|
|
|
InitScalers(555);
|
|
|
|
else
|
|
|
|
InitScalers(565);
|
2004-02-20 23:05:00 +00:00
|
|
|
initCEScaler();
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
// Need some extra bytes around when using 2xSaI
|
2008-12-10 20:46:19 +00:00
|
|
|
_tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
|
2004-01-26 08:20:26 +00:00
|
|
|
|
|
|
|
if (_tmpscreen == NULL)
|
2007-05-05 09:31:48 +00:00
|
|
|
error("_tmpscreen creation failed (%s)", SDL_GetError());
|
2005-03-16 22:27:11 +00:00
|
|
|
|
|
|
|
// Overlay
|
2006-06-20 18:03:02 +00:00
|
|
|
if (CEDevice::hasDesktopResolution()) {
|
2008-12-10 20:46:19 +00:00
|
|
|
_overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd, 16, 0, 0, 0, 0);
|
2006-06-20 18:03:02 +00:00
|
|
|
if (_overlayscreen == NULL)
|
2007-05-05 09:31:48 +00:00
|
|
|
error("_overlayscreen failed (%s)", SDL_GetError());
|
2008-12-10 20:46:19 +00:00
|
|
|
_tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd + 3, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd + 3, 16, 0, 0, 0, 0);
|
2006-06-20 18:03:02 +00:00
|
|
|
if (_tmpscreen2 == NULL)
|
2007-05-05 09:31:48 +00:00
|
|
|
error("_tmpscreen2 failed (%s)", SDL_GetError());
|
2006-06-20 18:03:02 +00:00
|
|
|
} else {
|
2008-12-10 20:46:19 +00:00
|
|
|
_overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight, 16, 0, 0, 0, 0);
|
2006-06-20 18:03:02 +00:00
|
|
|
if (_overlayscreen == NULL)
|
2007-05-05 09:31:48 +00:00
|
|
|
error("_overlayscreen failed (%s)", SDL_GetError());
|
2008-12-10 20:46:19 +00:00
|
|
|
_tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3, 16, 0, 0, 0, 0);
|
2006-06-20 18:03:02 +00:00
|
|
|
if (_tmpscreen2 == NULL)
|
2007-05-05 09:31:48 +00:00
|
|
|
error("_tmpscreen2 failed (%s)", SDL_GetError());
|
2006-06-20 18:03:02 +00:00
|
|
|
}
|
2005-03-16 22:27:11 +00:00
|
|
|
|
2004-01-28 01:12:48 +00:00
|
|
|
// Toolbar
|
2007-04-30 20:31:56 +00:00
|
|
|
_toolbarHighDrawn = false;
|
|
|
|
uint16 *toolbar_screen = (uint16 *)calloc(320 * 40, sizeof(uint16)); // *not* leaking memory here
|
2006-11-12 21:06:56 +00:00
|
|
|
_toolbarLow = SDL_CreateRGBSurfaceFrom(toolbar_screen, 320, 40, 16, 320 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
|
|
|
|
|
2004-01-28 01:12:48 +00:00
|
|
|
if (_toolbarLow == NULL)
|
2007-05-05 09:31:48 +00:00
|
|
|
error("_toolbarLow failed (%s)", SDL_GetError());
|
2004-01-28 01:12:48 +00:00
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (_videoMode.screenHeight > 240) {
|
2004-01-28 01:12:48 +00:00
|
|
|
uint16 *toolbar_screen = (uint16 *)calloc(640 * 80, sizeof(uint16));
|
2006-11-12 21:06:56 +00:00
|
|
|
_toolbarHigh = SDL_CreateRGBSurfaceFrom(toolbar_screen, 640, 80, 16, 640 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
|
|
|
|
|
2004-01-28 01:12:48 +00:00
|
|
|
if (_toolbarHigh == NULL)
|
2007-05-05 09:31:48 +00:00
|
|
|
error("_toolbarHigh failed (%s)", SDL_GetError());
|
2006-11-12 21:06:56 +00:00
|
|
|
} else
|
2004-01-28 01:12:48 +00:00
|
|
|
_toolbarHigh = NULL;
|
|
|
|
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
// keyboard cursor control, some other better place for it?
|
2008-12-10 20:46:19 +00:00
|
|
|
_km.x_max = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd - 1;
|
|
|
|
_km.y_max = _videoMode.screenHeight * _scaleFactorXm / _scaleFactorXd - 1;
|
2004-12-11 00:41:31 +00:00
|
|
|
_km.delay_time = 25;
|
2005-07-30 21:11:48 +00:00
|
|
|
_km.last_time = 0;
|
2009-01-01 15:06:43 +00:00
|
|
|
|
|
|
|
return true;
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
2004-12-11 00:41:31 +00:00
|
|
|
void OSystem_WINCE3::unloadGFXMode() {
|
2004-01-26 08:20:26 +00:00
|
|
|
if (_screen) {
|
|
|
|
SDL_FreeSurface(_screen);
|
2005-07-30 21:11:48 +00:00
|
|
|
_screen = NULL;
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_hwscreen) {
|
2005-07-30 21:11:48 +00:00
|
|
|
SDL_FreeSurface(_hwscreen);
|
2004-01-26 08:20:26 +00:00
|
|
|
_hwscreen = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_tmpscreen) {
|
|
|
|
SDL_FreeSurface(_tmpscreen);
|
|
|
|
_tmpscreen = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-04 08:10:32 +00:00
|
|
|
bool OSystem_WINCE3::hotswapGFXMode() {
|
2004-01-26 08:20:26 +00:00
|
|
|
if (!_screen)
|
2008-12-04 08:10:32 +00:00
|
|
|
return false;
|
2004-01-26 08:20:26 +00:00
|
|
|
|
|
|
|
// Keep around the old _screen & _tmpscreen so we can restore the screen data
|
2006-06-10 11:16:43 +00:00
|
|
|
// after the mode switch. (also for the overlay)
|
2004-01-26 08:20:26 +00:00
|
|
|
SDL_Surface *old_screen = _screen;
|
|
|
|
SDL_Surface *old_tmpscreen = _tmpscreen;
|
2006-06-10 11:16:43 +00:00
|
|
|
SDL_Surface *old_overlayscreen = _overlayscreen;
|
|
|
|
SDL_Surface *old_tmpscreen2 = _tmpscreen2;
|
2004-01-26 08:20:26 +00:00
|
|
|
|
|
|
|
// Release the HW screen surface
|
2005-07-30 21:11:48 +00:00
|
|
|
SDL_FreeSurface(_hwscreen);
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2004-01-28 01:12:48 +00:00
|
|
|
// Release toolbars
|
|
|
|
free(_toolbarLow->pixels);
|
|
|
|
SDL_FreeSurface(_toolbarLow);
|
|
|
|
if (_toolbarHigh) {
|
|
|
|
free(_toolbarHigh->pixels);
|
|
|
|
SDL_FreeSurface(_toolbarHigh);
|
|
|
|
}
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
// Setup the new GFX mode
|
2008-12-04 08:10:32 +00:00
|
|
|
if (!loadGFXMode()) {
|
|
|
|
unloadGFXMode();
|
|
|
|
|
|
|
|
_screen = old_screen;
|
|
|
|
_overlayscreen = old_overlayscreen;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2004-01-26 08:20:26 +00:00
|
|
|
|
|
|
|
// 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);
|
2006-06-10 11:16:43 +00:00
|
|
|
if (_overlayVisible) {
|
|
|
|
SDL_BlitSurface(old_overlayscreen, NULL, _overlayscreen, NULL);
|
|
|
|
SDL_BlitSurface(old_tmpscreen2, NULL, _tmpscreen2, NULL);
|
|
|
|
}
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
// Free the old surfaces
|
|
|
|
SDL_FreeSurface(old_screen);
|
|
|
|
SDL_FreeSurface(old_tmpscreen);
|
2006-06-10 11:16:43 +00:00
|
|
|
SDL_FreeSurface(old_overlayscreen);
|
|
|
|
SDL_FreeSurface(old_tmpscreen2);
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-04-28 22:37:42 +00:00
|
|
|
// Blit everything back to the screen
|
2007-04-30 20:31:56 +00:00
|
|
|
_toolbarHighDrawn = false;
|
2004-05-09 15:02:10 +00:00
|
|
|
internUpdateScreen();
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2007-04-28 17:48:58 +00:00
|
|
|
// Make sure that a Common::EVENT_SCREEN_CHANGED gets sent later -> FIXME this crashes when no game has been loaded.
|
|
|
|
// _modeChanged = true;
|
2008-12-04 08:10:32 +00:00
|
|
|
|
|
|
|
return true;
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
2004-03-28 20:31:18 +00:00
|
|
|
void OSystem_WINCE3::internUpdateScreen() {
|
2005-03-16 22:27:11 +00:00
|
|
|
SDL_Surface *srcSurf, *origSurf;
|
2006-06-10 11:16:43 +00:00
|
|
|
static bool old_overlayVisible = false;
|
2007-04-28 22:37:42 +00:00
|
|
|
int numRectsOut = 0;
|
2007-10-28 18:36:04 +00:00
|
|
|
int16 routx, routy, routw, routh, stretch;
|
2007-04-28 22:37:42 +00:00
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
assert(_hwscreen != NULL);
|
|
|
|
|
2007-04-28 22:37:42 +00:00
|
|
|
// bail if the application is minimized, be nice to OS
|
2007-04-28 17:48:58 +00:00
|
|
|
if (!_hasfocus) {
|
|
|
|
Sleep(20);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
// If the shake position changed, fill the dirty area with blackness
|
|
|
|
if (_currentShakePos != _newShakePos) {
|
2008-12-10 20:46:19 +00:00
|
|
|
SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd, _newShakePos * _scaleFactorYm / _scaleFactorYd};
|
|
|
|
if (_videoMode.aspectRatio)
|
2004-01-26 08:20:26 +00:00
|
|
|
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.
|
2004-12-11 00:41:31 +00:00
|
|
|
drawMouse();
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
// Check whether the palette was changed in the meantime and update the
|
2005-07-30 21:11:48 +00:00
|
|
|
// screen surface accordingly.
|
2004-01-26 08:20:26 +00:00
|
|
|
if (_paletteDirtyEnd != 0) {
|
2006-09-09 16:48:35 +00:00
|
|
|
SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart, _paletteDirtyStart, _paletteDirtyEnd - _paletteDirtyStart);
|
2004-01-26 08:20:26 +00:00
|
|
|
_paletteDirtyEnd = 0;
|
|
|
|
_forceFull = true;
|
|
|
|
}
|
|
|
|
|
2005-03-16 22:27:11 +00:00
|
|
|
if (!_overlayVisible) {
|
|
|
|
origSurf = _screen;
|
|
|
|
srcSurf = _tmpscreen;
|
2007-10-28 18:36:04 +00:00
|
|
|
} else {
|
2005-03-16 22:27:11 +00:00
|
|
|
origSurf = _overlayscreen;
|
|
|
|
srcSurf = _tmpscreen2;
|
|
|
|
}
|
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
if (old_overlayVisible != _overlayVisible) {
|
|
|
|
old_overlayVisible = _overlayVisible;
|
|
|
|
update_scalers();
|
|
|
|
}
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
// Force a full redraw if requested
|
|
|
|
if (_forceFull) {
|
2004-12-11 00:41:31 +00:00
|
|
|
_numDirtyRects = 1;
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2004-12-11 00:41:31 +00:00
|
|
|
_dirtyRectList[0].x = 0;
|
2004-05-09 15:02:10 +00:00
|
|
|
if (!_zoomDown)
|
2004-12-11 00:41:31 +00:00
|
|
|
_dirtyRectList[0].y = 0;
|
2004-05-09 15:02:10 +00:00
|
|
|
else
|
2008-12-10 20:46:19 +00:00
|
|
|
_dirtyRectList[0].y = _videoMode.screenHeight / 2;
|
|
|
|
_dirtyRectList[0].w = _videoMode.screenWidth;
|
2004-05-09 15:02:10 +00:00
|
|
|
if (!_zoomUp && !_zoomDown)
|
2008-12-10 20:46:19 +00:00
|
|
|
_dirtyRectList[0].h = _videoMode.screenHeight;
|
2004-05-09 15:02:10 +00:00
|
|
|
else
|
2008-12-10 20:46:19 +00:00
|
|
|
_dirtyRectList[0].h = _videoMode.screenHeight / 2;
|
2004-01-26 08:20:26 +00:00
|
|
|
|
|
|
|
_toolbarHandler.forceRedraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only draw anything if necessary
|
2004-12-11 00:41:31 +00:00
|
|
|
if (_numDirtyRects > 0) {
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-04-28 22:37:42 +00:00
|
|
|
SDL_Rect *r, *rout;
|
2004-01-26 08:20:26 +00:00
|
|
|
SDL_Rect dst;
|
|
|
|
uint32 srcPitch, dstPitch;
|
2004-12-11 00:41:31 +00:00
|
|
|
SDL_Rect *last_rect = _dirtyRectList + _numDirtyRects;
|
2004-01-26 22:38:08 +00:00
|
|
|
bool toolbarVisible = _toolbarHandler.visible();
|
2004-01-28 01:12:48 +00:00
|
|
|
int toolbarOffset = _toolbarHandler.getOffset();
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2006-09-09 16:48:35 +00:00
|
|
|
for (r = _dirtyRectList; r != last_rect; ++r) {
|
|
|
|
dst = *r;
|
2007-04-28 22:37:42 +00:00
|
|
|
dst.x++; // Shift rect by one since 2xSai needs to access the data around
|
2006-09-09 16:48:35 +00:00
|
|
|
dst.y++; // any pixel to scale it, and we want to avoid mem access crashes.
|
2007-04-28 22:37:42 +00:00
|
|
|
// NOTE: This is also known as BLACK MAGIC, copied from the sdl backend
|
2006-09-09 16:48:35 +00:00
|
|
|
if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)
|
|
|
|
error("SDL_BlitSurface failed: %s", SDL_GetError());
|
|
|
|
}
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2006-09-09 16:48:35 +00:00
|
|
|
SDL_LockSurface(srcSurf);
|
|
|
|
SDL_LockSurface(_hwscreen);
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2006-09-09 16:48:35 +00:00
|
|
|
srcPitch = srcSurf->pitch;
|
|
|
|
dstPitch = _hwscreen->pitch;
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-04-28 22:37:42 +00:00
|
|
|
for (r = _dirtyRectList, rout = _dirtyRectOut; r != last_rect; ++r) {
|
2007-10-28 18:36:04 +00:00
|
|
|
|
|
|
|
// always clamp to enclosing, downsampled-grid-aligned rect in the downscaled image
|
|
|
|
if (_scaleFactorXd != 1) {
|
|
|
|
stretch = r->x % _scaleFactorXd;
|
|
|
|
r->x -= stretch;
|
|
|
|
r->w += stretch;
|
|
|
|
r->w = (r->x + r->w + _scaleFactorXd - 1) / _scaleFactorXd * _scaleFactorXd - r->x;
|
|
|
|
}
|
|
|
|
if (_scaleFactorYd != 1) {
|
|
|
|
stretch = r->y % _scaleFactorYd;
|
|
|
|
r->y -= stretch;
|
|
|
|
r->h += stretch;
|
|
|
|
r->h = (r->y + r->h + _scaleFactorYd - 1) / _scaleFactorYd * _scaleFactorYd - r->y;
|
|
|
|
}
|
|
|
|
|
2007-04-28 22:37:42 +00:00
|
|
|
// transform
|
|
|
|
routx = r->x * _scaleFactorXm / _scaleFactorXd; // locate position in scaled screen
|
|
|
|
routy = (r->y + _currentShakePos) * _scaleFactorYm / _scaleFactorYd; // adjust for shake offset
|
|
|
|
routw = r->w * _scaleFactorXm / _scaleFactorXd;
|
|
|
|
routh = r->h * _scaleFactorYm / _scaleFactorYd;
|
|
|
|
|
|
|
|
// clipping destination rectangle inside device screen (more strict, also more tricky but more stable)
|
|
|
|
// note that all current scalers do not make dst rect exceed left/right, unless chosen badly (FIXME)
|
|
|
|
if (_zoomDown) routy -= 240; // adjust for zoom position
|
|
|
|
if (routy + routh < 0) continue;
|
2007-04-30 21:12:57 +00:00
|
|
|
if (routy < 0) {
|
|
|
|
routh += routy;
|
|
|
|
routy = 0;
|
|
|
|
}
|
2007-04-28 22:37:42 +00:00
|
|
|
if (_orientationLandscape) {
|
|
|
|
if (routy > _platformScreenWidth) continue;
|
|
|
|
if (routy + routh > _platformScreenWidth) {
|
|
|
|
routh = _platformScreenWidth - routy;
|
|
|
|
r->h = routh * _scaleFactorYd / _scaleFactorYm;
|
2007-04-28 17:48:58 +00:00
|
|
|
}
|
2007-04-28 22:37:42 +00:00
|
|
|
} else {
|
|
|
|
if (routy > _platformScreenHeight) continue;
|
|
|
|
if (routy + routh > _platformScreenHeight) {
|
|
|
|
routh = _platformScreenHeight - routy;
|
|
|
|
r->h = routh * _scaleFactorYd / _scaleFactorYm;
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
}
|
2006-09-09 16:48:35 +00:00
|
|
|
|
2007-04-28 22:37:42 +00:00
|
|
|
// check if the toolbar is overwritten
|
|
|
|
if (toolbarVisible && r->y + r->h >= toolbarOffset)
|
|
|
|
_toolbarHandler.forceRedraw();
|
|
|
|
|
|
|
|
// blit it (with added voodoo from the sdl backend, shifting the source rect again)
|
|
|
|
_scalerProc( (byte *)srcSurf->pixels + (r->x * 2 + 2)+ (r->y + 1) * srcPitch, srcPitch,
|
|
|
|
(byte *)_hwscreen->pixels + routx * 2 + routy * dstPitch, dstPitch,
|
|
|
|
r->w, r->h);
|
|
|
|
|
|
|
|
// add this rect to output
|
|
|
|
rout->x = routx; rout->y = routy;
|
|
|
|
rout->w = routw; rout->h = routh;
|
|
|
|
numRectsOut++;
|
|
|
|
rout++;
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
2006-09-09 16:48:35 +00:00
|
|
|
SDL_UnlockSurface(srcSurf);
|
|
|
|
SDL_UnlockSurface(_hwscreen);
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
// Add the toolbar if needed
|
|
|
|
SDL_Rect toolbar_rect[1];
|
2006-06-10 11:16:43 +00:00
|
|
|
if (_panelVisible && _toolbarHandler.draw(_toolbarLow, &toolbar_rect[0])) {
|
2005-07-30 21:11:48 +00:00
|
|
|
// It can be drawn, scale it
|
2004-01-26 08:20:26 +00:00
|
|
|
uint32 srcPitch, dstPitch;
|
2004-01-28 01:12:48 +00:00
|
|
|
SDL_Surface *toolbarSurface;
|
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (_videoMode.screenHeight > 240) {
|
2004-01-28 01:12:48 +00:00
|
|
|
if (!_toolbarHighDrawn) {
|
|
|
|
// Resize the toolbar
|
|
|
|
SDL_LockSurface(_toolbarLow);
|
|
|
|
SDL_LockSurface(_toolbarHigh);
|
|
|
|
Normal2x((byte*)_toolbarLow->pixels, _toolbarLow->pitch, (byte*)_toolbarHigh->pixels, _toolbarHigh->pitch, toolbar_rect[0].w, toolbar_rect[0].h);
|
|
|
|
SDL_UnlockSurface(_toolbarHigh);
|
|
|
|
SDL_UnlockSurface(_toolbarLow);
|
2005-07-30 21:11:48 +00:00
|
|
|
_toolbarHighDrawn = true;
|
2004-01-28 01:12:48 +00:00
|
|
|
}
|
|
|
|
toolbar_rect[0].w *= 2;
|
|
|
|
toolbar_rect[0].h *= 2;
|
|
|
|
toolbarSurface = _toolbarHigh;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
toolbarSurface = _toolbarLow;
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
drawToolbarMouse(toolbarSurface, true); // draw toolbar mouse if applicable
|
|
|
|
|
2004-01-28 01:12:48 +00:00
|
|
|
// Apply the appropriate scaler
|
|
|
|
SDL_LockSurface(toolbarSurface);
|
2004-01-26 08:20:26 +00:00
|
|
|
SDL_LockSurface(_hwscreen);
|
2004-01-28 01:12:48 +00:00
|
|
|
srcPitch = toolbarSurface->pitch;
|
2005-07-30 21:11:48 +00:00
|
|
|
dstPitch = _hwscreen->pitch;
|
2004-12-11 00:41:31 +00:00
|
|
|
_scalerProc((byte *)toolbarSurface->pixels, srcPitch, (byte *)_hwscreen->pixels + (_toolbarHandler.getOffset() * _scaleFactorYm / _scaleFactorYd * dstPitch), dstPitch, toolbar_rect[0].w, toolbar_rect[0].h);
|
2004-01-28 01:12:48 +00:00
|
|
|
SDL_UnlockSurface(toolbarSurface);
|
2004-01-26 08:20:26 +00:00
|
|
|
SDL_UnlockSurface(_hwscreen);
|
2004-01-28 01:12:48 +00:00
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
// And blit it
|
2004-01-28 01:12:48 +00:00
|
|
|
toolbar_rect[0].y = _toolbarHandler.getOffset();
|
|
|
|
toolbar_rect[0].x = toolbar_rect[0].x * _scaleFactorXm / _scaleFactorXd;
|
|
|
|
toolbar_rect[0].y = toolbar_rect[0].y * _scaleFactorYm / _scaleFactorYd;
|
|
|
|
toolbar_rect[0].w = toolbar_rect[0].w * _scaleFactorXm / _scaleFactorXd;
|
|
|
|
toolbar_rect[0].h = toolbar_rect[0].h * _scaleFactorYm / _scaleFactorYd;
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
SDL_UpdateRects(_hwscreen, 1, toolbar_rect);
|
2006-06-10 11:16:43 +00:00
|
|
|
|
|
|
|
drawToolbarMouse(toolbarSurface, false); // undraw toolbar mouse
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
2004-01-28 01:12:48 +00:00
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
// Finally, blit all our changes to the screen
|
2007-04-28 22:37:42 +00:00
|
|
|
if (numRectsOut > 0)
|
|
|
|
SDL_UpdateRects(_hwscreen, numRectsOut, _dirtyRectOut);
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2004-12-11 00:41:31 +00:00
|
|
|
_numDirtyRects = 0;
|
2004-01-26 08:20:26 +00:00
|
|
|
_forceFull = false;
|
|
|
|
}
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2007-06-19 22:39:59 +00:00
|
|
|
Graphics::Surface *OSystem_WINCE3::lockScreen() {
|
2007-10-28 18:36:04 +00:00
|
|
|
// FIXME: Fingolfin asks: Why is undrawMouse() needed here?
|
2007-06-19 22:39:59 +00:00
|
|
|
// Please document this.
|
2007-06-09 17:25:46 +00:00
|
|
|
undrawMouse();
|
2007-06-19 22:39:59 +00:00
|
|
|
return OSystem_SDL::lockScreen();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::unlockScreen() {
|
|
|
|
OSystem_SDL::unlockScreen();
|
2007-06-09 17:25:46 +00:00
|
|
|
}
|
|
|
|
|
2004-12-11 00:41:31 +00:00
|
|
|
bool OSystem_WINCE3::saveScreenshot(const char *filename) {
|
2004-01-26 08:20:26 +00:00
|
|
|
assert(_hwscreen != NULL);
|
|
|
|
|
2004-03-28 20:31:18 +00:00
|
|
|
Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends
|
2004-01-26 08:20:26 +00:00
|
|
|
SDL_SaveBMP(_hwscreen, filename);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2005-10-16 22:52:46 +00:00
|
|
|
void OSystem_WINCE3::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
|
|
|
|
assert (_transactionMode == kTransactionNone);
|
|
|
|
|
|
|
|
if (_overlayscreen == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Clip the coordinates
|
|
|
|
if (x < 0) {
|
|
|
|
w += x;
|
|
|
|
buf -= x;
|
|
|
|
x = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (y < 0) {
|
|
|
|
h += y; buf -= y * pitch;
|
|
|
|
y = 0;
|
|
|
|
}
|
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (w > _videoMode.overlayWidth - x) {
|
|
|
|
w = _videoMode.overlayWidth - x;
|
2005-10-16 22:52:46 +00:00
|
|
|
}
|
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (h > _videoMode.overlayHeight - y) {
|
|
|
|
h = _videoMode.overlayHeight - y;
|
2005-10-16 22:52:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (w <= 0 || h <= 0)
|
2008-01-27 19:47:41 +00:00
|
|
|
return;
|
2005-10-16 22:52:46 +00:00
|
|
|
|
|
|
|
// Mark the modified region as dirty
|
|
|
|
_cksumValid = false;
|
|
|
|
addDirtyRect(x, y, w, h);
|
|
|
|
|
|
|
|
undrawMouse();
|
|
|
|
|
|
|
|
if (SDL_LockSurface(_overlayscreen) == -1)
|
|
|
|
error("SDL_LockSurface failed: %s", SDL_GetError());
|
|
|
|
|
|
|
|
byte *dst = (byte *)_overlayscreen->pixels + y * _overlayscreen->pitch + x * 2;
|
|
|
|
do {
|
|
|
|
memcpy(dst, buf, w * 2);
|
|
|
|
dst += _overlayscreen->pitch;
|
|
|
|
buf += pitch;
|
|
|
|
} while (--h);
|
|
|
|
|
|
|
|
SDL_UnlockSurface(_overlayscreen);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) {
|
|
|
|
assert (_transactionMode == kTransactionNone);
|
|
|
|
assert(src);
|
|
|
|
|
2008-01-27 19:47:41 +00:00
|
|
|
if (_screen == NULL)
|
2005-10-16 22:52:46 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends
|
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (((long)src & 3) == 0 && pitch == _videoMode.screenWidth && x == 0 && y == 0 &&
|
|
|
|
w == _videoMode.screenWidth && h == _videoMode.screenHeight && _modeFlags & DF_WANT_RECT_OPTIM) {
|
2005-10-16 22:52:46 +00:00
|
|
|
/* Special, optimized case for full screen updates.
|
|
|
|
* It tries to determine what areas were actually changed,
|
|
|
|
* and just updates those, on the actual display. */
|
|
|
|
addDirtyRgnAuto(src);
|
|
|
|
} else {
|
|
|
|
/* Clip the coordinates */
|
|
|
|
if (x < 0) {
|
|
|
|
w += x;
|
|
|
|
src -= x;
|
|
|
|
x = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (y < 0) {
|
|
|
|
h += y;
|
|
|
|
src -= y * pitch;
|
|
|
|
y = 0;
|
|
|
|
}
|
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (w > _videoMode.screenWidth - x) {
|
|
|
|
w = _videoMode.screenWidth - x;
|
2005-10-16 22:52:46 +00:00
|
|
|
}
|
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (h > _videoMode.screenHeight - y) {
|
|
|
|
h = _videoMode.screenHeight - y;
|
2005-10-16 22:52:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (w <= 0 || h <= 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
_cksumValid = false;
|
|
|
|
addDirtyRect(x, y, w, h);
|
|
|
|
}
|
|
|
|
|
|
|
|
undrawMouse();
|
|
|
|
|
|
|
|
// Try to lock the screen surface
|
|
|
|
if (SDL_LockSurface(_screen) == -1)
|
|
|
|
error("SDL_LockSurface failed: %s", SDL_GetError());
|
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
|
2005-10-16 22:52:46 +00:00
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (_videoMode.screenWidth == pitch && pitch == w) {
|
2005-10-16 22:52:46 +00:00
|
|
|
memcpy(dst, src, h*w);
|
|
|
|
} else {
|
|
|
|
do {
|
|
|
|
memcpy(dst, src, w);
|
|
|
|
src += pitch;
|
2008-12-10 20:46:19 +00:00
|
|
|
dst += _videoMode.screenWidth;
|
2005-10-16 22:52:46 +00:00
|
|
|
} while (--h);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unlock the screen surface
|
|
|
|
SDL_UnlockSurface(_screen);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale) {
|
|
|
|
|
|
|
|
undrawMouse();
|
2006-06-20 18:03:02 +00:00
|
|
|
if (w == 0 || h == 0)
|
|
|
|
return;
|
2005-10-16 22:52:46 +00:00
|
|
|
|
|
|
|
_mouseCurState.w = w;
|
|
|
|
_mouseCurState.h = h;
|
|
|
|
|
|
|
|
_mouseHotspotX = hotspot_x;
|
|
|
|
_mouseHotspotY = hotspot_y;
|
|
|
|
|
|
|
|
_mouseKeyColor = keycolor;
|
|
|
|
|
|
|
|
free(_mouseData);
|
|
|
|
|
2007-02-12 17:25:36 +00:00
|
|
|
_mouseData = (byte *) malloc(w * h);
|
2005-10-16 22:52:46 +00:00
|
|
|
memcpy(_mouseData, buf, w * h);
|
2007-02-12 17:25:36 +00:00
|
|
|
|
|
|
|
if (w > _mouseBackupDim || h > _mouseBackupDim)
|
|
|
|
{
|
|
|
|
// mouse has been undrawn, adjust sprite backup area
|
|
|
|
free(_mouseBackupOld);
|
|
|
|
free(_mouseBackupToolbar);
|
|
|
|
uint16 tmp = (w > h) ? w : h;
|
|
|
|
_mouseBackupOld = (byte *) malloc(tmp * tmp * 2); // can hold 8bpp (playfield) or 16bpp (overlay) data
|
|
|
|
_mouseBackupToolbar = (uint16 *) malloc(tmp * tmp * 2); // 16 bpp
|
|
|
|
_mouseBackupDim = tmp;
|
|
|
|
}
|
2005-10-16 22:52:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::setMousePos(int x, int y) {
|
|
|
|
if (x != _mouseCurState.x || y != _mouseCurState.y) {
|
|
|
|
undrawMouse();
|
|
|
|
_mouseCurState.x = x;
|
|
|
|
_mouseCurState.y = y;
|
|
|
|
updateScreen();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void OSystem_WINCE3::internDrawMouse() {
|
|
|
|
if (_mouseDrawn || !_mouseVisible || !_mouseData)
|
|
|
|
return;
|
|
|
|
|
|
|
|
int x = _mouseCurState.x - _mouseHotspotX;
|
|
|
|
int y = _mouseCurState.y - _mouseHotspotY;
|
|
|
|
int w = _mouseCurState.w;
|
|
|
|
int h = _mouseCurState.h;
|
|
|
|
byte color;
|
|
|
|
const byte *src = _mouseData; // Image representing the mouse
|
2007-02-12 17:25:36 +00:00
|
|
|
int width;
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
// clip the mouse rect, and adjust the src pointer accordingly
|
2005-10-16 22:52:46 +00:00
|
|
|
if (x < 0) {
|
|
|
|
w += x;
|
|
|
|
src -= x;
|
|
|
|
x = 0;
|
|
|
|
}
|
|
|
|
if (y < 0) {
|
|
|
|
h += y;
|
|
|
|
src -= y * _mouseCurState.w;
|
|
|
|
y = 0;
|
|
|
|
}
|
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (w > _videoMode.screenWidth - x)
|
|
|
|
w = _videoMode.screenWidth - x;
|
|
|
|
if (h > _videoMode.screenHeight - y)
|
|
|
|
h = _videoMode.screenHeight - y;
|
2005-10-16 22:52:46 +00:00
|
|
|
|
|
|
|
// Quick check to see if anything has to be drawn at all
|
|
|
|
if (w <= 0 || h <= 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Draw the mouse cursor; backup the covered area in "bak"
|
|
|
|
if (SDL_LockSurface(_overlayVisible ? _overlayscreen : _screen) == -1)
|
|
|
|
error("SDL_LockSurface failed: %s", SDL_GetError());
|
|
|
|
|
|
|
|
// Mark as dirty
|
|
|
|
addDirtyRect(x, y, w, h);
|
|
|
|
|
|
|
|
if (!_overlayVisible) {
|
|
|
|
byte *bak = _mouseBackupOld; // Surface used to backup the area obscured by the mouse
|
|
|
|
byte *dst; // Surface we are drawing into
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
|
2005-10-16 22:52:46 +00:00
|
|
|
while (h > 0) {
|
2007-02-12 17:25:36 +00:00
|
|
|
width = w;
|
2005-10-16 22:52:46 +00:00
|
|
|
while (width > 0) {
|
|
|
|
*bak++ = *dst;
|
|
|
|
color = *src++;
|
|
|
|
if (color != _mouseKeyColor) // transparent, don't draw
|
|
|
|
*dst = color;
|
|
|
|
dst++;
|
|
|
|
width--;
|
|
|
|
}
|
|
|
|
src += _mouseCurState.w - w;
|
2007-02-12 17:25:36 +00:00
|
|
|
bak += _mouseBackupDim - w;
|
2008-12-10 20:46:19 +00:00
|
|
|
dst += _videoMode.screenWidth - w;
|
2005-10-16 22:52:46 +00:00
|
|
|
h--;
|
|
|
|
}
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2005-10-16 22:52:46 +00:00
|
|
|
} else {
|
|
|
|
uint16 *bak = (uint16 *)_mouseBackupOld; // Surface used to backup the area obscured by the mouse
|
|
|
|
byte *dst; // Surface we are drawing into
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2005-10-16 22:52:46 +00:00
|
|
|
dst = (byte *)_overlayscreen->pixels + (y + 1) * _overlayscreen->pitch + (x + 1) * 2;
|
|
|
|
while (h > 0) {
|
2007-02-12 17:25:36 +00:00
|
|
|
width = w;
|
2005-10-16 22:52:46 +00:00
|
|
|
while (width > 0) {
|
|
|
|
*bak++ = *(uint16 *)dst;
|
|
|
|
color = *src++;
|
|
|
|
if (color != 0xFF) // 0xFF = transparent, don't draw
|
2008-11-06 15:02:50 +00:00
|
|
|
*(uint16 *)dst = SDL_MapRGB(_overlayscreen->format, _currentPalette[color].r, _currentPalette[color].g, _currentPalette[color].b);
|
2005-10-16 22:52:46 +00:00
|
|
|
dst += 2;
|
|
|
|
width--;
|
|
|
|
}
|
|
|
|
src += _mouseCurState.w - w;
|
2007-02-12 17:25:36 +00:00
|
|
|
bak += _mouseBackupDim - w;
|
2005-10-16 22:52:46 +00:00
|
|
|
dst += _overlayscreen->pitch - w * 2;
|
|
|
|
h--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);
|
|
|
|
|
|
|
|
// Finally, set the flag to indicate the mouse has been drawn
|
|
|
|
_mouseDrawn = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::undrawMouse() {
|
2008-12-10 20:46:19 +00:00
|
|
|
assert (_transactionMode == kTransactionNone);
|
2005-10-16 22:52:46 +00:00
|
|
|
|
|
|
|
if (!_mouseDrawn)
|
|
|
|
return;
|
|
|
|
_mouseDrawn = false;
|
|
|
|
|
|
|
|
int old_mouse_x = _mouseCurState.x - _mouseHotspotX;
|
|
|
|
int old_mouse_y = _mouseCurState.y - _mouseHotspotY;
|
|
|
|
int old_mouse_w = _mouseCurState.w;
|
|
|
|
int old_mouse_h = _mouseCurState.h;
|
|
|
|
|
2006-08-25 06:30:18 +00:00
|
|
|
// clip the mouse rect, and adjust the src pointer accordingly
|
2005-10-16 22:52:46 +00:00
|
|
|
if (old_mouse_x < 0) {
|
|
|
|
old_mouse_w += old_mouse_x;
|
|
|
|
old_mouse_x = 0;
|
|
|
|
}
|
|
|
|
if (old_mouse_y < 0) {
|
|
|
|
old_mouse_h += old_mouse_y;
|
|
|
|
old_mouse_y = 0;
|
|
|
|
}
|
|
|
|
|
2008-12-10 20:46:19 +00:00
|
|
|
if (old_mouse_w > _videoMode.screenWidth - old_mouse_x)
|
|
|
|
old_mouse_w = _videoMode.screenWidth - old_mouse_x;
|
|
|
|
if (old_mouse_h > _videoMode.screenHeight - old_mouse_y)
|
|
|
|
old_mouse_h = _videoMode.screenHeight - old_mouse_y;
|
2005-10-16 22:52:46 +00:00
|
|
|
|
|
|
|
// Quick check to see if anything has to be drawn at all
|
|
|
|
if (old_mouse_w <= 0 || old_mouse_h <= 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (SDL_LockSurface(_overlayVisible ? _overlayscreen : _screen) == -1)
|
|
|
|
error("SDL_LockSurface failed: %s", SDL_GetError());
|
|
|
|
|
|
|
|
int x, y;
|
|
|
|
if (!_overlayVisible) {
|
|
|
|
byte *dst, *bak = _mouseBackupOld;
|
|
|
|
|
|
|
|
// No need to do clipping here, since drawMouse() did that already
|
2008-12-10 20:46:19 +00:00
|
|
|
dst = (byte *)_screen->pixels + old_mouse_y * _videoMode.screenWidth + old_mouse_x;
|
|
|
|
for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _videoMode.screenWidth)
|
2007-02-12 17:25:36 +00:00
|
|
|
memcpy(dst, bak, old_mouse_w);
|
2005-10-16 22:52:46 +00:00
|
|
|
} else {
|
|
|
|
byte *dst;
|
|
|
|
uint16 *bak = (uint16 *)_mouseBackupOld;
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2005-10-16 22:52:46 +00:00
|
|
|
// No need to do clipping here, since drawMouse() did that already
|
|
|
|
dst = (byte *)_overlayscreen->pixels + (old_mouse_y + 1) * _overlayscreen->pitch + (old_mouse_x + 1) * 2;
|
2007-02-12 17:25:36 +00:00
|
|
|
for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _overlayscreen->pitch)
|
|
|
|
memcpy(dst, bak, old_mouse_w << 1);
|
2005-10-16 22:52:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
addDirtyRect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h);
|
|
|
|
|
|
|
|
SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);
|
|
|
|
}
|
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
void OSystem_WINCE3::drawToolbarMouse(SDL_Surface *surf, bool draw) {
|
|
|
|
|
|
|
|
if (!_mouseData || !_usesEmulatedMouse) return;
|
|
|
|
|
|
|
|
int x = _mouseCurState.x - _mouseHotspotX;
|
|
|
|
int y = _mouseCurState.y - _mouseHotspotY - _toolbarHandler.getOffset();
|
|
|
|
int w = _mouseCurState.w;
|
|
|
|
int h = _mouseCurState.h;
|
|
|
|
byte color;
|
|
|
|
const byte *src = _mouseData;
|
2007-02-12 17:25:36 +00:00
|
|
|
int width;
|
2006-06-10 11:16:43 +00:00
|
|
|
|
|
|
|
// clip
|
|
|
|
if (x < 0) {
|
|
|
|
w += x;
|
|
|
|
src -= x;
|
|
|
|
x = 0;
|
|
|
|
}
|
|
|
|
if (y < 0) {
|
|
|
|
h += y;
|
|
|
|
src -= y * _mouseCurState.w;
|
|
|
|
y = 0;
|
|
|
|
}
|
|
|
|
if (w > surf->w - x)
|
|
|
|
w = surf->w - x;
|
|
|
|
if (h > surf->h - y)
|
|
|
|
h = surf->h - y;
|
|
|
|
if (w <= 0 || h <= 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (SDL_LockSurface(surf) == -1)
|
|
|
|
error("SDL_LockSurface failed at internDrawToolbarMouse: %s", SDL_GetError());
|
|
|
|
|
|
|
|
uint16 *bak = _mouseBackupToolbar; // toolbar surfaces are 16bpp
|
|
|
|
uint16 *dst;
|
|
|
|
dst = (uint16 *)surf->pixels + y * surf->w + x;
|
|
|
|
|
|
|
|
if (draw) { // blit it
|
|
|
|
while (h > 0) {
|
2007-02-12 17:25:36 +00:00
|
|
|
width = w;
|
2006-06-10 11:16:43 +00:00
|
|
|
while (width > 0) {
|
|
|
|
*bak++ = *dst;
|
|
|
|
color = *src++;
|
|
|
|
if (color != _mouseKeyColor) // transparent color
|
|
|
|
*dst = 0xFFFF;
|
|
|
|
dst++;
|
|
|
|
width--;
|
|
|
|
}
|
|
|
|
src += _mouseCurState.w - w;
|
2007-02-12 17:25:36 +00:00
|
|
|
bak += _mouseBackupDim - w;
|
2006-06-10 11:16:43 +00:00
|
|
|
dst += surf->w - w;
|
|
|
|
h--;
|
|
|
|
}
|
|
|
|
} else { // restore bg
|
2007-02-12 17:25:36 +00:00
|
|
|
for (y = 0; y < h; ++y, bak += _mouseBackupDim, dst += surf->w)
|
|
|
|
memcpy(dst, bak, w << 1);
|
2006-06-10 11:16:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SDL_UnlockSurface(surf);
|
|
|
|
}
|
|
|
|
|
2005-10-16 22:52:46 +00:00
|
|
|
void OSystem_WINCE3::blitCursor() {
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::showOverlay() {
|
|
|
|
assert (_transactionMode == kTransactionNone);
|
|
|
|
|
2008-12-28 20:16:53 +00:00
|
|
|
if (_overlayVisible)
|
|
|
|
return;
|
|
|
|
|
2005-10-16 22:52:46 +00:00
|
|
|
undrawMouse();
|
|
|
|
_overlayVisible = true;
|
2008-01-01 20:27:11 +00:00
|
|
|
update_scalers();
|
2005-10-16 22:52:46 +00:00
|
|
|
clearOverlay();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::hideOverlay() {
|
|
|
|
assert (_transactionMode == kTransactionNone);
|
|
|
|
|
2008-12-28 20:16:53 +00:00
|
|
|
if (!_overlayVisible)
|
|
|
|
return;
|
2005-10-16 22:52:46 +00:00
|
|
|
|
2008-12-28 20:16:53 +00:00
|
|
|
undrawMouse();
|
2005-10-16 22:52:46 +00:00
|
|
|
_overlayVisible = false;
|
|
|
|
clearOverlay();
|
|
|
|
_forceFull = true;
|
|
|
|
}
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2004-12-11 00:41:31 +00:00
|
|
|
void OSystem_WINCE3::drawMouse() {
|
2007-09-11 09:20:39 +00:00
|
|
|
// FIXME: Fingolfin asks: why is there a FIXME here? Please either clarify what
|
|
|
|
// needs fixing, or remove it!
|
2004-01-26 08:20:26 +00:00
|
|
|
// FIXME
|
2006-09-09 16:48:35 +00:00
|
|
|
if (!(_toolbarHandler.visible() && _mouseCurState.y >= _toolbarHandler.getOffset() && !_usesEmulatedMouse) && !_forceHideMouse)
|
2008-01-27 19:47:41 +00:00
|
|
|
internDrawMouse();
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
2007-03-17 19:02:05 +00:00
|
|
|
void OSystem_WINCE3::fillMouseEvent(Common::Event &event, int x, int y) {
|
2004-01-26 08:20:26 +00:00
|
|
|
event.mouse.x = x;
|
|
|
|
event.mouse.y = y;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
// Update the "keyboard mouse" coords
|
2004-12-11 00:41:31 +00:00
|
|
|
_km.x = event.mouse.x;
|
|
|
|
_km.y = event.mouse.y;
|
2004-01-26 08:20:26 +00:00
|
|
|
|
|
|
|
// Adjust for the screen scaling
|
2005-07-30 21:11:48 +00:00
|
|
|
if (_zoomDown)
|
2004-05-09 15:02:10 +00:00
|
|
|
event.mouse.y += 240;
|
|
|
|
|
2004-01-28 01:12:48 +00:00
|
|
|
event.mouse.x = event.mouse.x * _scaleFactorXd / _scaleFactorXm;
|
|
|
|
event.mouse.y = event.mouse.y * _scaleFactorYd / _scaleFactorYm;
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
2004-05-09 15:02:10 +00:00
|
|
|
void OSystem_WINCE3::retrieve_mouse_location(int &x, int &y) {
|
|
|
|
x = _mouseCurState.x;
|
|
|
|
y = _mouseCurState.y;
|
|
|
|
|
|
|
|
x = x * _scaleFactorXm / _scaleFactorXd;
|
|
|
|
y = y * _scaleFactorYm / _scaleFactorYd;
|
|
|
|
|
|
|
|
if (_zoomDown)
|
|
|
|
y -= 240;
|
|
|
|
}
|
|
|
|
|
2004-03-28 16:30:50 +00:00
|
|
|
void OSystem_WINCE3::warpMouse(int x, int y) {
|
2006-11-12 21:06:56 +00:00
|
|
|
if (_mouseCurState.x != x || _mouseCurState.y != y) {
|
2004-01-26 08:20:26 +00:00
|
|
|
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.
|
|
|
|
|
2004-12-11 00:41:31 +00:00
|
|
|
setMousePos(x, y);
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-16 22:27:11 +00:00
|
|
|
void OSystem_WINCE3::addDirtyRect(int x, int y, int w, int h, bool mouseRect) {
|
2005-10-16 22:52:46 +00:00
|
|
|
|
2007-10-28 18:36:04 +00:00
|
|
|
if (_forceFull || _paletteDirtyEnd) return;
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2005-10-16 22:52:46 +00:00
|
|
|
OSystem_SDL::addDirtyRect(x, y, w, h, false);
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
|
2007-06-03 19:29:13 +00:00
|
|
|
static int mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode, bool unfilter)
|
2007-04-28 17:48:58 +00:00
|
|
|
{
|
|
|
|
if (GUI::Actions::Instance()->mappingActive())
|
|
|
|
return key;
|
|
|
|
|
2007-06-03 19:29:13 +00:00
|
|
|
if (unfilter) {
|
|
|
|
switch (key) {
|
|
|
|
case SDLK_ESCAPE:
|
|
|
|
return SDLK_BACKSPACE;
|
|
|
|
case SDLK_F8:
|
|
|
|
return SDLK_ASTERISK;
|
|
|
|
case SDLK_F9:
|
|
|
|
return SDLK_HASH;
|
|
|
|
}
|
|
|
|
return key;
|
|
|
|
}
|
|
|
|
|
2007-04-28 17:48:58 +00:00
|
|
|
if (key >= SDLK_KP0 && key <= SDLK_KP9) {
|
|
|
|
return key - SDLK_KP0 + '0';
|
|
|
|
} else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) {
|
|
|
|
return key;
|
|
|
|
} else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return key;
|
|
|
|
}
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-03-17 19:02:05 +00:00
|
|
|
bool OSystem_WINCE3::pollEvent(Common::Event &event) {
|
2004-01-26 08:20:26 +00:00
|
|
|
SDL_Event ev;
|
|
|
|
byte b = 0;
|
2004-12-21 00:31:58 +00:00
|
|
|
DWORD currentTime;
|
|
|
|
bool keyEvent = false;
|
2007-12-16 20:21:19 +00:00
|
|
|
int deltaX, deltaY;
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-03-17 19:02:05 +00:00
|
|
|
memset(&event, 0, sizeof(Common::Event));
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2004-12-11 00:41:31 +00:00
|
|
|
handleKbdMouse();
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2007-03-17 19:02:05 +00:00
|
|
|
// If the screen mode changed, send an Common::EVENT_SCREEN_CHANGED
|
2004-01-26 08:20:26 +00:00
|
|
|
if (_modeChanged) {
|
|
|
|
_modeChanged = false;
|
2007-03-17 19:02:05 +00:00
|
|
|
event.type = Common::EVENT_SCREEN_CHANGED;
|
2006-10-08 18:15:18 +00:00
|
|
|
_screenChangeCount++;
|
2004-01-26 08:20:26 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2004-12-21 00:31:58 +00:00
|
|
|
CEDevice::wakeUp();
|
|
|
|
|
2007-01-11 21:53:30 +00:00
|
|
|
currentTime = GetTickCount();
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2007-09-18 20:16:33 +00:00
|
|
|
while (SDL_PollEvent(&ev)) {
|
2004-01-26 08:20:26 +00:00
|
|
|
switch(ev.type) {
|
|
|
|
case SDL_KEYDOWN:
|
2007-05-12 22:33:13 +00:00
|
|
|
debug(1, "Key down %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));
|
2007-06-03 19:29:13 +00:00
|
|
|
// KMOD_RESERVED is used if the key has been injected by an external buffer
|
|
|
|
if (ev.key.keysym.mod != KMOD_RESERVED && !_unfilteredkeys) {
|
2007-01-11 21:53:30 +00:00
|
|
|
keyEvent = true;
|
|
|
|
_lastKeyPressed = ev.key.keysym.sym;
|
|
|
|
_keyRepeatTime = currentTime;
|
|
|
|
_keyRepeat = 0;
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2005-07-05 20:22:56 +00:00
|
|
|
if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, true))
|
2005-01-28 23:45:53 +00:00
|
|
|
return true;
|
|
|
|
}
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2005-07-05 20:22:56 +00:00
|
|
|
if (GUI_Actions::Instance()->mappingActive())
|
2004-12-11 00:41:31 +00:00
|
|
|
event.kbd.flags = 0xFF;
|
2007-06-03 19:29:13 +00:00
|
|
|
else if (ev.key.keysym.sym == SDLK_PAUSE) {
|
|
|
|
_lastKeyPressed = 0;
|
|
|
|
event.type = Common::EVENT_PREDICTIVE_DIALOG;
|
|
|
|
return true;
|
2008-08-13 19:13:53 +00:00
|
|
|
} event.type = Common::EVENT_KEYDOWN;
|
2007-06-03 19:29:13 +00:00
|
|
|
if (!_unfilteredkeys)
|
2007-06-23 17:15:36 +00:00
|
|
|
event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
|
2007-06-03 19:29:13 +00:00
|
|
|
else
|
2007-06-23 17:15:36 +00:00
|
|
|
event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
|
2007-06-03 19:29:13 +00:00
|
|
|
event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2008-08-13 19:13:53 +00:00
|
|
|
if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
|
|
|
|
event.kbd.ascii ^= 0x20;
|
|
|
|
event.kbd.flags = Common::KBD_SHIFT;
|
|
|
|
}
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
return true;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
|
|
|
case SDL_KEYUP:
|
2007-05-12 22:33:13 +00:00
|
|
|
debug(1, "Key up %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));
|
2007-06-03 19:29:13 +00:00
|
|
|
// KMOD_RESERVED is used if the key has been injected by an external buffer
|
|
|
|
if (ev.key.keysym.mod != KMOD_RESERVED && !_unfilteredkeys) {
|
2007-01-11 21:53:30 +00:00
|
|
|
keyEvent = true;
|
|
|
|
_lastKeyPressed = 0;
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2005-07-05 20:22:56 +00:00
|
|
|
if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, false))
|
2005-01-28 23:45:53 +00:00
|
|
|
return true;
|
|
|
|
}
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2005-07-05 20:22:56 +00:00
|
|
|
if (GUI_Actions::Instance()->mappingActive())
|
2004-12-11 00:41:31 +00:00
|
|
|
event.kbd.flags = 0xFF;
|
2007-06-03 19:29:13 +00:00
|
|
|
else if (ev.key.keysym.sym == SDLK_PAUSE) {
|
|
|
|
_lastKeyPressed = 0;
|
|
|
|
return false; // chew up the show agi dialog key up event
|
|
|
|
}
|
|
|
|
|
|
|
|
event.type = Common::EVENT_KEYUP;
|
|
|
|
if (!_unfilteredkeys)
|
2007-06-23 17:15:36 +00:00
|
|
|
event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
|
2007-06-03 19:29:13 +00:00
|
|
|
else
|
2007-06-23 17:15:36 +00:00
|
|
|
event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
|
2007-06-03 19:29:13 +00:00
|
|
|
event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2008-08-13 19:13:53 +00:00
|
|
|
if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
|
|
|
|
event.kbd.ascii ^= 0x20;
|
|
|
|
event.kbd.flags = Common::KBD_SHIFT;
|
|
|
|
}
|
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
case SDL_MOUSEMOTION:
|
2007-03-17 19:02:05 +00:00
|
|
|
event.type = Common::EVENT_MOUSEMOVE;
|
2004-12-11 00:41:31 +00:00
|
|
|
fillMouseEvent(event, ev.motion.x, ev.motion.y);
|
|
|
|
setMousePos(event.mouse.x, event.mouse.y);
|
2004-01-26 08:20:26 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
|
|
if (ev.button.button == SDL_BUTTON_LEFT)
|
2007-12-16 20:21:19 +00:00
|
|
|
event.type = Common::EVENT_LBUTTONDOWN;
|
2004-01-26 08:20:26 +00:00
|
|
|
else if (ev.button.button == SDL_BUTTON_RIGHT)
|
2007-12-16 20:21:19 +00:00
|
|
|
event.type = Common::EVENT_RBUTTONDOWN;
|
2004-01-26 08:20:26 +00:00
|
|
|
else
|
|
|
|
break;
|
2007-12-16 20:21:19 +00:00
|
|
|
fillMouseEvent(event, ev.button.x, ev.button.y);
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-12-16 20:21:19 +00:00
|
|
|
|
|
|
|
if (event.mouse.x > _tapX)
|
|
|
|
deltaX = event.mouse.x - _tapX;
|
|
|
|
else
|
|
|
|
deltaX = _tapX - event.mouse.x;
|
|
|
|
if (event.mouse.y > _tapY)
|
|
|
|
deltaY = event.mouse.y - _tapY;
|
|
|
|
else
|
|
|
|
deltaY = _tapY - event.mouse.y;
|
|
|
|
_closeClick = (deltaX <= 5 && deltaY <= 5);
|
|
|
|
|
|
|
|
if (!_isSmartphone) {
|
|
|
|
// handle double-taps
|
|
|
|
if (_tapTime) { // second tap
|
|
|
|
if (_closeClick && (GetTickCount() - _tapTime < 1000)) {
|
|
|
|
if (event.mouse.y <= 20 && _panelInitialized) { // top of screen (show panel)
|
2006-06-10 11:16:43 +00:00
|
|
|
swap_panel_visibility();
|
2008-08-25 08:48:46 +00:00
|
|
|
} else if (!_noDoubleTapRMB) { // right click
|
2007-12-16 20:21:19 +00:00
|
|
|
event.type = Common::EVENT_RBUTTONDOWN;
|
2006-06-10 11:16:43 +00:00
|
|
|
_rbutton = true;
|
|
|
|
}
|
|
|
|
}
|
2008-01-27 19:47:41 +00:00
|
|
|
_tapTime = 0;
|
2006-06-10 11:16:43 +00:00
|
|
|
} else {
|
2005-10-16 22:52:46 +00:00
|
|
|
_tapTime = GetTickCount();
|
2007-12-16 20:21:19 +00:00
|
|
|
_tapX = event.mouse.x;
|
|
|
|
_tapY = event.mouse.y;
|
2005-10-16 22:52:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-16 20:21:19 +00:00
|
|
|
if (_freeLook && !_closeClick) {
|
|
|
|
_rbutton = false;
|
|
|
|
_tapTime = 0;
|
|
|
|
_tapX = event.mouse.x;
|
|
|
|
_tapY = event.mouse.y;
|
|
|
|
event.type = Common::EVENT_MOUSEMOVE;
|
|
|
|
setMousePos(event.mouse.x, event.mouse.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (_toolbarHandler.action(event.mouse.x, event.mouse.y, true)) {
|
|
|
|
if (!_toolbarHandler.drawn()) {
|
2007-04-30 20:31:56 +00:00
|
|
|
_toolbarHighDrawn = false;
|
2004-05-09 15:02:10 +00:00
|
|
|
internUpdateScreen();
|
2007-12-16 20:21:19 +00:00
|
|
|
}
|
2007-04-28 17:48:58 +00:00
|
|
|
if (_newOrientation != _orientationLandscape){
|
2004-01-26 08:20:26 +00:00
|
|
|
_orientationLandscape = _newOrientation;
|
2007-04-30 20:31:56 +00:00
|
|
|
_toolbarHighDrawn = false;
|
2006-06-10 11:16:43 +00:00
|
|
|
ConfMan.setInt("landscape", _orientationLandscape);
|
2004-01-26 08:20:26 +00:00
|
|
|
ConfMan.flushToDisk();
|
2004-12-11 00:41:31 +00:00
|
|
|
hotswapGFXMode();
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
2007-12-16 20:21:19 +00:00
|
|
|
return false;
|
2008-01-27 19:47:41 +00:00
|
|
|
}
|
2004-01-26 08:20:26 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
|
|
if (ev.button.button == SDL_BUTTON_LEFT)
|
2007-12-16 20:21:19 +00:00
|
|
|
event.type = Common::EVENT_LBUTTONUP;
|
2004-01-26 08:20:26 +00:00
|
|
|
else if (ev.button.button == SDL_BUTTON_RIGHT)
|
2007-12-16 20:21:19 +00:00
|
|
|
event.type = Common::EVENT_RBUTTONUP;
|
2004-01-26 08:20:26 +00:00
|
|
|
else
|
|
|
|
break;
|
|
|
|
|
2006-06-10 11:16:43 +00:00
|
|
|
if (_rbutton) {
|
2007-12-16 20:21:19 +00:00
|
|
|
event.type = Common::EVENT_RBUTTONUP;
|
2006-06-10 11:16:43 +00:00
|
|
|
_rbutton = false;
|
|
|
|
}
|
|
|
|
|
2007-12-16 20:21:19 +00:00
|
|
|
fillMouseEvent(event, ev.button.x, ev.button.y);
|
2004-01-26 08:20:26 +00:00
|
|
|
|
2007-12-16 20:21:19 +00:00
|
|
|
if (_freeLook && !_closeClick) {
|
|
|
|
_tapX = event.mouse.x;
|
|
|
|
_tapY = event.mouse.y;
|
|
|
|
event.type = Common::EVENT_MOUSEMOVE;
|
|
|
|
setMousePos(event.mouse.x, event.mouse.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_toolbarHandler.action(event.mouse.x, event.mouse.y, false)) {
|
2004-01-26 08:20:26 +00:00
|
|
|
if (!_toolbarHandler.drawn())
|
2007-04-30 20:31:56 +00:00
|
|
|
_toolbarHighDrawn = false;
|
2004-05-09 15:02:10 +00:00
|
|
|
internUpdateScreen();
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case SDL_VIDEOEXPOSE:
|
|
|
|
_forceFull = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_QUIT:
|
2007-03-17 19:02:05 +00:00
|
|
|
event.type = Common::EVENT_QUIT;
|
2004-01-26 08:20:26 +00:00
|
|
|
return true;
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2007-04-28 17:48:58 +00:00
|
|
|
case SDL_ACTIVEEVENT:
|
|
|
|
if (ev.active.state & SDL_APPMOUSEFOCUS)
|
2007-12-16 20:21:19 +00:00
|
|
|
debug(2, "%s mouse focus.", ev.active.gain ? "Got" : "Lost");
|
2007-04-28 17:48:58 +00:00
|
|
|
if (ev.active.state & SDL_APPINPUTFOCUS)
|
2007-12-16 20:21:19 +00:00
|
|
|
debug(2, "%s input focus.", ev.active.gain ? "Got" : "Lost");
|
2007-04-28 17:48:58 +00:00
|
|
|
if (ev.active.state & SDL_APPACTIVE)
|
2007-12-16 20:21:19 +00:00
|
|
|
debug(2, "%s total focus.", ev.active.gain ? "Got" : "Lost");
|
2007-04-28 17:48:58 +00:00
|
|
|
if (ev.active.state & SDL_APPINPUTFOCUS) {
|
|
|
|
_hasfocus = ev.active.gain;
|
|
|
|
SDL_PauseAudio(!_hasfocus);
|
|
|
|
_forceFull |= _hasfocus;
|
|
|
|
}
|
|
|
|
break;
|
2004-01-26 08:20:26 +00:00
|
|
|
}
|
|
|
|
}
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2007-04-28 17:48:58 +00:00
|
|
|
// Simulate repeated key for backend
|
|
|
|
if (!keyEvent && _lastKeyPressed && currentTime > _keyRepeatTime + _keyRepeatTrigger) {
|
|
|
|
_keyRepeatTime = currentTime;
|
|
|
|
_keyRepeat++;
|
|
|
|
GUI_Actions::Instance()->performMapped(_lastKeyPressed, true);
|
|
|
|
}
|
2004-12-21 00:31:58 +00:00
|
|
|
|
2004-01-26 08:20:26 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSystem_WINCE3::quit() {
|
2004-05-09 15:02:10 +00:00
|
|
|
fclose(stdout_file);
|
|
|
|
fclose(stderr_file);
|
2005-04-23 13:52:27 +00:00
|
|
|
if (gDebugLevel <= 0) {
|
2007-05-01 13:15:34 +00:00
|
|
|
DeleteFile(ASCIItoUnicode(stdout_fname));
|
|
|
|
DeleteFile(ASCIItoUnicode(stderr_fname));
|
2004-05-09 15:22:04 +00:00
|
|
|
}
|
2004-12-21 00:31:58 +00:00
|
|
|
CEDevice::end();
|
2004-03-28 20:31:18 +00:00
|
|
|
OSystem_SDL::quit();
|
2004-02-20 23:05:00 +00:00
|
|
|
}
|
2004-05-30 13:24:51 +00:00
|
|
|
|
2007-12-30 17:15:11 +00:00
|
|
|
void OSystem_WINCE3::getTimeAndDate(struct tm &t) const {
|
|
|
|
SYSTEMTIME systime;
|
|
|
|
|
|
|
|
GetLocalTime(&systime);
|
2008-01-28 00:14:17 +00:00
|
|
|
t.tm_year = systime.wYear - 1900;
|
2007-12-30 17:15:11 +00:00
|
|
|
t.tm_mon = systime.wMonth - 1;
|
|
|
|
t.tm_wday = systime.wDayOfWeek;
|
|
|
|
t.tm_mday = systime.wDay;
|
|
|
|
t.tm_hour = systime.wHour;
|
|
|
|
t.tm_min = systime.wMinute;
|
|
|
|
t.tm_sec = systime.wSecond;
|
|
|
|
}
|
|
|
|
|
2004-05-30 13:24:51 +00:00
|
|
|
int OSystem_WINCE3::_platformScreenWidth;
|
|
|
|
int OSystem_WINCE3::_platformScreenHeight;
|
|
|
|
bool OSystem_WINCE3::_isOzone;
|
2004-12-23 01:15:27 +00:00
|
|
|
OSystem_WINCE3::zoneDesc OSystem_WINCE3::_zones[TOTAL_ZONES] = {
|
|
|
|
{ 0, 0, 320, 145 },
|
|
|
|
{ 0, 145, 150, 55 },
|
|
|
|
{ 150, 145, 170, 55 }
|
2005-01-04 23:00:03 +00:00
|
|
|
};
|