comparison blastem.c @ 398:c26e48a93fa3

Make keybindings data driven so they can be populated from a config file later
author Mike Pavone <pavone@retrodev.com>
date Fri, 14 Jun 2013 00:25:04 -0700
parents 0b5f93358a93
children de2c085ce174
comparison
equal deleted inserted replaced
397:c20607e5b272 398:c26e48a93fa3
984 context->mem_pointers[2] = cart + 0x200000/2; 984 context->mem_pointers[2] = cart + 0x200000/2;
985 } 985 }
986 } 986 }
987 } 987 }
988 return context; 988 return context;
989 }
990
991 enum {
992 BIND_NONE,
993 BIND_GAMEPAD1,
994 BIND_GAMEPAD2,
995 BIND_UI
996 };
997
998 typedef enum {
999 UI_DEBUG_MODE_INC,
1000 UI_DEBUG_PAL_INC,
1001 UI_ENTER_DEBUGGER
1002 } ui_action;
1003
1004 typedef struct {
1005 uint8_t bind_type;
1006 uint8_t subtype_a;
1007 uint8_t subtype_b;
1008 uint8_t value;
1009 } keybinding;
1010
1011 keybinding * bindings[256];
1012
1013 void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value)
1014 {
1015 int bucket = keycode >> 8 & 0xFF;
1016 if (!bindings[bucket]) {
1017 bindings[bucket] = malloc(sizeof(keybinding) * 256);
1018 memset(bindings[bucket], 0, sizeof(keybinding) * 256);
1019 }
1020 int idx = keycode & 0xFF;
1021 bindings[bucket][idx].bind_type = bind_type;
1022 bindings[bucket][idx].subtype_a = subtype_a;
1023 bindings[bucket][idx].subtype_b = subtype_b;
1024 bindings[bucket][idx].value = value;
1025 }
1026
1027 #define GAMEPAD_BUTTON(PRI_SLOT, SEC_SLOT, VALUE) (PRI_SLOT << 12 | SEC_SLOT << 8 | VALUE)
1028
1029 #define DPAD_UP GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_TH1, 0x01)
1030 #define BUTTON_Z GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x01)
1031 #define DPAD_DOWN GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_TH1, 0x02)
1032 #define BUTTON_Y GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x02)
1033 #define DPAD_LEFT GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x04)
1034 #define BUTTON_X GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x04)
1035 #define DPAD_RIGHT GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x08)
1036 #define BUTTON_MODE GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x08)
1037 #define BUTTON_A GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x10)
1038 #define BUTTON_B GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x10)
1039 #define BUTTON_START GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x20)
1040 #define BUTTON_C GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x20)
1041
1042 void bind_gamepad(int keycode, int gamepadnum, int button)
1043 {
1044
1045 if (gamepadnum < 1 || gamepadnum > 2) {
1046 return;
1047 }
1048 uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1;
1049 bind_key(keycode, bind_type, button >> 12, button >> 8 & 0xF, button & 0xFF);
1050 }
1051
1052 void bind_ui(int keycode, ui_action action)
1053 {
1054 bind_key(keycode, BIND_UI, action, 0, 0);
1055 }
1056
1057 void handle_keydown(int keycode)
1058 {
1059 int bucket = keycode >> 8 & 0xFF;
1060 if (!bindings[bucket]) {
1061 return;
1062 }
1063 int idx = keycode & 0xFF;
1064 keybinding * binding = bindings[bucket] + idx;
1065 switch(binding->bind_type)
1066 {
1067 case BIND_GAMEPAD1:
1068 if (binding->subtype_a <= GAMEPAD_EXTRA) {
1069 gamepad_1.input[binding->subtype_a] |= binding->value;
1070 }
1071 if (binding->subtype_b <= GAMEPAD_EXTRA) {
1072 gamepad_1.input[binding->subtype_b] |= binding->value;
1073 }
1074 break;
1075 case BIND_GAMEPAD2:
1076 if (binding->subtype_a <= GAMEPAD_EXTRA) {
1077 gamepad_2.input[binding->subtype_a] |= binding->value;
1078 }
1079 if (binding->subtype_b <= GAMEPAD_EXTRA) {
1080 gamepad_2.input[binding->subtype_b] |= binding->value;
1081 }
1082 break;
1083 }
1084 }
1085
1086 uint8_t ui_debug_mode = 0;
1087 uint8_t ui_debug_pal = 0;
1088
1089 void handle_keyup(int keycode)
1090 {
1091 int bucket = keycode >> 8 & 0xFF;
1092 if (!bindings[bucket]) {
1093 return;
1094 }
1095 int idx = keycode & 0xFF;
1096 keybinding * binding = bindings[bucket] + idx;
1097 switch(binding->bind_type)
1098 {
1099 case BIND_GAMEPAD1:
1100 if (binding->subtype_a <= GAMEPAD_EXTRA) {
1101 gamepad_1.input[binding->subtype_a] &= ~binding->value;
1102 }
1103 if (binding->subtype_b <= GAMEPAD_EXTRA) {
1104 gamepad_1.input[binding->subtype_b] &= ~binding->value;
1105 }
1106 break;
1107 case BIND_GAMEPAD2:
1108 if (binding->subtype_a <= GAMEPAD_EXTRA) {
1109 gamepad_2.input[binding->subtype_a] &= ~binding->value;
1110 }
1111 if (binding->subtype_b <= GAMEPAD_EXTRA) {
1112 gamepad_2.input[binding->subtype_b] &= ~binding->value;
1113 }
1114 break;
1115 case BIND_UI:
1116 switch (binding->subtype_a)
1117 {
1118 case UI_DEBUG_MODE_INC:
1119 ui_debug_mode++;
1120 if (ui_debug_mode == 4) {
1121 ui_debug_mode = 0;
1122 }
1123 render_debug_mode(ui_debug_mode);
1124 break;
1125 case UI_DEBUG_PAL_INC:
1126 ui_debug_pal++;
1127 if (ui_debug_pal == 4) {
1128 ui_debug_pal = 0;
1129 }
1130 render_debug_pal(ui_debug_pal);
1131 break;
1132 case UI_ENTER_DEBUGGER:
1133 break_on_sync = 1;
1134 break;
1135 }
1136 break;
1137 }
1138 }
1139
1140 void set_keybindings()
1141 {
1142 bind_gamepad(RENDERKEY_UP, 1, DPAD_UP);
1143 bind_gamepad(RENDERKEY_DOWN, 1, DPAD_DOWN);
1144 bind_gamepad(RENDERKEY_LEFT, 1, DPAD_LEFT);
1145 bind_gamepad(RENDERKEY_RIGHT, 1, DPAD_RIGHT);
1146 bind_gamepad('a', 1, BUTTON_A);
1147 bind_gamepad('s', 1, BUTTON_B);
1148 bind_gamepad('d', 1, BUTTON_C);
1149 bind_gamepad('q', 1, BUTTON_X);
1150 bind_gamepad('w', 1, BUTTON_Y);
1151 bind_gamepad('e', 1, BUTTON_Z);
1152 bind_gamepad('\r', 1, BUTTON_START);
1153 bind_gamepad('f', 1, BUTTON_MODE);
1154 bind_ui('[', UI_DEBUG_MODE_INC);
1155 bind_ui(']', UI_DEBUG_PAL_INC);
1156 bind_ui('u', UI_ENTER_DEBUGGER);
989 } 1157 }
990 1158
991 typedef struct bp_def { 1159 typedef struct bp_def {
992 struct bp_def * next; 1160 struct bp_def * next;
993 uint32_t address; 1161 uint32_t address;
1998 } 2166 }
1999 } 2167 }
2000 if (i < 0) { 2168 if (i < 0) {
2001 strcpy(sram_filename + fname_size, ".sram"); 2169 strcpy(sram_filename + fname_size, ".sram");
2002 } 2170 }
2171 set_keybindings();
2003 2172
2004 init_run_cpu(&gen, debug, address_log); 2173 init_run_cpu(&gen, debug, address_log);
2005 return 0; 2174 return 0;
2006 } 2175 }