aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/events/wincesdl/wincesdl-events.cpp327
-rw-r--r--backends/events/wincesdl/wincesdl-events.h62
-rw-r--r--backends/graphics/sdl/sdl-graphics.cpp7
-rw-r--r--backends/graphics/wincesdl/wincesdl-graphics.cpp1638
-rw-r--r--backends/graphics/wincesdl/wincesdl-graphics.h206
-rw-r--r--backends/mixer/wincesdl/wincesdl-mixer.cpp183
-rw-r--r--backends/mixer/wincesdl/wincesdl-mixer.h53
-rw-r--r--backends/module.mk3
-rw-r--r--backends/platform/wince/CEActionsPocket.cpp42
-rw-r--r--backends/platform/wince/CEActionsSmartphone.cpp33
-rw-r--r--backends/platform/wince/CEDevice.cpp12
-rw-r--r--backends/platform/wince/CEDevice.h2
-rw-r--r--backends/platform/wince/wince-sdl.cpp2048
-rw-r--r--backends/platform/wince/wince-sdl.h180
14 files changed, 2599 insertions, 2197 deletions
diff --git a/backends/events/wincesdl/wincesdl-events.cpp b/backends/events/wincesdl/wincesdl-events.cpp
new file mode 100644
index 0000000000..86b2fd6917
--- /dev/null
+++ b/backends/events/wincesdl/wincesdl-events.cpp
@@ -0,0 +1,327 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/scummsys.h"
+
+#ifdef _WIN32_WCE
+
+#include "common/config-manager.h"
+
+#include "backends/events/wincesdl/wincesdl-events.h"
+#include "backends/graphics/wincesdl/wincesdl-graphics.h"
+#include "backends/platform/wince/CEActionsPocket.h"
+#include "backends/platform/wince/CEActionsSmartphone.h"
+#include "backends/platform/wince/CEDevice.h"
+
+#include "backends/platform/sdl/sdl.h"
+
+WINCESdlEventSource::WINCESdlEventSource()
+ : _tapTime(0), _closeClick(false), _rbutton(false),
+ _freeLook(false) {
+}
+
+void WINCESdlEventSource::fillMouseEvent(Common::Event &event, int x, int y) {
+ event.mouse.x = x;
+ event.mouse.y = y;
+
+ // Update the "keyboard mouse" coords
+ _km.x = event.mouse.x;
+ _km.y = event.mouse.y;
+
+ // Adjust for the screen scaling
+ if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_zoomDown)
+ event.mouse.y += 240;
+
+ event.mouse.x = event.mouse.x * ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_scaleFactorXd / ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_scaleFactorXm;
+ event.mouse.y = event.mouse.y * ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_scaleFactorYd / ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_scaleFactorYm;
+}
+
+bool WINCESdlEventSource::pollEvent(Common::Event &event) {
+ SDL_Event ev;
+ ev.type = SDL_NOEVENT;
+ DWORD currentTime;
+ bool keyEvent = false;
+ int deltaX, deltaY;
+
+ memset(&event, 0, sizeof(Common::Event));
+
+ handleKbdMouse();
+
+ // If the screen changed, send an Common::EVENT_SCREEN_CHANGED
+ int screenID = ((OSystem_SDL *)g_system)->getGraphicsManager()->getScreenChangeID();
+ if (screenID != _lastScreenID) {
+ _lastScreenID = screenID;
+ event.type = Common::EVENT_SCREEN_CHANGED;
+ return true;
+ }
+
+ CEDevice::wakeUp();
+
+ currentTime = GetTickCount();
+
+ while (SDL_PollEvent(&ev)) {
+ switch (ev.type) {
+ case SDL_KEYDOWN:
+ debug(1, "Key down %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));
+ // KMOD_RESERVED is used if the key has been injected by an external buffer
+ if (ev.key.keysym.mod != KMOD_RESERVED && !GUI::Actions::Instance()->mappingActive()) {
+ keyEvent = true;
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed = ev.key.keysym.sym;
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeatTime = currentTime;
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeat = 0;
+
+ if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, true))
+ return true;
+ }
+
+ if (GUI_Actions::Instance()->mappingActive())
+ event.kbd.flags = 0xFF;
+ else if (ev.key.keysym.sym == SDLK_PAUSE) {
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed = 0;
+ event.type = Common::EVENT_PREDICTIVE_DIALOG;
+ return true;
+ } event.type = Common::EVENT_KEYDOWN;
+ if (!GUI::Actions::Instance()->mappingActive())
+ event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
+ else
+ event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive());
+ event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive());
+
+ if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
+ event.kbd.ascii ^= 0x20;
+ event.kbd.flags = Common::KBD_SHIFT;
+ }
+
+ return true;
+
+ case SDL_KEYUP:
+ debug(1, "Key up %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));
+ // KMOD_RESERVED is used if the key has been injected by an external buffer
+ if (ev.key.keysym.mod != KMOD_RESERVED && !GUI::Actions::Instance()->mappingActive()) {
+ keyEvent = true;
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed = 0;
+
+ if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, false))
+ return true;
+ }
+
+ if (GUI_Actions::Instance()->mappingActive())
+ event.kbd.flags = 0xFF;
+ else if (ev.key.keysym.sym == SDLK_PAUSE) {
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed = 0;
+ return false; // chew up the show agi dialog key up event
+ }
+
+ event.type = Common::EVENT_KEYUP;
+ if (!GUI::Actions::Instance()->mappingActive())
+ event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
+ else
+ event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive());
+ event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive());
+
+ if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
+ event.kbd.ascii ^= 0x20;
+ event.kbd.flags = Common::KBD_SHIFT;
+ }
+
+ return true;
+
+ case SDL_MOUSEMOTION:
+ event.type = Common::EVENT_MOUSEMOVE;
+ fillMouseEvent(event, ev.motion.x, ev.motion.y);
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->setMousePos(event.mouse.x, event.mouse.y);
+
+ return true;
+
+ case SDL_MOUSEBUTTONDOWN:
+ if (ev.button.button == SDL_BUTTON_LEFT)
+ event.type = Common::EVENT_LBUTTONDOWN;
+ else if (ev.button.button == SDL_BUTTON_RIGHT)
+ event.type = Common::EVENT_RBUTTONDOWN;
+ else
+ break;
+ fillMouseEvent(event, ev.button.x, ev.button.y);
+
+
+ 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 &&
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_panelInitialized) {
+ // top of screen (show panel)
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_panel_visibility();
+ } else if (!((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_noDoubleTapRMB) {
+ // right click
+ event.type = Common::EVENT_RBUTTONDOWN;
+ _rbutton = true;
+ }
+ }
+ _tapTime = 0;
+ } else {
+ _tapTime = GetTickCount();
+ _tapX = event.mouse.x;
+ _tapY = event.mouse.y;
+ }
+ }
+
+ if (_freeLook && !_closeClick) {
+ _rbutton = false;
+ _tapTime = 0;
+ _tapX = event.mouse.x;
+ _tapY = event.mouse.y;
+ event.type = Common::EVENT_MOUSEMOVE;
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->setMousePos(event.mouse.x, event.mouse.y);
+ }
+
+
+ if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHandler.action(event.mouse.x, event.mouse.y, true)) {
+ if (!((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHandler.drawn()) {
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHighDrawn = false;
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->internUpdateScreen();
+ }
+ if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_newOrientation != ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_orientationLandscape){
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_orientationLandscape = ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_newOrientation;
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHighDrawn = false;
+ ConfMan.setInt("landscape", ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_orientationLandscape);
+ ConfMan.flushToDisk();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->hotswapGFXMode();
+ }
+ return false;
+ }
+
+ return true;
+
+ case SDL_MOUSEBUTTONUP:
+ if (ev.button.button == SDL_BUTTON_LEFT)
+ event.type = Common::EVENT_LBUTTONUP;
+ else if (ev.button.button == SDL_BUTTON_RIGHT)
+ event.type = Common::EVENT_RBUTTONUP;
+ else
+ break;
+
+ if (_rbutton) {
+ event.type = Common::EVENT_RBUTTONUP;
+ _rbutton = false;
+ }
+
+ fillMouseEvent(event, ev.button.x, ev.button.y);
+
+ if (_freeLook && !_closeClick) {
+ _tapX = event.mouse.x;
+ _tapY = event.mouse.y;
+ event.type = Common::EVENT_MOUSEMOVE;
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->setMousePos(event.mouse.x, event.mouse.y);
+ }
+
+ if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHandler.action(event.mouse.x, event.mouse.y, false)) {
+ if (!((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHandler.drawn()) {
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHighDrawn = false;
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->internUpdateScreen();
+ }
+ return false;
+
+ }
+ return true;
+
+ case SDL_VIDEOEXPOSE:
+ // HACK: Send a fake event, handled by SdlGraphicsManager
+ event.type = (Common::EventType)OSystem_SDL::kSdlEventExpose;
+ break;
+
+ case SDL_QUIT:
+ event.type = Common::EVENT_QUIT;
+ return true;
+
+ case SDL_ACTIVEEVENT:
+ if (ev.active.state & SDL_APPMOUSEFOCUS)
+ debug(2, "%s mouse focus.", ev.active.gain ? "Got" : "Lost");
+ if (ev.active.state & SDL_APPINPUTFOCUS)
+ debug(2, "%s input focus.", ev.active.gain ? "Got" : "Lost");
+ if (ev.active.state & SDL_APPACTIVE)
+ debug(2, "%s total focus.", ev.active.gain ? "Got" : "Lost");
+ if (ev.active.state & SDL_APPINPUTFOCUS) {
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_hasfocus = ev.active.gain;
+ SDL_PauseAudio(!((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_hasfocus);
+ if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_hasfocus) {
+ event.type = (Common::EventType)OSystem_SDL::kSdlEventExpose;
+ }
+ }
+ break;
+ }
+ }
+
+ // Simulate repeated key for backend
+ if (!keyEvent && ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed && (int)currentTime > ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeatTime + ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeatTrigger) {
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeatTime = currentTime;
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeat++;
+ GUI_Actions::Instance()->performMapped(((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed, true);
+ }
+
+ return false;
+}
+
+int WINCESdlEventSource::mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode, bool unfilter) {
+ if (GUI::Actions::Instance()->mappingActive())
+ return key;
+
+ if (unfilter) {
+ switch (key) {
+ case SDLK_ESCAPE:
+ return SDLK_BACKSPACE;
+ case SDLK_F8:
+ return SDLK_ASTERISK;
+ case SDLK_F9:
+ return SDLK_HASH;
+ default:
+ return key;
+ }
+ }
+
+ 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;
+}
+
+void WINCESdlEventSource::swap_freeLook() {
+ _freeLook = !_freeLook;
+}
+
+#endif /* _WIN32_WCE */
diff --git a/backends/events/wincesdl/wincesdl-events.h b/backends/events/wincesdl/wincesdl-events.h
new file mode 100644
index 0000000000..4c5b194abd
--- /dev/null
+++ b/backends/events/wincesdl/wincesdl-events.h
@@ -0,0 +1,62 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef BACKENDS_EVENTS_SDL_WINCE_H
+#define BACKENDS_EVENTS_SDL_WINCE_H
+
+#include "backends/events/sdl/sdl-events.h"
+
+extern bool _isSmartphone;
+
+class WINCESdlEventSource : public SdlEventSource {
+public:
+ WINCESdlEventSource();
+
+ void loadDeviceConfiguration();
+
+ // Overloaded from SDL backend (toolbar handling)
+ bool pollEvent(Common::Event &event);
+ // Overloaded from SDL backend (mouse and new scaler handling)
+ void fillMouseEvent(Common::Event &event, int x, int y);
+
+ void swap_freeLook();
+
+protected:
+
+private:
+ int mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode, bool unfilter);
+
+ // Keyboard tap
+ int _tapX;
+ int _tapY;
+ long _tapTime;
+
+ bool _closeClick; // flag when taps are spatially close together
+ bool _rbutton; // double tap -> right button simulation
+ bool _freeLook; // freeLook mode (do not send mouse button events)
+
+};
+
+#endif /* BACKENDS_EVENTS_SDL_WINCE_H */
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index d8b686e61f..7d36786b7d 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -161,13 +161,6 @@ SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *sdlEventSource)
_graphicsMutex = g_system->createMutex();
-#ifdef _WIN32_WCE
- if (ConfMan.hasKey("use_GDI") && ConfMan.getBool("use_GDI")) {
- SDL_VideoInit("windib", 0);
- sdlFlags ^= SDL_INIT_VIDEO;
- }
-#endif
-
SDL_ShowCursor(SDL_DISABLE);
memset(&_oldVideoMode, 0, sizeof(_oldVideoMode));
diff --git a/backends/graphics/wincesdl/wincesdl-graphics.cpp b/backends/graphics/wincesdl/wincesdl-graphics.cpp
new file mode 100644
index 0000000000..ad1a8e7a1a
--- /dev/null
+++ b/backends/graphics/wincesdl/wincesdl-graphics.cpp
@@ -0,0 +1,1638 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/scummsys.h"
+
+#ifdef _WIN32_WCE
+
+#include "common/system.h"
+#include "common/translation.h"
+#include "common/mutex.h"
+
+#include "graphics/scaler/downscaler.h"
+#include "graphics/scaler/aspect.h"
+#include "backends/graphics/wincesdl/wincesdl-graphics.h"
+#include "backends/events/wincesdl/wincesdl-events.h"
+#include "backends/platform/wince/wince-sdl.h"
+
+#include "backends/platform/wince/resource.h"
+#include "backends/platform/wince/CEActionsPocket.h"
+#include "backends/platform/wince/CEActionsSmartphone.h"
+#include "backends/platform/wince/CEDevice.h"
+#include "backends/platform/wince/CEScaler.h"
+#include "backends/platform/wince/CEgui/ItemAction.h"
+
+WINCESdlGraphicsManager::WINCESdlGraphicsManager(SdlEventSource *sdlEventSource)
+ : SdlGraphicsManager(sdlEventSource),
+ _panelInitialized(false), _noDoubleTapRMB(false),
+ _toolbarHighDrawn(false), _newOrientation(0), _orientationLandscape(0),
+ _panelVisible(true), _saveActiveToolbar(NAME_MAIN_PANEL), _panelStateForced(false),
+ _canBeAspectScaled(false), _scalersChanged(false), _saveToolbarState(false),
+ _mouseBackupOld(NULL), _mouseBackupDim(0), _mouseBackupToolbar(NULL),
+ _usesEmulatedMouse(false), _forceHideMouse(false), _hasfocus(true),
+ _zoomUp(false), _zoomDown(false) {
+ memset(&_mouseCurState, 0, sizeof(_mouseCurState));
+ if (_isSmartphone) {
+ _mouseCurState.x = 20;
+ _mouseCurState.y = 20;
+ }
+
+ loadDeviceConfigurationElement("repeatTrigger", _keyRepeatTrigger, 200);
+ loadDeviceConfigurationElement("repeatX", _repeatX, 4);
+ loadDeviceConfigurationElement("repeatY", _repeatY, 4);
+ loadDeviceConfigurationElement("stepX1", _stepX1, 2);
+ loadDeviceConfigurationElement("stepX2", _stepX2, 10);
+ loadDeviceConfigurationElement("stepX3", _stepX3, 40);
+ loadDeviceConfigurationElement("stepY1", _stepY1, 2);
+ loadDeviceConfigurationElement("stepY2", _stepY2, 10);
+ loadDeviceConfigurationElement("stepY3", _stepY3, 20);
+ ConfMan.flushToDisk();
+
+ _isSmartphone = CEDevice::isSmartphone();
+
+ // Query SDL for screen size and init screen dependent stuff
+ OSystem_WINCE3::initScreenInfos();
+ create_toolbar();
+ _hasSmartphoneResolution = CEDevice::hasSmartphoneResolution() || CEDevice::isSmartphone();
+ if (_hasSmartphoneResolution)
+ _panelVisible = false; // init correctly in smartphones
+
+ _screen = NULL;
+}
+
+// Graphics mode consts
+
+// Low end devices 240x320
+
+static const OSystem::GraphicsMode s_supportedGraphicsModesLow[] = {
+ {"1x", _s("Normal (no scaling)"), GFX_NORMAL},
+ {0, 0, 0}
+};
+
+// High end device 480x640
+
+static const OSystem::GraphicsMode s_supportedGraphicsModesHigh[] = {
+ {"1x", _s("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}
+};
+
+const OSystem::GraphicsMode *WINCESdlGraphicsManager::getSupportedGraphicsModes() const {
+ if (CEDevice::hasWideResolution())
+ return s_supportedGraphicsModesHigh;
+ else
+ return s_supportedGraphicsModesLow;
+}
+
+bool WINCESdlGraphicsManager::hasFeature(OSystem::Feature f) {
+ return (f == OSystem::kFeatureVirtualKeyboard);
+}
+
+void WINCESdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
+ switch (f) {
+ case OSystem::kFeatureFullscreenMode:
+ return;
+
+ case OSystem::kFeatureVirtualKeyboard:
+ if (_hasSmartphoneResolution)
+ return;
+ _toolbarHighDrawn = false;
+ if (enable) {
+ _panelStateForced = true;
+ if (!_toolbarHandler.visible()) swap_panel_visibility();
+ //_saveToolbarState = _toolbarHandler.visible();
+ _saveActiveToolbar = _toolbarHandler.activeName();
+ _toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
+ _toolbarHandler.setVisible(true);
+ } else
+ if (_panelStateForced) {
+ _panelStateForced = false;
+ _toolbarHandler.setActive(_saveActiveToolbar);
+ //_toolbarHandler.setVisible(_saveToolbarState);
+ }
+ return;
+
+ case OSystem::kFeatureDisableKeyFiltering:
+ if (_hasSmartphoneResolution) {
+ GUI::Actions::Instance()->beginMapping(enable);
+ }
+ return;
+
+ default:
+ SdlGraphicsManager::setFeatureState(f, enable);
+ }
+}
+
+bool WINCESdlGraphicsManager::getFeatureState(OSystem::Feature f) {
+ switch (f) {
+ case OSystem::kFeatureFullscreenMode:
+ return false;
+ case OSystem::kFeatureVirtualKeyboard:
+ return (_panelStateForced);
+ default:
+ return SdlGraphicsManager::getFeatureState(f);
+ }
+}
+
+int WINCESdlGraphicsManager::getDefaultGraphicsMode() const {
+ return GFX_NORMAL;
+}
+
+void WINCESdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFormat *format) {
+ if (_hasSmartphoneResolution && h == 240)
+ h = 200; // mainly for the launcher
+
+ if (_isSmartphone && !ConfMan.hasKey("landscape")) {
+ ConfMan.setInt("landscape", 1);
+ ConfMan.flushToDisk();
+ }
+
+ _canBeAspectScaled = false;
+ if (w == 320 && h == 200 && !_hasSmartphoneResolution) {
+ _canBeAspectScaled = true;
+ h = 240; // use the extra 40 pixels height for the toolbar
+ }
+
+ if (h == 400) // touche engine fixup
+ h += 80;
+
+ if (!_hasSmartphoneResolution) {
+ if (h == 240)
+ _toolbarHandler.setOffset(200);
+ else
+ _toolbarHandler.setOffset(400);
+ } else {
+ if (h == 240)
+ _toolbarHandler.setOffset(200);
+ else // 176x220
+ _toolbarHandler.setOffset(0);
+ }
+
+ if (w != (uint) _videoMode.screenWidth || h != (uint) _videoMode.screenHeight)
+ _scalersChanged = false;
+
+ _videoMode.overlayWidth = w;
+ _videoMode.overlayHeight = h;
+
+ SdlGraphicsManager::initSize(w, h, format);
+
+ if (_scalersChanged) {
+ unloadGFXMode();
+ loadGFXMode();
+ _scalersChanged = false;
+ }
+
+ update_game_settings();
+}
+
+void WINCESdlGraphicsManager::loadDeviceConfigurationElement(Common::String element, int &value, int defaultValue) {
+ value = ConfMan.getInt(element, ConfMan.kApplicationDomain);
+ if (!value) {
+ value = defaultValue;
+ ConfMan.setInt(element, value, ConfMan.kApplicationDomain);
+ }
+}
+
+void WINCESdlGraphicsManager::move_cursor_up() {
+ int x, y;
+ _usesEmulatedMouse = true;
+ retrieve_mouse_location(x, y);
+ if (_keyRepeat > _repeatY)
+ y -= _stepY3;
+ else if (_keyRepeat)
+ y -= _stepY2;
+ else
+ y -= _stepY1;
+
+ if (y < 0)
+ y = 0;
+
+ EventsBuffer::simulateMouseMove(x, y);
+}
+
+void WINCESdlGraphicsManager::move_cursor_down() {
+ int x, y;
+ _usesEmulatedMouse = true;
+ retrieve_mouse_location(x, y);
+ if (_keyRepeat > _repeatY)
+ y += _stepY3;
+ else if (_keyRepeat)
+ y += _stepY2;
+ else
+ y += _stepY1;
+
+ if (y > _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd)
+ y = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd;
+
+ EventsBuffer::simulateMouseMove(x, y);
+}
+
+void WINCESdlGraphicsManager::move_cursor_left() {
+ int x, y;
+ _usesEmulatedMouse = true;
+ retrieve_mouse_location(x, y);
+ if (_keyRepeat > _repeatX)
+ x -= _stepX3;
+ else if (_keyRepeat)
+ x -= _stepX2;
+ else
+ x -= _stepX1;
+
+ if (x < 0)
+ x = 0;
+
+ EventsBuffer::simulateMouseMove(x, y);
+}
+
+void WINCESdlGraphicsManager::move_cursor_right() {
+ int x, y;
+ _usesEmulatedMouse = true;
+ retrieve_mouse_location(x, y);
+ if (_keyRepeat > _repeatX)
+ x += _stepX3;
+ else if (_keyRepeat)
+ x += _stepX2;
+ else
+ x += _stepX1;
+
+ if (x > _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd)
+ x = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd;
+
+ EventsBuffer::simulateMouseMove(x, y);
+}
+
+void WINCESdlGraphicsManager::retrieve_mouse_location(int &x, int &y) {
+ x = _mouseCurState.x;
+ y = _mouseCurState.y;
+
+ x = x * _scaleFactorXm / _scaleFactorXd;
+ y = y * _scaleFactorYm / _scaleFactorYd;
+
+ if (_zoomDown)
+ y -= 240;
+}
+
+void WINCESdlGraphicsManager::switch_zone() {
+ int x, y;
+ int i;
+ retrieve_mouse_location(x, y);
+
+ for (i = 0; i < TOTAL_ZONES; i++)
+ if (x >= _zones[i].x && y >= _zones[i].y &&
+ x <= _zones[i].x + _zones[i].width && y <= _zones[i].y + _zones[i].height) {
+ _mouseXZone[i] = x;
+ _mouseYZone[i] = y;
+ break;
+ }
+ _currentZone = i + 1;
+ if (_currentZone >= TOTAL_ZONES)
+ _currentZone = 0;
+
+ EventsBuffer::simulateMouseMove(_mouseXZone[_currentZone], _mouseYZone[_currentZone]);
+}
+
+void WINCESdlGraphicsManager::add_right_click(bool pushed) {
+ int x, y;
+ retrieve_mouse_location(x, y);
+ EventsBuffer::simulateMouseRightClick(x, y, pushed);
+}
+
+void WINCESdlGraphicsManager::add_left_click(bool pushed) {
+ int x, y;
+ retrieve_mouse_location(x, y);
+ EventsBuffer::simulateMouseLeftClick(x, y, pushed);
+}
+
+bool WINCESdlGraphicsManager::update_scalers() {
+ _videoMode.aspectRatioCorrection = false;
+
+ if (CEDevice::hasPocketPCResolution()) {
+ if (_videoMode.mode != GFX_NORMAL)
+ return false;
+
+ if ((!_orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth))
+ || CEDevice::hasSquareQVGAResolution() ) {
+ if (OSystem_WINCE3::getScreenWidth() != 320) {
+ _scaleFactorXm = 3;
+ _scaleFactorXd = 4;
+ _scaleFactorYm = 1;
+ _scaleFactorYd = 1;
+ _scalerProc = DownscaleHorizByThreeQuarters;
+ } else {
+ _scaleFactorXm = 1;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = 1;
+ _scaleFactorYd = 1;
+ _scalerProc = Normal1x;
+ }
+ } else if ( _orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth)) {
+ if (!_panelVisible && !_hasSmartphoneResolution && !_overlayVisible && _canBeAspectScaled) {
+ _scaleFactorXm = 1;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = 6;
+ _scaleFactorYd = 5;
+ _scalerProc = Normal1xAspect;
+ _videoMode.aspectRatioCorrection = true;
+ } else {
+ _scaleFactorXm = 1;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = 1;
+ _scaleFactorYd = 1;
+ _scalerProc = Normal1x;
+ }
+ } else if (_videoMode.screenWidth == 640 && !(OSystem_WINCE3::isOzone() && (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640))) {
+ _scaleFactorXm = 1;
+ _scaleFactorXd = 2;
+ _scaleFactorYm = 1;
+ _scaleFactorYd = 2;
+ _scalerProc = DownscaleAllByHalf;
+ } else if (_videoMode.screenWidth == 640 && (OSystem_WINCE3::isOzone() && (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640))) {
+ _scaleFactorXm = 1;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = 1;
+ _scaleFactorYd = 1;
+ _scalerProc = Normal1x;
+ }
+
+ return true;
+ } else if (CEDevice::hasWideResolution()) {
+#ifdef USE_ARM_SCALER_ASM
+ if ( _videoMode.mode == GFX_DOUBLESIZE && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth) ) {
+ if ( !_panelVisible && !_overlayVisible && _canBeAspectScaled ) {
+ _scaleFactorXm = 2;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = 12;
+ _scaleFactorYd = 5;
+ _scalerProc = Normal2xAspect;
+ _videoMode.aspectRatioCorrection = true;
+ } else if ( (_panelVisible || _overlayVisible) && _canBeAspectScaled ) {
+ _scaleFactorXm = 2;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = 2;
+ _scaleFactorYd = 1;
+ _scalerProc = Normal2x;
+ }
+ return true;
+ }
+#endif
+ } else if (CEDevice::hasSmartphoneResolution()) {
+ if (_videoMode.mode != GFX_NORMAL)
+ return false;
+
+ if (_videoMode.screenWidth > 320)
+ error("Game resolution not supported on Smartphone");
+#ifdef ARM
+ _scaleFactorXm = 11;
+ _scaleFactorXd = 16;
+#else
+ _scaleFactorXm = 2;
+ _scaleFactorXd = 3;
+#endif
+ _scaleFactorYm = 7;
+ _scaleFactorYd = 8;
+ _scalerProc = SmartphoneLandscape;
+ initZones();
+ return true;
+ }
+
+ return false;
+}
+
+void WINCESdlGraphicsManager::update_game_settings() {
+ Common::String gameid(ConfMan.get("gameid"));
+
+ // Finish panel initialization
+ if (!_panelInitialized && !gameid.empty()) {
+ CEGUI::Panel *panel;
+ _panelInitialized = true;
+ // Add the main panel
+ panel = new CEGUI::Panel(0, 32);
+ panel->setBackground(IMAGE_PANEL);
+
+ // Save
+ panel->add(NAME_ITEM_OPTIONS, new CEGUI::ItemAction(ITEM_OPTIONS, POCKET_ACTION_SAVE));
+ // Skip
+ panel->add(NAME_ITEM_SKIP, new CEGUI::ItemAction(ITEM_SKIP, POCKET_ACTION_SKIP));
+ // sound
+//__XXX__ panel->add(NAME_ITEM_SOUND, new CEGUI::ItemSwitch(ITEM_SOUND_OFF, ITEM_SOUND_ON, &_soundMaster));
+ panel->add(NAME_ITEM_SOUND, new CEGUI::ItemSwitch(ITEM_SOUND_OFF, ITEM_SOUND_ON, &OSystem_WINCE3::_soundMaster));
+
+ // bind keys
+ panel->add(NAME_ITEM_BINDKEYS, new CEGUI::ItemAction(ITEM_BINDKEYS, POCKET_ACTION_BINDKEYS));
+ // portrait/landscape - screen dependent
+ // FIXME : will still display the portrait/landscape icon when using a scaler (but will be disabled)
+ if (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 CEGUI::ItemSwitch(ITEM_VIEW_LANDSCAPE, ITEM_VIEW_PORTRAIT, &_newOrientation, 2));
+ _toolbarHandler.add(NAME_MAIN_PANEL, *panel);
+ _toolbarHandler.setActive(NAME_MAIN_PANEL);
+ _toolbarHandler.setVisible(true);
+
+ if (_videoMode.mode == GFX_NORMAL && ConfMan.hasKey("landscape") && ConfMan.getInt("landscape")) {
+ setGraphicsMode(GFX_NORMAL);
+ hotswapGFXMode();
+ }
+
+ if (_hasSmartphoneResolution)
+ panel->setVisible(false);
+
+ _saveToolbarState = true;
+ }
+
+ if (ConfMan.hasKey("no_doubletap_rightclick"))
+ _noDoubleTapRMB = ConfMan.getBool("no_doubletap_rightclick");
+}
+
+void WINCESdlGraphicsManager::internUpdateScreen() {
+ SDL_Surface *srcSurf, *origSurf;
+ static bool old_overlayVisible = false;
+ int numRectsOut = 0;
+ int16 routx, routy, routw, routh, stretch, shakestretch;
+
+ assert(_hwscreen != NULL);
+
+ // bail if the application is minimized, be nice to OS
+ if (!_hasfocus) {
+ Sleep(20);
+ return;
+ }
+
+ // If the shake position changed, fill the dirty area with blackness
+ if (_currentShakePos != _newShakePos) {
+ SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd, _newShakePos * _scaleFactorYm / _scaleFactorYd};
+ if (_videoMode.aspectRatioCorrection)
+ blackrect.h = real2Aspect(blackrect.h - 1) + 1;
+ SDL_FillRect(_hwscreen, &blackrect, 0);
+ _currentShakePos = _newShakePos;
+ _forceFull = true;
+ }
+
+ // Make sure the mouse is drawn, if it should be drawn.
+ drawMouse();
+
+ // Check whether the palette was changed in the meantime and update the
+ // screen surface accordingly.
+ if (_paletteDirtyEnd != 0) {
+ SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart, _paletteDirtyStart, _paletteDirtyEnd - _paletteDirtyStart);
+ _paletteDirtyEnd = 0;
+ _forceFull = true;
+ }
+
+ if (!_overlayVisible) {
+ origSurf = _screen;
+ srcSurf = _tmpscreen;
+ } else {
+ origSurf = _overlayscreen;
+ srcSurf = _tmpscreen2;
+ }
+
+ if (old_overlayVisible != _overlayVisible) {
+ old_overlayVisible = _overlayVisible;
+ update_scalers();
+ }
+
+ // Force a full redraw if requested
+ if (_forceFull) {
+ _numDirtyRects = 1;
+
+ _dirtyRectList[0].x = 0;
+ if (!_zoomDown)
+ _dirtyRectList[0].y = 0;
+ else
+ _dirtyRectList[0].y = _videoMode.screenHeight / 2;
+ _dirtyRectList[0].w = _videoMode.screenWidth;
+ if (!_zoomUp && !_zoomDown)
+ _dirtyRectList[0].h = _videoMode.screenHeight;
+ else
+ _dirtyRectList[0].h = _videoMode.screenHeight / 2;
+
+ _toolbarHandler.forceRedraw();
+ }
+
+ // Only draw anything if necessary
+ if (_numDirtyRects > 0) {
+
+ SDL_Rect *r, *rout;
+ SDL_Rect dst;
+ uint32 srcPitch, dstPitch;
+ SDL_Rect *last_rect = _dirtyRectList + _numDirtyRects;
+ bool toolbarVisible = _toolbarHandler.visible();
+ int toolbarOffset = _toolbarHandler.getOffset();
+
+ for (r = _dirtyRectList; r != last_rect; ++r) {
+ dst = *r;
+ dst.x++; // Shift rect by one since 2xSai needs to access the data around
+ dst.y++; // any pixel to scale it, and we want to avoid mem access crashes.
+ // NOTE: This is also known as BLACK MAGIC, copied from the sdl backend
+ if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)
+ error("SDL_BlitSurface failed: %s", SDL_GetError());
+ }
+
+ SDL_LockSurface(srcSurf);
+ SDL_LockSurface(_hwscreen);
+
+ srcPitch = srcSurf->pitch;
+ dstPitch = _hwscreen->pitch;
+
+ for (r = _dirtyRectList, rout = _dirtyRectOut; r != last_rect; ++r) {
+
+ // 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;
+ }
+
+ // transform
+ shakestretch = _currentShakePos * _scaleFactorYm / _scaleFactorYd;
+ routx = r->x * _scaleFactorXm / _scaleFactorXd; // locate position in scaled screen
+ routy = r->y * _scaleFactorYm / _scaleFactorYd + shakestretch; // adjust for shake offset
+ routw = r->w * _scaleFactorXm / _scaleFactorXd;
+ routh = r->h * _scaleFactorYm / _scaleFactorYd - shakestretch;
+
+ // 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;
+ if (routy < 0) {
+ routh += routy;
+ r->y -= routy * _scaleFactorYd / _scaleFactorYm;
+ routy = 0;
+ r->h = routh * _scaleFactorYd / _scaleFactorYm;
+ }
+ if (_orientationLandscape) {
+ if (routy > OSystem_WINCE3::getScreenWidth()) continue;
+ if (routy + routh > OSystem_WINCE3::getScreenWidth()) {
+ routh = OSystem_WINCE3::getScreenWidth() - routy;
+ r->h = routh * _scaleFactorYd / _scaleFactorYm;
+ }
+ } else {
+ if (routy > OSystem_WINCE3::getScreenHeight()) continue;
+ if (routy + routh > OSystem_WINCE3::getScreenHeight()) {
+ routh = OSystem_WINCE3::getScreenHeight() - routy;
+ r->h = routh * _scaleFactorYd / _scaleFactorYm;
+ }
+ }
+
+ // 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 - _currentShakePos);
+
+ // add this rect to output
+ rout->x = routx; rout->y = routy - shakestretch;
+ rout->w = routw; rout->h = routh + shakestretch;
+ numRectsOut++;
+ rout++;
+
+ }
+ SDL_UnlockSurface(srcSurf);
+ SDL_UnlockSurface(_hwscreen);
+ }
+ // Add the toolbar if needed
+ SDL_Rect toolbar_rect[1];
+ if (_panelVisible && _toolbarHandler.draw(_toolbarLow, &toolbar_rect[0])) {
+ // It can be drawn, scale it
+ uint32 srcPitch, dstPitch;
+ SDL_Surface *toolbarSurface;
+ ScalerProc *toolbarScaler;
+
+ if (_videoMode.screenHeight > 240) {
+ if (!_toolbarHighDrawn) {
+ // Resize the toolbar
+ SDL_LockSurface(_toolbarLow);
+ SDL_LockSurface(_toolbarHigh);
+ Normal2x((byte*)_toolbarLow->pixels, _toolbarLow->pitch, (byte*)_toolbarHigh->pixels, _toolbarHigh->pitch, toolbar_rect[0].w, toolbar_rect[0].h);
+ SDL_UnlockSurface(_toolbarHigh);
+ SDL_UnlockSurface(_toolbarLow);
+ _toolbarHighDrawn = true;
+ }
+ toolbar_rect[0].w *= 2;
+ toolbar_rect[0].h *= 2;
+ toolbarSurface = _toolbarHigh;
+ }
+ else
+ toolbarSurface = _toolbarLow;
+
+ drawToolbarMouse(toolbarSurface, true); // draw toolbar mouse if applicable
+
+ // Apply the appropriate scaler
+ SDL_LockSurface(toolbarSurface);
+ SDL_LockSurface(_hwscreen);
+ srcPitch = toolbarSurface->pitch;
+ dstPitch = _hwscreen->pitch;
+
+ toolbarScaler = _scalerProc;
+ if (_videoMode.scaleFactor == 2)
+ toolbarScaler = Normal2x;
+ else if (_videoMode.scaleFactor == 3)
+ toolbarScaler = Normal3x;
+ toolbarScaler((byte *)toolbarSurface->pixels, srcPitch,
+ (byte *)_hwscreen->pixels + (_toolbarHandler.getOffset() * _scaleFactorYm / _scaleFactorYd * dstPitch),
+ dstPitch, toolbar_rect[0].w, toolbar_rect[0].h);
+ SDL_UnlockSurface(toolbarSurface);
+ SDL_UnlockSurface(_hwscreen);
+
+ // And blit it
+ toolbar_rect[0].y = _toolbarHandler.getOffset();
+ toolbar_rect[0].x = toolbar_rect[0].x * _scaleFactorXm / _scaleFactorXd;
+ toolbar_rect[0].y = toolbar_rect[0].y * _scaleFactorYm / _scaleFactorYd;
+ toolbar_rect[0].w = toolbar_rect[0].w * _scaleFactorXm / _scaleFactorXd;
+ toolbar_rect[0].h = toolbar_rect[0].h * _scaleFactorYm / _scaleFactorYd;
+
+ SDL_UpdateRects(_hwscreen, 1, toolbar_rect);
+
+ drawToolbarMouse(toolbarSurface, false); // undraw toolbar mouse
+ }
+
+ // Finally, blit all our changes to the screen
+ if (numRectsOut > 0)
+ SDL_UpdateRects(_hwscreen, numRectsOut, _dirtyRectOut);
+
+ _numDirtyRects = 0;
+ _forceFull = false;
+}
+
+bool WINCESdlGraphicsManager::setGraphicsMode(int mode) {
+
+ Common::StackLock lock(_graphicsMutex);
+ int oldScaleFactorXm = _scaleFactorXm;
+ int oldScaleFactorXd = _scaleFactorXd;
+ int oldScaleFactorYm = _scaleFactorYm;
+ int oldScaleFactorYd = _scaleFactorYd;
+
+ _scaleFactorXm = -1;
+ _scaleFactorXd = -1;
+ _scaleFactorYm = -1;
+ _scaleFactorYd = -1;
+
+ if (ConfMan.hasKey("landscape"))
+ if (ConfMan.get("landscape")[0] > 57) {
+ _newOrientation = _orientationLandscape = ConfMan.getBool("landscape");
+ ConfMan.setInt("landscape", _orientationLandscape);
+ } else
+ _newOrientation = _orientationLandscape = ConfMan.getInt("landscape");
+ else
+ _newOrientation = _orientationLandscape = 0;
+
+ if (OSystem_WINCE3::isOzone() && (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640) && mode)
+ _scaleFactorXm = -1;
+
+ if (CEDevice::hasPocketPCResolution() && !CEDevice::hasWideResolution() && _orientationLandscape)
+ _videoMode.mode = GFX_NORMAL;
+ else
+ _videoMode.mode = mode;
+
+ if (_scaleFactorXm < 0) {
+ /* Standard scalers, from the SDL backend */
+ switch (_videoMode.mode) {
+ case GFX_NORMAL:
+ _videoMode.scaleFactor = 1;
+ _scalerProc = Normal1x;
+ break;
+ case GFX_DOUBLESIZE:
+ _videoMode.scaleFactor = 2;
+ _scalerProc = Normal2x;
+ break;
+ case GFX_TRIPLESIZE:
+ _videoMode.scaleFactor = 3;
+ _scalerProc = Normal3x;
+ break;
+ case GFX_2XSAI:
+ _videoMode.scaleFactor = 2;
+ _scalerProc = _2xSaI;
+ break;
+ case GFX_SUPER2XSAI:
+ _videoMode.scaleFactor = 2;
+ _scalerProc = Super2xSaI;
+ break;
+ case GFX_SUPEREAGLE:
+ _videoMode.scaleFactor = 2;
+ _scalerProc = SuperEagle;
+ break;
+ case GFX_ADVMAME2X:
+ _videoMode.scaleFactor = 2;
+ _scalerProc = AdvMame2x;
+ break;
+ case GFX_ADVMAME3X:
+ _videoMode.scaleFactor = 3;
+ _scalerProc = AdvMame3x;
+ break;
+#ifdef USE_HQ_SCALERS
+ case GFX_HQ2X:
+ _videoMode.scaleFactor = 2;
+ _scalerProc = HQ2x;
+ break;
+ case GFX_HQ3X:
+ _videoMode.scaleFactor = 3;
+ _scalerProc = HQ3x;
+ break;
+#endif
+ case GFX_TV2X:
+ _videoMode.scaleFactor = 2;
+ _scalerProc = TV2x;
+ break;
+ case GFX_DOTMATRIX:
+ _videoMode.scaleFactor = 2;
+ _scalerProc = DotMatrix;
+ break;
+
+ default:
+ error("unknown gfx mode %d", mode);
+ }
+ }
+
+ // Check if the scaler can be accepted, if not get back to normal scaler
+ if (_videoMode.scaleFactor && ((_videoMode.scaleFactor * _videoMode.screenWidth > OSystem_WINCE3::getScreenWidth() && _videoMode.scaleFactor * _videoMode.screenWidth > OSystem_WINCE3::getScreenHeight())
+ || (_videoMode.scaleFactor * _videoMode.screenHeight > OSystem_WINCE3::getScreenWidth() && _videoMode.scaleFactor * _videoMode.screenHeight > OSystem_WINCE3::getScreenHeight()))) {
+ _videoMode.scaleFactor = 1;
+ _scalerProc = Normal1x;
+ }
+
+ // Common scaler system was used
+ if (_scaleFactorXm < 0) {
+ _scaleFactorXm = _videoMode.scaleFactor;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = _videoMode.scaleFactor;
+ _scaleFactorYd = 1;
+ }
+
+ _forceFull = true;
+
+ if (oldScaleFactorXm != _scaleFactorXm ||
+ oldScaleFactorXd != _scaleFactorXd ||
+ oldScaleFactorYm != _scaleFactorYm ||
+ oldScaleFactorYd != _scaleFactorYd) {
+ _scalersChanged = true;
+ }
+ else
+ _scalersChanged = false;
+
+
+ return true;
+
+}
+
+bool WINCESdlGraphicsManager::loadGFXMode() {
+ int displayWidth;
+ int displayHeight;
+ unsigned int flags = SDL_FULLSCREEN | SDL_SWSURFACE;
+
+ _videoMode.fullscreen = true; // forced
+ _forceFull = true;
+
+ _tmpscreen = NULL;
+
+ // Recompute scalers if necessary
+ update_scalers();
+
+ // Create the surface that contains the 8 bit game data
+ _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
+ if (_screen == NULL)
+ error("_screen failed (%s)", SDL_GetError());
+
+ // Create the surface that contains the scaled graphics in 16 bit mode
+ // Always use full screen mode to have a "clean screen"
+ if (!_videoMode.aspectRatioCorrection) {
+ displayWidth = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd;
+ displayHeight = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd;
+ } else {
+ displayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
+ displayHeight = _videoMode.screenHeight* _videoMode.scaleFactor;
+ }
+
+ switch (_orientationLandscape) {
+ case 1:
+ flags |= SDL_LANDSCVIDEO;
+ break;
+ case 2:
+ flags |= SDL_INVLNDVIDEO;
+ break;
+ default:
+ flags |= SDL_PORTRTVIDEO;
+ }
+ _hwscreen = SDL_SetVideoMode(displayWidth, displayHeight, 16, flags);
+
+ if (_hwscreen == NULL) {
+ warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
+ g_system->quit();
+ }
+
+ // 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;
+
+ // Create the surface used for the graphics in 16 bit before scaling, and also the overlay
+ // Distinguish 555 and 565 mode
+ if (_hwscreen->format->Rmask == 0x7C00)
+ InitScalers(555);
+ else
+ InitScalers(565);
+ _overlayFormat.bytesPerPixel = _hwscreen->format->BytesPerPixel;
+ _overlayFormat.rLoss = _hwscreen->format->Rloss;
+ _overlayFormat.gLoss = _hwscreen->format->Gloss;
+ _overlayFormat.bLoss = _hwscreen->format->Bloss;
+ _overlayFormat.aLoss = _hwscreen->format->Aloss;
+ _overlayFormat.rShift = _hwscreen->format->Rshift;
+ _overlayFormat.gShift = _hwscreen->format->Gshift;
+ _overlayFormat.bShift = _hwscreen->format->Bshift;
+ _overlayFormat.aShift = _hwscreen->format->Ashift;
+
+ // Need some extra bytes around when using 2xSaI
+ _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
+
+ if (_tmpscreen == NULL)
+ error("_tmpscreen creation failed (%s)", SDL_GetError());
+
+ // Overlay
+ if (CEDevice::hasDesktopResolution()) {
+ _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd, 16, 0, 0, 0, 0);
+ if (_overlayscreen == NULL)
+ error("_overlayscreen failed (%s)", SDL_GetError());
+ _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd + 3, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd + 3, 16, 0, 0, 0, 0);
+ if (_tmpscreen2 == NULL)
+ error("_tmpscreen2 failed (%s)", SDL_GetError());
+ } else {
+ _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight, 16, 0, 0, 0, 0);
+ if (_overlayscreen == NULL)
+ error("_overlayscreen failed (%s)", SDL_GetError());
+ _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3, 16, 0, 0, 0, 0);
+ if (_tmpscreen2 == NULL)
+ error("_tmpscreen2 failed (%s)", SDL_GetError());
+ }
+
+ // Toolbar
+ _toolbarHighDrawn = false;
+ uint16 *toolbar_screen = (uint16 *)calloc(320 * 40, sizeof(uint16)); // *not* leaking memory here
+ _toolbarLow = SDL_CreateRGBSurfaceFrom(toolbar_screen, 320, 40, 16, 320 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
+
+ if (_toolbarLow == NULL)
+ error("_toolbarLow failed (%s)", SDL_GetError());
+
+ if (_videoMode.screenHeight > 240) {
+ uint16 *toolbar_screen_high = (uint16 *)calloc(640 * 80, sizeof(uint16));
+ _toolbarHigh = SDL_CreateRGBSurfaceFrom(toolbar_screen_high, 640, 80, 16, 640 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
+
+ if (_toolbarHigh == NULL)
+ error("_toolbarHigh failed (%s)", SDL_GetError());
+ } else
+ _toolbarHigh = NULL;
+
+ // keyboard cursor control, some other better place for it?
+ _sdlEventSource->resetKeyboadEmulation(_videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd - 1, _videoMode.screenHeight * _scaleFactorXm / _scaleFactorXd - 1);
+
+ return true;
+}
+
+void WINCESdlGraphicsManager::unloadGFXMode() {
+ if (_screen) {
+ SDL_FreeSurface(_screen);
+ _screen = NULL;
+ }
+
+ if (_hwscreen) {
+ SDL_FreeSurface(_hwscreen);
+ _hwscreen = NULL;
+ }
+
+ if (_tmpscreen) {
+ SDL_FreeSurface(_tmpscreen);
+ _tmpscreen = NULL;
+ }
+}
+
+bool WINCESdlGraphicsManager::hotswapGFXMode() {
+ if (!_screen)
+ return false;
+
+ // Keep around the old _screen & _tmpscreen so we can restore the screen data
+ // after the mode switch. (also for the overlay)
+ SDL_Surface *old_screen = _screen;
+ SDL_Surface *old_tmpscreen = _tmpscreen;
+ SDL_Surface *old_overlayscreen = _overlayscreen;
+ SDL_Surface *old_tmpscreen2 = _tmpscreen2;
+
+ // Release the HW screen surface
+ SDL_FreeSurface(_hwscreen);
+
+ // Release toolbars
+ free(_toolbarLow->pixels);
+ SDL_FreeSurface(_toolbarLow);
+ if (_toolbarHigh) {
+ free(_toolbarHigh->pixels);
+ SDL_FreeSurface(_toolbarHigh);
+ }
+
+ // Setup the new GFX mode
+ if (!loadGFXMode()) {
+ unloadGFXMode();
+
+ _screen = old_screen;
+ _overlayscreen = old_overlayscreen;
+
+ return false;
+ }
+
+ // reset palette
+ SDL_SetColors(_screen, _currentPalette, 0, 256);
+
+ // Restore old screen content
+ SDL_BlitSurface(old_screen, NULL, _screen, NULL);
+ SDL_BlitSurface(old_tmpscreen, NULL, _tmpscreen, NULL);
+ if (_overlayVisible) {
+ SDL_BlitSurface(old_overlayscreen, NULL, _overlayscreen, NULL);
+ SDL_BlitSurface(old_tmpscreen2, NULL, _tmpscreen2, NULL);
+ }
+
+ // Free the old surfaces
+ SDL_FreeSurface(old_screen);
+ SDL_FreeSurface(old_tmpscreen);
+ SDL_FreeSurface(old_overlayscreen);
+ SDL_FreeSurface(old_tmpscreen2);
+
+ // Blit everything back to the screen
+ _toolbarHighDrawn = false;
+ internUpdateScreen();
+
+ // Make sure that a Common::EVENT_SCREEN_CHANGED gets sent later -> FIXME this crashes when no game has been loaded.
+// _modeChanged = true;
+
+ return true;
+}
+
+bool WINCESdlGraphicsManager::saveScreenshot(const char *filename) {
+ assert(_hwscreen != NULL);
+
+ Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends
+ SDL_SaveBMP(_hwscreen, filename);
+ return true;
+}
+
+void WINCESdlGraphicsManager::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
+ assert (_transactionMode == kTransactionNone);
+
+ if (_overlayscreen == NULL)
+ return;
+
+ // Clip the coordinates
+ if (x < 0) {
+ w += x;
+ buf -= x;
+ x = 0;
+ }
+
+ if (y < 0) {
+ h += y; buf -= y * pitch;
+ y = 0;
+ }
+
+ if (w > _videoMode.overlayWidth - x) {
+ w = _videoMode.overlayWidth - x;
+ }
+
+ if (h > _videoMode.overlayHeight - y) {
+ h = _videoMode.overlayHeight - y;
+ }
+
+ if (w <= 0 || h <= 0)
+ return;
+
+ // Mark the modified region as dirty
+ 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 WINCESdlGraphicsManager::copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) {
+ assert (_transactionMode == kTransactionNone);
+ assert(src);
+
+ if (_screen == NULL)
+ return;
+
+ Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends
+
+ /* Clip the coordinates */
+ if (x < 0) {
+ w += x;
+ src -= x;
+ x = 0;
+ }
+
+ if (y < 0) {
+ h += y;
+ src -= y * pitch;
+ y = 0;
+ }
+
+ if (w > _videoMode.screenWidth - x) {
+ w = _videoMode.screenWidth - x;
+ }
+
+ if (h > _videoMode.screenHeight - y) {
+ h = _videoMode.screenHeight - y;
+ }
+
+ if (w <= 0 || h <= 0)
+ return;
+
+ addDirtyRect(x, y, w, h);
+
+ undrawMouse();
+
+ // Try to lock the screen surface
+ if (SDL_LockSurface(_screen) == -1)
+ error("SDL_LockSurface failed: %s", SDL_GetError());
+
+ byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
+
+ if (_videoMode.screenWidth == pitch && pitch == w) {
+ memcpy(dst, src, h*w);
+ } else {
+ do {
+ memcpy(dst, src, w);
+ src += pitch;
+ dst += _videoMode.screenWidth;
+ } while (--h);
+ }
+
+ // Unlock the screen surface
+ SDL_UnlockSurface(_screen);
+}
+
+void WINCESdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
+
+ undrawMouse();
+ if (w == 0 || h == 0)
+ return;
+
+ _mouseCurState.w = w;
+ _mouseCurState.h = h;
+
+ _mouseHotspotX = hotspot_x;
+ _mouseHotspotY = hotspot_y;
+
+ _mouseKeyColor = keycolor;
+
+ free(_mouseData);
+
+ _mouseData = (byte *) malloc(w * h);
+ memcpy(_mouseData, buf, w * h);
+
+ 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;
+ }
+}
+
+void WINCESdlGraphicsManager::adjustMouseEvent(const Common::Event &event) {
+ if (!event.synthetic) {
+ Common::Event newEvent(event);
+ newEvent.synthetic = true;
+ if (!_overlayVisible) {
+ /*
+ newEvent.mouse.x = newEvent.mouse.x * _scaleFactorXd / _scaleFactorXm;
+ newEvent.mouse.y = newEvent.mouse.y * _scaleFactorYd / _scaleFactorYm;
+ newEvent.mouse.x /= _videoMode.scaleFactor;
+ newEvent.mouse.y /= _videoMode.scaleFactor;
+ */
+ if (_videoMode.aspectRatioCorrection)
+ newEvent.mouse.y = aspect2Real(newEvent.mouse.y);
+ }
+ g_system->getEventManager()->pushEvent(newEvent);
+ }
+}
+
+void WINCESdlGraphicsManager::setMousePos(int x, int y) {
+ if (x != _mouseCurState.x || y != _mouseCurState.y) {
+ undrawMouse();
+ _mouseCurState.x = x;
+ _mouseCurState.y = y;
+ updateScreen();
+ }
+}
+
+Graphics::Surface *WINCESdlGraphicsManager::lockScreen() {
+ // Make sure mouse pointer is not painted over the playfield at the time of locking
+ undrawMouse();
+ return SdlGraphicsManager::lockScreen();
+}
+
+void WINCESdlGraphicsManager::showOverlay() {
+ assert (_transactionMode == kTransactionNone);
+
+ if (_overlayVisible)
+ return;
+
+ undrawMouse();
+ _overlayVisible = true;
+ update_scalers();
+ clearOverlay();
+}
+
+void WINCESdlGraphicsManager::hideOverlay() {
+ assert (_transactionMode == kTransactionNone);
+
+ if (!_overlayVisible)
+ return;
+
+ undrawMouse();
+ _overlayVisible = false;
+ clearOverlay();
+ _forceFull = true;
+}
+
+void WINCESdlGraphicsManager::blitCursor() {
+}
+
+void WINCESdlGraphicsManager::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;
+ int width;
+
+ // 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) {
+ width = w;
+ while (width > 0) {
+ *bak++ = *dst;
+ color = *src++;
+ if (color != _mouseKeyColor) // transparent color
+ *dst = 0xFFFF;
+ dst++;
+ width--;
+ }
+ src += _mouseCurState.w - w;
+ bak += _mouseBackupDim - w;
+ dst += surf->w - w;
+ h--;
+ }
+ } else { // restore bg
+ for (y = 0; y < h; ++y, bak += _mouseBackupDim, dst += surf->w)
+ memcpy(dst, bak, w << 1);
+ }
+
+ SDL_UnlockSurface(surf);
+}
+
+void WINCESdlGraphicsManager::warpMouse(int x, int y) {
+ if (_mouseCurState.x != x || _mouseCurState.y != y) {
+ SDL_WarpMouse(x * _scaleFactorXm / _scaleFactorXd, y * _scaleFactorYm / _scaleFactorYd);
+
+ // SDL_WarpMouse() generates a mouse movement event, so
+ // set_mouse_pos() would be called eventually. However, the
+ // cannon script in CoMI calls this function twice each time
+ // the cannon is reloaded. Unless we update the mouse position
+ // immediately the second call is ignored, causing the cannon
+ // to change its aim.
+
+ setMousePos(x, y);
+ }
+}
+
+void WINCESdlGraphicsManager::unlockScreen() {
+ SdlGraphicsManager::unlockScreen();
+}
+
+void WINCESdlGraphicsManager::internDrawMouse() {
+ if (!_mouseNeedsRedraw || !_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
+ int width;
+
+ // clip the mouse rect, and adjust the src pointer accordingly
+ if (x < 0) {
+ w += x;
+ src -= x;
+ x = 0;
+ }
+ if (y < 0) {
+ h += y;
+ src -= y * _mouseCurState.w;
+ y = 0;
+ }
+
+ if (w > _videoMode.screenWidth - x)
+ w = _videoMode.screenWidth - x;
+ if (h > _videoMode.screenHeight - y)
+ h = _videoMode.screenHeight - y;
+
+ // Quick check to see if anything has to be drawn at all
+ if (w <= 0 || h <= 0)
+ return;
+
+ // Draw the mouse cursor; backup the covered area in "bak"
+ if (SDL_LockSurface(_overlayVisible ? _overlayscreen : _screen) == -1)
+ error("SDL_LockSurface failed: %s", SDL_GetError());
+
+ // Mark as dirty
+ addDirtyRect(x, y, w, h);
+
+ if (!_overlayVisible) {
+ byte *bak = _mouseBackupOld; // Surface used to backup the area obscured by the mouse
+ byte *dst; // Surface we are drawing into
+
+ dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
+ while (h > 0) {
+ width = w;
+ while (width > 0) {
+ *bak++ = *dst;
+ color = *src++;
+ if (color != _mouseKeyColor) // transparent, don't draw
+ *dst = color;
+ dst++;
+ width--;
+ }
+ src += _mouseCurState.w - w;
+ bak += _mouseBackupDim - w;
+ dst += _videoMode.screenWidth - w;
+ h--;
+ }
+
+ } else {
+ uint16 *bak = (uint16 *)_mouseBackupOld; // Surface used to backup the area obscured by the mouse
+ byte *dst; // Surface we are drawing into
+
+ dst = (byte *)_overlayscreen->pixels + (y + 1) * _overlayscreen->pitch + (x + 1) * 2;
+ while (h > 0) {
+ width = w;
+ while (width > 0) {
+ *bak++ = *(uint16 *)dst;
+ color = *src++;
+ if (color != 0xFF) // 0xFF = transparent, don't draw
+ *(uint16 *)dst = SDL_MapRGB(_overlayscreen->format, _currentPalette[color].r, _currentPalette[color].g, _currentPalette[color].b);
+ dst += 2;
+ width--;
+ }
+ src += _mouseCurState.w - w;
+ bak += _mouseBackupDim - w;
+ dst += _overlayscreen->pitch - w * 2;
+ h--;
+ }
+ }
+
+ SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);
+
+ // Finally, set the flag to indicate the mouse has been drawn
+ _mouseNeedsRedraw = false;
+}
+
+void WINCESdlGraphicsManager::undrawMouse() {
+ assert (_transactionMode == kTransactionNone);
+
+ if (_mouseNeedsRedraw)
+ return;
+
+ int old_mouse_x = _mouseCurState.x - _mouseHotspotX;
+ int old_mouse_y = _mouseCurState.y - _mouseHotspotY;
+ int old_mouse_w = _mouseCurState.w;
+ int old_mouse_h = _mouseCurState.h;
+
+ // clip the mouse rect, and adjust the src pointer accordingly
+ if (old_mouse_x < 0) {
+ old_mouse_w += old_mouse_x;
+ old_mouse_x = 0;
+ }
+ if (old_mouse_y < 0) {
+ old_mouse_h += old_mouse_y;
+ old_mouse_y = 0;
+ }
+
+ if (old_mouse_w > _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;
+
+ // 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 y;
+ if (!_overlayVisible) {
+ byte *dst, *bak = _mouseBackupOld;
+
+ // No need to do clipping here, since drawMouse() did that already
+ dst = (byte *)_screen->pixels + old_mouse_y * _videoMode.screenWidth + old_mouse_x;
+ for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _videoMode.screenWidth)
+ memcpy(dst, bak, old_mouse_w);
+ } else {
+ byte *dst;
+ uint16 *bak = (uint16 *)_mouseBackupOld;
+
+ // No need to do clipping here, since drawMouse() did that already
+ dst = (byte *)_overlayscreen->pixels + (old_mouse_y + 1) * _overlayscreen->pitch + (old_mouse_x + 1) * 2;
+ for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _overlayscreen->pitch)
+ memcpy(dst, bak, old_mouse_w << 1);
+ }
+
+ addDirtyRect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h);
+
+ SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);
+
+ _mouseNeedsRedraw = true;
+}
+
+void WINCESdlGraphicsManager::drawMouse() {
+ if (!(_toolbarHandler.visible() && _mouseCurState.y >= _toolbarHandler.getOffset() && !_usesEmulatedMouse) && !_forceHideMouse)
+ internDrawMouse();
+}
+
+bool WINCESdlGraphicsManager::showMouse(bool visible) {
+ if (_mouseVisible == visible)
+ return visible;
+
+ if (visible == false)
+ undrawMouse();
+
+ bool last = _mouseVisible;
+ _mouseVisible = visible;
+ _mouseNeedsRedraw = true;
+
+ return last;
+}
+
+void WINCESdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool mouseRect) {
+
+ if (_forceFull || _paletteDirtyEnd)
+ return;
+
+ SdlGraphicsManager::addDirtyRect(x, y, w, h, false);
+}
+
+void WINCESdlGraphicsManager::swap_panel_visibility() {
+ //if (!_forcePanelInvisible && !_panelStateForced) {
+ if (_zoomDown || _zoomUp) return;
+
+ if (_panelVisible) {
+ if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD)
+ _panelVisible = !_panelVisible;
+ else
+ _toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
+ } else {
+ _toolbarHandler.setActive(NAME_MAIN_PANEL);
+ _panelVisible = !_panelVisible;
+ }
+ _toolbarHandler.setVisible(_panelVisible);
+ _toolbarHighDrawn = false;
+
+ if (_videoMode.screenHeight > 240)
+ addDirtyRect(0, 400, 640, 80);
+ else
+ addDirtyRect(0, 200, 320, 40);
+
+ if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible)
+ internUpdateScreen();
+ else {
+ update_scalers();
+ hotswapGFXMode();
+ }
+ //}
+}
+
+void WINCESdlGraphicsManager::swap_panel() {
+ _toolbarHighDrawn = false;
+ //if (!_panelStateForced) {
+ if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible)
+ _toolbarHandler.setActive(NAME_MAIN_PANEL);
+ else
+ _toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
+
+ if (_videoMode.screenHeight > 240)
+ addDirtyRect(0, 400, 640, 80);
+ else
+ addDirtyRect(0, 200, 320, 40);
+
+ _toolbarHandler.setVisible(true);
+ if (!_panelVisible) {
+ _panelVisible = true;
+ update_scalers();
+ hotswapGFXMode();
+ }
+ //}
+}
+
+void WINCESdlGraphicsManager::swap_smartphone_keyboard() {
+ _toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
+ _panelVisible = !_panelVisible;
+ _toolbarHandler.setVisible(_panelVisible);
+ if (_videoMode.screenHeight > 240)
+ addDirtyRect(0, 0, 640, 80);
+ else
+ addDirtyRect(0, 0, 320, 40);
+ internUpdateScreen();
+}
+
+void WINCESdlGraphicsManager::swap_zoom_up() {
+ if (_zoomUp) {
+ // restore visibility
+ _toolbarHandler.setVisible(_saveToolbarZoom);
+ // restore scaler
+ _scaleFactorYd = 2;
+ _scalerProc = DownscaleAllByHalf;
+ _zoomUp = false;
+ _zoomDown = false;
+ } else {
+ // only active if running on a PocketPC
+ if (_scalerProc != DownscaleAllByHalf && _scalerProc != DownscaleHorizByHalf)
+ return;
+ if (_scalerProc == DownscaleAllByHalf) {
+ _saveToolbarZoom = _toolbarHandler.visible();
+ _toolbarHandler.setVisible(false);
+ // set zoom scaler
+ _scaleFactorYd = 1;
+ _scalerProc = DownscaleHorizByHalf;
+ }
+
+ _zoomDown = false;
+ _zoomUp = true;
+ }
+ // redraw whole screen
+ addDirtyRect(0, 0, 640, 480);
+ internUpdateScreen();
+}
+
+void WINCESdlGraphicsManager::swap_zoom_down() {
+ if (_zoomDown) {
+ // restore visibility
+ _toolbarHandler.setVisible(_saveToolbarZoom);
+ // restore scaler
+ _scaleFactorYd = 2;
+ _scalerProc = DownscaleAllByHalf;
+ _zoomDown = false;
+ _zoomUp = false;
+ } else {
+ // only active if running on a PocketPC
+ if (_scalerProc != DownscaleAllByHalf && _scalerProc != DownscaleHorizByHalf)
+ return;
+ if (_scalerProc == DownscaleAllByHalf) {
+ _saveToolbarZoom = _toolbarHandler.visible();
+ _toolbarHandler.setVisible(false);
+ // set zoom scaler
+ _scaleFactorYd = 1;
+ _scalerProc = DownscaleHorizByHalf;
+ }
+
+ _zoomUp = false;
+ _zoomDown = true;
+ }
+ // redraw whole screen
+ addDirtyRect(0, 0, 640, 480);
+ internUpdateScreen();
+}
+
+void WINCESdlGraphicsManager::swap_mouse_visibility() {
+ _forceHideMouse = !_forceHideMouse;
+ if (_forceHideMouse)
+ undrawMouse();
+}
+
+// Smartphone actions
+void WINCESdlGraphicsManager::initZones() {
+ int i;
+
+ _currentZone = 0;
+ for (i = 0; i < TOTAL_ZONES; i++) {
+ _mouseXZone[i] = (_zones[i].x + (_zones[i].width / 2)) * _scaleFactorXm / _scaleFactorXd;
+ _mouseYZone[i] = (_zones[i].y + (_zones[i].height / 2)) * _scaleFactorYm / _scaleFactorYd;
+ }
+}
+
+void WINCESdlGraphicsManager::smartphone_rotate_display() {
+ _orientationLandscape = _newOrientation = _orientationLandscape == 1 ? 2 : 1;
+ ConfMan.setInt("landscape", _orientationLandscape);
+ ConfMan.flushToDisk();
+ hotswapGFXMode();
+}
+
+void WINCESdlGraphicsManager::create_toolbar() {
+ CEGUI::PanelKeyboard *keyboard;
+
+ // Add the keyboard
+ keyboard = new CEGUI::PanelKeyboard(PANEL_KEYBOARD);
+ _toolbarHandler.add(NAME_PANEL_KEYBOARD, *keyboard);
+ _toolbarHandler.setVisible(false);
+}
+
+WINCESdlGraphicsManager::zoneDesc WINCESdlGraphicsManager::_zones[TOTAL_ZONES] = {
+ { 0, 0, 320, 145 },
+ { 0, 145, 150, 55 },
+ { 150, 145, 170, 55 }
+};
+
+#endif /* _WIN32_WCE */
+
diff --git a/backends/graphics/wincesdl/wincesdl-graphics.h b/backends/graphics/wincesdl/wincesdl-graphics.h
new file mode 100644
index 0000000000..76b623d5d3
--- /dev/null
+++ b/backends/graphics/wincesdl/wincesdl-graphics.h
@@ -0,0 +1,206 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_WINCE_SDL_H
+#define BACKENDS_GRAPHICS_WINCE_SDL_H
+
+#include "backends/graphics/sdl/sdl-graphics.h"
+#include "backends/platform/wince/CEgui/CEGUI.h"
+
+// Internal GUI names
+#define NAME_MAIN_PANEL "MainPanel"
+#define NAME_PANEL_KEYBOARD "Keyboard"
+#define NAME_ITEM_OPTIONS "Options"
+#define NAME_ITEM_SKIP "Skip"
+#define NAME_ITEM_SOUND "Sound"
+#define NAME_ITEM_ORIENTATION "Orientation"
+#define NAME_ITEM_BINDKEYS "Bindkeys"
+
+#define TOTAL_ZONES 3
+
+extern bool _hasSmartphoneResolution;
+
+class WINCESdlGraphicsManager : public SdlGraphicsManager {
+public:
+ WINCESdlGraphicsManager(SdlEventSource *sdlEventSource);
+
+ const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
+ void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
+
+ bool hasFeature(OSystem::Feature f);
+ void setFeatureState(OSystem::Feature f, bool enable);
+ bool getFeatureState(OSystem::Feature f);
+
+ int getDefaultGraphicsMode() const;
+ bool setGraphicsMode(int mode);
+ bool loadGFXMode();
+ void unloadGFXMode();
+ bool hotswapGFXMode();
+
+ // Overloaded from SDL backend (toolbar handling)
+ void drawMouse();
+ // Overloaded from SDL backend (new scaler handling)
+ void addDirtyRect(int x, int y, int w, int h, bool mouseRect = false);
+ // Overloaded from SDL backend (new scaler handling)
+ void warpMouse(int x, int y);
+
+ // Update the dirty areas of the screen
+ void internUpdateScreen();
+ bool saveScreenshot(const char *filename);
+
+ // Overloaded from SDL_Common (FIXME)
+ void internDrawMouse();
+ void undrawMouse();
+ bool showMouse(bool visible);
+ void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // overloaded by CE backend
+ void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
+ void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); // overloaded by CE backend (FIXME)
+ Graphics::Surface *lockScreen();
+ void unlockScreen();
+ void blitCursor();
+ void showOverlay();
+ void hideOverlay();
+ void setMousePos(int x, int y);
+
+ // GUI and action stuff
+ void swap_panel_visibility();
+ void swap_panel();
+ void swap_smartphone_keyboard();
+ void swap_zoom_up();
+ void swap_zoom_down();
+ void swap_mouse_visibility();
+
+
+//#ifdef WIN32_PLATFORM_WFSP
+ void move_cursor_up();
+ void move_cursor_down();
+ void move_cursor_left();
+ void move_cursor_right();
+
+ void retrieve_mouse_location(int &x, int &y);
+ void switch_zone();
+
+ void add_right_click(bool pushed);
+ void add_left_click(bool pushed);
+
+ void initZones();
+ void smartphone_rotate_display();
+//#endif
+
+ bool _panelInitialized; // only initialize the toolbar once
+ bool _noDoubleTapRMB; // disable double tap -> rmb click
+
+ CEGUI::ToolbarHandler _toolbarHandler;
+
+ bool _toolbarHighDrawn; // cache toolbar 640x80
+ int _newOrientation; // new orientation
+ int _orientationLandscape; // current orientation
+
+ int _scaleFactorXm; // scaler X *
+ int _scaleFactorXd; // scaler X /
+ int _scaleFactorYm; // scaler Y *
+ int _scaleFactorYd; // scaler Y /
+
+ bool _hasfocus; // scummvm has the top window
+
+ bool hasPocketPCResolution();
+ bool hasDesktopResolution();
+ bool hasSquareQVGAResolution();
+ bool hasWideResolution() const;
+
+ MousePos _mouseCurState;
+
+ bool _zoomUp; // zooming up mode
+ bool _zoomDown; // zooming down mode
+
+ bool _usesEmulatedMouse; // emulated mousemove ever been used in this session
+
+ int _mouseXZone[TOTAL_ZONES];
+ int _mouseYZone[TOTAL_ZONES];
+ int _currentZone;
+
+ // Smartphone specific variables
+ int _lastKeyPressed; // last key pressed
+ int _keyRepeat; // number of time the last key was repeated
+ int _keyRepeatTime; // elapsed time since the key was pressed
+ int _keyRepeatTrigger; // minimum time to consider the key was repeated
+
+ struct zoneDesc {
+ int x;
+ int y;
+ int width;
+ int height;
+ };
+
+ static zoneDesc _zones[TOTAL_ZONES];
+
+protected:
+ virtual void adjustMouseEvent(const Common::Event &event);
+
+private:
+ bool update_scalers();
+ void update_game_settings();
+ void drawToolbarMouse(SDL_Surface *surf, bool draw);
+
+ void create_toolbar();
+ bool _panelVisible; // panel visibility
+ bool _panelStateForced; // panel visibility forced by external call
+ String _saveActiveToolbar; // save active toolbar when forced
+
+ bool _canBeAspectScaled; // game screen size allows for aspect scaling
+
+ SDL_Rect _dirtyRectOut[NUM_DIRTY_RECT];
+ bool _scalersChanged;
+
+ bool isOzone();
+
+ bool _saveToolbarState; // save visibility when forced
+ bool _saveToolbarZoom; // save visibility when zooming
+
+ SDL_Surface *_toolbarLow; // toolbar 320x40
+ SDL_Surface *_toolbarHigh; // toolbar 640x80
+
+ // Mouse
+ int _mouseHotspotX, _mouseHotspotY;
+ byte *_mouseBackupOld;
+ uint16 *_mouseBackupToolbar;
+ uint16 _mouseBackupDim;
+
+ bool _forceHideMouse; // force invisible mouse cursor
+
+ // Smartphone specific variables
+ void loadDeviceConfigurationElement(Common::String element, int &value, int defaultValue);
+ int _repeatX; // repeat trigger for left and right cursor moves
+ int _repeatY; // repeat trigger for up and down cursor moves
+ int _stepX1; // offset for left and right cursor moves (slowest)
+ int _stepX2; // offset for left and right cursor moves (faster)
+ int _stepX3; // offset for left and right cursor moves (fastest)
+ int _stepY1; // offset for up and down cursor moves (slowest)
+ int _stepY2; // offset for up and down cursor moves (faster)
+ int _stepY3; // offset for up and down cursor moves (fastest)
+};
+
+#endif /* BACKENDS_GRAPHICS_WINCE_SDL_H */
+
diff --git a/backends/mixer/wincesdl/wincesdl-mixer.cpp b/backends/mixer/wincesdl/wincesdl-mixer.cpp
new file mode 100644
index 0000000000..fb8a7d10c7
--- /dev/null
+++ b/backends/mixer/wincesdl/wincesdl-mixer.cpp
@@ -0,0 +1,183 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifdef _WIN32_WCE
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "common/config-manager.h"
+#include "backends/platform/wince/wince-sdl.h"
+#include "backends/mixer/wincesdl/wincesdl-mixer.h"
+#include "common/system.h"
+
+#ifdef USE_VORBIS
+#ifndef USE_TREMOR
+#include <vorbis/vorbisfile.h>
+#else
+#include <tremor/ivorbisfile.h>
+#endif
+#endif
+
+#define SAMPLES_PER_SEC_OLD 11025
+#define SAMPLES_PER_SEC_NEW 22050
+
+WINCESdlMixerManager::WINCESdlMixerManager() {
+
+}
+
+WINCESdlMixerManager::~WINCESdlMixerManager() {
+
+}
+
+void WINCESdlMixerManager::init() {
+ SDL_AudioSpec desired;
+ int thread_priority;
+
+ uint32 sampleRate = compute_sample_rate();
+ if (sampleRate == 0)
+ warning("OSystem_WINCE3::setupMixer called with sample rate 0 - audio will not work");
+ else if (_mixer && _mixer->getOutputRate() == sampleRate) {
+ debug(1, "Skipping sound mixer re-init: samplerate is good");
+ return;
+ }
+
+ memset(&desired, 0, sizeof(desired));
+ desired.freq = sampleRate;
+ desired.format = AUDIO_S16SYS;
+ desired.channels = 2;
+ desired.samples = 128;
+ desired.callback = private_sound_proc;
+ desired.userdata = this;
+
+ // Create the mixer instance
+ if (_mixer == 0)
+ _mixer = new Audio::MixerImpl(g_system, sampleRate);
+
+ // Add sound thread priority
+ if (!ConfMan.hasKey("sound_thread_priority"))
+ thread_priority = THREAD_PRIORITY_NORMAL;
+ else
+ thread_priority = ConfMan.getInt("sound_thread_priority");
+
+ desired.thread_priority = thread_priority;
+
+ SDL_CloseAudio();
+ if (SDL_OpenAudio(&desired, NULL) != 0) {
+ warning("Could not open audio device: %s", SDL_GetError());
+ _mixer->setReady(false);
+
+ } else {
+ debug(1, "Sound opened OK, mixing at %d Hz", sampleRate);
+
+ // Re-create mixer to match the output rate
+ 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);
+ delete _mixer;
+ _mixer = new Audio::MixerImpl(g_system, sampleRate);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, vol1);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol2);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, vol3);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, vol4);
+ _mixer->setReady(true);
+ SDL_PauseAudio(0);
+ }
+}
+
+void WINCESdlMixerManager::private_sound_proc(void *param, byte *buf, int len) {
+ WINCESdlMixerManager *this_ = (WINCESdlMixerManager *)param;
+ assert(this_);
+
+ if (this_->_mixer)
+ this_->_mixer->mixCallback(buf, len);
+ if (!OSystem_WINCE3::_soundMaster)
+ memset(buf, 0, len);
+}
+
+uint32 WINCESdlMixerManager::compute_sample_rate() {
+ uint32 sampleRate;
+
+ // Force at least medium quality FM synthesis for FOTAQ
+ Common::String gameid(ConfMan.get("gameid"));
+ if (gameid == "queen") {
+ if (!((ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) ||
+ (ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")))) {
+ ConfMan.setBool("FM_medium_quality", true);
+ ConfMan.flushToDisk();
+ }
+ }
+ // See if the output frequency is forced by the game
+ if (gameid == "ft" || gameid == "dig" || gameid == "comi" || gameid == "queen" || gameid == "sword" || gameid == "agi")
+ sampleRate = SAMPLES_PER_SEC_NEW;
+ else {
+ if (ConfMan.hasKey("high_sample_rate") && ConfMan.getBool("high_sample_rate"))
+ sampleRate = SAMPLES_PER_SEC_NEW;
+ else
+ sampleRate = SAMPLES_PER_SEC_OLD;
+ }
+
+#ifdef USE_VORBIS
+ // Modify the sample rate on the fly if OGG is involved
+ if (sampleRate == SAMPLES_PER_SEC_OLD)
+ if (checkOggHighSampleRate())
+ sampleRate = SAMPLES_PER_SEC_NEW;
+#endif
+
+ return sampleRate;
+}
+
+#ifdef USE_VORBIS
+bool WINCESdlMixerManager::checkOggHighSampleRate() {
+ char trackFile[255];
+ FILE *testFile;
+ OggVorbis_File *test_ov_file = new OggVorbis_File;
+
+ // FIXME: The following sprintf assumes that "path" is always
+ // terminated by a path separator. This is *not* true in general.
+ // This code really should check for the path separator, or even
+ // better, use the FSNode API.
+ sprintf(trackFile, "%sTrack1.ogg", ConfMan.get("path").c_str());
+ // Check if we have an OGG audio track
+ testFile = fopen(trackFile, "rb");
+ if (testFile) {
+ if (!ov_open(testFile, test_ov_file, NULL, 0)) {
+ bool highSampleRate = (ov_info(test_ov_file, -1)->rate == 22050);
+ ov_clear(test_ov_file);
+ delete test_ov_file;
+ return highSampleRate;
+ }
+ }
+
+ // Do not test for OGG samples - too big and too slow anyway :)
+
+ delete test_ov_file;
+ return false;
+}
+#endif
+
+#endif
+
diff --git a/backends/mixer/wincesdl/wincesdl-mixer.h b/backends/mixer/wincesdl/wincesdl-mixer.h
new file mode 100644
index 0000000000..6c2f1efeee
--- /dev/null
+++ b/backends/mixer/wincesdl/wincesdl-mixer.h
@@ -0,0 +1,53 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef BACKENDS_MIXER_WINCE_SDL_H
+#define BACKENDS_MIXER_WINCE_SDL_H
+
+#include "backends/mixer/sdl/sdl-mixer.h"
+
+/**
+ * SDL mixer manager for WinCE
+ */
+class WINCESdlMixerManager : public SdlMixerManager {
+public:
+ WINCESdlMixerManager();
+ virtual ~WINCESdlMixerManager();
+
+ virtual void init();
+
+private:
+
+#ifdef USE_VORBIS
+ bool checkOggHighSampleRate();
+#endif
+
+ static void private_sound_proc(void *param, byte *buf, int len);
+ uint32 compute_sample_rate();
+
+};
+
+#endif
+
diff --git a/backends/module.mk b/backends/module.mk
index 5a8a63c2a2..484f804ee0 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -12,6 +12,7 @@ MODULE_OBJS := \
events/samsungtvsdl/samsungtvsdl-events.o \
events/sdl/sdl-events.o \
events/symbiansdl/symbiansdl-events.o \
+ events/wincesdl/wincesdl-events.o \
fs/abstract-fs.o \
fs/stdiostream.o \
fs/amigaos4/amigaos4-fs-factory.o \
@@ -27,6 +28,7 @@ MODULE_OBJS := \
graphics/openglsdl/openglsdl-graphics.o \
graphics/sdl/sdl-graphics.o \
graphics/symbiansdl/symbiansdl-graphics.o \
+ graphics/wincesdl/wincesdl-graphics.o \
keymapper/action.o \
keymapper/keymap.o \
keymapper/keymapper.o \
@@ -44,6 +46,7 @@ MODULE_OBJS := \
mixer/doublebuffersdl/doublebuffersdl-mixer.o \
mixer/sdl/sdl-mixer.o \
mixer/symbiansdl/symbiansdl-mixer.o \
+ mixer/wincesdl/wincesdl-mixer.o \
mutex/sdl/sdl-mutex.o \
plugins/elf/elf-loader.o \
plugins/elf/mips-loader.o \
diff --git a/backends/platform/wince/CEActionsPocket.cpp b/backends/platform/wince/CEActionsPocket.cpp
index 99d0be2bdc..b3ac10429b 100644
--- a/backends/platform/wince/CEActionsPocket.cpp
+++ b/backends/platform/wince/CEActionsPocket.cpp
@@ -239,10 +239,12 @@ bool CEActionsPocket::perform(GUI::ActionType action, bool pushed) {
if (!pushed) {
switch (action) {
case POCKET_ACTION_RIGHTCLICK:
- _CESystem->add_right_click(false);
+ //_CESystem->add_right_click(false);
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_right_click(false);
return true;
case POCKET_ACTION_LEFTCLICK:
- _CESystem->add_left_click(false);
+ //_CESystem->add_left_click(false);
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_left_click(false);
return true;
case POCKET_ACTION_PAUSE:
case POCKET_ACTION_SAVE:
@@ -272,43 +274,55 @@ bool CEActionsPocket::perform(GUI::ActionType action, bool pushed) {
EventsBuffer::simulateKey(&_key_action[action], true);
return true;
case POCKET_ACTION_KEYBOARD:
- _CESystem->swap_panel();
+ //_CESystem->swap_panel();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_panel();
return true;
case POCKET_ACTION_HIDE:
- _CESystem->swap_panel_visibility();
+ //_CESystem->swap_panel_visibility();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_panel_visibility();
return true;
case POCKET_ACTION_SOUND:
_CESystem->swap_sound_master();
return true;
case POCKET_ACTION_RIGHTCLICK:
- _CESystem->add_right_click(true);
+ //_CESystem->add_right_click(true);
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_right_click(true);
return true;
case POCKET_ACTION_CURSOR:
- _CESystem->swap_mouse_visibility();
+ //_CESystem->swap_mouse_visibility();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_mouse_visibility();
return true;
case POCKET_ACTION_FREELOOK:
- _CESystem->swap_freeLook();
+ //_CESystem->swap_freeLook();
+ ((WINCESdlEventSource *)((OSystem_SDL *)g_system)->getEventManager())->swap_freeLook();
return true;
case POCKET_ACTION_ZOOM_UP:
- _CESystem->swap_zoom_up();
+ //_CESystem->swap_zoom_up();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_zoom_up();
return true;
case POCKET_ACTION_ZOOM_DOWN:
- _CESystem->swap_zoom_down();
+ //_CESystem->swap_zoom_down();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_zoom_down();
return true;
case POCKET_ACTION_LEFTCLICK:
- _CESystem->add_left_click(true);
+ //_CESystem->add_left_click(true);
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_left_click(true);
return true;
case POCKET_ACTION_UP:
- _CESystem->move_cursor_up();
+ //_CESystem->move_cursor_up();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_up();
return true;
case POCKET_ACTION_DOWN:
- _CESystem->move_cursor_down();
+ //_CESystem->move_cursor_down();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_down();
return true;
case POCKET_ACTION_LEFT:
- _CESystem->move_cursor_left();
+ //_CESystem->move_cursor_left();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_left();
return true;
case POCKET_ACTION_RIGHT:
- _CESystem->move_cursor_right();
+ //_CESystem->move_cursor_right();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_right();
return true;
case POCKET_ACTION_QUIT:
if (!quitdialog) {
diff --git a/backends/platform/wince/CEActionsSmartphone.cpp b/backends/platform/wince/CEActionsSmartphone.cpp
index 5c7feb4950..a8684293f4 100644
--- a/backends/platform/wince/CEActionsSmartphone.cpp
+++ b/backends/platform/wince/CEActionsSmartphone.cpp
@@ -205,10 +205,12 @@ bool CEActionsSmartphone::perform(GUI::ActionType action, bool pushed) {
if (!pushed) {
switch (action) {
case SMARTPHONE_ACTION_RIGHTCLICK:
- _CESystem->add_right_click(false);
+ //_CESystem->add_right_click(false);
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_right_click(false);
return true;
case SMARTPHONE_ACTION_LEFTCLICK:
- _CESystem->add_left_click(false);
+ //_CESystem->add_left_click(false);
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_left_click(false);
return true;
case SMARTPHONE_ACTION_SAVE:
case SMARTPHONE_ACTION_SKIP:
@@ -235,25 +237,32 @@ bool CEActionsSmartphone::perform(GUI::ActionType action, bool pushed) {
EventsBuffer::simulateKey(&_key_action[action], true);
return true;
case SMARTPHONE_ACTION_RIGHTCLICK:
- _CESystem->add_right_click(true);
+ //_CESystem->add_right_click(true);
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_right_click(true);
return true;
case SMARTPHONE_ACTION_LEFTCLICK:
- _CESystem->add_left_click(true);
+ //_CESystem->add_left_click(true);
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_left_click(true);
return true;
case SMARTPHONE_ACTION_UP:
- _CESystem->move_cursor_up();
+ //_CESystem->move_cursor_up();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_up();
return true;
case SMARTPHONE_ACTION_DOWN:
- _CESystem->move_cursor_down();
+ //_CESystem->move_cursor_down();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_down();
return true;
case SMARTPHONE_ACTION_LEFT:
- _CESystem->move_cursor_left();
+ //_CESystem->move_cursor_left();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_left();
return true;
case SMARTPHONE_ACTION_RIGHT:
- _CESystem->move_cursor_right();
+ //_CESystem->move_cursor_right();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_right();
return true;
case SMARTPHONE_ACTION_ZONE:
- _CESystem->switch_zone();
+ //_CESystem->switch_zone();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->switch_zone();
return true;
case SMARTPHONE_ACTION_BINDKEYS:
if (!keydialogrunning) {
@@ -265,10 +274,12 @@ bool CEActionsSmartphone::perform(GUI::ActionType action, bool pushed) {
}
return true;
case SMARTPHONE_ACTION_KEYBOARD:
- _CESystem->swap_smartphone_keyboard();
+ //_CESystem->swap_smartphone_keyboard();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_smartphone_keyboard();
return true;
case SMARTPHONE_ACTION_ROTATE:
- _CESystem->smartphone_rotate_display();
+ //_CESystem->smartphone_rotate_display();
+ ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->smartphone_rotate_display();
return true;
case SMARTPHONE_ACTION_QUIT:
if (!quitdialog) {
diff --git a/backends/platform/wince/CEDevice.cpp b/backends/platform/wince/CEDevice.cpp
index d94ce6cde7..3686944cce 100644
--- a/backends/platform/wince/CEDevice.cpp
+++ b/backends/platform/wince/CEDevice.cpp
@@ -44,7 +44,7 @@ extern "C" void WINAPI SystemIdleTimerReset(void);
#define TIMER_TRIGGER 9000
-DWORD CEDevice::reg_access(TCHAR *key, TCHAR *val, DWORD data) {
+DWORD CEDevice::reg_access(const TCHAR *key, const TCHAR *val, DWORD data) {
HKEY regkey;
DWORD tmpval, cbdata;
@@ -70,7 +70,7 @@ DWORD CEDevice::reg_access(TCHAR *key, TCHAR *val, DWORD data) {
void CEDevice::backlight_xchg() {
HANDLE h;
- REG_bat = reg_access(TEXT("ControlPanel\\BackLight"), TEXT("BatteryTimeout"), REG_bat);
+ REG_bat = reg_access(TEXT("ControlPanel\\BackLight"), (const TCHAR*)TEXT("BatteryTimeout"), REG_bat);
REG_ac = reg_access(TEXT("ControlPanel\\BackLight"), TEXT("ACTimeout"), REG_ac);
REG_disp = reg_access(TEXT("ControlPanel\\Power"), TEXT("Display"), REG_disp);
@@ -127,6 +127,10 @@ bool CEDevice::hasSquareQVGAResolution() {
return (OSystem_WINCE3::getScreenWidth() == 240 && OSystem_WINCE3::getScreenHeight() == 240);
}
+bool CEDevice::hasWideResolution() {
+ return (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640);
+}
+
bool CEDevice::hasPocketPCResolution() {
if (OSystem_WINCE3::isOzone() && hasWideResolution())
return true;
@@ -139,10 +143,6 @@ bool CEDevice::hasDesktopResolution() {
return (OSystem_WINCE3::getScreenWidth() > 320);
}
-bool CEDevice::hasWideResolution() {
- return (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640);
-}
-
bool CEDevice::hasSmartphoneResolution() {
return (OSystem_WINCE3::getScreenWidth() < 240);
}
diff --git a/backends/platform/wince/CEDevice.h b/backends/platform/wince/CEDevice.h
index b2b20d05ce..24dffca0b3 100644
--- a/backends/platform/wince/CEDevice.h
+++ b/backends/platform/wince/CEDevice.h
@@ -43,7 +43,7 @@ public:
static bool isSmartphone();
private:
- static DWORD reg_access(TCHAR *key, TCHAR *val, DWORD data);
+ static DWORD reg_access(const TCHAR *key, const TCHAR *val, DWORD data);
static void backlight_xchg();
};
diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp
index ade90b2dfb..45aa63529f 100644
--- a/backends/platform/wince/wince-sdl.cpp
+++ b/backends/platform/wince/wince-sdl.cpp
@@ -23,6 +23,7 @@
*
*/
+
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
@@ -43,13 +44,12 @@
#include "audio/mixer_intern.h"
#include "audio/fmopl.h"
-#include "backends/timer/default/default-timer.h"
+#include "backends/timer/sdl/sdl-timer.h"
#include "gui/Actions.h"
#include "gui/KeysDialog.h"
#include "gui/message.h"
-#include "backends/platform/wince/resource.h"
#include "backends/platform/wince/CEActionsPocket.h"
#include "backends/platform/wince/CEActionsSmartphone.h"
#include "backends/platform/wince/CEgui/ItemAction.h"
@@ -60,13 +60,9 @@
#include "backends/platform/wince/CEException.h"
#include "backends/platform/wince/CEScaler.h"
-#ifdef USE_VORBIS
-#ifndef USE_TREMOR
-#include <vorbis/vorbisfile.h>
-#else
-#include <tremor/ivorbisfile.h>
-#endif
-#endif
+#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 "backends/plugins/win32/win32-provider.h"
@@ -76,23 +72,10 @@
extern "C" _CRTIMP FILE* __cdecl _wfreopen (const wchar_t*, const wchar_t*, FILE*);
#endif
-#define SAMPLES_PER_SEC_OLD 11025
-#define SAMPLES_PER_SEC_NEW 22050
-
using namespace CEGUI;
// ********************************************************************************************
-// Internal GUI names
-
-#define NAME_MAIN_PANEL "MainPanel"
-#define NAME_PANEL_KEYBOARD "Keyboard"
-#define NAME_ITEM_OPTIONS "Options"
-#define NAME_ITEM_SKIP "Skip"
-#define NAME_ITEM_SOUND "Sound"
-#define NAME_ITEM_ORIENTATION "Orientation"
-#define NAME_ITEM_BINDKEYS "Bindkeys"
-
// stdin/err redirection
#define STDOUT_FNAME "\\scummvm_stdout.txt"
#define STDERR_FNAME "\\scummvm_stderr.txt"
@@ -106,34 +89,6 @@ bool OSystem_WINCE3::_soundMaster = true;
bool _isSmartphone = false;
bool _hasSmartphoneResolution = false;
-// Graphics mode consts
-
-// Low end devices 240x320
-
-static const OSystem::GraphicsMode s_supportedGraphicsModesLow[] = {
- {"1x", _s("Normal (no scaling)"), GFX_NORMAL},
- {0, 0, 0}
-};
-
-// High end device 480x640
-
-static const OSystem::GraphicsMode s_supportedGraphicsModesHigh[] = {
- {"1x", _s("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}
-};
-
#define DEFAULT_CONFIG_FILE "scummvm.ini"
// ********************************************************************************************
@@ -380,7 +335,6 @@ int dynamic_modules_main(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR szCmdLine, int
// ********************************************************************************************
-
// ********************************************************************************************
void pumpMessages() {
@@ -407,28 +361,33 @@ static Uint32 timer_handler_wrapper(Uint32 interval) {
}
void OSystem_WINCE3::initBackend() {
- // Instantiate our own sound mixer
- // mixer init is rerun when a game engine is selected.
- setupMixer();
+
+ 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);
// 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
+ //_timerID = NULL; // OSystem_SDL will call removetimer with this, it's ok
SDL_SetTimer(10, &timer_handler_wrapper);
// Chain init
OSystem_SDL::initBackend();
- // 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);
@@ -437,17 +396,16 @@ void OSystem_WINCE3::initBackend() {
GUI_Actions::Instance()->saveMapping(); // write defaults
}
- loadDeviceConfiguration();
+ // Call parent implementation of this method
+ //OSystem_SDL::initBackend();
+
+ _inited = true;
}
int OSystem_WINCE3::getScreenWidth() {
return _platformScreenWidth;
}
-int OSystem_WINCE3::getScreenHeight() {
- return _platformScreenHeight;
-}
-
void OSystem_WINCE3::initScreenInfos() {
// sdl port ensures that we use correctly full screen
_isOzone = 0;
@@ -457,6 +415,10 @@ void OSystem_WINCE3::initScreenInfos() {
_platformScreenHeight = r[0]->h;
}
+int OSystem_WINCE3::getScreenHeight() {
+ return _platformScreenHeight;
+}
+
bool OSystem_WINCE3::isOzone() {
return _isOzone;
}
@@ -473,496 +435,38 @@ Common::String OSystem_WINCE3::getDefaultConfigFileName() {
OSystem_WINCE3::OSystem_WINCE3() : OSystem_SDL(),
- _orientationLandscape(0), _newOrientation(0), _panelInitialized(false), _canBeAspectScaled(false),
- _panelVisible(true), _panelStateForced(false), _forceHideMouse(false), _unfilteredkeys(false),
- _freeLook(false), _forcePanelInvisible(false), _toolbarHighDrawn(false), _zoomUp(false), _zoomDown(false),
- _scalersChanged(false), _lastKeyPressed(0), _tapTime(0), _closeClick(false), _noDoubleTapRMB(false),
- _saveToolbarState(false), _saveActiveToolbar(NAME_MAIN_PANEL), _rbutton(false), _hasfocus(true),
- _usesEmulatedMouse(false), _mouseBackupOld(NULL), _mouseBackupToolbar(NULL), _mouseBackupDim(0)
+ _forcePanelInvisible(false)
{
- memset(&_mouseCurState, 0, sizeof(_mouseCurState));
- if (_isSmartphone) {
- _mouseCurState.x = 20;
- _mouseCurState.y = 20;
- }
-
+ // Initialze File System Factory
+ _fsFactory = new WindowsFilesystemFactory();
_mixer = 0;
- _screen = NULL;
}
-void OSystem_WINCE3::swap_panel_visibility() {
- //if (!_forcePanelInvisible && !_panelStateForced) {
- if (_zoomDown || _zoomUp) return;
-
- if (_panelVisible) {
- if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD)
- _panelVisible = !_panelVisible;
- else
- _toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
- } else {
- _toolbarHandler.setActive(NAME_MAIN_PANEL);
- _panelVisible = !_panelVisible;
- }
- _toolbarHandler.setVisible(_panelVisible);
- _toolbarHighDrawn = false;
-
- if (_videoMode.screenHeight > 240)
- addDirtyRect(0, 400, 640, 80);
- else
- addDirtyRect(0, 200, 320, 40);
-
- if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible)
- internUpdateScreen();
- else {
- update_scalers();
- hotswapGFXMode();
- }
- //}
+OSystem_WINCE3::~OSystem_WINCE3() {
+ delete _fsFactory;
+ delete _mixer;
}
-void OSystem_WINCE3::swap_panel() {
- _toolbarHighDrawn = false;
- //if (!_panelStateForced) {
- if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible)
- _toolbarHandler.setActive(NAME_MAIN_PANEL);
- else
- _toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
-
- if (_videoMode.screenHeight > 240)
- addDirtyRect(0, 400, 640, 80);
- else
- addDirtyRect(0, 200, 320, 40);
-
- _toolbarHandler.setVisible(true);
- if (!_panelVisible) {
- _panelVisible = true;
- update_scalers();
- hotswapGFXMode();
- }
- //}
-}
-
-void OSystem_WINCE3::swap_smartphone_keyboard() {
- _toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
- _panelVisible = !_panelVisible;
- _toolbarHandler.setVisible(_panelVisible);
- if (_videoMode.screenHeight > 240)
- addDirtyRect(0, 0, 640, 80);
- else
- addDirtyRect(0, 0, 320, 40);
- internUpdateScreen();
-}
-
-void OSystem_WINCE3::smartphone_rotate_display() {
- _orientationLandscape = _newOrientation = _orientationLandscape == 1 ? 2 : 1;
- ConfMan.setInt("landscape", _orientationLandscape);
- ConfMan.flushToDisk();
- hotswapGFXMode();
+FilesystemFactory *OSystem_WINCE3::getFilesystemFactory() {
+ return _fsFactory;
}
void OSystem_WINCE3::swap_sound_master() {
_soundMaster = !_soundMaster;
- if (_toolbarHandler.activeName() == NAME_MAIN_PANEL)
- _toolbarHandler.forceRedraw(); // redraw sound icon
-}
-
-void OSystem_WINCE3::add_right_click(bool pushed) {
- int x, y;
- retrieve_mouse_location(x, y);
- EventsBuffer::simulateMouseRightClick(x, y, pushed);
-}
-void OSystem_WINCE3::swap_mouse_visibility() {
- _forceHideMouse = !_forceHideMouse;
- if (_forceHideMouse)
- undrawMouse();
-}
-
-void OSystem_WINCE3::swap_freeLook() {
- _freeLook = !_freeLook;
-}
-
-void OSystem_WINCE3::swap_zoom_up() {
- if (_zoomUp) {
- // restore visibility
- _toolbarHandler.setVisible(_saveToolbarZoom);
- // restore scaler
- _scaleFactorYd = 2;
- _scalerProc = DownscaleAllByHalf;
- _zoomUp = false;
- _zoomDown = false;
- } else {
- // only active if running on a PocketPC
- if (_scalerProc != DownscaleAllByHalf && _scalerProc != DownscaleHorizByHalf)
- return;
- if (_scalerProc == DownscaleAllByHalf) {
- _saveToolbarZoom = _toolbarHandler.visible();
- _toolbarHandler.setVisible(false);
- // set zoom scaler
- _scaleFactorYd = 1;
- _scalerProc = DownscaleHorizByHalf;
- }
+ //WINCESdlGraphicsManager _graphicsManager
- _zoomDown = false;
- _zoomUp = true;
- }
- // redraw whole screen
- addDirtyRect(0, 0, 640, 480);
- internUpdateScreen();
+ if (((WINCESdlGraphicsManager*)_graphicsManager)->_toolbarHandler.activeName() == NAME_MAIN_PANEL)
+ ((WINCESdlGraphicsManager*)_graphicsManager)->_toolbarHandler.forceRedraw(); // redraw sound icon
}
-void OSystem_WINCE3::swap_zoom_down() {
- if (_zoomDown) {
- // restore visibility
- _toolbarHandler.setVisible(_saveToolbarZoom);
- // restore scaler
- _scaleFactorYd = 2;
- _scalerProc = DownscaleAllByHalf;
- _zoomDown = false;
- _zoomUp = false;
- } else {
- // only active if running on a PocketPC
- if (_scalerProc != DownscaleAllByHalf && _scalerProc != DownscaleHorizByHalf)
- return;
- if (_scalerProc == DownscaleAllByHalf) {
- _saveToolbarZoom = _toolbarHandler.visible();
- _toolbarHandler.setVisible(false);
- // set zoom scaler
- _scaleFactorYd = 1;
- _scalerProc = DownscaleHorizByHalf;
- }
-
- _zoomUp = false;
- _zoomDown = true;
- }
- // redraw whole screen
- addDirtyRect(0, 0, 640, 480);
- internUpdateScreen();
-}
-
-// Smartphone actions
-void OSystem_WINCE3::initZones() {
- int i;
-
- _currentZone = 0;
- for (i = 0; i < TOTAL_ZONES; i++) {
- _mouseXZone[i] = (_zones[i].x + (_zones[i].width / 2)) * _scaleFactorXm / _scaleFactorXd;
- _mouseYZone[i] = (_zones[i].y + (_zones[i].height / 2)) * _scaleFactorYm / _scaleFactorYd;
- }
-}
-
-void OSystem_WINCE3::loadDeviceConfigurationElement(String element, int &value, int defaultValue) {
- value = ConfMan.getInt(element, ConfMan.kApplicationDomain);
- if (!value) {
- value = defaultValue;
- ConfMan.setInt(element, value, ConfMan.kApplicationDomain);
- }
-}
-
-void OSystem_WINCE3::loadDeviceConfiguration() {
- loadDeviceConfigurationElement("repeatTrigger", _keyRepeatTrigger, 200);
- loadDeviceConfigurationElement("repeatX", _repeatX, 4);
- loadDeviceConfigurationElement("repeatY", _repeatY, 4);
- loadDeviceConfigurationElement("stepX1", _stepX1, 2);
- loadDeviceConfigurationElement("stepX2", _stepX2, 10);
- loadDeviceConfigurationElement("stepX3", _stepX3, 40);
- loadDeviceConfigurationElement("stepY1", _stepY1, 2);
- loadDeviceConfigurationElement("stepY2", _stepY2, 10);
- loadDeviceConfigurationElement("stepY3", _stepY3, 20);
- ConfMan.flushToDisk();
-}
-
-void OSystem_WINCE3::add_left_click(bool pushed) {
- int x, y;
- retrieve_mouse_location(x, y);
- EventsBuffer::simulateMouseLeftClick(x, y, pushed);
-}
-
-void OSystem_WINCE3::move_cursor_up() {
- int x, y;
- _usesEmulatedMouse = true;
- retrieve_mouse_location(x, y);
- if (_keyRepeat > _repeatY)
- y -= _stepY3;
- else if (_keyRepeat)
- y -= _stepY2;
- else
- y -= _stepY1;
-
- if (y < 0)
- y = 0;
-
- EventsBuffer::simulateMouseMove(x, y);
-}
-
-void OSystem_WINCE3::move_cursor_down() {
- int x, y;
- _usesEmulatedMouse = true;
- retrieve_mouse_location(x, y);
- if (_keyRepeat > _repeatY)
- y += _stepY3;
- else if (_keyRepeat)
- y += _stepY2;
- else
- y += _stepY1;
-
- if (y > _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd)
- y = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd;
-
- EventsBuffer::simulateMouseMove(x, y);
-}
-
-void OSystem_WINCE3::move_cursor_left() {
- int x, y;
- _usesEmulatedMouse = true;
- retrieve_mouse_location(x, y);
- if (_keyRepeat > _repeatX)
- x -= _stepX3;
- else if (_keyRepeat)
- x -= _stepX2;
- else
- x -= _stepX1;
-
- if (x < 0)
- x = 0;
-
- EventsBuffer::simulateMouseMove(x, y);
-}
-
-void OSystem_WINCE3::move_cursor_right() {
- int x, y;
- _usesEmulatedMouse = true;
- retrieve_mouse_location(x, y);
- if (_keyRepeat > _repeatX)
- x += _stepX3;
- else if (_keyRepeat)
- x += _stepX2;
- else
- x += _stepX1;
-
- if (x > _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd)
- x = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd;
-
- EventsBuffer::simulateMouseMove(x, y);
-}
-
-void OSystem_WINCE3::switch_zone() {
- int x, y;
- int i;
- retrieve_mouse_location(x, y);
-
- for (i = 0; i < TOTAL_ZONES; i++)
- if (x >= _zones[i].x && y >= _zones[i].y &&
- x <= _zones[i].x + _zones[i].width && y <= _zones[i].y + _zones[i].height) {
- _mouseXZone[i] = x;
- _mouseYZone[i] = y;
- break;
- }
- _currentZone = i + 1;
- if (_currentZone >= TOTAL_ZONES)
- _currentZone = 0;
-
- EventsBuffer::simulateMouseMove(_mouseXZone[_currentZone], _mouseYZone[_currentZone]);
-}
-
-void OSystem_WINCE3::create_toolbar() {
- PanelKeyboard *keyboard;
-
- // Add the keyboard
- keyboard = new PanelKeyboard(PANEL_KEYBOARD);
- _toolbarHandler.add(NAME_PANEL_KEYBOARD, *keyboard);
- _toolbarHandler.setVisible(false);
-}
-
-void OSystem_WINCE3::setupMixer() {
- SDL_AudioSpec desired;
- int thread_priority;
-
- uint32 sampleRate = compute_sample_rate();
- if (sampleRate == 0)
- warning("OSystem_WINCE3::setupMixer called with sample rate 0 - audio will not work");
- else if (_mixer && _mixer->getOutputRate() == sampleRate) {
- debug(1, "Skipping sound mixer re-init: samplerate is good");
- return;
- }
-
- memset(&desired, 0, sizeof(desired));
- desired.freq = sampleRate;
- desired.format = AUDIO_S16SYS;
- desired.channels = 2;
- desired.samples = 128;
- desired.callback = private_sound_proc;
- desired.userdata = this;
-
- // Create the mixer instance
- if (_mixer == 0)
- _mixer = new Audio::MixerImpl(this, sampleRate);
-
- // Add sound thread priority
- if (!ConfMan.hasKey("sound_thread_priority"))
- thread_priority = THREAD_PRIORITY_NORMAL;
- else
- thread_priority = ConfMan.getInt("sound_thread_priority");
-
- desired.thread_priority = thread_priority;
-
- SDL_CloseAudio();
- if (SDL_OpenAudio(&desired, NULL) != 0) {
- warning("Could not open audio device: %s", SDL_GetError());
- _mixer->setReady(false);
-
- } else {
- debug(1, "Sound opened OK, mixing at %d Hz", sampleRate);
-
- // Re-create mixer to match the output rate
- 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);
- delete _mixer;
- _mixer = new Audio::MixerImpl(this, sampleRate);
- _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, vol1);
- _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol2);
- _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, vol3);
- _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, vol4);
- _mixer->setReady(true);
- SDL_PauseAudio(0);
- }
-}
-
-void OSystem_WINCE3::private_sound_proc(void *param, byte *buf, int len) {
- OSystem_WINCE3 *this_ = (OSystem_WINCE3 *)param;
- assert(this_);
-
- if (this_->_mixer)
- this_->_mixer->mixCallback(buf, len);
- if (!_soundMaster)
- memset(buf, 0, len);
-}
-
-#ifdef USE_VORBIS
-bool OSystem_WINCE3::checkOggHighSampleRate() {
- char trackFile[255];
- FILE *testFile;
- OggVorbis_File *test_ov_file = new OggVorbis_File;
-
- // FIXME: The following sprintf assumes that "path" is always
- // terminated by a path separator. This is *not* true in general.
- // This code really should check for the path separator, or even
- // better, use the FSNode API.
- sprintf(trackFile, "%sTrack1.ogg", ConfMan.get("path").c_str());
- // Check if we have an OGG audio track
- testFile = fopen(trackFile, "rb");
- if (testFile) {
- if (!ov_open(testFile, test_ov_file, NULL, 0)) {
- bool highSampleRate = (ov_info(test_ov_file, -1)->rate == 22050);
- ov_clear(test_ov_file);
- delete test_ov_file;
- return highSampleRate;
- }
- }
-
- // Do not test for OGG samples - too big and too slow anyway :)
-
- delete test_ov_file;
- return false;
-}
-#endif
-
-uint32 OSystem_WINCE3::compute_sample_rate() {
- uint32 sampleRate;
-
- // Force at least medium quality FM synthesis for FOTAQ
- Common::String gameid(ConfMan.get("gameid"));
- if (gameid == "queen") {
- if (!((ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) ||
- (ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")))) {
- ConfMan.setBool("FM_medium_quality", true);
- ConfMan.flushToDisk();
- }
- }
- // See if the output frequency is forced by the game
- if (gameid == "ft" || gameid == "dig" || gameid == "comi" || gameid == "queen" || gameid == "sword" || gameid == "agi")
- sampleRate = SAMPLES_PER_SEC_NEW;
- else {
- if (ConfMan.hasKey("high_sample_rate") && ConfMan.getBool("high_sample_rate"))
- sampleRate = SAMPLES_PER_SEC_NEW;
- else
- sampleRate = SAMPLES_PER_SEC_OLD;
- }
-
-#ifdef USE_VORBIS
- // Modify the sample rate on the fly if OGG is involved
- if (sampleRate == SAMPLES_PER_SEC_OLD)
- if (checkOggHighSampleRate())
- sampleRate = SAMPLES_PER_SEC_NEW;
-#endif
-
- return sampleRate;
-}
void OSystem_WINCE3::engineInit() {
check_mappings(); // called here to initialize virtual keys handling
//update_game_settings();
// finalize mixer init
- setupMixer();
-}
-
-const OSystem::GraphicsMode *OSystem_WINCE3::getSupportedGraphicsModes() const {
- if (CEDevice::hasWideResolution())
- return s_supportedGraphicsModesHigh;
- else
- return s_supportedGraphicsModesLow;
-}
-
-bool OSystem_WINCE3::hasFeature(Feature f) {
- return (f == kFeatureVirtualKeyboard);
-}
-
-void OSystem_WINCE3::setFeatureState(Feature f, bool enable) {
- switch (f) {
- case kFeatureFullscreenMode:
- return;
-
- case kFeatureVirtualKeyboard:
- if (_hasSmartphoneResolution)
- return;
- _toolbarHighDrawn = false;
- if (enable) {
- _panelStateForced = true;
- if (!_toolbarHandler.visible()) swap_panel_visibility();
- //_saveToolbarState = _toolbarHandler.visible();
- _saveActiveToolbar = _toolbarHandler.activeName();
- _toolbarHandler.setActive(NAME_PANEL_KEYBOARD);
- _toolbarHandler.setVisible(true);
- } else
- if (_panelStateForced) {
- _panelStateForced = false;
- _toolbarHandler.setActive(_saveActiveToolbar);
- //_toolbarHandler.setVisible(_saveToolbarState);
- }
- return;
-
- case kFeatureDisableKeyFiltering:
- if (_hasSmartphoneResolution)
- _unfilteredkeys = enable;
- return;
-
- default:
- OSystem_SDL::setFeatureState(f, enable);
- }
-}
-
-bool OSystem_WINCE3::getFeatureState(Feature f) {
- switch (f) {
- case kFeatureFullscreenMode:
- return false;
- case kFeatureVirtualKeyboard:
- return (_panelStateForced);
- default:
- return OSystem_SDL::getFeatureState(f);
- }
+ _mixerManager->init();
}
void OSystem_WINCE3::check_mappings() {
@@ -1021,1465 +525,32 @@ void OSystem_WINCE3::check_mappings() {
}
-void OSystem_WINCE3::update_game_settings() {
- Common::String gameid(ConfMan.get("gameid"));
-
- // Finish panel initialization
- if (!_panelInitialized && !gameid.empty()) {
- Panel *panel;
- _panelInitialized = true;
- // Add the main panel
- panel = new Panel(0, 32);
- panel->setBackground(IMAGE_PANEL);
- // Save
- panel->add(NAME_ITEM_OPTIONS, new ItemAction(ITEM_OPTIONS, POCKET_ACTION_SAVE));
- // Skip
- panel->add(NAME_ITEM_SKIP, new ItemAction(ITEM_SKIP, POCKET_ACTION_SKIP));
- // sound
- panel->add(NAME_ITEM_SOUND, new ItemSwitch(ITEM_SOUND_OFF, ITEM_SOUND_ON, &_soundMaster));
- // bind keys
- panel->add(NAME_ITEM_BINDKEYS, new ItemAction(ITEM_BINDKEYS, POCKET_ACTION_BINDKEYS));
- // portrait/landscape - screen dependent
- // FIXME : will still display the portrait/landscape icon when using a scaler (but will be disabled)
- if (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));
- _toolbarHandler.add(NAME_MAIN_PANEL, *panel);
- _toolbarHandler.setActive(NAME_MAIN_PANEL);
- _toolbarHandler.setVisible(true);
-
- if (_videoMode.mode == GFX_NORMAL && ConfMan.hasKey("landscape") && ConfMan.getInt("landscape")) {
- setGraphicsMode(GFX_NORMAL);
- hotswapGFXMode();
- }
-
- if (_hasSmartphoneResolution)
- panel->setVisible(false);
-
- _saveToolbarState = true;
- }
-
- if (ConfMan.hasKey("no_doubletap_rightclick"))
- _noDoubleTapRMB = ConfMan.getBool("no_doubletap_rightclick");
-}
-
-void OSystem_WINCE3::initSize(uint w, uint h, const Graphics::PixelFormat *format) {
- if (_hasSmartphoneResolution && h == 240)
- h = 200; // mainly for the launcher
-
- if (_isSmartphone && !ConfMan.hasKey("landscape")) {
- ConfMan.setInt("landscape", 1);
- ConfMan.flushToDisk();
- }
-
- _canBeAspectScaled = false;
- if (w == 320 && h == 200 && !_hasSmartphoneResolution) {
- _canBeAspectScaled = true;
- h = 240; // use the extra 40 pixels height for the toolbar
- }
-
- if (h == 400) // touche engine fixup
- h += 80;
-
- if (!_hasSmartphoneResolution) {
- if (h == 240)
- _toolbarHandler.setOffset(200);
- else
- _toolbarHandler.setOffset(400);
- } else {
- if (h == 240)
- _toolbarHandler.setOffset(200);
- else // 176x220
- _toolbarHandler.setOffset(0);
- }
-
- if (w != (uint) _videoMode.screenWidth || h != (uint) _videoMode.screenHeight)
- _scalersChanged = false;
-
- _videoMode.overlayWidth = w;
- _videoMode.overlayHeight = h;
-
- OSystem_SDL::initSize(w, h, format);
-
- if (_scalersChanged) {
- unloadGFXMode();
- loadGFXMode();
- _scalersChanged = false;
- }
-
- update_game_settings();
-}
-
-
-int OSystem_WINCE3::getDefaultGraphicsMode() const {
- return GFX_NORMAL;
-}
-
void OSystem_WINCE3::setGraphicsModeIntern() {
// Scalers have been pre-selected for the desired mode.
// No further tuning required.
}
-bool OSystem_WINCE3::update_scalers() {
- _videoMode.aspectRatioCorrection = false;
-
- if (CEDevice::hasPocketPCResolution()) {
- if (_videoMode.mode != GFX_NORMAL)
- return false;
-
- if ((!_orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth))
- || CEDevice::hasSquareQVGAResolution() ) {
- if (getScreenWidth() != 320) {
- _scaleFactorXm = 3;
- _scaleFactorXd = 4;
- _scaleFactorYm = 1;
- _scaleFactorYd = 1;
- _scalerProc = DownscaleHorizByThreeQuarters;
- } else {
- _scaleFactorXm = 1;
- _scaleFactorXd = 1;
- _scaleFactorYm = 1;
- _scaleFactorYd = 1;
- _scalerProc = Normal1x;
- }
- } else if ( _orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth)) {
- if (!_panelVisible && !_hasSmartphoneResolution && !_overlayVisible && _canBeAspectScaled) {
- _scaleFactorXm = 1;
- _scaleFactorXd = 1;
- _scaleFactorYm = 6;
- _scaleFactorYd = 5;
- _scalerProc = Normal1xAspect;
- _videoMode.aspectRatioCorrection = true;
- } else {
- _scaleFactorXm = 1;
- _scaleFactorXd = 1;
- _scaleFactorYm = 1;
- _scaleFactorYd = 1;
- _scalerProc = Normal1x;
- }
- } else if (_videoMode.screenWidth == 640 && !(isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) {
- _scaleFactorXm = 1;
- _scaleFactorXd = 2;
- _scaleFactorYm = 1;
- _scaleFactorYd = 2;
- _scalerProc = DownscaleAllByHalf;
- } else if (_videoMode.screenWidth == 640 && (isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) {
- _scaleFactorXm = 1;
- _scaleFactorXd = 1;
- _scaleFactorYm = 1;
- _scaleFactorYd = 1;
- _scalerProc = Normal1x;
- }
-
- return true;
- } else if (CEDevice::hasWideResolution()) {
-#ifdef USE_ARM_SCALER_ASM
- if ( _videoMode.mode == GFX_DOUBLESIZE && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth) ) {
- if ( !_panelVisible && !_overlayVisible && _canBeAspectScaled ) {
- _scaleFactorXm = 2;
- _scaleFactorXd = 1;
- _scaleFactorYm = 12;
- _scaleFactorYd = 5;
- _scalerProc = Normal2xAspect;
- _videoMode.aspectRatioCorrection = true;
- } else if ( (_panelVisible || _overlayVisible) && _canBeAspectScaled ) {
- _scaleFactorXm = 2;
- _scaleFactorXd = 1;
- _scaleFactorYm = 2;
- _scaleFactorYd = 1;
- _scalerProc = Normal2x;
- }
- return true;
- }
-#endif
- } else if (CEDevice::hasSmartphoneResolution()) {
- if (_videoMode.mode != GFX_NORMAL)
- return false;
-
- if (_videoMode.screenWidth > 320)
- error("Game resolution not supported on Smartphone");
-#ifdef ARM
- _scaleFactorXm = 11;
- _scaleFactorXd = 16;
-#else
- _scaleFactorXm = 2;
- _scaleFactorXd = 3;
-#endif
- _scaleFactorYm = 7;
- _scaleFactorYd = 8;
- _scalerProc = SmartphoneLandscape;
- initZones();
- return true;
- }
-
- return false;
-}
-
-bool OSystem_WINCE3::setGraphicsMode(int mode) {
-
- Common::StackLock lock(_graphicsMutex);
- int oldScaleFactorXm = _scaleFactorXm;
- int oldScaleFactorXd = _scaleFactorXd;
- int oldScaleFactorYm = _scaleFactorYm;
- int oldScaleFactorYd = _scaleFactorYd;
-
- _scaleFactorXm = -1;
- _scaleFactorXd = -1;
- _scaleFactorYm = -1;
- _scaleFactorYd = -1;
-
- if (ConfMan.hasKey("landscape"))
- if (ConfMan.get("landscape")[0] > 57) {
- _newOrientation = _orientationLandscape = ConfMan.getBool("landscape");
- ConfMan.setInt("landscape", _orientationLandscape);
- } else
- _newOrientation = _orientationLandscape = ConfMan.getInt("landscape");
- else
- _newOrientation = _orientationLandscape = 0;
-
- if (isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640) && mode)
- _scaleFactorXm = -1;
+void OSystem_WINCE3::initSDL() {
+ // Check if SDL has not been initialized
+ if (!_initedSDL) {
+ uint32 sdlFlags = SDL_INIT_EVENTTHREAD;
+ if (ConfMan.hasKey("disable_sdl_parachute"))
+ sdlFlags |= SDL_INIT_NOPARACHUTE;
- if (CEDevice::hasPocketPCResolution() && !CEDevice::hasWideResolution() && _orientationLandscape)
- _videoMode.mode = GFX_NORMAL;
- else
- _videoMode.mode = mode;
-
- if (_scaleFactorXm < 0) {
- /* Standard scalers, from the SDL backend */
- switch (_videoMode.mode) {
- case GFX_NORMAL:
- _videoMode.scaleFactor = 1;
- _scalerProc = Normal1x;
- break;
- case GFX_DOUBLESIZE:
- _videoMode.scaleFactor = 2;
- _scalerProc = Normal2x;
- break;
- case GFX_TRIPLESIZE:
- _videoMode.scaleFactor = 3;
- _scalerProc = Normal3x;
- break;
- case GFX_2XSAI:
- _videoMode.scaleFactor = 2;
- _scalerProc = _2xSaI;
- break;
- case GFX_SUPER2XSAI:
- _videoMode.scaleFactor = 2;
- _scalerProc = Super2xSaI;
- break;
- case GFX_SUPEREAGLE:
- _videoMode.scaleFactor = 2;
- _scalerProc = SuperEagle;
- break;
- case GFX_ADVMAME2X:
- _videoMode.scaleFactor = 2;
- _scalerProc = AdvMame2x;
- break;
- case GFX_ADVMAME3X:
- _videoMode.scaleFactor = 3;
- _scalerProc = AdvMame3x;
- break;
-#ifdef USE_HQ_SCALERS
- case GFX_HQ2X:
- _videoMode.scaleFactor = 2;
- _scalerProc = HQ2x;
- break;
- case GFX_HQ3X:
- _videoMode.scaleFactor = 3;
- _scalerProc = HQ3x;
- break;
-#endif
- case GFX_TV2X:
- _videoMode.scaleFactor = 2;
- _scalerProc = TV2x;
- break;
- case GFX_DOTMATRIX:
- _videoMode.scaleFactor = 2;
- _scalerProc = DotMatrix;
- break;
-
- default:
- error("unknown gfx mode %d", mode);
+ if (ConfMan.hasKey("use_GDI") && ConfMan.getBool("use_GDI")) {
+ SDL_VideoInit("windib", 0);
+ sdlFlags ^= SDL_INIT_VIDEO;
}
- }
-
- // Check if the scaler can be accepted, if not get back to normal scaler
- 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;
- _scalerProc = Normal1x;
- }
-
- // Common scaler system was used
- if (_scaleFactorXm < 0) {
- _scaleFactorXm = _videoMode.scaleFactor;
- _scaleFactorXd = 1;
- _scaleFactorYm = _videoMode.scaleFactor;
- _scaleFactorYd = 1;
- }
-
- _forceFull = true;
-
- if (oldScaleFactorXm != _scaleFactorXm ||
- oldScaleFactorXd != _scaleFactorXd ||
- oldScaleFactorYm != _scaleFactorYm ||
- oldScaleFactorYd != _scaleFactorYd) {
- _scalersChanged = true;
- }
- else
- _scalersChanged = false;
-
-
- return true;
-
-}
-
-bool OSystem_WINCE3::loadGFXMode() {
- int displayWidth;
- int displayHeight;
- unsigned int flags = SDL_FULLSCREEN | SDL_SWSURFACE;
-
- _videoMode.fullscreen = true; // forced
- _forceFull = true;
-
- _tmpscreen = NULL;
-
- // Recompute scalers if necessary
- update_scalers();
-
- // Create the surface that contains the 8 bit game data
- _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
- if (_screen == NULL)
- error("_screen failed (%s)", SDL_GetError());
-
- // Create the surface that contains the scaled graphics in 16 bit mode
- // Always use full screen mode to have a "clean screen"
- if (!_videoMode.aspectRatioCorrection) {
- displayWidth = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd;
- displayHeight = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd;
- } else {
- displayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
- displayHeight = _videoMode.screenHeight* _videoMode.scaleFactor;
- }
-
- switch (_orientationLandscape) {
- case 1:
- flags |= SDL_LANDSCVIDEO;
- break;
- case 2:
- flags |= SDL_INVLNDVIDEO;
- break;
- default:
- flags |= SDL_PORTRTVIDEO;
- }
- _hwscreen = SDL_SetVideoMode(displayWidth, displayHeight, 16, flags);
-
- if (_hwscreen == NULL) {
- warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
- quit();
- }
-
- // 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;
- // Create the surface used for the graphics in 16 bit before scaling, and also the overlay
- // Distinguish 555 and 565 mode
- if (_hwscreen->format->Rmask == 0x7C00)
- InitScalers(555);
- else
- InitScalers(565);
- _overlayFormat.bytesPerPixel = _hwscreen->format->BytesPerPixel;
- _overlayFormat.rLoss = _hwscreen->format->Rloss;
- _overlayFormat.gLoss = _hwscreen->format->Gloss;
- _overlayFormat.bLoss = _hwscreen->format->Bloss;
- _overlayFormat.aLoss = _hwscreen->format->Aloss;
- _overlayFormat.rShift = _hwscreen->format->Rshift;
- _overlayFormat.gShift = _hwscreen->format->Gshift;
- _overlayFormat.bShift = _hwscreen->format->Bshift;
- _overlayFormat.aShift = _hwscreen->format->Ashift;
-
- // Need some extra bytes around when using 2xSaI
- _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
-
- if (_tmpscreen == NULL)
- error("_tmpscreen creation failed (%s)", SDL_GetError());
-
- // Overlay
- if (CEDevice::hasDesktopResolution()) {
- _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd, 16, 0, 0, 0, 0);
- if (_overlayscreen == NULL)
- error("_overlayscreen failed (%s)", SDL_GetError());
- _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd + 3, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd + 3, 16, 0, 0, 0, 0);
- if (_tmpscreen2 == NULL)
- error("_tmpscreen2 failed (%s)", SDL_GetError());
- } else {
- _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight, 16, 0, 0, 0, 0);
- if (_overlayscreen == NULL)
- error("_overlayscreen failed (%s)", SDL_GetError());
- _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3, 16, 0, 0, 0, 0);
- if (_tmpscreen2 == NULL)
- error("_tmpscreen2 failed (%s)", SDL_GetError());
- }
-
- // Toolbar
- _toolbarHighDrawn = false;
- uint16 *toolbar_screen = (uint16 *)calloc(320 * 40, sizeof(uint16)); // *not* leaking memory here
- _toolbarLow = SDL_CreateRGBSurfaceFrom(toolbar_screen, 320, 40, 16, 320 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
-
- if (_toolbarLow == NULL)
- error("_toolbarLow failed (%s)", SDL_GetError());
-
- if (_videoMode.screenHeight > 240) {
- uint16 *toolbar_screen = (uint16 *)calloc(640 * 80, sizeof(uint16));
- _toolbarHigh = SDL_CreateRGBSurfaceFrom(toolbar_screen, 640, 80, 16, 640 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);
-
- if (_toolbarHigh == NULL)
- error("_toolbarHigh failed (%s)", SDL_GetError());
- } else
- _toolbarHigh = NULL;
-
-
- // keyboard cursor control, some other better place for it?
- _km.x_max = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd - 1;
- _km.y_max = _videoMode.screenHeight * _scaleFactorXm / _scaleFactorXd - 1;
- _km.delay_time = 25;
- _km.last_time = 0;
-
- return true;
-}
-
-void OSystem_WINCE3::unloadGFXMode() {
- if (_screen) {
- SDL_FreeSurface(_screen);
- _screen = NULL;
- }
-
- if (_hwscreen) {
- SDL_FreeSurface(_hwscreen);
- _hwscreen = NULL;
- }
+ // Initialize SDL (SDL Subsystems are initiliazed in the corresponding sdl managers)
+ if (SDL_Init(sdlFlags) == -1)
+ error("Could not initialize SDL: %s", SDL_GetError());
- if (_tmpscreen) {
- SDL_FreeSurface(_tmpscreen);
- _tmpscreen = NULL;
- }
-}
-
-bool OSystem_WINCE3::hotswapGFXMode() {
- if (!_screen)
- return false;
-
- // Keep around the old _screen & _tmpscreen so we can restore the screen data
- // after the mode switch. (also for the overlay)
- SDL_Surface *old_screen = _screen;
- SDL_Surface *old_tmpscreen = _tmpscreen;
- SDL_Surface *old_overlayscreen = _overlayscreen;
- SDL_Surface *old_tmpscreen2 = _tmpscreen2;
-
- // Release the HW screen surface
- SDL_FreeSurface(_hwscreen);
-
- // Release toolbars
- free(_toolbarLow->pixels);
- SDL_FreeSurface(_toolbarLow);
- if (_toolbarHigh) {
- free(_toolbarHigh->pixels);
- SDL_FreeSurface(_toolbarHigh);
- }
+ // Enable unicode support if possible
+ SDL_EnableUNICODE(1);
- // Setup the new GFX mode
- if (!loadGFXMode()) {
- unloadGFXMode();
-
- _screen = old_screen;
- _overlayscreen = old_overlayscreen;
-
- return false;
+ _initedSDL = true;
}
-
- // reset palette
- SDL_SetColors(_screen, _currentPalette, 0, 256);
-
- // Restore old screen content
- SDL_BlitSurface(old_screen, NULL, _screen, NULL);
- SDL_BlitSurface(old_tmpscreen, NULL, _tmpscreen, NULL);
- if (_overlayVisible) {
- SDL_BlitSurface(old_overlayscreen, NULL, _overlayscreen, NULL);
- SDL_BlitSurface(old_tmpscreen2, NULL, _tmpscreen2, NULL);
- }
-
- // Free the old surfaces
- SDL_FreeSurface(old_screen);
- SDL_FreeSurface(old_tmpscreen);
- SDL_FreeSurface(old_overlayscreen);
- SDL_FreeSurface(old_tmpscreen2);
-
- // Blit everything back to the screen
- _toolbarHighDrawn = false;
- internUpdateScreen();
-
- // Make sure that a Common::EVENT_SCREEN_CHANGED gets sent later -> FIXME this crashes when no game has been loaded.
-// _modeChanged = true;
-
- return true;
-}
-
-void OSystem_WINCE3::internUpdateScreen() {
- SDL_Surface *srcSurf, *origSurf;
- static bool old_overlayVisible = false;
- int numRectsOut = 0;
- int16 routx, routy, routw, routh, stretch, shakestretch;
-
- assert(_hwscreen != NULL);
-
- // bail if the application is minimized, be nice to OS
- if (!_hasfocus) {
- Sleep(20);
- return;
- }
-
- // If the shake position changed, fill the dirty area with blackness
- if (_currentShakePos != _newShakePos) {
- SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd, _newShakePos * _scaleFactorYm / _scaleFactorYd};
- if (_videoMode.aspectRatioCorrection)
- blackrect.h = real2Aspect(blackrect.h - 1) + 1;
- SDL_FillRect(_hwscreen, &blackrect, 0);
- _currentShakePos = _newShakePos;
- _forceFull = true;
- }
-
- // Make sure the mouse is drawn, if it should be drawn.
- drawMouse();
-
- // Check whether the palette was changed in the meantime and update the
- // screen surface accordingly.
- if (_paletteDirtyEnd != 0) {
- SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart, _paletteDirtyStart, _paletteDirtyEnd - _paletteDirtyStart);
- _paletteDirtyEnd = 0;
- _forceFull = true;
- }
-
- if (!_overlayVisible) {
- origSurf = _screen;
- srcSurf = _tmpscreen;
- } else {
- origSurf = _overlayscreen;
- srcSurf = _tmpscreen2;
- }
-
- if (old_overlayVisible != _overlayVisible) {
- old_overlayVisible = _overlayVisible;
- update_scalers();
- }
-
- // Force a full redraw if requested
- if (_forceFull) {
- _numDirtyRects = 1;
-
- _dirtyRectList[0].x = 0;
- if (!_zoomDown)
- _dirtyRectList[0].y = 0;
- else
- _dirtyRectList[0].y = _videoMode.screenHeight / 2;
- _dirtyRectList[0].w = _videoMode.screenWidth;
- if (!_zoomUp && !_zoomDown)
- _dirtyRectList[0].h = _videoMode.screenHeight;
- else
- _dirtyRectList[0].h = _videoMode.screenHeight / 2;
-
- _toolbarHandler.forceRedraw();
- }
-
- // Only draw anything if necessary
- if (_numDirtyRects > 0) {
-
- SDL_Rect *r, *rout;
- SDL_Rect dst;
- uint32 srcPitch, dstPitch;
- SDL_Rect *last_rect = _dirtyRectList + _numDirtyRects;
- bool toolbarVisible = _toolbarHandler.visible();
- int toolbarOffset = _toolbarHandler.getOffset();
-
- for (r = _dirtyRectList; r != last_rect; ++r) {
- dst = *r;
- dst.x++; // Shift rect by one since 2xSai needs to access the data around
- dst.y++; // any pixel to scale it, and we want to avoid mem access crashes.
- // NOTE: This is also known as BLACK MAGIC, copied from the sdl backend
- if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)
- error("SDL_BlitSurface failed: %s", SDL_GetError());
- }
-
- SDL_LockSurface(srcSurf);
- SDL_LockSurface(_hwscreen);
-
- srcPitch = srcSurf->pitch;
- dstPitch = _hwscreen->pitch;
-
- for (r = _dirtyRectList, rout = _dirtyRectOut; r != last_rect; ++r) {
-
- // 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;
- }
-
- // transform
- shakestretch = _currentShakePos * _scaleFactorYm / _scaleFactorYd;
- routx = r->x * _scaleFactorXm / _scaleFactorXd; // locate position in scaled screen
- routy = r->y * _scaleFactorYm / _scaleFactorYd + shakestretch; // adjust for shake offset
- routw = r->w * _scaleFactorXm / _scaleFactorXd;
- routh = r->h * _scaleFactorYm / _scaleFactorYd - shakestretch;
-
- // 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;
- if (routy < 0) {
- routh += routy;
- r->y -= routy * _scaleFactorYd / _scaleFactorYm;
- routy = 0;
- r->h = routh * _scaleFactorYd / _scaleFactorYm;
- }
- if (_orientationLandscape) {
- if (routy > _platformScreenWidth) continue;
- if (routy + routh > _platformScreenWidth) {
- routh = _platformScreenWidth - routy;
- r->h = routh * _scaleFactorYd / _scaleFactorYm;
- }
- } else {
- if (routy > _platformScreenHeight) continue;
- if (routy + routh > _platformScreenHeight) {
- routh = _platformScreenHeight - routy;
- r->h = routh * _scaleFactorYd / _scaleFactorYm;
- }
- }
-
- // 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 - _currentShakePos);
-
- // add this rect to output
- rout->x = routx; rout->y = routy - shakestretch;
- rout->w = routw; rout->h = routh + shakestretch;
- numRectsOut++;
- rout++;
-
- }
- SDL_UnlockSurface(srcSurf);
- SDL_UnlockSurface(_hwscreen);
- }
- // Add the toolbar if needed
- SDL_Rect toolbar_rect[1];
- if (_panelVisible && _toolbarHandler.draw(_toolbarLow, &toolbar_rect[0])) {
- // It can be drawn, scale it
- uint32 srcPitch, dstPitch;
- SDL_Surface *toolbarSurface;
- ScalerProc *toolbarScaler;
-
- if (_videoMode.screenHeight > 240) {
- if (!_toolbarHighDrawn) {
- // Resize the toolbar
- SDL_LockSurface(_toolbarLow);
- SDL_LockSurface(_toolbarHigh);
- Normal2x((byte*)_toolbarLow->pixels, _toolbarLow->pitch, (byte*)_toolbarHigh->pixels, _toolbarHigh->pitch, toolbar_rect[0].w, toolbar_rect[0].h);
- SDL_UnlockSurface(_toolbarHigh);
- SDL_UnlockSurface(_toolbarLow);
- _toolbarHighDrawn = true;
- }
- toolbar_rect[0].w *= 2;
- toolbar_rect[0].h *= 2;
- toolbarSurface = _toolbarHigh;
- }
- else
- toolbarSurface = _toolbarLow;
-
- drawToolbarMouse(toolbarSurface, true); // draw toolbar mouse if applicable
-
- // Apply the appropriate scaler
- SDL_LockSurface(toolbarSurface);
- SDL_LockSurface(_hwscreen);
- srcPitch = toolbarSurface->pitch;
- dstPitch = _hwscreen->pitch;
-
- toolbarScaler = _scalerProc;
- if (_videoMode.scaleFactor == 2)
- toolbarScaler = Normal2x;
- else if (_videoMode.scaleFactor == 3)
- toolbarScaler = Normal3x;
- toolbarScaler((byte *)toolbarSurface->pixels, srcPitch,
- (byte *)_hwscreen->pixels + (_toolbarHandler.getOffset() * _scaleFactorYm / _scaleFactorYd * dstPitch),
- dstPitch, toolbar_rect[0].w, toolbar_rect[0].h);
- SDL_UnlockSurface(toolbarSurface);
- SDL_UnlockSurface(_hwscreen);
-
- // And blit it
- toolbar_rect[0].y = _toolbarHandler.getOffset();
- toolbar_rect[0].x = toolbar_rect[0].x * _scaleFactorXm / _scaleFactorXd;
- toolbar_rect[0].y = toolbar_rect[0].y * _scaleFactorYm / _scaleFactorYd;
- toolbar_rect[0].w = toolbar_rect[0].w * _scaleFactorXm / _scaleFactorXd;
- toolbar_rect[0].h = toolbar_rect[0].h * _scaleFactorYm / _scaleFactorYd;
-
- SDL_UpdateRects(_hwscreen, 1, toolbar_rect);
-
- drawToolbarMouse(toolbarSurface, false); // undraw toolbar mouse
- }
-
- // Finally, blit all our changes to the screen
- if (numRectsOut > 0)
- SDL_UpdateRects(_hwscreen, numRectsOut, _dirtyRectOut);
-
- _numDirtyRects = 0;
- _forceFull = false;
-}
-
-Graphics::Surface *OSystem_WINCE3::lockScreen() {
- // Make sure mouse pointer is not painted over the playfield at the time of locking
- undrawMouse();
- return OSystem_SDL::lockScreen();
-}
-
-void OSystem_WINCE3::unlockScreen() {
- OSystem_SDL::unlockScreen();
-}
-
-bool OSystem_WINCE3::saveScreenshot(const char *filename) {
- assert(_hwscreen != NULL);
-
- Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends
- SDL_SaveBMP(_hwscreen, filename);
- return true;
-}
-
-void OSystem_WINCE3::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
- assert (_transactionMode == kTransactionNone);
-
- if (_overlayscreen == NULL)
- return;
-
- // Clip the coordinates
- if (x < 0) {
- w += x;
- buf -= x;
- x = 0;
- }
-
- if (y < 0) {
- h += y; buf -= y * pitch;
- y = 0;
- }
-
- if (w > _videoMode.overlayWidth - x) {
- w = _videoMode.overlayWidth - x;
- }
-
- if (h > _videoMode.overlayHeight - y) {
- h = _videoMode.overlayHeight - y;
- }
-
- if (w <= 0 || h <= 0)
- return;
-
- // Mark the modified region as dirty
- addDirtyRect(x, y, w, h);
-
- undrawMouse();
-
- if (SDL_LockSurface(_overlayscreen) == -1)
- error("SDL_LockSurface failed: %s", SDL_GetError());
-
- byte *dst = (byte *)_overlayscreen->pixels + y * _overlayscreen->pitch + x * 2;
- do {
- memcpy(dst, buf, w * 2);
- dst += _overlayscreen->pitch;
- buf += pitch;
- } while (--h);
-
- SDL_UnlockSurface(_overlayscreen);
-}
-
-void OSystem_WINCE3::copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) {
- assert (_transactionMode == kTransactionNone);
- assert(src);
-
- if (_screen == NULL)
- return;
-
- Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends
-
- /* Clip the coordinates */
- if (x < 0) {
- w += x;
- src -= x;
- x = 0;
- }
-
- if (y < 0) {
- h += y;
- src -= y * pitch;
- y = 0;
- }
-
- if (w > _videoMode.screenWidth - x) {
- w = _videoMode.screenWidth - x;
- }
-
- if (h > _videoMode.screenHeight - y) {
- h = _videoMode.screenHeight - y;
- }
-
- if (w <= 0 || h <= 0)
- return;
-
- addDirtyRect(x, y, w, h);
-
- undrawMouse();
-
- // Try to lock the screen surface
- if (SDL_LockSurface(_screen) == -1)
- error("SDL_LockSurface failed: %s", SDL_GetError());
-
- byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
-
- if (_videoMode.screenWidth == pitch && pitch == w) {
- memcpy(dst, src, h*w);
- } else {
- do {
- memcpy(dst, src, w);
- src += pitch;
- dst += _videoMode.screenWidth;
- } while (--h);
- }
-
- // Unlock the screen surface
- SDL_UnlockSurface(_screen);
-}
-
-void OSystem_WINCE3::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
-
- undrawMouse();
- if (w == 0 || h == 0)
- return;
-
- _mouseCurState.w = w;
- _mouseCurState.h = h;
-
- _mouseHotspotX = hotspot_x;
- _mouseHotspotY = hotspot_y;
-
- _mouseKeyColor = keycolor;
-
- free(_mouseData);
-
- _mouseData = (byte *) malloc(w * h);
- memcpy(_mouseData, buf, w * h);
-
- 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;
- }
-}
-
-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 (!_mouseNeedsRedraw || !_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
- int width;
-
- // clip the mouse rect, and adjust the src pointer accordingly
- if (x < 0) {
- w += x;
- src -= x;
- x = 0;
- }
- if (y < 0) {
- h += y;
- src -= y * _mouseCurState.w;
- y = 0;
- }
-
- if (w > _videoMode.screenWidth - x)
- w = _videoMode.screenWidth - x;
- if (h > _videoMode.screenHeight - y)
- h = _videoMode.screenHeight - y;
-
- // Quick check to see if anything has to be drawn at all
- if (w <= 0 || h <= 0)
- return;
-
- // Draw the mouse cursor; backup the covered area in "bak"
- if (SDL_LockSurface(_overlayVisible ? _overlayscreen : _screen) == -1)
- error("SDL_LockSurface failed: %s", SDL_GetError());
-
- // Mark as dirty
- addDirtyRect(x, y, w, h);
-
- if (!_overlayVisible) {
- byte *bak = _mouseBackupOld; // Surface used to backup the area obscured by the mouse
- byte *dst; // Surface we are drawing into
-
- dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
- while (h > 0) {
- width = w;
- while (width > 0) {
- *bak++ = *dst;
- color = *src++;
- if (color != _mouseKeyColor) // transparent, don't draw
- *dst = color;
- dst++;
- width--;
- }
- src += _mouseCurState.w - w;
- bak += _mouseBackupDim - w;
- dst += _videoMode.screenWidth - w;
- h--;
- }
-
- } else {
- uint16 *bak = (uint16 *)_mouseBackupOld; // Surface used to backup the area obscured by the mouse
- byte *dst; // Surface we are drawing into
-
- dst = (byte *)_overlayscreen->pixels + (y + 1) * _overlayscreen->pitch + (x + 1) * 2;
- while (h > 0) {
- width = w;
- while (width > 0) {
- *bak++ = *(uint16 *)dst;
- color = *src++;
- if (color != 0xFF) // 0xFF = transparent, don't draw
- *(uint16 *)dst = SDL_MapRGB(_overlayscreen->format, _currentPalette[color].r, _currentPalette[color].g, _currentPalette[color].b);
- dst += 2;
- width--;
- }
- src += _mouseCurState.w - w;
- bak += _mouseBackupDim - w;
- dst += _overlayscreen->pitch - w * 2;
- h--;
- }
- }
-
- SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);
-
- // Finally, set the flag to indicate the mouse has been drawn
- _mouseNeedsRedraw = false;
-}
-
-void OSystem_WINCE3::undrawMouse() {
- assert (_transactionMode == kTransactionNone);
-
- if (_mouseNeedsRedraw)
- return;
-
- int old_mouse_x = _mouseCurState.x - _mouseHotspotX;
- int old_mouse_y = _mouseCurState.y - _mouseHotspotY;
- int old_mouse_w = _mouseCurState.w;
- int old_mouse_h = _mouseCurState.h;
-
- // clip the mouse rect, and adjust the src pointer accordingly
- if (old_mouse_x < 0) {
- old_mouse_w += old_mouse_x;
- old_mouse_x = 0;
- }
- if (old_mouse_y < 0) {
- old_mouse_h += old_mouse_y;
- old_mouse_y = 0;
- }
-
- if (old_mouse_w > _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;
-
- // 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 y;
- if (!_overlayVisible) {
- byte *dst, *bak = _mouseBackupOld;
-
- // No need to do clipping here, since drawMouse() did that already
- dst = (byte *)_screen->pixels + old_mouse_y * _videoMode.screenWidth + old_mouse_x;
- for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _videoMode.screenWidth)
- memcpy(dst, bak, old_mouse_w);
- } else {
- byte *dst;
- uint16 *bak = (uint16 *)_mouseBackupOld;
-
- // No need to do clipping here, since drawMouse() did that already
- dst = (byte *)_overlayscreen->pixels + (old_mouse_y + 1) * _overlayscreen->pitch + (old_mouse_x + 1) * 2;
- for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _overlayscreen->pitch)
- memcpy(dst, bak, old_mouse_w << 1);
- }
-
- addDirtyRect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h);
-
- SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);
-
- _mouseNeedsRedraw = true;
-}
-
-bool OSystem_WINCE3::showMouse(bool visible) {
- if (_mouseVisible == visible)
- return visible;
-
- if (visible == false)
- undrawMouse();
-
- bool last = _mouseVisible;
- _mouseVisible = visible;
- _mouseNeedsRedraw = true;
-
- return last;
-}
-
-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;
- int width;
-
- // 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) {
- width = w;
- while (width > 0) {
- *bak++ = *dst;
- color = *src++;
- if (color != _mouseKeyColor) // transparent color
- *dst = 0xFFFF;
- dst++;
- width--;
- }
- src += _mouseCurState.w - w;
- bak += _mouseBackupDim - w;
- dst += surf->w - w;
- h--;
- }
- } else { // restore bg
- for (y = 0; y < h; ++y, bak += _mouseBackupDim, dst += surf->w)
- memcpy(dst, bak, w << 1);
- }
-
- SDL_UnlockSurface(surf);
-}
-
-void OSystem_WINCE3::blitCursor() {
-}
-
-void OSystem_WINCE3::showOverlay() {
- assert (_transactionMode == kTransactionNone);
-
- if (_overlayVisible)
- return;
-
- undrawMouse();
- _overlayVisible = true;
- update_scalers();
- clearOverlay();
-}
-
-void OSystem_WINCE3::hideOverlay() {
- assert (_transactionMode == kTransactionNone);
-
- if (!_overlayVisible)
- return;
-
- undrawMouse();
- _overlayVisible = false;
- clearOverlay();
- _forceFull = true;
-}
-
-void OSystem_WINCE3::drawMouse() {
- if (!(_toolbarHandler.visible() && _mouseCurState.y >= _toolbarHandler.getOffset() && !_usesEmulatedMouse) && !_forceHideMouse)
- internDrawMouse();
-}
-
-void OSystem_WINCE3::fillMouseEvent(Common::Event &event, int x, int y) {
- event.mouse.x = x;
- event.mouse.y = y;
-
- // Update the "keyboard mouse" coords
- _km.x = event.mouse.x;
- _km.y = event.mouse.y;
-
- // Adjust for the screen scaling
- if (_zoomDown)
- event.mouse.y += 240;
-
- event.mouse.x = event.mouse.x * _scaleFactorXd / _scaleFactorXm;
- event.mouse.y = event.mouse.y * _scaleFactorYd / _scaleFactorYm;
-}
-
-void OSystem_WINCE3::retrieve_mouse_location(int &x, int &y) {
- x = _mouseCurState.x;
- y = _mouseCurState.y;
-
- x = x * _scaleFactorXm / _scaleFactorXd;
- y = y * _scaleFactorYm / _scaleFactorYd;
-
- if (_zoomDown)
- y -= 240;
-}
-
-void OSystem_WINCE3::warpMouse(int x, int y) {
- if (_mouseCurState.x != x || _mouseCurState.y != y) {
- SDL_WarpMouse(x * _scaleFactorXm / _scaleFactorXd, y * _scaleFactorYm / _scaleFactorYd);
-
- // SDL_WarpMouse() generates a mouse movement event, so
- // set_mouse_pos() would be called eventually. However, the
- // cannon script in CoMI calls this function twice each time
- // the cannon is reloaded. Unless we update the mouse position
- // immediately the second call is ignored, causing the cannon
- // to change its aim.
-
- setMousePos(x, y);
- }
-}
-
-void OSystem_WINCE3::addDirtyRect(int x, int y, int w, int h, bool mouseRect) {
-
- if (_forceFull || _paletteDirtyEnd)
- return;
-
- OSystem_SDL::addDirtyRect(x, y, w, h, false);
-}
-
-static int mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode, bool unfilter) {
- if (GUI::Actions::Instance()->mappingActive())
- return key;
-
- if (unfilter) {
- switch (key) {
- case SDLK_ESCAPE:
- return SDLK_BACKSPACE;
- case SDLK_F8:
- return SDLK_ASTERISK;
- case SDLK_F9:
- return SDLK_HASH;
- default:
- return key;
- }
- }
-
- 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;
-}
-
-bool OSystem_WINCE3::pollEvent(Common::Event &event) {
- SDL_Event ev;
- ev.type = SDL_NOEVENT;
- DWORD currentTime;
- bool keyEvent = false;
- int deltaX, deltaY;
-
- memset(&event, 0, sizeof(Common::Event));
-
- handleKbdMouse();
-
- // If the screen mode changed, send an Common::EVENT_SCREEN_CHANGED
- if (_modeChanged) {
- _modeChanged = false;
- event.type = Common::EVENT_SCREEN_CHANGED;
- _screenChangeCount++;
- return true;
- }
-
- CEDevice::wakeUp();
-
- currentTime = GetTickCount();
-
- while (SDL_PollEvent(&ev)) {
- switch (ev.type) {
- case SDL_KEYDOWN:
- debug(1, "Key down %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));
- // KMOD_RESERVED is used if the key has been injected by an external buffer
- if (ev.key.keysym.mod != KMOD_RESERVED && !_unfilteredkeys) {
- keyEvent = true;
- _lastKeyPressed = ev.key.keysym.sym;
- _keyRepeatTime = currentTime;
- _keyRepeat = 0;
-
- if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, true))
- return true;
- }
-
- if (GUI_Actions::Instance()->mappingActive())
- event.kbd.flags = 0xFF;
- else if (ev.key.keysym.sym == SDLK_PAUSE) {
- _lastKeyPressed = 0;
- event.type = Common::EVENT_PREDICTIVE_DIALOG;
- return true;
- } event.type = Common::EVENT_KEYDOWN;
- if (!_unfilteredkeys)
- event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
- else
- event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
- event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
-
- if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
- event.kbd.ascii ^= 0x20;
- event.kbd.flags = Common::KBD_SHIFT;
- }
-
- return true;
-
- case SDL_KEYUP:
- debug(1, "Key up %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));
- // KMOD_RESERVED is used if the key has been injected by an external buffer
- if (ev.key.keysym.mod != KMOD_RESERVED && !_unfilteredkeys) {
- keyEvent = true;
- _lastKeyPressed = 0;
-
- if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, false))
- return true;
- }
-
- if (GUI_Actions::Instance()->mappingActive())
- event.kbd.flags = 0xFF;
- 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)
- event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
- else
- event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
- event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
-
- if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
- event.kbd.ascii ^= 0x20;
- event.kbd.flags = Common::KBD_SHIFT;
- }
-
- return true;
-
- case SDL_MOUSEMOTION:
- event.type = Common::EVENT_MOUSEMOVE;
- fillMouseEvent(event, ev.motion.x, ev.motion.y);
- setMousePos(event.mouse.x, event.mouse.y);
- return true;
-
- case SDL_MOUSEBUTTONDOWN:
- if (ev.button.button == SDL_BUTTON_LEFT)
- event.type = Common::EVENT_LBUTTONDOWN;
- else if (ev.button.button == SDL_BUTTON_RIGHT)
- event.type = Common::EVENT_RBUTTONDOWN;
- else
- break;
- fillMouseEvent(event, ev.button.x, ev.button.y);
-
-
- 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)
- swap_panel_visibility();
- } else if (!_noDoubleTapRMB) { // right click
- event.type = Common::EVENT_RBUTTONDOWN;
- _rbutton = true;
- }
- }
- _tapTime = 0;
- } else {
- _tapTime = GetTickCount();
- _tapX = event.mouse.x;
- _tapY = event.mouse.y;
- }
- }
-
- 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()) {
- _toolbarHighDrawn = false;
- internUpdateScreen();
- }
- if (_newOrientation != _orientationLandscape){
- _orientationLandscape = _newOrientation;
- _toolbarHighDrawn = false;
- ConfMan.setInt("landscape", _orientationLandscape);
- ConfMan.flushToDisk();
- hotswapGFXMode();
- }
- return false;
- }
-
- return true;
-
- case SDL_MOUSEBUTTONUP:
- if (ev.button.button == SDL_BUTTON_LEFT)
- event.type = Common::EVENT_LBUTTONUP;
- else if (ev.button.button == SDL_BUTTON_RIGHT)
- event.type = Common::EVENT_RBUTTONUP;
- else
- break;
-
- if (_rbutton) {
- event.type = Common::EVENT_RBUTTONUP;
- _rbutton = false;
- }
-
- fillMouseEvent(event, ev.button.x, ev.button.y);
-
- 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)) {
- if (!_toolbarHandler.drawn()) {
- _toolbarHighDrawn = false;
- internUpdateScreen();
- }
- return false;
-
- }
- return true;
-
- case SDL_VIDEOEXPOSE:
- _forceFull = true;
- break;
-
- case SDL_QUIT:
- event.type = Common::EVENT_QUIT;
- return true;
-
- case SDL_ACTIVEEVENT:
- if (ev.active.state & SDL_APPMOUSEFOCUS)
- debug(2, "%s mouse focus.", ev.active.gain ? "Got" : "Lost");
- if (ev.active.state & SDL_APPINPUTFOCUS)
- debug(2, "%s input focus.", ev.active.gain ? "Got" : "Lost");
- if (ev.active.state & SDL_APPACTIVE)
- debug(2, "%s total focus.", ev.active.gain ? "Got" : "Lost");
- if (ev.active.state & SDL_APPINPUTFOCUS) {
- _hasfocus = ev.active.gain;
- SDL_PauseAudio(!_hasfocus);
- _forceFull |= _hasfocus;
- }
- break;
- }
- }
-
- // Simulate repeated key for backend
- if (!keyEvent && _lastKeyPressed && currentTime > _keyRepeatTime + _keyRepeatTrigger) {
- _keyRepeatTime = currentTime;
- _keyRepeat++;
- GUI_Actions::Instance()->performMapped(_lastKeyPressed, true);
- }
-
- return false;
}
void OSystem_WINCE3::quit() {
@@ -2508,8 +579,3 @@ void OSystem_WINCE3::getTimeAndDate(TimeDate &t) const {
int OSystem_WINCE3::_platformScreenWidth;
int OSystem_WINCE3::_platformScreenHeight;
bool OSystem_WINCE3::_isOzone;
-OSystem_WINCE3::zoneDesc OSystem_WINCE3::_zones[TOTAL_ZONES] = {
- { 0, 0, 320, 145 },
- { 0, 145, 150, 55 },
- { 150, 145, 170, 55 }
-};
diff --git a/backends/platform/wince/wince-sdl.h b/backends/platform/wince/wince-sdl.h
index 6cc6e538e1..34672f84df 100644
--- a/backends/platform/wince/wince-sdl.h
+++ b/backends/platform/wince/wince-sdl.h
@@ -35,7 +35,10 @@
#include "backends/platform/wince/CEkeys/CEKeys.h"
#include "backends/platform/wince/CEDevice.h"
-#define TOTAL_ZONES 3
+#include "backends/graphics/wincesdl/wincesdl-graphics.h"
+#include "backends/events/wincesdl/wincesdl-events.h"
+#include "backends/timer/default/default-timer.h"
+#include "backends/fs/windows/windows-fs-factory.h"
// defines used for implementing the raw frame buffer access method (2003+)
#define GETRAWFRAMEBUFFER 0x00020001
@@ -46,202 +49,45 @@
class OSystem_WINCE3 : public OSystem_SDL {
public:
OSystem_WINCE3();
-
- // Update the dirty areas of the screen
- void internUpdateScreen();
+ virtual ~OSystem_WINCE3();
void setGraphicsModeIntern();
- void initSize(uint w, uint h, const Graphics::PixelFormat *format);
void initBackend();
- // Overloaded from SDL backend (toolbar handling)
- bool pollEvent(Common::Event &event);
- // Overloaded from SDL backend (toolbar handling)
- void drawMouse();
- // Overloaded from SDL backend (mouse and new scaler handling)
- void fillMouseEvent(Common::Event &event, int x, int y);
- // Overloaded from SDL backend (new scaler handling)
- void addDirtyRect(int x, int y, int w, int h, bool mouseRect = false);
- // Overloaded from SDL backend (new scaler handling)
- void warpMouse(int x, int y);
// Overloaded from SDL backend
void quit();
- // Overloaded from SDL backend (master volume and sample rate subtleties)
- void setupMixer();
// Overloaded from OSystem
void engineInit();
void getTimeAndDate(TimeDate &t) const;
virtual Common::String getDefaultConfigFileName();
+ virtual FilesystemFactory *getFilesystemFactory();
-
- // Overloaded from SDL_Common (FIXME)
- void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // overloaded by CE backend
- void undrawMouse();
- void blitCursor();
- bool showMouse(bool visible);
- void setMousePos(int x, int y);
- void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); // overloaded by CE backend (FIXME)
- void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
- void showOverlay();
- void hideOverlay();
- Graphics::Surface *lockScreen();
- void unlockScreen();
-
- // GUI and action stuff
- void swap_panel_visibility();
- void swap_panel();
void swap_sound_master();
- void add_right_click(bool pushed);
- void swap_mouse_visibility();
- void swap_freeLook();
- void swap_zoom_up();
- void swap_zoom_down();
- void swap_smartphone_keyboard();
-
-//#ifdef WIN32_PLATFORM_WFSP
- // Smartphone actions
-
- void initZones();
- void loadDeviceConfigurationElement(String element, int &value, int defaultValue);
- void loadDeviceConfiguration();
- void add_left_click(bool pushed);
- void move_cursor_up();
- void move_cursor_down();
- void move_cursor_left();
- void move_cursor_right();
- void switch_zone();
- void smartphone_rotate_display();
-//#endif
static int getScreenWidth();
static int getScreenHeight();
static void initScreenInfos();
static bool isOzone();
-protected:
- bool loadGFXMode();
- void unloadGFXMode();
- bool hotswapGFXMode();
- bool saveScreenshot(const char *filename);
-
-
- const GraphicsMode *getSupportedGraphicsModes() const;
- bool setGraphicsMode(int mode);
- //int getGraphicsMode() const;
- int getDefaultGraphicsMode() const;
-
- bool hasFeature(Feature f);
- void setFeatureState(Feature f, bool enable);
- bool getFeatureState(Feature f);
+ static bool _soundMaster; // turn off sound after all calculations
+ // static since needed by the SDL callback
- void internDrawMouse();
- void drawToolbarMouse(SDL_Surface *surf, bool draw);
+protected:
+ void initSDL();
+ Audio::MixerImpl *_mixer;
+ DefaultTimerManager *_timer;
+ FilesystemFactory *_fsFactory;
private:
-
-#ifdef USE_VORBIS
- bool checkOggHighSampleRate();
-#endif
-
- static void private_sound_proc(void *param, byte *buf, int len);
-
- bool update_scalers();
- void create_toolbar();
- void update_game_settings();
void check_mappings();
- uint32 compute_sample_rate();
-
- void retrieve_mouse_location(int &x, int &y);
-
- CEGUI::ToolbarHandler _toolbarHandler;
-
- SDL_Surface *_toolbarLow; // toolbar 320x40
- SDL_Surface *_toolbarHigh; // toolbar 640x80
- bool _toolbarHighDrawn; // cache toolbar 640x80
-
- bool _freeLook; // freeLook mode (do not send mouse button events)
-
- bool _forceHideMouse; // force invisible mouse cursor
bool _forcePanelInvisible; // force panel visibility for some cases
- bool _panelVisible; // panel visibility
- bool _panelStateForced; // panel visibility forced by external call
-
- bool _panelInitialized; // only initialize the toolbar once
-
- bool _unfilteredkeys; // discard key mapping temporarily (agi pred. dialog)
- static bool _soundMaster; // turn off sound after all calculations
- // static since needed by the SDL callback
- int _orientationLandscape; // current orientation
- int _newOrientation; // new orientation
-
- bool _saveToolbarState; // save visibility when forced
- String _saveActiveToolbar; // save active toolbar when forced
-
- bool _saveToolbarZoom; // save visibility when zooming
- bool _zoomUp; // zooming up mode
- bool _zoomDown; // zooming down mode
-
- bool _noDoubleTapRMB; // disable double tap -> rmb click
- bool _rbutton; // double tap -> right button simulation
- bool _closeClick; // flag when taps are spatially close together
-
- bool _usesEmulatedMouse; // emulated mousemove ever been used in this session
-
- bool _canBeAspectScaled; // game screen size allows for aspect scaling
-
- int _scaleFactorXm; // scaler X *
- int _scaleFactorXd; // scaler X /
- int _scaleFactorYm; // scaler Y *
- int _scaleFactorYd; // scaler Y /
- SDL_Rect _dirtyRectOut[NUM_DIRTY_RECT];
- bool _scalersChanged;
- bool _hasfocus; // scummvm has the top window
static int _platformScreenWidth;
static int _platformScreenHeight;
static bool _isOzone; // true if running on Windows 2003 SE
- // Keyboard tap
- int _tapX;
- int _tapY;
- long _tapTime;
-
- // Mouse
- int _mouseHotspotX, _mouseHotspotY;
- byte *_mouseBackupOld;
- uint16 *_mouseBackupToolbar;
- uint16 _mouseBackupDim;
-
- // Smartphone specific variables
-
- int _lastKeyPressed; // last key pressed
- int _keyRepeat; // number of time the last key was repeated
- int _keyRepeatTime; // elapsed time since the key was pressed
- int _keyRepeatTrigger; // minimum time to consider the key was repeated
-
- int _repeatX; // repeat trigger for left and right cursor moves
- int _repeatY; // repeat trigger for up and down cursor moves
- int _stepX1; // offset for left and right cursor moves (slowest)
- int _stepX2; // offset for left and right cursor moves (faster)
- int _stepX3; // offset for left and right cursor moves (fastest)
- int _stepY1; // offset for up and down cursor moves (slowest)
- int _stepY2; // offset for up and down cursor moves (faster)
- int _stepY3; // offset for up and down cursor moves (fastest)
-
- int _mouseXZone[TOTAL_ZONES];
- int _mouseYZone[TOTAL_ZONES];
- int _currentZone;
-
- struct zoneDesc {
- int x;
- int y;
- int width;
- int height;
- };
-
- static zoneDesc _zones[TOTAL_ZONES];
};
#endif