Mercurial > repos > blastem
comparison 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 |
comparison
equal
deleted
inserted
replaced
1598:5e2af89c3467 | 1599:1fc61c844ec5 |
---|---|
1 #include <string.h> | 1 #include <string.h> |
2 #include "render_sdl.h" | 2 #include "render_sdl.h" |
3 #include "controller_info.h" | 3 #include "controller_info.h" |
4 #include "config.h" | |
4 | 5 |
5 typedef struct { | 6 typedef struct { |
6 char const *name; | 7 char const *name; |
7 controller_info info; | 8 controller_info info; |
8 } heuristic; | 9 } heuristic; |
9 | 10 |
10 heuristic heuristics[] = { | 11 static heuristic heuristics[] = { |
11 //TODO: Add more heuristic rules | 12 //TODO: Add more heuristic rules |
12 {"DualShock 4", {.type = TYPE_PSX, .subtype = SUBTYPE_PS4}}, | 13 {"DualShock 4", {.type = TYPE_PSX, .subtype = SUBTYPE_PS4}}, |
13 {"PS4", {.type = TYPE_PSX, .subtype = SUBTYPE_PS4}}, | 14 {"PS4", {.type = TYPE_PSX, .subtype = SUBTYPE_PS4}}, |
14 {"PS3", {.type = TYPE_PSX, .subtype = SUBTYPE_PS3}}, | 15 {"PS3", {.type = TYPE_PSX, .subtype = SUBTYPE_PS3}}, |
15 {"X360", {.type = TYPE_XBOX, .subtype = SUBTYPE_X360}}, | 16 {"X360", {.type = TYPE_XBOX, .subtype = SUBTYPE_X360}}, |
22 {"Nintendo Switch", {.type = TYPE_NINTENDO, .subtype = SUBTYPE_SWITCH}}, | 23 {"Nintendo Switch", {.type = TYPE_NINTENDO, .subtype = SUBTYPE_SWITCH}}, |
23 {"Saturn", {.type = TYPE_SEGA, .subtype = SUBTYPE_SATURN}} | 24 {"Saturn", {.type = TYPE_SEGA, .subtype = SUBTYPE_SATURN}} |
24 }; | 25 }; |
25 const uint32_t num_heuristics = sizeof(heuristics)/sizeof(*heuristics); | 26 const uint32_t num_heuristics = sizeof(heuristics)/sizeof(*heuristics); |
26 | 27 |
28 static tern_node *info_config; | |
29 static uint8_t loaded; | |
30 static const char *subtype_names[] = { | |
31 "unknown", | |
32 "xbox", | |
33 "xbox 360", | |
34 "xbone", | |
35 "ps2", | |
36 "ps3", | |
37 "ps4", | |
38 "wiiu", | |
39 "switch", | |
40 "genesis", | |
41 "saturn" | |
42 }; | |
43 static const char *variant_names[] = { | |
44 "normal", | |
45 "6b bumpers", | |
46 "6b right" | |
47 }; | |
27 controller_info get_controller_info(int joystick) | 48 controller_info get_controller_info(int joystick) |
28 { | 49 { |
50 if (!loaded) { | |
51 info_config = load_overrideable_config("controller_types.cfg", "controller_types.cfg"); | |
52 loaded = 1; | |
53 } | |
54 char guid_string[33]; | |
55 SDL_Joystick *stick = render_get_joystick(joystick); | |
29 SDL_GameController *control = render_get_controller(joystick); | 56 SDL_GameController *control = render_get_controller(joystick); |
57 SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(stick), guid_string, sizeof(guid_string)); | |
58 tern_node *info = tern_find_node(info_config, guid_string); | |
59 if (info) { | |
60 controller_info res; | |
61 char *subtype = tern_find_ptr(info, "subtype"); | |
62 res.subtype = SUBTYPE_UNKNOWN; | |
63 if (subtype) { | |
64 for (int i = 0; i < SUBTYPE_NUM; i++) | |
65 { | |
66 if (!strcmp(subtype_names[i], subtype)) { | |
67 res.subtype = i; | |
68 break; | |
69 } | |
70 } | |
71 } | |
72 switch (res.subtype) | |
73 { | |
74 case SUBTYPE_XBOX: | |
75 case SUBTYPE_X360: | |
76 case SUBTYPE_XBONE: | |
77 res.type = TYPE_XBOX; | |
78 break; | |
79 case SUBTYPE_PS2: | |
80 case SUBTYPE_PS3: | |
81 case SUBTYPE_PS4: | |
82 res.type = TYPE_PSX; | |
83 break; | |
84 case SUBTYPE_WIIU: | |
85 case SUBTYPE_SWITCH: | |
86 res.type = TYPE_NINTENDO; | |
87 break; | |
88 case SUBTYPE_GENESIS: | |
89 case SUBTYPE_SATURN: | |
90 res.type = TYPE_SEGA; | |
91 break; | |
92 default: | |
93 res.type = TYPE_UNKNOWN; | |
94 break; | |
95 } | |
96 char *variant = tern_find_ptr(info, "variant"); | |
97 res.variant = VARIANT_NORMAL; | |
98 if (variant) { | |
99 for (int i = 0; i < VARIANT_NUM; i++) | |
100 { | |
101 if (!strcmp(variant_names[i], variant)) { | |
102 res.variant = i; | |
103 break; | |
104 } | |
105 } | |
106 } | |
107 res.name = control ? SDL_GameControllerName(control) : SDL_JoystickName(stick); | |
108 if (control) { | |
109 SDL_GameControllerClose(control); | |
110 } | |
111 return res; | |
112 } | |
30 if (!control) { | 113 if (!control) { |
31 return (controller_info) { | 114 return (controller_info) { |
32 .type = TYPE_UNKNOWN, | 115 .type = TYPE_UNKNOWN, |
33 .subtype = SUBTYPE_UNKNOWN, | 116 .subtype = SUBTYPE_UNKNOWN, |
34 .variant = VARIANT_NORMAL, | 117 .variant = VARIANT_NORMAL, |
35 .name = SDL_JoystickName(render_get_joystick(joystick)) | 118 .name = SDL_JoystickName(stick) |
36 }; | 119 }; |
37 } | 120 } |
38 const char *name = SDL_GameControllerName(control); | 121 const char *name = SDL_GameControllerName(control); |
39 SDL_GameControllerClose(control); | 122 SDL_GameControllerClose(control); |
40 for (uint32_t i = 0; i < num_heuristics; i++) | 123 for (uint32_t i = 0; i < num_heuristics; i++) |
50 .type = TYPE_GENERIC_MAPPING, | 133 .type = TYPE_GENERIC_MAPPING, |
51 .subtype = SUBTYPE_UNKNOWN, | 134 .subtype = SUBTYPE_UNKNOWN, |
52 .variant = VARIANT_NORMAL, | 135 .variant = VARIANT_NORMAL, |
53 .name = name | 136 .name = name |
54 }; | 137 }; |
138 } | |
139 | |
140 void save_controller_info(int joystick, controller_info *info) | |
141 { | |
142 char guid_string[33]; | |
143 SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(render_get_joystick(joystick)), guid_string, sizeof(guid_string)); | |
144 tern_node *existing = tern_find_node(info_config, guid_string); | |
145 existing = tern_insert_ptr(existing, "subtype", (void *)subtype_names[info->subtype]); | |
146 existing = tern_insert_ptr(existing, "variant", (void *)variant_names[info->variant]); | |
147 info_config = tern_insert_node(info_config, guid_string, existing); | |
148 persist_config_at(info_config, "controller_types.cfg"); | |
149 | |
55 } | 150 } |
56 | 151 |
57 char const *labels_xbox[] = { | 152 char const *labels_xbox[] = { |
58 "A", "B", "X", "Y", "Back", NULL, "Start", "Click", "Click", "White", "Black", "LT", "RT" | 153 "A", "B", "X", "Y", "Back", NULL, "Start", "Click", "Click", "White", "Black", "LT", "RT" |
59 }; | 154 }; |