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 ";
217 SDL_JoystickDriver *driver;
233 SDL_JoystickDriver *driver;
234 int player_index = -1;
238 player_index = driver->GetDevicePlayerIndex(device_index);
253 static Uint32 zero_centered_joysticks[] = {
270 if (
id == zero_centered_joysticks[
i]) {
287 SDL_JoystickDriver *driver;
290 SDL_Joystick *joysticklist;
291 const char *joystickname =
NULL;
304 instance_id = driver->GetDeviceInstanceID(device_index);
305 while (joysticklist) {
306 if (instance_id == joysticklist->instance_id) {
312 joysticklist = joysticklist->next;
323 joystick->instance_id = instance_id;
328 if (driver->Open(
joystick, device_index) < 0) {
334 joystickname = driver->GetDeviceName(device_index);
341 joystick->guid = driver->GetDeviceGUID(device_index);
350 joystick->balls = (
struct balldelta *)
SDL_calloc(joystick->nballs,
sizeof(*joystick->balls));
352 if (joystick->nbuttons > 0) {
355 if (((joystick->naxes > 0) && !joystick->axes)
356 || ((joystick->nhats > 0) && !joystick->hats)
357 || ((joystick->nballs > 0) && !joystick->balls)
358 || ((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;
384 driver->Update(joystick);
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;
722 #if !SDL_EVENTS_DISABLED
757 #if !SDL_EVENTS_DISABLED
762 if (device_index < 0) {
769 event.jdevice.which = device_index;
787 if (num_events <= 0) {
797 for (
i = 0;
i < num_events; ++
i) {
807 SDL_Joystick *joystick;
809 #if !SDL_EVENTS_DISABLED
815 event.jdevice.which = device_instance;
823 for (joystick =
SDL_joysticks; joystick; joystick = joystick->next) {
824 if (joystick->instance_id == device_instance) {
826 joystick->force_recentering =
SDL_TRUE;
838 if (
axis >= joystick->naxes) {
841 if (!joystick->axes[
axis].has_initial_value) {
842 joystick->axes[
axis].initial_value =
value;
847 if (
value == joystick->axes[
axis].value) {
850 if (!joystick->axes[
axis].sent_initial_value) {
876 #if !SDL_EVENTS_DISABLED
880 event.jaxis.which = joystick->instance_id;
881 event.jaxis.axis =
axis;
882 event.jaxis.value =
value;
895 if (hat >= joystick->nhats) {
898 if (
value == joystick->hats[hat]) {
912 joystick->hats[hat] =
value;
916 #if !SDL_EVENTS_DISABLED
920 event.jhat.which = joystick->instance_id;
921 event.jhat.hat = hat;
922 event.jhat.value =
value;
936 if (ball >= joystick->nballs) {
946 joystick->balls[ball].dx += xrel;
947 joystick->balls[ball].dy += yrel;
951 #if !SDL_EVENTS_DISABLED
955 event.jball.which = joystick->instance_id;
956 event.jball.ball = ball;
957 event.jball.xrel = xrel;
958 event.jball.yrel = yrel;
969 #if !SDL_EVENTS_DISABLED
986 if (
button >= joystick->nbuttons) {
1006 #if !SDL_EVENTS_DISABLED
1008 event.jbutton.which = joystick->instance_id;
1009 event.jbutton.button =
button;
1010 event.jbutton.state =
state;
1021 SDL_Joystick *joystick;
1040 for (joystick =
SDL_joysticks; joystick; joystick = joystick->next) {
1041 if (joystick->attached) {
1043 if (joystick->driver) {
1044 joystick->driver->Update(joystick);
1047 if (joystick->delayed_guide_button) {
1052 if (joystick->force_recentering) {
1054 for (
i = 0;
i < joystick->naxes;
i++) {
1055 if (joystick->axes[
i].has_initial_value) {
1060 for (
i = 0;
i < joystick->nbuttons;
i++) {
1064 for (
i = 0;
i < joystick->nhats;
i++) {
1068 joystick->force_recentering =
SDL_FALSE;
1077 for (joystick =
SDL_joysticks; joystick; joystick = joystick->next) {
1078 if (joystick->ref_count <= 0) {
1096 #if SDL_EVENTS_DISABLED
1099 const Uint32 event_list[] = {
1131 guid16[1] == 0x0000 &&
1133 guid16[3] == 0x0000 &&
1139 *vendor = guid16[2];
1142 *product = guid16[4];
1145 *version = guid16[6];
1186 if (vendor == 0x0000 && product == 0x0000) {
1189 if (vendor == 0x0001 && product == 0x0001) {
1215 static Uint32 wheel_joysticks[] = {
1233 if (vidpid == wheel_joysticks[
i]) {
1242 static Uint32 flightstick_joysticks[] = {
1249 if (vidpid == flightstick_joysticks[
i]) {
1258 static Uint32 throttle_joysticks[] = {
1265 if (vidpid == throttle_joysticks[
i]) {
1280 switch (guid.
data[15]) {
1329 const char *mapper_processes[] = {
1334 PROCESSENTRY32 pe32;
1338 HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
1339 if (hProcessSnap != INVALID_HANDLE_VALUE) {
1340 pe32.dwSize =
sizeof(PROCESSENTRY32);
1341 if (Process32First(hProcessSnap, &pe32)) {
1349 }
while (Process32Next(hProcessSnap, &pe32) && !found);
1351 CloseHandle(hProcessSnap);
1364 static Uint32 joystick_blacklist[] = {
1471 if (
id == joystick_blacklist[
i]) {
1491 SDL_JoystickDriver *driver;
1496 guid = driver->GetDeviceGUID(device_index);
1548 SDL_JoystickDriver *driver;
1553 instance_id = driver->GetDeviceInstanceID(device_index);
1562 int i, num_joysticks, device_index = -1;
1566 for (
i = 0;
i < num_joysticks; ++
i) {
1574 return device_index;
1584 return joystick->guid;
1621 if (joystick && joystick->is_game_controller) {
1631 static const char k_rgchHexToASCII[] =
"0123456789abcdef";
1634 if ((pszGUID ==
NULL) || (cbGUID <= 0)) {
1638 for (
i = 0;
i <
sizeof(guid.
data) &&
i < (cbGUID-1)/2;
i++) {
1641 unsigned char c = guid.
data[
i];
1643 *pszGUID++ = k_rgchHexToASCII[
c >> 4];
1644 *pszGUID++ = k_rgchHexToASCII[
c & 0x0F];
1656 if ((
c >=
'0') && (
c <=
'9')) {
1657 return (
unsigned char)(
c -
'0');
1660 if ((
c >=
'A') && (
c <=
'F')) {
1661 return (
unsigned char)(
c -
'A' + 0x0a);
1664 if ((
c >=
'a') && (
c <=
'f')) {
1665 return (
unsigned char)(
c -
'a' + 0x0a);
1677 int maxoutputbytes=
sizeof(guid);
1688 for (
i = 0; (
i <
len) && ((
p - (
Uint8 *)&guid) < maxoutputbytes);
i+=2,
p++) {
1698 joystick->epowerlevel = ePowerLevel;
1707 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)
@ k_eControllerType_SteamController
SDL_JoystickType SDL_JoystickGetDeviceType(int device_index)
@ k_eControllerType_SwitchInputOnlyController
#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...
#define SDL_small_free(ptr, isstack)
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)
#define SDL_INIT_JOYSTICK
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
#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)
SDL_JoystickID SDL_GetNextJoystickInstanceID()
int SDL_NumJoysticks(void)
@ SDL_JOYSTICK_TYPE_GUITAR
void SDL_UnlockJoysticks(void)
GLuint GLfloat GLfloat GLfloat x1
SDL_JoystickID SDL_JoystickGetDeviceInstanceID(int device_index)
#define SDL_InitSubSystem
#define SDL_small_alloc(type, count, pisstack)
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_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)
#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)
@ k_eControllerType_SteamControllerV2
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)
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
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)
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)
@ 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