|
23 | 23 | #include "SDL_syshaptic.h" |
24 | 24 | #include "SDL_haptic_c.h" |
25 | 25 | #include "../joystick/SDL_joystick_c.h" /* For SDL_PrivateJoystickValid */ |
| 26 | +#include "SDL_hints.h" |
| 27 | +#include "../SDL_hints_c.h" |
| 28 | + |
| 29 | +typedef struct SDL_Haptic_VIDPID_Naxes { |
| 30 | + Uint16 vid; |
| 31 | + Uint16 pid; |
| 32 | + Uint16 naxes; |
| 33 | +} SDL_Haptic_VIDPID_Naxes; |
| 34 | + |
| 35 | +static void SDL_HapticLoadAxesList(SDL_Haptic_VIDPID_Naxes **entries, int *num_entries) |
| 36 | +{ |
| 37 | + SDL_Haptic_VIDPID_Naxes entry; |
| 38 | + const char *spot; |
| 39 | + int length = 0; |
| 40 | + |
| 41 | + spot = SDL_GetHint(SDL_HINT_JOYSTICK_HAPTIC_AXES); |
| 42 | + if (!spot) |
| 43 | + return; |
| 44 | + |
| 45 | + while (SDL_sscanf(spot, "0x%hx/0x%hx/%hu%n", &entry.vid, &entry.pid, &entry.naxes, &length) == 3) { |
| 46 | + SDL_assert(length > 0); |
| 47 | + spot += length; |
| 48 | + length = 0; |
| 49 | + |
| 50 | + if ((*num_entries % 8) == 0) { |
| 51 | + int new_max = *num_entries + 8; |
| 52 | + SDL_Haptic_VIDPID_Naxes *new_entries = |
| 53 | + (SDL_Haptic_VIDPID_Naxes *)SDL_realloc(*entries, new_max * sizeof(**entries)); |
| 54 | + |
| 55 | + // Out of memory, go with what we have already |
| 56 | + if (!new_entries) |
| 57 | + break; |
| 58 | + |
| 59 | + *entries = new_entries; |
| 60 | + } |
| 61 | + (*entries)[(*num_entries)++] = entry; |
| 62 | + |
| 63 | + if (spot[0] == ',') |
| 64 | + spot++; |
| 65 | + } |
| 66 | +} |
| 67 | + |
| 68 | +// /* Return -1 if not found */ |
| 69 | +static int SDL_HapticNaxesListIndex(struct SDL_Haptic_VIDPID_Naxes *entries, int num_entries, Uint16 vid, Uint16 pid) |
| 70 | +{ |
| 71 | + int i; |
| 72 | + if (!entries) |
| 73 | + return -1; |
| 74 | + |
| 75 | + for (i = 0; i < num_entries; ++i) { |
| 76 | + if (entries[i].vid == vid && entries[i].pid == pid) |
| 77 | + return i; |
| 78 | + } |
| 79 | + |
| 80 | + return -1; |
| 81 | +} |
| 82 | + |
| 83 | +// Check if device needs a custom number of naxes |
| 84 | +static int SDL_HapticGetNaxes(Uint16 vid, Uint16 pid) |
| 85 | +{ |
| 86 | + int num_entries = 0, index = 0, naxes = -1; |
| 87 | + SDL_Haptic_VIDPID_Naxes *naxes_list = NULL; |
| 88 | + |
| 89 | + SDL_HapticLoadAxesList(&naxes_list, &num_entries); |
| 90 | + if (!num_entries || !naxes_list) |
| 91 | + return -1; |
| 92 | + |
| 93 | + // Perform "wildcard" pass |
| 94 | + index = SDL_HapticNaxesListIndex(naxes_list, num_entries, 0xffff, 0xffff); |
| 95 | + if (index >= 0) |
| 96 | + naxes = naxes_list[index].naxes; |
| 97 | + |
| 98 | + index = SDL_HapticNaxesListIndex(naxes_list, num_entries, vid, pid); |
| 99 | + if (index >= 0) |
| 100 | + naxes = naxes_list[index].naxes; |
| 101 | + |
| 102 | + SDL_free(naxes_list); |
| 103 | + return naxes; |
| 104 | +} |
26 | 105 |
|
27 | 106 | /* Global for SDL_windowshaptic.c */ |
28 | 107 | #if defined(SDL_HAPTIC_DINPUT) || defined(SDL_HAPTIC_XINPUT) |
@@ -258,6 +337,8 @@ SDL_Haptic *SDL_HapticOpenFromJoystick(SDL_Joystick *joystick) |
258 | 337 | { |
259 | 338 | SDL_Haptic *haptic; |
260 | 339 | SDL_Haptic *hapticlist; |
| 340 | + int naxes, general_axes; |
| 341 | + Uint16 vid, pid; |
261 | 342 |
|
262 | 343 | /* Make sure there is room. */ |
263 | 344 | if (SDL_NumHaptics() <= 0) { |
@@ -314,6 +395,18 @@ SDL_Haptic *SDL_HapticOpenFromJoystick(SDL_Joystick *joystick) |
314 | 395 | } |
315 | 396 | SDL_UnlockJoysticks(); |
316 | 397 |
|
| 398 | + vid = SDL_JoystickGetVendor(joystick); |
| 399 | + pid = SDL_JoystickGetProduct(joystick); |
| 400 | + general_axes = SDL_JoystickNumAxes(joystick); |
| 401 | + |
| 402 | + naxes = SDL_HapticGetNaxes(vid, pid); |
| 403 | + if (naxes > 0) |
| 404 | + haptic->naxes = naxes; |
| 405 | + |
| 406 | + // Limit to the actual number of axes found on the device |
| 407 | + if (general_axes >= 0 && naxes > general_axes) |
| 408 | + haptic->naxes = general_axes; |
| 409 | + |
317 | 410 | /* Add haptic to list */ |
318 | 411 | ++haptic->ref_count; |
319 | 412 | /* Link the haptic in the list */ |
|
0 commit comments