From 695840332e44da633a57b76624f385272aacc2b7 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Sat, 26 Oct 2024 01:19:15 +0300 Subject: [PATCH] Better gamepad events handling --- src/xrEngine/xr_input.cpp | 56 +++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/src/xrEngine/xr_input.cpp b/src/xrEngine/xr_input.cpp index 6b0aaea7c54..17c20d21054 100644 --- a/src/xrEngine/xr_input.cpp +++ b/src/xrEngine/xr_input.cpp @@ -306,28 +306,54 @@ void CInput::ControllerUpdate() SDL_Event events[MAX_CONTROLLER_EVENTS]; auto count = SDL_PeepEvents(events, MAX_CONTROLLER_EVENTS, - SDL_GETEVENT, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEADDED); + SDL_GETEVENT, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMAPPED); for (int i = 0; i < count; ++i) { const SDL_Event& event = events[i]; - OpenController(event.cdevice.which); + switch (event.type) + { + case SDL_CONTROLLERDEVICEADDED: + OpenController(event.cdevice.which); + break; + + case SDL_CONTROLLERDEVICEREMOVED: + { + const auto controller = SDL_GameControllerFromInstanceID(event.cdevice.which); + const auto it = std::find(controllers.begin(), controllers.end(), controller); + if (it != controllers.end()) + controllers.erase(it); + break; + } + + case SDL_CONTROLLERDEVICEREMAPPED: + // We are skipping it, + // but it's in the SDL_PeepEvents call + // to make sure it's removed from event queue + break; + } // switch (event.type) } if (!IsControllerAvailable()) return; + count = SDL_PeepEvents(nullptr, 0, + SDL_PEEKEVENT, SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERTOUCHPADUP); + + if (count) + SetCurrentInputType(Controller); + else if (currentInputType != Controller) + return; + + count = SDL_PeepEvents(events, MAX_CONTROLLER_EVENTS, + SDL_GETEVENT, SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERSENSORUPDATE); + const int controllerDeadZone = int(psControllerStickDeadZone * (SDL_JOYSTICK_AXIS_MAX / 100.f)); // raw const auto controllerPrev = controllerState; decltype(controllerAxisState) controllerAxisStatePrev; CopyMemory(controllerAxisStatePrev, controllerAxisState, sizeof(controllerAxisState)); - constexpr SDL_EventType MAX_EVENT = SDL_CONTROLLERSENSORUPDATE; - - count = SDL_PeepEvents(events, MAX_CONTROLLER_EVENTS, - SDL_GETEVENT, SDL_CONTROLLERAXISMOTION, MAX_EVENT); - for (int i = 0; i < count; ++i) { const SDL_Event& event = events[i]; @@ -347,7 +373,6 @@ void CInput::ControllerUpdate() else { controllerAxisState[event.caxis.axis] = event.caxis.value; - SetCurrentInputType(Controller); } break; } @@ -358,7 +383,6 @@ void CInput::ControllerUpdate() if (last_input_controller != event.cbutton.which) // don't write if don't really need to last_input_controller = event.cbutton.which; - SetCurrentInputType(Controller); controllerState[event.cbutton.button] = true; cbStack.back()->IR_OnControllerPress(ControllerButtonToKey[event.cbutton.button], 1.f, 0.f); @@ -370,25 +394,11 @@ void CInput::ControllerUpdate() if (last_input_controller != event.cbutton.which) // don't write if don't really need to last_input_controller = event.cbutton.which; - SetCurrentInputType(Controller); controllerState[event.cbutton.button] = false; cbStack.back()->IR_OnControllerRelease(ControllerButtonToKey[event.cbutton.button], 0.f, 0.f); break; - case SDL_CONTROLLERDEVICEADDED: - OpenController(event.cdevice.which); - break; - - case SDL_CONTROLLERDEVICEREMOVED: - { - const auto controller = SDL_GameControllerFromInstanceID(event.cdevice.which); - const auto it = std::find(controllers.begin(), controllers.end(), controller); - if (it != controllers.end()) - controllers.erase(it); - break; - } - case SDL_CONTROLLERSENSORUPDATE: { if (last_input_controller != event.csensor.which) // only use data from the recently used controller