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) 89 if (SDL_joystick_lock) {
97 if (SDL_joystick_lock) {
106 if (hint && *hint ==
'1') {
121 if (!SDL_joystick_lock) {
129 #if !SDL_EVENTS_DISABLED 137 if (SDL_joystick_drivers[i]->Init() >= 0) {
150 int i, total_joysticks = 0;
153 total_joysticks += SDL_joystick_drivers[
i]->
GetCount();
156 return total_joysticks;
175 int i, num_joysticks, total_joysticks = 0;
177 if (device_index >= 0) {
179 num_joysticks = SDL_joystick_drivers[
i]->
GetCount();
180 if (device_index < num_joysticks) {
181 *driver = SDL_joystick_drivers[
i];
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[] = {
264 if (joystick->naxes == 2) {
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) {
307 joystick = joysticklist;
308 ++joystick->ref_count;
312 joysticklist = joysticklist->next;
316 joystick = (SDL_Joystick *)
SDL_calloc(
sizeof(*joystick), 1);
317 if (joystick ==
NULL) {
322 joystick->driver = driver;
323 joystick->instance_id = instance_id;
325 joystick->player_index = -1;
328 if (driver->
Open(joystick, device_index) < 0) {
338 joystick->name =
NULL;
343 if (joystick->naxes > 0) {
346 if (joystick->nhats > 0) {
349 if (joystick->nballs > 0) {
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;
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) {
468 state = joystick->axes[
axis].value;
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) {
555 state = joystick->buttons[
button];
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;
717 SDL_joystick_drivers[
i]->
Quit();
722 #if !SDL_EVENTS_DISABLED 729 if (SDL_joystick_lock) {
731 SDL_joystick_lock =
NULL;
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) {
853 if (
SDL_abs(value - joystick->axes[axis].value) <= MAX_ALLOWED_JITTER) {
865 if ((value > joystick->axes[axis].zero && value >= joystick->axes[axis].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) {
989 if (state == joystick->buttons[button]) {
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) {
1087 SDL_joystick_drivers[
i]->
Detect();
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]) {
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;
static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
Uint16 SDL_JoystickGetVendor(SDL_Joystick *joystick)
void SDL_JoystickUpdate(void)
#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...
void SDL_LockJoysticks(void)
int SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy)
int SDL_PrivateJoystickValid(SDL_Joystick *joystick)
SDL_JoyDeviceEvent jdevice
GLuint GLfloat GLfloat GLfloat x1
SDL_bool SDL_JoystickGetAxisInitialState(SDL_Joystick *joystick, int axis, Sint16 *state)
#define MAKE_VIDPID(VID, PID)
void SDL_JoystickClose(SDL_Joystick *joystick)
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
Uint16 SDL_JoystickGetProduct(SDL_Joystick *joystick)
void SDL_GameControllerQuitMappings(void)
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
int SDL_JoystickGetPlayerIndex(SDL_Joystick *joystick)
#define SDL_INIT_JOYSTICK
int SDL_GameControllerInitMappings(void)
#define SDL_IsGameController
SDL_bool SDL_IsJoystickPS4(Uint16 vendor, Uint16 product)
A type representing an atomic integer value. It is a struct so people don't accidentally use numeric ...
SDL_bool SDL_IsJoystickSteamController(Uint16 vendor, Uint16 product)
SDL_JoystickDriver SDL_DUMMY_JoystickDriver
int SDL_JoystickGetDeviceIndexFromInstanceID(SDL_JoystickID instance_id)
SDL_bool SDL_IsJoystickNintendoSwitchPro(Uint16 vendor, Uint16 product)
static SDL_mutex * SDL_joystick_lock
SDL_JoystickID(* GetDeviceInstanceID)(int device_index)
#define SDL_QuitSubSystem
int SDL_JoystickInit(void)
static SDL_Event events[EVENT_BUF_SIZE]
SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
int SDL_JoystickNumHats(SDL_Joystick *joystick)
static SDL_atomic_t SDL_next_joystick_instance_id
void SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick)
static EControllerType GuessControllerType(int nVID, int nPID)
#define SDL_InitSubSystem
Uint16 SDL_JoystickGetDeviceProduct(int device_index)
Uint16 SDL_JoystickGetProductVersion(SDL_Joystick *joystick)
#define SDL_GetKeyboardFocus
int SDL_JoystickGetDevicePlayerIndex(int device_index)
Uint16 SDL_JoystickGetDeviceProductVersion(int device_index)
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
GLuint const GLchar * name
SDL_JoystickPowerLevel SDL_JoystickCurrentPowerLevel(SDL_Joystick *joystick)
SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor, Uint16 product)
SDL_JoystickDriver SDL_DARWIN_JoystickDriver
SDL_JoystickDriver SDL_IOS_JoystickDriver
static SDL_bool SDL_IsJoystickProductFlightStick(Uint32 vidpid)
SDL_JoystickDriver SDL_WINDOWS_JoystickDriver
#define SDL_small_alloc(type, count, pisstack)
static void UpdateEventsForDeviceRemoval()
const char * SDL_JoystickName(SDL_Joystick *joystick)
int SDL_JoystickEventState(int state)
#define SDL_JOYSTICK_AXIS_MAX
int SDL_PrivateJoystickBall(SDL_Joystick *joystick, Uint8 ball, Sint16 xrel, Sint16 yrel)
int SDL_NumJoysticks(void)
static SDL_JoystickDriver * SDL_joystick_drivers[]
static SDL_bool SDL_joystick_allows_background_events
#define SDL_GetEventState(type)
static SDL_bool SDL_IsPS4RemapperRunning(void)
SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick *joystick)
const char *(* GetDeviceName)(int device_index)
SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid)
GLsizei const GLfloat * value
SDL_bool SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid)
SDL_Joystick * SDL_JoystickOpen(int device_index)
SDL_JoystickDriver SDL_LINUX_JoystickDriver
void SDL_UnlockJoysticks(void)
SDL_JoystickDriver SDL_HIDAPI_JoystickDriver
int SDL_JoystickNumAxes(SDL_Joystick *joystick)
void(* Update)(SDL_Joystick *joystick)
#define SDL_AtomicIncRef(a)
Increment an atomic variable used as a reference count.
static const char * SDL_FixupJoystickName(const char *name)
SDL_Joystick * SDL_JoystickFromInstanceID(SDL_JoystickID joyid)
SDL_JoystickGUID(* GetDeviceGUID)(int device_index)
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_bool SDL_IsGameControllerNameAndGUID(const char *name, SDL_JoystickGUID guid)
SDL_JoystickGUID SDL_JoystickGetDeviceGUID(int device_index)
SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID)
SDL_JoystickID SDL_JoystickGetDeviceInstanceID(int device_index)
void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
int SDL_JoystickNumBalls(SDL_Joystick *joystick)
#define SDL_OutOfMemory()
int(* Open)(SDL_Joystick *joystick, int device_index)
SDL_JoystickDriver SDL_ANDROID_JoystickDriver
static unsigned char nibble(char c)
int(* GetDevicePlayerIndex)(int device_index)
SDL_JoystickDriver SDL_HAIKU_JoystickDriver
SDL_JoystickID SDL_JoystickInstanceID(SDL_Joystick *joystick)
int SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
SDL_bool SDL_HasWindows(void)
void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version)
SDL_JoystickID SDL_GetNextJoystickInstanceID()
void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel)
SDL_bool SDL_IsJoystickXbox360(Uint16 vendor, Uint16 product)
#define SDL_AddHintCallback
#define SDL_small_free(ptr, isstack)
int SDL_JoystickNumButtons(SDL_Joystick *joystick)
#define SDL_DelHintCallback
void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID)
GLuint GLuint GLsizei GLenum type
static SDL_bool SDL_JoystickAxesCenteredAtZero(SDL_Joystick *joystick)
static SDL_bool SDL_PrivateJoystickShouldIgnoreEvent()
#define SDL_arraysize(array)
Uint8 SDL_JoystickGetButton(SDL_Joystick *joystick, int button)
SDL_JoystickDriver SDL_BSD_JoystickDriver
Uint8 SDL_JoystickGetHat(SDL_Joystick *joystick, int hat)
void SDL_JoystickQuit(void)
static void SDL_JoystickAllowBackgroundEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
SDL_bool SDL_GetDriverAndJoystickIndex(int device_index, SDL_JoystickDriver **driver, int *driver_index)
SDL_bool SDL_JoystickGetAttached(SDL_Joystick *joystick)
static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_JoystickGUID guid)
SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver
Uint16 SDL_JoystickGetDeviceVendor(int device_index)
SDL_JoystickType SDL_JoystickGetDeviceType(int device_index)
static SDL_bool SDL_updating_joystick
SDL_JoystickType SDL_JoystickGetType(SDL_Joystick *joystick)
const char * SDL_JoystickNameForIndex(int device_index)
static SDL_bool SDL_IsJoystickProductThrottle(Uint32 vidpid)
static SDL_Joystick * SDL_joysticks
Sint16 SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis)