Mercurial > repos > blastem
comparison controller_info.c @ 1596:437e80a700aa
Initial heuristics for detecting controller types and showing different labels in UI. Modified controller settings view to first display a list of controllers, only showing mapping after selecting controller
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 22 Jul 2018 17:48:46 -0700 |
parents | |
children | 75aa418d0227 |
comparison
equal
deleted
inserted
replaced
1595:360d5bab199f | 1596:437e80a700aa |
---|---|
1 #include <string.h> | |
2 #include "render_sdl.h" | |
3 #include "controller_info.h" | |
4 | |
5 typedef struct { | |
6 char const *name; | |
7 controller_info info; | |
8 } heuristic; | |
9 | |
10 heuristic heuristics[] = { | |
11 //TODO: Add more heuristic rules | |
12 {"DualShock 4", {.type = TYPE_PSX, .subtype = SUBTYPE_PS4}}, | |
13 {"PS4", {.type = TYPE_PSX, .subtype = SUBTYPE_PS4}}, | |
14 {"PS3", {.type = TYPE_PSX, .subtype = SUBTYPE_PS3}}, | |
15 {"X360", {.type = TYPE_XBOX, .subtype = SUBTYPE_X360}}, | |
16 {"Xbox 360", {.type = TYPE_XBOX, .subtype = SUBTYPE_X360}}, | |
17 {"X-box 360", {.type = TYPE_XBOX, .subtype = SUBTYPE_X360}}, | |
18 {"Xbox One", {.type = TYPE_XBOX, .subtype = SUBTYPE_XBONE}}, | |
19 {"X-box One", {.type = TYPE_XBOX, .subtype = SUBTYPE_XBONE}}, | |
20 {"WiiU", {.type = TYPE_NINTENDO, .subtype = SUBTYPE_WIIU}}, | |
21 {"Wii U", {.type = TYPE_NINTENDO, .subtype = SUBTYPE_WIIU}}, | |
22 {"Nintendo Switch", {.type = TYPE_NINTENDO, .subtype = SUBTYPE_SWITCH}}, | |
23 {"Saturn", {.type = TYPE_SEGA, .subtype = SUBTYPE_SATURN}} | |
24 }; | |
25 const uint32_t num_heuristics = sizeof(heuristics)/sizeof(*heuristics); | |
26 | |
27 controller_info get_controller_info(int joystick) | |
28 { | |
29 SDL_GameController *control = render_get_controller(joystick); | |
30 if (!control) { | |
31 return (controller_info) { | |
32 .type = TYPE_UNKNOWN, | |
33 .subtype = SUBTYPE_UNKNOWN, | |
34 .variant = VARIANT_NORMAL, | |
35 .name = SDL_JoystickName(render_get_joystick(joystick)) | |
36 }; | |
37 } | |
38 const char *name = SDL_GameControllerName(control); | |
39 SDL_GameControllerClose(control); | |
40 for (uint32_t i = 0; i < num_heuristics; i++) | |
41 { | |
42 if (strstr(name, heuristics[i].name)) { | |
43 controller_info res = heuristics[i].info; | |
44 res.name = name; | |
45 return res; | |
46 } | |
47 } | |
48 //default to a 360 | |
49 return (controller_info){ | |
50 .type = TYPE_GENERIC_MAPPING, | |
51 .subtype = SUBTYPE_UNKNOWN, | |
52 .variant = VARIANT_NORMAL, | |
53 .name = name | |
54 }; | |
55 } | |
56 | |
57 char const *labels_xbox[] = { | |
58 "A", "B", "X", "Y", "Back", NULL, "Start", "Click", "Click", "White", "Black", "LT", "RT" | |
59 }; | |
60 char const *labels_360[] = { | |
61 "A", "B", "X", "Y", "Back", "Guide", "Start", "Click", "Click", "LB", "RB", "LT", "RT" | |
62 }; | |
63 static char const *labels_xbone[] = { | |
64 "A", "B", "X", "Y", "View", "Guide", "Menu", "Click", "Click", "LB", "RB", "LT", "RT" | |
65 }; | |
66 static char const *labels_ps3[] = { | |
67 "cross", "circle", "square", "triangle", "Select", "Guide", "Start", "L3", "R3", "L1", "R1", "L2", "R2" | |
68 }; | |
69 static char const *labels_ps4[] = { | |
70 "cross", "circle", "square", "triangle", "Share", "Guide", "Options", "L3", "R3", "L1", "R1", "L2", "R2" | |
71 }; | |
72 static char const *labels_nintendo[] = { | |
73 "B", "A", "Y", "X", "-", "Home", "+", "Click", "Click", "L", "R", "ZL", "ZR" | |
74 }; | |
75 static char const *labels_genesis[] = { | |
76 "A", "B", "X", "Y", NULL, NULL, "Start", NULL, NULL, "Z", "C", NULL, "Mode" | |
77 }; | |
78 static char const *labels_saturn[] = { | |
79 "A", "B", "X", "Y", NULL, NULL, "Start", NULL, NULL, "Z", "C", "LT", "RT" | |
80 }; | |
81 | |
82 static const char** label_source(controller_info *info) | |
83 { | |
84 if (info->type == TYPE_UNKNOWN || info->type == TYPE_GENERIC_MAPPING || info->subtype ==SUBTYPE_X360) { | |
85 return labels_360; | |
86 } else if (info->type == TYPE_NINTENDO) { | |
87 return labels_nintendo; | |
88 } else if (info->type == TYPE_PSX) { | |
89 if (info->subtype == SUBTYPE_PS4) { | |
90 return labels_ps4; | |
91 } else { | |
92 return labels_ps3; | |
93 } | |
94 } else if (info->type == TYPE_XBOX) { | |
95 if (info->subtype == SUBTYPE_XBONE) { | |
96 return labels_xbone; | |
97 } else { | |
98 return labels_xbox; | |
99 } | |
100 } else { | |
101 if (info->subtype == SUBTYPE_GENESIS) { | |
102 return labels_genesis; | |
103 } else { | |
104 return labels_saturn; | |
105 } | |
106 } | |
107 } | |
108 | |
109 const char *get_button_label(controller_info *info, int button) | |
110 { | |
111 return label_source(info)[button]; | |
112 } | |
113 | |
114 static char const *axis_labels[] = { | |
115 "Left X", "Left Y", "Right X", "Right Y" | |
116 }; | |
117 const char *get_axis_label(controller_info *info, int axis) | |
118 { | |
119 if (axis < SDL_CONTROLLER_AXIS_TRIGGERLEFT) { | |
120 return axis_labels[axis]; | |
121 } else { | |
122 return label_source(info)[axis - SDL_CONTROLLER_AXIS_TRIGGERLEFT + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER + 1]; | |
123 } | |
124 } | |
125 |