mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-21 09:21:08 +00:00
696 lines
19 KiB
C++
696 lines
19 KiB
C++
/* 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.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
|
|
// Disable symbol overrides so that we can use system headers.
|
|
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
|
|
|
#include "backends/platform/wince/wince-sdl.h"
|
|
|
|
#include "common/config-manager.h"
|
|
#include "common/debug.h"
|
|
#include "common/events.h"
|
|
#include "common/util.h"
|
|
#include "common/textconsole.h"
|
|
#include "common/timer.h"
|
|
#include "common/translation.h"
|
|
|
|
#include "engines/engine.h"
|
|
|
|
#include "base/main.h"
|
|
#include "base/plugins.h"
|
|
|
|
#include "audio/mixer_intern.h"
|
|
#include "audio/fmopl.h"
|
|
|
|
#include "backends/mutex/sdl/sdl-mutex.h"
|
|
#include "backends/timer/sdl/sdl-timer.h"
|
|
|
|
#include "gui/Actions.h"
|
|
#include "gui/KeysDialog.h"
|
|
#include "gui/message.h"
|
|
|
|
#include "backends/platform/wince/CEActionsPocket.h"
|
|
#include "backends/platform/wince/CEActionsSmartphone.h"
|
|
#include "backends/platform/wince/CEgui/ItemAction.h"
|
|
|
|
#include "graphics/scaler/downscaler.h"
|
|
#include "graphics/scaler/aspect.h"
|
|
|
|
#include "backends/platform/wince/CEException.h"
|
|
#include "backends/platform/wince/CEScaler.h"
|
|
|
|
#include "backends/graphics/wincesdl/wincesdl-graphics.h"
|
|
#include "backends/events/wincesdl/wincesdl-events.h"
|
|
#include "backends/mixer/wincesdl/wincesdl-mixer.h"
|
|
|
|
#ifdef DYNAMIC_MODULES
|
|
#include <malloc.h>
|
|
#include "backends/plugins/win32/win32-provider.h"
|
|
#endif
|
|
|
|
#ifdef __GNUC__
|
|
extern "C" _CRTIMP FILE *__cdecl _wfreopen(const wchar_t *, const wchar_t *, FILE *);
|
|
#endif
|
|
|
|
#ifdef WRAP_MALLOC
|
|
|
|
extern "C" void *__real_malloc(size_t size);
|
|
extern "C" void __real_free(void *ptr);
|
|
|
|
extern "C" void *__wrap_malloc(size_t size) {
|
|
/*
|
|
void *ptr = __real_malloc(size);
|
|
printf("malloc(%d) = %p\n", size, ptr);
|
|
return ptr;
|
|
*/
|
|
if (size < 64 * 1024) {
|
|
void *ptr = __real_malloc(size+4);
|
|
// printf("malloc(%d) = %p\n", size, ptr);
|
|
if (ptr != NULL) {
|
|
*((HANDLE *)ptr) = 0;
|
|
return 4+(char *)ptr;
|
|
}
|
|
return NULL;
|
|
}
|
|
HANDLE H = CreateFileMapping((HANDLE)INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, size+4, 0);
|
|
void *ptr = MapViewOfFile(H, FILE_MAP_ALL_ACCESS, 0, 0, 0);
|
|
*((HANDLE *)ptr) = H;
|
|
return 4+(char *)ptr;
|
|
}
|
|
|
|
extern "C" void __wrap_free(void *ptr) {
|
|
/*
|
|
__real_free(ptr);
|
|
printf("free(%p)\n", ptr);
|
|
*/
|
|
if (ptr != NULL) {
|
|
HANDLE H = *(HANDLE *)((char *)ptr-4);
|
|
if (H == 0) {
|
|
__real_free((char *)ptr-4);
|
|
return;
|
|
}
|
|
UnmapViewOfFile((char *)ptr-4);
|
|
CloseHandle(H);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
using namespace CEGUI;
|
|
|
|
// ********************************************************************************************
|
|
|
|
// 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];
|
|
|
|
// Static member inits
|
|
typedef void (*SoundProc)(void *param, byte *buf, int len);
|
|
bool OSystem_WINCE3::_soundMaster = true;
|
|
|
|
bool _isSmartphone = false;
|
|
bool _hasSmartphoneResolution = false;
|
|
|
|
#define DEFAULT_CONFIG_FILE "scummvm.ini"
|
|
|
|
// ********************************************************************************************
|
|
|
|
bool isSmartphone() {
|
|
//return _isSmartphone;
|
|
return _hasSmartphoneResolution;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
// MAIN
|
|
#ifndef __GNUC__
|
|
int handleException(EXCEPTION_POINTERS *exceptionPointers) {
|
|
CEException::writeException(TEXT("\\scummvmCrash"), exceptionPointers);
|
|
drawError("Unrecoverable exception occurred - see crash dump in latest \\scummvmCrash file");
|
|
fclose(stdout_file);
|
|
fclose(stderr_file);
|
|
CEDevice::end();
|
|
SDL_Quit();
|
|
exit(0);
|
|
return EXCEPTION_EXECUTE_HANDLER;
|
|
}
|
|
#endif
|
|
|
|
extern "C" char *getcwd(char *buf, int size);
|
|
int SDL_main(int argc, char **argv) {
|
|
FILE *newfp = NULL;
|
|
#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++; // First item in list of constructors has special meaning (platform dependent), ignore it.
|
|
while (*constructor) {
|
|
(*constructor)();
|
|
constructor++;
|
|
}
|
|
#endif
|
|
|
|
CEDevice::init();
|
|
|
|
/* 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);
|
|
#ifndef __GNUC__
|
|
stdout_file = fopen(stdout_fname, "w");
|
|
stderr_file = fopen(stderr_fname, "w");
|
|
#else
|
|
stdout_file = newfp = _wfreopen(ASCIItoUnicode(stdout_fname), TEXT("w"), stdout);
|
|
if (newfp == NULL) {
|
|
#if !defined(stdout)
|
|
stdout = fopen(stdout_fname, "w");
|
|
stdout_file = stdout;
|
|
#else
|
|
newfp = fopen(stdout_fname, "w");
|
|
if (newfp) {
|
|
//*stdout = *newfp;
|
|
stdout_file = stdout;
|
|
}
|
|
#endif
|
|
}
|
|
stderr_file = newfp = _wfreopen(ASCIItoUnicode(stderr_fname), TEXT("w"), stderr);
|
|
if (newfp == NULL) {
|
|
#if !defined(stderr)
|
|
stderr = fopen(stderr_fname, "w");
|
|
stderr_file = stderr;
|
|
#else
|
|
newfp = fopen(stderr_fname, "w");
|
|
if (newfp) {
|
|
//*stderr = *newfp;
|
|
stderr_file = stderr;
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef DYNAMIC_MODULES
|
|
PluginManager::instance().addPluginProvider(new Win32PluginProvider());
|
|
#endif
|
|
|
|
|
|
int res = 0;
|
|
#if !defined(DEBUG) && !defined(__GNUC__)
|
|
__try {
|
|
#endif
|
|
g_system = new OSystem_WINCE3();
|
|
assert(g_system);
|
|
|
|
// Pre initialize the backend
|
|
((OSystem_WINCE3 *)g_system)->init();
|
|
|
|
// Invoke the actual ScummVM main entry point:
|
|
res = scummvm_main(argc, argv);
|
|
|
|
// Free OSystem
|
|
delete(OSystem_WINCE3 *)g_system;
|
|
#if !defined(DEBUG) && !defined(__GNUC__)
|
|
}
|
|
__except(handleException(GetExceptionInformation())) {
|
|
}
|
|
#endif
|
|
|
|
return res;
|
|
}
|
|
|
|
#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;) {
|
|
// Skip leading whitespace
|
|
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);
|
|
|
|
// fix gdb-emulator combo
|
|
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
|
|
|
|
// ********************************************************************************************
|
|
|
|
// ********************************************************************************************
|
|
|
|
void pumpMessages() {
|
|
MSG msg;
|
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
|
|
void drawError(char *error) {
|
|
TCHAR errorUnicode[200];
|
|
MultiByteToWideChar(CP_ACP, 0, error, strlen(error) + 1, errorUnicode, sizeof(errorUnicode));
|
|
pumpMessages();
|
|
MessageBox(GetActiveWindow(), errorUnicode, TEXT("ScummVM error"), MB_OK | MB_ICONERROR);
|
|
pumpMessages();
|
|
}
|
|
|
|
// ********************************************************************************************
|
|
static Uint32 timer_handler_wrapper(Uint32 interval) {
|
|
DefaultTimerManager *tm = (DefaultTimerManager *)g_system->getTimerManager();
|
|
tm->handler();
|
|
return interval;
|
|
}
|
|
|
|
void OSystem_WINCE3::initBackend() {
|
|
|
|
assert(!_inited);
|
|
|
|
// Create the backend custom managers
|
|
if (_eventSource == 0)
|
|
_eventSource = new WINCESdlEventSource();
|
|
|
|
if (_mixerManager == 0) {
|
|
_mixerManager = new WINCESdlMixerManager();
|
|
|
|
// Setup and start mixer
|
|
_mixerManager->init();
|
|
}
|
|
|
|
if (_graphicsManager == 0)
|
|
_graphicsManager = new WINCESdlGraphicsManager(_eventSource);
|
|
|
|
((WINCESdlEventSource *)_eventSource)->init(dynamic_cast<WINCESdlGraphicsManager *>(_graphicsManager));
|
|
|
|
// Call parent implementation of this method
|
|
OSystem_SDL::initBackend();
|
|
|
|
// 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
|
|
}
|
|
|
|
_inited = true;
|
|
}
|
|
|
|
int OSystem_WINCE3::getScreenWidth() {
|
|
return _platformScreenWidth;
|
|
}
|
|
|
|
void OSystem_WINCE3::initScreenInfos() {
|
|
// sdl port ensures that we use correctly full screen
|
|
_isOzone = 0;
|
|
SDL_Rect **r;
|
|
r = SDL_ListModes(NULL, 0);
|
|
_platformScreenWidth = r[0]->w;
|
|
_platformScreenHeight = r[0]->h;
|
|
}
|
|
|
|
int OSystem_WINCE3::getScreenHeight() {
|
|
return _platformScreenHeight;
|
|
}
|
|
|
|
bool OSystem_WINCE3::isOzone() {
|
|
return _isOzone;
|
|
}
|
|
|
|
Common::String OSystem_WINCE3::getDefaultConfigFileName() {
|
|
char configFile[MAXPATHLEN];
|
|
strcpy(configFile, getcwd(NULL, MAX_PATH));
|
|
strcat(configFile, "\\");
|
|
strcat(configFile, DEFAULT_CONFIG_FILE);
|
|
return configFile;
|
|
}
|
|
|
|
// ********************************************************************************************
|
|
|
|
|
|
OSystem_WINCE3::OSystem_WINCE3() : OSystem_SDL(),
|
|
_forcePanelInvisible(false) {
|
|
// Initialze File System Factory
|
|
_fsFactory = new WindowsFilesystemFactory();
|
|
_mixer = 0;
|
|
}
|
|
|
|
OSystem_WINCE3::~OSystem_WINCE3() {
|
|
delete _mixer;
|
|
}
|
|
|
|
void OSystem_WINCE3::swap_sound_master() {
|
|
_soundMaster = !_soundMaster;
|
|
|
|
//WINCESdlGraphicsManager _graphicsManager
|
|
|
|
WINCESdlGraphicsManager *graphicsManager = dynamic_cast<WINCESdlGraphicsManager *>(_graphicsManager);
|
|
if (graphicsManager->_toolbarHandler.activeName() == NAME_MAIN_PANEL)
|
|
graphicsManager->_toolbarHandler.forceRedraw(); // redraw sound icon
|
|
}
|
|
|
|
|
|
void OSystem_WINCE3::engineInit() {
|
|
check_mappings(); // called here to initialize virtual keys handling
|
|
|
|
dynamic_cast<WINCESdlGraphicsManager *>(_graphicsManager)->update_game_settings();
|
|
// finalize mixer init
|
|
_mixerManager->init();
|
|
}
|
|
|
|
void OSystem_WINCE3::check_mappings() {
|
|
CEActionsPocket *instance;
|
|
|
|
Common::String gameid(ConfMan.get("gameid"));
|
|
|
|
if (gameid.empty() || GUI_Actions::Instance()->initialized())
|
|
return;
|
|
|
|
GUI_Actions::Instance()->initInstanceGame();
|
|
instance = (CEActionsPocket *)GUI_Actions::Instance();
|
|
|
|
// Some games need to map the right click button, signal it here if it wasn't done
|
|
if (instance->needsRightClickMapping()) {
|
|
GUI::KeysDialog *keysDialog = new GUI::KeysDialog(_("Map right click action"));
|
|
while (!instance->getMapping(POCKET_ACTION_RIGHTCLICK)) {
|
|
keysDialog->runModal();
|
|
if (!instance->getMapping(POCKET_ACTION_RIGHTCLICK)) {
|
|
GUI::MessageDialog alert(_("You must map a key to the 'Right Click' action to play this game"));
|
|
alert.runModal();
|
|
}
|
|
}
|
|
delete keysDialog;
|
|
}
|
|
|
|
// Map the "hide toolbar" action if needed
|
|
if (instance->needsHideToolbarMapping()) {
|
|
GUI::KeysDialog *keysDialog = new GUI::KeysDialog(_("Map hide toolbar action"));
|
|
while (!instance->getMapping(POCKET_ACTION_HIDE)) {
|
|
keysDialog->runModal();
|
|
if (!instance->getMapping(POCKET_ACTION_HIDE)) {
|
|
GUI::MessageDialog alert(_("You must map a key to the 'Hide toolbar' action to play this game"));
|
|
alert.runModal();
|
|
}
|
|
}
|
|
delete keysDialog;
|
|
}
|
|
|
|
// Map the "zoom" actions if needed
|
|
if (instance->needsZoomMapping()) {
|
|
GUI::KeysDialog *keysDialog = new GUI::KeysDialog(_("Map Zoom Up action (optional)"));
|
|
keysDialog->runModal();
|
|
delete keysDialog;
|
|
keysDialog = new GUI::KeysDialog(_("Map Zoom Down action (optional)"));
|
|
keysDialog->runModal();
|
|
delete keysDialog;
|
|
}
|
|
|
|
// Extra warning for Zak Mc Kracken
|
|
if (strncmp(gameid.c_str(), "zak", 3) == 0 &&
|
|
!GUI_Actions::Instance()->getMapping(POCKET_ACTION_HIDE)) {
|
|
GUI::MessageDialog alert(_("Don't forget to map a key to 'Hide Toolbar' action to see the whole inventory"));
|
|
alert.runModal();
|
|
}
|
|
|
|
}
|
|
|
|
void OSystem_WINCE3::setGraphicsModeIntern() {
|
|
// Scalers have been pre-selected for the desired mode.
|
|
// No further tuning required.
|
|
}
|
|
|
|
void OSystem_WINCE3::initSDL() {
|
|
// Check if SDL has not been initialized
|
|
if (!_initedSDL) {
|
|
uint32 sdlFlags = SDL_INIT_EVENTTHREAD | SDL_INIT_VIDEO;
|
|
if (ConfMan.hasKey("disable_sdl_parachute"))
|
|
sdlFlags |= SDL_INIT_NOPARACHUTE;
|
|
|
|
if (ConfMan.hasKey("use_GDI") && ConfMan.getBool("use_GDI")) {
|
|
SDL_VideoInit("windib", 0);
|
|
sdlFlags ^= SDL_INIT_VIDEO;
|
|
}
|
|
|
|
// Initialize SDL (SDL Subsystems are initiliazed in the corresponding sdl managers)
|
|
if (SDL_Init(sdlFlags) == -1)
|
|
error("Could not initialize SDL: %s", SDL_GetError());
|
|
|
|
_initedSDL = true;
|
|
}
|
|
}
|
|
|
|
void OSystem_WINCE3::init() {
|
|
// Create SdlMutexManager instance as the TimerManager relies on the
|
|
// MutexManager being already initialized
|
|
if (_mutexManager == 0)
|
|
_mutexManager = new SdlMutexManager();
|
|
|
|
// 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)
|
|
if (_timerManager == 0) {
|
|
_timerManager = new DefaultTimerManager();
|
|
SDL_SetTimer(10, &timer_handler_wrapper);
|
|
}
|
|
|
|
// Call parent implementation of this method
|
|
OSystem_SDL::init();
|
|
}
|
|
|
|
void OSystem_WINCE3::quit() {
|
|
fclose(stdout_file);
|
|
fclose(stderr_file);
|
|
if (gDebugLevel <= 0) {
|
|
DeleteFile(ASCIItoUnicode(stdout_fname));
|
|
DeleteFile(ASCIItoUnicode(stderr_fname));
|
|
}
|
|
CEDevice::end();
|
|
OSystem_SDL::quit();
|
|
}
|
|
|
|
void OSystem_WINCE3::getTimeAndDate(TimeDate &t) const {
|
|
SYSTEMTIME systime;
|
|
|
|
GetLocalTime(&systime);
|
|
t.tm_year = systime.wYear - 1900;
|
|
t.tm_mon = systime.wMonth - 1;
|
|
t.tm_mday = systime.wDay;
|
|
t.tm_hour = systime.wHour;
|
|
t.tm_min = systime.wMinute;
|
|
t.tm_sec = systime.wSecond;
|
|
t.tm_wday = systime.wDayOfWeek;
|
|
}
|
|
|
|
Common::String OSystem_WINCE3::getSystemLanguage() const {
|
|
#ifdef USE_DETECTLANG
|
|
// We can not use "setlocale" (at least not for MSVC builds), since it
|
|
// will return locales like: "English_USA.1252", thus we need a special
|
|
// way to determine the locale string for Win32.
|
|
char langName[9];
|
|
char ctryName[9];
|
|
TCHAR langNameW[32];
|
|
TCHAR ctryNameW[32];
|
|
int i = 0;
|
|
bool localeFound = false;
|
|
Common::String localeName;
|
|
|
|
// Really not nice, but the only way to map Windows CE language/country codes to posix NLS names,
|
|
// because Windows CE doesn't support LOCALE_SISO639LANGNAME and LOCALE_SISO3166CTRYNAME,
|
|
// according to this: http://msdn.microsoft.com/en-us/library/aa912934.aspx
|
|
//
|
|
// See http://msdn.microsoft.com/en-us/goglobal/bb896001.aspx for a translation table
|
|
// This table has to be updated manually when new translations are added
|
|
const char *posixMappingTable[][3] = {
|
|
{"CAT", "ESP", "ca_ES"},
|
|
{"CSY", "CZE", "cs_CZ"},
|
|
{"DAN", "DNK", "da_DA"},
|
|
{"DEU", "DEU", "de_DE"},
|
|
{"ESN", "ESP", "es_ES"},
|
|
{"ESP", "ESP", "es_ES"},
|
|
{"FRA", "FRA", "fr_FR"},
|
|
{"HUN", "HUN", "hu_HU"},
|
|
{"ITA", "ITA", "it_IT"},
|
|
{"NOR", "NOR", "nb_NO"},
|
|
{"NON", "NOR", "nn_NO"},
|
|
{"PLK", "POL", "pl_PL"},
|
|
{"PTB", "BRA", "pt_BR"},
|
|
{"RUS", "RUS", "ru_RU"},
|
|
{"SVE", "SWE", "se_SE"},
|
|
{"UKR", "UKR", "uk_UA"},
|
|
{NULL, NULL, NULL}
|
|
};
|
|
|
|
if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVLANGNAME, langNameW, sizeof(langNameW)) != 0 &&
|
|
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVCTRYNAME, ctryNameW, sizeof(ctryNameW)) != 0) {
|
|
WideCharToMultiByte(CP_ACP, 0, langNameW, -1, langName, (wcslen(langNameW) + 1), NULL, NULL);
|
|
WideCharToMultiByte(CP_ACP, 0, ctryNameW, -1, ctryName, (wcslen(ctryNameW) + 1), NULL, NULL);
|
|
|
|
debug(1, "Trying to find posix locale name for %s_%s", langName, ctryName);
|
|
while (posixMappingTable[i][0] && !localeFound) {
|
|
if ( (!strcmp(posixMappingTable[i][0], langName) || !strcmp(posixMappingTable[i][0], "*")) &&
|
|
(!strcmp(posixMappingTable[i][1], ctryName) || !strcmp(posixMappingTable[i][0], "*")) ) {
|
|
localeFound = true;
|
|
localeName = posixMappingTable[i][2];
|
|
}
|
|
i++;
|
|
}
|
|
if (!localeFound) warning("No posix locale name found for %s_%s", langName, ctryName);
|
|
}
|
|
|
|
if (localeFound) {
|
|
debug(1, "Found posix locale name: %s", localeName.c_str());
|
|
return localeName;
|
|
} else {
|
|
return ModularBackend::getSystemLanguage();
|
|
}
|
|
#else // USE_DETECTLANG
|
|
return ModularBackend::getSystemLanguage();
|
|
#endif // USE_DETECTLANG
|
|
}
|
|
|
|
int OSystem_WINCE3::_platformScreenWidth;
|
|
int OSystem_WINCE3::_platformScreenHeight;
|
|
bool OSystem_WINCE3::_isOzone;
|