21 #include "../../SDL_internal.h"
23 #ifdef SDL_JOYSTICK_HIDAPI
30 #include "../SDL_sysjoystick.h"
35 #ifdef SDL_JOYSTICK_HIDAPI_PS5
43 #define GYRO_RES_PER_DEGREE 1024.0f
44 #define ACCEL_RES_PER_G 8192.0f
45 #define BLUETOOTH_DISCONNECT_TIMEOUT_MS 500
47 #define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8))
51 k_EPS5ReportIdState = 0x01,
52 k_EPS5ReportIdUsbEffects = 0x02,
53 k_EPS5ReportIdBluetoothEffects = 0x31,
54 k_EPS5ReportIdBluetoothState = 0x31,
59 k_EPS5FeatureReportIdCalibration = 0x05,
60 k_EPS5FeatureReportIdSerialNumber = 0x09,
61 } EPS5FeatureReportId;
65 Uint8 ucLeftJoystickX;
66 Uint8 ucLeftJoystickY;
67 Uint8 ucRightJoystickX;
68 Uint8 ucRightJoystickY;
69 Uint8 rgucButtonsHatAndCounter[3];
72 } PS5SimpleStatePacket_t;
76 Uint8 ucLeftJoystickX;
77 Uint8 ucLeftJoystickY;
78 Uint8 ucRightJoystickX;
79 Uint8 ucRightJoystickY;
83 Uint8 rgucButtonsAndHat[3];
85 Uint8 rgucPacketSequence[4];
94 Uint8 ucTouchpadCounter1;
95 Uint8 rgucTouchpadData1[3];
96 Uint8 ucTouchpadCounter2;
97 Uint8 rgucTouchpadData2[3];
98 Uint8 rgucUnknown1[8];
100 Uint8 ucBatteryLevel;
101 Uint8 ucConnectState;
112 Uint8 ucHeadphoneVolume;
113 Uint8 ucSpeakerVolume;
114 Uint8 ucMicrophoneVolume;
115 Uint8 ucAudioEnableBits;
116 Uint8 ucMicLightMode;
117 Uint8 ucAudioMuteBits;
118 Uint8 rgucRightTriggerEffect[11];
119 Uint8 rgucLeftTriggerEffect[11];
120 Uint8 rgucUnknown1[6];
122 Uint8 rgucUnknown2[2];
124 Uint8 ucLedBrightness;
133 k_EDS5EffectRumbleStart,
135 k_EDS5EffectLEDReset,
137 k_EDS5EffectPadLights,
138 k_EDS5EffectMicLight,
142 k_EDS5LEDResetStateNone,
143 k_EDS5LEDResetStatePending,
144 k_EDS5LEDResetStateComplete,
150 } IMUCalibrationData;
156 IMUCalibrationData calibration[6];
165 EDS5LEDResetState led_reset_state;
168 PS5SimpleStatePacket_t simple;
169 PS5StatePacket_t
state;
171 } SDL_DriverPS5_Context;
181 HIDAPI_DriverPS5_GetDeviceName(
Uint16 vendor_id,
Uint16 product_id)
184 return "PS5 Controller";
192 report[0] = report_id;
197 SetLedsForPlayerIndex(DS5EffectsState_t *effects,
int player_index)
203 { 0x00, 0x00, 0x40 },
204 { 0x40, 0x00, 0x00 },
205 { 0x00, 0x40, 0x00 },
206 { 0x20, 0x00, 0x20 },
207 { 0x02, 0x01, 0x00 },
208 { 0x00, 0x01, 0x01 },
212 if (player_index >= 0) {
218 effects->ucLedRed =
colors[player_index][0];
219 effects->ucLedGreen =
colors[player_index][1];
220 effects->ucLedBlue =
colors[player_index][2];
238 SDL_DriverPS5_Context *
ctx = (SDL_DriverPS5_Context *)
device->context;
242 size = ReadFeatureReport(
device->dev, k_EPS5FeatureReportIdCalibration,
data,
sizeof(
data));
244 #ifdef DEBUG_PS5_CALIBRATION
245 SDL_Log(
"Short read of calibration data: %d, ignoring calibration\n",
size);
251 Sint16 sGyroPitchBias, sGyroYawBias, sGyroRollBias;
252 Sint16 sGyroPitchPlus, sGyroPitchMinus;
253 Sint16 sGyroYawPlus, sGyroYawMinus;
254 Sint16 sGyroRollPlus, sGyroRollMinus;
255 Sint16 sGyroSpeedPlus, sGyroSpeedMinus;
257 Sint16 sAccXPlus, sAccXMinus;
258 Sint16 sAccYPlus, sAccYMinus;
259 Sint16 sAccZPlus, sAccZMinus;
264 #ifdef DEBUG_PS5_CALIBRATION
268 sGyroPitchBias = LOAD16(
data[1],
data[2]);
269 sGyroYawBias = LOAD16(
data[3],
data[4]);
270 sGyroRollBias = LOAD16(
data[5],
data[6]);
272 sGyroPitchPlus = LOAD16(
data[7],
data[8]);
273 sGyroPitchMinus = LOAD16(
data[9],
data[10]);
274 sGyroYawPlus = LOAD16(
data[11],
data[12]);
275 sGyroYawMinus = LOAD16(
data[13],
data[14]);
276 sGyroRollPlus = LOAD16(
data[15],
data[16]);
277 sGyroRollMinus = LOAD16(
data[17],
data[18]);
279 sGyroSpeedPlus = LOAD16(
data[19],
data[20]);
280 sGyroSpeedMinus = LOAD16(
data[21],
data[22]);
282 sAccXPlus = LOAD16(
data[23],
data[24]);
283 sAccXMinus = LOAD16(
data[25],
data[26]);
284 sAccYPlus = LOAD16(
data[27],
data[28]);
285 sAccYMinus = LOAD16(
data[29],
data[30]);
286 sAccZPlus = LOAD16(
data[31],
data[32]);
287 sAccZMinus = LOAD16(
data[33],
data[34]);
289 flNumerator = (sGyroSpeedPlus + sGyroSpeedMinus) * GYRO_RES_PER_DEGREE;
290 ctx->calibration[0].bias = sGyroPitchBias;
291 ctx->calibration[0].sensitivity = flNumerator / (sGyroPitchPlus - sGyroPitchMinus);
293 ctx->calibration[1].bias = sGyroYawBias;
294 ctx->calibration[1].sensitivity = flNumerator / (sGyroYawPlus - sGyroYawMinus);
296 ctx->calibration[2].bias = sGyroRollBias;
297 ctx->calibration[2].sensitivity = flNumerator / (sGyroRollPlus - sGyroRollMinus);
299 sRange2g = sAccXPlus - sAccXMinus;
300 ctx->calibration[3].bias = sAccXPlus - sRange2g / 2;
301 ctx->calibration[3].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g;
303 sRange2g = sAccYPlus - sAccYMinus;
304 ctx->calibration[4].bias = sAccYPlus - sRange2g / 2;
305 ctx->calibration[4].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g;
307 sRange2g = sAccZPlus - sAccZMinus;
308 ctx->calibration[5].bias = sAccZPlus - sRange2g / 2;
309 ctx->calibration[5].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g;
312 for (
i = 0;
i < 6; ++
i) {
313 float divisor = (
i < 3 ? 64.0f : 1.0f);
314 #ifdef DEBUG_PS5_CALIBRATION
315 SDL_Log(
"calibration[%d] bias = %d, sensitivity = %f\n",
i,
ctx->calibration[
i].bias,
ctx->calibration[
i].sensitivity);
319 #ifdef DEBUG_PS5_CALIBRATION
320 SDL_Log(
"invalid calibration, ignoring\n");
333 if (
ctx->hardware_calibration) {
334 IMUCalibrationData *calibration = &
ctx->calibration[
index];
336 result = (
value - calibration->bias) * calibration->sensitivity;
337 }
else if (
index < 3) {
345 result = (
result / GYRO_RES_PER_DEGREE) * (
float)M_PI / 180.0f;
355 SDL_DriverPS5_Context *
ctx = (SDL_DriverPS5_Context *)
device->context;
356 DS5EffectsState_t *effects;
366 if (
ctx->is_bluetooth) {
367 data[0] = k_EPS5ReportIdBluetoothEffects;
373 data[0] = k_EPS5ReportIdUsbEffects;
381 if (effect == k_EDS5EffectLED &&
ctx->is_bluetooth) {
382 if (
ctx->led_reset_state != k_EDS5LEDResetStateComplete) {
383 ctx->led_reset_state = k_EDS5LEDResetStatePending;
388 if (
ctx->rumble_left ||
ctx->rumble_right) {
389 effects->ucEnableBits1 |= 0x01;
390 effects->ucEnableBits1 |= 0x02;
393 effects->ucRumbleLeft =
ctx->rumble_left >> 1;
394 effects->ucRumbleRight =
ctx->rumble_right >> 1;
400 case k_EDS5EffectRumbleStart:
401 effects->ucEnableBits1 |= 0x02;
403 case k_EDS5EffectRumble:
406 case k_EDS5EffectLEDReset:
407 effects->ucEnableBits2 |= 0x08;
409 case k_EDS5EffectLED:
410 effects->ucEnableBits2 |= 0x04;
413 if (
ctx->color_set) {
414 effects->ucLedRed =
ctx->led_red;
415 effects->ucLedGreen =
ctx->led_green;
416 effects->ucLedBlue =
ctx->led_blue;
418 SetLedsForPlayerIndex(effects,
ctx->player_index);
421 case k_EDS5EffectPadLights:
422 effects->ucEnableBits2 |= 0x10;
424 effects->ucPadLights = 0x00;
426 case k_EDS5EffectMicLight:
427 effects->ucEnableBits2 |= 0x01;
429 effects->ucMicLightMode = 0;
435 if (
ctx->is_bluetooth) {
440 unCRC =
SDL_crc32(unCRC,
data, (
size_t)(report_size -
sizeof(unCRC)));
441 SDL_memcpy(&
data[report_size -
sizeof(unCRC)], &unCRC,
sizeof(unCRC));
444 if (SDL_HIDAPI_LockRumble() < 0) {
449 if (SDL_HIDAPI_GetPendingRumbleLocked(
device, &pending_data, &pending_size, &maximum_size)) {
450 DS5EffectsState_t *pending_effects = (DS5EffectsState_t *)&pending_data[
offset];
451 if (report_size == *pending_size &&
452 effects->ucEnableBits1 == pending_effects->ucEnableBits1 &&
453 effects->ucEnableBits2 == pending_effects->ucEnableBits2) {
456 SDL_HIDAPI_UnlockRumble();
461 return SDL_HIDAPI_SendRumbleAndUnlock(
device,
data, report_size);
467 SDL_DriverPS5_Context *
ctx = (SDL_DriverPS5_Context *)
device->context;
469 if (
ctx->is_bluetooth != is_bluetooth) {
470 ctx->is_bluetooth = is_bluetooth;
471 HIDAPI_DriverPS5_UpdateEffects(
device, k_EDS5EffectLED);
478 SDL_DriverPS5_Context *
ctx = (SDL_DriverPS5_Context *)
device->context;
479 const PS5StatePacket_t *packet = &
ctx->last_state.state;
482 const Uint32 connection_complete = 10000000;
484 ((
Uint32)packet->rgucTimer1[1] << 8) |
485 ((
Uint32)packet->rgucTimer1[2] << 16) |
486 ((
Uint32)packet->rgucTimer1[3] << 24);
487 if (timer >= connection_complete) {
488 HIDAPI_DriverPS5_UpdateEffects(
device, k_EDS5EffectLEDReset);
490 ctx->led_reset_state = k_EDS5LEDResetStateComplete;
492 HIDAPI_DriverPS5_UpdateEffects(
device, k_EDS5EffectLED);
499 SDL_DriverPS5_Context *
ctx = (SDL_DriverPS5_Context *)
device->context;
505 ctx->player_index = player_index;
508 HIDAPI_DriverPS5_UpdateEffects(
device, k_EDS5EffectLED);
514 SDL_DriverPS5_Context *
ctx;
535 if (ReadFeatureReport(
device->dev, k_EPS5FeatureReportIdSerialNumber,
data,
sizeof(
data)) >= 7) {
538 SDL_snprintf(serial,
sizeof(serial),
"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
547 HIDAPI_DriverPS5_UpdateEffects(
device, k_EDS5EffectLED);
563 SDL_DriverPS5_Context *
ctx = (SDL_DriverPS5_Context *)
device->context;
565 if (!
ctx->rumble_left && !
ctx->rumble_right) {
566 HIDAPI_DriverPS5_UpdateEffects(
device, k_EDS5EffectRumbleStart);
569 ctx->rumble_left = (low_frequency_rumble >> 8);
570 ctx->rumble_right = (high_frequency_rumble >> 8);
572 return HIDAPI_DriverPS5_UpdateEffects(
device, k_EDS5EffectRumble);
590 SDL_DriverPS5_Context *
ctx = (SDL_DriverPS5_Context *)
device->context;
597 return HIDAPI_DriverPS5_UpdateEffects(
device, k_EDS5EffectLED);
603 SDL_DriverPS5_Context *
ctx = (SDL_DriverPS5_Context *)
device->context;
606 HIDAPI_DriverPS5_LoadCalibrationData(
device);
614 HIDAPI_DriverPS5_HandleSimpleStatePacket(SDL_Joystick *
joystick,
hid_device *dev, SDL_DriverPS5_Context *
ctx, PS5SimpleStatePacket_t *packet)
618 if (
ctx->last_state.simple.rgucButtonsHatAndCounter[0] != packet->rgucButtonsHatAndCounter[0]) {
620 Uint8 data = (packet->rgucButtonsHatAndCounter[0] >> 4);
628 Uint8 data = (packet->rgucButtonsHatAndCounter[0] & 0x0F);
673 if (
ctx->last_state.simple.rgucButtonsHatAndCounter[1] != packet->rgucButtonsHatAndCounter[1]) {
674 Uint8 data = packet->rgucButtonsHatAndCounter[1];
684 if (
ctx->last_state.simple.rgucButtonsHatAndCounter[2] != packet->rgucButtonsHatAndCounter[2]) {
685 Uint8 data = (packet->rgucButtonsHatAndCounter[2] & 0x03);
691 axis = ((
int)packet->ucTriggerLeft * 257) - 32768;
693 axis = ((
int)packet->ucTriggerRight * 257) - 32768;
695 axis = ((
int)packet->ucLeftJoystickX * 257) - 32768;
697 axis = ((
int)packet->ucLeftJoystickY * 257) - 32768;
699 axis = ((
int)packet->ucRightJoystickX * 257) - 32768;
701 axis = ((
int)packet->ucRightJoystickY * 257) - 32768;
704 SDL_memcpy(&
ctx->last_state.simple, packet,
sizeof(
ctx->last_state.simple));
708 HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *
joystick,
hid_device *dev, SDL_DriverPS5_Context *
ctx, PS5StatePacket_t *packet)
710 static const float TOUCHPAD_SCALEX = 1.0f / 1920;
711 static const float TOUCHPAD_SCALEY = 1.0f / 1070;
713 Uint8 touchpad_state;
714 int touchpad_x, touchpad_y;
716 if (
ctx->last_state.state.rgucButtonsAndHat[0] != packet->rgucButtonsAndHat[0]) {
718 Uint8 data = (packet->rgucButtonsAndHat[0] >> 4);
726 Uint8 data = (packet->rgucButtonsAndHat[0] & 0x0F);
771 if (
ctx->last_state.state.rgucButtonsAndHat[1] != packet->rgucButtonsAndHat[1]) {
772 Uint8 data = packet->rgucButtonsAndHat[1];
782 if (
ctx->last_state.state.rgucButtonsAndHat[2] != packet->rgucButtonsAndHat[2]) {
783 Uint8 data = packet->rgucButtonsAndHat[2];
790 axis = ((
int)packet->ucTriggerLeft * 257) - 32768;
792 axis = ((
int)packet->ucTriggerRight * 257) - 32768;
794 axis = ((
int)packet->ucLeftJoystickX * 257) - 32768;
796 axis = ((
int)packet->ucLeftJoystickY * 257) - 32768;
798 axis = ((
int)packet->ucRightJoystickX * 257) - 32768;
800 axis = ((
int)packet->ucRightJoystickY * 257) - 32768;
803 if (packet->ucBatteryLevel & 0x10) {
808 int level = (packet->ucBatteryLevel & 0xF);
811 }
else if (
level <= 2) {
813 }
else if (
level <= 7) {
821 touchpad_x = packet->rgucTouchpadData1[0] | (((
int)packet->rgucTouchpadData1[1] & 0x0F) << 8);
822 touchpad_y = (packet->rgucTouchpadData1[1] >> 4) | ((
int)packet->rgucTouchpadData1[2] << 4);
826 touchpad_x = packet->rgucTouchpadData2[0] | (((
int)packet->rgucTouchpadData2[1] & 0x0F) << 8);
827 touchpad_y = (packet->rgucTouchpadData2[1] >> 4) | ((
int)packet->rgucTouchpadData2[2] << 4);
830 if (
ctx->report_sensors) {
833 data[0] = HIDAPI_DriverPS5_ApplyCalibrationData(
ctx, 0, LOAD16(packet->rgucGyroX[0], packet->rgucGyroX[1]));
834 data[1] = HIDAPI_DriverPS5_ApplyCalibrationData(
ctx, 1, LOAD16(packet->rgucGyroY[0], packet->rgucGyroY[1]));
835 data[2] = HIDAPI_DriverPS5_ApplyCalibrationData(
ctx, 2, LOAD16(packet->rgucGyroZ[0], packet->rgucGyroZ[1]));
838 data[0] = HIDAPI_DriverPS5_ApplyCalibrationData(
ctx, 3, LOAD16(packet->rgucAccelX[0], packet->rgucAccelX[1]));
839 data[1] = HIDAPI_DriverPS5_ApplyCalibrationData(
ctx, 4, LOAD16(packet->rgucAccelY[0], packet->rgucAccelY[1]));
840 data[2] = HIDAPI_DriverPS5_ApplyCalibrationData(
ctx, 5, LOAD16(packet->rgucAccelZ[0], packet->rgucAccelZ[1]));
850 SDL_DriverPS5_Context *
ctx = (SDL_DriverPS5_Context *)
device->context;
854 int packet_count = 0;
864 #ifdef DEBUG_PS5_PROTOCOL
871 case k_EPS5ReportIdState:
874 HIDAPI_DriverPS5_HandleSimpleStatePacket(
joystick,
device->dev,
ctx, (PS5SimpleStatePacket_t *)&
data[1]);
880 case k_EPS5ReportIdBluetoothState:
883 if (
ctx->led_reset_state == k_EDS5LEDResetStatePending) {
884 HIDAPI_DriverPS5_CheckPendingLEDReset(
device);
888 #ifdef DEBUG_JOYSTICK
895 if (
ctx->is_bluetooth && packet_count == 0) {
899 HIDAPI_DriverPS5_UpdateEffects(
device, k_EDS5EffectNone);
929 HIDAPI_DriverPS5_IsSupportedDevice,
930 HIDAPI_DriverPS5_GetDeviceName,
931 HIDAPI_DriverPS5_InitDevice,
932 HIDAPI_DriverPS5_GetDevicePlayerIndex,
933 HIDAPI_DriverPS5_SetDevicePlayerIndex,
934 HIDAPI_DriverPS5_UpdateDevice,
935 HIDAPI_DriverPS5_OpenJoystick,
936 HIDAPI_DriverPS5_RumbleJoystick,
937 HIDAPI_DriverPS5_RumbleJoystickTriggers,
938 HIDAPI_DriverPS5_HasJoystickLED,
939 HIDAPI_DriverPS5_SetJoystickLED,
940 HIDAPI_DriverPS5_SetJoystickSensorsEnabled,
941 HIDAPI_DriverPS5_CloseJoystick,
942 HIDAPI_DriverPS5_FreeDevice,
#define SDL_JoystickGetPlayerIndex
#define SDL_JoystickFromInstanceID
#define SDL_OutOfMemory()
#define SDL_Unsupported()
@ SDL_CONTROLLER_AXIS_LEFTX
@ SDL_CONTROLLER_AXIS_TRIGGERRIGHT
@ SDL_CONTROLLER_AXIS_RIGHTY
@ SDL_CONTROLLER_AXIS_RIGHTX
@ SDL_CONTROLLER_AXIS_MAX
@ SDL_CONTROLLER_AXIS_TRIGGERLEFT
@ SDL_CONTROLLER_AXIS_LEFTY
@ 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_GUIDE
@ SDL_CONTROLLER_BUTTON_DPAD_RIGHT
@ SDL_CONTROLLER_BUTTON_X
@ SDL_CONTROLLER_BUTTON_RIGHTSTICK
@ SDL_CONTROLLER_BUTTON_Y
@ SDL_CONTROLLER_BUTTON_A
@ SDL_CONTROLLER_TYPE_PS5
#define USB_PACKET_LENGTH
void HIDAPI_DumpPacket(const char *prefix, Uint8 *data, int size)
SDL_bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID)
void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID)
SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5
#define SDL_HINT_JOYSTICK_HIDAPI_PS5
A variable controlling whether the HIDAPI driver for PS5 controllers should be used.
int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger, Uint8 state, float x, float y, float pressure)
void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel)
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers)
int SDL_PrivateJoystickSensor(SDL_Joystick *joystick, SDL_SensorType type, const float *data, int num_values)
void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
@ SDL_JOYSTICK_POWER_FULL
@ SDL_JOYSTICK_POWER_MEDIUM
@ SDL_JOYSTICK_POWER_EMPTY
@ SDL_JOYSTICK_POWER_WIRED
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLuint GLuint GLsizei GLenum type
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLuint const GLchar * name
GLuint GLsizei GLsizei * length
GLsizei const GLfloat * value
#define SDL_STANDARD_GRAVITY
#define SDL_arraysize(array)
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.
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)
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
Read an Input report from a HID device with timeout.
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length)
Get a feature report from a HID device.
HID_API_EXPORT hid_device *HID_API_CALL hid_open_path(const char *path, int bExclusive)
Open a HID device by its path name.
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
Close a HID device.
struct hid_device_ hid_device
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 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 skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
static SDL_Joystick * joystick
typedef int(__stdcall *FARPROC)()