SDL: Add support for joystick hotplug

Fixes #10366.
This commit is contained in:
Bastien Bouclet 2017-12-19 06:01:21 +01:00
parent a86eae6323
commit 1522fc8e2f
2 changed files with 90 additions and 27 deletions

View File

@ -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;

View File

@ -93,6 +93,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.
*/
@ -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