Mercurial > repos > blastem
comparison blastem.c @ 418:dbf4e1c86f3c
Implement basic joystick support
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 23 Jun 2013 22:27:12 -0700 |
parents | c3abc4ada43d |
children | d0cacb4ade0b |
comparison
equal
deleted
inserted
replaced
417:acdd6c5240fe | 418:dbf4e1c86f3c |
---|---|
864 uint8_t subtype_a; | 864 uint8_t subtype_a; |
865 uint8_t subtype_b; | 865 uint8_t subtype_b; |
866 uint8_t value; | 866 uint8_t value; |
867 } keybinding; | 867 } keybinding; |
868 | 868 |
869 typedef struct { | |
870 keybinding bindings[4]; | |
871 uint8_t state; | |
872 } joydpad; | |
873 | |
869 keybinding * bindings[256]; | 874 keybinding * bindings[256]; |
875 keybinding * joybindings[MAX_JOYSTICKS]; | |
876 joydpad * joydpads[MAX_JOYSTICKS]; | |
877 const uint8_t dpadbits[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; | |
870 | 878 |
871 void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) | 879 void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) |
872 { | 880 { |
873 int bucket = keycode >> 8 & 0xFF; | 881 int bucket = keycode >> 8 & 0xFF; |
874 if (!bindings[bucket]) { | 882 if (!bindings[bucket]) { |
878 int idx = keycode & 0xFF; | 886 int idx = keycode & 0xFF; |
879 bindings[bucket][idx].bind_type = bind_type; | 887 bindings[bucket][idx].bind_type = bind_type; |
880 bindings[bucket][idx].subtype_a = subtype_a; | 888 bindings[bucket][idx].subtype_a = subtype_a; |
881 bindings[bucket][idx].subtype_b = subtype_b; | 889 bindings[bucket][idx].subtype_b = subtype_b; |
882 bindings[bucket][idx].value = value; | 890 bindings[bucket][idx].value = value; |
891 } | |
892 | |
893 void bind_button(int joystick, int button, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) | |
894 { | |
895 if (joystick >= MAX_JOYSTICKS) { | |
896 return; | |
897 } | |
898 if (!joybindings[joystick]) { | |
899 int num = render_joystick_num_buttons(joystick); | |
900 if (!num) { | |
901 return; | |
902 } | |
903 joybindings[joystick] = malloc(sizeof(keybinding)*num); | |
904 memset(joybindings[joystick], 0, sizeof(keybinding)*num); | |
905 } | |
906 joybindings[joystick][button].bind_type = bind_type; | |
907 joybindings[joystick][button].subtype_a = subtype_a; | |
908 joybindings[joystick][button].subtype_b = subtype_b; | |
909 joybindings[joystick][button].value = value; | |
910 } | |
911 | |
912 void bind_dpad(int joystick, int dpad, int direction, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) | |
913 { | |
914 if (joystick >= MAX_JOYSTICKS) { | |
915 return; | |
916 } | |
917 if (!joydpads[joystick]) { | |
918 int num = render_joystick_num_hats(joystick); | |
919 if (!num) { | |
920 return; | |
921 } | |
922 joydpads[joystick] = malloc(sizeof(joydpad)*num); | |
923 memset(joydpads[joystick], 0, sizeof(joydpad)*num); | |
924 } | |
925 for (int i = 0; i < 4; i ++) { | |
926 if (dpadbits[i] & direction) { | |
927 joydpads[joystick][dpad].bindings[i].bind_type = bind_type; | |
928 joydpads[joystick][dpad].bindings[i].subtype_a = subtype_a; | |
929 joydpads[joystick][dpad].bindings[i].subtype_b = subtype_b; | |
930 joydpads[joystick][dpad].bindings[i].value = value; | |
931 break; | |
932 } | |
933 } | |
883 } | 934 } |
884 | 935 |
885 #define GAMEPAD_BUTTON(PRI_SLOT, SEC_SLOT, VALUE) (PRI_SLOT << 12 | SEC_SLOT << 8 | VALUE) | 936 #define GAMEPAD_BUTTON(PRI_SLOT, SEC_SLOT, VALUE) (PRI_SLOT << 12 | SEC_SLOT << 8 | VALUE) |
886 | 937 |
887 #define DPAD_UP GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_TH1, 0x01) | 938 #define DPAD_UP GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_TH1, 0x01) |
905 } | 956 } |
906 uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; | 957 uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; |
907 bind_key(keycode, bind_type, button >> 12, button >> 8 & 0xF, button & 0xFF); | 958 bind_key(keycode, bind_type, button >> 12, button >> 8 & 0xF, button & 0xFF); |
908 } | 959 } |
909 | 960 |
961 void bind_button_gamepad(int joystick, int joybutton, int gamepadnum, int padbutton) | |
962 { | |
963 if (gamepadnum < 1 || gamepadnum > 2) { | |
964 return; | |
965 } | |
966 uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; | |
967 bind_button(joystick, joybutton, bind_type, padbutton >> 12, padbutton >> 8 & 0xF, padbutton & 0xFF); | |
968 } | |
969 | |
970 void bind_dpad_gamepad(int joystick, int dpad, uint8_t direction, int gamepadnum, int button) | |
971 { | |
972 if (gamepadnum < 1 || gamepadnum > 2) { | |
973 return; | |
974 } | |
975 uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; | |
976 bind_dpad(joystick, dpad, direction, bind_type, button >> 12, button >> 8 & 0xF, button & 0xFF); | |
977 } | |
978 | |
910 void bind_ui(int keycode, ui_action action) | 979 void bind_ui(int keycode, ui_action action) |
911 { | 980 { |
912 bind_key(keycode, BIND_UI, action, 0, 0); | 981 bind_key(keycode, BIND_UI, action, 0, 0); |
913 } | 982 } |
914 | 983 |
915 void handle_keydown(int keycode) | 984 void handle_binding_down(keybinding * binding) |
916 { | 985 { |
917 int bucket = keycode >> 8 & 0xFF; | |
918 if (!bindings[bucket]) { | |
919 return; | |
920 } | |
921 int idx = keycode & 0xFF; | |
922 keybinding * binding = bindings[bucket] + idx; | |
923 switch(binding->bind_type) | 986 switch(binding->bind_type) |
924 { | 987 { |
925 case BIND_GAMEPAD1: | 988 case BIND_GAMEPAD1: |
926 if (binding->subtype_a <= GAMEPAD_EXTRA) { | 989 if (binding->subtype_a <= GAMEPAD_EXTRA) { |
927 gamepad_1.input[binding->subtype_a] |= binding->value; | 990 gamepad_1.input[binding->subtype_a] |= binding->value; |
939 } | 1002 } |
940 break; | 1003 break; |
941 } | 1004 } |
942 } | 1005 } |
943 | 1006 |
944 uint8_t ui_debug_mode = 0; | 1007 void handle_keydown(int keycode) |
945 uint8_t ui_debug_pal = 0; | |
946 | |
947 void handle_keyup(int keycode) | |
948 { | 1008 { |
949 int bucket = keycode >> 8 & 0xFF; | 1009 int bucket = keycode >> 8 & 0xFF; |
950 if (!bindings[bucket]) { | 1010 if (!bindings[bucket]) { |
951 return; | 1011 return; |
952 } | 1012 } |
953 int idx = keycode & 0xFF; | 1013 int idx = keycode & 0xFF; |
954 keybinding * binding = bindings[bucket] + idx; | 1014 keybinding * binding = bindings[bucket] + idx; |
1015 handle_binding_down(binding); | |
1016 } | |
1017 | |
1018 void handle_joydown(int joystick, int button) | |
1019 { | |
1020 if (!joybindings[joystick]) { | |
1021 return; | |
1022 } | |
1023 keybinding * binding = joybindings[joystick] + button; | |
1024 handle_binding_down(binding); | |
1025 } | |
1026 | |
1027 uint8_t ui_debug_mode = 0; | |
1028 uint8_t ui_debug_pal = 0; | |
1029 | |
1030 void handle_binding_up(keybinding * binding) | |
1031 { | |
955 switch(binding->bind_type) | 1032 switch(binding->bind_type) |
956 { | 1033 { |
957 case BIND_GAMEPAD1: | 1034 case BIND_GAMEPAD1: |
958 if (binding->subtype_a <= GAMEPAD_EXTRA) { | 1035 if (binding->subtype_a <= GAMEPAD_EXTRA) { |
959 gamepad_1.input[binding->subtype_a] &= ~binding->value; | 1036 gamepad_1.input[binding->subtype_a] &= ~binding->value; |
990 case UI_ENTER_DEBUGGER: | 1067 case UI_ENTER_DEBUGGER: |
991 break_on_sync = 1; | 1068 break_on_sync = 1; |
992 break; | 1069 break; |
993 } | 1070 } |
994 break; | 1071 break; |
1072 } | |
1073 } | |
1074 | |
1075 void handle_keyup(int keycode) | |
1076 { | |
1077 int bucket = keycode >> 8 & 0xFF; | |
1078 if (!bindings[bucket]) { | |
1079 return; | |
1080 } | |
1081 int idx = keycode & 0xFF; | |
1082 keybinding * binding = bindings[bucket] + idx; | |
1083 handle_binding_up(binding); | |
1084 } | |
1085 | |
1086 void handle_joyup(int joystick, int button) | |
1087 { | |
1088 if (!joybindings[joystick]) { | |
1089 return; | |
1090 } | |
1091 keybinding * binding = joybindings[joystick] + button; | |
1092 handle_binding_up(binding); | |
1093 } | |
1094 | |
1095 void handle_joy_dpad(int joystick, int dpadnum, uint8_t value) | |
1096 { | |
1097 if (!joydpads[joystick]) { | |
1098 return; | |
1099 } | |
1100 joydpad * dpad = joydpads[joystick] + dpadnum; | |
1101 uint8_t newdown = (value ^ dpad->state) & value; | |
1102 uint8_t newup = ((~value) ^ (~dpad->state)) & (~value); | |
1103 dpad->state = value; | |
1104 for (int i = 0; i < 4; i++) { | |
1105 if (newdown & dpadbits[i]) { | |
1106 handle_binding_down(dpad->bindings + i); | |
1107 } else if(newup & dpadbits[i]) { | |
1108 handle_binding_up(dpad->bindings + i); | |
1109 } | |
995 } | 1110 } |
996 } | 1111 } |
997 | 1112 |
998 void set_keybindings() | 1113 void set_keybindings() |
999 { | 1114 { |
1010 bind_gamepad('\r', 1, BUTTON_START); | 1125 bind_gamepad('\r', 1, BUTTON_START); |
1011 bind_gamepad('f', 1, BUTTON_MODE); | 1126 bind_gamepad('f', 1, BUTTON_MODE); |
1012 bind_ui('[', UI_DEBUG_MODE_INC); | 1127 bind_ui('[', UI_DEBUG_MODE_INC); |
1013 bind_ui(']', UI_DEBUG_PAL_INC); | 1128 bind_ui(']', UI_DEBUG_PAL_INC); |
1014 bind_ui('u', UI_ENTER_DEBUGGER); | 1129 bind_ui('u', UI_ENTER_DEBUGGER); |
1130 | |
1131 bind_dpad_gamepad(0, 0, RENDER_DPAD_UP, 2, DPAD_UP); | |
1132 bind_dpad_gamepad(0, 0, RENDER_DPAD_DOWN, 2, DPAD_DOWN); | |
1133 bind_dpad_gamepad(0, 0, RENDER_DPAD_LEFT, 2, DPAD_LEFT); | |
1134 bind_dpad_gamepad(0, 0, RENDER_DPAD_RIGHT, 2, DPAD_RIGHT); | |
1135 bind_button_gamepad(0, 0, 2, BUTTON_A); | |
1136 bind_button_gamepad(0, 1, 2, BUTTON_B); | |
1137 bind_button_gamepad(0, 2, 2, BUTTON_C); | |
1138 bind_button_gamepad(0, 3, 2, BUTTON_X); | |
1139 bind_button_gamepad(0, 4, 2, BUTTON_Y); | |
1140 bind_button_gamepad(0, 5, 2, BUTTON_Z); | |
1141 bind_button_gamepad(0, 6, 2, BUTTON_START); | |
1142 bind_button_gamepad(0, 7, 2, BUTTON_MODE); | |
1015 } | 1143 } |
1016 | 1144 |
1017 typedef struct bp_def { | 1145 typedef struct bp_def { |
1018 struct bp_def * next; | 1146 struct bp_def * next; |
1019 uint32_t address; | 1147 uint32_t address; |