From 9b5d60ee3e98de7f38d5ecb812a8c8a55507c6e4 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 30 Nov 2023 03:01:06 +0100 Subject: [PATCH] Rumble test --- virt_ds5.c | 67 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index e834fff..467f23f 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -14,6 +14,11 @@ #define DS_INPUT_REPORT_USB 0x01 #define DS_INPUT_REPORT_USB_SIZE 64 +#define DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT 0x02 + +#define DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2 0x04 +#define DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION 0x01 + #define DS5_SPEC_DELTA_TIME 188.0f static const char* path = "/dev/uhid"; @@ -94,14 +99,14 @@ static void destroy(int fd) uhid_write(fd, &ev); } -static void handle_output(struct uhid_event *ev, const logic_t *const logic) +static void handle_output(struct uhid_event *ev, logic_t *const logic) { // Rumble and LED messages are adverised via OUTPUT reports; ignore the rest if (ev->u.output.rtype != UHID_OUTPUT_REPORT) return; - if (ev->u.output.size != 63) { - fprintf(stderr, "Invalid data length: got %d, expected 63\n", (int)ev->u.output.size); + if (ev->u.output.size != 48) { + fprintf(stderr, "Invalid data length: got %d, expected 48\n", (int)ev->u.output.size); return; } @@ -114,16 +119,54 @@ static void handle_output(struct uhid_event *ev, const logic_t *const logic) const uint8_t valid_flag0 = ev->u.output.data[1]; const uint8_t valid_flag1 = ev->u.output.data[2]; - const uint8_t reserved = ev->u.output.data[3]; - const uint8_t motor_right = ev->u.output.data[4]; - const uint8_t motor_left = ev->u.output.data[5]; - const uint8_t lightbar_red = ev->u.output.data[6]; - const uint8_t lightbar_green = ev->u.output.data[7]; - const uint8_t lightbar_blue = ev->u.output.data[8]; - const uint8_t lightbar_blink_on = ev->u.output.data[9]; - const uint8_t lightbar_blink_off = ev->u.output.data[10]; + // For DualShock 4 compatibility mode. + const uint8_t motor_right = ev->u.output.data[3]; + const uint8_t motor_left = ev->u.output.data[4]; - // TODO dualsense logic + // Audio controls + const uint8_t reserved[4] = { ev->u.output.data[5], ev->u.output.data[6], ev->u.output.data[7], ev->u.output.data[8]}; + const uint8_t mute_button_led = ev->u.output.data[9]; + + uint8_t power_save_control = ev->u.output.data[10]; + uint8_t reserved2[28]; + + // LEDs and lightbar + uint8_t valid_flag2 = ev->u.output.data[39]; + uint8_t reserved3[2] = {ev->u.output.data[40], ev->u.output.data[41]}; + uint8_t lightbar_setup = ev->u.output.data[42]; + uint8_t led_brightness = ev->u.output.data[43]; + uint8_t player_leds = ev->u.output.data[44]; + uint8_t lightbar_red = ev->u.output.data[45]; + uint8_t lightbar_green = ev->u.output.data[46]; + uint8_t lightbar_blue = ev->u.output.data[47]; + + if ((valid_flag0 & DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT) && (logic->gamepad_output == LOGIC_FLAGS_VIRT_DS5_ENABLE)) { + if ((valid_flag2 & DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2) || (valid_flag0 & DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION)) { + + const int lock_res = pthread_mutex_lock(&logic->gamepad_mutex); + if (lock_res != 0) { + printf("Unable to lock gamepad mutex: %d, rumble will not be updated.\n", lock_res); + + return; + } + + logic->gamepad.motors_intensity[0] = motor_left; + logic->gamepad.motors_intensity[1] = motor_right; + ++logic->gamepad.rumble_events_count; + + pthread_mutex_unlock(&logic->gamepad_mutex); + +#if defined(VIRT_DS4_DEBUG) + printf( + "Updated rumble -- motor_left: %d, motor_right: %d, valid_flag0; %d, valid_flag1: %d\n", + motor_left, + motor_right, + valid_flag0, + valid_flag1 + ); +#endif + } + } } static int event(int fd, logic_t *const logic)