diff options
author | Bastien Bouclet | 2017-12-19 06:01:21 +0100 |
---|---|---|
committer | Bastien Bouclet | 2017-12-26 21:11:05 +0100 |
commit | 1522fc8e2f109229d9947158a1cd2ccc8c4642e1 (patch) | |
tree | 1007d8933bf584983d7caed1250e1ca5e29451d2 /backends/events | |
parent | a86eae63235357c942a55f2b320187880ebe823e (diff) | |
download | scummvm-rg350-1522fc8e2f109229d9947158a1cd2ccc8c4642e1.tar.gz scummvm-rg350-1522fc8e2f109229d9947158a1cd2ccc8c4642e1.tar.bz2 scummvm-rg350-1522fc8e2f109229d9947158a1cd2ccc8c4642e1.zip |
SDL: Add support for joystick hotplug
Fixes #10366.
Diffstat (limited to 'backends/events')
-rw-r--r-- | backends/events/sdl/sdl-events.cpp | 100 | ||||
-rw-r--r-- | backends/events/sdl/sdl-events.h | 17 |
2 files changed, 90 insertions, 27 deletions
diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp index d4e8956366..8a59aeb1a8 100644 --- a/backends/events/sdl/sdl-events.cpp +++ b/backends/events/sdl/sdl-events.cpp @@ -87,37 +87,12 @@ SdlEventSource::SdlEventSource() } #endif - // Enable joystick - if (SDL_NumJoysticks() > joystick_num) { -#if SDL_VERSION_ATLEAST(2, 0, 0) - if (SDL_IsGameController(joystick_num)) { - _controller = SDL_GameControllerOpen(joystick_num); - debug("Using game controller: %s", SDL_GameControllerName(_controller)); - } else -#endif - { - _joystick = SDL_JoystickOpen(joystick_num); - debug("Using joystick: %s", -#if SDL_VERSION_ATLEAST(2, 0, 0) - SDL_JoystickName(_joystick) -#else - SDL_JoystickName(joystick_num) -#endif - ); - } - } else { - warning("Invalid joystick: %d", joystick_num); - } + openJoystick(joystick_num); } } SdlEventSource::~SdlEventSource() { -#if SDL_VERSION_ATLEAST(2, 0, 0) - if (_controller) - SDL_GameControllerClose(_controller); -#endif - if (_joystick) - SDL_JoystickClose(_joystick); + closeJoystick(); } int SdlEventSource::mapKey(SDLKey sdlKey, SDLMod mod, Uint16 unicode) { @@ -617,6 +592,12 @@ bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) { default: return false; } + + case SDL_JOYDEVICEADDED: + return handleJoystickAdded(ev.jdevice); + + case SDL_JOYDEVICEREMOVED: + return handleJoystickRemoved(ev.jdevice); #else case SDL_VIDEOEXPOSE: if (_graphicsManager) @@ -831,6 +812,42 @@ bool SdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) { return processMouseEvent(event, ev.button.x, ev.button.y); } +void SdlEventSource::openJoystick(int joystickIndex) { + if (SDL_NumJoysticks() > joystickIndex) { +#if SDL_VERSION_ATLEAST(2, 0, 0) + if (SDL_IsGameController(joystickIndex)) { + _controller = SDL_GameControllerOpen(joystickIndex); + debug("Using game controller: %s", SDL_GameControllerName(_controller)); + } else +#endif + { + _joystick = SDL_JoystickOpen(joystickIndex); + debug("Using joystick: %s", +#if SDL_VERSION_ATLEAST(2, 0, 0) + SDL_JoystickName(_joystick) +#else + SDL_JoystickName(joystickIndex) +#endif + ); + } + } else { + warning("Invalid joystick: %d", joystickIndex); + } +} + +void SdlEventSource::closeJoystick() { +#if SDL_VERSION_ATLEAST(2, 0, 0) + if (_controller) { + SDL_GameControllerClose(_controller); + _controller = nullptr; + } +#endif + if (_joystick) { + SDL_JoystickClose(_joystick); + _joystick = nullptr; + } +} + bool SdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) { if (ev.jbutton.button == JOY_BUT_LMOUSE) { event.type = Common::EVENT_LBUTTONDOWN; @@ -906,6 +923,35 @@ bool SdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) { } #if SDL_VERSION_ATLEAST(2, 0, 0) +bool SdlEventSource::handleJoystickAdded(const SDL_JoyDeviceEvent &device) { + int joystick_num = ConfMan.getInt("joystick_num"); + if (joystick_num == device.which) { + closeJoystick(); + openJoystick(joystick_num); + } + + return false; +} + +bool SdlEventSource::handleJoystickRemoved(const SDL_JoyDeviceEvent &device) { + SDL_Joystick *joystick; + if (_controller) { + joystick = SDL_GameControllerGetJoystick(_controller); + } else { + joystick = _joystick; + } + + if (!joystick) { + return false; + } + + if (SDL_JoystickInstanceID(joystick) == device.which) { + closeJoystick(); + } + + return false; +} + bool SdlEventSource::handleControllerButton(const SDL_Event &ev, Common::Event &event, bool buttonUp) { using namespace Common; diff --git a/backends/events/sdl/sdl-events.h b/backends/events/sdl/sdl-events.h index 33d971a605..f5bbfeb15c 100644 --- a/backends/events/sdl/sdl-events.h +++ b/backends/events/sdl/sdl-events.h @@ -94,6 +94,21 @@ protected: SdlGraphicsManager *_graphicsManager; /** + * Open the SDL joystick with the specified index + * + * After this function completes successfully, SDL sends events for the device. + * + * If the joystick is also a SDL game controller, open it as a controller + * so an extended button mapping can be used. + */ + void openJoystick(int joystickIndex); + + /** + * Close the currently open joystick if any + */ + void closeJoystick(); + + /** * Pre process an event before it is dispatched. */ virtual void preprocessEvents(SDL_Event *event) {} @@ -123,6 +138,8 @@ protected: virtual bool handleKbdMouse(Common::Event &event); #if SDL_VERSION_ATLEAST(2, 0, 0) + virtual bool handleJoystickAdded(const SDL_JoyDeviceEvent &event); + virtual bool handleJoystickRemoved(const SDL_JoyDeviceEvent &device); virtual bool handleControllerButton(const SDL_Event &ev, Common::Event &event, bool buttonUp); virtual bool handleControllerAxisMotion(const SDL_Event &ev, Common::Event &event); #endif |