# HG changeset patch # User Michael Pavone # Date 1533349941 25200 # Node ID 419a0a133b5c06fa136987b4c7c380e2f7d0dea3 # Parent 0174759e559f2cb79dbaf65066d3f0e38d979d1d Allow a gamepad mapping to apply to all controllers, controllers of a particular type (i.e.e 6-button PS4 controllers) or specific controllers (based on SDL2 GUID) in addition to the controller in a certain slot diff -r 0174759e559f -r 419a0a133b5c bindings.c --- a/bindings.c Thu Aug 02 19:06:57 2018 -0700 +++ b/bindings.c Fri Aug 03 19:32:21 2018 -0700 @@ -8,6 +8,7 @@ #include "genesis.h" #include "menu.h" #include "bindings.h" +#include "controller_info.h" #ifndef DISABLE_NUKLEAR #include "nuklear_ui/blastem_nuklear.h" #endif @@ -502,13 +503,13 @@ } } -int parse_binding_target(char * target, tern_node * padbuttons, tern_node *mousebuttons, uint8_t * subtype_a, uint8_t * subtype_b) +int parse_binding_target(int device_num, char * target, tern_node * padbuttons, tern_node *mousebuttons, uint8_t * subtype_a, uint8_t * subtype_b) { const int gpadslen = strlen("gamepads."); const int mouselen = strlen("mouse."); if (!strncmp(target, "gamepads.", gpadslen)) { - if (target[gpadslen] >= '1' && target[gpadslen] <= '8') { - int padnum = target[gpadslen] - '0'; + int padnum = target[gpadslen] == 'n' ? device_num + 1 : target[gpadslen] - '0'; + if (padnum >= 1 && padnum <= 8) { int button = tern_find_int(padbuttons, target + gpadslen + 1, 0); if (button) { *subtype_a = padnum; @@ -525,8 +526,8 @@ warning("Gamepad mapping string '%s' refers to an invalid gamepad number %c\n", target, target[gpadslen]); } } else if(!strncmp(target, "mouse.", mouselen)) { - if (target[mouselen] >= '1' && target[mouselen] <= '8') { - int mousenum = target[mouselen] - '0'; + int mousenum = target[mouselen] == 'n' ? device_num + 1 : target[mouselen] - '0'; + if (mousenum >= 1 && mousenum <= 8) { int button = tern_find_int(mousebuttons, target + mouselen + 1, 0); if (button) { *subtype_a = mousenum; @@ -615,7 +616,7 @@ } char * target = cur->straight.value.ptrval; uint8_t subtype_a = 0, subtype_b = 0; - int bindtype = parse_binding_target(target, padbuttons, mousebuttons, &subtype_a, &subtype_b); + int bindtype = parse_binding_target(0, target, padbuttons, mousebuttons, &subtype_a, &subtype_b); bind_key(keycode, bindtype, subtype_a, subtype_b); } process_keys(cur->left, special, padbuttons, mousebuttons, prefix); @@ -691,7 +692,7 @@ } buttonnum--; uint8_t subtype_a = 0, subtype_b = 0; - int bindtype = parse_binding_target(value.ptrval, state->padbuttons, state->mousebuttons, &subtype_a, &subtype_b); + int bindtype = parse_binding_target(state->mouseidx, value.ptrval, state->padbuttons, state->mousebuttons, &subtype_a, &subtype_b); mice[state->mouseidx].buttons[buttonnum].bind_type = bindtype; mice[state->mouseidx].buttons[buttonnum].subtype_a = subtype_a; mice[state->mouseidx].buttons[buttonnum].subtype_b = subtype_b; @@ -716,7 +717,7 @@ char *motion = tern_find_ptr(mousedef, "motion"); if (motion) { uint8_t subtype_a = 0, subtype_b = 0; - int bindtype = parse_binding_target(motion, padbuttons, mousebuttons, &subtype_a, &subtype_b); + int bindtype = parse_binding_target(mouseidx, motion, padbuttons, mousebuttons, &subtype_a, &subtype_b); mice[mouseidx].motion.bind_type = bindtype; mice[mouseidx].motion.subtype_a = subtype_a; mice[mouseidx].motion.subtype_b = subtype_b; @@ -745,7 +746,7 @@ return; } uint8_t subtype_a = 0, subtype_b = 0; - int bindtype = parse_binding_target(val.ptrval, state->padbuttons, state->mousebuttons, &subtype_a, &subtype_b); + int bindtype = parse_binding_target(hostpadnum, val.ptrval, state->padbuttons, state->mousebuttons, &subtype_a, &subtype_b); char *end; long hostbutton = strtol(key, &end, 10); if (*end) { @@ -781,7 +782,7 @@ return; } uint8_t subtype_a = 0, subtype_b = 0; - int bindtype = parse_binding_target(val.ptrval, state->padbuttons, state->mousebuttons, &subtype_a, &subtype_b); + int bindtype = parse_binding_target(hostpadnum, val.ptrval, state->padbuttons, state->mousebuttons, &subtype_a, &subtype_b); char *modifier = strchr(key, '.'); int positive = 1; if (modifier) { @@ -866,6 +867,20 @@ char numstr[11]; sprintf(numstr, "%d", joystick); tern_node * pad = tern_find_node(pads, numstr); + if (!pad) { + char *type_id = render_joystick_type_id(joystick); + pad = tern_find_node(pads, type_id); + free(type_id); + } + if (!pad) { + controller_info info = get_controller_info(joystick); + char *key = make_controller_type_key(&info); + pad = tern_find_node(pads, key); + free(key); + } + if (!pad) { + pad = tern_find_node(pads, "default"); + } if (pad) { tern_node * dpad_node = tern_find_node(pad, "dpads"); if (dpad_node) { @@ -881,7 +896,7 @@ char * target = tern_find_ptr(pad_dpad, dirs[dir]); if (target) { uint8_t subtype_a = 0, subtype_b = 0; - int bindtype = parse_binding_target(target, get_pad_buttons(), get_mouse_buttons(), &subtype_a, &subtype_b); + int bindtype = parse_binding_target(joystick, target, get_pad_buttons(), get_mouse_buttons(), &subtype_a, &subtype_b); bind_dpad(joystick, dpad, dirnums[dir], bindtype, subtype_a, subtype_b); } } diff -r 0174759e559f -r 419a0a133b5c controller_info.c --- a/controller_info.c Thu Aug 02 19:06:57 2018 -0700 +++ b/controller_info.c Fri Aug 03 19:32:21 2018 -0700 @@ -261,3 +261,37 @@ } } +char *make_controller_type_key(controller_info *info) +{ + const char *subtype; + if (info->subtype == SUBTYPE_UNKNOWN) { + switch(info->type) + { + case TYPE_XBOX: + subtype = subtype_names[SUBTYPE_X360]; + break; + case TYPE_PSX: + subtype = subtype_names[SUBTYPE_PS4]; + break; + case TYPE_NINTENDO: + subtype = subtype_names[SUBTYPE_SWITCH]; + break; + default: + subtype = "unknown"; + } + } else { + subtype = subtype_names[info->subtype]; + } + const char *variant = variant_names[info->variant]; + const char *parts[] = {subtype, "_", variant}; + char *ret = alloc_concat_m(3, parts); + for (char *cur = ret; *cur; cur++) + { + if (*cur == ' ') + { + *cur = '_'; + } + } + return ret; +} + diff -r 0174759e559f -r 419a0a133b5c controller_info.h --- a/controller_info.h Thu Aug 02 19:06:57 2018 -0700 +++ b/controller_info.h Fri Aug 03 19:32:21 2018 -0700 @@ -46,5 +46,6 @@ void save_controller_info(int joystick, controller_info *info); void save_controller_mapping(int joystick, char *mapping_string); void controller_add_mappings(void); +char *make_controller_type_key(controller_info *info); #endif //CONTROLLER_INFO_H_ \ No newline at end of file diff -r 0174759e559f -r 419a0a133b5c default.cfg --- a/default.cfg Thu Aug 02 19:06:57 2018 -0700 +++ b/default.cfg Fri Aug 03 19:32:21 2018 -0700 @@ -38,67 +38,36 @@ rctrl ui.toggle_keyboard_captured } pads { - 0 { + default { dpads { 0 { - up gamepads.1.up - down gamepads.1.down - left gamepads.1.left - right gamepads.1.right + up gamepads.n.up + down gamepads.n.down + left gamepads.n.left + right gamepads.n.right } } buttons { - a gamepads.1.a - b gamepads.1.b - rightshoulder gamepads.1.c - x gamepads.1.x - y gamepads.1.y - leftshoulder gamepads.1.z - back gamepads.1.mode - start gamepads.1.start + a gamepads.n.a + b gamepads.n.b + rightshoulder gamepads.n.c + x gamepads.n.x + y gamepads.n.y + leftshoulder gamepads.n.z + back gamepads.n.mode + start gamepads.n.start guide ui.exit leftstick ui.save_state } axes { - lefty.positive gamepads.1.down - lefty.negative gamepads.1.up - leftx.positive gamepads.1.right - leftx.negative gamepads.1.left + lefty.positive gamepads.n.down + lefty.negative gamepads.n.up + leftx.positive gamepads.n.right + leftx.negative gamepads.n.left lefttrigger ui.prev_speed righttrigger ui.next_speed } } - 1 { - dpads { - 0 { - up gamepads.2.up - down gamepads.2.down - left gamepads.2.left - right gamepads.2.right - } - } - buttons { - #this is exactly the same mapping as above, but with PS4 style names - cross gamepads.2.a - circle gamepads.2.b - r1 gamepads.2.c - square gamepads.2.x - triangle gamepads.2.y - l1 gamepads.2.z - share gamepads.2.mode - options gamepads.2.start - guide ui.exit - l3 ui.save_state - } - axes { - lefty.positive gamepads.2.down - lefty.negative gamepads.2.up - leftx.positive gamepads.2.right - leftx.negative gamepads.2.left - l2 ui.prev_speed - r2 ui.next_speed - } - } } mice { 0 { diff -r 0174759e559f -r 419a0a133b5c render.h --- a/render.h Thu Aug 02 19:06:57 2018 -0700 +++ b/render.h Fri Aug 03 19:32:21 2018 -0700 @@ -107,6 +107,7 @@ int32_t render_dpad_part(int32_t input); int32_t render_axis_part(int32_t input); uint8_t render_direction_part(int32_t input); +char* render_joystick_type_id(int index); void render_errorbox(char *title, char *message); void render_warnbox(char *title, char *message); void render_infobox(char *title, char *message); diff -r 0174759e559f -r 419a0a133b5c render_sdl.c --- a/render_sdl.c Thu Aug 02 19:06:57 2018 -0700 +++ b/render_sdl.c Fri Aug 03 19:32:21 2018 -0700 @@ -814,6 +814,17 @@ return joysticks[index]; } +char* render_joystick_type_id(int index) +{ + SDL_Joystick *stick = render_get_joystick(index); + if (!stick) { + return NULL; + } + char *guid_string = malloc(33); + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(stick), guid_string, 33); + return guid_string; +} + SDL_GameController *render_get_controller(int index) { if (index >= MAX_JOYSTICKS) {