Improve gyro-to-analog(s)

This commit is contained in:
Denis 2024-01-06 16:59:41 +01:00
parent 0853d0cdc6
commit 3bd22ad542
No known key found for this signature in database
GPG key ID: DD9B63F805CF5C03
11 changed files with 132 additions and 29 deletions

View file

@ -34,6 +34,8 @@ int main(int argc, char ** argv) {
.controller_bluetooth = false, .controller_bluetooth = false,
.dualsense_edge = false, .dualsense_edge = false,
.swap_y_z = false, .swap_y_z = false,
.gyro_to_analog_activation_treshold = 16,
.gyro_to_analog_mapping = 4,
}; };
load_out_config(&out_settings, configuration_file); load_out_config(&out_settings, configuration_file);

View file

@ -6,6 +6,8 @@ rumble_on_mode_switch = true;
gamepad_rumble_control = true; gamepad_rumble_control = true;
gamepad_leds_control = true; gamepad_leds_control = true;
m1m2_mode = 1; m1m2_mode = 1;
gyro_to_analog_mapping = 5;
gyro_to_analog_activation_treshold = 1;
touchbar = true; touchbar = true;
controller_bluetooth = true; controller_bluetooth = true;
dualsense_edge = false; dualsense_edge = false;

View file

@ -21,3 +21,11 @@ int64_t min_max_clamp(int64_t value, int64_t min, int64_t max) {
return value; return value;
} }
int64_t absolute_value(int64_t value) {
if (value < 0) {
return (int64_t)-1 * value;
}
return value;
}

View file

@ -64,4 +64,6 @@ int32_t div_round_closest(int32_t x, int32_t divisor);
int64_t div_round_closest_i64(int64_t x, int64_t divisor); int64_t div_round_closest_i64(int64_t x, int64_t divisor);
int64_t min_max_clamp(int64_t value, int64_t min, int64_t max); int64_t min_max_clamp(int64_t value, int64_t min, int64_t max);
int64_t absolute_value(int64_t value);

View file

@ -120,6 +120,21 @@ void load_out_config(dev_out_settings_t *const out_conf, const char* const filep
fprintf(stderr, "swap_y_z (bool) configuration not found. Default value will be used.\n"); fprintf(stderr, "swap_y_z (bool) configuration not found. Default value will be used.\n");
} }
int gyro_to_analog_activation_treshold;
if (config_lookup_int(&cfg, "gyro_to_analog_activation_treshold", &gyro_to_analog_activation_treshold) != CONFIG_FALSE) {
out_conf->gyro_to_analog_activation_treshold = gyro_to_analog_activation_treshold;
} else {
fprintf(stderr, "gyro_to_analog_activation_treshold (int) configuration not found. Default value will be used.\n");
}
int gyro_to_analog_mapping;
if (config_lookup_int(&cfg, "gyro_to_analog_mapping", &gyro_to_analog_mapping) != CONFIG_FALSE) {
out_conf->gyro_to_analog_mapping = gyro_to_analog_mapping == 0 ? 1 : gyro_to_analog_mapping;
} else {
fprintf(stderr, "gyro_to_analog_mapping (int) configuration not found. Default value will be used.\n");
}
config_destroy(&cfg); config_destroy(&cfg);
load_out_config_err: load_out_config_err:

View file

@ -20,6 +20,8 @@ typedef struct dev_out_settings {
bool controller_bluetooth; bool controller_bluetooth;
bool dualsense_edge; bool dualsense_edge;
bool swap_y_z; bool swap_y_z;
int gyro_to_analog_activation_treshold;
int gyro_to_analog_mapping;
} dev_out_settings_t; } dev_out_settings_t;
void load_out_config(dev_out_settings_t *const out_conf, const char* const filepath); void load_out_config(dev_out_settings_t *const out_conf, const char* const filepath);

View file

