diff --git a/src/ship/controller/physicaldevice/ConnectedPhysicalDeviceManager.cpp b/src/ship/controller/physicaldevice/ConnectedPhysicalDeviceManager.cpp index 2f372434e..7f0397e25 100644 --- a/src/ship/controller/physicaldevice/ConnectedPhysicalDeviceManager.cpp +++ b/src/ship/controller/physicaldevice/ConnectedPhysicalDeviceManager.cpp @@ -1,4 +1,5 @@ #include "ship/controller/physicaldevice/ConnectedPhysicalDeviceManager.h" +#include namespace Ship { ConnectedPhysicalDeviceManager::ConnectedPhysicalDeviceManager() { @@ -51,19 +52,53 @@ void ConnectedPhysicalDeviceManager::HandlePhysicalDeviceDisconnect(int32_t sdlJ void ConnectedPhysicalDeviceManager::RefreshConnectedSDLGamepads() { mConnectedSDLGamepads.clear(); mConnectedSDLGamepadNames.clear(); + static SDL_JoystickGUID sZeroGuid; for (int32_t i = 0; i < SDL_NumJoysticks(); i++) { - // skip if this SDL joystick isn't a Gamepad + + SDL_JoystickGUID deviceGUID = SDL_JoystickGetDeviceGUID(i); + if (SDL_memcmp(&deviceGUID, &sZeroGuid, sizeof(deviceGUID)) == 0) { + SPDLOG_WARN( + "Calling SDL JoystickGetDeviceGUID with index ({:d}) returned zero GUID. This is likely due to an " + "invalid index. Refer to https://wiki.libsdl.org/SDL2/SDL_JoystickGetDeviceGUID for more information.", + i); + continue; + } + + char deviceGuidCStr[33] = ""; + SDL_JoystickGetGUIDString(deviceGUID, deviceGuidCStr, sizeof(deviceGuidCStr)); + if (!SDL_IsGameController(i)) { + SPDLOG_WARN("SDL Joystick (GUID: {}) not recognized as gamepad." + "This is likely due to a missing mapping string in gamecontrollerdb.txt." + "Refer to https://github.com/mdqinc/SDL_GameControllerDB for more information.", + deviceGuidCStr); continue; } auto gamepad = SDL_GameControllerOpen(i); + if (gamepad == nullptr) { + SPDLOG_ERROR("SDL GameControllerOpen error (GUID: {}): {}", deviceGuidCStr, SDL_GetError()); + continue; + } + auto instanceId = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamepad)); + if (instanceId < 0) { + SPDLOG_ERROR("SDL JoystickInstanceID error (GUID: {}): {}", deviceGuidCStr, SDL_GetError()); + continue; + } + + std::string gamepadName; auto name = SDL_GameControllerName(gamepad); + if (name == nullptr) { + gamepadName = deviceGuidCStr; + SPDLOG_WARN("SDL_GameControllerName returned null. Setting name to GUID \"{}\" instead.", gamepadName); + } else { + gamepadName = name; + } mConnectedSDLGamepads[instanceId] = gamepad; - mConnectedSDLGamepadNames[instanceId] = name; + mConnectedSDLGamepadNames[instanceId] = gamepadName; for (uint8_t port = 1; port < 4; port++) { mIgnoredInstanceIds[port].insert(instanceId);