feat: allow configuring menu toggle button (#181)

* feat: allow configuring menu toggle button

* fix: hide toggle menu binding config for keyboard

* fix: assign defaults for inputs that don't exist in `controls.json`
This commit is contained in:
briaguya 2024-05-26 09:58:51 -04:00 committed by GitHub
parent 3c34fa63c1
commit d4898f2316
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 70 additions and 6 deletions

View File

@ -41,6 +41,7 @@
data-for="input_bindings, i : inputs.array"
data-event-mouseover="set_input_row_focus(i)"
data-class-control-option--active="get_input_enum_name(i)==cur_input_row"
data-if="!input_device_is_keyboard || get_input_enum_name(i) != 'TOGGLE_MENU'"
>
<label
class="control-option__label"

View File

@ -36,9 +36,13 @@ namespace recomp {
DEFINE_INPUT(X_AXIS_NEG, 0, "Left") \
DEFINE_INPUT(X_AXIS_POS, 0, "Right") \
#define DEFINE_RECOMP_UI_INPUTS() \
DEFINE_INPUT(TOGGLE_MENU, 0, "Toggle Menu")
#define DEFINE_ALL_INPUTS() \
DEFINE_N64_BUTTON_INPUTS() \
DEFINE_N64_AXIS_INPUTS()
DEFINE_N64_AXIS_INPUTS() \
DEFINE_RECOMP_UI_INPUTS()
// Enum containing every recomp input.
#define DEFINE_INPUT(name, value, readable) name,
@ -104,8 +108,35 @@ namespace recomp {
std::vector<InputField> analog_right;
std::vector<InputField> analog_up;
std::vector<InputField> analog_down;
std::vector<InputField> toggle_menu;
};
constexpr const std::vector<InputField>& get_default_mapping_for_input(const DefaultN64Mappings& defaults, const GameInput input) {
switch (input) {
case GameInput::A: return defaults.a;
case GameInput::B: return defaults.b;
case GameInput::L: return defaults.l;
case GameInput::R: return defaults.r;
case GameInput::Z: return defaults.z;
case GameInput::START: return defaults.start;
case GameInput::C_LEFT: return defaults.c_left;
case GameInput::C_RIGHT: return defaults.c_right;
case GameInput::C_UP: return defaults.c_up;
case GameInput::C_DOWN: return defaults.c_down;
case GameInput::DPAD_LEFT: return defaults.dpad_left;
case GameInput::DPAD_RIGHT: return defaults.dpad_right;
case GameInput::DPAD_UP: return defaults.dpad_up;
case GameInput::DPAD_DOWN: return defaults.dpad_down;
case GameInput::X_AXIS_NEG: return defaults.analog_left;
case GameInput::X_AXIS_POS: return defaults.analog_right;
case GameInput::Y_AXIS_POS: return defaults.analog_up;
case GameInput::Y_AXIS_NEG: return defaults.analog_down;
case GameInput::TOGGLE_MENU: return defaults.toggle_menu;
default: return std::vector<InputField>();
}
}
extern const DefaultN64Mappings default_n64_keyboard_mappings;
extern const DefaultN64Mappings default_n64_controller_mappings;

View File

@ -232,6 +232,7 @@ void assign_all_mappings(recomp::InputDevice device, const recomp::DefaultN64Map
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);
assign_mapping_complete(device, recomp::GameInput::TOGGLE_MENU, values.toggle_menu);
};
void recomp::reset_input_bindings() {
@ -323,6 +324,16 @@ bool load_input_device_from_json(const nlohmann::json& config_json, recomp::Inpu
// Check if the json object for the given input exists and that it's an array.
auto find_input_it = mappings_json.find(input_name);
if (find_input_it == mappings_json.end() || !find_input_it->is_array()) {
assign_mapping(
device,
cur_input,
recomp::get_default_mapping_for_input(
device == recomp::InputDevice::Keyboard ?
recomp::default_n64_keyboard_mappings :
recomp::default_n64_controller_mappings,
cur_input
)
);
continue;
}
const nlohmann::json& input_json = *find_input_it;

View File

@ -172,7 +172,11 @@ bool sdl_event_filter(void* userdata, SDL_Event* event) {
break;
case SDL_EventType::SDL_CONTROLLERBUTTONDOWN:
if (scanning_device != recomp::InputDevice::COUNT) {
if (event->cbutton.button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK) {
auto menuToggleBinding0 = recomp::get_input_binding(recomp::GameInput::TOGGLE_MENU, 0, recomp::InputDevice::Controller);
auto menuToggleBinding1 = recomp::get_input_binding(recomp::GameInput::TOGGLE_MENU, 1, recomp::InputDevice::Controller);
// note - magic number: 0 is InputType::None
if ((menuToggleBinding0.input_type != 0 && event->cbutton.button == menuToggleBinding0.input_id) ||
(menuToggleBinding1.input_type != 0 && event->cbutton.button == menuToggleBinding1.input_id)) {
recomp::cancel_scanning_input();
} else if (scanning_device == recomp::InputDevice::Controller) {
SDL_ControllerButtonEvent* button_event = &event->cbutton;
@ -325,6 +329,9 @@ const recomp::DefaultN64Mappings recomp::default_n64_keyboard_mappings = {
.analog_down = {
{.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_S}
},
.toggle_menu = {
{.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_ESCAPE}
},
};
const recomp::DefaultN64Mappings recomp::default_n64_controller_mappings = {
@ -386,6 +393,9 @@ const recomp::DefaultN64Mappings recomp::default_n64_controller_mappings = {
.analog_down = {
{.input_type = (uint32_t)InputType::ControllerAnalog, .input_id = SDL_CONTROLLER_AXIS_LEFTY + 1},
},
.toggle_menu = {
{.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_BACK},
},
};
void recomp::poll_inputs() {

View File

@ -1193,10 +1193,17 @@ int cont_button_to_key(SDL_ControllerButtonEvent& button) {
case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X:
case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START:
return SDLK_f;
// Allows closing the menu
case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK:
return SDLK_ESCAPE;
}
// Allows closing the menu
auto menuToggleBinding0 = recomp::get_input_binding(recomp::GameInput::TOGGLE_MENU, 0, recomp::InputDevice::Controller);
auto menuToggleBinding1 = recomp::get_input_binding(recomp::GameInput::TOGGLE_MENU, 1, recomp::InputDevice::Controller);
// note - magic number: 0 is InputType::None
if ((menuToggleBinding0.input_type != 0 && button.button == menuToggleBinding0.input_id) ||
(menuToggleBinding1.input_type != 0 && button.button == menuToggleBinding1.input_id)) {
return SDLK_ESCAPE;
}
return 0;
}
@ -1383,7 +1390,11 @@ void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderFramebuffer* s
}
break;
case SDL_EventType::SDL_CONTROLLERBUTTONDOWN:
if (cur_event.cbutton.button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK) {
auto menuToggleBinding0 = recomp::get_input_binding(recomp::GameInput::TOGGLE_MENU, 0, recomp::InputDevice::Controller);
auto menuToggleBinding1 = recomp::get_input_binding(recomp::GameInput::TOGGLE_MENU, 1, recomp::InputDevice::Controller);
// note - magic number: 0 is InputType::None
if ((menuToggleBinding0.input_type != 0 && cur_event.cbutton.button == menuToggleBinding0.input_id) ||
(menuToggleBinding1.input_type != 0 && cur_event.cbutton.button == menuToggleBinding1.input_id)) {
open_config = true;
}
break;