main
controller_info.c
1#include <string.h>
2#include <stdlib.h>
3#include "controller_info.h"
4#include "config.h"
5#include "util.h"
6
7typedef struct {
8 char const *name;
9 controller_info info;
10} heuristic;
11
12static heuristic heuristics[] = {
13 //TODO: Add more heuristic rules
14 {"DualShock 4", {.type = TYPE_PSX, .subtype = SUBTYPE_PS4}},
15 {"PS4", {.type = TYPE_PSX, .subtype = SUBTYPE_PS4}},
16 {"PS3", {.type = TYPE_PSX, .subtype = SUBTYPE_PS3}},
17 {"X360", {.type = TYPE_XBOX, .subtype = SUBTYPE_X360}},
18 {"Xbox 360", {.type = TYPE_XBOX, .subtype = SUBTYPE_X360}},
19 {"X-box 360", {.type = TYPE_XBOX, .subtype = SUBTYPE_X360}},
20 {"Xbox One", {.type = TYPE_XBOX, .subtype = SUBTYPE_XBONE}},
21 {"X-box One", {.type = TYPE_XBOX, .subtype = SUBTYPE_XBONE}},
22 {"WiiU", {.type = TYPE_NINTENDO, .subtype = SUBTYPE_WIIU}},
23 {"Wii U", {.type = TYPE_NINTENDO, .subtype = SUBTYPE_WIIU}},
24 {"Nintendo Switch", {.type = TYPE_NINTENDO, .subtype = SUBTYPE_SWITCH}},
25 {"Saturn", {.type = TYPE_SEGA, .subtype = SUBTYPE_SATURN}}
26};
27const uint32_t num_heuristics = sizeof(heuristics)/sizeof(*heuristics);
28
29static tern_node *info_config;
30static uint8_t loaded;
31static const char *subtype_names[] = {
32 "unknown",
33 "xbox",
34 "xbox 360",
35 "xbone",
36 "ps2",
37 "ps3",
38 "ps4",
39 "wiiu",
40 "switch",
41 "genesis",
42 "saturn"
43};
44static const char *subtype_human_names[] = {
45 "unknown",
46 "Xbos",
47 "Xbox 360",
48 "Xbox One",
49 "PS2",
50 "PS3",
51 "PS4",
52 "Wii-U",
53 "Switch",
54 "Genesis",
55 "Saturn"
56};
57static const char *variant_names[] = {
58 "normal",
59 "6b bumpers",
60 "6b right"
61};
62
63static void load_ctype_config(void)
64{
65 if (!loaded) {
66 info_config = load_overrideable_config("controller_types.cfg", "controller_types.cfg");
67 loaded = 1;
68 }
69}
70
71controller_info get_controller_info(int joystick)
72{
73 const char *name = "Unknown";
74 return (controller_info){
75 .type = TYPE_GENERIC_MAPPING,
76 .subtype = SUBTYPE_UNKNOWN,
77 .variant = VARIANT_NORMAL,
78 .name = name
79 };
80}
81
82static void mappings_iter(char *key, tern_val val, uint8_t valtype, void *data)
83{
84}
85
86void controller_add_mappings(void)
87{
88 load_ctype_config();
89 if (info_config) {
90 tern_foreach(info_config, mappings_iter, NULL);
91 }
92}
93
94void save_controller_info(int joystick, controller_info *info)
95{
96}
97
98void save_controller_mapping(int joystick, char *mapping_string)
99{
100}
101
102char const *labels_xbox[] = {
103 "A", "B", "X", "Y", "Back", NULL, "Start", "Click", "Click", "White", "Black", "LT", "RT"
104};
105char const *labels_360[] = {
106 "A", "B", "X", "Y", "Back", "Xbox", "Start", "Click", "Click", "LB", "RB", "LT", "RT"
107};
108static char const *labels_xbone[] = {
109 "A", "B", "X", "Y", "View", "Xbox", "Menu", "Click", "Click", "LB", "RB", "LT", "RT"
110};
111static char const *labels_ps3[] = {
112 "cross", "circle", "square", "triangle", "Select", "PS", "Start", "L3", "R3", "L1", "R1", "L2", "R2"
113};
114static char const *labels_ps4[] = {
115 "cross", "circle", "square", "triangle", "Share", "PS", "Options", "L3", "R3", "L1", "R1", "L2", "R2"
116};
117static char const *labels_nintendo[] = {
118 "B", "A", "Y", "X", "-", "Home", "+", "Click", "Click", "L", "R", "ZL", "ZR"
119};
120static char const *labels_genesis[] = {
121 "A", "B", "X", "Y", NULL, NULL, "Start", NULL, NULL, "Z", "C", NULL, "Mode"
122};
123static char const *labels_saturn[] = {
124 "A", "B", "X", "Y", NULL, NULL, "Start", NULL, NULL, "Z", "C", "LT", "RT"
125};
126
127static const char** label_source(controller_info *info)
128{
129 if (info->type == TYPE_UNKNOWN || info->type == TYPE_GENERIC_MAPPING || info->subtype ==SUBTYPE_X360) {
130 return labels_360;
131 } else if (info->type == TYPE_NINTENDO) {
132 return labels_nintendo;
133 } else if (info->type == TYPE_PSX) {
134 if (info->subtype == SUBTYPE_PS4) {
135 return labels_ps4;
136 } else {
137 return labels_ps3;
138 }
139 } else if (info->type == TYPE_XBOX) {
140 if (info->subtype == SUBTYPE_XBONE) {
141 return labels_xbone;
142 } else {
143 return labels_xbox;
144 }
145 } else {
146 if (info->subtype == SUBTYPE_GENESIS) {
147 return labels_genesis;
148 } else {
149 return labels_saturn;
150 }
151 }
152}
153
154const char *get_button_label(controller_info *info, int button)
155{
156 return label_source(info)[button];
157}
158
159static char const *axis_labels[] = {
160 "Left X", "Left Y", "Right X", "Right Y"
161};
162const char *get_axis_label(controller_info *info, int axis)
163{
164 return NULL;
165}
166
167char *make_controller_type_key(controller_info *info)
168{
169 const char *subtype;
170 if (info->subtype == SUBTYPE_UNKNOWN) {
171 switch(info->type)
172 {
173 case TYPE_XBOX:
174 subtype = subtype_names[SUBTYPE_X360];
175 break;
176 case TYPE_PSX:
177 subtype = subtype_names[SUBTYPE_PS4];
178 break;
179 case TYPE_NINTENDO:
180 subtype = subtype_names[SUBTYPE_SWITCH];
181 break;
182 default:
183 subtype = "unknown";
184 }
185 } else {
186 subtype = subtype_names[info->subtype];
187 }
188 const char *variant = variant_names[info->variant];
189 const char *parts[] = {subtype, "_", variant};
190 char *ret = alloc_concat_m(3, parts);
191 for (char *cur = ret; *cur; cur++)
192 {
193 if (*cur == ' ')
194 {
195 *cur = '_';
196 }
197 }
198 return ret;
199}
200
201char *make_human_readable_type_name(controller_info *info)
202{
203 const char *base = subtype_human_names[info->subtype];
204 char *prefix;
205 if (info->variant == VARIANT_NORMAL) {
206 prefix = "Normal ";
207 } else {
208 static const char *parts[] = {"6 button (", NULL, "/", NULL, ") "};
209 parts[1] = parts[3] = "??";
210 prefix = alloc_concat_m(5, parts);
211 }
212 char *ret = alloc_concat(prefix, base);
213 if (info->variant != VARIANT_NORMAL) {
214 free(prefix);
215 }
216 return ret;
217}