32 #include "../../SDL_internal.h"
34 #if SDL_JOYSTICK_RAWINPUT
41 #include "../usb_ids.h"
42 #include "../SDL_sysjoystick.h"
43 #include "../../core/windows/SDL_windows.h"
44 #include "../../core/windows/SDL_hid.h"
45 #include "../hidapi/SDL_hidapijoystick_c.h"
47 #define SDL_JOYSTICK_RAWINPUT_XINPUT
48 #ifdef SDL_WINDOWS10_SDK
49 #define SDL_JOYSTICK_RAWINPUT_WGI
52 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
53 #include "../../core/windows/SDL_xinput.h"
56 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
57 #include "../../core/windows/SDL_windows.h"
58 typedef struct WindowsGamingInputGamepadState WindowsGamingInputGamepadState;
59 #define GamepadButtons_GUIDE 0x40000000
61 #include "windows.gaming.input.h"
64 #if defined(SDL_JOYSTICK_RAWINPUT_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT_WGI)
65 #define SDL_JOYSTICK_RAWINPUT_MATCHING
66 #define SDL_JOYSTICK_RAWINPUT_MATCH_AXES
71 #ifndef RIDEV_EXINPUTSINK
72 #define RIDEV_EXINPUTSINK 0x00001000
73 #define RIDEV_DEVNOTIFY 0x00002000
76 #ifndef WM_INPUT_DEVICE_CHANGE
77 #define WM_INPUT_DEVICE_CHANGE 0x00FE
80 #define WM_INPUT 0x00FF
83 #define GIDC_ARRIVAL 1
84 #define GIDC_REMOVAL 2
89 static int SDL_RAWINPUT_numjoysticks = 0;
92 static void RAWINPUT_JoystickClose(SDL_Joystick *
joystick);
94 typedef struct _SDL_RAWINPUT_Device
109 struct _SDL_RAWINPUT_Device *next;
110 } SDL_RAWINPUT_Device;
116 ULONG max_data_length;
118 USHORT *button_indices;
119 USHORT *axis_indices;
123 USHORT trigger_hack_index;
125 #ifdef SDL_JOYSTICK_RAWINPUT_MATCHING
130 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
133 Uint8 xinput_correlation_id;
134 Uint8 xinput_correlation_count;
135 Uint8 xinput_uncorrelate_count;
139 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
141 Uint8 wgi_correlation_id;
142 Uint8 wgi_correlation_count;
143 Uint8 wgi_uncorrelate_count;
144 WindowsGamingInputGamepadState *wgi_slot;
147 SDL_RAWINPUT_Device *
device;
151 SDL_RAWINPUT_Device *SDL_RAWINPUT_devices;
153 static const Uint16 subscribed_devices[] = {
161 #ifdef SDL_JOYSTICK_RAWINPUT_MATCHING
166 SDL_Joystick *last_joystick;
167 } guide_button_candidate;
169 typedef struct WindowsMatchState {
170 #ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES
173 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
176 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
182 static void RAWINPUT_FillMatchState(WindowsMatchState *
state,
Uint32 match_state)
184 #ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES
189 #ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES
196 for (ii = 0; ii < 4; ii++) {
197 state->match_axes[ii] = (match_state & (0x000F0000 << (ii * 4))) >> (4 + ii * 4);
198 if ((
Uint32)(
state->match_axes[ii] + 0x1000) > 0x2000) {
204 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
206 #define XInputAxesMatch(gamepad) (\
207 (Uint32)(gamepad.sThumbLX - state->match_axes[0] + 0x1000) <= 0x2fff && \
208 (Uint32)(~gamepad.sThumbLY - state->match_axes[1] + 0x1000) <= 0x2fff && \
209 (Uint32)(gamepad.sThumbRX - state->match_axes[2] + 0x1000) <= 0x2fff && \
210 (Uint32)(~gamepad.sThumbRY - state->match_axes[3] + 0x1000) <= 0x2fff)
218 state->xinput_buttons =
220 match_state << 12 | (match_state & 0x0780) >> 1 | (match_state & 0x0010) << 1 | (match_state & 0x0040) >> 2 | (match_state & 0x7800) >> 11;
238 if (
state->xinput_buttons)
242 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
244 #define WindowsGamingInputAxesMatch(gamepad) (\
245 (Uint16)(((Sint16)(gamepad.LeftThumbstickX * SDL_MAX_SINT16) & 0xF000) - state->match_axes[0] + 0x1000) <= 0x2fff && \
246 (Uint16)((~(Sint16)(gamepad.LeftThumbstickY * SDL_MAX_SINT16) & 0xF000) - state->match_axes[1] + 0x1000) <= 0x2fff && \
247 (Uint16)(((Sint16)(gamepad.RightThumbstickX * SDL_MAX_SINT16) & 0xF000) - state->match_axes[2] + 0x1000) <= 0x2fff && \
248 (Uint16)((~(Sint16)(gamepad.RightThumbstickY * SDL_MAX_SINT16) & 0xF000) - state->match_axes[3] + 0x1000) <= 0x2fff)
254 (match_state & 0x0180) << 5 | (match_state & 0x0600) << 1 | (match_state & 0x7800) >> 5 | (match_state & 0x000F) << 2 | (match_state & 0x0010) >> 3 | (match_state & 0x0040) >> 6;
271 if (
state->wgi_buttons)
279 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
282 XINPUT_STATE_EX
state;
283 XINPUT_BATTERY_INFORMATION_EX battery;
286 Uint8 correlation_id;
287 } xinput_state[XUSER_MAX_COUNT];
292 RAWINPUT_UpdateXInput()
295 if (xinput_device_change) {
296 for (user_index = 0; user_index < XUSER_MAX_COUNT; user_index++) {
297 XINPUT_CAPABILITIES capabilities;
298 xinput_state[user_index].connected = (XINPUTGETCAPABILITIES(user_index, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) ?
SDL_TRUE :
SDL_FALSE;
303 if (xinput_state_dirty) {
305 for (user_index = 0; user_index <
SDL_arraysize(xinput_state); ++user_index) {
306 if (xinput_state[user_index].connected) {
307 if (XINPUTGETSTATE(user_index, &xinput_state[user_index].
state) != ERROR_SUCCESS) {
308 xinput_state[user_index].connected =
SDL_FALSE;
310 xinput_state[user_index].battery.BatteryType = BATTERY_TYPE_UNKNOWN;
311 XINPUTGETBATTERYINFORMATION(user_index, BATTERY_DEVTYPE_GAMEPAD, &xinput_state[user_index].battery);
318 RAWINPUT_MarkXInputSlotUsed(
Uint8 xinput_slot)
320 if (xinput_slot != XUSER_INDEX_ANY) {
321 xinput_state[xinput_slot].used =
SDL_TRUE;
326 RAWINPUT_MarkXInputSlotFree(
Uint8 xinput_slot)
328 if (xinput_slot != XUSER_INDEX_ANY) {
329 xinput_state[xinput_slot].used =
SDL_FALSE;
333 RAWINPUT_MissingXInputSlot()
337 if (xinput_state[ii].connected && !xinput_state[ii].used) {
345 RAWINPUT_XInputSlotMatches(
const WindowsMatchState *
state,
Uint8 slot_idx)
347 if (xinput_state[slot_idx].connected) {
348 WORD xinput_buttons = xinput_state[slot_idx].state.Gamepad.wButtons;
349 if ((xinput_buttons & ~XINPUT_GAMEPAD_GUIDE) ==
state->xinput_buttons
350 #ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES
351 && XInputAxesMatch(xinput_state[slot_idx].
state.Gamepad)
362 RAWINPUT_GuessXInputSlot(
const WindowsMatchState *
state,
Uint8 *correlation_id,
Uint8 *slot_idx)
370 for (user_index = 0; user_index < XUSER_MAX_COUNT; ++user_index) {
371 if (!xinput_state[user_index].used && RAWINPUT_XInputSlotMatches(
state, user_index)) {
373 *slot_idx = (
Uint8)user_index;
375 *correlation_id = ++xinput_state[user_index].correlation_id;
381 if (match_count == 1 &&
state->any_data) {
389 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
391 typedef struct WindowsGamingInputGamepadState {
392 __x_ABI_CWindows_CGaming_CInput_CIGamepad *gamepad;
393 struct __x_ABI_CWindows_CGaming_CInput_CGamepadReading
state;
394 RAWINPUT_DeviceContext *correlated_context;
397 Uint8 correlation_id;
398 struct __x_ABI_CWindows_CGaming_CInput_CGamepadVibration vibration;
399 } WindowsGamingInputGamepadState;
402 WindowsGamingInputGamepadState **per_gamepad;
403 int per_gamepad_count;
408 __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics *gamepad_statics;
412 RAWINPUT_MarkWindowsGamingInputSlotUsed(WindowsGamingInputGamepadState *wgi_slot, RAWINPUT_DeviceContext *
ctx)
415 wgi_slot->correlated_context =
ctx;
419 RAWINPUT_MarkWindowsGamingInputSlotFree(WindowsGamingInputGamepadState *wgi_slot)
422 wgi_slot->correlated_context =
NULL;
426 RAWINPUT_MissingWindowsGamingInputSlot()
429 for (ii = 0; ii < wgi_state.per_gamepad_count; ii++) {
430 if (!wgi_state.per_gamepad[ii]->used) {
438 RAWINPUT_UpdateWindowsGamingInput()
441 if (!wgi_state.gamepad_statics)
444 if (!wgi_state.dirty)
449 if (wgi_state.need_device_list_update) {
450 wgi_state.need_device_list_update =
SDL_FALSE;
451 for (ii = 0; ii < wgi_state.per_gamepad_count; ii++) {
452 wgi_state.per_gamepad[ii]->connected =
SDL_FALSE;
455 __FIVectorView_1_Windows__CGaming__CInput__CGamepad *gamepads;
457 hr = __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_get_Gamepads(wgi_state.gamepad_statics, &gamepads);
459 unsigned int num_gamepads;
461 hr = __FIVectorView_1_Windows__CGaming__CInput__CGamepad_get_Size(gamepads, &num_gamepads);
464 for (
i = 0;
i < num_gamepads; ++
i) {
465 __x_ABI_CWindows_CGaming_CInput_CIGamepad *gamepad;
467 hr = __FIVectorView_1_Windows__CGaming__CInput__CGamepad_GetAt(gamepads,
i, &gamepad);
471 for (jj = 0; jj < wgi_state.per_gamepad_count ; jj++) {
472 if (wgi_state.per_gamepad[jj]->gamepad == gamepad) {
474 wgi_state.per_gamepad[jj]->connected =
SDL_TRUE;
480 wgi_state.per_gamepad_count++;
481 wgi_state.per_gamepad =
SDL_realloc(wgi_state.per_gamepad,
sizeof(wgi_state.per_gamepad[0]) * wgi_state.per_gamepad_count);
482 if (!wgi_state.per_gamepad) {
486 WindowsGamingInputGamepadState *gamepad_state =
SDL_calloc(1,
sizeof(*gamepad_state));
487 if (!gamepad_state) {
491 wgi_state.per_gamepad[wgi_state.per_gamepad_count - 1] = gamepad_state;
492 gamepad_state->gamepad = gamepad;
493 gamepad_state->connected =
SDL_TRUE;
496 __x_ABI_CWindows_CGaming_CInput_CIGamepad_Release(gamepad);
500 for (ii = wgi_state.per_gamepad_count - 1; ii >= 0; ii--) {
501 WindowsGamingInputGamepadState *gamepad_state = wgi_state.per_gamepad[ii];
502 if (!gamepad_state->connected) {
504 if (gamepad_state->correlated_context) {
505 gamepad_state->correlated_context->wgi_correlated =
SDL_FALSE;
506 gamepad_state->correlated_context->wgi_slot =
NULL;
508 __x_ABI_CWindows_CGaming_CInput_CIGamepad_Release(gamepad_state->gamepad);
510 wgi_state.per_gamepad[ii] = wgi_state.per_gamepad[wgi_state.per_gamepad_count - 1];
511 --wgi_state.per_gamepad_count;
515 __FIVectorView_1_Windows__CGaming__CInput__CGamepad_Release(gamepads);
519 for (ii = 0; ii < wgi_state.per_gamepad_count; ii++) {
520 HRESULT hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_GetCurrentReading(wgi_state.per_gamepad[ii]->gamepad, &wgi_state.per_gamepad[ii]->state);
522 wgi_state.per_gamepad[ii]->connected =
SDL_FALSE;
527 RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *
ctx)
529 wgi_state.need_device_list_update =
SDL_TRUE;
530 wgi_state.ref_count++;
531 if (!wgi_state.initialized) {
539 static const IID SDL_IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } };
541 HMODULE hModule = LoadLibraryA(
"combase.dll");
542 if (hModule !=
NULL) {
543 typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32
length, HSTRING_HEADER *hstringHeader, HSTRING*
string);
544 typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid,
void**
factory);
546 WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule,
"WindowsCreateStringReference");
547 RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule,
"RoGetActivationFactory");
548 if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
549 LPTSTR pNamespace = L
"Windows.Gaming.Input.Gamepad";
550 HSTRING_HEADER hNamespaceStringHeader;
551 HSTRING hNamespaceString;
553 hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)
SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
555 RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, &wgi_state.gamepad_statics);
558 FreeLibrary(hModule);
564 RAWINPUT_WindowsGamingInputSlotMatches(
const WindowsMatchState *
state, WindowsGamingInputGamepadState *slot)
566 Uint32 wgi_buttons = slot->state.Buttons;
567 if ((wgi_buttons & 0x3FFF) ==
state->wgi_buttons
568 #ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES
569 && WindowsGamingInputAxesMatch(slot->state)
578 RAWINPUT_GuessWindowsGamingInputSlot(
const WindowsMatchState *
state,
Uint8 *correlation_id, WindowsGamingInputGamepadState **slot)
580 int match_count, user_index;
583 for (user_index = 0; user_index < wgi_state.per_gamepad_count; ++user_index) {
584 WindowsGamingInputGamepadState *gamepad_state = wgi_state.per_gamepad[user_index];
585 if (RAWINPUT_WindowsGamingInputSlotMatches(
state, gamepad_state)) {
587 *slot = gamepad_state;
589 *correlation_id = ++gamepad_state->correlation_id;
595 if (match_count == 1 &&
state->any_data) {
602 RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *
ctx)
604 wgi_state.need_device_list_update =
SDL_TRUE;
605 --wgi_state.ref_count;
606 if (!wgi_state.ref_count && wgi_state.initialized) {
608 for (ii = 0; ii < wgi_state.per_gamepad_count; ii++) {
609 __x_ABI_CWindows_CGaming_CInput_CIGamepad_Release(wgi_state.per_gamepad[ii]->gamepad);
611 if (wgi_state.per_gamepad) {
613 wgi_state.per_gamepad =
NULL;
615 wgi_state.per_gamepad_count = 0;
616 if (wgi_state.gamepad_statics) {
617 __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(wgi_state.gamepad_statics);
618 wgi_state.gamepad_statics =
NULL;
628 static SDL_RAWINPUT_Device *
629 RAWINPUT_AcquireDevice(SDL_RAWINPUT_Device *
device)
636 RAWINPUT_ReleaseDevice(SDL_RAWINPUT_Device *
device)
638 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
640 RAWINPUT_DeviceContext *
ctx =
device->joystick->hwdata;
642 if (
ctx->xinput_enabled &&
ctx->xinput_correlated) {
643 RAWINPUT_MarkXInputSlotFree(
ctx->xinput_slot);
650 if (
device->preparsed_data) {
658 static SDL_RAWINPUT_Device *
659 RAWINPUT_DeviceFromHandle(HANDLE hDevice)
661 SDL_RAWINPUT_Device *curr;
663 for (curr = SDL_RAWINPUT_devices; curr; curr = curr->next) {
664 if (curr->hDevice == hDevice)
671 RAWINPUT_AddDevice(HANDLE hDevice)
673 #define CHECK(exp) { if(!(exp)) goto err; }
675 SDL_RAWINPUT_Device *curr, *last;
677 UINT rdi_size =
sizeof(rdi);
678 char dev_name[MAX_PATH];
680 HANDLE hFile = INVALID_HANDLE_VALUE;
683 if (RAWINPUT_DeviceFromHandle(hDevice)) {
688 CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICEINFO, &rdi, &rdi_size) != (UINT)-1);
689 CHECK(rdi.dwType == RIM_TYPEHID);
692 CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, dev_name, &name_size) != (UINT)-1);
695 #ifdef SDL_JOYSTICK_HIDAPI
700 CHECK(
device = (SDL_RAWINPUT_Device *)
SDL_calloc(1,
sizeof(SDL_RAWINPUT_Device)));
701 device->hDevice = hDevice;
723 device->guid.data[14] =
'r';
724 device->guid.data[15] = 0;
727 hFile = CreateFileA(dev_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0,
NULL);
728 CHECK(hFile != INVALID_HANDLE_VALUE);
731 char *manufacturer_string =
NULL;
732 char *product_string =
NULL;
744 if (manufacturer_string) {
747 if (product_string) {
755 hFile = INVALID_HANDLE_VALUE;
759 #ifdef DEBUG_RAWINPUT
764 RAWINPUT_AcquireDevice(
device);
765 for (curr = SDL_RAWINPUT_devices, last =
NULL; curr; last = curr, curr = curr->next) {
771 SDL_RAWINPUT_devices =
device;
774 ++SDL_RAWINPUT_numjoysticks;
781 if (hFile != INVALID_HANDLE_VALUE) {
793 RAWINPUT_DelDevice(SDL_RAWINPUT_Device *
device,
SDL_bool send_event)
795 SDL_RAWINPUT_Device *curr, *last;
796 for (curr = SDL_RAWINPUT_devices, last =
NULL; curr; last = curr, curr = curr->next) {
799 last->next = curr->next;
801 SDL_RAWINPUT_devices = curr->next;
803 --SDL_RAWINPUT_numjoysticks;
807 #ifdef DEBUG_RAWINPUT
810 RAWINPUT_ReleaseDevice(
device);
817 RAWINPUT_JoystickInit(
void)
819 UINT device_count = 0;
834 if ((GetRawInputDeviceList(
NULL, &device_count,
sizeof(RAWINPUTDEVICELIST)) != -1) && device_count > 0) {
838 devices = (PRAWINPUTDEVICELIST)
SDL_malloc(
sizeof(RAWINPUTDEVICELIST) * device_count);
840 if (GetRawInputDeviceList(
devices, &device_count,
sizeof(RAWINPUTDEVICELIST)) != -1) {
841 for (
i = 0;
i < device_count; ++
i) {
842 RAWINPUT_AddDevice(
devices[
i].hDevice);
853 RAWINPUT_JoystickGetCount(
void)
855 return SDL_RAWINPUT_numjoysticks;
861 return SDL_RAWINPUT_inited;
867 SDL_RAWINPUT_Device *
device;
870 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
873 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
874 wgi_state.need_device_list_update =
SDL_TRUE;
877 device = SDL_RAWINPUT_devices;
879 if (vendor_id ==
device->vendor_id && product_id ==
device->product_id ) {
884 if (vendor_id ==
device->vendor_id && product_id == 0 &&
902 RAWINPUT_PostUpdate(
void)
904 #ifdef SDL_JOYSTICK_RAWINPUT_MATCHING
907 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
908 if (!wgi_state.dirty) {
910 for (ii = 0; ii < wgi_state.per_gamepad_count; ii++) {
911 WindowsGamingInputGamepadState *gamepad_state = wgi_state.per_gamepad[ii];
912 if (!gamepad_state->used && (gamepad_state->state.Buttons & GamepadButtons_GUIDE)) {
921 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
922 if (!xinput_state_dirty) {
925 if (xinput_state[ii].connected && !xinput_state[ii].used && (xinput_state[ii].
state.Gamepad.wButtons & XINPUT_GAMEPAD_GUIDE)) {
934 if (unmapped_guide_pressed) {
935 if (guide_button_candidate.joystick && !guide_button_candidate.last_joystick) {
936 SDL_Joystick *
joystick = guide_button_candidate.joystick;
938 if (
ctx->guide_hack) {
939 int guide_button =
joystick->nbuttons - 1;
943 guide_button_candidate.last_joystick = guide_button_candidate.joystick;
945 }
else if (guide_button_candidate.last_joystick) {
946 SDL_Joystick *
joystick = guide_button_candidate.last_joystick;
948 if (
ctx->guide_hack) {
949 int guide_button =
joystick->nbuttons - 1;
953 guide_button_candidate.last_joystick =
NULL;
955 guide_button_candidate.joystick =
NULL;
961 RAWINPUT_JoystickDetect(
void)
963 RAWINPUT_PostUpdate();
966 static SDL_RAWINPUT_Device *
967 RAWINPUT_GetDeviceByIndex(
int device_index)
969 SDL_RAWINPUT_Device *
device = SDL_RAWINPUT_devices;
971 if (device_index == 0) {
981 RAWINPUT_JoystickGetDeviceName(
int device_index)
983 return RAWINPUT_GetDeviceByIndex(device_index)->name;
987 RAWINPUT_JoystickGetDevicePlayerIndex(
int device_index)
993 RAWINPUT_JoystickSetDevicePlayerIndex(
int device_index,
int player_index)
999 RAWINPUT_JoystickGetDeviceGUID(
int device_index)
1001 return RAWINPUT_GetDeviceByIndex(device_index)->guid;
1005 RAWINPUT_JoystickGetDeviceInstanceID(
int device_index)
1007 return RAWINPUT_GetDeviceByIndex(device_index)->joystick_id;
1011 RAWINPUT_SortValueCaps(
const void *A,
const void *B)
1021 RAWINPUT_JoystickOpen(SDL_Joystick *
joystick,
int device_index)
1023 SDL_RAWINPUT_Device *
device = RAWINPUT_GetDeviceByIndex(device_index);
1024 RAWINPUT_DeviceContext *
ctx;
1030 ctx = (RAWINPUT_DeviceContext *)
SDL_calloc(1,
sizeof(RAWINPUT_DeviceContext));
1036 ctx->device = RAWINPUT_AcquireDevice(
device);
1041 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
1044 if (
ctx->xinput_enabled && (WIN_LoadXInputDLL() < 0 || !XINPUTGETSTATE)) {
1047 ctx->xinput_slot = XUSER_INDEX_ANY;
1049 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
1050 RAWINPUT_InitWindowsGamingInput(
ctx);
1055 ctx->preparsed_data =
device->preparsed_data;
1065 return SDL_SetError(
"Couldn't get device capabilities");
1071 return SDL_SetError(
"Couldn't get device button capabilities");
1077 return SDL_SetError(
"Couldn't get device value capabilities");
1090 count = 1 + (
cap->Range.DataIndexMax -
cap->Range.DataIndexMin);
1100 int button_index = 0;
1103 if (!
ctx->button_indices) {
1113 int j,
count = 1 + (
cap->Range.DataIndexMax -
cap->Range.DataIndexMin);
1116 ctx->button_indices[button_index++] =
cap->Range.DataIndexMin +
j;
1119 ctx->button_indices[button_index++] =
cap->NotRange.DataIndex;
1156 if (!
ctx->axis_indices) {
1174 ctx->trigger_hack_index =
cap->NotRange.DataIndex;
1178 ctx->axis_indices[axis_index++] =
cap->NotRange.DataIndex;
1181 if (
ctx->trigger_hack) {
1189 if (!
ctx->hat_indices) {
1215 RAWINPUT_JoystickRumble(SDL_Joystick *
joystick,
Uint16 low_frequency_rumble,
Uint16 high_frequency_rumble)
1217 #if defined(SDL_JOYSTICK_RAWINPUT_WGI) || defined(SDL_JOYSTICK_RAWINPUT_XINPUT)
1223 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
1224 if (!rumbled &&
ctx->wgi_correlated) {
1225 WindowsGamingInputGamepadState *gamepad_state =
ctx->wgi_slot;
1227 gamepad_state->vibration.LeftMotor = (DOUBLE)low_frequency_rumble /
SDL_MAX_UINT16;
1228 gamepad_state->vibration.RightMotor = (DOUBLE)high_frequency_rumble /
SDL_MAX_UINT16;
1229 hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, gamepad_state->vibration);
1236 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
1237 if (!rumbled &&
ctx->xinput_correlated) {
1238 XINPUT_VIBRATION XVibration;
1240 if (!XINPUTSETSTATE) {
1244 XVibration.wLeftMotorSpeed = low_frequency_rumble;
1245 XVibration.wRightMotorSpeed = high_frequency_rumble;
1246 if (XINPUTSETSTATE(
ctx->xinput_slot, &XVibration) == ERROR_SUCCESS) {
1258 RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *
joystick,
Uint16 left_rumble,
Uint16 right_rumble)
1260 #if defined(SDL_JOYSTICK_RAWINPUT_WGI)
1263 if (
ctx->wgi_correlated) {
1264 WindowsGamingInputGamepadState *gamepad_state =
ctx->wgi_slot;
1266 gamepad_state->vibration.LeftTrigger = (DOUBLE)left_rumble /
SDL_MAX_UINT16;
1267 gamepad_state->vibration.RightTrigger = (DOUBLE)right_rumble /
SDL_MAX_UINT16;
1268 hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, gamepad_state->vibration);
1270 return SDL_SetError(
"Setting vibration failed: 0x%x\n", hr);
1280 RAWINPUT_JoystickHasLED(SDL_Joystick *
joystick)
1325 #ifdef SDL_JOYSTICK_RAWINPUT_MATCHING
1327 static const int button_map[] = {
1339 #define HAT_MASK ((1 << SDL_CONTROLLER_BUTTON_DPAD_UP) | (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN) | (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT) | (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT))
1340 static const int hat_map[] = {
1353 #define SDL_PrivateJoystickButton(joystick, button, state) if (button < SDL_arraysize(button_map)) { if (state) match_state |= 1 << button_map[button]; else match_state &= ~(1 << button_map[button]); } SDL_PrivateJoystickButton(joystick, button, state)
1354 #ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES
1356 #define SDL_PrivateJoystickAxis(joystick, axis, value) if (axis < 4) match_state = (match_state & ~(0xF << (4 * axis + 16))) | ((value) & 0xF000) << (4 * axis + 4); SDL_PrivateJoystickAxis(joystick, axis, value)
1360 ULONG data_length =
ctx->max_data_length;
1362 int nbuttons =
joystick->nbuttons - (
ctx->guide_hack * 1);
1363 int naxes =
joystick->naxes - (
ctx->trigger_hack * 2);
1371 for (
i = 0;
i < nbuttons; ++
i) {
1373 if (item && item->
On) {
1374 button_mask |= (1 <<
i);
1377 for (
i = 0;
i < nbuttons; ++
i) {
1381 for (
i = 0;
i < naxes; ++
i) {
1389 for (
i = 0;
i < nhats; ++
i) {
1392 const Uint8 hat_states[] = {
1406 #ifdef SDL_JOYSTICK_RAWINPUT_MATCHING
1407 match_state = (match_state & ~HAT_MASK) | hat_map[
state];
1414 #ifdef SDL_PrivateJoystickButton
1415 #undef SDL_PrivateJoystickButton
1417 #ifdef SDL_PrivateJoystickAxis
1418 #undef SDL_PrivateJoystickAxis
1421 if (
ctx->trigger_hack) {
1424 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
1426 if (!has_trigger_data &&
ctx->xinput_enabled &&
ctx->xinput_correlated) {
1431 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
1432 if (!has_trigger_data &&
ctx->wgi_correlated) {
1437 if (!has_trigger_data) {
1438 HIDP_DATA *item = GetData(
ctx->trigger_hack_index,
ctx->data, data_length);
1440 int left_trigger =
joystick->naxes - 2;
1441 int right_trigger =
joystick->naxes - 1;
1447 }
else if (
value > 0) {
1459 #ifdef SDL_JOYSTICK_RAWINPUT_MATCHING
1460 if (
ctx->is_xinput) {
1461 ctx->match_state = match_state;
1468 RAWINPUT_UpdateOtherAPIs(SDL_Joystick *
joystick)
1470 #ifdef SDL_JOYSTICK_RAWINPUT_MATCHING
1474 WindowsMatchState match_state_xinput;
1475 int guide_button =
joystick->nbuttons - 1;
1476 int left_trigger =
joystick->naxes - 2;
1477 int right_trigger =
joystick->naxes - 1;
1479 RAWINPUT_FillMatchState(&match_state_xinput,
ctx->match_state);
1481 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
1483 RAWINPUT_UpdateWindowsGamingInput();
1484 if (
ctx->wgi_correlated) {
1486 if (RAWINPUT_WindowsGamingInputSlotMatches(&match_state_xinput,
ctx->wgi_slot)) {
1487 ctx->wgi_uncorrelate_count = 0;
1489 ++
ctx->wgi_uncorrelate_count;
1494 if (
ctx->wgi_uncorrelate_count >= 3) {
1495 #ifdef DEBUG_RAWINPUT
1496 SDL_Log(
"UN-Correlated joystick %d to WindowsGamingInput device #%d\n",
joystick->instance_id,
ctx->wgi_slot);
1498 RAWINPUT_MarkWindowsGamingInputSlotFree(
ctx->wgi_slot);
1500 ctx->wgi_correlation_count = 0;
1504 if (
ctx->guide_hack) {
1510 if (!
ctx->wgi_correlated) {
1511 SDL_bool new_correlation_count = 0;
1512 if (RAWINPUT_MissingWindowsGamingInputSlot()) {
1513 Uint8 correlation_id;
1514 WindowsGamingInputGamepadState *slot_idx;
1515 if (RAWINPUT_GuessWindowsGamingInputSlot(&match_state_xinput, &correlation_id, &slot_idx)) {
1519 if (
ctx->wgi_correlation_count &&
ctx->wgi_slot == slot_idx) {
1521 if (
ctx->wgi_correlation_id + 1 == correlation_id) {
1523 new_correlation_count =
ctx->wgi_correlation_count + 1;
1524 if (new_correlation_count == 2) {
1527 #ifdef DEBUG_RAWINPUT
1528 SDL_Log(
"Correlated joystick %d to WindowsGamingInput device #%d\n",
joystick->instance_id, slot_idx);
1531 RAWINPUT_MarkWindowsGamingInputSlotUsed(
ctx->wgi_slot,
ctx);
1533 if (guide_button_candidate.joystick ==
joystick)
1534 guide_button_candidate.joystick =
NULL;
1535 if (guide_button_candidate.last_joystick ==
joystick)
1536 guide_button_candidate.last_joystick =
NULL;
1540 new_correlation_count = 1;
1544 new_correlation_count = 1;
1545 ctx->wgi_slot = slot_idx;
1547 ctx->wgi_correlation_id = correlation_id;
1552 ctx->wgi_correlation_count = new_correlation_count;
1558 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
1560 if (
ctx->xinput_enabled) {
1561 RAWINPUT_UpdateXInput();
1562 if (
ctx->xinput_correlated) {
1579 if (RAWINPUT_XInputSlotMatches(&match_state_xinput,
ctx->xinput_slot)) {
1580 ctx->xinput_uncorrelate_count = 0;
1582 ++
ctx->xinput_uncorrelate_count;
1587 if (
ctx->xinput_uncorrelate_count >= 3) {
1588 #ifdef DEBUG_RAWINPUT
1589 SDL_Log(
"UN-Correlated joystick %d to XInput device #%d\n",
joystick->instance_id,
ctx->xinput_slot);
1591 RAWINPUT_MarkXInputSlotFree(
ctx->xinput_slot);
1593 ctx->xinput_correlation_count = 0;
1597 if (
ctx->guide_hack) {
1603 if (!
ctx->xinput_correlated) {
1604 Uint8 new_correlation_count = 0;
1605 if (RAWINPUT_MissingXInputSlot()) {
1606 Uint8 correlation_id = 0;
1608 if (RAWINPUT_GuessXInputSlot(&match_state_xinput, &correlation_id, &slot_idx)) {
1612 if (
ctx->xinput_correlation_count &&
ctx->xinput_slot == slot_idx) {
1614 if (
ctx->xinput_correlation_id + 1 == correlation_id) {
1616 new_correlation_count =
ctx->xinput_correlation_count + 1;
1617 if (new_correlation_count == 2) {
1620 #ifdef DEBUG_RAWINPUT
1621 SDL_Log(
"Correlated joystick %d to XInput device #%d\n",
joystick->instance_id, slot_idx);
1624 RAWINPUT_MarkXInputSlotUsed(
ctx->xinput_slot);
1626 if (guide_button_candidate.joystick ==
joystick)
1627 guide_button_candidate.joystick =
NULL;
1628 if (guide_button_candidate.last_joystick ==
joystick)
1629 guide_button_candidate.last_joystick =
NULL;
1633 new_correlation_count = 1;
1637 new_correlation_count = 1;
1638 ctx->xinput_slot = slot_idx;
1640 ctx->xinput_correlation_id = correlation_id;
1645 ctx->xinput_correlation_count = new_correlation_count;
1653 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
1655 if (!has_trigger_data &&
ctx->xinput_enabled &&
ctx->xinput_correlated) {
1656 RAWINPUT_UpdateXInput();
1657 if (xinput_state[
ctx->xinput_slot].connected) {
1658 XINPUT_BATTERY_INFORMATION_EX *battery_info = &xinput_state[
ctx->xinput_slot].battery;
1660 if (
ctx->guide_hack) {
1663 if (
ctx->trigger_hack) {
1669 if (battery_info->BatteryType != BATTERY_TYPE_UNKNOWN) {
1671 if (battery_info->BatteryType == BATTERY_TYPE_WIRED) {
1674 switch (battery_info->BatteryLevel) {
1675 case BATTERY_LEVEL_EMPTY:
1678 case BATTERY_LEVEL_LOW:
1681 case BATTERY_LEVEL_MEDIUM:
1685 case BATTERY_LEVEL_FULL:
1696 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
1697 if (!has_trigger_data &&
ctx->wgi_correlated) {
1698 RAWINPUT_UpdateWindowsGamingInput();
1699 if (
ctx->wgi_correlated) {
1700 struct __x_ABI_CWindows_CGaming_CInput_CGamepadReading *
state = &
ctx->wgi_slot->state;
1702 if (
ctx->guide_hack) {
1705 if (
ctx->trigger_hack) {
1715 if (!guide_button_candidate.joystick ||
1716 (
ctx->last_state_packet && (
1717 !guide_button_candidate.last_state_packet ||
1721 guide_button_candidate.joystick =
joystick;
1722 guide_button_candidate.last_state_packet =
ctx->last_state_packet;
1729 RAWINPUT_JoystickUpdate(SDL_Joystick *
joystick)
1731 RAWINPUT_UpdateOtherAPIs(
joystick);
1735 RAWINPUT_JoystickClose(SDL_Joystick *
joystick)
1739 #ifdef SDL_JOYSTICK_RAWINPUT_MATCHING
1740 if (guide_button_candidate.joystick ==
joystick)
1741 guide_button_candidate.joystick =
NULL;
1742 if (guide_button_candidate.last_joystick ==
joystick)
1743 guide_button_candidate.last_joystick =
NULL;
1747 SDL_RAWINPUT_Device *
device;
1749 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
1751 if (
ctx->xinput_enabled) {
1752 if (
ctx->xinput_correlated) {
1753 RAWINPUT_MarkXInputSlotFree(
ctx->xinput_slot);
1755 WIN_UnloadXInputDLL();
1758 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
1759 RAWINPUT_QuitWindowsGamingInput(
ctx);
1766 RAWINPUT_ReleaseDevice(
device);
1786 rid[
i].usUsage = subscribed_devices[
i];
1787 rid[
i].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK;
1788 rid[
i].hwndTarget = hWnd;
1791 if (!RegisterRawInputDevices(rid,
SDL_arraysize(rid),
sizeof(RAWINPUTDEVICE))) {
1792 SDL_SetError(
"Couldn't register for raw input events");
1806 rid[
i].usUsage = subscribed_devices[
i];
1807 rid[
i].dwFlags = RIDEV_REMOVE;
1808 rid[
i].hwndTarget =
NULL;
1811 if (!RegisterRawInputDevices(rid,
SDL_arraysize(rid),
sizeof(RAWINPUTDEVICE))) {
1812 SDL_SetError(
"Couldn't unregister for raw input events");
1824 if (SDL_RAWINPUT_inited) {
1826 case WM_INPUT_DEVICE_CHANGE:
1828 HANDLE hDevice = (HANDLE)lParam;
1831 RAWINPUT_AddDevice(hDevice);
1835 SDL_RAWINPUT_Device *
device;
1836 device = RAWINPUT_DeviceFromHandle(hDevice);
1854 if ((
int)GetRawInputData((HRAWINPUT)lParam, RID_INPUT,
data, &buffer_size,
sizeof(RAWINPUTHEADER)) > 0) {
1855 PRAWINPUT raw_input = (PRAWINPUT)
data;
1856 SDL_RAWINPUT_Device *
device = RAWINPUT_DeviceFromHandle(raw_input->header.hDevice);
1860 RAWINPUT_HandleStatePacket(
joystick, raw_input->data.hid.bRawData, raw_input->data.hid.dwSizeHid);
1875 return CallWindowProc(DefWindowProc, hWnd, msg, wParam, lParam);
1879 RAWINPUT_JoystickQuit(
void)
1881 if (!SDL_RAWINPUT_inited) {
1887 while (SDL_RAWINPUT_devices) {
1888 RAWINPUT_DelDevice(SDL_RAWINPUT_devices,
SDL_FALSE);
1893 SDL_RAWINPUT_numjoysticks = 0;
1899 SDL_RAWINPUT_mutex =
NULL;
1910 RAWINPUT_JoystickInit,
1911 RAWINPUT_JoystickGetCount,
1912 RAWINPUT_JoystickDetect,
1913 RAWINPUT_JoystickGetDeviceName,
1914 RAWINPUT_JoystickGetDevicePlayerIndex,
1915 RAWINPUT_JoystickSetDevicePlayerIndex,
1916 RAWINPUT_JoystickGetDeviceGUID,
1917 RAWINPUT_JoystickGetDeviceInstanceID,
1918 RAWINPUT_JoystickOpen,
1919 RAWINPUT_JoystickRumble,
1920 RAWINPUT_JoystickRumbleTriggers,
1921 RAWINPUT_JoystickHasLED,
1922 RAWINPUT_JoystickSetLED,
1923 RAWINPUT_JoystickSetSensorsEnabled,
1924 RAWINPUT_JoystickUpdate,
1925 RAWINPUT_JoystickClose,
1926 RAWINPUT_JoystickQuit,
1927 RAWINPUT_JoystickGetGamepadMapping
#define SDL_assert(condition)
#define SDL_AtomicDecRef(a)
Decrement an atomic variable used as a reference count.
#define SDL_AtomicIncRef(a)
Increment an atomic variable used as a reference count.
#define SDL_GetHintBoolean
#define SDL_OutOfMemory()
#define SDL_Unsupported()
@ SDL_CONTROLLER_BUTTON_B
@ SDL_CONTROLLER_BUTTON_BACK
@ SDL_CONTROLLER_BUTTON_LEFTSTICK
@ SDL_CONTROLLER_BUTTON_START
@ SDL_CONTROLLER_BUTTON_DPAD_LEFT
@ SDL_CONTROLLER_BUTTON_RIGHTSHOULDER
@ SDL_CONTROLLER_BUTTON_DPAD_DOWN
@ SDL_CONTROLLER_BUTTON_DPAD_UP
@ SDL_CONTROLLER_BUTTON_LEFTSHOULDER
@ SDL_CONTROLLER_BUTTON_DPAD_RIGHT
@ SDL_CONTROLLER_BUTTON_X
@ SDL_CONTROLLER_BUTTON_RIGHTSTICK
@ SDL_CONTROLLER_BUTTON_Y
@ SDL_CONTROLLER_BUTTON_A
HidD_FreePreparsedData_t SDL_HidD_FreePreparsedData
HidP_GetCaps_t SDL_HidP_GetCaps
HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps
HidD_GetString_t SDL_HidD_GetManufacturerString
HidD_GetPreparsedData_t SDL_HidD_GetPreparsedData
void WIN_UnloadHIDDLL(void)
HidP_MaxDataListLength_t SDL_HidP_MaxDataListLength
HidP_GetValueCaps_t SDL_HidP_GetValueCaps
HidP_GetData_t SDL_HidP_GetData
HidD_GetString_t SDL_HidD_GetProductString
#define HIDP_STATUS_SUCCESS
struct _HIDP_PREPARSED_DATA * PHIDP_PREPARSED_DATA
#define USB_PACKET_LENGTH
SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
#define SDL_HINT_JOYSTICK_HIDAPI_CORRELATE_XINPUT
A variable controlling whether the HIDAPI driver for XBox controllers on Windows should pull correlat...
#define SDL_HINT_JOYSTICK_RAWINPUT
A variable controlling whether the RAWINPUT joystick drivers should be used for better handling XInpu...
void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel)
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
SDL_JoystickID SDL_GetNextJoystickInstanceID()
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
char * SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name)
@ SDL_JOYSTICK_POWER_FULL
@ SDL_JOYSTICK_POWER_MEDIUM
@ SDL_JOYSTICK_POWER_EMPTY
@ SDL_JOYSTICK_POWER_UNKNOWN
@ SDL_JOYSTICK_POWER_WIRED
GLuint GLuint GLsizei count
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLuint const GLchar * name
GLuint GLsizei GLsizei * length
GLsizei const GLfloat * value
GLsizei const GLchar *const * string
#define SDL_arraysize(array)
#define SDL_stack_alloc(type, count)
#define SDL_MAX_UINT16
An unsigned 16-bit integer type.
#define SDL_HARDWARE_BUS_USB
SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
HRESULT WIN_CoInitialize(void)
void WIN_CoUninitialize(void)
#define WIN_StringToUTF8(S)
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)
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 int in j)
static SDL_AudioDeviceID device
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 endif[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 skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if
USHORT NumberInputValueCaps
USHORT NumberInputButtonCaps
struct HIDP_VALUE_CAPS::@20::@23 NotRange
A type representing an atomic integer value. It is a struct so people don't accidentally use numeric ...
static SDL_Joystick * joystick
static NativeWindowFactory * factory
#define USB_USAGE_GENERIC_GAMEPAD
#define USB_USAGE_GENERIC_Z
#define USB_VENDOR_MICROSOFT
#define USB_USAGEPAGE_BUTTON
#define USB_PRODUCT_XBOX_ONE_RAW_INPUT_CONTROLLER
#define USB_USAGE_GENERIC_HAT
#define USB_USAGEPAGE_GENERIC_DESKTOP
typedef int(__stdcall *FARPROC)()