From 61842d980c1f27313f1f7872920743e2005988fa Mon Sep 17 00:00:00 2001 From: thecozies <79979276+thecozies@users.noreply.github.com> Date: Thu, 31 Jul 2025 13:11:51 -0500 Subject: [PATCH] clear and reset input bindings implemented --- include/recomp_input.h | 3 ++ src/game/controls.cpp | 56 ++++++++++++++++++++++++++++++ src/ui/ui_config_page_controls.cpp | 48 +++++++++++++++++-------- src/ui/ui_config_page_controls.h | 11 +++++- 4 files changed, 103 insertions(+), 15 deletions(-) diff --git a/include/recomp_input.h b/include/recomp_input.h index ce72ef9..fafa0ae 100644 --- a/include/recomp_input.h +++ b/include/recomp_input.h @@ -172,6 +172,9 @@ namespace recomp { GameInput get_input_from_enum_name(const std::string_view name); InputField& get_input_binding(int profile_index, GameInput input, size_t binding_index); void set_input_binding(int profile_index, GameInput input, size_t binding_index, InputField value); + void clear_input_binding(int profile_index, GameInput input); + void reset_input_binding(int profile_index, InputDevice device, GameInput input); + void reset_profile_bindings(int profile_index, recomp::InputDevice device); int add_input_profile(const std::string &key, const std::string &name, InputDevice device, bool custom); int get_input_profile_by_key(const std::string &key); const std::string &get_input_profile_key(int profile_index); diff --git a/src/game/controls.cpp b/src/game/controls.cpp index 98d8924..d99bbbf 100644 --- a/src/game/controls.cpp +++ b/src/game/controls.cpp @@ -103,6 +103,62 @@ void recomp::set_input_binding(int profile_index, recomp::GameInput input, size_ } } +void recomp::clear_input_binding(int profile_index, GameInput input) { + for (size_t binding_index = 0; binding_index < recomp::bindings_per_input; binding_index++) { + recomp::set_input_binding(profile_index, input, binding_index, recomp::InputField{}); + } +} + +void recomp::reset_input_binding(int profile_index, InputDevice device, GameInput input) { + std::vector new_mappings = recomp::get_default_mapping_for_input( + device == recomp::InputDevice::Keyboard ? + recomp::default_n64_keyboard_mappings : + recomp::default_n64_controller_mappings, + input + ); + for (size_t binding_index = 0; binding_index < recomp::bindings_per_input; binding_index++) { + if (binding_index >= new_mappings.size()) { + recomp::set_input_binding(profile_index, input, binding_index, recomp::InputField{}); + } else { + recomp::set_input_binding(profile_index, input, binding_index, new_mappings[binding_index]); + } + } +} + +void recomp::reset_profile_bindings(int profile_index, recomp::InputDevice device) { + const recomp::DefaultN64Mappings &defaults = (device == recomp::InputDevice::Keyboard) + ? recomp::default_n64_keyboard_mappings + : recomp::default_n64_controller_mappings; + + // multiplayer keyboard profiles just get cleared completely because of overlapping key bindings. + bool is_multiplayer_kb = false; + if (device == recomp::InputDevice::Keyboard) { + for (size_t i = 0; i < recompinput::get_num_players(); i++) { + if (recomp::get_mp_keyboard_profile_index(i) == profile_index) { + is_multiplayer_kb = true; + break; + } + } + } + + for (size_t i = 0; i < recomp::get_num_inputs(); i++) { + recomp::GameInput input = static_cast(i); + if (is_multiplayer_kb) { + recomp::clear_input_binding(profile_index, input); + continue; + } + + auto &new_mappings = recomp::get_default_mapping_for_input(defaults, input); + for (size_t binding_index = 0; binding_index < recomp::bindings_per_input; binding_index++) { + if (binding_index >= new_mappings.size()) { + recomp::set_input_binding(profile_index, input, binding_index, recomp::InputField{}); + } else { + recomp::set_input_binding(profile_index, input, binding_index, new_mappings[binding_index]); + } + } + } +} + int recomp::add_input_profile(const std::string &key, const std::string &name, InputDevice device, bool custom) { auto it = input_profile_key_index_map.find(key); if (it != input_profile_key_index_map.end()) { diff --git a/src/ui/ui_config_page_controls.cpp b/src/ui/ui_config_page_controls.cpp index 9b0c239..9dc05a6 100644 --- a/src/ui/ui_config_page_controls.cpp +++ b/src/ui/ui_config_page_controls.cpp @@ -15,7 +15,8 @@ GameInputRow::GameInputRow( Element *parent, GameInputContext *input_ctx, std::function on_hover_callback, - on_bind_click_callback on_bind_click + on_bind_click_callback on_bind_click, + on_clear_or_reset_callback on_clear_or_reset ) : Element(parent, Events(EventType::Hover), "div", false) { this->input_id = input_ctx->input_id; this->on_hover_callback = on_hover_callback; @@ -74,13 +75,13 @@ GameInputRow::GameInputRow( if (input_ctx->clearable) { auto clear_button = context.create_element(this, "icons/Trash.svg", ButtonStyle::Danger, IconButtonSize::Large); - clear_button->add_pressed_callback([this]() { - // TODO: Add clear callback + clear_button->add_pressed_callback([this, on_clear_or_reset]() { + on_clear_or_reset(this->input_id, false); }); } else { auto reset_button = context.create_element(this, "icons/Reset.svg", ButtonStyle::Warning, IconButtonSize::Large); - reset_button->add_pressed_callback([this]() { - // TODO: Add reset callback + reset_button->add_pressed_callback([this, on_clear_or_reset]() { + on_clear_or_reset(this->input_id, true); }); } @@ -329,8 +330,11 @@ void ConfigPageControls::render_footer() { { auto footer_right = footer->get_right(); footer_right->clear_children(); - context.create_element