@ -20,6 +20,8 @@ int main(int argc, char ** argv) {
.controller_bluetooth = false, .controller_bluetooth = false,
.dualsense_edge = false, .dualsense_edge = false,
.swap_y_z = false, .swap_y_z = false,
.gyro_to_analog_activation_treshold = 16,
.gyro_to_analog_mapping = 4,
}; };
load_out_config(&out_settings, configuration_file); load_out_config(&out_settings, configuration_file);

View file

@ -429,9 +429,16 @@ static ds4_dpad_status_t ds4_dpad_from_gamepad(uint8_t dpad) {
return DPAD_RELEASED; return DPAD_RELEASED;
} }
int virt_dualshock_init(virt_dualshock_t *const out_gamepad, bool bluetooth) { int virt_dualshock_init(
virt_dualshock_t *const out_gamepad,
bool bluetooth,
int64_t gyro_to_analog_activation_treshold,
int64_t gyro_to_analog_mapping
) {
int ret = 0; int ret = 0;
out_gamepad->gyro_to_analog_activation_treshold = absolute_value(gyro_to_analog_activation_treshold);
out_gamepad->gyro_to_analog_mapping = gyro_to_analog_mapping;
out_gamepad->dt_sum = 0; out_gamepad->dt_sum = 0;
out_gamepad->dt_buffer_current = 0; out_gamepad->dt_buffer_current = 0;
memset(out_gamepad->dt_buffer, 0, sizeof(out_gamepad->dt_buffer)); memset(out_gamepad->dt_buffer, 0, sizeof(out_gamepad->dt_buffer));
@ -781,11 +788,14 @@ void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *c
*/ */
const int16_t g_x = in_device_status->raw_gyro[0]; const int16_t g_x = in_device_status->raw_gyro[0];
const int16_t g_y = in_device_status->raw_gyro[1]; // Swap Y and Z const int16_t g_y = in_device_status->raw_gyro[1];
const int16_t g_z = in_device_status->raw_gyro[2]; // Swap Y and Z const int16_t g_z = in_device_status->raw_gyro[2];
const int16_t a_x = in_device_status->raw_accel[0]; const int16_t a_x = in_device_status->raw_accel[0];
const int16_t a_y = in_device_status->raw_accel[1]; // Swap Y and Z const int16_t a_y = in_device_status->raw_accel[1];
const int16_t a_z = in_device_status->raw_accel[2]; // Swap Y and Z const int16_t a_z = in_device_status->raw_accel[2];
const int64_t contrib_x = (int64_t)127 + ((int64_t)g_y / (int64_t)gamepad->gyro_to_analog_mapping);
const int64_t contrib_y = (int64_t)127 + ((int64_t)g_x / (int64_t)gamepad->gyro_to_analog_mapping);
out_buf[0] = gamepad->bluetooth ? DS4_INPUT_REPORT_BT : DS4_INPUT_REPORT_USB; // [00] report ID (0x01) out_buf[0] = gamepad->bluetooth ? DS4_INPUT_REPORT_BT : DS4_INPUT_REPORT_USB; // [00] report ID (0x01)
@ -811,10 +821,25 @@ void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *c
(in_device_status->r1 ? 0x02 : 0x00) | (in_device_status->r1 ? 0x02 : 0x00) |
(in_device_status->l1 ? 0x01 : 0x00); (in_device_status->l1 ? 0x01 : 0x00);
/* if (contrib_y > gamepad->gyro_to_analog_activation_treshold) {
static uint8_t counter = 0; if (absolute_value(contrib_x) > gamepad->gyro_to_analog_activation_treshold) {
buf[7] = (((counter++) % (uint8_t)64) << ((uint8_t)2)) | get_buttons_byte3_by_gs(&gs); out_shifted_buf[1] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[3] - (int64_t)127) + contrib_x), 0, 255);
*/ }
if (absolute_value(contrib_y) > gamepad->gyro_to_analog_activation_treshold) {
out_shifted_buf[2] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[4] - (int64_t)127) + contrib_y), 0, 255);
}
}
if (in_device_status->join_right_analog_and_gyroscope) {
if (absolute_value(contrib_x) > gamepad->gyro_to_analog_activation_treshold) {
out_shifted_buf[3] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[3] - (int64_t)127) + contrib_x), 0, 255);
}
if (absolute_value(contrib_y) > gamepad->gyro_to_analog_activation_treshold) {
out_shifted_buf[4] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[4] - (int64_t)127) + contrib_y), 0, 255);
}
}
out_shifted_buf[7] = in_device_status->center ? 0x01 : 0x00; out_shifted_buf[7] = in_device_status->center ? 0x01 : 0x00;

