Mercurial > repos > blastem
diff controller_info.c @ 1599:1fc61c844ec5
Allow selecting controller type when controllers have an SDL 2 mapping, but heuristics fail to idenify details
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 27 Jul 2018 22:40:56 -0700 |
parents | 75aa418d0227 |
children | 7f39c40b4b25 |
line wrap: on
line diff
--- a/controller_info.c Wed Jul 25 09:38:40 2018 -0700 +++ b/controller_info.c Fri Jul 27 22:40:56 2018 -0700 @@ -1,13 +1,14 @@ #include <string.h> #include "render_sdl.h" #include "controller_info.h" +#include "config.h" typedef struct { char const *name; controller_info info; } heuristic; -heuristic heuristics[] = { +static heuristic heuristics[] = { //TODO: Add more heuristic rules {"DualShock 4", {.type = TYPE_PSX, .subtype = SUBTYPE_PS4}}, {"PS4", {.type = TYPE_PSX, .subtype = SUBTYPE_PS4}}, @@ -24,15 +25,97 @@ }; const uint32_t num_heuristics = sizeof(heuristics)/sizeof(*heuristics); +static tern_node *info_config; +static uint8_t loaded; +static const char *subtype_names[] = { + "unknown", + "xbox", + "xbox 360", + "xbone", + "ps2", + "ps3", + "ps4", + "wiiu", + "switch", + "genesis", + "saturn" +}; +static const char *variant_names[] = { + "normal", + "6b bumpers", + "6b right" +}; controller_info get_controller_info(int joystick) { + if (!loaded) { + info_config = load_overrideable_config("controller_types.cfg", "controller_types.cfg"); + loaded = 1; + } + char guid_string[33]; + SDL_Joystick *stick = render_get_joystick(joystick); SDL_GameController *control = render_get_controller(joystick); + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(stick), guid_string, sizeof(guid_string)); + tern_node *info = tern_find_node(info_config, guid_string); + if (info) { + controller_info res; + char *subtype = tern_find_ptr(info, "subtype"); + res.subtype = SUBTYPE_UNKNOWN; + if (subtype) { + for (int i = 0; i < SUBTYPE_NUM; i++) + { + if (!strcmp(subtype_names[i], subtype)) { + res.subtype = i; + break; + } + } + } + switch (res.subtype) + { + case SUBTYPE_XBOX: + case SUBTYPE_X360: + case SUBTYPE_XBONE: + res.type = TYPE_XBOX; + break; + case SUBTYPE_PS2: + case SUBTYPE_PS3: + case SUBTYPE_PS4: + res.type = TYPE_PSX; + break; + case SUBTYPE_WIIU: + case SUBTYPE_SWITCH: + res.type = TYPE_NINTENDO; + break; + case SUBTYPE_GENESIS: + case SUBTYPE_SATURN: + res.type = TYPE_SEGA; + break; + default: + res.type = TYPE_UNKNOWN; + break; + } + char *variant = tern_find_ptr(info, "variant"); + res.variant = VARIANT_NORMAL; + if (variant) { + for (int i = 0; i < VARIANT_NUM; i++) + { + if (!strcmp(variant_names[i], variant)) { + res.variant = i; + break; + } + } + } + res.name = control ? SDL_GameControllerName(control) : SDL_JoystickName(stick); + if (control) { + SDL_GameControllerClose(control); + } + return res; + } if (!control) { return (controller_info) { .type = TYPE_UNKNOWN, .subtype = SUBTYPE_UNKNOWN, .variant = VARIANT_NORMAL, - .name = SDL_JoystickName(render_get_joystick(joystick)) + .name = SDL_JoystickName(stick) }; } const char *name = SDL_GameControllerName(control); @@ -54,6 +137,18 @@ }; } +void save_controller_info(int joystick, controller_info *info) +{ + char guid_string[33]; + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(render_get_joystick(joystick)), guid_string, sizeof(guid_string)); + tern_node *existing = tern_find_node(info_config, guid_string); + existing = tern_insert_ptr(existing, "subtype", (void *)subtype_names[info->subtype]); + existing = tern_insert_ptr(existing, "variant", (void *)variant_names[info->variant]); + info_config = tern_insert_node(info_config, guid_string, existing); + persist_config_at(info_config, "controller_types.cfg"); + +} + char const *labels_xbox[] = { "A", "B", "X", "Y", "Back", NULL, "Start", "Click", "Click", "White", "Black", "LT", "RT" };