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 };