View file

@ -21,16 +21,38 @@ typedef struct virt_dualshock {
uint32_t empty_reports; uint32_t empty_reports;
int64_t last_time; int64_t last_time;
int64_t gyro_to_analog_activation_treshold;
int64_t gyro_to_analog_mapping;
} virt_dualshock_t; } virt_dualshock_t;
int virt_dualshock_init(virt_dualshock_t *const gamepad, bool bluetooth); int virt_dualshock_init(
virt_dualshock_t *const gamepad,
bool bluetooth,
int64_t gyro_to_analog_activation_treshold,
int64_t gyro_to_analog_mapping
);
int virt_dualshock_get_fd(virt_dualshock_t *const gamepad); int virt_dualshock_get_fd(
virt_dualshock_t *const gamepad
);
int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *const out_device_status); int virt_dualshock_event(
virt_dualshock_t *const gamepad,
gamepad_status_t *const out_device_status
);
void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *const in_device_status, uint8_t *const out_buf); void virt_dualshock_compose(
virt_dualshock_t *const gamepad,
gamepad_status_t *const in_device_status,
uint8_t *const out_buf
);
int virt_dualshock_send(virt_dualshock_t *const gamepad, uint8_t *const out_buf); int virt_dualshock_send(
virt_dualshock_t *const gamepad,
uint8_t *const out_buf
);
void virt_dualshock_close(virt_dualshock_t *const gamepad); void virt_dualshock_close(
virt_dualshock_t *const gamepad
);

View file

