Configuration refactor

This commit is contained in:
Denis 2023-12-14 23:16:36 +01:00
parent 917ec565f8
commit a3b2eb0e41
No known key found for this signature in database
GPG key ID: DD9B63F805CF5C03
16 changed files with 226 additions and 148 deletions

View file

@ -10,32 +10,11 @@
#include "rog_ally.h" #include "rog_ally.h"
#include "legion_go.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"; static const char* configuration_file = "/etc/ROGueENEMY/config.cfg";
controller_settings_t settings;
int main(int argc, char ** argv) { int main(int argc, char ** argv) {
int ret = 0; int ret = 0;
init_config(&settings);
fill_config(&settings, configuration_file);
input_dev_composite_t* in_devs = NULL; input_dev_composite_t* in_devs = NULL;
int dmi_name_fd = open("/sys/class/dmi/id/board_name", O_RDONLY | O_NONBLOCK); 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)); read(dmi_name_fd, bname, sizeof(bname));
if (strstr(bname, "RC71L") != NULL) { if (strstr(bname, "RC71L") != NULL) {
printf("Running in an Asus ROG Ally device\n"); 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")) { } else if (strstr(bname, "LNVNB161216")) {
printf("Running in an Lenovo Legion Go device\n"); 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); close(dmi_name_fd);
@ -105,12 +84,18 @@ int main(int argc, char ** argv) {
.out_message_pipe_fd = out_message_pipes[0], .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 // populate the output device thread data
dev_out_data_t dev_out_thread_data = { dev_out_data_t dev_out_thread_data = {
.gamepad = GAMEPAD_DUALSENSE,
.flags = 0x00000000U, .flags = 0x00000000U,
.communication = { .communication = {
.type = ipc_unix_pipe, .type = ipc_unix_pipe,
@ -120,9 +105,15 @@ int main(int argc, char ** argv) {
.out_message_pipe_fd = out_message_pipes[1], .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; pthread_t dev_in_thread;
dev_in_thread_creation = pthread_create(&dev_in_thread, NULL, dev_in_thread_func, (void*)(&dev_in_thread_data)); 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) { if (dev_in_thread_creation != 0) {

View file

@ -6,6 +6,8 @@
#include "dev_evdev.h" #include "dev_evdev.h"
#include "dev_iio.h" #include "dev_iio.h"
#include <libconfig.h>
typedef enum dev_in_type { typedef enum dev_in_type {
DEV_IN_TYPE_NONE, DEV_IN_TYPE_NONE,
DEV_IN_TYPE_HIDRAW, DEV_IN_TYPE_HIDRAW,
@ -144,6 +146,7 @@ fill_message_from_evdev_err_completed:
} }
static int hidraw_open_device( static int hidraw_open_device(
const dev_in_settings_t *const in_settings,
const hidraw_filters_t *const in_filters, const hidraw_filters_t *const in_filters,
dev_in_hidraw_t *const out_dev dev_in_hidraw_t *const out_dev
) { ) {
@ -164,6 +167,7 @@ iio_open_device_err:
} }
static int iio_open_device( static int iio_open_device(
const dev_in_settings_t *const in_settings,
const iio_filters_t *const in_filters, const iio_filters_t *const in_filters,
dev_in_iio_t *const out_dev dev_in_iio_t *const out_dev
) { ) {
@ -187,6 +191,7 @@ iio_open_device_err:
} }
static int evdev_open_device( static int evdev_open_device(
const dev_in_settings_t *const in_settings,
const uinput_filters_t *const in_filters, const uinput_filters_t *const in_filters,
dev_in_ev_t *const out_dev 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.type = FF_RUMBLE;
out_dev->ff_effect.id = -1; out_dev->ff_effect.id = -1;
out_dev->ff_effect.replay.delay = 0; 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.strong_magnitude = 0x0000;
out_dev->ff_effect.u.rumble.weak_magnitude = 0x0000; out_dev->ff_effect.u.rumble.weak_magnitude = 0x0000;
const struct input_event gain = { const struct input_event gain = {
.type = EV_FF, .type = EV_FF,
.code = FF_GAIN, .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)); 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; dev_in_data_t *const dev_in_data = (dev_in_data_t*)ptr;
void* platform_data; 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) { if (platform_init_res != 0) {
fprintf(stderr, "Error setting up platform data: %d\n", platform_init_res); 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) { 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); 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) { if (open_res == 0) {
devices[i].type = DEV_IN_TYPE_EV; 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) { } 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); 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) { if (open_res == 0) {
devices[i].type = DEV_IN_TYPE_IIO; devices[i].type = DEV_IN_TYPE_IIO;
} }
} else if (d_type == input_dev_type_hidraw) { } 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); 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) { if (open_res == 0) {
devices[i].type = DEV_IN_TYPE_HIDRAW; 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); handle_rumble(devices, max_devices, &out_msg.data.rumble);
} else if (out_msg.type == OUT_MSG_TYPE_LEDS) { } else if (out_msg.type == OUT_MSG_TYPE_LEDS) {
// first inform the platform // 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) { if (platform_leds_res != 0) {
fprintf(stderr, "Error in changing platform LEDs: %d\n", platform_leds_res); fprintf(stderr, "Error in changing platform LEDs: %d\n", platform_leds_res);
} }
@ -506,9 +527,19 @@ void* dev_in_thread_func(void *ptr) {
continue; 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) { } 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) { 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); 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); iio_close_device(&devices[i].dev.iio);
@ -516,7 +547,13 @@ void* dev_in_thread_func(void *ptr) {
continue; continue;
} }
} else if (devices[i].type == DEV_IN_TYPE_HIDRAW) { } 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) { 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); 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); hidraw_close_device(&devices[i].dev.hidraw);
@ -585,11 +622,10 @@ void* dev_in_thread_func(void *ptr) {
} }
} }
// TODO: free every fd
free(devices); free(devices);
if (platform_init_res != 0) { 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; return NULL;

View file

@ -3,6 +3,7 @@
#include "ipc.h" #include "ipc.h"
#include "message.h" #include "message.h"
#include "input_dev.h" #include "input_dev.h"
#include "settings.h"
#define MAX_IN_MESSAGES 8 #define MAX_IN_MESSAGES 8
@ -19,6 +20,8 @@ typedef struct dev_in_data {
ipc_t communication; ipc_t communication;
dev_in_settings_t settings;
volatile uint32_t flags; volatile uint32_t flags;
} dev_in_data_t; } dev_in_data_t;

