From a0666cba2c430794f1f3e0de33415236a69b177e Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 13 Dec 2023 18:16:54 +0100 Subject: [PATCH 001/186] idead --- dev_in.c | 77 ++++++++++++++++++++++++++++++++++---------------------- dev_in.h | 2 -- 2 files changed, 47 insertions(+), 32 deletions(-) diff --git a/dev_in.c b/dev_in.c index 99554b5..4956b18 100644 --- a/dev_in.c +++ b/dev_in.c @@ -328,6 +328,9 @@ void* dev_in_thread_func(void *ptr) { const size_t max_devices = dev_in_data->input_dev_decl->dev_count; + in_message_t* controller_msg = malloc(sizeof(in_message_t) * 4); + size_t controller_msg_avail = controller_msg == NULL ? 0 : 4; + dev_in_t* const devices = malloc(sizeof(dev_in_t) * max_devices); if (devices == NULL) { fprintf(stderr, "Unable to allocate memory to hold devices -- aborting input thread\n"); @@ -463,40 +466,54 @@ void* dev_in_thread_func(void *ptr) { continue; } - in_message_t controller_msg[MAX_IN_MESSAGES]; - size_t controller_msg_avail = sizeof(controller_msg) / sizeof(in_message_t); - int controller_msg_count = -EIO; + int controller_msg_count = -ENOMEM; + while (controller_msg_count == -ENOMEM) { + // the following part fills controller_msg and writes in controller_msg_count an error or the number of messages to be sent to the output device + if (devices[i].type == DEV_IN_TYPE_EV) { + evdev_collected_t coll = { + .ev_count = 0 + }; - // the following part fills controller_msg and writes in controller_msg_count an error or the number of messages to be sent to the output device - if (devices[i].type == DEV_IN_TYPE_EV) { - evdev_collected_t coll = { - .ev_count = 0 - }; + controller_msg_count = fill_message_from_evdev(&devices[i].dev.evdev, &coll); + if (controller_msg_count != 0) { + fprintf(stderr, "Unable to fill input_event(s) for device %zd: %d -- Will reconnect the device\n", i, controller_msg_count); + evdev_close_device(&devices[i].dev.evdev); + devices[i].type = DEV_IN_TYPE_NONE; + continue; + } - controller_msg_count = fill_message_from_evdev(&devices[i].dev.evdev, &coll); - if (controller_msg_count != 0) { - fprintf(stderr, "Unable to fill input_event(s) for device %zd: %d -- Will reconnect the device\n", i, controller_msg_count); - evdev_close_device(&devices[i].dev.evdev); - devices[i].type = DEV_IN_TYPE_NONE; - continue; + controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.ev_input_map_fn(&coll, controller_msg, controller_msg_avail, dev_in_data->input_dev_decl->dev[i]->user_data); + } else if (devices[i].type == DEV_IN_TYPE_IIO) { + controller_msg_count = map_message_from_iio(&devices[i].dev.iio, controller_msg, controller_msg_avail); + if (controller_msg_count != 0) { + fprintf(stderr, "Error in performing operations for device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count); + iio_close_device(&devices[i].dev.iio); + devices[i].type = DEV_IN_TYPE_NONE; + continue; + } + } else if (devices[i].type == DEV_IN_TYPE_HIDRAW) { + controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.hidraw_input_map_fn(dev_hidraw_get_fd(devices[i].dev.hidraw.hidrawdev), controller_msg, controller_msg_avail, dev_in_data->input_dev_decl->dev[i]->user_data); + if (controller_msg_count != 0) { + fprintf(stderr, "Error in performing operations for device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count); + hidraw_close_device(&devices[i].dev.hidraw); + devices[i].type = DEV_IN_TYPE_NONE; + continue; + } } - controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.ev_input_map_fn(&coll, &controller_msg[0], controller_msg_avail, dev_in_data->input_dev_decl->dev[i]->user_data); - } else if (devices[i].type == DEV_IN_TYPE_IIO) { - controller_msg_count = map_message_from_iio(&devices[i].dev.iio, &controller_msg[0], controller_msg_avail); - if (controller_msg_count != 0) { - fprintf(stderr, "Error in performing operations for device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count); - iio_close_device(&devices[i].dev.iio); - devices[i].type = DEV_IN_TYPE_NONE; - continue; - } - } else if (devices[i].type == DEV_IN_TYPE_HIDRAW) { - controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.hidraw_input_map_fn(dev_hidraw_get_fd(devices[i].dev.hidraw.hidrawdev), &controller_msg[0], controller_msg_avail, dev_in_data->input_dev_decl->dev[i]->user_data); - if (controller_msg_count != 0) { - fprintf(stderr, "Error in performing operations for device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count); - hidraw_close_device(&devices[i].dev.hidraw); - devices[i].type = DEV_IN_TYPE_NONE; - continue; + // attempt to acquire more memory + if (controller_msg_count == -ENOMEM) { + printf("Map function reported not enough memory, allocating new one...\n"); + const size_t tmp_controller_msg_avail = controller_msg_avail * 2; + in_message_t *tmp_controller_msg = malloc(sizeof(in_message_t) * tmp_controller_msg_avail); + if (tmp_controller_msg == NULL) { + fprintf(stderr, "Could not allocate new memory -- will retry\n"); + } else { + printf("Allocated new memory to fill the buffer\n"); + free(controller_msg); + controller_msg = tmp_controller_msg; + controller_msg_avail = tmp_controller_msg_avail; + } } } diff --git a/dev_in.h b/dev_in.h index d66c0cf..1fd470f 100644 --- a/dev_in.h +++ b/dev_in.h @@ -4,8 +4,6 @@ #include "message.h" #include "input_dev.h" -#define MAX_IN_MESSAGES 8 - #define DEV_IN_FLAG_EXIT 0x00000001U typedef struct dev_in_data { From f87028f8f77fa43e944e5631ef05f5f2ee031e83 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 14 Dec 2023 02:55:46 +0100 Subject: [PATCH 002/186] report gyro & accel buffer to the output device --- dev_in.c | 28 +++++++++++++++++++++++++--- dev_out.c | 14 ++++++++++++++ message.h | 21 +++++++++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/dev_in.c b/dev_in.c index 99554b5..d81aa3f 100644 --- a/dev_in.c +++ b/dev_in.c @@ -5,8 +5,6 @@ #include "message.h" #include "dev_evdev.h" #include "dev_iio.h" -#include -#include typedef enum dev_in_type { DEV_IN_TYPE_NONE, @@ -61,6 +59,9 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const uint8_t data[32]; + struct timeval read_time; + gettimeofday(&read_time, NULL); + res = read(dev_iio_get_buffer_fd(in_iio->iiodev), &data[0], sizeof(data)); if (res == -1) { res = errno; @@ -68,7 +69,28 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const goto send_message_from_iio_err; } - res = 0; + if (res != 24) { + fprintf(stderr, "Invalid read lenght\n"); + res = -EIO; + goto send_message_from_iio_err; + } + + uint16_t *const scan_elements = (uint16_t*)&data[0]; + + messages[0].data.gamepad_set.element = GAMEPAD_ACCELEROMETER; + messages[0].data.gamepad_set.status.gyro.sample_time = read_time; + messages[0].data.gamepad_set.status.accel.x = scan_elements[0]; + messages[0].data.gamepad_set.status.accel.y = scan_elements[1]; + messages[0].data.gamepad_set.status.accel.z = scan_elements[2]; + + messages[1].type = GAMEPAD_SET_ELEMENT; + messages[1].data.gamepad_set.element = GAMEPAD_GYROSCOPE; + messages[1].data.gamepad_set.status.gyro.sample_time = read_time; + messages[1].data.gamepad_set.status.gyro.x = scan_elements[3]; + messages[1].data.gamepad_set.status.gyro.y = scan_elements[4]; + messages[1].data.gamepad_set.status.gyro.z = scan_elements[5]; + + res = 2; send_message_from_iio_err: return res; diff --git a/dev_out.c b/dev_out.c index 458ceca..dcf1f9e 100644 --- a/dev_out.c +++ b/dev_out.c @@ -134,6 +134,20 @@ static void handle_incoming_message_gamepad_set( break; } + case GAMEPAD_GYROSCOPE: { + inout_gamepad->last_gyro_motion_time = msg_payload->status.gyro.sample_time; + inout_gamepad->raw_gyro[0] = msg_payload->status.gyro.x; + inout_gamepad->raw_gyro[1] = msg_payload->status.gyro.y; + inout_gamepad->raw_gyro[2] = msg_payload->status.gyro.z; + break; + } + case GAMEPAD_ACCELEROMETER: { + inout_gamepad->last_accel_motion_time = msg_payload->status.accel.sample_time; + inout_gamepad->raw_accel[0] = msg_payload->status.accel.x; + inout_gamepad->raw_accel[1] = msg_payload->status.accel.y; + inout_gamepad->raw_accel[2] = msg_payload->status.accel.z; + break; + } default: { fprintf(stderr, "Unknown gamepad element: %d\n", msg_payload->element); break; diff --git a/message.h b/message.h index 91bc3b2..d16e371 100644 --- a/message.h +++ b/message.h @@ -32,14 +32,35 @@ typedef enum in_message_gamepad_btn { GAMEPAD_DPAD_X, GAMEPAD_DPAD_Y, + + GAMEPAD_GYROSCOPE, + GAMEPAD_ACCELEROMETER, } in_gamepad_element_t; +typedef struct in_message_gamepad_gyro { + struct timeval sample_time; + + uint16_t x; + uint16_t y; + uint16_t z; +} in_message_gamepad_gyro_t; + +typedef struct in_message_gamepad_accel { + struct timeval sample_time; + + uint16_t x; + uint16_t y; + uint16_t z; +} in_message_gamepad_accel_t; + typedef struct in_message_gamepad_set_element { in_gamepad_element_t element; union { uint8_t btn; int32_t joystick_pos; int8_t dpad; // -1 | 0 | +1 + in_message_gamepad_accel_t accel; + in_message_gamepad_gyro_t gyro; } status; } in_message_gamepad_set_element_t; From e580cca85cb88a8424a4ca91664d2c6120f14339 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 14 Dec 2023 03:04:29 +0100 Subject: [PATCH 003/186] fix iio and hidraw reads --- dev_in.c | 8 ++++---- dev_out.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dev_in.c b/dev_in.c index d81aa3f..ddbc784 100644 --- a/dev_in.c +++ b/dev_in.c @@ -458,7 +458,7 @@ void* dev_in_thread_func(void *ptr) { // TODO: handle_leds() } } else { - fprintf(stderr, "Error reading from out_message_pipe_fd: got %zu bytes, expected %zu butes\n", out_message_pipe_read_res, sizeof(out_message_t)); + fprintf(stderr, "Error reading from out_message_pipe_fd: got %zu bytes, expected %zu bytes\n", out_message_pipe_read_res, sizeof(out_message_t)); // in case of an error reschedule to socket for reconnection if (dev_in_data->communication.type == ipc_client_socket) { @@ -506,15 +506,15 @@ void* dev_in_thread_func(void *ptr) { controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.ev_input_map_fn(&coll, &controller_msg[0], controller_msg_avail, dev_in_data->input_dev_decl->dev[i]->user_data); } else if (devices[i].type == DEV_IN_TYPE_IIO) { controller_msg_count = map_message_from_iio(&devices[i].dev.iio, &controller_msg[0], controller_msg_avail); - if (controller_msg_count != 0) { - fprintf(stderr, "Error in performing operations for device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count); + if (controller_msg_count < 0) { + fprintf(stderr, "Error in reading iio buffer for device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count); iio_close_device(&devices[i].dev.iio); devices[i].type = DEV_IN_TYPE_NONE; continue; } } else if (devices[i].type == DEV_IN_TYPE_HIDRAW) { controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.hidraw_input_map_fn(dev_hidraw_get_fd(devices[i].dev.hidraw.hidrawdev), &controller_msg[0], controller_msg_avail, dev_in_data->input_dev_decl->dev[i]->user_data); - if (controller_msg_count != 0) { + if (controller_msg_count < 0) { fprintf(stderr, "Error in performing operations for device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count); hidraw_close_device(&devices[i].dev.hidraw); devices[i].type = DEV_IN_TYPE_NONE; diff --git a/dev_out.c b/dev_out.c index dcf1f9e..75901d8 100644 --- a/dev_out.c +++ b/dev_out.c @@ -358,7 +358,7 @@ void *dev_out_thread_func(void *ptr) { if (in_message_pipe_read_res == sizeof(in_message_t)) { handle_incoming_message(&incoming_message, &dev_out_data->dev_stats); } else { - fprintf(stderr, "Error reading from in_message_pipe_fd: got %zu bytes, expected %zu butes\n", in_message_pipe_read_res, sizeof(in_message_t)); + fprintf(stderr, "Error reading from in_message_pipe_fd: got %zu bytes, expected %zu bytes\n", in_message_pipe_read_res, sizeof(in_message_t)); } } } else if (dev_out_data->communication.type == ipc_server_sockets) { @@ -371,7 +371,7 @@ void *dev_out_thread_func(void *ptr) { if (in_message_pipe_read_res == sizeof(in_message_t)) { handle_incoming_message(&incoming_message, &dev_out_data->dev_stats); } else { - fprintf(stderr, "Error reading from socket number %d: got %zu bytes, expected %zu butes\n", i, in_message_pipe_read_res, sizeof(in_message_t)); + fprintf(stderr, "Error reading from socket number %d: got %zu bytes, expected %zu bytes\n", i, in_message_pipe_read_res, sizeof(in_message_t)); close(dev_out_data->communication.endpoint.ssocket.clients[i]); dev_out_data->communication.endpoint.ssocket.clients[i] = -1; } From 4d2c9c2e363a79f013c8ae2d458125928eabf81f Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 14 Dec 2023 03:15:34 +0100 Subject: [PATCH 004/186] Fixed a bug that prevented the gyro from being registered --- dev_in.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev_in.c b/dev_in.c index ddbc784..f27c847 100644 --- a/dev_in.c +++ b/dev_in.c @@ -77,8 +77,9 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const uint16_t *const scan_elements = (uint16_t*)&data[0]; + messages[0].type = GAMEPAD_SET_ELEMENT; messages[0].data.gamepad_set.element = GAMEPAD_ACCELEROMETER; - messages[0].data.gamepad_set.status.gyro.sample_time = read_time; + messages[0].data.gamepad_set.status.accel.sample_time = read_time; messages[0].data.gamepad_set.status.accel.x = scan_elements[0]; messages[0].data.gamepad_set.status.accel.y = scan_elements[1]; messages[0].data.gamepad_set.status.accel.z = scan_elements[2]; From c2e3a7704a25a4d170d2aac2e91be4c1b53a1293 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 14 Dec 2023 13:41:33 +0100 Subject: [PATCH 005/186] make logic work with both SOCK_STREAM and SEQ_PACKET --- dev_in.c | 22 +++++++++++++--------- dev_out.c | 23 ++++++++++++----------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/dev_in.c b/dev_in.c index f27c847..b342ba3 100644 --- a/dev_in.c +++ b/dev_in.c @@ -529,18 +529,22 @@ void* dev_in_thread_func(void *ptr) { } if (dev_in_data->communication.type == ipc_client_socket) { - const int write_res = write(dev_in_data->communication.endpoint.socket.fd, (void*)&controller_msg[0], sizeof(in_message_t) * controller_msg_count); - if (write_res < 0) { - fprintf(stderr, "Error in writing input event messages: %d -- connection will be drop and retried\n", write_res); + for (int msg_idx = 0; msg_idx < controller_msg_count; ++msg_idx) { + const int write_res = write(dev_in_data->communication.endpoint.socket.fd, (void*)&controller_msg[0], sizeof(in_message_t)); + if (write_res < 0) { + fprintf(stderr, "Error in writing input event messages: %d -- connection will be drop and retried\n", write_res); - // in case of an error reschedule to socket for reconnection - close(dev_in_data->communication.endpoint.socket.fd); - dev_in_data->communication.endpoint.socket.fd = -1; + // in case of an error reschedule to socket for reconnection + close(dev_in_data->communication.endpoint.socket.fd); + dev_in_data->communication.endpoint.socket.fd = -1; + } } } else if (dev_in_data->communication.type == ipc_unix_pipe) { - const int write_res = write(dev_in_data->communication.endpoint.pipe.in_message_pipe_fd, (void*)&controller_msg[0], sizeof(in_message_t) * controller_msg_count); - if (write_res < 0) { - fprintf(stderr, "Error in writing input event messages: %d\n", write_res); + for (int msg_idx = 0; msg_idx < controller_msg_count; ++msg_idx) { + const int write_res = write(dev_in_data->communication.endpoint.pipe.in_message_pipe_fd, (void*)&controller_msg[0], sizeof(in_message_t)); + if (write_res < 0) { + fprintf(stderr, "Error in writing input event messages: %d\n", write_res); + } } } } diff --git a/dev_out.c b/dev_out.c index 75901d8..43e7319 100644 --- a/dev_out.c +++ b/dev_out.c @@ -324,23 +324,24 @@ void *dev_out_thread_func(void *ptr) { } // send out game-generated events to sockets - int fd = -1; - const size_t bytes_to_send = sizeof(out_message_t) * out_msgs_count; - if (dev_out_data->communication.type == ipc_unix_pipe) { - const int write_res = write(dev_out_data->communication.endpoint.pipe.out_message_pipe_fd, (void*)&out_msgs, bytes_to_send); - if (write_res != bytes_to_send) { - fprintf(stderr, "Error in writing out_message to out_message_pipe: %d\n", write_res); + for (int msg_idx = 0; msg_idx < out_msgs_count; ++msg_idx) { + const int write_res = write(dev_out_data->communication.endpoint.pipe.out_message_pipe_fd, (void*)&out_msgs, sizeof(out_message_t)); + if (write_res != sizeof(out_message_t)) { + fprintf(stderr, "Error in writing out_message to out_message_pipe: %d\n", write_res); + } } } else if (dev_out_data->communication.type == ipc_server_sockets) { if (pthread_mutex_lock(&dev_out_data->communication.endpoint.ssocket.mutex) == 0) { for (int i = 0; i < MAX_CONNECTED_CLIENTS; ++i) { if (dev_out_data->communication.endpoint.ssocket.clients[i] > 0) { - const int write_res = write(dev_out_data->communication.endpoint.ssocket.clients[i], (void*)&out_msgs, bytes_to_send); - if (write_res != bytes_to_send) { - fprintf(stderr, "Error in writing out_message to socket number %d: %d\n", i, write_res); - close(dev_out_data->communication.endpoint.ssocket.clients[i]); - dev_out_data->communication.endpoint.ssocket.clients[i] = -1; + for (int msg_idx = 0; msg_idx < out_msgs_count; ++msg_idx) { + const int write_res = write(dev_out_data->communication.endpoint.ssocket.clients[i], (void*)&out_msgs, sizeof(out_message_t)); + if (write_res != sizeof(out_message_t)) { + fprintf(stderr, "Error in writing out_message to socket number %d: %d\n", i, write_res); + close(dev_out_data->communication.endpoint.ssocket.clients[i]); + dev_out_data->communication.endpoint.ssocket.clients[i] = -1; + } } } } From 971b661c5ea03982e2ba6a949e17edc31c14252f Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 14 Dec 2023 13:53:48 +0100 Subject: [PATCH 006/186] watch for messages on the receiving socket --- dev_in.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev_in.c b/dev_in.c index b342ba3..3149a87 100644 --- a/dev_in.c +++ b/dev_in.c @@ -384,6 +384,8 @@ void* dev_in_thread_func(void *ptr) { continue; } } + + FD_SET(dev_in_data->communication.endpoint.socket.fd, &read_fds); } for (size_t i = 0; i < max_devices; ++i) { From 49ba884623bd9c7e1c0fb606defe9604b3ab41c5 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 14 Dec 2023 13:58:50 +0100 Subject: [PATCH 007/186] try with SOCK_STREAM --- dev_in.c | 2 +- stray_ally.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev_in.c b/dev_in.c index 3149a87..3a872a5 100644 --- a/dev_in.c +++ b/dev_in.c @@ -315,7 +315,7 @@ static void handle_rumble(dev_in_t *const in_devs, size_t in_devs_count, const o static int open_socket(struct sockaddr_un *serveraddr) { int res = -ENODEV; - int sd = socket(AF_UNIX, SOCK_SEQPACKET, 0); + int sd = socket(AF_UNIX, SOCK_STREAM, 0); if (sd < 0) { res = sd; diff --git a/stray_ally.c b/stray_ally.c index 8020d5b..1755610 100644 --- a/stray_ally.c +++ b/stray_ally.c @@ -71,7 +71,7 @@ int main(int argc, char ** argv) { int sd=-1; struct sockaddr_un serveraddr; do { - sd = socket(AF_UNIX, SOCK_SEQPACKET, 0); + sd = socket(AF_UNIX, SOCK_STREAM, 0); if (sd < 0) { fprintf(stderr, "socket() failed"); From 917ec565f853a38dcc2835ccd632b74faf0c654d Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 14 Dec 2023 14:05:13 +0100 Subject: [PATCH 008/186] Can you please start working as indentended? please.... --- dev_in.c | 4 ++-- dev_out.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dev_in.c b/dev_in.c index 3a872a5..fb5814e 100644 --- a/dev_in.c +++ b/dev_in.c @@ -532,7 +532,7 @@ void* dev_in_thread_func(void *ptr) { if (dev_in_data->communication.type == ipc_client_socket) { for (int msg_idx = 0; msg_idx < controller_msg_count; ++msg_idx) { - const int write_res = write(dev_in_data->communication.endpoint.socket.fd, (void*)&controller_msg[0], sizeof(in_message_t)); + const int write_res = write(dev_in_data->communication.endpoint.socket.fd, (void*)&controller_msg[msg_idx], sizeof(in_message_t)); if (write_res < 0) { fprintf(stderr, "Error in writing input event messages: %d -- connection will be drop and retried\n", write_res); @@ -543,7 +543,7 @@ void* dev_in_thread_func(void *ptr) { } } else if (dev_in_data->communication.type == ipc_unix_pipe) { for (int msg_idx = 0; msg_idx < controller_msg_count; ++msg_idx) { - const int write_res = write(dev_in_data->communication.endpoint.pipe.in_message_pipe_fd, (void*)&controller_msg[0], sizeof(in_message_t)); + const int write_res = write(dev_in_data->communication.endpoint.pipe.in_message_pipe_fd, (void*)&controller_msg[msg_idx], sizeof(in_message_t)); if (write_res < 0) { fprintf(stderr, "Error in writing input event messages: %d\n", write_res); } diff --git a/dev_out.c b/dev_out.c index 43e7319..27b4209 100644 --- a/dev_out.c +++ b/dev_out.c @@ -326,7 +326,7 @@ void *dev_out_thread_func(void *ptr) { // send out game-generated events to sockets if (dev_out_data->communication.type == ipc_unix_pipe) { for (int msg_idx = 0; msg_idx < out_msgs_count; ++msg_idx) { - const int write_res = write(dev_out_data->communication.endpoint.pipe.out_message_pipe_fd, (void*)&out_msgs, sizeof(out_message_t)); + const int write_res = write(dev_out_data->communication.endpoint.pipe.out_message_pipe_fd, (void*)&out_msgs[msg_idx], sizeof(out_message_t)); if (write_res != sizeof(out_message_t)) { fprintf(stderr, "Error in writing out_message to out_message_pipe: %d\n", write_res); } @@ -336,7 +336,7 @@ void *dev_out_thread_func(void *ptr) { for (int i = 0; i < MAX_CONNECTED_CLIENTS; ++i) { if (dev_out_data->communication.endpoint.ssocket.clients[i] > 0) { for (int msg_idx = 0; msg_idx < out_msgs_count; ++msg_idx) { - const int write_res = write(dev_out_data->communication.endpoint.ssocket.clients[i], (void*)&out_msgs, sizeof(out_message_t)); + const int write_res = write(dev_out_data->communication.endpoint.ssocket.clients[i], (void*)&out_msgs[msg_idx], sizeof(out_message_t)); if (write_res != sizeof(out_message_t)) { fprintf(stderr, "Error in writing out_message to socket number %d: %d\n", i, write_res); close(dev_out_data->communication.endpoint.ssocket.clients[i]); From a3b2eb0e4135fe14a746b29cdbde60aa6ee8140c Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 14 Dec 2023 23:16:36 +0100 Subject: [PATCH 009/186] Configuration refactor --- allynone.c | 39 +++++++++++----------------- dev_in.c | 60 ++++++++++++++++++++++++++++++++++--------- dev_in.h | 3 +++ dev_out.c | 72 +++++++++++++++++++++++++++++++++++++++++++++------- dev_out.h | 5 ++-- input_dev.h | 11 ++++---- legion_go.c | 15 ++++------- legion_go.h | 2 +- main.c | 16 +++++++----- rog_ally.c | 21 +++++++-------- rog_ally.h | 2 +- settings.c | 62 ++++++++++++++++++++++---------------------- settings.h | 24 +++++++----------- stray_ally.c | 13 +++------- xbox360.c | 17 ++++++++----- xbox360.h | 12 +++++---- 16 files changed, 226 insertions(+), 148 deletions(-) diff --git a/allynone.c b/allynone.c index 8f39900..8caf8db 100644 --- a/allynone.c +++ b/allynone.c @@ -10,32 +10,11 @@ #include "rog_ally.h" #include "legion_go.h" -/* -logic_t global_logic; - -static output_dev_t out_gamepadd_dev = { - .logic = &global_logic, -}; - -void sig_handler(int signo) -{ - if (signo == SIGINT) { - logic_request_termination(&global_logic); - printf("Received SIGINT\n"); - } -} -*/ - static const char* configuration_file = "/etc/ROGueENEMY/config.cfg"; -controller_settings_t settings; - int main(int argc, char ** argv) { int ret = 0; - init_config(&settings); - fill_config(&settings, configuration_file); - input_dev_composite_t* in_devs = NULL; int dmi_name_fd = open("/sys/class/dmi/id/board_name", O_RDONLY | O_NONBLOCK); @@ -49,10 +28,10 @@ int main(int argc, char ** argv) { read(dmi_name_fd, bname, sizeof(bname)); if (strstr(bname, "RC71L") != NULL) { printf("Running in an Asus ROG Ally device\n"); - in_devs = rog_ally_device_def(&settings); + in_devs = rog_ally_device_def(); } else if (strstr(bname, "LNVNB161216")) { printf("Running in an Lenovo Legion Go device\n"); - in_devs = legion_go_device_def(&settings); + in_devs = legion_go_device_def(); } close(dmi_name_fd); @@ -105,12 +84,18 @@ int main(int argc, char ** argv) { .out_message_pipe_fd = out_message_pipes[0], } } + }, + .settings = { + .enable_qam = true, + .ff_gain = 0xFFFF, } }; + // fill in configuration from file: automatic fallback to default + load_in_config(&dev_in_thread_data.settings, configuration_file); + // populate the output device thread data dev_out_data_t dev_out_thread_data = { - .gamepad = GAMEPAD_DUALSENSE, .flags = 0x00000000U, .communication = { .type = ipc_unix_pipe, @@ -120,9 +105,15 @@ int main(int argc, char ** argv) { .out_message_pipe_fd = out_message_pipes[1], } } + }, + .settings = { + .default_gamepad = 0, + .nintendo_layout = false, } }; + load_out_config(&dev_out_thread_data.settings, configuration_file); + pthread_t dev_in_thread; dev_in_thread_creation = pthread_create(&dev_in_thread, NULL, dev_in_thread_func, (void*)(&dev_in_thread_data)); if (dev_in_thread_creation != 0) { diff --git a/dev_in.c b/dev_in.c index fb5814e..4b9502d 100644 --- a/dev_in.c +++ b/dev_in.c @@ -6,6 +6,8 @@ #include "dev_evdev.h" #include "dev_iio.h" +#include + typedef enum dev_in_type { DEV_IN_TYPE_NONE, DEV_IN_TYPE_HIDRAW, @@ -144,6 +146,7 @@ fill_message_from_evdev_err_completed: } static int hidraw_open_device( + const dev_in_settings_t *const in_settings, const hidraw_filters_t *const in_filters, dev_in_hidraw_t *const out_dev ) { @@ -164,6 +167,7 @@ iio_open_device_err: } static int iio_open_device( + const dev_in_settings_t *const in_settings, const iio_filters_t *const in_filters, dev_in_iio_t *const out_dev ) { @@ -187,6 +191,7 @@ iio_open_device_err: } static int evdev_open_device( + const dev_in_settings_t *const in_settings, const uinput_filters_t *const in_filters, dev_in_ev_t *const out_dev ) { @@ -219,14 +224,14 @@ static int evdev_open_device( out_dev->ff_effect.type = FF_RUMBLE; out_dev->ff_effect.id = -1; out_dev->ff_effect.replay.delay = 0; - out_dev->ff_effect.replay.length = 5000; + out_dev->ff_effect.replay.length = 1000; out_dev->ff_effect.u.rumble.strong_magnitude = 0x0000; out_dev->ff_effect.u.rumble.weak_magnitude = 0x0000; const struct input_event gain = { .type = EV_FF, .code = FF_GAIN, - .value = 0xFFFF, // TODO: give the user the ability to change this + .value = in_settings->ff_gain, }; const int gain_set_res = write(libevdev_get_fd(out_dev->evdev), (const void*)&gain, sizeof(gain)); @@ -337,7 +342,7 @@ void* dev_in_thread_func(void *ptr) { dev_in_data_t *const dev_in_data = (dev_in_data_t*)ptr; void* platform_data; - const int platform_init_res = dev_in_data->input_dev_decl->init_fn(&platform_data); + const int platform_init_res = dev_in_data->input_dev_decl->init_fn(&dev_in_data->settings, &platform_data); if (platform_init_res != 0) { fprintf(stderr, "Error setting up platform data: %d\n", platform_init_res); } @@ -401,7 +406,11 @@ void* dev_in_thread_func(void *ptr) { if (d_type == input_dev_type_uinput) { fprintf(stderr, "Device (evdev) %zu not found -- Attempt reconnection for device named %s\n", i, dev_in_data->input_dev_decl->dev[i]->filters.ev.name); - const int open_res = evdev_open_device(&dev_in_data->input_dev_decl->dev[i]->filters.ev, &devices[i].dev.evdev); + const int open_res = evdev_open_device( + &dev_in_data->settings, + &dev_in_data->input_dev_decl->dev[i]->filters.ev, + &devices[i].dev.evdev + ); if (open_res == 0) { devices[i].type = DEV_IN_TYPE_EV; @@ -411,14 +420,22 @@ void* dev_in_thread_func(void *ptr) { } else if (d_type == input_dev_type_iio) { fprintf(stderr, "Device (iio) %zu not found -- Attempt reconnection for device named %s\n", i, dev_in_data->input_dev_decl->dev[i]->filters.iio.name); - const int open_res = iio_open_device(&dev_in_data->input_dev_decl->dev[i]->filters.iio, &devices[i].dev.iio); + const int open_res = iio_open_device( + &dev_in_data->settings, + &dev_in_data->input_dev_decl->dev[i]->filters.iio, + &devices[i].dev.iio + ); if (open_res == 0) { devices[i].type = DEV_IN_TYPE_IIO; } } else if (d_type == input_dev_type_hidraw) { fprintf(stderr, "Device (hidraw) %zu not found -- Attempt reconnection for device %x:%x\n", i, dev_in_data->input_dev_decl->dev[i]->filters.hidraw.pid, dev_in_data->input_dev_decl->dev[i]->filters.hidraw.vid); - const int open_res = hidraw_open_device(&dev_in_data->input_dev_decl->dev[i]->filters.hidraw, &devices[i].dev.hidraw); + const int open_res = hidraw_open_device( + &dev_in_data->settings, + &dev_in_data->input_dev_decl->dev[i]->filters.hidraw, + &devices[i].dev.hidraw + ); if (open_res == 0) { devices[i].type = DEV_IN_TYPE_HIDRAW; } @@ -453,7 +470,11 @@ void* dev_in_thread_func(void *ptr) { handle_rumble(devices, max_devices, &out_msg.data.rumble); } else if (out_msg.type == OUT_MSG_TYPE_LEDS) { // first inform the platform - const int platform_leds_res = dev_in_data->input_dev_decl->leds_fn(out_msg.data.leds.r, out_msg.data.leds.g, out_msg.data.leds.b, platform_data); + const int platform_leds_res = dev_in_data->input_dev_decl->leds_fn( + &dev_in_data->settings, + out_msg.data.leds.r, out_msg.data.leds.g, + out_msg.data.leds.b, platform_data + ); if (platform_leds_res != 0) { fprintf(stderr, "Error in changing platform LEDs: %d\n", platform_leds_res); } @@ -506,9 +527,19 @@ void* dev_in_thread_func(void *ptr) { continue; } - controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.ev_input_map_fn(&coll, &controller_msg[0], controller_msg_avail, dev_in_data->input_dev_decl->dev[i]->user_data); + controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.ev_input_map_fn( + &dev_in_data->settings, + &coll, + &controller_msg[0], + controller_msg_avail, + dev_in_data->input_dev_decl->dev[i]->user_data + ); } else if (devices[i].type == DEV_IN_TYPE_IIO) { - controller_msg_count = map_message_from_iio(&devices[i].dev.iio, &controller_msg[0], controller_msg_avail); + controller_msg_count = map_message_from_iio( + &devices[i].dev.iio, + &controller_msg[0], + controller_msg_avail + ); if (controller_msg_count < 0) { fprintf(stderr, "Error in reading iio buffer for device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count); iio_close_device(&devices[i].dev.iio); @@ -516,7 +547,13 @@ void* dev_in_thread_func(void *ptr) { continue; } } else if (devices[i].type == DEV_IN_TYPE_HIDRAW) { - controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.hidraw_input_map_fn(dev_hidraw_get_fd(devices[i].dev.hidraw.hidrawdev), &controller_msg[0], controller_msg_avail, dev_in_data->input_dev_decl->dev[i]->user_data); + controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.hidraw_input_map_fn( + &dev_in_data->settings, + dev_hidraw_get_fd(devices[i].dev.hidraw.hidrawdev), + &controller_msg[0], + controller_msg_avail, + dev_in_data->input_dev_decl->dev[i]->user_data + ); if (controller_msg_count < 0) { fprintf(stderr, "Error in performing operations for device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count); hidraw_close_device(&devices[i].dev.hidraw); @@ -585,11 +622,10 @@ void* dev_in_thread_func(void *ptr) { } } - // TODO: free every fd free(devices); if (platform_init_res != 0) { - dev_in_data->input_dev_decl->deinit_fn(&platform_data); + dev_in_data->input_dev_decl->deinit_fn(&dev_in_data->settings, &platform_data); } return NULL; diff --git a/dev_in.h b/dev_in.h index d66c0cf..85aa114 100644 --- a/dev_in.h +++ b/dev_in.h @@ -3,6 +3,7 @@ #include "ipc.h" #include "message.h" #include "input_dev.h" +#include "settings.h" #define MAX_IN_MESSAGES 8 @@ -19,6 +20,8 @@ typedef struct dev_in_data { ipc_t communication; + dev_in_settings_t settings; + volatile uint32_t flags; } dev_in_data_t; diff --git a/dev_out.c b/dev_out.c index 27b4209..8ac09a9 100644 --- a/dev_out.c +++ b/dev_out.c @@ -6,7 +6,10 @@ #include "virt_ds4.h" #include "virt_ds5.h" +#include + static void handle_incoming_message_gamepad_action( + const dev_out_settings_t *const in_settings, const in_message_gamepad_action_t *const msg_payload, gamepad_status_t *const inout_gamepad ) { @@ -18,24 +21,45 @@ static void handle_incoming_message_gamepad_action( } static void handle_incoming_message_gamepad_set( + const dev_out_settings_t *const in_settings, const in_message_gamepad_set_element_t *const msg_payload, gamepad_status_t *const inout_gamepad ) { switch (msg_payload->element) { case GAMEPAD_BTN_CROSS: { - inout_gamepad->cross = msg_payload->status.btn; + if (!in_settings->nintendo_layout) { + inout_gamepad->cross = msg_payload->status.btn; + } else { + inout_gamepad->circle = msg_payload->status.btn; + } + break; } case GAMEPAD_BTN_CIRCLE: { - inout_gamepad->circle = msg_payload->status.btn; + if (in_settings->nintendo_layout) { + inout_gamepad->cross = msg_payload->status.btn; + } else { + inout_gamepad->circle = msg_payload->status.btn; + } + break; } case GAMEPAD_BTN_SQUARE: { - inout_gamepad->square = msg_payload->status.btn; + if (in_settings->nintendo_layout) { + inout_gamepad->triangle = msg_payload->status.btn; + } else { + inout_gamepad->square = msg_payload->status.btn; + } + break; } case GAMEPAD_BTN_TRIANGLE: { - inout_gamepad->triangle = msg_payload->status.btn; + if (!in_settings->nintendo_layout) { + inout_gamepad->triangle = msg_payload->status.btn; + } else { + inout_gamepad->square = msg_payload->status.btn; + } + break; } case GAMEPAD_BTN_OPTION: { @@ -156,13 +180,22 @@ static void handle_incoming_message_gamepad_set( } static void handle_incoming_message( + const dev_out_settings_t *const in_settings, const in_message_t *const msg, devices_status_t *const dev_stats ) { if (msg->type == GAMEPAD_SET_ELEMENT) { - handle_incoming_message_gamepad_set(&msg->data.gamepad_set, &dev_stats->gamepad); + handle_incoming_message_gamepad_set( + in_settings, + &msg->data.gamepad_set, + &dev_stats->gamepad + ); } else if (msg->type == GAMEPAD_ACTION) { - handle_incoming_message_gamepad_action(&msg->data.action, &dev_stats->gamepad); + handle_incoming_message_gamepad_action( + in_settings, + &msg->data.action, + &dev_stats->gamepad + ); } } @@ -181,7 +214,20 @@ void *dev_out_thread_func(void *ptr) { // Initialize device devices_status_init(&dev_out_data->dev_stats); - dev_out_gamepad_device_t current_gamepad = dev_out_data->gamepad; + dev_out_gamepad_device_t current_gamepad = GAMEPAD_DUALSENSE; + + switch (dev_out_data->settings.default_gamepad) { + case 1: + current_gamepad = GAMEPAD_DUALSENSE; + break; + case 2: + current_gamepad = GAMEPAD_DUALSHOCK; + break; + + default: + current_gamepad = GAMEPAD_DUALSENSE; + break; + } union { virt_dualshock_t ds4; @@ -357,7 +403,11 @@ void *dev_out_thread_func(void *ptr) { in_message_t incoming_message; const size_t in_message_pipe_read_res = read(dev_out_data->communication.endpoint.pipe.in_message_pipe_fd, (void*)&incoming_message, sizeof(in_message_t)); if (in_message_pipe_read_res == sizeof(in_message_t)) { - handle_incoming_message(&incoming_message, &dev_out_data->dev_stats); + handle_incoming_message( + &dev_out_data->settings, + &incoming_message, + &dev_out_data->dev_stats + ); } else { fprintf(stderr, "Error reading from in_message_pipe_fd: got %zu bytes, expected %zu bytes\n", in_message_pipe_read_res, sizeof(in_message_t)); } @@ -370,7 +420,11 @@ void *dev_out_thread_func(void *ptr) { in_message_t incoming_message; const size_t in_message_pipe_read_res = read(fd, (void*)&incoming_message, sizeof(in_message_t)); if (in_message_pipe_read_res == sizeof(in_message_t)) { - handle_incoming_message(&incoming_message, &dev_out_data->dev_stats); + handle_incoming_message( + &dev_out_data->settings, + &incoming_message, + &dev_out_data->dev_stats + ); } else { fprintf(stderr, "Error reading from socket number %d: got %zu bytes, expected %zu bytes\n", i, in_message_pipe_read_res, sizeof(in_message_t)); close(dev_out_data->communication.endpoint.ssocket.clients[i]); diff --git a/dev_out.h b/dev_out.h index a0c249c..f804e44 100644 --- a/dev_out.h +++ b/dev_out.h @@ -3,6 +3,7 @@ #include "ipc.h" #include "message.h" #include "devices_status.h" +#include "settings.h" #define DEV_OUT_FLAG_EXIT 0x00000001U @@ -16,10 +17,10 @@ typedef struct dev_out_data { ipc_t communication; - dev_out_gamepad_device_t gamepad; - devices_status_t dev_stats; + dev_out_settings_t settings; + volatile uint32_t flags; } dev_out_data_t; diff --git a/input_dev.h b/input_dev.h index edbbde0..e647197 100644 --- a/input_dev.h +++ b/input_dev.h @@ -1,6 +1,7 @@ #pragma once #include "message.h" +#include "settings.h" #undef INCLUDE_INPUT_DEBUG #undef IGNORE_INPUT_SCAN @@ -17,8 +18,8 @@ typedef struct evdev_collected { * A function with this signature grapbs input_event data and sends to the pipe messages * constructed from that data. */ -typedef int (*ev_map)(const evdev_collected_t *const e, in_message_t *const messages, size_t messages_len, void* user_data); -typedef int (*hidraw_map)(int hidraw_fd, in_message_t *const messages, size_t messages_len, void* user_data); +typedef int (*ev_map)(const dev_in_settings_t *const conf, const evdev_collected_t *const e, in_message_t *const messages, size_t messages_len, void* user_data); +typedef int (*hidraw_map)(const dev_in_settings_t *const conf, int hidraw_fd, in_message_t *const messages, size_t messages_len, void* user_data); typedef enum input_dev_type { input_dev_type_uinput, @@ -73,11 +74,11 @@ typedef struct input_dev { } input_dev_t; -typedef int (*platform_init)(void** platform_data); +typedef int (*platform_init)(const dev_in_settings_t *const conf, void** platform_data); -typedef void (*platform_deinit)(void** platform_data); +typedef void (*platform_deinit)(const dev_in_settings_t *const conf, void** platform_data); -typedef int (*platform_leds)(uint8_t r, uint8_t g, uint8_t b, void* platform_data); +typedef int (*platform_leds)(const dev_in_settings_t *const conf, uint8_t r, uint8_t g, uint8_t b, void* platform_data); typedef struct input_dev_composite { diff --git a/legion_go.c b/legion_go.c index 4f942df..9852643 100644 --- a/legion_go.c +++ b/legion_go.c @@ -15,8 +15,6 @@ static input_dev_t in_xbox_dev = { } }; -static xbox360_settings_t x360_cfg; - static input_dev_t in_iio_dev = { .dev_type = input_dev_type_iio, .filters = { @@ -40,7 +38,7 @@ static struct llg_hidraw_data { uint8_t last_packet[64]; } llg_hidraw_user_data; -static int llg_hidraw_map(int hidraw_fd, in_message_t *const messages, size_t messages_len, void* user_data) { +static int llg_hidraw_map(const dev_in_settings_t *const conf, int hidraw_fd, in_message_t *const messages, size_t messages_len, void* user_data) { struct llg_hidraw_data *const llg_data = (struct llg_hidraw_data*)user_data; int msg_count = 0; @@ -92,7 +90,7 @@ typedef struct legion_go_platform { int _pad; } legion_go_platform_t; -static int legion_platform_init(void** platform_data) { +static int legion_platform_init(const dev_in_settings_t *const conf, void** platform_data) { int res = -EINVAL; legion_go_platform_t *const llg_platform = malloc(sizeof(legion_go_platform_t)); @@ -109,12 +107,12 @@ legion_platform_init_err: return res; } -static void legion_platform_deinit(void** platform_data) { +static void legion_platform_deinit(const dev_in_settings_t *const conf, void** platform_data) { free(*platform_data); *platform_data = NULL; } -int legion_platform_leds(uint8_t r, uint8_t g, uint8_t b, void* platform_data) { +int legion_platform_leds(const dev_in_settings_t *const conf, uint8_t r, uint8_t g, uint8_t b, void* platform_data) { return 0; } @@ -131,10 +129,7 @@ input_dev_composite_t legion_composite = { }; -input_dev_composite_t* legion_go_device_def(const controller_settings_t *const settings) { - x360_cfg.nintendo_layout = settings->nintendo_layout; - - in_xbox_dev.user_data = (void*)&x360_cfg; +input_dev_composite_t* legion_go_device_def(void) { return &legion_composite; } diff --git a/legion_go.h b/legion_go.h index 712459c..847a0a6 100644 --- a/legion_go.h +++ b/legion_go.h @@ -3,4 +3,4 @@ #include "input_dev.h" #include "settings.h" -input_dev_composite_t* legion_go_device_def(const controller_settings_t *const settings); +input_dev_composite_t* legion_go_device_def(void); diff --git a/main.c b/main.c index 4c350a2..43d50dc 100644 --- a/main.c +++ b/main.c @@ -12,14 +12,9 @@ static const char* configuration_file = "/etc/ROGueENEMY/config.cfg"; -controller_settings_t settings; - int main(int argc, char ** argv) { int ret = 0; - init_config(&settings); - fill_config(&settings, configuration_file); - input_dev_composite_t* in_devs = NULL; int dmi_name_fd = open("/sys/class/dmi/id/board_name", O_RDONLY | O_NONBLOCK); @@ -33,10 +28,10 @@ int main(int argc, char ** argv) { read(dmi_name_fd, bname, sizeof(bname)); if (strstr(bname, "RC71L") != NULL) { printf("Running in an Asus ROG Ally device\n"); - in_devs = rog_ally_device_def(&settings); + in_devs = rog_ally_device_def(); } else if (strstr(bname, "LNVNB161216")) { printf("Running in an Lenovo Legion Go device\n"); - in_devs = legion_go_device_def(&settings); + in_devs = legion_go_device_def(); } close(dmi_name_fd); @@ -55,9 +50,16 @@ int main(int argc, char ** argv) { } }, } + }, + .settings = { + .enable_qam = true, + .ff_gain = 0xFFFF, } }; + // fill in configuration from file: automatic fallback to default + load_in_config(&dev_in_thread_data.settings, configuration_file); + //memset(&dev_in_thread_data.communication.endpoint.socket.serveraddr, 0, sizeof(dev_in_thread_data.communication.endpoint.socket.serveraddr)); pthread_t dev_in_thread; diff --git a/rog_ally.c b/rog_ally.c index 0d261a7..eb2cbbd 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -432,7 +432,13 @@ static const uint8_t rc71l_mode_switch_commands[][23][64] = { } }; -int asus_kbd_ev_map(const evdev_collected_t *const e, in_message_t *const messages, size_t messages_len, void* user_data) { +int asus_kbd_ev_map( + const dev_in_settings_t *const conf, + const evdev_collected_t *const e, + in_message_t *const messages, + size_t messages_len, + void* user_data +) { int written_msg = 0; if ( // this is what happens at release of the left-screen button of the ROG Ally @@ -601,8 +607,6 @@ static input_dev_t in_xbox_dev = { } }; -static xbox360_settings_t x360_cfg; - typedef enum rc71l_platform_mode { rc71l_platform_mode_hidraw, rc71l_platform_mode_linux_and_asusctl, @@ -639,7 +643,7 @@ enum rc71l_leds_direction { ROG_ALLY_DIRECTION_LEFT = 0x01 } rc71l_leds_direction_t; -static int rc71l_platform_init(void** platform_data) { +static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platform_data) { int res = -EINVAL; rc71l_platform_t *const platform = malloc(sizeof(rc71l_platform_t)); @@ -695,7 +699,7 @@ rc71l_platform_init_err: return res; } -static void rc71l_platform_deinit(void** platform_data) { +static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** platform_data) { rc71l_platform_t *const platform = (rc71l_platform_t *)(*platform_data); if ((platform->platform_mode == rc71l_platform_mode_hidraw) && (platform->platform.hidraw != NULL)) { @@ -707,7 +711,7 @@ static void rc71l_platform_deinit(void** platform_data) { *platform_data = NULL; } -static int rc71l_platform_leds(uint8_t r, uint8_t g, uint8_t b, void* platform_data) { +static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, uint8_t g, uint8_t b, void* platform_data) { rc71l_platform_t *const platform = (rc71l_platform_t *)platform_data; if (platform == NULL) { return -EINVAL; @@ -780,9 +784,6 @@ input_dev_composite_t rc71l_composite = { .leds_fn = rc71l_platform_leds, }; -input_dev_composite_t* rog_ally_device_def(const controller_settings_t *const settings) { - x360_cfg.nintendo_layout = settings->nintendo_layout; - - in_xbox_dev.user_data = (void*)&x360_cfg; +input_dev_composite_t* rog_ally_device_def(void) { return &rc71l_composite; } diff --git a/rog_ally.h b/rog_ally.h index 26af9b0..204614d 100644 --- a/rog_ally.h +++ b/rog_ally.h @@ -3,4 +3,4 @@ #include "input_dev.h" #include "settings.h" -input_dev_composite_t* rog_ally_device_def(const controller_settings_t *const settings); +input_dev_composite_t* rog_ally_device_def(void); diff --git a/settings.c b/settings.c index f1fc8a0..05f2daf 100644 --- a/settings.c +++ b/settings.c @@ -2,68 +2,66 @@ #include -void init_config(controller_settings_t *const conf) { - conf->ff_gain = 100; - conf->enable_qam = 0; - conf->nintendo_layout = 0; - conf->gamepad_output_device = 1; - conf->rumble_dedicated_thread = 0; -} - -int fill_config(controller_settings_t *const conf, const char* file) { - int res = 0; - +void load_in_config(dev_in_settings_t *const out_conf, const char* const filepath) { config_t cfg; - config_init(&cfg); - const int config_read_res = config_read_file(&cfg, file); + const int config_read_res = config_read_file(&cfg, filepath); if (config_read_res != CONFIG_TRUE) { fprintf(stderr, "Error in reading config file: %s\n", config_error_text(&cfg)); - goto fill_config_err; + goto load_in_config_err; } int enable_qam; if (config_lookup_bool(&cfg, "enable_qam", &enable_qam) != CONFIG_FALSE) { - conf->enable_qam = enable_qam; + out_conf->enable_qam = enable_qam; } else { fprintf(stderr, "enable_qam (bool) configuration not found. Default value will be used.\n"); } int ff_gain; if (config_lookup_int(&cfg, "ff_gain", &ff_gain) != CONFIG_FALSE) { - if (ff_gain <= 100) { - conf->ff_gain = (ff_gain == 100) ? 0xFFFF : ((int)0xFFFF / 100) * ff_gain; + if (ff_gain <= 0xFF) { + out_conf->ff_gain = (ff_gain == 0) ? 0x0000 : ((uint16_t)ff_gain << (uint16_t)8) | (uint16_t)0x00FF; } else { - fprintf(stderr, "ff_gain (int) must be a number between 0 and 100"); + fprintf(stderr, "ff_gain (int) must be a number between 0 and 255"); } } else { fprintf(stderr, "ff_gain (int) configuration not found. Default value will be used.\n"); } + config_destroy(&cfg); + +load_in_config_err: + return; +} + +void load_out_config(dev_out_settings_t *const out_conf, const char* const filepath) { + config_t cfg; + config_init(&cfg); + + const int config_read_res = config_read_file(&cfg, filepath); + if (config_read_res != CONFIG_TRUE) { + fprintf(stderr, "Error in reading config file: %s\n", config_error_text(&cfg)); + goto load_out_config_err; + } + int nintendo_layout; if (config_lookup_bool(&cfg, "nintendo_layout", &nintendo_layout) != CONFIG_FALSE) { - conf->nintendo_layout = nintendo_layout; + out_conf->nintendo_layout = nintendo_layout; } else { fprintf(stderr, "nintendo_layout (bool) configuration not found. Default value will be used.\n"); } - int gamepad_output_device; - if (config_lookup_int(&cfg, "gamepad_output_device", &gamepad_output_device) != CONFIG_FALSE) { - conf->gamepad_output_device = gamepad_output_device; + int default_gamepad; + if (config_lookup_bool(&cfg, "default_gamepad", &default_gamepad) != CONFIG_FALSE) { + out_conf->default_gamepad = default_gamepad % 3; } else { - fprintf(stderr, "gamepad_output_device (int) configuration not found. Default value will be used.\n"); - } - - int rumble_dedicated_thread; - if (config_lookup_bool(&cfg, "rumble_dedicated_thread", &rumble_dedicated_thread) != CONFIG_FALSE) { - conf->rumble_dedicated_thread = rumble_dedicated_thread; - } else { - fprintf(stderr, "rumble_dedicated_thread (bool) configuration not found. Default value will be used.\n"); + fprintf(stderr, "default_gamepad (int) configuration not found. Default value will be used.\n"); } config_destroy(&cfg); -fill_config_err: - return res; +load_out_config_err: + return; } diff --git a/settings.h b/settings.h index 517ef82..6abfb5f 100644 --- a/settings.h +++ b/settings.h @@ -2,22 +2,16 @@ #include "rogue_enemy.h" -typedef struct controller_settings { +typedef struct dev_in_settings { + bool enable_qam; uint16_t ff_gain; - int enable_qam; - int nintendo_layout; +} dev_in_settings_t; - /** - * 0 is virtual evdev - * 1 is DualSense - * 2 is DualShock - * 3 is Xbox one - */ - int gamepad_output_device; +void load_in_config(dev_in_settings_t *const out_conf, const char* const filepath); - int rumble_dedicated_thread; -} controller_settings_t; +typedef struct dev_out_settings { + bool nintendo_layout; + uint8_t default_gamepad; +} dev_out_settings_t; -void init_config(controller_settings_t *const conf); - -int fill_config(controller_settings_t *const conf, const char* file); +void load_out_config(dev_out_settings_t *const out_conf, const char* const filepath); \ No newline at end of file diff --git a/stray_ally.c b/stray_ally.c index 1755610..4bbbef9 100644 --- a/stray_ally.c +++ b/stray_ally.c @@ -7,19 +7,11 @@ #include "dev_out.h" #include "settings.h" -#include "rog_ally.h" -#include "legion_go.h" - static const char* configuration_file = "/etc/ROGueENEMY/config.cfg"; -controller_settings_t settings; - int main(int argc, char ** argv) { int ret = 0; - init_config(&settings); - fill_config(&settings, configuration_file); - // Create a signal set containing only SIGTERM sigset_t mask; sigemptyset(&mask); @@ -50,7 +42,10 @@ int main(int argc, char ** argv) { } } }, - .gamepad = GAMEPAD_DUALSENSE, + .settings = { + .default_gamepad = 0, + .nintendo_layout = false, + } }; pthread_t dev_out_thread; diff --git a/xbox360.c b/xbox360.c index bb0de29..5f72592 100644 --- a/xbox360.c +++ b/xbox360.c @@ -1,8 +1,13 @@ #include "xbox360.h" #include "message.h" -int xbox360_ev_map(const evdev_collected_t *const coll, in_message_t *const messages, size_t messages_len, void* user_data) { - const xbox360_settings_t *const settings = (xbox360_settings_t*)user_data; +int xbox360_ev_map( + const dev_in_settings_t *const conf, + const evdev_collected_t *const coll, + in_message_t *const messages, + size_t messages_len, + void* user_data +) { int written_msg = 0; for (uint32_t i = 0; i < coll->ev_count; ++i) { @@ -12,16 +17,16 @@ int xbox360_ev_map(const evdev_collected_t *const coll, in_message_t *const mess }; if (coll->ev[i].code == BTN_EAST) { - current_message.data.gamepad_set.element = (settings->nintendo_layout) ? GAMEPAD_BTN_CROSS : GAMEPAD_BTN_CIRCLE; + current_message.data.gamepad_set.element = GAMEPAD_BTN_CIRCLE; current_message.data.gamepad_set.status.btn = coll->ev[i].value; } else if (coll->ev[i].code == BTN_NORTH) { - current_message.data.gamepad_set.element = (settings->nintendo_layout) ? GAMEPAD_BTN_TRIANGLE : GAMEPAD_BTN_SQUARE; + current_message.data.gamepad_set.element = GAMEPAD_BTN_SQUARE; current_message.data.gamepad_set.status.btn = coll->ev[i].value; } else if (coll->ev[i].code == BTN_SOUTH) { - current_message.data.gamepad_set.element = (settings->nintendo_layout) ? GAMEPAD_BTN_CIRCLE : GAMEPAD_BTN_CROSS; + current_message.data.gamepad_set.element = GAMEPAD_BTN_CROSS; current_message.data.gamepad_set.status.btn = coll->ev[i].value; } else if (coll->ev[i].code == BTN_WEST) { - current_message.data.gamepad_set.element = (settings->nintendo_layout) ? GAMEPAD_BTN_SQUARE : GAMEPAD_BTN_TRIANGLE; + current_message.data.gamepad_set.element = GAMEPAD_BTN_TRIANGLE; current_message.data.gamepad_set.status.btn = coll->ev[i].value; } else if (coll->ev[i].code == BTN_SELECT) { current_message.data.gamepad_set.element = GAMEPAD_BTN_OPTION; diff --git a/xbox360.h b/xbox360.h index 824c30f..2df7ec8 100644 --- a/xbox360.h +++ b/xbox360.h @@ -2,8 +2,10 @@ #include "input_dev.h" -typedef struct xbox360_settings { - bool nintendo_layout; -} xbox360_settings_t; - -int xbox360_ev_map(const evdev_collected_t *const coll, in_message_t *const messages, size_t messages_len, void* user_data); +int xbox360_ev_map( + const dev_in_settings_t *const conf, + const evdev_collected_t *const coll, + in_message_t *const messages, + size_t messages_len, + void* user_data +); From f55c055ad5c735383ea18215bc32e589128d500e Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 14 Dec 2023 23:28:28 +0100 Subject: [PATCH 010/186] honor the enable qam setting --- rog_ally.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index eb2cbbd..3b634ee 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -467,14 +467,16 @@ int asus_kbd_ev_map( (e->ev[1].code == KEY_PROG1) && (e->ev[1].value == 1) ) { - const in_message_t current_message = { - .type = GAMEPAD_ACTION, - .data = { - .action = GAMEPAD_ACTION_OPEN_STEAM_QAM, - } - }; + if (conf->enable_qam) { + const in_message_t current_message = { + .type = GAMEPAD_ACTION, + .data = { + .action = GAMEPAD_ACTION_OPEN_STEAM_QAM, + } + }; - messages[written_msg++] = current_message; + messages[written_msg++] = current_message; + } } else if ( (e->ev_count == 2) && (e->ev[0].type == EV_MSC) && From bcabb2732bb547b387c6790714cec86cfcf19d61 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 14 Dec 2023 23:34:20 +0100 Subject: [PATCH 011/186] honor settings in output server --- stray_ally.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stray_ally.c b/stray_ally.c index 4bbbef9..3ab735a 100644 --- a/stray_ally.c +++ b/stray_ally.c @@ -48,6 +48,8 @@ int main(int argc, char ** argv) { } }; + load_out_config(&dev_out_thread_data.settings, configuration_file); + pthread_t dev_out_thread; const int dev_out_thread_creation = pthread_create(&dev_out_thread, NULL, dev_out_thread_func, (void*)(&dev_out_thread_data)); if (dev_out_thread_creation != 0) { From 8b57c19d0ab88244699714d9dc75064ac5afc63e Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 14 Dec 2023 23:38:51 +0100 Subject: [PATCH 012/186] default_gamepad is an int: load config as such --- settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.c b/settings.c index 05f2daf..bc301cf 100644 --- a/settings.c +++ b/settings.c @@ -54,7 +54,7 @@ void load_out_config(dev_out_settings_t *const out_conf, const char* const filep } int default_gamepad; - if (config_lookup_bool(&cfg, "default_gamepad", &default_gamepad) != CONFIG_FALSE) { + if (config_lookup_int(&cfg, "default_gamepad", &default_gamepad) != CONFIG_FALSE) { out_conf->default_gamepad = default_gamepad % 3; } else { fprintf(stderr, "default_gamepad (int) configuration not found. Default value will be used.\n"); From fb363028838912a64b8bbbb057224f43e8c9a98f Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 14 Dec 2023 23:53:52 +0100 Subject: [PATCH 013/186] as a temporary workaround swap z and y and also do -1 where needed --- dev_in.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/dev_in.c b/dev_in.c index 4b9502d..6b62f22 100644 --- a/dev_in.c +++ b/dev_in.c @@ -82,16 +82,22 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const messages[0].type = GAMEPAD_SET_ELEMENT; messages[0].data.gamepad_set.element = GAMEPAD_ACCELEROMETER; messages[0].data.gamepad_set.status.accel.sample_time = read_time; + //messages[0].data.gamepad_set.status.accel.x = scan_elements[0]; + //messages[0].data.gamepad_set.status.accel.y = scan_elements[1]; + //messages[0].data.gamepad_set.status.accel.z = scan_elements[2]; messages[0].data.gamepad_set.status.accel.x = scan_elements[0]; - messages[0].data.gamepad_set.status.accel.y = scan_elements[1]; - messages[0].data.gamepad_set.status.accel.z = scan_elements[2]; + messages[0].data.gamepad_set.status.accel.y = (uint16_t)(-1) * scan_elements[2]; + messages[0].data.gamepad_set.status.accel.z = (uint16_t)(-1) * scan_elements[1]; messages[1].type = GAMEPAD_SET_ELEMENT; messages[1].data.gamepad_set.element = GAMEPAD_GYROSCOPE; messages[1].data.gamepad_set.status.gyro.sample_time = read_time; + //messages[1].data.gamepad_set.status.gyro.x = scan_elements[3]; + //messages[1].data.gamepad_set.status.gyro.y = scan_elements[4]; + //messages[1].data.gamepad_set.status.gyro.z = scan_elements[5]; messages[1].data.gamepad_set.status.gyro.x = scan_elements[3]; - messages[1].data.gamepad_set.status.gyro.y = scan_elements[4]; - messages[1].data.gamepad_set.status.gyro.z = scan_elements[5]; + messages[1].data.gamepad_set.status.gyro.y = (uint16_t)(-1) * scan_elements[5]; + messages[1].data.gamepad_set.status.gyro.z = (uint16_t)(-1) * scan_elements[4]; res = 2; From 75b4bb1912e3af8d10c9419f84973003edb4b2e9 Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 15 Dec 2023 00:06:46 +0100 Subject: [PATCH 014/186] toggle controller mode on the rog ally --- rog_ally.c | 99 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 39 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 3b634ee..821fe79 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -432,6 +432,24 @@ static const uint8_t rc71l_mode_switch_commands[][23][64] = { } }; +typedef enum rc71l_platform_mode { + rc71l_platform_mode_hidraw, + rc71l_platform_mode_linux_and_asusctl, +} rc71l_platform_mode_t; + +typedef struct rc71l_platform { + rc71l_platform_mode_t platform_mode; + + union { + dev_hidraw_t *hidraw; + } platform; + + unsigned long mode; + unsigned int modes_count; +} rc71l_platform_t; + +static rc71l_platform_t hw_platform; + int asus_kbd_ev_map( const dev_in_settings_t *const conf, const evdev_collected_t *const e, @@ -441,7 +459,27 @@ int asus_kbd_ev_map( ) { int written_msg = 0; - if ( // this is what happens at release of the left-screen button of the ROG Ally + if ( + (e->ev_count >= 2) && + (e->ev[0].type == EV_MSC) && + (e->ev[0].code == MSC_SCAN) && + (e->ev[0].value == -13565784) && + (e->ev[1].type == EV_KEY) && + (e->ev[1].code == KEY_F18) && + (e->ev[1].value == 1) + ) { + if (hw_platform.mode == rc71l_platform_mode_hidraw) { + printf("Using hidraw to switch controller mode\n"); + + for (int i = 0; i < 23; ++i) { + const int write_res = write(hw_platform.platform.hidraw->fd, &rc71l_mode_switch_commands[0][i][0], 64); + if (write_res != 64) { + fprintf(stderr, "Error writing packet %d/23: %d bytes sent, 64 expected\n", i, write_res); + break; + } + } + } + } else if ( // this is what happens at release of the left-screen button of the ROG Ally (e->ev_count == 2) && (e->ev[0].type == EV_MSC) && (e->ev[0].code == MSC_SCAN) && @@ -450,14 +488,14 @@ int asus_kbd_ev_map( (e->ev[1].code == KEY_F16) && (e->ev[1].value == 1) ) { - const in_message_t current_message = { - .type = GAMEPAD_ACTION, - .data = { - .action = GAMEPAD_ACTION_PRESS_AND_RELEASE_CENTER, - } - }; + const in_message_t current_message = { + .type = GAMEPAD_ACTION, + .data = { + .action = GAMEPAD_ACTION_PRESS_AND_RELEASE_CENTER, + } + }; - messages[written_msg++] = current_message; + messages[written_msg++] = current_message; } else if ( // this is what happens at release of the right-screen button of the ROG Ally (e->ev_count == 2) && (e->ev[0].type == EV_MSC) && @@ -485,20 +523,20 @@ int asus_kbd_ev_map( (e->ev[1].type == EV_KEY) && (e->ev[1].code == KEY_F17) ) { - const in_message_t current_message = { - .type = GAMEPAD_SET_ELEMENT, - .data = { - .gamepad_set = { - .element = GAMEPAD_BTN_L5, - .status = { - .btn = e->ev[1].value, - } - } - } - }; + const in_message_t current_message = { + .type = GAMEPAD_SET_ELEMENT, + .data = { + .gamepad_set = { + .element = GAMEPAD_BTN_L5, + .status = { + .btn = e->ev[1].value, + } + } + } + }; - messages[written_msg++] = current_message; - } else if ( + messages[written_msg++] = current_message; + } else if ( (e->ev_count == 2) && (e->ev[0].type == EV_MSC) && (e->ev[0].code == MSC_SCAN) && @@ -609,22 +647,6 @@ static input_dev_t in_xbox_dev = { } }; -typedef enum rc71l_platform_mode { - rc71l_platform_mode_hidraw, - rc71l_platform_mode_linux_and_asusctl, -} rc71l_platform_mode_t; - -typedef struct rc71l_platform { - rc71l_platform_mode_t platform_mode; - - union { - dev_hidraw_t *hidraw; - } platform; - - unsigned long mode; - unsigned int modes_count; -} rc71l_platform_t; - enum rc71l_leds_mode { ROG_ALLY_MODE_STATIC = 0, ROG_ALLY_MODE_BREATHING = 1, @@ -648,7 +670,7 @@ enum rc71l_leds_direction { static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platform_data) { int res = -EINVAL; - rc71l_platform_t *const platform = malloc(sizeof(rc71l_platform_t)); + rc71l_platform_t *const platform = &hw_platform; if (platform == NULL) { fprintf(stderr, "Unable to setup platform\n"); res = -ENOMEM; @@ -709,7 +731,6 @@ static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** pl platform->platform.hidraw = NULL; } - free(platform); *platform_data = NULL; } From 13f35d69240d75a813583485a0ff3efe28a0d3bc Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 15 Dec 2023 00:12:36 +0100 Subject: [PATCH 015/186] text for when controller mode is switched --- rog_ally.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 821fe79..3635275 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -469,15 +469,24 @@ int asus_kbd_ev_map( (e->ev[1].value == 1) ) { if (hw_platform.mode == rc71l_platform_mode_hidraw) { - printf("Using hidraw to switch controller mode\n"); + const unsigned long new_mode = (hw_platform.mode + 1) % hw_platform.modes_count; + printf("Using hidraw to switch controller mode from %lu to %lu\n", hw_platform.mode, new_mode); - for (int i = 0; i < 23; ++i) { - const int write_res = write(hw_platform.platform.hidraw->fd, &rc71l_mode_switch_commands[0][i][0], 64); + int i; + for (i = 0; i < 23; ++i) { + const int write_res = write(hw_platform.platform.hidraw->fd, &rc71l_mode_switch_commands[new_mode][i][0], 64); if (write_res != 64) { fprintf(stderr, "Error writing packet %d/23: %d bytes sent, 64 expected\n", i, write_res); break; } } + + if (i == 23) { + printf("Mode correctly switched\n"); + hw_platform.mode = new_mode; + } else { + fprintf(stderr, "Mode was not switched correctly: you should retry -- expect bugs\n"); + } } } else if ( // this is what happens at release of the left-screen button of the ROG Ally (e->ev_count == 2) && From 3ca8c5983713602140500c5158dbfc956ef4e336 Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 15 Dec 2023 00:15:00 +0100 Subject: [PATCH 016/186] whoopsie --- rog_ally.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rog_ally.c b/rog_ally.c index 3635275..b7803fd 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -725,7 +725,9 @@ static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platf break; } } - + + platform->mode = 0; + platform->modes_count = 2; printf("ROG Ally platform will be managed over hidraw. I'm sorry fluke.\n"); rc71l_platform_init_err: From b69d2d719836ce3735dd64c558f8d7a016babd53 Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 15 Dec 2023 00:55:17 +0100 Subject: [PATCH 017/186] better formatting --- rog_ally.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index b7803fd..626f728 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -498,10 +498,10 @@ int asus_kbd_ev_map( (e->ev[1].value == 1) ) { const in_message_t current_message = { - .type = GAMEPAD_ACTION, - .data = { - .action = GAMEPAD_ACTION_PRESS_AND_RELEASE_CENTER, - } + .type = GAMEPAD_ACTION, + .data = { + .action = GAMEPAD_ACTION_PRESS_AND_RELEASE_CENTER, + } }; messages[written_msg++] = current_message; @@ -533,15 +533,15 @@ int asus_kbd_ev_map( (e->ev[1].code == KEY_F17) ) { const in_message_t current_message = { - .type = GAMEPAD_SET_ELEMENT, - .data = { - .gamepad_set = { - .element = GAMEPAD_BTN_L5, - .status = { - .btn = e->ev[1].value, + .type = GAMEPAD_SET_ELEMENT, + .data = { + .gamepad_set = { + .element = GAMEPAD_BTN_L5, + .status = { + .btn = e->ev[1].value, + } + } } - } - } }; messages[written_msg++] = current_message; @@ -557,10 +557,10 @@ int asus_kbd_ev_map( .type = GAMEPAD_SET_ELEMENT, .data = { .gamepad_set = { - .element = GAMEPAD_BTN_R5, - .status = { - .btn = e->ev[1].value, - } + .element = GAMEPAD_BTN_R5, + .status = { + .btn = e->ev[1].value, + } } } }; From 563da79b2baa87def846a720d9fa4e24616b2067 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 16 Dec 2023 14:58:33 +0100 Subject: [PATCH 018/186] add buttons references --- References/Ally/left_back_paddle.log | 22 +++++++++++++++++++ References/Ally/left_screen_button_long.log | 18 +++++++++++++++ References/Ally/left_screen_button_short.log | 6 +++++ References/Ally/right_back_paddle.log | 14 ++++++++++++ References/Ally/right_screen_button_long.log | 17 ++++++++++++++ References/Ally/right_screen_button_short.log | 6 +++++ 6 files changed, 83 insertions(+) create mode 100644 References/Ally/left_back_paddle.log create mode 100644 References/Ally/left_screen_button_long.log create mode 100644 References/Ally/left_screen_button_short.log create mode 100644 References/Ally/right_back_paddle.log create mode 100644 References/Ally/right_screen_button_long.log create mode 100644 References/Ally/right_screen_button_short.log diff --git a/References/Ally/left_back_paddle.log b/References/Ally/left_back_paddle.log new file mode 100644 index 0000000..65dbadb --- /dev/null +++ b/References/Ally/left_back_paddle.log @@ -0,0 +1,22 @@ +Event: time 1702734480.395212, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70069 +Event: time 1702734480.395212, type 1 (EV_KEY), code 184 (KEY_F14), value 1 +Event: time 1702734480.395212, -------------- SYN_REPORT ------------ +Event: time 1702734480.666881, type 1 (EV_KEY), code 184 (KEY_F14), value 2 +Event: time 1702734480.666881, -------------- SYN_REPORT ------------ +Event: time 1702734480.703572, type 1 (EV_KEY), code 184 (KEY_F14), value 2 +Event: time 1702734480.703572, -------------- SYN_REPORT ------------ +Event: time 1702734480.740210, type 1 (EV_KEY), code 184 (KEY_F14), value 2 +Event: time 1702734480.740210, -------------- SYN_REPORT ------------ +Event: time 1702734480.776877, type 1 (EV_KEY), code 184 (KEY_F14), value 2 +Event: time 1702734480.776877, -------------- SYN_REPORT ------------ +Event: time 1702734480.813547, type 1 (EV_KEY), code 184 (KEY_F14), value 2 +Event: time 1702734480.813547, -------------- SYN_REPORT ------------ +Event: time 1702734480.850210, type 1 (EV_KEY), code 184 (KEY_F14), value 2 +Event: time 1702734480.850210, -------------- SYN_REPORT ------------ +Event: time 1702734480.890215, type 1 (EV_KEY), code 184 (KEY_F14), value 2 +Event: time 1702734480.890215, -------------- SYN_REPORT ------------ +Event: time 1702734480.930212, type 1 (EV_KEY), code 184 (KEY_F14), value 2 +Event: time 1702734480.930212, -------------- SYN_REPORT ------------ +Event: time 1702734480.943181, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70069 +Event: time 1702734480.943181, type 1 (EV_KEY), code 184 (KEY_F14), value 0 +Event: time 1702734480.943181, -------------- SYN_REPORT ------------ \ No newline at end of file diff --git a/References/Ally/left_screen_button_long.log b/References/Ally/left_screen_button_long.log new file mode 100644 index 0000000..d3d1b69 --- /dev/null +++ b/References/Ally/left_screen_button_long.log @@ -0,0 +1,18 @@ +Event: time 1702734659.559525, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e0 +Event: time 1702734659.559525, type 1 (EV_KEY), code 29 (KEY_LEFTCTRL), value 1 +Event: time 1702734659.559525, -------------- SYN_REPORT ------------ +Event: time 1702734659.560490, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e2 +Event: time 1702734659.560490, type 1 (EV_KEY), code 56 (KEY_LEFTALT), value 1 +Event: time 1702734659.560490, -------------- SYN_REPORT ------------ +Event: time 1702734659.561435, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7004c +Event: time 1702734659.561435, type 1 (EV_KEY), code 111 (KEY_DELETE), value 1 +Event: time 1702734659.561435, -------------- SYN_REPORT ------------ +Event: time 1702734659.562485, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e0 +Event: time 1702734659.562485, type 1 (EV_KEY), code 29 (KEY_LEFTCTRL), value 0 +Event: time 1702734659.562485, -------------- SYN_REPORT ------------ +Event: time 1702734659.563486, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e2 +Event: time 1702734659.563486, type 1 (EV_KEY), code 56 (KEY_LEFTALT), value 0 +Event: time 1702734659.563486, -------------- SYN_REPORT ------------ +Event: time 1702734659.565433, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7004c +Event: time 1702734659.565433, type 1 (EV_KEY), code 111 (KEY_DELETE), value 0 +Event: time 1702734659.565433, -------------- SYN_REPORT ------------ diff --git a/References/Ally/left_screen_button_short.log b/References/Ally/left_screen_button_short.log new file mode 100644 index 0000000..e42715c --- /dev/null +++ b/References/Ally/left_screen_button_short.log @@ -0,0 +1,6 @@ +Event: time 1702734692.300847, type 4 (EV_MSC), code 4 (MSC_SCAN), value ff3100a6 +Event: time 1702734692.300847, type 1 (EV_KEY), code 186 (KEY_F16), value 1 +Event: time 1702734692.300847, -------------- SYN_REPORT ------------ +Event: time 1702734692.301778, type 4 (EV_MSC), code 4 (MSC_SCAN), value ff3100a6 +Event: time 1702734692.301778, type 1 (EV_KEY), code 186 (KEY_F16), value 0 +Event: time 1702734692.301778, -------------- SYN_REPORT ------------ diff --git a/References/Ally/right_back_paddle.log b/References/Ally/right_back_paddle.log new file mode 100644 index 0000000..b5d833b --- /dev/null +++ b/References/Ally/right_back_paddle.log @@ -0,0 +1,14 @@ +Event: time 1702734541.227670, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7006a +Event: time 1702734541.227670, type 1 (EV_KEY), code 185 (KEY_F15), value 1 +Event: time 1702734541.227670, -------------- SYN_REPORT ------------ +Event: time 1702734541.490206, type 1 (EV_KEY), code 185 (KEY_F15), value 2 +Event: time 1702734541.490206, -------------- SYN_REPORT ------------ +Event: time 1702734541.530208, type 1 (EV_KEY), code 185 (KEY_F15), value 2 +Event: time 1702734541.530208, -------------- SYN_REPORT ------------ +Event: time 1702734541.570205, type 1 (EV_KEY), code 185 (KEY_F15), value 2 +Event: time 1702734541.570205, -------------- SYN_REPORT ------------ +Event: time 1702734541.606872, type 1 (EV_KEY), code 185 (KEY_F15), value 2 +Event: time 1702734541.606872, -------------- SYN_REPORT ------------ +Event: time 1702734541.640678, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7006a +Event: time 1702734541.640678, type 1 (EV_KEY), code 185 (KEY_F15), value 0 +Event: time 1702734541.640678, -------------- SYN_REPORT ------------ diff --git a/References/Ally/right_screen_button_long.log b/References/Ally/right_screen_button_long.log new file mode 100644 index 0000000..24492de --- /dev/null +++ b/References/Ally/right_screen_button_long.log @@ -0,0 +1,17 @@ +Event: time 1702734610.835523, type 4 (EV_MSC), code 4 (MSC_SCAN), value ff3100a7 +Event: time 1702734610.835523, type 1 (EV_KEY), code 187 (KEY_F17), value 1 +Event: time 1702734610.835523, -------------- SYN_REPORT ------------ +Event: time 1702734610.836480, type 4 (EV_MSC), code 4 (MSC_SCAN), value ff3100a7 +Event: time 1702734610.836480, type 1 (EV_KEY), code 187 (KEY_F17), value 0 +Event: time 1702734610.836480, -------------- SYN_REPORT ------------ + + +F17 appears before release + + +Event: time 1702734611.433499, type 4 (EV_MSC), code 4 (MSC_SCAN), value ff3100a8 +Event: time 1702734611.433499, type 1 (EV_KEY), code 188 (KEY_F18), value 1 +Event: time 1702734611.433499, -------------- SYN_REPORT ------------ +Event: time 1702734611.434434, type 4 (EV_MSC), code 4 (MSC_SCAN), value ff3100a8 +Event: time 1702734611.434434, type 1 (EV_KEY), code 188 (KEY_F18), value 0 +Event: time 1702734611.434434, -------------- SYN_REPORT ------------ diff --git a/References/Ally/right_screen_button_short.log b/References/Ally/right_screen_button_short.log new file mode 100644 index 0000000..8f4ad4d --- /dev/null +++ b/References/Ally/right_screen_button_short.log @@ -0,0 +1,6 @@ +Event: time 1702734588.908929, type 4 (EV_MSC), code 4 (MSC_SCAN), value ff310038 +Event: time 1702734588.908929, type 1 (EV_KEY), code 148 (KEY_PROG1), value 1 +Event: time 1702734588.908929, -------------- SYN_REPORT ------------ +Event: time 1702734588.909906, type 4 (EV_MSC), code 4 (MSC_SCAN), value ff310038 +Event: time 1702734588.909906, type 1 (EV_KEY), code 148 (KEY_PROG1), value 0 +Event: time 1702734588.909906, -------------- SYN_REPORT ------------ From 0797e2e326d3d54c690199a5c5522ad4d21984f5 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 16 Dec 2023 18:39:15 +0100 Subject: [PATCH 019/186] discarding hidraw mode change and initial setup --- rog_ally.c | 845 +++++++++++++------------------------------------- rogue_enemy.h | 2 + 2 files changed, 211 insertions(+), 636 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 626f728..227fb8c 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -3,435 +3,6 @@ #include "dev_hidraw.h" #include "xbox360.h" -/* - * USB buffers to be used in a control transfer to make the joystick change buttons mode and scancodes - * 0 is default (game_mode with back buttons sending F17 and F18 instead of F15 for both as when unconfigured) - * 1 is mouse mode: back buttons still are F17 and F18 - * 2 is macro mode: the default when back paddles are chords. to be avoided as pressing those will break others buttons status. - */ -static const uint8_t rc71l_mode_switch_commands[][23][64] = { - { - { - 0x5A, 0xD1, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x01, 0x2C, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8C, 0x88, 0x76, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x02, 0x2C, 0x01, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x23, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x0D, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x03, 0x2C, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x04, 0x2C, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x05, 0x2C, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x31, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x06, 0x2C, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x4D, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x07, 0x2C, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x08, 0x2C, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x09, 0x2C, 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x06, 0x02, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x04, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x05, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - } - }, - { - { - 0x5A, 0xD1, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x01, 0x2C, 0x02, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x99, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8C, 0x88, 0x76, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x02, 0x2C, 0x02, 0x00, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x9B, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x0D, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x03, 0x2C, 0x02, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x04, 0x2C, 0x02, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x05, 0x2C, 0x02, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x31, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x06, 0x2C, 0x02, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x4D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x96, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x07, 0x2C, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x08, 0x2C, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x09, 0x2C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x88, 0x0D, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x06, 0x02, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x04, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x05, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - } - }, - { - { - 0x5A, 0xD1, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x01, 0x2C, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8C, 0x88, 0x76, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x02, 0x2C, 0x01, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x23, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x0D, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x03, 0x2C, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x04, 0x2C, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x05, 0x2C, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x31, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x06, 0x2C, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x4D, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x07, 0x2C, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x08, 0x2C, 0x02, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x8F, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x02, 0x09, 0x2C, 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x0F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x06, 0x02, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x04, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x5A, 0xD1, 0x05, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - } - } -}; - typedef enum rc71l_platform_mode { rc71l_platform_mode_hidraw, rc71l_platform_mode_linux_and_asusctl, @@ -450,6 +21,66 @@ typedef struct rc71l_platform { static rc71l_platform_t hw_platform; +typedef struct rc71l_asus_kbd_user_data { + struct udev *udev; +} rc71l_asus_kbd_user_data_t; + +static rc71l_asus_kbd_user_data_t asus_userdata; + +static char* find_kernel_sysfs_device_path(struct udev *udev) { + struct udev_enumerate *const enumerate = udev_enumerate_new(udev); + if (enumerate == NULL) { + fprintf(stderr, "Error in udev_enumerate_new: mode switch will not be available.\n"); + return NULL; + } + + const int add_match_subsystem_res = udev_enumerate_add_match_subsystem(enumerate, "hid"); + if (add_match_subsystem_res != 0) { + fprintf(stderr, "Error in udev_enumerate_add_match_subsystem: %d\n", add_match_subsystem_res); + + udev_enumerate_unref(enumerate); + + return NULL; + } + + const int add_match_sysattr_res = udev_enumerate_add_match_sysattr(enumerate, "gamepad_mode", NULL); + if (add_match_sysattr_res != 0) { + fprintf(stderr, "Error in udev_enumerate_add_match_sysattr: %d\n", add_match_sysattr_res); + + udev_enumerate_unref(enumerate); + + return NULL; + } + + const int enumerate_scan_devices_res = udev_enumerate_scan_devices(enumerate); + if (enumerate_scan_devices_res != 0) { + fprintf(stderr, "Error in udev_enumerate_scan_devices: %d\n", enumerate_scan_devices_res); + + udev_enumerate_unref(enumerate); + + return NULL; + } + + struct udev_list_entry *const udev_lst_frst = udev_enumerate_get_list_entry(enumerate); + + struct udev_list_entry *list_entry = NULL; + udev_list_entry_foreach(list_entry, udev_lst_frst) { + const char* const name = udev_list_entry_get_name(list_entry); + + const unsigned long len = strlen(name) + 1; + char *const result = malloc(len); + memset(result, 0, len); + strncat(result, name, len - 1); + + udev_enumerate_unref(enumerate); + + return result; + } + + udev_enumerate_unref(enumerate); + return NULL; +} + int asus_kbd_ev_map( const dev_in_settings_t *const conf, const evdev_collected_t *const e, @@ -457,115 +88,79 @@ int asus_kbd_ev_map( size_t messages_len, void* user_data ) { + rc71l_asus_kbd_user_data_t *const asus_kbd_user_data = (rc71l_asus_kbd_user_data_t*)user_data; int written_msg = 0; - if ( - (e->ev_count >= 2) && - (e->ev[0].type == EV_MSC) && - (e->ev[0].code == MSC_SCAN) && - (e->ev[0].value == -13565784) && - (e->ev[1].type == EV_KEY) && - (e->ev[1].code == KEY_F18) && - (e->ev[1].value == 1) - ) { - if (hw_platform.mode == rc71l_platform_mode_hidraw) { - const unsigned long new_mode = (hw_platform.mode + 1) % hw_platform.modes_count; - printf("Using hidraw to switch controller mode from %lu to %lu\n", hw_platform.mode, new_mode); - - int i; - for (i = 0; i < 23; ++i) { - const int write_res = write(hw_platform.platform.hidraw->fd, &rc71l_mode_switch_commands[new_mode][i][0], 64); - if (write_res != 64) { - fprintf(stderr, "Error writing packet %d/23: %d bytes sent, 64 expected\n", i, write_res); - break; - } - } - - if (i == 23) { - printf("Mode correctly switched\n"); - hw_platform.mode = new_mode; - } else { - fprintf(stderr, "Mode was not switched correctly: you should retry -- expect bugs\n"); - } - } - } else if ( // this is what happens at release of the left-screen button of the ROG Ally - (e->ev_count == 2) && - (e->ev[0].type == EV_MSC) && - (e->ev[0].code == MSC_SCAN) && - (e->ev[0].value == -13565786) && - (e->ev[1].type == EV_KEY) && - (e->ev[1].code == KEY_F16) && - (e->ev[1].value == 1) - ) { - const in_message_t current_message = { - .type = GAMEPAD_ACTION, - .data = { - .action = GAMEPAD_ACTION_PRESS_AND_RELEASE_CENTER, - } - }; - - messages[written_msg++] = current_message; - } else if ( // this is what happens at release of the right-screen button of the ROG Ally - (e->ev_count == 2) && - (e->ev[0].type == EV_MSC) && - (e->ev[0].code == MSC_SCAN) && - (e->ev[0].value == -13565896) && - (e->ev[1].type == EV_KEY) && - (e->ev[1].code == KEY_PROG1) && - (e->ev[1].value == 1) - ) { - if (conf->enable_qam) { - const in_message_t current_message = { - .type = GAMEPAD_ACTION, - .data = { - .action = GAMEPAD_ACTION_OPEN_STEAM_QAM, - } - }; - - messages[written_msg++] = current_message; - } - } else if ( - (e->ev_count == 2) && - (e->ev[0].type == EV_MSC) && - (e->ev[0].code == MSC_SCAN) && - (e->ev[0].value == 458860) && - (e->ev[1].type == EV_KEY) && - (e->ev[1].code == KEY_F17) - ) { - const in_message_t current_message = { - .type = GAMEPAD_SET_ELEMENT, - .data = { - .gamepad_set = { - .element = GAMEPAD_BTN_L5, - .status = { - .btn = e->ev[1].value, - } - } - } - }; - - messages[written_msg++] = current_message; - } else if ( - (e->ev_count == 2) && - (e->ev[0].type == EV_MSC) && - (e->ev[0].code == MSC_SCAN) && - (e->ev[0].value == 458861) && - (e->ev[1].type == EV_KEY) && - (e->ev[1].code == KEY_F18) - ) { - const in_message_t current_message = { - .type = GAMEPAD_SET_ELEMENT, - .data = { - .gamepad_set = { - .element = GAMEPAD_BTN_R5, - .status = { - .btn = e->ev[1].value, + for (size_t i = 0; i < e->ev_count; ++i) { + if (e->ev[i].type == EV_KEY) { + if (e->ev[i].code == KEY_F14) { + // this is left back paddle, works as expected + const in_message_t current_message = { + .type = GAMEPAD_SET_ELEMENT, + .data = { + .gamepad_set = { + .element = GAMEPAD_BTN_L5, + .status = { + .btn = e->ev[1].value, + } + } } - } - } - }; + }; - messages[written_msg++] = current_message; + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_F15) { + // this is right back paddle, works as expected + const in_message_t current_message = { + .type = GAMEPAD_SET_ELEMENT, + .data = { + .gamepad_set = { + .element = GAMEPAD_BTN_R5, + .status = { + .btn = e->ev[1].value, + } + } + } + }; + + messages[written_msg++] = current_message; + } else if ((e->ev[i].code == KEY_F16) && (e->ev[i].value != 0)) { + // this is left screen button, on release both 0 and 1 events are emitted so just discard the 0 + + } else if ((e->ev[i].code == KEY_PROG1) && (e->ev[i].value != 0)) { + // this is right screen button, on short release both 0 and 1 events are emitted so just discard the 0 + if (conf->enable_qam) { + const in_message_t current_message = { + .type = GAMEPAD_ACTION, + .data = { + .action = GAMEPAD_ACTION_OPEN_STEAM_QAM, + } + }; + + messages[written_msg++] = current_message; + } + } else if ((e->ev[i].code == KEY_F17) && (e->ev[i].value != 0)) { + // this is right screen button, on long release, after passing short threshold both 0 and 1 events are emitted so just discard the 0 + + } else if ((e->ev[i].code == KEY_F18) && (e->ev[i].value != 0)) { + // this is right screen button, on release both 0 and 1 events are emitted so just discard the 0 + + // change controller mode + if (asus_kbd_user_data == NULL) { + fprintf(stderr, "asus keyboard user data unavailable -- skipping mode change\n"); + continue; + } + + char *const kernel_sysfs = find_kernel_sysfs_device_path(asus_kbd_user_data->udev); + if (kernel_sysfs == NULL) { + fprintf(stderr, "Kernel interface to Asus MCU not found -- skipping mode change\n"); + continue; + } + + printf("Asus MCU kernel interface found at %s -- switching mode\n", kernel_sysfs); + + free(kernel_sysfs); + } + } } return written_msg; @@ -615,6 +210,7 @@ static input_dev_t in_asus_kb_1_dev = { .name = "Asus Keyboard" } }, + .user_data = (void*)&asus_userdata, .map = { .ev_input_map_fn = asus_kbd_ev_map, } @@ -627,6 +223,7 @@ static input_dev_t in_asus_kb_2_dev = { .name = "Asus Keyboard" } }, + .user_data = (void*)&asus_userdata, .map = { .ev_input_map_fn = asus_kbd_ev_map, } @@ -639,6 +236,7 @@ static input_dev_t in_asus_kb_3_dev = { .name = "Asus Keyboard" } }, + .user_data = &asus_userdata, .map = { .ev_input_map_fn = asus_kbd_ev_map, } @@ -677,128 +275,103 @@ enum rc71l_leds_direction { } rc71l_leds_direction_t; static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platform_data) { - int res = -EINVAL; + int res = -EINVAL; - rc71l_platform_t *const platform = &hw_platform; - if (platform == NULL) { - fprintf(stderr, "Unable to setup platform\n"); - res = -ENOMEM; - goto rc71l_platform_init_err; - } + rc71l_platform_t *const platform = &hw_platform; + if (platform == NULL) { + fprintf(stderr, "Unable to setup platform\n"); + res = -ENOMEM; + goto rc71l_platform_init_err; + } - *platform_data = (void*)platform; + *platform_data = (void*)platform; - res = dev_hidraw_open(&n_key_hidraw_filters, &platform->platform.hidraw); - if (res != 0) { - fprintf(stderr, "Unable to open the ROG ally hidraw main device...\n"); - free(*platform_data); - *platform_data = NULL; - goto rc71l_platform_init_err; - } + // setup asus keyboard(s) user_data + asus_userdata.udev = udev_new(); - uint8_t rdesc[256]; - size_t rdesc_sz; - res = dev_hidraw_get_rdesc(platform->platform.hidraw, rdesc, sizeof(rdesc), &rdesc_sz); - if (res != 0) { - fprintf(stderr, "Unable to get rc71l rdesc\n"); - goto rc71l_platform_init_err; - } + res = dev_hidraw_open(&n_key_hidraw_filters, &platform->platform.hidraw); + if (res != 0) { + fprintf(stderr, "Unable to open the ROG ally hidraw main device...\n"); + free(*platform_data); + *platform_data = NULL; + goto rc71l_platform_init_err; + } - platform->platform_mode = rc71l_platform_mode_hidraw; + platform->platform_mode = rc71l_platform_mode_hidraw; - const int fd = dev_hidraw_get_fd(platform->platform.hidraw); -/* - - const uint8_t hidraw_buf[] = { - 0x5D, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, 0x65, 0x63, 0x68, 0x2E, 0x49, 0x6E, 0x63, 0x2E, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - write(fd, hidraw_buf, sizeof(hidraw_buf)); -*/ - for (int i = 0; i < 23; ++i) { - const int write_res = write(fd, &rc71l_mode_switch_commands[0][i][0], 64); - if (write_res != 64) { - fprintf(stderr, "Error writing packet %d/23: %d bytes sent, 64 expected\n", i, write_res); - break; - } - } - - platform->mode = 0; - platform->modes_count = 2; - printf("ROG Ally platform will be managed over hidraw. I'm sorry fluke.\n"); + const int fd = dev_hidraw_get_fd(platform->platform.hidraw); + + platform->mode = 0; + platform->modes_count = 2; + printf("ROG Ally platform will be managed over hidraw. I'm sorry fluke.\n"); rc71l_platform_init_err: - return res; + return res; } static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** platform_data) { - rc71l_platform_t *const platform = (rc71l_platform_t *)(*platform_data); + rc71l_platform_t *const platform = (rc71l_platform_t *)(*platform_data); - if ((platform->platform_mode == rc71l_platform_mode_hidraw) && (platform->platform.hidraw != NULL)) { - dev_hidraw_close(platform->platform.hidraw); - platform->platform.hidraw = NULL; - } + udev_unref(asus_userdata.udev); - *platform_data = NULL; + if ((platform->platform_mode == rc71l_platform_mode_hidraw) && (platform->platform.hidraw != NULL)) { + dev_hidraw_close(platform->platform.hidraw); + platform->platform.hidraw = NULL; + } + + *platform_data = NULL; } static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, uint8_t g, uint8_t b, void* platform_data) { - rc71l_platform_t *const platform = (rc71l_platform_t *)platform_data; - if (platform == NULL) { - return -EINVAL; - } + rc71l_platform_t *const platform = (rc71l_platform_t *)platform_data; + if (platform == NULL) { + return -EINVAL; + } - const uint8_t brightness_buf[] = { - 0x5A, 0xBA, 0xC5, 0xC4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; + const uint8_t brightness_buf[] = { + 0x5A, 0xBA, 0xC5, 0xC4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; - uint8_t colors_buf[] = { - 0x5A, 0xB3, 0x00, ROG_ALLY_MODE_STATIC, r, g, b, 0x00, ROG_ALLY_DIRECTION_RIGHT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; -/* - const uint8_t save_mode[] = { - 0x5A, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; -*/ - if ((platform->platform_mode == rc71l_platform_mode_hidraw) && (platform->platform.hidraw != NULL)) { - int fd = dev_hidraw_get_fd(platform->platform.hidraw); + uint8_t colors_buf[] = { + 0x5A, 0xB3, 0x00, ROG_ALLY_MODE_STATIC, r, g, b, 0x00, ROG_ALLY_DIRECTION_RIGHT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; - if (write(fd, brightness_buf, sizeof(brightness_buf)) != 64) { - fprintf(stderr, "Unable to send LEDs brightness (1) command change\n"); - goto rc71l_platform_leds_err; - } + if ((platform->platform_mode == rc71l_platform_mode_hidraw) && (platform->platform.hidraw != NULL)) { + int fd = dev_hidraw_get_fd(platform->platform.hidraw); - if (write(fd, colors_buf, sizeof(colors_buf)) != 64) { - fprintf(stderr, "Unable to send LEDs color command change (1)\n"); - goto rc71l_platform_leds_err; - } -/* - colors_buf[0x00] = 0x5A; - colors_buf[0x01] = 0xB5; - if (write(fd, colors_buf, sizeof(colors_buf)) != 64) { - fprintf(stderr, "Unable to send LEDs color command change (2)\n"); - goto rc71l_platform_leds_err; - } + if (write(fd, brightness_buf, sizeof(brightness_buf)) != 64) { + fprintf(stderr, "Unable to send LEDs brightness (1) command change -- attempt to reacquire hidraw\n"); - if (write(fd, save_mode, sizeof(save_mode)) != 64) { - fprintf(stderr, "Unable to send LEDs save mode command\n"); - goto rc71l_platform_leds_err; - } -*/ - return 0; - } + dev_hidraw_close(platform->platform.hidraw); + + const int reopen_res = dev_hidraw_open(&n_key_hidraw_filters, &platform->platform.hidraw); + if (reopen_res != 0) { + fprintf(stderr, "Unable to (re)open the ROG ally hidraw main device...\n"); + goto rc71l_platform_leds_err; + } else { + printf("ROG ally hidraw main device reacquired\n"); + fd = dev_hidraw_get_fd(platform->platform.hidraw); + + if (write(fd, brightness_buf, sizeof(brightness_buf)) != 64) { + fprintf(stderr, "Unable to send LEDs brightness (1) command change after hidraw reset -- giving up\n"); + goto rc71l_platform_leds_err; + } + } + } + + if (write(fd, colors_buf, sizeof(colors_buf)) != 64) { + fprintf(stderr, "Unable to send LEDs color command change (1)\n"); + goto rc71l_platform_leds_err; + } + + return 0; + } rc71l_platform_leds_err: return -EINVAL; @@ -819,5 +392,5 @@ input_dev_composite_t rc71l_composite = { }; input_dev_composite_t* rog_ally_device_def(void) { - return &rc71l_composite; + return &rc71l_composite; } diff --git a/rogue_enemy.h b/rogue_enemy.h index 1e7cfac..4d17389 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -41,6 +41,8 @@ #include +#include + #define LSB_PER_RAD_S_2000_DEG_S ((double)0.001064724) #define LSB_PER_RAD_S_2000_DEG_S_STR "0.001064724" From 6072f88002de9097046c0fc69be3d6bbc5965100 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 16 Dec 2023 19:08:03 +0100 Subject: [PATCH 020/186] reimplement BTN_MODE --- rog_ally.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rog_ally.c b/rog_ally.c index 227fb8c..02a891f 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -125,7 +125,14 @@ int asus_kbd_ev_map( messages[written_msg++] = current_message; } else if ((e->ev[i].code == KEY_F16) && (e->ev[i].value != 0)) { // this is left screen button, on release both 0 and 1 events are emitted so just discard the 0 + const in_message_t current_message = { + .type = GAMEPAD_ACTION, + .data = { + .action = GAMEPAD_ACTION_PRESS_AND_RELEASE_CENTER, + } + }; + messages[written_msg++] = current_message; } else if ((e->ev[i].code == KEY_PROG1) && (e->ev[i].value != 0)) { // this is right screen button, on short release both 0 and 1 events are emitted so just discard the 0 if (conf->enable_qam) { From 0b7f888a2fc1a1ce20c25eb2dc39a5352920196f Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 16 Dec 2023 22:10:57 +0100 Subject: [PATCH 021/186] Implementing virtual mouse and mode switch --- CMakeLists.txt | 2 + dev_out.c | 366 ++++++++++++++++++++++++++++------------------- devices_status.c | 12 +- devices_status.h | 17 +++ message.h | 16 +++ rog_ally.c | 72 +++++++++- virt_mouse.c | 141 ++++++++++++++++++ virt_mouse.h | 29 ++++ 8 files changed, 502 insertions(+), 153 deletions(-) create mode 100644 virt_mouse.c create mode 100644 virt_mouse.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d85d929..30e3c1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ add_executable(${STRAY_EXECUTABLE_NAME} settings.c virt_ds4.c virt_ds5.c + virt_mouse.c devices_status.c ) @@ -44,6 +45,7 @@ add_executable(${ALLINONE_EXECUTABLE_NAME} settings.c virt_ds4.c virt_ds5.c + virt_mouse.c devices_status.c dev_evdev.c dev_iio.c diff --git a/dev_out.c b/dev_out.c index 8ac09a9..8f121b0 100644 --- a/dev_out.c +++ b/dev_out.c @@ -5,6 +5,7 @@ #include "message.h" #include "virt_ds4.h" #include "virt_ds5.h" +#include "virt_mouse.h" #include @@ -20,6 +21,24 @@ static void handle_incoming_message_gamepad_action( } } +static void handle_incoming_message_mouse_event( + const dev_out_settings_t *const in_settings, + const in_message_mouse_event_t *const msg_payload, + mouse_status_t *const inout_mouse +) { + if (msg_payload->type == MOUSE_ELEMENT_X) { + inout_mouse->x += msg_payload->value; + } else if (msg_payload->type == MOUSE_ELEMENT_Y) { + inout_mouse->y += msg_payload->value; + } else if (msg_payload->type == MOUSE_BTN_LEFT) { + inout_mouse->btn_left = msg_payload->value; + } else if (msg_payload->type == MOUSE_BTN_MIDDLE) { + inout_mouse->btn_middle = msg_payload->value; + } else if (msg_payload->type == MOUSE_BTN_RIGHT) { + inout_mouse->btn_right = msg_payload->value; + } +} + static void handle_incoming_message_gamepad_set( const dev_out_settings_t *const in_settings, const in_message_gamepad_set_element_t *const msg_payload, @@ -196,6 +215,12 @@ static void handle_incoming_message( &msg->data.action, &dev_stats->gamepad ); + } else if (msg->type == MOUSE_EVENT) { + handle_incoming_message_mouse_event( + in_settings, + &msg->data.mouse_event, + &dev_stats->mouse + ); } } @@ -229,14 +254,26 @@ void *dev_out_thread_func(void *ptr) { break; } + int current_gamepad_fd = -1; + int current_keyboard_fd = -1; + int current_mouse_fd = -1; + union { virt_dualshock_t ds4; virt_dualsense_t ds5; } controller_data; - int current_gamepad_fd = -1; - //int current_keyboard_fd = -1; - //int current_mouse_fd = -1; + virt_mouse_t mouse_data; + const int mouse_init_res = virt_mouse_init(&mouse_data); + if (mouse_init_res < 0) { + fprintf(stderr, "Unable to initialize virtual mouse -- will continue regardless\n"); + } else { + current_mouse_fd = virt_mouse_get_fd(&mouse_data); + } + + const int64_t kbd_report_timing_us = 1125; + const int64_t mouse_report_timing_us = 950; + const int64_t gamepad_report_timing_us = 1250; if (current_gamepad == GAMEPAD_DUALSENSE) { const int ds5_init_res = virt_dualsense_init(&controller_data.ds5); @@ -260,8 +297,8 @@ void *dev_out_thread_func(void *ptr) { gettimeofday(&now, NULL); struct timeval gamepad_last_hid_report_sent = now; - //struct timeval mouse_last_hid_report_sent = now; - //struct timeval keyboard_last_hid_report_sent = now; + struct timeval mouse_last_hid_report_sent = now; + struct timeval keyboard_last_hid_report_sent = now; uint8_t tmp_buf[256]; @@ -272,9 +309,12 @@ void *dev_out_thread_func(void *ptr) { break; } + const int64_t gamepad_time_diff_usecs = get_timediff_usec(&gamepad_last_hid_report_sent, &now); + const int64_t mouse_time_diff_usecs = get_timediff_usec(&mouse_last_hid_report_sent, &now); + const int64_t kbd_time_diff_usecs = get_timediff_usec(&keyboard_last_hid_report_sent, &now); + gettimeofday(&now, NULL); - int64_t gamepad_time_diff_usecs = get_timediff_usec(&gamepad_last_hid_report_sent, &now); - if (gamepad_time_diff_usecs >= 1250) { + if (gamepad_time_diff_usecs >= gamepad_report_timing_us) { gamepad_last_hid_report_sent = now; if (current_gamepad == GAMEPAD_DUALSENSE) { @@ -284,170 +324,200 @@ void *dev_out_thread_func(void *ptr) { virt_dualshock_compose(&controller_data.ds4, &dev_out_data->dev_stats.gamepad, tmp_buf); virt_dualshock_send(&controller_data.ds4, tmp_buf); } - } else { - FD_ZERO(&read_fds); + // this does reset the for, ensuring every other device has nothing to say + continue; + } else if (mouse_time_diff_usecs >= mouse_report_timing_us) { + mouse_last_hid_report_sent = now; + + virt_mouse_send(&mouse_data, &dev_out_data->dev_stats.mouse, &now); + + // this does reset the for, ensuring every other device has nothing to say + continue; + } else if (kbd_time_diff_usecs >= kbd_report_timing_us) { + keyboard_last_hid_report_sent = now; + + // this does reset the for, ensuring every other device has nothing to say + continue; + } + + + // once here no output device needs to send out its report + FD_ZERO(&read_fds); + + if (dev_out_data->communication.type == ipc_unix_pipe) { + FD_SET(dev_out_data->communication.endpoint.pipe.in_message_pipe_fd, &read_fds); + } else if (dev_out_data->communication.type == ipc_server_sockets) { + if (pthread_mutex_lock(&dev_out_data->communication.endpoint.ssocket.mutex) == 0) { + for (int i = 0; i < MAX_CONNECTED_CLIENTS; ++i) { + const int fd = dev_out_data->communication.endpoint.ssocket.clients[i]; + if (fd > 0) { + FD_SET(fd, &read_fds); + } + } + + pthread_mutex_unlock(&dev_out_data->communication.endpoint.ssocket.mutex); + } + } + + if (current_mouse_fd > 0) { + FD_SET(current_mouse_fd, &read_fds); + } + + // TODO: FD_SET(current_keyboard_fd, &read_fds); + + if (current_gamepad_fd > 0) { + FD_SET(current_gamepad_fd, &read_fds); + } + + const int64_t timeout_gamepad_time_diff_usecs = gamepad_report_timing_us - gamepad_time_diff_usecs; + const int64_t timeout_mouse_time_diff_usecs = mouse_time_diff_usecs - mouse_report_timing_us; + const int64_t timeout_kbd_time_diff_usecs = kbd_report_timing_us - kbd_time_diff_usecs; + + int64_t next_timing_out_device_diff_usecs = timeout_kbd_time_diff_usecs < timeout_mouse_time_diff_usecs ? timeout_kbd_time_diff_usecs : timeout_mouse_time_diff_usecs; + next_timing_out_device_diff_usecs = next_timing_out_device_diff_usecs < timeout_gamepad_time_diff_usecs ? next_timing_out_device_diff_usecs : timeout_gamepad_time_diff_usecs; + + // calculate the shortest timeout between one of the multiple device will needs to send out its hid report + struct timeval timeout = { + .tv_sec = (__time_t)next_timing_out_device_diff_usecs / (__time_t)1000000, + .tv_usec = (__suseconds_t)next_timing_out_device_diff_usecs % (__suseconds_t)1000000, + }; + + int ready_fds = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout); + gamepad_status_qam_quirk_ext_time(&dev_out_data->dev_stats.gamepad, &now); + + if (ready_fds == -1) { + const int err = errno; + fprintf(stderr, "Error reading events for output devices: %d\n", err); + continue; + } else if (ready_fds == 0) { + // timeout: do nothing but continue. next iteration will take care + continue; + } + + if ((current_gamepad_fd > 0) && (FD_ISSET(current_gamepad_fd, &read_fds))) { + const uint64_t prev_leds_events_count = dev_out_data->dev_stats.gamepad.leds_events_count; + const uint64_t prev_motors_events_count = dev_out_data->dev_stats.gamepad.rumble_events_count; + + out_message_t out_msgs[4]; + size_t out_msgs_count = 0; + if (current_gamepad == GAMEPAD_DUALSENSE) { + virt_dualsense_event(&controller_data.ds5, &dev_out_data->dev_stats.gamepad); + } else if (current_gamepad == GAMEPAD_DUALSHOCK) { + virt_dualshock_event(&controller_data.ds4, &dev_out_data->dev_stats.gamepad); + } + + const uint64_t current_leds_events_count = dev_out_data->dev_stats.gamepad.leds_events_count; + const uint64_t current_motors_events_count = dev_out_data->dev_stats.gamepad.rumble_events_count; + + if (current_leds_events_count != prev_leds_events_count) { + const out_message_t msg = { + .type = OUT_MSG_TYPE_LEDS, + .data = { + .leds = { + .r = dev_out_data->dev_stats.gamepad.leds_colors[0], + .g = dev_out_data->dev_stats.gamepad.leds_colors[1], + .b = dev_out_data->dev_stats.gamepad.leds_colors[2], + } + } + }; + + out_msgs[out_msgs_count++] = msg; + } + + if (current_motors_events_count != prev_motors_events_count) { + const out_message_t msg = { + .type = OUT_MSG_TYPE_RUMBLE, + .data = { + .rumble = { + .motors_left = dev_out_data->dev_stats.gamepad.motors_intensity[0], + .motors_right = dev_out_data->dev_stats.gamepad.motors_intensity[1], + } + } + }; + + out_msgs[out_msgs_count++] = msg; + } + + // send out game-generated events to sockets if (dev_out_data->communication.type == ipc_unix_pipe) { - FD_SET(dev_out_data->communication.endpoint.pipe.in_message_pipe_fd, &read_fds); + for (int msg_idx = 0; msg_idx < out_msgs_count; ++msg_idx) { + const int write_res = write(dev_out_data->communication.endpoint.pipe.out_message_pipe_fd, (void*)&out_msgs[msg_idx], sizeof(out_message_t)); + if (write_res != sizeof(out_message_t)) { + fprintf(stderr, "Error in writing out_message to out_message_pipe: %d\n", write_res); + } + } } else if (dev_out_data->communication.type == ipc_server_sockets) { if (pthread_mutex_lock(&dev_out_data->communication.endpoint.ssocket.mutex) == 0) { for (int i = 0; i < MAX_CONNECTED_CLIENTS; ++i) { - const int fd = dev_out_data->communication.endpoint.ssocket.clients[i]; - if (fd > 0) { - FD_SET(fd, &read_fds); - } - } - - pthread_mutex_unlock(&dev_out_data->communication.endpoint.ssocket.mutex); - } - } - - // TODO: FD_SET(current_mouse_fd, &read_fds); - // TODO: FD_SET(current_keyboard_fd, &read_fds); - FD_SET(current_gamepad_fd, &read_fds); - - // calculate the shortest timeout between one of the multiple device will needs to send out its hid report - struct timeval timeout = { - .tv_sec = (__time_t)gamepad_time_diff_usecs / (__time_t)1000000, - .tv_usec = (__suseconds_t)gamepad_time_diff_usecs % (__suseconds_t)1000000, - }; - - int ready_fds = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout); - gamepad_status_qam_quirk_ext_time(&dev_out_data->dev_stats.gamepad, &now); - - if (ready_fds == -1) { - const int err = errno; - fprintf(stderr, "Error reading events for output devices: %d\n", err); - continue; - } else if (ready_fds == 0) { - // timeout: do nothing but continue. next iteration will take care - continue; - } - - - if (FD_ISSET(current_gamepad_fd, &read_fds)) { - const uint64_t prev_leds_events_count = dev_out_data->dev_stats.gamepad.leds_events_count; - const uint64_t prev_motors_events_count = dev_out_data->dev_stats.gamepad.rumble_events_count; - - out_message_t out_msgs[4]; - size_t out_msgs_count = 0; - if (current_gamepad == GAMEPAD_DUALSENSE) { - virt_dualsense_event(&controller_data.ds5, &dev_out_data->dev_stats.gamepad); - } else if (current_gamepad == GAMEPAD_DUALSHOCK) { - virt_dualshock_event(&controller_data.ds4, &dev_out_data->dev_stats.gamepad); - } - - const uint64_t current_leds_events_count = dev_out_data->dev_stats.gamepad.leds_events_count; - const uint64_t current_motors_events_count = dev_out_data->dev_stats.gamepad.rumble_events_count; - - if (current_leds_events_count != prev_leds_events_count) { - const out_message_t msg = { - .type = OUT_MSG_TYPE_LEDS, - .data = { - .leds = { - .r = dev_out_data->dev_stats.gamepad.leds_colors[0], - .g = dev_out_data->dev_stats.gamepad.leds_colors[1], - .b = dev_out_data->dev_stats.gamepad.leds_colors[2], - } - } - }; - - out_msgs[out_msgs_count++] = msg; - } - - if (current_motors_events_count != prev_motors_events_count) { - const out_message_t msg = { - .type = OUT_MSG_TYPE_RUMBLE, - .data = { - .rumble = { - .motors_left = dev_out_data->dev_stats.gamepad.motors_intensity[0], - .motors_right = dev_out_data->dev_stats.gamepad.motors_intensity[1], - } - } - }; - - out_msgs[out_msgs_count++] = msg; - } - - // send out game-generated events to sockets - if (dev_out_data->communication.type == ipc_unix_pipe) { - for (int msg_idx = 0; msg_idx < out_msgs_count; ++msg_idx) { - const int write_res = write(dev_out_data->communication.endpoint.pipe.out_message_pipe_fd, (void*)&out_msgs[msg_idx], sizeof(out_message_t)); - if (write_res != sizeof(out_message_t)) { - fprintf(stderr, "Error in writing out_message to out_message_pipe: %d\n", write_res); - } - } - } else if (dev_out_data->communication.type == ipc_server_sockets) { - if (pthread_mutex_lock(&dev_out_data->communication.endpoint.ssocket.mutex) == 0) { - for (int i = 0; i < MAX_CONNECTED_CLIENTS; ++i) { - if (dev_out_data->communication.endpoint.ssocket.clients[i] > 0) { - for (int msg_idx = 0; msg_idx < out_msgs_count; ++msg_idx) { - const int write_res = write(dev_out_data->communication.endpoint.ssocket.clients[i], (void*)&out_msgs[msg_idx], sizeof(out_message_t)); - if (write_res != sizeof(out_message_t)) { - fprintf(stderr, "Error in writing out_message to socket number %d: %d\n", i, write_res); - close(dev_out_data->communication.endpoint.ssocket.clients[i]); - dev_out_data->communication.endpoint.ssocket.clients[i] = -1; - } + if (dev_out_data->communication.endpoint.ssocket.clients[i] > 0) { + for (int msg_idx = 0; msg_idx < out_msgs_count; ++msg_idx) { + const int write_res = write(dev_out_data->communication.endpoint.ssocket.clients[i], (void*)&out_msgs[msg_idx], sizeof(out_message_t)); + if (write_res != sizeof(out_message_t)) { + fprintf(stderr, "Error in writing out_message to socket number %d: %d\n", i, write_res); + close(dev_out_data->communication.endpoint.ssocket.clients[i]); + dev_out_data->communication.endpoint.ssocket.clients[i] = -1; } } } + } - pthread_mutex_unlock(&dev_out_data->communication.endpoint.ssocket.mutex); - } - } - } - - // read and handle incoming data: this data is packed into in_message_t - if (dev_out_data->communication.type == ipc_unix_pipe) { - if (FD_ISSET(dev_out_data->communication.endpoint.pipe.in_message_pipe_fd, &read_fds)) { - in_message_t incoming_message; - const size_t in_message_pipe_read_res = read(dev_out_data->communication.endpoint.pipe.in_message_pipe_fd, (void*)&incoming_message, sizeof(in_message_t)); - if (in_message_pipe_read_res == sizeof(in_message_t)) { - handle_incoming_message( - &dev_out_data->settings, - &incoming_message, - &dev_out_data->dev_stats - ); - } else { - fprintf(stderr, "Error reading from in_message_pipe_fd: got %zu bytes, expected %zu bytes\n", in_message_pipe_read_res, sizeof(in_message_t)); - } - } - } else if (dev_out_data->communication.type == ipc_server_sockets) { - if (pthread_mutex_lock(&dev_out_data->communication.endpoint.ssocket.mutex) == 0) { - for (int i = 0; i < MAX_CONNECTED_CLIENTS; ++i) { - const int fd = dev_out_data->communication.endpoint.ssocket.clients[i]; - if ((fd > 0) && (FD_ISSET(fd, &read_fds))) { - in_message_t incoming_message; - const size_t in_message_pipe_read_res = read(fd, (void*)&incoming_message, sizeof(in_message_t)); - if (in_message_pipe_read_res == sizeof(in_message_t)) { - handle_incoming_message( - &dev_out_data->settings, - &incoming_message, - &dev_out_data->dev_stats - ); - } else { - fprintf(stderr, "Error reading from socket number %d: got %zu bytes, expected %zu bytes\n", i, in_message_pipe_read_res, sizeof(in_message_t)); - close(dev_out_data->communication.endpoint.ssocket.clients[i]); - dev_out_data->communication.endpoint.ssocket.clients[i] = -1; - } - } - } - pthread_mutex_unlock(&dev_out_data->communication.endpoint.ssocket.mutex); } } + } + // read and handle incoming data: this data is packed into in_message_t + if (dev_out_data->communication.type == ipc_unix_pipe) { + if (FD_ISSET(dev_out_data->communication.endpoint.pipe.in_message_pipe_fd, &read_fds)) { + in_message_t incoming_message; + const size_t in_message_pipe_read_res = read(dev_out_data->communication.endpoint.pipe.in_message_pipe_fd, (void*)&incoming_message, sizeof(in_message_t)); + if (in_message_pipe_read_res == sizeof(in_message_t)) { + handle_incoming_message( + &dev_out_data->settings, + &incoming_message, + &dev_out_data->dev_stats + ); + } else { + fprintf(stderr, "Error reading from in_message_pipe_fd: got %zu bytes, expected %zu bytes\n", in_message_pipe_read_res, sizeof(in_message_t)); + } + } + } else if (dev_out_data->communication.type == ipc_server_sockets) { + if (pthread_mutex_lock(&dev_out_data->communication.endpoint.ssocket.mutex) == 0) { + for (int i = 0; i < MAX_CONNECTED_CLIENTS; ++i) { + const int fd = dev_out_data->communication.endpoint.ssocket.clients[i]; + if ((fd > 0) && (FD_ISSET(fd, &read_fds))) { + in_message_t incoming_message; + const size_t in_message_pipe_read_res = read(fd, (void*)&incoming_message, sizeof(in_message_t)); + if (in_message_pipe_read_res == sizeof(in_message_t)) { + handle_incoming_message( + &dev_out_data->settings, + &incoming_message, + &dev_out_data->dev_stats + ); + } else { + fprintf(stderr, "Error reading from socket number %d: got %zu bytes, expected %zu bytes\n", i, in_message_pipe_read_res, sizeof(in_message_t)); + close(dev_out_data->communication.endpoint.ssocket.clients[i]); + dev_out_data->communication.endpoint.ssocket.clients[i] = -1; + } + } + } + pthread_mutex_unlock(&dev_out_data->communication.endpoint.ssocket.mutex); + } } } - // close the output device + // close the gamepad output device if (current_gamepad == GAMEPAD_DUALSENSE) { virt_dualsense_close(&controller_data.ds5); } else if (current_gamepad == GAMEPAD_DUALSHOCK) { virt_dualshock_close(&controller_data.ds4); } + // close the mouse device + virt_mouse_close(&mouse_data); + // end communication if (dev_out_data->communication.type == ipc_server_sockets) { // close every client socket diff --git a/devices_status.c b/devices_status.c index bd67963..14e38c8 100644 --- a/devices_status.c +++ b/devices_status.c @@ -4,6 +4,16 @@ void kbd_status_init(keyboard_status_t *const stats) { stats->connected = true; } +void mouse_status_init(mouse_status_t *const stats) { + stats->connected = true; + + stats->x = 0; + stats->y = 0; + stats->btn_left = 0; + stats->btn_middle = 0; + stats->btn_right = 0; +} + void gamepad_status_init(gamepad_status_t *const stats) { stats->connected = true; stats->joystick_positions[0][0] = 0; @@ -45,7 +55,7 @@ void gamepad_status_init(gamepad_status_t *const stats) { void devices_status_init(devices_status_t *const stats) { gamepad_status_init(&stats->gamepad); kbd_status_init(&stats->kbd); - // TODO: mouse init + mouse_status_init(&stats->mouse); } void gamepad_status_qam_quirk(gamepad_status_t *const gamepad_stats) { diff --git a/devices_status.h b/devices_status.h index 8d39b26..869e7a7 100644 --- a/devices_status.h +++ b/devices_status.h @@ -69,6 +69,19 @@ typedef struct keyboard_status { bool connected; } keyboard_status_t; + +typedef struct mouse_status { + bool connected; + + int32_t x; + int32_t y; + + uint8_t btn_left; + uint8_t btn_middle; + uint8_t btn_right; + +} mouse_status_t; + typedef struct devices_status { // this mutex MUST be grabbed when reading and/or writing below properties pthread_mutex_t mutex; @@ -77,8 +90,12 @@ typedef struct devices_status { keyboard_status_t kbd; + mouse_status_t mouse; + } devices_status_t; +void mouse_status_init(mouse_status_t *const stats); + void kbd_status_init(keyboard_status_t *const stats); void gamepad_status_init(gamepad_status_t *const stats); diff --git a/message.h b/message.h index d16e371..372c124 100644 --- a/message.h +++ b/message.h @@ -64,6 +64,19 @@ typedef struct in_message_gamepad_set_element { } status; } in_message_gamepad_set_element_t; +typedef enum mouse_element { + MOUSE_ELEMENT_X, + MOUSE_ELEMENT_Y, + MOUSE_BTN_LEFT, + MOUSE_BTN_MIDDLE, + MOUSE_BTN_RIGHT, +} mouse_element_t; + +typedef struct in_message_mouse_event { + mouse_element_t type; + int32_t value; +} in_message_mouse_event_t; + typedef enum in_message_gamepad_action { GAMEPAD_ACTION_PRESS_AND_RELEASE_CENTER, GAMEPAD_ACTION_OPEN_STEAM_QAM, @@ -72,6 +85,7 @@ typedef enum in_message_gamepad_action { typedef enum in_in_message_type { GAMEPAD_SET_ELEMENT, GAMEPAD_ACTION, + MOUSE_EVENT, } in_message_type_t; typedef struct in_message { @@ -83,6 +97,8 @@ typedef struct in_message { in_message_gamepad_action_t action; in_message_gamepad_set_element_t gamepad_set; + + in_message_mouse_event_t mouse_event; } data; } in_message_t; diff --git a/rog_ally.c b/rog_ally.c index 02a891f..f7ac59e 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1,7 +1,9 @@ #include "rog_ally.h" #include "input_dev.h" #include "dev_hidraw.h" +#include "message.h" #include "xbox360.h" +#include typedef enum rc71l_platform_mode { rc71l_platform_mode_hidraw, @@ -99,10 +101,10 @@ int asus_kbd_ev_map( .type = GAMEPAD_SET_ELEMENT, .data = { .gamepad_set = { - .element = GAMEPAD_BTN_L5, - .status = { - .btn = e->ev[1].value, - } + .element = GAMEPAD_BTN_L5, + .status = { + .btn = e->ev[1].value, + } } } }; @@ -166,6 +168,68 @@ int asus_kbd_ev_map( printf("Asus MCU kernel interface found at %s -- switching mode\n", kernel_sysfs); free(kernel_sysfs); + } else if (e->ev[i].code == BTN_LEFT) { + const in_message_t current_message = { + .type = MOUSE_EVENT, + .data = { + .mouse_event = { + .type = MOUSE_BTN_LEFT, + .value = e->ev[i].value, + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == BTN_MIDDLE) { + const in_message_t current_message = { + .type = MOUSE_EVENT, + .data = { + .mouse_event = { + .type = MOUSE_BTN_MIDDLE, + .value = e->ev[i].value, + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == BTN_RIGHT) { + const in_message_t current_message = { + .type = MOUSE_EVENT, + .data = { + .mouse_event = { + .type = MOUSE_BTN_RIGHT, + .value = e->ev[i].value, + } + } + }; + + messages[written_msg++] = current_message; + } + } else if (e->ev[i].type == EV_REL) { + if (e->ev[i].code == REL_X) { + const in_message_t current_message = { + .type = MOUSE_EVENT, + .data = { + .mouse_event = { + .type = MOUSE_ELEMENT_X, + .value = e->ev[i].value, + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == REL_Y) { + const in_message_t current_message = { + .type = MOUSE_EVENT, + .data = { + .mouse_event = { + .type = MOUSE_ELEMENT_Y, + .value = e->ev[i].value, + } + } + }; + + messages[written_msg++] = current_message; } } } diff --git a/virt_mouse.c b/virt_mouse.c new file mode 100644 index 0000000..add0a18 --- /dev/null +++ b/virt_mouse.c @@ -0,0 +1,141 @@ +#include "virt_mouse.h" +#include +#include +#include + +int virt_mouse_init(virt_mouse_t *const mouse) { + int ret = -EINVAL; + + mouse->status_recv = 0; + + int fd = open("/dev/uinput", O_RDWR); + if(fd < 0) { + ret = errno; + goto virt_mouse_init_err; + } + + ioctl(fd, UI_SET_EVBIT, EV_REL); + ioctl(fd, UI_SET_EVBIT, EV_KEY); + ioctl(fd, UI_SET_EVBIT, EV_MSC); + ioctl(fd, UI_SET_EVBIT, EV_SYN); + ioctl(fd, UI_SET_MSCBIT, MSC_TIMESTAMP); + ioctl(fd, UI_SET_KEYBIT, BTN_LEFT); + ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE); + ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT); + ioctl(fd, UI_SET_RELBIT, REL_X); + ioctl(fd, UI_SET_RELBIT, REL_Y); + ioctl(fd, UI_SET_RELBIT, REL_WHEEL); + ioctl(fd, UI_SET_RELBIT, REL_WHEEL_HI_RES); + + struct uinput_setup dev = {0}; + strncpy(dev.name, VIRT_MOUSE_DEV_NAME, UINPUT_MAX_NAME_SIZE-1); + dev.id.bustype = BUS_VIRTUAL; + dev.id.vendor = VIRT_MOUSE_DEV_VENDOR_ID; + dev.id.product = VIRT_MOUSE_DEV_PRODUCT_ID; + dev.id.version = VIRT_MOUSE_DEV_VERSION; + + if(ioctl(fd, UI_DEV_SETUP, &dev) < 0) { + ret = errno > 0 ? errno : -1 * errno; + ret = ret == 0 ? -EIO : ret; + goto virt_mouse_init_err; + } + + if(ioctl(fd, UI_DEV_CREATE) < 0) { + ret = errno > 0 ? errno : -1 * errno; + ret = ret == 0 ? -EIO : ret; + goto virt_mouse_init_err; + } + + // initialization ok + mouse->prev_btn_left = 0; + mouse->prev_btn_right = 0; + mouse->prev_btn_middle = 0; + mouse->fd = fd; + ret = 0; + +virt_mouse_init_err: + if (ret != 0) { + mouse->fd = -1; + close(fd); + } + + return ret; +} + +int virt_mouse_get_fd(virt_mouse_t *const mouse) { + return mouse->fd; +} + +int virt_mouse_send(virt_mouse_t *const mouse, mouse_status_t *const status, struct timeval *const now) { + int res = 0; + + struct input_event tmp_ev; + if (now == NULL) { + gettimeofday(&tmp_ev.time, NULL); + } else { + tmp_ev.time = *now; + } + + tmp_ev.type = EV_REL; + + if (status->x > 0) { + tmp_ev.code = REL_X; + tmp_ev.value = status->x; + if (write(mouse->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_mouse_send_err; + } else { + status->x = 0; + } + } + + if (status->y > 0) { + tmp_ev.code = REL_Y; + tmp_ev.value = status->y; + if (write(mouse->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_mouse_send_err; + } else { + status->y = 0; + } + } + + tmp_ev.type = EV_KEY; + + if (status->btn_left != mouse->prev_btn_left) { + mouse->prev_btn_left = status->btn_left; + tmp_ev.code = BTN_LEFT; + tmp_ev.value = status->btn_left; + if (write(mouse->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_mouse_send_err; + } + } + + if (status->btn_middle != mouse->prev_btn_middle) { + mouse->prev_btn_middle = status->btn_middle; + tmp_ev.code = BTN_MIDDLE; + tmp_ev.value = status->btn_middle; + if (write(mouse->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_mouse_send_err; + } + } + + if (status->btn_right != mouse->prev_btn_right) { + mouse->prev_btn_right = status->btn_right; + tmp_ev.code = BTN_RIGHT; + tmp_ev.value = status->btn_right; + if (write(mouse->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_mouse_send_err; + } + } + +virt_mouse_send_err: + return res; +} + +void virt_mouse_close(virt_mouse_t *const mouse) { + close(mouse->fd); +} \ No newline at end of file diff --git a/virt_mouse.h b/virt_mouse.h new file mode 100644 index 0000000..1ac8da5 --- /dev/null +++ b/virt_mouse.h @@ -0,0 +1,29 @@ +#pragma once + +#include "message.h" +#include "devices_status.h" + +#define VIRT_MOUSE_DEV_NAME "ROGueENEMY - mouse" + +#define VIRT_MOUSE_DEV_VENDOR_ID 0x108c +#define VIRT_MOUSE_DEV_PRODUCT_ID 0x0323 +#define VIRT_MOUSE_DEV_VERSION 0x0111 + +typedef struct virt_mouse { + int fd; + + uint8_t prev_btn_left; + uint8_t prev_btn_right; + uint8_t prev_btn_middle; + + uint64_t status_recv; + +} virt_mouse_t; + +int virt_mouse_init(virt_mouse_t *const mouse); + +int virt_mouse_get_fd(virt_mouse_t *const mouse); + +int virt_mouse_send(virt_mouse_t *const mouse, mouse_status_t *const status, struct timeval *const now); + +void virt_mouse_close(virt_mouse_t *const mouse); \ No newline at end of file From cc16d4983e27d258692485973fd43eb77b0a8262 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 16 Dec 2023 22:26:37 +0100 Subject: [PATCH 022/186] mode switch should work --- rog_ally.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/rog_ally.c b/rog_ally.c index f7ac59e..0c59607 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -4,6 +4,7 @@ #include "message.h" #include "xbox360.h" #include +#include typedef enum rc71l_platform_mode { rc71l_platform_mode_hidraw, @@ -83,7 +84,11 @@ static char* find_kernel_sysfs_device_path(struct udev *udev) { return NULL; } -int asus_kbd_ev_map( +static int get_next_mode(int current_mode) { + return 1 + ((current_mode + 1) % 3); +} + +static int asus_kbd_ev_map( const dev_in_settings_t *const conf, const evdev_collected_t *const e, in_message_t *const messages, @@ -167,6 +172,53 @@ int asus_kbd_ev_map( printf("Asus MCU kernel interface found at %s -- switching mode\n", kernel_sysfs); + const size_t tmp_path_max_len = strlen(kernel_sysfs) + 256; + char *tmp_path = malloc(tmp_path_max_len); + + if (tmp_path != NULL) { + memset(tmp_path, 0, tmp_path_max_len); + snprintf(tmp_path, tmp_path_max_len - 1, "%s/gamepad_mode", kernel_sysfs); + + int gamepad_mode_fd = open(tmp_path, O_RDONLY | O_NONBLOCK); + if (gamepad_mode_fd > 0) { + char current_mode_str[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int current_mode_read_res = read(gamepad_mode_fd, (void*)current_mode_str, sizeof(current_mode_str)); + if (current_mode_read_res > 0) { + int current_mode; + sscanf("%d", current_mode_str, ¤t_mode); + + const int new_mode = get_next_mode(current_mode); + printf("Current mode is set to %d -- switching to %d", current_mode, new_mode); + + // end the current mode read + close(gamepad_mode_fd); + + char new_mode_str[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + snprintf(new_mode_str, sizeof(new_mode_str) - 1, "%d", new_mode); + gamepad_mode_fd = open(tmp_path, O_RDONLY); + if (gamepad_mode_fd > 0) { + if (write(gamepad_mode_fd, new_mode_str, strlen(new_mode_str)) > 0) { + printf("Controller mode switched successfully to %d\n", new_mode); + } else { + fprintf(stderr, "Unable to switch controller mode: %d -- expect bugs\n", errno); + } + close(gamepad_mode_fd); + } else { + fprintf(stderr, "Unable to open gamepad mode file to switch mode: %d\n", errno); + } + } else { + close(gamepad_mode_fd); + fprintf(stderr, "Unable to read gamepad_mode file to get current mode: %d", errno); + } + } else { + fprintf(stderr, "Unable to open gamepad_mode file in read-only mode to get current mode: %d", errno); + } + + free(tmp_path); + } else { + fprintf(stderr, "Unable to allocate enough memory\n"); + } + free(kernel_sysfs); } else if (e->ev[i].code == BTN_LEFT) { const in_message_t current_message = { From 4bdff1a50d96ab2ab54782af8ed104993dd89c85 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 16 Dec 2023 22:35:26 +0100 Subject: [PATCH 023/186] bugfix --- dev_out.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev_out.c b/dev_out.c index 8f121b0..495ce50 100644 --- a/dev_out.c +++ b/dev_out.c @@ -269,6 +269,7 @@ void *dev_out_thread_func(void *ptr) { fprintf(stderr, "Unable to initialize virtual mouse -- will continue regardless\n"); } else { current_mouse_fd = virt_mouse_get_fd(&mouse_data); + printf("Mouse initialized: fd=%d\n", current_mouse_fd); } const int64_t kbd_report_timing_us = 1125; @@ -371,7 +372,7 @@ void *dev_out_thread_func(void *ptr) { } const int64_t timeout_gamepad_time_diff_usecs = gamepad_report_timing_us - gamepad_time_diff_usecs; - const int64_t timeout_mouse_time_diff_usecs = mouse_time_diff_usecs - mouse_report_timing_us; + const int64_t timeout_mouse_time_diff_usecs = mouse_report_timing_us - mouse_time_diff_usecs; const int64_t timeout_kbd_time_diff_usecs = kbd_report_timing_us - kbd_time_diff_usecs; int64_t next_timing_out_device_diff_usecs = timeout_kbd_time_diff_usecs < timeout_mouse_time_diff_usecs ? timeout_kbd_time_diff_usecs : timeout_mouse_time_diff_usecs; From 587fe7ffcf314ea247e3f9a768479fde2ee1769a Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 16 Dec 2023 23:15:04 +0100 Subject: [PATCH 024/186] testing mouse mode and swtich --- dev_out.c | 4 ++++ rog_ally.c | 24 ++++++++++++++++-------- virt_mouse.c | 41 ++++++++++++++++++++++++++++++++--------- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/dev_out.c b/dev_out.c index 495ce50..2e6182d 100644 --- a/dev_out.c +++ b/dev_out.c @@ -332,6 +332,10 @@ void *dev_out_thread_func(void *ptr) { mouse_last_hid_report_sent = now; virt_mouse_send(&mouse_data, &dev_out_data->dev_stats.mouse, &now); + + // reset mouse movements now + dev_out_data->dev_stats.mouse.x = 0; + dev_out_data->dev_stats.mouse.y = 0; // this does reset the for, ensuring every other device has nothing to say continue; diff --git a/rog_ally.c b/rog_ally.c index 0c59607..ea6fc35 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -85,7 +85,16 @@ static char* find_kernel_sysfs_device_path(struct udev *udev) { } static int get_next_mode(int current_mode) { - return 1 + ((current_mode + 1) % 3); + if (current_mode == 1) + return 2; + if (current_mode == 2) + return 3; + if (current_mode == 3) + return 2; + else + fprintf(stderr, "Invalid current mode: %d -- gamepad will be set\n", current_mode); + + return 1; } static int asus_kbd_ev_map( @@ -184,23 +193,22 @@ static int asus_kbd_ev_map( char current_mode_str[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int current_mode_read_res = read(gamepad_mode_fd, (void*)current_mode_str, sizeof(current_mode_str)); if (current_mode_read_res > 0) { + close(gamepad_mode_fd); + int current_mode; sscanf("%d", current_mode_str, ¤t_mode); const int new_mode = get_next_mode(current_mode); - printf("Current mode is set to %d -- switching to %d", current_mode, new_mode); - - // end the current mode read - close(gamepad_mode_fd); + printf("Current mode is set to %d (read from %s) -- switching to %d", current_mode, current_mode_str, new_mode); char new_mode_str[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; snprintf(new_mode_str, sizeof(new_mode_str) - 1, "%d", new_mode); - gamepad_mode_fd = open(tmp_path, O_RDONLY); + gamepad_mode_fd = open(tmp_path, O_WRONLY); if (gamepad_mode_fd > 0) { if (write(gamepad_mode_fd, new_mode_str, strlen(new_mode_str)) > 0) { - printf("Controller mode switched successfully to %d\n", new_mode); + printf("Controller mode switched successfully to %s\n", new_mode_str); } else { - fprintf(stderr, "Unable to switch controller mode: %d -- expect bugs\n", errno); + fprintf(stderr, "Unable to switch controller mode to %s: %d -- expect bugs\n", new_mode_str, errno); } close(gamepad_mode_fd); } else { diff --git a/virt_mouse.c b/virt_mouse.c index add0a18..f09db6c 100644 --- a/virt_mouse.c +++ b/virt_mouse.c @@ -69,34 +69,32 @@ int virt_mouse_get_fd(virt_mouse_t *const mouse) { int virt_mouse_send(virt_mouse_t *const mouse, mouse_status_t *const status, struct timeval *const now) { int res = 0; + struct timeval syn_time; + gettimeofday(&syn_time, NULL); + struct input_event tmp_ev; - if (now == NULL) { - gettimeofday(&tmp_ev.time, NULL); - } else { + gettimeofday(&tmp_ev.time, NULL); + if (now != NULL) { tmp_ev.time = *now; } tmp_ev.type = EV_REL; - if (status->x > 0) { + if (status->x != 0) { tmp_ev.code = REL_X; tmp_ev.value = status->x; if (write(mouse->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { res = errno < 0 ? errno : -1 * errno; goto virt_mouse_send_err; - } else { - status->x = 0; } } - if (status->y > 0) { + if (status->y != 0) { tmp_ev.code = REL_Y; tmp_ev.value = status->y; if (write(mouse->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { res = errno < 0 ? errno : -1 * errno; goto virt_mouse_send_err; - } else { - status->y = 0; } } @@ -132,6 +130,31 @@ int virt_mouse_send(virt_mouse_t *const mouse, mouse_status_t *const status, str } } + #if 0 + const struct input_event timestamp_ev = { + .code = MSC_TIMESTAMP, + .type = EV_MSC, + .value = (now.tv_sec - secAtInit)*1000000 + (now.tv_usec - usecAtInit), + .time = now, + }; + const ssize_t timestamp_written = write(fd, (void*)×tamp_ev, sizeof(timestamp_ev)); + if (timestamp_written != sizeof(timestamp_ev)) { + fprintf(stderr, "Error in sync: written %ld bytes out of %ld\n", timestamp_written, sizeof(timestamp_ev)); + } + #endif + + syn_time.tv_usec += 1; + const struct input_event syn_ev = { + .code = SYN_REPORT, + .type = EV_SYN, + .value = 0, + .time = syn_time, + }; + const ssize_t sync_written = write(mouse->fd, (void*)&syn_ev, sizeof(syn_ev)); + if (sync_written != sizeof(syn_ev)) { + fprintf(stderr, "Error in sync: written %ld bytes out of %ld\n", sync_written, sizeof(syn_ev)); + } + virt_mouse_send_err: return res; } From 5548eb806fc2872a3b2856bac2c67b9e272426bb Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 16 Dec 2023 23:19:32 +0100 Subject: [PATCH 025/186] Improved mode switch --- rog_ally.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index ea6fc35..6fe9c81 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -90,9 +90,9 @@ static int get_next_mode(int current_mode) { if (current_mode == 2) return 3; if (current_mode == 3) - return 2; + return 1; else - fprintf(stderr, "Invalid current mode: %d -- gamepad will be set\n", current_mode); + fprintf(stderr, "Invalid current mode: %d -- 1 (gamepad) will be set\n", current_mode); return 1; } @@ -188,7 +188,7 @@ static int asus_kbd_ev_map( memset(tmp_path, 0, tmp_path_max_len); snprintf(tmp_path, tmp_path_max_len - 1, "%s/gamepad_mode", kernel_sysfs); - int gamepad_mode_fd = open(tmp_path, O_RDONLY | O_NONBLOCK); + int gamepad_mode_fd = open(tmp_path, O_RDONLY); if (gamepad_mode_fd > 0) { char current_mode_str[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int current_mode_read_res = read(gamepad_mode_fd, (void*)current_mode_str, sizeof(current_mode_str)); From 00cc6adf7d8c5a5c6835d4d0927ff3108690bb19 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 16 Dec 2023 23:33:19 +0100 Subject: [PATCH 026/186] whoopsie... --- rog_ally.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rog_ally.c b/rog_ally.c index 6fe9c81..87ac317 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -196,7 +196,7 @@ static int asus_kbd_ev_map( close(gamepad_mode_fd); int current_mode; - sscanf("%d", current_mode_str, ¤t_mode); + sscanf(current_mode_str, "%d", ¤t_mode); const int new_mode = get_next_mode(current_mode); printf("Current mode is set to %d (read from %s) -- switching to %d", current_mode, current_mode_str, new_mode); From f9f5b67690c4f89b53b8ed16c68bd7dc35d62906 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 00:05:09 +0100 Subject: [PATCH 027/186] use hidraw dev to change leds --- dev_in.c | 23 +++++-- input_dev.h | 10 ++-- legion_go.c | 4 +- rog_ally.c | 170 ++++++++++++++++++++++++---------------------------- 4 files changed, 103 insertions(+), 104 deletions(-) diff --git a/dev_in.c b/dev_in.c index 6b62f22..8db5a0c 100644 --- a/dev_in.c +++ b/dev_in.c @@ -23,6 +23,8 @@ typedef struct dev_in_iio { typedef struct dev_in_hidraw { dev_hidraw_t *hidrawdev; + + hidraw_callbacks_t callbacks; } dev_in_hidraw_t; typedef struct dev_in_ev { @@ -266,7 +268,7 @@ static void hidraw_close_device(dev_in_hidraw_t *const out_hidraw) { dev_hidraw_close(out_hidraw->hidrawdev); } -static void handle_rumble_device(dev_in_ev_t *const in_dev, const out_message_rumble_t *const in_rumble_msg) { +static void handle_rumble_device(const dev_in_settings_t *const conf, dev_in_ev_t *const in_dev, const out_message_rumble_t *const in_rumble_msg) { if (!in_dev->has_rumble_support) { return; } @@ -315,10 +317,18 @@ static void handle_rumble_device(dev_in_ev_t *const in_dev, const out_message_ru } } -static void handle_rumble(dev_in_t *const in_devs, size_t in_devs_count, const out_message_rumble_t *const in_rumble_msg) { +static void handle_rumble(const dev_in_settings_t *const conf, dev_in_t *const in_devs, size_t in_devs_count, const out_message_rumble_t *const in_rumble_msg) { for (size_t i = 0; i < in_devs_count; ++i) { if (in_devs[i].type == DEV_IN_TYPE_EV) { - handle_rumble_device(&in_devs[i].dev.evdev, in_rumble_msg); + handle_rumble_device(conf, &in_devs[i].dev.evdev, in_rumble_msg); + } + } +} + +static void handle_leds(const dev_in_settings_t *const conf, dev_in_t *const in_devs, size_t in_devs_count, const out_message_leds_t *const in_rumble_msg) { + for (size_t i = 0; i < in_devs_count; ++i) { + if (in_devs[i].type == DEV_IN_TYPE_HIDRAW) { + } } } @@ -443,6 +453,7 @@ void* dev_in_thread_func(void *ptr) { &devices[i].dev.hidraw ); if (open_res == 0) { + devices[i].dev.hidraw.callbacks = dev_in_data->input_dev_decl->dev[i]->map.hidraw_callbacks; devices[i].type = DEV_IN_TYPE_HIDRAW; } } @@ -473,7 +484,7 @@ void* dev_in_thread_func(void *ptr) { const ssize_t out_message_pipe_read_res = read(out_message_fd, (void*)&out_msg, sizeof(out_message_t)); if (out_message_pipe_read_res == sizeof(out_message_t)) { if (out_msg.type == OUT_MSG_TYPE_RUMBLE) { - handle_rumble(devices, max_devices, &out_msg.data.rumble); + handle_rumble(&dev_in_data->settings, devices, max_devices, &out_msg.data.rumble); } else if (out_msg.type == OUT_MSG_TYPE_LEDS) { // first inform the platform const int platform_leds_res = dev_in_data->input_dev_decl->leds_fn( @@ -485,7 +496,7 @@ void* dev_in_thread_func(void *ptr) { fprintf(stderr, "Error in changing platform LEDs: %d\n", platform_leds_res); } - // TODO: handle_leds() + handle_leds(&dev_in_data->settings, devices, max_devices, &out_msg.data.leds); } } else { fprintf(stderr, "Error reading from out_message_pipe_fd: got %zu bytes, expected %zu bytes\n", out_message_pipe_read_res, sizeof(out_message_t)); @@ -553,7 +564,7 @@ void* dev_in_thread_func(void *ptr) { continue; } } else if (devices[i].type == DEV_IN_TYPE_HIDRAW) { - controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.hidraw_input_map_fn( + controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.hidraw_callbacks.map_callback( &dev_in_data->settings, dev_hidraw_get_fd(devices[i].dev.hidraw.hidrawdev), &controller_msg[0], diff --git a/input_dev.h b/input_dev.h index e647197..377c689 100644 --- a/input_dev.h +++ b/input_dev.h @@ -19,7 +19,6 @@ typedef struct evdev_collected { * constructed from that data. */ typedef int (*ev_map)(const dev_in_settings_t *const conf, const evdev_collected_t *const e, in_message_t *const messages, size_t messages_len, void* user_data); -typedef int (*hidraw_map)(const dev_in_settings_t *const conf, int hidraw_fd, in_message_t *const messages, size_t messages_len, void* user_data); typedef enum input_dev_type { input_dev_type_uinput, @@ -41,13 +40,14 @@ typedef struct iio_filters { const char name[256]; } iio_filters_t; -typedef int (*hidraw_set_leds)(uint8_t r, uint8_t g, uint8_t b, void* user_data); - -typedef int (*hidraw_rumble)(uint8_t left_motor, uint8_t right_motor, void* user_data); +typedef int (*hidraw_map)(const dev_in_settings_t *const conf, int hidraw_fd, in_message_t *const messages, size_t messages_len, void* user_data); +typedef int (*hidraw_set_leds)(const dev_in_settings_t *const conf, int hidraw_fd, uint8_t r, uint8_t g, uint8_t b, void* user_data); +typedef int (*hidraw_rumble)(const dev_in_settings_t *const conf, int hidraw_fd, uint8_t left_motor, uint8_t right_motor, void* user_data); typedef struct hidraw_callbacks { hidraw_set_leds leds_callback; hidraw_rumble rumble_callback; + hidraw_map map_callback; } hidraw_callbacks_t; typedef struct iio_settings { @@ -69,7 +69,7 @@ typedef struct input_dev { union input_dev_map { iio_settings_t iio_settings; ev_map ev_input_map_fn; - hidraw_map hidraw_input_map_fn; + hidraw_callbacks_t hidraw_callbacks; } map; } input_dev_t; diff --git a/legion_go.c b/legion_go.c index 9852643..6f15eb0 100644 --- a/legion_go.c +++ b/legion_go.c @@ -82,7 +82,9 @@ static input_dev_t in_hidraw_dev = { }, .user_data = (void*)&llg_hidraw_user_data, .map = { - .hidraw_input_map_fn = llg_hidraw_map, + .hidraw_callbacks = { + .map_callback = llg_hidraw_map, + } }, }; diff --git a/rog_ally.c b/rog_ally.c index 87ac317..8b201aa 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -6,6 +6,26 @@ #include #include +enum rc71l_leds_mode { + ROG_ALLY_MODE_STATIC = 0, + ROG_ALLY_MODE_BREATHING = 1, + ROG_ALLY_MODE_COLOR_CYCLE = 2, + ROG_ALLY_MODE_RAINBOW = 3, + ROG_ALLY_MODE_STROBING = 10, + ROG_ALLY_MODE_DIRECT = 0xFF, +} rc71l_leds_mode_t; + +enum rc71l_leds_speed { + ROG_ALLY_SPEED_MIN = 0xE1, + ROG_ALLY_SPEED_MED = 0xEB, + ROG_ALLY_SPEED_MAX = 0xF5 +} rc71l_leds_speed_t; + +enum rc71l_leds_direction { + ROG_ALLY_DIRECTION_RIGHT = 0x00, + ROG_ALLY_DIRECTION_LEFT = 0x01 +} rc71l_leds_direction_t; + typedef enum rc71l_platform_mode { rc71l_platform_mode_hidraw, rc71l_platform_mode_linux_and_asusctl, @@ -297,12 +317,6 @@ static int asus_kbd_ev_map( return written_msg; } -static hidraw_filters_t n_key_hidraw_filters = { - .pid = 0x1abe, - .vid = 0x0b05, - .rdesc_size = 167, // 48 83 167 -}; - static input_dev_t in_iio_dev = { .dev_type = input_dev_type_iio, .filters = { @@ -385,25 +399,63 @@ static input_dev_t in_xbox_dev = { } }; -enum rc71l_leds_mode { - ROG_ALLY_MODE_STATIC = 0, - ROG_ALLY_MODE_BREATHING = 1, - ROG_ALLY_MODE_COLOR_CYCLE = 2, - ROG_ALLY_MODE_RAINBOW = 3, - ROG_ALLY_MODE_STROBING = 10, - ROG_ALLY_MODE_DIRECT = 0xFF, -} rc71l_leds_mode_t; +static int rc71l_hidraw_map(const dev_in_settings_t *const conf, int hidraw_fd, in_message_t *const messages, size_t messages_len, void* user_data) { + return 0; +} -enum rc71l_leds_speed { - ROG_ALLY_SPEED_MIN = 0xE1, - ROG_ALLY_SPEED_MED = 0xEB, - ROG_ALLY_SPEED_MAX = 0xF5 -} rc71l_leds_speed_t; +static int rc71l_hidraw_rumble(const dev_in_settings_t *const conf, int hidraw_fd, uint8_t left_motor, uint8_t right_motor, void* user_data) { + return 0; +} -enum rc71l_leds_direction { - ROG_ALLY_DIRECTION_RIGHT = 0x00, - ROG_ALLY_DIRECTION_LEFT = 0x01 -} rc71l_leds_direction_t; +static int rc71l_hidraw_set_leds(const dev_in_settings_t *const conf, int hidraw_fd, uint8_t r, uint8_t g, uint8_t b, void* user_data) { + const uint8_t brightness_buf[] = { + 0x5A, 0xBA, 0xC5, 0xC4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + const uint8_t colors_buf[] = { + 0x5A, 0xB3, 0x00, ROG_ALLY_MODE_STATIC, r, g, b, 0x00, ROG_ALLY_DIRECTION_RIGHT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + if (write(hidraw_fd, brightness_buf, sizeof(brightness_buf)) != 64) { + fprintf(stderr, "Unable to send LEDs brightness (1) command change: %d\n", errno); + goto rc71l_hidraw_set_leds_err; + } + + if (write(hidraw_fd, colors_buf, sizeof(colors_buf)) != 64) { + fprintf(stderr, "Unable to send LEDs color command change (1)\n"); + goto rc71l_hidraw_set_leds_err; + } + + return 0; + +rc71l_hidraw_set_leds_err: + return -EIO; +} + +static input_dev_t nkey_dev = { + .dev_type = input_dev_type_hidraw, + .filters = { + .hidraw = { + .pid = 0x1abe, + .vid = 0x0b05, + .rdesc_size = 167, // 48 83 167 + } + }, + .user_data = NULL, + .map = { + .hidraw_callbacks = { + .leds_callback = rc71l_hidraw_set_leds, + .rumble_callback = rc71l_hidraw_rumble, + .map_callback = rc71l_hidraw_map, + } + } +}; static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platform_data) { int res = -EINVAL; @@ -420,22 +472,6 @@ static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platf // setup asus keyboard(s) user_data asus_userdata.udev = udev_new(); - res = dev_hidraw_open(&n_key_hidraw_filters, &platform->platform.hidraw); - if (res != 0) { - fprintf(stderr, "Unable to open the ROG ally hidraw main device...\n"); - free(*platform_data); - *platform_data = NULL; - goto rc71l_platform_init_err; - } - - platform->platform_mode = rc71l_platform_mode_hidraw; - - const int fd = dev_hidraw_get_fd(platform->platform.hidraw); - - platform->mode = 0; - platform->modes_count = 2; - printf("ROG Ally platform will be managed over hidraw. I'm sorry fluke.\n"); - rc71l_platform_init_err: return res; } @@ -454,58 +490,7 @@ static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** pl } static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, uint8_t g, uint8_t b, void* platform_data) { - rc71l_platform_t *const platform = (rc71l_platform_t *)platform_data; - if (platform == NULL) { - return -EINVAL; - } - - const uint8_t brightness_buf[] = { - 0x5A, 0xBA, 0xC5, 0xC4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - uint8_t colors_buf[] = { - 0x5A, 0xB3, 0x00, ROG_ALLY_MODE_STATIC, r, g, b, 0x00, ROG_ALLY_DIRECTION_RIGHT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - if ((platform->platform_mode == rc71l_platform_mode_hidraw) && (platform->platform.hidraw != NULL)) { - int fd = dev_hidraw_get_fd(platform->platform.hidraw); - - if (write(fd, brightness_buf, sizeof(brightness_buf)) != 64) { - fprintf(stderr, "Unable to send LEDs brightness (1) command change -- attempt to reacquire hidraw\n"); - - dev_hidraw_close(platform->platform.hidraw); - - const int reopen_res = dev_hidraw_open(&n_key_hidraw_filters, &platform->platform.hidraw); - if (reopen_res != 0) { - fprintf(stderr, "Unable to (re)open the ROG ally hidraw main device...\n"); - goto rc71l_platform_leds_err; - } else { - printf("ROG ally hidraw main device reacquired\n"); - fd = dev_hidraw_get_fd(platform->platform.hidraw); - - if (write(fd, brightness_buf, sizeof(brightness_buf)) != 64) { - fprintf(stderr, "Unable to send LEDs brightness (1) command change after hidraw reset -- giving up\n"); - goto rc71l_platform_leds_err; - } - } - } - - if (write(fd, colors_buf, sizeof(colors_buf)) != 64) { - fprintf(stderr, "Unable to send LEDs color command change (1)\n"); - goto rc71l_platform_leds_err; - } - - return 0; - } - -rc71l_platform_leds_err: - return -EINVAL; + return 0; } input_dev_composite_t rc71l_composite = { @@ -515,8 +500,9 @@ input_dev_composite_t rc71l_composite = { &in_asus_kb_1_dev, &in_asus_kb_2_dev, &in_asus_kb_3_dev, + &nkey_dev, }, - .dev_count = 5, + .dev_count = 6, .init_fn = rc71l_platform_init, .deinit_fn = rc71l_platform_deinit, .leds_fn = rc71l_platform_leds, From 5e3a1e4e985c2e4511232b545b7708598e489e4f Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 00:11:45 +0100 Subject: [PATCH 028/186] whoopsie --- dev_in.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/dev_in.c b/dev_in.c index 8db5a0c..c4104e1 100644 --- a/dev_in.c +++ b/dev_in.c @@ -25,6 +25,8 @@ typedef struct dev_in_hidraw { dev_hidraw_t *hidrawdev; hidraw_callbacks_t callbacks; + + void* user_data; } dev_in_hidraw_t; typedef struct dev_in_ev { @@ -320,15 +322,26 @@ static void handle_rumble_device(const dev_in_settings_t *const conf, dev_in_ev_ static void handle_rumble(const dev_in_settings_t *const conf, dev_in_t *const in_devs, size_t in_devs_count, const out_message_rumble_t *const in_rumble_msg) { for (size_t i = 0; i < in_devs_count; ++i) { if (in_devs[i].type == DEV_IN_TYPE_EV) { - handle_rumble_device(conf, &in_devs[i].dev.evdev, in_rumble_msg); + handle_rumble_device( + conf, + &in_devs[i].dev.evdev, + in_rumble_msg + ); } } } -static void handle_leds(const dev_in_settings_t *const conf, dev_in_t *const in_devs, size_t in_devs_count, const out_message_leds_t *const in_rumble_msg) { +static void handle_leds(const dev_in_settings_t *const conf, dev_in_t *const in_devs, size_t in_devs_count, const out_message_leds_t *const in_leds_msg) { for (size_t i = 0; i < in_devs_count; ++i) { if (in_devs[i].type == DEV_IN_TYPE_HIDRAW) { - + in_devs[i].dev.hidraw.callbacks.leds_callback( + conf, + in_devs[i].dev.hidraw.hidrawdev->fd, + in_leds_msg->r, + in_leds_msg->g, + in_leds_msg->b, + in_devs[i].dev.hidraw.user_data + ); } } } @@ -435,25 +448,28 @@ void* dev_in_thread_func(void *ptr) { } } else if (d_type == input_dev_type_iio) { fprintf(stderr, "Device (iio) %zu not found -- Attempt reconnection for device named %s\n", i, dev_in_data->input_dev_decl->dev[i]->filters.iio.name); - + const int open_res = iio_open_device( &dev_in_data->settings, &dev_in_data->input_dev_decl->dev[i]->filters.iio, &devices[i].dev.iio ); + if (open_res == 0) { devices[i].type = DEV_IN_TYPE_IIO; } } else if (d_type == input_dev_type_hidraw) { fprintf(stderr, "Device (hidraw) %zu not found -- Attempt reconnection for device %x:%x\n", i, dev_in_data->input_dev_decl->dev[i]->filters.hidraw.pid, dev_in_data->input_dev_decl->dev[i]->filters.hidraw.vid); - + const int open_res = hidraw_open_device( &dev_in_data->settings, &dev_in_data->input_dev_decl->dev[i]->filters.hidraw, &devices[i].dev.hidraw ); + if (open_res == 0) { devices[i].dev.hidraw.callbacks = dev_in_data->input_dev_decl->dev[i]->map.hidraw_callbacks; + devices[i].dev.hidraw.user_data = dev_in_data->input_dev_decl->dev[i]->user_data; devices[i].type = DEV_IN_TYPE_HIDRAW; } } From 046f635de6d19aacd19f945a8efe21ebff36b6e2 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 00:35:23 +0100 Subject: [PATCH 029/186] Removed useless files --- platform.c | 276 ----------------------------------------------------- platform.h | 23 ----- 2 files changed, 299 deletions(-) delete mode 100644 platform.c delete mode 100644 platform.h diff --git a/platform.c b/platform.c deleted file mode 100644 index dee1d51..0000000 --- a/platform.c +++ /dev/null @@ -1,276 +0,0 @@ -#include -#include -#include - -#include - -#include "platform.h" - -static const char* const platform_input_path = "/sys/devices/platform/asus-mcu.0/input/mode"; - -static int hidraw_cycle_to_mode(const char* const path, int controller_mode) { - int res = 0; - - if ((controller_mode < 0) || (controller_mode > 2)) { - res = -EINVAL; - goto hidraw_cycle_to_mode_err_mode; - } - - const char* hidraw_subdir = "/hidraw/"; - - const unsigned long len = strlen(path) + strlen(hidraw_subdir) + 64; - char* hidraw_path = malloc(len + 1); - if (hidraw_path == NULL) { - res = -ENOMEM; - goto hidraw_cycle_to_mode_err_path; - } - - memset(hidraw_path, 0, len + 1); - strcat(hidraw_path, path); - strcat(hidraw_path, hidraw_subdir); - - DIR *d; - struct dirent *dir; - d = opendir(hidraw_path); - if (d) { - while ((dir = readdir(d)) != NULL) { - if (strstr(dir->d_name, "hidraw") == NULL) { // h as in hidraw - continue; - } - - memset(hidraw_path, 0, len + 1); - strcat(hidraw_path, "/dev/"); - strcat(hidraw_path, dir->d_name); - - //strcat(hidraw_path, dir->d_name); - //strcat(hidraw_path, "/dev"); - - printf("Using hidraw located at: %s\n", hidraw_path); - - int fd = open(hidraw_path, O_RDWR); - if (fd == -1) { - fprintf(stderr, "Error opening hidraw device %s\n", hidraw_path); - - res = -EIO; - - goto hidraw_cycle_to_mode_err; - } - - for (int i = 0; i < 23; ++i) { - const int write_res = write(fd, &rc71l_mode_switch_commands[controller_mode][i][0], 64); - if (write_res != 64) { - fprintf(stderr, "Error writing packet %d/23: %d bytes sent, 64 expected\n", i, write_res); - break; - } - } - - close(fd); - - if (res == 0) { - printf("Control messages sent successfully.\n"); - } else { - goto hidraw_cycle_to_mode_err; - } - - } - } - - - -hidraw_cycle_to_mode_err: - free(hidraw_path); - -hidraw_cycle_to_mode_err_path: -hidraw_cycle_to_mode_err_mode: - return res; -} - -static char* find_device(struct udev *udev) { - struct udev_enumerate *const enumerate = udev_enumerate_new(udev); - if (enumerate == NULL) { - fprintf(stderr, "Error in udev_enumerate_new: mode switch will not be available.\n"); - return NULL; - } - - const int add_match_subsystem_res = udev_enumerate_add_match_subsystem(enumerate, "hid"); - if (add_match_subsystem_res != 0) { - fprintf(stderr, "Error in udev_enumerate_add_match_subsystem: %d\n", add_match_subsystem_res); - - udev_enumerate_unref(enumerate); - - return NULL; - } - - const int add_match_sysattr_res = udev_enumerate_add_match_sysattr(enumerate, "gamepad_mode", NULL); - if (add_match_sysattr_res != 0) { - fprintf(stderr, "Error in udev_enumerate_add_match_sysattr: %d\n", add_match_sysattr_res); - - udev_enumerate_unref(enumerate); - - return NULL; - } - - const int enumerate_scan_devices_res = udev_enumerate_scan_devices(enumerate); - if (enumerate_scan_devices_res != 0) { - fprintf(stderr, "Error in udev_enumerate_scan_devices: %d\n", enumerate_scan_devices_res); - - udev_enumerate_unref(enumerate); - - return NULL; - } - - struct udev_list_entry *const udev_lst_frst = udev_enumerate_get_list_entry(enumerate); - - struct udev_list_entry *list_entry = NULL; - udev_list_entry_foreach(list_entry, udev_lst_frst) { - const char* const name = udev_list_entry_get_name(list_entry); - - const unsigned long len = strlen(name) + 1; - char *const result = malloc(len); - memset(result, 0, len); - strncat(result, name, len - 1); - - udev_enumerate_unref(enumerate); - - return result; - } - - udev_enumerate_unref(enumerate); - return NULL; -} - -int init_platform(rc71l_platform_t *const platform) { - platform->udev = NULL; - - if (access(platform_input_path, F_OK) != 0) { - fprintf(stderr, "Unable to find the MCU platform mode file %s: asus-mcu not found.\n", platform_input_path); - - /* create udev object */ - platform->udev = udev_new(); - if (platform->udev == NULL) { - fprintf(stderr, "Cannot create udev context: mode switch will not be available.\n"); - platform->mode = -1; - return -ENOENT; - } - - char *const dev_name = find_device(platform->udev); - if (dev_name == NULL) { - fprintf(stderr, "Cannot locate asus-mcu device: mode switch will not be available.\n"); - platform->mode = -1; - return -ENOENT; - } else { - printf("Asus MCU over hidraw: %s -- mode will be reset\n", dev_name); - - platform->platform_mode = rc71l_platform_mode_hidraw; - platform->modes_count = 2; - platform->mode = 0; - - // reset to mode 0: game mode - const int reset_res = hidraw_cycle_to_mode(dev_name, 0); - if (reset_res != 0) { - fprintf(stderr, "Unable to reset Asus MCU over hidraw: %d -- Asus MCU will be unavailable.\n", reset_res); - - free(dev_name); - - return -EIO; - } - - // find_device does malloc - free(dev_name); - - return 0; - } - - return -ENOENT; - } - - FILE* mode_file = fopen(platform_input_path, "r"); - if (mode_file == NULL) { - fprintf(stderr, "Unable to open the MCU platform mode file %s: modes cannot be switched.\n", platform_input_path); - platform->mode = -1; - return -EINVAL; - } - - char mode_str[12]; - unsigned long read_bytes = fread((void*)&mode_str[0], 1, sizeof(mode_str), mode_file); - if (read_bytes < 1) { - fprintf(stderr, "Unable to read the MCU platform mode file %s: no bytes.\n", platform_input_path); - fclose(mode_file); - platform->mode = -1; - return -EINVAL; - } - - platform->mode = strtoul(&mode_str[0], NULL, 10); - - fclose(mode_file); - - printf("Asus MCU platform found: current mode %lu\n", platform->mode); - platform->modes_count = 2; - - platform->platform_mode = rc71l_platform_mode_asus_mcu; - - return 0; -} - -int cycle_mode(rc71l_platform_t *const platform) { - if (platform == NULL) { - return -ENOENT; - } - - char new_mode_str[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 - }; - - unsigned long new_mode = (platform->mode + 1) % platform->modes_count; - sprintf(new_mode_str, "%lu\n", new_mode); - - if (platform->platform_mode == rc71l_platform_mode_hidraw) { - char *const dev_name = find_device(platform->udev); - if (dev_name == NULL) { - fprintf(stderr, "Unable to locate Asus MCU hidraw to mode-switch. Mode will not be switched.\n"); - return -ENOENT; - } - - const int next_mode = (platform->mode + 1) % platform->modes_count; - - const int reset_res = hidraw_cycle_to_mode(dev_name, next_mode); - if (reset_res != 0) { - fprintf(stderr, "Unable to change mode of Asus MCU over hidraw: %d.\n", reset_res); - } - - free(dev_name); - - platform->mode = next_mode; - - printf("Used hidraw to switch Asus MCU to mode %lu\n", platform->mode); - - return reset_res; - } else if (platform->platform_mode == rc71l_platform_mode_asus_mcu) { - FILE* mode_file = fopen(platform_input_path, "w"); - if (mode_file == NULL) { - fprintf(stderr, "Unable to open the MCU platform mode file %s: modes cannot be switched.\n", platform_input_path); - return -1; - } - - size_t len = strlen(new_mode_str); - const int write_bytes = fwrite((void*)&new_mode_str[0], 1, len, mode_file); - if (write_bytes < len) { - fprintf(stderr, "Error writing new mode: expected to write %d bytes, %d written.\n", (int)len, (int)write_bytes); - return -EIO; - } - - platform->mode = new_mode; - - printf("Used asus-mcu to switch Asus MCU to mode %lu\n", platform->mode); - - fclose(mode_file); - } - - return -ENOENT; -} - -int is_mouse_mode(rc71l_platform_t *const platform) { - return platform != NULL ? platform->mode == 1 : 0; -} diff --git a/platform.h b/platform.h deleted file mode 100644 index 26cbf0f..0000000 --- a/platform.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "rogue_enemy.h" - -typedef enum rc71l_platform_mode { - rc71l_platform_mode_hidraw, - rc71l_platform_mode_asus_mcu, -} rc71l_platform_mode_t; - -typedef struct rc71l_platform { - struct udev *udev; - - rc71l_platform_mode_t platform_mode; - - unsigned long mode; - unsigned int modes_count; -} rc71l_platform_t; - -int init_platform(rc71l_platform_t *const platform); - -int cycle_mode(rc71l_platform_t *const platform); - -int is_mouse_mode(rc71l_platform_t *const platform); From c6ecb53bd38705058dcaef3b419addbe3b5d5a77 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 01:38:06 +0100 Subject: [PATCH 030/186] chatgpt blatantly refused to write this so I had to do it myself. --- CMakeLists.txt | 2 + dev_out.c | 27 ++- devices_status.c | 42 +++++ devices_status.h | 7 + message.h | 50 ++++- virt_kbd.c | 474 +++++++++++++++++++++++++++++++++++++++++++++++ virt_kbd.h | 62 +++++++ virt_mouse.c | 3 - virt_mouse.h | 1 - 9 files changed, 661 insertions(+), 7 deletions(-) create mode 100644 virt_kbd.c create mode 100644 virt_kbd.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 30e3c1c..515d8aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ add_executable(${STRAY_EXECUTABLE_NAME} virt_ds4.c virt_ds5.c virt_mouse.c + virt_kbd.c devices_status.c ) @@ -46,6 +47,7 @@ add_executable(${ALLINONE_EXECUTABLE_NAME} virt_ds4.c virt_ds5.c virt_mouse.c + virt_kbd.c devices_status.c dev_evdev.c dev_iio.c diff --git a/dev_out.c b/dev_out.c index 2e6182d..dfdd322 100644 --- a/dev_out.c +++ b/dev_out.c @@ -6,6 +6,7 @@ #include "virt_ds4.h" #include "virt_ds5.h" #include "virt_mouse.h" +#include "virt_kbd.h" #include @@ -272,6 +273,15 @@ void *dev_out_thread_func(void *ptr) { printf("Mouse initialized: fd=%d\n", current_mouse_fd); } + virt_kbd_t keyboard_data; + const int kbd_init_res = virt_kbd_init(&keyboard_data); + if (kbd_init_res < 0) { + fprintf(stderr, "Unable to initialize virtual keyboard -- will continue regardless\n"); + } else { + current_keyboard_fd = virt_kbd_get_fd(&keyboard_data); + printf("Keyboard initialized: fd=%d\n", current_keyboard_fd); + } + const int64_t kbd_report_timing_us = 1125; const int64_t mouse_report_timing_us = 950; const int64_t gamepad_report_timing_us = 1250; @@ -342,6 +352,8 @@ void *dev_out_thread_func(void *ptr) { } else if (kbd_time_diff_usecs >= kbd_report_timing_us) { keyboard_last_hid_report_sent = now; + virt_kbd_send(&keyboard_data, &dev_out_data->dev_stats.kbd, &now); + // this does reset the for, ensuring every other device has nothing to say continue; } @@ -369,7 +381,9 @@ void *dev_out_thread_func(void *ptr) { FD_SET(current_mouse_fd, &read_fds); } - // TODO: FD_SET(current_keyboard_fd, &read_fds); + if (current_mouse_fd > 0) { + FD_SET(current_keyboard_fd, &read_fds); + } if (current_gamepad_fd > 0) { FD_SET(current_gamepad_fd, &read_fds); @@ -472,6 +486,14 @@ void *dev_out_thread_func(void *ptr) { } } + if ((current_keyboard_fd > 0) && (FD_ISSET(current_keyboard_fd, &read_fds))) { + // TODO: read keyboard events + } + + if ((current_mouse_fd > 0) && (FD_ISSET(current_mouse_fd, &read_fds))) { + // TODO: read mouse events + } + // read and handle incoming data: this data is packed into in_message_t if (dev_out_data->communication.type == ipc_unix_pipe) { if (FD_ISSET(dev_out_data->communication.endpoint.pipe.in_message_pipe_fd, &read_fds)) { @@ -523,6 +545,9 @@ void *dev_out_thread_func(void *ptr) { // close the mouse device virt_mouse_close(&mouse_data); + // close the keyboard device + virt_kbd_close(&keyboard_data); + // end communication if (dev_out_data->communication.type == ipc_server_sockets) { // close every client socket diff --git a/devices_status.c b/devices_status.c index 14e38c8..03ee44e 100644 --- a/devices_status.c +++ b/devices_status.c @@ -1,7 +1,48 @@ #include "devices_status.h" +#include void kbd_status_init(keyboard_status_t *const stats) { stats->connected = true; + + stats->q = 0; + stats->w = 0; + stats->e = 0; + stats->r = 0; + stats->t = 0; + stats->y = 0; + stats->u = 0; + stats->i = 0; + stats->o = 0; + stats->p = 0; + stats->a = 0; + stats->s = 0; + stats->d = 0; + stats->f = 0; + stats->g = 0; + stats->h = 0; + stats->j = 0; + stats->k = 0; + stats->l = 0; + stats->z = 0; + stats->x = 0; + stats->c = 0; + stats->v = 0; + stats->b = 0; + stats->n = 0; + stats->m = 0; + + stats->num_1 = 0; + stats->num_2 = 0; + stats->num_3 = 0; + stats->num_4 = 0; + stats->num_5 = 0; + stats->num_6 = 0; + stats->num_7 = 0; + stats->num_8 = 0; + stats->num_9 = 0; + stats->num_0 = 0; + + stats->lctrl = 0; } void mouse_status_init(mouse_status_t *const stats) { @@ -53,6 +94,7 @@ void gamepad_status_init(gamepad_status_t *const stats) { } void devices_status_init(devices_status_t *const stats) { + pthread_mutex_init(&stats->mutex, NULL); gamepad_status_init(&stats->gamepad); kbd_status_init(&stats->kbd); mouse_status_init(&stats->mouse); diff --git a/devices_status.h b/devices_status.h index 869e7a7..4a61186 100644 --- a/devices_status.h +++ b/devices_status.h @@ -67,6 +67,13 @@ typedef struct gamepad_status { typedef struct keyboard_status { bool connected; + + uint8_t q,w,e,r,t,y,u,i,o,p,a,s,d,f,g,h,j,k,l,z,x,c,v,b,n,m; + + uint8_t num_1, num_2, num_3, num_4, num_5, num_6, num_7, num_8, num_9, num_0; + + uint8_t lctrl; + } keyboard_status_t; diff --git a/message.h b/message.h index 372c124..b7a5391 100644 --- a/message.h +++ b/message.h @@ -82,23 +82,69 @@ typedef enum in_message_gamepad_action { GAMEPAD_ACTION_OPEN_STEAM_QAM, } in_message_gamepad_action_t; +typedef enum kbd_element { + KEYBOARD_KEY_Q, + KEYBOARD_KEY_W, + KEYBOARD_KEY_E, + KEYBOARD_KEY_R, + KEYBOARD_KEY_T, + KEYBOARD_KEY_Y, + KEYBOARD_KEY_U, + KEYBOARD_KEY_I, + KEYBOARD_KEY_O, + KEYBOARD_KEY_P, + KEYBOARD_KEY_A, + KEYBOARD_KEY_S, + KEYBOARD_KEY_D, + KEYBOARD_KEY_F, + KEYBOARD_KEY_G, + KEYBOARD_KEY_H, + KEYBOARD_KEY_J, + KEYBOARD_KEY_K, + KEYBOARD_KEY_L, + KEYBOARD_KEY_Z, + KEYBOARD_KEY_X, + KEYBOARD_KEY_C, + KEYBOARD_KEY_V, + KEYBOARD_KEY_B, + KEYBOARD_KEY_N, + KEYBOARD_KEY_M, + KEYBOARD_KEY_NUM_1, + KEYBOARD_KEY_NUM_2, + KEYBOARD_KEY_NUM_3, + KEYBOARD_KEY_NUM_4, + KEYBOARD_KEY_NUM_5, + KEYBOARD_KEY_NUM_6, + KEYBOARD_KEY_NUM_7, + KEYBOARD_KEY_NUM_8, + KEYBOARD_KEY_NUM_9, + KEYBOARD_KEY_NUM_0, + KEYBOARD_KEY_LCRTL, +} kbd_element_t; + +typedef struct in_message_keyboard_set_element { + kbd_element_t type; + uint8_t value; +} in_message_keyboard_set_element_t; + typedef enum in_in_message_type { GAMEPAD_SET_ELEMENT, GAMEPAD_ACTION, MOUSE_EVENT, + KEYBOARD_SET_ELEMENT, } in_message_type_t; typedef struct in_message { in_message_type_t type; union { - //imu_in_message_t imu; - in_message_gamepad_action_t action; in_message_gamepad_set_element_t gamepad_set; in_message_mouse_event_t mouse_event; + + in_message_keyboard_set_element_t kbd_set; } data; } in_message_t; diff --git a/virt_kbd.c b/virt_kbd.c new file mode 100644 index 0000000..c9aec1c --- /dev/null +++ b/virt_kbd.c @@ -0,0 +1,474 @@ +#include "virt_kbd.h" +#include "message.h" +#include + +int virt_kbd_init(virt_kbd_t *const kbd) { + int ret = -EINVAL; + + memset(kbd, 0, sizeof(virt_kbd_t)); + + int fd = open("/dev/uinput", O_RDWR); + if(fd < 0) { + ret = errno; + goto virt_mouse_init_err; + } + + ioctl(fd, UI_SET_EVBIT, EV_REL); + ioctl(fd, UI_SET_EVBIT, EV_KEY); + ioctl(fd, UI_SET_EVBIT, EV_MSC); + ioctl(fd, UI_SET_EVBIT, EV_SYN); + ioctl(fd, UI_SET_MSCBIT, MSC_TIMESTAMP); + ioctl(fd, UI_SET_KEYBIT, KEY_Q); + ioctl(fd, UI_SET_KEYBIT, KEY_W); + ioctl(fd, UI_SET_KEYBIT, KEY_E); + ioctl(fd, UI_SET_KEYBIT, KEY_R); + ioctl(fd, UI_SET_KEYBIT, KEY_T); + ioctl(fd, UI_SET_KEYBIT, KEY_Y); + ioctl(fd, UI_SET_KEYBIT, KEY_U); + ioctl(fd, UI_SET_KEYBIT, KEY_I); + ioctl(fd, UI_SET_KEYBIT, KEY_O); + ioctl(fd, UI_SET_KEYBIT, KEY_P); + ioctl(fd, UI_SET_KEYBIT, KEY_A); + ioctl(fd, UI_SET_KEYBIT, KEY_S); + ioctl(fd, UI_SET_KEYBIT, KEY_D); + ioctl(fd, UI_SET_KEYBIT, KEY_F); + ioctl(fd, UI_SET_KEYBIT, KEY_G); + ioctl(fd, UI_SET_KEYBIT, KEY_H); + ioctl(fd, UI_SET_KEYBIT, KEY_J); + ioctl(fd, UI_SET_KEYBIT, KEY_K); + ioctl(fd, UI_SET_KEYBIT, KEY_L); + ioctl(fd, UI_SET_KEYBIT, KEY_Z); + ioctl(fd, UI_SET_KEYBIT, KEY_X); + ioctl(fd, UI_SET_KEYBIT, KEY_C); + ioctl(fd, UI_SET_KEYBIT, KEY_V); + ioctl(fd, UI_SET_KEYBIT, KEY_B); + ioctl(fd, UI_SET_KEYBIT, KEY_N); + ioctl(fd, UI_SET_KEYBIT, KEY_M); + ioctl(fd, UI_SET_KEYBIT, KEY_1); + ioctl(fd, UI_SET_KEYBIT, KEY_2); + ioctl(fd, UI_SET_KEYBIT, KEY_3); + ioctl(fd, UI_SET_KEYBIT, KEY_4); + ioctl(fd, UI_SET_KEYBIT, KEY_5); + ioctl(fd, UI_SET_KEYBIT, KEY_6); + ioctl(fd, UI_SET_KEYBIT, KEY_7); + ioctl(fd, UI_SET_KEYBIT, KEY_8); + ioctl(fd, UI_SET_KEYBIT, KEY_9); + ioctl(fd, UI_SET_KEYBIT, KEY_0); + ioctl(fd, UI_SET_KEYBIT, KEYBOARD_KEY_LCRTL); + + struct uinput_setup dev = {0}; + strncpy(dev.name, VIRT_KBD_DEV_NAME, UINPUT_MAX_NAME_SIZE-1); + dev.id.bustype = BUS_VIRTUAL; + dev.id.vendor = VIRT_KBD_DEV_VENDOR_ID; + dev.id.product = VIRT_KBD_DEV_PRODUCT_ID; + dev.id.version = VIRT_KBD_DEV_VERSION; + + if(ioctl(fd, UI_DEV_SETUP, &dev) < 0) { + ret = errno > 0 ? errno : -1 * errno; + ret = ret == 0 ? -EIO : ret; + goto virt_mouse_init_err; + } + + if(ioctl(fd, UI_DEV_CREATE) < 0) { + ret = errno > 0 ? errno : -1 * errno; + ret = ret == 0 ? -EIO : ret; + goto virt_mouse_init_err; + } + + // initialization ok + kbd->fd = fd; + ret = 0; + +virt_mouse_init_err: + if (ret != 0) { + kbd->fd = -1; + close(fd); + } + + return ret; +} + +int virt_kbd_get_fd(virt_kbd_t *const kbd) { + return kbd->fd; +} + +int virt_kbd_send(virt_kbd_t *const kbd, keyboard_status_t *const status, struct timeval *const now) { + int res = 0; + + struct timeval syn_time; + gettimeofday(&syn_time, NULL); + + struct input_event tmp_ev; + gettimeofday(&tmp_ev.time, NULL); + if (now != NULL) { + tmp_ev.time = *now; + } + + tmp_ev.type = EV_KEY; + + if (status->q != kbd->prev_q) { + tmp_ev.code = KEY_Q; + tmp_ev.value = kbd->prev_q = status->q; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->w != kbd->prev_w) { + tmp_ev.code = KEY_W; + tmp_ev.value = kbd->prev_w = status->w; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->e != kbd->prev_e) { + tmp_ev.code = KEY_E; + tmp_ev.value = kbd->prev_e = status->e; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->r != kbd->prev_r) { + tmp_ev.code = KEY_R; + tmp_ev.value = kbd->prev_r = status->r; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->t != kbd->prev_t) { + tmp_ev.code = KEY_T; + tmp_ev.value = kbd->prev_t = status->t; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->y != kbd->prev_y) { + tmp_ev.code = KEY_Y; + tmp_ev.value = kbd->prev_y = status->y; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->u != kbd->prev_u) { + tmp_ev.code = KEY_U; + tmp_ev.value = kbd->prev_u = status->u; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->i != kbd->prev_i) { + tmp_ev.code = KEY_I; + tmp_ev.value = kbd->prev_i = status->i; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->o != kbd->prev_o) { + tmp_ev.code = KEY_O; + tmp_ev.value = kbd->prev_o = status->o; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->p != kbd->prev_p) { + tmp_ev.code = KEY_P; + tmp_ev.value = kbd->prev_p = status->p; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->a != kbd->prev_a) { + tmp_ev.code = KEY_A; + tmp_ev.value = kbd->prev_a = status->a; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->s != kbd->prev_s) { + tmp_ev.code = KEY_S; + tmp_ev.value = kbd->prev_s = status->s; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + + if (status->d != kbd->prev_d) { + tmp_ev.code = KEY_D; + tmp_ev.value = kbd->prev_d = status->d; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->f != kbd->prev_f) { + tmp_ev.code = KEY_F; + tmp_ev.value = kbd->prev_f = status->f; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->g != kbd->prev_g) { + tmp_ev.code = KEY_G; + tmp_ev.value = kbd->prev_g = status->g; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->h != kbd->prev_h) { + tmp_ev.code = KEY_H; + tmp_ev.value = kbd->prev_h = status->h; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->j != kbd->prev_j) { + tmp_ev.code = KEY_J; + tmp_ev.value = kbd->prev_j = status->j; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->k != kbd->prev_k) { + tmp_ev.code = KEY_K; + tmp_ev.value = kbd->prev_k = status->k; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->l != kbd->prev_l) { + tmp_ev.code = KEY_L; + tmp_ev.value = kbd->prev_l = status->l; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->z != kbd->prev_z) { + tmp_ev.code = KEY_Z; + tmp_ev.value = kbd->prev_z = status->z; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->x != kbd->prev_x) { + tmp_ev.code = KEY_X; + tmp_ev.value = kbd->prev_x = status->x; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->c != kbd->prev_c) { + tmp_ev.code = KEY_C; + tmp_ev.value = kbd->prev_c = status->c; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->v != kbd->prev_v) { + tmp_ev.code = KEY_V; + tmp_ev.value = kbd->prev_v = status->v; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->b != kbd->prev_b) { + tmp_ev.code = KEY_B; + tmp_ev.value = kbd->prev_b = status->b; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->n != kbd->prev_n) { + tmp_ev.code = KEY_N; + tmp_ev.value = kbd->prev_n = status->n; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->m != kbd->prev_m) { + tmp_ev.code = KEY_M; + tmp_ev.value = kbd->prev_m = status->m; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_0 != kbd->prev_num_0) { + tmp_ev.code = KEY_0; + tmp_ev.value = kbd->prev_num_0 = status->num_0; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_1 != kbd->prev_num_1) { + tmp_ev.code = KEY_1; + tmp_ev.value = kbd->prev_num_1 = status->num_1; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_2 != kbd->prev_num_2) { + tmp_ev.code = KEY_2; + tmp_ev.value = kbd->prev_num_2 = status->num_2; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_3 != kbd->prev_num_3) { + tmp_ev.code = KEY_3; + tmp_ev.value = kbd->prev_num_3 = status->num_3; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_4 != kbd->prev_num_4) { + tmp_ev.code = KEY_4; + tmp_ev.value = kbd->prev_num_4 = status->num_4; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_5 != kbd->prev_num_5) { + tmp_ev.code = KEY_5; + tmp_ev.value = kbd->prev_num_5 = status->num_5; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_6 != kbd->prev_num_6) { + tmp_ev.code = KEY_6; + tmp_ev.value = kbd->prev_num_6 = status->num_6; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_7 != kbd->prev_num_7) { + tmp_ev.code = KEY_7; + tmp_ev.value = kbd->prev_num_7 = status->num_7; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_8 != kbd->prev_num_8) { + tmp_ev.code = KEY_8; + tmp_ev.value = kbd->prev_num_8 = status->num_8; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_9 != kbd->prev_num_9) { + tmp_ev.code = KEY_9; + tmp_ev.value = kbd->prev_num_9 = status->num_9; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->lctrl != kbd->prev_lctrl) { + tmp_ev.code = KEYBOARD_KEY_LCRTL; + tmp_ev.value = kbd->prev_lctrl = status->lctrl; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + #if 0 + const struct input_event timestamp_ev = { + .code = MSC_TIMESTAMP, + .type = EV_MSC, + .value = (now.tv_sec - secAtInit)*1000000 + (now.tv_usec - usecAtInit), + .time = now, + }; + const ssize_t timestamp_written = write(fd, (void*)×tamp_ev, sizeof(timestamp_ev)); + if (timestamp_written != sizeof(timestamp_ev)) { + fprintf(stderr, "Error in sync: written %ld bytes out of %ld\n", timestamp_written, sizeof(timestamp_ev)); + } + #endif + + syn_time.tv_usec += 1; + const struct input_event syn_ev = { + .code = SYN_REPORT, + .type = EV_SYN, + .value = 0, + .time = syn_time, + }; + const ssize_t sync_written = write(kbd->fd, (void*)&syn_ev, sizeof(syn_ev)); + if (sync_written != sizeof(syn_ev)) { + fprintf(stderr, "Error in sync: written %ld bytes out of %ld\n", sync_written, sizeof(syn_ev)); + } + +virt_kbd_send_err: + return res; +} + +void virt_kbd_close(virt_kbd_t *const kbd) { + close(kbd->fd); +} \ No newline at end of file diff --git a/virt_kbd.h b/virt_kbd.h new file mode 100644 index 0000000..5fa6181 --- /dev/null +++ b/virt_kbd.h @@ -0,0 +1,62 @@ +#pragma once + +#include "message.h" +#include "devices_status.h" + +#define VIRT_KBD_DEV_NAME "ROGueENEMY - kbd" +#define VIRT_KBD_DEV_VENDOR_ID 0x108c +#define VIRT_KBD_DEV_PRODUCT_ID 0x0323 +#define VIRT_KBD_DEV_VERSION 0x0111 + +typedef struct virt_kbd { + int fd; + + uint8_t prev_q; + uint8_t prev_w; + uint8_t prev_e; + uint8_t prev_r; + uint8_t prev_t; + uint8_t prev_y; + uint8_t prev_u; + uint8_t prev_i; + uint8_t prev_o; + uint8_t prev_p; + uint8_t prev_a; + uint8_t prev_s; + uint8_t prev_d; + uint8_t prev_f; + uint8_t prev_g; + uint8_t prev_h; + uint8_t prev_j; + uint8_t prev_k; + uint8_t prev_l; + uint8_t prev_z; + uint8_t prev_x; + uint8_t prev_c; + uint8_t prev_v; + uint8_t prev_b; + uint8_t prev_n; + uint8_t prev_m; + + uint8_t prev_num_1; + uint8_t prev_num_2; + uint8_t prev_num_3; + uint8_t prev_num_4; + uint8_t prev_num_5; + uint8_t prev_num_6; + uint8_t prev_num_7; + uint8_t prev_num_8; + uint8_t prev_num_9; + uint8_t prev_num_0; + + uint8_t prev_lctrl; + +} virt_kbd_t; + +int virt_kbd_init(virt_kbd_t *const mouse); + +int virt_kbd_get_fd(virt_kbd_t *const mouse); + +int virt_kbd_send(virt_kbd_t *const mouse, keyboard_status_t *const status, struct timeval *const now); + +void virt_kbd_close(virt_kbd_t *const mouse); \ No newline at end of file diff --git a/virt_mouse.c b/virt_mouse.c index f09db6c..24374f8 100644 --- a/virt_mouse.c +++ b/virt_mouse.c @@ -1,7 +1,4 @@ #include "virt_mouse.h" -#include -#include -#include int virt_mouse_init(virt_mouse_t *const mouse) { int ret = -EINVAL; diff --git a/virt_mouse.h b/virt_mouse.h index 1ac8da5..2c6477a 100644 --- a/virt_mouse.h +++ b/virt_mouse.h @@ -4,7 +4,6 @@ #include "devices_status.h" #define VIRT_MOUSE_DEV_NAME "ROGueENEMY - mouse" - #define VIRT_MOUSE_DEV_VENDOR_ID 0x108c #define VIRT_MOUSE_DEV_PRODUCT_ID 0x0323 #define VIRT_MOUSE_DEV_VERSION 0x0111 From c9354dc3578575743228a9bf73bf9c868221b1ff Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 02:22:29 +0100 Subject: [PATCH 031/186] keyboard should work now --- dev_out.c | 140 ++++++++++++++ devices_status.c | 5 + devices_status.h | 2 + message.h | 4 + rog_ally.c | 486 ++++++++++++++++++++++++++++++++++++++++++++++- virt_kbd.c | 36 ++++ virt_kbd.h | 5 + 7 files changed, 675 insertions(+), 3 deletions(-) diff --git a/dev_out.c b/dev_out.c index dfdd322..ef4687f 100644 --- a/dev_out.c +++ b/dev_out.c @@ -199,6 +199,140 @@ static void handle_incoming_message_gamepad_set( } } +static void handle_incoming_message_keyboard_set( + const dev_out_settings_t *const in_settings, + const in_message_keyboard_set_element_t *const msg_payload, + keyboard_status_t *const inout_kbd +) { + switch (msg_payload->type) { + case KEYBOARD_KEY_Q: + inout_kbd->q = msg_payload->value; + break; + case KEYBOARD_KEY_W: + inout_kbd->w = msg_payload->value; + break; + case KEYBOARD_KEY_E: + inout_kbd->e = msg_payload->value; + break; + case KEYBOARD_KEY_R: + inout_kbd->r = msg_payload->value; + break; + case KEYBOARD_KEY_T: + inout_kbd->t = msg_payload->value; + break; + case KEYBOARD_KEY_Y: + inout_kbd->y = msg_payload->value; + break; + case KEYBOARD_KEY_U: + inout_kbd->u = msg_payload->value; + break; + case KEYBOARD_KEY_I: + inout_kbd->i = msg_payload->value; + break; + case KEYBOARD_KEY_O: + inout_kbd->o = msg_payload->value; + break; + case KEYBOARD_KEY_P: + inout_kbd->p = msg_payload->value; + break; + case KEYBOARD_KEY_A: + inout_kbd->a = msg_payload->value; + break; + case KEYBOARD_KEY_S: + inout_kbd->s = msg_payload->value; + break; + case KEYBOARD_KEY_D: + inout_kbd->d = msg_payload->value; + break; + case KEYBOARD_KEY_F: + inout_kbd->f = msg_payload->value; + break; + case KEYBOARD_KEY_G: + inout_kbd->g = msg_payload->value; + break; + case KEYBOARD_KEY_H: + inout_kbd->h = msg_payload->value; + break; + case KEYBOARD_KEY_J: + inout_kbd->j = msg_payload->value; + break; + case KEYBOARD_KEY_K: + inout_kbd->k = msg_payload->value; + break; + case KEYBOARD_KEY_L: + inout_kbd->l = msg_payload->value; + break; + case KEYBOARD_KEY_Z: + inout_kbd->z = msg_payload->value; + break; + case KEYBOARD_KEY_X: + inout_kbd->x = msg_payload->value; + break; + case KEYBOARD_KEY_C: + inout_kbd->c = msg_payload->value; + break; + case KEYBOARD_KEY_V: + inout_kbd->v = msg_payload->value; + break; + case KEYBOARD_KEY_B: + inout_kbd->b = msg_payload->value; + break; + case KEYBOARD_KEY_N: + inout_kbd->n = msg_payload->value; + break; + case KEYBOARD_KEY_M: + inout_kbd->m = msg_payload->value; + break; + case KEYBOARD_KEY_UP: + inout_kbd->up = msg_payload->value; + break; + case KEYBOARD_KEY_DOWN: + inout_kbd->down = msg_payload->value; + break; + case KEYBOARD_KEY_LEFT: + inout_kbd->left = msg_payload->value; + break; + case KEYBOARD_KEY_RIGHT: + inout_kbd->right = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_0: + inout_kbd->num_0 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_1: + inout_kbd->num_1 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_2: + inout_kbd->num_2 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_3: + inout_kbd->num_3 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_4: + inout_kbd->num_4 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_5: + inout_kbd->num_5 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_6: + inout_kbd->num_6 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_7: + inout_kbd->num_7 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_8: + inout_kbd->num_8 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_9: + inout_kbd->num_9 = msg_payload->value; + break; + case KEYBOARD_KEY_LCRTL: + inout_kbd->lctrl = msg_payload->value; + break; + default: + fprintf(stderr, "key not implemented\n"); + } +} + static void handle_incoming_message( const dev_out_settings_t *const in_settings, const in_message_t *const msg, @@ -222,6 +356,12 @@ static void handle_incoming_message( &msg->data.mouse_event, &dev_stats->mouse ); + } else if (msg->type == KEYBOARD_SET_ELEMENT) { + handle_incoming_message_keyboard_set( + in_settings, + &msg->data.kbd_set, + &dev_stats->kbd + ); } } diff --git a/devices_status.c b/devices_status.c index 03ee44e..ddd1b97 100644 --- a/devices_status.c +++ b/devices_status.c @@ -42,6 +42,11 @@ void kbd_status_init(keyboard_status_t *const stats) { stats->num_9 = 0; stats->num_0 = 0; + stats->up = 0; + stats->down = 0; + stats->left = 0; + stats->right = 0; + stats->lctrl = 0; } diff --git a/devices_status.h b/devices_status.h index 4a61186..e32f42d 100644 --- a/devices_status.h +++ b/devices_status.h @@ -72,6 +72,8 @@ typedef struct keyboard_status { uint8_t num_1, num_2, num_3, num_4, num_5, num_6, num_7, num_8, num_9, num_0; + uint8_t up, down, left, right; + uint8_t lctrl; } keyboard_status_t; diff --git a/message.h b/message.h index b7a5391..7270f5d 100644 --- a/message.h +++ b/message.h @@ -109,6 +109,10 @@ typedef enum kbd_element { KEYBOARD_KEY_B, KEYBOARD_KEY_N, KEYBOARD_KEY_M, + KEYBOARD_KEY_UP, + KEYBOARD_KEY_DOWN, + KEYBOARD_KEY_LEFT, + KEYBOARD_KEY_RIGHT, KEYBOARD_KEY_NUM_1, KEYBOARD_KEY_NUM_2, KEYBOARD_KEY_NUM_3, diff --git a/rog_ally.c b/rog_ally.c index 8b201aa..e827627 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -219,7 +219,7 @@ static int asus_kbd_ev_map( sscanf(current_mode_str, "%d", ¤t_mode); const int new_mode = get_next_mode(current_mode); - printf("Current mode is set to %d (read from %s) -- switching to %d", current_mode, current_mode_str, new_mode); + printf("Current mode is set to %d (read from %s) -- switching to %d\n", current_mode, current_mode_str, new_mode); char new_mode_str[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; snprintf(new_mode_str, sizeof(new_mode_str) - 1, "%d", new_mode); @@ -236,10 +236,10 @@ static int asus_kbd_ev_map( } } else { close(gamepad_mode_fd); - fprintf(stderr, "Unable to read gamepad_mode file to get current mode: %d", errno); + fprintf(stderr, "Unable to read gamepad_mode file to get current mode: %d\n", errno); } } else { - fprintf(stderr, "Unable to open gamepad_mode file in read-only mode to get current mode: %d", errno); + fprintf(stderr, "Unable to open gamepad_mode file in read-only mode to get current mode: %d\n", errno); } free(tmp_path); @@ -283,6 +283,486 @@ static int asus_kbd_ev_map( } }; + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_Q) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_Q, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_W) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_W, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_E) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_E, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_R) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_R, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_T) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_T, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_Y) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_Y, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_U) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_U, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_I) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_I, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_O) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_O, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_P) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_P, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_A) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_A, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_S) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_S, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_D) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_D, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_F) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_F, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_G) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_G, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_H) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_H, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_J) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_J, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_K) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_K, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_L) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_L, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_Z) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_Z, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_X) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_X, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_C) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_C, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_V) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_V, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_B) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_B, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_N) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_N, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_M) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_M, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_0) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_0, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_1) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_1, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_2) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_2, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_3) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_3, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_4) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_4, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_5) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_5, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_6) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_6, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_7) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_7, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_8) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_8, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_9) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_9, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_UP) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_UP, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_DOWN) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_DOWN, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_LEFT) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_LEFT, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_RIGHT) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_RIGHT, + .value = e->ev[i].value + } + } + }; + messages[written_msg++] = current_message; } } else if (e->ev[i].type == EV_REL) { diff --git a/virt_kbd.c b/virt_kbd.c index c9aec1c..db8dbc0 100644 --- a/virt_kbd.c +++ b/virt_kbd.c @@ -440,6 +440,42 @@ int virt_kbd_send(virt_kbd_t *const kbd, keyboard_status_t *const status, struct } } + if (status->up != kbd->prev_up) { + tmp_ev.code = KEYBOARD_KEY_UP; + tmp_ev.value = kbd->prev_up = status->up; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->down != kbd->prev_down) { + tmp_ev.code = KEYBOARD_KEY_DOWN; + tmp_ev.value = kbd->prev_down = status->down; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->left != kbd->prev_left) { + tmp_ev.code = KEYBOARD_KEY_LEFT; + tmp_ev.value = kbd->prev_left = status->left; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->right != kbd->prev_right) { + tmp_ev.code = KEYBOARD_KEY_RIGHT; + tmp_ev.value = kbd->prev_right = status->right; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + #if 0 const struct input_event timestamp_ev = { .code = MSC_TIMESTAMP, diff --git a/virt_kbd.h b/virt_kbd.h index 5fa6181..542039a 100644 --- a/virt_kbd.h +++ b/virt_kbd.h @@ -49,6 +49,11 @@ typedef struct virt_kbd { uint8_t prev_num_9; uint8_t prev_num_0; + uint8_t prev_up; + uint8_t prev_down; + uint8_t prev_left; + uint8_t prev_right; + uint8_t prev_lctrl; } virt_kbd_t; From 0105251e34dcdb36c25d45cd6a0381d23588699d Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 02:36:23 +0100 Subject: [PATCH 032/186] Also sends arrows --- virt_kbd.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/virt_kbd.c b/virt_kbd.c index db8dbc0..62a0365 100644 --- a/virt_kbd.c +++ b/virt_kbd.c @@ -44,6 +44,7 @@ int virt_kbd_init(virt_kbd_t *const kbd) { ioctl(fd, UI_SET_KEYBIT, KEY_B); ioctl(fd, UI_SET_KEYBIT, KEY_N); ioctl(fd, UI_SET_KEYBIT, KEY_M); + ioctl(fd, UI_SET_KEYBIT, KEY_0); ioctl(fd, UI_SET_KEYBIT, KEY_1); ioctl(fd, UI_SET_KEYBIT, KEY_2); ioctl(fd, UI_SET_KEYBIT, KEY_3); @@ -53,8 +54,11 @@ int virt_kbd_init(virt_kbd_t *const kbd) { ioctl(fd, UI_SET_KEYBIT, KEY_7); ioctl(fd, UI_SET_KEYBIT, KEY_8); ioctl(fd, UI_SET_KEYBIT, KEY_9); - ioctl(fd, UI_SET_KEYBIT, KEY_0); - ioctl(fd, UI_SET_KEYBIT, KEYBOARD_KEY_LCRTL); + ioctl(fd, UI_SET_KEYBIT, KEY_UP); + ioctl(fd, UI_SET_KEYBIT, KEY_DOWN); + ioctl(fd, UI_SET_KEYBIT, KEY_LEFT); + ioctl(fd, UI_SET_KEYBIT, KEY_RIGHT); + //ioctl(fd, UI_SET_KEYBIT, KEY_); struct uinput_setup dev = {0}; strncpy(dev.name, VIRT_KBD_DEV_NAME, UINPUT_MAX_NAME_SIZE-1); From c331a4e139ee12328ace24e21fc6d740e35cf232 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 03:05:34 +0100 Subject: [PATCH 033/186] Avoid fooding with unnecessary messages --- rog_ally.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rog_ally.c b/rog_ally.c index e827627..22067ac 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -129,6 +129,10 @@ static int asus_kbd_ev_map( for (size_t i = 0; i < e->ev_count; ++i) { if (e->ev[i].type == EV_KEY) { + if (e->ev[i].value > 1) { + continue; + } + if (e->ev[i].code == KEY_F14) { // this is left back paddle, works as expected const in_message_t current_message = { From 660f73c26d8bf1b2c282410551f1f1aa3ac78ead Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 03:12:21 +0100 Subject: [PATCH 034/186] fixed arrows and lctrl --- rog_ally.c | 12 ++++++++++++ virt_kbd.c | 8 ++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 22067ac..1b808e0 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -287,6 +287,18 @@ static int asus_kbd_ev_map( } }; + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_LEFTCTRL) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_LCRTL, + .value = e->ev[i].value + } + } + }; + messages[written_msg++] = current_message; } else if (e->ev[i].code == KEY_Q) { const in_message_t current_message = { diff --git a/virt_kbd.c b/virt_kbd.c index 62a0365..b6e7b1e 100644 --- a/virt_kbd.c +++ b/virt_kbd.c @@ -445,7 +445,7 @@ int virt_kbd_send(virt_kbd_t *const kbd, keyboard_status_t *const status, struct } if (status->up != kbd->prev_up) { - tmp_ev.code = KEYBOARD_KEY_UP; + tmp_ev.code = KEY_LEFTCTRL; tmp_ev.value = kbd->prev_up = status->up; if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { res = errno < 0 ? errno : -1 * errno; @@ -454,7 +454,7 @@ int virt_kbd_send(virt_kbd_t *const kbd, keyboard_status_t *const status, struct } if (status->down != kbd->prev_down) { - tmp_ev.code = KEYBOARD_KEY_DOWN; + tmp_ev.code = KEY_DOWN; tmp_ev.value = kbd->prev_down = status->down; if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { res = errno < 0 ? errno : -1 * errno; @@ -463,7 +463,7 @@ int virt_kbd_send(virt_kbd_t *const kbd, keyboard_status_t *const status, struct } if (status->left != kbd->prev_left) { - tmp_ev.code = KEYBOARD_KEY_LEFT; + tmp_ev.code = KEY_LEFT; tmp_ev.value = kbd->prev_left = status->left; if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { res = errno < 0 ? errno : -1 * errno; @@ -472,7 +472,7 @@ int virt_kbd_send(virt_kbd_t *const kbd, keyboard_status_t *const status, struct } if (status->right != kbd->prev_right) { - tmp_ev.code = KEYBOARD_KEY_RIGHT; + tmp_ev.code = KEY_RIGHT; tmp_ev.value = kbd->prev_right = status->right; if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { res = errno < 0 ? errno : -1 * errno; From 466f1a4db69b445a51f6a3f0cf3a826444491556 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 03:50:36 +0100 Subject: [PATCH 035/186] improving devices support --- dev_in.c | 10 ++++++++++ input_dev.h | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/dev_in.c b/dev_in.c index c4104e1..c1a3da3 100644 --- a/dev_in.c +++ b/dev_in.c @@ -44,6 +44,8 @@ typedef struct dev_in_ev { struct ff_effect ff_effect; + void* user_data; + } dev_in_ev_t; typedef union dev_in_aggr { @@ -440,8 +442,10 @@ void* dev_in_thread_func(void *ptr) { &dev_in_data->input_dev_decl->dev[i]->filters.ev, &devices[i].dev.evdev ); + if (open_res == 0) { devices[i].type = DEV_IN_TYPE_EV; + devices[i].dev.evdev.user_data = dev_in_data->input_dev_decl->dev[i]->user_data; // device is now connected, query it in select FD_SET(libevdev_get_fd(devices[i].dev.evdev.evdev), &read_fds); @@ -457,6 +461,9 @@ void* dev_in_thread_func(void *ptr) { if (open_res == 0) { devices[i].type = DEV_IN_TYPE_IIO; + + // device is now connected, query it in select + FD_SET(dev_iio_get_buffer_fd(devices[i].dev.iio.iiodev), &read_fds); } } else if (d_type == input_dev_type_hidraw) { fprintf(stderr, "Device (hidraw) %zu not found -- Attempt reconnection for device %x:%x\n", i, dev_in_data->input_dev_decl->dev[i]->filters.hidraw.pid, dev_in_data->input_dev_decl->dev[i]->filters.hidraw.vid); @@ -471,6 +478,9 @@ void* dev_in_thread_func(void *ptr) { devices[i].dev.hidraw.callbacks = dev_in_data->input_dev_decl->dev[i]->map.hidraw_callbacks; devices[i].dev.hidraw.user_data = dev_in_data->input_dev_decl->dev[i]->user_data; devices[i].type = DEV_IN_TYPE_HIDRAW; + + // device is now connected, query it in select + FD_SET(dev_hidraw_get_fd(devices[i].dev.hidraw.hidrawdev), &read_fds); } } } diff --git a/input_dev.h b/input_dev.h index 377c689..f52e4be 100644 --- a/input_dev.h +++ b/input_dev.h @@ -55,6 +55,11 @@ typedef struct iio_settings { int8_t post_matrix[3][3]; } iio_settings_t; +typedef struct timer_filters { + char name[128]; + uint64_t ticktime_ms; +} timer_filters_t; + typedef struct input_dev { input_dev_type_t dev_type; From 71603dc4d60d5f70cfbedd21d067a827173fe6b5 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 15:48:17 +0100 Subject: [PATCH 036/186] WIP: timer implementation --- CMakeLists.txt | 2 ++ dev_in.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++--- dev_timer.c | 60 +++++++++++++++++++++++++++++++ dev_timer.h | 18 ++++++++++ input_dev.h | 15 +++++++- legion_go.c | 4 ++- rog_ally.c | 39 +++++++++++++++++--- rogue_enemy.h | 1 + 8 files changed, 223 insertions(+), 12 deletions(-) create mode 100644 dev_timer.c create mode 100644 dev_timer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 515d8aa..d662d5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) add_executable(${ROGUE_EXECUTABLE_NAME} + dev_timer.c dev_evdev.c dev_iio.c dev_hidraw.c @@ -49,6 +50,7 @@ add_executable(${ALLINONE_EXECUTABLE_NAME} virt_mouse.c virt_kbd.c devices_status.c + dev_timer.c dev_evdev.c dev_iio.c dev_hidraw.c diff --git a/dev_in.c b/dev_in.c index c1a3da3..8ac7e0a 100644 --- a/dev_in.c +++ b/dev_in.c @@ -5,6 +5,7 @@ #include "message.h" #include "dev_evdev.h" #include "dev_iio.h" +#include "dev_timer.h" #include @@ -13,6 +14,7 @@ typedef enum dev_in_type { DEV_IN_TYPE_HIDRAW, DEV_IN_TYPE_IIO, DEV_IN_TYPE_EV, + DEV_IN_TYPE_TIMER, } dev_in_type_t; typedef struct dev_in_iio { @@ -44,14 +46,27 @@ typedef struct dev_in_ev { struct ff_effect ff_effect; + ev_callbacks_t callbacks; + void* user_data; } dev_in_ev_t; +typedef struct dev_in_timer { + + dev_timer_t* timer; + + timer_callbacks_t callbacks; + + void* user_data; + +} dev_in_timer_t; + typedef union dev_in_aggr { dev_in_ev_t evdev; dev_in_iio_t iio; dev_in_hidraw_t hidraw; + dev_in_timer_t timer; } dev_in_aggr_t; typedef struct dev_in { @@ -157,6 +172,23 @@ fill_message_from_evdev_err_completed: return res; } +static int timer_open_device( + const dev_in_settings_t *const in_settings, + const timer_filters_t *const in_filters, + dev_in_timer_t *const out_dev +) { + int res = dev_timer_open(in_filters, &out_dev->timer); + if (res != 0) { + fprintf(stderr, "Unable to open the timer device: %d\n", res); + goto timer_open_device_err; + } + + printf("Opened timer device: %s\n", in_filters->name); + +timer_open_device_err: + return res; +} + static int hidraw_open_device( const dev_in_settings_t *const in_settings, const hidraw_filters_t *const in_filters, @@ -272,6 +304,10 @@ static void hidraw_close_device(dev_in_hidraw_t *const out_hidraw) { dev_hidraw_close(out_hidraw->hidrawdev); } +static void timer_close_device(dev_in_timer_t *const out_hidraw) { + dev_timer_close(out_hidraw->timer); +} + static void handle_rumble_device(const dev_in_settings_t *const conf, dev_in_ev_t *const in_dev, const out_message_rumble_t *const in_rumble_msg) { if (!in_dev->has_rumble_support) { return; @@ -446,6 +482,7 @@ void* dev_in_thread_func(void *ptr) { if (open_res == 0) { devices[i].type = DEV_IN_TYPE_EV; devices[i].dev.evdev.user_data = dev_in_data->input_dev_decl->dev[i]->user_data; + devices[i].dev.evdev.callbacks = dev_in_data->input_dev_decl->dev[i]->map.ev_callbacks; // device is now connected, query it in select FD_SET(libevdev_get_fd(devices[i].dev.evdev.evdev), &read_fds); @@ -482,6 +519,23 @@ void* dev_in_thread_func(void *ptr) { // device is now connected, query it in select FD_SET(dev_hidraw_get_fd(devices[i].dev.hidraw.hidrawdev), &read_fds); } + } else if (d_type == input_dev_type_timer) { + fprintf(stderr, "Device (timer) %zu not found -- Attempt to create it with name %s\n", i, dev_in_data->input_dev_decl->dev[i]->filters.timer.name); + + const int open_res = timer_open_device( + &dev_in_data->settings, + &dev_in_data->input_dev_decl->dev[i]->filters.timer, + &devices[i].dev.timer + ); + + if (open_res == 0) { + devices[i].dev.timer.callbacks = dev_in_data->input_dev_decl->dev[i]->map.timer_callbacks; + devices[i].dev.timer.user_data = dev_in_data->input_dev_decl->dev[i]->user_data; + devices[i].type = DEV_IN_TYPE_TIMER; + + // device is now connected, query it in select + FD_SET(dev_timer_get_fd(devices[i].dev.timer.timer), &read_fds); + } } } } @@ -544,6 +598,8 @@ void* dev_in_thread_func(void *ptr) { fd = dev_iio_get_buffer_fd(devices[i].dev.iio.iiodev); } else if (devices[i].type == DEV_IN_TYPE_HIDRAW) { fd = dev_hidraw_get_fd(devices[i].dev.hidraw.hidrawdev); + } else if (devices[i].type == DEV_IN_TYPE_TIMER) { + fd = dev_timer_get_fd(devices[i].dev.timer.timer); } else { continue; } @@ -570,12 +626,12 @@ void* dev_in_thread_func(void *ptr) { continue; } - controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.ev_input_map_fn( + controller_msg_count = devices[i].dev.evdev.callbacks.input_map_fn( &dev_in_data->settings, &coll, &controller_msg[0], controller_msg_avail, - dev_in_data->input_dev_decl->dev[i]->user_data + devices[i].dev.evdev.user_data ); } else if (devices[i].type == DEV_IN_TYPE_IIO) { controller_msg_count = map_message_from_iio( @@ -583,6 +639,7 @@ void* dev_in_thread_func(void *ptr) { &controller_msg[0], controller_msg_avail ); + if (controller_msg_count < 0) { fprintf(stderr, "Error in reading iio buffer for device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count); iio_close_device(&devices[i].dev.iio); @@ -590,19 +647,45 @@ void* dev_in_thread_func(void *ptr) { continue; } } else if (devices[i].type == DEV_IN_TYPE_HIDRAW) { - controller_msg_count = dev_in_data->input_dev_decl->dev[i]->map.hidraw_callbacks.map_callback( + controller_msg_count = devices[i].dev.hidraw.callbacks.map_callback( &dev_in_data->settings, - dev_hidraw_get_fd(devices[i].dev.hidraw.hidrawdev), + fd, &controller_msg[0], controller_msg_avail, - dev_in_data->input_dev_decl->dev[i]->user_data + devices[i].dev.hidraw.user_data ); + if (controller_msg_count < 0) { fprintf(stderr, "Error in performing operations for device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count); hidraw_close_device(&devices[i].dev.hidraw); devices[i].type = DEV_IN_TYPE_NONE; continue; } + } else if (devices[i].type == DEV_IN_TYPE_TIMER) { + uint64_t expirations; + ssize_t num_read = read(fd, &expirations, sizeof(uint64_t)); + if (num_read != sizeof(uint64_t)) { + fprintf(stderr, "Error in reading expirations from timer device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count); + timer_close_device(&devices[i].dev.timer); + devices[i].type = DEV_IN_TYPE_NONE; + continue; + } + + controller_msg_count = devices[i].dev.timer.callbacks.map_fn( + &dev_in_data->settings, + fd, + expirations, + &controller_msg[0], + controller_msg_avail, + devices[i].dev.timer.user_data + ); + + if (controller_msg_count < 0) { + fprintf(stderr, "Error in timer device %zd: %d -- Will reconnect to the device\n", i, controller_msg_count); + timer_close_device(&devices[i].dev.timer); + devices[i].type = DEV_IN_TYPE_NONE; + continue; + } } // send messages (if any) @@ -662,6 +745,9 @@ void* dev_in_thread_func(void *ptr) { } else if (devices[i].type == DEV_IN_TYPE_HIDRAW) { hidraw_close_device(&devices[i].dev.hidraw); devices[i].type = DEV_IN_TYPE_NONE; + } else if (devices[i].type == DEV_IN_TYPE_TIMER) { + timer_close_device(&devices[i].dev.timer); + devices[i].type = DEV_IN_TYPE_NONE; } } diff --git a/dev_timer.c b/dev_timer.c new file mode 100644 index 0000000..9fe0275 --- /dev/null +++ b/dev_timer.c @@ -0,0 +1,60 @@ +#include "dev_timer.h" + +int dev_timer_open( + const timer_filters_t *const in_filters, + dev_timer_t **const out_dev +) { + int res = -ENODEV; + + *out_dev = malloc(sizeof(dev_timer_t)); + if (*out_dev == NULL) { + res = -ENOMEM; + goto dev_timer_open_err; + } + + memset(*out_dev, 0, sizeof(dev_timer_t)); + + const int fd = timerfd_create(CLOCK_MONOTONIC, 0); + if (fd < 0) { + res = errno < 0 ? errno : -1 * errno; + if (res == 0) { + res = fd; + } + goto dev_timer_open_err; + } + + (*out_dev)->fd = fd; + (*out_dev)->timer_spec.it_value.tv_sec = in_filters->ticktime_ms / (__time_t)1000; + (*out_dev)->timer_spec.it_value.tv_nsec = (in_filters->ticktime_ms % (__syscall_slong_t)1000) * (__syscall_slong_t)1000; + (*out_dev)->timer_spec.it_interval.tv_sec = in_filters->ticktime_ms / (__time_t)1000; + (*out_dev)->timer_spec.it_interval.tv_nsec = (in_filters->ticktime_ms % (__syscall_slong_t)1000) * (__syscall_slong_t)1000; + + if (timerfd_settime((*out_dev)->fd, 0, &(*out_dev)->timer_spec, NULL) < 0) { + res = errno < 0 ? errno : -1 * errno; + if (res == 0) { + res = -EIO; + } + goto dev_timer_open_err; + } + + res = 0; + +dev_timer_open_err: + if (res != 0) { + if (fd > 0) { + close(fd); + } + + free(*out_dev); + } + + return res; +} + +void dev_timer_close(dev_timer_t *const inout_dev) { + close(inout_dev->fd); +} + +int dev_timer_get_fd(const dev_timer_t *const in_dev) { + return in_dev->fd; +} diff --git a/dev_timer.h b/dev_timer.h new file mode 100644 index 0000000..41c6ba5 --- /dev/null +++ b/dev_timer.h @@ -0,0 +1,18 @@ +#pragma once + +#include "input_dev.h" + +typedef struct dev_timer { + struct itimerspec timer_spec; + + int fd; +} dev_timer_t; + +int dev_timer_open( + const timer_filters_t *const in_filters, + dev_timer_t **const out_dev +); + +void dev_timer_close(dev_timer_t *const inout_dev); + +int dev_timer_get_fd(const dev_timer_t *const in_dev); diff --git a/input_dev.h b/input_dev.h index f52e4be..07558a9 100644 --- a/input_dev.h +++ b/input_dev.h @@ -24,6 +24,7 @@ typedef enum input_dev_type { input_dev_type_uinput, input_dev_type_iio, input_dev_type_hidraw, + input_dev_type_timer, } input_dev_type_t; typedef struct hidraw_filters { @@ -55,6 +56,16 @@ typedef struct iio_settings { int8_t post_matrix[3][3]; } iio_settings_t; +typedef int (*timer_map)(const dev_in_settings_t *const conf, int timer_fd, uint64_t expirations, in_message_t *const messages, size_t messages_len, void* user_data); + +typedef struct timer_callbacks { + timer_map map_fn; +} timer_callbacks_t; + +typedef struct ev_callbacks { + ev_map input_map_fn; +} ev_callbacks_t; + typedef struct timer_filters { char name[128]; uint64_t ticktime_ms; @@ -67,14 +78,16 @@ typedef struct input_dev { uinput_filters_t ev; iio_filters_t iio; hidraw_filters_t hidraw; + timer_filters_t timer; } filters; void* user_data; union input_dev_map { iio_settings_t iio_settings; - ev_map ev_input_map_fn; + ev_callbacks_t ev_callbacks; hidraw_callbacks_t hidraw_callbacks; + timer_callbacks_t timer_callbacks; } map; } input_dev_t; diff --git a/legion_go.c b/legion_go.c index 6f15eb0..6d5c33e 100644 --- a/legion_go.c +++ b/legion_go.c @@ -11,7 +11,9 @@ static input_dev_t in_xbox_dev = { } }, .map = { - .ev_input_map_fn = xbox360_ev_map, + .ev_callbacks = { + .input_map_fn = xbox360_ev_map, + }, } }; diff --git a/rog_ally.c b/rog_ally.c index 1b808e0..3c35e11 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -853,7 +853,9 @@ static input_dev_t in_asus_kb_1_dev = { }, .user_data = (void*)&asus_userdata, .map = { - .ev_input_map_fn = asus_kbd_ev_map, + .ev_callbacks = { + .input_map_fn = asus_kbd_ev_map, + }, } }; @@ -866,7 +868,9 @@ static input_dev_t in_asus_kb_2_dev = { }, .user_data = (void*)&asus_userdata, .map = { - .ev_input_map_fn = asus_kbd_ev_map, + .ev_callbacks = { + .input_map_fn = asus_kbd_ev_map, + }, } }; @@ -879,7 +883,9 @@ static input_dev_t in_asus_kb_3_dev = { }, .user_data = &asus_userdata, .map = { - .ev_input_map_fn = asus_kbd_ev_map, + .ev_callbacks = { + .input_map_fn = asus_kbd_ev_map, + }, } }; @@ -891,7 +897,9 @@ static input_dev_t in_xbox_dev = { } }, .map = { - .ev_input_map_fn = xbox360_ev_map, + .ev_callbacks = { + .input_map_fn = xbox360_ev_map, + }, } }; @@ -989,6 +997,26 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u return 0; } +int rc71l_timer_map(const dev_in_settings_t *const conf, int timer_fd, uint64_t expirations, in_message_t *const messages, size_t messages_len, void* user_data) { + return 0; +} + +input_dev_t timer_dev = { + .dev_type = input_dev_type_timer, + .filters = { + .timer = { + .name = "RC71L_timer", + .ticktime_ms = 650, + } + }, + .user_data = NULL, + .map = { + .timer_callbacks = { + .map_fn = rc71l_timer_map, + } + } +}; + input_dev_composite_t rc71l_composite = { .dev = { &in_xbox_dev, @@ -997,8 +1025,9 @@ input_dev_composite_t rc71l_composite = { &in_asus_kb_2_dev, &in_asus_kb_3_dev, &nkey_dev, + &timer_dev, }, - .dev_count = 6, + .dev_count = 7, .init_fn = rc71l_platform_init, .deinit_fn = rc71l_platform_deinit, .leds_fn = rc71l_platform_leds, diff --git a/rogue_enemy.h b/rogue_enemy.h index 4d17389..00197be 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include From 6eb684744458db4eb0de98ca97120ed920677ae0 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 16:43:45 +0100 Subject: [PATCH 037/186] using nanoseconds as such --- dev_timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev_timer.c b/dev_timer.c index 9fe0275..6c6e2e3 100644 --- a/dev_timer.c +++ b/dev_timer.c @@ -25,9 +25,9 @@ int dev_timer_open( (*out_dev)->fd = fd; (*out_dev)->timer_spec.it_value.tv_sec = in_filters->ticktime_ms / (__time_t)1000; - (*out_dev)->timer_spec.it_value.tv_nsec = (in_filters->ticktime_ms % (__syscall_slong_t)1000) * (__syscall_slong_t)1000; + (*out_dev)->timer_spec.it_value.tv_nsec = (in_filters->ticktime_ms % (__syscall_slong_t)1000) * (__syscall_slong_t)1000000; (*out_dev)->timer_spec.it_interval.tv_sec = in_filters->ticktime_ms / (__time_t)1000; - (*out_dev)->timer_spec.it_interval.tv_nsec = (in_filters->ticktime_ms % (__syscall_slong_t)1000) * (__syscall_slong_t)1000; + (*out_dev)->timer_spec.it_interval.tv_nsec = (in_filters->ticktime_ms % (__syscall_slong_t)1000) * (__syscall_slong_t)1000000; if (timerfd_settime((*out_dev)->fd, 0, &(*out_dev)->timer_spec, NULL) < 0) { res = errno < 0 ? errno : -1 * errno; From ea5f026e046600cb406bbfedbd5641edd31935b4 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 17:37:58 +0100 Subject: [PATCH 038/186] timer timeout to evdev --- dev_in.c | 30 ++++++++++++++++++++++++++++++ input_dev.h | 16 +++++++++++++++- rog_ally.c | 24 +++++++++++++++++++++++- 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/dev_in.c b/dev_in.c index 8ac7e0a..141f113 100644 --- a/dev_in.c +++ b/dev_in.c @@ -56,6 +56,8 @@ typedef struct dev_in_timer { dev_timer_t* timer; + const char* name; + timer_callbacks_t callbacks; void* user_data; @@ -384,6 +386,25 @@ static void handle_leds(const dev_in_settings_t *const conf, dev_in_t *const in_ } } +static void handle_timeout( + const dev_in_settings_t *const conf, + dev_in_t *const in_devs, + size_t in_devs_count, + const char* name, + uint64_t expirations +) { + for (size_t i = 0; i < in_devs_count; ++i) { + if (in_devs[i].type == DEV_IN_TYPE_EV) { + in_devs[i].dev.hidraw.callbacks.timeout_callback( + conf, + name, + expirations, + in_devs[i].dev.evdev.user_data + ); + } + } +} + static int open_socket(struct sockaddr_un *serveraddr) { int res = -ENODEV; @@ -531,6 +552,7 @@ void* dev_in_thread_func(void *ptr) { if (open_res == 0) { devices[i].dev.timer.callbacks = dev_in_data->input_dev_decl->dev[i]->map.timer_callbacks; devices[i].dev.timer.user_data = dev_in_data->input_dev_decl->dev[i]->user_data; + devices[i].dev.timer.name = dev_in_data->input_dev_decl->dev[i]->filters.timer.name; devices[i].type = DEV_IN_TYPE_TIMER; // device is now connected, query it in select @@ -686,6 +708,14 @@ void* dev_in_thread_func(void *ptr) { devices[i].type = DEV_IN_TYPE_NONE; continue; } + + handle_timeout( + &dev_in_data->settings, + devices, + max_devices, + devices[i].dev.timer.name, + expirations + ); } // send messages (if any) diff --git a/input_dev.h b/input_dev.h index 07558a9..c7cb973 100644 --- a/input_dev.h +++ b/input_dev.h @@ -18,7 +18,19 @@ typedef struct evdev_collected { * A function with this signature grapbs input_event data and sends to the pipe messages * constructed from that data. */ -typedef int (*ev_map)(const dev_in_settings_t *const conf, const evdev_collected_t *const e, in_message_t *const messages, size_t messages_len, void* user_data); +typedef int (*ev_map)( + const dev_in_settings_t *const conf, + const evdev_collected_t *const e, + in_message_t *const messages, + size_t messages_len, + void* user_data +); +typedef void (*ev_timer)( + const dev_in_settings_t *const conf, + const char* const timer_name, + uint64_t expired, + void* user_data +); typedef enum input_dev_type { input_dev_type_uinput, @@ -49,6 +61,7 @@ typedef struct hidraw_callbacks { hidraw_set_leds leds_callback; hidraw_rumble rumble_callback; hidraw_map map_callback; + ev_timer timeout_callback; } hidraw_callbacks_t; typedef struct iio_settings { @@ -64,6 +77,7 @@ typedef struct timer_callbacks { typedef struct ev_callbacks { ev_map input_map_fn; + ev_timer timeout_callback; } ev_callbacks_t; typedef struct timer_filters { diff --git a/rog_ally.c b/rog_ally.c index 3c35e11..59072a2 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -844,6 +844,15 @@ static input_dev_t in_iio_dev = { //.input_filter_fn = input_filter_imu_identity, }; +static void rc71l_timer_asus_kbd( + const dev_in_settings_t *const conf, + const char* const timer_name, + uint64_t expired, + void* user_data +) { + +} + static input_dev_t in_asus_kb_1_dev = { .dev_type = input_dev_type_uinput, .filters = { @@ -855,6 +864,7 @@ static input_dev_t in_asus_kb_1_dev = { .map = { .ev_callbacks = { .input_map_fn = asus_kbd_ev_map, + .timeout_callback = rc71l_timer_asus_kbd, }, } }; @@ -870,6 +880,7 @@ static input_dev_t in_asus_kb_2_dev = { .map = { .ev_callbacks = { .input_map_fn = asus_kbd_ev_map, + .timeout_callback = rc71l_timer_asus_kbd, }, } }; @@ -885,10 +896,20 @@ static input_dev_t in_asus_kb_3_dev = { .map = { .ev_callbacks = { .input_map_fn = asus_kbd_ev_map, + .timeout_callback = rc71l_timer_asus_kbd, }, } }; +static void rc71l_timer_xbox360( + const dev_in_settings_t *const conf, + const char* const timer_name, + uint64_t expired, + void* user_data +) { + +} + static input_dev_t in_xbox_dev = { .dev_type = input_dev_type_uinput, .filters = { @@ -899,6 +920,7 @@ static input_dev_t in_xbox_dev = { .map = { .ev_callbacks = { .input_map_fn = xbox360_ev_map, + .timeout_callback = rc71l_timer_xbox360, }, } }; @@ -1006,7 +1028,7 @@ input_dev_t timer_dev = { .filters = { .timer = { .name = "RC71L_timer", - .ticktime_ms = 650, + .ticktime_ms = 150, } }, .user_data = NULL, From f6e0173854701e9100cf3e41acf74b8bbb39009a Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 23:03:41 +0100 Subject: [PATCH 039/186] whoopsie... --- dev_in.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_in.c b/dev_in.c index 141f113..ebb3ace 100644 --- a/dev_in.c +++ b/dev_in.c @@ -395,7 +395,7 @@ static void handle_timeout( ) { for (size_t i = 0; i < in_devs_count; ++i) { if (in_devs[i].type == DEV_IN_TYPE_EV) { - in_devs[i].dev.hidraw.callbacks.timeout_callback( + in_devs[i].dev.evdev.callbacks.timeout_callback( conf, name, expirations, From bc8911e180e900bd1bbc7d8403030894c786c9d4 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 17 Dec 2023 23:14:26 +0100 Subject: [PATCH 040/186] fix an error --- rog_ally.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rog_ally.c b/rog_ally.c index 59072a2..278cbef 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -998,6 +998,14 @@ static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platf // setup asus keyboard(s) user_data asus_userdata.udev = udev_new(); + if (asus_userdata.udev == NULL) { + fprintf(stderr, "Unable to initialize udev\n"); + res = -ENOMEM; + goto rc71l_platform_init_err; + } + + res = 0; + rc71l_platform_init_err: return res; } From a9eb18319d50b41f5ab5df6c27ed374b97b3b060 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 18 Dec 2023 00:39:49 +0100 Subject: [PATCH 041/186] Read and discard bytes from Asus MCU --- dev_hidraw.c | 2 +- rog_ally.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/dev_hidraw.c b/dev_hidraw.c index bb8d1c9..4f04f04 100644 --- a/dev_hidraw.c +++ b/dev_hidraw.c @@ -82,7 +82,7 @@ int dev_hidraw_open( //printf("Testing for device %s\n", path); // try to open the device, if it cannot be opened to go the next - int fd = open(path, O_RDWR); + int fd = open(path, O_RDWR | O_NONBLOCK); if (fd < 0) { //fprintf(stderr, "Cannot open %s, device skipped.\n", path); continue; diff --git a/rog_ally.c b/rog_ally.c index 278cbef..7d2c3ec 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -926,6 +926,15 @@ static input_dev_t in_xbox_dev = { }; static int rc71l_hidraw_map(const dev_in_settings_t *const conf, int hidraw_fd, in_message_t *const messages, size_t messages_len, void* user_data) { + uint8_t data[256]; + const int read_res = read(hidraw_fd, data, sizeof(data)); + + if (read_res < 0) { + return -EIO; + } else { + printf("Got %d bytes from Asus MCU\n", read_res); + } + return 0; } From ff7b0d918cc84d36c11140a6204d843daef33d77 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 18 Dec 2023 01:29:08 +0100 Subject: [PATCH 042/186] Prepare the logic for the rumble-on-switch --- rog_ally.c | 82 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 7d2c3ec..085206e 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -26,29 +26,43 @@ enum rc71l_leds_direction { ROG_ALLY_DIRECTION_LEFT = 0x01 } rc71l_leds_direction_t; -typedef enum rc71l_platform_mode { - rc71l_platform_mode_hidraw, - rc71l_platform_mode_linux_and_asusctl, -} rc71l_platform_mode_t; +struct rc71l_platform; -typedef struct rc71l_platform { - rc71l_platform_mode_t platform_mode; - - union { - dev_hidraw_t *hidraw; - } platform; +typedef struct rc71l_xbox360_user_data { + struct rc71l_platform* parent; - unsigned long mode; - unsigned int modes_count; -} rc71l_platform_t; + uint64_t accounted_mode_switches; -static rc71l_platform_t hw_platform; + uint64_t mode_switched; + + uint64_t expired_after_unaccounded_mode_switch; + +} rc71l_xbox360_user_data_t; typedef struct rc71l_asus_kbd_user_data { + struct rc71l_platform* parent; + struct udev *udev; } rc71l_asus_kbd_user_data_t; -static rc71l_asus_kbd_user_data_t asus_userdata; +typedef struct rc71l_platform { + rc71l_asus_kbd_user_data_t* kbd_user_data; + + rc71l_xbox360_user_data_t* xbox360_user_data; +} rc71l_platform_t; + +static rc71l_asus_kbd_user_data_t asus_userdata = {}; + +static rc71l_xbox360_user_data_t controller_user_data = { + .accounted_mode_switches = 0, + .mode_switched = 0, + .expired_after_unaccounded_mode_switch = 0, +}; + +static rc71l_platform_t hw_platform = { + .kbd_user_data = &asus_userdata, + .xbox360_user_data = &controller_user_data, +}; static char* find_kernel_sysfs_device_path(struct udev *udev) { struct udev_enumerate *const enumerate = udev_enumerate_new(udev); @@ -231,6 +245,8 @@ static int asus_kbd_ev_map( if (gamepad_mode_fd > 0) { if (write(gamepad_mode_fd, new_mode_str, strlen(new_mode_str)) > 0) { printf("Controller mode switched successfully to %s\n", new_mode_str); + + asus_kbd_user_data->parent->xbox360_user_data->mode_switched++; } else { fprintf(stderr, "Unable to switch controller mode to %s: %d -- expect bugs\n", new_mode_str, errno); } @@ -907,7 +923,16 @@ static void rc71l_timer_xbox360( uint64_t expired, void* user_data ) { - + rc71l_xbox360_user_data_t *const xbox360_data = (rc71l_xbox360_user_data_t*)user_data; + + if (xbox360_data->accounted_mode_switches != xbox360_data->mode_switched) { + xbox360_data->accounted_mode_switches = xbox360_data->mode_switched; + xbox360_data->expired_after_unaccounded_mode_switch = expired; + printf("modeswitch rumble start\n"); + } else if ((expired - xbox360_data->expired_after_unaccounded_mode_switch) == 4) { + xbox360_data->expired_after_unaccounded_mode_switch = expired; + printf("modeswitch rumble stop\n"); + } } static input_dev_t in_xbox_dev = { @@ -917,6 +942,7 @@ static input_dev_t in_xbox_dev = { .name = "Microsoft X-Box 360 pad" } }, + .user_data = &controller_user_data, .map = { .ev_callbacks = { .input_map_fn = xbox360_ev_map, @@ -931,9 +957,9 @@ static int rc71l_hidraw_map(const dev_in_settings_t *const conf, int hidraw_fd, if (read_res < 0) { return -EIO; - } else { - printf("Got %d bytes from Asus MCU\n", read_res); } + + //printf("Got %d bytes from Asus MCU\n", read_res); // either 6 or 32 return 0; } @@ -996,18 +1022,13 @@ static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platf int res = -EINVAL; rc71l_platform_t *const platform = &hw_platform; - if (platform == NULL) { - fprintf(stderr, "Unable to setup platform\n"); - res = -ENOMEM; - goto rc71l_platform_init_err; - } - *platform_data = (void*)platform; // setup asus keyboard(s) user_data - asus_userdata.udev = udev_new(); - - if (asus_userdata.udev == NULL) { + platform->kbd_user_data->parent = platform; + platform->xbox360_user_data->parent = platform; + platform->kbd_user_data->udev = udev_new(); + if (platform->kbd_user_data->udev == NULL) { fprintf(stderr, "Unable to initialize udev\n"); res = -ENOMEM; goto rc71l_platform_init_err; @@ -1022,11 +1043,8 @@ rc71l_platform_init_err: static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** platform_data) { rc71l_platform_t *const platform = (rc71l_platform_t *)(*platform_data); - udev_unref(asus_userdata.udev); - - if ((platform->platform_mode == rc71l_platform_mode_hidraw) && (platform->platform.hidraw != NULL)) { - dev_hidraw_close(platform->platform.hidraw); - platform->platform.hidraw = NULL; + if (platform->kbd_user_data != NULL) { + udev_unref(platform->kbd_user_data->udev); } *platform_data = NULL; From a89d9b5ad1eae8e816cc7ceb94f78165d1c4cc55 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 18 Dec 2023 02:24:53 +0100 Subject: [PATCH 043/186] Fix timer only firing up once --- dev_in.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev_in.c b/dev_in.c index ebb3ace..abcefbf 100644 --- a/dev_in.c +++ b/dev_in.c @@ -489,6 +489,8 @@ void* dev_in_thread_func(void *ptr) { FD_SET(dev_iio_get_buffer_fd(devices[i].dev.iio.iiodev), &read_fds); } else if (devices[i].type == DEV_IN_TYPE_HIDRAW) { FD_SET(dev_hidraw_get_fd(devices[i].dev.hidraw.hidrawdev), &read_fds); + } else if (devices[i].type == DEV_IN_TYPE_TIMER) { + FD_SET(dev_timer_get_fd(devices[i].dev.timer.timer), &read_fds); } else if (devices[i].type == DEV_IN_TYPE_NONE) { const input_dev_type_t d_type = dev_in_data->input_dev_decl->dev[i]->dev_type; if (d_type == input_dev_type_uinput) { From 4623413b5ad03025b023cdb9c36f8192cc01212d Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 18 Dec 2023 02:39:30 +0100 Subject: [PATCH 044/186] Placeholder code to get rumble working on mode switch --- rog_ally.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 085206e..a7c2a60 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -35,7 +35,9 @@ typedef struct rc71l_xbox360_user_data { uint64_t mode_switched; - uint64_t expired_after_unaccounded_mode_switch; + uint64_t timeout_after_mode_switch; + + bool mode_switch_rumbling; } rc71l_xbox360_user_data_t; @@ -56,7 +58,8 @@ static rc71l_asus_kbd_user_data_t asus_userdata = {}; static rc71l_xbox360_user_data_t controller_user_data = { .accounted_mode_switches = 0, .mode_switched = 0, - .expired_after_unaccounded_mode_switch = 0, + .timeout_after_mode_switch = 0, + .mode_switch_rumbling = false, }; static rc71l_platform_t hw_platform = { @@ -199,11 +202,11 @@ static int asus_kbd_ev_map( messages[written_msg++] = current_message; } - } else if ((e->ev[i].code == KEY_F17) && (e->ev[i].value != 0)) { - // this is right screen button, on long release, after passing short threshold both 0 and 1 events are emitted so just discard the 0 - } else if ((e->ev[i].code == KEY_F18) && (e->ev[i].value != 0)) { - // this is right screen button, on release both 0 and 1 events are emitted so just discard the 0 + // this is right screen button, on long release both 0 and 1 events are emitted so just discard the 0 + + } else if ((e->ev[i].code == KEY_F17) && (e->ev[i].value != 0)) { + // this is right screen button, on long press, after passing short threshold both 0 and 1 events are emitted so just discard the 0 // change controller mode if (asus_kbd_user_data == NULL) { @@ -927,11 +930,16 @@ static void rc71l_timer_xbox360( if (xbox360_data->accounted_mode_switches != xbox360_data->mode_switched) { xbox360_data->accounted_mode_switches = xbox360_data->mode_switched; - xbox360_data->expired_after_unaccounded_mode_switch = expired; + + xbox360_data->mode_switch_rumbling = true; printf("modeswitch rumble start\n"); - } else if ((expired - xbox360_data->expired_after_unaccounded_mode_switch) == 4) { - xbox360_data->expired_after_unaccounded_mode_switch = expired; - printf("modeswitch rumble stop\n"); + } else if (xbox360_data->mode_switch_rumbling) { + xbox360_data->timeout_after_mode_switch++; + + if (xbox360_data->timeout_after_mode_switch >= 4) { + xbox360_data->mode_switch_rumbling = false; + printf("modeswitch rumble stop\n"); + } } } From 89f32b5eb19f7ac221ca4e0a07f9546a2decb8ee Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 18 Dec 2023 23:12:59 +0100 Subject: [PATCH 045/186] Rumble on mode switch --- dev_in.c | 9 ++++++ input_dev.h | 38 +++++++++++++++++++--- rog_ally.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++------ settings.c | 7 +++++ settings.h | 1 + 5 files changed, 131 insertions(+), 14 deletions(-) diff --git a/dev_in.c b/dev_in.c index abcefbf..17edd8d 100644 --- a/dev_in.c +++ b/dev_in.c @@ -397,10 +397,19 @@ static void handle_timeout( if (in_devs[i].type == DEV_IN_TYPE_EV) { in_devs[i].dev.evdev.callbacks.timeout_callback( conf, + in_devs[i].dev.evdev.evdev, name, expirations, in_devs[i].dev.evdev.user_data ); + } else if (in_devs[i].type == DEV_IN_TYPE_HIDRAW) { + in_devs[i].dev.hidraw.callbacks.timeout_callback( + conf, + dev_hidraw_get_fd(in_devs[i].dev.hidraw.hidrawdev), + name, + expirations, + in_devs[i].dev.hidraw.user_data + ); } } } diff --git a/input_dev.h b/input_dev.h index c7cb973..788e17b 100644 --- a/input_dev.h +++ b/input_dev.h @@ -27,6 +27,7 @@ typedef int (*ev_map)( ); typedef void (*ev_timer)( const dev_in_settings_t *const conf, + struct libevdev* evdev, const char* const timer_name, uint64_t expired, void* user_data @@ -53,15 +54,44 @@ typedef struct iio_filters { const char name[256]; } iio_filters_t; -typedef int (*hidraw_map)(const dev_in_settings_t *const conf, int hidraw_fd, in_message_t *const messages, size_t messages_len, void* user_data); -typedef int (*hidraw_set_leds)(const dev_in_settings_t *const conf, int hidraw_fd, uint8_t r, uint8_t g, uint8_t b, void* user_data); -typedef int (*hidraw_rumble)(const dev_in_settings_t *const conf, int hidraw_fd, uint8_t left_motor, uint8_t right_motor, void* user_data); +typedef int (*hidraw_map)( + const dev_in_settings_t *const conf, + int hidraw_fd, + in_message_t *const messages, + size_t messages_len, + void* user_data +); + +typedef int (*hidraw_set_leds)( + const dev_in_settings_t *const conf, + int hidraw_fd, + uint8_t r, + uint8_t g, + uint8_t b, + void* user_data +); + +typedef int (*hidraw_rumble)( + const dev_in_settings_t *const conf, + int hidraw_fd, + uint8_t left_motor, + uint8_t right_motor, + void* user_data +); + +typedef void (*hidraw_timer)( + const dev_in_settings_t *const conf, + int fd, + const char* const timer_name, + uint64_t expired, + void* user_data +); typedef struct hidraw_callbacks { hidraw_set_leds leds_callback; hidraw_rumble rumble_callback; hidraw_map map_callback; - ev_timer timeout_callback; + hidraw_timer timeout_callback; } hidraw_callbacks_t; typedef struct iio_settings { diff --git a/rog_ally.c b/rog_ally.c index a7c2a60..b6f75d9 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -39,6 +39,8 @@ typedef struct rc71l_xbox360_user_data { bool mode_switch_rumbling; + struct ff_effect mode_switch_rumble_effect; + } rc71l_xbox360_user_data_t; typedef struct rc71l_asus_kbd_user_data { @@ -60,6 +62,20 @@ static rc71l_xbox360_user_data_t controller_user_data = { .mode_switched = 0, .timeout_after_mode_switch = 0, .mode_switch_rumbling = false, + .mode_switch_rumble_effect = { + .type = FF_RUMBLE, + .id = -1, + .replay = { + .delay = 0x00, + .length = 5000 + }, + .u = { + .rumble = { + .strong_magnitude = 0xFFFF, + .weak_magnitude = 0xFFFF, + } + } + } }; static rc71l_platform_t hw_platform = { @@ -865,6 +881,7 @@ static input_dev_t in_iio_dev = { static void rc71l_timer_asus_kbd( const dev_in_settings_t *const conf, + struct libevdev* evdev, const char* const timer_name, uint64_t expired, void* user_data @@ -922,23 +939,65 @@ static input_dev_t in_asus_kb_3_dev = { static void rc71l_timer_xbox360( const dev_in_settings_t *const conf, + struct libevdev* evdev, const char* const timer_name, uint64_t expired, void* user_data ) { rc71l_xbox360_user_data_t *const xbox360_data = (rc71l_xbox360_user_data_t*)user_data; + - if (xbox360_data->accounted_mode_switches != xbox360_data->mode_switched) { - xbox360_data->accounted_mode_switches = xbox360_data->mode_switched; + if (conf->rumble_on_mode_switch) { + if (xbox360_data->accounted_mode_switches != xbox360_data->mode_switched) { + const int fd = libevdev_get_fd(evdev); - xbox360_data->mode_switch_rumbling = true; - printf("modeswitch rumble start\n"); - } else if (xbox360_data->mode_switch_rumbling) { - xbox360_data->timeout_after_mode_switch++; - - if (xbox360_data->timeout_after_mode_switch >= 4) { - xbox360_data->mode_switch_rumbling = false; - printf("modeswitch rumble stop\n"); + xbox360_data->accounted_mode_switches = xbox360_data->mode_switched; + + xbox360_data->mode_switch_rumbling = true; + + // load the new effect data + xbox360_data->mode_switch_rumble_effect.u.rumble.strong_magnitude = 0xFFFF; + xbox360_data->mode_switch_rumble_effect.u.rumble.weak_magnitude = 0xFFFF; + + // upload the new effect to the device + const int effect_upload_res = ioctl(fd, EVIOCSFF, &xbox360_data->mode_switch_rumble_effect); + if (effect_upload_res == 0) { + const struct input_event rumble_play = { + .type = EV_FF, + .code = xbox360_data->mode_switch_rumble_effect.id, + .value = 1, + }; + + const int effect_start_res = write(fd, (const void*)&rumble_play, sizeof(rumble_play)); + if (effect_start_res != sizeof(rumble_play)) { + fprintf(stderr, "Unable to write input event starting the mode-switch rumble: %d\n", effect_start_res); + } + } else { + fprintf(stderr, "Unable to update force-feedback effect for mode-switch rumble: %d\n", effect_upload_res); + + xbox360_data->mode_switch_rumble_effect.id = -1; + } + } else if (xbox360_data->mode_switch_rumbling) { + const int fd = libevdev_get_fd(evdev); + + xbox360_data->timeout_after_mode_switch++; + + if (xbox360_data->timeout_after_mode_switch >= 4) { + xbox360_data->mode_switch_rumbling = false; + + if (xbox360_data->mode_switch_rumble_effect.id != -1) { + struct input_event rumble_stop = { + .type = EV_FF, + .code = xbox360_data->mode_switch_rumble_effect.id, + .value = 0, + }; + + const int rumble_stop_res = write(fd, (const void*) &rumble_stop, sizeof(rumble_stop)); + if (rumble_stop_res != sizeof(rumble_stop)) { + fprintf(stderr, "Unable to stop the previous rumble: %d\n", rumble_stop_res); + } + } + } } } } @@ -1007,6 +1066,16 @@ rc71l_hidraw_set_leds_err: return -EIO; } +static void rc71l_hidraw_timer( + const dev_in_settings_t *const conf, + int fd, + const char* const timer_name, + uint64_t expired, + void* user_data +) { + +} + static input_dev_t nkey_dev = { .dev_type = input_dev_type_hidraw, .filters = { @@ -1022,6 +1091,7 @@ static input_dev_t nkey_dev = { .leds_callback = rc71l_hidraw_set_leds, .rumble_callback = rc71l_hidraw_rumble, .map_callback = rc71l_hidraw_map, + .timeout_callback = rc71l_hidraw_timer, } } }; diff --git a/settings.c b/settings.c index bc301cf..dbaa8ff 100644 --- a/settings.c +++ b/settings.c @@ -19,6 +19,13 @@ void load_in_config(dev_in_settings_t *const out_conf, const char* const filepat fprintf(stderr, "enable_qam (bool) configuration not found. Default value will be used.\n"); } + int rumble_on_mode_switch; + if (config_lookup_bool(&cfg, "rumble_on_mode_switch", &enable_qam) != CONFIG_FALSE) { + out_conf->rumble_on_mode_switch = rumble_on_mode_switch; + } else { + fprintf(stderr, "rumble_on_mode_switch (bool) configuration not found. Default value will be used.\n"); + } + int ff_gain; if (config_lookup_int(&cfg, "ff_gain", &ff_gain) != CONFIG_FALSE) { if (ff_gain <= 0xFF) { diff --git a/settings.h b/settings.h index 6abfb5f..6e13d12 100644 --- a/settings.h +++ b/settings.h @@ -4,6 +4,7 @@ typedef struct dev_in_settings { bool enable_qam; + bool rumble_on_mode_switch; uint16_t ff_gain; } dev_in_settings_t; From 0336bf3777ca22cab9fdf85e9247fdb2a2ef805f Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 18 Dec 2023 23:13:38 +0100 Subject: [PATCH 046/186] maybe this fixes the too long rumble on the dualsense? --- rog_ally.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rog_ally.c b/rog_ally.c index b6f75d9..6c0021a 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -67,7 +67,7 @@ static rc71l_xbox360_user_data_t controller_user_data = { .id = -1, .replay = { .delay = 0x00, - .length = 5000 + .length = 1000 }, .u = { .rumble = { From 692ff53ff78da7ecd8730ad8866ce40c2320a41d Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 18 Dec 2023 23:37:36 +0100 Subject: [PATCH 047/186] Rumble on mode switch is ON by default --- allynone.c | 1 + main.c | 1 + 2 files changed, 2 insertions(+) diff --git a/allynone.c b/allynone.c index 8caf8db..fd0e324 100644 --- a/allynone.c +++ b/allynone.c @@ -88,6 +88,7 @@ int main(int argc, char ** argv) { .settings = { .enable_qam = true, .ff_gain = 0xFFFF, + .rumble_on_mode_switch = true, } }; diff --git a/main.c b/main.c index 43d50dc..08999d3 100644 --- a/main.c +++ b/main.c @@ -54,6 +54,7 @@ int main(int argc, char ** argv) { .settings = { .enable_qam = true, .ff_gain = 0xFFFF, + .rumble_on_mode_switch = true, } }; From 9397aa2348411df955f774264e06d049bd26836d Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 18 Dec 2023 23:41:32 +0100 Subject: [PATCH 048/186] whoopsie... --- settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.c b/settings.c index dbaa8ff..609923c 100644 --- a/settings.c +++ b/settings.c @@ -20,7 +20,7 @@ void load_in_config(dev_in_settings_t *const out_conf, const char* const filepat } int rumble_on_mode_switch; - if (config_lookup_bool(&cfg, "rumble_on_mode_switch", &enable_qam) != CONFIG_FALSE) { + if (config_lookup_bool(&cfg, "rumble_on_mode_switch", &rumble_on_mode_switch) != CONFIG_FALSE) { out_conf->rumble_on_mode_switch = rumble_on_mode_switch; } else { fprintf(stderr, "rumble_on_mode_switch (bool) configuration not found. Default value will be used.\n"); From 96b47c6e49d6ae08654809ff6be86267ccde10f7 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 19 Dec 2023 00:08:51 +0100 Subject: [PATCH 049/186] this might work better... --- rog_ally.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 6c0021a..94d2770 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -67,7 +67,7 @@ static rc71l_xbox360_user_data_t controller_user_data = { .id = -1, .replay = { .delay = 0x00, - .length = 1000 + .length = 500 }, .u = { .rumble = { @@ -982,7 +982,7 @@ static void rc71l_timer_xbox360( xbox360_data->timeout_after_mode_switch++; - if (xbox360_data->timeout_after_mode_switch >= 4) { + if (xbox360_data->timeout_after_mode_switch >= 10) { xbox360_data->mode_switch_rumbling = false; if (xbox360_data->mode_switch_rumble_effect.id != -1) { @@ -1141,7 +1141,7 @@ input_dev_t timer_dev = { .filters = { .timer = { .name = "RC71L_timer", - .ticktime_ms = 150, + .ticktime_ms = 60, } }, .user_data = NULL, From e6a940dc4d6ad6b68d56a50ceaba043e10a858c5 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 19 Dec 2023 00:12:26 +0100 Subject: [PATCH 050/186] Why do I get uneven rumbles? --- rog_ally.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/rog_ally.c b/rog_ally.c index 94d2770..232378a 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -67,7 +67,7 @@ static rc71l_xbox360_user_data_t controller_user_data = { .id = -1, .replay = { .delay = 0x00, - .length = 500 + .length = 1000 }, .u = { .rumble = { @@ -962,6 +962,17 @@ static void rc71l_timer_xbox360( // upload the new effect to the device const int effect_upload_res = ioctl(fd, EVIOCSFF, &xbox360_data->mode_switch_rumble_effect); if (effect_upload_res == 0) { + struct input_event rumble_stop = { + .type = EV_FF, + .code = xbox360_data->mode_switch_rumble_effect.id, + .value = 0, + }; + + const int rumble_stop_res = write(fd, (const void*) &rumble_stop, sizeof(rumble_stop)); + if (rumble_stop_res != sizeof(rumble_stop)) { + fprintf(stderr, "Unable to stop the previous rumble: %d\n", rumble_stop_res); + } + const struct input_event rumble_play = { .type = EV_FF, .code = xbox360_data->mode_switch_rumble_effect.id, @@ -986,6 +997,7 @@ static void rc71l_timer_xbox360( xbox360_data->mode_switch_rumbling = false; if (xbox360_data->mode_switch_rumble_effect.id != -1) { + /* struct input_event rumble_stop = { .type = EV_FF, .code = xbox360_data->mode_switch_rumble_effect.id, @@ -996,6 +1008,7 @@ static void rc71l_timer_xbox360( if (rumble_stop_res != sizeof(rumble_stop)) { fprintf(stderr, "Unable to stop the previous rumble: %d\n", rumble_stop_res); } + */ } } } From 8fc2bd42b572dd5179e31878cc66552af40454b2 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 19 Dec 2023 00:15:27 +0100 Subject: [PATCH 051/186] 1s is too much... --- rog_ally.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rog_ally.c b/rog_ally.c index 232378a..2bafebd 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -67,7 +67,7 @@ static rc71l_xbox360_user_data_t controller_user_data = { .id = -1, .replay = { .delay = 0x00, - .length = 1000 + .length = 800 }, .u = { .rumble = { From 68412b33186d346b9f9b38b0f26641714fd5e23d Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 19 Dec 2023 00:37:56 +0100 Subject: [PATCH 052/186] quickly vibrate --- rog_ally.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rog_ally.c b/rog_ally.c index 2bafebd..deca43e 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -67,7 +67,7 @@ static rc71l_xbox360_user_data_t controller_user_data = { .id = -1, .replay = { .delay = 0x00, - .length = 800 + .length = 300 }, .u = { .rumble = { From c4b6616675ef4047586e025cbd06302591156dda Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 19 Dec 2023 01:25:33 +0100 Subject: [PATCH 053/186] reference bash scripts for start buffered mode --- rogue-enemy_iio_buffer_off.sh | 4 ++++ rogue-enemy_iio_buffer_on.sh | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 rogue-enemy_iio_buffer_off.sh create mode 100644 rogue-enemy_iio_buffer_on.sh diff --git a/rogue-enemy_iio_buffer_off.sh b/rogue-enemy_iio_buffer_off.sh new file mode 100644 index 0000000..5b3c6b3 --- /dev/null +++ b/rogue-enemy_iio_buffer_off.sh @@ -0,0 +1,4 @@ +#!/bin/bash +cd /sys/bus/iio/devices/iio\:device0 +echo "void" > trigger/current_trigger +echo 0 > buffer0/enable \ No newline at end of file diff --git a/rogue-enemy_iio_buffer_on.sh b/rogue-enemy_iio_buffer_on.sh new file mode 100644 index 0000000..c20cd0b --- /dev/null +++ b/rogue-enemy_iio_buffer_on.sh @@ -0,0 +1,23 @@ +#!/bin/bash +modprobe industrialio-sw-trigger +modprobe iio-trig-sysfs +modprobe iio-trig-hrtimer + +# hrtimer +if [! -d "/home/config"]; then + mkdir /home/config +fi + +mount -t configfs none /home/config +mkdir /home/config/iio/triggers/hrtimer/rogue + +cd /sys/bus/iio/devices/iio\:device0 +echo 1 > scan_elements/in_accel_x_en +echo 1 > scan_elements/in_accel_y_en +echo 1 > scan_elements/in_accel_z_en +echo 1 > scan_elements/in_anglvel_x_en +echo 1 > scan_elements/in_anglvel_y_en +echo 1 > scan_elements/in_anglvel_z_en +echo 1 > scan_elements/in_timestamp_en +echo "rogue" > trigger/current_trigger +echo 1 > buffer0/enable \ No newline at end of file From 23dad1ba604cff01e2042e7d084eb4f24fe86a58 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 19 Dec 2023 01:46:43 +0100 Subject: [PATCH 054/186] use mkdir -p --- rogue-enemy_iio_buffer_on.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rogue-enemy_iio_buffer_on.sh b/rogue-enemy_iio_buffer_on.sh index c20cd0b..1f9e7f6 100644 --- a/rogue-enemy_iio_buffer_on.sh +++ b/rogue-enemy_iio_buffer_on.sh @@ -5,11 +5,11 @@ modprobe iio-trig-hrtimer # hrtimer if [! -d "/home/config"]; then - mkdir /home/config + mkdir -p /home/config fi mount -t configfs none /home/config -mkdir /home/config/iio/triggers/hrtimer/rogue +mkdir -p /home/config/iio/triggers/hrtimer/rogue cd /sys/bus/iio/devices/iio\:device0 echo 1 > scan_elements/in_accel_x_en From 0324cd2760c60f106f3a9b339c3f5afa78bf7e40 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 19 Dec 2023 02:08:32 +0100 Subject: [PATCH 055/186] make it feel like a phone toggle --- rog_ally.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rog_ally.c b/rog_ally.c index deca43e..5f2c0f8 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -67,7 +67,7 @@ static rc71l_xbox360_user_data_t controller_user_data = { .id = -1, .replay = { .delay = 0x00, - .length = 300 + .length = 50 }, .u = { .rumble = { From 18c1e27c3a3e724c7796afdd6e2d0b5a871964dc Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 19 Dec 2023 21:22:39 +0100 Subject: [PATCH 056/186] fix reported USB name --- virt_ds5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt_ds5.c b/virt_ds5.c index 3117d1d..e9b70e2 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -85,7 +85,7 @@ static int create(int fd) memset(&ev, 0, sizeof(ev)); ev.type = UHID_CREATE; - strcpy((char*)ev.u.create.name, "Sony Interactive Entertainment DualSense Wireless Controller"); + strcpy((char*)ev.u.create.name, "Sony Corp. DualSense Edge wireless controller (PS5)"); ev.u.create.rd_data = rdesc; ev.u.create.rd_size = sizeof(rdesc); ev.u.create.bus = BUS_USB; From 793f9e7e56ac5f6e8132545602bfce01f6c9cd1d Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 19 Dec 2023 21:23:01 +0100 Subject: [PATCH 057/186] fix both dpad up in mouse mode and lctrl --- virt_kbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/virt_kbd.c b/virt_kbd.c index b6e7b1e..b535124 100644 --- a/virt_kbd.c +++ b/virt_kbd.c @@ -436,7 +436,7 @@ int virt_kbd_send(virt_kbd_t *const kbd, keyboard_status_t *const status, struct } if (status->lctrl != kbd->prev_lctrl) { - tmp_ev.code = KEYBOARD_KEY_LCRTL; + tmp_ev.code = KEY_LEFTCTRL; tmp_ev.value = kbd->prev_lctrl = status->lctrl; if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { res = errno < 0 ? errno : -1 * errno; @@ -445,7 +445,7 @@ int virt_kbd_send(virt_kbd_t *const kbd, keyboard_status_t *const status, struct } if (status->up != kbd->prev_up) { - tmp_ev.code = KEY_LEFTCTRL; + tmp_ev.code = KEY_UP; tmp_ev.value = kbd->prev_up = status->up; if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { res = errno < 0 ? errno : -1 * errno; From 9aa38f416cf4e5c1d8135833fd3705b45848fee3 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 19 Dec 2023 22:23:19 +0100 Subject: [PATCH 058/186] Change default configuration --- config.cfg.default | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config.cfg.default b/config.cfg.default index a6ff041..e9940b9 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -1,5 +1,5 @@ enable_qam = true; -ff_gain = 100; +ff_gain = 255; nintendo_layout = false; -gamepad_output_device = 1; -rumble_dedicated_thread = false; \ No newline at end of file +default_gamepad = 1; +rumble_on_mode_switch = true; \ No newline at end of file From 646ed984debd260fb54d6c7865e95e38fed4323c Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 19 Dec 2023 22:54:57 +0100 Subject: [PATCH 059/186] wrong if statement --- rogue-enemy_iio_buffer_on.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rogue-enemy_iio_buffer_on.sh b/rogue-enemy_iio_buffer_on.sh index 1f9e7f6..2f71ab5 100644 --- a/rogue-enemy_iio_buffer_on.sh +++ b/rogue-enemy_iio_buffer_on.sh @@ -4,7 +4,7 @@ modprobe iio-trig-sysfs modprobe iio-trig-hrtimer # hrtimer -if [! -d "/home/config"]; then +if [ ! -d "/home/config" ]; then mkdir -p /home/config fi From 566d89df296d6eeb2ce5cb5ac8db26f9251d80c9 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 20 Dec 2023 14:35:46 +0100 Subject: [PATCH 060/186] Allow the user to disable gamepad rumble and leds control --- allynone.c | 2 ++ config.cfg.default | 4 +++- dev_out.c | 8 ++++++-- settings.c | 14 ++++++++++++++ settings.h | 2 ++ stray_ally.c | 2 ++ 6 files changed, 29 insertions(+), 3 deletions(-) diff --git a/allynone.c b/allynone.c index fd0e324..8172706 100644 --- a/allynone.c +++ b/allynone.c @@ -110,6 +110,8 @@ int main(int argc, char ** argv) { .settings = { .default_gamepad = 0, .nintendo_layout = false, + .gamepad_leds_control = true, + .gamepad_rumble_control = true, } }; diff --git a/config.cfg.default b/config.cfg.default index e9940b9..a932f9a 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -2,4 +2,6 @@ enable_qam = true; ff_gain = 255; nintendo_layout = false; default_gamepad = 1; -rumble_on_mode_switch = true; \ No newline at end of file +rumble_on_mode_switch = true; +gamepad_rumble_control = true; +gamepad_leds_control = true; \ No newline at end of file diff --git a/dev_out.c b/dev_out.c index ef4687f..1fb944e 100644 --- a/dev_out.c +++ b/dev_out.c @@ -581,7 +581,9 @@ void *dev_out_thread_func(void *ptr) { } }; - out_msgs[out_msgs_count++] = msg; + if (dev_out_data->settings.gamepad_leds_control) { + out_msgs[out_msgs_count++] = msg; + } } if (current_motors_events_count != prev_motors_events_count) { @@ -595,7 +597,9 @@ void *dev_out_thread_func(void *ptr) { } }; - out_msgs[out_msgs_count++] = msg; + if (dev_out_data->settings.gamepad_rumble_control) { + out_msgs[out_msgs_count++] = msg; + } } // send out game-generated events to sockets diff --git a/settings.c b/settings.c index 609923c..6442215 100644 --- a/settings.c +++ b/settings.c @@ -67,6 +67,20 @@ void load_out_config(dev_out_settings_t *const out_conf, const char* const filep fprintf(stderr, "default_gamepad (int) configuration not found. Default value will be used.\n"); } + int gamepad_leds_control; + if (config_lookup_bool(&cfg, "gamepad_leds_control", &gamepad_leds_control) != CONFIG_FALSE) { + out_conf->gamepad_leds_control = gamepad_leds_control; + } else { + fprintf(stderr, "gamepad_leds_control (bool) configuration not found. Default value will be used.\n"); + } + + int gamepad_rumble_control; + if (config_lookup_bool(&cfg, "gamepad_rumble_control", &gamepad_rumble_control) != CONFIG_FALSE) { + out_conf->gamepad_rumble_control = gamepad_rumble_control; + } else { + fprintf(stderr, "gamepad_rumble_control (bool) configuration not found. Default value will be used.\n"); + } + config_destroy(&cfg); load_out_config_err: diff --git a/settings.h b/settings.h index 6e13d12..3d32878 100644 --- a/settings.h +++ b/settings.h @@ -13,6 +13,8 @@ void load_in_config(dev_in_settings_t *const out_conf, const char* const filepat typedef struct dev_out_settings { bool nintendo_layout; uint8_t default_gamepad; + bool gamepad_leds_control; + bool gamepad_rumble_control; } dev_out_settings_t; void load_out_config(dev_out_settings_t *const out_conf, const char* const filepath); \ No newline at end of file diff --git a/stray_ally.c b/stray_ally.c index 3ab735a..fb165e2 100644 --- a/stray_ally.c +++ b/stray_ally.c @@ -45,6 +45,8 @@ int main(int argc, char ** argv) { .settings = { .default_gamepad = 0, .nintendo_layout = false, + .gamepad_leds_control = true, + .gamepad_rumble_control = true, } }; From 628e803834d5d97ea789b58ccc147279bdb5e5ff Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 20 Dec 2023 15:32:43 +0100 Subject: [PATCH 061/186] better imu startup --- rogue-enemy_iio_buffer_on.sh | 57 +++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/rogue-enemy_iio_buffer_on.sh b/rogue-enemy_iio_buffer_on.sh index 2f71ab5..bc64b9a 100644 --- a/rogue-enemy_iio_buffer_on.sh +++ b/rogue-enemy_iio_buffer_on.sh @@ -11,13 +11,50 @@ fi mount -t configfs none /home/config mkdir -p /home/config/iio/triggers/hrtimer/rogue -cd /sys/bus/iio/devices/iio\:device0 -echo 1 > scan_elements/in_accel_x_en -echo 1 > scan_elements/in_accel_y_en -echo 1 > scan_elements/in_accel_z_en -echo 1 > scan_elements/in_anglvel_x_en -echo 1 > scan_elements/in_anglvel_y_en -echo 1 > scan_elements/in_anglvel_z_en -echo 1 > scan_elements/in_timestamp_en -echo "rogue" > trigger/current_trigger -echo 1 > buffer0/enable \ No newline at end of file +# set sampling frequency for rogue +for i in /sys/bus/iio/devices/* ; do + if [ -d "$i" ]; then + if [ -f "$i/name" ]; then + name=$(cat "$i/name") + if [ "$name" = "rogue" ]; then + echo "800" > "$i/sampling_frequency" + fi + fi + fi +done + +# set the gyroscope +for i in /sys/bus/iio/devices/* ; do + if [ -d "$i" ]; then + if [ -f "$i/name" ]; then + name=$(cat "$i/name") + if [ "$name" = "bmi323-imu" ]; then + + # change chip sampling frequency + echo "800.000000" > "$i/in_accel_sampling_frequency" + echo "800.000000" > "$i/in_anglvel_sampling_frequency" + + # enable accel data acquisition + echo 1 > "$i/scan_elements/in_accel_x_en" + echo 1 > "$i/scan_elements/in_accel_y_en" + echo 1 > "$i/scan_elements/in_accel_z_en" + + # enable gyroscope data acquisition + echo 1 > "$i/scan_elements/in_anglvel_x_en" + echo 1 > "$i/scan_elements/in_anglvel_y_en" + echo 1 > "$i/scan_elements/in_anglvel_z_en" + + # enable timestamp reporting + echo 1 > "$i/scan_elements/in_timestamp_en" + + # bind rogue hrtimer to to the iio device + echo "rogue" > "$i/trigger/current_trigger" + + # enable the buffer + echo 1 > "$i/buffer0/enable" + + echo "bmi323-imu buffer started" + fi + fi + fi +done From 8637035ab28d66e1959bbcde70bc6751f8bb5cd6 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 20 Dec 2023 19:17:48 +0100 Subject: [PATCH 062/186] use the ACPI mount matrix --- dev_in.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dev_in.c b/dev_in.c index 17edd8d..84d5bc9 100644 --- a/dev_in.c +++ b/dev_in.c @@ -108,9 +108,9 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const //messages[0].data.gamepad_set.status.accel.x = scan_elements[0]; //messages[0].data.gamepad_set.status.accel.y = scan_elements[1]; //messages[0].data.gamepad_set.status.accel.z = scan_elements[2]; - messages[0].data.gamepad_set.status.accel.x = scan_elements[0]; - messages[0].data.gamepad_set.status.accel.y = (uint16_t)(-1) * scan_elements[2]; - messages[0].data.gamepad_set.status.accel.z = (uint16_t)(-1) * scan_elements[1]; + messages[0].data.gamepad_set.status.accel.x = (uint16_t)(-1) * scan_elements[0]; + messages[0].data.gamepad_set.status.accel.y = scan_elements[1]; + messages[0].data.gamepad_set.status.accel.z = scan_elements[2]; messages[1].type = GAMEPAD_SET_ELEMENT; messages[1].data.gamepad_set.element = GAMEPAD_GYROSCOPE; @@ -118,9 +118,9 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const //messages[1].data.gamepad_set.status.gyro.x = scan_elements[3]; //messages[1].data.gamepad_set.status.gyro.y = scan_elements[4]; //messages[1].data.gamepad_set.status.gyro.z = scan_elements[5]; - messages[1].data.gamepad_set.status.gyro.x = scan_elements[3]; - messages[1].data.gamepad_set.status.gyro.y = (uint16_t)(-1) * scan_elements[5]; - messages[1].data.gamepad_set.status.gyro.z = (uint16_t)(-1) * scan_elements[4]; + messages[1].data.gamepad_set.status.gyro.x = (uint16_t)(-1) * scan_elements[3]; + messages[1].data.gamepad_set.status.gyro.y = scan_elements[4]; + messages[1].data.gamepad_set.status.gyro.z = scan_elements[5]; res = 2; From 8857d30a580f57c565b9ee74cbfa22d486721123 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 20 Dec 2023 23:21:43 +0100 Subject: [PATCH 063/186] Revert "use the ACPI mount matrix" This reverts commit 8637035ab28d66e1959bbcde70bc6751f8bb5cd6. --- dev_in.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dev_in.c b/dev_in.c index 84d5bc9..17edd8d 100644 --- a/dev_in.c +++ b/dev_in.c @@ -108,9 +108,9 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const //messages[0].data.gamepad_set.status.accel.x = scan_elements[0]; //messages[0].data.gamepad_set.status.accel.y = scan_elements[1]; //messages[0].data.gamepad_set.status.accel.z = scan_elements[2]; - messages[0].data.gamepad_set.status.accel.x = (uint16_t)(-1) * scan_elements[0]; - messages[0].data.gamepad_set.status.accel.y = scan_elements[1]; - messages[0].data.gamepad_set.status.accel.z = scan_elements[2]; + messages[0].data.gamepad_set.status.accel.x = scan_elements[0]; + messages[0].data.gamepad_set.status.accel.y = (uint16_t)(-1) * scan_elements[2]; + messages[0].data.gamepad_set.status.accel.z = (uint16_t)(-1) * scan_elements[1]; messages[1].type = GAMEPAD_SET_ELEMENT; messages[1].data.gamepad_set.element = GAMEPAD_GYROSCOPE; @@ -118,9 +118,9 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const //messages[1].data.gamepad_set.status.gyro.x = scan_elements[3]; //messages[1].data.gamepad_set.status.gyro.y = scan_elements[4]; //messages[1].data.gamepad_set.status.gyro.z = scan_elements[5]; - messages[1].data.gamepad_set.status.gyro.x = (uint16_t)(-1) * scan_elements[3]; - messages[1].data.gamepad_set.status.gyro.y = scan_elements[4]; - messages[1].data.gamepad_set.status.gyro.z = scan_elements[5]; + messages[1].data.gamepad_set.status.gyro.x = scan_elements[3]; + messages[1].data.gamepad_set.status.gyro.y = (uint16_t)(-1) * scan_elements[5]; + messages[1].data.gamepad_set.status.gyro.z = (uint16_t)(-1) * scan_elements[4]; res = 2; From a4b98139ee9b73c16aaf2fbbfc64b9dfb60d51bb Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 21 Dec 2023 02:04:54 +0100 Subject: [PATCH 064/186] Use bluetooth dualshock --- CMakeLists.txt | 4 +- dev_out.c | 2 +- rog_ally.c | 8 + rogue_enemy.h | 2 + virt_ds5.c | 992 +++++++++++++++++++++++++++++++++++++++++++++---- virt_ds5.h | 4 +- 6 files changed, 937 insertions(+), 75 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d662d5f..54aa180 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,7 +64,7 @@ add_executable(${ALLINONE_EXECUTABLE_NAME} set_property(TARGET ${ALLINONE_EXECUTABLE_NAME} PROPERTY C_STANDARD 17) -target_link_libraries(${ALLINONE_EXECUTABLE_NAME} PRIVATE Threads::Threads -levdev -ludev -lconfig -lm) +target_link_libraries(${ALLINONE_EXECUTABLE_NAME} PRIVATE Threads::Threads -levdev -ludev -lconfig -lm -lz) set_target_properties(${ALLINONE_EXECUTABLE_NAME} PROPERTIES LINKER_LANGUAGE C) @@ -80,7 +80,7 @@ install(TARGETS ${ROGUE_EXECUTABLE_NAME} DESTINATION bin) set_property(TARGET ${STRAY_EXECUTABLE_NAME} PROPERTY C_STANDARD 17) -target_link_libraries(${STRAY_EXECUTABLE_NAME} PRIVATE Threads::Threads -levdev -ludev -lconfig -lm) +target_link_libraries(${STRAY_EXECUTABLE_NAME} PRIVATE Threads::Threads -levdev -ludev -lconfig -lm -lz) set_target_properties(${STRAY_EXECUTABLE_NAME} PROPERTIES LINKER_LANGUAGE C) diff --git a/dev_out.c b/dev_out.c index 1fb944e..707efe0 100644 --- a/dev_out.c +++ b/dev_out.c @@ -427,7 +427,7 @@ void *dev_out_thread_func(void *ptr) { const int64_t gamepad_report_timing_us = 1250; if (current_gamepad == GAMEPAD_DUALSENSE) { - const int ds5_init_res = virt_dualsense_init(&controller_data.ds5); + const int ds5_init_res = virt_dualsense_init(&controller_data.ds5, true); if (ds5_init_res != 0) { fprintf(stderr, "Unable to initialize the DualSense device: %d\n", ds5_init_res); } else { diff --git a/rog_ally.c b/rog_ally.c index 5f2c0f8..3259efd 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1141,7 +1141,15 @@ static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** pl *platform_data = NULL; } +/** + * This function should use the following: + * pub static DBUS_NAME: &str = "org.asuslinux.Daemon"; + * pub static DBUS_PATH: &str = "/org/asuslinux/Daemon"; + * pub static DBUS_IFACE: &str = "org.asuslinux.Daemon"; + */ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, uint8_t g, uint8_t b, void* platform_data) { + + return 0; } diff --git a/rogue_enemy.h b/rogue_enemy.h index 00197be..a01f1f1 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -44,6 +44,8 @@ #include +#include + #define LSB_PER_RAD_S_2000_DEG_S ((double)0.001064724) #define LSB_PER_RAD_S_2000_DEG_S_STR "0.001064724" diff --git a/virt_ds5.c b/virt_ds5.c index e9b70e2..23dadc6 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -3,10 +3,6 @@ #include #include -#include -#include -#include -#include #define DS_FEATURE_REPORT_PAIRING_INFO 0x09 #define DS_FEATURE_REPORT_PAIRING_INFO_SIZE 20 @@ -19,6 +15,8 @@ #define DS_INPUT_REPORT_USB 0x01 #define DS_INPUT_REPORT_USB_SIZE 64 +#define DS_INPUT_REPORT_BT 0x31 +#define DS_INPUT_REPORT_BT_SIZE 78 #define DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT 0x02 @@ -29,37 +27,855 @@ #define DS5_SPEC_DELTA_TIME 4096.0f +static uint32_t le(uint32_t num) { + const uint32_t b0 = (num & 0x000000ff) << 24u; + const uint32_t b1 = (num & 0x0000ff00) << 8u; + const uint32_t b2 = (num & 0x00ff0000) >> 8u; + const uint32_t b3 = (num & 0xff000000) >> 24u; + + return b0 | b1 | b2 | b3; +} + +static uint32_t crc32_le(uint32_t crc_initial, const uint8_t *const buf, size_t len) { + return crc32(crc_initial ^ 0xffffffff, buf, len) ^ 0xffffffff; +} + +/* Seed values for DualShock4 / DualSense CRC32 for different report types. */ +static uint8_t PS_INPUT_CRC32_SEED = 0xA1; +static uint8_t PS_OUTPUT_CRC32_SEED = 0xA2; +static uint8_t PS_FEATURE_CRC32_SEED = 0xA3; + +#define DS5_EDGE_VERSION 256 +#define DS5_EDGE_VENDOR 0x054C +#define DS5_EDGE_PRODUCT 0x0DF2 + static const char* path = "/dev/uhid"; //static const char* const MAC_ADDR_STR = "e8:47:3a:d6:e7:74"; static const uint8_t MAC_ADDR[] = { 0x74, 0xe7, 0xd6, 0x3a, 0x47, 0xe8 }; static unsigned char rdesc[] = { - 0x05, 0x01, 0x09, 0x05, 0xA1, 0x01, 0x85, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, - 0x09, 0x33, 0x09, 0x34, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x06, 0x81, 0x02, 0x06, - 0x00, 0xFF, 0x09, 0x20, 0x95, 0x01, 0x81, 0x02, 0x05, 0x01, 0x09, 0x39, 0x15, 0x00, 0x25, 0x07, - 0x35, 0x00, 0x46, 0x3B, 0x01, 0x65, 0x14, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42, 0x65, 0x00, 0x05, - 0x09, 0x19, 0x01, 0x29, 0x0F, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0F, 0x81, 0x02, 0x06, - 0x00, 0xFF, 0x09, 0x21, 0x95, 0x0D, 0x81, 0x02, 0x06, 0x00, 0xFF, 0x09, 0x22, 0x15, 0x00, 0x26, - 0xFF, 0x00, 0x75, 0x08, 0x95, 0x34, 0x81, 0x02, 0x85, 0x02, 0x09, 0x23, 0x95, 0x3F, 0x91, 0x02, - 0x85, 0x05, 0x09, 0x33, 0x95, 0x28, 0xB1, 0x02, 0x85, 0x08, 0x09, 0x34, 0x95, 0x2F, 0xB1, 0x02, - 0x85, 0x09, 0x09, 0x24, 0x95, 0x13, 0xB1, 0x02, 0x85, 0x0A, 0x09, 0x25, 0x95, 0x1A, 0xB1, 0x02, - 0x85, 0x20, 0x09, 0x26, 0x95, 0x3F, 0xB1, 0x02, 0x85, 0x21, 0x09, 0x27, 0x95, 0x04, 0xB1, 0x02, - 0x85, 0x22, 0x09, 0x40, 0x95, 0x3F, 0xB1, 0x02, 0x85, 0x80, 0x09, 0x28, 0x95, 0x3F, 0xB1, 0x02, - 0x85, 0x81, 0x09, 0x29, 0x95, 0x3F, 0xB1, 0x02, 0x85, 0x82, 0x09, 0x2A, 0x95, 0x09, 0xB1, 0x02, - 0x85, 0x83, 0x09, 0x2B, 0x95, 0x3F, 0xB1, 0x02, 0x85, 0x84, 0x09, 0x2C, 0x95, 0x3F, 0xB1, 0x02, - 0x85, 0x85, 0x09, 0x2D, 0x95, 0x02, 0xB1, 0x02, 0x85, 0xA0, 0x09, 0x2E, 0x95, 0x01, 0xB1, 0x02, - 0x85, 0xE0, 0x09, 0x2F, 0x95, 0x3F, 0xB1, 0x02, 0x85, 0xF0, 0x09, 0x30, 0x95, 0x3F, 0xB1, 0x02, - 0x85, 0xF1, 0x09, 0x31, 0x95, 0x3F, 0xB1, 0x02, 0x85, 0xF2, 0x09, 0x32, 0x95, 0x34, 0xB1, 0x02, - 0x85, 0xF4, 0x09, 0x35, 0x95, 0x3F, 0xB1, 0x02, 0x85, 0xF5, 0x09, 0x36, 0x95, 0x03, 0xB1, 0x02, - 0x85, 0x60, 0x09, 0x41, 0x95, 0x3F, 0xB1, 0x02, 0x85, 0x61, 0x09, 0x42, 0xB1, 0x02, 0x85, 0x62, - 0x09, 0x43, 0xB1, 0x02, 0x85, 0x63, 0x09, 0x44, 0xB1, 0x02, 0x85, 0x64, 0x09, 0x45, 0xB1, 0x02, - 0x85, 0x65, 0x09, 0x46, 0xB1, 0x02, 0x85, 0x68, 0x09, 0x47, 0xB1, 0x02, 0x85, 0x70, 0x09, 0x48, - 0xB1, 0x02, 0x85, 0x71, 0x09, 0x49, 0xB1, 0x02, 0x85, 0x72, 0x09, 0x4A, 0xB1, 0x02, 0x85, 0x73, - 0x09, 0x4B, 0xB1, 0x02, 0x85, 0x74, 0x09, 0x4C, 0xB1, 0x02, 0x85, 0x75, 0x09, 0x4D, 0xB1, 0x02, - 0x85, 0x76, 0x09, 0x4E, 0xB1, 0x02, 0x85, 0x77, 0x09, 0x4F, 0xB1, 0x02, 0x85, 0x78, 0x09, 0x50, - 0xB1, 0x02, 0x85, 0x79, 0x09, 0x51, 0xB1, 0x02, 0x85, 0x7A, 0x09, 0x52, 0xB1, 0x02, 0x85, 0x7B, - 0x09, 0x53, 0xB1, 0x02, 0xC0 + 0x05, + 0x01, // Usage Page (Generic Desktop) 0 + 0x09, + 0x05, // Usage (Game Pad) 2 + 0xA1, + 0x01, // Collection (Application) 4 + 0x85, + 0x01, // Report ID (1) 6 + 0x09, + 0x30, // Usage (X) 8 + 0x09, + 0x31, // Usage (Y) 10 + 0x09, + 0x32, // Usage (Z) 12 + 0x09, + 0x35, // Usage (Rz) 14 + 0x09, + 0x33, // Usage (Rx) 16 + 0x09, + 0x34, // Usage (Ry) 18 + 0x15, + 0x00, // Logical Minimum (0) 20 + 0x26, + 0xFF, + 0x00, // Logical Maximum (255) 22 + 0x75, + 0x08, // Report Size (8) 25 + 0x95, + 0x06, // Report Count (6) 27 + 0x81, + 0x02, // Input (Data,Var,Abs) 29 + 0x06, + 0x00, + 0xFF, // Usage Page (Vendor Defined Page 1) 31 + 0x09, + 0x20, // Usage (Vendor Usage 0x20) 34 + 0x95, + 0x01, // Report Count (1) 36 + 0x81, + 0x02, // Input (Data,Var,Abs) 38 + 0x05, + 0x01, // Usage Page (Generic Desktop) 40 + 0x09, + 0x39, // Usage (Hat switch) 42 + 0x15, + 0x00, // Logical Minimum (0) 44 + 0x25, + 0x07, // Logical Maximum (7) 46 + 0x35, + 0x00, // Physical Minimum (0) 48 + 0x46, + 0x3B, + 0x01, // Physical Maximum (315) 50 + 0x65, + 0x14, // Unit (EnglishRotation: deg) 53 + 0x75, + 0x04, // Report Size (4) 55 + 0x95, + 0x01, // Report Count (1) 57 + 0x81, + 0x42, // Input (Data,Var,Abs,Null) 59 + 0x65, + 0x00, // Unit (None) 61 + 0x05, + 0x09, // Usage Page (Button) 63 + 0x19, + 0x01, // Usage Minimum (1) 65 + 0x29, + 0x0F, // Usage Maximum (15) 67 + 0x15, + 0x00, // Logical Minimum (0) 69 + 0x25, + 0x01, // Logical Maximum (1) 71 + 0x75, + 0x01, // Report Size (1) 73 + 0x95, + 0x0F, // Report Count (15) 75 + 0x81, + 0x02, // Input (Data,Var,Abs) 77 + 0x06, + 0x00, + 0xFF, // Usage Page (Vendor Defined Page 1) 79 + 0x09, + 0x21, // Usage (Vendor Usage 0x21) 82 + 0x95, + 0x0D, // Report Count (13) 84 + 0x81, + 0x02, // Input (Data,Var,Abs) 86 + 0x06, + 0x00, + 0xFF, // Usage Page (Vendor Defined Page 1) 88 + 0x09, + 0x22, // Usage (Vendor Usage 0x22) 91 + 0x15, + 0x00, // Logical Minimum (0) 93 + 0x26, + 0xFF, + 0x00, // Logical Maximum (255) 95 + 0x75, + 0x08, // Report Size (8) 98 + 0x95, + 0x34, // Report Count (52) 100 + 0x81, + 0x02, // Input (Data,Var,Abs) 102 + 0x85, + 0x02, // Report ID (2) 104 + 0x09, + 0x23, // Usage (Vendor Usage 0x23) 106 + 0x95, + 0x3F, // Report Count (63) 108 + 0x91, + 0x02, // Output (Data,Var,Abs) 110 + 0x85, + 0x05, // Report ID (5) 112 + 0x09, + 0x33, // Usage (Vendor Usage 0x33) 114 + 0x95, + 0x28, // Report Count (40) 116 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 118 + 0x85, + 0x08, // Report ID (8) 120 + 0x09, + 0x34, // Usage (Vendor Usage 0x34) 122 + 0x95, + 0x2F, // Report Count (47) 124 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 126 + 0x85, + 0x09, // Report ID (9) 128 + 0x09, + 0x24, // Usage (Vendor Usage 0x24) 130 + 0x95, + 0x13, // Report Count (19) 132 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 134 + 0x85, + 0x0A, // Report ID (10) 136 + 0x09, + 0x25, // Usage (Vendor Usage 0x25) 138 + 0x95, + 0x1A, // Report Count (26) 140 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 142 + 0x85, + 0x20, // Report ID (32) 144 + 0x09, + 0x26, // Usage (Vendor Usage 0x26) 146 + 0x95, + 0x3F, // Report Count (63) 148 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 150 + 0x85, + 0x21, // Report ID (33) 152 + 0x09, + 0x27, // Usage (Vendor Usage 0x27) 154 + 0x95, + 0x04, // Report Count (4) 156 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 158 + 0x85, + 0x22, // Report ID (34) 160 + 0x09, + 0x40, // Usage (Vendor Usage 0x40) 162 + 0x95, + 0x3F, // Report Count (63) 164 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 166 + 0x85, + 0x80, // Report ID (128) 168 + 0x09, + 0x28, // Usage (Vendor Usage 0x28) 170 + 0x95, + 0x3F, // Report Count (63) 172 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 174 + 0x85, + 0x81, // Report ID (129) 176 + 0x09, + 0x29, // Usage (Vendor Usage 0x29) 178 + 0x95, + 0x3F, // Report Count (63) 180 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 182 + 0x85, + 0x82, // Report ID (130) 184 + 0x09, + 0x2A, // Usage (Vendor Usage 0x2a) 186 + 0x95, + 0x09, // Report Count (9) 188 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 190 + 0x85, + 0x83, // Report ID (131) 192 + 0x09, + 0x2B, // Usage (Vendor Usage 0x2b) 194 + 0x95, + 0x3F, // Report Count (63) 196 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 198 + 0x85, + 0x84, // Report ID (132) 200 + 0x09, + 0x2C, // Usage (Vendor Usage 0x2c) 202 + 0x95, + 0x3F, // Report Count (63) 204 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 206 + 0x85, + 0x85, // Report ID (133) 208 + 0x09, + 0x2D, // Usage (Vendor Usage 0x2d) 210 + 0x95, + 0x02, // Report Count (2) 212 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 214 + 0x85, + 0xA0, // Report ID (160) 216 + 0x09, + 0x2E, // Usage (Vendor Usage 0x2e) 218 + 0x95, + 0x01, // Report Count (1) 220 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 222 + 0x85, + 0xE0, // Report ID (224) 224 + 0x09, + 0x2F, // Usage (Vendor Usage 0x2f) 226 + 0x95, + 0x3F, // Report Count (63) 228 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 230 + 0x85, + 0xF0, // Report ID (240) 232 + 0x09, + 0x30, // Usage (Vendor Usage 0x30) 234 + 0x95, + 0x3F, // Report Count (63) 236 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 238 + 0x85, + 0xF1, // Report ID (241) 240 + 0x09, + 0x31, // Usage (Vendor Usage 0x31) 242 + 0x95, + 0x3F, // Report Count (63) 244 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 246 + 0x85, + 0xF2, // Report ID (242) 248 + 0x09, + 0x32, // Usage (Vendor Usage 0x32) 250 + 0x95, + 0x34, // Report Count (52) 252 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 254 + 0x85, + 0xF4, // Report ID (244) 256 + 0x09, + 0x35, // Usage (Vendor Usage 0x35) 258 + 0x95, + 0x3F, // Report Count (63) 260 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 262 + 0x85, + 0xF5, // Report ID (245) 264 + 0x09, + 0x36, // Usage (Vendor Usage 0x36) 266 + 0x95, + 0x03, // Report Count (3) 268 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 270 + 0x85, + 0x60, // Report ID (96) 272 + 0x09, + 0x41, // Usage (Vendor Usage 0x41) 274 + 0x95, + 0x3F, // Report Count (63) 276 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 278 + 0x85, + 0x61, // Report ID (97) 280 + 0x09, + 0x42, // Usage (Vendor Usage 0x42) 282 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 284 + 0x85, + 0x62, // Report ID (98) 286 + 0x09, + 0x43, // Usage (Vendor Usage 0x43) 288 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 290 + 0x85, + 0x63, // Report ID (99) 292 + 0x09, + 0x44, // Usage (Vendor Usage 0x44) 294 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 296 + 0x85, + 0x64, // Report ID (100) 298 + 0x09, + 0x45, // Usage (Vendor Usage 0x45) 300 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 302 + 0x85, + 0x65, // Report ID (101) 304 + 0x09, + 0x46, // Usage (Vendor Usage 0x46) 306 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 308 + 0x85, + 0x68, // Report ID (104) 310 + 0x09, + 0x47, // Usage (Vendor Usage 0x47) 312 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 314 + 0x85, + 0x70, // Report ID (112) 316 + 0x09, + 0x48, // Usage (Vendor Usage 0x48) 318 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 320 + 0x85, + 0x71, // Report ID (113) 322 + 0x09, + 0x49, // Usage (Vendor Usage 0x49) 324 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 326 + 0x85, + 0x72, // Report ID (114) 328 + 0x09, + 0x4A, // Usage (Vendor Usage 0x4a) 330 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 332 + 0x85, + 0x73, // Report ID (115) 334 + 0x09, + 0x4B, // Usage (Vendor Usage 0x4b) 336 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 338 + 0x85, + 0x74, // Report ID (116) 340 + 0x09, + 0x4C, // Usage (Vendor Usage 0x4c) 342 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 344 + 0x85, + 0x75, // Report ID (117) 346 + 0x09, + 0x4D, // Usage (Vendor Usage 0x4d) 348 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 350 + 0x85, + 0x76, // Report ID (118) 352 + 0x09, + 0x4E, // Usage (Vendor Usage 0x4e) 354 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 356 + 0x85, + 0x77, // Report ID (119) 358 + 0x09, + 0x4F, // Usage (Vendor Usage 0x4f) 360 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 362 + 0x85, + 0x78, // Report ID (120) 364 + 0x09, + 0x50, // Usage (Vendor Usage 0x50) 366 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 368 + 0x85, + 0x79, // Report ID (121) 370 + 0x09, + 0x51, // Usage (Vendor Usage 0x51) 372 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 374 + 0x85, + 0x7A, // Report ID (122) 376 + 0x09, + 0x52, // Usage (Vendor Usage 0x52) 378 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 380 + 0x85, + 0x7B, // Report ID (123) 382 + 0x09, + 0x53, // Usage (Vendor Usage 0x53) 384 + 0xB1, + 0x02, // Feature (Data,Var,Abs) 386 + 0xC0, // End Collection 388 +}; + +static unsigned char rdesc_bt[] = { + 0x05, + 0x01, + 0x09, + 0x05, + 0xA1, + 0x01, + 0x85, + 0x01, + 0x09, + 0x30, + 0x09, + 0x31, + 0x09, + 0x32, + 0x09, + 0x35, + 0x15, + 0x00, + 0x26, + 0xFF, + 0x00, + 0x75, + 0x08, + 0x95, + 0x04, + 0x81, + 0x02, + 0x09, + 0x39, + 0x15, + 0x00, + 0x25, + 0x07, + 0x35, + 0x00, + 0x46, + 0x3B, + 0x01, + 0x65, + 0x14, + 0x75, + 0x04, + 0x95, + 0x01, + 0x81, + 0x42, + 0x65, + 0x00, + 0x05, + 0x09, + 0x19, + 0x01, + 0x29, + 0x0E, + 0x15, + 0x00, + 0x25, + 0x01, + 0x75, + 0x01, + 0x95, + 0x0E, + 0x81, + 0x02, + 0x75, + 0x06, + 0x95, + 0x01, + 0x81, + 0x01, + 0x05, + 0x01, + 0x09, + 0x33, + 0x09, + 0x34, + 0x15, + 0x00, + 0x26, + 0xFF, + 0x00, + 0x75, + 0x08, + 0x95, + 0x02, + 0x81, + 0x02, + 0x06, + 0x00, + 0xFF, + 0x15, + 0x00, + 0x26, + 0xFF, + 0x00, + 0x75, + 0x08, + 0x95, + 0x4D, + 0x85, + 0x31, + 0x09, + 0x31, + 0x91, + 0x02, + 0x09, + 0x3B, + 0x81, + 0x02, + 0x85, + 0x32, + 0x09, + 0x32, + 0x95, + 0x8D, + 0x91, + 0x02, + 0x85, + 0x33, + 0x09, + 0x33, + 0x95, + 0xCD, + 0x91, + 0x02, + 0x85, + 0x34, + 0x09, + 0x34, + 0x96, + 0x0D, + 0x01, + 0x91, + 0x02, + 0x85, + 0x35, + 0x09, + 0x35, + 0x96, + 0x4D, + 0x01, + 0x91, + 0x02, + 0x85, + 0x36, + 0x09, + 0x36, + 0x96, + 0x8D, + 0x01, + 0x91, + 0x02, + 0x85, + 0x37, + 0x09, + 0x37, + 0x96, + 0xCD, + 0x01, + 0x91, + 0x02, + 0x85, + 0x38, + 0x09, + 0x38, + 0x96, + 0x0D, + 0x02, + 0x91, + 0x02, + 0x85, + 0x39, + 0x09, + 0x39, + 0x96, + 0x22, + 0x02, + 0x91, + 0x02, + 0x06, + 0x80, + 0xFF, + 0x85, + 0x05, + 0x09, + 0x33, + 0x95, + 0x28, + 0xB1, + 0x02, + 0x85, + 0x08, + 0x09, + 0x34, + 0x95, + 0x2F, + 0xB1, + 0x02, + 0x85, + 0x09, + 0x09, + 0x24, + 0x95, + 0x13, + 0xB1, + 0x02, + 0x85, + 0x20, + 0x09, + 0x26, + 0x95, + 0x3F, + 0xB1, + 0x02, + 0x85, + 0x22, + 0x09, + 0x40, + 0x95, + 0x3F, + 0xB1, + 0x02, + 0x85, + 0x80, + 0x09, + 0x28, + 0x95, + 0x3F, + 0xB1, + 0x02, + 0x85, + 0x81, + 0x09, + 0x29, + 0x95, + 0x3F, + 0xB1, + 0x02, + 0x85, + 0x82, + 0x09, + 0x2A, + 0x95, + 0x09, + 0xB1, + 0x02, + 0x85, + 0x83, + 0x09, + 0x2B, + 0x95, + 0x3F, + 0xB1, + 0x02, + 0x85, + 0xF1, + 0x09, + 0x31, + 0x95, + 0x3F, + 0xB1, + 0x02, + 0x85, + 0xF2, + 0x09, + 0x32, + 0x95, + 0x34, + 0xB1, + 0x02, + 0x85, + 0xF0, + 0x09, + 0x30, + 0x95, + 0x3F, + 0xB1, + 0x02, + 0x85, + 0x60, + 0x09, + 0x41, + 0x95, + 0x3F, + 0xB1, + 0x02, + 0x85, + 0x61, + 0x09, + 0x42, + 0xB1, + 0x02, + 0x85, + 0x62, + 0x09, + 0x43, + 0xB1, + 0x02, + 0x85, + 0x63, + 0x09, + 0x44, + 0xB1, + 0x02, + 0x85, + 0x64, + 0x09, + 0x45, + 0xB1, + 0x02, + 0x85, + 0x65, + 0x09, + 0x46, + 0xB1, + 0x02, + 0x85, + 0x68, + 0x09, + 0x47, + 0xB1, + 0x02, + 0x85, + 0x70, + 0x09, + 0x48, + 0xB1, + 0x02, + 0x85, + 0x71, + 0x09, + 0x49, + 0xB1, + 0x02, + 0x85, + 0x72, + 0x09, + 0x4A, + 0xB1, + 0x02, + 0x85, + 0x73, + 0x09, + 0x4B, + 0xB1, + 0x02, + 0x85, + 0x74, + 0x09, + 0x4C, + 0xB1, + 0x02, + 0x85, + 0x75, + 0x09, + 0x4D, + 0xB1, + 0x02, + 0x85, + 0x76, + 0x09, + 0x4E, + 0xB1, + 0x02, + 0x85, + 0x77, + 0x09, + 0x4F, + 0xB1, + 0x02, + 0x85, + 0x78, + 0x09, + 0x50, + 0xB1, + 0x02, + 0x85, + 0x79, + 0x09, + 0x51, + 0xB1, + 0x02, + 0x85, + 0x7A, + 0x09, + 0x52, + 0xB1, + 0x02, + 0x85, + 0x7B, + 0x09, + 0x53, + 0xB1, + 0x02, + 0x85, + 0xF4, + 0x09, + 0x2C, + 0x95, + 0x3F, + 0xB1, + 0x02, + 0x85, + 0xF5, + 0x09, + 0x2D, + 0x95, + 0x07, + 0xB1, + 0x02, + 0x85, + 0xF6, + 0x09, + 0x2E, + 0x96, + 0x22, + 0x02, + 0xB1, + 0x02, + 0x85, + 0xF7, + 0x09, + 0x2F, + 0x95, + 0x07, + 0xB1, + 0x02, + 0xC0, + 0x00, }; static int uhid_write(int fd, const struct uhid_event *ev) @@ -79,19 +895,19 @@ static int uhid_write(int fd, const struct uhid_event *ev) } } -static int create(int fd) +static int create(int fd, bool bluetooth) { struct uhid_event ev; memset(&ev, 0, sizeof(ev)); ev.type = UHID_CREATE; strcpy((char*)ev.u.create.name, "Sony Corp. DualSense Edge wireless controller (PS5)"); - ev.u.create.rd_data = rdesc; - ev.u.create.rd_size = sizeof(rdesc); - ev.u.create.bus = BUS_USB; - ev.u.create.vendor = 0x054C; - ev.u.create.product = 0x0df2; - ev.u.create.version = 0; + ev.u.create.rd_data = bluetooth ? rdesc_bt : rdesc; + ev.u.create.rd_size = bluetooth ? sizeof(rdesc_bt) : sizeof(rdesc); + ev.u.create.bus = bluetooth ? BUS_BLUETOOTH : BUS_USB; + ev.u.create.vendor = DS5_EDGE_VENDOR; + ev.u.create.product = DS5_EDGE_PRODUCT; + ev.u.create.version = DS5_EDGE_VERSION; ev.u.create.country = 0; memset(&ev.u.create.uniq, 0, sizeof(ev.u.create.uniq)); memcpy(&ev.u.create.uniq, (void*)MAC_ADDR, sizeof(MAC_ADDR)); @@ -109,9 +925,10 @@ static void destroy(int fd) uhid_write(fd, &ev); } -int virt_dualsense_init(virt_dualsense_t *const out_gamepad) { +int virt_dualsense_init(virt_dualsense_t *const out_gamepad, bool bluetooth) { int ret = 0; + out_gamepad->bluetooth = bluetooth; out_gamepad->dt_sum = 0; out_gamepad->dt_buffer_current = 0; memset(out_gamepad->dt_buffer, 0, sizeof(out_gamepad->dt_buffer)); @@ -127,7 +944,7 @@ int virt_dualsense_init(virt_dualsense_t *const out_gamepad) { goto virt_dualshock_init_err; } - ret = create(out_gamepad->fd); + ret = create(out_gamepad->fd, bluetooth); if (ret) { fprintf(stderr, "Error creating uhid device: %d\n", ret); close(out_gamepad->fd); @@ -263,7 +1080,7 @@ int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *cons case UHID_GET_REPORT: //fprintf(stderr, "UHID_GET_REPORT from uhid-dev, report=%d\n", ev.u.get_report.rnum); if (ev.u.get_report.rnum == DS_FEATURE_REPORT_PAIRING_INFO) { - const struct uhid_event mac_addr_response = { + struct uhid_event mac_addr_response = { .type = UHID_GET_REPORT_REPLY, .u = { .get_report_reply = { @@ -281,9 +1098,15 @@ int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *cons } }; + if (gamepad->bluetooth) { + uint32_t crc = crc32_le(0xFFFFFFFFU, (const uint8_t*)&PS_FEATURE_CRC32_SEED, sizeof(PS_FEATURE_CRC32_SEED)); + crc = ~crc32_le(crc, (const Bytef *)&mac_addr_response.u.get_report_reply.data[0], mac_addr_response.u.get_report_reply.size - 4); + memcpy(&mac_addr_response.u.get_report_reply.data[mac_addr_response.u.get_report_reply.size - sizeof(crc)], &crc, sizeof(crc)); + } + uhid_write(fd, &mac_addr_response); } else if (ev.u.get_report.rnum == DS_FEATURE_REPORT_FIRMWARE_INFO) { - const struct uhid_event firmware_info_response = { + struct uhid_event firmware_info_response = { .type = UHID_GET_REPORT_REPLY, .u = { .get_report_reply = { @@ -301,9 +1124,15 @@ int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *cons } }; + if (gamepad->bluetooth) { + uint32_t crc = crc32_le(0xFFFFFFFFU, (const uint8_t*)&PS_FEATURE_CRC32_SEED, sizeof(PS_FEATURE_CRC32_SEED)); + crc = ~crc32_le(crc, (const Bytef *)&firmware_info_response.u.get_report_reply.data[0], firmware_info_response.u.get_report_reply.size - 4); + memcpy(&firmware_info_response.u.get_report_reply.data[firmware_info_response.u.get_report_reply.size - sizeof(crc)], &crc, sizeof(crc)); + } + uhid_write(fd, &firmware_info_response); } else if (ev.u.get_report.rnum == DS_FEATURE_REPORT_CALIBRATION) { - struct uhid_event firmware_info_response = { + struct uhid_event calibration_response = { .type = UHID_GET_REPORT_REPLY, .u = { .get_report_reply = { @@ -320,7 +1149,13 @@ int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *cons } }; - uhid_write(fd, &firmware_info_response); + if (gamepad->bluetooth) { + uint32_t crc = crc32_le(0xFFFFFFFFU, (const uint8_t*)&PS_FEATURE_CRC32_SEED, sizeof(PS_FEATURE_CRC32_SEED)); + crc = ~crc32_le(crc, (const Bytef *)&calibration_response.u.get_report_reply.data[0], calibration_response.u.get_report_reply.size - 4); + memcpy(&calibration_response.u.get_report_reply.data[calibration_response.u.get_report_reply.size - sizeof(crc)], &crc, sizeof(crc)); + } + + uhid_write(fd, &calibration_response); } break; @@ -407,20 +1242,22 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c const int16_t a_z = (int16_t)(-1) * in_device_status->raw_accel[2]; // Swap Y and Z - out_buf[0] = DS_INPUT_REPORT_USB; // [00] report ID (0x01) - out_buf[1] = ((uint64_t)((int64_t)in_device_status->joystick_positions[0][0] + (int64_t)32768) >> (uint64_t)8); // L stick, X axis - out_buf[2] = ((uint64_t)((int64_t)in_device_status->joystick_positions[0][1] + (int64_t)32768) >> (uint64_t)8); // L stick, Y axis - out_buf[3] = ((uint64_t)((int64_t)in_device_status->joystick_positions[1][0] + (int64_t)32768) >> (uint64_t)8); // R stick, X axis - out_buf[4] = ((uint64_t)((int64_t)in_device_status->joystick_positions[1][1] + (int64_t)32768) >> (uint64_t)8); // R stick, Y axis - out_buf[5] = in_device_status->l2_trigger; // Z - out_buf[6] = in_device_status->r2_trigger; // RZ - out_buf[7] = gamepad->seq_num++; // seq_number - out_buf[8] = (in_device_status->square ? 0x10 : 0x00) | + out_buf[0] = gamepad->bluetooth ? DS_INPUT_REPORT_BT : DS_INPUT_REPORT_USB; // [00] report ID (0x01) + + uint8_t *const out_shifted_buf = gamepad->bluetooth ? &out_buf[1] : &out_buf[0]; + out_shifted_buf[1] = ((uint64_t)((int64_t)in_device_status->joystick_positions[0][0] + (int64_t)32768) >> (uint64_t)8); // L stick, X axis + out_shifted_buf[2] = ((uint64_t)((int64_t)in_device_status->joystick_positions[0][1] + (int64_t)32768) >> (uint64_t)8); // L stick, Y 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[5] = in_device_status->l2_trigger; // Z + out_shifted_buf[6] = in_device_status->r2_trigger; // RZ + out_shifted_buf[7] = gamepad->seq_num++; // seq_number + out_shifted_buf[8] = (in_device_status->square ? 0x10 : 0x00) | (in_device_status->cross ? 0x20 : 0x00) | (in_device_status->circle ? 0x40 : 0x00) | (in_device_status->triangle ? 0x80 : 0x00) | (uint8_t)ds5_dpad_from_gamepad(in_device_status->dpad); - out_buf[9] = (in_device_status->l1 ? 0x01 : 0x00) | + out_shifted_buf[9] = (in_device_status->l1 ? 0x01 : 0x00) | (in_device_status->r1 ? 0x02 : 0x00) | (in_device_status->l2_trigger >= 225 ? 0x04 : 0x00) | (in_device_status->r2_trigger >= 225 ? 0x08 : 0x00) | @@ -430,7 +1267,7 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c (in_device_status->r3 ? 0x80 : 0x00); // mic button press is 0x04, touchpad press is 0x02 - out_buf[10] = (in_device_status->l5 ? 0x40 : 0x00) | + out_shifted_buf[10] = (in_device_status->l5 ? 0x40 : 0x00) | (in_device_status->r5 ? 0x80 : 0x00) | (in_device_status->l4 ? 0x10 : 0x00) | (in_device_status->r4 ? 0x20 : 0x00) | @@ -439,40 +1276,53 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c //buf[11] = ; //buf[12] = 0x20; // [12] battery level | this is called sensor_temparature in the kernel driver but is never used... - memcpy(&out_buf[16], &g_x, sizeof(int16_t)); - memcpy(&out_buf[18], &g_y, sizeof(int16_t)); - memcpy(&out_buf[20], &g_z, sizeof(int16_t)); - memcpy(&out_buf[22], &a_x, sizeof(int16_t)); - memcpy(&out_buf[24], &a_y, sizeof(int16_t)); - memcpy(&out_buf[26], &a_z, sizeof(int16_t)); - memcpy(&out_buf[28], ×tamp, sizeof(timestamp)); + memcpy(&out_shifted_buf[16], &g_x, sizeof(int16_t)); + memcpy(&out_shifted_buf[18], &g_y, sizeof(int16_t)); + memcpy(&out_shifted_buf[20], &g_z, sizeof(int16_t)); + memcpy(&out_shifted_buf[22], &a_x, sizeof(int16_t)); + memcpy(&out_shifted_buf[24], &a_y, sizeof(int16_t)); + memcpy(&out_shifted_buf[26], &a_z, sizeof(int16_t)); + memcpy(&out_shifted_buf[28], ×tamp, sizeof(timestamp)); // TODO: when touch is detected send 0x7F, when not 0x80 - out_buf[33] = 0x80; //touch0 active? - out_buf[37] = 0x80; //touch1 active? + out_shifted_buf[33] = 0x80; //touch0 active? + out_shifted_buf[37] = 0x80; //touch1 active? /* buf[30] = 0x1b; // no headset attached */ - out_buf[62] = 0x80; // IDK... it seems constant... - out_buf[57] = 0x80; // IDK... it seems constant... - out_buf[53] = 0x80; // IDK... it seems constant... - out_buf[48] = 0x80; // IDK... it seems constant... - out_buf[35] = 0x80; // IDK... it seems constant... - out_buf[44] = 0x80; // IDK... it seems constant... + out_shifted_buf[62] = 0x80; // IDK... it seems constant... + out_shifted_buf[57] = 0x80; // IDK... it seems constant... + out_shifted_buf[53] = 0x80; // IDK... it seems constant... + out_shifted_buf[48] = 0x80; // IDK... it seems constant... + out_shifted_buf[35] = 0x80; // IDK... it seems constant... + out_shifted_buf[44] = 0x80; // IDK... it seems constant... + + if (gamepad->bluetooth) { + uint32_t crc = crc32_le(0xFFFFFFFFU, (const uint8_t*)&PS_FEATURE_CRC32_SEED, sizeof(PS_FEATURE_CRC32_SEED)); + crc = ~crc32_le(crc, (const Bytef *)&out_shifted_buf[0], DS_INPUT_REPORT_BT_SIZE - 4); + memcpy(&out_shifted_buf[DS_INPUT_REPORT_BT_SIZE - sizeof(crc)], &crc, sizeof(crc)); + } } -int virt_dualsense_send(virt_dualsense_t *const gamepad, uint8_t *const out_buf) { +int virt_dualsense_send(virt_dualsense_t *const gamepad, uint8_t *const out_shifted_buf) { struct uhid_event l = { .type = UHID_INPUT2, .u = { .input2 = { - .size = 64, + .size = gamepad->bluetooth ? DS_INPUT_REPORT_BT_SIZE : DS_INPUT_REPORT_USB_SIZE, } } }; + - memcpy(&l.u.input2.data[0], &out_buf[0], l.u.input2.size); + memcpy(&l.u.input2.data[0], &out_shifted_buf[0], l.u.input2.size); + + if (gamepad->bluetooth) { + uint32_t crc = crc32_le(0xFFFFFFFFU, (const uint8_t*)&PS_INPUT_CRC32_SEED, sizeof(PS_INPUT_CRC32_SEED)); + crc = ~crc32_le(crc, (const uint8_t *)&l.u.input2.data[0], l.u.input2.size - 4); + memcpy(&l.u.input2.data[l.u.input2.size - sizeof(crc)], &crc, sizeof(crc)); + } return uhid_write(gamepad->fd, &l); } diff --git a/virt_ds5.h b/virt_ds5.h index 61a4c5d..6f9d63d 100644 --- a/virt_ds5.h +++ b/virt_ds5.h @@ -13,6 +13,8 @@ typedef struct virt_dualsense { bool debug; + bool bluetooth; + uint8_t seq_num; uint32_t dt_sum; @@ -23,7 +25,7 @@ typedef struct virt_dualsense { uint64_t last_time; } virt_dualsense_t; -int virt_dualsense_init(virt_dualsense_t *const gamepad); +int virt_dualsense_init(virt_dualsense_t *const gamepad, bool bluetooth); int virt_dualsense_get_fd(virt_dualsense_t *const gamepad); From a4981b2ad396b7295b1e8247195670fce89abedb Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 21 Dec 2023 03:13:36 +0100 Subject: [PATCH 065/186] fix the command recognition while in bluetooth mode --- virt_ds5.c | 69 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index 23dadc6..6b90fe2 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -17,6 +17,10 @@ #define DS_INPUT_REPORT_USB_SIZE 64 #define DS_INPUT_REPORT_BT 0x31 #define DS_INPUT_REPORT_BT_SIZE 78 +#define DS_OUTPUT_REPORT_USB 0x02 +#define DS_OUTPUT_REPORT_USB_SIZE 63 +#define DS_OUTPUT_REPORT_BT 0x31 +#define DS_OUTPUT_REPORT_BT_SIZE 78 #define DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT 0x02 @@ -1011,43 +1015,68 @@ int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *cons if (ev.u.output.rtype != UHID_OUTPUT_REPORT) return 0; - if (ev.u.output.size != 48) { - fprintf(stderr, "Invalid data length: got %d, expected 48\n", (int)ev.u.output.size); + if (ev.u.output.size == 48) { + fprintf(stderr, "Ignored a 48 bytes report on purpose\n"); + } + + //if (ev.u.output.size != 48) + if ( + (!gamepad->bluetooth) && (ev.u.output.size != DS_OUTPUT_REPORT_USB_SIZE) && + (gamepad->bluetooth) && (ev.u.output.size != DS_OUTPUT_REPORT_BT_SIZE) + ) { + fprintf( + stderr, + "Invalid data length: got %d, expected %d\n", + (int)ev.u.output.size, + (gamepad->bluetooth) ? DS_OUTPUT_REPORT_BT_SIZE : DS_OUTPUT_REPORT_USB_SIZE + ); return 0; } // first byte is report-id which is 0x01 - if (ev.u.output.data[0] != 0x02) { - fprintf(stderr, "Unrecognised report-id: got 0x%x expected 0x02\n", (int)ev.u.output.data[0]); + if ( + (!gamepad->bluetooth) && (ev.u.output.data[0] != DS_OUTPUT_REPORT_USB) && + (gamepad->bluetooth) && (ev.u.output.data[0] != DS_OUTPUT_REPORT_BT) + ) { + fprintf( + stderr, + "Unrecognised report-id: got 0x%x expected 0x%x\n", + (int)ev.u.output.data[0], + (gamepad->bluetooth) ? DS_OUTPUT_REPORT_BT : DS_OUTPUT_REPORT_USB + ); return 0; } - const uint8_t valid_flag0 = ev.u.output.data[1]; - const uint8_t valid_flag1 = ev.u.output.data[2]; + // When using bluetooth, the first byte after the reportID is uint8_t seq_tag, + // while the next one is uint8_t tag, following bytes are the same. + const uint8_t *const common_report = (gamepad->bluetooth) ? &ev.u.output.data[3] : &ev.u.output.data[1]; + + const uint8_t valid_flag0 = common_report[0]; + const uint8_t valid_flag1 = common_report[1]; // 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]; + const uint8_t motor_right = common_report[2]; + const uint8_t motor_left = common_report[3]; // 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]; + const uint8_t reserved[4] = { common_report[4], common_report[5], common_report[6], common_report[7]}; + const uint8_t mute_button_led = common_report[8]; - uint8_t power_save_control = ev.u.output.data[10]; + uint8_t power_save_control = common_report[9]; 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]; + uint8_t valid_flag2 = common_report[38]; + uint8_t reserved3[2] = {common_report[39], common_report[40]}; + uint8_t lightbar_setup = common_report[41]; + uint8_t led_brightness = common_report[42]; + uint8_t player_leds = common_report[43]; + uint8_t lightbar_red = common_report[44]; + uint8_t lightbar_green = common_report[45]; + uint8_t lightbar_blue = common_report[46]; if ((valid_flag0 & DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT)) { - if (/*(valid_flag2 & DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2) ||*/ (valid_flag0 & DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION)) { + if ((valid_flag2 & DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2) || (valid_flag0 & DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION)) { out_device_status->motors_intensity[0] = motor_left; out_device_status->motors_intensity[1] = motor_right; ++out_device_status->rumble_events_count; From 2aa79bb180c19532a5d116cee2457f077f09c756 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 21 Dec 2023 21:42:12 +0100 Subject: [PATCH 066/186] Use monotonic clock for gyroscope data --- dev_in.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dev_in.c b/dev_in.c index 17edd8d..208b311 100644 --- a/dev_in.c +++ b/dev_in.c @@ -84,8 +84,13 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const uint8_t data[32]; +/* struct timeval read_time; gettimeofday(&read_time, NULL); +*/ + + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); res = read(dev_iio_get_buffer_fd(in_iio->iiodev), &data[0], sizeof(data)); if (res == -1) { @@ -104,7 +109,9 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const messages[0].type = GAMEPAD_SET_ELEMENT; messages[0].data.gamepad_set.element = GAMEPAD_ACCELEROMETER; - messages[0].data.gamepad_set.status.accel.sample_time = read_time; + messages[1].data.gamepad_set.status.accel.sample_time.tv_sec = now.tv_sec; + messages[1].data.gamepad_set.status.accel.sample_time.tv_usec = now.tv_nsec / 1000; + //messages[0].data.gamepad_set.status.accel.sample_time = read_time; //messages[0].data.gamepad_set.status.accel.x = scan_elements[0]; //messages[0].data.gamepad_set.status.accel.y = scan_elements[1]; //messages[0].data.gamepad_set.status.accel.z = scan_elements[2]; @@ -114,7 +121,9 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const messages[1].type = GAMEPAD_SET_ELEMENT; messages[1].data.gamepad_set.element = GAMEPAD_GYROSCOPE; - messages[1].data.gamepad_set.status.gyro.sample_time = read_time; + messages[1].data.gamepad_set.status.gyro.sample_time.tv_sec = now.tv_sec; + messages[1].data.gamepad_set.status.gyro.sample_time.tv_usec = now.tv_nsec / 1000; + //messages[0].data.gamepad_set.status.gyro.sample_time = read_time; //messages[1].data.gamepad_set.status.gyro.x = scan_elements[3]; //messages[1].data.gamepad_set.status.gyro.y = scan_elements[4]; //messages[1].data.gamepad_set.status.gyro.z = scan_elements[5]; From 464d257a23a787b0dc22ea795a22efbc546b1ac7 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 21 Dec 2023 21:46:51 +0100 Subject: [PATCH 067/186] performance test --- dev_out.c | 9 +++++++++ rog_ally.c | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/dev_out.c b/dev_out.c index 707efe0..2d319ab 100644 --- a/dev_out.c +++ b/dev_out.c @@ -45,6 +45,8 @@ static void handle_incoming_message_gamepad_set( const in_message_gamepad_set_element_t *const msg_payload, gamepad_status_t *const inout_gamepad ) { + static int numpackets = 0; + static uint64_t lastsec = 0; switch (msg_payload->element) { case GAMEPAD_BTN_CROSS: { if (!in_settings->nintendo_layout) { @@ -179,6 +181,13 @@ static void handle_incoming_message_gamepad_set( break; } case GAMEPAD_GYROSCOPE: { + if (msg_payload->status.gyro.sample_time.tv_sec != lastsec) { + printf("%d\n", numpackets); + lastsec = msg_payload->status.gyro.sample_time.tv_sec; + numpackets = 0; + } else { + ++numpackets; + } inout_gamepad->last_gyro_motion_time = msg_payload->status.gyro.sample_time; inout_gamepad->raw_gyro[0] = msg_payload->status.gyro.x; inout_gamepad->raw_gyro[1] = msg_payload->status.gyro.y; diff --git a/rog_ally.c b/rog_ally.c index 3259efd..7de3eea 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1180,10 +1180,10 @@ input_dev_composite_t rc71l_composite = { &in_asus_kb_1_dev, &in_asus_kb_2_dev, &in_asus_kb_3_dev, - &nkey_dev, - &timer_dev, + //&nkey_dev, + //&timer_dev, }, - .dev_count = 7, + .dev_count = 5, .init_fn = rc71l_platform_init, .deinit_fn = rc71l_platform_deinit, .leds_fn = rc71l_platform_leds, From 6f9a16e694f3b0d0094b161ad40a3a886cabcc47 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 21 Dec 2023 22:08:08 +0100 Subject: [PATCH 068/186] Remove performance measurement printf --- dev_out.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_out.c b/dev_out.c index 2d319ab..5566383 100644 --- a/dev_out.c +++ b/dev_out.c @@ -182,7 +182,7 @@ static void handle_incoming_message_gamepad_set( } case GAMEPAD_GYROSCOPE: { if (msg_payload->status.gyro.sample_time.tv_sec != lastsec) { - printf("%d\n", numpackets); + //printf("%d\n", numpackets); lastsec = msg_payload->status.gyro.sample_time.tv_sec; numpackets = 0; } else { From 80331fa85a745bdd4adbcc5831e82ca959061876 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 21 Dec 2023 22:55:00 +0100 Subject: [PATCH 069/186] additional checks for fd > 0 --- dev_out.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/dev_out.c b/dev_out.c index 5566383..05c850e 100644 --- a/dev_out.c +++ b/dev_out.c @@ -474,7 +474,7 @@ void *dev_out_thread_func(void *ptr) { const int64_t kbd_time_diff_usecs = get_timediff_usec(&keyboard_last_hid_report_sent, &now); gettimeofday(&now, NULL); - if (gamepad_time_diff_usecs >= gamepad_report_timing_us) { + if ((current_gamepad_fd > 0) && (gamepad_time_diff_usecs >= gamepad_report_timing_us)) { gamepad_last_hid_report_sent = now; if (current_gamepad == GAMEPAD_DUALSENSE) { @@ -487,7 +487,7 @@ void *dev_out_thread_func(void *ptr) { // this does reset the for, ensuring every other device has nothing to say continue; - } else if (mouse_time_diff_usecs >= mouse_report_timing_us) { + } else if ((current_mouse_fd > 0) && (mouse_time_diff_usecs >= mouse_report_timing_us)) { mouse_last_hid_report_sent = now; virt_mouse_send(&mouse_data, &dev_out_data->dev_stats.mouse, &now); @@ -498,7 +498,7 @@ void *dev_out_thread_func(void *ptr) { // this does reset the for, ensuring every other device has nothing to say continue; - } else if (kbd_time_diff_usecs >= kbd_report_timing_us) { + } else if ((current_keyboard_fd > 0) && (kbd_time_diff_usecs >= kbd_report_timing_us)) { keyboard_last_hid_report_sent = now; virt_kbd_send(&keyboard_data, &dev_out_data->dev_stats.kbd, &now); @@ -689,17 +689,23 @@ void *dev_out_thread_func(void *ptr) { } // close the gamepad output device - if (current_gamepad == GAMEPAD_DUALSENSE) { - virt_dualsense_close(&controller_data.ds5); - } else if (current_gamepad == GAMEPAD_DUALSHOCK) { - virt_dualshock_close(&controller_data.ds4); + if (current_gamepad_fd > 0) { + if (current_gamepad == GAMEPAD_DUALSENSE) { + virt_dualsense_close(&controller_data.ds5); + } else if (current_gamepad == GAMEPAD_DUALSHOCK) { + virt_dualshock_close(&controller_data.ds4); + } } // close the mouse device - virt_mouse_close(&mouse_data); + if (current_mouse_fd > 0) { + virt_mouse_close(&mouse_data); + } // close the keyboard device - virt_kbd_close(&keyboard_data); + if (current_keyboard_fd > 0) { + virt_kbd_close(&keyboard_data); + } // end communication if (dev_out_data->communication.type == ipc_server_sockets) { From 4825ee8e17199162b3156411984aa3b0e8e661c7 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 21 Dec 2023 22:55:58 +0100 Subject: [PATCH 070/186] perf testing: exclude mouse and keyboard --- dev_out.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev_out.c b/dev_out.c index 05c850e..a205f0a 100644 --- a/dev_out.c +++ b/dev_out.c @@ -414,22 +414,22 @@ void *dev_out_thread_func(void *ptr) { } controller_data; virt_mouse_t mouse_data; - const int mouse_init_res = virt_mouse_init(&mouse_data); + /*const int mouse_init_res = virt_mouse_init(&mouse_data); if (mouse_init_res < 0) { fprintf(stderr, "Unable to initialize virtual mouse -- will continue regardless\n"); } else { current_mouse_fd = virt_mouse_get_fd(&mouse_data); printf("Mouse initialized: fd=%d\n", current_mouse_fd); - } + }*/ virt_kbd_t keyboard_data; - const int kbd_init_res = virt_kbd_init(&keyboard_data); + /*const int kbd_init_res = virt_kbd_init(&keyboard_data); if (kbd_init_res < 0) { fprintf(stderr, "Unable to initialize virtual keyboard -- will continue regardless\n"); } else { current_keyboard_fd = virt_kbd_get_fd(&keyboard_data); printf("Keyboard initialized: fd=%d\n", current_keyboard_fd); - } + }*/ const int64_t kbd_report_timing_us = 1125; const int64_t mouse_report_timing_us = 950; From 458ef9f07d187ad45932285bc1d2d90c9d9f041a Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 23 Dec 2023 23:59:33 +0100 Subject: [PATCH 071/186] works with both kernel and sdl2 while using bt --- dev_out.c | 21 ++--- virt_ds5.c | 13 ++- virt_kbd.c | 251 +++++++++++++++------------------------------------ virt_mouse.c | 78 ++++++++-------- 4 files changed, 133 insertions(+), 230 deletions(-) diff --git a/dev_out.c b/dev_out.c index a205f0a..2707747 100644 --- a/dev_out.c +++ b/dev_out.c @@ -374,13 +374,8 @@ static void handle_incoming_message( } } -int64_t get_timediff_usec(const struct timeval *const past, const struct timeval *const now) { - struct timeval tdiff; - timersub(now, past, &tdiff); - - //const int64_t sgn = ((now->tv_sec > past->tv_sec) || ((now->tv_sec == past->tv_sec) && (now->tv_usec > past->tv_usec))) ? -1 : +1; - - return (int64_t)(tdiff.tv_sec) * (int64_t)1000000 + (int64_t)(tdiff.tv_usec); +int64_t get_timediff_usec(const struct timespec *const start, const struct timespec *const end) { + return (end->tv_sec - start->tv_sec) * 1000000000LL + (end->tv_nsec - start->tv_nsec); } void *dev_out_thread_func(void *ptr) { @@ -453,12 +448,12 @@ void *dev_out_thread_func(void *ptr) { } } - struct timeval now = {0}; - gettimeofday(&now, NULL); + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); - struct timeval gamepad_last_hid_report_sent = now; - struct timeval mouse_last_hid_report_sent = now; - struct timeval keyboard_last_hid_report_sent = now; + struct timespec gamepad_last_hid_report_sent = now; + struct timespec mouse_last_hid_report_sent = now; + struct timespec keyboard_last_hid_report_sent = now; uint8_t tmp_buf[256]; @@ -473,7 +468,7 @@ void *dev_out_thread_func(void *ptr) { const int64_t mouse_time_diff_usecs = get_timediff_usec(&mouse_last_hid_report_sent, &now); const int64_t kbd_time_diff_usecs = get_timediff_usec(&keyboard_last_hid_report_sent, &now); - gettimeofday(&now, NULL); + clock_gettime(CLOCK_MONOTONIC, &now); if ((current_gamepad_fd > 0) && (gamepad_time_diff_usecs >= gamepad_report_timing_us)) { gamepad_last_hid_report_sent = now; diff --git a/virt_ds5.c b/virt_ds5.c index 6b90fe2..65f3969 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1037,7 +1037,7 @@ int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *cons // first byte is report-id which is 0x01 if ( (!gamepad->bluetooth) && (ev.u.output.data[0] != DS_OUTPUT_REPORT_USB) && - (gamepad->bluetooth) && (ev.u.output.data[0] != DS_OUTPUT_REPORT_BT) + (gamepad->bluetooth) && ((ev.u.output.data[0] != DS_OUTPUT_REPORT_BT) && (ev.u.output.data[0] < 0x10)) ) { fprintf( stderr, @@ -1050,7 +1050,16 @@ int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *cons // When using bluetooth, the first byte after the reportID is uint8_t seq_tag, // while the next one is uint8_t tag, following bytes are the same. - const uint8_t *const common_report = (gamepad->bluetooth) ? &ev.u.output.data[3] : &ev.u.output.data[1]; + size_t offset = 1; + if ((gamepad->bluetooth) && (ev.u.output.data[0] > 0x10)) { + offset = 2; + } else if ((gamepad->bluetooth) && (ev.u.output.data[0] == 0x02)) { + offset = 3; + } else if ((gamepad->bluetooth) && (ev.u.output.data[0] == 0x01)) { + offset = 1; + } + + const uint8_t *const common_report = &ev.u.output.data[offset]; const uint8_t valid_flag0 = common_report[0]; const uint8_t valid_flag1 = common_report[1]; diff --git a/virt_kbd.c b/virt_kbd.c index b535124..7a7ca3a 100644 --- a/virt_kbd.c +++ b/virt_kbd.c @@ -99,376 +99,252 @@ int virt_kbd_get_fd(virt_kbd_t *const kbd) { int virt_kbd_send(virt_kbd_t *const kbd, keyboard_status_t *const status, struct timeval *const now) { int res = 0; - struct timeval syn_time; - gettimeofday(&syn_time, NULL); + size_t events_count = 0; + struct input_event events[12]; struct input_event tmp_ev; - gettimeofday(&tmp_ev.time, NULL); - if (now != NULL) { - tmp_ev.time = *now; - } tmp_ev.type = EV_KEY; if (status->q != kbd->prev_q) { tmp_ev.code = KEY_Q; tmp_ev.value = kbd->prev_q = status->q; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->w != kbd->prev_w) { tmp_ev.code = KEY_W; tmp_ev.value = kbd->prev_w = status->w; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->e != kbd->prev_e) { tmp_ev.code = KEY_E; tmp_ev.value = kbd->prev_e = status->e; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->r != kbd->prev_r) { tmp_ev.code = KEY_R; tmp_ev.value = kbd->prev_r = status->r; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->t != kbd->prev_t) { tmp_ev.code = KEY_T; tmp_ev.value = kbd->prev_t = status->t; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->y != kbd->prev_y) { tmp_ev.code = KEY_Y; tmp_ev.value = kbd->prev_y = status->y; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->u != kbd->prev_u) { tmp_ev.code = KEY_U; tmp_ev.value = kbd->prev_u = status->u; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->i != kbd->prev_i) { tmp_ev.code = KEY_I; tmp_ev.value = kbd->prev_i = status->i; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->o != kbd->prev_o) { tmp_ev.code = KEY_O; tmp_ev.value = kbd->prev_o = status->o; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->p != kbd->prev_p) { tmp_ev.code = KEY_P; tmp_ev.value = kbd->prev_p = status->p; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->a != kbd->prev_a) { tmp_ev.code = KEY_A; tmp_ev.value = kbd->prev_a = status->a; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->s != kbd->prev_s) { tmp_ev.code = KEY_S; tmp_ev.value = kbd->prev_s = status->s; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->d != kbd->prev_d) { tmp_ev.code = KEY_D; tmp_ev.value = kbd->prev_d = status->d; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->f != kbd->prev_f) { tmp_ev.code = KEY_F; tmp_ev.value = kbd->prev_f = status->f; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->g != kbd->prev_g) { tmp_ev.code = KEY_G; tmp_ev.value = kbd->prev_g = status->g; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->h != kbd->prev_h) { tmp_ev.code = KEY_H; tmp_ev.value = kbd->prev_h = status->h; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->j != kbd->prev_j) { tmp_ev.code = KEY_J; tmp_ev.value = kbd->prev_j = status->j; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->k != kbd->prev_k) { tmp_ev.code = KEY_K; tmp_ev.value = kbd->prev_k = status->k; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->l != kbd->prev_l) { tmp_ev.code = KEY_L; tmp_ev.value = kbd->prev_l = status->l; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->z != kbd->prev_z) { tmp_ev.code = KEY_Z; tmp_ev.value = kbd->prev_z = status->z; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->x != kbd->prev_x) { tmp_ev.code = KEY_X; tmp_ev.value = kbd->prev_x = status->x; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->c != kbd->prev_c) { tmp_ev.code = KEY_C; tmp_ev.value = kbd->prev_c = status->c; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->v != kbd->prev_v) { tmp_ev.code = KEY_V; tmp_ev.value = kbd->prev_v = status->v; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->b != kbd->prev_b) { tmp_ev.code = KEY_B; tmp_ev.value = kbd->prev_b = status->b; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->n != kbd->prev_n) { tmp_ev.code = KEY_N; tmp_ev.value = kbd->prev_n = status->n; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->m != kbd->prev_m) { tmp_ev.code = KEY_M; tmp_ev.value = kbd->prev_m = status->m; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->num_0 != kbd->prev_num_0) { tmp_ev.code = KEY_0; tmp_ev.value = kbd->prev_num_0 = status->num_0; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->num_1 != kbd->prev_num_1) { tmp_ev.code = KEY_1; tmp_ev.value = kbd->prev_num_1 = status->num_1; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->num_2 != kbd->prev_num_2) { tmp_ev.code = KEY_2; tmp_ev.value = kbd->prev_num_2 = status->num_2; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->num_3 != kbd->prev_num_3) { tmp_ev.code = KEY_3; tmp_ev.value = kbd->prev_num_3 = status->num_3; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->num_4 != kbd->prev_num_4) { tmp_ev.code = KEY_4; tmp_ev.value = kbd->prev_num_4 = status->num_4; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->num_5 != kbd->prev_num_5) { tmp_ev.code = KEY_5; tmp_ev.value = kbd->prev_num_5 = status->num_5; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->num_6 != kbd->prev_num_6) { tmp_ev.code = KEY_6; tmp_ev.value = kbd->prev_num_6 = status->num_6; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->num_7 != kbd->prev_num_7) { tmp_ev.code = KEY_7; tmp_ev.value = kbd->prev_num_7 = status->num_7; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->num_8 != kbd->prev_num_8) { tmp_ev.code = KEY_8; tmp_ev.value = kbd->prev_num_8 = status->num_8; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->num_9 != kbd->prev_num_9) { tmp_ev.code = KEY_9; tmp_ev.value = kbd->prev_num_9 = status->num_9; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->lctrl != kbd->prev_lctrl) { tmp_ev.code = KEY_LEFTCTRL; tmp_ev.value = kbd->prev_lctrl = status->lctrl; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->up != kbd->prev_up) { tmp_ev.code = KEY_UP; tmp_ev.value = kbd->prev_up = status->up; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->down != kbd->prev_down) { tmp_ev.code = KEY_DOWN; tmp_ev.value = kbd->prev_down = status->down; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->left != kbd->prev_left) { tmp_ev.code = KEY_LEFT; tmp_ev.value = kbd->prev_left = status->left; - if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_kbd_send_err; - } + events[events_count++] = tmp_ev; } if (status->right != kbd->prev_right) { @@ -493,18 +369,39 @@ int virt_kbd_send(virt_kbd_t *const kbd, keyboard_status_t *const status, struct } #endif - syn_time.tv_usec += 1; - const struct input_event syn_ev = { - .code = SYN_REPORT, - .type = EV_SYN, - .value = 0, - .time = syn_time, - }; - const ssize_t sync_written = write(kbd->fd, (void*)&syn_ev, sizeof(syn_ev)); - if (sync_written != sizeof(syn_ev)) { - fprintf(stderr, "Error in sync: written %ld bytes out of %ld\n", sync_written, sizeof(syn_ev)); - } + if (events_count > 0) { + struct timeval t; + if (now != NULL) { + t = *now; + } else { + gettimeofday(&t, NULL); + } + + struct input_event syn_ev = { + .code = SYN_REPORT, + .type = EV_SYN, + .value = 0, + .time = t, + }; + syn_ev.time.tv_usec += 1; + events[events_count++] = syn_ev; + + for (size_t i = 0; i < events_count; ++i) { + if (i != (events_count - 1)) { + events[i].time = t; + } + + const ssize_t sync_written = write(kbd->fd, (void*)&events[i], sizeof(struct input_event)); + if (sync_written != sizeof(syn_ev)) { + fprintf(stderr, "Error in sync: written %ld bytes out of %ld\n", sync_written, sizeof(syn_ev)); + res = errno; + res = res < 0 ? res : -1*res; + res = res == 0 ? -EIO : res; + goto virt_kbd_send_err; + } + } + } virt_kbd_send_err: return res; } diff --git a/virt_mouse.c b/virt_mouse.c index 24374f8..ff02eaf 100644 --- a/virt_mouse.c +++ b/virt_mouse.c @@ -66,33 +66,22 @@ int virt_mouse_get_fd(virt_mouse_t *const mouse) { int virt_mouse_send(virt_mouse_t *const mouse, mouse_status_t *const status, struct timeval *const now) { int res = 0; - struct timeval syn_time; - gettimeofday(&syn_time, NULL); + size_t events_count = 0; + struct input_event events[12]; struct input_event tmp_ev; - gettimeofday(&tmp_ev.time, NULL); - if (now != NULL) { - tmp_ev.time = *now; - } - tmp_ev.type = EV_REL; if (status->x != 0) { tmp_ev.code = REL_X; tmp_ev.value = status->x; - if (write(mouse->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_mouse_send_err; - } + events[events_count++] = tmp_ev; } if (status->y != 0) { tmp_ev.code = REL_Y; tmp_ev.value = status->y; - if (write(mouse->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_mouse_send_err; - } + events[events_count++] = tmp_ev; } tmp_ev.type = EV_KEY; @@ -101,30 +90,21 @@ int virt_mouse_send(virt_mouse_t *const mouse, mouse_status_t *const status, str mouse->prev_btn_left = status->btn_left; tmp_ev.code = BTN_LEFT; tmp_ev.value = status->btn_left; - if (write(mouse->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_mouse_send_err; - } + events[events_count++] = tmp_ev; } if (status->btn_middle != mouse->prev_btn_middle) { mouse->prev_btn_middle = status->btn_middle; tmp_ev.code = BTN_MIDDLE; tmp_ev.value = status->btn_middle; - if (write(mouse->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_mouse_send_err; - } + events[events_count++] = tmp_ev; } if (status->btn_right != mouse->prev_btn_right) { mouse->prev_btn_right = status->btn_right; tmp_ev.code = BTN_RIGHT; tmp_ev.value = status->btn_right; - if (write(mouse->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { - res = errno < 0 ? errno : -1 * errno; - goto virt_mouse_send_err; - } + events[events_count++] = tmp_ev; } #if 0 @@ -140,17 +120,39 @@ int virt_mouse_send(virt_mouse_t *const mouse, mouse_status_t *const status, str } #endif - syn_time.tv_usec += 1; - const struct input_event syn_ev = { - .code = SYN_REPORT, - .type = EV_SYN, - .value = 0, - .time = syn_time, - }; - const ssize_t sync_written = write(mouse->fd, (void*)&syn_ev, sizeof(syn_ev)); - if (sync_written != sizeof(syn_ev)) { - fprintf(stderr, "Error in sync: written %ld bytes out of %ld\n", sync_written, sizeof(syn_ev)); - } + if (events_count > 0) { + struct timeval t; + if (now != NULL) { + t = *now; + } else { + gettimeofday(&t, NULL); + } + + struct input_event syn_ev = { + .code = SYN_REPORT, + .type = EV_SYN, + .value = 0, + .time = t, + }; + syn_ev.time.tv_usec += 1; + + events[events_count++] = syn_ev; + + for (size_t i = 0; i < events_count; ++i) { + if (i != (events_count - 1)) { + events[i].time = t; + } + + const ssize_t sync_written = write(mouse->fd, (void*)&events[i], sizeof(struct input_event)); + if (sync_written != sizeof(syn_ev)) { + fprintf(stderr, "Error in sync: written %ld bytes out of %ld\n", sync_written, sizeof(syn_ev)); + res = errno; + res = res < 0 ? res : -1*res; + res = res == 0 ? -EIO : res; + goto virt_mouse_send_err; + } + } + } virt_mouse_send_err: return res; From f351427a0581a6b5e32581b25ef7e30a7884ffb5 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 24 Dec 2023 00:08:18 +0100 Subject: [PATCH 072/186] do not fail on no fd --- dev_out.c | 29 ++++++++++++++++++++--------- devices_status.c | 8 +++++--- devices_status.h | 2 +- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/dev_out.c b/dev_out.c index 2707747..fbaeb76 100644 --- a/dev_out.c +++ b/dev_out.c @@ -485,7 +485,7 @@ void *dev_out_thread_func(void *ptr) { } else if ((current_mouse_fd > 0) && (mouse_time_diff_usecs >= mouse_report_timing_us)) { mouse_last_hid_report_sent = now; - virt_mouse_send(&mouse_data, &dev_out_data->dev_stats.mouse, &now); + virt_mouse_send(&mouse_data, &dev_out_data->dev_stats.mouse, NULL); // reset mouse movements now dev_out_data->dev_stats.mouse.x = 0; @@ -496,7 +496,7 @@ void *dev_out_thread_func(void *ptr) { } else if ((current_keyboard_fd > 0) && (kbd_time_diff_usecs >= kbd_report_timing_us)) { keyboard_last_hid_report_sent = now; - virt_kbd_send(&keyboard_data, &dev_out_data->dev_stats.kbd, &now); + virt_kbd_send(&keyboard_data, &dev_out_data->dev_stats.kbd, NULL); // this does reset the for, ensuring every other device has nothing to say continue; @@ -525,7 +525,7 @@ void *dev_out_thread_func(void *ptr) { FD_SET(current_mouse_fd, &read_fds); } - if (current_mouse_fd > 0) { + if (current_keyboard_fd > 0) { FD_SET(current_keyboard_fd, &read_fds); } @@ -533,12 +533,23 @@ void *dev_out_thread_func(void *ptr) { FD_SET(current_gamepad_fd, &read_fds); } - const int64_t timeout_gamepad_time_diff_usecs = gamepad_report_timing_us - gamepad_time_diff_usecs; - const int64_t timeout_mouse_time_diff_usecs = mouse_report_timing_us - mouse_time_diff_usecs; - const int64_t timeout_kbd_time_diff_usecs = kbd_report_timing_us - kbd_time_diff_usecs; + const int64_t timeout_gamepad_time_diff_usecs = (current_gamepad_fd > 0) ? gamepad_report_timing_us - gamepad_time_diff_usecs : 5000; + const int64_t timeout_mouse_time_diff_usecs = (current_mouse_fd > 0) ? mouse_report_timing_us - mouse_time_diff_usecs : 5000; + const int64_t timeout_kbd_time_diff_usecs = (current_keyboard_fd > 0) ? kbd_report_timing_us - kbd_time_diff_usecs : 5000; - int64_t next_timing_out_device_diff_usecs = timeout_kbd_time_diff_usecs < timeout_mouse_time_diff_usecs ? timeout_kbd_time_diff_usecs : timeout_mouse_time_diff_usecs; - next_timing_out_device_diff_usecs = next_timing_out_device_diff_usecs < timeout_gamepad_time_diff_usecs ? next_timing_out_device_diff_usecs : timeout_gamepad_time_diff_usecs; + int64_t next_timing_out_device_diff_usecs = 5000; + + if ((timeout_kbd_time_diff_usecs > 0) && (timeout_kbd_time_diff_usecs < next_timing_out_device_diff_usecs)) { + next_timing_out_device_diff_usecs = timeout_kbd_time_diff_usecs; + } + + if ((timeout_mouse_time_diff_usecs > 0) && (timeout_mouse_time_diff_usecs < next_timing_out_device_diff_usecs)) { + next_timing_out_device_diff_usecs = timeout_mouse_time_diff_usecs; + } + + if ((timeout_gamepad_time_diff_usecs > 0) && (timeout_gamepad_time_diff_usecs < next_timing_out_device_diff_usecs)) { + next_timing_out_device_diff_usecs = timeout_gamepad_time_diff_usecs; + } // calculate the shortest timeout between one of the multiple device will needs to send out its hid report struct timeval timeout = { @@ -547,7 +558,7 @@ void *dev_out_thread_func(void *ptr) { }; int ready_fds = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout); - gamepad_status_qam_quirk_ext_time(&dev_out_data->dev_stats.gamepad, &now); + gamepad_status_qam_quirk_ext_time(&dev_out_data->dev_stats.gamepad); if (ready_fds == -1) { const int err = errno; diff --git a/devices_status.c b/devices_status.c index ddd1b97..f852b15 100644 --- a/devices_status.c +++ b/devices_status.c @@ -163,13 +163,15 @@ void gamepad_status_qam_quirk(gamepad_status_t *const gamepad_stats) { } } -void gamepad_status_qam_quirk_ext_time(gamepad_status_t *const gamepad_stats, struct timeval *now) { +void gamepad_status_qam_quirk_ext_time(gamepad_status_t *const gamepad_stats) { static struct timeval press_time; if (gamepad_stats->flags & GAMEPAD_STATUS_FLAGS_PRESS_AND_REALEASE_CENTER) { + struct timeval now; + gettimeofday(&now, NULL); // Calculate elapsed time in milliseconds - const int64_t elapsed_time = (now->tv_sec - press_time.tv_sec) * 1000 + - (now->tv_usec - press_time.tv_usec) / 1000; + const int64_t elapsed_time = (now.tv_sec - press_time.tv_sec) * 1000 + + (now.tv_usec - press_time.tv_usec) / 1000; if (gamepad_stats->center) { // If the center button is pressed and at least X ms have passed diff --git a/devices_status.h b/devices_status.h index e32f42d..8543f89 100644 --- a/devices_status.h +++ b/devices_status.h @@ -113,4 +113,4 @@ void devices_status_init(devices_status_t *const stats); void gamepad_status_qam_quirk(gamepad_status_t *const gamepad_stats); -void gamepad_status_qam_quirk_ext_time(gamepad_status_t *const gamepad_stats, struct timeval *now); +void gamepad_status_qam_quirk_ext_time(gamepad_status_t *const gamepad_stats); From 7498f90f1a0b4a0884f574d4b48da295753594cd Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 24 Dec 2023 02:08:12 +0100 Subject: [PATCH 073/186] too much time --- dev_out.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev_out.c b/dev_out.c index fbaeb76..6b4bd4e 100644 --- a/dev_out.c +++ b/dev_out.c @@ -533,11 +533,11 @@ void *dev_out_thread_func(void *ptr) { FD_SET(current_gamepad_fd, &read_fds); } - const int64_t timeout_gamepad_time_diff_usecs = (current_gamepad_fd > 0) ? gamepad_report_timing_us - gamepad_time_diff_usecs : 5000; - const int64_t timeout_mouse_time_diff_usecs = (current_mouse_fd > 0) ? mouse_report_timing_us - mouse_time_diff_usecs : 5000; - const int64_t timeout_kbd_time_diff_usecs = (current_keyboard_fd > 0) ? kbd_report_timing_us - kbd_time_diff_usecs : 5000; + const int64_t timeout_gamepad_time_diff_usecs = (current_gamepad_fd > 0) ? gamepad_report_timing_us - gamepad_time_diff_usecs : 500; + const int64_t timeout_mouse_time_diff_usecs = (current_mouse_fd > 0) ? mouse_report_timing_us - mouse_time_diff_usecs : 500; + const int64_t timeout_kbd_time_diff_usecs = (current_keyboard_fd > 0) ? kbd_report_timing_us - kbd_time_diff_usecs : 500; - int64_t next_timing_out_device_diff_usecs = 5000; + int64_t next_timing_out_device_diff_usecs = 500; if ((timeout_kbd_time_diff_usecs > 0) && (timeout_kbd_time_diff_usecs < next_timing_out_device_diff_usecs)) { next_timing_out_device_diff_usecs = timeout_kbd_time_diff_usecs; From cca9a4b375e17c180d7b5a2062ffe645f5274cc4 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 24 Dec 2023 02:58:01 +0100 Subject: [PATCH 074/186] restore virtual mouse and keyboard --- dev_out.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev_out.c b/dev_out.c index 6b4bd4e..30aee0d 100644 --- a/dev_out.c +++ b/dev_out.c @@ -409,22 +409,22 @@ void *dev_out_thread_func(void *ptr) { } controller_data; virt_mouse_t mouse_data; - /*const int mouse_init_res = virt_mouse_init(&mouse_data); + const int mouse_init_res = virt_mouse_init(&mouse_data); if (mouse_init_res < 0) { fprintf(stderr, "Unable to initialize virtual mouse -- will continue regardless\n"); } else { current_mouse_fd = virt_mouse_get_fd(&mouse_data); printf("Mouse initialized: fd=%d\n", current_mouse_fd); - }*/ + } virt_kbd_t keyboard_data; - /*const int kbd_init_res = virt_kbd_init(&keyboard_data); + const int kbd_init_res = virt_kbd_init(&keyboard_data); if (kbd_init_res < 0) { fprintf(stderr, "Unable to initialize virtual keyboard -- will continue regardless\n"); } else { current_keyboard_fd = virt_kbd_get_fd(&keyboard_data); printf("Keyboard initialized: fd=%d\n", current_keyboard_fd); - }*/ + } const int64_t kbd_report_timing_us = 1125; const int64_t mouse_report_timing_us = 950; From 82fab22cffdaff30a412cffbabe568934c2b2fca Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 25 Dec 2023 20:25:46 +0100 Subject: [PATCH 075/186] restore vibration and brightness value --- CMakeLists.txt | 11 ++++-- rog_ally.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++---- rogue_enemy.h | 2 ++ 3 files changed, 96 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54aa180..5bf77b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,13 @@ set(ROGUE_EXECUTABLE_NAME "rogue-enemy") set(STRAY_EXECUTABLE_NAME "stray-ally") set(ALLINONE_EXECUTABLE_NAME "allynone") +find_package(PkgConfig REQUIRED) # Include functions provided by PkgConfig module. + +pkg_check_modules(DBUS REQUIRED dbus-1) # This calls pkgconfig with appropriate arguments +# Use results of pkg_check_modules() call. +include_directories(${DBUS_INCLUDE_DIRS}) +link_directories(${DBUS_LIBRARY_DIRS}) + set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) @@ -64,7 +71,7 @@ add_executable(${ALLINONE_EXECUTABLE_NAME} set_property(TARGET ${ALLINONE_EXECUTABLE_NAME} PROPERTY C_STANDARD 17) -target_link_libraries(${ALLINONE_EXECUTABLE_NAME} PRIVATE Threads::Threads -levdev -ludev -lconfig -lm -lz) +target_link_libraries(${ALLINONE_EXECUTABLE_NAME} PRIVATE Threads::Threads ${DBUS_LIBRARIES} -levdev -ludev -lconfig -lm -lz) set_target_properties(${ALLINONE_EXECUTABLE_NAME} PROPERTIES LINKER_LANGUAGE C) @@ -72,7 +79,7 @@ install(TARGETS ${ALLINONE_EXECUTABLE_NAME} DESTINATION bin) set_property(TARGET ${ROGUE_EXECUTABLE_NAME} PROPERTY C_STANDARD 17) -target_link_libraries(${ROGUE_EXECUTABLE_NAME} PRIVATE Threads::Threads -levdev -ludev -lconfig -lm) +target_link_libraries(${ROGUE_EXECUTABLE_NAME} PRIVATE Threads::Threads ${DBUS_LIBRARIES} -levdev -ludev -lconfig -lm) set_target_properties(${ROGUE_EXECUTABLE_NAME} PROPERTIES LINKER_LANGUAGE C) diff --git a/rog_ally.c b/rog_ally.c index 7de3eea..70843bb 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -3,8 +3,6 @@ #include "dev_hidraw.h" #include "message.h" #include "xbox360.h" -#include -#include enum rc71l_leds_mode { ROG_ALLY_MODE_STATIC = 0, @@ -49,10 +47,24 @@ typedef struct rc71l_asus_kbd_user_data { struct udev *udev; } rc71l_asus_kbd_user_data_t; +typedef struct rc71l_timer_user_data { + struct rc71l_platform* parent; + +} rc71l_timer_user_data_t; + +rc71l_timer_user_data_t timer_user_data; + typedef struct rc71l_platform { rc71l_asus_kbd_user_data_t* kbd_user_data; rc71l_xbox360_user_data_t* xbox360_user_data; + + rc71l_timer_user_data_t* timer_data; + + DBusError dbus_error; + + DBusConnection * dbus_conn; + } rc71l_platform_t; static rc71l_asus_kbd_user_data_t asus_userdata = {}; @@ -81,6 +93,8 @@ static rc71l_xbox360_user_data_t controller_user_data = { static rc71l_platform_t hw_platform = { .kbd_user_data = &asus_userdata, .xbox360_user_data = &controller_user_data, + .timer_data = &timer_user_data, + .dbus_conn = NULL, }; static char* find_kernel_sysfs_device_path(struct udev *udev) { @@ -1118,6 +1132,7 @@ static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platf // setup asus keyboard(s) user_data platform->kbd_user_data->parent = platform; platform->xbox360_user_data->parent = platform; + platform->timer_data->parent = platform; platform->kbd_user_data->udev = udev_new(); if (platform->kbd_user_data->udev == NULL) { fprintf(stderr, "Unable to initialize udev\n"); @@ -1125,6 +1140,8 @@ static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platf goto rc71l_platform_init_err; } + dbus_error_init(&platform->dbus_error); + res = 0; rc71l_platform_init_err: @@ -1134,8 +1151,13 @@ rc71l_platform_init_err: static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** platform_data) { rc71l_platform_t *const platform = (rc71l_platform_t *)(*platform_data); - if (platform->kbd_user_data != NULL) { - udev_unref(platform->kbd_user_data->udev); + if (platform_data != NULL) { + if (platform->kbd_user_data != NULL) { + udev_unref(platform->kbd_user_data->udev); + } + + // Close the D-Bus connection + dbus_connection_close(platform->dbus_conn); } *platform_data = NULL; @@ -1148,12 +1170,68 @@ static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** pl * pub static DBUS_IFACE: &str = "org.asuslinux.Daemon"; */ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, uint8_t g, uint8_t b, void* platform_data) { + rc71l_platform_t *const platform = (rc71l_platform_t*)platform_data; + uint32_t new_brightness = (r << 24) | (g << 16) | (b << 8) | (3); + + if (platform_data == NULL) { + return 0; + } + + // Replace "org.asuslinux.Daemon" and "/org/asuslinux/Aura" with the actual service and object paths + const char *service_name = "org.asuslinux.Daemon"; + const char *object_path = "/org/asuslinux/Aura"; + const char *interface_name = "org.asuslinux.Aura"; + + // Replace "Brightness" with the actual property name + const char *property_name = "Brightness"; + + // Build the D-Bus message to set the property + DBusMessage *const message = dbus_message_new_method_call(service_name, object_path, interface_name, "SetProperty"); + if (!message) { + fprintf(stderr, "Error creating D-Bus message\n"); + return -ENOMEM; + } + + // Append the property name and the new value to the message + dbus_message_append_args(message, DBUS_TYPE_STRING, &property_name, DBUS_TYPE_UINT32, &new_brightness, DBUS_TYPE_INVALID); + + // Send the message + DBusMessage *reply = dbus_connection_send_with_reply_and_block(platform->dbus_conn, message, -1, &platform->dbus_error); + dbus_message_unref(message); + + if (!reply || dbus_error_is_set(&platform->dbus_error)) { + fprintf(stderr, "D-Bus method call error: %s\n", platform->dbus_error.message); + dbus_error_free(&platform->dbus_error); + return -EIO; + } + + // Handle the reply if needed + + return 0; } int rc71l_timer_map(const dev_in_settings_t *const conf, int timer_fd, uint64_t expirations, in_message_t *const messages, size_t messages_len, void* user_data) { + rc71l_timer_user_data_t *const timer_data = (rc71l_timer_user_data_t*)user_data; + rc71l_platform_t *const platform_data = timer_data->parent; + + if (platform_data == NULL) { + return 0; + } + + + // try to connect + if (platform_data->dbus_conn == NULL) { + platform_data->dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &platform_data->dbus_error); + if (dbus_error_is_set(&platform_data->dbus_error)) { + fprintf(stderr, "DBus error connection : %s -- %s \n", platform_data->dbus_error.name, platform_data->dbus_error.message); + dbus_error_free(&platform_data->dbus_error); + return 0; + } + } + return 0; } @@ -1165,7 +1243,7 @@ input_dev_t timer_dev = { .ticktime_ms = 60, } }, - .user_data = NULL, + .user_data = &timer_user_data, .map = { .timer_callbacks = { .map_fn = rc71l_timer_map, @@ -1181,9 +1259,9 @@ input_dev_composite_t rc71l_composite = { &in_asus_kb_2_dev, &in_asus_kb_3_dev, //&nkey_dev, - //&timer_dev, + &timer_dev, }, - .dev_count = 5, + .dev_count = 6, .init_fn = rc71l_platform_init, .deinit_fn = rc71l_platform_deinit, .leds_fn = rc71l_platform_leds, diff --git a/rogue_enemy.h b/rogue_enemy.h index a01f1f1..5ccb243 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -46,6 +46,8 @@ #include +#include + #define LSB_PER_RAD_S_2000_DEG_S ((double)0.001064724) #define LSB_PER_RAD_S_2000_DEG_S_STR "0.001064724" From 17afabd24cb1efb1dd7aad4c91b49c3963c85685 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 25 Dec 2023 20:31:25 +0100 Subject: [PATCH 076/186] Try to connect to dbus --- rog_ally.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 70843bb..ac6fedc 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1186,6 +1186,16 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u // Replace "Brightness" with the actual property name const char *property_name = "Brightness"; + // try to connect + if (platform->dbus_conn == NULL) { + platform->dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &platform->dbus_error); + if (dbus_error_is_set(&platform->dbus_error)) { + fprintf(stderr, "DBus error connection : %s -- %s \n", platform->dbus_error.name, platform->dbus_error.message); + dbus_error_free(&platform->dbus_error); + return 0; + } + } + // Build the D-Bus message to set the property DBusMessage *const message = dbus_message_new_method_call(service_name, object_path, interface_name, "SetProperty"); if (!message) { @@ -1222,15 +1232,7 @@ int rc71l_timer_map(const dev_in_settings_t *const conf, int timer_fd, uint64_t } - // try to connect - if (platform_data->dbus_conn == NULL) { - platform_data->dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &platform_data->dbus_error); - if (dbus_error_is_set(&platform_data->dbus_error)) { - fprintf(stderr, "DBus error connection : %s -- %s \n", platform_data->dbus_error.name, platform_data->dbus_error.message); - dbus_error_free(&platform_data->dbus_error); - return 0; - } - } + return 0; } From 566ab8b93a3f6bd868892d02f2bebb234ec94089 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 25 Dec 2023 21:35:11 +0100 Subject: [PATCH 077/186] changed the problematic interface name --- rog_ally.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rog_ally.c b/rog_ally.c index ac6fedc..7caad99 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1181,7 +1181,7 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u // Replace "org.asuslinux.Daemon" and "/org/asuslinux/Aura" with the actual service and object paths const char *service_name = "org.asuslinux.Daemon"; const char *object_path = "/org/asuslinux/Aura"; - const char *interface_name = "org.asuslinux.Aura"; + const char *interface_name = "org.asuslinux.Daemon"; // Replace "Brightness" with the actual property name const char *property_name = "Brightness"; From fe11a9f5b6e4faa23f11893433cc87726e4e48e7 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 25 Dec 2023 23:03:52 +0100 Subject: [PATCH 078/186] Change set method --- rog_ally.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rog_ally.c b/rog_ally.c index 7caad99..f78860d 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1197,7 +1197,7 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u } // Build the D-Bus message to set the property - DBusMessage *const message = dbus_message_new_method_call(service_name, object_path, interface_name, "SetProperty"); + DBusMessage *const message = dbus_message_new_method_call(service_name, object_path, interface_name, "Set"); if (!message) { fprintf(stderr, "Error creating D-Bus message\n"); return -ENOMEM; From acd59cecf33ab7b43640ae6b3a5d9df249ace209 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 26 Dec 2023 14:40:21 +0100 Subject: [PATCH 079/186] retry to change properties --- rog_ally.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index f78860d..106ded8 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1181,7 +1181,8 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u // Replace "org.asuslinux.Daemon" and "/org/asuslinux/Aura" with the actual service and object paths const char *service_name = "org.asuslinux.Daemon"; const char *object_path = "/org/asuslinux/Aura"; - const char *interface_name = "org.asuslinux.Daemon"; + const char *interface_name = "org.freedesktop.DBus.Properties"; + const char *target_interface_name = "org.asuslinux.Daemon"; // Replace "Brightness" with the actual property name const char *property_name = "Brightness"; @@ -1204,7 +1205,7 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u } // Append the property name and the new value to the message - dbus_message_append_args(message, DBUS_TYPE_STRING, &property_name, DBUS_TYPE_UINT32, &new_brightness, DBUS_TYPE_INVALID); + dbus_message_append_args(message, DBUS_TYPE_STRING, &target_interface_name, DBUS_TYPE_STRING, &property_name, DBUS_TYPE_UINT32, &new_brightness, DBUS_TYPE_INVALID); // Send the message DBusMessage *reply = dbus_connection_send_with_reply_and_block(platform->dbus_conn, message, -1, &platform->dbus_error); From 95ce2a687b0b25444def349c311ebc491a6a4f58 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 26 Dec 2023 14:52:26 +0100 Subject: [PATCH 080/186] hopefully this works --- rog_ally.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 106ded8..2df0bda 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1172,7 +1172,7 @@ static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** pl static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, uint8_t g, uint8_t b, void* platform_data) { rc71l_platform_t *const platform = (rc71l_platform_t*)platform_data; - uint32_t new_brightness = (r << 24) | (g << 16) | (b << 8) | (3); + dbus_uint32_t new_brightness = (r << 24) | (g << 16) | (b << 8) | (3); if (platform_data == NULL) { return 0; @@ -1205,7 +1205,23 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u } // Append the property name and the new value to the message - dbus_message_append_args(message, DBUS_TYPE_STRING, &target_interface_name, DBUS_TYPE_STRING, &property_name, DBUS_TYPE_UINT32, &new_brightness, DBUS_TYPE_INVALID); + dbus_message_append_args(message, DBUS_TYPE_STRING, &target_interface_name, DBUS_TYPE_STRING, &property_name, DBUS_TYPE_INVALID); + + // Initialize an iterator for the message arguments + DBusMessageIter iter; + dbus_message_iter_init_append(message, &iter); + + dbus_message_iter_append_basic(&iter, DBUS_TYPE_VARIANT, "u"); + + // Open the variant container + DBusMessageIter variantIter; + dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "u", &variantIter); + + // Append the uint32 value to the variant container + dbus_message_iter_append_basic(&variantIter, DBUS_TYPE_UINT32, &new_brightness); + + // Close the variant container + dbus_message_iter_close_container(&iter, &variantIter); // Send the message DBusMessage *reply = dbus_connection_send_with_reply_and_block(platform->dbus_conn, message, -1, &platform->dbus_error); @@ -1214,12 +1230,14 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u if (!reply || dbus_error_is_set(&platform->dbus_error)) { fprintf(stderr, "D-Bus method call error: %s\n", platform->dbus_error.message); dbus_error_free(&platform->dbus_error); + dbus_message_unref(message); return -EIO; } // Handle the reply if needed - + // Free the D-Bus message + dbus_message_unref(message); return 0; } From 6abee8e0e8ad05c40bee676cd55de3f2587d2064 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 26 Dec 2023 14:55:09 +0100 Subject: [PATCH 081/186] well... --- rog_ally.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 2df0bda..9768750 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1211,8 +1211,6 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u DBusMessageIter iter; dbus_message_iter_init_append(message, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_VARIANT, "u"); - // Open the variant container DBusMessageIter variantIter; dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "u", &variantIter); From 8021eba1e4d72cda0adb0f8124655eee444b2fb8 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 26 Dec 2023 15:00:57 +0100 Subject: [PATCH 082/186] wtf... --- rog_ally.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 9768750..bd4a27e 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1205,21 +1205,7 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u } // Append the property name and the new value to the message - dbus_message_append_args(message, DBUS_TYPE_STRING, &target_interface_name, DBUS_TYPE_STRING, &property_name, DBUS_TYPE_INVALID); - - // Initialize an iterator for the message arguments - DBusMessageIter iter; - dbus_message_iter_init_append(message, &iter); - - // Open the variant container - DBusMessageIter variantIter; - dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "u", &variantIter); - - // Append the uint32 value to the variant container - dbus_message_iter_append_basic(&variantIter, DBUS_TYPE_UINT32, &new_brightness); - - // Close the variant container - dbus_message_iter_close_container(&iter, &variantIter); + dbus_message_append_args(message, DBUS_TYPE_STRING, &target_interface_name, DBUS_TYPE_STRING, &property_name, DBUS_TYPE_VARIANT, "v", DBUS_TYPE_UINT32, &new_brightness, DBUS_TYPE_INVALID); // Send the message DBusMessage *reply = dbus_connection_send_with_reply_and_block(platform->dbus_conn, message, -1, &platform->dbus_error); @@ -1235,7 +1221,7 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u // Handle the reply if needed // Free the D-Bus message - dbus_message_unref(message); + //dbus_message_unref(message); return 0; } From 2bcbb4d9fadf041c926d7a87b4c13664e71ee716 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 26 Dec 2023 15:05:54 +0100 Subject: [PATCH 083/186] .... --- rog_ally.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/rog_ally.c b/rog_ally.c index bd4a27e..7b52e71 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1205,7 +1205,25 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u } // Append the property name and the new value to the message - dbus_message_append_args(message, DBUS_TYPE_STRING, &target_interface_name, DBUS_TYPE_STRING, &property_name, DBUS_TYPE_VARIANT, "v", DBUS_TYPE_UINT32, &new_brightness, DBUS_TYPE_INVALID); + //dbus_message_append_args(message, DBUS_TYPE_STRING, &target_interface_name, DBUS_TYPE_STRING, &property_name, DBUS_TYPE_INVALID); + + // Initialize an iterator for the message arguments + DBusMessageIter iter; + dbus_message_iter_init_append(message, &iter); + + dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &target_interface_name); + + dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property_name); + + // Open the variant container + DBusMessageIter variantIter; + dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "u", &variantIter); + + // Append the uint32 value to the variant container + dbus_message_iter_append_basic(&variantIter, DBUS_TYPE_UINT32, &new_brightness); + + // Close the variant container + dbus_message_iter_close_container(&iter, &variantIter); // Send the message DBusMessage *reply = dbus_connection_send_with_reply_and_block(platform->dbus_conn, message, -1, &platform->dbus_error); From 5b5592b0a7866b03dd300a2e5a1eabca843fe5f3 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 26 Dec 2023 15:27:57 +0100 Subject: [PATCH 084/186] Restore hidraw set leds --- rog_ally.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 7b52e71..5c2a430 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1172,6 +1172,8 @@ static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** pl static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, uint8_t g, uint8_t b, void* platform_data) { rc71l_platform_t *const platform = (rc71l_platform_t*)platform_data; + return 0; + dbus_uint32_t new_brightness = (r << 24) | (g << 16) | (b << 8) | (3); if (platform_data == NULL) { @@ -1232,7 +1234,6 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u if (!reply || dbus_error_is_set(&platform->dbus_error)) { fprintf(stderr, "D-Bus method call error: %s\n", platform->dbus_error.message); dbus_error_free(&platform->dbus_error); - dbus_message_unref(message); return -EIO; } @@ -1281,10 +1282,10 @@ input_dev_composite_t rc71l_composite = { &in_asus_kb_1_dev, &in_asus_kb_2_dev, &in_asus_kb_3_dev, - //&nkey_dev, + &nkey_dev, &timer_dev, }, - .dev_count = 6, + .dev_count = 7, .init_fn = rc71l_platform_init, .deinit_fn = rc71l_platform_deinit, .leds_fn = rc71l_platform_leds, From a0a5eba0f4d70df0b11fdb2edf77e578b226e47d Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 26 Dec 2023 15:46:19 +0100 Subject: [PATCH 085/186] note --- rog_ally.c | 1 + 1 file changed, 1 insertion(+) diff --git a/rog_ally.c b/rog_ally.c index 5c2a430..2671a72 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1172,6 +1172,7 @@ static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** pl static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, uint8_t g, uint8_t b, void* platform_data) { rc71l_platform_t *const platform = (rc71l_platform_t*)platform_data; + // TODO: before removing this make sure to disable the hidraw backend return 0; dbus_uint32_t new_brightness = (r << 24) | (g << 16) | (b << 8) | (3); From 309609a377bd1a4731c6e261399bf1da02ec8483 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 26 Dec 2023 18:52:40 +0100 Subject: [PATCH 086/186] Lower CPU usage --- dev_out.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/dev_out.c b/dev_out.c index 30aee0d..807a711 100644 --- a/dev_out.c +++ b/dev_out.c @@ -479,10 +479,9 @@ void *dev_out_thread_func(void *ptr) { virt_dualshock_compose(&controller_data.ds4, &dev_out_data->dev_stats.gamepad, tmp_buf); virt_dualshock_send(&controller_data.ds4, tmp_buf); } - - // this does reset the for, ensuring every other device has nothing to say - continue; - } else if ((current_mouse_fd > 0) && (mouse_time_diff_usecs >= mouse_report_timing_us)) { + } + + if ((current_mouse_fd > 0) && (mouse_time_diff_usecs >= mouse_report_timing_us)) { mouse_last_hid_report_sent = now; virt_mouse_send(&mouse_data, &dev_out_data->dev_stats.mouse, NULL); @@ -490,16 +489,12 @@ void *dev_out_thread_func(void *ptr) { // reset mouse movements now dev_out_data->dev_stats.mouse.x = 0; dev_out_data->dev_stats.mouse.y = 0; - - // this does reset the for, ensuring every other device has nothing to say - continue; - } else if ((current_keyboard_fd > 0) && (kbd_time_diff_usecs >= kbd_report_timing_us)) { + } + + if ((current_keyboard_fd > 0) && (kbd_time_diff_usecs >= kbd_report_timing_us)) { keyboard_last_hid_report_sent = now; virt_kbd_send(&keyboard_data, &dev_out_data->dev_stats.kbd, NULL); - - // this does reset the for, ensuring every other device has nothing to say - continue; } @@ -533,11 +528,11 @@ void *dev_out_thread_func(void *ptr) { FD_SET(current_gamepad_fd, &read_fds); } - const int64_t timeout_gamepad_time_diff_usecs = (current_gamepad_fd > 0) ? gamepad_report_timing_us - gamepad_time_diff_usecs : 500; - const int64_t timeout_mouse_time_diff_usecs = (current_mouse_fd > 0) ? mouse_report_timing_us - mouse_time_diff_usecs : 500; - const int64_t timeout_kbd_time_diff_usecs = (current_keyboard_fd > 0) ? kbd_report_timing_us - kbd_time_diff_usecs : 500; + const int64_t timeout_gamepad_time_diff_usecs = (current_gamepad_fd > 0) ? gamepad_report_timing_us - gamepad_time_diff_usecs : 5000; + const int64_t timeout_mouse_time_diff_usecs = (current_mouse_fd > 0) ? mouse_report_timing_us - mouse_time_diff_usecs : 5000; + const int64_t timeout_kbd_time_diff_usecs = (current_keyboard_fd > 0) ? kbd_report_timing_us - kbd_time_diff_usecs : 5000; - int64_t next_timing_out_device_diff_usecs = 500; + int64_t next_timing_out_device_diff_usecs = 5000; if ((timeout_kbd_time_diff_usecs > 0) && (timeout_kbd_time_diff_usecs < next_timing_out_device_diff_usecs)) { next_timing_out_device_diff_usecs = timeout_kbd_time_diff_usecs; @@ -563,6 +558,7 @@ void *dev_out_thread_func(void *ptr) { if (ready_fds == -1) { const int err = errno; fprintf(stderr, "Error reading events for output devices: %d\n", err); + usleep(1000); continue; } else if (ready_fds == 0) { // timeout: do nothing but continue. next iteration will take care From 1055f4d7961681b8625f8168d391a976de235fa5 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 26 Dec 2023 20:59:57 +0100 Subject: [PATCH 087/186] try to exclude iio --- rog_ally.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 2671a72..e0d473e 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1279,14 +1279,14 @@ input_dev_t timer_dev = { input_dev_composite_t rc71l_composite = { .dev = { &in_xbox_dev, - &in_iio_dev, + //&in_iio_dev, &in_asus_kb_1_dev, &in_asus_kb_2_dev, &in_asus_kb_3_dev, &nkey_dev, &timer_dev, }, - .dev_count = 7, + .dev_count = 6, .init_fn = rc71l_platform_init, .deinit_fn = rc71l_platform_deinit, .leds_fn = rc71l_platform_leds, From 34aa554e2981d218f923d3b8285745f0b1d9c9ee Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 26 Dec 2023 21:21:37 +0100 Subject: [PATCH 088/186] exclude the rest --- rog_ally.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index e0d473e..b064508 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1278,15 +1278,15 @@ input_dev_t timer_dev = { input_dev_composite_t rc71l_composite = { .dev = { - &in_xbox_dev, - //&in_iio_dev, - &in_asus_kb_1_dev, - &in_asus_kb_2_dev, - &in_asus_kb_3_dev, - &nkey_dev, - &timer_dev, + //&in_xbox_dev, + &in_iio_dev, + //&in_asus_kb_1_dev, + //&in_asus_kb_2_dev, + //&in_asus_kb_3_dev, + //&nkey_dev, + //&timer_dev, }, - .dev_count = 6, + .dev_count = 1, .init_fn = rc71l_platform_init, .deinit_fn = rc71l_platform_deinit, .leds_fn = rc71l_platform_leds, From bca99cefcac598c54cfd65d895f2aec04b71a36b Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 26 Dec 2023 22:27:39 +0100 Subject: [PATCH 089/186] check if the problem is constant timeouts --- dev_in.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dev_in.c b/dev_in.c index 208b311..dc258c9 100644 --- a/dev_in.c +++ b/dev_in.c @@ -590,6 +590,7 @@ void* dev_in_thread_func(void *ptr) { continue; } else if (ready_fds == 0) { // Timeout... simply retry + printf("TIMEOUT\n"); continue; } From 6f60b53745fdfb7434b2721c3ef696a69cc5c628 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 26 Dec 2023 23:42:12 +0100 Subject: [PATCH 090/186] check if this solves the problem --- dev_in.c | 10 +++++----- rog_ally.c | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dev_in.c b/dev_in.c index dc258c9..f36a702 100644 --- a/dev_in.c +++ b/dev_in.c @@ -453,11 +453,6 @@ void* dev_in_thread_func(void *ptr) { fprintf(stderr, "Error setting up platform data: %d\n", platform_init_res); } - struct timeval timeout = { - .tv_sec = (__time_t)dev_in_data->timeout_ms / (__time_t)1000, - .tv_usec = ((__suseconds_t)dev_in_data->timeout_ms % (__suseconds_t)1000) * (__suseconds_t)1000000, - }; - fd_set read_fds; const size_t max_devices = dev_in_data->input_dev_decl->dev_count; @@ -582,6 +577,11 @@ void* dev_in_thread_func(void *ptr) { } } + struct timeval timeout = { + .tv_sec = (__time_t)dev_in_data->timeout_ms / (__time_t)1000, + .tv_usec = ((__suseconds_t)dev_in_data->timeout_ms % (__suseconds_t)1000) * (__suseconds_t)1000000, + }; + int ready_fds = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout); if (ready_fds == -1) { diff --git a/rog_ally.c b/rog_ally.c index b064508..2671a72 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1278,15 +1278,15 @@ input_dev_t timer_dev = { input_dev_composite_t rc71l_composite = { .dev = { - //&in_xbox_dev, + &in_xbox_dev, &in_iio_dev, - //&in_asus_kb_1_dev, - //&in_asus_kb_2_dev, - //&in_asus_kb_3_dev, - //&nkey_dev, - //&timer_dev, + &in_asus_kb_1_dev, + &in_asus_kb_2_dev, + &in_asus_kb_3_dev, + &nkey_dev, + &timer_dev, }, - .dev_count = 1, + .dev_count = 7, .init_fn = rc71l_platform_init, .deinit_fn = rc71l_platform_deinit, .leds_fn = rc71l_platform_leds, From 10c3ce4fe744395997b6733fd55ef8745cdfb2c0 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 27 Dec 2023 22:14:21 +0100 Subject: [PATCH 091/186] fix nsecs used as usecs --- dev_out.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dev_out.c b/dev_out.c index 807a711..b74478f 100644 --- a/dev_out.c +++ b/dev_out.c @@ -374,7 +374,7 @@ static void handle_incoming_message( } } -int64_t get_timediff_usec(const struct timespec *const start, const struct timespec *const end) { +int64_t get_timediff_nsec(const struct timespec *const start, const struct timespec *const end) { return (end->tv_sec - start->tv_sec) * 1000000000LL + (end->tv_nsec - start->tv_nsec); } @@ -464,11 +464,12 @@ void *dev_out_thread_func(void *ptr) { break; } - const int64_t gamepad_time_diff_usecs = get_timediff_usec(&gamepad_last_hid_report_sent, &now); - const int64_t mouse_time_diff_usecs = get_timediff_usec(&mouse_last_hid_report_sent, &now); - const int64_t kbd_time_diff_usecs = get_timediff_usec(&keyboard_last_hid_report_sent, &now); - clock_gettime(CLOCK_MONOTONIC, &now); + + const int64_t gamepad_time_diff_usecs = get_timediff_nsec(&gamepad_last_hid_report_sent, &now) / 1000; + const int64_t mouse_time_diff_usecs = get_timediff_nsec(&mouse_last_hid_report_sent, &now) / 1000; + const int64_t kbd_time_diff_usecs = get_timediff_nsec(&keyboard_last_hid_report_sent, &now) / 1000; + if ((current_gamepad_fd > 0) && (gamepad_time_diff_usecs >= gamepad_report_timing_us)) { gamepad_last_hid_report_sent = now; From 6ff835405efd1b2776baf39310e61c9b52abc244 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 28 Dec 2023 15:09:41 +0100 Subject: [PATCH 092/186] Removed benchmarking stuff --- dev_out.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/dev_out.c b/dev_out.c index b74478f..e25046f 100644 --- a/dev_out.c +++ b/dev_out.c @@ -45,8 +45,6 @@ static void handle_incoming_message_gamepad_set( const in_message_gamepad_set_element_t *const msg_payload, gamepad_status_t *const inout_gamepad ) { - static int numpackets = 0; - static uint64_t lastsec = 0; switch (msg_payload->element) { case GAMEPAD_BTN_CROSS: { if (!in_settings->nintendo_layout) { @@ -181,13 +179,6 @@ static void handle_incoming_message_gamepad_set( break; } case GAMEPAD_GYROSCOPE: { - if (msg_payload->status.gyro.sample_time.tv_sec != lastsec) { - //printf("%d\n", numpackets); - lastsec = msg_payload->status.gyro.sample_time.tv_sec; - numpackets = 0; - } else { - ++numpackets; - } inout_gamepad->last_gyro_motion_time = msg_payload->status.gyro.sample_time; inout_gamepad->raw_gyro[0] = msg_payload->status.gyro.x; inout_gamepad->raw_gyro[1] = msg_payload->status.gyro.y; From b9ea79a558a73fb1fe43d48589da08a418bc980e Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 28 Dec 2023 15:22:34 +0100 Subject: [PATCH 093/186] hide opened input --- dev_evdev.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/dev_evdev.c b/dev_evdev.c index 107db4f..df210a2 100644 --- a/dev_evdev.c +++ b/dev_evdev.c @@ -2,6 +2,7 @@ #include static const char *input_path = "/dev/input/"; +static const char *hidden_input_path = "/dev/input/.hidden/"; static pthread_mutex_t input_acquire_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -133,6 +134,12 @@ int dev_evdev_open( int open_sysfs_idx = -1; + struct stat st = {0}; + + if (stat(hidden_input_path, &st) == -1) { + mkdir(hidden_input_path, 0700); + } + const int mutex_lock_res = pthread_mutex_lock(&input_acquire_mutex); if (mutex_lock_res != 0) { fprintf(stderr, "Cannot lock input mutex: %d\n", mutex_lock_res); @@ -146,6 +153,13 @@ int dev_evdev_open( goto dev_evdev_open_err; } + char *const hidden_path = malloc(MAX_PATH_LEN); + if (path == NULL) { + free(path); + res = -ENOMEM; + goto dev_evdev_open_err; + } + DIR *d; struct dirent *dir; d = opendir(input_path); @@ -159,6 +173,7 @@ int dev_evdev_open( continue; } + snprintf(hidden_path, MAX_PATH_LEN - 1, "%s%s", hidden_input_path, dir->d_name); snprintf(path, MAX_PATH_LEN - 1, "%s%s", input_path, dir->d_name); //printf("Testing for device %s\n", path); @@ -199,6 +214,14 @@ int dev_evdev_open( continue; } + if (rename(path, hidden_path) != 0) { + libevdev_free(*out_evdev); + close(fd); + continue; + } else { + chmod(hidden_path, 000); + } + // register the device as being opened already open_paths[open_sysfs_idx].sysfs_path = path; open_paths[open_sysfs_idx].fd = fd; From f7ee474659d145a48dae3ce4217d584b08128270 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 28 Dec 2023 15:36:50 +0100 Subject: [PATCH 094/186] Warn about failures hiding controllers --- dev_evdev.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/dev_evdev.c b/dev_evdev.c index df210a2..2dbba3f 100644 --- a/dev_evdev.c +++ b/dev_evdev.c @@ -137,7 +137,12 @@ int dev_evdev_open( struct stat st = {0}; if (stat(hidden_input_path, &st) == -1) { - mkdir(hidden_input_path, 0700); + printf("Directory %s does not exits -- creating it\n", hidden_input_path); + if (mkdir(hidden_input_path, 0700) == 0) { + printf("Directory %s creates successfully", hidden_input_path); + } else { + fprintf(stderr, "Error creating %s directory: %d\n", hidden_input_path, errno); + } } const int mutex_lock_res = pthread_mutex_lock(&input_acquire_mutex); @@ -215,11 +220,14 @@ int dev_evdev_open( } if (rename(path, hidden_path) != 0) { + fprintf(stderr, "Unable to move the device: %d\n", errno); libevdev_free(*out_evdev); close(fd); continue; } else { - chmod(hidden_path, 000); + if (chmod(hidden_path, 000) != 0) { + fprintf(stderr, "Unable to perform chmod 000 to opened device\n"); + } } // register the device as being opened already From 089e289003c9b0e3f65281697d82139b4ab8aaae Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 28 Dec 2023 18:01:34 +0100 Subject: [PATCH 095/186] crank up sampling frequency to the max --- rogue-enemy_iio_buffer_off.sh | 20 +++++++++++++++++--- rogue-enemy_iio_buffer_on.sh | 6 +++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/rogue-enemy_iio_buffer_off.sh b/rogue-enemy_iio_buffer_off.sh index 5b3c6b3..c18677c 100644 --- a/rogue-enemy_iio_buffer_off.sh +++ b/rogue-enemy_iio_buffer_off.sh @@ -1,4 +1,18 @@ #!/bin/bash -cd /sys/bus/iio/devices/iio\:device0 -echo "void" > trigger/current_trigger -echo 0 > buffer0/enable \ No newline at end of file + +for i in /sys/bus/iio/devices/* ; do + if [ -d "$i" ]; then + if [ -f "$i/name" ]; then + name=$(cat "$i/name") + if [ "$name" = "bmi323-imu" ]; then + # bind fake hrtimer to to the iio device + echo "void" > "$i/trigger/current_trigger" + + # enable the buffer + echo 0 > "$i/buffer0/enable" + + echo "bmi323-imu buffer started" + fi + fi + fi +done diff --git a/rogue-enemy_iio_buffer_on.sh b/rogue-enemy_iio_buffer_on.sh index bc64b9a..b86c376 100644 --- a/rogue-enemy_iio_buffer_on.sh +++ b/rogue-enemy_iio_buffer_on.sh @@ -17,7 +17,7 @@ for i in /sys/bus/iio/devices/* ; do if [ -f "$i/name" ]; then name=$(cat "$i/name") if [ "$name" = "rogue" ]; then - echo "800" > "$i/sampling_frequency" + echo "1600" > "$i/sampling_frequency" fi fi fi @@ -31,8 +31,8 @@ for i in /sys/bus/iio/devices/* ; do if [ "$name" = "bmi323-imu" ]; then # change chip sampling frequency - echo "800.000000" > "$i/in_accel_sampling_frequency" - echo "800.000000" > "$i/in_anglvel_sampling_frequency" + echo "1600.000000" > "$i/in_accel_sampling_frequency" + echo "1600.000000" > "$i/in_anglvel_sampling_frequency" # enable accel data acquisition echo 1 > "$i/scan_elements/in_accel_x_en" From 62c903830e75e20d4d91ea4e2b77685610a26338 Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 29 Dec 2023 02:25:38 +0100 Subject: [PATCH 096/186] Remove problematic pressis based on trigger values --- virt_ds4.c | 4 ++-- virt_ds5.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/virt_ds4.c b/virt_ds4.c index b615aaa..1f2a376 100644 --- a/virt_ds4.c +++ b/virt_ds4.c @@ -736,8 +736,8 @@ void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *c (in_device_status->l3 ? 0x40 : 0x00) | (in_device_status->share ? 0x20 : 0x00) | (in_device_status->option ? 0x10 : 0x00) | - (in_device_status->r2_trigger > 200 ? 0x08 : 0x00) | - (in_device_status->l2_trigger > 200 ? 0x04 : 0x00) | + /*(in_device_status->r2_trigger > 200 ? 0x08 : 0x00)*/ 0x00 | + /*(in_device_status->l2_trigger > 200 ? 0x04 : 0x00)*/ 0x00 | (in_device_status->r1 ? 0x02 : 0x00) | (in_device_status->l1 ? 0x01 : 0x00); diff --git a/virt_ds5.c b/virt_ds5.c index 65f3969..2a4cdf2 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1297,8 +1297,8 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c (uint8_t)ds5_dpad_from_gamepad(in_device_status->dpad); out_shifted_buf[9] = (in_device_status->l1 ? 0x01 : 0x00) | (in_device_status->r1 ? 0x02 : 0x00) | - (in_device_status->l2_trigger >= 225 ? 0x04 : 0x00) | - (in_device_status->r2_trigger >= 225 ? 0x08 : 0x00) | + /*(in_device_status->l2_trigger >= 225 ? 0x04 : 0x00)*/ 0x00 | + /*(in_device_status->r2_trigger >= 225 ? 0x08 : 0x00)*/ 0x00 | (in_device_status->option ? 0x10 : 0x00) | (in_device_status->share ? 0x20 : 0x00) | (in_device_status->l3 ? 0x40 : 0x00) | From 72df979cf6f3aae99456df08b09eb28f30ccff93 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 17:58:10 +0100 Subject: [PATCH 097/186] Can use m1 and m2 to simulate touchpad --- allynone.c | 1 + config.cfg.default | 3 +- main.c | 1 + rog_ally.c | 95 ++++++++++++++++++++++++++++++++++++---------- settings.c | 11 ++++++ settings.h | 1 + 6 files changed, 90 insertions(+), 22 deletions(-) diff --git a/allynone.c b/allynone.c index 8172706..987a55f 100644 --- a/allynone.c +++ b/allynone.c @@ -89,6 +89,7 @@ int main(int argc, char ** argv) { .enable_qam = true, .ff_gain = 0xFFFF, .rumble_on_mode_switch = true, + .m1m2_mode = 0, } }; diff --git a/config.cfg.default b/config.cfg.default index a932f9a..f6dd94b 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -4,4 +4,5 @@ nintendo_layout = false; default_gamepad = 1; rumble_on_mode_switch = true; gamepad_rumble_control = true; -gamepad_leds_control = true; \ No newline at end of file +gamepad_leds_control = true; +m1m2_mode = 0; \ No newline at end of file diff --git a/main.c b/main.c index 08999d3..62f4a24 100644 --- a/main.c +++ b/main.c @@ -55,6 +55,7 @@ int main(int argc, char ** argv) { .enable_qam = true, .ff_gain = 0xFFFF, .rumble_on_mode_switch = true, + .m1m2_mode = 0, } }; diff --git a/rog_ally.c b/rog_ally.c index 2671a72..b966a76 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -45,6 +45,8 @@ typedef struct rc71l_asus_kbd_user_data { struct rc71l_platform* parent; struct udev *udev; + + int m1, m2; } rc71l_asus_kbd_user_data_t; typedef struct rc71l_timer_user_data { @@ -67,7 +69,12 @@ typedef struct rc71l_platform { } rc71l_platform_t; -static rc71l_asus_kbd_user_data_t asus_userdata = {}; +static rc71l_asus_kbd_user_data_t asus_userdata = { + .parent = NULL, + .udev = NULL, + .m1 = 0, + .m2 = 0, +}; static rc71l_xbox360_user_data_t controller_user_data = { .accounted_mode_switches = 0, @@ -182,34 +189,80 @@ static int asus_kbd_ev_map( if (e->ev[i].code == KEY_F14) { // this is left back paddle, works as expected - const in_message_t current_message = { - .type = GAMEPAD_SET_ELEMENT, - .data = { - .gamepad_set = { - .element = GAMEPAD_BTN_L5, - .status = { - .btn = e->ev[1].value, + + if (e->ev[i].value == 0) { + asus_kbd_user_data->m1 -= (asus_kbd_user_data->m1 == 0) ? 0 : 1; + } else if (e->ev[i].value == 1) { + asus_kbd_user_data->m1 += 1; + } + + if (conf->m1m2_mode == 0) { + const in_message_t current_message = { + .type = GAMEPAD_SET_ELEMENT, + .data = { + .gamepad_set = { + .element = GAMEPAD_BTN_L5, + .status = { + .btn = e->ev[1].value, + } } } - } - }; + }; - messages[written_msg++] = current_message; + messages[written_msg++] = current_message; + } else if (conf->m1m2_mode == 1) { + const in_message_t current_message = { + .type = GAMEPAD_SET_ELEMENT, + .data = { + .gamepad_set = { + .element = GAMEPAD_BTN_TOUCHPAD, + .status = { + .btn = (asus_kbd_user_data->m1 + asus_kbd_user_data->m2) == 0 ? 0 : 1, + } + } + } + }; + + messages[written_msg++] = current_message; + } } else if (e->ev[i].code == KEY_F15) { // this is right back paddle, works as expected - const in_message_t current_message = { - .type = GAMEPAD_SET_ELEMENT, - .data = { - .gamepad_set = { - .element = GAMEPAD_BTN_R5, - .status = { - .btn = e->ev[1].value, + + if (e->ev[i].value == 0) { + asus_kbd_user_data->m2 -= (asus_kbd_user_data->m2 == 0) ? 0 : 1; + } else if (e->ev[i].value == 1) { + asus_kbd_user_data->m2 += 1; + } + + if (conf->m1m2_mode == 0) { + const in_message_t current_message = { + .type = GAMEPAD_SET_ELEMENT, + .data = { + .gamepad_set = { + .element = GAMEPAD_BTN_R5, + .status = { + .btn = e->ev[1].value, + } } } - } - }; + }; - messages[written_msg++] = current_message; + messages[written_msg++] = current_message; + } else if (conf->m1m2_mode == 1) { + const in_message_t current_message = { + .type = GAMEPAD_SET_ELEMENT, + .data = { + .gamepad_set = { + .element = GAMEPAD_BTN_TOUCHPAD, + .status = { + .btn = (asus_kbd_user_data->m1 + asus_kbd_user_data->m2) == 0 ? 0 : 1, + } + } + } + }; + + messages[written_msg++] = current_message; + } } else if ((e->ev[i].code == KEY_F16) && (e->ev[i].value != 0)) { // this is left screen button, on release both 0 and 1 events are emitted so just discard the 0 const in_message_t current_message = { diff --git a/settings.c b/settings.c index 6442215..6a2ef48 100644 --- a/settings.c +++ b/settings.c @@ -37,6 +37,17 @@ void load_in_config(dev_in_settings_t *const out_conf, const char* const filepat fprintf(stderr, "ff_gain (int) configuration not found. Default value will be used.\n"); } + int m1m2_mode; + if (config_lookup_int(&cfg, "m1m2_mode", &m1m2_mode) != CONFIG_FALSE) { + if (m1m2_mode <= 2) { + out_conf->m1m2_mode = m1m2_mode; + } else { + fprintf(stderr, "m1m2_mode (int) must be a number between 0 and 2"); + } + } else { + fprintf(stderr, "m1m2_mode (int) configuration not found. Default value will be used.\n"); + } + config_destroy(&cfg); load_in_config_err: diff --git a/settings.h b/settings.h index 3d32878..878ae1a 100644 --- a/settings.h +++ b/settings.h @@ -6,6 +6,7 @@ typedef struct dev_in_settings { bool enable_qam; bool rumble_on_mode_switch; uint16_t ff_gain; + uint8_t m1m2_mode; } dev_in_settings_t; void load_in_config(dev_in_settings_t *const out_conf, const char* const filepath); From 8870020cab6cf79e957a028be562e6bc09e1584b Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 19:17:56 +0100 Subject: [PATCH 098/186] Fix one axis improperly inverted --- dev_in.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev_in.c b/dev_in.c index f36a702..bd513b7 100644 --- a/dev_in.c +++ b/dev_in.c @@ -117,7 +117,7 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const //messages[0].data.gamepad_set.status.accel.z = scan_elements[2]; messages[0].data.gamepad_set.status.accel.x = scan_elements[0]; messages[0].data.gamepad_set.status.accel.y = (uint16_t)(-1) * scan_elements[2]; - messages[0].data.gamepad_set.status.accel.z = (uint16_t)(-1) * scan_elements[1]; + messages[0].data.gamepad_set.status.accel.z = scan_elements[1]; messages[1].type = GAMEPAD_SET_ELEMENT; messages[1].data.gamepad_set.element = GAMEPAD_GYROSCOPE; @@ -129,7 +129,7 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const //messages[1].data.gamepad_set.status.gyro.z = scan_elements[5]; messages[1].data.gamepad_set.status.gyro.x = scan_elements[3]; messages[1].data.gamepad_set.status.gyro.y = (uint16_t)(-1) * scan_elements[5]; - messages[1].data.gamepad_set.status.gyro.z = (uint16_t)(-1) * scan_elements[4]; + messages[1].data.gamepad_set.status.gyro.z = scan_elements[4]; res = 2; From ebf83d6350d20c75fb707d0e4290424bd851db87 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 19:18:12 +0100 Subject: [PATCH 099/186] Add touchbar to dualsense --- dev_out.c | 12 ++++++ devices_status.c | 3 ++ devices_status.h | 4 ++ message.h | 19 ++++++++++ rog_ally.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++- virt_ds5.c | 14 +++++-- 6 files changed, 144 insertions(+), 4 deletions(-) diff --git a/dev_out.c b/dev_out.c index e25046f..36e9f76 100644 --- a/dev_out.c +++ b/dev_out.c @@ -192,6 +192,18 @@ static void handle_incoming_message_gamepad_set( inout_gamepad->raw_accel[2] = msg_payload->status.accel.z; break; } + case GAMEPAD_TOUCHPAD_TOUCH_ACTIVE: { + inout_gamepad->touchpad_touch_num = msg_payload->status.touchpad_active.status; + break; + } + case GAMEPAD_TOUCHPAD_X: { + inout_gamepad->touchpad_x = msg_payload->status.touchpad_x.value; + break; + } + case GAMEPAD_TOUCHPAD_Y: { + inout_gamepad->touchpad_y = msg_payload->status.touchpad_y.value; + break; + } default: { fprintf(stderr, "Unknown gamepad element: %d\n", msg_payload->element); break; diff --git a/devices_status.c b/devices_status.c index f852b15..6173659 100644 --- a/devices_status.c +++ b/devices_status.c @@ -95,6 +95,9 @@ void gamepad_status_init(gamepad_status_t *const stats) { stats->leds_colors[0] = 0; stats->leds_colors[1] = 0; stats->leds_colors[2] = 0; + stats->touchpad_touch_num = -1; + stats->touchpad_x = 0; + stats->touchpad_y = 0; stats->flags = 0; } diff --git a/devices_status.h b/devices_status.h index 8543f89..c137df1 100644 --- a/devices_status.h +++ b/devices_status.h @@ -46,6 +46,10 @@ typedef struct gamepad_status { uint8_t touchpad_press; + int16_t touchpad_touch_num; // touchpad is inactive when this is -1 + int16_t touchpad_x; + int16_t touchpad_y; + struct timeval last_gyro_motion_time; struct timeval last_accel_motion_time; diff --git a/message.h b/message.h index 7270f5d..4fe7632 100644 --- a/message.h +++ b/message.h @@ -35,8 +35,24 @@ typedef enum in_message_gamepad_btn { GAMEPAD_GYROSCOPE, GAMEPAD_ACCELEROMETER, + + GAMEPAD_TOUCHPAD_X, + GAMEPAD_TOUCHPAD_Y, + GAMEPAD_TOUCHPAD_TOUCH_ACTIVE, } in_gamepad_element_t; +typedef struct in_message_gamepad_touchpad_x { + int16_t value; +} in_message_gamepad_touchpad_x_t; + +typedef struct in_message_gamepad_touchpad_y { + int16_t value; +} in_message_gamepad_touchpad_y_t; + +typedef struct in_message_gamepad_touchpad_active { + int16_t status; +} in_message_gamepad_touchpad_active_t; + typedef struct in_message_gamepad_gyro { struct timeval sample_time; @@ -61,6 +77,9 @@ typedef struct in_message_gamepad_set_element { int8_t dpad; // -1 | 0 | +1 in_message_gamepad_accel_t accel; in_message_gamepad_gyro_t gyro; + in_message_gamepad_touchpad_active_t touchpad_active; + in_message_gamepad_touchpad_x_t touchpad_x; + in_message_gamepad_touchpad_y_t touchpad_y; } status; } in_message_gamepad_set_element_t; diff --git a/rog_ally.c b/rog_ally.c index b966a76..1357c3d 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -3,6 +3,7 @@ #include "dev_hidraw.h" #include "message.h" #include "xbox360.h" +#include enum rc71l_leds_mode { ROG_ALLY_MODE_STATIC = 0, @@ -946,6 +947,98 @@ static input_dev_t in_iio_dev = { //.input_filter_fn = input_filter_imu_identity, }; +static void rc71l_timer_touchscreen( + const dev_in_settings_t *const conf, + struct libevdev* evdev, + const char* const timer_name, + uint64_t expired, + void* user_data +) { + +} + +static int touchscreen_ev_map( + const dev_in_settings_t *const conf, + const evdev_collected_t *const e, + in_message_t *const messages, + size_t messages_len, + void* user_data +) { + int written_msg = 0; + + for (size_t i = 0; i < e->ev_count; ++i) { + if (e->ev[i].type == EV_ABS) { + if (e->ev[i].code == ABS_MT_TRACKING_ID) { + const in_message_t current_message = { + .type = GAMEPAD_SET_ELEMENT, + .data = { + .gamepad_set = { + .element = GAMEPAD_TOUCHPAD_TOUCH_ACTIVE, + .status = { + .touchpad_active = { + .status = e->ev[i].value, + } + } + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == ABS_MT_POSITION_X) { + const in_message_t current_message = { + .type = GAMEPAD_SET_ELEMENT, + .data = { + .gamepad_set = { + .element = GAMEPAD_TOUCHPAD_X, + .status = { + .touchpad_active = { + .status = e->ev[i].value, + } + } + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == ABS_MT_POSITION_Y) { + const in_message_t current_message = { + .type = GAMEPAD_SET_ELEMENT, + .data = { + .gamepad_set = { + .element = GAMEPAD_TOUCHPAD_Y, + .status = { + .touchpad_active = { + .status = e->ev[i].value, + } + } + } + } + }; + + messages[written_msg++] = current_message; + } + } + } + + return written_msg; +} + +static input_dev_t in_touchscreen_dev = { + .dev_type = input_dev_type_uinput, + .filters = { + .ev = { + .name = "NVTK0603:00 0603:F200" + } + }, + .user_data = NULL, + .map = { + .ev_callbacks = { + .input_map_fn = touchscreen_ev_map, + .timeout_callback = rc71l_timer_touchscreen, + }, + } +}; + static void rc71l_timer_asus_kbd( const dev_in_settings_t *const conf, struct libevdev* evdev, @@ -1338,8 +1431,9 @@ input_dev_composite_t rc71l_composite = { &in_asus_kb_3_dev, &nkey_dev, &timer_dev, + &in_touchscreen_dev, }, - .dev_count = 7, + .dev_count = 8, .init_fn = rc71l_platform_init, .deinit_fn = rc71l_platform_deinit, .leds_fn = rc71l_platform_leds, diff --git a/virt_ds5.c b/virt_ds5.c index 2a4cdf2..a2bff02 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1322,9 +1322,17 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c memcpy(&out_shifted_buf[26], &a_z, sizeof(int16_t)); memcpy(&out_shifted_buf[28], ×tamp, sizeof(timestamp)); - // TODO: when touch is detected send 0x7F, when not 0x80 - out_shifted_buf[33] = 0x80; //touch0 active? - out_shifted_buf[37] = 0x80; //touch1 active? + // point of contact number 0 + out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact + out_shifted_buf[34] = in_device_status->touchpad_x & (int16_t)0x00FF; //x_lo + out_shifted_buf[35] = ((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) | ((in_device_status->touchpad_y & (int16_t)0x000F) >> (int16_t)0); //x_hi:4 y_lo:4 + out_shifted_buf[36] = ((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4); //y_hi + + // point of contact number 1 + out_shifted_buf[37] = 0x80; //contact + out_shifted_buf[38] = 0x00; //x_lo + out_shifted_buf[39] = 0x00; //x_hi:4 y_lo:4 + out_shifted_buf[40] = 0x00; //y_hi /* buf[30] = 0x1b; // no headset attached From ae2e50cc2c0f2c81cbd336ff9250680b47eb1981 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 20:53:04 +0100 Subject: [PATCH 100/186] whoopsie... --- virt_ds5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt_ds5.c b/virt_ds5.c index a2bff02..e860724 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1325,7 +1325,7 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c // point of contact number 0 out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact out_shifted_buf[34] = in_device_status->touchpad_x & (int16_t)0x00FF; //x_lo - out_shifted_buf[35] = ((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) | ((in_device_status->touchpad_y & (int16_t)0x000F) >> (int16_t)0); //x_hi:4 y_lo:4 + out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) << (int16_t)4) | ((in_device_status->touchpad_y & (int16_t)0x000F) >> (int16_t)0); //x_hi:4 y_lo:4 out_shifted_buf[36] = ((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4); //y_hi // point of contact number 1 From e3e2a7e83e55f33423987f120871bfd804237920 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 20:56:29 +0100 Subject: [PATCH 101/186] wtf... --- virt_ds5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt_ds5.c b/virt_ds5.c index e860724..2f4b606 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1325,7 +1325,7 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c // point of contact number 0 out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact out_shifted_buf[34] = in_device_status->touchpad_x & (int16_t)0x00FF; //x_lo - out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) << (int16_t)4) | ((in_device_status->touchpad_y & (int16_t)0x000F) >> (int16_t)0); //x_hi:4 y_lo:4 + out_shifted_buf[35] = ((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)4) | ((in_device_status->touchpad_y & (int16_t)0x000F)); //x_hi:4 y_lo:4 out_shifted_buf[36] = ((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4); //y_hi // point of contact number 1 From e36ad2e47d7392e08991d010a7bd81c817ae2bf7 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 21:02:42 +0100 Subject: [PATCH 102/186] try this way --- virt_ds5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt_ds5.c b/virt_ds5.c index 2f4b606..aaad393 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1325,7 +1325,7 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c // point of contact number 0 out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact out_shifted_buf[34] = in_device_status->touchpad_x & (int16_t)0x00FF; //x_lo - out_shifted_buf[35] = ((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)4) | ((in_device_status->touchpad_y & (int16_t)0x000F)); //x_hi:4 y_lo:4 + out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) | ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)); // x_hi:4 y_lo:4 out_shifted_buf[36] = ((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4); //y_hi // point of contact number 1 From a755e2a18c6112a67835a74032a2eb83f51a6073 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 21:04:09 +0100 Subject: [PATCH 103/186] default to touchpad button for m1 and m2 buttons --- config.cfg.default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.cfg.default b/config.cfg.default index f6dd94b..2297cb6 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -5,4 +5,4 @@ default_gamepad = 1; rumble_on_mode_switch = true; gamepad_rumble_control = true; gamepad_leds_control = true; -m1m2_mode = 0; \ No newline at end of file +m1m2_mode = 1; \ No newline at end of file From c400ee7d22367ac2d9a8a9c436a05db87b71e91f Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 21:08:08 +0100 Subject: [PATCH 104/186] let's fix X alone --- virt_ds5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index aaad393..7536cd4 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1325,8 +1325,8 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c // point of contact number 0 out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact out_shifted_buf[34] = in_device_status->touchpad_x & (int16_t)0x00FF; //x_lo - out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) | ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)); // x_hi:4 y_lo:4 - out_shifted_buf[36] = ((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4); //y_hi + out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 + out_shifted_buf[36] = 0 /*((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4)*/; //y_hi // point of contact number 1 out_shifted_buf[37] = 0x80; //contact From 922dd9083150ed6d72279ab2c42574c9ec341a36 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 21:11:00 +0100 Subject: [PATCH 105/186] let's exclude the other part of X too --- virt_ds5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index 7536cd4..3b9bb36 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1324,8 +1324,8 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c // point of contact number 0 out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact - out_shifted_buf[34] = in_device_status->touchpad_x & (int16_t)0x00FF; //x_lo - out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 + out_shifted_buf[34] = 0/*in_device_status->touchpad_x & (int16_t)0x00FF*/; //x_lo + out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)4) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 out_shifted_buf[36] = 0 /*((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4)*/; //y_hi // point of contact number 1 From c668a9406ce6708d62d44148d63823d2a698c5de Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 21:16:53 +0100 Subject: [PATCH 106/186] what about this? --- virt_ds5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt_ds5.c b/virt_ds5.c index 3b9bb36..99e08ec 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1325,7 +1325,7 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c // point of contact number 0 out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact out_shifted_buf[34] = 0/*in_device_status->touchpad_x & (int16_t)0x00FF*/; //x_lo - out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)4) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 + out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 out_shifted_buf[36] = 0 /*((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4)*/; //y_hi // point of contact number 1 From 58d7d7c5539fdd12e57eecbc98f9c97ad3d83548 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 21:20:07 +0100 Subject: [PATCH 107/186] better? --- rog_ally.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 1357c3d..03d2e0a 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -991,8 +991,8 @@ static int touchscreen_ev_map( .gamepad_set = { .element = GAMEPAD_TOUCHPAD_X, .status = { - .touchpad_active = { - .status = e->ev[i].value, + .touchpad_x = { + .value = e->ev[i].value, } } } @@ -1007,8 +1007,8 @@ static int touchscreen_ev_map( .gamepad_set = { .element = GAMEPAD_TOUCHPAD_Y, .status = { - .touchpad_active = { - .status = e->ev[i].value, + .touchpad_y = { + .value = e->ev[i].value, } } } From 782865dbb6f61c4b350797b867294d28bf6c9ae2 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 21:24:12 +0100 Subject: [PATCH 108/186] no idea... --- virt_ds5.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/virt_ds5.c b/virt_ds5.c index 99e08ec..81f58ca 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1325,9 +1325,11 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c // point of contact number 0 out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact out_shifted_buf[34] = 0/*in_device_status->touchpad_x & (int16_t)0x00FF*/; //x_lo - out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 + out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)4) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 out_shifted_buf[36] = 0 /*((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4)*/; //y_hi + sprintf(stderr, "%d -> %d\n", (int)in_device_status->touchpad_x, (int)out_shifted_buf[35]); + // point of contact number 1 out_shifted_buf[37] = 0x80; //contact out_shifted_buf[38] = 0x00; //x_lo From 42832e0b0d7eb007bd2bb982a658c8d85e82d04f Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 21:30:49 +0100 Subject: [PATCH 109/186] dafuq? --- virt_ds5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt_ds5.c b/virt_ds5.c index 81f58ca..1bfd7c3 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1328,7 +1328,7 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)4) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 out_shifted_buf[36] = 0 /*((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4)*/; //y_hi - sprintf(stderr, "%d -> %d\n", (int)in_device_status->touchpad_x, (int)out_shifted_buf[35]); + printf("%d -> %d\n", (int)in_device_status->touchpad_x, (int)out_shifted_buf[35]); // point of contact number 1 out_shifted_buf[37] = 0x80; //contact From f3ac4dc285eea5f9c1fbc57653ad659516800b5e Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 21:35:54 +0100 Subject: [PATCH 110/186] I have finished messages --- virt_ds5.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index 1bfd7c3..4625258 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1325,10 +1325,12 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c // point of contact number 0 out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact out_shifted_buf[34] = 0/*in_device_status->touchpad_x & (int16_t)0x00FF*/; //x_lo - out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)4) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 + out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 out_shifted_buf[36] = 0 /*((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4)*/; //y_hi - printf("%d -> %d\n", (int)in_device_status->touchpad_x, (int)out_shifted_buf[35]); + if (in_device_status->touchpad_touch_num != -1) { + printf("%d -> %d\n", (int)in_device_status->touchpad_x, (int)out_shifted_buf[35]); + } // point of contact number 1 out_shifted_buf[37] = 0x80; //contact From e85322e38ccf382d675ae6311fa12c0b7a184da1 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 21:47:35 +0100 Subject: [PATCH 111/186] debug --- virt_ds5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt_ds5.c b/virt_ds5.c index 4625258..aae82cf 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1329,7 +1329,7 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c out_shifted_buf[36] = 0 /*((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4)*/; //y_hi if (in_device_status->touchpad_touch_num != -1) { - printf("%d -> %d\n", (int)in_device_status->touchpad_x, (int)out_shifted_buf[35]); + printf("%4x -> %2x\n", (int)in_device_status->touchpad_x, (int)out_shifted_buf[35]); } // point of contact number 1 From 1c401c9dbf42ecf3967e3875a17ee7bec2e6ad15 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 21:51:41 +0100 Subject: [PATCH 112/186] debug --- virt_ds5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index aae82cf..c1e363d 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1324,8 +1324,8 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c // point of contact number 0 out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact - out_shifted_buf[34] = 0/*in_device_status->touchpad_x & (int16_t)0x00FF*/; //x_lo - out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 + out_shifted_buf[34] = 0x7F/*in_device_status->touchpad_x & (int16_t)0x00FF*/; //x_lo + out_shifted_buf[35] = ((((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) << (int16_t)4) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 out_shifted_buf[36] = 0 /*((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4)*/; //y_hi if (in_device_status->touchpad_touch_num != -1) { From 9cf162681e9c1bc718a1d152f94c481925a51088 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 21:58:21 +0100 Subject: [PATCH 113/186] I do have no words to express how stupid I am --- virt_ds5.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index c1e363d..703d3cf 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1338,16 +1338,6 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c out_shifted_buf[39] = 0x00; //x_hi:4 y_lo:4 out_shifted_buf[40] = 0x00; //y_hi -/* - buf[30] = 0x1b; // no headset attached -*/ - out_shifted_buf[62] = 0x80; // IDK... it seems constant... - out_shifted_buf[57] = 0x80; // IDK... it seems constant... - out_shifted_buf[53] = 0x80; // IDK... it seems constant... - out_shifted_buf[48] = 0x80; // IDK... it seems constant... - out_shifted_buf[35] = 0x80; // IDK... it seems constant... - out_shifted_buf[44] = 0x80; // IDK... it seems constant... - if (gamepad->bluetooth) { uint32_t crc = crc32_le(0xFFFFFFFFU, (const uint8_t*)&PS_FEATURE_CRC32_SEED, sizeof(PS_FEATURE_CRC32_SEED)); crc = ~crc32_le(crc, (const Bytef *)&out_shifted_buf[0], DS_INPUT_REPORT_BT_SIZE - 4); From c68ddd85b8187ac45fce98cd89a0521ff20f5985 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 22:03:11 +0100 Subject: [PATCH 114/186] I have no idea... --- virt_ds5.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index 703d3cf..da896e6 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1325,13 +1325,9 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c // point of contact number 0 out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact out_shifted_buf[34] = 0x7F/*in_device_status->touchpad_x & (int16_t)0x00FF*/; //x_lo - out_shifted_buf[35] = ((((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) << (int16_t)4) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 + out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 out_shifted_buf[36] = 0 /*((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4)*/; //y_hi - if (in_device_status->touchpad_touch_num != -1) { - printf("%4x -> %2x\n", (int)in_device_status->touchpad_x, (int)out_shifted_buf[35]); - } - // point of contact number 1 out_shifted_buf[37] = 0x80; //contact out_shifted_buf[38] = 0x00; //x_lo @@ -1343,6 +1339,10 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c crc = ~crc32_le(crc, (const Bytef *)&out_shifted_buf[0], DS_INPUT_REPORT_BT_SIZE - 4); memcpy(&out_shifted_buf[DS_INPUT_REPORT_BT_SIZE - sizeof(crc)], &crc, sizeof(crc)); } + + if (in_device_status->touchpad_touch_num != -1) { + printf("%4x -> %2x @\n", (int)in_device_status->touchpad_x, (int)out_shifted_buf[35]); + } } int virt_dualsense_send(virt_dualsense_t *const gamepad, uint8_t *const out_shifted_buf) { From 31fc20de9a879211592e1010e9abbb2fa81c0308 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 22:09:53 +0100 Subject: [PATCH 115/186] X MSB works, compose the rest ox X --- virt_ds5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt_ds5.c b/virt_ds5.c index da896e6..1a9ebbe 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1324,7 +1324,7 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c // point of contact number 0 out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact - out_shifted_buf[34] = 0x7F/*in_device_status->touchpad_x & (int16_t)0x00FF*/; //x_lo + out_shifted_buf[34] = in_device_status->touchpad_x & (int16_t)0x00FF; //x_lo out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 out_shifted_buf[36] = 0 /*((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4)*/; //y_hi From 664081231597d423c5f773316de59faec84b27c1 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 22:13:06 +0100 Subject: [PATCH 116/186] restore Y too --- virt_ds5.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index 1a9ebbe..2373fd7 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1325,8 +1325,8 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c // point of contact number 0 out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact out_shifted_buf[34] = in_device_status->touchpad_x & (int16_t)0x00FF; //x_lo - out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) /*| ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)*/); // x_hi:4 y_lo:4 - out_shifted_buf[36] = 0 /*((in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4)*/; //y_hi + out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) | ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)); // x_hi:4 y_lo:4 + out_shifted_buf[36] = (in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4; //y_hi // point of contact number 1 out_shifted_buf[37] = 0x80; //contact @@ -1339,10 +1339,6 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c crc = ~crc32_le(crc, (const Bytef *)&out_shifted_buf[0], DS_INPUT_REPORT_BT_SIZE - 4); memcpy(&out_shifted_buf[DS_INPUT_REPORT_BT_SIZE - sizeof(crc)], &crc, sizeof(crc)); } - - if (in_device_status->touchpad_touch_num != -1) { - printf("%4x -> %2x @\n", (int)in_device_status->touchpad_x, (int)out_shifted_buf[35]); - } } int virt_dualsense_send(virt_dualsense_t *const gamepad, uint8_t *const out_shifted_buf) { From d777f284b0dd4db73b6e0a48b239e66bbf1544ea Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 22:24:03 +0100 Subject: [PATCH 117/186] udev rules --- 99-js-block.rules | 1 + 99-xbox360-block.rules | 1 + 2 files changed, 2 insertions(+) create mode 100644 99-js-block.rules create mode 100644 99-xbox360-block.rules diff --git a/99-js-block.rules b/99-js-block.rules new file mode 100644 index 0000000..da1ef16 --- /dev/null +++ b/99-js-block.rules @@ -0,0 +1 @@ +KERNEL=="js[0-9]*|event[0-9]*", SUBSYSTEM=="input", ATTRS{idVendor}=="045e", ATTRS{idProduct}=="028e", MODE="000", GROUP="root", TAG="", RUN+="/bin/chmod 000 /dev/input/%k" \ No newline at end of file diff --git a/99-xbox360-block.rules b/99-xbox360-block.rules new file mode 100644 index 0000000..b4e576a --- /dev/null +++ b/99-xbox360-block.rules @@ -0,0 +1 @@ +ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="045E", ATTRS{idProduct}=="028E", RUN+="/bin/sh -c 'echo 0 > /sys$DEVPATH/authorized'" \ No newline at end of file From 6b5aeaa9efff4e0270e5a00a66073fc57cfb698d Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 22:54:13 +0100 Subject: [PATCH 118/186] Rumble should work better... --- virt_ds5.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index 2373fd7..bcbd2bd 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1084,21 +1084,26 @@ int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *cons uint8_t lightbar_green = common_report[45]; uint8_t lightbar_blue = common_report[46]; - if ((valid_flag0 & DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT)) { + if ((valid_flag0 & DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT) || ((motor_left == 0) && (motor_right == 0))) { + uint8_t motors_shift = 0; if ((valid_flag2 & DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2) || (valid_flag0 & DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION)) { + out_device_status->motors_intensity[0] = (motor_left << 1) | ((motor_left == 0) ? 0 : 1); + out_device_status->motors_intensity[1] = (motor_right << 1) | ((motor_right == 0) ? 0 : 1); + } else { out_device_status->motors_intensity[0] = motor_left; out_device_status->motors_intensity[1] = motor_right; - ++out_device_status->rumble_events_count; + } - if (gamepad->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 - ); - } + ++out_device_status->rumble_events_count; + + if (gamepad->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 + ); } } From bb4ff25130ac4278d0abe552df5123a85dcfb130 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 2 Jan 2024 23:06:51 +0100 Subject: [PATCH 119/186] pressing touchbar should also count as touchbar pressed because on the real hardware you cannot avoid that. --- virt_ds5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt_ds5.c b/virt_ds5.c index bcbd2bd..c4308a2 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1328,7 +1328,7 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c memcpy(&out_shifted_buf[28], ×tamp, sizeof(timestamp)); // point of contact number 0 - out_shifted_buf[33] = in_device_status->touchpad_touch_num == -1 ? 0x80 : 0x7F; //contact + out_shifted_buf[33] = ((in_device_status->touchpad_touch_num == -1) && (!in_device_status->touchpad_press)) ? 0x80 : 0x7F; //contact out_shifted_buf[34] = in_device_status->touchpad_x & (int16_t)0x00FF; //x_lo out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) | ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)); // x_hi:4 y_lo:4 out_shifted_buf[36] = (in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4; //y_hi From 358fba86d65f13f6f7e70be0a129180862673b05 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 00:59:57 +0100 Subject: [PATCH 120/186] allow disabling touchbar + use timestamp from the bmi323 --- allynone.c | 41 +++++++++++++++++++++++------------------ dev_in.c | 23 +++-------------------- dev_out.c | 4 ++-- devices_status.h | 8 ++++---- main.c | 19 ++++++++++++------- message.h | 4 ++-- rog_ally.c | 7 ++++++- rog_ally.h | 2 +- settings.c | 7 +++++++ settings.h | 1 + stray_ally.c | 16 ++++++++++------ virt_ds4.c | 4 ++-- virt_ds4.h | 2 +- virt_ds5.c | 4 ++-- virt_ds5.h | 2 +- 15 files changed, 77 insertions(+), 67 deletions(-) diff --git a/allynone.c b/allynone.c index 987a55f..ba343d1 100644 --- a/allynone.c +++ b/allynone.c @@ -15,6 +15,26 @@ static const char* configuration_file = "/etc/ROGueENEMY/config.cfg"; int main(int argc, char ** argv) { int ret = 0; + // fill in configuration from file: automatic fallback to default + dev_in_settings_t in_settings = { + .enable_qam = true, + .ff_gain = 0xFFFF, + .rumble_on_mode_switch = true, + .m1m2_mode = 0, + .touchbar = true, + }; + + load_in_config(&in_settings, configuration_file); + + dev_out_settings_t out_settings = { + .default_gamepad = 0, + .nintendo_layout = false, + .gamepad_leds_control = true, + .gamepad_rumble_control = true, + }; + + load_out_config(&out_settings, configuration_file); + input_dev_composite_t* in_devs = NULL; int dmi_name_fd = open("/sys/class/dmi/id/board_name", O_RDONLY | O_NONBLOCK); @@ -28,7 +48,7 @@ int main(int argc, char ** argv) { read(dmi_name_fd, bname, sizeof(bname)); if (strstr(bname, "RC71L") != NULL) { printf("Running in an Asus ROG Ally device\n"); - in_devs = rog_ally_device_def(); + in_devs = rog_ally_device_def(&in_settings); } else if (strstr(bname, "LNVNB161216")) { printf("Running in an Lenovo Legion Go device\n"); in_devs = legion_go_device_def(); @@ -85,17 +105,9 @@ int main(int argc, char ** argv) { } } }, - .settings = { - .enable_qam = true, - .ff_gain = 0xFFFF, - .rumble_on_mode_switch = true, - .m1m2_mode = 0, - } + .settings = in_settings, }; - // fill in configuration from file: automatic fallback to default - load_in_config(&dev_in_thread_data.settings, configuration_file); - // populate the output device thread data dev_out_data_t dev_out_thread_data = { .flags = 0x00000000U, @@ -108,16 +120,9 @@ int main(int argc, char ** argv) { } } }, - .settings = { - .default_gamepad = 0, - .nintendo_layout = false, - .gamepad_leds_control = true, - .gamepad_rumble_control = true, - } + .settings = out_settings, }; - load_out_config(&dev_out_thread_data.settings, configuration_file); - pthread_t dev_in_thread; dev_in_thread_creation = pthread_create(&dev_in_thread, NULL, dev_in_thread_func, (void*)(&dev_in_thread_data)); if (dev_in_thread_creation != 0) { diff --git a/dev_in.c b/dev_in.c index bd513b7..3f2418e 100644 --- a/dev_in.c +++ b/dev_in.c @@ -84,14 +84,6 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const uint8_t data[32]; -/* - struct timeval read_time; - gettimeofday(&read_time, NULL); -*/ - - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - res = read(dev_iio_get_buffer_fd(in_iio->iiodev), &data[0], sizeof(data)); if (res == -1) { res = errno; @@ -106,27 +98,18 @@ static int map_message_from_iio(dev_in_iio_t *const in_iio, in_message_t *const } uint16_t *const scan_elements = (uint16_t*)&data[0]; + int64_t *const timestamp = (int64_t*)&data[16]; // either that or (int64_t*)&data[12] messages[0].type = GAMEPAD_SET_ELEMENT; messages[0].data.gamepad_set.element = GAMEPAD_ACCELEROMETER; - messages[1].data.gamepad_set.status.accel.sample_time.tv_sec = now.tv_sec; - messages[1].data.gamepad_set.status.accel.sample_time.tv_usec = now.tv_nsec / 1000; - //messages[0].data.gamepad_set.status.accel.sample_time = read_time; - //messages[0].data.gamepad_set.status.accel.x = scan_elements[0]; - //messages[0].data.gamepad_set.status.accel.y = scan_elements[1]; - //messages[0].data.gamepad_set.status.accel.z = scan_elements[2]; + messages[1].data.gamepad_set.status.accel.sample_timestamp_ns = *timestamp; messages[0].data.gamepad_set.status.accel.x = scan_elements[0]; messages[0].data.gamepad_set.status.accel.y = (uint16_t)(-1) * scan_elements[2]; messages[0].data.gamepad_set.status.accel.z = scan_elements[1]; messages[1].type = GAMEPAD_SET_ELEMENT; messages[1].data.gamepad_set.element = GAMEPAD_GYROSCOPE; - messages[1].data.gamepad_set.status.gyro.sample_time.tv_sec = now.tv_sec; - messages[1].data.gamepad_set.status.gyro.sample_time.tv_usec = now.tv_nsec / 1000; - //messages[0].data.gamepad_set.status.gyro.sample_time = read_time; - //messages[1].data.gamepad_set.status.gyro.x = scan_elements[3]; - //messages[1].data.gamepad_set.status.gyro.y = scan_elements[4]; - //messages[1].data.gamepad_set.status.gyro.z = scan_elements[5]; + messages[1].data.gamepad_set.status.gyro.sample_timestamp_ns = *timestamp; messages[1].data.gamepad_set.status.gyro.x = scan_elements[3]; messages[1].data.gamepad_set.status.gyro.y = (uint16_t)(-1) * scan_elements[5]; messages[1].data.gamepad_set.status.gyro.z = scan_elements[4]; diff --git a/dev_out.c b/dev_out.c index 36e9f76..ee10a5d 100644 --- a/dev_out.c +++ b/dev_out.c @@ -179,14 +179,14 @@ static void handle_incoming_message_gamepad_set( break; } case GAMEPAD_GYROSCOPE: { - inout_gamepad->last_gyro_motion_time = msg_payload->status.gyro.sample_time; + inout_gamepad->last_gyro_motion_timestamp_ns = msg_payload->status.gyro.sample_timestamp_ns; inout_gamepad->raw_gyro[0] = msg_payload->status.gyro.x; inout_gamepad->raw_gyro[1] = msg_payload->status.gyro.y; inout_gamepad->raw_gyro[2] = msg_payload->status.gyro.z; break; } case GAMEPAD_ACCELEROMETER: { - inout_gamepad->last_accel_motion_time = msg_payload->status.accel.sample_time; + inout_gamepad->last_accel_motion_timestamp_ns = msg_payload->status.accel.sample_timestamp_ns; inout_gamepad->raw_accel[0] = msg_payload->status.accel.x; inout_gamepad->raw_accel[1] = msg_payload->status.accel.y; inout_gamepad->raw_accel[2] = msg_payload->status.accel.z; diff --git a/devices_status.h b/devices_status.h index c137df1..51f8ec9 100644 --- a/devices_status.h +++ b/devices_status.h @@ -47,11 +47,11 @@ typedef struct gamepad_status { uint8_t touchpad_press; int16_t touchpad_touch_num; // touchpad is inactive when this is -1 - int16_t touchpad_x; - int16_t touchpad_y; + int16_t touchpad_x; // 0 to 1920 + int16_t touchpad_y; // 0 to 1080 - struct timeval last_gyro_motion_time; - struct timeval last_accel_motion_time; + int64_t last_gyro_motion_timestamp_ns; + int64_t last_accel_motion_timestamp_ns; double gyro[3]; // | x, y, z| right-hand-rules -- in rad/s double accel[3]; // | x, y, z| positive: right, up, towards player -- in m/s^2 diff --git a/main.c b/main.c index 62f4a24..389fb3d 100644 --- a/main.c +++ b/main.c @@ -15,6 +15,16 @@ static const char* configuration_file = "/etc/ROGueENEMY/config.cfg"; int main(int argc, char ** argv) { int ret = 0; + dev_in_settings_t in_settings = { + .enable_qam = true, + .ff_gain = 0xFFFF, + .rumble_on_mode_switch = true, + .m1m2_mode = 1, + .touchbar = true, + }; + + load_in_config(&in_settings, configuration_file); + input_dev_composite_t* in_devs = NULL; int dmi_name_fd = open("/sys/class/dmi/id/board_name", O_RDONLY | O_NONBLOCK); @@ -28,7 +38,7 @@ int main(int argc, char ** argv) { read(dmi_name_fd, bname, sizeof(bname)); if (strstr(bname, "RC71L") != NULL) { printf("Running in an Asus ROG Ally device\n"); - in_devs = rog_ally_device_def(); + in_devs = rog_ally_device_def(&in_settings); } else if (strstr(bname, "LNVNB161216")) { printf("Running in an Lenovo Legion Go device\n"); in_devs = legion_go_device_def(); @@ -51,12 +61,7 @@ int main(int argc, char ** argv) { }, } }, - .settings = { - .enable_qam = true, - .ff_gain = 0xFFFF, - .rumble_on_mode_switch = true, - .m1m2_mode = 0, - } + .settings = in_settings, }; // fill in configuration from file: automatic fallback to default diff --git a/message.h b/message.h index 4fe7632..00f2303 100644 --- a/message.h +++ b/message.h @@ -54,7 +54,7 @@ typedef struct in_message_gamepad_touchpad_active { } in_message_gamepad_touchpad_active_t; typedef struct in_message_gamepad_gyro { - struct timeval sample_time; + int64_t sample_timestamp_ns; uint16_t x; uint16_t y; @@ -62,7 +62,7 @@ typedef struct in_message_gamepad_gyro { } in_message_gamepad_gyro_t; typedef struct in_message_gamepad_accel { - struct timeval sample_time; + int64_t sample_timestamp_ns; uint16_t x; uint16_t y; diff --git a/rog_ally.c b/rog_ally.c index 03d2e0a..25c9b16 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1439,6 +1439,11 @@ input_dev_composite_t rc71l_composite = { .leds_fn = rc71l_platform_leds, }; -input_dev_composite_t* rog_ally_device_def(void) { +input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const settings) { + if (!settings->touchbar) { + // this is because the touchscreen is the latest in the list + rc71l_composite.dev_count -= 1; + } + return &rc71l_composite; } diff --git a/rog_ally.h b/rog_ally.h index 204614d..9152b22 100644 --- a/rog_ally.h +++ b/rog_ally.h @@ -3,4 +3,4 @@ #include "input_dev.h" #include "settings.h" -input_dev_composite_t* rog_ally_device_def(void); +input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const settings); diff --git a/settings.c b/settings.c index 6a2ef48..7efab3c 100644 --- a/settings.c +++ b/settings.c @@ -48,6 +48,13 @@ void load_in_config(dev_in_settings_t *const out_conf, const char* const filepat fprintf(stderr, "m1m2_mode (int) configuration not found. Default value will be used.\n"); } + int touchbar; + if (config_lookup_bool(&cfg, "touchbar", &touchbar) != CONFIG_FALSE) { + out_conf->touchbar = touchbar; + } else { + fprintf(stderr, "touchbar (bool) configuration not found. Default value will be used.\n"); + } + config_destroy(&cfg); load_in_config_err: diff --git a/settings.h b/settings.h index 878ae1a..4ab4f63 100644 --- a/settings.h +++ b/settings.h @@ -7,6 +7,7 @@ typedef struct dev_in_settings { bool rumble_on_mode_switch; uint16_t ff_gain; uint8_t m1m2_mode; + bool touchbar; } dev_in_settings_t; void load_in_config(dev_in_settings_t *const out_conf, const char* const filepath); diff --git a/stray_ally.c b/stray_ally.c index fb165e2..0af98a3 100644 --- a/stray_ally.c +++ b/stray_ally.c @@ -12,6 +12,15 @@ static const char* configuration_file = "/etc/ROGueENEMY/config.cfg"; int main(int argc, char ** argv) { int ret = 0; + dev_out_settings_t out_settings = { + .default_gamepad = 0, + .nintendo_layout = false, + .gamepad_leds_control = true, + .gamepad_rumble_control = true, + }; + + load_out_config(&out_settings, configuration_file); + // Create a signal set containing only SIGTERM sigset_t mask; sigemptyset(&mask); @@ -42,12 +51,7 @@ int main(int argc, char ** argv) { } } }, - .settings = { - .default_gamepad = 0, - .nintendo_layout = false, - .gamepad_leds_control = true, - .gamepad_rumble_control = true, - } + .settings = out_settings, }; load_out_config(&dev_out_thread_data.settings, configuration_file); diff --git a/virt_ds4.c b/virt_ds4.c index 1f2a376..d35627d 100644 --- a/virt_ds4.c +++ b/virt_ds4.c @@ -642,9 +642,9 @@ void virt_dualshock_close(virt_dualshock_t *const out_gamepad) { * This function arranges HID packets as described on https://www.psdevwiki.com/ps4/DS4-USB */ void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *const in_device_status, uint8_t *const out_buf) { - const int64_t time_us = in_device_status->last_gyro_motion_time.tv_sec * 1000000 + in_device_status->last_gyro_motion_time.tv_usec; + const int64_t time_us = in_device_status->last_gyro_motion_timestamp_ns / (int64_t)1000; - const int delta_time = time_us - gamepad->last_time; + const int64_t delta_time = time_us - gamepad->last_time; gamepad->last_time = time_us; // find the average Δt in the last 30 non-zero inputs; diff --git a/virt_ds4.h b/virt_ds4.h index 986e011..83c10c1 100644 --- a/virt_ds4.h +++ b/virt_ds4.h @@ -18,7 +18,7 @@ typedef struct virt_dualshock { uint32_t dt_buffer[30]; uint32_t empty_reports; - uint64_t last_time; + int64_t last_time; } virt_dualshock_t; int virt_dualshock_init(virt_dualshock_t *const gamepad); diff --git a/virt_ds5.c b/virt_ds5.c index c4308a2..6b4ec07 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1248,9 +1248,9 @@ void virt_dualsense_close(virt_dualsense_t *const out_gamepad) { } void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *const in_device_status, uint8_t *const out_buf) { - const int64_t time_us = in_device_status->last_gyro_motion_time.tv_sec * 1000000 + in_device_status->last_gyro_motion_time.tv_usec; + const int64_t time_us = in_device_status->last_gyro_motion_timestamp_ns / (int64_t)1000; - const int delta_time = time_us - gamepad->last_time; + const int64_t delta_time = time_us - gamepad->last_time; gamepad->last_time = time_us; // find the average Δt in the last 30 non-zero inputs; diff --git a/virt_ds5.h b/virt_ds5.h index 6f9d63d..0d111a9 100644 --- a/virt_ds5.h +++ b/virt_ds5.h @@ -22,7 +22,7 @@ typedef struct virt_dualsense { uint32_t dt_buffer[30]; uint32_t empty_reports; - uint64_t last_time; + int64_t last_time; } virt_dualsense_t; int virt_dualsense_init(virt_dualsense_t *const gamepad, bool bluetooth); From d091e54ecb6cb059ee8bcd255ced1cd0ae519858 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 02:09:51 +0100 Subject: [PATCH 121/186] dualshock4 over bluetooth as well --- dev_out.c | 2 +- virt_ds4.c | 289 ++++++++++++++++++++++++++++++++++------------------- virt_ds4.h | 4 +- virt_ds5.c | 10 -- 4 files changed, 192 insertions(+), 113 deletions(-) diff --git a/dev_out.c b/dev_out.c index ee10a5d..b71eb9b 100644 --- a/dev_out.c +++ b/dev_out.c @@ -442,7 +442,7 @@ void *dev_out_thread_func(void *ptr) { printf("DualSense initialized: fd=%d\n", current_gamepad_fd); } } else if (current_gamepad == GAMEPAD_DUALSHOCK) { - const int ds4_init_res = virt_dualshock_init(&controller_data.ds4); + const int ds4_init_res = virt_dualshock_init(&controller_data.ds4, true); if (ds4_init_res != 0) { fprintf(stderr, "Unable to initialize the DualShock device: %d\n", ds4_init_res); } else { diff --git a/virt_ds4.c b/virt_ds4.c index d35627d..9c039f9 100644 --- a/virt_ds4.c +++ b/virt_ds4.c @@ -1,12 +1,7 @@ #include "virt_ds4.h" #include "message.h" -#include #include -#include -#include -#include -#include #define DS4_GYRO_RES_PER_DEG_S 1024 #define DS4_ACC_RES_PER_G 8192 @@ -17,6 +12,24 @@ #define DS4_OUTPUT_VALID_FLAG0_LED 0x02 #define DS4_OUTPUT_VALID_FLAG0_LED_BLINK 0x04 +#define DS4_INPUT_REPORT_USB 0x01 +#define DS4_INPUT_REPORT_USB_SIZE 64 +#define DS4_INPUT_REPORT_BT 0x11 +#define DS4_INPUT_REPORT_BT_SIZE 78 +#define DS4_OUTPUT_REPORT_USB 0x05 +#define DS4_OUTPUT_REPORT_USB_SIZE 32 +#define DS4_OUTPUT_REPORT_BT 0x11 +#define DS4_OUTPUT_REPORT_BT_SIZE 78 + +#define DS4_FEATURE_REPORT_CALIBRATION 0x02 +#define DS4_FEATURE_REPORT_CALIBRATION_SIZE 37 +#define DS4_FEATURE_REPORT_CALIBRATION_BT 0x05 +#define DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE 41 +#define DS4_FEATURE_REPORT_FIRMWARE_INFO 0xa3 +#define DS4_FEATURE_REPORT_FIRMWARE_INFO_SIZE 49 +#define DS4_FEATURE_REPORT_PAIRING_INFO 0x12 +#define DS4_FEATURE_REPORT_PAIRING_INFO_SIZE 16 + static const uint16_t gyro_pitch_bias = 0xfff9; static const uint16_t gyro_yaw_bias = 0x0009; static const uint16_t gyro_roll_bias = 0xfff9; @@ -37,6 +50,15 @@ static const uint16_t acc_z_minus = 0xe086; static const char* path = "/dev/uhid"; +/* Seed values for DualShock4 / DualSense CRC32 for different report types. */ +static uint8_t PS_INPUT_CRC32_SEED = 0xA1; +static uint8_t PS_OUTPUT_CRC32_SEED = 0xA2; +static uint8_t PS_FEATURE_CRC32_SEED = 0xA3; + +static uint32_t crc32_le(uint32_t crc_initial, const uint8_t *const buf, size_t len) { + return crc32(crc_initial ^ 0xffffffff, buf, len) ^ 0xffffffff; +} + static unsigned char rdesc[] = { 0x05, 0x01, /* Usage Page (Desktop), */ 0x09, 0x05, /* Usage (Gamepad), */ @@ -291,6 +313,37 @@ static unsigned char rdesc[] = { 0xC0 /* End Collection */ }; +static unsigned char rdesc_bt[] = { +0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, +0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x04, 0x81, 0x02, 0x09, 0x39, 0x15, 0x00, 0x25, +0x07, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42, 0x05, 0x09, 0x19, 0x01, 0x29, 0x0e, 0x15, 0x00, 0x25, +0x01, 0x75, 0x01, 0x95, 0x0e, 0x81, 0x02, 0x75, 0x06, 0x95, 0x01, 0x81, 0x01, 0x05, 0x01, 0x09, +0x33, 0x09, 0x34, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x02, 0x81, 0x02, 0x06, 0x04, +0xff, 0x85, 0x02, 0x09, 0x24, 0x95, 0x24, 0xb1, 0x02, 0x85, 0xa3, 0x09, 0x25, 0x95, 0x30, 0xb1, +0x02, 0x85, 0x05, 0x09, 0x26, 0x95, 0x28, 0xb1, 0x02, 0x85, 0x06, 0x09, 0x27, 0x95, 0x34, 0xb1, +0x02, 0x85, 0x07, 0x09, 0x28, 0x95, 0x30, 0xb1, 0x02, 0x85, 0x08, 0x09, 0x29, 0x95, 0x2f, 0xb1, +0x02, 0x85, 0x09, 0x09, 0x2a, 0x95, 0x13, 0xb1, 0x02, 0x06, 0x03, 0xff, 0x85, 0x03, 0x09, 0x21, +0x95, 0x26, 0xb1, 0x02, 0x85, 0x04, 0x09, 0x22, 0x95, 0x2e, 0xb1, 0x02, 0x85, 0xf0, 0x09, 0x47, +0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf1, 0x09, 0x48, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf2, 0x09, 0x49, +0x95, 0x0f, 0xb1, 0x02, 0x06, 0x00, 0xff, 0x85, 0x11, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, +0x75, 0x08, 0x95, 0x4d, 0x81, 0x02, 0x09, 0x21, 0x91, 0x02, 0x85, 0x12, 0x09, 0x22, 0x95, 0x8d, +0x81, 0x02, 0x09, 0x23, 0x91, 0x02, 0x85, 0x13, 0x09, 0x24, 0x95, 0xcd, 0x81, 0x02, 0x09, 0x25, +0x91, 0x02, 0x85, 0x14, 0x09, 0x26, 0x96, 0x0d, 0x01, 0x81, 0x02, 0x09, 0x27, 0x91, 0x02, 0x85, +0x15, 0x09, 0x28, 0x96, 0x4d, 0x01, 0x81, 0x02, 0x09, 0x29, 0x91, 0x02, 0x85, 0x16, 0x09, 0x2a, +0x96, 0x8d, 0x01, 0x81, 0x02, 0x09, 0x2b, 0x91, 0x02, 0x85, 0x17, 0x09, 0x2c, 0x96, 0xcd, 0x01, +0x81, 0x02, 0x09, 0x2d, 0x91, 0x02, 0x85, 0x18, 0x09, 0x2e, 0x96, 0x0d, 0x02, 0x81, 0x02, 0x09, +0x2f, 0x91, 0x02, 0x85, 0x19, 0x09, 0x30, 0x96, 0x22, 0x02, 0x81, 0x02, 0x09, 0x31, 0x91, 0x02, +0x06, 0x80, 0xff, 0x85, 0x82, 0x09, 0x22, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0x83, 0x09, 0x23, 0xb1, +0x02, 0x85, 0x84, 0x09, 0x24, 0xb1, 0x02, 0x85, 0x90, 0x09, 0x30, 0xb1, 0x02, 0x85, 0x91, 0x09, +0x31, 0xb1, 0x02, 0x85, 0x92, 0x09, 0x32, 0xb1, 0x02, 0x85, 0x93, 0x09, 0x33, 0xb1, 0x02, 0x85, +0x94, 0x09, 0x34, 0xb1, 0x02, 0x85, 0xa0, 0x09, 0x40, 0xb1, 0x02, 0x85, 0xa4, 0x09, 0x44, 0xb1, +0x02, 0x85, 0xa7, 0x09, 0x45, 0xb1, 0x02, 0x85, 0xa8, 0x09, 0x45, 0xb1, 0x02, 0x85, 0xa9, 0x09, +0x45, 0xb1, 0x02, 0x85, 0xaa, 0x09, 0x45, 0xb1, 0x02, 0x85, 0xab, 0x09, 0x45, 0xb1, 0x02, 0x85, +0xac, 0x09, 0x45, 0xb1, 0x02, 0x85, 0xad, 0x09, 0x45, 0xb1, 0x02, 0x85, 0xb3, 0x09, 0x45, 0xb1, +0x02, 0x85, 0xb4, 0x09, 0x46, 0xb1, 0x02, 0x85, 0xb5, 0x09, 0x47, 0xb1, 0x02, 0x85, 0xd0, 0x09, +0x40, 0xb1, 0x02, 0x85, 0xd4, 0x09, 0x44, 0xb1, 0x02, 0xc0, 0x00 +}; + static int uhid_write(int fd, const struct uhid_event *ev) { ssize_t ret; @@ -308,16 +361,16 @@ static int uhid_write(int fd, const struct uhid_event *ev) } } -static int create(int fd) +static int create(int fd, bool bluetooth) { struct uhid_event ev; memset(&ev, 0, sizeof(ev)); ev.type = UHID_CREATE; strcpy((char*)ev.u.create.name, "Sony Corp. DualShock 4 [CUH-ZCT2x]"); - ev.u.create.rd_data = rdesc; - ev.u.create.rd_size = sizeof(rdesc); - ev.u.create.bus = BUS_USB; + ev.u.create.rd_data = bluetooth ? rdesc_bt : rdesc; + ev.u.create.rd_size = bluetooth ? sizeof(rdesc_bt) : sizeof(rdesc); + ev.u.create.bus = bluetooth ? BUS_BLUETOOTH : BUS_USB; ev.u.create.vendor = 0x054C; ev.u.create.product = 0x09CC; ev.u.create.version = 0; @@ -370,7 +423,7 @@ static ds4_dpad_status_t ds4_dpad_from_gamepad(uint8_t dpad) { return DPAD_RELEASED; } -int virt_dualshock_init(virt_dualshock_t *const out_gamepad) { +int virt_dualshock_init(virt_dualshock_t *const out_gamepad, bool bluetooth) { int ret = 0; out_gamepad->dt_sum = 0; @@ -379,6 +432,7 @@ int virt_dualshock_init(virt_dualshock_t *const out_gamepad) { out_gamepad->debug = false; out_gamepad->empty_reports = 0; out_gamepad->last_time = 0; + out_gamepad->bluetooth = bluetooth; out_gamepad->fd = open(path, O_RDWR | O_CLOEXEC /* | O_NONBLOCK */); if (out_gamepad->fd < 0) { @@ -387,7 +441,7 @@ int virt_dualshock_init(virt_dualshock_t *const out_gamepad) { goto virt_dualshock_init_err; } - ret = create(out_gamepad->fd); + ret = create(out_gamepad->fd, out_gamepad->bluetooth); if (ret) { fprintf(stderr, "Error creating uhid device: %d\n", ret); close(out_gamepad->fd); @@ -452,57 +506,57 @@ int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *cons if (ev.u.output.rtype != UHID_OUTPUT_REPORT) return 0; - /* - if (ds4->update_rumble) { - * Select classic rumble style haptics and enable it. * - common->valid_flag0 |= DS4_OUTPUT_VALID_FLAG0_MOTOR; - common->motor_left = ds4->motor_left; - common->motor_right = ds4->motor_right; - ds4->update_rumble = false; - } - - if (ds4->update_lightbar) { - common->valid_flag0 |= DS4_OUTPUT_VALID_FLAG0_LED; - * Comptabile behavior with hid-sony, which used a dummy global LED to - * allow enabling/disabling the lightbar. The global LED maps to - * lightbar_enabled. - * - common->lightbar_red = ds4->lightbar_enabled ? ds4->lightbar_red : 0; - common->lightbar_green = ds4->lightbar_enabled ? ds4->lightbar_green : 0; - common->lightbar_blue = ds4->lightbar_enabled ? ds4->lightbar_blue : 0; - ds4->update_lightbar = false; - } - - if (ds4->update_lightbar_blink) { - common->valid_flag0 |= DS4_OUTPUT_VALID_FLAG0_LED_BLINK; - common->lightbar_blink_on = ds4->lightbar_blink_on; - common->lightbar_blink_off = ds4->lightbar_blink_off; - ds4->update_lightbar_blink = false; - } - */ - - if (ev.u.output.size != 32) { - fprintf(stderr, "Invalid data length: got %d, expected 32\n", (int)ev.u.output.size); + if ( + (!gamepad->bluetooth) && (ev.u.output.size != DS4_OUTPUT_REPORT_USB_SIZE) && + (gamepad->bluetooth) && (ev.u.output.size != DS4_OUTPUT_REPORT_BT_SIZE) + ) { + fprintf( + stderr, + "Invalid data length: got %d, expected %d\n", + (int)ev.u.output.size, + (gamepad->bluetooth) ? DS4_OUTPUT_REPORT_BT_SIZE : DS4_OUTPUT_REPORT_USB_SIZE + ); return 0; } // first byte is report-id which is 0x01 - if (ev.u.output.data[0] != 0x05) { - fprintf(stderr, "Unrecognised report-id: %d\n", (int)ev.u.output.data[0]); + if ( + (!gamepad->bluetooth) && (ev.u.output.data[0] != DS4_OUTPUT_REPORT_USB) && + (gamepad->bluetooth) && ((ev.u.output.data[0] != DS4_OUTPUT_REPORT_BT) && (ev.u.output.data[0] < 0x10)) + ) { + fprintf( + stderr, + "Unrecognised report-id: got 0x%x expected 0x%x\n", + (int)ev.u.output.data[0], + (gamepad->bluetooth) ? DS4_OUTPUT_REPORT_BT : DS4_OUTPUT_REPORT_USB + ); return 0; } - 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]; + // When using bluetooth, the first byte after the reportID is uint8_t seq_tag, + // while the next one is uint8_t tag, following bytes are the same. + size_t offset = 1; + if ((gamepad->bluetooth) && (ev.u.output.data[0] > 0x10)) { + offset = 2; + } else if ((gamepad->bluetooth) && (ev.u.output.data[0] == 0x02)) { + offset = 3; + } else if ((gamepad->bluetooth) && (ev.u.output.data[0] == 0x01)) { + offset = 1; + } + + const uint8_t *const common_report = &ev.u.output.data[offset]; + + const uint8_t valid_flag0 = common_report[0]; + const uint8_t valid_flag1 = common_report[1]; + const uint8_t reserved = common_report[2]; + const uint8_t motor_right = common_report[3]; + const uint8_t motor_left = common_report[4]; + const uint8_t lightbar_red = common_report[5]; + const uint8_t lightbar_green = common_report[6]; + const uint8_t lightbar_blue = common_report[7]; + const uint8_t lightbar_blink_on = common_report[8]; + const uint8_t lightbar_blink_off = common_report[9]; if ((valid_flag0 & DS4_OUTPUT_VALID_FLAG0_LED)) { out_device_status->leds_colors[0] = lightbar_red; @@ -543,7 +597,7 @@ int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *cons } if (ev.u.get_report.rnum == 18) { - const struct uhid_event mac_addr_response = { + struct uhid_event mac_addr_response = { .type = UHID_GET_REPORT_REPLY, .u = { .get_report_reply = { @@ -558,9 +612,15 @@ int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *cons } }; + if (gamepad->bluetooth) { + uint32_t crc = crc32_le(0xFFFFFFFFU, (const uint8_t*)&PS_FEATURE_CRC32_SEED, sizeof(PS_FEATURE_CRC32_SEED)); + crc = ~crc32_le(crc, (const Bytef *)&mac_addr_response.u.get_report_reply.data[0], mac_addr_response.u.get_report_reply.size - 4); + memcpy(&mac_addr_response.u.get_report_reply.data[mac_addr_response.u.get_report_reply.size - sizeof(crc)], &crc, sizeof(crc)); + } + uhid_write(gamepad->fd, &mac_addr_response); } else if (ev.u.get_report.rnum == 0xa3) { - const struct uhid_event firmware_info_response = { + struct uhid_event firmware_info_response = { .type = UHID_GET_REPORT_REPLY, .u = { .get_report_reply = { @@ -580,9 +640,15 @@ int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *cons } }; + if (gamepad->bluetooth) { + uint32_t crc = crc32_le(0xFFFFFFFFU, (const uint8_t*)&PS_FEATURE_CRC32_SEED, sizeof(PS_FEATURE_CRC32_SEED)); + crc = ~crc32_le(crc, (const Bytef *)&firmware_info_response.u.get_report_reply.data[0], firmware_info_response.u.get_report_reply.size - 4); + memcpy(&firmware_info_response.u.get_report_reply.data[firmware_info_response.u.get_report_reply.size - sizeof(crc)], &crc, sizeof(crc)); + } + uhid_write(gamepad->fd, &firmware_info_response); } else if (ev.u.get_report.rnum == 0x02) { // dualshock4_get_calibration_data - struct uhid_event firmware_info_response = { + struct uhid_event calibration_response = { .type = UHID_GET_REPORT_REPLY, .u = { .get_report_reply = { @@ -605,25 +671,31 @@ int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *cons // speed_2x = speed_2x*DS4_GYRO_RES_PER_DEG_S; calculated by the kernel will be 1080. // As a consequence sens_numer (for every axis) is 1080*1024. // that number will be 1105920 - memcpy((void*)&firmware_info_response.u.get_report_reply.data[1], (const void*)&gyro_pitch_bias, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[3], (const void*)&gyro_yaw_bias, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[5], (const void*)&gyro_roll_bias, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[7], (const void*)&gyro_pitch_plus, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[9], (const void*)&gyro_pitch_minus, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[11], (const void*)&gyro_yaw_plus, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[13], (const void*)&gyro_yaw_minus, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[15], (const void*)&gyro_roll_plus, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[17], (const void*)&gyro_roll_minus, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[19], (const void*)&gyro_speed_plus, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[21], (const void*)&gyro_speed_minus, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[23], (const void*)&acc_x_plus, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[25], (const void*)&acc_x_minus, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[27], (const void*)&acc_y_plus, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[29], (const void*)&acc_y_minus, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[31], (const void*)&acc_z_plus, sizeof(int16_t)); - memcpy((void*)&firmware_info_response.u.get_report_reply.data[33], (const void*)&acc_z_minus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[1], (const void*)&gyro_pitch_bias, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[3], (const void*)&gyro_yaw_bias, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[5], (const void*)&gyro_roll_bias, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[7], (const void*)&gyro_pitch_plus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[9], (const void*)&gyro_pitch_minus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[11], (const void*)&gyro_yaw_plus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[13], (const void*)&gyro_yaw_minus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[15], (const void*)&gyro_roll_plus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[17], (const void*)&gyro_roll_minus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[19], (const void*)&gyro_speed_plus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[21], (const void*)&gyro_speed_minus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[23], (const void*)&acc_x_plus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[25], (const void*)&acc_x_minus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[27], (const void*)&acc_y_plus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[29], (const void*)&acc_y_minus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[31], (const void*)&acc_z_plus, sizeof(int16_t)); + memcpy((void*)&calibration_response.u.get_report_reply.data[33], (const void*)&acc_z_minus, sizeof(int16_t)); - uhid_write(gamepad->fd, &firmware_info_response); + if (gamepad->bluetooth) { + uint32_t crc = crc32_le(0xFFFFFFFFU, (const uint8_t*)&PS_FEATURE_CRC32_SEED, sizeof(PS_FEATURE_CRC32_SEED)); + crc = ~crc32_le(crc, (const Bytef *)&calibration_response.u.get_report_reply.data[0], calibration_response.u.get_report_reply.size - 4); + memcpy(&calibration_response.u.get_report_reply.data[calibration_response.u.get_report_reply.size - sizeof(crc)], &crc, sizeof(crc)); + } + + uhid_write(gamepad->fd, &calibration_response); } break; @@ -720,18 +792,21 @@ void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *c const int16_t a_y = (int16_t)(-1) * in_device_status->raw_accel[1]; // Swap Y and Z const int16_t a_z = (int16_t)(-1) * in_device_status->raw_accel[2]; // Swap Y and Z - out_buf[0] = 0x01; // [00] report ID (0x01) - out_buf[1] = ((uint64_t)((int64_t)in_device_status->joystick_positions[0][0] + (int64_t)32768) >> (uint64_t)8); // L stick, X axis - out_buf[2] = ((uint64_t)((int64_t)in_device_status->joystick_positions[0][1] + (int64_t)32768) >> (uint64_t)8); // L stick, Y axis - out_buf[3] = ((uint64_t)((int64_t)in_device_status->joystick_positions[1][0] + (int64_t)32768) >> (uint64_t)8); // R stick, X axis - out_buf[4] = ((uint64_t)((int64_t)in_device_status->joystick_positions[1][1] + (int64_t)32768) >> (uint64_t)8); // R stick, Y axis - out_buf[5] = + out_buf[0] = gamepad->bluetooth ? DS4_INPUT_REPORT_BT : DS4_INPUT_REPORT_USB; // [00] report ID (0x01) + + uint8_t *const out_shifted_buf = gamepad->bluetooth ? &out_buf[1] : &out_buf[0]; + + out_shifted_buf[1] = ((uint64_t)((int64_t)in_device_status->joystick_positions[0][0] + (int64_t)32768) >> (uint64_t)8); // L stick, X axis + out_shifted_buf[2] = ((uint64_t)((int64_t)in_device_status->joystick_positions[0][1] + (int64_t)32768) >> (uint64_t)8); // L stick, Y 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[5] = (in_device_status->triangle ? 0x80 : 0x00) | (in_device_status->circle ? 0x40 : 0x00) | (in_device_status->cross ? 0x20 : 0x00) | (in_device_status->square ? 0x10 : 0x00) | (uint8_t)ds4_dpad_from_gamepad(in_device_status->dpad); - out_buf[6] = + out_shifted_buf[6] = (in_device_status->r3 ? 0x80 : 0x00) | (in_device_status->l3 ? 0x40 : 0x00) | (in_device_status->share ? 0x20 : 0x00) | @@ -746,27 +821,33 @@ void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *c buf[7] = (((counter++) % (uint8_t)64) << ((uint8_t)2)) | get_buttons_byte3_by_gs(&gs); */ - out_buf[7] = in_device_status->center ? 0x01 : 0x00; + out_shifted_buf[7] = in_device_status->center ? 0x01 : 0x00; - out_buf[8] = in_device_status->l2_trigger; - out_buf[9] = in_device_status->r2_trigger; - memcpy(&out_buf[10], ×tamp, sizeof(timestamp)); - out_buf[12] = 0x20; // [12] battery level | this is called sensor_temparature in the kernel driver but is never used... - memcpy(&out_buf[13], &g_x, sizeof(int16_t)); - memcpy(&out_buf[15], &g_y, sizeof(int16_t)); - memcpy(&out_buf[17], &g_z, sizeof(int16_t)); - memcpy(&out_buf[19], &a_x, sizeof(int16_t)); - memcpy(&out_buf[21], &a_y, sizeof(int16_t)); - memcpy(&out_buf[23], &a_z, sizeof(int16_t)); + out_shifted_buf[8] = in_device_status->l2_trigger; + out_shifted_buf[9] = in_device_status->r2_trigger; + memcpy(&out_shifted_buf[10], ×tamp, sizeof(timestamp)); + out_shifted_buf[12] = 0x20; // [12] battery level | this is called sensor_temparature in the kernel driver but is never used... + memcpy(&out_shifted_buf[13], &g_x, sizeof(int16_t)); + memcpy(&out_shifted_buf[15], &g_y, sizeof(int16_t)); + memcpy(&out_shifted_buf[17], &g_z, sizeof(int16_t)); + memcpy(&out_shifted_buf[19], &a_x, sizeof(int16_t)); + memcpy(&out_shifted_buf[21], &a_y, sizeof(int16_t)); + memcpy(&out_shifted_buf[23], &a_z, sizeof(int16_t)); - out_buf[30] = 0x1b; // no headset attached + out_shifted_buf[30] = 0x1b; // no headset attached - out_buf[62] = 0x80; // IDK... it seems constant... - out_buf[57] = 0x80; // IDK... it seems constant... - out_buf[53] = 0x80; // IDK... it seems constant... - out_buf[48] = 0x80; // IDK... it seems constant... - out_buf[35] = 0x80; // IDK... it seems constant... - out_buf[44] = 0x80; // IDK... it seems constant... + out_shifted_buf[62] = 0x80; // IDK... it seems constant... + out_shifted_buf[57] = 0x80; // IDK... it seems constant... + out_shifted_buf[53] = 0x80; // IDK... it seems constant... + out_shifted_buf[48] = 0x80; // IDK... it seems constant... + out_shifted_buf[35] = 0x80; // IDK... it seems constant... + out_shifted_buf[44] = 0x80; // IDK... it seems constant... + + if (gamepad->bluetooth) { + uint32_t crc = crc32_le(0xFFFFFFFFU, (const uint8_t*)&PS_FEATURE_CRC32_SEED, sizeof(PS_FEATURE_CRC32_SEED)); + crc = ~crc32_le(crc, (const Bytef *)&out_shifted_buf[0], DS4_INPUT_REPORT_BT_SIZE - 4); + memcpy(&out_shifted_buf[DS4_INPUT_REPORT_BT_SIZE - sizeof(crc)], &crc, sizeof(crc)); + } } int virt_dualshock_send(virt_dualshock_t *const gamepad, uint8_t *const out_buf) { @@ -774,12 +855,18 @@ int virt_dualshock_send(virt_dualshock_t *const gamepad, uint8_t *const out_buf) .type = UHID_INPUT2, .u = { .input2 = { - .size = 64, + .size = gamepad->bluetooth ? DS4_INPUT_REPORT_BT_SIZE : DS4_INPUT_REPORT_USB_SIZE, } } }; memcpy(&l.u.input2.data[0], &out_buf[0], l.u.input2.size); + if (gamepad->bluetooth) { + uint32_t crc = crc32_le(0xFFFFFFFFU, (const uint8_t*)&PS_INPUT_CRC32_SEED, sizeof(PS_INPUT_CRC32_SEED)); + crc = ~crc32_le(crc, (const uint8_t *)&l.u.input2.data[0], l.u.input2.size - 4); + memcpy(&l.u.input2.data[l.u.input2.size - sizeof(crc)], &crc, sizeof(crc)); + } + return uhid_write(gamepad->fd, &l); } diff --git a/virt_ds4.h b/virt_ds4.h index 83c10c1..b9faa7f 100644 --- a/virt_ds4.h +++ b/virt_ds4.h @@ -13,6 +13,8 @@ typedef struct virt_dualshock { bool debug; + bool bluetooth; + uint32_t dt_sum; uint8_t dt_buffer_current; uint32_t dt_buffer[30]; @@ -21,7 +23,7 @@ typedef struct virt_dualshock { int64_t last_time; } virt_dualshock_t; -int virt_dualshock_init(virt_dualshock_t *const gamepad); +int virt_dualshock_init(virt_dualshock_t *const gamepad, bool bluetooth); int virt_dualshock_get_fd(virt_dualshock_t *const gamepad); diff --git a/virt_ds5.c b/virt_ds5.c index 6b4ec07..ee5d274 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1,7 +1,6 @@ #include "virt_ds5.h" #include "message.h" -#include #include #define DS_FEATURE_REPORT_PAIRING_INFO 0x09 @@ -31,15 +30,6 @@ #define DS5_SPEC_DELTA_TIME 4096.0f -static uint32_t le(uint32_t num) { - const uint32_t b0 = (num & 0x000000ff) << 24u; - const uint32_t b1 = (num & 0x0000ff00) << 8u; - const uint32_t b2 = (num & 0x00ff0000) >> 8u; - const uint32_t b3 = (num & 0xff000000) >> 24u; - - return b0 | b1 | b2 | b3; -} - static uint32_t crc32_le(uint32_t crc_initial, const uint8_t *const buf, size_t len) { return crc32(crc_initial ^ 0xffffffff, buf, len) ^ 0xffffffff; } From 337244b0de7001d28fe4f8765c4f364a2442abc1 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 02:26:45 +0100 Subject: [PATCH 122/186] oh uniq must be 16 bytes --- virt_ds4.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/virt_ds4.c b/virt_ds4.c index 9c039f9..dd173af 100644 --- a/virt_ds4.c +++ b/virt_ds4.c @@ -59,6 +59,8 @@ static uint32_t crc32_le(uint32_t crc_initial, const uint8_t *const buf, size_t return crc32(crc_initial ^ 0xffffffff, buf, len) ^ 0xffffffff; } +static const uint8_t MAC_ADDR[] = { 0xf2, 0xa5, 0x71, 0x68, 0xaf, 0xdc }; + static unsigned char rdesc[] = { 0x05, 0x01, /* Usage Page (Desktop), */ 0x09, 0x05, /* Usage (Gamepad), */ @@ -376,6 +378,10 @@ static int create(int fd, bool bluetooth) ev.u.create.version = 0; ev.u.create.country = 0; + sprintf((char*)ev.u.create.uniq, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + MAC_ADDR[5], MAC_ADDR[4], MAC_ADDR[3], MAC_ADDR[2], MAC_ADDR[1], MAC_ADDR[0] + ); + return uhid_write(fd, &ev); } @@ -605,7 +611,9 @@ int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *cons .id = ev.u.get_report.id, .err = 0, .data = { - 0x12, 0xf2, 0xa5, 0x71, 0x68, 0xaf, 0xdc, 0x08, + DS4_FEATURE_REPORT_PAIRING_INFO, + MAC_ADDR[0], MAC_ADDR[1], MAC_ADDR[2], MAC_ADDR[3], MAC_ADDR[4], MAC_ADDR[5], + 0x08, 0x25, 0x00, 0x4c, 0x46, 0x49, 0x0e, 0x41, 0x00 } } From 7b50fbfca1b5519bbc329a3fd79ea54677d4dcb1 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 02:41:51 +0100 Subject: [PATCH 123/186] Fix dualshock emulating over bluetooth --- virt_ds4.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/virt_ds4.c b/virt_ds4.c index dd173af..6ccb11a 100644 --- a/virt_ds4.c +++ b/virt_ds4.c @@ -607,7 +607,7 @@ int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *cons .type = UHID_GET_REPORT_REPLY, .u = { .get_report_reply = { - .size = 16, + .size = DS4_FEATURE_REPORT_PAIRING_INFO_SIZE, .id = ev.u.get_report.id, .err = 0, .data = { @@ -627,16 +627,16 @@ int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *cons } uhid_write(gamepad->fd, &mac_addr_response); - } else if (ev.u.get_report.rnum == 0xa3) { + } else if (ev.u.get_report.rnum == DS4_FEATURE_REPORT_FIRMWARE_INFO) { struct uhid_event firmware_info_response = { .type = UHID_GET_REPORT_REPLY, .u = { .get_report_reply = { - .size = 49, + .size = DS4_FEATURE_REPORT_FIRMWARE_INFO_SIZE, .id = ev.u.get_report.id, .err = 0, .data = { - 0xa3, 0x53, 0x65, 0x70, 0x20, 0x32, 0x31, 0x20, + DS4_FEATURE_REPORT_FIRMWARE_INFO, 0x53, 0x65, 0x70, 0x20, 0x32, 0x31, 0x20, 0x32, 0x30, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x34, 0x3a, 0x35, 0x30, 0x3a, 0x35, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -655,21 +655,25 @@ int virt_dualshock_event(virt_dualshock_t *const gamepad, gamepad_status_t *cons } uhid_write(gamepad->fd, &firmware_info_response); - } else if (ev.u.get_report.rnum == 0x02) { // dualshock4_get_calibration_data + } else if ( + ((gamepad->bluetooth) && (ev.u.get_report.rnum == DS4_FEATURE_REPORT_CALIBRATION_BT)) || + ((!gamepad->bluetooth) && (ev.u.get_report.rnum == DS4_FEATURE_REPORT_CALIBRATION)) + ) { // dualshock4_get_calibration_data struct uhid_event calibration_response = { .type = UHID_GET_REPORT_REPLY, .u = { .get_report_reply = { - .size = 37, + .size = gamepad->bluetooth ? DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE : DS4_FEATURE_REPORT_CALIBRATION_SIZE, .id = ev.u.get_report.id, .err = 0, .data = { - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + gamepad->bluetooth ? DS4_FEATURE_REPORT_CALIBRATION_BT : DS4_FEATURE_REPORT_CALIBRATION, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x00, - + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, } } } From 2c3d7de0e4f7bd8f45aa501f07c916c189a09443 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 02:56:07 +0100 Subject: [PATCH 124/186] kernel does it this way... --- virt_ds4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt_ds4.c b/virt_ds4.c index 6ccb11a..3dda39d 100644 --- a/virt_ds4.c +++ b/virt_ds4.c @@ -806,7 +806,7 @@ void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *c out_buf[0] = gamepad->bluetooth ? DS4_INPUT_REPORT_BT : DS4_INPUT_REPORT_USB; // [00] report ID (0x01) - uint8_t *const out_shifted_buf = gamepad->bluetooth ? &out_buf[1] : &out_buf[0]; + uint8_t *const out_shifted_buf = gamepad->bluetooth ? &out_buf[2] : &out_buf[0]; out_shifted_buf[1] = ((uint64_t)((int64_t)in_device_status->joystick_positions[0][0] + (int64_t)32768) >> (uint64_t)8); // L stick, X axis out_shifted_buf[2] = ((uint64_t)((int64_t)in_device_status->joystick_positions[0][1] + (int64_t)32768) >> (uint64_t)8); // L stick, Y axis From 4b6183eeb6f6018759b1daeafe32d19851388f16 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 03:16:18 +0100 Subject: [PATCH 125/186] Remove the finger emulation for m1m2 --- virt_ds5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt_ds5.c b/virt_ds5.c index ee5d274..b135fc8 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1318,7 +1318,7 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c memcpy(&out_shifted_buf[28], ×tamp, sizeof(timestamp)); // point of contact number 0 - out_shifted_buf[33] = ((in_device_status->touchpad_touch_num == -1) && (!in_device_status->touchpad_press)) ? 0x80 : 0x7F; //contact + out_shifted_buf[33] = (in_device_status->touchpad_touch_num == -1) ? 0x80 : 0x7F; //contact out_shifted_buf[34] = in_device_status->touchpad_x & (int16_t)0x00FF; //x_lo out_shifted_buf[35] = (((in_device_status->touchpad_x & (int16_t)0x0F00) >> (int16_t)8) | ((in_device_status->touchpad_y & (int16_t)0x000F) << (int16_t)4)); // x_hi:4 y_lo:4 out_shifted_buf[36] = (in_device_status->touchpad_y & (int16_t)0x0FF0) >> (int16_t)4; //y_hi From b38563243f4575836d7ff60df37e82e55a056c1b Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 03:16:39 +0100 Subject: [PATCH 126/186] Do not use bluetooth for dualshock for now --- dev_out.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_out.c b/dev_out.c index b71eb9b..721737c 100644 --- a/dev_out.c +++ b/dev_out.c @@ -442,7 +442,7 @@ void *dev_out_thread_func(void *ptr) { printf("DualSense initialized: fd=%d\n", current_gamepad_fd); } } else if (current_gamepad == GAMEPAD_DUALSHOCK) { - const int ds4_init_res = virt_dualshock_init(&controller_data.ds4, true); + const int ds4_init_res = virt_dualshock_init(&controller_data.ds4, false); if (ds4_init_res != 0) { fprintf(stderr, "Unable to initialize the DualShock device: %d\n", ds4_init_res); } else { From eec5cadf8c8e007cb016622aad371e3949ba2f48 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 03:36:55 +0100 Subject: [PATCH 127/186] Remove dead code --- virt_ds4.c | 6 ------ virt_ds5.c | 6 ------ 2 files changed, 12 deletions(-) diff --git a/virt_ds4.c b/virt_ds4.c index 3dda39d..d9f58a2 100644 --- a/virt_ds4.c +++ b/virt_ds4.c @@ -854,12 +854,6 @@ void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *c out_shifted_buf[48] = 0x80; // IDK... it seems constant... out_shifted_buf[35] = 0x80; // IDK... it seems constant... out_shifted_buf[44] = 0x80; // IDK... it seems constant... - - if (gamepad->bluetooth) { - uint32_t crc = crc32_le(0xFFFFFFFFU, (const uint8_t*)&PS_FEATURE_CRC32_SEED, sizeof(PS_FEATURE_CRC32_SEED)); - crc = ~crc32_le(crc, (const Bytef *)&out_shifted_buf[0], DS4_INPUT_REPORT_BT_SIZE - 4); - memcpy(&out_shifted_buf[DS4_INPUT_REPORT_BT_SIZE - sizeof(crc)], &crc, sizeof(crc)); - } } int virt_dualshock_send(virt_dualshock_t *const gamepad, uint8_t *const out_buf) { diff --git a/virt_ds5.c b/virt_ds5.c index b135fc8..15c994b 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1328,12 +1328,6 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c out_shifted_buf[38] = 0x00; //x_lo out_shifted_buf[39] = 0x00; //x_hi:4 y_lo:4 out_shifted_buf[40] = 0x00; //y_hi - - if (gamepad->bluetooth) { - uint32_t crc = crc32_le(0xFFFFFFFFU, (const uint8_t*)&PS_FEATURE_CRC32_SEED, sizeof(PS_FEATURE_CRC32_SEED)); - crc = ~crc32_le(crc, (const Bytef *)&out_shifted_buf[0], DS_INPUT_REPORT_BT_SIZE - 4); - memcpy(&out_shifted_buf[DS_INPUT_REPORT_BT_SIZE - sizeof(crc)], &crc, sizeof(crc)); - } } int virt_dualsense_send(virt_dualsense_t *const gamepad, uint8_t *const out_shifted_buf) { From 778082077cc03f64b60f5dd48bb505973c28ac8f Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 04:05:34 +0100 Subject: [PATCH 128/186] controller over bluetooth settings parameter added --- allynone.c | 1 + config.cfg.default | 3 ++- dev_out.c | 4 ++-- settings.c | 7 +++++++ settings.h | 1 + stray_ally.c | 1 + 6 files changed, 14 insertions(+), 3 deletions(-) diff --git a/allynone.c b/allynone.c index ba343d1..218d089 100644 --- a/allynone.c +++ b/allynone.c @@ -31,6 +31,7 @@ int main(int argc, char ** argv) { .nintendo_layout = false, .gamepad_leds_control = true, .gamepad_rumble_control = true, + .controller_bluetooth = false, }; load_out_config(&out_settings, configuration_file); diff --git a/config.cfg.default b/config.cfg.default index 2297cb6..2049acd 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -5,4 +5,5 @@ default_gamepad = 1; rumble_on_mode_switch = true; gamepad_rumble_control = true; gamepad_leds_control = true; -m1m2_mode = 1; \ No newline at end of file +m1m2_mode = 1; +controller_bluetooth = false; \ No newline at end of file diff --git a/dev_out.c b/dev_out.c index 721737c..c5fd3a1 100644 --- a/dev_out.c +++ b/dev_out.c @@ -434,7 +434,7 @@ void *dev_out_thread_func(void *ptr) { const int64_t gamepad_report_timing_us = 1250; if (current_gamepad == GAMEPAD_DUALSENSE) { - const int ds5_init_res = virt_dualsense_init(&controller_data.ds5, true); + const int ds5_init_res = virt_dualsense_init(&controller_data.ds5, dev_out_data->settings.controller_bluetooth); if (ds5_init_res != 0) { fprintf(stderr, "Unable to initialize the DualSense device: %d\n", ds5_init_res); } else { @@ -442,7 +442,7 @@ void *dev_out_thread_func(void *ptr) { printf("DualSense initialized: fd=%d\n", current_gamepad_fd); } } else if (current_gamepad == GAMEPAD_DUALSHOCK) { - const int ds4_init_res = virt_dualshock_init(&controller_data.ds4, false); + const int ds4_init_res = virt_dualshock_init(&controller_data.ds4, dev_out_data->settings.controller_bluetooth); if (ds4_init_res != 0) { fprintf(stderr, "Unable to initialize the DualShock device: %d\n", ds4_init_res); } else { diff --git a/settings.c b/settings.c index 7efab3c..15f0c7b 100644 --- a/settings.c +++ b/settings.c @@ -99,6 +99,13 @@ void load_out_config(dev_out_settings_t *const out_conf, const char* const filep fprintf(stderr, "gamepad_rumble_control (bool) configuration not found. Default value will be used.\n"); } + int controller_bluetooth; + if (config_lookup_bool(&cfg, "controller_bluetooth", &controller_bluetooth) != CONFIG_FALSE) { + out_conf->controller_bluetooth = controller_bluetooth; + } else { + fprintf(stderr, "controller_bluetooth (bool) configuration not found. Default value will be used.\n"); + } + config_destroy(&cfg); load_out_config_err: diff --git a/settings.h b/settings.h index 4ab4f63..8a9af80 100644 --- a/settings.h +++ b/settings.h @@ -17,6 +17,7 @@ typedef struct dev_out_settings { uint8_t default_gamepad; bool gamepad_leds_control; bool gamepad_rumble_control; + bool controller_bluetooth; } dev_out_settings_t; void load_out_config(dev_out_settings_t *const out_conf, const char* const filepath); \ No newline at end of file diff --git a/stray_ally.c b/stray_ally.c index 0af98a3..bf395db 100644 --- a/stray_ally.c +++ b/stray_ally.c @@ -17,6 +17,7 @@ int main(int argc, char ** argv) { .nintendo_layout = false, .gamepad_leds_control = true, .gamepad_rumble_control = true, + .controller_bluetooth = false, }; load_out_config(&out_settings, configuration_file); From 92344032975e355d4b580c81812b980de3535619 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 04:09:58 +0100 Subject: [PATCH 129/186] change default config --- config.cfg.default | 1 + 1 file changed, 1 insertion(+) diff --git a/config.cfg.default b/config.cfg.default index 2049acd..6cb1260 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -6,4 +6,5 @@ rumble_on_mode_switch = true; gamepad_rumble_control = true; gamepad_leds_control = true; m1m2_mode = 1; +touchbar = true; controller_bluetooth = false; \ No newline at end of file From d208f5dc2a8bb219525a77c77a58c5d05135ca94 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 15:11:39 +0100 Subject: [PATCH 130/186] Print bluetooth emulation info --- dev_out.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev_out.c b/dev_out.c index c5fd3a1..fb04007 100644 --- a/dev_out.c +++ b/dev_out.c @@ -439,7 +439,7 @@ void *dev_out_thread_func(void *ptr) { fprintf(stderr, "Unable to initialize the DualSense device: %d\n", ds5_init_res); } else { current_gamepad_fd = virt_dualsense_get_fd(&controller_data.ds5); - printf("DualSense initialized: fd=%d\n", current_gamepad_fd); + printf("DualSense initialized: fd=%d, bluetooth=%s\n", current_gamepad_fd, dev_out_data->settings.controller_bluetooth ? "true" : "false"); } } else if (current_gamepad == GAMEPAD_DUALSHOCK) { const int ds4_init_res = virt_dualshock_init(&controller_data.ds4, dev_out_data->settings.controller_bluetooth); @@ -447,7 +447,7 @@ void *dev_out_thread_func(void *ptr) { fprintf(stderr, "Unable to initialize the DualShock device: %d\n", ds4_init_res); } else { current_gamepad_fd = virt_dualshock_get_fd(&controller_data.ds4); - printf("DualShock initialized: fd=%d\n", current_gamepad_fd); + printf("DualShock initialized: fd=%d, bluetooth=%s\n", current_gamepad_fd, dev_out_data->settings.controller_bluetooth ? "true" : "false"); } } From 026e9706153c4162da2c3fe1ab598b63addedfbe Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 15:39:19 +0100 Subject: [PATCH 131/186] join analogs and gyroscope --- dev_out.c | 8 ++++++++ devices_status.c | 2 ++ devices_status.h | 3 +++ message.h | 2 ++ rog_ally.c | 28 ++++++++++++++++++++++++++++ rogue_enemy.c | 6 ++++++ rogue_enemy.h | 2 ++ virt_ds5.c | 39 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 90 insertions(+) diff --git a/dev_out.c b/dev_out.c index fb04007..3d1707c 100644 --- a/dev_out.c +++ b/dev_out.c @@ -134,6 +134,14 @@ static void handle_incoming_message_gamepad_set( inout_gamepad->touchpad_press = msg_payload->status.btn; break; } + case GAMEPAD_BTN_JOIN_LEFT_ANALOG_AND_GYROSCOPE: { + inout_gamepad->join_left_analog_and_gyroscope = msg_payload->status.btn; + break; + } + case GAMEPAD_BTN_JOIN_RIGHT_ANALOG_AND_GYROSCOPE: { + inout_gamepad->join_right_analog_and_gyroscope = msg_payload->status.btn; + break; + } case GAMEPAD_LEFT_JOYSTICK_X: { inout_gamepad->joystick_positions[0][0] = msg_payload->status.joystick_pos; break; diff --git a/devices_status.c b/devices_status.c index 6173659..ef12fba 100644 --- a/devices_status.c +++ b/devices_status.c @@ -98,6 +98,8 @@ void gamepad_status_init(gamepad_status_t *const stats) { stats->touchpad_touch_num = -1; stats->touchpad_x = 0; stats->touchpad_y = 0; + stats->join_left_analog_and_gyroscope = 0; + stats->join_right_analog_and_gyroscope = 0; stats->flags = 0; } diff --git a/devices_status.h b/devices_status.h index 51f8ec9..6c55136 100644 --- a/devices_status.h +++ b/devices_status.h @@ -65,6 +65,9 @@ typedef struct gamepad_status { uint64_t leds_events_count; uint8_t leds_colors[3]; // r | g | b + uint8_t join_left_analog_and_gyroscope; + uint8_t join_right_analog_and_gyroscope; + volatile uint32_t flags; } gamepad_status_t; diff --git a/message.h b/message.h index 00f2303..7f91be8 100644 --- a/message.h +++ b/message.h @@ -24,6 +24,8 @@ typedef enum in_message_gamepad_btn { GAMEPAD_BTN_L5, GAMEPAD_BTN_R5, GAMEPAD_BTN_TOUCHPAD, + GAMEPAD_BTN_JOIN_LEFT_ANALOG_AND_GYROSCOPE, + GAMEPAD_BTN_JOIN_RIGHT_ANALOG_AND_GYROSCOPE, GAMEPAD_LEFT_JOYSTICK_X, GAMEPAD_LEFT_JOYSTICK_Y, diff --git a/rog_ally.c b/rog_ally.c index 25c9b16..eab7cc6 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -224,6 +224,20 @@ static int asus_kbd_ev_map( } }; + messages[written_msg++] = current_message; + } else if (conf->m1m2_mode == 2) { + const in_message_t current_message = { + .type = GAMEPAD_SET_ELEMENT, + .data = { + .gamepad_set = { + .element = GAMEPAD_BTN_JOIN_RIGHT_ANALOG_AND_GYROSCOPE, + .status = { + .btn = e->ev[1].value, + } + } + } + }; + messages[written_msg++] = current_message; } } else if (e->ev[i].code == KEY_F15) { @@ -262,6 +276,20 @@ static int asus_kbd_ev_map( } }; + messages[written_msg++] = current_message; + } else if (conf->m1m2_mode == 2) { + const in_message_t current_message = { + .type = GAMEPAD_SET_ELEMENT, + .data = { + .gamepad_set = { + .element = GAMEPAD_BTN_JOIN_LEFT_ANALOG_AND_GYROSCOPE, + .status = { + .btn = e->ev[1].value, + } + } + } + }; + messages[written_msg++] = current_message; } } else if ((e->ev[i].code == KEY_F16) && (e->ev[i].value != 0)) { diff --git a/rogue_enemy.c b/rogue_enemy.c index 218b4ff..88572a4 100644 --- a/rogue_enemy.c +++ b/rogue_enemy.c @@ -5,3 +5,9 @@ int32_t div_round_closest(int32_t x, int32_t divisor) { const int32_t __d = divisor; return ((__x) > 0) == ((__d) > 0) ? (((__x) + ((__d) / 2)) / (__d)) : (((__x) - ((__d) / 2)) / (__d)); } + +int64_t div_round_closest_i64(int64_t x, int64_t divisor) { + const int64_t __x = x; + const int64_t __d = divisor; + return ((__x) > 0) == ((__d) > 0) ? (((__x) + ((__d) / 2)) / (__d)) : (((__x) - ((__d) / 2)) / (__d)); +} \ No newline at end of file diff --git a/rogue_enemy.h b/rogue_enemy.h index 5ccb243..b868579 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -61,3 +61,5 @@ // also courtesy of linux kernel int32_t div_round_closest(int32_t x, int32_t divisor); + +int64_t div_round_closest_i64(int64_t x, int64_t divisor); diff --git a/virt_ds5.c b/virt_ds5.c index 15c994b..6840260 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1282,6 +1282,45 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c out_shifted_buf[2] = ((uint64_t)((int64_t)in_device_status->joystick_positions[0][1] + (int64_t)32768) >> (uint64_t)8); // L stick, Y 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 + + if (in_device_status->join_left_analog_and_gyroscope) { + int64_t joint_x = ((int64_t)out_shifted_buf[1] - (int64_t)128) + (div_round_closest_i64((int64_t)255 * ((int64_t)32768 + (int64_t)in_device_status->raw_gyro[0]), 0xFFFF) - (int64_t)128); + if (joint_x < (int64_t)-128) { + joint_x = -128; + } else if (joint_x < (int64_t)127) { + joint_x = 127; + } + + int64_t joint_y = ((int64_t)out_shifted_buf[2] - (int64_t)128) + (div_round_closest_i64((int64_t)255 * ((int64_t)32768 + (int64_t)in_device_status->raw_gyro[1]), 0xFFFF) - (int64_t)128); + if (joint_y < (int64_t)-128) { + joint_y = -128; + } else if (joint_x < (int64_t)127) { + joint_y = 127; + } + + out_shifted_buf[1] = joint_x + (int64_t)128; + out_shifted_buf[2] = joint_y + (int64_t)128; + } + + if (in_device_status->join_right_analog_and_gyroscope) { + int64_t joint_x = ((int64_t)out_shifted_buf[3] - (int64_t)128) + (div_round_closest_i64((int64_t)255 * ((int64_t)32768 + (int64_t)in_device_status->raw_gyro[0]), 0xFFFF) - (int64_t)128); + if (joint_x < (int64_t)-128) { + joint_x = -128; + } else if (joint_x < (int64_t)127) { + joint_x = 127; + } + + int64_t joint_y = ((int64_t)out_shifted_buf[4] - (int64_t)128) + (div_round_closest_i64((int64_t)255 * ((int64_t)32768 + (int64_t)in_device_status->raw_gyro[1]), 0xFFFF) - (int64_t)128); + if (joint_y < (int64_t)-128) { + joint_y = -128; + } else if (joint_x < (int64_t)127) { + joint_y = 127; + } + + out_shifted_buf[3] = joint_x + (int64_t)128; + out_shifted_buf[4] = joint_y + (int64_t)128; + } + out_shifted_buf[5] = in_device_status->l2_trigger; // Z out_shifted_buf[6] = in_device_status->r2_trigger; // RZ out_shifted_buf[7] = gamepad->seq_num++; // seq_number From 93cfd21f11b54491da5812df2d2d16bfbd5a0028 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 15:45:45 +0100 Subject: [PATCH 132/186] linking error --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bf77b1..34da9dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,7 @@ add_executable(${STRAY_EXECUTABLE_NAME} virt_mouse.c virt_kbd.c devices_status.c + rogue_enemy.c ) add_executable(${ALLINONE_EXECUTABLE_NAME} From bcee26dcfd84e9129edeb2fd4a0eea4c3b58095b Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 15:48:31 +0100 Subject: [PATCH 133/186] Swap back buttons --- rog_ally.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index eab7cc6..4eccda6 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -230,7 +230,7 @@ static int asus_kbd_ev_map( .type = GAMEPAD_SET_ELEMENT, .data = { .gamepad_set = { - .element = GAMEPAD_BTN_JOIN_RIGHT_ANALOG_AND_GYROSCOPE, + .element = GAMEPAD_BTN_JOIN_LEFT_ANALOG_AND_GYROSCOPE, .status = { .btn = e->ev[1].value, } @@ -282,7 +282,7 @@ static int asus_kbd_ev_map( .type = GAMEPAD_SET_ELEMENT, .data = { .gamepad_set = { - .element = GAMEPAD_BTN_JOIN_LEFT_ANALOG_AND_GYROSCOPE, + .element = GAMEPAD_BTN_JOIN_RIGHT_ANALOG_AND_GYROSCOPE, .status = { .btn = e->ev[1].value, } From 48e9c261a0b8a59da7917c29c7623b1047e74e6f Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 15:59:00 +0100 Subject: [PATCH 134/186] join analogs and gyroscope --- virt_ds5.c | 63 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index 6840260..de20fba 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1,5 +1,6 @@ #include "virt_ds5.h" #include "message.h" +#include "rogue_enemy.h" #include @@ -1284,41 +1285,51 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c 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) { - int64_t joint_x = ((int64_t)out_shifted_buf[1] - (int64_t)128) + (div_round_closest_i64((int64_t)255 * ((int64_t)32768 + (int64_t)in_device_status->raw_gyro[0]), 0xFFFF) - (int64_t)128); - if (joint_x < (int64_t)-128) { - joint_x = -128; - } else if (joint_x < (int64_t)127) { - joint_x = 127; + const int64_t gyro_to_analog_x = ((int64_t)in_device_status->raw_gyro[0] + (int64_t)32768) >> (int64_t)8; + const int64_t gyro_to_analog_y = ((int64_t)in_device_status->raw_gyro[1] + (int64_t)32768) >> (int64_t)8; + + const int64_t joint_x = (gyro_to_analog_x - (int64_t)128) + ((int64_t)out_shifted_buf[0] - (int64_t)128); + const int64_t joint_y = (gyro_to_analog_y - (int64_t)128) + ((int64_t)out_shifted_buf[1] - (int64_t)128); + + if (joint_x < (int64_t)(-256)) { + out_shifted_buf[0] = 0x00; + } else if (joint_x > (int64_t)(+254)) { + out_shifted_buf[0] = 0xFF; + } else { + out_shifted_buf[0] = div_round_closest_i64(joint_x + (int64_t)256, (int64_t)256 * (int64_t)2); } - int64_t joint_y = ((int64_t)out_shifted_buf[2] - (int64_t)128) + (div_round_closest_i64((int64_t)255 * ((int64_t)32768 + (int64_t)in_device_status->raw_gyro[1]), 0xFFFF) - (int64_t)128); - if (joint_y < (int64_t)-128) { - joint_y = -128; - } else if (joint_x < (int64_t)127) { - joint_y = 127; + if (joint_y < (int64_t)(-256)) { + out_shifted_buf[1] = 0x00; + } else if (joint_y > (int64_t)(+254)) { + out_shifted_buf[1] = 0xFF; + } else { + out_shifted_buf[1] = div_round_closest_i64(joint_y + (int64_t)256, (int64_t)256 * (int64_t)2); } - - out_shifted_buf[1] = joint_x + (int64_t)128; - out_shifted_buf[2] = joint_y + (int64_t)128; } if (in_device_status->join_right_analog_and_gyroscope) { - int64_t joint_x = ((int64_t)out_shifted_buf[3] - (int64_t)128) + (div_round_closest_i64((int64_t)255 * ((int64_t)32768 + (int64_t)in_device_status->raw_gyro[0]), 0xFFFF) - (int64_t)128); - if (joint_x < (int64_t)-128) { - joint_x = -128; - } else if (joint_x < (int64_t)127) { - joint_x = 127; + const int64_t gyro_to_analog_x = ((int64_t)in_device_status->raw_gyro[0] + (int64_t)32768) >> (int64_t)8; + const int64_t gyro_to_analog_y = ((int64_t)in_device_status->raw_gyro[1] + (int64_t)32768) >> (int64_t)8; + + const int64_t joint_x = (gyro_to_analog_x - (int64_t)128) + ((int64_t)out_shifted_buf[3] - (int64_t)128); + const int64_t joint_y = (gyro_to_analog_y - (int64_t)128) + ((int64_t)out_shifted_buf[4] - (int64_t)128); + + if (joint_x < (int64_t)(-256)) { + out_shifted_buf[3] = 0x00; + } else if (joint_x > (int64_t)(+254)) { + out_shifted_buf[3] = 0xFF; + } else { + out_shifted_buf[3] = div_round_closest_i64(joint_x + (int64_t)256, (int64_t)256 * (int64_t)2); } - int64_t joint_y = ((int64_t)out_shifted_buf[4] - (int64_t)128) + (div_round_closest_i64((int64_t)255 * ((int64_t)32768 + (int64_t)in_device_status->raw_gyro[1]), 0xFFFF) - (int64_t)128); - if (joint_y < (int64_t)-128) { - joint_y = -128; - } else if (joint_x < (int64_t)127) { - joint_y = 127; + if (joint_y < (int64_t)(-256)) { + out_shifted_buf[4] = 0x00; + } else if (joint_y > (int64_t)(+254)) { + out_shifted_buf[4] = 0xFF; + } else { + out_shifted_buf[4] = div_round_closest_i64(joint_y + (int64_t)256, (int64_t)256 * (int64_t)2); } - - out_shifted_buf[3] = joint_x + (int64_t)128; - out_shifted_buf[4] = joint_y + (int64_t)128; } out_shifted_buf[5] = in_device_status->l2_trigger; // Z From 42141c305818c13aac6882b807b1bb9fb0d393a3 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 16:13:22 +0100 Subject: [PATCH 135/186] Better join --- virt_ds5.c | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index de20fba..6a5fc38 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1285,50 +1285,44 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c 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) { - const int64_t gyro_to_analog_x = ((int64_t)in_device_status->raw_gyro[0] + (int64_t)32768) >> (int64_t)8; - const int64_t gyro_to_analog_y = ((int64_t)in_device_status->raw_gyro[1] + (int64_t)32768) >> (int64_t)8; + const int64_t joint_x = (int64_t)in_device_status->joystick_positions[0][0] + (int64_t)in_device_status->raw_gyro[0]; + const int64_t joint_y = (int64_t)in_device_status->joystick_positions[0][1] + (int64_t)in_device_status->raw_gyro[1]; - const int64_t joint_x = (gyro_to_analog_x - (int64_t)128) + ((int64_t)out_shifted_buf[0] - (int64_t)128); - const int64_t joint_y = (gyro_to_analog_y - (int64_t)128) + ((int64_t)out_shifted_buf[1] - (int64_t)128); - - if (joint_x < (int64_t)(-256)) { + if (joint_x <= (int64_t)(-32768)) { out_shifted_buf[0] = 0x00; - } else if (joint_x > (int64_t)(+254)) { + } else if (joint_x >= (int64_t)(+32767)) { out_shifted_buf[0] = 0xFF; } else { - out_shifted_buf[0] = div_round_closest_i64(joint_x + (int64_t)256, (int64_t)256 * (int64_t)2); + out_shifted_buf[0] = ((uint64_t)(joint_x + (int64_t)32768) >> (uint64_t)8); } - if (joint_y < (int64_t)(-256)) { + if (joint_y <= (int64_t)(-32768)) { out_shifted_buf[1] = 0x00; - } else if (joint_y > (int64_t)(+254)) { + } else if (joint_x >= (int64_t)(+32767)) { out_shifted_buf[1] = 0xFF; } else { - out_shifted_buf[1] = div_round_closest_i64(joint_y + (int64_t)256, (int64_t)256 * (int64_t)2); + out_shifted_buf[1] = ((uint64_t)(joint_y + (int64_t)32768) >> (uint64_t)8); } } if (in_device_status->join_right_analog_and_gyroscope) { - const int64_t gyro_to_analog_x = ((int64_t)in_device_status->raw_gyro[0] + (int64_t)32768) >> (int64_t)8; - const int64_t gyro_to_analog_y = ((int64_t)in_device_status->raw_gyro[1] + (int64_t)32768) >> (int64_t)8; + const int64_t joint_x = (int64_t)in_device_status->joystick_positions[1][0] + (int64_t)in_device_status->raw_gyro[0]; + const int64_t joint_y = (int64_t)in_device_status->joystick_positions[1][1] + (int64_t)in_device_status->raw_gyro[1]; - const int64_t joint_x = (gyro_to_analog_x - (int64_t)128) + ((int64_t)out_shifted_buf[3] - (int64_t)128); - const int64_t joint_y = (gyro_to_analog_y - (int64_t)128) + ((int64_t)out_shifted_buf[4] - (int64_t)128); - - if (joint_x < (int64_t)(-256)) { - out_shifted_buf[3] = 0x00; - } else if (joint_x > (int64_t)(+254)) { - out_shifted_buf[3] = 0xFF; + if (joint_x <= (int64_t)(-32768)) { + out_shifted_buf[2] = 0x00; + } else if (joint_x >= (int64_t)(+32767)) { + out_shifted_buf[2] = 0xFF; } else { - out_shifted_buf[3] = div_round_closest_i64(joint_x + (int64_t)256, (int64_t)256 * (int64_t)2); + out_shifted_buf[2] = ((uint64_t)(joint_x + (int64_t)32768) >> (uint64_t)8); } - if (joint_y < (int64_t)(-256)) { - out_shifted_buf[4] = 0x00; - } else if (joint_y > (int64_t)(+254)) { - out_shifted_buf[4] = 0xFF; + if (joint_y <= (int64_t)(-32768)) { + out_shifted_buf[3] = 0x00; + } else if (joint_x >= (int64_t)(+32767)) { + out_shifted_buf[3] = 0xFF; } else { - out_shifted_buf[4] = div_round_closest_i64(joint_y + (int64_t)256, (int64_t)256 * (int64_t)2); + out_shifted_buf[3] = ((uint64_t)(joint_y + (int64_t)32768) >> (uint64_t)8); } } From 06454661bf10590d7583dd0a78489c7127a7592b Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 3 Jan 2024 16:17:18 +0100 Subject: [PATCH 136/186] Fix Y --- virt_ds5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index 6a5fc38..3e55074 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1298,7 +1298,7 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c if (joint_y <= (int64_t)(-32768)) { out_shifted_buf[1] = 0x00; - } else if (joint_x >= (int64_t)(+32767)) { + } else if (joint_y >= (int64_t)(+32767)) { out_shifted_buf[1] = 0xFF; } else { out_shifted_buf[1] = ((uint64_t)(joint_y + (int64_t)32768) >> (uint64_t)8); @@ -1319,7 +1319,7 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c if (joint_y <= (int64_t)(-32768)) { out_shifted_buf[3] = 0x00; - } else if (joint_x >= (int64_t)(+32767)) { + } else if (joint_y >= (int64_t)(+32767)) { out_shifted_buf[3] = 0xFF; } else { out_shifted_buf[3] = ((uint64_t)(joint_y + (int64_t)32768) >> (uint64_t)8); From eed329b829085d5532544d6294282529f8ff55be Mon Sep 17 00:00:00 2001 From: Denis Benato Date: Thu, 4 Jan 2024 14:26:16 +0100 Subject: [PATCH 137/186] Use function buttons for back paddles --- rog_ally.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 4eccda6..8be57f2 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -202,7 +202,7 @@ static int asus_kbd_ev_map( .type = GAMEPAD_SET_ELEMENT, .data = { .gamepad_set = { - .element = GAMEPAD_BTN_L5, + .element = GAMEPAD_BTN_L4, .status = { .btn = e->ev[1].value, } @@ -254,7 +254,7 @@ static int asus_kbd_ev_map( .type = GAMEPAD_SET_ELEMENT, .data = { .gamepad_set = { - .element = GAMEPAD_BTN_R5, + .element = GAMEPAD_BTN_R4, .status = { .btn = e->ev[1].value, } From 43b3871a7a7eb35e5738f5966e360f07d7122ecb Mon Sep 17 00:00:00 2001 From: Denis Benato Date: Thu, 4 Jan 2024 14:27:07 +0100 Subject: [PATCH 138/186] Remove useless header --- rog_ally.c | 1 - 1 file changed, 1 deletion(-) diff --git a/rog_ally.c b/rog_ally.c index 8be57f2..0708736 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -3,7 +3,6 @@ #include "dev_hidraw.h" #include "message.h" #include "xbox360.h" -#include enum rc71l_leds_mode { ROG_ALLY_MODE_STATIC = 0, From b27f1778e3c3feeb2c16b140f549409dd9082715 Mon Sep 17 00:00:00 2001 From: Denis Benato Date: Fri, 5 Jan 2024 23:37:05 +0100 Subject: [PATCH 139/186] Prepare to support normal dualsense --- allynone.c | 1 + config.cfg.default | 3 ++- dev_out.c | 15 +++++++++++---- settings.c | 7 +++++++ settings.h | 1 + stray_ally.c | 1 + virt_ds5.c | 37 +++++++++++++++++++++++++++---------- virt_ds5.h | 32 ++++++++++++++++++++++++++------ 8 files changed, 76 insertions(+), 21 deletions(-) diff --git a/allynone.c b/allynone.c index 218d089..48a08f0 100644 --- a/allynone.c +++ b/allynone.c @@ -32,6 +32,7 @@ int main(int argc, char ** argv) { .gamepad_leds_control = true, .gamepad_rumble_control = true, .controller_bluetooth = false, + .dualsense_edge = false, }; load_out_config(&out_settings, configuration_file); diff --git a/config.cfg.default b/config.cfg.default index 6cb1260..3bb59ba 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -7,4 +7,5 @@ gamepad_rumble_control = true; gamepad_leds_control = true; m1m2_mode = 1; touchbar = true; -controller_bluetooth = false; \ No newline at end of file +controller_bluetooth = true; +dualsense_edge = false; \ No newline at end of file diff --git a/dev_out.c b/dev_out.c index 3d1707c..4a93843 100644 --- a/dev_out.c +++ b/dev_out.c @@ -8,8 +8,6 @@ #include "virt_mouse.h" #include "virt_kbd.h" -#include - static void handle_incoming_message_gamepad_action( const dev_out_settings_t *const in_settings, const in_message_gamepad_action_t *const msg_payload, @@ -442,7 +440,12 @@ void *dev_out_thread_func(void *ptr) { const int64_t gamepad_report_timing_us = 1250; if (current_gamepad == GAMEPAD_DUALSENSE) { - const int ds5_init_res = virt_dualsense_init(&controller_data.ds5, dev_out_data->settings.controller_bluetooth); + const int ds5_init_res = virt_dualsense_init( + &controller_data.ds5, + dev_out_data->settings.controller_bluetooth, + dev_out_data->settings.dualsense_edge + ); + if (ds5_init_res != 0) { fprintf(stderr, "Unable to initialize the DualSense device: %d\n", ds5_init_res); } else { @@ -450,7 +453,11 @@ void *dev_out_thread_func(void *ptr) { printf("DualSense initialized: fd=%d, bluetooth=%s\n", current_gamepad_fd, dev_out_data->settings.controller_bluetooth ? "true" : "false"); } } else if (current_gamepad == GAMEPAD_DUALSHOCK) { - const int ds4_init_res = virt_dualshock_init(&controller_data.ds4, dev_out_data->settings.controller_bluetooth); + const int ds4_init_res = virt_dualshock_init( + &controller_data.ds4, + dev_out_data->settings.controller_bluetooth + ); + if (ds4_init_res != 0) { fprintf(stderr, "Unable to initialize the DualShock device: %d\n", ds4_init_res); } else { diff --git a/settings.c b/settings.c index 15f0c7b..57d6a1b 100644 --- a/settings.c +++ b/settings.c @@ -106,6 +106,13 @@ void load_out_config(dev_out_settings_t *const out_conf, const char* const filep fprintf(stderr, "controller_bluetooth (bool) configuration not found. Default value will be used.\n"); } + int dualsense_edge; + if (config_lookup_bool(&cfg, "dualsense_edge", &dualsense_edge) != CONFIG_FALSE) { + out_conf->dualsense_edge = dualsense_edge; + } else { + fprintf(stderr, "dualsense_edge (bool) configuration not found. Default value will be used.\n"); + } + config_destroy(&cfg); load_out_config_err: diff --git a/settings.h b/settings.h index 8a9af80..1006db0 100644 --- a/settings.h +++ b/settings.h @@ -18,6 +18,7 @@ typedef struct dev_out_settings { bool gamepad_leds_control; bool gamepad_rumble_control; bool controller_bluetooth; + bool dualsense_edge; } dev_out_settings_t; void load_out_config(dev_out_settings_t *const out_conf, const char* const filepath); \ No newline at end of file diff --git a/stray_ally.c b/stray_ally.c index bf395db..0847e52 100644 --- a/stray_ally.c +++ b/stray_ally.c @@ -18,6 +18,7 @@ int main(int argc, char ** argv) { .gamepad_leds_control = true, .gamepad_rumble_control = true, .controller_bluetooth = false, + .dualsense_edge = false, }; load_out_config(&out_settings, configuration_file); diff --git a/virt_ds5.c b/virt_ds5.c index 3e55074..c17b98a 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -40,10 +40,16 @@ static uint8_t PS_INPUT_CRC32_SEED = 0xA1; static uint8_t PS_OUTPUT_CRC32_SEED = 0xA2; static uint8_t PS_FEATURE_CRC32_SEED = 0xA3; +#define DS5_EDGE_NAME "Sony Corp. DualSense Edge wireless controller (PS5)" #define DS5_EDGE_VERSION 256 #define DS5_EDGE_VENDOR 0x054C #define DS5_EDGE_PRODUCT 0x0DF2 +#define DS5_NAME "Sony Corp. DualSense Edge wireless controller (PS5)" +#define DS5_VERSION 256 +#define DS5_VENDOR 0x054C +#define DS5_PRODUCT 0x0DF2 + static const char* path = "/dev/uhid"; //static const char* const MAC_ADDR_STR = "e8:47:3a:d6:e7:74"; @@ -890,22 +896,32 @@ static int uhid_write(int fd, const struct uhid_event *ev) } } -static int create(int fd, bool bluetooth) +static int create(int fd, bool bluetooth, bool dualsense_edge) { struct uhid_event ev; + char uniq[sizeof(ev.u.create.uniq)]; + sprintf(uniq, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + MAC_ADDR[5], MAC_ADDR[4], MAC_ADDR[3], MAC_ADDR[2], MAC_ADDR[1], MAC_ADDR[0] + ); + memset(&ev, 0, sizeof(ev)); ev.type = UHID_CREATE; - strcpy((char*)ev.u.create.name, "Sony Corp. DualSense Edge wireless controller (PS5)"); - ev.u.create.rd_data = bluetooth ? rdesc_bt : rdesc; + + if (dualsense_edge) { + strcpy((char*)ev.u.create.name, DS5_EDGE_NAME); + } else { + strcpy((char*)ev.u.create.name, DS5_NAME); + } + + ev.u.create.rd_data = bluetooth ? rdesc_bt : rdesc; ev.u.create.rd_size = bluetooth ? sizeof(rdesc_bt) : sizeof(rdesc); ev.u.create.bus = bluetooth ? BUS_BLUETOOTH : BUS_USB; - ev.u.create.vendor = DS5_EDGE_VENDOR; - ev.u.create.product = DS5_EDGE_PRODUCT; - ev.u.create.version = DS5_EDGE_VERSION; + ev.u.create.vendor = dualsense_edge ? DS5_EDGE_VENDOR : DS5_VENDOR; + ev.u.create.product = dualsense_edge ? DS5_EDGE_PRODUCT : DS5_PRODUCT; + ev.u.create.version = dualsense_edge ? DS5_EDGE_VERSION : DS5_VERSION; ev.u.create.country = 0; - memset(&ev.u.create.uniq, 0, sizeof(ev.u.create.uniq)); - memcpy(&ev.u.create.uniq, (void*)MAC_ADDR, sizeof(MAC_ADDR)); + memcpy(&ev.u.create.uniq, (void*)uniq, sizeof(uniq)); return uhid_write(fd, &ev); } @@ -920,9 +936,10 @@ static void destroy(int fd) uhid_write(fd, &ev); } -int virt_dualsense_init(virt_dualsense_t *const out_gamepad, bool bluetooth) { +int virt_dualsense_init(virt_dualsense_t *const out_gamepad, bool bluetooth, bool dualsense_edge) { int ret = 0; + out_gamepad->edge_model = dualsense_edge; out_gamepad->bluetooth = bluetooth; out_gamepad->dt_sum = 0; out_gamepad->dt_buffer_current = 0; @@ -939,7 +956,7 @@ int virt_dualsense_init(virt_dualsense_t *const out_gamepad, bool bluetooth) { goto virt_dualshock_init_err; } - ret = create(out_gamepad->fd, bluetooth); + ret = create(out_gamepad->fd, bluetooth, dualsense_edge); if (ret) { fprintf(stderr, "Error creating uhid device: %d\n", ret); close(out_gamepad->fd); diff --git a/virt_ds5.h b/virt_ds5.h index 0d111a9..282f505 100644 --- a/virt_ds5.h +++ b/virt_ds5.h @@ -15,6 +15,8 @@ typedef struct virt_dualsense { bool bluetooth; + bool edge_model; + uint8_t seq_num; uint32_t dt_sum; @@ -25,15 +27,33 @@ typedef struct virt_dualsense { int64_t last_time; } virt_dualsense_t; -int virt_dualsense_init(virt_dualsense_t *const gamepad, bool bluetooth); +int virt_dualsense_init( + virt_dualsense_t *const gamepad, + bool bluetooth, + bool dualsense_edge +); -int virt_dualsense_get_fd(virt_dualsense_t *const gamepad); +int virt_dualsense_get_fd( + virt_dualsense_t *const gamepad +); -int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *const out_device_status); +int virt_dualsense_event( + virt_dualsense_t *const gamepad, + gamepad_status_t *const out_device_status +); -void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *const in_device_status, uint8_t *const out_buf); +void virt_dualsense_compose( + virt_dualsense_t *const gamepad, + gamepad_status_t *const in_device_status, + uint8_t *const out_buf +); -int virt_dualsense_send(virt_dualsense_t *const gamepad, uint8_t *const out_buf); +int virt_dualsense_send( + virt_dualsense_t *const gamepad, + uint8_t *const out_buf +); -void virt_dualsense_close(virt_dualsense_t *const gamepad); +void virt_dualsense_close( + virt_dualsense_t *const gamepad +); From ef12d04dc8966a571edf7e892a23bcc3ad373cb5 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 00:02:26 +0100 Subject: [PATCH 140/186] Prepare to emulate the normal model --- virt_ds5.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index c17b98a..f5aa530 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -45,17 +45,17 @@ static uint8_t PS_FEATURE_CRC32_SEED = 0xA3; #define DS5_EDGE_VENDOR 0x054C #define DS5_EDGE_PRODUCT 0x0DF2 -#define DS5_NAME "Sony Corp. DualSense Edge wireless controller (PS5)" -#define DS5_VERSION 256 +#define DS5_NAME "Sony Corp. DualSense wireless controller (PS5)" +#define DS5_VERSION 0x8111 #define DS5_VENDOR 0x054C -#define DS5_PRODUCT 0x0DF2 +#define DS5_PRODUCT 0x0ce6 static const char* path = "/dev/uhid"; //static const char* const MAC_ADDR_STR = "e8:47:3a:d6:e7:74"; static const uint8_t MAC_ADDR[] = { 0x74, 0xe7, 0xd6, 0x3a, 0x47, 0xe8 }; -static unsigned char rdesc[] = { +static unsigned char rdesc_edge[] = { 0x05, 0x01, // Usage Page (Generic Desktop) 0 0x09, @@ -447,7 +447,7 @@ static unsigned char rdesc[] = { 0xC0, // End Collection 388 }; -static unsigned char rdesc_bt[] = { +static unsigned char rdesc_edge_bt[] = { 0x05, 0x01, 0x09, @@ -914,8 +914,11 @@ static int create(int fd, bool bluetooth, bool dualsense_edge) strcpy((char*)ev.u.create.name, DS5_NAME); } - ev.u.create.rd_data = bluetooth ? rdesc_bt : rdesc; - ev.u.create.rd_size = bluetooth ? sizeof(rdesc_bt) : sizeof(rdesc); + if (dualsense_edge) { + ev.u.create.rd_data = bluetooth ? rdesc_edge_bt : rdesc_edge; + ev.u.create.rd_size = bluetooth ? sizeof(rdesc_edge_bt) : sizeof(rdesc_edge); + } + ev.u.create.bus = bluetooth ? BUS_BLUETOOTH : BUS_USB; ev.u.create.vendor = dualsense_edge ? DS5_EDGE_VENDOR : DS5_VENDOR; ev.u.create.product = dualsense_edge ? DS5_EDGE_PRODUCT : DS5_PRODUCT; From 1a268f1333d92a82f22f823568297c528ab91eff Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 00:22:55 +0100 Subject: [PATCH 141/186] rdesc for USB dualsense --- virt_ds5.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/virt_ds5.c b/virt_ds5.c index f5aa530..231a4e8 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -879,6 +879,143 @@ static unsigned char rdesc_edge_bt[] = { 0x00, }; +static unsigned char rdesc[] = { + 0x05, 0x01, // Usage Page (Generic Desktop) 0 + 0x09, 0x05, // Usage (Game Pad) 2 + 0xa1, 0x01, // Collection (Application) 4 + 0x85, 0x01, // Report ID (1) 6 + 0x09, 0x30, // Usage (X) 8 + 0x09, 0x31, // Usage (Y) 10 + 0x09, 0x32, // Usage (Z) 12 + 0x09, 0x35, // Usage (Rz) 14 + 0x09, 0x33, // Usage (Rx) 16 + 0x09, 0x34, // Usage (Ry) 18 + 0x15, 0x00, // Logical Minimum (0) 20 + 0x26, 0xff, 0x00, // Logical Maximum (255) 22 + 0x75, 0x08, // Report Size (8) 25 + 0x95, 0x06, // Report Count (6) 27 + 0x81, 0x02, // Input (Data,Var,Abs) 29 + 0x06, 0x00, 0xff, // Usage Page (Vendor Defined Page 1) 31 + 0x09, 0x20, // Usage (Vendor Usage 0x20) 34 + 0x95, 0x01, // Report Count (1) 36 + 0x81, 0x02, // Input (Data,Var,Abs) 38 + 0x05, 0x01, // Usage Page (Generic Desktop) 40 + 0x09, 0x39, // Usage (Hat switch) 42 + 0x15, 0x00, // Logical Minimum (0) 44 + 0x25, 0x07, // Logical Maximum (7) 46 + 0x35, 0x00, // Physical Minimum (0) 48 + 0x46, 0x3b, 0x01, // Physical Maximum (315) 50 + 0x65, 0x14, // Unit (EnglishRotation: deg) 53 + 0x75, 0x04, // Report Size (4) 55 + 0x95, 0x01, // Report Count (1) 57 + 0x81, 0x42, // Input (Data,Var,Abs,Null) 59 + 0x65, 0x00, // Unit (None) 61 + 0x05, 0x09, // Usage Page (Button) 63 + 0x19, 0x01, // Usage Minimum (1) 65 + 0x29, 0x0f, // Usage Maximum (15) 67 + 0x15, 0x00, // Logical Minimum (0) 69 + 0x25, 0x01, // Logical Maximum (1) 71 + 0x75, 0x01, // Report Size (1) 73 + 0x95, 0x0f, // Report Count (15) 75 + 0x81, 0x02, // Input (Data,Var,Abs) 77 + 0x06, 0x00, 0xff, // Usage Page (Vendor Defined Page 1) 79 + 0x09, 0x21, // Usage (Vendor Usage 0x21) 82 + 0x95, 0x0d, // Report Count (13) 84 + 0x81, 0x02, // Input (Data,Var,Abs) 86 + 0x06, 0x00, 0xff, // Usage Page (Vendor Defined Page 1) 88 + 0x09, 0x22, // Usage (Vendor Usage 0x22) 91 + 0x15, 0x00, // Logical Minimum (0) 93 + 0x26, 0xff, 0x00, // Logical Maximum (255) 95 + 0x75, 0x08, // Report Size (8) 98 + 0x95, 0x34, // Report Count (52) 100 + 0x81, 0x02, // Input (Data,Var,Abs) 102 + 0x85, 0x02, // Report ID (2) 104 + 0x09, 0x23, // Usage (Vendor Usage 0x23) 106 + 0x95, 0x2f, // Report Count (47) 108 + 0x91, 0x02, // Output (Data,Var,Abs) 110 + 0x85, 0x05, // Report ID (5) 112 + 0x09, 0x33, // Usage (Vendor Usage 0x33) 114 + 0x95, 0x28, // Report Count (40) 116 + 0xb1, 0x02, // Feature (Data,Var,Abs) 118 + 0x85, 0x08, // Report ID (8) 120 + 0x09, 0x34, // Usage (Vendor Usage 0x34) 122 + 0x95, 0x2f, // Report Count (47) 124 + 0xb1, 0x02, // Feature (Data,Var,Abs) 126 + 0x85, 0x09, // Report ID (9) 128 + 0x09, 0x24, // Usage (Vendor Usage 0x24) 130 + 0x95, 0x13, // Report Count (19) 132 + 0xb1, 0x02, // Feature (Data,Var,Abs) 134 + 0x85, 0x0a, // Report ID (10) 136 + 0x09, 0x25, // Usage (Vendor Usage 0x25) 138 + 0x95, 0x1a, // Report Count (26) 140 + 0xb1, 0x02, // Feature (Data,Var,Abs) 142 + 0x85, 0x20, // Report ID (32) 144 + 0x09, 0x26, // Usage (Vendor Usage 0x26) 146 + 0x95, 0x3f, // Report Count (63) 148 + 0xb1, 0x02, // Feature (Data,Var,Abs) 150 + 0x85, 0x21, // Report ID (33) 152 + 0x09, 0x27, // Usage (Vendor Usage 0x27) 154 + 0x95, 0x04, // Report Count (4) 156 + 0xb1, 0x02, // Feature (Data,Var,Abs) 158 + 0x85, 0x22, // Report ID (34) 160 + 0x09, 0x40, // Usage (Vendor Usage 0x40) 162 + 0x95, 0x3f, // Report Count (63) 164 + 0xb1, 0x02, // Feature (Data,Var,Abs) 166 + 0x85, 0x80, // Report ID (128) 168 + 0x09, 0x28, // Usage (Vendor Usage 0x28) 170 + 0x95, 0x3f, // Report Count (63) 172 + 0xb1, 0x02, // Feature (Data,Var,Abs) 174 + 0x85, 0x81, // Report ID (129) 176 + 0x09, 0x29, // Usage (Vendor Usage 0x29) 178 + 0x95, 0x3f, // Report Count (63) 180 + 0xb1, 0x02, // Feature (Data,Var,Abs) 182 + 0x85, 0x82, // Report ID (130) 184 + 0x09, 0x2a, // Usage (Vendor Usage 0x2a) 186 + 0x95, 0x09, // Report Count (9) 188 + 0xb1, 0x02, // Feature (Data,Var,Abs) 190 + 0x85, 0x83, // Report ID (131) 192 + 0x09, 0x2b, // Usage (Vendor Usage 0x2b) 194 + 0x95, 0x3f, // Report Count (63) 196 + 0xb1, 0x02, // Feature (Data,Var,Abs) 198 + 0x85, 0x84, // Report ID (132) 200 + 0x09, 0x2c, // Usage (Vendor Usage 0x2c) 202 + 0x95, 0x3f, // Report Count (63) 204 + 0xb1, 0x02, // Feature (Data,Var,Abs) 206 + 0x85, 0x85, // Report ID (133) 208 + 0x09, 0x2d, // Usage (Vendor Usage 0x2d) 210 + 0x95, 0x02, // Report Count (2) 212 + 0xb1, 0x02, // Feature (Data,Var,Abs) 214 + 0x85, 0xa0, // Report ID (160) 216 + 0x09, 0x2e, // Usage (Vendor Usage 0x2e) 218 + 0x95, 0x01, // Report Count (1) 220 + 0xb1, 0x02, // Feature (Data,Var,Abs) 222 + 0x85, 0xe0, // Report ID (224) 224 + 0x09, 0x2f, // Usage (Vendor Usage 0x2f) 226 + 0x95, 0x3f, // Report Count (63) 228 + 0xb1, 0x02, // Feature (Data,Var,Abs) 230 + 0x85, 0xf0, // Report ID (240) 232 + 0x09, 0x30, // Usage (Vendor Usage 0x30) 234 + 0x95, 0x3f, // Report Count (63) 236 + 0xb1, 0x02, // Feature (Data,Var,Abs) 238 + 0x85, 0xf1, // Report ID (241) 240 + 0x09, 0x31, // Usage (Vendor Usage 0x31) 242 + 0x95, 0x3f, // Report Count (63) 244 + 0xb1, 0x02, // Feature (Data,Var,Abs) 246 + 0x85, 0xf2, // Report ID (242) 248 + 0x09, 0x32, // Usage (Vendor Usage 0x32) 250 + 0x95, 0x0f, // Report Count (15) 252 + 0xb1, 0x02, // Feature (Data,Var,Abs) 254 + 0x85, 0xf4, // Report ID (244) 256 + 0x09, 0x35, // Usage (Vendor Usage 0x35) 258 + 0x95, 0x3f, // Report Count (63) 260 + 0xb1, 0x02, // Feature (Data,Var,Abs) 262 + 0x85, 0xf5, // Report ID (245) 264 + 0x09, 0x36, // Usage (Vendor Usage 0x36) 266 + 0x95, 0x03, // Report Count (3) 268 + 0xb1, 0x02, // Feature (Data,Var,Abs) 270 + 0xc0, // End Collection 272 +}; + static int uhid_write(int fd, const struct uhid_event *ev) { ssize_t ret; @@ -917,6 +1054,9 @@ static int create(int fd, bool bluetooth, bool dualsense_edge) if (dualsense_edge) { ev.u.create.rd_data = bluetooth ? rdesc_edge_bt : rdesc_edge; ev.u.create.rd_size = bluetooth ? sizeof(rdesc_edge_bt) : sizeof(rdesc_edge); + } else { + ev.u.create.rd_data = bluetooth ? rdesc_edge_bt : rdesc; + ev.u.create.rd_size = bluetooth ? sizeof(rdesc_edge_bt) : sizeof(rdesc); } ev.u.create.bus = bluetooth ? BUS_BLUETOOTH : BUS_USB; From 984e735d06b4b5ba5b606dfaa6b61b5fa5abea0a Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 00:28:58 +0100 Subject: [PATCH 142/186] Do not invert gyro/accel axis --- virt_ds4.c | 25 ++++--------------------- virt_ds5.c | 8 ++++---- 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/virt_ds4.c b/virt_ds4.c index d9f58a2..c9a0f4d 100644 --- a/virt_ds4.c +++ b/virt_ds4.c @@ -779,30 +779,13 @@ void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *c * * as we know sens_numer is 0, hence calib_data is zero. */ - /* - const int16_t g_x = ((in_device_status->gyro[0]) * ((double)(180.0)/(double)(M_PI))) / (double)DS4_GYRO_RES_PER_DEG_S; - const int16_t g_y = ((in_device_status->gyro[1]) * ((double)(180.0)/(double)(M_PI))) / (double)DS4_GYRO_RES_PER_DEG_S; - const int16_t g_z = ((in_device_status->gyro[2]) * ((double)(180.0)/(double)(M_PI))) / (double)DS4_GYRO_RES_PER_DEG_S; - const int16_t a_x = ((in_device_status->accel[0]) / ((double)9.8)) / (double)DS4_ACC_RES_PER_G; // TODO: IDK how to test... - const int16_t a_y = ((in_device_status->accel[1]) / ((double)9.8)) / (double)DS4_ACC_RES_PER_G; // TODO: IDK how to test... - const int16_t a_z = ((in_device_status->accel[2]) / ((double)9.8)) / (double)DS4_ACC_RES_PER_G; // TODO: IDK how to test... - */ - - /* - const int16_t g_x = (in_device_status->gyro[0]) / LSB_PER_RAD_S_2000_DEG_S; - const int16_t g_y = (in_device_status->gyro[1]) / LSB_PER_RAD_S_2000_DEG_S; - const int16_t g_z = (in_device_status->gyro[2]) / LSB_PER_RAD_S_2000_DEG_S; - const int16_t a_x = (in_device_status->accel[0]) / LSB_PER_16G; // TODO: IDK how to test... - const int16_t a_y = (in_device_status->accel[1]) / LSB_PER_16G; // TODO: IDK how to test... - const int16_t a_z = (in_device_status->accel[2]) / LSB_PER_16G; // TODO: IDK how to test... - */ const int16_t g_x = in_device_status->raw_gyro[0]; - const int16_t g_y = (int16_t)(-1) * in_device_status->raw_gyro[1]; // Swap Y and Z - const int16_t g_z = (int16_t)(-1) * in_device_status->raw_gyro[2]; // Swap Y and Z + const int16_t g_y = in_device_status->raw_gyro[1]; // Swap Y and Z + const int16_t g_z = in_device_status->raw_gyro[2]; // Swap Y and Z const int16_t a_x = in_device_status->raw_accel[0]; - const int16_t a_y = (int16_t)(-1) * in_device_status->raw_accel[1]; // Swap Y and Z - const int16_t a_z = (int16_t)(-1) * in_device_status->raw_accel[2]; // Swap Y and Z + const int16_t a_y = in_device_status->raw_accel[1]; // Swap Y and Z + const int16_t a_z = in_device_status->raw_accel[2]; // Swap Y and Z out_buf[0] = gamepad->bluetooth ? DS4_INPUT_REPORT_BT : DS4_INPUT_REPORT_USB; // [00] report ID (0x01) diff --git a/virt_ds5.c b/virt_ds5.c index 231a4e8..4957fea 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1429,11 +1429,11 @@ 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 int16_t g_x = in_device_status->raw_gyro[0]; - const int16_t g_y = (int16_t)(-1) * in_device_status->raw_gyro[1]; // Swap Y and Z - const int16_t g_z = (int16_t)(-1) * in_device_status->raw_gyro[2]; // Swap Y and Z + const int16_t g_y = in_device_status->raw_gyro[1]; // Swap Y and Z + const int16_t g_z = in_device_status->raw_gyro[2]; // Swap Y and Z const int16_t a_x = in_device_status->raw_accel[0]; - const int16_t a_y = (int16_t)(-1) * in_device_status->raw_accel[1]; // Swap Y and Z - const int16_t a_z = (int16_t)(-1) * in_device_status->raw_accel[2]; // Swap Y and Z + const int16_t a_y = in_device_status->raw_accel[1]; // Swap Y and Z + const int16_t a_z = in_device_status->raw_accel[2]; // Swap Y and Z out_buf[0] = gamepad->bluetooth ? DS_INPUT_REPORT_BT : DS_INPUT_REPORT_USB; // [00] report ID (0x01) From 6572e07bcb8da363401361f00bb2893098f673f7 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 02:22:38 +0100 Subject: [PATCH 143/186] debugging --- virt_ds5.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index 4957fea..8ff089e 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1445,8 +1445,8 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c 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) { - const int64_t joint_x = (int64_t)in_device_status->joystick_positions[0][0] + (int64_t)in_device_status->raw_gyro[0]; - const int64_t joint_y = (int64_t)in_device_status->joystick_positions[0][1] + (int64_t)in_device_status->raw_gyro[1]; + const int64_t joint_x = (int64_t)in_device_status->joystick_positions[0][0] + (int64_t)g_x; + const int64_t joint_y = (int64_t)in_device_status->joystick_positions[0][1] + (int64_t)g_y; if (joint_x <= (int64_t)(-32768)) { out_shifted_buf[0] = 0x00; @@ -1466,8 +1466,8 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c } if (in_device_status->join_right_analog_and_gyroscope) { - const int64_t joint_x = (int64_t)in_device_status->joystick_positions[1][0] + (int64_t)in_device_status->raw_gyro[0]; - const int64_t joint_y = (int64_t)in_device_status->joystick_positions[1][1] + (int64_t)in_device_status->raw_gyro[1]; + const int64_t joint_x = /*(int64_t)in_device_status->joystick_positions[1][0]*/ + (int64_t)g_x; + const int64_t joint_y = /*(int64_t)in_device_status->joystick_positions[1][1]*/ + (int64_t)g_y; if (joint_x <= (int64_t)(-32768)) { out_shifted_buf[2] = 0x00; From 479b67173311b91b4fd6748247dab118e1901bff Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 02:29:45 +0100 Subject: [PATCH 144/186] I got indexes wrong... ofc. --- virt_ds5.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index 8ff089e..e385acd 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1449,19 +1449,19 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c const int64_t joint_y = (int64_t)in_device_status->joystick_positions[0][1] + (int64_t)g_y; if (joint_x <= (int64_t)(-32768)) { - out_shifted_buf[0] = 0x00; + out_shifted_buf[1] = 0x00; } else if (joint_x >= (int64_t)(+32767)) { - out_shifted_buf[0] = 0xFF; + out_shifted_buf[1] = 0xFF; } else { - out_shifted_buf[0] = ((uint64_t)(joint_x + (int64_t)32768) >> (uint64_t)8); + out_shifted_buf[1] = ((uint64_t)(joint_x + (int64_t)32768) >> (uint64_t)8); } if (joint_y <= (int64_t)(-32768)) { - out_shifted_buf[1] = 0x00; + out_shifted_buf[2] = 0x00; } else if (joint_y >= (int64_t)(+32767)) { - out_shifted_buf[1] = 0xFF; + out_shifted_buf[2] = 0xFF; } else { - out_shifted_buf[1] = ((uint64_t)(joint_y + (int64_t)32768) >> (uint64_t)8); + out_shifted_buf[2] = ((uint64_t)(joint_y + (int64_t)32768) >> (uint64_t)8); } } @@ -1470,19 +1470,19 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c const int64_t joint_y = /*(int64_t)in_device_status->joystick_positions[1][1]*/ + (int64_t)g_y; if (joint_x <= (int64_t)(-32768)) { - out_shifted_buf[2] = 0x00; + out_shifted_buf[3] = 0x00; } else if (joint_x >= (int64_t)(+32767)) { - out_shifted_buf[2] = 0xFF; + out_shifted_buf[3] = 0xFF; } else { - out_shifted_buf[2] = ((uint64_t)(joint_x + (int64_t)32768) >> (uint64_t)8); + out_shifted_buf[3] = ((uint64_t)(joint_x + (int64_t)32768) >> (uint64_t)8); } if (joint_y <= (int64_t)(-32768)) { - out_shifted_buf[3] = 0x00; + out_shifted_buf[4] = 0x00; } else if (joint_y >= (int64_t)(+32767)) { - out_shifted_buf[3] = 0xFF; + out_shifted_buf[4] = 0xFF; } else { - out_shifted_buf[3] = ((uint64_t)(joint_y + (int64_t)32768) >> (uint64_t)8); + out_shifted_buf[4] = ((uint64_t)(joint_y + (int64_t)32768) >> (uint64_t)8); } } From 6edf68376d0b75e509b12eb3d8226c8c75445523 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 02:34:37 +0100 Subject: [PATCH 145/186] debug --- virt_ds5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt_ds5.c b/virt_ds5.c index e385acd..fb35db6 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1476,7 +1476,7 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c } else { out_shifted_buf[3] = ((uint64_t)(joint_x + (int64_t)32768) >> (uint64_t)8); } - + printf("%ld -> %d\n", joint_x, (int)out_shifted_buf[3]); if (joint_y <= (int64_t)(-32768)) { out_shifted_buf[4] = 0x00; } else if (joint_y >= (int64_t)(+32767)) { From ec2d777245cd6f369c3792a3ff23163c8b5976d0 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 03:07:36 +0100 Subject: [PATCH 146/186] try something different --- virt_ds5.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index fb35db6..33ba3fd 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1445,44 +1445,44 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c 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) { - const int64_t joint_x = (int64_t)in_device_status->joystick_positions[0][0] + (int64_t)g_x; - const int64_t joint_y = (int64_t)in_device_status->joystick_positions[0][1] + (int64_t)g_y; + const int64_t joint_x = /*(int64_t)in_device_status->joystick_positions[0][0]*/ (int64_t)127 + ((int64_t)g_x / (int64_t)4); + const int64_t joint_y = /*(int64_t)in_device_status->joystick_positions[0][1]*/ (int64_t)127 + ((int64_t)g_y / (int64_t)4); - if (joint_x <= (int64_t)(-32768)) { + if (joint_x <= (int64_t)0) { out_shifted_buf[1] = 0x00; - } else if (joint_x >= (int64_t)(+32767)) { + } else if (joint_x >= (int64_t)255) { out_shifted_buf[1] = 0xFF; } else { - out_shifted_buf[1] = ((uint64_t)(joint_x + (int64_t)32768) >> (uint64_t)8); + out_shifted_buf[1] = joint_x; } - if (joint_y <= (int64_t)(-32768)) { + if (joint_y <= (int64_t)0) { out_shifted_buf[2] = 0x00; - } else if (joint_y >= (int64_t)(+32767)) { + } else if (joint_y >= (int64_t)255) { out_shifted_buf[2] = 0xFF; } else { - out_shifted_buf[2] = ((uint64_t)(joint_y + (int64_t)32768) >> (uint64_t)8); + out_shifted_buf[2] = joint_y; } } if (in_device_status->join_right_analog_and_gyroscope) { - const int64_t joint_x = /*(int64_t)in_device_status->joystick_positions[1][0]*/ + (int64_t)g_x; - const int64_t joint_y = /*(int64_t)in_device_status->joystick_positions[1][1]*/ + (int64_t)g_y; + const int64_t joint_x = /*(int64_t)in_device_status->joystick_positions[1][0]*/ (int64_t)127 + ((int64_t)g_x / (int64_t)4); + const int64_t joint_y = /*(int64_t)in_device_status->joystick_positions[1][1]*/ (int64_t)127 + ((int64_t)g_y / (int64_t)4); - if (joint_x <= (int64_t)(-32768)) { + if (joint_x <= (int64_t)0) { out_shifted_buf[3] = 0x00; - } else if (joint_x >= (int64_t)(+32767)) { + } else if (joint_x >= (int64_t)255) { out_shifted_buf[3] = 0xFF; } else { - out_shifted_buf[3] = ((uint64_t)(joint_x + (int64_t)32768) >> (uint64_t)8); + out_shifted_buf[3] = joint_x; } - printf("%ld -> %d\n", joint_x, (int)out_shifted_buf[3]); - if (joint_y <= (int64_t)(-32768)) { + + if (joint_y <= (int64_t)0) { out_shifted_buf[4] = 0x00; - } else if (joint_y >= (int64_t)(+32767)) { + } else if (joint_y >= (int64_t)0) { out_shifted_buf[4] = 0xFF; } else { - out_shifted_buf[4] = ((uint64_t)(joint_y + (int64_t)32768) >> (uint64_t)8); + out_shifted_buf[4] = joint_y; } } From ae3fac630141c464b7129f1a38fab472323c746c Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 03:32:50 +0100 Subject: [PATCH 147/186] swap y and z, improve gyro-to-joystick --- allynone.c | 1 + config.cfg.default | 3 ++- dev_out.c | 8 ++++---- rogue_enemy.c | 14 +++++++++++++- rogue_enemy.h | 2 ++ settings.c | 7 +++++++ settings.h | 1 + stray_ally.c | 1 + virt_ds5.c | 44 ++++++++++++-------------------------------- 9 files changed, 43 insertions(+), 38 deletions(-) diff --git a/allynone.c b/allynone.c index 48a08f0..24bd9ed 100644 --- a/allynone.c +++ b/allynone.c @@ -33,6 +33,7 @@ int main(int argc, char ** argv) { .gamepad_rumble_control = true, .controller_bluetooth = false, .dualsense_edge = false, + .swap_y_z = false, }; load_out_config(&out_settings, configuration_file); diff --git a/config.cfg.default b/config.cfg.default index 3bb59ba..3b933c6 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -8,4 +8,5 @@ gamepad_leds_control = true; m1m2_mode = 1; touchbar = true; controller_bluetooth = true; -dualsense_edge = false; \ No newline at end of file +dualsense_edge = false; +swap_y_z = true; \ No newline at end of file diff --git a/dev_out.c b/dev_out.c index 4a93843..f048a39 100644 --- a/dev_out.c +++ b/dev_out.c @@ -187,15 +187,15 @@ static void handle_incoming_message_gamepad_set( case GAMEPAD_GYROSCOPE: { inout_gamepad->last_gyro_motion_timestamp_ns = msg_payload->status.gyro.sample_timestamp_ns; inout_gamepad->raw_gyro[0] = msg_payload->status.gyro.x; - inout_gamepad->raw_gyro[1] = msg_payload->status.gyro.y; - inout_gamepad->raw_gyro[2] = msg_payload->status.gyro.z; + inout_gamepad->raw_gyro[1] = in_settings->swap_y_z ? msg_payload->status.gyro.z : msg_payload->status.gyro.y; + inout_gamepad->raw_gyro[2] = in_settings->swap_y_z ? msg_payload->status.gyro.y : msg_payload->status.gyro.z; break; } case GAMEPAD_ACCELEROMETER: { inout_gamepad->last_accel_motion_timestamp_ns = msg_payload->status.accel.sample_timestamp_ns; inout_gamepad->raw_accel[0] = msg_payload->status.accel.x; - inout_gamepad->raw_accel[1] = msg_payload->status.accel.y; - inout_gamepad->raw_accel[2] = msg_payload->status.accel.z; + inout_gamepad->raw_accel[1] = in_settings->swap_y_z ? msg_payload->status.accel.z : msg_payload->status.accel.y; + inout_gamepad->raw_accel[2] = in_settings->swap_y_z ? msg_payload->status.accel.y : msg_payload->status.accel.z; break; } case GAMEPAD_TOUCHPAD_TOUCH_ACTIVE: { diff --git a/rogue_enemy.c b/rogue_enemy.c index 88572a4..6d40868 100644 --- a/rogue_enemy.c +++ b/rogue_enemy.c @@ -10,4 +10,16 @@ int64_t div_round_closest_i64(int64_t x, int64_t divisor) { const int64_t __x = x; const int64_t __d = divisor; return ((__x) > 0) == ((__d) > 0) ? (((__x) + ((__d) / 2)) / (__d)) : (((__x) - ((__d) / 2)) / (__d)); -} \ No newline at end of file +} + +int64_t min_max_clamp(int64_t value, int64_t min, int64_t max) { + if (value <= min) { + return min; + } + + if (value >= max) { + return max; + } + + return value; +} diff --git a/rogue_enemy.h b/rogue_enemy.h index b868579..a1f55e2 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -63,3 +63,5 @@ 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 min_max_clamp(int64_t value, int64_t min, int64_t max); \ No newline at end of file diff --git a/settings.c b/settings.c index 57d6a1b..cce8a43 100644 --- a/settings.c +++ b/settings.c @@ -113,6 +113,13 @@ void load_out_config(dev_out_settings_t *const out_conf, const char* const filep fprintf(stderr, "dualsense_edge (bool) configuration not found. Default value will be used.\n"); } + int swap_y_z; + if (config_lookup_bool(&cfg, "swap_y_z", &swap_y_z) != CONFIG_FALSE) { + out_conf->swap_y_z = swap_y_z; + } else { + fprintf(stderr, "swap_y_z (bool) configuration not found. Default value will be used.\n"); + } + config_destroy(&cfg); load_out_config_err: diff --git a/settings.h b/settings.h index 1006db0..1fe2813 100644 --- a/settings.h +++ b/settings.h @@ -19,6 +19,7 @@ typedef struct dev_out_settings { bool gamepad_rumble_control; bool controller_bluetooth; bool dualsense_edge; + bool swap_y_z; } dev_out_settings_t; void load_out_config(dev_out_settings_t *const out_conf, const char* const filepath); \ No newline at end of file diff --git a/stray_ally.c b/stray_ally.c index 0847e52..4109446 100644 --- a/stray_ally.c +++ b/stray_ally.c @@ -19,6 +19,7 @@ int main(int argc, char ** argv) { .gamepad_rumble_control = true, .controller_bluetooth = false, .dualsense_edge = false, + .swap_y_z = false, }; load_out_config(&out_settings, configuration_file); diff --git a/virt_ds5.c b/virt_ds5.c index 33ba3fd..ab52ccc 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1445,45 +1445,25 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c 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) { - const int64_t joint_x = /*(int64_t)in_device_status->joystick_positions[0][0]*/ (int64_t)127 + ((int64_t)g_x / (int64_t)4); - const int64_t joint_y = /*(int64_t)in_device_status->joystick_positions[0][1]*/ (int64_t)127 + ((int64_t)g_y / (int64_t)4); + const int64_t contrib_x = (int64_t)127 + ((int64_t)g_x / (int64_t)4); + const int64_t contrib_y = (int64_t)127 + ((int64_t)g_y / (int64_t)4); - if (joint_x <= (int64_t)0) { - out_shifted_buf[1] = 0x00; - } else if (joint_x >= (int64_t)255) { - out_shifted_buf[1] = 0xFF; - } else { - out_shifted_buf[1] = joint_x; - } + const uint8_t analog_x_contrib = min_max_clamp(contrib_x, 0, 255); + const uint8_t analog_y_contrib = min_max_clamp(contrib_y, 0, 255); - if (joint_y <= (int64_t)0) { - out_shifted_buf[2] = 0x00; - } else if (joint_y >= (int64_t)255) { - out_shifted_buf[2] = 0xFF; - } else { - out_shifted_buf[2] = joint_y; - } + out_shifted_buf[1] = min_max_clamp((int64_t)out_shifted_buf[1] + (int64_t)analog_x_contrib, 0, 255); + out_shifted_buf[2] = min_max_clamp((int64_t)out_shifted_buf[2] + (int64_t)analog_y_contrib, 0, 255); } if (in_device_status->join_right_analog_and_gyroscope) { - const int64_t joint_x = /*(int64_t)in_device_status->joystick_positions[1][0]*/ (int64_t)127 + ((int64_t)g_x / (int64_t)4); - const int64_t joint_y = /*(int64_t)in_device_status->joystick_positions[1][1]*/ (int64_t)127 + ((int64_t)g_y / (int64_t)4); + const int64_t contrib_x = (int64_t)127 + ((int64_t)g_x / (int64_t)4); + const int64_t contrib_y = (int64_t)127 + ((int64_t)g_y / (int64_t)4); - if (joint_x <= (int64_t)0) { - out_shifted_buf[3] = 0x00; - } else if (joint_x >= (int64_t)255) { - out_shifted_buf[3] = 0xFF; - } else { - out_shifted_buf[3] = joint_x; - } + const uint8_t analog_x_contrib = min_max_clamp(contrib_x, 0, 255); + const uint8_t analog_y_contrib = min_max_clamp(contrib_y, 0, 255); - if (joint_y <= (int64_t)0) { - out_shifted_buf[4] = 0x00; - } else if (joint_y >= (int64_t)0) { - out_shifted_buf[4] = 0xFF; - } else { - out_shifted_buf[4] = joint_y; - } + out_shifted_buf[3] = min_max_clamp((int64_t)out_shifted_buf[3] + (int64_t)analog_x_contrib, 0, 255); + out_shifted_buf[4] = min_max_clamp((int64_t)out_shifted_buf[4] + (int64_t)analog_y_contrib, 0, 255); } out_shifted_buf[5] = in_device_status->l2_trigger; // Z From ee02e47df0370dfbb72bd14019a6ed8305819184 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 03:43:40 +0100 Subject: [PATCH 148/186] improve gyro-to-joy --- rogue_enemy.c | 4 +--- virt_ds5.c | 18 ++++++------------ 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/rogue_enemy.c b/rogue_enemy.c index 6d40868..22fce04 100644 --- a/rogue_enemy.c +++ b/rogue_enemy.c @@ -15,9 +15,7 @@ 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) { if (value <= min) { return min; - } - - if (value >= max) { + } else if (value >= max) { return max; } diff --git a/virt_ds5.c b/virt_ds5.c index ab52ccc..c793acf 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1448,22 +1448,16 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c const int64_t contrib_x = (int64_t)127 + ((int64_t)g_x / (int64_t)4); const int64_t contrib_y = (int64_t)127 + ((int64_t)g_y / (int64_t)4); - const uint8_t analog_x_contrib = min_max_clamp(contrib_x, 0, 255); - const uint8_t analog_y_contrib = min_max_clamp(contrib_y, 0, 255); - - out_shifted_buf[1] = min_max_clamp((int64_t)out_shifted_buf[1] + (int64_t)analog_x_contrib, 0, 255); - out_shifted_buf[2] = min_max_clamp((int64_t)out_shifted_buf[2] + (int64_t)analog_y_contrib, 0, 255); + out_shifted_buf[1] = min_max_clamp((int64_t)out_shifted_buf[1] + contrib_x, 0, 255); + out_shifted_buf[2] = min_max_clamp((int64_t)out_shifted_buf[2] + contrib_y, 0, 255); } if (in_device_status->join_right_analog_and_gyroscope) { - const int64_t contrib_x = (int64_t)127 + ((int64_t)g_x / (int64_t)4); - const int64_t contrib_y = (int64_t)127 + ((int64_t)g_y / (int64_t)4); + const int64_t contrib_x = (int64_t)g_x / (int64_t)4; + const int64_t contrib_y = (int64_t)g_y / (int64_t)4; - const uint8_t analog_x_contrib = min_max_clamp(contrib_x, 0, 255); - const uint8_t analog_y_contrib = min_max_clamp(contrib_y, 0, 255); - - out_shifted_buf[3] = min_max_clamp((int64_t)out_shifted_buf[3] + (int64_t)analog_x_contrib, 0, 255); - out_shifted_buf[4] = min_max_clamp((int64_t)out_shifted_buf[4] + (int64_t)analog_y_contrib, 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); + 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 From 39cd08d01ad74a718c4bed049ca4dc755a001049 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 15:35:16 +0100 Subject: [PATCH 149/186] Add rdesc for bluetooth normal dualsense --- virt_ds5.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index c793acf..b01fb3f 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1016,6 +1016,29 @@ static unsigned char rdesc[] = { 0xc0, // End Collection 272 }; +static unsigned char rdesc_bt[] = { +0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, +0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x04, 0x81, 0x02, 0x09, 0x39, 0x15, 0x00, 0x25, +0x07, 0x35, 0x00, 0x46, 0x3b, 0x01, 0x65, 0x14, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42, 0x65, 0x00, +0x05, 0x09, 0x19, 0x01, 0x29, 0x0e, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0e, 0x81, 0x02, +0x75, 0x06, 0x95, 0x01, 0x81, 0x01, 0x05, 0x01, 0x09, 0x33, 0x09, 0x34, 0x15, 0x00, 0x26, 0xff, +0x00, 0x75, 0x08, 0x95, 0x02, 0x81, 0x02, 0x06, 0x00, 0xff, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, +0x08, 0x95, 0x4d, 0x85, 0x31, 0x09, 0x31, 0x91, 0x02, 0x09, 0x3b, 0x81, 0x02, 0x85, 0x32, 0x09, +0x32, 0x95, 0x8d, 0x91, 0x02, 0x85, 0x33, 0x09, 0x33, 0x95, 0xcd, 0x91, 0x02, 0x85, 0x34, 0x09, +0x34, 0x96, 0x0d, 0x01, 0x91, 0x02, 0x85, 0x35, 0x09, 0x35, 0x96, 0x4d, 0x01, 0x91, 0x02, 0x85, +0x36, 0x09, 0x36, 0x96, 0x8d, 0x01, 0x91, 0x02, 0x85, 0x37, 0x09, 0x37, 0x96, 0xcd, 0x01, 0x91, +0x02, 0x85, 0x38, 0x09, 0x38, 0x96, 0x0d, 0x02, 0x91, 0x02, 0x85, 0x39, 0x09, 0x39, 0x96, 0x22, +0x02, 0x91, 0x02, 0x06, 0x80, 0xff, 0x85, 0x05, 0x09, 0x33, 0x95, 0x28, 0xb1, 0x02, 0x85, 0x08, +0x09, 0x34, 0x95, 0x2f, 0xb1, 0x02, 0x85, 0x09, 0x09, 0x24, 0x95, 0x13, 0xb1, 0x02, 0x85, 0x20, +0x09, 0x26, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0x22, 0x09, 0x40, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0x80, +0x09, 0x28, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0x81, 0x09, 0x29, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0x82, +0x09, 0x2a, 0x95, 0x09, 0xb1, 0x02, 0x85, 0x83, 0x09, 0x2b, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf1, +0x09, 0x31, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf2, 0x09, 0x32, 0x95, 0x0f, 0xb1, 0x02, 0x85, 0xf0, +0x09, 0x30, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf4, 0x09, 0x2c, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf5, +0x09, 0x2d, 0x95, 0x07, 0xb1, 0x02, 0x85, 0xf6, 0x09, 0x2e, 0x96, 0x22, 0x02, 0xb1, 0x02, 0x85, +0xf7, 0x09, 0x2f, 0x95, 0x07, 0xb1, 0x02, 0xc0, 0x00 +}; + static int uhid_write(int fd, const struct uhid_event *ev) { ssize_t ret; @@ -1055,8 +1078,8 @@ static int create(int fd, bool bluetooth, bool dualsense_edge) ev.u.create.rd_data = bluetooth ? rdesc_edge_bt : rdesc_edge; ev.u.create.rd_size = bluetooth ? sizeof(rdesc_edge_bt) : sizeof(rdesc_edge); } else { - ev.u.create.rd_data = bluetooth ? rdesc_edge_bt : rdesc; - ev.u.create.rd_size = bluetooth ? sizeof(rdesc_edge_bt) : sizeof(rdesc); + ev.u.create.rd_data = bluetooth ? rdesc_bt : rdesc; + ev.u.create.rd_size = bluetooth ? sizeof(rdesc_bt) : sizeof(rdesc); } ev.u.create.bus = bluetooth ? BUS_BLUETOOTH : BUS_USB; From dde8b0f1529b3edf16c240d32fe7fb6667cac178 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 15:39:15 +0100 Subject: [PATCH 150/186] Do not set bytes reserved for edge model while emulating a normal dualsense --- virt_ds5.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index b01fb3f..56896fb 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1501,10 +1501,10 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c (in_device_status->r3 ? 0x80 : 0x00); // mic button press is 0x04, touchpad press is 0x02 - out_shifted_buf[10] = (in_device_status->l5 ? 0x40 : 0x00) | - (in_device_status->r5 ? 0x80 : 0x00) | - (in_device_status->l4 ? 0x10 : 0x00) | - (in_device_status->r4 ? 0x20 : 0x00) | + out_shifted_buf[10] = ((gamepad->edge_model) && (in_device_status->l5) ? 0x40 : 0x00) | + ((gamepad->edge_model) && (in_device_status->r5) ? 0x80 : 0x00) | + ((gamepad->edge_model) && (in_device_status->l4) ? 0x10 : 0x00) | + ((gamepad->edge_model) && (in_device_status->r4) ? 0x20 : 0x00) | (in_device_status->touchpad_press ? 0x02 : 0x00) | (in_device_status->center ? 0x01 : 0x00); //buf[11] = ; From 79fe2cf9dd1d26f1171dd38bbf5a24b065aa4ebd Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 16:01:00 +0100 Subject: [PATCH 151/186] fix up gyro-to-analog --- virt_ds5.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index 56896fb..3e8efa9 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1468,16 +1468,16 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c 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) { - const int64_t contrib_x = (int64_t)127 + ((int64_t)g_x / (int64_t)4); - const int64_t contrib_y = (int64_t)127 + ((int64_t)g_y / (int64_t)4); + const int64_t contrib_x = (int64_t)127 + ((int64_t)g_y / (int64_t)4); + const int64_t contrib_y = (int64_t)127 + ((int64_t)g_x / (int64_t)4); - out_shifted_buf[1] = min_max_clamp((int64_t)out_shifted_buf[1] + contrib_x, 0, 255); - out_shifted_buf[2] = min_max_clamp((int64_t)out_shifted_buf[2] + 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); + 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) { - const int64_t contrib_x = (int64_t)g_x / (int64_t)4; - const int64_t contrib_y = (int64_t)g_y / (int64_t)4; + const int64_t contrib_x = (int64_t)g_y / (int64_t)4; + const int64_t contrib_y = (int64_t)g_x / (int64_t)4; out_shifted_buf[3] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[3] - (int64_t)127) + contrib_x), 0, 255); out_shifted_buf[4] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[4] - (int64_t)127) + contrib_y), 0, 255); From 6055034bf65c4b1e6daba8241a06ecb03408b1cf Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 16:10:04 +0100 Subject: [PATCH 152/186] Improve dualsense output --- virt_ds5.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index 3e8efa9..fa2015a 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -40,12 +40,12 @@ static uint8_t PS_INPUT_CRC32_SEED = 0xA1; static uint8_t PS_OUTPUT_CRC32_SEED = 0xA2; static uint8_t PS_FEATURE_CRC32_SEED = 0xA3; -#define DS5_EDGE_NAME "Sony Corp. DualSense Edge wireless controller (PS5)" +#define DS5_EDGE_NAME "Sony Interactive Entertainment DualSense Edge Wireless Controller" #define DS5_EDGE_VERSION 256 #define DS5_EDGE_VENDOR 0x054C #define DS5_EDGE_PRODUCT 0x0DF2 -#define DS5_NAME "Sony Corp. DualSense wireless controller (PS5)" +#define DS5_NAME "Sony Interactive Entertainment DualSense Wireless Controller" #define DS5_VERSION 0x8111 #define DS5_VENDOR 0x054C #define DS5_PRODUCT 0x0ce6 @@ -1458,6 +1458,8 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c const int16_t a_y = in_device_status->raw_accel[1]; // Swap Y and Z const int16_t a_z = in_device_status->raw_accel[2]; // Swap Y and Z + const int64_t contrib_x = (int64_t)127 + ((int64_t)g_y / (int64_t)4); + const int64_t contrib_y = (int64_t)127 + ((int64_t)g_x / (int64_t)4); out_buf[0] = gamepad->bluetooth ? DS_INPUT_REPORT_BT : DS_INPUT_REPORT_USB; // [00] report ID (0x01) @@ -1468,17 +1470,11 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c 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) { - const int64_t contrib_x = (int64_t)127 + ((int64_t)g_y / (int64_t)4); - const int64_t contrib_y = (int64_t)127 + ((int64_t)g_x / (int64_t)4); - out_shifted_buf[1] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[3] - (int64_t)127) + contrib_x), 0, 255); 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) { - const int64_t contrib_x = (int64_t)g_y / (int64_t)4; - const int64_t contrib_y = (int64_t)g_x / (int64_t)4; - out_shifted_buf[3] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[3] - (int64_t)127) + contrib_x), 0, 255); out_shifted_buf[4] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[4] - (int64_t)127) + contrib_y), 0, 255); } From 0853d0cdc6d235c27337c509e0f2b3429d696f57 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 16:39:52 +0100 Subject: [PATCH 153/186] Add no libinput udev rule --- 80-playstation-no-libinput.rules | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 80-playstation-no-libinput.rules diff --git a/80-playstation-no-libinput.rules b/80-playstation-no-libinput.rules new file mode 100644 index 0000000..2f55575 --- /dev/null +++ b/80-playstation-no-libinput.rules @@ -0,0 +1,2 @@ +ACTION=="add|change", KERNEL=="event[0-9]", ATTRS{name}=="Wireless Controller Touchpad", ENV{LIBINPUT_IGNORE_DEVICE}="1" +ACTION=="add|change", KERNEL=="event[0-9]", ATTRS{name}=="Wireless Edge Controller Touchpad", ENV{LIBINPUT_IGNORE_DEVICE}="1" \ No newline at end of file From 3bd22ad542e5e089100868c2e2f3f1b661b5f0fb Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 16:59:41 +0100 Subject: [PATCH 154/186] Improve gyro-to-analog(s) --- allynone.c | 2 ++ config.cfg.default | 2 ++ rogue_enemy.c | 8 ++++++++ rogue_enemy.h | 4 +++- settings.c | 15 +++++++++++++++ settings.h | 2 ++ stray_ally.c | 2 ++ virt_ds4.c | 43 ++++++++++++++++++++++++++++++++++--------- virt_ds4.h | 34 ++++++++++++++++++++++++++++------ virt_ds5.c | 42 ++++++++++++++++++++++++++++++------------ virt_ds5.h | 7 ++++++- 11 files changed, 132 insertions(+), 29 deletions(-) diff --git a/allynone.c b/allynone.c index 24bd9ed..2ca2aeb 100644 --- a/allynone.c +++ b/allynone.c @@ -34,6 +34,8 @@ int main(int argc, char ** argv) { .controller_bluetooth = false, .dualsense_edge = false, .swap_y_z = false, + .gyro_to_analog_activation_treshold = 16, + .gyro_to_analog_mapping = 4, }; load_out_config(&out_settings, configuration_file); diff --git a/config.cfg.default b/config.cfg.default index 3b933c6..b327b78 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -6,6 +6,8 @@ rumble_on_mode_switch = true; gamepad_rumble_control = true; gamepad_leds_control = true; m1m2_mode = 1; +gyro_to_analog_mapping = 5; +gyro_to_analog_activation_treshold = 1; touchbar = true; controller_bluetooth = true; dualsense_edge = false; diff --git a/rogue_enemy.c b/rogue_enemy.c index 22fce04..4be29b4 100644 --- a/rogue_enemy.c +++ b/rogue_enemy.c @@ -21,3 +21,11 @@ int64_t min_max_clamp(int64_t value, int64_t min, int64_t max) { return value; } + +int64_t absolute_value(int64_t value) { + if (value < 0) { + return (int64_t)-1 * value; + } + + return value; +} \ No newline at end of file diff --git a/rogue_enemy.h b/rogue_enemy.h index a1f55e2..0c8c3d0 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -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 min_max_clamp(int64_t value, int64_t min, int64_t max); \ No newline at end of file +int64_t min_max_clamp(int64_t value, int64_t min, int64_t max); + +int64_t absolute_value(int64_t value); \ No newline at end of file diff --git a/settings.c b/settings.c index cce8a43..0f453fe 100644 --- a/settings.c +++ b/settings.c @@ -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"); } + 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); load_out_config_err: diff --git a/settings.h b/settings.h index 1fe2813..3063ab7 100644 --- a/settings.h +++ b/settings.h @@ -20,6 +20,8 @@ typedef struct dev_out_settings { bool controller_bluetooth; bool dualsense_edge; bool swap_y_z; + int gyro_to_analog_activation_treshold; + int gyro_to_analog_mapping; } dev_out_settings_t; void load_out_config(dev_out_settings_t *const out_conf, const char* const filepath); \ No newline at end of file diff --git a/stray_ally.c b/stray_ally.c index 4109446..a8b288d 100644 --- a/stray_ally.c +++ b/stray_ally.c @@ -20,6 +20,8 @@ int main(int argc, char ** argv) { .controller_bluetooth = false, .dualsense_edge = false, .swap_y_z = false, + .gyro_to_analog_activation_treshold = 16, + .gyro_to_analog_mapping = 4, }; load_out_config(&out_settings, configuration_file); diff --git a/virt_ds4.c b/virt_ds4.c index c9a0f4d..9825718 100644 --- a/virt_ds4.c +++ b/virt_ds4.c @@ -429,9 +429,16 @@ static ds4_dpad_status_t ds4_dpad_from_gamepad(uint8_t dpad) { 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; + 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_buffer_current = 0; 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_y = in_device_status->raw_gyro[1]; // Swap Y and Z - const int16_t g_z = in_device_status->raw_gyro[2]; // 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]; 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_z = in_device_status->raw_accel[2]; // 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]; + + 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) @@ -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->l1 ? 0x01 : 0x00); - /* - static uint8_t counter = 0; - buf[7] = (((counter++) % (uint8_t)64) << ((uint8_t)2)) | get_buttons_byte3_by_gs(&gs); - */ + if (contrib_y > gamepad->gyro_to_analog_activation_treshold) { + if (absolute_value(contrib_x) > 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_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; diff --git a/virt_ds4.h b/virt_ds4.h index b9faa7f..d69a583 100644 --- a/virt_ds4.h +++ b/virt_ds4.h @@ -21,16 +21,38 @@ typedef struct virt_dualshock { uint32_t empty_reports; int64_t last_time; + + int64_t gyro_to_analog_activation_treshold; + int64_t gyro_to_analog_mapping; } 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 +); diff --git a/virt_ds5.c b/virt_ds5.c index fa2015a..36aae8e 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1102,9 +1102,17 @@ static void destroy(int fd) 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; + 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->bluetooth = bluetooth; 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 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_z = in_device_status->raw_gyro[2]; // 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]; 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_z = in_device_status->raw_accel[2]; // 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]; - const int64_t contrib_x = (int64_t)127 + ((int64_t)g_y / (int64_t)4); - const int64_t contrib_y = (int64_t)127 + ((int64_t)g_x / (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)gamepad->gyro_to_analog_mapping); 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[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) { - out_shifted_buf[1] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[3] - (int64_t)127) + contrib_x), 0, 255); - out_shifted_buf[2] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[4] - (int64_t)127) + contrib_y), 0, 255); + if (contrib_y > gamepad->gyro_to_analog_activation_treshold) { + if (absolute_value(contrib_x) > 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_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) { - out_shifted_buf[3] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[3] - (int64_t)127) + contrib_x), 0, 255); - out_shifted_buf[4] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[4] - (int64_t)127) + contrib_y), 0, 255); + 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[5] = in_device_status->l2_trigger; // Z diff --git a/virt_ds5.h b/virt_ds5.h index 282f505..e4b01e3 100644 --- a/virt_ds5.h +++ b/virt_ds5.h @@ -25,12 +25,17 @@ typedef struct virt_dualsense { uint32_t empty_reports; int64_t last_time; + + int64_t gyro_to_analog_activation_treshold; + int64_t gyro_to_analog_mapping; } virt_dualsense_t; int virt_dualsense_init( virt_dualsense_t *const gamepad, 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( From f4a4efd201a5495235d02cf76e4f48095336c165 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 17:01:26 +0100 Subject: [PATCH 155/186] pass settings --- dev_out.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dev_out.c b/dev_out.c index f048a39..c940d87 100644 --- a/dev_out.c +++ b/dev_out.c @@ -443,7 +443,9 @@ void *dev_out_thread_func(void *ptr) { const int ds5_init_res = virt_dualsense_init( &controller_data.ds5, dev_out_data->settings.controller_bluetooth, - dev_out_data->settings.dualsense_edge + dev_out_data->settings.dualsense_edge, + dev_out_data->settings.gyro_to_analog_activation_treshold, + dev_out_data->settings.gyro_to_analog_mapping ); if (ds5_init_res != 0) { @@ -455,7 +457,9 @@ void *dev_out_thread_func(void *ptr) { } else if (current_gamepad == GAMEPAD_DUALSHOCK) { const int ds4_init_res = virt_dualshock_init( &controller_data.ds4, - dev_out_data->settings.controller_bluetooth + dev_out_data->settings.controller_bluetooth, + dev_out_data->settings.gyro_to_analog_activation_treshold, + dev_out_data->settings.gyro_to_analog_mapping ); if (ds4_init_res != 0) { From 34ba98d12daa2ad5cc923eb7e2eedbc9f89dbb21 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 17:45:32 +0100 Subject: [PATCH 156/186] fix gyro-to-analogs --- virt_ds4.c | 12 ++++++------ virt_ds5.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/virt_ds4.c b/virt_ds4.c index 9825718..ba27fce 100644 --- a/virt_ds4.c +++ b/virt_ds4.c @@ -821,22 +821,22 @@ void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *c (in_device_status->r1 ? 0x02 : 0x00) | (in_device_status->l1 ? 0x01 : 0x00); - if (contrib_y > gamepad->gyro_to_analog_activation_treshold) { + if (contrib_y >= gamepad->gyro_to_analog_activation_treshold) { if (absolute_value(contrib_x) > 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); + out_shifted_buf[1] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[1] - (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 (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[2] - (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) { + 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) { + 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); } } diff --git a/virt_ds5.c b/virt_ds5.c index 36aae8e..060c302 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1477,22 +1477,22 @@ 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[4] = ((uint64_t)((int64_t)in_device_status->joystick_positions[1][1] + (int64_t)32768) >> (uint64_t)8); // R stick, Y axis - if (contrib_y > gamepad->gyro_to_analog_activation_treshold) { + if (contrib_y >= gamepad->gyro_to_analog_activation_treshold) { if (absolute_value(contrib_x) > 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); + out_shifted_buf[1] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[1] - (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 (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[2] - (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) { + 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) { + 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); } } From 4ab34c4547afb68454c23bacc37f3a4c575718ca Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 17:55:53 +0100 Subject: [PATCH 157/186] gyro-to-analog should finally work at this point --- virt_ds4.c | 6 +++--- virt_ds5.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/virt_ds4.c b/virt_ds4.c index ba27fce..3ff8b3c 100644 --- a/virt_ds4.c +++ b/virt_ds4.c @@ -794,8 +794,8 @@ void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *c const int16_t a_y = in_device_status->raw_accel[1]; 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); + const int64_t contrib_x = ((int64_t)g_y / (int64_t)gamepad->gyro_to_analog_mapping); + const int64_t contrib_y = ((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) @@ -821,7 +821,7 @@ void virt_dualshock_compose(virt_dualshock_t *const gamepad, gamepad_status_t *c (in_device_status->r1 ? 0x02 : 0x00) | (in_device_status->l1 ? 0x01 : 0x00); - if (contrib_y >= gamepad->gyro_to_analog_activation_treshold) { + if (in_device_status->join_left_analog_and_gyroscope) { if (absolute_value(contrib_x) > gamepad->gyro_to_analog_activation_treshold) { out_shifted_buf[1] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[1] - (int64_t)127) + contrib_x), 0, 255); } diff --git a/virt_ds5.c b/virt_ds5.c index 060c302..0c8354e 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1466,8 +1466,8 @@ void virt_dualsense_compose(virt_dualsense_t *const gamepad, gamepad_status_t *c const int16_t a_y = in_device_status->raw_accel[1]; 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); + const int64_t contrib_x = ((int64_t)g_y / (int64_t)gamepad->gyro_to_analog_mapping); + const int64_t contrib_y = ((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) @@ -1477,7 +1477,7 @@ 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[4] = ((uint64_t)((int64_t)in_device_status->joystick_positions[1][1] + (int64_t)32768) >> (uint64_t)8); // R stick, Y axis - if (contrib_y >= gamepad->gyro_to_analog_activation_treshold) { + if (in_device_status->join_left_analog_and_gyroscope) { if (absolute_value(contrib_x) > gamepad->gyro_to_analog_activation_treshold) { out_shifted_buf[1] = min_max_clamp((int64_t)127 + (((int64_t)out_shifted_buf[1] - (int64_t)127) + contrib_x), 0, 255); } From 658551fac15ce6a41ed95b25b86db0cf0cb4fde0 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 21:46:55 +0100 Subject: [PATCH 158/186] Disregard the haptics select flag for vibration --- virt_ds5.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/virt_ds5.c b/virt_ds5.c index 0c8354e..2f34d0a 100644 --- a/virt_ds5.c +++ b/virt_ds5.c @@ -1266,16 +1266,10 @@ int virt_dualsense_event(virt_dualsense_t *const gamepad, gamepad_status_t *cons uint8_t lightbar_green = common_report[45]; uint8_t lightbar_blue = common_report[46]; - if ((valid_flag0 & DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT) || ((motor_left == 0) && (motor_right == 0))) { - uint8_t motors_shift = 0; - if ((valid_flag2 & DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2) || (valid_flag0 & DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION)) { - out_device_status->motors_intensity[0] = (motor_left << 1) | ((motor_left == 0) ? 0 : 1); - out_device_status->motors_intensity[1] = (motor_right << 1) | ((motor_right == 0) ? 0 : 1); - } else { - out_device_status->motors_intensity[0] = motor_left; - out_device_status->motors_intensity[1] = motor_right; - } - + if ((valid_flag2 & DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2) || (valid_flag0 & DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION)) { + uint8_t motors_shift = valid_flag2 & DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2 ? 0 : 1; + out_device_status->motors_intensity[0] = (motor_left << motors_shift) | ((motors_shift > 0) ? ((motor_left == 0) ? 0 : 1) : 0); + out_device_status->motors_intensity[1] = (motor_right << motors_shift) | ((motors_shift > 0) ? ((motor_right == 0) ? 0 : 1) : 0); ++out_device_status->rumble_events_count; if (gamepad->debug) { From 8a97652d057c9ae2e46c813485d3a0f3bc94548f Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 23:41:42 +0100 Subject: [PATCH 159/186] use a shell command to set leds --- rog_ally.c | 162 ++--------------------------------------------------- 1 file changed, 5 insertions(+), 157 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 0708736..890a358 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1218,84 +1218,6 @@ static input_dev_t in_xbox_dev = { } }; -static int rc71l_hidraw_map(const dev_in_settings_t *const conf, int hidraw_fd, in_message_t *const messages, size_t messages_len, void* user_data) { - uint8_t data[256]; - const int read_res = read(hidraw_fd, data, sizeof(data)); - - if (read_res < 0) { - return -EIO; - } - - //printf("Got %d bytes from Asus MCU\n", read_res); // either 6 or 32 - - return 0; -} - -static int rc71l_hidraw_rumble(const dev_in_settings_t *const conf, int hidraw_fd, uint8_t left_motor, uint8_t right_motor, void* user_data) { - return 0; -} - -static int rc71l_hidraw_set_leds(const dev_in_settings_t *const conf, int hidraw_fd, uint8_t r, uint8_t g, uint8_t b, void* user_data) { - const uint8_t brightness_buf[] = { - 0x5A, 0xBA, 0xC5, 0xC4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - const uint8_t colors_buf[] = { - 0x5A, 0xB3, 0x00, ROG_ALLY_MODE_STATIC, r, g, b, 0x00, ROG_ALLY_DIRECTION_RIGHT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - if (write(hidraw_fd, brightness_buf, sizeof(brightness_buf)) != 64) { - fprintf(stderr, "Unable to send LEDs brightness (1) command change: %d\n", errno); - goto rc71l_hidraw_set_leds_err; - } - - if (write(hidraw_fd, colors_buf, sizeof(colors_buf)) != 64) { - fprintf(stderr, "Unable to send LEDs color command change (1)\n"); - goto rc71l_hidraw_set_leds_err; - } - - return 0; - -rc71l_hidraw_set_leds_err: - return -EIO; -} - -static void rc71l_hidraw_timer( - const dev_in_settings_t *const conf, - int fd, - const char* const timer_name, - uint64_t expired, - void* user_data -) { - -} - -static input_dev_t nkey_dev = { - .dev_type = input_dev_type_hidraw, - .filters = { - .hidraw = { - .pid = 0x1abe, - .vid = 0x0b05, - .rdesc_size = 167, // 48 83 167 - } - }, - .user_data = NULL, - .map = { - .hidraw_callbacks = { - .leds_callback = rc71l_hidraw_set_leds, - .rumble_callback = rc71l_hidraw_rumble, - .map_callback = rc71l_hidraw_map, - .timeout_callback = rc71l_hidraw_timer, - } - } -}; - static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platform_data) { int res = -EINVAL; @@ -1336,87 +1258,17 @@ static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** pl *platform_data = NULL; } -/** - * This function should use the following: - * pub static DBUS_NAME: &str = "org.asuslinux.Daemon"; - * pub static DBUS_PATH: &str = "/org/asuslinux/Daemon"; - * pub static DBUS_IFACE: &str = "org.asuslinux.Daemon"; - */ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, uint8_t g, uint8_t b, void* platform_data) { rc71l_platform_t *const platform = (rc71l_platform_t*)platform_data; - // TODO: before removing this make sure to disable the hidraw backend - return 0; - - dbus_uint32_t new_brightness = (r << 24) | (g << 16) | (b << 8) | (3); - if (platform_data == NULL) { return 0; } - // Replace "org.asuslinux.Daemon" and "/org/asuslinux/Aura" with the actual service and object paths - const char *service_name = "org.asuslinux.Daemon"; - const char *object_path = "/org/asuslinux/Aura"; - const char *interface_name = "org.freedesktop.DBus.Properties"; - const char *target_interface_name = "org.asuslinux.Daemon"; - - // Replace "Brightness" with the actual property name - const char *property_name = "Brightness"; - - // try to connect - if (platform->dbus_conn == NULL) { - platform->dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &platform->dbus_error); - if (dbus_error_is_set(&platform->dbus_error)) { - fprintf(stderr, "DBus error connection : %s -- %s \n", platform->dbus_error.name, platform->dbus_error.message); - dbus_error_free(&platform->dbus_error); - return 0; - } - } - - // Build the D-Bus message to set the property - DBusMessage *const message = dbus_message_new_method_call(service_name, object_path, interface_name, "Set"); - if (!message) { - fprintf(stderr, "Error creating D-Bus message\n"); - return -ENOMEM; - } - - // Append the property name and the new value to the message - //dbus_message_append_args(message, DBUS_TYPE_STRING, &target_interface_name, DBUS_TYPE_STRING, &property_name, DBUS_TYPE_INVALID); - - // Initialize an iterator for the message arguments - DBusMessageIter iter; - dbus_message_iter_init_append(message, &iter); - - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &target_interface_name); - - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property_name); - - // Open the variant container - DBusMessageIter variantIter; - dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "u", &variantIter); - - // Append the uint32 value to the variant container - dbus_message_iter_append_basic(&variantIter, DBUS_TYPE_UINT32, &new_brightness); - - // Close the variant container - dbus_message_iter_close_container(&iter, &variantIter); - - // Send the message - DBusMessage *reply = dbus_connection_send_with_reply_and_block(platform->dbus_conn, message, -1, &platform->dbus_error); - dbus_message_unref(message); - - if (!reply || dbus_error_is_set(&platform->dbus_error)) { - fprintf(stderr, "D-Bus method call error: %s\n", platform->dbus_error.message); - dbus_error_free(&platform->dbus_error); - return -EIO; - } - - // Handle the reply if needed - - // Free the D-Bus message - //dbus_message_unref(message); - - return 0; + char command_str[64] = "\0"; + sprintf(command_str, "asusctl led-mode static -c %02X%02X%02X",r ,g ,b); + + return system(command_str); } int rc71l_timer_map(const dev_in_settings_t *const conf, int timer_fd, uint64_t expirations, in_message_t *const messages, size_t messages_len, void* user_data) { @@ -1427,9 +1279,6 @@ int rc71l_timer_map(const dev_in_settings_t *const conf, int timer_fd, uint64_t return 0; } - - - return 0; } @@ -1456,11 +1305,10 @@ input_dev_composite_t rc71l_composite = { &in_asus_kb_1_dev, &in_asus_kb_2_dev, &in_asus_kb_3_dev, - &nkey_dev, &timer_dev, &in_touchscreen_dev, }, - .dev_count = 8, + .dev_count = 7, .init_fn = rc71l_platform_init, .deinit_fn = rc71l_platform_deinit, .leds_fn = rc71l_platform_leds, From 612fb701c597173ebb3249cf2129154e8c887600 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 6 Jan 2024 23:49:08 +0100 Subject: [PATCH 160/186] use asusctl command to set leds --- CMakeLists.txt | 9 ++------- rog_ally.c | 20 ++++++++++---------- rogue_enemy.h | 2 -- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 34da9dc..9aeeb08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,11 +15,6 @@ set(ALLINONE_EXECUTABLE_NAME "allynone") find_package(PkgConfig REQUIRED) # Include functions provided by PkgConfig module. -pkg_check_modules(DBUS REQUIRED dbus-1) # This calls pkgconfig with appropriate arguments -# Use results of pkg_check_modules() call. -include_directories(${DBUS_INCLUDE_DIRS}) -link_directories(${DBUS_LIBRARY_DIRS}) - set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) @@ -72,7 +67,7 @@ add_executable(${ALLINONE_EXECUTABLE_NAME} set_property(TARGET ${ALLINONE_EXECUTABLE_NAME} PROPERTY C_STANDARD 17) -target_link_libraries(${ALLINONE_EXECUTABLE_NAME} PRIVATE Threads::Threads ${DBUS_LIBRARIES} -levdev -ludev -lconfig -lm -lz) +target_link_libraries(${ALLINONE_EXECUTABLE_NAME} PRIVATE Threads::Threads -levdev -ludev -lconfig -lm -lz) set_target_properties(${ALLINONE_EXECUTABLE_NAME} PROPERTIES LINKER_LANGUAGE C) @@ -80,7 +75,7 @@ install(TARGETS ${ALLINONE_EXECUTABLE_NAME} DESTINATION bin) set_property(TARGET ${ROGUE_EXECUTABLE_NAME} PROPERTY C_STANDARD 17) -target_link_libraries(${ROGUE_EXECUTABLE_NAME} PRIVATE Threads::Threads ${DBUS_LIBRARIES} -levdev -ludev -lconfig -lm) +target_link_libraries(${ROGUE_EXECUTABLE_NAME} PRIVATE Threads::Threads -levdev -ludev -lconfig -lm) set_target_properties(${ROGUE_EXECUTABLE_NAME} PROPERTIES LINKER_LANGUAGE C) diff --git a/rog_ally.c b/rog_ally.c index 890a358..3181d6f 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -63,9 +63,11 @@ typedef struct rc71l_platform { rc71l_timer_user_data_t* timer_data; - DBusError dbus_error; - - DBusConnection * dbus_conn; + struct { + uint8_t r; + uint8_t g; + uint8_t b; + } static_led_color; } rc71l_platform_t; @@ -101,7 +103,6 @@ static rc71l_platform_t hw_platform = { .kbd_user_data = &asus_userdata, .xbox360_user_data = &controller_user_data, .timer_data = &timer_user_data, - .dbus_conn = NULL, }; static char* find_kernel_sysfs_device_path(struct udev *udev) { @@ -1235,8 +1236,6 @@ static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platf goto rc71l_platform_init_err; } - dbus_error_init(&platform->dbus_error); - res = 0; rc71l_platform_init_err: @@ -1250,9 +1249,6 @@ static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** pl if (platform->kbd_user_data != NULL) { udev_unref(platform->kbd_user_data->udev); } - - // Close the D-Bus connection - dbus_connection_close(platform->dbus_conn); } *platform_data = NULL; @@ -1265,8 +1261,12 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u return 0; } + platform->static_led_color.r = r; + platform->static_led_color.g = g; + platform->static_led_color.b = b; + char command_str[64] = "\0"; - sprintf(command_str, "asusctl led-mode static -c %02X%02X%02X",r ,g ,b); + sprintf(command_str, "asusctl led-mode static -c %02X%02X%02X", r ,g ,b); return system(command_str); } diff --git a/rogue_enemy.h b/rogue_enemy.h index 0c8c3d0..c13675d 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -46,8 +46,6 @@ #include -#include - #define LSB_PER_RAD_S_2000_DEG_S ((double)0.001064724) #define LSB_PER_RAD_S_2000_DEG_S_STR "0.001064724" From a64c7680fdee49b9d93f77acc0572a0ed3378d32 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 7 Jan 2024 00:04:35 +0100 Subject: [PATCH 161/186] Prepare to switch thermal profiles --- rog_ally.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 3181d6f..202bc87 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -57,17 +57,19 @@ typedef struct rc71l_timer_user_data { rc71l_timer_user_data_t timer_user_data; typedef struct rc71l_platform { - rc71l_asus_kbd_user_data_t* kbd_user_data; + rc71l_asus_kbd_user_data_t* kbd_user_data; - rc71l_xbox360_user_data_t* xbox360_user_data; + rc71l_xbox360_user_data_t* xbox360_user_data; - rc71l_timer_user_data_t* timer_data; + rc71l_timer_user_data_t* timer_data; - struct { - uint8_t r; - uint8_t g; - uint8_t b; - } static_led_color; + struct { + uint8_t r; + uint8_t g; + uint8_t b; + } static_led_color; + + size_t thermal_profile; } rc71l_platform_t; @@ -103,6 +105,12 @@ static rc71l_platform_t hw_platform = { .kbd_user_data = &asus_userdata, .xbox360_user_data = &controller_user_data, .timer_data = &timer_user_data, + .static_led_color = { + .r = 0x00, + .g = 0x00, + .b = 0x00, + }, + .thermal_profile = 0, }; static char* find_kernel_sysfs_device_path(struct udev *udev) { @@ -317,6 +325,9 @@ static int asus_kbd_ev_map( } else if ((e->ev[i].code == KEY_F18) && (e->ev[i].value != 0)) { // this is right screen button, on long release both 0 and 1 events are emitted so just discard the 0 + } else if ((e->ev[i].code == KEY_DELETE) && (e->ev[i].value != 0)) { + // this is left screen button, on long release both 0 and 1 events are emitted so just discard the 0 + printf("requested switch to thermal profile %d\n", (int)++asus_kbd_user_data->parent->thermal_profile); } else if ((e->ev[i].code == KEY_F17) && (e->ev[i].value != 0)) { // this is right screen button, on long press, after passing short threshold both 0 and 1 events are emitted so just discard the 0 From 57ca777219a1e4501298e9a07e39b7120b6d83ff Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 7 Jan 2024 00:25:57 +0100 Subject: [PATCH 162/186] revert to hidraw leds setting --- rog_ally.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 13 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 202bc87..b7043e8 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1230,6 +1230,84 @@ static input_dev_t in_xbox_dev = { } }; +static int rc71l_hidraw_map(const dev_in_settings_t *const conf, int hidraw_fd, in_message_t *const messages, size_t messages_len, void* user_data) { + uint8_t data[256]; + const int read_res = read(hidraw_fd, data, sizeof(data)); + + if (read_res < 0) { + return -EIO; + } + + //printf("Got %d bytes from Asus MCU\n", read_res); // either 6 or 32 + + return 0; +} + +static int rc71l_hidraw_rumble(const dev_in_settings_t *const conf, int hidraw_fd, uint8_t left_motor, uint8_t right_motor, void* user_data) { + return 0; +} + +static int rc71l_hidraw_set_leds(const dev_in_settings_t *const conf, int hidraw_fd, uint8_t r, uint8_t g, uint8_t b, void* user_data) { + const uint8_t brightness_buf[] = { + 0x5A, 0xBA, 0xC5, 0xC4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + const uint8_t colors_buf[] = { + 0x5A, 0xB3, 0x00, ROG_ALLY_MODE_STATIC, r, g, b, 0x00, ROG_ALLY_DIRECTION_RIGHT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + if (write(hidraw_fd, brightness_buf, sizeof(brightness_buf)) != 64) { + fprintf(stderr, "Unable to send LEDs brightness (1) command change: %d\n", errno); + goto rc71l_hidraw_set_leds_err; + } + + if (write(hidraw_fd, colors_buf, sizeof(colors_buf)) != 64) { + fprintf(stderr, "Unable to send LEDs color command change (1)\n"); + goto rc71l_hidraw_set_leds_err; + } + + return 0; + +rc71l_hidraw_set_leds_err: + return -EIO; +} + +static void rc71l_hidraw_timer( + const dev_in_settings_t *const conf, + int fd, + const char* const timer_name, + uint64_t expired, + void* user_data +) { + +} + +static input_dev_t nkey_dev = { + .dev_type = input_dev_type_hidraw, + .filters = { + .hidraw = { + .pid = 0x1abe, + .vid = 0x0b05, + .rdesc_size = 167, // 48 83 167 + } + }, + .user_data = NULL, + .map = { + .hidraw_callbacks = { + .leds_callback = rc71l_hidraw_set_leds, + .rumble_callback = rc71l_hidraw_rumble, + .map_callback = rc71l_hidraw_map, + .timeout_callback = rc71l_hidraw_timer, + } + } +}; + static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platform_data) { int res = -EINVAL; @@ -1268,18 +1346,8 @@ static void rc71l_platform_deinit(const dev_in_settings_t *const conf, void** pl static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, uint8_t g, uint8_t b, void* platform_data) { rc71l_platform_t *const platform = (rc71l_platform_t*)platform_data; - if (platform_data == NULL) { - return 0; - } - - platform->static_led_color.r = r; - platform->static_led_color.g = g; - platform->static_led_color.b = b; - - char command_str[64] = "\0"; - sprintf(command_str, "asusctl led-mode static -c %02X%02X%02X", r ,g ,b); - - return system(command_str); + // hidraw is used for now + return 0; } int rc71l_timer_map(const dev_in_settings_t *const conf, int timer_fd, uint64_t expirations, in_message_t *const messages, size_t messages_len, void* user_data) { @@ -1290,6 +1358,9 @@ int rc71l_timer_map(const dev_in_settings_t *const conf, int timer_fd, uint64_t return 0; } + + + return 0; } @@ -1316,10 +1387,11 @@ input_dev_composite_t rc71l_composite = { &in_asus_kb_1_dev, &in_asus_kb_2_dev, &in_asus_kb_3_dev, + &nkey_dev, &timer_dev, &in_touchscreen_dev, }, - .dev_count = 7, + .dev_count = 8, .init_fn = rc71l_platform_init, .deinit_fn = rc71l_platform_deinit, .leds_fn = rc71l_platform_leds, From 5b7b977ec4af1971b506c3baccb95c13dcb6c1b5 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 7 Jan 2024 02:37:09 +0100 Subject: [PATCH 163/186] Implement thermal profile switch over asusctl --- rog_ally.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 100 insertions(+), 12 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index b7043e8..c68625f 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -49,6 +49,11 @@ typedef struct rc71l_asus_kbd_user_data { int m1, m2; } rc71l_asus_kbd_user_data_t; +typedef struct rc71l_asus_hidraw_user_data { + struct rc71l_platform* parent; + +} rc71l_asus_hidraw_user_data_t; + typedef struct rc71l_timer_user_data { struct rc71l_platform* parent; @@ -63,16 +68,24 @@ typedef struct rc71l_platform { rc71l_timer_user_data_t* timer_data; + rc71l_asus_hidraw_user_data_t* hidraw_user_data; + struct { uint8_t r; uint8_t g; uint8_t b; } static_led_color; - size_t thermal_profile; + uint64_t thermal_profile_expired; + size_t current_thermal_profile; + size_t next_thermal_profile; } rc71l_platform_t; +static rc71l_asus_hidraw_user_data_t hidraw_userdata = { + .parent = NULL, +}; + static rc71l_asus_kbd_user_data_t asus_userdata = { .parent = NULL, .udev = NULL, @@ -105,12 +118,14 @@ static rc71l_platform_t hw_platform = { .kbd_user_data = &asus_userdata, .xbox360_user_data = &controller_user_data, .timer_data = &timer_user_data, + .hidraw_user_data = &hidraw_userdata, .static_led_color = { .r = 0x00, .g = 0x00, .b = 0x00, }, - .thermal_profile = 0, + .current_thermal_profile = 0, + .next_thermal_profile = 0, }; static char* find_kernel_sysfs_device_path(struct udev *udev) { @@ -327,7 +342,10 @@ static int asus_kbd_ev_map( } else if ((e->ev[i].code == KEY_DELETE) && (e->ev[i].value != 0)) { // this is left screen button, on long release both 0 and 1 events are emitted so just discard the 0 - printf("requested switch to thermal profile %d\n", (int)++asus_kbd_user_data->parent->thermal_profile); + + asus_kbd_user_data->parent->next_thermal_profile = asus_kbd_user_data->parent->current_thermal_profile + 1; + + printf("Requested switch to thermal profile %d\n", (int)asus_kbd_user_data->parent->next_thermal_profile); } else if ((e->ev[i].code == KEY_F17) && (e->ev[i].value != 0)) { // this is right screen button, on long press, after passing short threshold both 0 and 1 events are emitted so just discard the 0 @@ -1247,7 +1265,7 @@ static int rc71l_hidraw_rumble(const dev_in_settings_t *const conf, int hidraw_f return 0; } -static int rc71l_hidraw_set_leds(const dev_in_settings_t *const conf, int hidraw_fd, uint8_t r, uint8_t g, uint8_t b, void* user_data) { +static int rc71l_hidraw_set_leds_inner(int hidraw_fd, uint8_t r, uint8_t g, uint8_t b) { const uint8_t brightness_buf[] = { 0x5A, 0xBA, 0xC5, 0xC4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1264,28 +1282,100 @@ static int rc71l_hidraw_set_leds(const dev_in_settings_t *const conf, int hidraw if (write(hidraw_fd, brightness_buf, sizeof(brightness_buf)) != 64) { fprintf(stderr, "Unable to send LEDs brightness (1) command change: %d\n", errno); - goto rc71l_hidraw_set_leds_err; + goto rc71l_hidraw_set_leds_inner_err; } if (write(hidraw_fd, colors_buf, sizeof(colors_buf)) != 64) { fprintf(stderr, "Unable to send LEDs color command change (1)\n"); - goto rc71l_hidraw_set_leds_err; + goto rc71l_hidraw_set_leds_inner_err; } return 0; -rc71l_hidraw_set_leds_err: +rc71l_hidraw_set_leds_inner_err: return -EIO; } +static int rc71l_hidraw_set_leds(const dev_in_settings_t *const conf, int hidraw_fd, uint8_t r, uint8_t g, uint8_t b, void* user_data) { + rc71l_asus_hidraw_user_data_t *const hidraw_data = (rc71l_asus_hidraw_user_data_t*)user_data; + if (hidraw_data == NULL) { + return -ENOENT; + } + + if ( + (hidraw_data->parent->static_led_color.r == r) && + (hidraw_data->parent->static_led_color.g == g) && + (hidraw_data->parent->static_led_color.b == b) + ) { + return 0; + } + + hidraw_data->parent->static_led_color.r = r; + hidraw_data->parent->static_led_color.g = g; + hidraw_data->parent->static_led_color.b = b; + + return rc71l_hidraw_set_leds_inner( + hidraw_fd, + hidraw_data->parent->static_led_color.r, + hidraw_data->parent->static_led_color.g, + hidraw_data->parent->static_led_color.b + ); +} + +#define PROFILES_COUNT 3 + +static const char* profiles[PROFILES_COUNT] = { + "asusctl profile -P Quiet", + "asusctl profile -P Balanced", + "asusctl profile -P Performance", +}; + static void rc71l_hidraw_timer( const dev_in_settings_t *const conf, - int fd, + int hidraw_fd, const char* const timer_name, uint64_t expired, void* user_data ) { + // one tick is 60ms + rc71l_asus_hidraw_user_data_t *const hidraw_data = (rc71l_asus_hidraw_user_data_t*)user_data; + if (hidraw_data == NULL) { + return; + } + + if (hidraw_data->parent->current_thermal_profile != hidraw_data->parent->next_thermal_profile) { + if (hidraw_data->parent->thermal_profile_expired == 0) { + uint64_t thermal_profile_index = hidraw_data->parent->next_thermal_profile % PROFILES_COUNT; + + const int leds_set = rc71l_hidraw_set_leds_inner( + hidraw_fd, + thermal_profile_index == 2 ? 0xFF : 0x00, + thermal_profile_index == 1 ? 0xFF : 0x00, + thermal_profile_index == 0 ? 0xFF : 0x00 + ); + + if (leds_set != 0) { + sprintf(stderr, "Error setting leds to tell the user about the new profile: %d\n", leds_set); + } + + printf("Setting the new thermal profile with '%s'\n", profiles[thermal_profile_index]); + // system(profiles[thermal_profile_index]); + } else { + ++hidraw_data->parent->thermal_profile_expired; + + if (hidraw_data->parent->thermal_profile_expired > 18) { + hidraw_data->parent->current_thermal_profile = hidraw_data->parent->next_thermal_profile; + hidraw_data->parent->thermal_profile_expired = 0; + rc71l_hidraw_set_leds_inner( + hidraw_fd, + hidraw_data->parent->static_led_color.r, + hidraw_data->parent->static_led_color.g, + hidraw_data->parent->static_led_color.b + ); + } + } + } } static input_dev_t nkey_dev = { @@ -1297,7 +1387,7 @@ static input_dev_t nkey_dev = { .rdesc_size = 167, // 48 83 167 } }, - .user_data = NULL, + .user_data = (void*)&hidraw_userdata, .map = { .hidraw_callbacks = { .leds_callback = rc71l_hidraw_set_leds, @@ -1319,6 +1409,7 @@ static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platf platform->xbox360_user_data->parent = platform; platform->timer_data->parent = platform; platform->kbd_user_data->udev = udev_new(); + platform->hidraw_user_data->parent = platform; if (platform->kbd_user_data->udev == NULL) { fprintf(stderr, "Unable to initialize udev\n"); res = -ENOMEM; @@ -1358,9 +1449,6 @@ int rc71l_timer_map(const dev_in_settings_t *const conf, int timer_fd, uint64_t return 0; } - - - return 0; } From 50d36ba6fe54e78c6726a85da4e74f0508f3c309 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 7 Jan 2024 02:40:32 +0100 Subject: [PATCH 164/186] this was missing --- rog_ally.c | 1 + 1 file changed, 1 insertion(+) diff --git a/rog_ally.c b/rog_ally.c index c68625f..b86cd88 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1346,6 +1346,7 @@ static void rc71l_hidraw_timer( if (hidraw_data->parent->current_thermal_profile != hidraw_data->parent->next_thermal_profile) { if (hidraw_data->parent->thermal_profile_expired == 0) { + ++hidraw_data->parent->thermal_profile_expired; uint64_t thermal_profile_index = hidraw_data->parent->next_thermal_profile % PROFILES_COUNT; const int leds_set = rc71l_hidraw_set_leds_inner( From e0d36026e7dfc998b677cc1a0cd89fa1c639a2d6 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 7 Jan 2024 03:28:57 +0100 Subject: [PATCH 165/186] set thermal profile to quiet as default --- rog_ally.c | 82 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index b86cd88..0b26bb4 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -120,11 +120,11 @@ static rc71l_platform_t hw_platform = { .timer_data = &timer_user_data, .hidraw_user_data = &hidraw_userdata, .static_led_color = { - .r = 0x00, - .g = 0x00, - .b = 0x00, + .r = 0x40, + .g = 0x40, + .b = 0x40, }, - .current_thermal_profile = 0, + .current_thermal_profile = 0xFFFFFFFFFFFFFFFF, .next_thermal_profile = 0, }; @@ -1266,13 +1266,6 @@ static int rc71l_hidraw_rumble(const dev_in_settings_t *const conf, int hidraw_f } static int rc71l_hidraw_set_leds_inner(int hidraw_fd, uint8_t r, uint8_t g, uint8_t b) { - const uint8_t brightness_buf[] = { - 0x5A, 0xBA, 0xC5, 0xC4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - const uint8_t colors_buf[] = { 0x5A, 0xB3, 0x00, ROG_ALLY_MODE_STATIC, r, g, b, 0x00, ROG_ALLY_DIRECTION_RIGHT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1280,11 +1273,6 @@ static int rc71l_hidraw_set_leds_inner(int hidraw_fd, uint8_t r, uint8_t g, uint 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - if (write(hidraw_fd, brightness_buf, sizeof(brightness_buf)) != 64) { - fprintf(stderr, "Unable to send LEDs brightness (1) command change: %d\n", errno); - goto rc71l_hidraw_set_leds_inner_err; - } - if (write(hidraw_fd, colors_buf, sizeof(colors_buf)) != 64) { fprintf(stderr, "Unable to send LEDs color command change (1)\n"); goto rc71l_hidraw_set_leds_inner_err; @@ -1309,7 +1297,7 @@ static int rc71l_hidraw_set_leds(const dev_in_settings_t *const conf, int hidraw ) { return 0; } - + hidraw_data->parent->static_led_color.r = r; hidraw_data->parent->static_led_color.g = g; hidraw_data->parent->static_led_color.b = b; @@ -1349,19 +1337,27 @@ static void rc71l_hidraw_timer( ++hidraw_data->parent->thermal_profile_expired; uint64_t thermal_profile_index = hidraw_data->parent->next_thermal_profile % PROFILES_COUNT; - const int leds_set = rc71l_hidraw_set_leds_inner( - hidraw_fd, - thermal_profile_index == 2 ? 0xFF : 0x00, - thermal_profile_index == 1 ? 0xFF : 0x00, - thermal_profile_index == 0 ? 0xFF : 0x00 - ); + int change_thermal_result = system(profiles[thermal_profile_index]); - if (leds_set != 0) { - sprintf(stderr, "Error setting leds to tell the user about the new profile: %d\n", leds_set); + if (change_thermal_result == 0) { + const int leds_set = rc71l_hidraw_set_leds_inner( + hidraw_fd, + thermal_profile_index == 2 ? 0xFF : 0x00, + thermal_profile_index == 1 ? 0xFF : 0x00, + thermal_profile_index == 0 ? 0xFF : 0x00 + ); + + if (leds_set != 0) { + sprintf(stderr, "Error setting leds to tell the user about the new profile: %d\n", leds_set); + } + } else { + fprintf( + stderr, + "Error setting the new thermal profile with '%s': %d\n", + profiles[thermal_profile_index], + change_thermal_result + ); } - - printf("Setting the new thermal profile with '%s'\n", profiles[thermal_profile_index]); - // system(profiles[thermal_profile_index]); } else { ++hidraw_data->parent->thermal_profile_expired; @@ -1419,6 +1415,36 @@ static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platf res = 0; + char command_str[64] = "\0"; + sprintf( + command_str, + "asusctl led-mode static -c %02X%02X%02X", + platform->static_led_color.r, + platform->static_led_color.g, + platform->static_led_color.b + ); + + const int led_mode_cmd_result = system(command_str); + if (led_mode_cmd_result != 0) { + fprintf( + stderr, + "Error setting led mode to static over asusctl: %d\n", + led_mode_cmd_result + ); + } + + memset(command_str, 0, sizeof(command_str)); + sprintf(command_str, "asusctl -k high"); + + const int led_brightness_cmd_result = system(command_str); + if (led_brightness_cmd_result != 0) { + fprintf( + stderr, + "Error setting led brightness over asusctl: %d\n", + led_brightness_cmd_result + ); + } + rc71l_platform_init_err: return res; } From f75351fa36ea983ab2ce5d761ce0df122fab9a63 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 7 Jan 2024 15:44:47 +0100 Subject: [PATCH 166/186] Allow disabling thermal profiles switching and leds management --- allynone.c | 2 + config.cfg.default | 4 +- main.c | 2 + rog_ally.c | 140 +++++++++++++++++++++++++-------------------- settings.c | 15 ++++- settings.h | 2 + 6 files changed, 102 insertions(+), 63 deletions(-) diff --git a/allynone.c b/allynone.c index 2ca2aeb..10e8e0b 100644 --- a/allynone.c +++ b/allynone.c @@ -22,6 +22,8 @@ int main(int argc, char ** argv) { .rumble_on_mode_switch = true, .m1m2_mode = 0, .touchbar = true, + .enable_thermal_profiles_switching = false, + .enable_leds_commands = false, }; load_in_config(&in_settings, configuration_file); diff --git a/config.cfg.default b/config.cfg.default index b327b78..38faede 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -11,4 +11,6 @@ gyro_to_analog_activation_treshold = 1; touchbar = true; controller_bluetooth = true; dualsense_edge = false; -swap_y_z = true; \ No newline at end of file +swap_y_z = true; +enable_thermal_profiles_switching = true; +enable_leds_commands = true; \ No newline at end of file diff --git a/main.c b/main.c index 389fb3d..5c1ab85 100644 --- a/main.c +++ b/main.c @@ -21,6 +21,8 @@ int main(int argc, char ** argv) { .rumble_on_mode_switch = true, .m1m2_mode = 1, .touchbar = true, + .enable_thermal_profiles_switching = false, + .enable_leds_commands = false, }; load_in_config(&in_settings, configuration_file); diff --git a/rog_ally.c b/rog_ally.c index 0b26bb4..9b022b6 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -343,9 +343,11 @@ static int asus_kbd_ev_map( } else if ((e->ev[i].code == KEY_DELETE) && (e->ev[i].value != 0)) { // this is left screen button, on long release both 0 and 1 events are emitted so just discard the 0 - asus_kbd_user_data->parent->next_thermal_profile = asus_kbd_user_data->parent->current_thermal_profile + 1; + if (conf->enable_thermal_profiles_switching) { + asus_kbd_user_data->parent->next_thermal_profile = asus_kbd_user_data->parent->current_thermal_profile + 1; - printf("Requested switch to thermal profile %d\n", (int)asus_kbd_user_data->parent->next_thermal_profile); + printf("Requested switch to thermal profile %d\n", (int)asus_kbd_user_data->parent->next_thermal_profile); + } } else if ((e->ev[i].code == KEY_F17) && (e->ev[i].value != 0)) { // this is right screen button, on long press, after passing short threshold both 0 and 1 events are emitted so just discard the 0 @@ -1302,12 +1304,18 @@ static int rc71l_hidraw_set_leds(const dev_in_settings_t *const conf, int hidraw hidraw_data->parent->static_led_color.g = g; hidraw_data->parent->static_led_color.b = b; - return rc71l_hidraw_set_leds_inner( + const int res = conf->enable_leds_commands ? rc71l_hidraw_set_leds_inner( hidraw_fd, hidraw_data->parent->static_led_color.r, hidraw_data->parent->static_led_color.g, hidraw_data->parent->static_led_color.b - ); + ) : 0; + + if (res != 0) { + sprintf(stderr, "Error setting leds: %d\n", res); + } + + return res; } #define PROFILES_COUNT 3 @@ -1332,44 +1340,46 @@ static void rc71l_hidraw_timer( return; } - if (hidraw_data->parent->current_thermal_profile != hidraw_data->parent->next_thermal_profile) { - if (hidraw_data->parent->thermal_profile_expired == 0) { - ++hidraw_data->parent->thermal_profile_expired; - uint64_t thermal_profile_index = hidraw_data->parent->next_thermal_profile % PROFILES_COUNT; + if (conf->enable_thermal_profiles_switching) { + if (hidraw_data->parent->current_thermal_profile != hidraw_data->parent->next_thermal_profile) { + if (hidraw_data->parent->thermal_profile_expired == 0) { + ++hidraw_data->parent->thermal_profile_expired; + uint64_t thermal_profile_index = hidraw_data->parent->next_thermal_profile % PROFILES_COUNT; - int change_thermal_result = system(profiles[thermal_profile_index]); + int change_thermal_result = system(profiles[thermal_profile_index]); - if (change_thermal_result == 0) { - const int leds_set = rc71l_hidraw_set_leds_inner( - hidraw_fd, - thermal_profile_index == 2 ? 0xFF : 0x00, - thermal_profile_index == 1 ? 0xFF : 0x00, - thermal_profile_index == 0 ? 0xFF : 0x00 - ); + if (change_thermal_result == 0) { + const int leds_set = rc71l_hidraw_set_leds_inner( + hidraw_fd, + thermal_profile_index == 2 ? 0xFF : 0x00, + thermal_profile_index == 1 ? 0xFF : 0x00, + thermal_profile_index == 0 ? 0xFF : 0x00 + ); - if (leds_set != 0) { - sprintf(stderr, "Error setting leds to tell the user about the new profile: %d\n", leds_set); + if (leds_set != 0) { + sprintf(stderr, "Error setting leds to tell the user about the new profile: %d\n", leds_set); + } + } else { + fprintf( + stderr, + "Error setting the new thermal profile with '%s': %d\n", + profiles[thermal_profile_index], + change_thermal_result + ); } } else { - fprintf( - stderr, - "Error setting the new thermal profile with '%s': %d\n", - profiles[thermal_profile_index], - change_thermal_result - ); - } - } else { - ++hidraw_data->parent->thermal_profile_expired; + ++hidraw_data->parent->thermal_profile_expired; - if (hidraw_data->parent->thermal_profile_expired > 18) { - hidraw_data->parent->current_thermal_profile = hidraw_data->parent->next_thermal_profile; - hidraw_data->parent->thermal_profile_expired = 0; - rc71l_hidraw_set_leds_inner( - hidraw_fd, - hidraw_data->parent->static_led_color.r, - hidraw_data->parent->static_led_color.g, - hidraw_data->parent->static_led_color.b - ); + if (hidraw_data->parent->thermal_profile_expired > 18) { + hidraw_data->parent->current_thermal_profile = hidraw_data->parent->next_thermal_profile; + hidraw_data->parent->thermal_profile_expired = 0; + rc71l_hidraw_set_leds_inner( + hidraw_fd, + hidraw_data->parent->static_led_color.r, + hidraw_data->parent->static_led_color.g, + hidraw_data->parent->static_led_color.b + ); + } } } } @@ -1415,34 +1425,42 @@ static int rc71l_platform_init(const dev_in_settings_t *const conf, void** platf res = 0; - char command_str[64] = "\0"; - sprintf( - command_str, - "asusctl led-mode static -c %02X%02X%02X", - platform->static_led_color.r, - platform->static_led_color.g, - platform->static_led_color.b - ); - - const int led_mode_cmd_result = system(command_str); - if (led_mode_cmd_result != 0) { - fprintf( - stderr, - "Error setting led mode to static over asusctl: %d\n", - led_mode_cmd_result + if (conf->enable_leds_commands) { + char command_str[64] = "\0"; + sprintf( + command_str, + "asusctl led-mode static -c %02X%02X%02X", + platform->static_led_color.r, + platform->static_led_color.g, + platform->static_led_color.b ); - } - memset(command_str, 0, sizeof(command_str)); - sprintf(command_str, "asusctl -k high"); + const int led_mode_cmd_result = system(command_str); + if (led_mode_cmd_result != 0) { + fprintf( + stderr, + "Error setting led mode to static over asusctl: %d\n", + led_mode_cmd_result + ); - const int led_brightness_cmd_result = system(command_str); - if (led_brightness_cmd_result != 0) { - fprintf( - stderr, - "Error setting led brightness over asusctl: %d\n", - led_brightness_cmd_result - ); + res = led_mode_cmd_result; + goto rc71l_platform_init_err; + } + + memset(command_str, 0, sizeof(command_str)); + sprintf(command_str, "asusctl -k high"); + + const int led_brightness_cmd_result = system(command_str); + if (led_brightness_cmd_result != 0) { + fprintf( + stderr, + "Error setting led brightness over asusctl: %d\n", + led_brightness_cmd_result + ); + + res = led_brightness_cmd_result; + goto rc71l_platform_init_err; + } } rc71l_platform_init_err: diff --git a/settings.c b/settings.c index 0f453fe..bbba22c 100644 --- a/settings.c +++ b/settings.c @@ -55,6 +55,20 @@ void load_in_config(dev_in_settings_t *const out_conf, const char* const filepat fprintf(stderr, "touchbar (bool) configuration not found. Default value will be used.\n"); } + int enable_thermal_profiles_switching; + if (config_lookup_bool(&cfg, "enable_thermal_profiles_switching", &enable_thermal_profiles_switching) != CONFIG_FALSE) { + out_conf->enable_thermal_profiles_switching = enable_thermal_profiles_switching; + } else { + fprintf(stderr, "enable_thermal_profiles_switching (bool) configuration not found. Default value will be used.\n"); + } + + int enable_leds_commands; + if (config_lookup_bool(&cfg, "enable_leds_commands", &enable_leds_commands) != CONFIG_FALSE) { + out_conf->enable_leds_commands = enable_leds_commands; + } else { + fprintf(stderr, "enable_leds_commands (bool) configuration not found. Default value will be used.\n"); + } + config_destroy(&cfg); load_in_config_err: @@ -134,7 +148,6 @@ void load_out_config(dev_out_settings_t *const out_conf, const char* const filep fprintf(stderr, "gyro_to_analog_mapping (int) configuration not found. Default value will be used.\n"); } - config_destroy(&cfg); load_out_config_err: diff --git a/settings.h b/settings.h index 3063ab7..cfbe019 100644 --- a/settings.h +++ b/settings.h @@ -8,6 +8,8 @@ typedef struct dev_in_settings { uint16_t ff_gain; uint8_t m1m2_mode; bool touchbar; + bool enable_thermal_profiles_switching; + bool enable_leds_commands; } dev_in_settings_t; void load_in_config(dev_in_settings_t *const out_conf, const char* const filepath); From cb9b5e5c4a9a62e70c076f0ddab0b7b78af6c658 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 7 Jan 2024 15:50:59 +0100 Subject: [PATCH 167/186] Improve device grabbing based on configuration options --- rog_ally.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 9b022b6..2cc61c0 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1520,20 +1520,21 @@ input_dev_composite_t rc71l_composite = { &in_asus_kb_1_dev, &in_asus_kb_2_dev, &in_asus_kb_3_dev, - &nkey_dev, &timer_dev, - &in_touchscreen_dev, }, - .dev_count = 8, + .dev_count = 6, .init_fn = rc71l_platform_init, .deinit_fn = rc71l_platform_deinit, .leds_fn = rc71l_platform_leds, }; input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const settings) { - if (!settings->touchbar) { - // this is because the touchscreen is the latest in the list - rc71l_composite.dev_count -= 1; + if (settings->touchbar) { + rc71l_composite.dev[rc71l_composite.dev_count++] = &in_touchscreen_dev; + } + + if ((settings->enable_leds_commands) || (settings->enable_thermal_profiles_switching)) { + rc71l_composite.dev[rc71l_composite.dev_count++] = &nkey_dev; } return &rc71l_composite; From d608d07d89153448ce61113ad3f28fbd7f5f0dc0 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 7 Jan 2024 18:02:09 +0100 Subject: [PATCH 168/186] Allow to set a specific thermal profile at start-up time --- allynone.c | 1 + config.cfg.default | 1 + main.c | 1 + rog_ally.c | 13 +++++++++---- settings.c | 7 +++++++ settings.h | 1 + 6 files changed, 20 insertions(+), 4 deletions(-) diff --git a/allynone.c b/allynone.c index 10e8e0b..3f3ecbe 100644 --- a/allynone.c +++ b/allynone.c @@ -23,6 +23,7 @@ int main(int argc, char ** argv) { .m1m2_mode = 0, .touchbar = true, .enable_thermal_profiles_switching = false, + .default_thermal_profile = -1, .enable_leds_commands = false, }; diff --git a/config.cfg.default b/config.cfg.default index 38faede..8fb3b16 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -13,4 +13,5 @@ controller_bluetooth = true; dualsense_edge = false; swap_y_z = true; enable_thermal_profiles_switching = true; +default_thermal_profile = -1; enable_leds_commands = true; \ No newline at end of file diff --git a/main.c b/main.c index 5c1ab85..e1822ab 100644 --- a/main.c +++ b/main.c @@ -22,6 +22,7 @@ int main(int argc, char ** argv) { .m1m2_mode = 1, .touchbar = true, .enable_thermal_profiles_switching = false, + .default_thermal_profile = -1, .enable_leds_commands = false, }; diff --git a/rog_ally.c b/rog_ally.c index 2cc61c0..cdf4a32 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -124,7 +124,7 @@ static rc71l_platform_t hw_platform = { .g = 0x40, .b = 0x40, }, - .current_thermal_profile = 0xFFFFFFFFFFFFFFFF, + .current_thermal_profile = 0, .next_thermal_profile = 0, }; @@ -1528,14 +1528,19 @@ input_dev_composite_t rc71l_composite = { .leds_fn = rc71l_platform_leds, }; -input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const settings) { - if (settings->touchbar) { +input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const conf) { + if (conf->touchbar) { rc71l_composite.dev[rc71l_composite.dev_count++] = &in_touchscreen_dev; } - if ((settings->enable_leds_commands) || (settings->enable_thermal_profiles_switching)) { + if ((conf->enable_leds_commands) || (conf->enable_thermal_profiles_switching)) { rc71l_composite.dev[rc71l_composite.dev_count++] = &nkey_dev; } + if ((conf->enable_thermal_profiles_switching) && (conf->default_thermal_profile >= 0) && (conf->default_thermal_profile < 3)) { + hw_platform.current_thermal_profile = 0xFFFFFFFFFFFFFFFF; + hw_platform.next_thermal_profile = conf->default_thermal_profile; + } + return &rc71l_composite; } diff --git a/settings.c b/settings.c index bbba22c..31c80fe 100644 --- a/settings.c +++ b/settings.c @@ -62,6 +62,13 @@ void load_in_config(dev_in_settings_t *const out_conf, const char* const filepat fprintf(stderr, "enable_thermal_profiles_switching (bool) configuration not found. Default value will be used.\n"); } + int default_thermal_profile; + if (config_lookup_int(&cfg, "default_thermal_profile", &default_thermal_profile) != CONFIG_FALSE) { + out_conf->default_thermal_profile = default_thermal_profile; + } else { + fprintf(stderr, "default_thermal_profile (int) configuration not found. Default value will be used.\n"); + } + int enable_leds_commands; if (config_lookup_bool(&cfg, "enable_leds_commands", &enable_leds_commands) != CONFIG_FALSE) { out_conf->enable_leds_commands = enable_leds_commands; diff --git a/settings.h b/settings.h index cfbe019..2cacd0f 100644 --- a/settings.h +++ b/settings.h @@ -9,6 +9,7 @@ typedef struct dev_in_settings { uint8_t m1m2_mode; bool touchbar; bool enable_thermal_profiles_switching; + int default_thermal_profile; bool enable_leds_commands; } dev_in_settings_t; From f4f638ea243835b9edf9d38a1559d7b94519b365 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 8 Jan 2024 03:42:34 +0100 Subject: [PATCH 169/186] add a * to match every input device --- 80-playstation-no-libinput.rules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/80-playstation-no-libinput.rules b/80-playstation-no-libinput.rules index 2f55575..23c66ac 100644 --- a/80-playstation-no-libinput.rules +++ b/80-playstation-no-libinput.rules @@ -1,2 +1,2 @@ -ACTION=="add|change", KERNEL=="event[0-9]", ATTRS{name}=="Wireless Controller Touchpad", ENV{LIBINPUT_IGNORE_DEVICE}="1" -ACTION=="add|change", KERNEL=="event[0-9]", ATTRS{name}=="Wireless Edge Controller Touchpad", ENV{LIBINPUT_IGNORE_DEVICE}="1" \ No newline at end of file +ACTION=="add|change", KERNEL=="event[0-9]*", ATTRS{name}=="Wireless Controller Touchpad", ENV{LIBINPUT_IGNORE_DEVICE}="1" +ACTION=="add|change", KERNEL=="event[0-9]*", ATTRS{name}=="Wireless Edge Controller Touchpad", ENV{LIBINPUT_IGNORE_DEVICE}="1" \ No newline at end of file From 1866d65b9ee82e8048981fefa18757a55cc6b4eb Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 15 Jan 2024 02:15:06 +0100 Subject: [PATCH 170/186] Ability to disable IMU --- allynone.c | 1 + config.cfg.default | 3 ++- main.c | 1 + rog_ally.c | 7 +++++-- settings.c | 7 +++++++ settings.h | 1 + 6 files changed, 17 insertions(+), 3 deletions(-) diff --git a/allynone.c b/allynone.c index 3f3ecbe..304cf61 100644 --- a/allynone.c +++ b/allynone.c @@ -25,6 +25,7 @@ int main(int argc, char ** argv) { .enable_thermal_profiles_switching = false, .default_thermal_profile = -1, .enable_leds_commands = false, + .enable_imu = true, }; load_in_config(&in_settings, configuration_file); diff --git a/config.cfg.default b/config.cfg.default index 8fb3b16..2d8ffe9 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -14,4 +14,5 @@ dualsense_edge = false; swap_y_z = true; enable_thermal_profiles_switching = true; default_thermal_profile = -1; -enable_leds_commands = true; \ No newline at end of file +enable_leds_commands = true; +enable_imu = true; \ No newline at end of file diff --git a/main.c b/main.c index e1822ab..17d94a4 100644 --- a/main.c +++ b/main.c @@ -24,6 +24,7 @@ int main(int argc, char ** argv) { .enable_thermal_profiles_switching = false, .default_thermal_profile = -1, .enable_leds_commands = false, + .enable_imu = true, }; load_in_config(&in_settings, configuration_file); diff --git a/rog_ally.c b/rog_ally.c index cdf4a32..0f20bba 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1516,19 +1516,22 @@ input_dev_t timer_dev = { input_dev_composite_t rc71l_composite = { .dev = { &in_xbox_dev, - &in_iio_dev, &in_asus_kb_1_dev, &in_asus_kb_2_dev, &in_asus_kb_3_dev, &timer_dev, }, - .dev_count = 6, + .dev_count = 5, .init_fn = rc71l_platform_init, .deinit_fn = rc71l_platform_deinit, .leds_fn = rc71l_platform_leds, }; input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const conf) { + if (conf->enable_imu) { + rc71l_composite.dev[rc71l_composite.dev_count++] = &in_iio_dev; + } + if (conf->touchbar) { rc71l_composite.dev[rc71l_composite.dev_count++] = &in_touchscreen_dev; } diff --git a/settings.c b/settings.c index 31c80fe..3a8da9d 100644 --- a/settings.c +++ b/settings.c @@ -76,6 +76,13 @@ void load_in_config(dev_in_settings_t *const out_conf, const char* const filepat fprintf(stderr, "enable_leds_commands (bool) configuration not found. Default value will be used.\n"); } + int enable_imu; + if (config_lookup_bool(&cfg, "enable_imu", &enable_imu) != CONFIG_FALSE) { + out_conf->enable_imu = enable_imu; + } else { + fprintf(stderr, "enable_imu (bool) configuration not found. Default value will be used.\n"); + } + config_destroy(&cfg); load_in_config_err: diff --git a/settings.h b/settings.h index 2cacd0f..5576d54 100644 --- a/settings.h +++ b/settings.h @@ -11,6 +11,7 @@ typedef struct dev_in_settings { bool enable_thermal_profiles_switching; int default_thermal_profile; bool enable_leds_commands; + bool enable_imu; } dev_in_settings_t; void load_in_config(dev_in_settings_t *const out_conf, const char* const filepath); From 35bbaa4f2dfc9168832e17f4bbccd29da0c2ede0 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 15 Jan 2024 02:32:21 +0100 Subject: [PATCH 171/186] prepare to work in backward-comaptible mode --- dev_timer.c | 15 +++++++++++---- input_dev.h | 1 + rog_ally.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/dev_timer.c b/dev_timer.c index 6c6e2e3..bcbd23a 100644 --- a/dev_timer.c +++ b/dev_timer.c @@ -24,10 +24,17 @@ int dev_timer_open( } (*out_dev)->fd = fd; - (*out_dev)->timer_spec.it_value.tv_sec = in_filters->ticktime_ms / (__time_t)1000; - (*out_dev)->timer_spec.it_value.tv_nsec = (in_filters->ticktime_ms % (__syscall_slong_t)1000) * (__syscall_slong_t)1000000; - (*out_dev)->timer_spec.it_interval.tv_sec = in_filters->ticktime_ms / (__time_t)1000; - (*out_dev)->timer_spec.it_interval.tv_nsec = (in_filters->ticktime_ms % (__syscall_slong_t)1000) * (__syscall_slong_t)1000000; + if (in_filters->ticktime_ms != 0) { + (*out_dev)->timer_spec.it_value.tv_sec = in_filters->ticktime_ms / (__time_t)1000; + (*out_dev)->timer_spec.it_value.tv_nsec = (in_filters->ticktime_ms % (__syscall_slong_t)1000) * (__syscall_slong_t)1000000; + (*out_dev)->timer_spec.it_interval.tv_sec = in_filters->ticktime_ms / (__time_t)1000; + (*out_dev)->timer_spec.it_interval.tv_nsec = (in_filters->ticktime_ms % (__syscall_slong_t)1000) * (__syscall_slong_t)1000000; + } else { + (*out_dev)->timer_spec.it_value.tv_sec = 0; + (*out_dev)->timer_spec.it_value.tv_nsec = in_filters->ticktime_ns; + (*out_dev)->timer_spec.it_interval.tv_sec = 0; + (*out_dev)->timer_spec.it_interval.tv_nsec = in_filters->ticktime_ns; + } if (timerfd_settime((*out_dev)->fd, 0, &(*out_dev)->timer_spec, NULL) < 0) { res = errno < 0 ? errno : -1 * errno; diff --git a/input_dev.h b/input_dev.h index 788e17b..39d7e62 100644 --- a/input_dev.h +++ b/input_dev.h @@ -113,6 +113,7 @@ typedef struct ev_callbacks { typedef struct timer_filters { char name[128]; uint64_t ticktime_ms; + uint64_t ticktime_ns; } timer_filters_t; typedef struct input_dev { diff --git a/rog_ally.c b/rog_ally.c index 0f20bba..1b6cb37 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1312,7 +1312,7 @@ static int rc71l_hidraw_set_leds(const dev_in_settings_t *const conf, int hidraw ) : 0; if (res != 0) { - sprintf(stderr, "Error setting leds: %d\n", res); + fprintf(stderr, "Error setting leds: %d\n", res); } return res; @@ -1357,7 +1357,7 @@ static void rc71l_hidraw_timer( ); if (leds_set != 0) { - sprintf(stderr, "Error setting leds to tell the user about the new profile: %d\n", leds_set); + fprintf(stderr, "Error setting leds to tell the user about the new profile: %d\n", leds_set); } } else { fprintf( @@ -1513,6 +1513,41 @@ input_dev_t timer_dev = { } }; +typedef struct bmc150_accel_user_data { + +} bmc150_accel_user_data_t; + +static bmc150_accel_user_data_t bmc15_timer_data = { + +}; + +int rc71l_bmc150_accel_timer_map(const dev_in_settings_t *const conf, int timer_fd, uint64_t expirations, in_message_t *const messages, size_t messages_len, void* user_data) { + bmc150_accel_user_data_t *const timer_data = (bmc150_accel_user_data_t*)user_data; + + if (timer_data == NULL) { + return 0; + } + + return 0; +} + +input_dev_t bmc150_timer_dev = { + .dev_type = input_dev_type_timer, + .filters = { + .timer = { + .name = "RC71L_bmc150-accel_timer", + .ticktime_ms = 0, + .ticktime_ns = 625000 + } + }, + .user_data = &bmc15_timer_data, + .map = { + .timer_callbacks = { + .map_fn = rc71l_bmc150_accel_timer_map, + } + } +}; + input_dev_composite_t rc71l_composite = { .dev = { &in_xbox_dev, @@ -1529,7 +1564,11 @@ input_dev_composite_t rc71l_composite = { input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const conf) { if (conf->enable_imu) { - rc71l_composite.dev[rc71l_composite.dev_count++] = &in_iio_dev; + if (false) { + rc71l_composite.dev[rc71l_composite.dev_count++] = &bmc150_timer_dev; + } else { + rc71l_composite.dev[rc71l_composite.dev_count++] = &in_iio_dev; + } } if (conf->touchbar) { From 749b184d13a47dcc68e78e183b492fb4b01448eb Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 15 Jan 2024 03:11:32 +0100 Subject: [PATCH 172/186] Read data from the old bmc150-accel-i2c modified driver --- rog_ally.c | 553 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 517 insertions(+), 36 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 1b6cb37..a78aab5 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -3,6 +3,9 @@ #include "dev_hidraw.h" #include "message.h" #include "xbox360.h" +#include + +static const char iio_base_path[] = "/sys/bus/iio/devices/iio:device0/"; enum rc71l_leds_mode { ROG_ALLY_MODE_STATIC = 0, @@ -1486,6 +1489,516 @@ static int rc71l_platform_leds(const dev_in_settings_t *const conf, uint8_t r, u return 0; } + + +typedef struct dev_iio { + char* path; + char* name; + uint32_t flags; + + FILE* accel_x_fd; + FILE* accel_y_fd; + FILE* accel_z_fd; + + double accel_scale_x; + double accel_scale_y; + double accel_scale_z; + + FILE* anglvel_x_fd; + FILE* anglvel_y_fd; + FILE* anglvel_z_fd; + + double anglvel_scale_x; + double anglvel_scale_y; + double anglvel_scale_z; + + double temp_scale; + + double outer_temp_scale; + + double mount_matrix[3][3]; + + double sampling_rate_hz; +} dev_old_iio_t; + + +static char* read_file(const char* base_path, const char *file) { + char* res = NULL; + char* fdir = NULL; + long len = 0; + + len = strlen(base_path) + strlen(file) + 1; + fdir = malloc(len); + if (fdir == NULL) { + fprintf(stderr, "Cannot allocate %ld bytes for device path, device skipped.\n", len); + goto read_file_err; + } + strcpy(fdir, base_path); + strcat(fdir, file); + + if (access(fdir, F_OK) == 0) { + FILE* fp = fopen(fdir, "r"); + if (fp != NULL) { + fseek(fp, 0L, SEEK_END); + len = ftell(fp); + rewind(fp); + + len += 1; + res = malloc(len); + if (res != NULL) { + unsigned long read_bytes = fread(res, 1, len, fp); + printf("Read %lu bytes from file %s\n", read_bytes, fdir); + } else { + fprintf(stderr, "Cannot allocate %ld bytes for %s content.\n", len, fdir); + } + + fclose(fp); + } else { + fprintf(stderr, "Cannot open file %s.\n", fdir); + } + } else { + fprintf(stderr, "File %s does not exists.\n", fdir); + } + + free(fdir); + fdir = NULL; + +read_file_err: + return res; +} + +int write_file(const char* base_path, const char *file, const void* buf, size_t buf_sz) { + char* fdir = NULL; + + int res = 0; + + const size_t len = strlen(base_path) + strlen(file) + 1; + fdir = malloc(len); + if (fdir == NULL) { + fprintf(stderr, "Cannot allocate %ld bytes for device path, device skipped.\n", len); + goto write_file_err; + } + strcpy(fdir, base_path); + strcat(fdir, file); + + if (access(fdir, F_OK) == 0) { + FILE* fp = fopen(fdir, "w"); + if (fp != NULL) { + res = fwrite(buf, 1, buf_sz, fp); + if (res >= buf_sz) { + printf("Written %d bytes to file %s\n", res, fdir); + } else { + fprintf(stderr, "Cannot write to %s: %d.\n", fdir, res); + } + + fclose(fp); + } else { + fprintf(stderr, "Cannot open file %s.\n", fdir); + } + } else { + fprintf(stderr, "File %s does not exists.\n", fdir); + } + + free(fdir); + fdir = NULL; + +write_file_err: + return res; +} + +dev_old_iio_t* dev_old_iio_create(const char* path) { + dev_old_iio_t *iio = malloc(sizeof(dev_old_iio_t)); + if (iio == NULL) { + return NULL; + } + + iio->anglvel_x_fd = NULL; + iio->anglvel_y_fd = NULL; + iio->anglvel_z_fd = NULL; + iio->accel_x_fd = NULL; + iio->accel_y_fd = NULL; + iio->accel_z_fd = NULL; + + iio->accel_scale_x = 0.0f; + iio->accel_scale_y = 0.0f; + iio->accel_scale_z = 0.0f; + iio->anglvel_scale_x = 0.0f; + iio->anglvel_scale_y = 0.0f; + iio->anglvel_scale_z = 0.0f; + iio->temp_scale = 0.0f; + + iio->outer_temp_scale = 0.0; + + double mm[3][3] = + // this is the correct matrix: + { + {-1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0} + }; + + // store the mount matrix + memcpy(iio->mount_matrix, mm, sizeof(mm)); + + const long path_len = strlen(path) + 1; + iio->path = malloc(path_len); + if (iio->path == NULL) { + fprintf(stderr, "Cannot allocate %ld bytes for device name, device skipped.\n", path_len); + free(iio); + iio = NULL; + goto dev_old_iio_create_err; + } + strcpy(iio->path, path); + + // ============================================= DEVICE NAME ================================================ + iio->name = read_file(iio->path, "/name"); + if (iio->name == NULL) { + fprintf(stderr, "Unable to read iio device name.\n"); + free(iio); + iio = NULL; + goto dev_old_iio_create_err; + } else { + int idx = strlen(iio->name) - 1; + if ((iio->name[idx] == '\n') || ((iio->name[idx] == '\t'))) { + iio->name[idx] = '\0'; + } + } + // ========================================================================================================== + + // ========================================== in_anglvel_scale ============================================== + { + const char* preferred_scale = LSB_PER_RAD_S_2000_DEG_S_STR; + const char *scale_main_file = "/in_anglvel_scale"; + + char* const anglvel_scale = read_file(iio->path, scale_main_file); + if (anglvel_scale != NULL) { + iio->anglvel_scale_x = iio->anglvel_scale_y = iio->anglvel_scale_z = strtod(anglvel_scale, NULL); + free((void*)anglvel_scale); + + if (write_file(iio->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) { + iio->anglvel_scale_x = iio->anglvel_scale_y = iio->anglvel_scale_z = LSB_PER_RAD_S_2000_DEG_S; + printf("anglvel scale changed to %f for device %s\n", iio->anglvel_scale_x, iio->name); + } else { + fprintf(stderr, "Unable to set preferred in_anglvel_scale for device %s.\n", iio->name); + } + } else { + // TODO: what about if those are split in in_anglvel_{x,y,z}_scale? + fprintf(stderr, "Unable to read in_anglvel_scale from path %s%s.\n", iio->path, scale_main_file); + + free(iio); + iio = NULL; + goto dev_old_iio_create_err; + } + } + // ========================================================================================================== + + // =========================================== in_accel_scale =============================================== + { + const char* preferred_scale = LSB_PER_16G_STR; + const char *scale_main_file = "/in_accel_scale"; + + char* const accel_scale = read_file(iio->path, scale_main_file); + if (accel_scale != NULL) { + iio->accel_scale_x = iio->accel_scale_y = iio->accel_scale_z = strtod(accel_scale, NULL); + free((void*)accel_scale); + + if (write_file(iio->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) { + iio->accel_scale_x = iio->accel_scale_y = iio->accel_scale_z = LSB_PER_16G; + printf("accel scale changed to %f for device %s\n", iio->accel_scale_x, iio->name); + } else { + fprintf(stderr, "Unable to set preferred in_accel_scale for device %s.\n", iio->name); + } + } else { + // TODO: what about if those are plit in in_accel_{x,y,z}_scale? + fprintf(stderr, "Unable to read in_accel_scale file from path %s%s.\n", iio->path, scale_main_file); + + free(iio); + iio = NULL; + goto dev_old_iio_create_err; + } + } + // ========================================================================================================== + + // ============================================= temp_scale ================================================= + { + char* const accel_scale = read_file(iio->path, "/in_temp_scale"); + if (accel_scale != NULL) { + iio->temp_scale = strtod(accel_scale, NULL); + free((void*)accel_scale); + } else { + fprintf(stderr, "Unable to read in_accel_scale file from path %s%s.\n", iio->path, "/in_accel_scale"); + + free(iio); + iio = NULL; + goto dev_old_iio_create_err; + } + } + // ========================================================================================================== + + // ============================================ sampling_rate ================================================ + { + char* const accel_scale = read_file(iio->path, "/in_temp_scale"); + if (accel_scale != NULL) { + iio->temp_scale = strtod(accel_scale, NULL); + free((void*)accel_scale); + } else { + fprintf(stderr, "Unable to read in_accel_scale file from path %s%s.\n", iio->path, "/in_accel_scale"); + + free(iio); + iio = NULL; + goto dev_old_iio_create_err; + } + } + // ========================================================================================================== + + const size_t tmp_sz = path_len + 128 + 1; + char* const tmp = malloc(tmp_sz); + + memset(tmp, 0, tmp_sz); + strcat(tmp, iio->path); + strcat(tmp, "/in_accel_x_raw"); + iio->accel_x_fd = fopen(tmp, "r"); + + memset(tmp, 0, tmp_sz); + strcat(tmp, iio->path); + strcat(tmp, "/in_accel_y_raw"); + iio->accel_y_fd = fopen(tmp, "r"); + + memset(tmp, 0, tmp_sz); + strcat(tmp, iio->path); + strcat(tmp, "/in_accel_z_raw"); + iio->accel_z_fd = fopen(tmp, "r"); + + memset(tmp, 0, tmp_sz); + strcat(tmp, iio->path); + strcat(tmp, "/in_anglvel_x_raw"); + iio->anglvel_x_fd = fopen(tmp, "r"); + + memset(tmp, 0, tmp_sz); + strcat(tmp, iio->path); + strcat(tmp, "/in_anglvel_y_raw"); + iio->anglvel_y_fd = fopen(tmp, "r"); + + memset(tmp, 0, tmp_sz); + strcat(tmp, iio->path); + strcat(tmp, "/in_anglvel_z_raw"); + iio->anglvel_z_fd = fopen(tmp, "r"); + + free(tmp); + + printf( + "anglvel scale: x=%f, y=%f, z=%f | accel scale: x=%f, y=%f, z=%f\n", + iio->anglvel_scale_x, + iio->anglvel_scale_y, + iio->anglvel_scale_z, + iio->accel_scale_x, + iio->accel_scale_y, + iio->accel_scale_z + ); + + // give time to change the scale + sleep(4); + +dev_old_iio_create_err: + return iio; +} + +void dev_old_iio_destroy(dev_old_iio_t* iio) { + fclose(iio->accel_x_fd); + fclose(iio->accel_y_fd); + fclose(iio->accel_z_fd); + fclose(iio->anglvel_x_fd); + fclose(iio->anglvel_y_fd); + fclose(iio->anglvel_z_fd); + free(iio->name); + free(iio->path); + free(iio); +} + +const char* dev_old_iio_get_name(const dev_old_iio_t* iio) { + return iio->name; +} + +const char* dev_old_iio_get_path(const dev_old_iio_t* iio) { + return iio->path; +} + +static void multiplyMatrixVector(const double matrix[3][3], const double vector[3], double result[3]) { + result[0] = matrix[0][0] * vector[0] + matrix[1][0] * vector[1] + matrix[2][0] * vector[2]; + result[1] = matrix[0][1] * vector[0] + matrix[1][1] * vector[1] + matrix[2][1] * vector[2]; + result[2] = matrix[0][2] * vector[0] + matrix[1][2] * vector[1] + matrix[2][2] * vector[2]; +} + +int dev_old_iio_read_imu(const dev_old_iio_t *const iio, in_message_t *const messages) { + int res = 0; + + struct timespec tp; + if (clock_gettime(CLOCK_MONOTONIC, &tp) == -1) { + perror("Error getting time"); + return res; // Handle the error appropriately in your application + } + + const uint64_t nanoseconds = (tp.tv_sec * 1000000000ULL) + tp.tv_nsec; + + uint16_t accel_x_raw = 0, accel_y_raw = 0, accel_z_raw = 0; + uint16_t gyro_x_raw = 0, gyro_y_raw = 0, gyro_z_raw = 0; + + char tmp[128]; + + + if (iio->accel_x_fd != NULL) { + rewind(iio->accel_x_fd); + memset((void*)&tmp[0], 0, sizeof(tmp)); + const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->accel_x_fd); + if (tmp_read >= 0) { + accel_x_raw = strtol(&tmp[0], NULL, 10); + } else { + fprintf(stderr, "While reading accel(x): %d\n", tmp_read); + goto dev_old_iio_read_imu_err; + } + } + + if (iio->accel_y_fd != NULL) { + rewind(iio->accel_y_fd); + memset((void*)&tmp[0], 0, sizeof(tmp)); + const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->accel_y_fd); + if (tmp_read >= 0) { + accel_y_raw = strtol(&tmp[0], NULL, 10); + } else { + fprintf(stderr, "While reading accel(y): %d\n", tmp_read); + goto dev_old_iio_read_imu_err; + } + } + + if (iio->accel_z_fd != NULL) { + rewind(iio->accel_z_fd); + memset((void*)&tmp[0], 0, sizeof(tmp)); + const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->accel_z_fd); + if (tmp_read >= 0) { + accel_z_raw = strtol(&tmp[0], NULL, 10); + } else { + fprintf(stderr, "While reading accel(z): %d\n", tmp_read); + goto dev_old_iio_read_imu_err; + } + } + + if (iio->anglvel_x_fd != NULL) { + rewind(iio->anglvel_x_fd); + memset((void*)&tmp[0], 0, sizeof(tmp)); + const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->anglvel_x_fd); + if (tmp_read >= 0) { + gyro_x_raw = strtol(&tmp[0], NULL, 10); + } else { + fprintf(stderr, "While reading anglvel(x): %d\n", tmp_read); + goto dev_old_iio_read_imu_err; + } + } + + if (iio->anglvel_y_fd != NULL) { + rewind(iio->anglvel_y_fd); + memset((void*)&tmp[0], 0, sizeof(tmp)); + const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->anglvel_y_fd); + if (tmp_read >= 0) { + gyro_y_raw = strtol(&tmp[0], NULL, 10); + } else { + fprintf(stderr, "While reading anglvel(y): %d\n", tmp_read); + goto dev_old_iio_read_imu_err; + } + } + + if (iio->anglvel_z_fd != NULL) { + rewind(iio->anglvel_z_fd); + memset((void*)&tmp[0], 0, sizeof(tmp)); + const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->anglvel_z_fd); + if (tmp_read >= 0) { + gyro_z_raw = strtol(&tmp[0], NULL, 10); + } else { + fprintf(stderr, "While reading anglvel(z): %d\n", tmp_read); + goto dev_old_iio_read_imu_err; + } + } + + messages[0].type = GAMEPAD_SET_ELEMENT; + messages[0].data.gamepad_set.element = GAMEPAD_ACCELEROMETER; + messages[1].data.gamepad_set.status.accel.sample_timestamp_ns = nanoseconds; + messages[0].data.gamepad_set.status.accel.x = (uint16_t)(-1) * accel_x_raw; + messages[0].data.gamepad_set.status.accel.y = accel_y_raw; + messages[0].data.gamepad_set.status.accel.z = accel_z_raw; + + messages[1].type = GAMEPAD_SET_ELEMENT; + messages[1].data.gamepad_set.element = GAMEPAD_GYROSCOPE; + messages[1].data.gamepad_set.status.gyro.sample_timestamp_ns = nanoseconds; + messages[1].data.gamepad_set.status.gyro.x = (uint16_t)(-1) * gyro_x_raw; + messages[1].data.gamepad_set.status.gyro.y = gyro_y_raw; + messages[1].data.gamepad_set.status.gyro.z = gyro_z_raw; + + res = 2; + +dev_old_iio_read_imu_err: + return res; +} + +typedef struct bmc150_accel_user_data { + dev_old_iio_t *iio; + char* name; + uint64_t errors; +} bmc150_accel_user_data_t; + +static bmc150_accel_user_data_t bmc15_timer_data = { + .iio = NULL, + .name = NULL, + .errors = 0, +}; + +int rc71l_bmc150_accel_timer_map(const dev_in_settings_t *const conf, int timer_fd, uint64_t expirations, in_message_t *const messages, size_t messages_len, void* user_data) { + bmc150_accel_user_data_t *const timer_data = (bmc150_accel_user_data_t*)user_data; + + static const uint64_t max_attempts = 250000000; + + if (timer_data == NULL) { + return 0; + } + + if (timer_data->iio == NULL) { + if (timer_data->errors < max_attempts) { + // try to open the device and give up after some errors + timer_data->iio = dev_old_iio_create(iio_base_path); + + if (timer_data->iio == NULL) { + timer_data->errors++; + + if (timer_data->errors == max_attempts) { + fprintf(stderr, "Max attempts to acquire bmc150 accel driver reached.\n"); + } + } + } + + return 0; + } else { + // read the device and fill data from that + return dev_old_iio_read_imu(timer_data->iio, messages); + } + + return 0; +} + +input_dev_t bmc150_timer_dev = { + .dev_type = input_dev_type_timer, + .filters = { + .timer = { + .name = "RC71L_bmc150-accel_timer", + .ticktime_ms = 0, + .ticktime_ns = 625000 + } + }, + .user_data = &bmc15_timer_data, + .map = { + .timer_callbacks = { + .map_fn = rc71l_bmc150_accel_timer_map, + } + } +}; + int rc71l_timer_map(const dev_in_settings_t *const conf, int timer_fd, uint64_t expirations, in_message_t *const messages, size_t messages_len, void* user_data) { rc71l_timer_user_data_t *const timer_data = (rc71l_timer_user_data_t*)user_data; rc71l_platform_t *const platform_data = timer_data->parent; @@ -1513,41 +2026,6 @@ input_dev_t timer_dev = { } }; -typedef struct bmc150_accel_user_data { - -} bmc150_accel_user_data_t; - -static bmc150_accel_user_data_t bmc15_timer_data = { - -}; - -int rc71l_bmc150_accel_timer_map(const dev_in_settings_t *const conf, int timer_fd, uint64_t expirations, in_message_t *const messages, size_t messages_len, void* user_data) { - bmc150_accel_user_data_t *const timer_data = (bmc150_accel_user_data_t*)user_data; - - if (timer_data == NULL) { - return 0; - } - - return 0; -} - -input_dev_t bmc150_timer_dev = { - .dev_type = input_dev_type_timer, - .filters = { - .timer = { - .name = "RC71L_bmc150-accel_timer", - .ticktime_ms = 0, - .ticktime_ns = 625000 - } - }, - .user_data = &bmc15_timer_data, - .map = { - .timer_callbacks = { - .map_fn = rc71l_bmc150_accel_timer_map, - } - } -}; - input_dev_composite_t rc71l_composite = { .dev = { &in_xbox_dev, @@ -1564,9 +2042,12 @@ input_dev_composite_t rc71l_composite = { input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const conf) { if (conf->enable_imu) { - if (false) { + bmc15_timer_data.name = read_file(iio_base_path, "name"); + if ((bmc15_timer_data.name != NULL) && (strcmp(bmc15_timer_data.name, "bmi323"))) { + printf("Old bmc150-accel-i2c for bmi323 device has been selected! Are you running a neptune kernel?\n"); rc71l_composite.dev[rc71l_composite.dev_count++] = &bmc150_timer_dev; } else { + printf("Using the newer upstreamed bmi323-imu driver\n"); rc71l_composite.dev[rc71l_composite.dev_count++] = &in_iio_dev; } } From c8e81eb272c329c4ea5ce076b7caff3e1db5b9fe Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 15 Jan 2024 03:13:49 +0100 Subject: [PATCH 173/186] fix build issue --- rog_ally.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index a78aab5..9201b22 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1567,7 +1567,7 @@ read_file_err: return res; } -int write_file(const char* base_path, const char *file, const void* buf, size_t buf_sz) { +static int inline_write_file(const char* base_path, const char *file, const void* buf, size_t buf_sz) { char* fdir = NULL; int res = 0; @@ -1576,7 +1576,7 @@ int write_file(const char* base_path, const char *file, const void* buf, size_t fdir = malloc(len); if (fdir == NULL) { fprintf(stderr, "Cannot allocate %ld bytes for device path, device skipped.\n", len); - goto write_file_err; + goto inline_write_file_err; } strcpy(fdir, base_path); strcat(fdir, file); @@ -1602,11 +1602,11 @@ int write_file(const char* base_path, const char *file, const void* buf, size_t free(fdir); fdir = NULL; -write_file_err: +inline_write_file_err: return res; } -dev_old_iio_t* dev_old_iio_create(const char* path) { +static dev_old_iio_t* dev_old_iio_create(const char* path) { dev_old_iio_t *iio = malloc(sizeof(dev_old_iio_t)); if (iio == NULL) { return NULL; @@ -1675,7 +1675,7 @@ dev_old_iio_t* dev_old_iio_create(const char* path) { iio->anglvel_scale_x = iio->anglvel_scale_y = iio->anglvel_scale_z = strtod(anglvel_scale, NULL); free((void*)anglvel_scale); - if (write_file(iio->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) { + if (inline_write_file(iio->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) { iio->anglvel_scale_x = iio->anglvel_scale_y = iio->anglvel_scale_z = LSB_PER_RAD_S_2000_DEG_S; printf("anglvel scale changed to %f for device %s\n", iio->anglvel_scale_x, iio->name); } else { @@ -1702,7 +1702,7 @@ dev_old_iio_t* dev_old_iio_create(const char* path) { iio->accel_scale_x = iio->accel_scale_y = iio->accel_scale_z = strtod(accel_scale, NULL); free((void*)accel_scale); - if (write_file(iio->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) { + if (inline_write_file(iio->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) { iio->accel_scale_x = iio->accel_scale_y = iio->accel_scale_z = LSB_PER_16G; printf("accel scale changed to %f for device %s\n", iio->accel_scale_x, iio->name); } else { @@ -1803,7 +1803,7 @@ dev_old_iio_create_err: return iio; } -void dev_old_iio_destroy(dev_old_iio_t* iio) { +static void dev_old_iio_destroy(dev_old_iio_t* iio) { fclose(iio->accel_x_fd); fclose(iio->accel_y_fd); fclose(iio->accel_z_fd); From 8c8a4884663590a3eeeedff910988b0c2f9135c4 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 15 Jan 2024 03:43:35 +0100 Subject: [PATCH 174/186] Fix sleep issie: allow using IMU polling interface in bmi323-imu too --- allynone.c | 1 + config.cfg.default | 3 ++- main.c | 1 + rog_ally.c | 4 ++++ settings.c | 7 +++++++ settings.h | 1 + 6 files changed, 16 insertions(+), 1 deletion(-) diff --git a/allynone.c b/allynone.c index 304cf61..991e3a8 100644 --- a/allynone.c +++ b/allynone.c @@ -26,6 +26,7 @@ int main(int argc, char ** argv) { .default_thermal_profile = -1, .enable_leds_commands = false, .enable_imu = true, + .imu_polling_interface = true, }; load_in_config(&in_settings, configuration_file); diff --git a/config.cfg.default b/config.cfg.default index 2d8ffe9..282f30b 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -15,4 +15,5 @@ swap_y_z = true; enable_thermal_profiles_switching = true; default_thermal_profile = -1; enable_leds_commands = true; -enable_imu = true; \ No newline at end of file +enable_imu = true; +imu_polling_interface = true; \ No newline at end of file diff --git a/main.c b/main.c index 17d94a4..9446964 100644 --- a/main.c +++ b/main.c @@ -25,6 +25,7 @@ int main(int argc, char ** argv) { .default_thermal_profile = -1, .enable_leds_commands = false, .enable_imu = true, + .imu_polling_interface = true, }; load_in_config(&in_settings, configuration_file); diff --git a/rog_ally.c b/rog_ally.c index 9201b22..f33e056 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -2046,6 +2046,10 @@ input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const conf) if ((bmc15_timer_data.name != NULL) && (strcmp(bmc15_timer_data.name, "bmi323"))) { printf("Old bmc150-accel-i2c for bmi323 device has been selected! Are you running a neptune kernel?\n"); rc71l_composite.dev[rc71l_composite.dev_count++] = &bmc150_timer_dev; + } else if ((conf->imu_polling_interface)) { + if (bmc15_timer_data.name != NULL) { + printf("Forced polling on a %s, suspend/resume issues?\n", bmc15_timer_data.name); + } } else { printf("Using the newer upstreamed bmi323-imu driver\n"); rc71l_composite.dev[rc71l_composite.dev_count++] = &in_iio_dev; diff --git a/settings.c b/settings.c index 3a8da9d..77b2784 100644 --- a/settings.c +++ b/settings.c @@ -83,6 +83,13 @@ void load_in_config(dev_in_settings_t *const out_conf, const char* const filepat fprintf(stderr, "enable_imu (bool) configuration not found. Default value will be used.\n"); } + int imu_polling_interface; + if (config_lookup_bool(&cfg, "imu_polling_interface", &imu_polling_interface) != CONFIG_FALSE) { + out_conf->imu_polling_interface = imu_polling_interface; + } else { + fprintf(stderr, "imu_polling_interface (bool) configuration not found. Default value will be used.\n"); + } + config_destroy(&cfg); load_in_config_err: diff --git a/settings.h b/settings.h index 5576d54..0d66409 100644 --- a/settings.h +++ b/settings.h @@ -12,6 +12,7 @@ typedef struct dev_in_settings { int default_thermal_profile; bool enable_leds_commands; bool enable_imu; + bool imu_polling_interface; } dev_in_settings_t; void load_in_config(dev_in_settings_t *const out_conf, const char* const filepath); From 75c19eace117b1d5df5e965e21c10274413abad1 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 15 Jan 2024 19:24:41 +0100 Subject: [PATCH 175/186] Allow inverting x axis --- allynone.c | 1 + config.cfg.default | 1 + dev_out.c | 4 ++-- settings.c | 7 +++++++ settings.h | 1 + stray_ally.c | 1 + 6 files changed, 13 insertions(+), 2 deletions(-) diff --git a/allynone.c b/allynone.c index 991e3a8..c174f45 100644 --- a/allynone.c +++ b/allynone.c @@ -39,6 +39,7 @@ int main(int argc, char ** argv) { .controller_bluetooth = false, .dualsense_edge = false, .swap_y_z = false, + .invert_x = false, .gyro_to_analog_activation_treshold = 16, .gyro_to_analog_mapping = 4, }; diff --git a/config.cfg.default b/config.cfg.default index 282f30b..9a8a917 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -12,6 +12,7 @@ touchbar = true; controller_bluetooth = true; dualsense_edge = false; swap_y_z = true; +invert_x = false; enable_thermal_profiles_switching = true; default_thermal_profile = -1; enable_leds_commands = true; diff --git a/dev_out.c b/dev_out.c index c940d87..b6409b4 100644 --- a/dev_out.c +++ b/dev_out.c @@ -186,14 +186,14 @@ static void handle_incoming_message_gamepad_set( } case GAMEPAD_GYROSCOPE: { inout_gamepad->last_gyro_motion_timestamp_ns = msg_payload->status.gyro.sample_timestamp_ns; - inout_gamepad->raw_gyro[0] = msg_payload->status.gyro.x; + inout_gamepad->raw_gyro[0] = in_settings->invert_x ? (int16_t)(-1) * msg_payload->status.gyro.x : msg_payload->status.gyro.x; inout_gamepad->raw_gyro[1] = in_settings->swap_y_z ? msg_payload->status.gyro.z : msg_payload->status.gyro.y; inout_gamepad->raw_gyro[2] = in_settings->swap_y_z ? msg_payload->status.gyro.y : msg_payload->status.gyro.z; break; } case GAMEPAD_ACCELEROMETER: { inout_gamepad->last_accel_motion_timestamp_ns = msg_payload->status.accel.sample_timestamp_ns; - inout_gamepad->raw_accel[0] = msg_payload->status.accel.x; + inout_gamepad->raw_accel[0] = in_settings->invert_x ? (int16_t)(-1) * msg_payload->status.accel.x : msg_payload->status.accel.x; inout_gamepad->raw_accel[1] = in_settings->swap_y_z ? msg_payload->status.accel.z : msg_payload->status.accel.y; inout_gamepad->raw_accel[2] = in_settings->swap_y_z ? msg_payload->status.accel.y : msg_payload->status.accel.z; break; diff --git a/settings.c b/settings.c index 77b2784..8db164b 100644 --- a/settings.c +++ b/settings.c @@ -155,6 +155,13 @@ 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"); } + int invert_x; + if (config_lookup_bool(&cfg, "invert_x", &invert_x) != CONFIG_FALSE) { + out_conf->invert_x = invert_x; + } else { + fprintf(stderr, "invert_x (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; diff --git a/settings.h b/settings.h index 0d66409..867a831 100644 --- a/settings.h +++ b/settings.h @@ -25,6 +25,7 @@ typedef struct dev_out_settings { bool controller_bluetooth; bool dualsense_edge; bool swap_y_z; + bool invert_x; int gyro_to_analog_activation_treshold; int gyro_to_analog_mapping; } dev_out_settings_t; diff --git a/stray_ally.c b/stray_ally.c index a8b288d..b156adb 100644 --- a/stray_ally.c +++ b/stray_ally.c @@ -20,6 +20,7 @@ int main(int argc, char ** argv) { .controller_bluetooth = false, .dualsense_edge = false, .swap_y_z = false, + .invert_x = false, .gyro_to_analog_activation_treshold = 16, .gyro_to_analog_mapping = 4, }; From 288a1bce18c85b9a771e5377a287971e4236cce7 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 15 Jan 2024 21:16:18 +0100 Subject: [PATCH 176/186] Avoid timers cross-referencing --- rog_ally.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index f33e056..46f3592 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1166,8 +1166,11 @@ static void rc71l_timer_xbox360( uint64_t expired, void* user_data ) { - rc71l_xbox360_user_data_t *const xbox360_data = (rc71l_xbox360_user_data_t*)user_data; - + if (strcmp(timer_name, "RC71L_timer") != 0) { + return; + } + + rc71l_xbox360_user_data_t *const xbox360_data = (rc71l_xbox360_user_data_t*)user_data; if (conf->rumble_on_mode_switch) { if (xbox360_data->accounted_mode_switches != xbox360_data->mode_switched) { @@ -1336,7 +1339,10 @@ static void rc71l_hidraw_timer( uint64_t expired, void* user_data ) { - // one tick is 60ms + // one tick is 60ms, avoid all other timers + if (strcmp(timer_name, "RC71L_timer") != 0) { + return; + } rc71l_asus_hidraw_user_data_t *const hidraw_data = (rc71l_asus_hidraw_user_data_t*)user_data; if (hidraw_data == NULL) { @@ -2016,6 +2022,7 @@ input_dev_t timer_dev = { .timer = { .name = "RC71L_timer", .ticktime_ms = 60, + .ticktime_ns = 0, } }, .user_data = &timer_user_data, From 9da2278640dad32b4f865f3c7a38893bc9813435 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 13 Feb 2024 00:37:22 +0100 Subject: [PATCH 177/186] Implement more performance modes --- rog_ally.c | 71 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 46f3592..97769c4 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1324,12 +1324,47 @@ static int rc71l_hidraw_set_leds(const dev_in_settings_t *const conf, int hidraw return res; } -#define PROFILES_COUNT 3 +#define PROFILES_COUNT 4 + +static const char* epp[PROFILES_COUNT] = { + "/bin/bash -c 'shopt -s nullglob; echo \"power\" | tee /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference'", + "/bin/bash -c 'shopt -s nullglob; echo \"balance_performance\" | tee /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference'", + "/bin/bash -c 'shopt -s nullglob; echo \"balance_power\" | tee /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference'", + "/bin/bash -c 'shopt -s nullglob; echo \"performance\" | tee /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference'" +}; static const char* profiles[PROFILES_COUNT] = { "asusctl profile -P Quiet", "asusctl profile -P Balanced", "asusctl profile -P Performance", + "asusctl profile -P Performance", +}; + +static const struct { + uint8_t r; + uint8_t g; + uint8_t b; +} colors[PROFILES_COUNT] = { + { + .r = 0x00, // Blue + .g = 0x00, + .b = 0xFF, + }, + { + .r = 0x00, // Green + .g = 0xFF, + .b = 0x00, + }, + { + .r = 0xFF, // Almost-orange/yellow + .g = 0xBF, + .b = 0x00, + }, + { + .r = 0xFF, // Red + .g = 0x00, + .b = 0x00, + } }; static void rc71l_hidraw_timer( @@ -1355,18 +1390,27 @@ static void rc71l_hidraw_timer( ++hidraw_data->parent->thermal_profile_expired; uint64_t thermal_profile_index = hidraw_data->parent->next_thermal_profile % PROFILES_COUNT; - int change_thermal_result = system(profiles[thermal_profile_index]); - + const int change_thermal_result = system(profiles[thermal_profile_index]); if (change_thermal_result == 0) { - const int leds_set = rc71l_hidraw_set_leds_inner( - hidraw_fd, - thermal_profile_index == 2 ? 0xFF : 0x00, - thermal_profile_index == 1 ? 0xFF : 0x00, - thermal_profile_index == 0 ? 0xFF : 0x00 - ); + const int change_amd_pstate_epp = system(epp[thermal_profile_index]); + if (change_amd_pstate_epp == 0) { + const int leds_set = rc71l_hidraw_set_leds_inner( + hidraw_fd, + colors[thermal_profile_index].r, + colors[thermal_profile_index].g, + colors[thermal_profile_index].b + ); - if (leds_set != 0) { - fprintf(stderr, "Error setting leds to tell the user about the new profile: %d\n", leds_set); + if (leds_set != 0) { + fprintf(stderr, "Error setting leds to tell the user about the new profile: %d\n", leds_set); + } + } else { + fprintf( + stderr, + "Error setting the new AMD P-State hint with '%s': %d\n", + epp[thermal_profile_index], + change_amd_pstate_epp + ); } } else { fprintf( @@ -2056,6 +2100,7 @@ input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const conf) } else if ((conf->imu_polling_interface)) { if (bmc15_timer_data.name != NULL) { printf("Forced polling on a %s, suspend/resume issues?\n", bmc15_timer_data.name); + rc71l_composite.dev[rc71l_composite.dev_count++] = &bmc150_timer_dev; } } else { printf("Using the newer upstreamed bmi323-imu driver\n"); @@ -2071,9 +2116,9 @@ input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const conf) rc71l_composite.dev[rc71l_composite.dev_count++] = &nkey_dev; } - if ((conf->enable_thermal_profiles_switching) && (conf->default_thermal_profile >= 0) && (conf->default_thermal_profile < 3)) { + if ((conf->enable_thermal_profiles_switching) && (conf->default_thermal_profile >= 0)) { hw_platform.current_thermal_profile = 0xFFFFFFFFFFFFFFFF; - hw_platform.next_thermal_profile = conf->default_thermal_profile; + hw_platform.next_thermal_profile = conf->default_thermal_profile % PROFILES_COUNT; } return &rc71l_composite; From 98e64bb864528261e73d4dcb41a36fac7479b44e Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 13 Feb 2024 01:12:05 +0100 Subject: [PATCH 178/186] Fix sampling rate of iio and reduce reporting frequency from devices --- dev_out.c | 6 +++--- rog_ally.c | 49 +++++++++++++++++++++++++++++++++++++++++++------ rogue_enemy.h | 3 +++ 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/dev_out.c b/dev_out.c index b6409b4..4b3d003 100644 --- a/dev_out.c +++ b/dev_out.c @@ -435,9 +435,9 @@ void *dev_out_thread_func(void *ptr) { printf("Keyboard initialized: fd=%d\n", current_keyboard_fd); } - const int64_t kbd_report_timing_us = 1125; - const int64_t mouse_report_timing_us = 950; - const int64_t gamepad_report_timing_us = 1250; + const int64_t kbd_report_timing_us = 2025; + const int64_t mouse_report_timing_us = 1650; + const int64_t gamepad_report_timing_us = 2500; if (current_gamepad == GAMEPAD_DUALSENSE) { const int ds5_init_res = virt_dualsense_init( diff --git a/rog_ally.c b/rog_ally.c index 97769c4..d6afd12 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1568,7 +1568,8 @@ typedef struct dev_iio { double mount_matrix[3][3]; - double sampling_rate_hz; + double anglvel_sampling_rate_hz; + double accel_sampling_rate_hz; } dev_old_iio_t; @@ -1785,14 +1786,50 @@ static dev_old_iio_t* dev_old_iio_create(const char* path) { } // ========================================================================================================== - // ============================================ sampling_rate ================================================ + // ======================================= anglvel_sampling_rate_hz ========================================== { - char* const accel_scale = read_file(iio->path, "/in_temp_scale"); + const char* preferred_scale = PREFERRED_SAMPLING_FREQ_STR; + const char *scale_main_file = "/in_anglvel_sampling_frequency"; + + char* const accel_scale = read_file(iio->path, scale_main_file); if (accel_scale != NULL) { - iio->temp_scale = strtod(accel_scale, NULL); + iio->anglvel_sampling_rate_hz = strtod(accel_scale, NULL); free((void*)accel_scale); + + if (inline_write_file(iio->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) { + iio->anglvel_sampling_rate_hz = PREFERRED_SAMPLING_FREQ; + printf("anglvel sampling rate changed to %f for device %s\n", iio->accel_scale_x, iio->name); + } else { + fprintf(stderr, "Unable to set preferred in_anglvel_sampling_frequency for device %s.\n", iio->name); + } } else { - fprintf(stderr, "Unable to read in_accel_scale file from path %s%s.\n", iio->path, "/in_accel_scale"); + fprintf(stderr, "Unable to read in_anglvel_sampling_frequency file from path %s%s.\n", iio->path, scale_main_file); + + free(iio); + iio = NULL; + goto dev_old_iio_create_err; + } + } + // ========================================================================================================== + + // ======================================= accel_sampling_rate_hz ========================================== + { + const char* preferred_scale = PREFERRED_SAMPLING_FREQ_STR; + const char *scale_main_file = "/in_accel_sampling_frequency"; + + char* const accel_scale = read_file(iio->path, scale_main_file); + if (accel_scale != NULL) { + iio->accel_sampling_rate_hz = strtod(accel_scale, NULL); + free((void*)accel_scale); + + if (inline_write_file(iio->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) { + iio->accel_sampling_rate_hz = PREFERRED_SAMPLING_FREQ; + printf("accel sampling rate changed to %f for device %s\n", iio->accel_scale_x, iio->name); + } else { + fprintf(stderr, "Unable to set preferred in_accel_sampling_frequency for device %s.\n", iio->name); + } + } else { + fprintf(stderr, "Unable to read in_accel_sampling_frequency file from path %s%s.\n", iio->path, scale_main_file); free(iio); iio = NULL; @@ -2038,7 +2075,7 @@ input_dev_t bmc150_timer_dev = { .timer = { .name = "RC71L_bmc150-accel_timer", .ticktime_ms = 0, - .ticktime_ns = 625000 + .ticktime_ns = 1250000 } }, .user_data = &bmc15_timer_data, diff --git a/rogue_enemy.h b/rogue_enemy.h index c13675d..127574f 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -52,6 +52,9 @@ #define LSB_PER_16G ((double)0.004785) #define LSB_PER_16G_STR "0.004785" +#define PREFERRED_SAMPLING_FREQ ((double)800.000000) +#define PREFERRED_SAMPLING_FREQ_STR "800.000000" + // courtesy of linux kernel #ifndef __packed #define __packed __attribute__((packed)) From e3fa85d6c83e2514e213519b0c6f489b312e2917 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 14 Feb 2024 02:16:32 +0100 Subject: [PATCH 179/186] fix spelling of a variable --- rog_ally.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index d6afd12..910a20a 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -2031,7 +2031,7 @@ typedef struct bmc150_accel_user_data { uint64_t errors; } bmc150_accel_user_data_t; -static bmc150_accel_user_data_t bmc15_timer_data = { +static bmc150_accel_user_data_t bmc150_timer_data = { .iio = NULL, .name = NULL, .errors = 0, @@ -2078,7 +2078,7 @@ input_dev_t bmc150_timer_dev = { .ticktime_ns = 1250000 } }, - .user_data = &bmc15_timer_data, + .user_data = &bmc150_timer_data, .map = { .timer_callbacks = { .map_fn = rc71l_bmc150_accel_timer_map, @@ -2130,13 +2130,13 @@ input_dev_composite_t rc71l_composite = { input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const conf) { if (conf->enable_imu) { - bmc15_timer_data.name = read_file(iio_base_path, "name"); - if ((bmc15_timer_data.name != NULL) && (strcmp(bmc15_timer_data.name, "bmi323"))) { + bmc150_timer_data.name = read_file(iio_base_path, "name"); + if ((bmc150_timer_data.name != NULL) && (strcmp(bmc150_timer_data.name, "bmi323"))) { printf("Old bmc150-accel-i2c for bmi323 device has been selected! Are you running a neptune kernel?\n"); rc71l_composite.dev[rc71l_composite.dev_count++] = &bmc150_timer_dev; } else if ((conf->imu_polling_interface)) { - if (bmc15_timer_data.name != NULL) { - printf("Forced polling on a %s, suspend/resume issues?\n", bmc15_timer_data.name); + if (bmc150_timer_data.name != NULL) { + printf("Forced polling on a %s, suspend/resume issues?\n", bmc150_timer_data.name); rc71l_composite.dev[rc71l_composite.dev_count++] = &bmc150_timer_dev; } } else { From 5b007e36d250fa10680c853fc7604085e83329c7 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 14 Feb 2024 02:16:58 +0100 Subject: [PATCH 180/186] Change default config to comply with what will soon be upstreamed --- config.cfg.default | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.cfg.default b/config.cfg.default index 9a8a917..245f287 100644 --- a/config.cfg.default +++ b/config.cfg.default @@ -12,9 +12,9 @@ touchbar = true; controller_bluetooth = true; dualsense_edge = false; swap_y_z = true; -invert_x = false; +invert_x = true; enable_thermal_profiles_switching = true; -default_thermal_profile = -1; +default_thermal_profile = 3; enable_leds_commands = true; enable_imu = true; imu_polling_interface = true; \ No newline at end of file From 2166c6a3372747e8df66872be5115df7962263e0 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 14 Feb 2024 02:22:56 +0100 Subject: [PATCH 181/186] Use only two modes until Luke finishes upstreaming his patch --- rog_ally.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rog_ally.c b/rog_ally.c index 910a20a..6915c6a 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -188,10 +188,15 @@ static char* find_kernel_sysfs_device_path(struct udev *udev) { static int get_next_mode(int current_mode) { if (current_mode == 1) return 2; + else if (current_mode == 2) + return 1; + /* + // TODO: luke has yet to complete the mapping for mode 3, use only 1 and 2 for now if (current_mode == 2) return 3; if (current_mode == 3) return 1; + */ else fprintf(stderr, "Invalid current mode: %d -- 1 (gamepad) will be set\n", current_mode); From 3834651c0e18d613ff52d041879954b938534aa1 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 20 Feb 2024 01:56:37 +0100 Subject: [PATCH 182/186] move dmi board read --- allynone.c | 11 ++++------- rogue_enemy.c | 13 +++++++++++++ rogue_enemy.h | 4 +++- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/allynone.c b/allynone.c index c174f45..d2b0fb5 100644 --- a/allynone.c +++ b/allynone.c @@ -47,16 +47,13 @@ int main(int argc, char ** argv) { load_out_config(&out_settings, configuration_file); input_dev_composite_t* in_devs = NULL; - - int dmi_name_fd = open("/sys/class/dmi/id/board_name", O_RDONLY | O_NONBLOCK); - if (dmi_name_fd < 0) { + + char bname[256]; + if (dmi_board_name(bname, sizeof(bname)) < 0) { fprintf(stderr, "Cannot get the board name\n"); return EXIT_FAILURE; } - char bname[256]; - memset(bname, 0, sizeof(bname)); - read(dmi_name_fd, bname, sizeof(bname)); if (strstr(bname, "RC71L") != NULL) { printf("Running in an Asus ROG Ally device\n"); in_devs = rog_ally_device_def(&in_settings); @@ -64,7 +61,7 @@ int main(int argc, char ** argv) { printf("Running in an Lenovo Legion Go device\n"); in_devs = legion_go_device_def(); } - close(dmi_name_fd); + int dev_in_thread_creation = -1; int dev_out_thread_creation = -1; diff --git a/rogue_enemy.c b/rogue_enemy.c index 4be29b4..31be1db 100644 --- a/rogue_enemy.c +++ b/rogue_enemy.c @@ -28,4 +28,17 @@ int64_t absolute_value(int64_t value) { } return value; +} + +ssize_t dmi_board_name(char *const buf, size_t buf_len) { +int dmi_name_fd = open("/sys/class/dmi/id/board_name", O_RDONLY | O_NONBLOCK); + if (dmi_name_fd < 0) { + return -1; + } + + memset(buf, 0, buf_len); + const ssize_t ret = read(dmi_name_fd, buf, buf_len); + close(dmi_name_fd); + + return ret; } \ No newline at end of file diff --git a/rogue_enemy.h b/rogue_enemy.h index 127574f..4b2d85b 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -67,4 +67,6 @@ 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 absolute_value(int64_t value); \ No newline at end of file +int64_t absolute_value(int64_t value); + +ssize_t dmi_board_name(char *const buf, size_t buf_len); \ No newline at end of file From c68e06a88b094a1ff883c8aa419ec318352efb22 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 20 Feb 2024 02:02:40 +0100 Subject: [PATCH 183/186] moved inline_read_file and inline_write_file --- rog_ally.c | 99 ++++----------------------------------------------- rogue_enemy.c | 86 +++++++++++++++++++++++++++++++++++++++++++- rogue_enemy.h | 6 +++- 3 files changed, 97 insertions(+), 94 deletions(-) diff --git a/rog_ally.c b/rog_ally.c index 6915c6a..c01ca7d 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1577,91 +1577,6 @@ typedef struct dev_iio { double accel_sampling_rate_hz; } dev_old_iio_t; - -static char* read_file(const char* base_path, const char *file) { - char* res = NULL; - char* fdir = NULL; - long len = 0; - - len = strlen(base_path) + strlen(file) + 1; - fdir = malloc(len); - if (fdir == NULL) { - fprintf(stderr, "Cannot allocate %ld bytes for device path, device skipped.\n", len); - goto read_file_err; - } - strcpy(fdir, base_path); - strcat(fdir, file); - - if (access(fdir, F_OK) == 0) { - FILE* fp = fopen(fdir, "r"); - if (fp != NULL) { - fseek(fp, 0L, SEEK_END); - len = ftell(fp); - rewind(fp); - - len += 1; - res = malloc(len); - if (res != NULL) { - unsigned long read_bytes = fread(res, 1, len, fp); - printf("Read %lu bytes from file %s\n", read_bytes, fdir); - } else { - fprintf(stderr, "Cannot allocate %ld bytes for %s content.\n", len, fdir); - } - - fclose(fp); - } else { - fprintf(stderr, "Cannot open file %s.\n", fdir); - } - } else { - fprintf(stderr, "File %s does not exists.\n", fdir); - } - - free(fdir); - fdir = NULL; - -read_file_err: - return res; -} - -static int inline_write_file(const char* base_path, const char *file, const void* buf, size_t buf_sz) { - char* fdir = NULL; - - int res = 0; - - const size_t len = strlen(base_path) + strlen(file) + 1; - fdir = malloc(len); - if (fdir == NULL) { - fprintf(stderr, "Cannot allocate %ld bytes for device path, device skipped.\n", len); - goto inline_write_file_err; - } - strcpy(fdir, base_path); - strcat(fdir, file); - - if (access(fdir, F_OK) == 0) { - FILE* fp = fopen(fdir, "w"); - if (fp != NULL) { - res = fwrite(buf, 1, buf_sz, fp); - if (res >= buf_sz) { - printf("Written %d bytes to file %s\n", res, fdir); - } else { - fprintf(stderr, "Cannot write to %s: %d.\n", fdir, res); - } - - fclose(fp); - } else { - fprintf(stderr, "Cannot open file %s.\n", fdir); - } - } else { - fprintf(stderr, "File %s does not exists.\n", fdir); - } - - free(fdir); - fdir = NULL; - -inline_write_file_err: - return res; -} - static dev_old_iio_t* dev_old_iio_create(const char* path) { dev_old_iio_t *iio = malloc(sizeof(dev_old_iio_t)); if (iio == NULL) { @@ -1707,7 +1622,7 @@ static dev_old_iio_t* dev_old_iio_create(const char* path) { strcpy(iio->path, path); // ============================================= DEVICE NAME ================================================ - iio->name = read_file(iio->path, "/name"); + iio->name = inline_read_file(iio->path, "/name"); if (iio->name == NULL) { fprintf(stderr, "Unable to read iio device name.\n"); free(iio); @@ -1726,7 +1641,7 @@ static dev_old_iio_t* dev_old_iio_create(const char* path) { const char* preferred_scale = LSB_PER_RAD_S_2000_DEG_S_STR; const char *scale_main_file = "/in_anglvel_scale"; - char* const anglvel_scale = read_file(iio->path, scale_main_file); + char* const anglvel_scale = inline_read_file(iio->path, scale_main_file); if (anglvel_scale != NULL) { iio->anglvel_scale_x = iio->anglvel_scale_y = iio->anglvel_scale_z = strtod(anglvel_scale, NULL); free((void*)anglvel_scale); @@ -1753,7 +1668,7 @@ static dev_old_iio_t* dev_old_iio_create(const char* path) { const char* preferred_scale = LSB_PER_16G_STR; const char *scale_main_file = "/in_accel_scale"; - char* const accel_scale = read_file(iio->path, scale_main_file); + char* const accel_scale = inline_read_file(iio->path, scale_main_file); if (accel_scale != NULL) { iio->accel_scale_x = iio->accel_scale_y = iio->accel_scale_z = strtod(accel_scale, NULL); free((void*)accel_scale); @@ -1777,7 +1692,7 @@ static dev_old_iio_t* dev_old_iio_create(const char* path) { // ============================================= temp_scale ================================================= { - char* const accel_scale = read_file(iio->path, "/in_temp_scale"); + char* const accel_scale = inline_read_file(iio->path, "/in_temp_scale"); if (accel_scale != NULL) { iio->temp_scale = strtod(accel_scale, NULL); free((void*)accel_scale); @@ -1796,7 +1711,7 @@ static dev_old_iio_t* dev_old_iio_create(const char* path) { const char* preferred_scale = PREFERRED_SAMPLING_FREQ_STR; const char *scale_main_file = "/in_anglvel_sampling_frequency"; - char* const accel_scale = read_file(iio->path, scale_main_file); + char* const accel_scale = inline_read_file(iio->path, scale_main_file); if (accel_scale != NULL) { iio->anglvel_sampling_rate_hz = strtod(accel_scale, NULL); free((void*)accel_scale); @@ -1822,7 +1737,7 @@ static dev_old_iio_t* dev_old_iio_create(const char* path) { const char* preferred_scale = PREFERRED_SAMPLING_FREQ_STR; const char *scale_main_file = "/in_accel_sampling_frequency"; - char* const accel_scale = read_file(iio->path, scale_main_file); + char* const accel_scale = inline_read_file(iio->path, scale_main_file); if (accel_scale != NULL) { iio->accel_sampling_rate_hz = strtod(accel_scale, NULL); free((void*)accel_scale); @@ -2135,7 +2050,7 @@ input_dev_composite_t rc71l_composite = { input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const conf) { if (conf->enable_imu) { - bmc150_timer_data.name = read_file(iio_base_path, "name"); + bmc150_timer_data.name = inline_read_file(iio_base_path, "name"); if ((bmc150_timer_data.name != NULL) && (strcmp(bmc150_timer_data.name, "bmi323"))) { printf("Old bmc150-accel-i2c for bmi323 device has been selected! Are you running a neptune kernel?\n"); rc71l_composite.dev[rc71l_composite.dev_count++] = &bmc150_timer_dev; diff --git a/rogue_enemy.c b/rogue_enemy.c index 31be1db..4f7fe04 100644 --- a/rogue_enemy.c +++ b/rogue_enemy.c @@ -41,4 +41,88 @@ int dmi_name_fd = open("/sys/class/dmi/id/board_name", O_RDONLY | O_NONBLOCK); close(dmi_name_fd); return ret; -} \ No newline at end of file +} + +char* inline_read_file(const char* base_path, const char *file) { + char* res = NULL; + char* fdir = NULL; + long len = 0; + + len = strlen(base_path) + strlen(file) + 1; + fdir = malloc(len); + if (fdir == NULL) { + fprintf(stderr, "Cannot allocate %ld bytes for device path, device skipped.\n", len); + goto read_file_err; + } + strcpy(fdir, base_path); + strcat(fdir, file); + + if (access(fdir, F_OK) == 0) { + FILE* fp = fopen(fdir, "r"); + if (fp != NULL) { + fseek(fp, 0L, SEEK_END); + len = ftell(fp); + rewind(fp); + + len += 1; + res = malloc(len); + if (res != NULL) { + unsigned long read_bytes = fread(res, 1, len, fp); + printf("Read %lu bytes from file %s\n", read_bytes, fdir); + } else { + fprintf(stderr, "Cannot allocate %ld bytes for %s content.\n", len, fdir); + } + + fclose(fp); + } else { + fprintf(stderr, "Cannot open file %s.\n", fdir); + } + } else { + fprintf(stderr, "File %s does not exists.\n", fdir); + } + + free(fdir); + fdir = NULL; + +read_file_err: + return res; +} + +int inline_write_file(const char* base_path, const char *file, const void* buf, size_t buf_sz) { + char* fdir = NULL; + + int res = 0; + + const size_t len = strlen(base_path) + strlen(file) + 1; + fdir = malloc(len); + if (fdir == NULL) { + fprintf(stderr, "Cannot allocate %ld bytes for device path, device skipped.\n", len); + goto inline_write_file_err; + } + strcpy(fdir, base_path); + strcat(fdir, file); + + if (access(fdir, F_OK) == 0) { + FILE* fp = fopen(fdir, "w"); + if (fp != NULL) { + res = fwrite(buf, 1, buf_sz, fp); + if (res >= buf_sz) { + printf("Written %d bytes to file %s\n", res, fdir); + } else { + fprintf(stderr, "Cannot write to %s: %d.\n", fdir, res); + } + + fclose(fp); + } else { + fprintf(stderr, "Cannot open file %s.\n", fdir); + } + } else { + fprintf(stderr, "File %s does not exists.\n", fdir); + } + + free(fdir); + fdir = NULL; + +inline_write_file_err: + return res; +} diff --git a/rogue_enemy.h b/rogue_enemy.h index 4b2d85b..2b2e450 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -69,4 +69,8 @@ int64_t min_max_clamp(int64_t value, int64_t min, int64_t max); int64_t absolute_value(int64_t value); -ssize_t dmi_board_name(char *const buf, size_t buf_len); \ No newline at end of file +ssize_t dmi_board_name(char *const buf, size_t buf_len); + +char* inline_read_file(const char* base_path, const char *file); + +int inline_write_file(const char* base_path, const char *file, const void* buf, size_t buf_sz); \ No newline at end of file From 5947da5f2d4876f6a94421cb945b426b2ac51c11 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 20 Feb 2024 02:23:14 +0100 Subject: [PATCH 184/186] Use high frequency when available --- dev_out.c | 13 ++++++++++--- rog_ally.c | 26 ++++++++++++++++++++++++-- rogue_enemy.h | 3 +++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/dev_out.c b/dev_out.c index 4b3d003..e81afc0 100644 --- a/dev_out.c +++ b/dev_out.c @@ -435,9 +435,16 @@ void *dev_out_thread_func(void *ptr) { printf("Keyboard initialized: fd=%d\n", current_keyboard_fd); } - const int64_t kbd_report_timing_us = 2025; - const int64_t mouse_report_timing_us = 1650; - const int64_t gamepad_report_timing_us = 2500; + bool high_hz_avail = false; + const char *const avail_freq = inline_read_file("/sys/bus/iio/devices/iio:device0/", "name"); + if ((avail_freq != NULL) && (strstr(avail_freq, "1600.0") != NULL)) { + printf("High iio sampling frequency available: 1600.0 Hz"); + high_hz_avail = true; + } + + const int64_t kbd_report_timing_us = high_hz_avail ? 1125 : 2025; + const int64_t mouse_report_timing_us = high_hz_avail ? 950 : 1650; + const int64_t gamepad_report_timing_us = high_hz_avail ? 1250 : 2500; if (current_gamepad == GAMEPAD_DUALSENSE) { const int ds5_init_res = virt_dualsense_init( diff --git a/rog_ally.c b/rog_ally.c index c01ca7d..8b6fb45 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1708,7 +1708,15 @@ static dev_old_iio_t* dev_old_iio_create(const char* path) { // ======================================= anglvel_sampling_rate_hz ========================================== { + const char *const avail_freq = inline_read_file(iio->path, "/in_anglvel_sampling_frequency_available"); + const char* preferred_scale = PREFERRED_SAMPLING_FREQ_STR; + double new_freq = PREFERRED_SAMPLING_FREQ; + if ((avail_freq != NULL) && (strstr(avail_freq, "1600.0"))) { + preferred_scale = PREFERRED_SAMPLING_FREQ_HIGH_HZ_STR; + new_freq = PREFERRED_SAMPLING_FREQ_HIGH_HZ; + } + const char *scale_main_file = "/in_anglvel_sampling_frequency"; char* const accel_scale = inline_read_file(iio->path, scale_main_file); @@ -1717,7 +1725,7 @@ static dev_old_iio_t* dev_old_iio_create(const char* path) { free((void*)accel_scale); if (inline_write_file(iio->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) { - iio->anglvel_sampling_rate_hz = PREFERRED_SAMPLING_FREQ; + iio->anglvel_sampling_rate_hz = new_freq; printf("anglvel sampling rate changed to %f for device %s\n", iio->accel_scale_x, iio->name); } else { fprintf(stderr, "Unable to set preferred in_anglvel_sampling_frequency for device %s.\n", iio->name); @@ -1734,7 +1742,15 @@ static dev_old_iio_t* dev_old_iio_create(const char* path) { // ======================================= accel_sampling_rate_hz ========================================== { + const char *const avail_freq = inline_read_file(iio->path, "/in_accel_sampling_frequency_available"); + const char* preferred_scale = PREFERRED_SAMPLING_FREQ_STR; + double new_freq = PREFERRED_SAMPLING_FREQ; + if ((avail_freq != NULL) && (strstr(avail_freq, "1600.0"))) { + preferred_scale = PREFERRED_SAMPLING_FREQ_HIGH_HZ_STR; + new_freq = PREFERRED_SAMPLING_FREQ_HIGH_HZ; + } + const char *scale_main_file = "/in_accel_sampling_frequency"; char* const accel_scale = inline_read_file(iio->path, scale_main_file); @@ -1743,7 +1759,7 @@ static dev_old_iio_t* dev_old_iio_create(const char* path) { free((void*)accel_scale); if (inline_write_file(iio->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) { - iio->accel_sampling_rate_hz = PREFERRED_SAMPLING_FREQ; + iio->accel_sampling_rate_hz = new_freq; printf("accel sampling rate changed to %f for device %s\n", iio->accel_scale_x, iio->name); } else { fprintf(stderr, "Unable to set preferred in_accel_sampling_frequency for device %s.\n", iio->name); @@ -2050,6 +2066,12 @@ input_dev_composite_t rc71l_composite = { input_dev_composite_t* rog_ally_device_def(const dev_in_settings_t *const conf) { if (conf->enable_imu) { + const char *const avail_freq = inline_read_file(iio_base_path, "/in_accel_sampling_frequency_available"); + if ((avail_freq != NULL) && (strstr(avail_freq, "1600.0"))) { + printf("Using high sampling rate mode"); + bmc150_timer_dev.filters.timer.ticktime_ns = 625000; + } + bmc150_timer_data.name = inline_read_file(iio_base_path, "name"); if ((bmc150_timer_data.name != NULL) && (strcmp(bmc150_timer_data.name, "bmi323"))) { printf("Old bmc150-accel-i2c for bmi323 device has been selected! Are you running a neptune kernel?\n"); diff --git a/rogue_enemy.h b/rogue_enemy.h index 2b2e450..3643faf 100644 --- a/rogue_enemy.h +++ b/rogue_enemy.h @@ -55,6 +55,9 @@ #define PREFERRED_SAMPLING_FREQ ((double)800.000000) #define PREFERRED_SAMPLING_FREQ_STR "800.000000" +#define PREFERRED_SAMPLING_FREQ_HIGH_HZ ((double)1600.000000) +#define PREFERRED_SAMPLING_FREQ_HIGH_HZ_STR "1600.000000" + // courtesy of linux kernel #ifndef __packed #define __packed __attribute__((packed)) From f64a33613895729b70e1ac44c5872d653af30af2 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 4 Mar 2024 02:57:21 +0100 Subject: [PATCH 185/186] By default do not manage epp and leave that to asusctl --- rog_ally.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/rog_ally.c b/rog_ally.c index 8b6fb45..6bbce76 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -1329,19 +1329,27 @@ static int rc71l_hidraw_set_leds(const dev_in_settings_t *const conf, int hidraw return res; } +#if defined(MANAGE_EPP) #define PROFILES_COUNT 4 +#else +#define PROFILES_COUNT 3 +#endif +#if defined(MANAGE_EPP) static const char* epp[PROFILES_COUNT] = { "/bin/bash -c 'shopt -s nullglob; echo \"power\" | tee /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference'", "/bin/bash -c 'shopt -s nullglob; echo \"balance_performance\" | tee /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference'", "/bin/bash -c 'shopt -s nullglob; echo \"balance_power\" | tee /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference'", "/bin/bash -c 'shopt -s nullglob; echo \"performance\" | tee /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference'" }; +#endif static const char* profiles[PROFILES_COUNT] = { "asusctl profile -P Quiet", "asusctl profile -P Balanced", +#if defined(MANAGE_EPP) "asusctl profile -P Performance", +#endif "asusctl profile -P Performance", }; @@ -1360,11 +1368,13 @@ static const struct { .g = 0xFF, .b = 0x00, }, +#if defined(MANAGE_EPP) { .r = 0xFF, // Almost-orange/yellow .g = 0xBF, .b = 0x00, }, +#endif { .r = 0xFF, // Red .g = 0x00, @@ -1397,6 +1407,7 @@ static void rc71l_hidraw_timer( const int change_thermal_result = system(profiles[thermal_profile_index]); if (change_thermal_result == 0) { + #if defined(MANAGE_EPP) const int change_amd_pstate_epp = system(epp[thermal_profile_index]); if (change_amd_pstate_epp == 0) { const int leds_set = rc71l_hidraw_set_leds_inner( @@ -1417,6 +1428,18 @@ static void rc71l_hidraw_timer( change_amd_pstate_epp ); } + #else + const int leds_set = rc71l_hidraw_set_leds_inner( + hidraw_fd, + colors[thermal_profile_index].r, + colors[thermal_profile_index].g, + colors[thermal_profile_index].b + ); + + if (leds_set != 0) { + fprintf(stderr, "Error setting leds to tell the user about the new profile: %d\n", leds_set); + } + #endif } else { fprintf( stderr, From 16f1c520255924280d309db73444759002fdfb00 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 4 Mar 2024 03:12:54 +0100 Subject: [PATCH 186/186] Added support for real-time kernels --- allynone.c | 8 ++++++++ main.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- stray_ally.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 99 insertions(+), 2 deletions(-) diff --git a/allynone.c b/allynone.c index d2b0fb5..e95d6a7 100644 --- a/allynone.c +++ b/allynone.c @@ -10,9 +10,17 @@ #include "rog_ally.h" #include "legion_go.h" +#include + static const char* configuration_file = "/etc/ROGueENEMY/config.cfg"; int main(int argc, char ** argv) { + // Lock all current and future pages from preventing of being paged to swap + const int lockall_res = mlockall( MCL_CURRENT | MCL_FUTURE ); + if (lockall_res) { + fprintf(stderr, "mlockall failed: %d", lockall_res); + } + int ret = 0; // fill in configuration from file: automatic fallback to default diff --git a/main.c b/main.c index 9446964..a598955 100644 --- a/main.c +++ b/main.c @@ -10,9 +10,17 @@ #include "rog_ally.h" #include "legion_go.h" +#include + static const char* configuration_file = "/etc/ROGueENEMY/config.cfg"; int main(int argc, char ** argv) { + // Lock all current and future pages from preventing of being paged to swap + const int lockall_res = mlockall( MCL_CURRENT | MCL_FUTURE ); + if (lockall_res) { + fprintf(stderr, "mlockall failed: %d", lockall_res); + } + int ret = 0; dev_in_settings_t in_settings = { @@ -74,8 +82,45 @@ int main(int argc, char ** argv) { //memset(&dev_in_thread_data.communication.endpoint.socket.serveraddr, 0, sizeof(dev_in_thread_data.communication.endpoint.socket.serveraddr)); + // Initialize pthread attributes (default values) + struct sched_param param; + pthread_attr_t attr; + ret = pthread_attr_init(&attr); + if (ret) { + printf("init pthread attributes failed\n"); + goto main_err; + } + + // Set a specific stack size + ret = pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + 8192); + if (ret) { + printf("pthread setstacksize failed\n"); + goto main_err; + } + + // Set scheduler policy and priority of pthread + ret = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); + if (ret) { + printf("pthread setschedpolicy failed\n"); + goto main_err; + } + param.sched_priority = 80; + ret = pthread_attr_setschedparam(&attr, ¶m); + if (ret) { + printf("pthread setschedparam failed\n"); + goto main_err; + } + + // Use scheduling parameters of attr + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + if (ret) { + printf("pthread setinheritsched failed\n"); + goto main_err; + } + + pthread_t dev_in_thread; - const int dev_in_thread_creation = pthread_create(&dev_in_thread, NULL, dev_in_thread_func, (void*)(&dev_in_thread_data)); + const int dev_in_thread_creation = pthread_create(&dev_in_thread, &attr, dev_in_thread_func, (void*)(&dev_in_thread_data)); if (dev_in_thread_creation != 0) { fprintf(stderr, "Error creating dev_in thread: %d\n", dev_in_thread_creation); ret = -1; diff --git a/stray_ally.c b/stray_ally.c index b156adb..dd39718 100644 --- a/stray_ally.c +++ b/stray_ally.c @@ -7,9 +7,17 @@ #include "dev_out.h" #include "settings.h" +#include + static const char* configuration_file = "/etc/ROGueENEMY/config.cfg"; int main(int argc, char ** argv) { + // Lock all current and future pages from preventing of being paged to swap + const int lockall_res = mlockall( MCL_CURRENT | MCL_FUTURE ); + if (lockall_res) { + fprintf(stderr, "mlockall failed: %d", lockall_res); + } + int ret = 0; dev_out_settings_t out_settings = { @@ -62,8 +70,44 @@ int main(int argc, char ** argv) { load_out_config(&dev_out_thread_data.settings, configuration_file); + // Initialize pthread attributes (default values) + struct sched_param param; + pthread_attr_t attr; + ret = pthread_attr_init(&attr); + if (ret) { + printf("init pthread attributes failed\n"); + goto main_err; + } + + // Set a specific stack size + ret = pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + 8192); + if (ret) { + printf("pthread setstacksize failed\n"); + goto main_err; + } + + // Set scheduler policy and priority of pthread + ret = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); + if (ret) { + printf("pthread setschedpolicy failed\n"); + goto main_err; + } + param.sched_priority = 80; + ret = pthread_attr_setschedparam(&attr, ¶m); + if (ret) { + printf("pthread setschedparam failed\n"); + goto main_err; + } + + // Use scheduling parameters of attr + ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + if (ret) { + printf("pthread setinheritsched failed\n"); + goto main_err; + } + pthread_t dev_out_thread; - const int dev_out_thread_creation = pthread_create(&dev_out_thread, NULL, dev_out_thread_func, (void*)(&dev_out_thread_data)); + const int dev_out_thread_creation = pthread_create(&dev_out_thread, &attr, dev_out_thread_func, (void*)(&dev_out_thread_data)); if (dev_out_thread_creation != 0) { fprintf(stderr, "Error creating dev_out thread: %d\n", dev_out_thread_creation); ret = -1;