Mercurial > repos > blastem
comparison controller_info.c @ 2053:3414a4423de1 segacd
Merge from default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 15 Jan 2022 13:15:21 -0800 |
parents | 193b804c9845 |
children | a8af8d898a7c |
comparison
equal
deleted
inserted
replaced
1692:5dacaef602a7 | 2053:3414a4423de1 |
---|---|
1 #include <string.h> | 1 #include <string.h> |
2 #include <stdlib.h> | |
3 #ifndef USE_FBDEV | |
2 #include "render_sdl.h" | 4 #include "render_sdl.h" |
5 #endif | |
3 #include "controller_info.h" | 6 #include "controller_info.h" |
4 #include "config.h" | 7 #include "config.h" |
5 #include "util.h" | 8 #include "util.h" |
9 #include "blastem.h" | |
10 #include "bindings.h" | |
6 | 11 |
7 typedef struct { | 12 typedef struct { |
8 char const *name; | 13 char const *name; |
9 controller_info info; | 14 controller_info info; |
10 } heuristic; | 15 } heuristic; |
55 "Saturn" | 60 "Saturn" |
56 }; | 61 }; |
57 static const char *variant_names[] = { | 62 static const char *variant_names[] = { |
58 "normal", | 63 "normal", |
59 "6b bumpers", | 64 "6b bumpers", |
60 "6b right" | 65 "6b right", |
66 "3button", | |
67 "6button", | |
68 "8button" | |
61 }; | 69 }; |
62 | 70 |
63 static void load_ctype_config(void) | 71 static void load_ctype_config(void) |
64 { | 72 { |
65 if (!loaded) { | 73 if (!loaded) { |
66 info_config = load_overrideable_config("controller_types.cfg", "controller_types.cfg"); | 74 info_config = load_overrideable_config("controller_types.cfg", "controller_types.cfg", NULL); |
67 loaded = 1; | 75 loaded = 1; |
68 } | 76 } |
69 } | 77 } |
70 | 78 |
71 controller_info get_controller_info(int joystick) | 79 controller_info get_controller_info(int joystick) |
72 { | 80 { |
81 #ifndef USE_FBDEV | |
73 load_ctype_config(); | 82 load_ctype_config(); |
74 char guid_string[33]; | 83 char guid_string[33]; |
75 SDL_Joystick *stick = render_get_joystick(joystick); | 84 SDL_Joystick *stick = render_get_joystick(joystick); |
76 SDL_GameController *control = render_get_controller(joystick); | 85 SDL_GameController *control = render_get_controller(joystick); |
77 SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(stick), guid_string, sizeof(guid_string)); | 86 SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(stick), guid_string, sizeof(guid_string)); |
146 controller_info res = heuristics[i].info; | 155 controller_info res = heuristics[i].info; |
147 res.name = name; | 156 res.name = name; |
148 return res; | 157 return res; |
149 } | 158 } |
150 } | 159 } |
160 #else | |
161 const char *name = "Unknown"; | |
162 #endif | |
151 //default to a 360 | 163 //default to a 360 |
152 return (controller_info){ | 164 return (controller_info){ |
153 .type = TYPE_GENERIC_MAPPING, | 165 .type = TYPE_GENERIC_MAPPING, |
154 .subtype = SUBTYPE_UNKNOWN, | 166 .subtype = SUBTYPE_UNKNOWN, |
155 .variant = VARIANT_NORMAL, | 167 .variant = VARIANT_NORMAL, |
157 }; | 169 }; |
158 } | 170 } |
159 | 171 |
160 static void mappings_iter(char *key, tern_val val, uint8_t valtype, void *data) | 172 static void mappings_iter(char *key, tern_val val, uint8_t valtype, void *data) |
161 { | 173 { |
174 #ifndef USE_FBDEV | |
162 if (valtype != TVAL_NODE) { | 175 if (valtype != TVAL_NODE) { |
163 return; | 176 return; |
164 } | 177 } |
165 char *mapping = tern_find_ptr(val.ptrval, "mapping"); | 178 char *mapping = tern_find_ptr(val.ptrval, "mapping"); |
166 if (mapping) { | 179 if (mapping) { |
167 const char *parts[] = {key, ",", mapping}; | 180 const char *parts[] = {key, ",", mapping}; |
168 char * full = alloc_concat_m(3, parts); | 181 char * full = alloc_concat_m(3, parts); |
169 SDL_GameControllerAddMapping(full); | 182 SDL_GameControllerAddMapping(full); |
170 free(full); | 183 free(full); |
171 } | 184 } |
185 #endif | |
172 } | 186 } |
173 | 187 |
174 void controller_add_mappings(void) | 188 void controller_add_mappings(void) |
175 { | 189 { |
176 load_ctype_config(); | 190 load_ctype_config(); |
179 } | 193 } |
180 } | 194 } |
181 | 195 |
182 void save_controller_info(int joystick, controller_info *info) | 196 void save_controller_info(int joystick, controller_info *info) |
183 { | 197 { |
198 #ifndef USE_FBDEV | |
184 char guid_string[33]; | 199 char guid_string[33]; |
185 SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(render_get_joystick(joystick)), guid_string, sizeof(guid_string)); | 200 SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(render_get_joystick(joystick)), guid_string, sizeof(guid_string)); |
186 tern_node *existing = tern_find_node(info_config, guid_string); | 201 tern_node *existing = tern_find_node(info_config, guid_string); |
187 existing = tern_insert_ptr(existing, "subtype", (void *)subtype_names[info->subtype]); | 202 existing = tern_insert_ptr(existing, "subtype", strdup(subtype_names[info->subtype])); |
188 existing = tern_insert_ptr(existing, "variant", (void *)variant_names[info->variant]); | 203 existing = tern_insert_ptr(existing, "variant", strdup(variant_names[info->variant])); |
189 info_config = tern_insert_node(info_config, guid_string, existing); | 204 info_config = tern_insert_node(info_config, guid_string, existing); |
190 persist_config_at(info_config, "controller_types.cfg"); | 205 persist_config_at(config, info_config, "controller_types.cfg"); |
191 | 206 handle_joy_added(joystick); |
207 #endif | |
192 } | 208 } |
193 | 209 |
194 void save_controller_mapping(int joystick, char *mapping_string) | 210 void save_controller_mapping(int joystick, char *mapping_string) |
195 { | 211 { |
212 #ifndef USE_FBDEV | |
196 char guid_string[33]; | 213 char guid_string[33]; |
197 SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(render_get_joystick(joystick)), guid_string, sizeof(guid_string)); | 214 SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(render_get_joystick(joystick)), guid_string, sizeof(guid_string)); |
198 tern_node *existing = tern_find_node(info_config, guid_string); | 215 tern_node *existing = tern_find_node(info_config, guid_string); |
199 existing = tern_insert_ptr(existing, "mapping", mapping_string); | 216 existing = tern_insert_ptr(existing, "mapping", mapping_string); |
200 info_config = tern_insert_node(info_config, guid_string, existing); | 217 info_config = tern_insert_node(info_config, guid_string, existing); |
201 persist_config_at(info_config, "controller_types.cfg"); | 218 persist_config_at(config, info_config, "controller_types.cfg"); |
219 const char *parts[] = {guid_string, ",", mapping_string}; | |
220 char * full = alloc_concat_m(3, parts); | |
221 SDL_GameControllerAddMapping(full); | |
222 free(full); | |
223 handle_joy_added(joystick); | |
224 #endif | |
225 } | |
226 | |
227 void delete_controller_info(void) | |
228 { | |
229 delete_custom_config_at("controller_types.cfg"); | |
230 loaded = 0; | |
231 tern_free(info_config); | |
232 info_config = NULL; | |
233 render_reset_mappings(); | |
202 } | 234 } |
203 | 235 |
204 char const *labels_xbox[] = { | 236 char const *labels_xbox[] = { |
205 "A", "B", "X", "Y", "Back", NULL, "Start", "Click", "Click", "White", "Black", "LT", "RT" | 237 "A", "B", "X", "Y", "Back", NULL, "Start", "Click", "Click", "White", "Black", "LT", "RT" |
206 }; | 238 }; |
219 static char const *labels_nintendo[] = { | 251 static char const *labels_nintendo[] = { |
220 "B", "A", "Y", "X", "-", "Home", "+", "Click", "Click", "L", "R", "ZL", "ZR" | 252 "B", "A", "Y", "X", "-", "Home", "+", "Click", "Click", "L", "R", "ZL", "ZR" |
221 }; | 253 }; |
222 static char const *labels_genesis[] = { | 254 static char const *labels_genesis[] = { |
223 "A", "B", "X", "Y", NULL, NULL, "Start", NULL, NULL, "Z", "C", NULL, "Mode" | 255 "A", "B", "X", "Y", NULL, NULL, "Start", NULL, NULL, "Z", "C", NULL, "Mode" |
256 }; | |
257 static char const *labels_genesis_3button[] = { | |
258 "A", "B", NULL, NULL, NULL, NULL, "Start", NULL, NULL, NULL, "C", NULL, "Mode" | |
259 }; | |
260 static char const *labels_genesis_8button[] = { | |
261 "A", "B", "X", "Y", "Mode", NULL, "Start", NULL, NULL, "Z", "C", "L", "R" | |
224 }; | 262 }; |
225 static char const *labels_saturn[] = { | 263 static char const *labels_saturn[] = { |
226 "A", "B", "X", "Y", NULL, NULL, "Start", NULL, NULL, "Z", "C", "LT", "RT" | 264 "A", "B", "X", "Y", NULL, NULL, "Start", NULL, NULL, "Z", "C", "LT", "RT" |
227 }; | 265 }; |
228 | 266 |
244 } else { | 282 } else { |
245 return labels_xbox; | 283 return labels_xbox; |
246 } | 284 } |
247 } else { | 285 } else { |
248 if (info->subtype == SUBTYPE_GENESIS) { | 286 if (info->subtype == SUBTYPE_GENESIS) { |
249 return labels_genesis; | 287 if (info->variant == VARIANT_8BUTTON) { |
288 return labels_genesis_8button; | |
289 } else if (info->variant == VARIANT_3BUTTON) { | |
290 return labels_genesis_3button; | |
291 } else { | |
292 return labels_genesis; | |
293 } | |
250 } else { | 294 } else { |
251 return labels_saturn; | 295 return labels_saturn; |
252 } | 296 } |
253 } | 297 } |
254 } | 298 } |
255 | 299 |
256 const char *get_button_label(controller_info *info, int button) | 300 const char *get_button_label(controller_info *info, int button) |
257 { | 301 { |
302 #ifndef USE_FBDEV | |
258 if (button >= SDL_CONTROLLER_BUTTON_DPAD_UP) { | 303 if (button >= SDL_CONTROLLER_BUTTON_DPAD_UP) { |
259 static char const * dirs[] = {"Up", "Down", "Left", "Right"}; | 304 static char const * dirs[] = {"Up", "Down", "Left", "Right"}; |
260 return dirs[button - SDL_CONTROLLER_BUTTON_DPAD_UP]; | 305 return dirs[button - SDL_CONTROLLER_BUTTON_DPAD_UP]; |
261 } | 306 } |
307 #endif | |
262 return label_source(info)[button]; | 308 return label_source(info)[button]; |
263 } | 309 } |
264 | 310 |
265 static char const *axis_labels[] = { | 311 static char const *axis_labels[] = { |
266 "Left X", "Left Y", "Right X", "Right Y" | 312 "Left X", "Left Y", "Right X", "Right Y" |
267 }; | 313 }; |
268 const char *get_axis_label(controller_info *info, int axis) | 314 const char *get_axis_label(controller_info *info, int axis) |
269 { | 315 { |
316 #ifndef USE_FBDEV | |
270 if (axis < SDL_CONTROLLER_AXIS_TRIGGERLEFT) { | 317 if (axis < SDL_CONTROLLER_AXIS_TRIGGERLEFT) { |
271 return axis_labels[axis]; | 318 return axis_labels[axis]; |
272 } else { | 319 } else { |
273 return label_source(info)[axis - SDL_CONTROLLER_AXIS_TRIGGERLEFT + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER + 1]; | 320 return label_source(info)[axis - SDL_CONTROLLER_AXIS_TRIGGERLEFT + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER + 1]; |
274 } | 321 } |
322 #else | |
323 return NULL; | |
324 #endif | |
275 } | 325 } |
276 | 326 |
277 char *make_controller_type_key(controller_info *info) | 327 char *make_controller_type_key(controller_info *info) |
278 { | 328 { |
279 const char *subtype; | 329 const char *subtype; |
314 char *prefix; | 364 char *prefix; |
315 if (info->variant == VARIANT_NORMAL) { | 365 if (info->variant == VARIANT_NORMAL) { |
316 prefix = "Normal "; | 366 prefix = "Normal "; |
317 } else { | 367 } else { |
318 static const char *parts[] = {"6 button (", NULL, "/", NULL, ") "}; | 368 static const char *parts[] = {"6 button (", NULL, "/", NULL, ") "}; |
369 #ifdef USE_FBDEV | |
370 parts[1] = parts[3] = "??"; | |
371 #else | |
319 if (info->variant == VARIANT_6B_BUMPERS) { | 372 if (info->variant == VARIANT_6B_BUMPERS) { |
320 parts[1] = get_button_label(info, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); | 373 parts[1] = get_button_label(info, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); |
321 parts[3] = get_button_label(info, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); | 374 parts[3] = get_button_label(info, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); |
322 } else { | 375 } else { |
323 parts[1] = get_button_label(info, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); | 376 parts[1] = get_button_label(info, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); |
324 parts[3] = get_axis_label(info, SDL_CONTROLLER_AXIS_TRIGGERRIGHT); | 377 parts[3] = get_axis_label(info, SDL_CONTROLLER_AXIS_TRIGGERRIGHT); |
325 } | 378 } |
379 #endif | |
326 prefix = alloc_concat_m(5, parts); | 380 prefix = alloc_concat_m(5, parts); |
327 } | 381 } |
328 char *ret = alloc_concat(prefix, base); | 382 char *ret = alloc_concat(prefix, base); |
329 if (info->variant != VARIANT_NORMAL) { | 383 if (info->variant != VARIANT_NORMAL) { |
330 free(prefix); | 384 free(prefix); |