diff --git a/src/modules/joystick/sdl/JoystickModule.cpp b/src/modules/joystick/sdl/JoystickModule.cpp index 878406a61..1c1fab0ba 100644 --- a/src/modules/joystick/sdl/JoystickModule.cpp +++ b/src/modules/joystick/sdl/JoystickModule.cpp @@ -41,10 +41,13 @@ namespace sdl JoystickModule::JoystickModule() { - // Init the SDL Joystick and Game Controller systems. if (SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) throw love::Exception("%s", SDL_GetError()); + // Initialize any joysticks which are already connected. + for (int i = 0; i < SDL_NumJoysticks(); i++) + addJoystick(i); + // Start joystick event watching. Joysticks are automatically added and // removed via love.event. SDL_JoystickEventState(SDL_ENABLE); @@ -54,10 +57,11 @@ JoystickModule::JoystickModule() JoystickModule::~JoystickModule() { // Close any open Joysticks. - for (size_t i = 0; i < joysticks.size(); i++) + std::list::iterator it; + for (it = joysticks.begin(); it != joysticks.end(); ++it) { - joysticks[i]->close(); - joysticks[i]->release(); + (*it)->close(); + (*it)->release(); } SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); @@ -110,32 +114,52 @@ love::joystick::Joystick *JoystickModule::addJoystick(int deviceindex) return 0; std::string guidstr = getDeviceGUID(deviceindex); - joystick::Joystick *joystick = 0; + bool reused = false; - for (size_t i = 0; i < joysticks.size(); i++) + std::list::iterator it; + for (it = joysticks.begin(); it != joysticks.end(); ++it) { // Try to re-use a disconnected Joystick with the same GUID. - if (!joysticks[i]->isConnected() && joysticks[i]->getGUID() == guidstr) + if (!(*it)->isConnected() && (*it)->getGUID() == guidstr) { - joystick = joysticks[i]; - joystick->open(deviceindex); + joystick = *it; + reused = true; break; } } if (!joystick) { - // Make a new Joystick and add it to the persistent list, if we can't - // re-use one. - joystick = new Joystick(joysticks.size(), deviceindex); + joystick = new Joystick(joysticks.size()); joysticks.push_back(joystick); } - // Add the Joystick to the connected list, if it's not there already. - if (std::find(activeSticks.begin(), activeSticks.end(), joystick) == activeSticks.end()) - activeSticks.push_back(joystick); + // Make sure the Joystick object isn't in the active list already. + removeJoystick(joystick); + if (!joystick->open(deviceindex)) + return 0; + + // Make sure multiple instances of the same physical joystick aren't added + // to the active list. + for (size_t i = 0; i < activeSticks.size(); i++) + { + if (joystick->getHandle() == activeSticks[i]->getHandle()) + { + joystick->close(); + + if (!reused) + { + joysticks.remove(joystick); + joystick->release(); + } + + return activeSticks[i]; + } + } + + activeSticks.push_back(joystick); return joystick; } diff --git a/src/modules/joystick/sdl/JoystickModule.h b/src/modules/joystick/sdl/JoystickModule.h index 55f224ffe..0e91ac091 100644 --- a/src/modules/joystick/sdl/JoystickModule.h +++ b/src/modules/joystick/sdl/JoystickModule.h @@ -24,9 +24,10 @@ // LOVE #include "joystick/JoystickModule.h" -// STL +// C++ #include -#include +#include +#include namespace love { @@ -52,6 +53,7 @@ public: love::joystick::Joystick *getJoystick(int joyindex); int getIndex(const love::joystick::Joystick *joystick); int getJoystickCount() const; + bool setGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput, Joystick::JoystickInput joyinput); Joystick::JoystickInput getGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput); @@ -60,6 +62,7 @@ private: std::string stringFromGamepadInput(Joystick::GamepadInput gpinput) const; Joystick::JoystickInput JoystickInputFromString(const std::string &str) const; void removeBindFromMapString(std::string &mapstr, const std::string &joybindstr) const; + void checkGamepads(const std::string &guid) const; // SDL2's GUIDs identify *classes* of devices, instead of unique devices. @@ -69,7 +72,7 @@ private: std::vector activeSticks; // Persistent list of all Joysticks which have been connected at some point. - std::vector joysticks; + std::list joysticks; }; // JoystickModule