21 #include "../SDL_internal.h"
32 #if !SDL_EVENTS_DISABLED
33 #include "../events/SDL_events_c.h"
35 #include "../video/SDL_sysvideo.h"
43 #include "../core/windows/SDL_windows.h"
50 #if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
53 #ifdef SDL_JOYSTICK_LINUX
56 #ifdef SDL_JOYSTICK_IOKIT
59 #if defined(__IPHONEOS__) || defined(__TVOS__)
62 #ifdef SDL_JOYSTICK_ANDROID
65 #ifdef SDL_JOYSTICK_EMSCRIPTEN
68 #ifdef SDL_JOYSTICK_HAIKU
71 #ifdef SDL_JOYSTICK_USBHID
74 #ifdef SDL_JOYSTICK_HIDAPI
77 #if defined(SDL_JOYSTICK_DUMMY) || defined(SDL_JOYSTICK_DISABLED)
147 SDL_JoystickDriver *driver;
149 int existing_player_index;
151 if (player_index < 0) {
171 if (existing_player_index >= 0) {
180 driver->SetDevicePlayerIndex(device_index, player_index);
184 if (existing_instance >= 0) {
193 if (hint && *hint ==
'1') {
216 #if !SDL_EVENTS_DISABLED
237 int i, total_joysticks = 0;
243 return total_joysticks;
262 int i, num_joysticks, total_joysticks = 0;
264 if (device_index >= 0) {
267 if (device_index < num_joysticks) {
269 *driver_index = device_index;
272 device_index -= num_joysticks;
273 total_joysticks += num_joysticks;
277 SDL_SetError(
"There are %d joysticks available", total_joysticks);
288 const char *skip_prefix =
"NVIDIA Corporation ";
304 SDL_JoystickDriver *driver;
340 static Uint32 zero_centered_joysticks[] = {
357 if (
id == zero_centered_joysticks[
i]) {
374 SDL_JoystickDriver *driver;
377 SDL_Joystick *joysticklist;
378 const char *joystickname =
NULL;
391 instance_id = driver->GetDeviceInstanceID(device_index);
392 while (joysticklist) {
393 if (instance_id == joysticklist->instance_id) {
399 joysticklist = joysticklist->next;
410 joystick->instance_id = instance_id;
414 if (driver->Open(
joystick, device_index) < 0) {
420 joystickname = driver->GetDeviceName(device_index);
427 joystick->guid = driver->GetDeviceGUID(device_index);
436 joystick->balls = (
struct balldelta *)
SDL_calloc(joystick->nballs,
sizeof(*joystick->balls));
438 if (joystick->nbuttons > 0) {
441 if (((joystick->naxes > 0) && !joystick->axes)
442 || ((joystick->nhats > 0) && !joystick->hats)
443 || ((joystick->nballs > 0) && !joystick->balls)
444 || ((joystick->nbuttons > 0) && !joystick->buttons)) {
455 for (
i = 0;
i < joystick->naxes; ++
i) {
456 joystick->axes[
i].has_initial_value =
SDL_TRUE;
463 ++joystick->ref_count;
470 driver->Update(joystick);
484 if (joystick ==
NULL) {
503 return joystick->naxes;
515 return joystick->nhats;
527 return joystick->nballs;
539 return joystick->nbuttons;
553 if (axis < joystick->naxes) {
556 SDL_SetError(
"Joystick only has %d axes", joystick->naxes);
571 if (
axis >= joystick->naxes) {
572 SDL_SetError(
"Joystick only has %d axes", joystick->naxes);
576 *
state = joystick->axes[
axis].initial_value;
578 return joystick->axes[
axis].has_initial_value;
592 if (hat < joystick->nhats) {
593 state = joystick->hats[hat];
595 SDL_SetError(
"Joystick only has %d hats", joystick->nhats);
614 if (ball < joystick->nballs) {
616 *dx = joystick->balls[ball].dx;
619 *dy = joystick->balls[ball].dy;
621 joystick->balls[ball].dx = 0;
622 joystick->balls[ball].dy = 0;
624 return SDL_SetError(
"Joystick only has %d balls", joystick->nballs);
640 if (button < joystick->nbuttons) {
643 SDL_SetError(
"Joystick only has %d buttons", joystick->nbuttons);
660 return joystick->attached;
673 return joystick->instance_id;
682 SDL_Joystick *joystick;
685 for (joystick =
SDL_joysticks; joystick; joystick = joystick->next) {
686 if (joystick->instance_id == instance_id) {
701 SDL_Joystick *joystick;
705 for (joystick =
SDL_joysticks; joystick; joystick = joystick->next) {
706 if (joystick->instance_id == instance_id) {
771 if (low_frequency_rumble == joystick->low_frequency_rumble &&
772 high_frequency_rumble == joystick->high_frequency_rumble) {
776 result = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble);
780 joystick->low_frequency_rumble = low_frequency_rumble;
781 joystick->high_frequency_rumble = high_frequency_rumble;
783 if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
785 if (!joystick->rumble_expiration) {
786 joystick->rumble_expiration = 1;
789 joystick->rumble_expiration = 0;
802 SDL_Joystick *joysticklist;
803 SDL_Joystick *joysticklistprev;
812 if (--joystick->ref_count > 0) {
822 if (joystick->rumble_expiration) {
826 joystick->driver->Close(joystick);
827 joystick->hwdata =
NULL;
830 joysticklistprev =
NULL;
831 while (joysticklist) {
832 if (joystick == joysticklist) {
833 if (joysticklistprev) {
835 joysticklistprev->next = joysticklist->next;
841 joysticklistprev = joysticklist;
842 joysticklist = joysticklist->next;
888 #if !SDL_EVENTS_DISABLED
923 SDL_JoystickDriver *driver;
924 int driver_device_index;
925 int player_index = -1;
927 if (device_index < 0) {
933 player_index = driver->GetDevicePlayerIndex(driver_device_index);
938 if (player_index >= 0) {
943 #if !SDL_EVENTS_DISABLED
950 event.jdevice.which = device_index;
969 if (num_events <= 0) {
979 for (
i = 0;
i < num_events; ++
i) {
989 SDL_Joystick *joystick;
992 #if !SDL_EVENTS_DISABLED
998 event.jdevice.which = device_instance;
1006 for (joystick =
SDL_joysticks; joystick; joystick = joystick->next) {
1007 if (joystick->instance_id == device_instance) {
1009 joystick->force_recentering =
SDL_TRUE;
1016 if (player_index >= 0) {
1026 SDL_JoystickAxisInfo *info;
1029 if (
axis >= joystick->naxes) {
1033 info = &joystick->axes[
axis];
1034 if (!info->has_initial_value ||
1036 info->initial_value =
value;
1037 info->value =
value;
1039 info->has_initial_value =
SDL_TRUE;
1043 if (
value == info->value) {
1046 if (!info->sent_initial_value) {
1049 if (
SDL_abs(
value - info->value) <= MAX_ALLOWED_JITTER) {
1052 info->sent_initial_value =
SDL_TRUE;
1053 info->value =
value;
1061 if ((
value > info->zero &&
value >= info->value) ||
1068 info->value =
value;
1072 #if !SDL_EVENTS_DISABLED
1076 event.jaxis.which = joystick->instance_id;
1077 event.jaxis.axis =
axis;
1078 event.jaxis.value =
value;
1091 if (hat >= joystick->nhats) {
1094 if (
value == joystick->hats[hat]) {
1108 joystick->hats[hat] =
value;
1112 #if !SDL_EVENTS_DISABLED
1116 event.jhat.which = joystick->instance_id;
1117 event.jhat.hat = hat;
1118 event.jhat.value =
value;
1132 if (ball >= joystick->nballs) {
1142 joystick->balls[ball].dx += xrel;
1143 joystick->balls[ball].dy += yrel;
1147 #if !SDL_EVENTS_DISABLED
1151 event.jball.which = joystick->instance_id;
1152 event.jball.ball = ball;
1153 event.jball.xrel = xrel;
1154 event.jball.yrel = yrel;
1165 #if !SDL_EVENTS_DISABLED
1182 if (
button >= joystick->nbuttons) {
1202 #if !SDL_EVENTS_DISABLED
1204 event.jbutton.which = joystick->instance_id;
1205 event.jbutton.button =
button;
1206 event.jbutton.state =
state;
1217 SDL_Joystick *joystick, *next;
1236 #ifdef SDL_JOYSTICK_HIDAPI
1241 for (joystick =
SDL_joysticks; joystick; joystick = joystick->next) {
1242 if (joystick->attached) {
1244 if (joystick->driver) {
1245 joystick->driver->Update(joystick);
1248 if (joystick->delayed_guide_button) {
1253 if (joystick->rumble_expiration) {
1256 if (joystick->rumble_expiration &&
1263 if (joystick->force_recentering) {
1265 for (
i = 0;
i < joystick->naxes;
i++) {
1266 if (joystick->axes[
i].has_initial_value) {
1271 for (
i = 0;
i < joystick->nbuttons;
i++) {
1275 for (
i = 0;
i < joystick->nhats;
i++) {
1279 joystick->force_recentering =
SDL_FALSE;
1289 next = joystick->next;
1290 if (joystick->ref_count <= 0) {
1308 #if SDL_EVENTS_DISABLED
1311 const Uint32 event_list[] = {
1343 guid16[1] == 0x0000 &&
1345 guid16[3] == 0x0000 &&
1351 *vendor = guid16[2];
1354 *product = guid16[4];
1357 *version = guid16[6];
1376 if (
SDL_strcmp(manufacturer,
"Performance Designed Products") == 0) {
1378 }
else if (
SDL_strcmp(manufacturer,
"HORI CO.,LTD") == 0) {
1382 return manufacturer;
1411 static const int LIBUSB_CLASS_VENDOR_SPEC = 0xFF;
1412 static const int XB360_IFACE_SUBCLASS = 93;
1413 static const int XB360_IFACE_PROTOCOL = 1;
1414 static const int XB360W_IFACE_PROTOCOL = 129;
1415 static const int XBONE_IFACE_SUBCLASS = 71;
1416 static const int XBONE_IFACE_PROTOCOL = 208;
1421 if (interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
1422 interface_subclass == XB360_IFACE_SUBCLASS &&
1423 (interface_protocol == XB360_IFACE_PROTOCOL ||
1424 interface_protocol == XB360W_IFACE_PROTOCOL)) {
1426 static const int SUPPORTED_VENDORS[] = {
1452 if (vendor == SUPPORTED_VENDORS[
i]) {
1459 if (interface_number == 0 &&
1460 interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
1461 interface_subclass == XBONE_IFACE_SUBCLASS &&
1462 interface_protocol == XBONE_IFACE_PROTOCOL) {
1464 static const int SUPPORTED_VENDORS[] = {
1476 if (vendor == SUPPORTED_VENDORS[
i]) {
1484 if (vendor == 0x0000 && product == 0x0000) {
1495 }
else if (vendor == 0x0001 && product == 0x0001) {
1554 static Uint32 wheel_joysticks[] = {
1572 if (vidpid == wheel_joysticks[
i]) {
1581 static Uint32 flightstick_joysticks[] = {
1588 if (vidpid == flightstick_joysticks[
i]) {
1597 static Uint32 throttle_joysticks[] = {
1604 if (vidpid == throttle_joysticks[
i]) {
1619 switch (guid.
data[15]) {
1668 const char *mapper_processes[] = {
1673 PROCESSENTRY32 pe32;
1677 HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
1678 if (hProcessSnap != INVALID_HANDLE_VALUE) {
1679 pe32.dwSize =
sizeof(PROCESSENTRY32);
1680 if (Process32First(hProcessSnap, &pe32)) {
1688 }
while (Process32Next(hProcessSnap, &pe32) && !found);
1690 CloseHandle(hProcessSnap);
1703 static Uint32 joystick_blacklist[] = {
1810 if (
id == joystick_blacklist[
i]) {
1830 SDL_JoystickDriver *driver;
1835 guid = driver->GetDeviceGUID(device_index);
1887 SDL_JoystickDriver *driver;
1892 instance_id = driver->GetDeviceInstanceID(device_index);
1901 int i, num_joysticks, device_index = -1;
1905 for (
i = 0;
i < num_joysticks; ++
i) {
1913 return device_index;
1923 return joystick->guid;
1960 if (joystick && joystick->is_game_controller) {
1970 static const char k_rgchHexToASCII[] =
"0123456789abcdef";
1973 if ((pszGUID ==
NULL) || (cbGUID <= 0)) {
1977 for (
i = 0;
i <
sizeof(guid.
data) &&
i < (cbGUID-1)/2;
i++) {
1980 unsigned char c = guid.
data[
i];
1982 *pszGUID++ = k_rgchHexToASCII[
c >> 4];
1983 *pszGUID++ = k_rgchHexToASCII[
c & 0x0F];
1995 if ((
c >=
'0') && (
c <=
'9')) {
1996 return (
unsigned char)(
c -
'0');
1999 if ((
c >=
'A') && (
c <=
'F')) {
2000 return (
unsigned char)(
c -
'A' + 0x0a);
2003 if ((
c >=
'a') && (
c <=
'f')) {
2004 return (
unsigned char)(
c -
'a' + 0x0a);
2016 int maxoutputbytes=
sizeof(guid);
2027 for (
i = 0; (
i <
len) && ((
p - (
Uint8 *)&guid) < maxoutputbytes);
i+=2,
p++) {
2037 joystick->epowerlevel = ePowerLevel;
2046 return joystick->epowerlevel;