View file

@ -6,7 +6,10 @@
#include "virt_ds4.h" #include "virt_ds4.h"
#include "virt_ds5.h" #include "virt_ds5.h"
#include <libconfig.h>
static void handle_incoming_message_gamepad_action( static void handle_incoming_message_gamepad_action(
const dev_out_settings_t *const in_settings,
const in_message_gamepad_action_t *const msg_payload, const in_message_gamepad_action_t *const msg_payload,
gamepad_status_t *const inout_gamepad gamepad_status_t *const inout_gamepad
) { ) {
@ -18,24 +21,45 @@ static void handle_incoming_message_gamepad_action(
} }
static void handle_incoming_message_gamepad_set( 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, const in_message_gamepad_set_element_t *const msg_payload,
gamepad_status_t *const inout_gamepad gamepad_status_t *const inout_gamepad
) { ) {
switch (msg_payload->element) { switch (msg_payload->element) {
case GAMEPAD_BTN_CROSS: { 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; break;
} }
case GAMEPAD_BTN_CIRCLE: { 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; break;
} }
case GAMEPAD_BTN_SQUARE: { 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; break;
} }
case GAMEPAD_BTN_TRIANGLE: { 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; break;
} }
case GAMEPAD_BTN_OPTION: { case GAMEPAD_BTN_OPTION: {
@ -156,13 +180,22 @@ static void handle_incoming_message_gamepad_set(
} }
static void handle_incoming_message( static void handle_incoming_message(
const dev_out_settings_t *const in_settings,
const in_message_t *const msg, const in_message_t *const msg,
devices_status_t *const dev_stats devices_status_t *const dev_stats
) { ) {
if (msg->type == GAMEPAD_SET_ELEMENT) { 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) { } 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 // Initialize device
devices_status_init(&dev_out_data->dev_stats); 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 { union {
virt_dualshock_t ds4; virt_dualshock_t ds4;
@ -357,7 +403,11 @@ void *dev_out_thread_func(void *ptr) {
in_message_t incoming_message; 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)); 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)) { 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 { } 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)); 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; in_message_t incoming_message;
const size_t in_message_pipe_read_res = read(fd, (void*)&incoming_message, sizeof(in_message_t)); 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)) { 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 { } 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)); 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]); close(dev_out_data->communication.endpoint.ssocket.clients[i]);