@ -1102,9 +1102,17 @@ static void destroy(int fd)
uhid_write(fd, &ev); uhid_write(fd, &ev);
} }
int virt_dualsense_init(virt_dualsense_t *const out_gamepad, bool bluetooth, bool dualsense_edge) { int virt_dualsense_init(
virt_dualsense_t *const out_gamepad,
bool bluetooth,
bool dualsense_edge,
int64_t gyro_to_analog_activation_treshold,
int64_t gyro_to_analog_mapping
) {
int ret = 0; int ret = 0;
out_gamepad->gyro_to_analog_activation_treshold = absolute_value(gyro_to_analog_activation_treshold);
out_gamepad->gyro_to_analog_mapping = gyro_to_analog_mapping;
out_gamepad->edge_model = dualsense_edge; out_gamepad->edge_model = dualsense_edge;
out_gamepad->bluetooth = bluetooth; out_gamepad->bluetooth = bluetooth;
out_gamepad->dt_sum = 0; out_gamepad->dt_sum = 0;
@ -1452,14 +1460,14 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c
const uint32_t timestamp = sim_time + (int)((double)gamepad->empty_reports * DS5_SPEC_DELTA_TIME); const uint32_t timestamp = sim_time + (int)((double)gamepad->empty_reports * DS5_SPEC_DELTA_TIME);
const int16_t g_x = in_device_status->raw_gyro[0]; const int16_t g_x = in_device_status->raw_gyro[0];
const int16_t g_y = in_device_status->raw_gyro[1]; // Swap Y and Z const int16_t g_y = in_device_status->raw_gyro[1];
const int16_t g_z = in_device_status->raw_gyro[2]; // Swap Y and Z const int16_t g_z = in_device_status->raw_gyro[2];
const int16_t a_x = in_device_status->raw_accel[0]; const int16_t a_x = in_device_status->raw_accel[0];
const int16_t a_y = in_device_status->raw_accel[1]; // Swap Y and Z const int16_t a_y = in_device_status->raw_accel[1];
const int16_t a_z = in_device_status->raw_accel[2]; // Swap Y and Z const int16_t a_z = in_device_status->raw_accel[2];
const int64_t contrib_x = (int64_t)127 + ((int64_t)g_y / (int64_t)4); const int64_t contrib_x = (int64_t)127 + ((int64_t)g_y / (int64_t)gamepad->gyro_to_analog_mapping);
const int64_t contrib_y = (int64_t)127 + ((int64_t)g_x / (int64_t)4); const int64_t contrib_y = (int64_t)127 + ((int64_t)g_x / (int64_t)gamepad->gyro_to_analog_mapping);
out_buf[0] = gamepad->bluetooth ? DS_INPUT_REPORT_BT : DS_INPUT_REPORT_USB; // [00] report ID (0x01) out_buf[0] = gamepad->bluetooth ? DS_INPUT_REPORT_BT : DS_INPUT_REPORT_USB; // [00] report ID (0x01)
@ -1469,14 +1477,24 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c
out_shifted_buf[3] = ((uint64_t)((int64_t)in_device_status->joystick_positions[1][0] + (int64_t)32768) >> (uint64_t)8); // R stick, X axis out_shifted_buf[3] = ((uint64_t)((int64_t)in_device_status->joystick_positions[1][0] + (int64_t)32768) >> (uint64_t)8); // R stick, X axis
out_shifted_buf[4] = ((uint64_t)((int64_t)in_device_status->joystick_positions[1][1] + (int64_t)32768) >> (uint64_t)8); // R stick, Y axis out_shifted_buf[4] = ((uint64_t)((int64_t)in_device_status->joystick_positions[1][1] + (int64_t)32768) >> (uint64_t)8); // R stick, Y axis
if (in_device_status->join_left_analog_and_gyroscope) { if (contrib_y > gamepad->gyro_to_analog_activation_treshold) {
out_shifted_buf[1] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[3] - (int64_t)127) + contrib_x), 0, 255); if (absolute_value(contrib_x) > gamepad->gyro_to_analog_activation_treshold) {
out_shifted_buf[2] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[4] - (int64_t)127) + contrib_y), 0, 255); out_shifted_buf[1] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[3] - (int64_t)127) + contrib_x), 0, 255);
}
if (absolute_value(contrib_y) > gamepad->gyro_to_analog_activation_treshold) {
out_shifted_buf[2] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[4] - (int64_t)127) + contrib_y), 0, 255);
}
} }
if (in_device_status->join_right_analog_and_gyroscope) { if (in_device_status->join_right_analog_and_gyroscope) {
out_shifted_buf[3] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[3] - (int64_t)127) + contrib_x), 0, 255); if (absolute_value(contrib_x) > gamepad->gyro_to_analog_activation_treshold) {
out_shifted_buf[4] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[4] - (int64_t)127) + contrib_y), 0, 255); out_shifted_buf[3] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[3] - (int64_t)127) + contrib_x), 0, 255);
}
if (absolute_value(contrib_y) > gamepad->gyro_to_analog_activation_treshold) {
out_shifted_buf[4] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[4] - (int64_t)127) + contrib_y), 0, 255);
}
} }
out_shifted_buf[5] = in_device_status->l2_trigger; // Z out_shifted_buf[5] = in_device_status->l2_trigger; // Z

View file

@ -25,12 +25,17 @@ typedef struct virt_dualsense {
uint32_t empty_reports; uint32_t empty_reports;
int64_t last_time; int64_t last_time;
int64_t gyro_to_analog_activation_treshold;
int64_t gyro_to_analog_mapping;
} virt_dualsense_t; } virt_dualsense_t;
int virt_dualsense_init( int virt_dualsense_init(
virt_dualsense_t *const gamepad, virt_dualsense_t *const gamepad,
bool bluetooth, bool bluetooth,
bool dualsense_edge bool dualsense_edge,
int64_t gyro_to_analog_activation_treshold,
int64_t gyro_to_analog_mapping
); );
int virt_dualsense_get_fd( int virt_dualsense_get_fd(