diff --git a/assets/config_menu/controls.rml b/assets/config_menu/controls.rml
index 15d6cde..4621093 100644
--- a/assets/config_menu/controls.rml
+++ b/assets/config_menu/controls.rml
@@ -24,6 +24,7 @@
diff --git a/include/recomp_config.h b/include/recomp_config.h
index 1dd9a16..98abbc9 100644
--- a/include/recomp_config.h
+++ b/include/recomp_config.h
@@ -13,6 +13,8 @@ namespace recomp {
void save_config();
void reset_input_bindings();
+ void reset_cont_input_bindings();
+ void reset_kb_input_bindings();
std::filesystem::path get_app_folder_path();
diff --git a/src/game/config.cpp b/src/game/config.cpp
index d030b8a..5dcabed 100644
--- a/src/game/config.cpp
+++ b/src/game/config.cpp
@@ -151,26 +151,37 @@ void assign_mapping(recomp::InputDevice device, recomp::GameInput input, const s
}
};
-void assign_all_mappings(recomp::InputDevice device, const recomp::DefaultN64Mappings& values) {
- assign_mapping(device, recomp::GameInput::A, values.a);
- assign_mapping(device, recomp::GameInput::B, values.b);
- assign_mapping(device, recomp::GameInput::Z, values.z);
- assign_mapping(device, recomp::GameInput::START, values.start);
- assign_mapping(device, recomp::GameInput::DPAD_UP, values.dpad_up);
- assign_mapping(device, recomp::GameInput::DPAD_DOWN, values.dpad_down);
- assign_mapping(device, recomp::GameInput::DPAD_LEFT, values.dpad_left);
- assign_mapping(device, recomp::GameInput::DPAD_RIGHT, values.dpad_right);
- assign_mapping(device, recomp::GameInput::L, values.l);
- assign_mapping(device, recomp::GameInput::R, values.r);
- assign_mapping(device, recomp::GameInput::C_UP, values.c_up);
- assign_mapping(device, recomp::GameInput::C_DOWN, values.c_down);
- assign_mapping(device, recomp::GameInput::C_LEFT, values.c_left);
- assign_mapping(device, recomp::GameInput::C_RIGHT, values.c_right);
+// same as assign_mapping, except will clear unassigned bindings if not in value
+void assign_mapping_complete(recomp::InputDevice device, recomp::GameInput input, const std::vector& value) {
+ for (size_t binding_index = 0; binding_index < recomp::bindings_per_input; binding_index++) {
+ if (binding_index >= value.size()) {
+ recomp::set_input_binding(input, binding_index, device, recomp::InputField{});
+ } else {
+ recomp::set_input_binding(input, binding_index, device, value[binding_index]);
+ }
+ }
+};
- assign_mapping(device, recomp::GameInput::X_AXIS_NEG, values.analog_left);
- assign_mapping(device, recomp::GameInput::X_AXIS_POS, values.analog_right);
- assign_mapping(device, recomp::GameInput::Y_AXIS_NEG, values.analog_down);
- assign_mapping(device, recomp::GameInput::Y_AXIS_POS, values.analog_up);
+void assign_all_mappings(recomp::InputDevice device, const recomp::DefaultN64Mappings& values) {
+ assign_mapping_complete(device, recomp::GameInput::A, values.a);
+ assign_mapping_complete(device, recomp::GameInput::B, values.b);
+ assign_mapping_complete(device, recomp::GameInput::Z, values.z);
+ assign_mapping_complete(device, recomp::GameInput::START, values.start);
+ assign_mapping_complete(device, recomp::GameInput::DPAD_UP, values.dpad_up);
+ assign_mapping_complete(device, recomp::GameInput::DPAD_DOWN, values.dpad_down);
+ assign_mapping_complete(device, recomp::GameInput::DPAD_LEFT, values.dpad_left);
+ assign_mapping_complete(device, recomp::GameInput::DPAD_RIGHT, values.dpad_right);
+ assign_mapping_complete(device, recomp::GameInput::L, values.l);
+ assign_mapping_complete(device, recomp::GameInput::R, values.r);
+ assign_mapping_complete(device, recomp::GameInput::C_UP, values.c_up);
+ assign_mapping_complete(device, recomp::GameInput::C_DOWN, values.c_down);
+ assign_mapping_complete(device, recomp::GameInput::C_LEFT, values.c_left);
+ assign_mapping_complete(device, recomp::GameInput::C_RIGHT, values.c_right);
+
+ assign_mapping_complete(device, recomp::GameInput::X_AXIS_NEG, values.analog_left);
+ assign_mapping_complete(device, recomp::GameInput::X_AXIS_POS, values.analog_right);
+ assign_mapping_complete(device, recomp::GameInput::Y_AXIS_NEG, values.analog_down);
+ assign_mapping_complete(device, recomp::GameInput::Y_AXIS_POS, values.analog_up);
};
void recomp::reset_input_bindings() {
@@ -178,6 +189,14 @@ void recomp::reset_input_bindings() {
assign_all_mappings(recomp::InputDevice::Controller, recomp::default_n64_controller_mappings);
}
+void recomp::reset_cont_input_bindings() {
+ assign_all_mappings(recomp::InputDevice::Controller, recomp::default_n64_controller_mappings);
+}
+
+void recomp::reset_kb_input_bindings() {
+ assign_all_mappings(recomp::InputDevice::Keyboard, recomp::default_n64_keyboard_mappings);
+}
+
void reset_graphics_options() {
ultramodern::GraphicsConfig new_config{};
new_config.res_option = res_default;
diff --git a/src/ui/ui_config.cpp b/src/ui/ui_config.cpp
index 7466e57..116433a 100644
--- a/src/ui/ui_config.cpp
+++ b/src/ui/ui_config.cpp
@@ -527,6 +527,16 @@ public:
model_handle.DirtyVariable("active_binding_slot");
});
+ constructor.BindEventCallback("reset_input_bindings_to_defaults",
+ [](Rml::DataModelHandle model_handle, Rml::Event& event, const Rml::VariantList& inputs) {
+ if (cur_device == recomp::InputDevice::Controller) {
+ recomp::reset_cont_input_bindings();
+ } else {
+ recomp::reset_kb_input_bindings();
+ }
+ model_handle.DirtyAllVariables();
+ });
+
constructor.BindEventCallback("clear_input_bindings",
[](Rml::DataModelHandle model_handle, Rml::Event& event, const Rml::VariantList& inputs) {
recomp::GameInput input = static_cast(inputs.at(0).Get());