Go to the documentation of this file.
21 #include "../SDL_internal.h"
32 #if !SDL_EVENTS_DISABLED
33 #include "../events/SDL_events_c.h"
35 #include "../video/SDL_sysvideo.h"
42 #include "../core/windows/SDL_windows.h"
49 #if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
52 #ifdef SDL_JOYSTICK_LINUX
55 #ifdef SDL_JOYSTICK_IOKIT
58 #if defined(__IPHONEOS__) || defined(__TVOS__)
61 #ifdef SDL_JOYSTICK_ANDROID
64 #ifdef SDL_JOYSTICK_EMSCRIPTEN
67 #ifdef SDL_JOYSTICK_HAIKU
70 #ifdef SDL_JOYSTICK_USBHID
73 #ifdef SDL_JOYSTICK_HIDAPI
76 #if defined(SDL_JOYSTICK_DUMMY) || defined(SDL_JOYSTICK_DISABLED)
106 if (hint && *hint ==
'1') {
129 #if !SDL_EVENTS_DISABLED
150 int i, total_joysticks = 0;
156 return total_joysticks;
175 int i, num_joysticks, total_joysticks = 0;
177 if (device_index >= 0) {
180 if (device_index < num_joysticks) {
182 *driver_index = device_index;
185 device_index -= num_joysticks;
186 total_joysticks += num_joysticks;
190 SDL_SetError(
"There are %d joysticks available", total_joysticks);
201 const char *skip_prefix =
"NVIDIA Corporation ";
234 int player_index = -1;
253 static Uint32 zero_centered_joysticks[] = {
270 if (
id == zero_centered_joysticks[
i]) {
290 SDL_Joystick *joysticklist;
291 const char *joystickname =
NULL;
305 while (joysticklist) {
306 if (instance_id == joysticklist->instance_id) {
312 joysticklist = joysticklist->next;
323 joystick->instance_id = instance_id;
349 joystick->balls = (
struct balldelta *)
SDL_calloc(joystick->nballs,
sizeof(*joystick->balls));
351 if (joystick->nbuttons > 0) {
354 if (((joystick->naxes > 0) && !joystick->axes)
355 || ((joystick->nhats > 0) && !joystick->hats)
356 || ((joystick->nballs > 0) && !joystick->balls)
357 || ((joystick->nbuttons > 0) && !joystick->buttons)) {
369 for (
i = 0;
i < joystick->naxes; ++
i) {
370 joystick->axes[
i].has_initial_value =
SDL_TRUE;
377 ++joystick->ref_count;
398 if (joystick ==
NULL) {
417 return joystick->naxes;
429 return joystick->nhats;
441 return joystick->nballs;
453 return joystick->nbuttons;
467 if (axis < joystick->naxes) {
470 SDL_SetError(
"Joystick only has %d axes", joystick->naxes);
485 if (
axis >= joystick->naxes) {
486 SDL_SetError(
"Joystick only has %d axes", joystick->naxes);
490 *
state = joystick->axes[
axis].initial_value;
492 return joystick->axes[
axis].has_initial_value;
506 if (hat < joystick->nhats) {
507 state = joystick->hats[hat];
509 SDL_SetError(
"Joystick only has %d hats", joystick->nhats);
528 if (ball < joystick->nballs) {
530 *dx = joystick->balls[ball].dx;
533 *dy = joystick->balls[ball].dy;
535 joystick->balls[ball].dx = 0;
536 joystick->balls[ball].dy = 0;
538 return SDL_SetError(
"Joystick only has %d balls", joystick->nballs);
554 if (button < joystick->nbuttons) {
557 SDL_SetError(
"Joystick only has %d buttons", joystick->nbuttons);
574 return joystick->attached;
587 return joystick->instance_id;
596 SDL_Joystick *joystick;
599 for (joystick =
SDL_joysticks; joystick; joystick = joystick->next) {
600 if (joystick->instance_id == joyid) {
627 return joystick->player_index;
636 return joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble, duration_ms);
645 SDL_Joystick *joysticklist;
646 SDL_Joystick *joysticklistprev;
655 if (--joystick->ref_count > 0) {
665 joystick->driver->Close(joystick);
666 joystick->hwdata =
NULL;
669 joysticklistprev =
NULL;
670 while (joysticklist) {
671 if (joystick == joysticklist) {
672 if (joysticklistprev) {
674 joysticklistprev->next = joysticklist->next;
680 joysticklistprev = joysticklist;
681 joysticklist = joysticklist->next;
719 #if !SDL_EVENTS_DISABLED
753 #if !SDL_EVENTS_DISABLED
758 if (device_index < 0) {
765 event.jdevice.which = device_index;
782 if (num_events <= 0) {
792 for (
i = 0;
i < num_events; ++
i) {
802 SDL_Joystick *joystick;
804 #if !SDL_EVENTS_DISABLED
810 event.jdevice.which = device_instance;
818 for (joystick =
SDL_joysticks; joystick; joystick = joystick->next) {
819 if (joystick->instance_id == device_instance) {
821 joystick->force_recentering =
SDL_TRUE;
833 if (
axis >= joystick->naxes) {
836 if (!joystick->axes[
axis].has_initial_value) {
837 joystick->axes[
axis].initial_value =
value;
842 if (
value == joystick->axes[
axis].value) {
845 if (!joystick->axes[
axis].sent_initial_value) {
871 #if !SDL_EVENTS_DISABLED
875 event.jaxis.which = joystick->instance_id;
876 event.jaxis.axis =
axis;
877 event.jaxis.value =
value;
890 if (hat >= joystick->nhats) {
893 if (
value == joystick->hats[hat]) {
907 joystick->hats[hat] =
value;
911 #if !SDL_EVENTS_DISABLED
915 event.jhat.which = joystick->instance_id;
916 event.jhat.hat = hat;
917 event.jhat.value =
value;
931 if (ball >= joystick->nballs) {
941 joystick->balls[ball].dx += xrel;
942 joystick->balls[ball].dy += yrel;
946 #if !SDL_EVENTS_DISABLED
950 event.jball.which = joystick->instance_id;
951 event.jball.ball = ball;
952 event.jball.xrel = xrel;
953 event.jball.yrel = yrel;
964 #if !SDL_EVENTS_DISABLED
981 if (
button >= joystick->nbuttons) {
1001 #if !SDL_EVENTS_DISABLED
1003 event.jbutton.which = joystick->instance_id;
1004 event.jbutton.button =
button;
1005 event.jbutton.state =
state;
1016 SDL_Joystick *joystick;
1031 for (joystick =
SDL_joysticks; joystick; joystick = joystick->next) {
1032 if (joystick->attached) {
1033 joystick->driver->Update(joystick);
1035 if (joystick->delayed_guide_button) {
1040 if (joystick->force_recentering) {
1042 for (
i = 0;
i < joystick->naxes;
i++) {
1043 if (joystick->axes[
i].has_initial_value) {
1048 for (
i = 0;
i < joystick->nbuttons;
i++) {
1052 for (
i = 0;
i < joystick->nhats;
i++) {
1056 joystick->force_recentering =
SDL_FALSE;
1065 for (joystick =
SDL_joysticks; joystick; joystick = joystick->next) {
1066 if (joystick->ref_count <= 0) {
1084 #if SDL_EVENTS_DISABLED
1087 const Uint32 event_list[] = {
1119 guid16[1] == 0x0000 &&
1121 guid16[3] == 0x0000 &&
1127 *vendor = guid16[2];
1130 *product = guid16[4];
1133 *version = guid16[6];
1170 if (vendor == 0x0000 && product == 0x0000) {
1173 if (vendor == 0x0001 && product == 0x0001) {
1199 static Uint32 wheel_joysticks[] = {
1217 if (vidpid == wheel_joysticks[
i]) {
1226 static Uint32 flightstick_joysticks[] = {
1233 if (vidpid == flightstick_joysticks[
i]) {
1242 static Uint32 throttle_joysticks[] = {
1249 if (vidpid == throttle_joysticks[
i]) {
1264 switch (guid.
data[15]) {
1313 const char *mapper_processes[] = {
1318 PROCESSENTRY32 pe32;
1322 HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
1323 if (hProcessSnap != INVALID_HANDLE_VALUE) {
1324 pe32.dwSize =
sizeof(PROCESSENTRY32);
1325 if (Process32First(hProcessSnap, &pe32)) {
1333 }
while (Process32Next(hProcessSnap, &pe32) && !found);
1335 CloseHandle(hProcessSnap);
1436 int i, num_joysticks, device_index = -1;
1440 for (
i = 0;
i < num_joysticks; ++
i) {
1448 return device_index;
1458 return joystick->guid;
1495 if (joystick && joystick->is_game_controller) {
1505 static const char k_rgchHexToASCII[] =
"0123456789abcdef";
1508 if ((pszGUID ==
NULL) || (cbGUID <= 0)) {
1512 for (
i = 0;
i <
sizeof(guid.
data) &&
i < (cbGUID-1)/2;
i++) {
1515 unsigned char c = guid.
data[
i];
1517 *pszGUID++ = k_rgchHexToASCII[
c >> 4];
1518 *pszGUID++ = k_rgchHexToASCII[
c & 0x0F];
1530 if ((
c >=
'0') && (
c <=
'9')) {
1531 return (
unsigned char)(
c -
'0');
1534 if ((
c >=
'A') && (
c <=
'F')) {
1535 return (
unsigned char)(
c -
'A' + 0x0a);
1538 if ((
c >=
'a') && (
c <=
'f')) {
1539 return (
unsigned char)(
c -
'a' + 0x0a);
1551 int maxoutputbytes=
sizeof(guid);
1562 for (
i = 0; (
i <
len) && ((
p - (
Uint8 *)&guid) < maxoutputbytes);
i+=2,
p++) {
1572 joystick->epowerlevel = ePowerLevel;
1581 return joystick->epowerlevel;
int SDL_JoystickEventState(int state)
@ SDL_JOYSTICK_TYPE_GAMECONTROLLER
SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
SDL_bool SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid)
SDL_JoystickType SDL_JoystickGetDeviceType(int device_index)
#define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS
A variable that lets you enable joystick (and gamecontroller) events even when your app is in the bac...
int SDL_JoystickNumButtons(SDL_Joystick *joystick)
#define SDL_IsGameController
void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID)
static SDL_bool SDL_JoystickAxesCenteredAtZero(SDL_Joystick *joystick)
SDL_bool SDL_JoystickGetAxisInitialState(SDL_Joystick *joystick, int axis, Sint16 *state)
int SDL_JoystickInit(void)
const char * SDL_JoystickNameForIndex(int device_index)
@ k_eControllerType_SwitchProController
int SDL_JoystickGetDeviceIndexFromInstanceID(SDL_JoystickID instance_id)
SDL_bool SDL_IsJoystickNintendoSwitchPro(Uint16 vendor, Uint16 product)
static SDL_bool SDL_IsPS4RemapperRunning(void)
static const char * SDL_FixupJoystickName(const char *name)
SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID)
SDL_Joystick * SDL_JoystickFromInstanceID(SDL_JoystickID joyid)
SDL_JoystickDriver SDL_BSD_JoystickDriver
SDL_bool SDL_IsJoystickPS4(Uint16 vendor, Uint16 product)
static SDL_bool SDL_joystick_allows_background_events
SDL_JoystickID(* GetDeviceInstanceID)(int device_index)
#define SDL_AtomicIncRef(a)
Increment an atomic variable used as a reference count.
#define SDL_QuitSubSystem
SDL_JoyDeviceEvent jdevice
void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
int(* Open)(SDL_Joystick *joystick, int device_index)
SDL_JoystickID SDL_GetNextJoystickInstanceID()
int SDL_NumJoysticks(void)
static SDL_bool BIsSteamController(EControllerType eType)
@ SDL_JOYSTICK_TYPE_GUITAR
void SDL_UnlockJoysticks(void)
GLuint GLfloat GLfloat GLfloat x1
SDL_JoystickID SDL_JoystickGetDeviceInstanceID(int device_index)
#define SDL_InitSubSystem
SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor, Uint16 product)
Sint16 SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis)
SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
@ SDL_JOYSTICK_TYPE_DANCE_PAD
Uint16 SDL_JoystickGetVendor(SDL_Joystick *joystick)
#define SDL_stack_alloc(type, count)
#define SDL_GetKeyboardFocus
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
@ k_eControllerType_PS4Controller
SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick *joystick)
@ SDL_JOYSTICK_TYPE_DRUM_KIT
Uint16 SDL_JoystickGetDeviceProduct(int device_index)
void SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick)
SDL_bool SDL_IsJoystickSteamController(Uint16 vendor, Uint16 product)
SDL_JoystickID SDL_JoystickInstanceID(SDL_Joystick *joystick)
SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid)
int SDL_JoystickGetPlayerIndex(SDL_Joystick *joystick)
void(* Update)(SDL_Joystick *joystick)
#define SDL_GetEventState(type)
@ k_eControllerType_XBox360Controller
@ SDL_JOYSTICK_POWER_UNKNOWN
int SDL_PrivateJoystickValid(SDL_Joystick *joystick)
void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version)
static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_JoystickGUID guid)
SDL_JoystickDriver SDL_HAIKU_JoystickDriver
static SDL_bool SDL_updating_joystick
@ SDL_JOYSTICK_TYPE_FLIGHT_STICK
static void UpdateEventsForDeviceRemoval()
Uint16 SDL_JoystickGetProductVersion(SDL_Joystick *joystick)
SDL_JoystickDriver SDL_DARWIN_JoystickDriver
static SDL_bool SDL_PrivateJoystickShouldIgnoreEvent()
SDL_bool SDL_IsJoystickXbox360(Uint16 vendor, Uint16 product)
GLuint const GLchar * name
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
@ SDL_JOYSTICK_TYPE_THROTTLE
void SDL_JoystickQuit(void)
Uint16 SDL_JoystickGetDeviceProductVersion(int device_index)
int SDL_GameControllerInitMappings(void)
SDL_JoystickDriver SDL_DUMMY_JoystickDriver
static unsigned char nibble(char c)
SDL_bool SDL_GetDriverAndJoystickIndex(int device_index, SDL_JoystickDriver **driver, int *driver_index)
static EControllerType GuessControllerType(int nVID, int nPID)
#define MAKE_VIDPID(VID, PID)
static SDL_atomic_t SDL_next_joystick_instance_id
int SDL_PrivateJoystickBall(SDL_Joystick *joystick, Uint8 ball, Sint16 xrel, Sint16 yrel)
int SDL_JoystickNumAxes(SDL_Joystick *joystick)
void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel)
static void SDL_JoystickAllowBackgroundEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
Uint16 SDL_JoystickGetProduct(SDL_Joystick *joystick)
static SDL_mutex * SDL_joystick_lock
#define SDL_JOYSTICK_AXIS_MAX
@ k_eControllerType_UnknownNonSteamController
void SDL_LockJoysticks(void)
int SDL_JoystickGetDevicePlayerIndex(int device_index)
#define SDL_assert(condition)
static SDL_JoystickDriver * SDL_joystick_drivers[]
SDL_JoystickType SDL_JoystickGetType(SDL_Joystick *joystick)
Uint16 SDL_JoystickGetDeviceVendor(int device_index)
SDL_JoystickDriver SDL_WINDOWS_JoystickDriver
const char * SDL_JoystickName(SDL_Joystick *joystick)
#define SDL_OutOfMemory()
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
SDL_bool SDL_JoystickGetAttached(SDL_Joystick *joystick)
#define SDL_arraysize(array)
void SDL_GameControllerQuitMappings(void)
static SDL_Event events[EVENT_BUF_SIZE]
static SDL_bool SDL_IsJoystickProductFlightStick(Uint32 vidpid)
#define SDL_AddHintCallback
const char *(* GetDeviceName)(int device_index)
#define SDL_stack_free(data)
void SDL_JoystickClose(SDL_Joystick *joystick)
int SDL_JoystickNumHats(SDL_Joystick *joystick)
GLsizei const GLfloat * value
SDL_bool SDL_IsGameControllerNameAndGUID(const char *name, SDL_JoystickGUID guid)
A type representing an atomic integer value. It is a struct so people don't accidentally use numeric ...
@ SDL_JOYSTICK_TYPE_ARCADE_PAD
SDL_bool SDL_HasWindows(void)
void SDL_JoystickUpdate(void)
int SDL_JoystickNumBalls(SDL_Joystick *joystick)
static SDL_Joystick * SDL_joysticks
SDL_JoystickDriver SDL_LINUX_JoystickDriver
int SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
Uint8 SDL_JoystickGetHat(SDL_Joystick *joystick, int hat)
SDL_JoystickGUID(* GetDeviceGUID)(int device_index)
static SDL_bool SDL_IsJoystickProductThrottle(Uint32 vidpid)
int SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy)
SDL_JoystickDriver SDL_IOS_JoystickDriver
#define SDL_DelHintCallback
SDL_JoystickGUID SDL_JoystickGetDeviceGUID(int device_index)
SDL_Joystick * SDL_JoystickOpen(int device_index)
int(* GetDevicePlayerIndex)(int device_index)
@ SDL_JOYSTICK_TYPE_WHEEL
Uint8 SDL_JoystickGetButton(SDL_Joystick *joystick, int button)
GLuint GLuint GLsizei GLenum type
SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver
SDL_JoystickPowerLevel SDL_JoystickCurrentPowerLevel(SDL_Joystick *joystick)
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)
@ SDL_JOYSTICK_TYPE_UNKNOWN
@ k_eControllerType_XBoxOneController
SDL_JoystickDriver SDL_HIDAPI_JoystickDriver
@ SDL_JOYSTICK_TYPE_ARCADE_STICK
SDL_JoystickDriver SDL_ANDROID_JoystickDriver