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}