From 22aac69fe5c3ef2f719c5348ef85510513191eea Mon Sep 17 00:00:00 2001 From: Nicolas Bacca Date: Tue, 21 Dec 2004 00:31:58 +0000 Subject: [PATCH] Cleanup mouseclick emulation (and make the new about dialog happy) svn-id: r16222 --- backends/wince/CEActionsPocket.cpp | 10 +- backends/wince/CEActionsSmartphone.cpp | 12 +- backends/wince/CEkeys/EventsBuffer.cpp | 14 +- backends/wince/CEkeys/EventsBuffer.h | 4 +- backends/wince/wince-sdl.cpp | 254 +++++++++++++++++++++---- backends/wince/wince-sdl.h | 38 +++- 6 files changed, 268 insertions(+), 64 deletions(-) diff --git a/backends/wince/CEActionsPocket.cpp b/backends/wince/CEActionsPocket.cpp index 06bfc244524..be65a855343 100644 --- a/backends/wince/CEActionsPocket.cpp +++ b/backends/wince/CEActionsPocket.cpp @@ -160,8 +160,14 @@ CEActionsPocket::~CEActionsPocket() { } bool CEActionsPocket::perform(ActionType action, bool pushed) { - if (!pushed) + if (!pushed) { + switch(action) { + case POCKET_ACTION_RIGHTCLICK: + _mainSystem->add_right_click(false); + return true; + } return false; + } switch (action) { case POCKET_ACTION_PAUSE: @@ -179,7 +185,7 @@ bool CEActionsPocket::perform(ActionType action, bool pushed) { _mainSystem->swap_sound_master(); return true; case POCKET_ACTION_RIGHTCLICK: - _mainSystem->add_right_click(); + _mainSystem->add_right_click(true); return true; case POCKET_ACTION_CURSOR: _mainSystem->swap_mouse_visibility(); diff --git a/backends/wince/CEActionsSmartphone.cpp b/backends/wince/CEActionsSmartphone.cpp index 1dfd7af190b..db27395f32a 100644 --- a/backends/wince/CEActionsSmartphone.cpp +++ b/backends/wince/CEActionsSmartphone.cpp @@ -146,6 +146,14 @@ CEActionsSmartphone::~CEActionsSmartphone() { bool CEActionsSmartphone::perform(ActionType action, bool pushed) { if (!pushed) { + switch (action) { + case SMARTPHONE_ACTION_RIGHTCLICK: + _mainSystem->add_right_click(false); + return true; + case SMARTPHONE_ACTION_LEFTCLICK: + _mainSystem->add_left_click(false); + return true; + } return false; } @@ -155,10 +163,10 @@ bool CEActionsSmartphone::perform(ActionType action, bool pushed) { EventsBuffer::simulateKey(&_key_action[action]); return true; case SMARTPHONE_ACTION_RIGHTCLICK: - _mainSystem->add_right_click(); + _mainSystem->add_right_click(true); return true; case SMARTPHONE_ACTION_LEFTCLICK: - _mainSystem->add_left_click(); + _mainSystem->add_left_click(true); return true; case SMARTPHONE_ACTION_UP: _mainSystem->move_cursor_up(); diff --git a/backends/wince/CEkeys/EventsBuffer.cpp b/backends/wince/CEkeys/EventsBuffer.cpp index 37b58f640fe..97ec7c20046 100644 --- a/backends/wince/CEkeys/EventsBuffer.cpp +++ b/backends/wince/CEkeys/EventsBuffer.cpp @@ -52,29 +52,23 @@ namespace CEKEYS { return (SDL_PushEvent(&ev) == 0); } - bool EventsBuffer::simulateMouseLeftClick(int x, int y) { + bool EventsBuffer::simulateMouseLeftClick(int x, int y, bool pushed) { SDL_Event ev = {0}; - ev.type = SDL_MOUSEBUTTONDOWN; + ev.type = (pushed ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP); ev.button.button = SDL_BUTTON_LEFT; ev.button.x = x; ev.button.y = y; - if (SDL_PushEvent(&ev)) - return false; - ev.type = SDL_MOUSEBUTTONUP; return (SDL_PushEvent(&ev) == 0); } - bool EventsBuffer::simulateMouseRightClick(int x, int y) { + bool EventsBuffer::simulateMouseRightClick(int x, int y, bool pushed) { SDL_Event ev = {0}; - ev.type = SDL_MOUSEBUTTONDOWN; + ev.type = (pushed ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP); ev.button.button = SDL_BUTTON_RIGHT; ev.button.x = x; ev.button.y = y; - if (SDL_PushEvent(&ev)) - return false; - ev.type = SDL_MOUSEBUTTONUP; return (SDL_PushEvent(&ev) == 0); } } diff --git a/backends/wince/CEkeys/EventsBuffer.h b/backends/wince/CEkeys/EventsBuffer.h index 12dacee94d9..200478026d8 100644 --- a/backends/wince/CEkeys/EventsBuffer.h +++ b/backends/wince/CEkeys/EventsBuffer.h @@ -37,8 +37,8 @@ namespace CEKEYS { public: static bool simulateKey(Key *key); static bool simulateMouseMove(int x, int y); - static bool simulateMouseLeftClick(int x, int y); - static bool simulateMouseRightClick(int x, int y); + static bool simulateMouseLeftClick(int x, int y, bool pushed); + static bool simulateMouseRightClick(int x, int y, bool pushed); }; } diff --git a/backends/wince/wince-sdl.cpp b/backends/wince/wince-sdl.cpp index d4f487ca6c1..4edf203d030 100644 --- a/backends/wince/wince-sdl.cpp +++ b/backends/wince/wince-sdl.cpp @@ -75,6 +75,8 @@ static FILE *stderr_file; bool OSystem_WINCE3::_soundMaster = true; OSystem::SoundProc OSystem_WINCE3::_originalSoundProc = NULL; +bool _isSmartphone = false; + // Graphics mode consts // Low end devices 240x320 @@ -104,6 +106,12 @@ static const OSystem::GraphicsMode s_supportedGraphicsModesHigh[] = { }; +// ******************************************************************************************** + +bool isSmartphone() { + return _isSmartphone; +} + // ******************************************************************************************** // MAIN @@ -113,29 +121,37 @@ extern "C" int scummvm_main(GameDetector &gameDetector, int argc, char **argv); void handleException(EXCEPTION_POINTERS *exceptionPointers) { CEException::writeException(TEXT("\\scummvmCrash"), exceptionPointers); drawError("Unrecoverable exception occurred - see crash dump in latest \\scummvmCrash file"); - exit(1); + fclose(stdout_file); + fclose(stderr_file); + CEDevice::end(); + SDL_Quit(); + exit(0); } int SDL_main(int argc, char **argv) { + CEDevice::init(); OSystem_WINCE3::initScreenInfos(); /* Sanity check */ -#ifndef WIN32_PLATFORM_WFSP - if (CEDevice::hasSmartphoneResolution()) { - MessageBox(NULL, TEXT("This build was not compiled with Smartphone support"), TEXT("ScummVM error"), MB_OK | MB_ICONERROR); - return 0; - } -#endif +//#ifndef WIN32_PLATFORM_WFSP +// if (CEDevice::hasSmartphoneResolution()) { +// MessageBox(NULL, TEXT("This build was not compiled with Smartphone support"), TEXT("ScummVM error"), MB_OK | MB_ICONERROR); +// return 0; +// } +//#endif /* Avoid print problems - this file will be put in RAM anyway */ stdout_file = fopen("\\scummvm_stdout.txt", "w"); stderr_file = fopen("\\scummvm_stderr.txt", "w"); CEActions::init(_gameDetector); + __try { return scummvm_main(_gameDetector, argc, argv); } __except (handleException(GetExceptionInformation())) { } + + return 0; } - + // ******************************************************************************************** @@ -157,10 +173,6 @@ void drawError(char *error) { pumpMessages(); } -bool isSmartphone(void) { - return CEDevice::hasSmartphoneResolution(); -} - // ******************************************************************************************** int OSystem_WINCE3::getScreenWidth() { @@ -199,9 +211,23 @@ OSystem_WINCE3::OSystem_WINCE3() : OSystem_SDL(), _orientationLandscape(false), _newOrientation(false), _panelInitialized(false), _panelVisible(false), _panelStateForced(false), _forceHideMouse(false), _freeLook(false), _toolbarHighDrawn(false), _zoomUp(false), _zoomDown(false), - _scalersChanged(false) + _scalersChanged(false), _monkeyKeyboard(false), _lastKeyPressed(0) { + _isSmartphone = CEDevice::hasSmartphoneResolution(); + memset(&_mouseCurState, 0, sizeof(_mouseCurState)); + if (_isSmartphone) { + _mouseCurState.x = 20; + _mouseCurState.y = 20; + } create_toolbar(); + // Initialize global key mapping for Smartphones + CEActions::Instance()->initInstanceMain(this); + CEActions::Instance()->loadMapping(); + + if (_isSmartphone) { + loadSmartphoneConfiguration(); + } + } void OSystem_WINCE3::swap_panel_visibility() { @@ -233,10 +259,10 @@ void OSystem_WINCE3::swap_sound_master() { _toolbarHandler.forceRedraw(); // redraw sound icon } -void OSystem_WINCE3::add_right_click() { +void OSystem_WINCE3::add_right_click(bool pushed) { int x, y; retrieve_mouse_location(x, y); - EventsBuffer::simulateMouseRightClick(x, y); + EventsBuffer::simulateMouseRightClick(x, y, pushed); } void OSystem_WINCE3::swap_mouse_visibility() { @@ -311,36 +337,117 @@ void OSystem_WINCE3::swap_zoom_down() { internUpdateScreen(); } -#ifdef WIN32_PLATFORM_WFSP +//#ifdef WIN32_PLATFORM_WFSP // Smartphone actions -void OSystem_WINCE3::add_left_click() { - _addLeftClickDown = true; +void OSystem_WINCE3::loadSmartphoneConfigurationElement(String element, int &value, int defaultValue) { + value = ConfMan.getInt(element, "smartphone"); + if (!value) { + value = defaultValue; + ConfMan.set(element, value, "smartphone"); + } +} + +void OSystem_WINCE3::loadSmartphoneConfiguration() { + loadSmartphoneConfigurationElement("repeatTrigger", _keyRepeatTrigger, 200); + loadSmartphoneConfigurationElement("repeatX", _repeatX, 4); + loadSmartphoneConfigurationElement("repeatY", _repeatY, 4); + loadSmartphoneConfigurationElement("stepX1", _stepX1, 2); + loadSmartphoneConfigurationElement("stepX2", _stepX2, 10); + loadSmartphoneConfigurationElement("stepX3", _stepX3, 40); + loadSmartphoneConfigurationElement("stepY1", _stepY1, 2); + loadSmartphoneConfigurationElement("stepY2", _stepY2, 10); + loadSmartphoneConfigurationElement("stepY3", _stepY3, 20); + ConfMan.flushToDisk(); +} + +void OSystem_WINCE3::add_left_click(bool pushed) { + int x, y; + retrieve_mouse_location(x, y); + EventsBuffer::simulateMouseLeftClick(x, y, pushed); } void OSystem_WINCE3::move_cursor_up() { + int x,y; + retrieve_mouse_location(x, y); + if (_keyRepeat > _repeatY) + y -= _stepY3; + else + if (_keyRepeat) + y -= _stepY2; + else + y -= _stepY1; + + if (y < 0) + y = 0; + + EventsBuffer::simulateMouseMove(x, y); } void OSystem_WINCE3::move_cursor_down() { + int x,y; + retrieve_mouse_location(x, y); + if (_keyRepeat > _repeatY) + y += _stepY3; + else + if (_keyRepeat) + y += _stepY2; + else + y += _stepY1; + + if (y > 200) + y = 200; + + EventsBuffer::simulateMouseMove(x, y); } void OSystem_WINCE3::move_cursor_left() { + int x,y; + retrieve_mouse_location(x, y); + if (_keyRepeat > _repeatX) + x -= _stepX3; + else + if (_keyRepeat) + x -= _stepX2; + else + x -= _stepX1; + + if (x < 0) + x = 0; + + EventsBuffer::simulateMouseMove(x, y); } void OSystem_WINCE3::move_cursor_right() { + int x,y; + retrieve_mouse_location(x, y); + if (_keyRepeat > _repeatX) + x += _stepX3; + else + if (_keyRepeat) + x += _stepX2; + else + x += _stepX1; + + if (x > 320) + x = 320; + + EventsBuffer::simulateMouseMove(x, y); } void OSystem_WINCE3::switch_zone() { } -#endif +//#endif void OSystem_WINCE3::create_toolbar() { PanelKeyboard *keyboard; // Add the keyboard - keyboard = new PanelKeyboard(PANEL_KEYBOARD); - _toolbarHandler.add(NAME_PANEL_KEYBOARD, *keyboard); + if (!_isSmartphone) { + keyboard = new PanelKeyboard(PANEL_KEYBOARD); + _toolbarHandler.add(NAME_PANEL_KEYBOARD, *keyboard); + } } @@ -428,6 +535,8 @@ void OSystem_WINCE3::setFeatureState(Feature f, bool enable) { case kFeatureFullscreenMode: return; case kFeatureVirtualKeyboard: + if (_isSmartphone) + return; _toolbarHighDrawn = false; if (enable) { _panelStateForced = true; @@ -498,13 +607,7 @@ void OSystem_WINCE3::check_mappings() { if (!_gameDetector._targetName.size() || CEActions::Instance()->initialized()) return; - CEActions::Instance()->initInstance(this); - // Load key mapping - CEActions::Instance()->loadMapping(); - - if (CEDevice::hasSmartphoneResolution()) - return; - + CEActions::Instance()->initInstanceGame(); instance = (CEActionsPocket*)CEActions::Instance(); // Some games need to map the right click button, signal it here if it wasn't done @@ -549,6 +652,7 @@ void OSystem_WINCE3::check_mappings() { GUI::MessageDialog alert("Don't forget to map a key to 'Hide Toolbar' action to see the whole inventory"); alert.runModal(); } + } void OSystem_WINCE3::update_game_settings() { @@ -566,6 +670,7 @@ void OSystem_WINCE3::update_game_settings() { // sound panel->add(NAME_ITEM_SOUND, new ItemSwitch(ITEM_SOUND_OFF, ITEM_SOUND_ON, &_soundMaster)); // portrait/landscape - screen dependant + // FIXME : will still display the portrait/landscape icon when using a scaler (but will be disabled) if (_screenWidth <= 320 && (isOzone() || !CEDevice::hasDesktopResolution())) { _newOrientation = _orientationLandscape = (ConfMan.hasKey("landscape") ? ConfMan.getBool("landscape") : false); panel->add(NAME_ITEM_ORIENTATION, new ItemSwitch(ITEM_VIEW_LANDSCAPE, ITEM_VIEW_PORTRAIT, &_newOrientation)); @@ -573,7 +678,7 @@ void OSystem_WINCE3::update_game_settings() { _toolbarHandler.add(NAME_MAIN_PANEL, *panel); _toolbarHandler.setActive(NAME_MAIN_PANEL); - // Keyboard is active for Monkey 1 or 2 + // Keyboard is active for Monkey 1 or 2 initial copy-protection if (strncmp(_gameDetector._targetName.c_str(), "monkey", 6) == 0) { _monkeyKeyboard = true; _toolbarHandler.setActive(NAME_PANEL_KEYBOARD); @@ -583,19 +688,42 @@ void OSystem_WINCE3::update_game_settings() { setGraphicsMode(GFX_NORMAL); hotswapGFXMode(); } + + if (_isSmartphone) + panel->setVisible(false); } get_sample_rate(); } void OSystem_WINCE3::initSize(uint w, uint h) { - if (w == 320 && h == 200) + + if (_isSmartphone && h == 240) + h = 200; // mainly for the launcher + + switch (_transactionMode) { + case kTransactionActive: + _transactionDetails.w = w; + _transactionDetails.wChanged = true; + _transactionDetails.h = h; + _transactionDetails.hChanged = true; + return; + break; + case kTransactionCommit: + break; + default: + break; + } + + if (w == 320 && h == 200 && !_isSmartphone) h = 240; // use the extra 40 pixels height for the toolbar - if (h == 240) - _toolbarHandler.setOffset(200); - else - _toolbarHandler.setOffset(400); + if (!_isSmartphone) { + if (h == 240) + _toolbarHandler.setOffset(200); + else + _toolbarHandler.setOffset(400); + } if (w != _screenWidth || h != _screenHeight) _scalersChanged = false; @@ -649,8 +777,8 @@ bool OSystem_WINCE3::update_scalers() { return true; } -#ifdef WIN32_PLATFORM_WFSP - if (CEDevice::hasSmartphoneResolution()) { +//#ifdef WIN32_PLATFORM_WFSP + if (_isSmartphone) { if (_screenWidth > 320) error("Game resolution not supported on Smartphone"); _scaleFactorXm = 2; @@ -661,12 +789,25 @@ bool OSystem_WINCE3::update_scalers() { _modeFlags = 0; return true; } -#endif +//#endif return false; } bool OSystem_WINCE3::setGraphicsMode(int mode) { + + switch (_transactionMode) { + case kTransactionActive: + _transactionDetails.mode = mode; + _transactionDetails.modeChanged = true; + return true; + break; + case kTransactionCommit: + break; + default: + break; + } + Common::StackLock lock(_graphicsMutex); int oldScaleFactorXm = _scaleFactorXm; int oldScaleFactorXd = _scaleFactorXd; @@ -776,6 +917,7 @@ bool OSystem_WINCE3::setGraphicsMode(int mode) { else _scalersChanged = false; + return true; } @@ -1301,6 +1443,8 @@ bool OSystem_WINCE3::pollEvent(Event &event) { SDL_Event ev; byte b = 0; Event temp_event; + DWORD currentTime; + bool keyEvent = false; memset(&temp_event, 0, sizeof(Event)); memset(&event, 0, sizeof(Event)); @@ -1314,9 +1458,21 @@ bool OSystem_WINCE3::pollEvent(Event &event) { return true; } + CEDevice::wakeUp(); + + if (isSmartphone) + currentTime = GetTickCount(); + while(SDL_PollEvent(&ev)) { switch(ev.type) { case SDL_KEYDOWN: + if (_isSmartphone) { + keyEvent = true; + _lastKeyPressed = ev.key.keysym.sym; + _keyRepeatTime = currentTime; + _keyRepeat = 0; + } + if (CEActions::Instance()->performMapped(ev.key.keysym.sym, true)) return true; @@ -1330,6 +1486,11 @@ bool OSystem_WINCE3::pollEvent(Event &event) { return true; case SDL_KEYUP: + if (_isSmartphone) { + keyEvent = true; + _lastKeyPressed = 0; + } + if (CEActions::Instance()->performMapped(ev.key.keysym.sym, false)) return true; @@ -1361,7 +1522,7 @@ bool OSystem_WINCE3::pollEvent(Event &event) { if (_toolbarHandler.action(temp_event.mouse.x, temp_event.mouse.y, true)) { if (!_toolbarHandler.drawn()) internUpdateScreen(); - if (_newOrientation != _orientationLandscape) { + if (_newOrientation != _orientationLandscape && _mode == GFX_NORMAL) { _orientationLandscape = _newOrientation; ConfMan.set("landscape", _orientationLandscape); ConfMan.flushToDisk(); @@ -1406,6 +1567,22 @@ bool OSystem_WINCE3::pollEvent(Event &event) { return true; } } + + // Simulate repeated key for Smartphones + + if (!keyEvent) { + if (_isSmartphone) { + + if (_lastKeyPressed) { + if (currentTime > _keyRepeatTime + _keyRepeatTrigger) { + _keyRepeatTime = currentTime; + _keyRepeat++; + CEActions::Instance()->performMapped(_lastKeyPressed, true); + } + } + } + } + return false; } @@ -1416,6 +1593,7 @@ void OSystem_WINCE3::quit() { DeleteFile(TEXT("\\scummvm_stdout.txt")); DeleteFile(TEXT("\\scummvm_stderr.txt")); } + CEDevice::end(); OSystem_SDL::quit(); } diff --git a/backends/wince/wince-sdl.h b/backends/wince/wince-sdl.h index 4496bbb7552..cbc2e6083ad 100644 --- a/backends/wince/wince-sdl.h +++ b/backends/wince/wince-sdl.h @@ -64,21 +64,23 @@ public: void swap_panel_visibility(); void swap_panel(); void swap_sound_master(); - void add_right_click(); + void add_right_click(bool pushed); void swap_mouse_visibility(); void swap_freeLook(); void swap_zoom_up(); void swap_zoom_down(); -#ifdef WIN32_PLATFORM_WFSP +//#ifdef WIN32_PLATFORM_WFSP // Smartphone actions - void add_left_click(); + void loadSmartphoneConfigurationElement(String element, int &value, int defaultValue); + void loadSmartphoneConfiguration(); + void add_left_click(bool pushed); void move_cursor_up(); void move_cursor_down(); void move_cursor_left(); void move_cursor_right(); void switch_zone(); -#endif +//#endif static int getScreenWidth(); static int getScreenHeight(); @@ -154,15 +156,31 @@ private: bool _zoomUp; // zooming up mode bool _zoomDown; // zooming down mode - int _scaleFactorXm; - int _scaleFactorXd; - int _scaleFactorYm; - int _scaleFactorYd; - bool _scalersChanged; + int _scaleFactorXm; // scaler X * + int _scaleFactorXd; // scaler X / + int _scaleFactorYm; // scaler Y * + int _scaleFactorYd; // scaler Y / + bool _scalersChanged; static int _platformScreenWidth; static int _platformScreenHeight; - static bool _isOzone; + static bool _isOzone; // true if running on Windows 2003 SE + + // Smartphone specific variables + + int _lastKeyPressed; // last key pressed + int _keyRepeat; // number of time the last key was repeated + int _keyRepeatTime; // elapsed time since the key was pressed + int _keyRepeatTrigger; // minimum time to consider the key was repeated + + int _repeatX; // repeat trigger for left and right cursor moves + int _repeatY; // repeat trigger for up and down cursor moves + int _stepX1; // offset for left and right cursor moves (slowest) + int _stepX2; // offset for left and right cursor moves (faster) + int _stepX3; // offset for left and right cursor moves (fastest) + int _stepY1; // offset for up and down cursor moves (slowest) + int _stepY2; // offset for up and down cursor moves (faster) + int _stepY3; // offset for up and down cursor moves (fastest) }; #endif