ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

resvm-sdl-events.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/scummsys.h"
00024 
00025 #if defined(SDL_BACKEND)
00026 
00027 #include "resvm-sdl-events.h"
00028 #include "backends/graphics/sdl/resvm-sdl-graphics.h"
00029 #include "engines/engine.h"
00030 #include "gui/gui-manager.h"
00031 
00032 #if defined(ENABLE_VKEYBD) && SDL_VERSION_ATLEAST(2, 0, 0)
00033 #define CONTROLLER_BUT_VKEYBOARD SDL_CONTROLLER_BUTTON_BACK
00034 #endif
00035 
00036 bool ResVmSdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
00037     if (shouldGenerateMouseEvents()) {
00038         return SdlEventSource::handleJoyButtonDown(ev, event);
00039     } else {
00040         event.type = Common::EVENT_JOYBUTTON_DOWN;
00041         event.joystick.button = ev.jbutton.button;
00042         return true;
00043     }
00044 }
00045 
00046 bool ResVmSdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
00047     if (shouldGenerateMouseEvents()) {
00048         return SdlEventSource::handleJoyButtonUp(ev, event);
00049     } else {
00050         event.type = Common::EVENT_JOYBUTTON_UP;
00051         event.joystick.button = ev.jbutton.button;
00052         return true;
00053     }
00054 }
00055 
00056 bool ResVmSdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) {
00057     if (shouldGenerateMouseEvents()) {
00058         return SdlEventSource::handleJoyAxisMotion(ev, event);
00059     } else {
00060         event.type = Common::EVENT_JOYAXIS_MOTION;
00061         event.joystick.axis = ev.jaxis.axis;
00062         event.joystick.position = ev.jaxis.value;
00063         return true;
00064     }
00065 }
00066 
00067 #if SDL_VERSION_ATLEAST(2, 0, 0)
00068 
00069 byte mapSDLControllerButtonToResVM(Uint8 sdlButton) {
00070     Common::JoystickButton resvmButtons[] = {
00071         Common::JOYSTICK_BUTTON_A,
00072         Common::JOYSTICK_BUTTON_B,
00073         Common::JOYSTICK_BUTTON_X,
00074         Common::JOYSTICK_BUTTON_Y,
00075         Common::JOYSTICK_BUTTON_BACK,
00076         Common::JOYSTICK_BUTTON_GUIDE,
00077         Common::JOYSTICK_BUTTON_START,
00078         Common::JOYSTICK_BUTTON_LEFT_STICK,
00079         Common::JOYSTICK_BUTTON_RIGHT_STICK,
00080         Common::JOYSTICK_BUTTON_LEFT_SHOULDER,
00081         Common::JOYSTICK_BUTTON_RIGHT_SHOULDER,
00082         Common::JOYSTICK_BUTTON_DPAD_UP,
00083         Common::JOYSTICK_BUTTON_DPAD_DOWN,
00084         Common::JOYSTICK_BUTTON_DPAD_LEFT,
00085         Common::JOYSTICK_BUTTON_DPAD_RIGHT,
00086     };
00087 
00088     if (sdlButton >= ARRAYSIZE(resvmButtons)) {
00089         return -1;
00090     }
00091 
00092     return resvmButtons[sdlButton];
00093 }
00094 
00095 bool ResVmSdlEventSource::handleControllerButton(const SDL_Event &ev, Common::Event &event, bool buttonUp) {
00096     if (shouldGenerateMouseEvents()) {
00097         return SdlEventSource::handleControllerButton(ev, event, buttonUp);
00098     } else {
00099 #ifdef ENABLE_VKEYBD
00100         // Trigger virtual keyboard on long press of more than 1 second of configured button
00101         const uint32 vkeybdTime = 1000;
00102         static uint32 vkeybdThen = 0;
00103 
00104         if (ev.cbutton.button == CONTROLLER_BUT_VKEYBOARD) {
00105             if (!buttonUp) {
00106                 vkeybdThen = g_system->getMillis();
00107             } else if ((vkeybdThen > 0) && (g_system->getMillis() - vkeybdThen >= vkeybdTime)) {
00108                 vkeybdThen = 0;
00109                 event.type = Common::EVENT_VIRTUAL_KEYBOARD;
00110                 return true;
00111             }
00112         }
00113 #endif
00114         byte button = mapSDLControllerButtonToResVM(ev.cbutton.button);
00115         if (button == -1) {
00116             return false;
00117         }
00118 
00119         event.type = buttonUp ? Common::EVENT_JOYBUTTON_UP : Common::EVENT_JOYBUTTON_DOWN;
00120         event.joystick.button = button;
00121         return true;
00122     }
00123 }
00124 
00125 bool ResVmSdlEventSource::handleControllerAxisMotion(const SDL_Event &ev, Common::Event &event) {
00126     if (shouldGenerateMouseEvents()) {
00127         return SdlEventSource::handleControllerAxisMotion(ev, event);
00128     } else {
00129         // Indicates if L2/R2 are currently pushed or not
00130         static bool l2Pushed = false, r2Pushed = false;
00131         // Simulate buttons from left and right triggers (needed for EMI)
00132         if (ev.caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT) {
00133             bool pushed = (ev.caxis.value > 0);
00134             if (l2Pushed == pushed)
00135                 return false;
00136             event.type = (pushed) ? Common::EVENT_JOYBUTTON_DOWN : Common::EVENT_JOYBUTTON_UP;
00137             event.joystick.button = Common::JOYSTICK_BUTTON_LEFT_TRIGGER;
00138             l2Pushed = pushed;
00139             return true;
00140         } else if (ev.caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) {
00141             bool pushed = (ev.caxis.value > 0);
00142             if (r2Pushed == pushed)
00143                 return false;
00144             event.type = (pushed) ? Common::EVENT_JOYBUTTON_DOWN : Common::EVENT_JOYBUTTON_UP;
00145             event.joystick.button = Common::JOYSTICK_BUTTON_RIGHT_TRIGGER;
00146             r2Pushed = pushed;
00147             return true;
00148         } else {
00149             event.type = Common::EVENT_JOYAXIS_MOTION;
00150             event.joystick.axis = ev.caxis.axis;
00151             event.joystick.position = ev.caxis.value;
00152             return true;
00153         }
00154     }
00155 }
00156 #endif
00157 
00158 bool ResVmSdlEventSource::shouldGenerateMouseEvents() {
00159     // Engine doesn't support joystick -> emulate mouse events
00160     if (g_engine && !g_engine->hasFeature(Engine::kSupportsJoystick)) {
00161         return true;
00162     }
00163 
00164     // Even if engine supports joystick, emulate mouse events if in GUI or in virtual keyboard
00165     if (g_gui.isActive() || g_engine->isPaused()) {
00166         return true;
00167     }
00168 
00169     return false;
00170 }
00171 
00172 bool ResVmSdlEventSource::handleKbdMouse(Common::Event &event) {
00173     // The ResidualVM version of this method handles relative mouse
00174     // movement, as required by Myst III.
00175 
00176     int16 oldKmX = _km.x;
00177     int16 oldKmY = _km.y;
00178 
00179     updateKbdMouse();
00180 
00181     if (_km.x != oldKmX || _km.y != oldKmY) {
00182         ResVmSdlGraphicsManager *graphicsManager = dynamic_cast<ResVmSdlGraphicsManager *>(_graphicsManager);
00183 
00184         int16 relX = _km.x - oldKmX;
00185         int16 relY = _km.y - oldKmY;
00186 
00187         if (graphicsManager) {
00188             if (graphicsManager->isMouseLocked()) {
00189                 _km.x = oldKmX;
00190                 _km.y = oldKmY;
00191             } else {
00192                 // warpMouseInWindow causes SDL to generate mouse events. Don't use it when the mouse is locked
00193                 // to avoid inconsistent events that would cause crazy camera movement in Myst III.
00194                 graphicsManager->getWindow()->warpMouseInWindow((Uint16)(_km.x / MULTIPLIER), (Uint16)(_km.y / MULTIPLIER));
00195             }
00196         }
00197 
00198         event.type = Common::EVENT_MOUSEMOVE;
00199         return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER, relX / MULTIPLIER, relY / MULTIPLIER);
00200     }
00201 
00202     return false;
00203 }
00204 
00205 #endif


Generated on Sat May 18 2019 05:01:18 for ResidualVM by doxygen 1.7.1
curved edge   curved edge