diff --git a/src/dusk/ui/controller_config.cpp b/src/dusk/ui/controller_config.cpp index af39782c02..393f2e2e4f 100644 --- a/src/dusk/ui/controller_config.cpp +++ b/src/dusk/ui/controller_config.cpp @@ -6,6 +6,7 @@ #include "select_button.hpp" #include +#include #include #include @@ -193,6 +194,14 @@ bool input_neutral(int port) { return PADGetNativeButtonPressed(port) == -1 && PADGetNativeAxisPulled(port).nativeAxis == -1; } +// A Keydown event with KI_ESCAPE may have been dispatched from the controller bindings, +// so instead poll the keyboard input directly for Escape-to-unbind +bool keyboard_escape_pressed() { + int keyCount = 0; + const bool* keys = SDL_GetKeyboardState(&keyCount); + return keys != nullptr && SDL_SCANCODE_ESCAPE < keyCount && keys[SDL_SCANCODE_ESCAPE]; +} + } // namespace ControllerConfigWindow::ControllerConfigWindow() { @@ -532,6 +541,11 @@ void ControllerConfigWindow::poll_pending_binding() { return; } + if (keyboard_escape_pressed()) { + unmap_pending_binding(); + return; + } + if (!mPendingBindingArmed) { if (pending_input_neutral()) { mPendingBindingArmed = true; @@ -544,12 +558,7 @@ void ControllerConfigWindow::poll_pending_binding() { if (nativeButton != -1) { const int completedPort = mPendingPort; mPendingButtonMapping->nativeButton = static_cast(nativeButton); - mPendingButtonMapping = nullptr; - mPendingPort = -1; - mPendingBindingArmed = false; - mSuppressNavigationUntilNeutral = true; - mSuppressNavigationPort = completedPort; - PADSerializeMappings(); + finish_pending_binding(completedPort); } return; } @@ -560,12 +569,7 @@ void ControllerConfigWindow::poll_pending_binding() { const int completedPort = mPendingPort; mPendingAxisMapping->nativeAxis = nativeAxis; mPendingAxisMapping->nativeButton = -1; - mPendingAxisMapping = nullptr; - mPendingPort = -1; - mPendingBindingArmed = false; - mSuppressNavigationUntilNeutral = true; - mSuppressNavigationPort = completedPort; - PADSerializeMappings(); + finish_pending_binding(completedPort); return; } @@ -574,16 +578,37 @@ void ControllerConfigWindow::poll_pending_binding() { const int completedPort = mPendingPort; mPendingAxisMapping->nativeAxis = {-1, AXIS_SIGN_POSITIVE}; mPendingAxisMapping->nativeButton = nativeButton; - mPendingAxisMapping = nullptr; - mPendingPort = -1; - mPendingBindingArmed = false; - mSuppressNavigationUntilNeutral = true; - mSuppressNavigationPort = completedPort; - PADSerializeMappings(); + finish_pending_binding(completedPort); } } } +void ControllerConfigWindow::finish_pending_binding(int completedPort) { + mPendingButtonMapping = nullptr; + mPendingAxisMapping = nullptr; + mPendingPort = -1; + mPendingBindingArmed = false; + mSuppressNavigationUntilNeutral = true; + mSuppressNavigationPort = completedPort; + PADSerializeMappings(); +} + +void ControllerConfigWindow::unmap_pending_binding() { + if (mPendingButtonMapping == nullptr && mPendingAxisMapping == nullptr) { + return; + } + + const int completedPort = mPendingPort; + if (mPendingButtonMapping != nullptr) { + mPendingButtonMapping->nativeButton = PAD_NATIVE_BUTTON_INVALID; + } + if (mPendingAxisMapping != nullptr) { + mPendingAxisMapping->nativeAxis = {-1, AXIS_SIGN_POSITIVE}; + mPendingAxisMapping->nativeButton = -1; + } + finish_pending_binding(completedPort); +} + bool ControllerConfigWindow::capture_active() const { return mPendingButtonMapping != nullptr || mPendingAxisMapping != nullptr; } diff --git a/src/dusk/ui/controller_config.hpp b/src/dusk/ui/controller_config.hpp index 67379dbf87..4bcf41ae8d 100644 --- a/src/dusk/ui/controller_config.hpp +++ b/src/dusk/ui/controller_config.hpp @@ -25,6 +25,8 @@ private: void render_page(class Pane& pane, int port, Page page); void refresh_controller_page(); void poll_pending_binding(); + void finish_pending_binding(int completedPort); + void unmap_pending_binding(); bool capture_active() const; bool pending_input_neutral() const; Rml::String pending_button_label() const;