SDL: Release all input when a controller is disconnected

The last platform that was missing this - it was held back waiting for
the SDL 3.0 migration, which has now happened. Without it, whatever was
held when the pad vanished stays held, which tends to walk the player
off a cliff.

Fixes #20418

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01JvJR8oJNSCimCM9KXVLjfq
This commit is contained in:
Henrik RydgårdandClaude Opus 5 committed 2026-09-04 13:10:54 -06:00
1 parent b5bafa43b8
commit b115206a66
2 files changed
+31

No files matched your search

+30
View File
@@ -167,6 +167,31 @@ InputKeyCode SDLJoystick::getKeycodeForButton(SDL_GamepadButton button) {
}
}
// Called when a pad is disconnected - we won't be getting any more up events from it.
void SDLJoystick::releaseAllKeys() {
for (int i = 0; i < SDL_GAMEPAD_BUTTON_COUNT; i++) {
const InputKeyCode code = getKeycodeForButton((SDL_GamepadButton)i);
if (code == NKCODE_UNKNOWN) {
continue;
}
KeyInput key{};
key.deviceId = DEVICE_ID_PAD_0;
key.keyCode = code;
key.flags = KeyInputFlags::UP;
NativeKey(key);
}
// Zero every axis we've actually sent a value for, so sticks and triggers recenter.
for (auto &[key, value] : prevAxisValue_) {
AxisInput axis{};
axis.deviceId = key.first;
axis.axisId = key.second;
axis.value = 0.0f;
NativeAxis(&axis, 1);
}
prevAxisValue_.clear();
}
void SDLJoystick::ProcessInput(const SDL_Event &event){
switch (event.type) {
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
@@ -211,6 +236,11 @@ void SDLJoystick::ProcessInput(const SDL_Event &event){
SDL_CloseGamepad(*it);
controllerDeviceMap.erase(event.gdevice.which);
controllers.erase(it);
// Otherwise whatever was held when the pad vanished stays held forever, which
// tends to walk the player off a cliff. Note that we map every pad to pad 0,
// so we can't release just the one that went away.
releaseAllKeys();
KeyMap::NotifyPadDisconnected(DEVICE_ID_PAD_0);
break;
}
}
+1
View File
@@ -20,6 +20,7 @@ private:
void setUpControllers();
InputKeyCode getKeycodeForButton(SDL_GamepadButton button);
int getDeviceIndex(int instanceId);
void releaseAllKeys();
bool registeredAsEventHandler;
std::vector<SDL_Gamepad *> controllers;