Mercurial > repos > blastem
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 } |