aboutsummaryrefslogtreecommitdiff
path: root/backends/events
diff options
context:
space:
mode:
authorBastien Bouclet2017-12-19 06:01:21 +0100
committerBastien Bouclet2017-12-26 21:11:05 +0100
commit1522fc8e2f109229d9947158a1cd2ccc8c4642e1 (patch)
tree1007d8933bf584983d7caed1250e1ca5e29451d2 /backends/events
parenta86eae63235357c942a55f2b320187880ebe823e (diff)
downloadscummvm-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.cpp100
-rw-r--r--backends/events/sdl/sdl-events.h17
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