View file

@ -3,6 +3,7 @@
#include "ipc.h" #include "ipc.h"
#include "message.h" #include "message.h"
#include "devices_status.h" #include "devices_status.h"
#include "settings.h"
#define DEV_OUT_FLAG_EXIT 0x00000001U #define DEV_OUT_FLAG_EXIT 0x00000001U
@ -16,10 +17,10 @@ typedef struct dev_out_data {
ipc_t communication; ipc_t communication;
dev_out_gamepad_device_t gamepad;
devices_status_t dev_stats; devices_status_t dev_stats;
dev_out_settings_t settings;
volatile uint32_t flags; volatile uint32_t flags;
} dev_out_data_t; } dev_out_data_t;

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "message.h" #include "message.h"
#include "settings.h"
#undef INCLUDE_INPUT_DEBUG #undef INCLUDE_INPUT_DEBUG
#undef IGNORE_INPUT_SCAN #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 * A function with this signature grapbs input_event data and sends to the pipe messages
* constructed from that data. * 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 (*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)(int hidraw_fd, 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 { typedef enum input_dev_type {
input_dev_type_uinput, input_dev_type_uinput,
@ -73,11 +74,11 @@ typedef struct input_dev {
} input_dev_t; } 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 { typedef struct input_dev_composite {

View file

@ -15,8 +15,6 @@ static input_dev_t in_xbox_dev = {
} }
}; };
static xbox360_settings_t x360_cfg;
static input_dev_t in_iio_dev = { static input_dev_t in_iio_dev = {
.dev_type = input_dev_type_iio, .dev_type = input_dev_type_iio,
.filters = { .filters = {
@ -40,7 +38,7 @@ static struct llg_hidraw_data {
uint8_t last_packet[64]; uint8_t last_packet[64];
} llg_hidraw_user_data; } 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; struct llg_hidraw_data *const llg_data = (struct llg_hidraw_data*)user_data;
int msg_count = 0; int msg_count = 0;
@ -92,7 +90,7 @@ typedef struct legion_go_platform {
int _pad; int _pad;
} legion_go_platform_t; } 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; int res = -EINVAL;
legion_go_platform_t *const llg_platform = malloc(sizeof(legion_go_platform_t)); legion_go_platform_t *const llg_platform = malloc(sizeof(legion_go_platform_t));
@ -109,12 +107,12 @@ legion_platform_init_err:
return res; 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); free(*platform_data);
*platform_data = NULL; *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; 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) { input_dev_composite_t* legion_go_device_def(void) {
x360_cfg.nintendo_layout = settings->nintendo_layout;
in_xbox_dev.user_data = (void*)&x360_cfg;
return &legion_composite; return &legion_composite;
} }

View file

@ -3,4 +3,4 @@
#include "input_dev.h" #include "input_dev.h"
#include "settings.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);

16
main.c
View file

@ -12,14 +12,9 @@
static const char* configuration_file = "/etc/ROGueENEMY/config.cfg"; static const char* configuration_file = "/etc/ROGueENEMY/config.cfg";
controller_settings_t settings;
int main(int argc, char ** argv) { int main(int argc, char ** argv) {
int ret = 0; int ret = 0;
init_config(&settings);
fill_config(&settings, configuration_file);
input_dev_composite_t* in_devs = NULL; input_dev_composite_t* in_devs = NULL;
int dmi_name_fd = open("/sys/class/dmi/id/board_name", O_RDONLY | O_NONBLOCK); 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)); read(dmi_name_fd, bname, sizeof(bname));
if (strstr(bname, "RC71L") != NULL) { if (strstr(bname, "RC71L") != NULL) {
printf("Running in an Asus ROG Ally device\n"); 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")) { } else if (strstr(bname, "LNVNB161216")) {
printf("Running in an Lenovo Legion Go device\n"); 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); 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)); //memset(&dev_in_thread_data.communication.endpoint.socket.serveraddr, 0, sizeof(dev_in_thread_data.communication.endpoint.socket.serveraddr));
pthread_t dev_in_thread; pthread_t dev_in_thread;

