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