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