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;
327 if (driver->
Open(joystick, device_index) < 0) {
337 joystick->name =
NULL;
342 if (joystick->naxes > 0) {
345 if (joystick->nhats > 0) {
348 if (joystick->nballs > 0) {
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) {
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;
714 SDL_joystick_drivers[
i]->
Quit();
719 #if !SDL_EVENTS_DISABLED 726 if (SDL_joystick_lock) {
728 SDL_joystick_lock =
NULL;
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) {
848 if (
SDL_abs(value - joystick->axes[axis].value) <= MAX_ALLOWED_JITTER) {
860 if ((value > joystick->axes[axis].zero && value >= joystick->axes[axis].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) {
984 if (state == joystick->buttons[button]) {
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) {
1075 SDL_joystick_drivers[
i]->
Detect();
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;
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)
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)
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 ®2 endm macro vzip8 reg2 vzip d d ®2 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 local skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
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
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)
#define SDL_stack_alloc(type, count)
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
static SDL_bool BIsSteamController(EControllerType eType)
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)
#define SDL_assert(condition)
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
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)
#define SDL_stack_free(data)
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)