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;