SDL  2.0
SDL_hidapi_gamecube.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
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 #include "../../SDL_internal.h"
22 
23 #ifdef SDL_JOYSTICK_HIDAPI
24 
25 #include "SDL_hints.h"
26 #include "SDL_log.h"
27 #include "SDL_events.h"
28 #include "SDL_timer.h"
29 #include "SDL_haptic.h"
30 #include "SDL_joystick.h"
31 #include "SDL_gamecontroller.h"
32 #include "../../SDL_hints_c.h"
33 #include "../SDL_sysjoystick.h"
34 #include "SDL_hidapijoystick_c.h"
35 #include "SDL_hidapi_rumble.h"
36 
37 
38 #ifdef SDL_JOYSTICK_HIDAPI_GAMECUBE
39 
40 #define MAX_CONTROLLERS 4
41 
42 typedef struct {
43  SDL_JoystickID joysticks[MAX_CONTROLLERS];
44  Uint8 wireless[MAX_CONTROLLERS];
45  Uint8 min_axis[MAX_CONTROLLERS*SDL_CONTROLLER_AXIS_MAX];
46  Uint8 max_axis[MAX_CONTROLLERS*SDL_CONTROLLER_AXIS_MAX];
47  Uint8 rumbleAllowed[MAX_CONTROLLERS];
48  Uint8 rumble[1+MAX_CONTROLLERS];
49  /* Without this variable, hid_write starts to lag a TON */
50  SDL_bool rumbleUpdate;
51  SDL_bool m_bUseButtonLabels;
52 } SDL_DriverGameCube_Context;
53 
54 static SDL_bool
55 HIDAPI_DriverGameCube_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
56 {
57  if (vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER) {
58  /* Nintendo Co., Ltd. Wii U GameCube Controller Adapter */
59  return SDL_TRUE;
60  }
61  return SDL_FALSE;
62 }
63 
64 static const char *
65 HIDAPI_DriverGameCube_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
66 {
67  return "Nintendo GameCube Controller";
68 }
69 
70 static void
71 ResetAxisRange(SDL_DriverGameCube_Context *ctx, int joystick_index)
72 {
73  SDL_memset(&ctx->min_axis[joystick_index*SDL_CONTROLLER_AXIS_MAX], 128-88, SDL_CONTROLLER_AXIS_MAX);
74  SDL_memset(&ctx->max_axis[joystick_index*SDL_CONTROLLER_AXIS_MAX], 128+88, SDL_CONTROLLER_AXIS_MAX);
75 
76  /* Trigger axes may have a higher resting value */
77  ctx->min_axis[joystick_index*SDL_CONTROLLER_AXIS_MAX+SDL_CONTROLLER_AXIS_TRIGGERLEFT] = 40;
78  ctx->min_axis[joystick_index*SDL_CONTROLLER_AXIS_MAX+SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = 40;
79 }
80 
81 static float fsel(float fComparand, float fValGE, float fLT)
82 {
83  return fComparand >= 0 ? fValGE : fLT;
84 }
85 
86 static float RemapVal(float val, float A, float B, float C, float D)
87 {
88  if (A == B) {
89  return fsel(val - B , D , C);
90  }
91  if (val < A) {
92  val = A;
93  }
94  if (val > B) {
95  val = B;
96  }
97  return C + (D - C) * (val - A) / (B - A);
98 }
99 
100 static void SDLCALL SDL_GameControllerButtonReportingHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
101 {
102  SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)userdata;
103  ctx->m_bUseButtonLabels = SDL_GetStringBoolean(hint, SDL_TRUE);
104 }
105 
106 static Uint8 RemapButton(SDL_DriverGameCube_Context *ctx, Uint8 button)
107 {
108  if (!ctx->m_bUseButtonLabels) {
109  /* Use button positions */
110  switch (button) {
115  default:
116  break;
117  }
118  }
119  return button;
120 }
121 
122 static SDL_bool
123 HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
124 {
125  SDL_DriverGameCube_Context *ctx;
126  Uint8 packet[37];
127  Uint8 *curSlot;
128  Uint8 i;
129  int size;
130  Uint8 initMagic = 0x13;
131  Uint8 rumbleMagic = 0x11;
132 
133  ctx = (SDL_DriverGameCube_Context *)SDL_calloc(1, sizeof(*ctx));
134  if (!ctx) {
135  SDL_OutOfMemory();
136  return SDL_FALSE;
137  }
138 
139  device->dev = hid_open_path(device->path, 0);
140  if (!device->dev) {
141  SDL_free(ctx);
142  SDL_SetError("Couldn't open %s", device->path);
143  return SDL_FALSE;
144  }
145  device->context = ctx;
146 
147  ctx->joysticks[0] = -1;
148  ctx->joysticks[1] = -1;
149  ctx->joysticks[2] = -1;
150  ctx->joysticks[3] = -1;
151  ctx->rumble[0] = rumbleMagic;
152 
153  /* This is all that's needed to initialize the device. Really! */
154  if (hid_write(device->dev, &initMagic, sizeof(initMagic)) != sizeof(initMagic)) {
155  SDL_SetError("Couldn't initialize WUP-028");
156  goto error;
157  }
158 
159  /* Wait for the adapter to initialize */
160  SDL_Delay(10);
161 
162  /* Add all the applicable joysticks */
163  while ((size = hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) {
164  if (size < 37 || packet[0] != 0x21) {
165  continue; /* Nothing to do yet...? */
166  }
167 
168  /* Go through all 4 slots */
169  curSlot = packet + 1;
170  for (i = 0; i < MAX_CONTROLLERS; i += 1, curSlot += 9) {
171  ctx->wireless[i] = (curSlot[0] & 0x20) != 0;
172 
173  /* Only allow rumble if the adapter's second USB cable is connected */
174  ctx->rumbleAllowed[i] = (curSlot[0] & 0x04) != 0 && !ctx->wireless[i];
175 
176  if (curSlot[0] & 0x30) { /* 0x10 - Wired, 0x20 - Wireless */
177  if (ctx->joysticks[i] == -1) {
178  ResetAxisRange(ctx, i);
179  HIDAPI_JoystickConnected(device, &ctx->joysticks[i]);
180  }
181  } else {
182  if (ctx->joysticks[i] != -1) {
183  HIDAPI_JoystickDisconnected(device, ctx->joysticks[i]);
184  ctx->joysticks[i] = -1;
185  }
186  continue;
187  }
188  }
189  }
190 
192  SDL_GameControllerButtonReportingHintChanged, ctx);
193 
194  return SDL_TRUE;
195 
196 error:
197  if (device->dev) {
198  hid_close(device->dev);
199  device->dev = NULL;
200  }
201  if (device->context) {
202  SDL_free(device->context);
203  device->context = NULL;
204  }
205  return SDL_FALSE;
206 }
207 
208 static int
209 HIDAPI_DriverGameCube_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
210 {
211  SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
212  Uint8 i;
213 
214  for (i = 0; i < 4; ++i) {
215  if (instance_id == ctx->joysticks[i]) {
216  return i;
217  }
218  }
219  return -1;
220 }
221 
222 static void
223 HIDAPI_DriverGameCube_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
224 {
225 }
226 
227 static SDL_bool
228 HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device)
229 {
230  SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
231  SDL_Joystick *joystick;
232  Uint8 packet[37];
233  Uint8 *curSlot;
234  Uint8 i;
235  Sint16 axis_value;
236  int size;
237 
238  /* Read input packet */
239  while ((size = hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) {
240  if (size < 37 || packet[0] != 0x21) {
241  continue; /* Nothing to do right now...? */
242  }
243 
244  /* Go through all 4 slots */
245  curSlot = packet + 1;
246  for (i = 0; i < MAX_CONTROLLERS; i += 1, curSlot += 9) {
247  ctx->wireless[i] = (curSlot[0] & 0x20) != 0;
248 
249  /* Only allow rumble if the adapter's second USB cable is connected */
250  ctx->rumbleAllowed[i] = (curSlot[0] & 0x04) != 0 && !ctx->wireless[i];
251 
252  if (curSlot[0] & 0x30) { /* 0x10 - Wired, 0x20 - Wireless */
253  if (ctx->joysticks[i] == -1) {
254  ResetAxisRange(ctx, i);
255  HIDAPI_JoystickConnected(device, &ctx->joysticks[i]);
256  }
257  joystick = SDL_JoystickFromInstanceID(ctx->joysticks[i]);
258 
259  /* Hasn't been opened yet, skip */
260  if (joystick == NULL) {
261  continue;
262  }
263  } else {
264  if (ctx->joysticks[i] != -1) {
265  HIDAPI_JoystickDisconnected(device, ctx->joysticks[i]);
266  ctx->joysticks[i] = -1;
267  }
268  continue;
269  }
270 
271  #define READ_BUTTON(off, flag, button) \
272  SDL_PrivateJoystickButton( \
273  joystick, \
274  RemapButton(ctx, button), \
275  (curSlot[off] & flag) ? SDL_PRESSED : SDL_RELEASED \
276  );
277  READ_BUTTON(1, 0x01, 0) /* A */
278  READ_BUTTON(1, 0x04, 1) /* B */
279  READ_BUTTON(1, 0x02, 2) /* X */
280  READ_BUTTON(1, 0x08, 3) /* Y */
281  READ_BUTTON(1, 0x10, 4) /* DPAD_LEFT */
282  READ_BUTTON(1, 0x20, 5) /* DPAD_RIGHT */
283  READ_BUTTON(1, 0x40, 6) /* DPAD_DOWN */
284  READ_BUTTON(1, 0x80, 7) /* DPAD_UP */
285  READ_BUTTON(2, 0x01, 8) /* START */
286  READ_BUTTON(2, 0x02, 9) /* RIGHTSHOULDER */
287  /* These two buttons are for the bottoms of the analog triggers.
288  * More than likely, you're going to want to read the axes instead!
289  * -flibit
290  */
291  READ_BUTTON(2, 0x04, 10) /* TRIGGERRIGHT */
292  READ_BUTTON(2, 0x08, 11) /* TRIGGERLEFT */
293  #undef READ_BUTTON
294 
295  #define READ_AXIS(off, axis) \
296  if (axis < SDL_CONTROLLER_AXIS_TRIGGERLEFT) \
297  if (curSlot[off] < ctx->min_axis[i*SDL_CONTROLLER_AXIS_MAX+axis]) ctx->min_axis[i*SDL_CONTROLLER_AXIS_MAX+axis] = curSlot[off]; \
298  if (curSlot[off] > ctx->max_axis[i*SDL_CONTROLLER_AXIS_MAX+axis]) ctx->max_axis[i*SDL_CONTROLLER_AXIS_MAX+axis] = curSlot[off]; \
299  axis_value = (Sint16)(RemapVal(curSlot[off], ctx->min_axis[i*SDL_CONTROLLER_AXIS_MAX+axis], ctx->max_axis[i*SDL_CONTROLLER_AXIS_MAX+axis], SDL_MIN_SINT16, SDL_MAX_SINT16)); \
300  SDL_PrivateJoystickAxis( \
301  joystick, \
302  axis, axis_value \
303  );
304  READ_AXIS(3, SDL_CONTROLLER_AXIS_LEFTX)
305  READ_AXIS(4, SDL_CONTROLLER_AXIS_LEFTY)
306  READ_AXIS(5, SDL_CONTROLLER_AXIS_RIGHTX)
307  READ_AXIS(6, SDL_CONTROLLER_AXIS_RIGHTY)
308  READ_AXIS(7, SDL_CONTROLLER_AXIS_TRIGGERLEFT)
310  #undef READ_AXIS
311  }
312  }
313 
314  /* Write rumble packet */
315  if (ctx->rumbleUpdate) {
316  SDL_HIDAPI_SendRumble(device, ctx->rumble, sizeof(ctx->rumble));
317  ctx->rumbleUpdate = SDL_FALSE;
318  }
319 
320  /* If we got here, nothing bad happened! */
321  return SDL_TRUE;
322 }
323 
324 static SDL_bool
325 HIDAPI_DriverGameCube_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
326 {
327  SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
328  Uint8 i;
329  for (i = 0; i < MAX_CONTROLLERS; i += 1) {
330  if (joystick->instance_id == ctx->joysticks[i]) {
331  joystick->nbuttons = 12;
332  joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
333  joystick->epowerlevel = ctx->wireless[i] ? SDL_JOYSTICK_POWER_UNKNOWN : SDL_JOYSTICK_POWER_WIRED;
334  return SDL_TRUE;
335  }
336  }
337  return SDL_FALSE; /* Should never get here! */
338 }
339 
340 static int
341 HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
342 {
343  SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
344  Uint8 i, val;
345  for (i = 0; i < MAX_CONTROLLERS; i += 1) {
346  if (joystick->instance_id == ctx->joysticks[i]) {
347  if (ctx->wireless[i]) {
348  return SDL_SetError("Ninteno GameCube WaveBird controllers do not support rumble");
349  }
350  if (!ctx->rumbleAllowed[i]) {
351  return SDL_SetError("Second USB cable for WUP-028 not connected");
352  }
353  val = (low_frequency_rumble > 0 || high_frequency_rumble > 0);
354  if (val != ctx->rumble[i + 1]) {
355  ctx->rumble[i + 1] = val;
356  ctx->rumbleUpdate = SDL_TRUE;
357  }
358  return 0;
359  }
360  }
361 
362  /* Should never get here! */
363  SDL_SetError("Couldn't find joystick");
364  return -1;
365 }
366 
367 static void
368 HIDAPI_DriverGameCube_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
369 {
370  SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
371 
372  /* Stop rumble activity */
373  if (ctx->rumbleUpdate) {
374  SDL_HIDAPI_SendRumble(device, ctx->rumble, sizeof(ctx->rumble));
375  ctx->rumbleUpdate = SDL_FALSE;
376  }
377 }
378 
379 static void
380 HIDAPI_DriverGameCube_FreeDevice(SDL_HIDAPI_Device *device)
381 {
382  SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
383 
384  hid_close(device->dev);
385  device->dev = NULL;
386 
388  SDL_GameControllerButtonReportingHintChanged, ctx);
389 
390  SDL_free(device->context);
391  device->context = NULL;
392 }
393 
394 SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
395 {
397  SDL_TRUE,
398  HIDAPI_DriverGameCube_IsSupportedDevice,
399  HIDAPI_DriverGameCube_GetDeviceName,
400  HIDAPI_DriverGameCube_InitDevice,
401  HIDAPI_DriverGameCube_GetDevicePlayerIndex,
402  HIDAPI_DriverGameCube_SetDevicePlayerIndex,
403  HIDAPI_DriverGameCube_UpdateDevice,
404  HIDAPI_DriverGameCube_OpenJoystick,
405  HIDAPI_DriverGameCube_RumbleJoystick,
406  HIDAPI_DriverGameCube_CloseJoystick,
407  HIDAPI_DriverGameCube_FreeDevice
408 };
409 
410 #endif /* SDL_JOYSTICK_HIDAPI_GAMECUBE */
411 
412 #endif /* SDL_JOYSTICK_HIDAPI */
413 
414 /* vi: set ts=4 sw=4 expandtab: */
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:386
SDL_CONTROLLER_AXIS_RIGHTX
@ SDL_CONTROLLER_AXIS_RIGHTX
Definition: SDL_gamecontroller.h:307
SDL_events.h
if
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
Definition: pixman-arm-neon-asm.h:469
hid_write
int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length)
Write an Output report to a HID device.
NULL
#define NULL
Definition: begin_code.h:167
SDL_timer.h
HIDAPI_JoystickConnected
SDL_bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID)
SDL_joystick.h
hid_close
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
Close a HID device.
SDL_log.h
SDL_hidapi_rumble.h
SDLCALL
#define SDLCALL
Definition: SDL_internal.h:49
SDL_CONTROLLER_AXIS_LEFTX
@ SDL_CONTROLLER_AXIS_LEFTX
Definition: SDL_gamecontroller.h:305
ctx
EGLContext ctx
Definition: eglext.h:208
SDL_CONTROLLER_BUTTON_B
@ SDL_CONTROLLER_BUTTON_B
Definition: SDL_gamecontroller.h:350
SDL_hidapijoystick_c.h
SDL_JoystickID
Sint32 SDL_JoystickID
Definition: SDL_joystick.h:81
SDL_haptic.h
The SDL haptic subsystem allows you to control haptic (force feedback) devices.
Sint16
int16_t Sint16
Definition: SDL_stdinc.h:185
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER
#define USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER
Definition: usb_ids.h:37
SDL_JOYSTICK_POWER_UNKNOWN
@ SDL_JOYSTICK_POWER_UNKNOWN
Definition: SDL_joystick.h:99
SDL_CONTROLLER_AXIS_TRIGGERLEFT
@ SDL_CONTROLLER_AXIS_TRIGGERLEFT
Definition: SDL_gamecontroller.h:309
SDL_JoystickFromInstanceID
#define SDL_JoystickFromInstanceID
Definition: SDL_dynapi_overrides.h:595
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
hid_read_timeout
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
Read an Input report from a HID device with timeout.
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:663
SDL_JOYSTICK_POWER_WIRED
@ SDL_JOYSTICK_POWER_WIRED
Definition: SDL_joystick.h:104
SDL_CONTROLLER_AXIS_MAX
@ SDL_CONTROLLER_AXIS_MAX
Definition: SDL_gamecontroller.h:311
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:191
SDL_gamecontroller.h
SDL_Delay
#define SDL_Delay
Definition: SDL_dynapi_overrides.h:486
hid_open_path
HID_API_EXPORT hid_device *HID_API_CALL hid_open_path(const char *path, int bExclusive)
Open a HID device by its path name.
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:540
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
USB_VENDOR_NINTENDO
#define USB_VENDOR_NINTENDO
Definition: usb_ids.h:29
HIDAPI_JoystickDisconnected
void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID)
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_AddHintCallback
#define SDL_AddHintCallback
Definition: SDL_dynapi_overrides.h:192
val
GLuint GLfloat * val
Definition: SDL_opengl_glext.h:1495
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_GameControllerType
SDL_GameControllerType
Definition: SDL_gamecontroller.h:60
SDL_hints.h
SDL_CONTROLLER_AXIS_LEFTY
@ SDL_CONTROLLER_AXIS_LEFTY
Definition: SDL_gamecontroller.h:306
SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS
#define SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS
If set, game controller face buttons report their values according to their labels instead of their p...
Definition: SDL_hints.h:556
SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE
#define SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE
A variable controlling whether the HIDAPI driver for Nintendo GameCube controllers should be used.
Definition: SDL_hints.h:650
SDL_HIDAPI_DriverGameCube
SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube
SDL_GetStringBoolean
SDL_bool SDL_GetStringBoolean(const char *value, SDL_bool default_value)
Definition: SDL_hints.c:123
SDL_DelHintCallback
#define SDL_DelHintCallback
Definition: SDL_dynapi_overrides.h:193
SDL_CONTROLLER_AXIS_TRIGGERRIGHT
@ SDL_CONTROLLER_AXIS_TRIGGERRIGHT
Definition: SDL_gamecontroller.h:310
SDL_CONTROLLER_AXIS_RIGHTY
@ SDL_CONTROLLER_AXIS_RIGHTY
Definition: SDL_gamecontroller.h:308
SDL_CONTROLLER_BUTTON_X
@ SDL_CONTROLLER_BUTTON_X
Definition: SDL_gamecontroller.h:351
device
static SDL_AudioDeviceID device
Definition: loopwave.c:37
type
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
button
SDL_Texture * button
Definition: testgamecontroller.c:67
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179