clear and reset input bindings implemented

This commit is contained in:
thecozies
2025-07-31 13:11:51 -05:00
parent 6f53279cf0
commit 61842d980c
4 changed files with 103 additions and 15 deletions
+3
View File
@@ -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);
+56
View File
@@ -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<recomp::InputField> 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<recomp::GameInput>(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()) {
+34 -14
View File
@@ -15,7 +15,8 @@ GameInputRow::GameInputRow(
Element *parent,
GameInputContext *input_ctx,
std::function<void()> 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<IconButton>(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<IconButton>(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<Button>(footer_right, "Reset to defaults", ButtonStyle::Warning);
// TODO: Add reset to defaults callback
auto reset_to_defaults_button = context.create_element<Button>(footer_right, "Reset to defaults", ButtonStyle::Warning);
reset_to_defaults_button->add_pressed_callback([this]() {
recomp::reset_profile_bindings(this->selected_profile_index, this->get_player_input_device());
this->update_control_mappings();
});
}
}
@@ -361,6 +365,9 @@ void ConfigPageControls::render_control_mappings() {
},
[this](recompinput::GameInput game_input, int input_index) {
this->on_bind_click(game_input, input_index);
},
[this](recompinput::GameInput game_input, bool reset) {
this->on_clear_or_reset_game_input(game_input, reset);
}
);
game_input_rows.push_back(row);
@@ -399,20 +406,33 @@ void ConfigPageControls::update_control_mappings() {
ConfigPageControls::~ConfigPageControls() {
}
void ConfigPageControls::on_bind_click(recompinput::GameInput game_input, int input_index) {
recompinput::InputDevice device;
recompinput::InputDevice ConfigPageControls::get_player_input_device() {
if (multiplayer_enabled) {
device = recompinput::get_assigned_player_input_device(this->selected_player);
} else {
device = single_player_show_keyboard_mappings
? recomp::InputDevice::Keyboard
: recomp::InputDevice::Controller;
return recompinput::get_assigned_player_input_device(this->selected_player);
}
return single_player_show_keyboard_mappings
? recomp::InputDevice::Keyboard
: recomp::InputDevice::Controller;
}
void ConfigPageControls::on_bind_click(recompinput::GameInput game_input, int input_index) {
recompinput::InputDevice device = get_player_input_device();
recompinput::start_scanning_for_binding(this->selected_player, game_input, input_index, device);
awaiting_binding = true;
}
void ConfigPageControls::on_clear_or_reset_game_input(recompinput::GameInput game_input, bool reset) {
if (!reset) {
recomp::clear_input_binding(selected_profile_index, game_input);
} else {
recompinput::InputDevice device = get_player_input_device();
recomp::reset_input_binding(selected_profile_index, device, game_input);
}
update_control_mappings();
}
void ConfigPageControls::set_selected_player(int player) {
selected_player = player;
}
+10 -1
View File
@@ -32,6 +32,8 @@ using on_bind_click_callback = std::function<void(recompinput::GameInput, int)>;
// Player index, GameInput to be bound to, and the index of the binding that is being assigned
using on_player_bind_callback = std::function<void(int, recompinput::GameInput, int)>;
using on_clear_or_reset_callback = std::function<void(recompinput::GameInput, bool)>;
// One single row of a game input mapping
class GameInputRow : public Element {
protected:
@@ -53,7 +55,8 @@ public:
Element *parent,
GameInputContext *input_ctx,
std::function<void()> 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
);
virtual ~GameInputRow();
void update_bindings(BindingList &new_bindings);
@@ -93,6 +96,10 @@ protected:
private:
void on_option_hover(uint8_t index);
void on_bind_click(recompinput::GameInput game_input, int input_index);
void on_clear_or_reset_game_input(
recompinput::GameInput game_input,
bool reset = false
);
void on_select_player_profile(int player_index, int profile_index);
void on_edit_player_profile(int player_index);
@@ -103,6 +110,8 @@ private:
void render_body_players();
void render_body_mappings();
void render_footer();
recompinput::InputDevice get_player_input_device();
public:
ConfigPageControls(
Element *parent,