Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/sdl/joystick/hidapi/SDL_hidapi_combined.c
9913 views
1
/*
2
Simple DirectMedia Layer
3
Copyright (C) 1997-2025 Sam Lantinga <[email protected]>
4
5
This software is provided 'as-is', without any express or implied
6
warranty. In no event will the authors be held liable for any damages
7
arising from the use of this software.
8
9
Permission is granted to anyone to use this software for any purpose,
10
including commercial applications, and to alter it and redistribute it
11
freely, subject to the following restrictions:
12
13
1. The origin of this software must not be misrepresented; you must not
14
claim that you wrote the original software. If you use this software
15
in a product, an acknowledgment in the product documentation would be
16
appreciated but is not required.
17
2. Altered source versions must be plainly marked as such, and must not be
18
misrepresented as being the original software.
19
3. This notice may not be removed or altered from any source distribution.
20
*/
21
// This driver supports the Nintendo Switch Joy-Cons pair controllers
22
#include "SDL_internal.h"
23
24
#ifdef SDL_JOYSTICK_HIDAPI
25
26
#include "SDL_hidapijoystick_c.h"
27
#include "../SDL_sysjoystick.h"
28
29
static void HIDAPI_DriverCombined_RegisterHints(SDL_HintCallback callback, void *userdata)
30
{
31
}
32
33
static void HIDAPI_DriverCombined_UnregisterHints(SDL_HintCallback callback, void *userdata)
34
{
35
}
36
37
static bool HIDAPI_DriverCombined_IsEnabled(void)
38
{
39
return true;
40
}
41
42
static bool HIDAPI_DriverCombined_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GamepadType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
43
{
44
// This is always explicitly created for combined devices
45
return false;
46
}
47
48
static bool HIDAPI_DriverCombined_InitDevice(SDL_HIDAPI_Device *device)
49
{
50
return HIDAPI_JoystickConnected(device, NULL);
51
}
52
53
static int HIDAPI_DriverCombined_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
54
{
55
return -1;
56
}
57
58
static void HIDAPI_DriverCombined_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
59
{
60
}
61
62
static bool HIDAPI_DriverCombined_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
63
{
64
int i;
65
char *serial = NULL, *new_serial;
66
size_t serial_length = 0, new_length;
67
68
SDL_AssertJoysticksLocked();
69
70
for (i = 0; i < device->num_children; ++i) {
71
SDL_HIDAPI_Device *child = device->children[i];
72
if (!child->driver->OpenJoystick(child, joystick)) {
73
child->broken = true;
74
75
while (i-- > 0) {
76
child = device->children[i];
77
child->driver->CloseJoystick(child, joystick);
78
}
79
if (serial) {
80
SDL_free(serial);
81
}
82
return false;
83
}
84
85
// Extend the serial number with the child serial number
86
if (joystick->serial) {
87
new_length = serial_length + 1 + SDL_strlen(joystick->serial);
88
new_serial = (char *)SDL_realloc(serial, new_length);
89
if (new_serial) {
90
if (serial) {
91
SDL_strlcat(new_serial, ",", new_length);
92
SDL_strlcat(new_serial, joystick->serial, new_length);
93
} else {
94
SDL_strlcpy(new_serial, joystick->serial, new_length);
95
}
96
serial = new_serial;
97
serial_length = new_length;
98
}
99
SDL_free(joystick->serial);
100
joystick->serial = NULL;
101
}
102
}
103
104
// Update the joystick with the combined serial numbers
105
if (joystick->serial) {
106
SDL_free(joystick->serial);
107
}
108
joystick->serial = serial;
109
110
return true;
111
}
112
113
static bool HIDAPI_DriverCombined_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
114
{
115
int i;
116
bool result = false;
117
118
for (i = 0; i < device->num_children; ++i) {
119
SDL_HIDAPI_Device *child = device->children[i];
120
if (child->driver->RumbleJoystick(child, joystick, low_frequency_rumble, high_frequency_rumble)) {
121
result = true;
122
}
123
}
124
return result;
125
}
126
127
static bool HIDAPI_DriverCombined_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
128
{
129
int i;
130
bool result = false;
131
132
for (i = 0; i < device->num_children; ++i) {
133
SDL_HIDAPI_Device *child = device->children[i];
134
if (child->driver->RumbleJoystickTriggers(child, joystick, left_rumble, right_rumble)) {
135
result = true;
136
}
137
}
138
return result;
139
}
140
141
static Uint32 HIDAPI_DriverCombined_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
142
{
143
int i;
144
Uint32 caps = 0;
145
146
for (i = 0; i < device->num_children; ++i) {
147
SDL_HIDAPI_Device *child = device->children[i];
148
caps |= child->driver->GetJoystickCapabilities(child, joystick);
149
}
150
return caps;
151
}
152
153
static bool HIDAPI_DriverCombined_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
154
{
155
int i;
156
bool result = false;
157
158
for (i = 0; i < device->num_children; ++i) {
159
SDL_HIDAPI_Device *child = device->children[i];
160
if (child->driver->SetJoystickLED(child, joystick, red, green, blue)) {
161
result = true;
162
}
163
}
164
return result;
165
}
166
167
static bool HIDAPI_DriverCombined_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
168
{
169
return SDL_Unsupported();
170
}
171
172
static bool HIDAPI_DriverCombined_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, bool enabled)
173
{
174
int i;
175
bool result = false;
176
177
for (i = 0; i < device->num_children; ++i) {
178
SDL_HIDAPI_Device *child = device->children[i];
179
if (child->driver->SetJoystickSensorsEnabled(child, joystick, enabled)) {
180
result = true;
181
}
182
}
183
return result;
184
}
185
186
static bool HIDAPI_DriverCombined_UpdateDevice(SDL_HIDAPI_Device *device)
187
{
188
int i;
189
int result = true;
190
191
for (i = 0; i < device->num_children; ++i) {
192
SDL_HIDAPI_Device *child = device->children[i];
193
if (!child->driver->UpdateDevice(child)) {
194
result = false;
195
}
196
}
197
return result;
198
}
199
200
static void HIDAPI_DriverCombined_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
201
{
202
int i;
203
204
for (i = 0; i < device->num_children; ++i) {
205
SDL_HIDAPI_Device *child = device->children[i];
206
child->driver->CloseJoystick(child, joystick);
207
}
208
}
209
210
static void HIDAPI_DriverCombined_FreeDevice(SDL_HIDAPI_Device *device)
211
{
212
}
213
214
SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverCombined = {
215
"SDL_JOYSTICK_HIDAPI_COMBINED",
216
true,
217
HIDAPI_DriverCombined_RegisterHints,
218
HIDAPI_DriverCombined_UnregisterHints,
219
HIDAPI_DriverCombined_IsEnabled,
220
HIDAPI_DriverCombined_IsSupportedDevice,
221
HIDAPI_DriverCombined_InitDevice,
222
HIDAPI_DriverCombined_GetDevicePlayerIndex,
223
HIDAPI_DriverCombined_SetDevicePlayerIndex,
224
HIDAPI_DriverCombined_UpdateDevice,
225
HIDAPI_DriverCombined_OpenJoystick,
226
HIDAPI_DriverCombined_RumbleJoystick,
227
HIDAPI_DriverCombined_RumbleJoystickTriggers,
228
HIDAPI_DriverCombined_GetJoystickCapabilities,
229
HIDAPI_DriverCombined_SetJoystickLED,
230
HIDAPI_DriverCombined_SendJoystickEffect,
231
HIDAPI_DriverCombined_SetJoystickSensorsEnabled,
232
HIDAPI_DriverCombined_CloseJoystick,
233
HIDAPI_DriverCombined_FreeDevice,
234
};
235
236
#endif // SDL_JOYSTICK_HIDAPI
237
238