Initial Gamepad Hotplug Logic improvements

This changes the way how a Controller will be prioritized. By default: it'll always prioritize based on Player 1. It should play nicely with Steam Deck's internal inputs when Steam Input is active
This commit is contained in:
AL2009man 2025-03-06 16:44:40 -05:00
parent a8cac8763d
commit c9b3a5e03f

View file

@ -197,111 +197,137 @@ static void SetControllerTimeOfDayLED(Controller& controller, bool isNight)
auto g = isNight ? 0 : 37; auto g = isNight ? 0 : 37;
auto b = isNight ? 101 : 184; auto b = isNight ? 101 : 184;
controller.SetLED(r, g, b); // Ensure the lightbar is set correctly
if (SDL_GameControllerHasLED(controller.controller))
{
SDL_GameControllerSetLED(controller.controller, r, g, b);
}
} }
int HID_OnSDLEvent(void*, SDL_Event* event) int HID_OnSDLEvent(void*, SDL_Event* event)
{ {
switch (event->type) switch (event->type)
{ {
case SDL_CONTROLLERDEVICEADDED: case SDL_CONTROLLERDEVICEADDED:
{
const auto freeIndex = FindFreeController();
if (freeIndex != -1)
{ {
const auto freeIndex = FindFreeController(); auto controller = Controller(event->cdevice.which);
if (freeIndex != -1) g_controllers[freeIndex] = controller;
SetControllerTimeOfDayLED(controller, App::s_isWerehog);
// Ensure Player 1's controller is always the active controller
if (freeIndex == 0)
{ {
auto controller = Controller(event->cdevice.which); SetControllerInputDevice(&g_controllers[0]);
g_controllers[freeIndex] = controller;
SetControllerTimeOfDayLED(controller, App::s_isWerehog);
} }
break;
} }
case SDL_CONTROLLERDEVICEREMOVED: break;
}
case SDL_CONTROLLERDEVICEREMOVED:
{
auto* controller = FindController(event->cdevice.which);
if (controller)
controller->Close();
// If Player 1's controller is removed, set the next available controller as active
if (controller == &g_controllers[0])
{ {
auto* controller = FindController(event->cdevice.which); for (auto& ctrl : g_controllers)
if (controller)
controller->Close();
break;
}
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
case SDL_CONTROLLERAXISMOTION:
case SDL_CONTROLLERTOUCHPADDOWN:
{
auto* controller = FindController(event->cdevice.which);
if (!controller)
break;
if (event->type == SDL_CONTROLLERAXISMOTION)
{ {
if (abs(event->caxis.value) > 8000) if (ctrl.CanPoll())
{ {
SDL_ShowCursor(SDL_DISABLE); SetControllerInputDevice(&ctrl);
SetControllerInputDevice(controller); break;
} }
controller->PollAxis();
} }
else }
break;
}
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
case SDL_CONTROLLERAXISMOTION:
case SDL_CONTROLLERTOUCHPADDOWN:
{
auto* controller = FindController(event->cdevice.which);
if (!controller)
break;
if (event->type == SDL_CONTROLLERAXISMOTION)
{
if (abs(event->caxis.value) > 8000)
{ {
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
SetControllerInputDevice(controller); SetControllerInputDevice(controller);
controller->Poll();
} }
break; controller->PollAxis();
}
else
{
SDL_ShowCursor(SDL_DISABLE);
SetControllerInputDevice(controller);
controller->Poll();
} }
case SDL_KEYDOWN: break;
case SDL_KEYUP: }
hid::g_inputDevice = hid::EInputDevice::Keyboard;
break;
case SDL_MOUSEMOTION: case SDL_KEYDOWN:
case SDL_MOUSEBUTTONDOWN: case SDL_KEYUP:
case SDL_MOUSEBUTTONUP: hid::g_inputDevice = hid::EInputDevice::Keyboard;
{ break;
if (!GameWindow::IsFullscreen() || GameWindow::s_isFullscreenCursorVisible)
SDL_ShowCursor(SDL_ENABLE); case SDL_MOUSEMOTION:
case SDL_MOUSEBUTTONDOWN:
hid::g_inputDevice = hid::EInputDevice::Mouse; case SDL_MOUSEBUTTONUP:
{
break; if (!GameWindow::IsFullscreen() || GameWindow::s_isFullscreenCursorVisible)
} SDL_ShowCursor(SDL_ENABLE);
case SDL_WINDOWEVENT: hid::g_inputDevice = hid::EInputDevice::Mouse;
{
if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST) break;
{ }
// Stop vibrating controllers on focus lost.
for (auto& controller : g_controllers) case SDL_WINDOWEVENT:
controller.SetVibration({ 0, 0 }); {
} if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST)
break;
}
case SDL_USER_EVILSONIC:
{ {
// Stop vibrating controllers on focus lost.
for (auto& controller : g_controllers) for (auto& controller : g_controllers)
SetControllerTimeOfDayLED(controller, event->user.code); controller.SetVibration({ 0, 0 });
break;
} }
break;
}
case SDL_USER_EVILSONIC:
{
for (auto& controller : g_controllers)
SetControllerTimeOfDayLED(controller, event->user.code);
break;
}
} }
return 0; return 0;
} }
void hid::Init() void hid::Init()
{ {
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");