View file

@ -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; int written_msg = 0;
if ( // this is what happens at release of the left-screen button of the ROG Ally 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 { typedef enum rc71l_platform_mode {
rc71l_platform_mode_hidraw, rc71l_platform_mode_hidraw,
rc71l_platform_mode_linux_and_asusctl, rc71l_platform_mode_linux_and_asusctl,
@ -639,7 +643,7 @@ enum rc71l_leds_direction {
ROG_ALLY_DIRECTION_LEFT = 0x01 ROG_ALLY_DIRECTION_LEFT = 0x01
} rc71l_leds_direction_t; } 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; int res = -EINVAL;
rc71l_platform_t *const platform = malloc(sizeof(rc71l_platform_t)); rc71l_platform_t *const platform = malloc(sizeof(rc71l_platform_t));
@ -695,7 +699,7 @@ rc71l_platform_init_err:
return res; 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); rc71l_platform_t *const platform = (rc71l_platform_t *)(*platform_data);
if ((platform->platform_mode == rc71l_platform_mode_hidraw) && (platform->platform.hidraw != NULL)) { 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; *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; rc71l_platform_t *const platform = (rc71l_platform_t *)platform_data;
if (platform == NULL) { if (platform == NULL) {
return -EINVAL; return -EINVAL;
@ -780,9 +784,6 @@ input_dev_composite_t rc71l_composite = {
.leds_fn = rc71l_platform_leds, .leds_fn = rc71l_platform_leds,
}; };
input_dev_composite_t* rog_ally_device_def(const controller_settings_t *const settings) { input_dev_composite_t* rog_ally_device_def(void) {
x360_cfg.nintendo_layout = settings->nintendo_layout;
in_xbox_dev.user_data = (void*)&x360_cfg;
return &rc71l_composite; return &rc71l_composite;
} }

View file

@ -3,4 +3,4 @@
#include "input_dev.h" #include "input_dev.h"
#include "settings.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);

View file

@ -2,68 +2,66 @@
#include <libconfig.h> #include <libconfig.h>
void init_config(controller_settings_t *const conf) { void load_in_config(dev_in_settings_t *const out_conf, const char* const filepath) {
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;
config_t cfg; config_t cfg;
config_init(&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) { if (config_read_res != CONFIG_TRUE) {
fprintf(stderr, "Error in reading config file: %s\n", config_error_text(&cfg)); 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; int enable_qam;
if (config_lookup_bool(&cfg, "enable_qam", &enable_qam) != CONFIG_FALSE) { if (config_lookup_bool(&cfg, "enable_qam", &enable_qam) != CONFIG_FALSE) {
conf->enable_qam = enable_qam; out_conf->enable_qam = enable_qam;
} else { } else {
fprintf(stderr, "enable_qam (bool) configuration not found. Default value will be used.\n"); fprintf(stderr, "enable_qam (bool) configuration not found. Default value will be used.\n");
} }
int ff_gain; int ff_gain;
if (config_lookup_int(&cfg, "ff_gain", &ff_gain) != CONFIG_FALSE) { if (config_lookup_int(&cfg, "ff_gain", &ff_gain) != CONFIG_FALSE) {
if (ff_gain <= 100) { if (ff_gain <= 0xFF) {
conf->ff_gain = (ff_gain == 100) ? 0xFFFF : ((int)0xFFFF / 100) * ff_gain; out_conf->ff_gain = (ff_gain == 0) ? 0x0000 : ((uint16_t)ff_gain << (uint16_t)8) | (uint16_t)0x00FF;
} else { } 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 { } else {
fprintf(stderr, "ff_gain (int) configuration not found. Default value will be used.\n"); 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; int nintendo_layout;
if (config_lookup_bool(&cfg, "nintendo_layout", &nintendo_layout) != CONFIG_FALSE) { if (config_lookup_bool(&cfg, "nintendo_layout", &nintendo_layout) != CONFIG_FALSE) {
conf->nintendo_layout = nintendo_layout; out_conf->nintendo_layout = nintendo_layout;
} else { } else {
fprintf(stderr, "nintendo_layout (bool) configuration not found. Default value will be used.\n"); fprintf(stderr, "nintendo_layout (bool) configuration not found. Default value will be used.\n");
} }
int gamepad_output_device; int default_gamepad;
if (config_lookup_int(&cfg, "gamepad_output_device", &gamepad_output_device) != CONFIG_FALSE) { if (config_lookup_bool(&cfg, "default_gamepad", &default_gamepad) != CONFIG_FALSE) {
conf->gamepad_output_device = gamepad_output_device; out_conf->default_gamepad = default_gamepad % 3;
} else { } else {
fprintf(stderr, "gamepad_output_device (int) configuration not found. Default value will be used.\n"); fprintf(stderr, "default_gamepad (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");
} }
config_destroy(&cfg); config_destroy(&cfg);
fill_config_err: load_out_config_err:
return res; return;
} }

View file

@ -2,22 +2,16 @@
#include "rogue_enemy.h" #include "rogue_enemy.h"
typedef struct controller_settings { typedef struct dev_in_settings {
bool enable_qam;
uint16_t ff_gain; uint16_t ff_gain;
int enable_qam; } dev_in_settings_t;
int nintendo_layout;
/** void load_in_config(dev_in_settings_t *const out_conf, const char* const filepath);
* 0 is virtual evdev
* 1 is DualSense
* 2 is DualShock
* 3 is Xbox one
*/
int gamepad_output_device;
int rumble_dedicated_thread; typedef struct dev_out_settings {
} controller_settings_t; bool nintendo_layout;
uint8_t default_gamepad;
} dev_out_settings_t;
void init_config(controller_settings_t *const conf); void load_out_config(dev_out_settings_t *const out_conf, const char* const filepath);
int fill_config(controller_settings_t *const conf, const char* file);

View file

@ -7,19 +7,11 @@
#include "dev_out.h" #include "dev_out.h"
#include "settings.h" #include "settings.h"
#include "rog_ally.h"
#include "legion_go.h"
static const char* configuration_file = "/etc/ROGueENEMY/config.cfg"; static const char* configuration_file = "/etc/ROGueENEMY/config.cfg";
controller_settings_t settings;
int main(int argc, char ** argv) { int main(int argc, char ** argv) {
int ret = 0; int ret = 0;
init_config(&settings);
fill_config(&settings, configuration_file);
// Create a signal set containing only SIGTERM // Create a signal set containing only SIGTERM
sigset_t mask; sigset_t mask;
sigemptyset(&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; pthread_t dev_out_thread;

View file

@ -1,8 +1,13 @@
#include "xbox360.h" #include "xbox360.h"
#include "message.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) { int xbox360_ev_map(
const xbox360_settings_t *const settings = (xbox360_settings_t*)user_data; 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; int written_msg = 0;
for (uint32_t i = 0; i < coll->ev_count; ++i) { 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) { 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; current_message.data.gamepad_set.status.btn = coll->ev[i].value;
} else if (coll->ev[i].code == BTN_NORTH) { } 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; current_message.data.gamepad_set.status.btn = coll->ev[i].value;
} else if (coll->ev[i].code == BTN_SOUTH) { } 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; current_message.data.gamepad_set.status.btn = coll->ev[i].value;
} else if (coll->ev[i].code == BTN_WEST) { } 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; current_message.data.gamepad_set.status.btn = coll->ev[i].value;
} else if (coll->ev[i].code == BTN_SELECT) { } else if (coll->ev[i].code == BTN_SELECT) {
current_message.data.gamepad_set.element = GAMEPAD_BTN_OPTION; current_message.data.gamepad_set.element = GAMEPAD_BTN_OPTION;

View file

@ -2,8 +2,10 @@
#include "input_dev.h" #include "input_dev.h"
typedef struct xbox360_settings { int xbox360_ev_map(
bool nintendo_layout; const dev_in_settings_t *const conf,
} xbox360_settings_t; const evdev_collected_t *const coll,
in_message_t *const messages,
int xbox360_ev_map(const evdev_collected_t *const coll, in_message_t *const messages, size_t messages_len, void* user_data); size_t messages_len,
void* user_data
);