Ticket #9287: scummvm-df1a800-wince.patch
File scummvm-df1a800-wince.patch, 160.2 KB (added by , 13 years ago) |
---|
-
backends/events/wincesdl/wincesdl-events.cpp
diff -rupN scummvm-df1a800-orig/backends/events/wincesdl/wincesdl-events.cpp scummvm-git/backends/events/wincesdl/wincesdl-events.cpp
old new 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 * 24 */ 25 26 #include "common/scummsys.h" 27 28 #ifdef _WIN32_WCE 29 30 #include "common/config-manager.h" 31 32 #include "backends/events/wincesdl/wincesdl-events.h" 33 #include "backends/graphics/wincesdl/wincesdl-graphics.h" 34 #include "backends/platform/wince/CEActionsPocket.h" 35 #include "backends/platform/wince/CEActionsSmartphone.h" 36 #include "backends/platform/wince/CEDevice.h" 37 38 #include "backends/platform/sdl/sdl.h" 39 40 WINCESdlEventSource::WINCESdlEventSource() 41 : _tapTime(0), _closeClick(false), _rbutton(false), 42 _freeLook(false) { 43 } 44 45 void WINCESdlEventSource::fillMouseEvent(Common::Event &event, int x, int y) { 46 event.mouse.x = x; 47 event.mouse.y = y; 48 49 // Update the "keyboard mouse" coords 50 _km.x = event.mouse.x; 51 _km.y = event.mouse.y; 52 53 // Adjust for the screen scaling 54 if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_zoomDown) 55 event.mouse.y += 240; 56 57 event.mouse.x = event.mouse.x * ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_scaleFactorXd / ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_scaleFactorXm; 58 event.mouse.y = event.mouse.y * ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_scaleFactorYd / ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_scaleFactorYm; 59 } 60 61 bool WINCESdlEventSource::pollEvent(Common::Event &event) { 62 SDL_Event ev; 63 ev.type = SDL_NOEVENT; 64 DWORD currentTime; 65 bool keyEvent = false; 66 int deltaX, deltaY; 67 68 memset(&event, 0, sizeof(Common::Event)); 69 70 handleKbdMouse(); 71 72 // If the screen changed, send an Common::EVENT_SCREEN_CHANGED 73 int screenID = ((OSystem_SDL *)g_system)->getGraphicsManager()->getScreenChangeID(); 74 if (screenID != _lastScreenID) { 75 _lastScreenID = screenID; 76 event.type = Common::EVENT_SCREEN_CHANGED; 77 return true; 78 } 79 80 CEDevice::wakeUp(); 81 82 currentTime = GetTickCount(); 83 84 while (SDL_PollEvent(&ev)) { 85 switch (ev.type) { 86 case SDL_KEYDOWN: 87 debug(1, "Key down %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym)); 88 // KMOD_RESERVED is used if the key has been injected by an external buffer 89 if (ev.key.keysym.mod != KMOD_RESERVED && !GUI::Actions::Instance()->mappingActive()) { 90 keyEvent = true; 91 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed = ev.key.keysym.sym; 92 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeatTime = currentTime; 93 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeat = 0; 94 95 if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, true)) 96 return true; 97 } 98 99 if (GUI_Actions::Instance()->mappingActive()) 100 event.kbd.flags = 0xFF; 101 else if (ev.key.keysym.sym == SDLK_PAUSE) { 102 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed = 0; 103 event.type = Common::EVENT_PREDICTIVE_DIALOG; 104 return true; 105 } event.type = Common::EVENT_KEYDOWN; 106 if (!GUI::Actions::Instance()->mappingActive()) 107 event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym; 108 else 109 event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive()); 110 event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive()); 111 112 if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) { 113 event.kbd.ascii ^= 0x20; 114 event.kbd.flags = Common::KBD_SHIFT; 115 } 116 117 return true; 118 119 case SDL_KEYUP: 120 debug(1, "Key up %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym)); 121 // KMOD_RESERVED is used if the key has been injected by an external buffer 122 if (ev.key.keysym.mod != KMOD_RESERVED && !GUI::Actions::Instance()->mappingActive()) { 123 keyEvent = true; 124 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed = 0; 125 126 if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, false)) 127 return true; 128 } 129 130 if (GUI_Actions::Instance()->mappingActive()) 131 event.kbd.flags = 0xFF; 132 else if (ev.key.keysym.sym == SDLK_PAUSE) { 133 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed = 0; 134 return false; // chew up the show agi dialog key up event 135 } 136 137 event.type = Common::EVENT_KEYUP; 138 if (!GUI::Actions::Instance()->mappingActive()) 139 event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym; 140 else 141 event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive()); 142 event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive()); 143 144 if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) { 145 event.kbd.ascii ^= 0x20; 146 event.kbd.flags = Common::KBD_SHIFT; 147 } 148 149 return true; 150 151 case SDL_MOUSEMOTION: 152 event.type = Common::EVENT_MOUSEMOVE; 153 fillMouseEvent(event, ev.motion.x, ev.motion.y); 154 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->setMousePos(event.mouse.x, event.mouse.y); 155 156 return true; 157 158 case SDL_MOUSEBUTTONDOWN: 159 if (ev.button.button == SDL_BUTTON_LEFT) 160 event.type = Common::EVENT_LBUTTONDOWN; 161 else if (ev.button.button == SDL_BUTTON_RIGHT) 162 event.type = Common::EVENT_RBUTTONDOWN; 163 else 164 break; 165 fillMouseEvent(event, ev.button.x, ev.button.y); 166 167 168 if (event.mouse.x > _tapX) 169 deltaX = event.mouse.x - _tapX; 170 else 171 deltaX = _tapX - event.mouse.x; 172 if (event.mouse.y > _tapY) 173 deltaY = event.mouse.y - _tapY; 174 else 175 deltaY = _tapY - event.mouse.y; 176 _closeClick = (deltaX <= 5 && deltaY <= 5); 177 178 if (!_isSmartphone) { 179 // handle double-taps 180 if (_tapTime) { // second tap 181 if (_closeClick && (GetTickCount() - _tapTime < 1000)) { 182 if ( event.mouse.y <= 20 && 183 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_panelInitialized) { 184 // top of screen (show panel) 185 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_panel_visibility(); 186 } else if (!((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_noDoubleTapRMB) { 187 // right click 188 event.type = Common::EVENT_RBUTTONDOWN; 189 _rbutton = true; 190 } 191 } 192 _tapTime = 0; 193 } else { 194 _tapTime = GetTickCount(); 195 _tapX = event.mouse.x; 196 _tapY = event.mouse.y; 197 } 198 } 199 200 if (_freeLook && !_closeClick) { 201 _rbutton = false; 202 _tapTime = 0; 203 _tapX = event.mouse.x; 204 _tapY = event.mouse.y; 205 event.type = Common::EVENT_MOUSEMOVE; 206 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->setMousePos(event.mouse.x, event.mouse.y); 207 } 208 209 210 if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHandler.action(event.mouse.x, event.mouse.y, true)) { 211 if (!((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHandler.drawn()) { 212 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHighDrawn = false; 213 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->internUpdateScreen(); 214 } 215 if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_newOrientation != ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_orientationLandscape){ 216 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_orientationLandscape = ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_newOrientation; 217 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHighDrawn = false; 218 ConfMan.setInt("landscape", ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_orientationLandscape); 219 ConfMan.flushToDisk(); 220 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->hotswapGFXMode(); 221 } 222 return false; 223 } 224 225 return true; 226 227 case SDL_MOUSEBUTTONUP: 228 if (ev.button.button == SDL_BUTTON_LEFT) 229 event.type = Common::EVENT_LBUTTONUP; 230 else if (ev.button.button == SDL_BUTTON_RIGHT) 231 event.type = Common::EVENT_RBUTTONUP; 232 else 233 break; 234 235 if (_rbutton) { 236 event.type = Common::EVENT_RBUTTONUP; 237 _rbutton = false; 238 } 239 240 fillMouseEvent(event, ev.button.x, ev.button.y); 241 242 if (_freeLook && !_closeClick) { 243 _tapX = event.mouse.x; 244 _tapY = event.mouse.y; 245 event.type = Common::EVENT_MOUSEMOVE; 246 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->setMousePos(event.mouse.x, event.mouse.y); 247 } 248 249 if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHandler.action(event.mouse.x, event.mouse.y, false)) { 250 if (!((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHandler.drawn()) { 251 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_toolbarHighDrawn = false; 252 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->internUpdateScreen(); 253 } 254 return false; 255 256 } 257 return true; 258 259 case SDL_VIDEOEXPOSE: 260 // HACK: Send a fake event, handled by SdlGraphicsManager 261 event.type = (Common::EventType)OSystem_SDL::kSdlEventExpose; 262 break; 263 264 case SDL_QUIT: 265 event.type = Common::EVENT_QUIT; 266 return true; 267 268 case SDL_ACTIVEEVENT: 269 if (ev.active.state & SDL_APPMOUSEFOCUS) 270 debug(2, "%s mouse focus.", ev.active.gain ? "Got" : "Lost"); 271 if (ev.active.state & SDL_APPINPUTFOCUS) 272 debug(2, "%s input focus.", ev.active.gain ? "Got" : "Lost"); 273 if (ev.active.state & SDL_APPACTIVE) 274 debug(2, "%s total focus.", ev.active.gain ? "Got" : "Lost"); 275 if (ev.active.state & SDL_APPINPUTFOCUS) { 276 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_hasfocus = ev.active.gain; 277 SDL_PauseAudio(!((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_hasfocus); 278 if (((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_hasfocus) { 279 event.type = (Common::EventType)OSystem_SDL::kSdlEventExpose; 280 } 281 } 282 break; 283 } 284 } 285 286 // Simulate repeated key for backend 287 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) { 288 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeatTime = currentTime; 289 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_keyRepeat++; 290 GUI_Actions::Instance()->performMapped(((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->_lastKeyPressed, true); 291 } 292 293 return false; 294 } 295 296 int WINCESdlEventSource::mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode, bool unfilter) { 297 if (GUI::Actions::Instance()->mappingActive()) 298 return key; 299 300 if (unfilter) { 301 switch (key) { 302 case SDLK_ESCAPE: 303 return SDLK_BACKSPACE; 304 case SDLK_F8: 305 return SDLK_ASTERISK; 306 case SDLK_F9: 307 return SDLK_HASH; 308 default: 309 return key; 310 } 311 } 312 313 if (key >= SDLK_KP0 && key <= SDLK_KP9) { 314 return key - SDLK_KP0 + '0'; 315 } else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) { 316 return key; 317 } else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) { 318 return 0; 319 } 320 return key; 321 } 322 323 void WINCESdlEventSource::swap_freeLook() { 324 _freeLook = !_freeLook; 325 } 326 327 #endif /* _WIN32_WCE */ -
backends/events/wincesdl/wincesdl-events.h
diff -rupN scummvm-df1a800-orig/backends/events/wincesdl/wincesdl-events.h scummvm-git/backends/events/wincesdl/wincesdl-events.h
old new 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 * 24 */ 25 26 #ifndef BACKENDS_EVENTS_SDL_WINCE_H 27 #define BACKENDS_EVENTS_SDL_WINCE_H 28 29 #include "backends/events/sdl/sdl-events.h" 30 31 extern bool _isSmartphone; 32 33 class WINCESdlEventSource : public SdlEventSource { 34 public: 35 WINCESdlEventSource(); 36 37 void loadDeviceConfiguration(); 38 39 // Overloaded from SDL backend (toolbar handling) 40 bool pollEvent(Common::Event &event); 41 // Overloaded from SDL backend (mouse and new scaler handling) 42 void fillMouseEvent(Common::Event &event, int x, int y); 43 44 void swap_freeLook(); 45 46 protected: 47 48 private: 49 int mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode, bool unfilter); 50 51 // Keyboard tap 52 int _tapX; 53 int _tapY; 54 long _tapTime; 55 56 bool _closeClick; // flag when taps are spatially close together 57 bool _rbutton; // double tap -> right button simulation 58 bool _freeLook; // freeLook mode (do not send mouse button events) 59 60 }; 61 62 #endif /* BACKENDS_EVENTS_SDL_WINCE_H */ -
backends/graphics/sdl/sdl-graphics.cpp
diff -rupN scummvm-df1a800-orig/backends/graphics/sdl/sdl-graphics.cpp scummvm-git/backends/graphics/sdl/sdl-graphics.cpp
old new SdlGraphicsManager::SdlGraphicsManager(S 161 161 162 162 _graphicsMutex = g_system->createMutex(); 163 163 164 #ifdef _WIN32_WCE165 if (ConfMan.hasKey("use_GDI") && ConfMan.getBool("use_GDI")) {166 SDL_VideoInit("windib", 0);167 sdlFlags ^= SDL_INIT_VIDEO;168 }169 #endif170 171 164 SDL_ShowCursor(SDL_DISABLE); 172 165 173 166 memset(&_oldVideoMode, 0, sizeof(_oldVideoMode)); -
backends/graphics/wincesdl/wincesdl-graphics.cpp
diff -rupN scummvm-df1a800-orig/backends/graphics/wincesdl/wincesdl-graphics.cpp scummvm-git/backends/graphics/wincesdl/wincesdl-graphics.cpp
old new 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 * 24 */ 25 26 #include "common/scummsys.h" 27 28 #ifdef _WIN32_WCE 29 30 #include "common/system.h" 31 #include "common/translation.h" 32 #include "common/mutex.h" 33 34 #include "graphics/scaler/downscaler.h" 35 #include "graphics/scaler/aspect.h" 36 #include "backends/graphics/wincesdl/wincesdl-graphics.h" 37 #include "backends/events/wincesdl/wincesdl-events.h" 38 #include "backends/platform/wince/wince-sdl.h" 39 40 #include "backends/platform/wince/resource.h" 41 #include "backends/platform/wince/CEActionsPocket.h" 42 #include "backends/platform/wince/CEActionsSmartphone.h" 43 #include "backends/platform/wince/CEDevice.h" 44 #include "backends/platform/wince/CEScaler.h" 45 #include "backends/platform/wince/CEgui/ItemAction.h" 46 47 WINCESdlGraphicsManager::WINCESdlGraphicsManager(SdlEventSource *sdlEventSource) 48 : SdlGraphicsManager(sdlEventSource), 49 _panelInitialized(false), _noDoubleTapRMB(false), 50 _toolbarHighDrawn(false), _newOrientation(0), _orientationLandscape(0), 51 _panelVisible(true), _saveActiveToolbar(NAME_MAIN_PANEL), _panelStateForced(false), 52 _canBeAspectScaled(false), _scalersChanged(false), _saveToolbarState(false), 53 _mouseBackupOld(NULL), _mouseBackupDim(0), _mouseBackupToolbar(NULL), 54 _usesEmulatedMouse(false), _forceHideMouse(false), _hasfocus(true), 55 _zoomUp(false), _zoomDown(false) { 56 memset(&_mouseCurState, 0, sizeof(_mouseCurState)); 57 if (_isSmartphone) { 58 _mouseCurState.x = 20; 59 _mouseCurState.y = 20; 60 } 61 62 loadDeviceConfigurationElement("repeatTrigger", _keyRepeatTrigger, 200); 63 loadDeviceConfigurationElement("repeatX", _repeatX, 4); 64 loadDeviceConfigurationElement("repeatY", _repeatY, 4); 65 loadDeviceConfigurationElement("stepX1", _stepX1, 2); 66 loadDeviceConfigurationElement("stepX2", _stepX2, 10); 67 loadDeviceConfigurationElement("stepX3", _stepX3, 40); 68 loadDeviceConfigurationElement("stepY1", _stepY1, 2); 69 loadDeviceConfigurationElement("stepY2", _stepY2, 10); 70 loadDeviceConfigurationElement("stepY3", _stepY3, 20); 71 ConfMan.flushToDisk(); 72 73 _isSmartphone = CEDevice::isSmartphone(); 74 75 // Query SDL for screen size and init screen dependent stuff 76 OSystem_WINCE3::initScreenInfos(); 77 create_toolbar(); 78 _hasSmartphoneResolution = CEDevice::hasSmartphoneResolution() || CEDevice::isSmartphone(); 79 if (_hasSmartphoneResolution) 80 _panelVisible = false; // init correctly in smartphones 81 82 _screen = NULL; 83 } 84 85 // Graphics mode consts 86 87 // Low end devices 240x320 88 89 static const OSystem::GraphicsMode s_supportedGraphicsModesLow[] = { 90 {"1x", _s("Normal (no scaling)"), GFX_NORMAL}, 91 {0, 0, 0} 92 }; 93 94 // High end device 480x640 95 96 static const OSystem::GraphicsMode s_supportedGraphicsModesHigh[] = { 97 {"1x", _s("Normal (no scaling)"), GFX_NORMAL}, 98 {"2x", "2x", GFX_DOUBLESIZE}, 99 #ifndef _MSC_VER // EVC breaks template functions, and I'm tired of fixing them :) 100 {"2xsai", "2xSAI", GFX_2XSAI}, 101 {"super2xsai", "Super2xSAI", GFX_SUPER2XSAI}, 102 {"supereagle", "SuperEagle", GFX_SUPEREAGLE}, 103 #endif 104 {"advmame2x", "AdvMAME2x", GFX_ADVMAME2X}, 105 #ifndef _MSC_VER 106 {"hq2x", "HQ2x", GFX_HQ2X}, 107 {"tv2x", "TV2x", GFX_TV2X}, 108 #endif 109 {"dotmatrix", "DotMatrix", GFX_DOTMATRIX}, 110 {0, 0, 0} 111 }; 112 113 const OSystem::GraphicsMode *WINCESdlGraphicsManager::getSupportedGraphicsModes() const { 114 if (CEDevice::hasWideResolution()) 115 return s_supportedGraphicsModesHigh; 116 else 117 return s_supportedGraphicsModesLow; 118 } 119 120 bool WINCESdlGraphicsManager::hasFeature(OSystem::Feature f) { 121 return (f == OSystem::kFeatureVirtualKeyboard); 122 } 123 124 void WINCESdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) { 125 switch (f) { 126 case OSystem::kFeatureFullscreenMode: 127 return; 128 129 case OSystem::kFeatureVirtualKeyboard: 130 if (_hasSmartphoneResolution) 131 return; 132 _toolbarHighDrawn = false; 133 if (enable) { 134 _panelStateForced = true; 135 if (!_toolbarHandler.visible()) swap_panel_visibility(); 136 //_saveToolbarState = _toolbarHandler.visible(); 137 _saveActiveToolbar = _toolbarHandler.activeName(); 138 _toolbarHandler.setActive(NAME_PANEL_KEYBOARD); 139 _toolbarHandler.setVisible(true); 140 } else 141 if (_panelStateForced) { 142 _panelStateForced = false; 143 _toolbarHandler.setActive(_saveActiveToolbar); 144 //_toolbarHandler.setVisible(_saveToolbarState); 145 } 146 return; 147 148 case OSystem::kFeatureDisableKeyFiltering: 149 if (_hasSmartphoneResolution) { 150 GUI::Actions::Instance()->beginMapping(enable); 151 } 152 return; 153 154 default: 155 SdlGraphicsManager::setFeatureState(f, enable); 156 } 157 } 158 159 bool WINCESdlGraphicsManager::getFeatureState(OSystem::Feature f) { 160 switch (f) { 161 case OSystem::kFeatureFullscreenMode: 162 return false; 163 case OSystem::kFeatureVirtualKeyboard: 164 return (_panelStateForced); 165 default: 166 return SdlGraphicsManager::getFeatureState(f); 167 } 168 } 169 170 int WINCESdlGraphicsManager::getDefaultGraphicsMode() const { 171 return GFX_NORMAL; 172 } 173 174 void WINCESdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFormat *format) { 175 if (_hasSmartphoneResolution && h == 240) 176 h = 200; // mainly for the launcher 177 178 if (_isSmartphone && !ConfMan.hasKey("landscape")) { 179 ConfMan.setInt("landscape", 1); 180 ConfMan.flushToDisk(); 181 } 182 183 _canBeAspectScaled = false; 184 if (w == 320 && h == 200 && !_hasSmartphoneResolution) { 185 _canBeAspectScaled = true; 186 h = 240; // use the extra 40 pixels height for the toolbar 187 } 188 189 if (h == 400) // touche engine fixup 190 h += 80; 191 192 if (!_hasSmartphoneResolution) { 193 if (h == 240) 194 _toolbarHandler.setOffset(200); 195 else 196 _toolbarHandler.setOffset(400); 197 } else { 198 if (h == 240) 199 _toolbarHandler.setOffset(200); 200 else // 176x220 201 _toolbarHandler.setOffset(0); 202 } 203 204 if (w != (uint) _videoMode.screenWidth || h != (uint) _videoMode.screenHeight) 205 _scalersChanged = false; 206 207 _videoMode.overlayWidth = w; 208 _videoMode.overlayHeight = h; 209 210 SdlGraphicsManager::initSize(w, h, format); 211 212 if (_scalersChanged) { 213 unloadGFXMode(); 214 loadGFXMode(); 215 _scalersChanged = false; 216 } 217 218 update_game_settings(); 219 } 220 221 void WINCESdlGraphicsManager::loadDeviceConfigurationElement(Common::String element, int &value, int defaultValue) { 222 value = ConfMan.getInt(element, ConfMan.kApplicationDomain); 223 if (!value) { 224 value = defaultValue; 225 ConfMan.setInt(element, value, ConfMan.kApplicationDomain); 226 } 227 } 228 229 void WINCESdlGraphicsManager::move_cursor_up() { 230 int x, y; 231 _usesEmulatedMouse = true; 232 retrieve_mouse_location(x, y); 233 if (_keyRepeat > _repeatY) 234 y -= _stepY3; 235 else if (_keyRepeat) 236 y -= _stepY2; 237 else 238 y -= _stepY1; 239 240 if (y < 0) 241 y = 0; 242 243 EventsBuffer::simulateMouseMove(x, y); 244 } 245 246 void WINCESdlGraphicsManager::move_cursor_down() { 247 int x, y; 248 _usesEmulatedMouse = true; 249 retrieve_mouse_location(x, y); 250 if (_keyRepeat > _repeatY) 251 y += _stepY3; 252 else if (_keyRepeat) 253 y += _stepY2; 254 else 255 y += _stepY1; 256 257 if (y > _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd) 258 y = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd; 259 260 EventsBuffer::simulateMouseMove(x, y); 261 } 262 263 void WINCESdlGraphicsManager::move_cursor_left() { 264 int x, y; 265 _usesEmulatedMouse = true; 266 retrieve_mouse_location(x, y); 267 if (_keyRepeat > _repeatX) 268 x -= _stepX3; 269 else if (_keyRepeat) 270 x -= _stepX2; 271 else 272 x -= _stepX1; 273 274 if (x < 0) 275 x = 0; 276 277 EventsBuffer::simulateMouseMove(x, y); 278 } 279 280 void WINCESdlGraphicsManager::move_cursor_right() { 281 int x, y; 282 _usesEmulatedMouse = true; 283 retrieve_mouse_location(x, y); 284 if (_keyRepeat > _repeatX) 285 x += _stepX3; 286 else if (_keyRepeat) 287 x += _stepX2; 288 else 289 x += _stepX1; 290 291 if (x > _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd) 292 x = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd; 293 294 EventsBuffer::simulateMouseMove(x, y); 295 } 296 297 void WINCESdlGraphicsManager::retrieve_mouse_location(int &x, int &y) { 298 x = _mouseCurState.x; 299 y = _mouseCurState.y; 300 301 x = x * _scaleFactorXm / _scaleFactorXd; 302 y = y * _scaleFactorYm / _scaleFactorYd; 303 304 if (_zoomDown) 305 y -= 240; 306 } 307 308 void WINCESdlGraphicsManager::switch_zone() { 309 int x, y; 310 int i; 311 retrieve_mouse_location(x, y); 312 313 for (i = 0; i < TOTAL_ZONES; i++) 314 if (x >= _zones[i].x && y >= _zones[i].y && 315 x <= _zones[i].x + _zones[i].width && y <= _zones[i].y + _zones[i].height) { 316 _mouseXZone[i] = x; 317 _mouseYZone[i] = y; 318 break; 319 } 320 _currentZone = i + 1; 321 if (_currentZone >= TOTAL_ZONES) 322 _currentZone = 0; 323 324 EventsBuffer::simulateMouseMove(_mouseXZone[_currentZone], _mouseYZone[_currentZone]); 325 } 326 327 void WINCESdlGraphicsManager::add_right_click(bool pushed) { 328 int x, y; 329 retrieve_mouse_location(x, y); 330 EventsBuffer::simulateMouseRightClick(x, y, pushed); 331 } 332 333 void WINCESdlGraphicsManager::add_left_click(bool pushed) { 334 int x, y; 335 retrieve_mouse_location(x, y); 336 EventsBuffer::simulateMouseLeftClick(x, y, pushed); 337 } 338 339 bool WINCESdlGraphicsManager::update_scalers() { 340 _videoMode.aspectRatioCorrection = false; 341 342 if (CEDevice::hasPocketPCResolution()) { 343 if (_videoMode.mode != GFX_NORMAL) 344 return false; 345 346 if ((!_orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth)) 347 || CEDevice::hasSquareQVGAResolution() ) { 348 if (OSystem_WINCE3::getScreenWidth() != 320) { 349 _scaleFactorXm = 3; 350 _scaleFactorXd = 4; 351 _scaleFactorYm = 1; 352 _scaleFactorYd = 1; 353 _scalerProc = DownscaleHorizByThreeQuarters; 354 } else { 355 _scaleFactorXm = 1; 356 _scaleFactorXd = 1; 357 _scaleFactorYm = 1; 358 _scaleFactorYd = 1; 359 _scalerProc = Normal1x; 360 } 361 } else if ( _orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth)) { 362 if (!_panelVisible && !_hasSmartphoneResolution && !_overlayVisible && _canBeAspectScaled) { 363 _scaleFactorXm = 1; 364 _scaleFactorXd = 1; 365 _scaleFactorYm = 6; 366 _scaleFactorYd = 5; 367 _scalerProc = Normal1xAspect; 368 _videoMode.aspectRatioCorrection = true; 369 } else { 370 _scaleFactorXm = 1; 371 _scaleFactorXd = 1; 372 _scaleFactorYm = 1; 373 _scaleFactorYd = 1; 374 _scalerProc = Normal1x; 375 } 376 } else if (_videoMode.screenWidth == 640 && !(OSystem_WINCE3::isOzone() && (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640))) { 377 _scaleFactorXm = 1; 378 _scaleFactorXd = 2; 379 _scaleFactorYm = 1; 380 _scaleFactorYd = 2; 381 _scalerProc = DownscaleAllByHalf; 382 } else if (_videoMode.screenWidth == 640 && (OSystem_WINCE3::isOzone() && (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640))) { 383 _scaleFactorXm = 1; 384 _scaleFactorXd = 1; 385 _scaleFactorYm = 1; 386 _scaleFactorYd = 1; 387 _scalerProc = Normal1x; 388 } 389 390 return true; 391 } else if (CEDevice::hasWideResolution()) { 392 #ifdef USE_ARM_SCALER_ASM 393 if ( _videoMode.mode == GFX_DOUBLESIZE && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth) ) { 394 if ( !_panelVisible && !_overlayVisible && _canBeAspectScaled ) { 395 _scaleFactorXm = 2; 396 _scaleFactorXd = 1; 397 _scaleFactorYm = 12; 398 _scaleFactorYd = 5; 399 _scalerProc = Normal2xAspect; 400 _videoMode.aspectRatioCorrection = true; 401 } else if ( (_panelVisible || _overlayVisible) && _canBeAspectScaled ) { 402 _scaleFactorXm = 2; 403 _scaleFactorXd = 1; 404 _scaleFactorYm = 2; 405 _scaleFactorYd = 1; 406 _scalerProc = Normal2x; 407 } 408 return true; 409 } 410 #endif 411 } else if (CEDevice::hasSmartphoneResolution()) { 412 if (_videoMode.mode != GFX_NORMAL) 413 return false; 414 415 if (_videoMode.screenWidth > 320) 416 error("Game resolution not supported on Smartphone"); 417 #ifdef ARM 418 _scaleFactorXm = 11; 419 _scaleFactorXd = 16; 420 #else 421 _scaleFactorXm = 2; 422 _scaleFactorXd = 3; 423 #endif 424 _scaleFactorYm = 7; 425 _scaleFactorYd = 8; 426 _scalerProc = SmartphoneLandscape; 427 initZones(); 428 return true; 429 } 430 431 return false; 432 } 433 434 void WINCESdlGraphicsManager::update_game_settings() { 435 Common::String gameid(ConfMan.get("gameid")); 436 437 // Finish panel initialization 438 if (!_panelInitialized && !gameid.empty()) { 439 CEGUI::Panel *panel; 440 _panelInitialized = true; 441 // Add the main panel 442 panel = new CEGUI::Panel(0, 32); 443 panel->setBackground(IMAGE_PANEL); 444 445 // Save 446 panel->add(NAME_ITEM_OPTIONS, new CEGUI::ItemAction(ITEM_OPTIONS, POCKET_ACTION_SAVE)); 447 // Skip 448 panel->add(NAME_ITEM_SKIP, new CEGUI::ItemAction(ITEM_SKIP, POCKET_ACTION_SKIP)); 449 // sound 450 //__XXX__ panel->add(NAME_ITEM_SOUND, new CEGUI::ItemSwitch(ITEM_SOUND_OFF, ITEM_SOUND_ON, &_soundMaster)); 451 panel->add(NAME_ITEM_SOUND, new CEGUI::ItemSwitch(ITEM_SOUND_OFF, ITEM_SOUND_ON, &OSystem_WINCE3::_soundMaster)); 452 453 // bind keys 454 panel->add(NAME_ITEM_BINDKEYS, new CEGUI::ItemAction(ITEM_BINDKEYS, POCKET_ACTION_BINDKEYS)); 455 // portrait/landscape - screen dependent 456 // FIXME : will still display the portrait/landscape icon when using a scaler (but will be disabled) 457 if (ConfMan.hasKey("landscape")) { 458 if (ConfMan.get("landscape")[0] > 57) { 459 _newOrientation = _orientationLandscape = ConfMan.getBool("landscape"); 460 //ConfMan.removeKey("landscape", ""); 461 ConfMan.setInt("landscape", _orientationLandscape); 462 } else 463 _newOrientation = _orientationLandscape = ConfMan.getInt("landscape"); 464 } else { 465 _newOrientation = _orientationLandscape = 0; 466 } 467 panel->add(NAME_ITEM_ORIENTATION, new CEGUI::ItemSwitch(ITEM_VIEW_LANDSCAPE, ITEM_VIEW_PORTRAIT, &_newOrientation, 2)); 468 _toolbarHandler.add(NAME_MAIN_PANEL, *panel); 469 _toolbarHandler.setActive(NAME_MAIN_PANEL); 470 _toolbarHandler.setVisible(true); 471 472 if (_videoMode.mode == GFX_NORMAL && ConfMan.hasKey("landscape") && ConfMan.getInt("landscape")) { 473 setGraphicsMode(GFX_NORMAL); 474 hotswapGFXMode(); 475 } 476 477 if (_hasSmartphoneResolution) 478 panel->setVisible(false); 479 480 _saveToolbarState = true; 481 } 482 483 if (ConfMan.hasKey("no_doubletap_rightclick")) 484 _noDoubleTapRMB = ConfMan.getBool("no_doubletap_rightclick"); 485 } 486 487 void WINCESdlGraphicsManager::internUpdateScreen() { 488 SDL_Surface *srcSurf, *origSurf; 489 static bool old_overlayVisible = false; 490 int numRectsOut = 0; 491 int16 routx, routy, routw, routh, stretch, shakestretch; 492 493 assert(_hwscreen != NULL); 494 495 // bail if the application is minimized, be nice to OS 496 if (!_hasfocus) { 497 Sleep(20); 498 return; 499 } 500 501 // If the shake position changed, fill the dirty area with blackness 502 if (_currentShakePos != _newShakePos) { 503 SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd, _newShakePos * _scaleFactorYm / _scaleFactorYd}; 504 if (_videoMode.aspectRatioCorrection) 505 blackrect.h = real2Aspect(blackrect.h - 1) + 1; 506 SDL_FillRect(_hwscreen, &blackrect, 0); 507 _currentShakePos = _newShakePos; 508 _forceFull = true; 509 } 510 511 // Make sure the mouse is drawn, if it should be drawn. 512 drawMouse(); 513 514 // Check whether the palette was changed in the meantime and update the 515 // screen surface accordingly. 516 if (_paletteDirtyEnd != 0) { 517 SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart, _paletteDirtyStart, _paletteDirtyEnd - _paletteDirtyStart); 518 _paletteDirtyEnd = 0; 519 _forceFull = true; 520 } 521 522 if (!_overlayVisible) { 523 origSurf = _screen; 524 srcSurf = _tmpscreen; 525 } else { 526 origSurf = _overlayscreen; 527 srcSurf = _tmpscreen2; 528 } 529 530 if (old_overlayVisible != _overlayVisible) { 531 old_overlayVisible = _overlayVisible; 532 update_scalers(); 533 } 534 535 // Force a full redraw if requested 536 if (_forceFull) { 537 _numDirtyRects = 1; 538 539 _dirtyRectList[0].x = 0; 540 if (!_zoomDown) 541 _dirtyRectList[0].y = 0; 542 else 543 _dirtyRectList[0].y = _videoMode.screenHeight / 2; 544 _dirtyRectList[0].w = _videoMode.screenWidth; 545 if (!_zoomUp && !_zoomDown) 546 _dirtyRectList[0].h = _videoMode.screenHeight; 547 else 548 _dirtyRectList[0].h = _videoMode.screenHeight / 2; 549 550 _toolbarHandler.forceRedraw(); 551 } 552 553 // Only draw anything if necessary 554 if (_numDirtyRects > 0) { 555 556 SDL_Rect *r, *rout; 557 SDL_Rect dst; 558 uint32 srcPitch, dstPitch; 559 SDL_Rect *last_rect = _dirtyRectList + _numDirtyRects; 560 bool toolbarVisible = _toolbarHandler.visible(); 561 int toolbarOffset = _toolbarHandler.getOffset(); 562 563 for (r = _dirtyRectList; r != last_rect; ++r) { 564 dst = *r; 565 dst.x++; // Shift rect by one since 2xSai needs to access the data around 566 dst.y++; // any pixel to scale it, and we want to avoid mem access crashes. 567 // NOTE: This is also known as BLACK MAGIC, copied from the sdl backend 568 if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0) 569 error("SDL_BlitSurface failed: %s", SDL_GetError()); 570 } 571 572 SDL_LockSurface(srcSurf); 573 SDL_LockSurface(_hwscreen); 574 575 srcPitch = srcSurf->pitch; 576 dstPitch = _hwscreen->pitch; 577 578 for (r = _dirtyRectList, rout = _dirtyRectOut; r != last_rect; ++r) { 579 580 // always clamp to enclosing, downsampled-grid-aligned rect in the downscaled image 581 if (_scaleFactorXd != 1) { 582 stretch = r->x % _scaleFactorXd; 583 r->x -= stretch; 584 r->w += stretch; 585 r->w = (r->x + r->w + _scaleFactorXd - 1) / _scaleFactorXd * _scaleFactorXd - r->x; 586 } 587 if (_scaleFactorYd != 1) { 588 stretch = r->y % _scaleFactorYd; 589 r->y -= stretch; 590 r->h += stretch; 591 r->h = (r->y + r->h + _scaleFactorYd - 1) / _scaleFactorYd * _scaleFactorYd - r->y; 592 } 593 594 // transform 595 shakestretch = _currentShakePos * _scaleFactorYm / _scaleFactorYd; 596 routx = r->x * _scaleFactorXm / _scaleFactorXd; // locate position in scaled screen 597 routy = r->y * _scaleFactorYm / _scaleFactorYd + shakestretch; // adjust for shake offset 598 routw = r->w * _scaleFactorXm / _scaleFactorXd; 599 routh = r->h * _scaleFactorYm / _scaleFactorYd - shakestretch; 600 601 // clipping destination rectangle inside device screen (more strict, also more tricky but more stable) 602 // note that all current scalers do not make dst rect exceed left/right, unless chosen badly (FIXME) 603 if (_zoomDown) routy -= 240; // adjust for zoom position 604 if (routy + routh < 0) continue; 605 if (routy < 0) { 606 routh += routy; 607 r->y -= routy * _scaleFactorYd / _scaleFactorYm; 608 routy = 0; 609 r->h = routh * _scaleFactorYd / _scaleFactorYm; 610 } 611 if (_orientationLandscape) { 612 if (routy > OSystem_WINCE3::getScreenWidth()) continue; 613 if (routy + routh > OSystem_WINCE3::getScreenWidth()) { 614 routh = OSystem_WINCE3::getScreenWidth() - routy; 615 r->h = routh * _scaleFactorYd / _scaleFactorYm; 616 } 617 } else { 618 if (routy > OSystem_WINCE3::getScreenHeight()) continue; 619 if (routy + routh > OSystem_WINCE3::getScreenHeight()) { 620 routh = OSystem_WINCE3::getScreenHeight() - routy; 621 r->h = routh * _scaleFactorYd / _scaleFactorYm; 622 } 623 } 624 625 // check if the toolbar is overwritten 626 if (toolbarVisible && r->y + r->h >= toolbarOffset) 627 _toolbarHandler.forceRedraw(); 628 629 // blit it (with added voodoo from the sdl backend, shifting the source rect again) 630 _scalerProc( (byte *)srcSurf->pixels + (r->x * 2 + 2)+ (r->y + 1) * srcPitch, srcPitch, 631 (byte *)_hwscreen->pixels + routx * 2 + routy * dstPitch, dstPitch, 632 r->w, r->h - _currentShakePos); 633 634 // add this rect to output 635 rout->x = routx; rout->y = routy - shakestretch; 636 rout->w = routw; rout->h = routh + shakestretch; 637 numRectsOut++; 638 rout++; 639 640 } 641 SDL_UnlockSurface(srcSurf); 642 SDL_UnlockSurface(_hwscreen); 643 } 644 // Add the toolbar if needed 645 SDL_Rect toolbar_rect[1]; 646 if (_panelVisible && _toolbarHandler.draw(_toolbarLow, &toolbar_rect[0])) { 647 // It can be drawn, scale it 648 uint32 srcPitch, dstPitch; 649 SDL_Surface *toolbarSurface; 650 ScalerProc *toolbarScaler; 651 652 if (_videoMode.screenHeight > 240) { 653 if (!_toolbarHighDrawn) { 654 // Resize the toolbar 655 SDL_LockSurface(_toolbarLow); 656 SDL_LockSurface(_toolbarHigh); 657 Normal2x((byte*)_toolbarLow->pixels, _toolbarLow->pitch, (byte*)_toolbarHigh->pixels, _toolbarHigh->pitch, toolbar_rect[0].w, toolbar_rect[0].h); 658 SDL_UnlockSurface(_toolbarHigh); 659 SDL_UnlockSurface(_toolbarLow); 660 _toolbarHighDrawn = true; 661 } 662 toolbar_rect[0].w *= 2; 663 toolbar_rect[0].h *= 2; 664 toolbarSurface = _toolbarHigh; 665 } 666 else 667 toolbarSurface = _toolbarLow; 668 669 drawToolbarMouse(toolbarSurface, true); // draw toolbar mouse if applicable 670 671 // Apply the appropriate scaler 672 SDL_LockSurface(toolbarSurface); 673 SDL_LockSurface(_hwscreen); 674 srcPitch = toolbarSurface->pitch; 675 dstPitch = _hwscreen->pitch; 676 677 toolbarScaler = _scalerProc; 678 if (_videoMode.scaleFactor == 2) 679 toolbarScaler = Normal2x; 680 else if (_videoMode.scaleFactor == 3) 681 toolbarScaler = Normal3x; 682 toolbarScaler((byte *)toolbarSurface->pixels, srcPitch, 683 (byte *)_hwscreen->pixels + (_toolbarHandler.getOffset() * _scaleFactorYm / _scaleFactorYd * dstPitch), 684 dstPitch, toolbar_rect[0].w, toolbar_rect[0].h); 685 SDL_UnlockSurface(toolbarSurface); 686 SDL_UnlockSurface(_hwscreen); 687 688 // And blit it 689 toolbar_rect[0].y = _toolbarHandler.getOffset(); 690 toolbar_rect[0].x = toolbar_rect[0].x * _scaleFactorXm / _scaleFactorXd; 691 toolbar_rect[0].y = toolbar_rect[0].y * _scaleFactorYm / _scaleFactorYd; 692 toolbar_rect[0].w = toolbar_rect[0].w * _scaleFactorXm / _scaleFactorXd; 693 toolbar_rect[0].h = toolbar_rect[0].h * _scaleFactorYm / _scaleFactorYd; 694 695 SDL_UpdateRects(_hwscreen, 1, toolbar_rect); 696 697 drawToolbarMouse(toolbarSurface, false); // undraw toolbar mouse 698 } 699 700 // Finally, blit all our changes to the screen 701 if (numRectsOut > 0) 702 SDL_UpdateRects(_hwscreen, numRectsOut, _dirtyRectOut); 703 704 _numDirtyRects = 0; 705 _forceFull = false; 706 } 707 708 bool WINCESdlGraphicsManager::setGraphicsMode(int mode) { 709 710 Common::StackLock lock(_graphicsMutex); 711 int oldScaleFactorXm = _scaleFactorXm; 712 int oldScaleFactorXd = _scaleFactorXd; 713 int oldScaleFactorYm = _scaleFactorYm; 714 int oldScaleFactorYd = _scaleFactorYd; 715 716 _scaleFactorXm = -1; 717 _scaleFactorXd = -1; 718 _scaleFactorYm = -1; 719 _scaleFactorYd = -1; 720 721 if (ConfMan.hasKey("landscape")) 722 if (ConfMan.get("landscape")[0] > 57) { 723 _newOrientation = _orientationLandscape = ConfMan.getBool("landscape"); 724 ConfMan.setInt("landscape", _orientationLandscape); 725 } else 726 _newOrientation = _orientationLandscape = ConfMan.getInt("landscape"); 727 else 728 _newOrientation = _orientationLandscape = 0; 729 730 if (OSystem_WINCE3::isOzone() && (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640) && mode) 731 _scaleFactorXm = -1; 732 733 if (CEDevice::hasPocketPCResolution() && !CEDevice::hasWideResolution() && _orientationLandscape) 734 _videoMode.mode = GFX_NORMAL; 735 else 736 _videoMode.mode = mode; 737 738 if (_scaleFactorXm < 0) { 739 /* Standard scalers, from the SDL backend */ 740 switch (_videoMode.mode) { 741 case GFX_NORMAL: 742 _videoMode.scaleFactor = 1; 743 _scalerProc = Normal1x; 744 break; 745 case GFX_DOUBLESIZE: 746 _videoMode.scaleFactor = 2; 747 _scalerProc = Normal2x; 748 break; 749 case GFX_TRIPLESIZE: 750 _videoMode.scaleFactor = 3; 751 _scalerProc = Normal3x; 752 break; 753 case GFX_2XSAI: 754 _videoMode.scaleFactor = 2; 755 _scalerProc = _2xSaI; 756 break; 757 case GFX_SUPER2XSAI: 758 _videoMode.scaleFactor = 2; 759 _scalerProc = Super2xSaI; 760 break; 761 case GFX_SUPEREAGLE: 762 _videoMode.scaleFactor = 2; 763 _scalerProc = SuperEagle; 764 break; 765 case GFX_ADVMAME2X: 766 _videoMode.scaleFactor = 2; 767 _scalerProc = AdvMame2x; 768 break; 769 case GFX_ADVMAME3X: 770 _videoMode.scaleFactor = 3; 771 _scalerProc = AdvMame3x; 772 break; 773 #ifdef USE_HQ_SCALERS 774 case GFX_HQ2X: 775 _videoMode.scaleFactor = 2; 776 _scalerProc = HQ2x; 777 break; 778 case GFX_HQ3X: 779 _videoMode.scaleFactor = 3; 780 _scalerProc = HQ3x; 781 break; 782 #endif 783 case GFX_TV2X: 784 _videoMode.scaleFactor = 2; 785 _scalerProc = TV2x; 786 break; 787 case GFX_DOTMATRIX: 788 _videoMode.scaleFactor = 2; 789 _scalerProc = DotMatrix; 790 break; 791 792 default: 793 error("unknown gfx mode %d", mode); 794 } 795 } 796 797 // Check if the scaler can be accepted, if not get back to normal scaler 798 if (_videoMode.scaleFactor && ((_videoMode.scaleFactor * _videoMode.screenWidth > OSystem_WINCE3::getScreenWidth() && _videoMode.scaleFactor * _videoMode.screenWidth > OSystem_WINCE3::getScreenHeight()) 799 || (_videoMode.scaleFactor * _videoMode.screenHeight > OSystem_WINCE3::getScreenWidth() && _videoMode.scaleFactor * _videoMode.screenHeight > OSystem_WINCE3::getScreenHeight()))) { 800 _videoMode.scaleFactor = 1; 801 _scalerProc = Normal1x; 802 } 803 804 // Common scaler system was used 805 if (_scaleFactorXm < 0) { 806 _scaleFactorXm = _videoMode.scaleFactor; 807 _scaleFactorXd = 1; 808 _scaleFactorYm = _videoMode.scaleFactor; 809 _scaleFactorYd = 1; 810 } 811 812 _forceFull = true; 813 814 if (oldScaleFactorXm != _scaleFactorXm || 815 oldScaleFactorXd != _scaleFactorXd || 816 oldScaleFactorYm != _scaleFactorYm || 817 oldScaleFactorYd != _scaleFactorYd) { 818 _scalersChanged = true; 819 } 820 else 821 _scalersChanged = false; 822 823 824 return true; 825 826 } 827 828 bool WINCESdlGraphicsManager::loadGFXMode() { 829 int displayWidth; 830 int displayHeight; 831 unsigned int flags = SDL_FULLSCREEN | SDL_SWSURFACE; 832 833 _videoMode.fullscreen = true; // forced 834 _forceFull = true; 835 836 _tmpscreen = NULL; 837 838 // Recompute scalers if necessary 839 update_scalers(); 840 841 // Create the surface that contains the 8 bit game data 842 _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0); 843 if (_screen == NULL) 844 error("_screen failed (%s)", SDL_GetError()); 845 846 // Create the surface that contains the scaled graphics in 16 bit mode 847 // Always use full screen mode to have a "clean screen" 848 if (!_videoMode.aspectRatioCorrection) { 849 displayWidth = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd; 850 displayHeight = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd; 851 } else { 852 displayWidth = _videoMode.screenWidth * _videoMode.scaleFactor; 853 displayHeight = _videoMode.screenHeight* _videoMode.scaleFactor; 854 } 855 856 switch (_orientationLandscape) { 857 case 1: 858 flags |= SDL_LANDSCVIDEO; 859 break; 860 case 2: 861 flags |= SDL_INVLNDVIDEO; 862 break; 863 default: 864 flags |= SDL_PORTRTVIDEO; 865 } 866 _hwscreen = SDL_SetVideoMode(displayWidth, displayHeight, 16, flags); 867 868 if (_hwscreen == NULL) { 869 warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError()); 870 g_system->quit(); 871 } 872 873 // see what orientation sdl finally accepted 874 if (_hwscreen->flags & SDL_PORTRTVIDEO) 875 _orientationLandscape = _newOrientation = 0; 876 else if (_hwscreen->flags & SDL_LANDSCVIDEO) 877 _orientationLandscape = _newOrientation = 1; 878 else 879 _orientationLandscape = _newOrientation = 2; 880 881 // Create the surface used for the graphics in 16 bit before scaling, and also the overlay 882 // Distinguish 555 and 565 mode 883 if (_hwscreen->format->Rmask == 0x7C00) 884 InitScalers(555); 885 else 886 InitScalers(565); 887 _overlayFormat.bytesPerPixel = _hwscreen->format->BytesPerPixel; 888 _overlayFormat.rLoss = _hwscreen->format->Rloss; 889 _overlayFormat.gLoss = _hwscreen->format->Gloss; 890 _overlayFormat.bLoss = _hwscreen->format->Bloss; 891 _overlayFormat.aLoss = _hwscreen->format->Aloss; 892 _overlayFormat.rShift = _hwscreen->format->Rshift; 893 _overlayFormat.gShift = _hwscreen->format->Gshift; 894 _overlayFormat.bShift = _hwscreen->format->Bshift; 895 _overlayFormat.aShift = _hwscreen->format->Ashift; 896 897 // Need some extra bytes around when using 2xSaI 898 _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask); 899 900 if (_tmpscreen == NULL) 901 error("_tmpscreen creation failed (%s)", SDL_GetError()); 902 903 // Overlay 904 if (CEDevice::hasDesktopResolution()) { 905 _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd, 16, 0, 0, 0, 0); 906 if (_overlayscreen == NULL) 907 error("_overlayscreen failed (%s)", SDL_GetError()); 908 _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd + 3, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd + 3, 16, 0, 0, 0, 0); 909 if (_tmpscreen2 == NULL) 910 error("_tmpscreen2 failed (%s)", SDL_GetError()); 911 } else { 912 _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight, 16, 0, 0, 0, 0); 913 if (_overlayscreen == NULL) 914 error("_overlayscreen failed (%s)", SDL_GetError()); 915 _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3, 16, 0, 0, 0, 0); 916 if (_tmpscreen2 == NULL) 917 error("_tmpscreen2 failed (%s)", SDL_GetError()); 918 } 919 920 // Toolbar 921 _toolbarHighDrawn = false; 922 uint16 *toolbar_screen = (uint16 *)calloc(320 * 40, sizeof(uint16)); // *not* leaking memory here 923 _toolbarLow = SDL_CreateRGBSurfaceFrom(toolbar_screen, 320, 40, 16, 320 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask); 924 925 if (_toolbarLow == NULL) 926 error("_toolbarLow failed (%s)", SDL_GetError()); 927 928 if (_videoMode.screenHeight > 240) { 929 uint16 *toolbar_screen_high = (uint16 *)calloc(640 * 80, sizeof(uint16)); 930 _toolbarHigh = SDL_CreateRGBSurfaceFrom(toolbar_screen_high, 640, 80, 16, 640 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask); 931 932 if (_toolbarHigh == NULL) 933 error("_toolbarHigh failed (%s)", SDL_GetError()); 934 } else 935 _toolbarHigh = NULL; 936 937 // keyboard cursor control, some other better place for it? 938 _sdlEventSource->resetKeyboadEmulation(_videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd - 1, _videoMode.screenHeight * _scaleFactorXm / _scaleFactorXd - 1); 939 940 return true; 941 } 942 943 void WINCESdlGraphicsManager::unloadGFXMode() { 944 if (_screen) { 945 SDL_FreeSurface(_screen); 946 _screen = NULL; 947 } 948 949 if (_hwscreen) { 950 SDL_FreeSurface(_hwscreen); 951 _hwscreen = NULL; 952 } 953 954 if (_tmpscreen) { 955 SDL_FreeSurface(_tmpscreen); 956 _tmpscreen = NULL; 957 } 958 } 959 960 bool WINCESdlGraphicsManager::hotswapGFXMode() { 961 if (!_screen) 962 return false; 963 964 // Keep around the old _screen & _tmpscreen so we can restore the screen data 965 // after the mode switch. (also for the overlay) 966 SDL_Surface *old_screen = _screen; 967 SDL_Surface *old_tmpscreen = _tmpscreen; 968 SDL_Surface *old_overlayscreen = _overlayscreen; 969 SDL_Surface *old_tmpscreen2 = _tmpscreen2; 970 971 // Release the HW screen surface 972 SDL_FreeSurface(_hwscreen); 973 974 // Release toolbars 975 free(_toolbarLow->pixels); 976 SDL_FreeSurface(_toolbarLow); 977 if (_toolbarHigh) { 978 free(_toolbarHigh->pixels); 979 SDL_FreeSurface(_toolbarHigh); 980 } 981 982 // Setup the new GFX mode 983 if (!loadGFXMode()) { 984 unloadGFXMode(); 985 986 _screen = old_screen; 987 _overlayscreen = old_overlayscreen; 988 989 return false; 990 } 991 992 // reset palette 993 SDL_SetColors(_screen, _currentPalette, 0, 256); 994 995 // Restore old screen content 996 SDL_BlitSurface(old_screen, NULL, _screen, NULL); 997 SDL_BlitSurface(old_tmpscreen, NULL, _tmpscreen, NULL); 998 if (_overlayVisible) { 999 SDL_BlitSurface(old_overlayscreen, NULL, _overlayscreen, NULL); 1000 SDL_BlitSurface(old_tmpscreen2, NULL, _tmpscreen2, NULL); 1001 } 1002 1003 // Free the old surfaces 1004 SDL_FreeSurface(old_screen); 1005 SDL_FreeSurface(old_tmpscreen); 1006 SDL_FreeSurface(old_overlayscreen); 1007 SDL_FreeSurface(old_tmpscreen2); 1008 1009 // Blit everything back to the screen 1010 _toolbarHighDrawn = false; 1011 internUpdateScreen(); 1012 1013 // Make sure that a Common::EVENT_SCREEN_CHANGED gets sent later -> FIXME this crashes when no game has been loaded. 1014 // _modeChanged = true; 1015 1016 return true; 1017 } 1018 1019 bool WINCESdlGraphicsManager::saveScreenshot(const char *filename) { 1020 assert(_hwscreen != NULL); 1021 1022 Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends 1023 SDL_SaveBMP(_hwscreen, filename); 1024 return true; 1025 } 1026 1027 void WINCESdlGraphicsManager::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) { 1028 assert (_transactionMode == kTransactionNone); 1029 1030 if (_overlayscreen == NULL) 1031 return; 1032 1033 // Clip the coordinates 1034 if (x < 0) { 1035 w += x; 1036 buf -= x; 1037 x = 0; 1038 } 1039 1040 if (y < 0) { 1041 h += y; buf -= y * pitch; 1042 y = 0; 1043 } 1044 1045 if (w > _videoMode.overlayWidth - x) { 1046 w = _videoMode.overlayWidth - x; 1047 } 1048 1049 if (h > _videoMode.overlayHeight - y) { 1050 h = _videoMode.overlayHeight - y; 1051 } 1052 1053 if (w <= 0 || h <= 0) 1054 return; 1055 1056 // Mark the modified region as dirty 1057 addDirtyRect(x, y, w, h); 1058 1059 undrawMouse(); 1060 1061 if (SDL_LockSurface(_overlayscreen) == -1) 1062 error("SDL_LockSurface failed: %s", SDL_GetError()); 1063 1064 byte *dst = (byte *)_overlayscreen->pixels + y * _overlayscreen->pitch + x * 2; 1065 do { 1066 memcpy(dst, buf, w * 2); 1067 dst += _overlayscreen->pitch; 1068 buf += pitch; 1069 } while (--h); 1070 1071 SDL_UnlockSurface(_overlayscreen); 1072 } 1073 1074 void WINCESdlGraphicsManager::copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) { 1075 assert (_transactionMode == kTransactionNone); 1076 assert(src); 1077 1078 if (_screen == NULL) 1079 return; 1080 1081 Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends 1082 1083 /* Clip the coordinates */ 1084 if (x < 0) { 1085 w += x; 1086 src -= x; 1087 x = 0; 1088 } 1089 1090 if (y < 0) { 1091 h += y; 1092 src -= y * pitch; 1093 y = 0; 1094 } 1095 1096 if (w > _videoMode.screenWidth - x) { 1097 w = _videoMode.screenWidth - x; 1098 } 1099 1100 if (h > _videoMode.screenHeight - y) { 1101 h = _videoMode.screenHeight - y; 1102 } 1103 1104 if (w <= 0 || h <= 0) 1105 return; 1106 1107 addDirtyRect(x, y, w, h); 1108 1109 undrawMouse(); 1110 1111 // Try to lock the screen surface 1112 if (SDL_LockSurface(_screen) == -1) 1113 error("SDL_LockSurface failed: %s", SDL_GetError()); 1114 1115 byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x; 1116 1117 if (_videoMode.screenWidth == pitch && pitch == w) { 1118 memcpy(dst, src, h*w); 1119 } else { 1120 do { 1121 memcpy(dst, src, w); 1122 src += pitch; 1123 dst += _videoMode.screenWidth; 1124 } while (--h); 1125 } 1126 1127 // Unlock the screen surface 1128 SDL_UnlockSurface(_screen); 1129 } 1130 1131 void WINCESdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { 1132 1133 undrawMouse(); 1134 if (w == 0 || h == 0) 1135 return; 1136 1137 _mouseCurState.w = w; 1138 _mouseCurState.h = h; 1139 1140 _mouseHotspotX = hotspot_x; 1141 _mouseHotspotY = hotspot_y; 1142 1143 _mouseKeyColor = keycolor; 1144 1145 free(_mouseData); 1146 1147 _mouseData = (byte *) malloc(w * h); 1148 memcpy(_mouseData, buf, w * h); 1149 1150 if (w > _mouseBackupDim || h > _mouseBackupDim) { 1151 // mouse has been undrawn, adjust sprite backup area 1152 free(_mouseBackupOld); 1153 free(_mouseBackupToolbar); 1154 uint16 tmp = (w > h) ? w : h; 1155 _mouseBackupOld = (byte *) malloc(tmp * tmp * 2); // can hold 8bpp (playfield) or 16bpp (overlay) data 1156 _mouseBackupToolbar = (uint16 *) malloc(tmp * tmp * 2); // 16 bpp 1157 _mouseBackupDim = tmp; 1158 } 1159 } 1160 1161 void WINCESdlGraphicsManager::adjustMouseEvent(const Common::Event &event) { 1162 if (!event.synthetic) { 1163 Common::Event newEvent(event); 1164 newEvent.synthetic = true; 1165 if (!_overlayVisible) { 1166 /* 1167 newEvent.mouse.x = newEvent.mouse.x * _scaleFactorXd / _scaleFactorXm; 1168 newEvent.mouse.y = newEvent.mouse.y * _scaleFactorYd / _scaleFactorYm; 1169 newEvent.mouse.x /= _videoMode.scaleFactor; 1170 newEvent.mouse.y /= _videoMode.scaleFactor; 1171 */ 1172 if (_videoMode.aspectRatioCorrection) 1173 newEvent.mouse.y = aspect2Real(newEvent.mouse.y); 1174 } 1175 g_system->getEventManager()->pushEvent(newEvent); 1176 } 1177 } 1178 1179 void WINCESdlGraphicsManager::setMousePos(int x, int y) { 1180 if (x != _mouseCurState.x || y != _mouseCurState.y) { 1181 undrawMouse(); 1182 _mouseCurState.x = x; 1183 _mouseCurState.y = y; 1184 updateScreen(); 1185 } 1186 } 1187 1188 Graphics::Surface *WINCESdlGraphicsManager::lockScreen() { 1189 // Make sure mouse pointer is not painted over the playfield at the time of locking 1190 undrawMouse(); 1191 return SdlGraphicsManager::lockScreen(); 1192 } 1193 1194 void WINCESdlGraphicsManager::showOverlay() { 1195 assert (_transactionMode == kTransactionNone); 1196 1197 if (_overlayVisible) 1198 return; 1199 1200 undrawMouse(); 1201 _overlayVisible = true; 1202 update_scalers(); 1203 clearOverlay(); 1204 } 1205 1206 void WINCESdlGraphicsManager::hideOverlay() { 1207 assert (_transactionMode == kTransactionNone); 1208 1209 if (!_overlayVisible) 1210 return; 1211 1212 undrawMouse(); 1213 _overlayVisible = false; 1214 clearOverlay(); 1215 _forceFull = true; 1216 } 1217 1218 void WINCESdlGraphicsManager::blitCursor() { 1219 } 1220 1221 void WINCESdlGraphicsManager::drawToolbarMouse(SDL_Surface *surf, bool draw) { 1222 1223 if (!_mouseData || !_usesEmulatedMouse) 1224 return; 1225 1226 int x = _mouseCurState.x - _mouseHotspotX; 1227 int y = _mouseCurState.y - _mouseHotspotY - _toolbarHandler.getOffset(); 1228 int w = _mouseCurState.w; 1229 int h = _mouseCurState.h; 1230 byte color; 1231 const byte *src = _mouseData; 1232 int width; 1233 1234 // clip 1235 if (x < 0) { 1236 w += x; 1237 src -= x; 1238 x = 0; 1239 } 1240 if (y < 0) { 1241 h += y; 1242 src -= y * _mouseCurState.w; 1243 y = 0; 1244 } 1245 if (w > surf->w - x) 1246 w = surf->w - x; 1247 if (h > surf->h - y) 1248 h = surf->h - y; 1249 if (w <= 0 || h <= 0) 1250 return; 1251 1252 if (SDL_LockSurface(surf) == -1) 1253 error("SDL_LockSurface failed at internDrawToolbarMouse: %s", SDL_GetError()); 1254 1255 uint16 *bak = _mouseBackupToolbar; // toolbar surfaces are 16bpp 1256 uint16 *dst; 1257 dst = (uint16 *)surf->pixels + y * surf->w + x; 1258 1259 if (draw) { // blit it 1260 while (h > 0) { 1261 width = w; 1262 while (width > 0) { 1263 *bak++ = *dst; 1264 color = *src++; 1265 if (color != _mouseKeyColor) // transparent color 1266 *dst = 0xFFFF; 1267 dst++; 1268 width--; 1269 } 1270 src += _mouseCurState.w - w; 1271 bak += _mouseBackupDim - w; 1272 dst += surf->w - w; 1273 h--; 1274 } 1275 } else { // restore bg 1276 for (y = 0; y < h; ++y, bak += _mouseBackupDim, dst += surf->w) 1277 memcpy(dst, bak, w << 1); 1278 } 1279 1280 SDL_UnlockSurface(surf); 1281 } 1282 1283 void WINCESdlGraphicsManager::warpMouse(int x, int y) { 1284 if (_mouseCurState.x != x || _mouseCurState.y != y) { 1285 SDL_WarpMouse(x * _scaleFactorXm / _scaleFactorXd, y * _scaleFactorYm / _scaleFactorYd); 1286 1287 // SDL_WarpMouse() generates a mouse movement event, so 1288 // set_mouse_pos() would be called eventually. However, the 1289 // cannon script in CoMI calls this function twice each time 1290 // the cannon is reloaded. Unless we update the mouse position 1291 // immediately the second call is ignored, causing the cannon 1292 // to change its aim. 1293 1294 setMousePos(x, y); 1295 } 1296 } 1297 1298 void WINCESdlGraphicsManager::unlockScreen() { 1299 SdlGraphicsManager::unlockScreen(); 1300 } 1301 1302 void WINCESdlGraphicsManager::internDrawMouse() { 1303 if (!_mouseNeedsRedraw || !_mouseVisible || !_mouseData) 1304 return; 1305 1306 int x = _mouseCurState.x - _mouseHotspotX; 1307 int y = _mouseCurState.y - _mouseHotspotY; 1308 int w = _mouseCurState.w; 1309 int h = _mouseCurState.h; 1310 byte color; 1311 const byte *src = _mouseData; // Image representing the mouse 1312 int width; 1313 1314 // clip the mouse rect, and adjust the src pointer accordingly 1315 if (x < 0) { 1316 w += x; 1317 src -= x; 1318 x = 0; 1319 } 1320 if (y < 0) { 1321 h += y; 1322 src -= y * _mouseCurState.w; 1323 y = 0; 1324 } 1325 1326 if (w > _videoMode.screenWidth - x) 1327 w = _videoMode.screenWidth - x; 1328 if (h > _videoMode.screenHeight - y) 1329 h = _videoMode.screenHeight - y; 1330 1331 // Quick check to see if anything has to be drawn at all 1332 if (w <= 0 || h <= 0) 1333 return; 1334 1335 // Draw the mouse cursor; backup the covered area in "bak" 1336 if (SDL_LockSurface(_overlayVisible ? _overlayscreen : _screen) == -1) 1337 error("SDL_LockSurface failed: %s", SDL_GetError()); 1338 1339 // Mark as dirty 1340 addDirtyRect(x, y, w, h); 1341 1342 if (!_overlayVisible) { 1343 byte *bak = _mouseBackupOld; // Surface used to backup the area obscured by the mouse 1344 byte *dst; // Surface we are drawing into 1345 1346 dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x; 1347 while (h > 0) { 1348 width = w; 1349 while (width > 0) { 1350 *bak++ = *dst; 1351 color = *src++; 1352 if (color != _mouseKeyColor) // transparent, don't draw 1353 *dst = color; 1354 dst++; 1355 width--; 1356 } 1357 src += _mouseCurState.w - w; 1358 bak += _mouseBackupDim - w; 1359 dst += _videoMode.screenWidth - w; 1360 h--; 1361 } 1362 1363 } else { 1364 uint16 *bak = (uint16 *)_mouseBackupOld; // Surface used to backup the area obscured by the mouse 1365 byte *dst; // Surface we are drawing into 1366 1367 dst = (byte *)_overlayscreen->pixels + (y + 1) * _overlayscreen->pitch + (x + 1) * 2; 1368 while (h > 0) { 1369 width = w; 1370 while (width > 0) { 1371 *bak++ = *(uint16 *)dst; 1372 color = *src++; 1373 if (color != 0xFF) // 0xFF = transparent, don't draw 1374 *(uint16 *)dst = SDL_MapRGB(_overlayscreen->format, _currentPalette[color].r, _currentPalette[color].g, _currentPalette[color].b); 1375 dst += 2; 1376 width--; 1377 } 1378 src += _mouseCurState.w - w; 1379 bak += _mouseBackupDim - w; 1380 dst += _overlayscreen->pitch - w * 2; 1381 h--; 1382 } 1383 } 1384 1385 SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen); 1386 1387 // Finally, set the flag to indicate the mouse has been drawn 1388 _mouseNeedsRedraw = false; 1389 } 1390 1391 void WINCESdlGraphicsManager::undrawMouse() { 1392 assert (_transactionMode == kTransactionNone); 1393 1394 if (_mouseNeedsRedraw) 1395 return; 1396 1397 int old_mouse_x = _mouseCurState.x - _mouseHotspotX; 1398 int old_mouse_y = _mouseCurState.y - _mouseHotspotY; 1399 int old_mouse_w = _mouseCurState.w; 1400 int old_mouse_h = _mouseCurState.h; 1401 1402 // clip the mouse rect, and adjust the src pointer accordingly 1403 if (old_mouse_x < 0) { 1404 old_mouse_w += old_mouse_x; 1405 old_mouse_x = 0; 1406 } 1407 if (old_mouse_y < 0) { 1408 old_mouse_h += old_mouse_y; 1409 old_mouse_y = 0; 1410 } 1411 1412 if (old_mouse_w > _videoMode.screenWidth - old_mouse_x) 1413 old_mouse_w = _videoMode.screenWidth - old_mouse_x; 1414 if (old_mouse_h > _videoMode.screenHeight - old_mouse_y) 1415 old_mouse_h = _videoMode.screenHeight - old_mouse_y; 1416 1417 // Quick check to see if anything has to be drawn at all 1418 if (old_mouse_w <= 0 || old_mouse_h <= 0) 1419 return; 1420 1421 1422 if (SDL_LockSurface(_overlayVisible ? _overlayscreen : _screen) == -1) 1423 error("SDL_LockSurface failed: %s", SDL_GetError()); 1424 1425 int y; 1426 if (!_overlayVisible) { 1427 byte *dst, *bak = _mouseBackupOld; 1428 1429 // No need to do clipping here, since drawMouse() did that already 1430 dst = (byte *)_screen->pixels + old_mouse_y * _videoMode.screenWidth + old_mouse_x; 1431 for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _videoMode.screenWidth) 1432 memcpy(dst, bak, old_mouse_w); 1433 } else { 1434 byte *dst; 1435 uint16 *bak = (uint16 *)_mouseBackupOld; 1436 1437 // No need to do clipping here, since drawMouse() did that already 1438 dst = (byte *)_overlayscreen->pixels + (old_mouse_y + 1) * _overlayscreen->pitch + (old_mouse_x + 1) * 2; 1439 for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _overlayscreen->pitch) 1440 memcpy(dst, bak, old_mouse_w << 1); 1441 } 1442 1443 addDirtyRect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h); 1444 1445 SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen); 1446 1447 _mouseNeedsRedraw = true; 1448 } 1449 1450 void WINCESdlGraphicsManager::drawMouse() { 1451 if (!(_toolbarHandler.visible() && _mouseCurState.y >= _toolbarHandler.getOffset() && !_usesEmulatedMouse) && !_forceHideMouse) 1452 internDrawMouse(); 1453 } 1454 1455 bool WINCESdlGraphicsManager::showMouse(bool visible) { 1456 if (_mouseVisible == visible) 1457 return visible; 1458 1459 if (visible == false) 1460 undrawMouse(); 1461 1462 bool last = _mouseVisible; 1463 _mouseVisible = visible; 1464 _mouseNeedsRedraw = true; 1465 1466 return last; 1467 } 1468 1469 void WINCESdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool mouseRect) { 1470 1471 if (_forceFull || _paletteDirtyEnd) 1472 return; 1473 1474 SdlGraphicsManager::addDirtyRect(x, y, w, h, false); 1475 } 1476 1477 void WINCESdlGraphicsManager::swap_panel_visibility() { 1478 //if (!_forcePanelInvisible && !_panelStateForced) { 1479 if (_zoomDown || _zoomUp) return; 1480 1481 if (_panelVisible) { 1482 if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD) 1483 _panelVisible = !_panelVisible; 1484 else 1485 _toolbarHandler.setActive(NAME_PANEL_KEYBOARD); 1486 } else { 1487 _toolbarHandler.setActive(NAME_MAIN_PANEL); 1488 _panelVisible = !_panelVisible; 1489 } 1490 _toolbarHandler.setVisible(_panelVisible); 1491 _toolbarHighDrawn = false; 1492 1493 if (_videoMode.screenHeight > 240) 1494 addDirtyRect(0, 400, 640, 80); 1495 else 1496 addDirtyRect(0, 200, 320, 40); 1497 1498 if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible) 1499 internUpdateScreen(); 1500 else { 1501 update_scalers(); 1502 hotswapGFXMode(); 1503 } 1504 //} 1505 } 1506 1507 void WINCESdlGraphicsManager::swap_panel() { 1508 _toolbarHighDrawn = false; 1509 //if (!_panelStateForced) { 1510 if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible) 1511 _toolbarHandler.setActive(NAME_MAIN_PANEL); 1512 else 1513 _toolbarHandler.setActive(NAME_PANEL_KEYBOARD); 1514 1515 if (_videoMode.screenHeight > 240) 1516 addDirtyRect(0, 400, 640, 80); 1517 else 1518 addDirtyRect(0, 200, 320, 40); 1519 1520 _toolbarHandler.setVisible(true); 1521 if (!_panelVisible) { 1522 _panelVisible = true; 1523 update_scalers(); 1524 hotswapGFXMode(); 1525 } 1526 //} 1527 } 1528 1529 void WINCESdlGraphicsManager::swap_smartphone_keyboard() { 1530 _toolbarHandler.setActive(NAME_PANEL_KEYBOARD); 1531 _panelVisible = !_panelVisible; 1532 _toolbarHandler.setVisible(_panelVisible); 1533 if (_videoMode.screenHeight > 240) 1534 addDirtyRect(0, 0, 640, 80); 1535 else 1536 addDirtyRect(0, 0, 320, 40); 1537 internUpdateScreen(); 1538 } 1539 1540 void WINCESdlGraphicsManager::swap_zoom_up() { 1541 if (_zoomUp) { 1542 // restore visibility 1543 _toolbarHandler.setVisible(_saveToolbarZoom); 1544 // restore scaler 1545 _scaleFactorYd = 2; 1546 _scalerProc = DownscaleAllByHalf; 1547 _zoomUp = false; 1548 _zoomDown = false; 1549 } else { 1550 // only active if running on a PocketPC 1551 if (_scalerProc != DownscaleAllByHalf && _scalerProc != DownscaleHorizByHalf) 1552 return; 1553 if (_scalerProc == DownscaleAllByHalf) { 1554 _saveToolbarZoom = _toolbarHandler.visible(); 1555 _toolbarHandler.setVisible(false); 1556 // set zoom scaler 1557 _scaleFactorYd = 1; 1558 _scalerProc = DownscaleHorizByHalf; 1559 } 1560 1561 _zoomDown = false; 1562 _zoomUp = true; 1563 } 1564 // redraw whole screen 1565 addDirtyRect(0, 0, 640, 480); 1566 internUpdateScreen(); 1567 } 1568 1569 void WINCESdlGraphicsManager::swap_zoom_down() { 1570 if (_zoomDown) { 1571 // restore visibility 1572 _toolbarHandler.setVisible(_saveToolbarZoom); 1573 // restore scaler 1574 _scaleFactorYd = 2; 1575 _scalerProc = DownscaleAllByHalf; 1576 _zoomDown = false; 1577 _zoomUp = false; 1578 } else { 1579 // only active if running on a PocketPC 1580 if (_scalerProc != DownscaleAllByHalf && _scalerProc != DownscaleHorizByHalf) 1581 return; 1582 if (_scalerProc == DownscaleAllByHalf) { 1583 _saveToolbarZoom = _toolbarHandler.visible(); 1584 _toolbarHandler.setVisible(false); 1585 // set zoom scaler 1586 _scaleFactorYd = 1; 1587 _scalerProc = DownscaleHorizByHalf; 1588 } 1589 1590 _zoomUp = false; 1591 _zoomDown = true; 1592 } 1593 // redraw whole screen 1594 addDirtyRect(0, 0, 640, 480); 1595 internUpdateScreen(); 1596 } 1597 1598 void WINCESdlGraphicsManager::swap_mouse_visibility() { 1599 _forceHideMouse = !_forceHideMouse; 1600 if (_forceHideMouse) 1601 undrawMouse(); 1602 } 1603 1604 // Smartphone actions 1605 void WINCESdlGraphicsManager::initZones() { 1606 int i; 1607 1608 _currentZone = 0; 1609 for (i = 0; i < TOTAL_ZONES; i++) { 1610 _mouseXZone[i] = (_zones[i].x + (_zones[i].width / 2)) * _scaleFactorXm / _scaleFactorXd; 1611 _mouseYZone[i] = (_zones[i].y + (_zones[i].height / 2)) * _scaleFactorYm / _scaleFactorYd; 1612 } 1613 } 1614 1615 void WINCESdlGraphicsManager::smartphone_rotate_display() { 1616 _orientationLandscape = _newOrientation = _orientationLandscape == 1 ? 2 : 1; 1617 ConfMan.setInt("landscape", _orientationLandscape); 1618 ConfMan.flushToDisk(); 1619 hotswapGFXMode(); 1620 } 1621 1622 void WINCESdlGraphicsManager::create_toolbar() { 1623 CEGUI::PanelKeyboard *keyboard; 1624 1625 // Add the keyboard 1626 keyboard = new CEGUI::PanelKeyboard(PANEL_KEYBOARD); 1627 _toolbarHandler.add(NAME_PANEL_KEYBOARD, *keyboard); 1628 _toolbarHandler.setVisible(false); 1629 } 1630 1631 WINCESdlGraphicsManager::zoneDesc WINCESdlGraphicsManager::_zones[TOTAL_ZONES] = { 1632 { 0, 0, 320, 145 }, 1633 { 0, 145, 150, 55 }, 1634 { 150, 145, 170, 55 } 1635 }; 1636 1637 #endif /* _WIN32_WCE */ 1638 -
backends/graphics/wincesdl/wincesdl-graphics.h
diff -rupN scummvm-df1a800-orig/backends/graphics/wincesdl/wincesdl-graphics.h scummvm-git/backends/graphics/wincesdl/wincesdl-graphics.h
old new 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 * 24 */ 25 26 #ifndef BACKENDS_GRAPHICS_WINCE_SDL_H 27 #define BACKENDS_GRAPHICS_WINCE_SDL_H 28 29 #include "backends/graphics/sdl/sdl-graphics.h" 30 #include "backends/platform/wince/CEgui/CEGUI.h" 31 32 // Internal GUI names 33 #define NAME_MAIN_PANEL "MainPanel" 34 #define NAME_PANEL_KEYBOARD "Keyboard" 35 #define NAME_ITEM_OPTIONS "Options" 36 #define NAME_ITEM_SKIP "Skip" 37 #define NAME_ITEM_SOUND "Sound" 38 #define NAME_ITEM_ORIENTATION "Orientation" 39 #define NAME_ITEM_BINDKEYS "Bindkeys" 40 41 #define TOTAL_ZONES 3 42 43 extern bool _hasSmartphoneResolution; 44 45 class WINCESdlGraphicsManager : public SdlGraphicsManager { 46 public: 47 WINCESdlGraphicsManager(SdlEventSource *sdlEventSource); 48 49 const OSystem::GraphicsMode *getSupportedGraphicsModes() const; 50 void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL); 51 52 bool hasFeature(OSystem::Feature f); 53 void setFeatureState(OSystem::Feature f, bool enable); 54 bool getFeatureState(OSystem::Feature f); 55 56 int getDefaultGraphicsMode() const; 57 bool setGraphicsMode(int mode); 58 bool loadGFXMode(); 59 void unloadGFXMode(); 60 bool hotswapGFXMode(); 61 62 // Overloaded from SDL backend (toolbar handling) 63 void drawMouse(); 64 // Overloaded from SDL backend (new scaler handling) 65 void addDirtyRect(int x, int y, int w, int h, bool mouseRect = false); 66 // Overloaded from SDL backend (new scaler handling) 67 void warpMouse(int x, int y); 68 69 // Update the dirty areas of the screen 70 void internUpdateScreen(); 71 bool saveScreenshot(const char *filename); 72 73 // Overloaded from SDL_Common (FIXME) 74 void internDrawMouse(); 75 void undrawMouse(); 76 bool showMouse(bool visible); 77 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 78 void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); 79 void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); // overloaded by CE backend (FIXME) 80 Graphics::Surface *lockScreen(); 81 void unlockScreen(); 82 void blitCursor(); 83 void showOverlay(); 84 void hideOverlay(); 85 void setMousePos(int x, int y); 86 87 // GUI and action stuff 88 void swap_panel_visibility(); 89 void swap_panel(); 90 void swap_smartphone_keyboard(); 91 void swap_zoom_up(); 92 void swap_zoom_down(); 93 void swap_mouse_visibility(); 94 95 96 //#ifdef WIN32_PLATFORM_WFSP 97 void move_cursor_up(); 98 void move_cursor_down(); 99 void move_cursor_left(); 100 void move_cursor_right(); 101 102 void retrieve_mouse_location(int &x, int &y); 103 void switch_zone(); 104 105 void add_right_click(bool pushed); 106 void add_left_click(bool pushed); 107 108 void initZones(); 109 void smartphone_rotate_display(); 110 //#endif 111 112 bool _panelInitialized; // only initialize the toolbar once 113 bool _noDoubleTapRMB; // disable double tap -> rmb click 114 115 CEGUI::ToolbarHandler _toolbarHandler; 116 117 bool _toolbarHighDrawn; // cache toolbar 640x80 118 int _newOrientation; // new orientation 119 int _orientationLandscape; // current orientation 120 121 int _scaleFactorXm; // scaler X * 122 int _scaleFactorXd; // scaler X / 123 int _scaleFactorYm; // scaler Y * 124 int _scaleFactorYd; // scaler Y / 125 126 bool _hasfocus; // scummvm has the top window 127 128 bool hasPocketPCResolution(); 129 bool hasDesktopResolution(); 130 bool hasSquareQVGAResolution(); 131 bool hasWideResolution() const; 132 133 MousePos _mouseCurState; 134 135 bool _zoomUp; // zooming up mode 136 bool _zoomDown; // zooming down mode 137 138 bool _usesEmulatedMouse; // emulated mousemove ever been used in this session 139 140 int _mouseXZone[TOTAL_ZONES]; 141 int _mouseYZone[TOTAL_ZONES]; 142 int _currentZone; 143 144 // Smartphone specific variables 145 int _lastKeyPressed; // last key pressed 146 int _keyRepeat; // number of time the last key was repeated 147 int _keyRepeatTime; // elapsed time since the key was pressed 148 int _keyRepeatTrigger; // minimum time to consider the key was repeated 149 150 struct zoneDesc { 151 int x; 152 int y; 153 int width; 154 int height; 155 }; 156 157 static zoneDesc _zones[TOTAL_ZONES]; 158 159 protected: 160 virtual void adjustMouseEvent(const Common::Event &event); 161 162 private: 163 bool update_scalers(); 164 void update_game_settings(); 165 void drawToolbarMouse(SDL_Surface *surf, bool draw); 166 167 void create_toolbar(); 168 bool _panelVisible; // panel visibility 169 bool _panelStateForced; // panel visibility forced by external call 170 String _saveActiveToolbar; // save active toolbar when forced 171 172 bool _canBeAspectScaled; // game screen size allows for aspect scaling 173 174 SDL_Rect _dirtyRectOut[NUM_DIRTY_RECT]; 175 bool _scalersChanged; 176 177 bool isOzone(); 178 179 bool _saveToolbarState; // save visibility when forced 180 bool _saveToolbarZoom; // save visibility when zooming 181 182 SDL_Surface *_toolbarLow; // toolbar 320x40 183 SDL_Surface *_toolbarHigh; // toolbar 640x80 184 185 // Mouse 186 int _mouseHotspotX, _mouseHotspotY; 187 byte *_mouseBackupOld; 188 uint16 *_mouseBackupToolbar; 189 uint16 _mouseBackupDim; 190 191 bool _forceHideMouse; // force invisible mouse cursor 192 193 // Smartphone specific variables 194 void loadDeviceConfigurationElement(Common::String element, int &value, int defaultValue); 195 int _repeatX; // repeat trigger for left and right cursor moves 196 int _repeatY; // repeat trigger for up and down cursor moves 197 int _stepX1; // offset for left and right cursor moves (slowest) 198 int _stepX2; // offset for left and right cursor moves (faster) 199 int _stepX3; // offset for left and right cursor moves (fastest) 200 int _stepY1; // offset for up and down cursor moves (slowest) 201 int _stepY2; // offset for up and down cursor moves (faster) 202 int _stepY3; // offset for up and down cursor moves (fastest) 203 }; 204 205 #endif /* BACKENDS_GRAPHICS_WINCE_SDL_H */ 206 -
backends/mixer/wincesdl/wincesdl-mixer.cpp
diff -rupN scummvm-df1a800-orig/backends/mixer/wincesdl/wincesdl-mixer.cpp scummvm-git/backends/mixer/wincesdl/wincesdl-mixer.cpp
old new 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 * 24 */ 25 26 #ifdef _WIN32_WCE 27 28 // Disable symbol overrides so that we can use system headers. 29 #define FORBIDDEN_SYMBOL_ALLOW_ALL 30 31 #include "common/config-manager.h" 32 #include "backends/platform/wince/wince-sdl.h" 33 #include "backends/mixer/wincesdl/wincesdl-mixer.h" 34 #include "common/system.h" 35 36 #ifdef USE_VORBIS 37 #ifndef USE_TREMOR 38 #include <vorbis/vorbisfile.h> 39 #else 40 #include <tremor/ivorbisfile.h> 41 #endif 42 #endif 43 44 #define SAMPLES_PER_SEC_OLD 11025 45 #define SAMPLES_PER_SEC_NEW 22050 46 47 WINCESdlMixerManager::WINCESdlMixerManager() { 48 49 } 50 51 WINCESdlMixerManager::~WINCESdlMixerManager() { 52 53 } 54 55 void WINCESdlMixerManager::init() { 56 SDL_AudioSpec desired; 57 int thread_priority; 58 59 uint32 sampleRate = compute_sample_rate(); 60 if (sampleRate == 0) 61 warning("OSystem_WINCE3::setupMixer called with sample rate 0 - audio will not work"); 62 else if (_mixer && _mixer->getOutputRate() == sampleRate) { 63 debug(1, "Skipping sound mixer re-init: samplerate is good"); 64 return; 65 } 66 67 memset(&desired, 0, sizeof(desired)); 68 desired.freq = sampleRate; 69 desired.format = AUDIO_S16SYS; 70 desired.channels = 2; 71 desired.samples = 128; 72 desired.callback = private_sound_proc; 73 desired.userdata = this; 74 75 // Create the mixer instance 76 if (_mixer == 0) 77 _mixer = new Audio::MixerImpl(g_system, sampleRate); 78 79 // Add sound thread priority 80 if (!ConfMan.hasKey("sound_thread_priority")) 81 thread_priority = THREAD_PRIORITY_NORMAL; 82 else 83 thread_priority = ConfMan.getInt("sound_thread_priority"); 84 85 desired.thread_priority = thread_priority; 86 87 SDL_CloseAudio(); 88 if (SDL_OpenAudio(&desired, NULL) != 0) { 89 warning("Could not open audio device: %s", SDL_GetError()); 90 _mixer->setReady(false); 91 92 } else { 93 debug(1, "Sound opened OK, mixing at %d Hz", sampleRate); 94 95 // Re-create mixer to match the output rate 96 int vol1 = _mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType); 97 int vol2 = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType); 98 int vol3 = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType); 99 int vol4 = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType); 100 delete _mixer; 101 _mixer = new Audio::MixerImpl(g_system, sampleRate); 102 _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, vol1); 103 _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol2); 104 _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, vol3); 105 _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, vol4); 106 _mixer->setReady(true); 107 SDL_PauseAudio(0); 108 } 109 } 110 111 void WINCESdlMixerManager::private_sound_proc(void *param, byte *buf, int len) { 112 WINCESdlMixerManager *this_ = (WINCESdlMixerManager *)param; 113 assert(this_); 114 115 if (this_->_mixer) 116 this_->_mixer->mixCallback(buf, len); 117 if (!OSystem_WINCE3::_soundMaster) 118 memset(buf, 0, len); 119 } 120 121 uint32 WINCESdlMixerManager::compute_sample_rate() { 122 uint32 sampleRate; 123 124 // Force at least medium quality FM synthesis for FOTAQ 125 Common::String gameid(ConfMan.get("gameid")); 126 if (gameid == "queen") { 127 if (!((ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) || 128 (ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")))) { 129 ConfMan.setBool("FM_medium_quality", true); 130 ConfMan.flushToDisk(); 131 } 132 } 133 // See if the output frequency is forced by the game 134 if (gameid == "ft" || gameid == "dig" || gameid == "comi" || gameid == "queen" || gameid == "sword" || gameid == "agi") 135 sampleRate = SAMPLES_PER_SEC_NEW; 136 else { 137 if (ConfMan.hasKey("high_sample_rate") && ConfMan.getBool("high_sample_rate")) 138 sampleRate = SAMPLES_PER_SEC_NEW; 139 else 140 sampleRate = SAMPLES_PER_SEC_OLD; 141 } 142 143 #ifdef USE_VORBIS 144 // Modify the sample rate on the fly if OGG is involved 145 if (sampleRate == SAMPLES_PER_SEC_OLD) 146 if (checkOggHighSampleRate()) 147 sampleRate = SAMPLES_PER_SEC_NEW; 148 #endif 149 150 return sampleRate; 151 } 152 153 #ifdef USE_VORBIS 154 bool WINCESdlMixerManager::checkOggHighSampleRate() { 155 char trackFile[255]; 156 FILE *testFile; 157 OggVorbis_File *test_ov_file = new OggVorbis_File; 158 159 // FIXME: The following sprintf assumes that "path" is always 160 // terminated by a path separator. This is *not* true in general. 161 // This code really should check for the path separator, or even 162 // better, use the FSNode API. 163 sprintf(trackFile, "%sTrack1.ogg", ConfMan.get("path").c_str()); 164 // Check if we have an OGG audio track 165 testFile = fopen(trackFile, "rb"); 166 if (testFile) { 167 if (!ov_open(testFile, test_ov_file, NULL, 0)) { 168 bool highSampleRate = (ov_info(test_ov_file, -1)->rate == 22050); 169 ov_clear(test_ov_file); 170 delete test_ov_file; 171 return highSampleRate; 172 } 173 } 174 175 // Do not test for OGG samples - too big and too slow anyway :) 176 177 delete test_ov_file; 178 return false; 179 } 180 #endif 181 182 #endif 183 -
backends/mixer/wincesdl/wincesdl-mixer.h
diff -rupN scummvm-df1a800-orig/backends/mixer/wincesdl/wincesdl-mixer.h scummvm-git/backends/mixer/wincesdl/wincesdl-mixer.h
old new 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 * 24 */ 25 26 #ifndef BACKENDS_MIXER_WINCE_SDL_H 27 #define BACKENDS_MIXER_WINCE_SDL_H 28 29 #include "backends/mixer/sdl/sdl-mixer.h" 30 31 /** 32 * SDL mixer manager for WinCE 33 */ 34 class WINCESdlMixerManager : public SdlMixerManager { 35 public: 36 WINCESdlMixerManager(); 37 virtual ~WINCESdlMixerManager(); 38 39 virtual void init(); 40 41 private: 42 43 #ifdef USE_VORBIS 44 bool checkOggHighSampleRate(); 45 #endif 46 47 static void private_sound_proc(void *param, byte *buf, int len); 48 uint32 compute_sample_rate(); 49 50 }; 51 52 #endif 53 -
backends/module.mk
diff -rupN scummvm-df1a800-orig/backends/module.mk scummvm-git/backends/module.mk
old new MODULE_OBJS := \ 12 12 events/samsungtvsdl/samsungtvsdl-events.o \ 13 13 events/sdl/sdl-events.o \ 14 14 events/symbiansdl/symbiansdl-events.o \ 15 events/wincesdl/wincesdl-events.o \ 15 16 fs/abstract-fs.o \ 16 17 fs/stdiostream.o \ 17 18 fs/amigaos4/amigaos4-fs-factory.o \ … … MODULE_OBJS := \ 27 28 graphics/openglsdl/openglsdl-graphics.o \ 28 29 graphics/sdl/sdl-graphics.o \ 29 30 graphics/symbiansdl/symbiansdl-graphics.o \ 31 graphics/wincesdl/wincesdl-graphics.o \ 30 32 keymapper/action.o \ 31 33 keymapper/keymap.o \ 32 34 keymapper/keymapper.o \ … … MODULE_OBJS := \ 44 46 mixer/doublebuffersdl/doublebuffersdl-mixer.o \ 45 47 mixer/sdl/sdl-mixer.o \ 46 48 mixer/symbiansdl/symbiansdl-mixer.o \ 49 mixer/wincesdl/wincesdl-mixer.o \ 47 50 mutex/sdl/sdl-mutex.o \ 48 51 plugins/elf/elf-loader.o \ 49 52 plugins/elf/mips-loader.o \ -
backends/platform/wince/CEActionsPocket.cpp
diff -rupN scummvm-df1a800-orig/backends/platform/wince/CEActionsPocket.cpp scummvm-git/backends/platform/wince/CEActionsPocket.cpp
old new bool CEActionsPocket::perform(GUI::Actio 239 239 if (!pushed) { 240 240 switch (action) { 241 241 case POCKET_ACTION_RIGHTCLICK: 242 _CESystem->add_right_click(false); 242 //_CESystem->add_right_click(false); 243 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_right_click(false); 243 244 return true; 244 245 case POCKET_ACTION_LEFTCLICK: 245 _CESystem->add_left_click(false); 246 //_CESystem->add_left_click(false); 247 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_left_click(false); 246 248 return true; 247 249 case POCKET_ACTION_PAUSE: 248 250 case POCKET_ACTION_SAVE: … … bool CEActionsPocket::perform(GUI::Actio 272 274 EventsBuffer::simulateKey(&_key_action[action], true); 273 275 return true; 274 276 case POCKET_ACTION_KEYBOARD: 275 _CESystem->swap_panel(); 277 //_CESystem->swap_panel(); 278 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_panel(); 276 279 return true; 277 280 case POCKET_ACTION_HIDE: 278 _CESystem->swap_panel_visibility(); 281 //_CESystem->swap_panel_visibility(); 282 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_panel_visibility(); 279 283 return true; 280 284 case POCKET_ACTION_SOUND: 281 285 _CESystem->swap_sound_master(); 282 286 return true; 283 287 case POCKET_ACTION_RIGHTCLICK: 284 _CESystem->add_right_click(true); 288 //_CESystem->add_right_click(true); 289 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_right_click(true); 285 290 return true; 286 291 case POCKET_ACTION_CURSOR: 287 _CESystem->swap_mouse_visibility(); 292 //_CESystem->swap_mouse_visibility(); 293 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_mouse_visibility(); 288 294 return true; 289 295 case POCKET_ACTION_FREELOOK: 290 _CESystem->swap_freeLook(); 296 //_CESystem->swap_freeLook(); 297 ((WINCESdlEventSource *)((OSystem_SDL *)g_system)->getEventManager())->swap_freeLook(); 291 298 return true; 292 299 case POCKET_ACTION_ZOOM_UP: 293 _CESystem->swap_zoom_up(); 300 //_CESystem->swap_zoom_up(); 301 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_zoom_up(); 294 302 return true; 295 303 case POCKET_ACTION_ZOOM_DOWN: 296 _CESystem->swap_zoom_down(); 304 //_CESystem->swap_zoom_down(); 305 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_zoom_down(); 297 306 return true; 298 307 case POCKET_ACTION_LEFTCLICK: 299 _CESystem->add_left_click(true); 308 //_CESystem->add_left_click(true); 309 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_left_click(true); 300 310 return true; 301 311 case POCKET_ACTION_UP: 302 _CESystem->move_cursor_up(); 312 //_CESystem->move_cursor_up(); 313 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_up(); 303 314 return true; 304 315 case POCKET_ACTION_DOWN: 305 _CESystem->move_cursor_down(); 316 //_CESystem->move_cursor_down(); 317 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_down(); 306 318 return true; 307 319 case POCKET_ACTION_LEFT: 308 _CESystem->move_cursor_left(); 320 //_CESystem->move_cursor_left(); 321 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_left(); 309 322 return true; 310 323 case POCKET_ACTION_RIGHT: 311 _CESystem->move_cursor_right(); 324 //_CESystem->move_cursor_right(); 325 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_right(); 312 326 return true; 313 327 case POCKET_ACTION_QUIT: 314 328 if (!quitdialog) { -
backends/platform/wince/CEActionsSmartphone.cpp
diff -rupN scummvm-df1a800-orig/backends/platform/wince/CEActionsSmartphone.cpp scummvm-git/backends/platform/wince/CEActionsSmartphone.cpp
old new bool CEActionsSmartphone::perform(GUI::A 205 205 if (!pushed) { 206 206 switch (action) { 207 207 case SMARTPHONE_ACTION_RIGHTCLICK: 208 _CESystem->add_right_click(false); 208 //_CESystem->add_right_click(false); 209 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_right_click(false); 209 210 return true; 210 211 case SMARTPHONE_ACTION_LEFTCLICK: 211 _CESystem->add_left_click(false); 212 //_CESystem->add_left_click(false); 213 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_left_click(false); 212 214 return true; 213 215 case SMARTPHONE_ACTION_SAVE: 214 216 case SMARTPHONE_ACTION_SKIP: … … bool CEActionsSmartphone::perform(GUI::A 235 237 EventsBuffer::simulateKey(&_key_action[action], true); 236 238 return true; 237 239 case SMARTPHONE_ACTION_RIGHTCLICK: 238 _CESystem->add_right_click(true); 240 //_CESystem->add_right_click(true); 241 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_right_click(true); 239 242 return true; 240 243 case SMARTPHONE_ACTION_LEFTCLICK: 241 _CESystem->add_left_click(true); 244 //_CESystem->add_left_click(true); 245 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->add_left_click(true); 242 246 return true; 243 247 case SMARTPHONE_ACTION_UP: 244 _CESystem->move_cursor_up(); 248 //_CESystem->move_cursor_up(); 249 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_up(); 245 250 return true; 246 251 case SMARTPHONE_ACTION_DOWN: 247 _CESystem->move_cursor_down(); 252 //_CESystem->move_cursor_down(); 253 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_down(); 248 254 return true; 249 255 case SMARTPHONE_ACTION_LEFT: 250 _CESystem->move_cursor_left(); 256 //_CESystem->move_cursor_left(); 257 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_left(); 251 258 return true; 252 259 case SMARTPHONE_ACTION_RIGHT: 253 _CESystem->move_cursor_right(); 260 //_CESystem->move_cursor_right(); 261 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->move_cursor_right(); 254 262 return true; 255 263 case SMARTPHONE_ACTION_ZONE: 256 _CESystem->switch_zone(); 264 //_CESystem->switch_zone(); 265 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->switch_zone(); 257 266 return true; 258 267 case SMARTPHONE_ACTION_BINDKEYS: 259 268 if (!keydialogrunning) { … … bool CEActionsSmartphone::perform(GUI::A 265 274 } 266 275 return true; 267 276 case SMARTPHONE_ACTION_KEYBOARD: 268 _CESystem->swap_smartphone_keyboard(); 277 //_CESystem->swap_smartphone_keyboard(); 278 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->swap_smartphone_keyboard(); 269 279 return true; 270 280 case SMARTPHONE_ACTION_ROTATE: 271 _CESystem->smartphone_rotate_display(); 281 //_CESystem->smartphone_rotate_display(); 282 ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->smartphone_rotate_display(); 272 283 return true; 273 284 case SMARTPHONE_ACTION_QUIT: 274 285 if (!quitdialog) { -
backends/platform/wince/CEDevice.cpp
diff -rupN scummvm-df1a800-orig/backends/platform/wince/CEDevice.cpp scummvm-git/backends/platform/wince/CEDevice.cpp
old new extern "C" void WINAPI SystemIdleTimerRe 44 44 45 45 #define TIMER_TRIGGER 9000 46 46 47 DWORD CEDevice::reg_access( TCHAR *key,TCHAR *val, DWORD data) {47 DWORD CEDevice::reg_access(const TCHAR *key, const TCHAR *val, DWORD data) { 48 48 HKEY regkey; 49 49 DWORD tmpval, cbdata; 50 50 … … DWORD CEDevice::reg_access(TCHAR *key, T 70 70 void CEDevice::backlight_xchg() { 71 71 HANDLE h; 72 72 73 REG_bat = reg_access(TEXT("ControlPanel\\BackLight"), TEXT("BatteryTimeout"), REG_bat);73 REG_bat = reg_access(TEXT("ControlPanel\\BackLight"), (const TCHAR*)TEXT("BatteryTimeout"), REG_bat); 74 74 REG_ac = reg_access(TEXT("ControlPanel\\BackLight"), TEXT("ACTimeout"), REG_ac); 75 75 REG_disp = reg_access(TEXT("ControlPanel\\Power"), TEXT("Display"), REG_disp); 76 76 … … bool CEDevice::hasSquareQVGAResolution() 127 127 return (OSystem_WINCE3::getScreenWidth() == 240 && OSystem_WINCE3::getScreenHeight() == 240); 128 128 } 129 129 130 bool CEDevice::hasWideResolution() { 131 return (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640); 132 } 133 130 134 bool CEDevice::hasPocketPCResolution() { 131 135 if (OSystem_WINCE3::isOzone() && hasWideResolution()) 132 136 return true; … … bool CEDevice::hasDesktopResolution() { 139 143 return (OSystem_WINCE3::getScreenWidth() > 320); 140 144 } 141 145 142 bool CEDevice::hasWideResolution() {143 return (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640);144 }145 146 146 bool CEDevice::hasSmartphoneResolution() { 147 147 return (OSystem_WINCE3::getScreenWidth() < 240); 148 148 } -
backends/platform/wince/CEDevice.h
diff -rupN scummvm-df1a800-orig/backends/platform/wince/CEDevice.h scummvm-git/backends/platform/wince/CEDevice.h
old new public: 43 43 static bool isSmartphone(); 44 44 45 45 private: 46 static DWORD reg_access( TCHAR *key,TCHAR *val, DWORD data);46 static DWORD reg_access(const TCHAR *key, const TCHAR *val, DWORD data); 47 47 static void backlight_xchg(); 48 48 }; 49 49 -
backends/platform/wince/wince-sdl.cpp
diff -rupN scummvm-df1a800-orig/backends/platform/wince/wince-sdl.cpp scummvm-git/backends/platform/wince/wince-sdl.cpp
old new 23 23 * 24 24 */ 25 25 26 26 27 // Disable symbol overrides so that we can use system headers. 27 28 #define FORBIDDEN_SYMBOL_ALLOW_ALL 28 29 … … 43 44 #include "audio/mixer_intern.h" 44 45 #include "audio/fmopl.h" 45 46 46 #include "backends/timer/ default/default-timer.h"47 #include "backends/timer/sdl/sdl-timer.h" 47 48 48 49 #include "gui/Actions.h" 49 50 #include "gui/KeysDialog.h" 50 51 #include "gui/message.h" 51 52 52 #include "backends/platform/wince/resource.h"53 53 #include "backends/platform/wince/CEActionsPocket.h" 54 54 #include "backends/platform/wince/CEActionsSmartphone.h" 55 55 #include "backends/platform/wince/CEgui/ItemAction.h" … … 60 60 #include "backends/platform/wince/CEException.h" 61 61 #include "backends/platform/wince/CEScaler.h" 62 62 63 #ifdef USE_VORBIS 64 #ifndef USE_TREMOR 65 #include <vorbis/vorbisfile.h> 66 #else 67 #include <tremor/ivorbisfile.h> 68 #endif 69 #endif 63 #include "backends/graphics/wincesdl/wincesdl-graphics.h" 64 #include "backends/events/wincesdl/wincesdl-events.h" 65 #include "backends/mixer/wincesdl/wincesdl-mixer.h" 70 66 71 67 #ifdef DYNAMIC_MODULES 72 68 #include "backends/plugins/win32/win32-provider.h" … … 76 72 extern "C" _CRTIMP FILE* __cdecl _wfreopen (const wchar_t*, const wchar_t*, FILE*); 77 73 #endif 78 74 79 #define SAMPLES_PER_SEC_OLD 1102580 #define SAMPLES_PER_SEC_NEW 2205081 82 75 using namespace CEGUI; 83 76 84 77 // ******************************************************************************************** 85 78 86 // Internal GUI names87 88 #define NAME_MAIN_PANEL "MainPanel"89 #define NAME_PANEL_KEYBOARD "Keyboard"90 #define NAME_ITEM_OPTIONS "Options"91 #define NAME_ITEM_SKIP "Skip"92 #define NAME_ITEM_SOUND "Sound"93 #define NAME_ITEM_ORIENTATION "Orientation"94 #define NAME_ITEM_BINDKEYS "Bindkeys"95 96 79 // stdin/err redirection 97 80 #define STDOUT_FNAME "\\scummvm_stdout.txt" 98 81 #define STDERR_FNAME "\\scummvm_stderr.txt" … … bool OSystem_WINCE3::_soundMaster = true 106 89 bool _isSmartphone = false; 107 90 bool _hasSmartphoneResolution = false; 108 91 109 // Graphics mode consts110 111 // Low end devices 240x320112 113 static const OSystem::GraphicsMode s_supportedGraphicsModesLow[] = {114 {"1x", _s("Normal (no scaling)"), GFX_NORMAL},115 {0, 0, 0}116 };117 118 // High end device 480x640119 120 static const OSystem::GraphicsMode s_supportedGraphicsModesHigh[] = {121 {"1x", _s("Normal (no scaling)"), GFX_NORMAL},122 {"2x", "2x", GFX_DOUBLESIZE},123 #ifndef _MSC_VER // EVC breaks template functions, and I'm tired of fixing them :)124 {"2xsai", "2xSAI", GFX_2XSAI},125 {"super2xsai", "Super2xSAI", GFX_SUPER2XSAI},126 {"supereagle", "SuperEagle", GFX_SUPEREAGLE},127 #endif128 {"advmame2x", "AdvMAME2x", GFX_ADVMAME2X},129 #ifndef _MSC_VER130 {"hq2x", "HQ2x", GFX_HQ2X},131 {"tv2x", "TV2x", GFX_TV2X},132 #endif133 {"dotmatrix", "DotMatrix", GFX_DOTMATRIX},134 {0, 0, 0}135 };136 137 92 #define DEFAULT_CONFIG_FILE "scummvm.ini" 138 93 139 94 // ******************************************************************************************** … … int dynamic_modules_main(HINSTANCE hInst 380 335 381 336 // ******************************************************************************************** 382 337 383 384 338 // ******************************************************************************************** 385 339 386 340 void pumpMessages() { … … static Uint32 timer_handler_wrapper(Uint 407 361 } 408 362 409 363 void OSystem_WINCE3::initBackend() { 410 // Instantiate our own sound mixer 411 // mixer init is rerun when a game engine is selected. 412 setupMixer(); 364 365 assert(!_inited); 366 367 // Create the backend custom managers 368 if (_eventSource == 0) 369 _eventSource = new WINCESdlEventSource(); 370 371 if (_mixerManager == 0) { 372 _mixerManager = new WINCESdlMixerManager(); 373 374 // Setup and start mixer 375 _mixerManager->init(); 376 } 377 378 if (_graphicsManager == 0) 379 _graphicsManager = new WINCESdlGraphicsManager(_eventSource); 413 380 414 381 // Create the timer. CE SDL does not support multiple timers (SDL_AddTimer). 415 382 // We work around this by using the SetTimer function, since we only use 416 383 // one timer in scummvm (for the time being) 417 384 _timer = _int_timer = new DefaultTimerManager(); 418 _timerID = NULL; // OSystem_SDL will call removetimer with this, it's ok385 //_timerID = NULL; // OSystem_SDL will call removetimer with this, it's ok 419 386 SDL_SetTimer(10, &timer_handler_wrapper); 420 387 421 388 // Chain init 422 389 OSystem_SDL::initBackend(); 423 390 424 // Query SDL for screen size and init screen dependent stuff425 OSystem_WINCE3::initScreenInfos();426 _isSmartphone = CEDevice::isSmartphone();427 create_toolbar();428 _hasSmartphoneResolution = CEDevice::hasSmartphoneResolution() || CEDevice::isSmartphone();429 if (_hasSmartphoneResolution)430 _panelVisible = false; // init correctly in smartphones431 432 391 // Initialize global key mapping 433 392 GUI::Actions::init(); 434 393 GUI_Actions::Instance()->initInstanceMain(this); … … void OSystem_WINCE3::initBackend() { 437 396 GUI_Actions::Instance()->saveMapping(); // write defaults 438 397 } 439 398 440 loadDeviceConfiguration(); 399 // Call parent implementation of this method 400 //OSystem_SDL::initBackend(); 401 402 _inited = true; 441 403 } 442 404 443 405 int OSystem_WINCE3::getScreenWidth() { 444 406 return _platformScreenWidth; 445 407 } 446 408 447 int OSystem_WINCE3::getScreenHeight() {448 return _platformScreenHeight;449 }450 451 409 void OSystem_WINCE3::initScreenInfos() { 452 410 // sdl port ensures that we use correctly full screen 453 411 _isOzone = 0; … … void OSystem_WINCE3::initScreenInfos() { 457 415 _platformScreenHeight = r[0]->h; 458 416 } 459 417 418 int OSystem_WINCE3::getScreenHeight() { 419 return _platformScreenHeight; 420 } 421 460 422 bool OSystem_WINCE3::isOzone() { 461 423 return _isOzone; 462 424 } … … Common::String OSystem_WINCE3::getDefaul 473 435 474 436 475 437 OSystem_WINCE3::OSystem_WINCE3() : OSystem_SDL(), 476 _orientationLandscape(0), _newOrientation(0), _panelInitialized(false), _canBeAspectScaled(false), 477 _panelVisible(true), _panelStateForced(false), _forceHideMouse(false), _unfilteredkeys(false), 478 _freeLook(false), _forcePanelInvisible(false), _toolbarHighDrawn(false), _zoomUp(false), _zoomDown(false), 479 _scalersChanged(false), _lastKeyPressed(0), _tapTime(0), _closeClick(false), _noDoubleTapRMB(false), 480 _saveToolbarState(false), _saveActiveToolbar(NAME_MAIN_PANEL), _rbutton(false), _hasfocus(true), 481 _usesEmulatedMouse(false), _mouseBackupOld(NULL), _mouseBackupToolbar(NULL), _mouseBackupDim(0) 438 _forcePanelInvisible(false) 482 439 { 483 memset(&_mouseCurState, 0, sizeof(_mouseCurState)); 484 if (_isSmartphone) { 485 _mouseCurState.x = 20; 486 _mouseCurState.y = 20; 487 } 488 440 // Initialze File System Factory 441 _fsFactory = new WindowsFilesystemFactory(); 489 442 _mixer = 0; 490 _screen = NULL;491 443 } 492 444 493 void OSystem_WINCE3::swap_panel_visibility() { 494 //if (!_forcePanelInvisible && !_panelStateForced) { 495 if (_zoomDown || _zoomUp) return; 496 497 if (_panelVisible) { 498 if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD) 499 _panelVisible = !_panelVisible; 500 else 501 _toolbarHandler.setActive(NAME_PANEL_KEYBOARD); 502 } else { 503 _toolbarHandler.setActive(NAME_MAIN_PANEL); 504 _panelVisible = !_panelVisible; 505 } 506 _toolbarHandler.setVisible(_panelVisible); 507 _toolbarHighDrawn = false; 508 509 if (_videoMode.screenHeight > 240) 510 addDirtyRect(0, 400, 640, 80); 511 else 512 addDirtyRect(0, 200, 320, 40); 513 514 if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible) 515 internUpdateScreen(); 516 else { 517 update_scalers(); 518 hotswapGFXMode(); 519 } 520 //} 445 OSystem_WINCE3::~OSystem_WINCE3() { 446 delete _fsFactory; 447 delete _mixer; 521 448 } 522 449 523 void OSystem_WINCE3::swap_panel() { 524 _toolbarHighDrawn = false; 525 //if (!_panelStateForced) { 526 if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible) 527 _toolbarHandler.setActive(NAME_MAIN_PANEL); 528 else 529 _toolbarHandler.setActive(NAME_PANEL_KEYBOARD); 530 531 if (_videoMode.screenHeight > 240) 532 addDirtyRect(0, 400, 640, 80); 533 else 534 addDirtyRect(0, 200, 320, 40); 535 536 _toolbarHandler.setVisible(true); 537 if (!_panelVisible) { 538 _panelVisible = true; 539 update_scalers(); 540 hotswapGFXMode(); 541 } 542 //} 543 } 544 545 void OSystem_WINCE3::swap_smartphone_keyboard() { 546 _toolbarHandler.setActive(NAME_PANEL_KEYBOARD); 547 _panelVisible = !_panelVisible; 548 _toolbarHandler.setVisible(_panelVisible); 549 if (_videoMode.screenHeight > 240) 550 addDirtyRect(0, 0, 640, 80); 551 else 552 addDirtyRect(0, 0, 320, 40); 553 internUpdateScreen(); 554 } 555 556 void OSystem_WINCE3::smartphone_rotate_display() { 557 _orientationLandscape = _newOrientation = _orientationLandscape == 1 ? 2 : 1; 558 ConfMan.setInt("landscape", _orientationLandscape); 559 ConfMan.flushToDisk(); 560 hotswapGFXMode(); 450 FilesystemFactory *OSystem_WINCE3::getFilesystemFactory() { 451 return _fsFactory; 561 452 } 562 453 563 454 void OSystem_WINCE3::swap_sound_master() { 564 455 _soundMaster = !_soundMaster; 565 if (_toolbarHandler.activeName() == NAME_MAIN_PANEL)566 _toolbarHandler.forceRedraw(); // redraw sound icon567 }568 456 569 void OSystem_WINCE3::add_right_click(bool pushed) { 570 int x, y; 571 retrieve_mouse_location(x, y); 572 EventsBuffer::simulateMouseRightClick(x, y, pushed); 573 } 574 575 void OSystem_WINCE3::swap_mouse_visibility() { 576 _forceHideMouse = !_forceHideMouse; 577 if (_forceHideMouse) 578 undrawMouse(); 579 } 580 581 void OSystem_WINCE3::swap_freeLook() { 582 _freeLook = !_freeLook; 583 } 584 585 void OSystem_WINCE3::swap_zoom_up() { 586 if (_zoomUp) { 587 // restore visibility 588 _toolbarHandler.setVisible(_saveToolbarZoom); 589 // restore scaler 590 _scaleFactorYd = 2; 591 _scalerProc = DownscaleAllByHalf; 592 _zoomUp = false; 593 _zoomDown = false; 594 } else { 595 // only active if running on a PocketPC 596 if (_scalerProc != DownscaleAllByHalf && _scalerProc != DownscaleHorizByHalf) 597 return; 598 if (_scalerProc == DownscaleAllByHalf) { 599 _saveToolbarZoom = _toolbarHandler.visible(); 600 _toolbarHandler.setVisible(false); 601 // set zoom scaler 602 _scaleFactorYd = 1; 603 _scalerProc = DownscaleHorizByHalf; 604 } 457 //WINCESdlGraphicsManager _graphicsManager 605 458 606 _zoomDown = false; 607 _zoomUp = true; 608 } 609 // redraw whole screen 610 addDirtyRect(0, 0, 640, 480); 611 internUpdateScreen(); 612 } 613 614 void OSystem_WINCE3::swap_zoom_down() { 615 if (_zoomDown) { 616 // restore visibility 617 _toolbarHandler.setVisible(_saveToolbarZoom); 618 // restore scaler 619 _scaleFactorYd = 2; 620 _scalerProc = DownscaleAllByHalf; 621 _zoomDown = false; 622 _zoomUp = false; 623 } else { 624 // only active if running on a PocketPC 625 if (_scalerProc != DownscaleAllByHalf && _scalerProc != DownscaleHorizByHalf) 626 return; 627 if (_scalerProc == DownscaleAllByHalf) { 628 _saveToolbarZoom = _toolbarHandler.visible(); 629 _toolbarHandler.setVisible(false); 630 // set zoom scaler 631 _scaleFactorYd = 1; 632 _scalerProc = DownscaleHorizByHalf; 633 } 634 635 _zoomUp = false; 636 _zoomDown = true; 637 } 638 // redraw whole screen 639 addDirtyRect(0, 0, 640, 480); 640 internUpdateScreen(); 641 } 642 643 // Smartphone actions 644 void OSystem_WINCE3::initZones() { 645 int i; 646 647 _currentZone = 0; 648 for (i = 0; i < TOTAL_ZONES; i++) { 649 _mouseXZone[i] = (_zones[i].x + (_zones[i].width / 2)) * _scaleFactorXm / _scaleFactorXd; 650 _mouseYZone[i] = (_zones[i].y + (_zones[i].height / 2)) * _scaleFactorYm / _scaleFactorYd; 651 } 652 } 653 654 void OSystem_WINCE3::loadDeviceConfigurationElement(String element, int &value, int defaultValue) { 655 value = ConfMan.getInt(element, ConfMan.kApplicationDomain); 656 if (!value) { 657 value = defaultValue; 658 ConfMan.setInt(element, value, ConfMan.kApplicationDomain); 659 } 459 if (((WINCESdlGraphicsManager*)_graphicsManager)->_toolbarHandler.activeName() == NAME_MAIN_PANEL) 460 ((WINCESdlGraphicsManager*)_graphicsManager)->_toolbarHandler.forceRedraw(); // redraw sound icon 660 461 } 661 462 662 void OSystem_WINCE3::loadDeviceConfiguration() {663 loadDeviceConfigurationElement("repeatTrigger", _keyRepeatTrigger, 200);664 loadDeviceConfigurationElement("repeatX", _repeatX, 4);665 loadDeviceConfigurationElement("repeatY", _repeatY, 4);666 loadDeviceConfigurationElement("stepX1", _stepX1, 2);667 loadDeviceConfigurationElement("stepX2", _stepX2, 10);668 loadDeviceConfigurationElement("stepX3", _stepX3, 40);669 loadDeviceConfigurationElement("stepY1", _stepY1, 2);670 loadDeviceConfigurationElement("stepY2", _stepY2, 10);671 loadDeviceConfigurationElement("stepY3", _stepY3, 20);672 ConfMan.flushToDisk();673 }674 675 void OSystem_WINCE3::add_left_click(bool pushed) {676 int x, y;677 retrieve_mouse_location(x, y);678 EventsBuffer::simulateMouseLeftClick(x, y, pushed);679 }680 681 void OSystem_WINCE3::move_cursor_up() {682 int x, y;683 _usesEmulatedMouse = true;684 retrieve_mouse_location(x, y);685 if (_keyRepeat > _repeatY)686 y -= _stepY3;687 else if (_keyRepeat)688 y -= _stepY2;689 else690 y -= _stepY1;691 692 if (y < 0)693 y = 0;694 695 EventsBuffer::simulateMouseMove(x, y);696 }697 698 void OSystem_WINCE3::move_cursor_down() {699 int x, y;700 _usesEmulatedMouse = true;701 retrieve_mouse_location(x, y);702 if (_keyRepeat > _repeatY)703 y += _stepY3;704 else if (_keyRepeat)705 y += _stepY2;706 else707 y += _stepY1;708 709 if (y > _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd)710 y = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd;711 712 EventsBuffer::simulateMouseMove(x, y);713 }714 715 void OSystem_WINCE3::move_cursor_left() {716 int x, y;717 _usesEmulatedMouse = true;718 retrieve_mouse_location(x, y);719 if (_keyRepeat > _repeatX)720 x -= _stepX3;721 else if (_keyRepeat)722 x -= _stepX2;723 else724 x -= _stepX1;725 726 if (x < 0)727 x = 0;728 729 EventsBuffer::simulateMouseMove(x, y);730 }731 732 void OSystem_WINCE3::move_cursor_right() {733 int x, y;734 _usesEmulatedMouse = true;735 retrieve_mouse_location(x, y);736 if (_keyRepeat > _repeatX)737 x += _stepX3;738 else if (_keyRepeat)739 x += _stepX2;740 else741 x += _stepX1;742 743 if (x > _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd)744 x = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd;745 746 EventsBuffer::simulateMouseMove(x, y);747 }748 749 void OSystem_WINCE3::switch_zone() {750 int x, y;751 int i;752 retrieve_mouse_location(x, y);753 754 for (i = 0; i < TOTAL_ZONES; i++)755 if (x >= _zones[i].x && y >= _zones[i].y &&756 x <= _zones[i].x + _zones[i].width && y <= _zones[i].y + _zones[i].height) {757 _mouseXZone[i] = x;758 _mouseYZone[i] = y;759 break;760 }761 _currentZone = i + 1;762 if (_currentZone >= TOTAL_ZONES)763 _currentZone = 0;764 765 EventsBuffer::simulateMouseMove(_mouseXZone[_currentZone], _mouseYZone[_currentZone]);766 }767 768 void OSystem_WINCE3::create_toolbar() {769 PanelKeyboard *keyboard;770 771 // Add the keyboard772 keyboard = new PanelKeyboard(PANEL_KEYBOARD);773 _toolbarHandler.add(NAME_PANEL_KEYBOARD, *keyboard);774 _toolbarHandler.setVisible(false);775 }776 777 void OSystem_WINCE3::setupMixer() {778 SDL_AudioSpec desired;779 int thread_priority;780 781 uint32 sampleRate = compute_sample_rate();782 if (sampleRate == 0)783 warning("OSystem_WINCE3::setupMixer called with sample rate 0 - audio will not work");784 else if (_mixer && _mixer->getOutputRate() == sampleRate) {785 debug(1, "Skipping sound mixer re-init: samplerate is good");786 return;787 }788 789 memset(&desired, 0, sizeof(desired));790 desired.freq = sampleRate;791 desired.format = AUDIO_S16SYS;792 desired.channels = 2;793 desired.samples = 128;794 desired.callback = private_sound_proc;795 desired.userdata = this;796 797 // Create the mixer instance798 if (_mixer == 0)799 _mixer = new Audio::MixerImpl(this, sampleRate);800 801 // Add sound thread priority802 if (!ConfMan.hasKey("sound_thread_priority"))803 thread_priority = THREAD_PRIORITY_NORMAL;804 else805 thread_priority = ConfMan.getInt("sound_thread_priority");806 807 desired.thread_priority = thread_priority;808 809 SDL_CloseAudio();810 if (SDL_OpenAudio(&desired, NULL) != 0) {811 warning("Could not open audio device: %s", SDL_GetError());812 _mixer->setReady(false);813 814 } else {815 debug(1, "Sound opened OK, mixing at %d Hz", sampleRate);816 817 // Re-create mixer to match the output rate818 int vol1 = _mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);819 int vol2 = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);820 int vol3 = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);821 int vol4 = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);822 delete _mixer;823 _mixer = new Audio::MixerImpl(this, sampleRate);824 _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, vol1);825 _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol2);826 _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, vol3);827 _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, vol4);828 _mixer->setReady(true);829 SDL_PauseAudio(0);830 }831 }832 833 void OSystem_WINCE3::private_sound_proc(void *param, byte *buf, int len) {834 OSystem_WINCE3 *this_ = (OSystem_WINCE3 *)param;835 assert(this_);836 837 if (this_->_mixer)838 this_->_mixer->mixCallback(buf, len);839 if (!_soundMaster)840 memset(buf, 0, len);841 }842 843 #ifdef USE_VORBIS844 bool OSystem_WINCE3::checkOggHighSampleRate() {845 char trackFile[255];846 FILE *testFile;847 OggVorbis_File *test_ov_file = new OggVorbis_File;848 849 // FIXME: The following sprintf assumes that "path" is always850 // terminated by a path separator. This is *not* true in general.851 // This code really should check for the path separator, or even852 // better, use the FSNode API.853 sprintf(trackFile, "%sTrack1.ogg", ConfMan.get("path").c_str());854 // Check if we have an OGG audio track855 testFile = fopen(trackFile, "rb");856 if (testFile) {857 if (!ov_open(testFile, test_ov_file, NULL, 0)) {858 bool highSampleRate = (ov_info(test_ov_file, -1)->rate == 22050);859 ov_clear(test_ov_file);860 delete test_ov_file;861 return highSampleRate;862 }863 }864 865 // Do not test for OGG samples - too big and too slow anyway :)866 867 delete test_ov_file;868 return false;869 }870 #endif871 872 uint32 OSystem_WINCE3::compute_sample_rate() {873 uint32 sampleRate;874 875 // Force at least medium quality FM synthesis for FOTAQ876 Common::String gameid(ConfMan.get("gameid"));877 if (gameid == "queen") {878 if (!((ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) ||879 (ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")))) {880 ConfMan.setBool("FM_medium_quality", true);881 ConfMan.flushToDisk();882 }883 }884 // See if the output frequency is forced by the game885 if (gameid == "ft" || gameid == "dig" || gameid == "comi" || gameid == "queen" || gameid == "sword" || gameid == "agi")886 sampleRate = SAMPLES_PER_SEC_NEW;887 else {888 if (ConfMan.hasKey("high_sample_rate") && ConfMan.getBool("high_sample_rate"))889 sampleRate = SAMPLES_PER_SEC_NEW;890 else891 sampleRate = SAMPLES_PER_SEC_OLD;892 }893 894 #ifdef USE_VORBIS895 // Modify the sample rate on the fly if OGG is involved896 if (sampleRate == SAMPLES_PER_SEC_OLD)897 if (checkOggHighSampleRate())898 sampleRate = SAMPLES_PER_SEC_NEW;899 #endif900 901 return sampleRate;902 }903 463 904 464 void OSystem_WINCE3::engineInit() { 905 465 check_mappings(); // called here to initialize virtual keys handling 906 466 907 467 //update_game_settings(); 908 468 // finalize mixer init 909 setupMixer(); 910 } 911 912 const OSystem::GraphicsMode *OSystem_WINCE3::getSupportedGraphicsModes() const { 913 if (CEDevice::hasWideResolution()) 914 return s_supportedGraphicsModesHigh; 915 else 916 return s_supportedGraphicsModesLow; 917 } 918 919 bool OSystem_WINCE3::hasFeature(Feature f) { 920 return (f == kFeatureVirtualKeyboard); 921 } 922 923 void OSystem_WINCE3::setFeatureState(Feature f, bool enable) { 924 switch (f) { 925 case kFeatureFullscreenMode: 926 return; 927 928 case kFeatureVirtualKeyboard: 929 if (_hasSmartphoneResolution) 930 return; 931 _toolbarHighDrawn = false; 932 if (enable) { 933 _panelStateForced = true; 934 if (!_toolbarHandler.visible()) swap_panel_visibility(); 935 //_saveToolbarState = _toolbarHandler.visible(); 936 _saveActiveToolbar = _toolbarHandler.activeName(); 937 _toolbarHandler.setActive(NAME_PANEL_KEYBOARD); 938 _toolbarHandler.setVisible(true); 939 } else 940 if (_panelStateForced) { 941 _panelStateForced = false; 942 _toolbarHandler.setActive(_saveActiveToolbar); 943 //_toolbarHandler.setVisible(_saveToolbarState); 944 } 945 return; 946 947 case kFeatureDisableKeyFiltering: 948 if (_hasSmartphoneResolution) 949 _unfilteredkeys = enable; 950 return; 951 952 default: 953 OSystem_SDL::setFeatureState(f, enable); 954 } 955 } 956 957 bool OSystem_WINCE3::getFeatureState(Feature f) { 958 switch (f) { 959 case kFeatureFullscreenMode: 960 return false; 961 case kFeatureVirtualKeyboard: 962 return (_panelStateForced); 963 default: 964 return OSystem_SDL::getFeatureState(f); 965 } 469 _mixerManager->init(); 966 470 } 967 471 968 472 void OSystem_WINCE3::check_mappings() { … … void OSystem_WINCE3::check_mappings() { 1021 525 1022 526 } 1023 527 1024 void OSystem_WINCE3::update_game_settings() {1025 Common::String gameid(ConfMan.get("gameid"));1026 1027 // Finish panel initialization1028 if (!_panelInitialized && !gameid.empty()) {1029 Panel *panel;1030 _panelInitialized = true;1031 // Add the main panel1032 panel = new Panel(0, 32);1033 panel->setBackground(IMAGE_PANEL);1034 // Save1035 panel->add(NAME_ITEM_OPTIONS, new ItemAction(ITEM_OPTIONS, POCKET_ACTION_SAVE));1036 // Skip1037 panel->add(NAME_ITEM_SKIP, new ItemAction(ITEM_SKIP, POCKET_ACTION_SKIP));1038 // sound1039 panel->add(NAME_ITEM_SOUND, new ItemSwitch(ITEM_SOUND_OFF, ITEM_SOUND_ON, &_soundMaster));1040 // bind keys1041 panel->add(NAME_ITEM_BINDKEYS, new ItemAction(ITEM_BINDKEYS, POCKET_ACTION_BINDKEYS));1042 // portrait/landscape - screen dependent1043 // FIXME : will still display the portrait/landscape icon when using a scaler (but will be disabled)1044 if (ConfMan.hasKey("landscape")) {1045 if (ConfMan.get("landscape")[0] > 57) {1046 _newOrientation = _orientationLandscape = ConfMan.getBool("landscape");1047 //ConfMan.removeKey("landscape", "");1048 ConfMan.setInt("landscape", _orientationLandscape);1049 } else1050 _newOrientation = _orientationLandscape = ConfMan.getInt("landscape");1051 } else {1052 _newOrientation = _orientationLandscape = 0;1053 }1054 panel->add(NAME_ITEM_ORIENTATION, new ItemSwitch(ITEM_VIEW_LANDSCAPE, ITEM_VIEW_PORTRAIT, &_newOrientation, 2));1055 _toolbarHandler.add(NAME_MAIN_PANEL, *panel);1056 _toolbarHandler.setActive(NAME_MAIN_PANEL);1057 _toolbarHandler.setVisible(true);1058 1059 if (_videoMode.mode == GFX_NORMAL && ConfMan.hasKey("landscape") && ConfMan.getInt("landscape")) {1060 setGraphicsMode(GFX_NORMAL);1061 hotswapGFXMode();1062 }1063 1064 if (_hasSmartphoneResolution)1065 panel->setVisible(false);1066 1067 _saveToolbarState = true;1068 }1069 1070 if (ConfMan.hasKey("no_doubletap_rightclick"))1071 _noDoubleTapRMB = ConfMan.getBool("no_doubletap_rightclick");1072 }1073 1074 void OSystem_WINCE3::initSize(uint w, uint h, const Graphics::PixelFormat *format) {1075 if (_hasSmartphoneResolution && h == 240)1076 h = 200; // mainly for the launcher1077 1078 if (_isSmartphone && !ConfMan.hasKey("landscape")) {1079 ConfMan.setInt("landscape", 1);1080 ConfMan.flushToDisk();1081 }1082 1083 _canBeAspectScaled = false;1084 if (w == 320 && h == 200 && !_hasSmartphoneResolution) {1085 _canBeAspectScaled = true;1086 h = 240; // use the extra 40 pixels height for the toolbar1087 }1088 1089 if (h == 400) // touche engine fixup1090 h += 80;1091 1092 if (!_hasSmartphoneResolution) {1093 if (h == 240)1094 _toolbarHandler.setOffset(200);1095 else1096 _toolbarHandler.setOffset(400);1097 } else {1098 if (h == 240)1099 _toolbarHandler.setOffset(200);1100 else // 176x2201101 _toolbarHandler.setOffset(0);1102 }1103 1104 if (w != (uint) _videoMode.screenWidth || h != (uint) _videoMode.screenHeight)1105 _scalersChanged = false;1106 1107 _videoMode.overlayWidth = w;1108 _videoMode.overlayHeight = h;1109 1110 OSystem_SDL::initSize(w, h, format);1111 1112 if (_scalersChanged) {1113 unloadGFXMode();1114 loadGFXMode();1115 _scalersChanged = false;1116 }1117 1118 update_game_settings();1119 }1120 1121 1122 int OSystem_WINCE3::getDefaultGraphicsMode() const {1123 return GFX_NORMAL;1124 }1125 1126 528 void OSystem_WINCE3::setGraphicsModeIntern() { 1127 529 // Scalers have been pre-selected for the desired mode. 1128 530 // No further tuning required. 1129 531 } 1130 532 1131 bool OSystem_WINCE3::update_scalers() { 1132 _videoMode.aspectRatioCorrection = false; 533 void OSystem_WINCE3::initSDL() { 534 // Check if SDL has not been initialized 535 if (!_initedSDL) { 536 uint32 sdlFlags = SDL_INIT_EVENTTHREAD; 537 if (ConfMan.hasKey("disable_sdl_parachute")) 538 sdlFlags |= SDL_INIT_NOPARACHUTE; 539 540 if (ConfMan.hasKey("use_GDI") && ConfMan.getBool("use_GDI")) { 541 SDL_VideoInit("windib", 0); 542 sdlFlags ^= SDL_INIT_VIDEO; 543 } 544 545 // Initialize SDL (SDL Subsystems are initiliazed in the corresponding sdl managers) 546 if (SDL_Init(sdlFlags) == -1) 547 error("Could not initialize SDL: %s", SDL_GetError()); 1133 548 1134 if (CEDevice::hasPocketPCResolution()) { 1135 if (_videoMode.mode != GFX_NORMAL) 1136 return false; 1137 1138 if ((!_orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth)) 1139 || CEDevice::hasSquareQVGAResolution() ) { 1140 if (getScreenWidth() != 320) { 1141 _scaleFactorXm = 3; 1142 _scaleFactorXd = 4; 1143 _scaleFactorYm = 1; 1144 _scaleFactorYd = 1; 1145 _scalerProc = DownscaleHorizByThreeQuarters; 1146 } else { 1147 _scaleFactorXm = 1; 1148 _scaleFactorXd = 1; 1149 _scaleFactorYm = 1; 1150 _scaleFactorYd = 1; 1151 _scalerProc = Normal1x; 1152 } 1153 } else if ( _orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth)) { 1154 if (!_panelVisible && !_hasSmartphoneResolution && !_overlayVisible && _canBeAspectScaled) { 1155 _scaleFactorXm = 1; 1156 _scaleFactorXd = 1; 1157 _scaleFactorYm = 6; 1158 _scaleFactorYd = 5; 1159 _scalerProc = Normal1xAspect; 1160 _videoMode.aspectRatioCorrection = true; 1161 } else { 1162 _scaleFactorXm = 1; 1163 _scaleFactorXd = 1; 1164 _scaleFactorYm = 1; 1165 _scaleFactorYd = 1; 1166 _scalerProc = Normal1x; 1167 } 1168 } else if (_videoMode.screenWidth == 640 && !(isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) { 1169 _scaleFactorXm = 1; 1170 _scaleFactorXd = 2; 1171 _scaleFactorYm = 1; 1172 _scaleFactorYd = 2; 1173 _scalerProc = DownscaleAllByHalf; 1174 } else if (_videoMode.screenWidth == 640 && (isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) { 1175 _scaleFactorXm = 1; 1176 _scaleFactorXd = 1; 1177 _scaleFactorYm = 1; 1178 _scaleFactorYd = 1; 1179 _scalerProc = Normal1x; 1180 } 549 // Enable unicode support if possible 550 SDL_EnableUNICODE(1); 1181 551 1182 return true; 1183 } else if (CEDevice::hasWideResolution()) { 1184 #ifdef USE_ARM_SCALER_ASM 1185 if ( _videoMode.mode == GFX_DOUBLESIZE && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth) ) { 1186 if ( !_panelVisible && !_overlayVisible && _canBeAspectScaled ) { 1187 _scaleFactorXm = 2; 1188 _scaleFactorXd = 1; 1189 _scaleFactorYm = 12; 1190 _scaleFactorYd = 5; 1191 _scalerProc = Normal2xAspect; 1192 _videoMode.aspectRatioCorrection = true; 1193 } else if ( (_panelVisible || _overlayVisible) && _canBeAspectScaled ) { 1194 _scaleFactorXm = 2; 1195 _scaleFactorXd = 1; 1196 _scaleFactorYm = 2; 1197 _scaleFactorYd = 1; 1198 _scalerProc = Normal2x; 1199 } 1200 return true; 1201 } 1202 #endif 1203 } else if (CEDevice::hasSmartphoneResolution()) { 1204 if (_videoMode.mode != GFX_NORMAL) 1205 return false; 1206 1207 if (_videoMode.screenWidth > 320) 1208 error("Game resolution not supported on Smartphone"); 1209 #ifdef ARM 1210 _scaleFactorXm = 11; 1211 _scaleFactorXd = 16; 1212 #else 1213 _scaleFactorXm = 2; 1214 _scaleFactorXd = 3; 1215 #endif 1216 _scaleFactorYm = 7; 1217 _scaleFactorYd = 8; 1218 _scalerProc = SmartphoneLandscape; 1219 initZones(); 1220 return true; 552 _initedSDL = true; 1221 553 } 1222 1223 return false;1224 }1225 1226 bool OSystem_WINCE3::setGraphicsMode(int mode) {1227 1228 Common::StackLock lock(_graphicsMutex);1229 int oldScaleFactorXm = _scaleFactorXm;1230 int oldScaleFactorXd = _scaleFactorXd;1231 int oldScaleFactorYm = _scaleFactorYm;1232 int oldScaleFactorYd = _scaleFactorYd;1233 1234 _scaleFactorXm = -1;1235 _scaleFactorXd = -1;1236 _scaleFactorYm = -1;1237 _scaleFactorYd = -1;1238 1239 if (ConfMan.hasKey("landscape"))1240 if (ConfMan.get("landscape")[0] > 57) {1241 _newOrientation = _orientationLandscape = ConfMan.getBool("landscape");1242 ConfMan.setInt("landscape", _orientationLandscape);1243 } else1244 _newOrientation = _orientationLandscape = ConfMan.getInt("landscape");1245 else1246 _newOrientation = _orientationLandscape = 0;1247 1248 if (isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640) && mode)1249 _scaleFactorXm = -1;1250 1251 if (CEDevice::hasPocketPCResolution() && !CEDevice::hasWideResolution() && _orientationLandscape)1252 _videoMode.mode = GFX_NORMAL;1253 else1254 _videoMode.mode = mode;1255 1256 if (_scaleFactorXm < 0) {1257 /* Standard scalers, from the SDL backend */1258 switch (_videoMode.mode) {1259 case GFX_NORMAL:1260 _videoMode.scaleFactor = 1;1261 _scalerProc = Normal1x;1262 break;1263 case GFX_DOUBLESIZE:1264 _videoMode.scaleFactor = 2;1265 _scalerProc = Normal2x;1266 break;1267 case GFX_TRIPLESIZE:1268 _videoMode.scaleFactor = 3;1269 _scalerProc = Normal3x;1270 break;1271 case GFX_2XSAI:1272 _videoMode.scaleFactor = 2;1273 _scalerProc = _2xSaI;1274 break;1275 case GFX_SUPER2XSAI:1276 _videoMode.scaleFactor = 2;1277 _scalerProc = Super2xSaI;1278 break;1279 case GFX_SUPEREAGLE:1280 _videoMode.scaleFactor = 2;1281 _scalerProc = SuperEagle;1282 break;1283 case GFX_ADVMAME2X:1284 _videoMode.scaleFactor = 2;1285 _scalerProc = AdvMame2x;1286 break;1287 case GFX_ADVMAME3X:1288 _videoMode.scaleFactor = 3;1289 _scalerProc = AdvMame3x;1290 break;1291 #ifdef USE_HQ_SCALERS1292 case GFX_HQ2X:1293 _videoMode.scaleFactor = 2;1294 _scalerProc = HQ2x;1295 break;1296 case GFX_HQ3X:1297 _videoMode.scaleFactor = 3;1298 _scalerProc = HQ3x;1299 break;1300 #endif1301 case GFX_TV2X:1302 _videoMode.scaleFactor = 2;1303 _scalerProc = TV2x;1304 break;1305 case GFX_DOTMATRIX:1306 _videoMode.scaleFactor = 2;1307 _scalerProc = DotMatrix;1308 break;1309 1310 default:1311 error("unknown gfx mode %d", mode);1312 }1313 }1314 1315 // Check if the scaler can be accepted, if not get back to normal scaler1316 if (_videoMode.scaleFactor && ((_videoMode.scaleFactor * _videoMode.screenWidth > getScreenWidth() && _videoMode.scaleFactor * _videoMode.screenWidth > getScreenHeight())1317 || (_videoMode.scaleFactor * _videoMode.screenHeight > getScreenWidth() && _videoMode.scaleFactor * _videoMode.screenHeight > getScreenHeight()))) {1318 _videoMode.scaleFactor = 1;1319 _scalerProc = Normal1x;1320 }1321 1322 // Common scaler system was used1323 if (_scaleFactorXm < 0) {1324 _scaleFactorXm = _videoMode.scaleFactor;1325 _scaleFactorXd = 1;1326 _scaleFactorYm = _videoMode.scaleFactor;1327 _scaleFactorYd = 1;1328 }1329 1330 _forceFull = true;1331 1332 if (oldScaleFactorXm != _scaleFactorXm ||1333 oldScaleFactorXd != _scaleFactorXd ||1334 oldScaleFactorYm != _scaleFactorYm ||1335 oldScaleFactorYd != _scaleFactorYd) {1336 _scalersChanged = true;1337 }1338 else1339 _scalersChanged = false;1340 1341 1342 return true;1343 1344 }1345 1346 bool OSystem_WINCE3::loadGFXMode() {1347 int displayWidth;1348 int displayHeight;1349 unsigned int flags = SDL_FULLSCREEN | SDL_SWSURFACE;1350 1351 _videoMode.fullscreen = true; // forced1352 _forceFull = true;1353 1354 _tmpscreen = NULL;1355 1356 // Recompute scalers if necessary1357 update_scalers();1358 1359 // Create the surface that contains the 8 bit game data1360 _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);1361 if (_screen == NULL)1362 error("_screen failed (%s)", SDL_GetError());1363 1364 // Create the surface that contains the scaled graphics in 16 bit mode1365 // Always use full screen mode to have a "clean screen"1366 if (!_videoMode.aspectRatioCorrection) {1367 displayWidth = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd;1368 displayHeight = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd;1369 } else {1370 displayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;1371 displayHeight = _videoMode.screenHeight* _videoMode.scaleFactor;1372 }1373 1374 switch (_orientationLandscape) {1375 case 1:1376 flags |= SDL_LANDSCVIDEO;1377 break;1378 case 2:1379 flags |= SDL_INVLNDVIDEO;1380 break;1381 default:1382 flags |= SDL_PORTRTVIDEO;1383 }1384 _hwscreen = SDL_SetVideoMode(displayWidth, displayHeight, 16, flags);1385 1386 if (_hwscreen == NULL) {1387 warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());1388 quit();1389 }1390 1391 // see what orientation sdl finally accepted1392 if (_hwscreen->flags & SDL_PORTRTVIDEO)1393 _orientationLandscape = _newOrientation = 0;1394 else if (_hwscreen->flags & SDL_LANDSCVIDEO)1395 _orientationLandscape = _newOrientation = 1;1396 else1397 _orientationLandscape = _newOrientation = 2;1398 1399 // Create the surface used for the graphics in 16 bit before scaling, and also the overlay1400 // Distinguish 555 and 565 mode1401 if (_hwscreen->format->Rmask == 0x7C00)1402 InitScalers(555);1403 else1404 InitScalers(565);1405 _overlayFormat.bytesPerPixel = _hwscreen->format->BytesPerPixel;1406 _overlayFormat.rLoss = _hwscreen->format->Rloss;1407 _overlayFormat.gLoss = _hwscreen->format->Gloss;1408 _overlayFormat.bLoss = _hwscreen->format->Bloss;1409 _overlayFormat.aLoss = _hwscreen->format->Aloss;1410 _overlayFormat.rShift = _hwscreen->format->Rshift;1411 _overlayFormat.gShift = _hwscreen->format->Gshift;1412 _overlayFormat.bShift = _hwscreen->format->Bshift;1413 _overlayFormat.aShift = _hwscreen->format->Ashift;1414 1415 // Need some extra bytes around when using 2xSaI1416 _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);1417 1418 if (_tmpscreen == NULL)1419 error("_tmpscreen creation failed (%s)", SDL_GetError());1420 1421 // Overlay1422 if (CEDevice::hasDesktopResolution()) {1423 _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd, 16, 0, 0, 0, 0);1424 if (_overlayscreen == NULL)1425 error("_overlayscreen failed (%s)", SDL_GetError());1426 _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth * _scaleFactorXm / _scaleFactorXd + 3, _videoMode.overlayHeight * _scaleFactorYm / _scaleFactorYd + 3, 16, 0, 0, 0, 0);1427 if (_tmpscreen2 == NULL)1428 error("_tmpscreen2 failed (%s)", SDL_GetError());1429 } else {1430 _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight, 16, 0, 0, 0, 0);1431 if (_overlayscreen == NULL)1432 error("_overlayscreen failed (%s)", SDL_GetError());1433 _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3, 16, 0, 0, 0, 0);1434 if (_tmpscreen2 == NULL)1435 error("_tmpscreen2 failed (%s)", SDL_GetError());1436 }1437 1438 // Toolbar1439 _toolbarHighDrawn = false;1440 uint16 *toolbar_screen = (uint16 *)calloc(320 * 40, sizeof(uint16)); // *not* leaking memory here1441 _toolbarLow = SDL_CreateRGBSurfaceFrom(toolbar_screen, 320, 40, 16, 320 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);1442 1443 if (_toolbarLow == NULL)1444 error("_toolbarLow failed (%s)", SDL_GetError());1445 1446 if (_videoMode.screenHeight > 240) {1447 uint16 *toolbar_screen = (uint16 *)calloc(640 * 80, sizeof(uint16));1448 _toolbarHigh = SDL_CreateRGBSurfaceFrom(toolbar_screen, 640, 80, 16, 640 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask);1449 1450 if (_toolbarHigh == NULL)1451 error("_toolbarHigh failed (%s)", SDL_GetError());1452 } else1453 _toolbarHigh = NULL;1454 1455 1456 // keyboard cursor control, some other better place for it?1457 _km.x_max = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd - 1;1458 _km.y_max = _videoMode.screenHeight * _scaleFactorXm / _scaleFactorXd - 1;1459 _km.delay_time = 25;1460 _km.last_time = 0;1461 1462 return true;1463 }1464 1465 void OSystem_WINCE3::unloadGFXMode() {1466 if (_screen) {1467 SDL_FreeSurface(_screen);1468 _screen = NULL;1469 }1470 1471 if (_hwscreen) {1472 SDL_FreeSurface(_hwscreen);1473 _hwscreen = NULL;1474 }1475 1476 if (_tmpscreen) {1477 SDL_FreeSurface(_tmpscreen);1478 _tmpscreen = NULL;1479 }1480 }1481 1482 bool OSystem_WINCE3::hotswapGFXMode() {1483 if (!_screen)1484 return false;1485 1486 // Keep around the old _screen & _tmpscreen so we can restore the screen data1487 // after the mode switch. (also for the overlay)1488 SDL_Surface *old_screen = _screen;1489 SDL_Surface *old_tmpscreen = _tmpscreen;1490 SDL_Surface *old_overlayscreen = _overlayscreen;1491 SDL_Surface *old_tmpscreen2 = _tmpscreen2;1492 1493 // Release the HW screen surface1494 SDL_FreeSurface(_hwscreen);1495 1496 // Release toolbars1497 free(_toolbarLow->pixels);1498 SDL_FreeSurface(_toolbarLow);1499 if (_toolbarHigh) {1500 free(_toolbarHigh->pixels);1501 SDL_FreeSurface(_toolbarHigh);1502 }1503 1504 // Setup the new GFX mode1505 if (!loadGFXMode()) {1506 unloadGFXMode();1507 1508 _screen = old_screen;1509 _overlayscreen = old_overlayscreen;1510 1511 return false;1512 }1513 1514 // reset palette1515 SDL_SetColors(_screen, _currentPalette, 0, 256);1516 1517 // Restore old screen content1518 SDL_BlitSurface(old_screen, NULL, _screen, NULL);1519 SDL_BlitSurface(old_tmpscreen, NULL, _tmpscreen, NULL);1520 if (_overlayVisible) {1521 SDL_BlitSurface(old_overlayscreen, NULL, _overlayscreen, NULL);1522 SDL_BlitSurface(old_tmpscreen2, NULL, _tmpscreen2, NULL);1523 }1524 1525 // Free the old surfaces1526 SDL_FreeSurface(old_screen);1527 SDL_FreeSurface(old_tmpscreen);1528 SDL_FreeSurface(old_overlayscreen);1529 SDL_FreeSurface(old_tmpscreen2);1530 1531 // Blit everything back to the screen1532 _toolbarHighDrawn = false;1533 internUpdateScreen();1534 1535 // Make sure that a Common::EVENT_SCREEN_CHANGED gets sent later -> FIXME this crashes when no game has been loaded.1536 // _modeChanged = true;1537 1538 return true;1539 }1540 1541 void OSystem_WINCE3::internUpdateScreen() {1542 SDL_Surface *srcSurf, *origSurf;1543 static bool old_overlayVisible = false;1544 int numRectsOut = 0;1545 int16 routx, routy, routw, routh, stretch, shakestretch;1546 1547 assert(_hwscreen != NULL);1548 1549 // bail if the application is minimized, be nice to OS1550 if (!_hasfocus) {1551 Sleep(20);1552 return;1553 }1554 1555 // If the shake position changed, fill the dirty area with blackness1556 if (_currentShakePos != _newShakePos) {1557 SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd, _newShakePos * _scaleFactorYm / _scaleFactorYd};1558 if (_videoMode.aspectRatioCorrection)1559 blackrect.h = real2Aspect(blackrect.h - 1) + 1;1560 SDL_FillRect(_hwscreen, &blackrect, 0);1561 _currentShakePos = _newShakePos;1562 _forceFull = true;1563 }1564 1565 // Make sure the mouse is drawn, if it should be drawn.1566 drawMouse();1567 1568 // Check whether the palette was changed in the meantime and update the1569 // screen surface accordingly.1570 if (_paletteDirtyEnd != 0) {1571 SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart, _paletteDirtyStart, _paletteDirtyEnd - _paletteDirtyStart);1572 _paletteDirtyEnd = 0;1573 _forceFull = true;1574 }1575 1576 if (!_overlayVisible) {1577 origSurf = _screen;1578 srcSurf = _tmpscreen;1579 } else {1580 origSurf = _overlayscreen;1581 srcSurf = _tmpscreen2;1582 }1583 1584 if (old_overlayVisible != _overlayVisible) {1585 old_overlayVisible = _overlayVisible;1586 update_scalers();1587 }1588 1589 // Force a full redraw if requested1590 if (_forceFull) {1591 _numDirtyRects = 1;1592 1593 _dirtyRectList[0].x = 0;1594 if (!_zoomDown)1595 _dirtyRectList[0].y = 0;1596 else1597 _dirtyRectList[0].y = _videoMode.screenHeight / 2;1598 _dirtyRectList[0].w = _videoMode.screenWidth;1599 if (!_zoomUp && !_zoomDown)1600 _dirtyRectList[0].h = _videoMode.screenHeight;1601 else1602 _dirtyRectList[0].h = _videoMode.screenHeight / 2;1603 1604 _toolbarHandler.forceRedraw();1605 }1606 1607 // Only draw anything if necessary1608 if (_numDirtyRects > 0) {1609 1610 SDL_Rect *r, *rout;1611 SDL_Rect dst;1612 uint32 srcPitch, dstPitch;1613 SDL_Rect *last_rect = _dirtyRectList + _numDirtyRects;1614 bool toolbarVisible = _toolbarHandler.visible();1615 int toolbarOffset = _toolbarHandler.getOffset();1616 1617 for (r = _dirtyRectList; r != last_rect; ++r) {1618 dst = *r;1619 dst.x++; // Shift rect by one since 2xSai needs to access the data around1620 dst.y++; // any pixel to scale it, and we want to avoid mem access crashes.1621 // NOTE: This is also known as BLACK MAGIC, copied from the sdl backend1622 if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)1623 error("SDL_BlitSurface failed: %s", SDL_GetError());1624 }1625 1626 SDL_LockSurface(srcSurf);1627 SDL_LockSurface(_hwscreen);1628 1629 srcPitch = srcSurf->pitch;1630 dstPitch = _hwscreen->pitch;1631 1632 for (r = _dirtyRectList, rout = _dirtyRectOut; r != last_rect; ++r) {1633 1634 // always clamp to enclosing, downsampled-grid-aligned rect in the downscaled image1635 if (_scaleFactorXd != 1) {1636 stretch = r->x % _scaleFactorXd;1637 r->x -= stretch;1638 r->w += stretch;1639 r->w = (r->x + r->w + _scaleFactorXd - 1) / _scaleFactorXd * _scaleFactorXd - r->x;1640 }1641 if (_scaleFactorYd != 1) {1642 stretch = r->y % _scaleFactorYd;1643 r->y -= stretch;1644 r->h += stretch;1645 r->h = (r->y + r->h + _scaleFactorYd - 1) / _scaleFactorYd * _scaleFactorYd - r->y;1646 }1647 1648 // transform1649 shakestretch = _currentShakePos * _scaleFactorYm / _scaleFactorYd;1650 routx = r->x * _scaleFactorXm / _scaleFactorXd; // locate position in scaled screen1651 routy = r->y * _scaleFactorYm / _scaleFactorYd + shakestretch; // adjust for shake offset1652 routw = r->w * _scaleFactorXm / _scaleFactorXd;1653 routh = r->h * _scaleFactorYm / _scaleFactorYd - shakestretch;1654 1655 // clipping destination rectangle inside device screen (more strict, also more tricky but more stable)1656 // note that all current scalers do not make dst rect exceed left/right, unless chosen badly (FIXME)1657 if (_zoomDown) routy -= 240; // adjust for zoom position1658 if (routy + routh < 0) continue;1659 if (routy < 0) {1660 routh += routy;1661 r->y -= routy * _scaleFactorYd / _scaleFactorYm;1662 routy = 0;1663 r->h = routh * _scaleFactorYd / _scaleFactorYm;1664 }1665 if (_orientationLandscape) {1666 if (routy > _platformScreenWidth) continue;1667 if (routy + routh > _platformScreenWidth) {1668 routh = _platformScreenWidth - routy;1669 r->h = routh * _scaleFactorYd / _scaleFactorYm;1670 }1671 } else {1672 if (routy > _platformScreenHeight) continue;1673 if (routy + routh > _platformScreenHeight) {1674 routh = _platformScreenHeight - routy;1675 r->h = routh * _scaleFactorYd / _scaleFactorYm;1676 }1677 }1678 1679 // check if the toolbar is overwritten1680 if (toolbarVisible && r->y + r->h >= toolbarOffset)1681 _toolbarHandler.forceRedraw();1682 1683 // blit it (with added voodoo from the sdl backend, shifting the source rect again)1684 _scalerProc( (byte *)srcSurf->pixels + (r->x * 2 + 2)+ (r->y + 1) * srcPitch, srcPitch,1685 (byte *)_hwscreen->pixels + routx * 2 + routy * dstPitch, dstPitch,1686 r->w, r->h - _currentShakePos);1687 1688 // add this rect to output1689 rout->x = routx; rout->y = routy - shakestretch;1690 rout->w = routw; rout->h = routh + shakestretch;1691 numRectsOut++;1692 rout++;1693 1694 }1695 SDL_UnlockSurface(srcSurf);1696 SDL_UnlockSurface(_hwscreen);1697 }1698 // Add the toolbar if needed1699 SDL_Rect toolbar_rect[1];1700 if (_panelVisible && _toolbarHandler.draw(_toolbarLow, &toolbar_rect[0])) {1701 // It can be drawn, scale it1702 uint32 srcPitch, dstPitch;1703 SDL_Surface *toolbarSurface;1704 ScalerProc *toolbarScaler;1705 1706 if (_videoMode.screenHeight > 240) {1707 if (!_toolbarHighDrawn) {1708 // Resize the toolbar1709 SDL_LockSurface(_toolbarLow);1710 SDL_LockSurface(_toolbarHigh);1711 Normal2x((byte*)_toolbarLow->pixels, _toolbarLow->pitch, (byte*)_toolbarHigh->pixels, _toolbarHigh->pitch, toolbar_rect[0].w, toolbar_rect[0].h);1712 SDL_UnlockSurface(_toolbarHigh);1713 SDL_UnlockSurface(_toolbarLow);1714 _toolbarHighDrawn = true;1715 }1716 toolbar_rect[0].w *= 2;1717 toolbar_rect[0].h *= 2;1718 toolbarSurface = _toolbarHigh;1719 }1720 else1721 toolbarSurface = _toolbarLow;1722 1723 drawToolbarMouse(toolbarSurface, true); // draw toolbar mouse if applicable1724 1725 // Apply the appropriate scaler1726 SDL_LockSurface(toolbarSurface);1727 SDL_LockSurface(_hwscreen);1728 srcPitch = toolbarSurface->pitch;1729 dstPitch = _hwscreen->pitch;1730 1731 toolbarScaler = _scalerProc;1732 if (_videoMode.scaleFactor == 2)1733 toolbarScaler = Normal2x;1734 else if (_videoMode.scaleFactor == 3)1735 toolbarScaler = Normal3x;1736 toolbarScaler((byte *)toolbarSurface->pixels, srcPitch,1737 (byte *)_hwscreen->pixels + (_toolbarHandler.getOffset() * _scaleFactorYm / _scaleFactorYd * dstPitch),1738 dstPitch, toolbar_rect[0].w, toolbar_rect[0].h);1739 SDL_UnlockSurface(toolbarSurface);1740 SDL_UnlockSurface(_hwscreen);1741 1742 // And blit it1743 toolbar_rect[0].y = _toolbarHandler.getOffset();1744 toolbar_rect[0].x = toolbar_rect[0].x * _scaleFactorXm / _scaleFactorXd;1745 toolbar_rect[0].y = toolbar_rect[0].y * _scaleFactorYm / _scaleFactorYd;1746 toolbar_rect[0].w = toolbar_rect[0].w * _scaleFactorXm / _scaleFactorXd;1747 toolbar_rect[0].h = toolbar_rect[0].h * _scaleFactorYm / _scaleFactorYd;1748 1749 SDL_UpdateRects(_hwscreen, 1, toolbar_rect);1750 1751 drawToolbarMouse(toolbarSurface, false); // undraw toolbar mouse1752 }1753 1754 // Finally, blit all our changes to the screen1755 if (numRectsOut > 0)1756 SDL_UpdateRects(_hwscreen, numRectsOut, _dirtyRectOut);1757 1758 _numDirtyRects = 0;1759 _forceFull = false;1760 }1761 1762 Graphics::Surface *OSystem_WINCE3::lockScreen() {1763 // Make sure mouse pointer is not painted over the playfield at the time of locking1764 undrawMouse();1765 return OSystem_SDL::lockScreen();1766 }1767 1768 void OSystem_WINCE3::unlockScreen() {1769 OSystem_SDL::unlockScreen();1770 }1771 1772 bool OSystem_WINCE3::saveScreenshot(const char *filename) {1773 assert(_hwscreen != NULL);1774 1775 Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends1776 SDL_SaveBMP(_hwscreen, filename);1777 return true;1778 }1779 1780 void OSystem_WINCE3::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {1781 assert (_transactionMode == kTransactionNone);1782 1783 if (_overlayscreen == NULL)1784 return;1785 1786 // Clip the coordinates1787 if (x < 0) {1788 w += x;1789 buf -= x;1790 x = 0;1791 }1792 1793 if (y < 0) {1794 h += y; buf -= y * pitch;1795 y = 0;1796 }1797 1798 if (w > _videoMode.overlayWidth - x) {1799 w = _videoMode.overlayWidth - x;1800 }1801 1802 if (h > _videoMode.overlayHeight - y) {1803 h = _videoMode.overlayHeight - y;1804 }1805 1806 if (w <= 0 || h <= 0)1807 return;1808 1809 // Mark the modified region as dirty1810 addDirtyRect(x, y, w, h);1811 1812 undrawMouse();1813 1814 if (SDL_LockSurface(_overlayscreen) == -1)1815 error("SDL_LockSurface failed: %s", SDL_GetError());1816 1817 byte *dst = (byte *)_overlayscreen->pixels + y * _overlayscreen->pitch + x * 2;1818 do {1819 memcpy(dst, buf, w * 2);1820 dst += _overlayscreen->pitch;1821 buf += pitch;1822 } while (--h);1823 1824 SDL_UnlockSurface(_overlayscreen);1825 }1826 1827 void OSystem_WINCE3::copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) {1828 assert (_transactionMode == kTransactionNone);1829 assert(src);1830 1831 if (_screen == NULL)1832 return;1833 1834 Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends1835 1836 /* Clip the coordinates */1837 if (x < 0) {1838 w += x;1839 src -= x;1840 x = 0;1841 }1842 1843 if (y < 0) {1844 h += y;1845 src -= y * pitch;1846 y = 0;1847 }1848 1849 if (w > _videoMode.screenWidth - x) {1850 w = _videoMode.screenWidth - x;1851 }1852 1853 if (h > _videoMode.screenHeight - y) {1854 h = _videoMode.screenHeight - y;1855 }1856 1857 if (w <= 0 || h <= 0)1858 return;1859 1860 addDirtyRect(x, y, w, h);1861 1862 undrawMouse();1863 1864 // Try to lock the screen surface1865 if (SDL_LockSurface(_screen) == -1)1866 error("SDL_LockSurface failed: %s", SDL_GetError());1867 1868 byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;1869 1870 if (_videoMode.screenWidth == pitch && pitch == w) {1871 memcpy(dst, src, h*w);1872 } else {1873 do {1874 memcpy(dst, src, w);1875 src += pitch;1876 dst += _videoMode.screenWidth;1877 } while (--h);1878 }1879 1880 // Unlock the screen surface1881 SDL_UnlockSurface(_screen);1882 }1883 1884 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) {1885 1886 undrawMouse();1887 if (w == 0 || h == 0)1888 return;1889 1890 _mouseCurState.w = w;1891 _mouseCurState.h = h;1892 1893 _mouseHotspotX = hotspot_x;1894 _mouseHotspotY = hotspot_y;1895 1896 _mouseKeyColor = keycolor;1897 1898 free(_mouseData);1899 1900 _mouseData = (byte *) malloc(w * h);1901 memcpy(_mouseData, buf, w * h);1902 1903 if (w > _mouseBackupDim || h > _mouseBackupDim) {1904 // mouse has been undrawn, adjust sprite backup area1905 free(_mouseBackupOld);1906 free(_mouseBackupToolbar);1907 uint16 tmp = (w > h) ? w : h;1908 _mouseBackupOld = (byte *) malloc(tmp * tmp * 2); // can hold 8bpp (playfield) or 16bpp (overlay) data1909 _mouseBackupToolbar = (uint16 *) malloc(tmp * tmp * 2); // 16 bpp1910 _mouseBackupDim = tmp;1911 }1912 }1913 1914 void OSystem_WINCE3::setMousePos(int x, int y) {1915 if (x != _mouseCurState.x || y != _mouseCurState.y) {1916 undrawMouse();1917 _mouseCurState.x = x;1918 _mouseCurState.y = y;1919 updateScreen();1920 }1921 }1922 1923 1924 void OSystem_WINCE3::internDrawMouse() {1925 if (!_mouseNeedsRedraw || !_mouseVisible || !_mouseData)1926 return;1927 1928 int x = _mouseCurState.x - _mouseHotspotX;1929 int y = _mouseCurState.y - _mouseHotspotY;1930 int w = _mouseCurState.w;1931 int h = _mouseCurState.h;1932 byte color;1933 const byte *src = _mouseData; // Image representing the mouse1934 int width;1935 1936 // clip the mouse rect, and adjust the src pointer accordingly1937 if (x < 0) {1938 w += x;1939 src -= x;1940 x = 0;1941 }1942 if (y < 0) {1943 h += y;1944 src -= y * _mouseCurState.w;1945 y = 0;1946 }1947 1948 if (w > _videoMode.screenWidth - x)1949 w = _videoMode.screenWidth - x;1950 if (h > _videoMode.screenHeight - y)1951 h = _videoMode.screenHeight - y;1952 1953 // Quick check to see if anything has to be drawn at all1954 if (w <= 0 || h <= 0)1955 return;1956 1957 // Draw the mouse cursor; backup the covered area in "bak"1958 if (SDL_LockSurface(_overlayVisible ? _overlayscreen : _screen) == -1)1959 error("SDL_LockSurface failed: %s", SDL_GetError());1960 1961 // Mark as dirty1962 addDirtyRect(x, y, w, h);1963 1964 if (!_overlayVisible) {1965 byte *bak = _mouseBackupOld; // Surface used to backup the area obscured by the mouse1966 byte *dst; // Surface we are drawing into1967 1968 dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;1969 while (h > 0) {1970 width = w;1971 while (width > 0) {1972 *bak++ = *dst;1973 color = *src++;1974 if (color != _mouseKeyColor) // transparent, don't draw1975 *dst = color;1976 dst++;1977 width--;1978 }1979 src += _mouseCurState.w - w;1980 bak += _mouseBackupDim - w;1981 dst += _videoMode.screenWidth - w;1982 h--;1983 }1984 1985 } else {1986 uint16 *bak = (uint16 *)_mouseBackupOld; // Surface used to backup the area obscured by the mouse1987 byte *dst; // Surface we are drawing into1988 1989 dst = (byte *)_overlayscreen->pixels + (y + 1) * _overlayscreen->pitch + (x + 1) * 2;1990 while (h > 0) {1991 width = w;1992 while (width > 0) {1993 *bak++ = *(uint16 *)dst;1994 color = *src++;1995 if (color != 0xFF) // 0xFF = transparent, don't draw1996 *(uint16 *)dst = SDL_MapRGB(_overlayscreen->format, _currentPalette[color].r, _currentPalette[color].g, _currentPalette[color].b);1997 dst += 2;1998 width--;1999 }2000 src += _mouseCurState.w - w;2001 bak += _mouseBackupDim - w;2002 dst += _overlayscreen->pitch - w * 2;2003 h--;2004 }2005 }2006 2007 SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);2008 2009 // Finally, set the flag to indicate the mouse has been drawn2010 _mouseNeedsRedraw = false;2011 }2012 2013 void OSystem_WINCE3::undrawMouse() {2014 assert (_transactionMode == kTransactionNone);2015 2016 if (_mouseNeedsRedraw)2017 return;2018 2019 int old_mouse_x = _mouseCurState.x - _mouseHotspotX;2020 int old_mouse_y = _mouseCurState.y - _mouseHotspotY;2021 int old_mouse_w = _mouseCurState.w;2022 int old_mouse_h = _mouseCurState.h;2023 2024 // clip the mouse rect, and adjust the src pointer accordingly2025 if (old_mouse_x < 0) {2026 old_mouse_w += old_mouse_x;2027 old_mouse_x = 0;2028 }2029 if (old_mouse_y < 0) {2030 old_mouse_h += old_mouse_y;2031 old_mouse_y = 0;2032 }2033 2034 if (old_mouse_w > _videoMode.screenWidth - old_mouse_x)2035 old_mouse_w = _videoMode.screenWidth - old_mouse_x;2036 if (old_mouse_h > _videoMode.screenHeight - old_mouse_y)2037 old_mouse_h = _videoMode.screenHeight - old_mouse_y;2038 2039 // Quick check to see if anything has to be drawn at all2040 if (old_mouse_w <= 0 || old_mouse_h <= 0)2041 return;2042 2043 2044 if (SDL_LockSurface(_overlayVisible ? _overlayscreen : _screen) == -1)2045 error("SDL_LockSurface failed: %s", SDL_GetError());2046 2047 int y;2048 if (!_overlayVisible) {2049 byte *dst, *bak = _mouseBackupOld;2050 2051 // No need to do clipping here, since drawMouse() did that already2052 dst = (byte *)_screen->pixels + old_mouse_y * _videoMode.screenWidth + old_mouse_x;2053 for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _videoMode.screenWidth)2054 memcpy(dst, bak, old_mouse_w);2055 } else {2056 byte *dst;2057 uint16 *bak = (uint16 *)_mouseBackupOld;2058 2059 // No need to do clipping here, since drawMouse() did that already2060 dst = (byte *)_overlayscreen->pixels + (old_mouse_y + 1) * _overlayscreen->pitch + (old_mouse_x + 1) * 2;2061 for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _overlayscreen->pitch)2062 memcpy(dst, bak, old_mouse_w << 1);2063 }2064 2065 addDirtyRect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h);2066 2067 SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen);2068 2069 _mouseNeedsRedraw = true;2070 }2071 2072 bool OSystem_WINCE3::showMouse(bool visible) {2073 if (_mouseVisible == visible)2074 return visible;2075 2076 if (visible == false)2077 undrawMouse();2078 2079 bool last = _mouseVisible;2080 _mouseVisible = visible;2081 _mouseNeedsRedraw = true;2082 2083 return last;2084 }2085 2086 void OSystem_WINCE3::drawToolbarMouse(SDL_Surface *surf, bool draw) {2087 2088 if (!_mouseData || !_usesEmulatedMouse)2089 return;2090 2091 int x = _mouseCurState.x - _mouseHotspotX;2092 int y = _mouseCurState.y - _mouseHotspotY - _toolbarHandler.getOffset();2093 int w = _mouseCurState.w;2094 int h = _mouseCurState.h;2095 byte color;2096 const byte *src = _mouseData;2097 int width;2098 2099 // clip2100 if (x < 0) {2101 w += x;2102 src -= x;2103 x = 0;2104 }2105 if (y < 0) {2106 h += y;2107 src -= y * _mouseCurState.w;2108 y = 0;2109 }2110 if (w > surf->w - x)2111 w = surf->w - x;2112 if (h > surf->h - y)2113 h = surf->h - y;2114 if (w <= 0 || h <= 0)2115 return;2116 2117 if (SDL_LockSurface(surf) == -1)2118 error("SDL_LockSurface failed at internDrawToolbarMouse: %s", SDL_GetError());2119 2120 uint16 *bak = _mouseBackupToolbar; // toolbar surfaces are 16bpp2121 uint16 *dst;2122 dst = (uint16 *)surf->pixels + y * surf->w + x;2123 2124 if (draw) { // blit it2125 while (h > 0) {2126 width = w;2127 while (width > 0) {2128 *bak++ = *dst;2129 color = *src++;2130 if (color != _mouseKeyColor) // transparent color2131 *dst = 0xFFFF;2132 dst++;2133 width--;2134 }2135 src += _mouseCurState.w - w;2136 bak += _mouseBackupDim - w;2137 dst += surf->w - w;2138 h--;2139 }2140 } else { // restore bg2141 for (y = 0; y < h; ++y, bak += _mouseBackupDim, dst += surf->w)2142 memcpy(dst, bak, w << 1);2143 }2144 2145 SDL_UnlockSurface(surf);2146 }2147 2148 void OSystem_WINCE3::blitCursor() {2149 }2150 2151 void OSystem_WINCE3::showOverlay() {2152 assert (_transactionMode == kTransactionNone);2153 2154 if (_overlayVisible)2155 return;2156 2157 undrawMouse();2158 _overlayVisible = true;2159 update_scalers();2160 clearOverlay();2161 }2162 2163 void OSystem_WINCE3::hideOverlay() {2164 assert (_transactionMode == kTransactionNone);2165 2166 if (!_overlayVisible)2167 return;2168 2169 undrawMouse();2170 _overlayVisible = false;2171 clearOverlay();2172 _forceFull = true;2173 }2174 2175 void OSystem_WINCE3::drawMouse() {2176 if (!(_toolbarHandler.visible() && _mouseCurState.y >= _toolbarHandler.getOffset() && !_usesEmulatedMouse) && !_forceHideMouse)2177 internDrawMouse();2178 }2179 2180 void OSystem_WINCE3::fillMouseEvent(Common::Event &event, int x, int y) {2181 event.mouse.x = x;2182 event.mouse.y = y;2183 2184 // Update the "keyboard mouse" coords2185 _km.x = event.mouse.x;2186 _km.y = event.mouse.y;2187 2188 // Adjust for the screen scaling2189 if (_zoomDown)2190 event.mouse.y += 240;2191 2192 event.mouse.x = event.mouse.x * _scaleFactorXd / _scaleFactorXm;2193 event.mouse.y = event.mouse.y * _scaleFactorYd / _scaleFactorYm;2194 }2195 2196 void OSystem_WINCE3::retrieve_mouse_location(int &x, int &y) {2197 x = _mouseCurState.x;2198 y = _mouseCurState.y;2199 2200 x = x * _scaleFactorXm / _scaleFactorXd;2201 y = y * _scaleFactorYm / _scaleFactorYd;2202 2203 if (_zoomDown)2204 y -= 240;2205 }2206 2207 void OSystem_WINCE3::warpMouse(int x, int y) {2208 if (_mouseCurState.x != x || _mouseCurState.y != y) {2209 SDL_WarpMouse(x * _scaleFactorXm / _scaleFactorXd, y * _scaleFactorYm / _scaleFactorYd);2210 2211 // SDL_WarpMouse() generates a mouse movement event, so2212 // set_mouse_pos() would be called eventually. However, the2213 // cannon script in CoMI calls this function twice each time2214 // the cannon is reloaded. Unless we update the mouse position2215 // immediately the second call is ignored, causing the cannon2216 // to change its aim.2217 2218 setMousePos(x, y);2219 }2220 }2221 2222 void OSystem_WINCE3::addDirtyRect(int x, int y, int w, int h, bool mouseRect) {2223 2224 if (_forceFull || _paletteDirtyEnd)2225 return;2226 2227 OSystem_SDL::addDirtyRect(x, y, w, h, false);2228 }2229 2230 static int mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode, bool unfilter) {2231 if (GUI::Actions::Instance()->mappingActive())2232 return key;2233 2234 if (unfilter) {2235 switch (key) {2236 case SDLK_ESCAPE:2237 return SDLK_BACKSPACE;2238 case SDLK_F8:2239 return SDLK_ASTERISK;2240 case SDLK_F9:2241 return SDLK_HASH;2242 default:2243 return key;2244 }2245 }2246 2247 if (key >= SDLK_KP0 && key <= SDLK_KP9) {2248 return key - SDLK_KP0 + '0';2249 } else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) {2250 return key;2251 } else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) {2252 return 0;2253 }2254 return key;2255 }2256 2257 bool OSystem_WINCE3::pollEvent(Common::Event &event) {2258 SDL_Event ev;2259 ev.type = SDL_NOEVENT;2260 DWORD currentTime;2261 bool keyEvent = false;2262 int deltaX, deltaY;2263 2264 memset(&event, 0, sizeof(Common::Event));2265 2266 handleKbdMouse();2267 2268 // If the screen mode changed, send an Common::EVENT_SCREEN_CHANGED2269 if (_modeChanged) {2270 _modeChanged = false;2271 event.type = Common::EVENT_SCREEN_CHANGED;2272 _screenChangeCount++;2273 return true;2274 }2275 2276 CEDevice::wakeUp();2277 2278 currentTime = GetTickCount();2279 2280 while (SDL_PollEvent(&ev)) {2281 switch (ev.type) {2282 case SDL_KEYDOWN:2283 debug(1, "Key down %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));2284 // KMOD_RESERVED is used if the key has been injected by an external buffer2285 if (ev.key.keysym.mod != KMOD_RESERVED && !_unfilteredkeys) {2286 keyEvent = true;2287 _lastKeyPressed = ev.key.keysym.sym;2288 _keyRepeatTime = currentTime;2289 _keyRepeat = 0;2290 2291 if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, true))2292 return true;2293 }2294 2295 if (GUI_Actions::Instance()->mappingActive())2296 event.kbd.flags = 0xFF;2297 else if (ev.key.keysym.sym == SDLK_PAUSE) {2298 _lastKeyPressed = 0;2299 event.type = Common::EVENT_PREDICTIVE_DIALOG;2300 return true;2301 } event.type = Common::EVENT_KEYDOWN;2302 if (!_unfilteredkeys)2303 event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;2304 else2305 event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);2306 event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);2307 2308 if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {2309 event.kbd.ascii ^= 0x20;2310 event.kbd.flags = Common::KBD_SHIFT;2311 }2312 2313 return true;2314 2315 case SDL_KEYUP:2316 debug(1, "Key up %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));2317 // KMOD_RESERVED is used if the key has been injected by an external buffer2318 if (ev.key.keysym.mod != KMOD_RESERVED && !_unfilteredkeys) {2319 keyEvent = true;2320 _lastKeyPressed = 0;2321 2322 if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, false))2323 return true;2324 }2325 2326 if (GUI_Actions::Instance()->mappingActive())2327 event.kbd.flags = 0xFF;2328 else if (ev.key.keysym.sym == SDLK_PAUSE) {2329 _lastKeyPressed = 0;2330 return false; // chew up the show agi dialog key up event2331 }2332 2333 event.type = Common::EVENT_KEYUP;2334 if (!_unfilteredkeys)2335 event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;2336 else2337 event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);2338 event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);2339 2340 if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {2341 event.kbd.ascii ^= 0x20;2342 event.kbd.flags = Common::KBD_SHIFT;2343 }2344 2345 return true;2346 2347 case SDL_MOUSEMOTION:2348 event.type = Common::EVENT_MOUSEMOVE;2349 fillMouseEvent(event, ev.motion.x, ev.motion.y);2350 setMousePos(event.mouse.x, event.mouse.y);2351 return true;2352 2353 case SDL_MOUSEBUTTONDOWN:2354 if (ev.button.button == SDL_BUTTON_LEFT)2355 event.type = Common::EVENT_LBUTTONDOWN;2356 else if (ev.button.button == SDL_BUTTON_RIGHT)2357 event.type = Common::EVENT_RBUTTONDOWN;2358 else2359 break;2360 fillMouseEvent(event, ev.button.x, ev.button.y);2361 2362 2363 if (event.mouse.x > _tapX)2364 deltaX = event.mouse.x - _tapX;2365 else2366 deltaX = _tapX - event.mouse.x;2367 if (event.mouse.y > _tapY)2368 deltaY = event.mouse.y - _tapY;2369 else2370 deltaY = _tapY - event.mouse.y;2371 _closeClick = (deltaX <= 5 && deltaY <= 5);2372 2373 if (!_isSmartphone) {2374 // handle double-taps2375 if (_tapTime) { // second tap2376 if (_closeClick && (GetTickCount() - _tapTime < 1000)) {2377 if (event.mouse.y <= 20 && _panelInitialized) { // top of screen (show panel)2378 swap_panel_visibility();2379 } else if (!_noDoubleTapRMB) { // right click2380 event.type = Common::EVENT_RBUTTONDOWN;2381 _rbutton = true;2382 }2383 }2384 _tapTime = 0;2385 } else {2386 _tapTime = GetTickCount();2387 _tapX = event.mouse.x;2388 _tapY = event.mouse.y;2389 }2390 }2391 2392 if (_freeLook && !_closeClick) {2393 _rbutton = false;2394 _tapTime = 0;2395 _tapX = event.mouse.x;2396 _tapY = event.mouse.y;2397 event.type = Common::EVENT_MOUSEMOVE;2398 setMousePos(event.mouse.x, event.mouse.y);2399 }2400 2401 2402 if (_toolbarHandler.action(event.mouse.x, event.mouse.y, true)) {2403 if (!_toolbarHandler.drawn()) {2404 _toolbarHighDrawn = false;2405 internUpdateScreen();2406 }2407 if (_newOrientation != _orientationLandscape){2408 _orientationLandscape = _newOrientation;2409 _toolbarHighDrawn = false;2410 ConfMan.setInt("landscape", _orientationLandscape);2411 ConfMan.flushToDisk();2412 hotswapGFXMode();2413 }2414 return false;2415 }2416 2417 return true;2418 2419 case SDL_MOUSEBUTTONUP:2420 if (ev.button.button == SDL_BUTTON_LEFT)2421 event.type = Common::EVENT_LBUTTONUP;2422 else if (ev.button.button == SDL_BUTTON_RIGHT)2423 event.type = Common::EVENT_RBUTTONUP;2424 else2425 break;2426 2427 if (_rbutton) {2428 event.type = Common::EVENT_RBUTTONUP;2429 _rbutton = false;2430 }2431 2432 fillMouseEvent(event, ev.button.x, ev.button.y);2433 2434 if (_freeLook && !_closeClick) {2435 _tapX = event.mouse.x;2436 _tapY = event.mouse.y;2437 event.type = Common::EVENT_MOUSEMOVE;2438 setMousePos(event.mouse.x, event.mouse.y);2439 }2440 2441 if (_toolbarHandler.action(event.mouse.x, event.mouse.y, false)) {2442 if (!_toolbarHandler.drawn()) {2443 _toolbarHighDrawn = false;2444 internUpdateScreen();2445 }2446 return false;2447 2448 }2449 return true;2450 2451 case SDL_VIDEOEXPOSE:2452 _forceFull = true;2453 break;2454 2455 case SDL_QUIT:2456 event.type = Common::EVENT_QUIT;2457 return true;2458 2459 case SDL_ACTIVEEVENT:2460 if (ev.active.state & SDL_APPMOUSEFOCUS)2461 debug(2, "%s mouse focus.", ev.active.gain ? "Got" : "Lost");2462 if (ev.active.state & SDL_APPINPUTFOCUS)2463 debug(2, "%s input focus.", ev.active.gain ? "Got" : "Lost");2464 if (ev.active.state & SDL_APPACTIVE)2465 debug(2, "%s total focus.", ev.active.gain ? "Got" : "Lost");2466 if (ev.active.state & SDL_APPINPUTFOCUS) {2467 _hasfocus = ev.active.gain;2468 SDL_PauseAudio(!_hasfocus);2469 _forceFull |= _hasfocus;2470 }2471 break;2472 }2473 }2474 2475 // Simulate repeated key for backend2476 if (!keyEvent && _lastKeyPressed && currentTime > _keyRepeatTime + _keyRepeatTrigger) {2477 _keyRepeatTime = currentTime;2478 _keyRepeat++;2479 GUI_Actions::Instance()->performMapped(_lastKeyPressed, true);2480 }2481 2482 return false;2483 554 } 2484 555 2485 556 void OSystem_WINCE3::quit() { … … void OSystem_WINCE3::getTimeAndDate(Time 2508 579 int OSystem_WINCE3::_platformScreenWidth; 2509 580 int OSystem_WINCE3::_platformScreenHeight; 2510 581 bool OSystem_WINCE3::_isOzone; 2511 OSystem_WINCE3::zoneDesc OSystem_WINCE3::_zones[TOTAL_ZONES] = {2512 { 0, 0, 320, 145 },2513 { 0, 145, 150, 55 },2514 { 150, 145, 170, 55 }2515 }; -
backends/platform/wince/wince-sdl.h
diff -rupN scummvm-df1a800-orig/backends/platform/wince/wince-sdl.h scummvm-git/backends/platform/wince/wince-sdl.h
old new 35 35 #include "backends/platform/wince/CEkeys/CEKeys.h" 36 36 #include "backends/platform/wince/CEDevice.h" 37 37 38 #define TOTAL_ZONES 3 38 #include "backends/graphics/wincesdl/wincesdl-graphics.h" 39 #include "backends/events/wincesdl/wincesdl-events.h" 40 #include "backends/timer/default/default-timer.h" 41 #include "backends/fs/windows/windows-fs-factory.h" 39 42 40 43 // defines used for implementing the raw frame buffer access method (2003+) 41 44 #define GETRAWFRAMEBUFFER 0x00020001 … … 46 49 class OSystem_WINCE3 : public OSystem_SDL { 47 50 public: 48 51 OSystem_WINCE3(); 49 50 // Update the dirty areas of the screen 51 void internUpdateScreen(); 52 virtual ~OSystem_WINCE3(); 52 53 53 54 void setGraphicsModeIntern(); 54 void initSize(uint w, uint h, const Graphics::PixelFormat *format);55 55 void initBackend(); 56 56 57 // Overloaded from SDL backend (toolbar handling)58 bool pollEvent(Common::Event &event);59 // Overloaded from SDL backend (toolbar handling)60 void drawMouse();61 // Overloaded from SDL backend (mouse and new scaler handling)62 void fillMouseEvent(Common::Event &event, int x, int y);63 // Overloaded from SDL backend (new scaler handling)64 void addDirtyRect(int x, int y, int w, int h, bool mouseRect = false);65 // Overloaded from SDL backend (new scaler handling)66 void warpMouse(int x, int y);67 57 // Overloaded from SDL backend 68 58 void quit(); 69 // Overloaded from SDL backend (master volume and sample rate subtleties)70 void setupMixer();71 59 // Overloaded from OSystem 72 60 void engineInit(); 73 61 void getTimeAndDate(TimeDate &t) const; 74 62 75 63 virtual Common::String getDefaultConfigFileName(); 64 virtual FilesystemFactory *getFilesystemFactory(); 76 65 77 78 // Overloaded from SDL_Common (FIXME)79 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 backend80 void undrawMouse();81 void blitCursor();82 bool showMouse(bool visible);83 void setMousePos(int x, int y);84 void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); // overloaded by CE backend (FIXME)85 void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);86 void showOverlay();87 void hideOverlay();88 Graphics::Surface *lockScreen();89 void unlockScreen();90 91 // GUI and action stuff92 void swap_panel_visibility();93 void swap_panel();94 66 void swap_sound_master(); 95 void add_right_click(bool pushed);96 void swap_mouse_visibility();97 void swap_freeLook();98 void swap_zoom_up();99 void swap_zoom_down();100 void swap_smartphone_keyboard();101 102 //#ifdef WIN32_PLATFORM_WFSP103 // Smartphone actions104 105 void initZones();106 void loadDeviceConfigurationElement(String element, int &value, int defaultValue);107 void loadDeviceConfiguration();108 void add_left_click(bool pushed);109 void move_cursor_up();110 void move_cursor_down();111 void move_cursor_left();112 void move_cursor_right();113 void switch_zone();114 void smartphone_rotate_display();115 //#endif116 67 117 68 static int getScreenWidth(); 118 69 static int getScreenHeight(); 119 70 static void initScreenInfos(); 120 71 static bool isOzone(); 121 72 122 protected: 123 bool loadGFXMode(); 124 void unloadGFXMode(); 125 bool hotswapGFXMode(); 126 bool saveScreenshot(const char *filename); 127 128 129 const GraphicsMode *getSupportedGraphicsModes() const; 130 bool setGraphicsMode(int mode); 131 //int getGraphicsMode() const; 132 int getDefaultGraphicsMode() const; 133 134 bool hasFeature(Feature f); 135 void setFeatureState(Feature f, bool enable); 136 bool getFeatureState(Feature f); 73 static bool _soundMaster; // turn off sound after all calculations 74 // static since needed by the SDL callback 137 75 138 void internDrawMouse(); 139 void drawToolbarMouse(SDL_Surface *surf, bool draw); 76 protected: 77 void initSDL(); 78 Audio::MixerImpl *_mixer; 79 DefaultTimerManager *_timer; 80 FilesystemFactory *_fsFactory; 140 81 141 82 private: 142 143 #ifdef USE_VORBIS144 bool checkOggHighSampleRate();145 #endif146 147 static void private_sound_proc(void *param, byte *buf, int len);148 149 bool update_scalers();150 void create_toolbar();151 void update_game_settings();152 83 void check_mappings(); 153 uint32 compute_sample_rate();154 155 void retrieve_mouse_location(int &x, int &y);156 157 CEGUI::ToolbarHandler _toolbarHandler;158 159 SDL_Surface *_toolbarLow; // toolbar 320x40160 SDL_Surface *_toolbarHigh; // toolbar 640x80161 bool _toolbarHighDrawn; // cache toolbar 640x80162 163 bool _freeLook; // freeLook mode (do not send mouse button events)164 165 bool _forceHideMouse; // force invisible mouse cursor166 84 167 85 bool _forcePanelInvisible; // force panel visibility for some cases 168 bool _panelVisible; // panel visibility169 bool _panelStateForced; // panel visibility forced by external call170 171 bool _panelInitialized; // only initialize the toolbar once172 173 bool _unfilteredkeys; // discard key mapping temporarily (agi pred. dialog)174 static bool _soundMaster; // turn off sound after all calculations175 // static since needed by the SDL callback176 int _orientationLandscape; // current orientation177 int _newOrientation; // new orientation178 179 bool _saveToolbarState; // save visibility when forced180 String _saveActiveToolbar; // save active toolbar when forced181 182 bool _saveToolbarZoom; // save visibility when zooming183 bool _zoomUp; // zooming up mode184 bool _zoomDown; // zooming down mode185 186 bool _noDoubleTapRMB; // disable double tap -> rmb click187 bool _rbutton; // double tap -> right button simulation188 bool _closeClick; // flag when taps are spatially close together189 190 bool _usesEmulatedMouse; // emulated mousemove ever been used in this session191 192 bool _canBeAspectScaled; // game screen size allows for aspect scaling193 194 int _scaleFactorXm; // scaler X *195 int _scaleFactorXd; // scaler X /196 int _scaleFactorYm; // scaler Y *197 int _scaleFactorYd; // scaler Y /198 SDL_Rect _dirtyRectOut[NUM_DIRTY_RECT];199 bool _scalersChanged;200 bool _hasfocus; // scummvm has the top window201 86 202 87 static int _platformScreenWidth; 203 88 static int _platformScreenHeight; 204 89 static bool _isOzone; // true if running on Windows 2003 SE 205 90 206 // Keyboard tap207 int _tapX;208 int _tapY;209 long _tapTime;210 211 // Mouse212 int _mouseHotspotX, _mouseHotspotY;213 byte *_mouseBackupOld;214 uint16 *_mouseBackupToolbar;215 uint16 _mouseBackupDim;216 217 // Smartphone specific variables218 219 int _lastKeyPressed; // last key pressed220 int _keyRepeat; // number of time the last key was repeated221 int _keyRepeatTime; // elapsed time since the key was pressed222 int _keyRepeatTrigger; // minimum time to consider the key was repeated223 224 int _repeatX; // repeat trigger for left and right cursor moves225 int _repeatY; // repeat trigger for up and down cursor moves226 int _stepX1; // offset for left and right cursor moves (slowest)227 int _stepX2; // offset for left and right cursor moves (faster)228 int _stepX3; // offset for left and right cursor moves (fastest)229 int _stepY1; // offset for up and down cursor moves (slowest)230 int _stepY2; // offset for up and down cursor moves (faster)231 int _stepY3; // offset for up and down cursor moves (fastest)232 233 int _mouseXZone[TOTAL_ZONES];234 int _mouseYZone[TOTAL_ZONES];235 int _currentZone;236 237 struct zoneDesc {238 int x;239 int y;240 int width;241 int height;242 };243 244 static zoneDesc _zones[TOTAL_ZONES];245 91 }; 246 92 247 93 #endif