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[] = {
264 if (joystick->naxes == 2) {
270 if (
id == zero_centered_joysticks[
i]) {
289 SDL_Joystick *joystick;
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) {
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]) {
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;
#define SDL_INIT_JOYSTICK
#define SDL_AtomicIncRef(a)
Increment an atomic variable used as a reference count.
#define SDL_InitSubSystem
#define SDL_DelHintCallback
#define SDL_GetKeyboardFocus
#define SDL_AddHintCallback
#define SDL_QuitSubSystem
#define SDL_IsGameController
#define SDL_OutOfMemory()
#define SDL_GetEventState(type)
void SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick)
void SDL_GameControllerQuitMappings(void)
SDL_bool SDL_IsGameControllerNameAndGUID(const char *name, SDL_JoystickGUID guid)
SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
int SDL_GameControllerInitMappings(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...
#define SDL_small_alloc(type, count, pisstack)
#define SDL_small_free(ptr, isstack)
SDL_bool SDL_JoystickGetAxisInitialState(SDL_Joystick *joystick, int axis, Sint16 *state)
SDL_JoystickID SDL_JoystickGetDeviceInstanceID(int device_index)
Uint16 SDL_JoystickGetProductVersion(SDL_Joystick *joystick)
int SDL_JoystickGetPlayerIndex(SDL_Joystick *joystick)
SDL_JoystickGUID SDL_JoystickGetDeviceGUID(int device_index)
Uint8 SDL_JoystickGetButton(SDL_Joystick *joystick, int button)
static SDL_JoystickDriver * SDL_joystick_drivers[]
static SDL_bool SDL_JoystickAxesCenteredAtZero(SDL_Joystick *joystick)
SDL_JoystickID SDL_JoystickInstanceID(SDL_Joystick *joystick)
int SDL_PrivateJoystickBall(SDL_Joystick *joystick, Uint8 ball, Sint16 xrel, Sint16 yrel)
int SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy)
SDL_bool SDL_IsJoystickXbox360(Uint16 vendor, Uint16 product)
SDL_JoystickPowerLevel SDL_JoystickCurrentPowerLevel(SDL_Joystick *joystick)
static SDL_bool SDL_PrivateJoystickShouldIgnoreEvent()
void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel)
const char * SDL_JoystickNameForIndex(int device_index)
static unsigned char nibble(char c)
int SDL_NumJoysticks(void)
static SDL_bool SDL_IsJoystickProductFlightStick(Uint32 vidpid)
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Uint16 SDL_JoystickGetDeviceProduct(int device_index)
Uint16 SDL_JoystickGetDeviceProductVersion(int device_index)
SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID)
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
int SDL_JoystickInit(void)
SDL_bool SDL_GetDriverAndJoystickIndex(int device_index, SDL_JoystickDriver **driver, int *driver_index)
Uint16 SDL_JoystickGetDeviceVendor(int device_index)
SDL_Joystick * SDL_JoystickOpen(int device_index)
SDL_bool SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid)
static void SDL_JoystickAllowBackgroundEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
int SDL_JoystickNumBalls(SDL_Joystick *joystick)
SDL_Joystick * SDL_JoystickFromInstanceID(SDL_JoystickID joyid)
int SDL_JoystickNumHats(SDL_Joystick *joystick)
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
void SDL_JoystickQuit(void)
void SDL_JoystickClose(SDL_Joystick *joystick)
SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick *joystick)
SDL_bool SDL_IsJoystickPS4(Uint16 vendor, Uint16 product)
int SDL_JoystickGetDevicePlayerIndex(int device_index)
SDL_bool SDL_JoystickGetAttached(SDL_Joystick *joystick)
SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor, Uint16 product)
Uint16 SDL_JoystickGetProduct(SDL_Joystick *joystick)
static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
SDL_bool SDL_IsJoystickNintendoSwitchPro(Uint16 vendor, Uint16 product)
void SDL_LockJoysticks(void)
static void UpdateEventsForDeviceRemoval()
void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version)
static SDL_bool SDL_IsJoystickProductThrottle(Uint32 vidpid)
static SDL_bool SDL_joystick_allows_background_events
static SDL_mutex * SDL_joystick_lock
Uint16 SDL_JoystickGetVendor(SDL_Joystick *joystick)
SDL_JoystickType SDL_JoystickGetType(SDL_Joystick *joystick)
SDL_bool SDL_IsJoystickSteamController(Uint16 vendor, Uint16 product)
static SDL_bool SDL_updating_joystick
int SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID)
void SDL_UnlockJoysticks(void)
static const char * SDL_FixupJoystickName(const char *name)
Uint8 SDL_JoystickGetHat(SDL_Joystick *joystick, int hat)
static SDL_bool SDL_IsPS4RemapperRunning(void)
void SDL_JoystickUpdate(void)
int SDL_JoystickEventState(int state)
static SDL_Joystick * SDL_joysticks
SDL_JoystickType SDL_JoystickGetDeviceType(int device_index)
static SDL_atomic_t SDL_next_joystick_instance_id
int SDL_JoystickNumAxes(SDL_Joystick *joystick)
const char * SDL_JoystickName(SDL_Joystick *joystick)
static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_JoystickGUID guid)
SDL_JoystickID SDL_GetNextJoystickInstanceID()
Sint16 SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis)
int SDL_PrivateJoystickValid(SDL_Joystick *joystick)
int SDL_JoystickGetDeviceIndexFromInstanceID(SDL_JoystickID instance_id)
SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
int SDL_JoystickNumButtons(SDL_Joystick *joystick)
@ SDL_JOYSTICK_TYPE_DANCE_PAD
@ SDL_JOYSTICK_TYPE_ARCADE_PAD
@ SDL_JOYSTICK_TYPE_UNKNOWN
@ SDL_JOYSTICK_TYPE_ARCADE_STICK
@ SDL_JOYSTICK_TYPE_WHEEL
@ SDL_JOYSTICK_TYPE_THROTTLE
@ SDL_JOYSTICK_TYPE_GUITAR
@ SDL_JOYSTICK_TYPE_FLIGHT_STICK
@ SDL_JOYSTICK_TYPE_GAMECONTROLLER
@ SDL_JOYSTICK_TYPE_DRUM_KIT
@ SDL_JOYSTICK_POWER_UNKNOWN
#define SDL_JOYSTICK_AXIS_MAX
GLuint GLuint GLsizei GLenum type
GLuint const GLchar * name
GLsizei const GLfloat * value
#define SDL_arraysize(array)
SDL_JoystickDriver SDL_BSD_JoystickDriver
SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver
SDL_JoystickDriver SDL_ANDROID_JoystickDriver
SDL_JoystickDriver SDL_DUMMY_JoystickDriver
SDL_JoystickDriver SDL_LINUX_JoystickDriver
SDL_JoystickDriver SDL_HIDAPI_JoystickDriver
SDL_JoystickDriver SDL_DARWIN_JoystickDriver
#define MAKE_VIDPID(VID, PID)
SDL_JoystickDriver SDL_WINDOWS_JoystickDriver
SDL_JoystickDriver SDL_HAIKU_JoystickDriver
SDL_JoystickDriver SDL_IOS_JoystickDriver
SDL_bool SDL_HasWindows(void)
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)
@ k_eControllerType_SteamController
@ k_eControllerType_SteamControllerV2
@ k_eControllerType_SwitchProController
@ k_eControllerType_PS4Controller
@ k_eControllerType_XBox360Controller
@ k_eControllerType_XBoxOneController
@ k_eControllerType_UnknownNonSteamController
@ k_eControllerType_SwitchInputOnlyController
static EControllerType GuessControllerType(int nVID, int nPID)
SDL_JoystickGUID(* GetDeviceGUID)(int device_index)
SDL_JoystickID(* GetDeviceInstanceID)(int device_index)
void(* Update)(SDL_Joystick *joystick)
int(* GetDevicePlayerIndex)(int device_index)
const char *(* GetDeviceName)(int device_index)
int(* Open)(SDL_Joystick *joystick, int device_index)
A type representing an atomic integer value. It is a struct so people don't accidentally use numeric ...
static SDL_Event events[EVENT_BUF_SIZE]
SDL_JoyDeviceEvent jdevice