comparison bindings.c @ 1608:419a0a133b5c

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
author Michael Pavone <pavone@retrodev.com>
date Fri, 03 Aug 2018 19:32:21 -0700
parents ea687ca7d845
children 18a946ec74c8
comparison
equal deleted inserted replaced
1607:0174759e559f 1608:419a0a133b5c
6 #include "saves.h" 6 #include "saves.h"
7 #include "util.h" 7 #include "util.h"
8 #include "genesis.h" 8 #include "genesis.h"
9 #include "menu.h" 9 #include "menu.h"
10 #include "bindings.h" 10 #include "bindings.h"
11 #include "controller_info.h"
11 #ifndef DISABLE_NUKLEAR 12 #ifndef DISABLE_NUKLEAR
12 #include "nuklear_ui/blastem_nuklear.h" 13 #include "nuklear_ui/blastem_nuklear.h"
13 #endif 14 #endif
14 15
15 enum { 16 enum {
500 if (mouse_mode == MOUSE_RELATIVE || (mouse_mode == MOUSE_CAPTURE && mouse_captured)) { 501 if (mouse_mode == MOUSE_RELATIVE || (mouse_mode == MOUSE_CAPTURE && mouse_captured)) {
501 render_relative_mouse(1); 502 render_relative_mouse(1);
502 } 503 }
503 } 504 }
504 505
505 int parse_binding_target(char * target, tern_node * padbuttons, tern_node *mousebuttons, uint8_t * subtype_a, uint8_t * subtype_b) 506 int parse_binding_target(int device_num, char * target, tern_node * padbuttons, tern_node *mousebuttons, uint8_t * subtype_a, uint8_t * subtype_b)
506 { 507 {
507 const int gpadslen = strlen("gamepads."); 508 const int gpadslen = strlen("gamepads.");
508 const int mouselen = strlen("mouse."); 509 const int mouselen = strlen("mouse.");
509 if (!strncmp(target, "gamepads.", gpadslen)) { 510 if (!strncmp(target, "gamepads.", gpadslen)) {
510 if (target[gpadslen] >= '1' && target[gpadslen] <= '8') { 511 int padnum = target[gpadslen] == 'n' ? device_num + 1 : target[gpadslen] - '0';
511 int padnum = target[gpadslen] - '0'; 512 if (padnum >= 1 && padnum <= 8) {
512 int button = tern_find_int(padbuttons, target + gpadslen + 1, 0); 513 int button = tern_find_int(padbuttons, target + gpadslen + 1, 0);
513 if (button) { 514 if (button) {
514 *subtype_a = padnum; 515 *subtype_a = padnum;
515 *subtype_b = button; 516 *subtype_b = button;
516 return BIND_GAMEPAD; 517 return BIND_GAMEPAD;
523 } 524 }
524 } else { 525 } else {
525 warning("Gamepad mapping string '%s' refers to an invalid gamepad number %c\n", target, target[gpadslen]); 526 warning("Gamepad mapping string '%s' refers to an invalid gamepad number %c\n", target, target[gpadslen]);
526 } 527 }
527 } else if(!strncmp(target, "mouse.", mouselen)) { 528 } else if(!strncmp(target, "mouse.", mouselen)) {
528 if (target[mouselen] >= '1' && target[mouselen] <= '8') { 529 int mousenum = target[mouselen] == 'n' ? device_num + 1 : target[mouselen] - '0';
529 int mousenum = target[mouselen] - '0'; 530 if (mousenum >= 1 && mousenum <= 8) {
530 int button = tern_find_int(mousebuttons, target + mouselen + 1, 0); 531 int button = tern_find_int(mousebuttons, target + mouselen + 1, 0);
531 if (button) { 532 if (button) {
532 *subtype_a = mousenum; 533 *subtype_a = mousenum;
533 *subtype_b = button; 534 *subtype_b = button;
534 return BIND_MOUSE; 535 return BIND_MOUSE;
613 warning("%s is not recognized as a key identifier, truncating to %c\n", curstr, curstr[0]); 614 warning("%s is not recognized as a key identifier, truncating to %c\n", curstr, curstr[0]);
614 } 615 }
615 } 616 }
616 char * target = cur->straight.value.ptrval; 617 char * target = cur->straight.value.ptrval;
617 uint8_t subtype_a = 0, subtype_b = 0; 618 uint8_t subtype_a = 0, subtype_b = 0;
618 int bindtype = parse_binding_target(target, padbuttons, mousebuttons, &subtype_a, &subtype_b); 619 int bindtype = parse_binding_target(0, target, padbuttons, mousebuttons, &subtype_a, &subtype_b);
619 bind_key(keycode, bindtype, subtype_a, subtype_b); 620 bind_key(keycode, bindtype, subtype_a, subtype_b);
620 } 621 }
621 process_keys(cur->left, special, padbuttons, mousebuttons, prefix); 622 process_keys(cur->left, special, padbuttons, mousebuttons, prefix);
622 process_keys(cur->right, special, padbuttons, mousebuttons, prefix); 623 process_keys(cur->right, special, padbuttons, mousebuttons, prefix);
623 if (curstr && len) { 624 if (curstr && len) {
689 warning("Mouse button %s is not a scalar value!\n", buttonstr); 690 warning("Mouse button %s is not a scalar value!\n", buttonstr);
690 return; 691 return;
691 } 692 }
692 buttonnum--; 693 buttonnum--;
693 uint8_t subtype_a = 0, subtype_b = 0; 694 uint8_t subtype_a = 0, subtype_b = 0;
694 int bindtype = parse_binding_target(value.ptrval, state->padbuttons, state->mousebuttons, &subtype_a, &subtype_b); 695 int bindtype = parse_binding_target(state->mouseidx, value.ptrval, state->padbuttons, state->mousebuttons, &subtype_a, &subtype_b);
695 mice[state->mouseidx].buttons[buttonnum].bind_type = bindtype; 696 mice[state->mouseidx].buttons[buttonnum].bind_type = bindtype;
696 mice[state->mouseidx].buttons[buttonnum].subtype_a = subtype_a; 697 mice[state->mouseidx].buttons[buttonnum].subtype_a = subtype_a;
697 mice[state->mouseidx].buttons[buttonnum].subtype_b = subtype_b; 698 mice[state->mouseidx].buttons[buttonnum].subtype_b = subtype_b;
698 } 699 }
699 700
714 return; 715 return;
715 } 716 }
716 char *motion = tern_find_ptr(mousedef, "motion"); 717 char *motion = tern_find_ptr(mousedef, "motion");
717 if (motion) { 718 if (motion) {
718 uint8_t subtype_a = 0, subtype_b = 0; 719 uint8_t subtype_a = 0, subtype_b = 0;
719 int bindtype = parse_binding_target(motion, padbuttons, mousebuttons, &subtype_a, &subtype_b); 720 int bindtype = parse_binding_target(mouseidx, motion, padbuttons, mousebuttons, &subtype_a, &subtype_b);
720 mice[mouseidx].motion.bind_type = bindtype; 721 mice[mouseidx].motion.bind_type = bindtype;
721 mice[mouseidx].motion.subtype_a = subtype_a; 722 mice[mouseidx].motion.subtype_a = subtype_a;
722 mice[mouseidx].motion.subtype_b = subtype_b; 723 mice[mouseidx].motion.subtype_b = subtype_b;
723 } 724 }
724 tern_node *buttons = tern_find_path(mousedef, "buttons\0\0", TVAL_NODE).ptrval; 725 tern_node *buttons = tern_find_path(mousedef, "buttons\0\0", TVAL_NODE).ptrval;
743 if (valtype != TVAL_PTR) { 744 if (valtype != TVAL_PTR) {
744 warning("Pad button %s has a non-scalar value\n", key); 745 warning("Pad button %s has a non-scalar value\n", key);
745 return; 746 return;
746 } 747 }
747 uint8_t subtype_a = 0, subtype_b = 0; 748 uint8_t subtype_a = 0, subtype_b = 0;
748 int bindtype = parse_binding_target(val.ptrval, state->padbuttons, state->mousebuttons, &subtype_a, &subtype_b); 749 int bindtype = parse_binding_target(hostpadnum, val.ptrval, state->padbuttons, state->mousebuttons, &subtype_a, &subtype_b);
749 char *end; 750 char *end;
750 long hostbutton = strtol(key, &end, 10); 751 long hostbutton = strtol(key, &end, 10);
751 if (*end) { 752 if (*end) {
752 //key is not a valid base 10 integer 753 //key is not a valid base 10 integer
753 hostbutton = render_translate_input_name(hostpadnum, key, 0); 754 hostbutton = render_translate_input_name(hostpadnum, key, 0);
779 if (valtype != TVAL_PTR) { 780 if (valtype != TVAL_PTR) {
780 warning("Mapping for axis %s has a non-scalar value", key); 781 warning("Mapping for axis %s has a non-scalar value", key);
781 return; 782 return;
782 } 783 }
783 uint8_t subtype_a = 0, subtype_b = 0; 784 uint8_t subtype_a = 0, subtype_b = 0;
784 int bindtype = parse_binding_target(val.ptrval, state->padbuttons, state->mousebuttons, &subtype_a, &subtype_b); 785 int bindtype = parse_binding_target(hostpadnum, val.ptrval, state->padbuttons, state->mousebuttons, &subtype_a, &subtype_b);
785 char *modifier = strchr(key, '.'); 786 char *modifier = strchr(key, '.');
786 int positive = 1; 787 int positive = 1;
787 if (modifier) { 788 if (modifier) {
788 *modifier = 0; 789 *modifier = 0;
789 modifier++; 790 modifier++;
864 tern_node * pads = tern_find_path(config, "bindings\0pads\0", TVAL_NODE).ptrval; 865 tern_node * pads = tern_find_path(config, "bindings\0pads\0", TVAL_NODE).ptrval;
865 if (pads) { 866 if (pads) {
866 char numstr[11]; 867 char numstr[11];
867 sprintf(numstr, "%d", joystick); 868 sprintf(numstr, "%d", joystick);
868 tern_node * pad = tern_find_node(pads, numstr); 869 tern_node * pad = tern_find_node(pads, numstr);
870 if (!pad) {
871 char *type_id = render_joystick_type_id(joystick);
872 pad = tern_find_node(pads, type_id);
873 free(type_id);
874 }
875 if (!pad) {
876 controller_info info = get_controller_info(joystick);
877 char *key = make_controller_type_key(&info);
878 pad = tern_find_node(pads, key);
879 free(key);
880 }
881 if (!pad) {
882 pad = tern_find_node(pads, "default");
883 }
869 if (pad) { 884 if (pad) {
870 tern_node * dpad_node = tern_find_node(pad, "dpads"); 885 tern_node * dpad_node = tern_find_node(pad, "dpads");
871 if (dpad_node) { 886 if (dpad_node) {
872 for (int dpad = 0; dpad < 10; dpad++) 887 for (int dpad = 0; dpad < 10; dpad++)
873 { 888 {
879 int dirnums[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; 894 int dirnums[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT};
880 for (int dir = 0; dir < sizeof(dirs)/sizeof(dirs[0]); dir++) { 895 for (int dir = 0; dir < sizeof(dirs)/sizeof(dirs[0]); dir++) {
881 char * target = tern_find_ptr(pad_dpad, dirs[dir]); 896 char * target = tern_find_ptr(pad_dpad, dirs[dir]);
882 if (target) { 897 if (target) {
883 uint8_t subtype_a = 0, subtype_b = 0; 898 uint8_t subtype_a = 0, subtype_b = 0;
884 int bindtype = parse_binding_target(target, get_pad_buttons(), get_mouse_buttons(), &subtype_a, &subtype_b); 899 int bindtype = parse_binding_target(joystick, target, get_pad_buttons(), get_mouse_buttons(), &subtype_a, &subtype_b);
885 bind_dpad(joystick, dpad, dirnums[dir], bindtype, subtype_a, subtype_b); 900 bind_dpad(joystick, dpad, dirnums[dir], bindtype, subtype_a, subtype_b);
886 } 901 }
887 } 902 }
888 } 903 }
889 } 904 }