solved warning and cleaned up code
This commit is contained in:
parent
213f24c65f
commit
44326dc69c
15 changed files with 40 additions and 1206 deletions
|
|
@ -25,8 +25,6 @@ add_executable(${EXECUTABLE_NAME}
|
|||
settings.c
|
||||
virt_ds4.c
|
||||
virt_ds5.c
|
||||
virt_mouse_kbd.c
|
||||
virt_evdev.c
|
||||
devices_status.c
|
||||
rog_ally.c
|
||||
legion_go.c
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -2,7 +2,7 @@
|
|||
CFLAGS= -std=c17 -O3 -march=znver4 -D _DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112L -std=c11 -fPIE -pedantic -Wall -flto=full # -Werror
|
||||
LDFLAGS=-lpthread -levdev -ludev -lconfig -lrt -lm -flto=full
|
||||
CC=clang
|
||||
OBJECTS=main.o dev_in.o dev_out.o dev_iio.o dev_evdev.o dev_hidraw.o settings.o virt_ds4.o virt_ds5.o virt_mouse_kbd.o virt_evdev.o devices_status.o xbox360.o rog_ally.o legion_go.o rogue_enemy.o
|
||||
OBJECTS=main.o dev_in.o dev_out.o dev_iio.o dev_evdev.o dev_hidraw.o settings.o virt_ds4.o virt_ds5.o devices_status.o xbox360.o rog_ally.o legion_go.o rogue_enemy.o
|
||||
TARGET=rogue-enemy
|
||||
|
||||
all: $(TARGET)
|
||||
|
|
|
|||
|
|
@ -106,7 +106,6 @@ int dev_hidraw_open(
|
|||
closedir(d);
|
||||
}
|
||||
|
||||
dev_hidraw_open_err:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
244
dev_iio.c
244
dev_iio.c
|
|
@ -143,21 +143,12 @@ static int dev_iio_create(int fd, const char* path, dev_iio_t **const out_iio) {
|
|||
|
||||
// ========================================== 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((*out_iio)->path, scale_main_file);
|
||||
if (anglvel_scale != NULL) {
|
||||
(*out_iio)->flags |= DEV_IIO_HAS_ANGLVEL;
|
||||
(*out_iio)->anglvel_scale_x = (*out_iio)->anglvel_scale_y = (*out_iio)->anglvel_scale_z = strtod(anglvel_scale, NULL);
|
||||
free((void*)anglvel_scale);
|
||||
|
||||
if (write_file((*out_iio)->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) {
|
||||
(*out_iio)->anglvel_scale_x = (*out_iio)->anglvel_scale_y = (*out_iio)->anglvel_scale_z = LSB_PER_RAD_S_2000_DEG_S;
|
||||
printf("anglvel scale changed to %f for device %s\n", (*out_iio)->anglvel_scale_x, (*out_iio)->name);
|
||||
} else {
|
||||
fprintf(stderr, "Unable to set preferred in_anglvel_scale for device %s.\n", (*out_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", (*out_iio)->path, scale_main_file);
|
||||
|
|
@ -171,21 +162,12 @@ static int dev_iio_create(int fd, const char* path, dev_iio_t **const out_iio) {
|
|||
|
||||
// =========================================== 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((*out_iio)->path, scale_main_file);
|
||||
if (accel_scale != NULL) {
|
||||
(*out_iio)->flags |= DEV_IIO_HAS_ACCEL;
|
||||
(*out_iio)->accel_scale_x = (*out_iio)->accel_scale_y = (*out_iio)->accel_scale_z = strtod(accel_scale, NULL);
|
||||
free((void*)accel_scale);
|
||||
|
||||
if (write_file((*out_iio)->path, scale_main_file, preferred_scale, strlen(preferred_scale)) >= 0) {
|
||||
(*out_iio)->accel_scale_x = (*out_iio)->accel_scale_y = (*out_iio)->accel_scale_z = LSB_PER_16G;
|
||||
printf("accel scale changed to %f for device %s\n", (*out_iio)->accel_scale_x, (*out_iio)->name);
|
||||
} else {
|
||||
fprintf(stderr, "Unable to set preferred in_accel_scale for device %s.\n", (*out_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", (*out_iio)->path, scale_main_file);
|
||||
|
|
@ -221,45 +203,27 @@ dev_iio_create_err:
|
|||
return res;
|
||||
}
|
||||
|
||||
int dev_iio_change_anglvel_sampling_freq(const dev_iio_t *const iio, uint16_t freq_hz, uint16_t freq_hz_frac) {
|
||||
int dev_iio_change_anglvel_sampling_freq(const dev_iio_t *const iio, const char *const freq_str_hz) {
|
||||
int res = -EINVAL;
|
||||
if (!dev_iio_has_anglvel(iio)) {
|
||||
res = -ENOENT;
|
||||
goto dev_iio_change_anglvel_sampling_freq_err;
|
||||
}
|
||||
|
||||
char freq_str[16] = {};
|
||||
snprintf(freq_str, sizeof(freq_str), "%u.%u", (unsigned)freq_hz, (unsigned)freq_hz_frac);
|
||||
|
||||
const char* const preferred_samplig_freq = " 1600.000000";
|
||||
const size_t preferred_samplig_freq_len = strlen(preferred_samplig_freq);
|
||||
|
||||
if (write_file(iio->path, "/in_accel_sampling_frequency", preferred_samplig_freq, preferred_samplig_freq_len) >= 0) {
|
||||
printf("Accel sampling frequency changed to %s\n", preferred_samplig_freq);
|
||||
} else {
|
||||
fprintf(stderr, "Could not change accel sampling frequency\n");
|
||||
}
|
||||
|
||||
res = write_file(iio->path, "/in_anglvel_sampling_frequency", preferred_samplig_freq, preferred_samplig_freq_len);
|
||||
res = write_file(iio->path, "/in_anglvel_sampling_frequency", freq_str_hz, strlen(freq_str_hz));
|
||||
|
||||
dev_iio_change_anglvel_sampling_freq_err:
|
||||
return res;
|
||||
}
|
||||
|
||||
int dev_iio_change_accel_sampling_freq(const dev_iio_t *const iio, uint16_t freq_hz, uint16_t freq_hz_frac) {
|
||||
int dev_iio_change_accel_sampling_freq(const dev_iio_t *const iio, const char *const freq_str_hz) {
|
||||
int res = -EINVAL;
|
||||
if (!dev_iio_has_anglvel(iio)) {
|
||||
res = -ENOENT;
|
||||
goto dev_iio_change_accel_sampling_freq_err;
|
||||
}
|
||||
|
||||
char freq_str[16] = {};
|
||||
snprintf(freq_str, sizeof(freq_str), "%u.%u", (unsigned)freq_hz, (unsigned)freq_hz_frac);
|
||||
|
||||
const char* const preferred_samplig_freq = " 1600.000000";
|
||||
const size_t preferred_samplig_freq_len = strlen(preferred_samplig_freq);
|
||||
|
||||
res = write_file(iio->path, "/in_accel_sampling_frequency", preferred_samplig_freq, preferred_samplig_freq_len);
|
||||
res = write_file(iio->path, "/in_accel_sampling_frequency", freq_str_hz, strlen(freq_str_hz));
|
||||
|
||||
dev_iio_change_accel_sampling_freq_err:
|
||||
return res;
|
||||
|
|
@ -301,6 +265,16 @@ static bool iio_matches(
|
|||
}
|
||||
|
||||
/*
|
||||
|
||||
// Load the kernel module
|
||||
int result = syscall(__NR_finit_module, -1, "iio-trig-hrtimer", 0);
|
||||
if (result == 0) {
|
||||
printf("Kernel module '%s' loaded successfully.\n", "iio-trig-hrtimer");
|
||||
} else {
|
||||
perror("Error loading kernel module");
|
||||
}
|
||||
|
||||
|
||||
modprobe industrialio-sw-trigger
|
||||
modprobe iio-trig-sysfs
|
||||
modprobe iio-trig-hrtimer
|
||||
|
|
@ -328,7 +302,7 @@ mount -t configfs none /home/config
|
|||
mkdir /home/config
|
||||
mkdir /home/config/iio/triggers/hrtimer/rogue
|
||||
*/
|
||||
static const char *const iio_hrtrigger_name = "iio-trig-hrtimer";
|
||||
//static const char *const iio_hrtrigger_name = "iio-trig-hrtimer";
|
||||
|
||||
static const char *const iio_path = "/sys/bus/iio/devices/";
|
||||
|
||||
|
|
@ -377,197 +351,9 @@ int dev_iio_open(
|
|||
closedir(d);
|
||||
}
|
||||
|
||||
/*
|
||||
// Load the kernel module
|
||||
int result = syscall(__NR_finit_module, -1, iio_hrtrigger_name, 0);
|
||||
|
||||
if (result == 0) {
|
||||
printf("Kernel module '%s' loaded successfully.\n", iio_hrtrigger_name);
|
||||
} else {
|
||||
perror("Error loading kernel module");
|
||||
}
|
||||
*/
|
||||
|
||||
dev_iio_open_err:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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_iio_read_imu(const dev_iio_t *const iio, imu_in_message_t *const out) {
|
||||
struct timeval read_time;
|
||||
gettimeofday(&read_time, NULL);
|
||||
|
||||
out->flags = 0x00000000U;
|
||||
|
||||
char tmp[128];
|
||||
|
||||
double gyro_in[3];
|
||||
double accel_in[3];
|
||||
|
||||
double gyro_out[3];
|
||||
double accel_out[3];
|
||||
|
||||
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) {
|
||||
out->accel_x_raw = strtol(&tmp[0], NULL, 10);
|
||||
accel_in[0] = (double)out->accel_x_raw * iio->accel_scale_x;
|
||||
if ((out->flags & IMU_MESSAGE_FLAGS_ACCEL) == 0) {
|
||||
out->accel_read_time = read_time;
|
||||
out->flags |= IMU_MESSAGE_FLAGS_ACCEL;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "While reading accel(x): %d\n", tmp_read);
|
||||
return tmp_read;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
out->accel_y_raw = strtol(&tmp[0], NULL, 10);
|
||||
accel_in[1] = (double)out->accel_y_raw * iio->accel_scale_y;
|
||||
if ((out->flags & IMU_MESSAGE_FLAGS_ACCEL) == 0) {
|
||||
out->accel_read_time = read_time;
|
||||
out->flags |= IMU_MESSAGE_FLAGS_ACCEL;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "While reading accel(y): %d\n", tmp_read);
|
||||
return tmp_read;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
out->accel_z_raw = strtol(&tmp[0], NULL, 10);
|
||||
accel_in[2] = (double)out->accel_z_raw * iio->accel_scale_z;
|
||||
if ((out->flags & IMU_MESSAGE_FLAGS_ACCEL) == 0) {
|
||||
out->accel_read_time = read_time;
|
||||
out->flags |= IMU_MESSAGE_FLAGS_ACCEL;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "While reading accel(z): %d\n", tmp_read);
|
||||
return tmp_read;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
out->gyro_x_raw = strtol(&tmp[0], NULL, 10);
|
||||
gyro_in[0] = (double)out->gyro_x_raw * iio->anglvel_scale_x;
|
||||
if ((out->flags & IMU_MESSAGE_FLAGS_ANGLVEL) == 0) {
|
||||
out->gyro_read_time = read_time;
|
||||
out->flags |= IMU_MESSAGE_FLAGS_ANGLVEL;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "While reading anglvel(x): %d\n", tmp_read);
|
||||
return tmp_read;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
out->gyro_y_raw = strtol(&tmp[0], NULL, 10);
|
||||
gyro_in[1] = (double)out->gyro_y_raw *iio->anglvel_scale_y;
|
||||
if ((out->flags & IMU_MESSAGE_FLAGS_ANGLVEL) == 0) {
|
||||
out->gyro_read_time = read_time;
|
||||
out->flags |= IMU_MESSAGE_FLAGS_ANGLVEL;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "While reading anglvel(y): %d\n", tmp_read);
|
||||
return tmp_read;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
out->gyro_z_raw = strtol(&tmp[0], NULL, 10);
|
||||
gyro_in[2] = (double)out->gyro_z_raw *iio->anglvel_scale_z;
|
||||
if ((out->flags & IMU_MESSAGE_FLAGS_ANGLVEL) == 0) {
|
||||
out->gyro_read_time = read_time;
|
||||
out->flags |= IMU_MESSAGE_FLAGS_ANGLVEL;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "While reading anglvel(z): %d\n", tmp_read);
|
||||
return tmp_read;
|
||||
}
|
||||
}
|
||||
|
||||
if (iio->temp_fd != NULL) {
|
||||
rewind(iio->temp_fd);
|
||||
memset((void*)&tmp[0], 0, sizeof(tmp));
|
||||
const int tmp_read = fread((void*)&tmp[0], 1, sizeof(tmp), iio->temp_fd);
|
||||
if (tmp_read >= 0) {
|
||||
out->temp_raw = strtol(&tmp[0], NULL, 10);
|
||||
out->temp_in_k = (double)out->temp_raw *iio->temp_scale;
|
||||
} else {
|
||||
fprintf(stderr, "While reading temp: %d\n", tmp_read);
|
||||
return tmp_read;
|
||||
}
|
||||
}
|
||||
|
||||
multiplyMatrixVector(iio->mount_matrix, gyro_in, gyro_out);
|
||||
multiplyMatrixVector(iio->mount_matrix, accel_in, accel_out);
|
||||
|
||||
memcpy(out->accel_m2s, accel_out, sizeof(double[3]));
|
||||
memcpy(out->gyro_rad_s, gyro_out, sizeof(double[3]));
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
int dev_iio_has_anglvel(const dev_iio_t* iio) {
|
||||
return (iio->flags & DEV_IIO_HAS_ANGLVEL) != 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,6 @@ int dev_iio_has_anglvel(const dev_iio_t* iio);
|
|||
|
||||
int dev_iio_has_accel(const dev_iio_t* iio);
|
||||
|
||||
int dev_iio_change_anglvel_sampling_freq(const dev_iio_t *const iio, uint16_t freq_hz, uint16_t freq_hz_frac);
|
||||
int dev_iio_change_anglvel_sampling_freq(const dev_iio_t *const iio, const char *const freq_str_hz);
|
||||
|
||||
int dev_iio_change_accel_sampling_freq(const dev_iio_t *const iio, uint16_t freq_hz, uint16_t freq_hz_frac);
|
||||
int dev_iio_change_accel_sampling_freq(const dev_iio_t *const iio, const char *const freq_str_hz);
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ int64_t get_timediff_usec(const struct timeval *const past, const struct timeval
|
|||
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;
|
||||
//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);
|
||||
}
|
||||
|
|
@ -198,8 +198,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];
|
||||
|
||||
|
|
|
|||
|
|
@ -50,8 +50,7 @@ typedef struct hidraw_callbacks {
|
|||
} hidraw_callbacks_t;
|
||||
|
||||
typedef struct iio_settings {
|
||||
uint16_t sampling_freq_hz;
|
||||
uint16_t sampling_freq_hz_frac;
|
||||
const char* const sampling_freq_hz;
|
||||
int8_t post_matrix[3][3];
|
||||
} iio_settings_t;
|
||||
|
||||
|
|
|
|||
17
legion_go.c
17
legion_go.c
|
|
@ -24,6 +24,16 @@ static input_dev_t in_iio_dev = {
|
|||
.name = "gyro_3d",
|
||||
}
|
||||
},
|
||||
.map = {
|
||||
.iio_settings = {
|
||||
.sampling_freq_hz = "70.000",
|
||||
.post_matrix = {
|
||||
{1, 0, 0},
|
||||
{0, 1, 0},
|
||||
{0, 0, 1}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static struct llg_hidraw_data {
|
||||
|
|
@ -40,7 +50,7 @@ static int llg_hidraw_map(int hidraw_fd, int in_messages_pipe_fd, void* user_dat
|
|||
}
|
||||
|
||||
// here we have llg_data->last_packet filled with 64 bytes from the input device
|
||||
|
||||
/*
|
||||
const in_message_t current_message = {
|
||||
.type = GAMEPAD_SET_ELEMENT,
|
||||
.data = {
|
||||
|
|
@ -53,7 +63,6 @@ static int llg_hidraw_map(int hidraw_fd, int in_messages_pipe_fd, void* user_dat
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
// this does send messages to the output device
|
||||
|
||||
const ssize_t in_message_pipe_write_res = write(in_messages_pipe_fd, (void*)¤t_message, sizeof(in_message_t));
|
||||
|
|
@ -116,9 +125,9 @@ input_dev_composite_t legion_composite = {
|
|||
.dev = {
|
||||
&in_hidraw_dev,
|
||||
&in_xbox_dev,
|
||||
// &in_iio_dev,
|
||||
&in_iio_dev,
|
||||
},
|
||||
.dev_count = 2,
|
||||
.dev_count = 3,
|
||||
.init_fn = legion_platform_init,
|
||||
.leds_fn = legion_platform_leds,
|
||||
.deinit_fn = legion_platform_deinit,
|
||||
|
|
|
|||
199
logic.c
199
logic.c
|
|
@ -1,199 +0,0 @@
|
|||
#include "virt_ds4.h"
|
||||
#include "virt_ds5.h"
|
||||
#include "virt_evdev.h"
|
||||
#include "virt_mouse_kbd.h"
|
||||
|
||||
static const char* configuration_file = "/etc/ROGueENEMY/config.cfg";
|
||||
|
||||
int logic_create(logic_t *const logic) {
|
||||
int ret = 0;
|
||||
|
||||
logic->flags = 0x00000000U;
|
||||
|
||||
init_config(&logic->controller_settings);
|
||||
const int fill_config_res = fill_config(&logic->controller_settings, configuration_file);
|
||||
if (fill_config_res != 0) {
|
||||
fprintf(stderr, "Unable to fill configuration from file %s -- defaults will be used\n", configuration_file);
|
||||
}
|
||||
|
||||
devices_status_init(&logic->dev_stats);
|
||||
|
||||
ret = pthread_mutex_init(&logic->dev_stats.mutex, NULL);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Unable to create mutex: %d\n", ret);
|
||||
goto logic_create_err;
|
||||
}
|
||||
|
||||
bool lizard_thread_started = false;
|
||||
const int init_platform_res = init_platform(&logic->platform);
|
||||
if (init_platform_res == 0) {
|
||||
printf("RC71L platform correctly initialized\n");
|
||||
|
||||
logic->flags |= LOGIC_FLAGS_PLATFORM_ENABLE;
|
||||
|
||||
if (is_mouse_mode(&logic->platform)) {
|
||||
printf("Device is in lizard mode\n");
|
||||
// TODO: start the appropriate output thread
|
||||
|
||||
lizard_thread_started = true;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Unable to initialize Asus RC71L MCU: %d\n", init_platform_res);
|
||||
}
|
||||
|
||||
if (!lizard_thread_started) {
|
||||
logic_start_output_dev_thread(logic);
|
||||
}
|
||||
|
||||
logic_create_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int is_rc71l_ready(const logic_t *const logic) {
|
||||
return logic->flags & LOGIC_FLAGS_PLATFORM_ENABLE;
|
||||
}
|
||||
|
||||
void logic_terminate_output_thread(logic_t *const logic) {
|
||||
if (logic->virt_dev_thread_running) {
|
||||
void* thread_return = NULL;
|
||||
pthread_join(logic->virt_dev_thread, &thread_return);
|
||||
}
|
||||
}
|
||||
|
||||
int logic_start_output_mouse_kbd_thread(logic_t *const logic) {
|
||||
logic->dev_stats.kbd.connected = true;
|
||||
|
||||
const int ret = pthread_create(&logic->virt_dev_thread, NULL, virt_mouse_kbd_thread_func, (void*)(&logic->dev_stats));
|
||||
|
||||
logic->virt_dev_thread_running = ret == 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int logic_start_output_dev_thread(logic_t *const logic) {
|
||||
logic->dev_stats.gamepad.connected = true;
|
||||
|
||||
int ret = -EINVAL;
|
||||
switch (logic->controller_settings.gamepad_output_device) {
|
||||
|
||||
case 0:
|
||||
ret = pthread_create(&logic->virt_dev_thread, NULL, virt_evdev_thread_func, (void*)(&logic->dev_stats));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ret = pthread_create(&logic->virt_dev_thread, NULL, virt_ds5_thread_func, (void*)(&logic->dev_stats));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
ret = pthread_create(&logic->virt_dev_thread, NULL, virt_ds4_thread_func, (void*)(&logic->dev_stats));
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Invalid output device specified\n");
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
logic->virt_dev_thread_running = ret == 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
int logic_copy_gamepad_status(logic_t *const logic, gamepad_status_t *const out) {
|
||||
int res = 0;
|
||||
|
||||
res = pthread_mutex_lock(&logic->gamepad_mutex);
|
||||
if (res != 0) {
|
||||
goto logic_copy_gamepad_status_err;
|
||||
}
|
||||
|
||||
static struct timeval press_time;
|
||||
if (logic->gamepad.flags & GAMEPAD_STATUS_FLAGS_PRESS_AND_REALEASE_CENTER) {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
// Calculate elapsed time in milliseconds
|
||||
int64_t elapsed_time = (now.tv_sec - press_time.tv_sec) * 1000 +
|
||||
(now.tv_usec - press_time.tv_usec) / 1000;
|
||||
|
||||
if (logic->gamepad.center) {
|
||||
// If the center button is pressed and at least X ms have passed
|
||||
if (elapsed_time >= PRESS_AND_RELEASE_DURATION_FOR_CENTER_BUTTON_MS) {
|
||||
logic->gamepad.center = 0;
|
||||
logic->gamepad.flags &= ~GAMEPAD_STATUS_FLAGS_PRESS_AND_REALEASE_CENTER;
|
||||
}
|
||||
} else {
|
||||
// If the center button is pressed
|
||||
logic->gamepad.center = 1;
|
||||
gettimeofday(&press_time, NULL);
|
||||
}
|
||||
} else if (logic->gamepad.flags & GAMEPAD_STATUS_FLAGS_OPEN_STEAM_QAM) {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
static int releasing = 0;
|
||||
|
||||
// Calculate elapsed time in milliseconds
|
||||
int64_t elapsed_time = (now.tv_sec - press_time.tv_sec) * 1000 +
|
||||
(now.tv_usec - press_time.tv_usec) / 1000;
|
||||
|
||||
if ((logic->gamepad.center) && (!logic->gamepad.cross)) {
|
||||
if ((!releasing) && (elapsed_time >= PRESS_TIME_BEFORE_CROSS_BUTTON_MS)) {
|
||||
logic->gamepad.center = 1;
|
||||
logic->gamepad.cross = 1;
|
||||
press_time = now;
|
||||
} else if ((releasing) && (elapsed_time >= PRESS_TIME_AFTER_CROSS_BUTTON_MS)) {
|
||||
logic->gamepad.center = 0;
|
||||
logic->gamepad.cross = 0;
|
||||
press_time = now;
|
||||
logic->gamepad.flags &= ~GAMEPAD_STATUS_FLAGS_OPEN_STEAM_QAM;
|
||||
}
|
||||
} else if ((logic->gamepad.center) && (logic->gamepad.cross)) {
|
||||
if (elapsed_time >= PRESS_TIME_CROSS_BUTTON_MS) {
|
||||
logic->gamepad.center = 1;
|
||||
logic->gamepad.cross = 0;
|
||||
releasing = 1;
|
||||
press_time = now;
|
||||
}
|
||||
} else {
|
||||
logic->gamepad.center = 1;
|
||||
logic->gamepad.cross = 0;
|
||||
releasing = 0;
|
||||
gettimeofday(&press_time, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
*out = logic->gamepad;
|
||||
|
||||
pthread_mutex_unlock(&logic->gamepad_mutex);
|
||||
|
||||
logic_copy_gamepad_status_err:
|
||||
return res;
|
||||
}
|
||||
|
||||
int logic_begin_status_update(logic_t *const logic) {
|
||||
int res = 0;
|
||||
|
||||
res = pthread_mutex_lock(&logic->gamepad_mutex);
|
||||
if (res != 0) {
|
||||
goto logic_begin_status_update_err;
|
||||
}
|
||||
|
||||
logic_begin_status_update_err:
|
||||
return res;
|
||||
}
|
||||
|
||||
void logic_end_status_update(logic_t *const logic) {
|
||||
pthread_mutex_unlock(&logic->gamepad_mutex);
|
||||
}
|
||||
*/
|
||||
|
||||
void logic_request_termination(logic_t *const logic) {
|
||||
logic->flags |= LOGIC_FLAGS_TERMINATION_REQUESTED;
|
||||
}
|
||||
|
||||
int logic_termination_requested(logic_t *const logic) {
|
||||
return (logic->flags & LOGIC_FLAGS_TERMINATION_REQUESTED) != 0;
|
||||
}
|
||||
|
|
@ -539,8 +539,7 @@ static input_dev_t in_iio_dev = {
|
|||
},
|
||||
.map = {
|
||||
.iio_settings = {
|
||||
.sampling_freq_hz = 1600,
|
||||
.sampling_freq_hz_frac = 000,
|
||||
.sampling_freq_hz = "1600.000",
|
||||
.post_matrix =
|
||||
/*
|
||||
// this is the testing but "wrong" mount matrix
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
static const char* path = "/dev/uhid";
|
||||
|
||||
static const char* const MAC_ADDR_STR = "e8:47:3a:d6:e7:74";
|
||||
//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[] = {
|
||||
|
|
@ -93,6 +93,8 @@ static int create(int fd)
|
|||
ev.u.create.product = 0x0df2;
|
||||
ev.u.create.version = 0;
|
||||
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));
|
||||
|
||||
return uhid_write(fd, &ev);
|
||||
}
|
||||
|
|
|
|||
571
virt_evdev.c
571
virt_evdev.c
|
|
@ -1,571 +0,0 @@
|
|||
#include "virt_evdev.h"
|
||||
#include "devices_status.h"
|
||||
|
||||
static const char* uinput_path = "/dev/uinput";
|
||||
|
||||
static int create_gamepad_uinput(void) {
|
||||
int fd = open(uinput_path, O_WRONLY | O_NONBLOCK);
|
||||
if(fd < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_gamepad_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_setup dev = {0};
|
||||
strncpy(dev.name, OUTPUT_DEV_NAME, UINPUT_MAX_NAME_SIZE-1);
|
||||
|
||||
#if defined(OUTPUT_DEV_BUS_TYPE)
|
||||
dev.id.bustype = OUTPUT_DEV_BUS_TYPE;
|
||||
#else
|
||||
dev.id.bustype = BUS_VIRTUAL;
|
||||
#endif
|
||||
dev.id.vendor = OUTPUT_DEV_VENDOR_ID;
|
||||
dev.id.product = OUTPUT_DEV_PRODUCT_ID;
|
||||
|
||||
#if defined(OUTPUT_DEV_VERSION)
|
||||
dev.id.version = OUTPUT_DEV_VERSION;
|
||||
#endif
|
||||
|
||||
//if (ioctl(fd, /*UI_SET_PHYS_STR*/ 18, PHYS_STR) != 0) {
|
||||
// fprintf(stderr, "Controller and gyroscope will NOT be recognized as a single device!\n");
|
||||
//}
|
||||
|
||||
if (ioctl(fd, UI_SET_PHYS, PHYS_STR) != 0) {
|
||||
fprintf(stderr, "Error setting the phys of the virtual controller.\n");
|
||||
}
|
||||
|
||||
#if !defined(UI_SET_PHYS_STR)
|
||||
#warning Will not change the PHYS
|
||||
#endif
|
||||
|
||||
#if !defined(UI_SET_UNIQ_STR)
|
||||
#warning Will not change the UNIQ
|
||||
#endif
|
||||
|
||||
#if defined(UI_SET_PHYS_STR)
|
||||
ioctl(fd, UI_SET_PHYS_STR(18), PHYS_STR);
|
||||
#else
|
||||
fprintf(stderr, "UI_SET_PHYS_STR unavailable.\n");
|
||||
#endif
|
||||
|
||||
#if defined(UI_SET_UNIQ_STR)
|
||||
ioctl(fd, UI_SET_UNIQ_STR(18), PHYS_STR);
|
||||
#else
|
||||
fprintf(stderr, "UI_SET_UNIQ_STR unavailable.\n");
|
||||
#endif
|
||||
|
||||
//ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_BUTTONPAD);
|
||||
ioctl(fd, UI_SET_EVBIT, EV_ABS);
|
||||
ioctl(fd, UI_SET_EVBIT, EV_KEY);
|
||||
ioctl(fd, UI_SET_EVBIT, EV_SYN);
|
||||
#if defined(INCLUDE_TIMESTAMP)
|
||||
ioctl(fd, UI_SET_EVBIT, EV_MSC);
|
||||
ioctl(fd, UI_SET_MSCBIT, MSC_TIMESTAMP);
|
||||
#endif
|
||||
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_X);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_Y);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_Z);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_RX);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_RY);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_RZ);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_HAT0X);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_HAT0Y);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_HAT2X);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_HAT2Y);
|
||||
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_SOUTH);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_EAST);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_NORTH);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_WEST);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_TL);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_TR);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_TL2);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_TR2);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_SELECT);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_START);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_MODE);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_THUMBL);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_THUMBR);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_GEAR_DOWN);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_GEAR_UP);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_DPAD_UP);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_DPAD_DOWN);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_DPAD_LEFT);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_DPAD_RIGHT);
|
||||
|
||||
const struct uinput_abs_setup devAbsX = {
|
||||
.code = ABS_X,
|
||||
.absinfo = {
|
||||
.value = 0,
|
||||
.minimum = -32768,
|
||||
.maximum = +32768,
|
||||
.resolution = 1,
|
||||
.fuzz = 16,
|
||||
.flat = 128,
|
||||
}
|
||||
};
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsX) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_gamepad_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsY = {
|
||||
.code = ABS_Y,
|
||||
.absinfo = {
|
||||
.value = 0,
|
||||
.minimum = -32768,
|
||||
.maximum = +32768,
|
||||
.resolution = 1,
|
||||
.fuzz = 16,
|
||||
.flat = 128,
|
||||
}
|
||||
};
|
||||
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsY) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_gamepad_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsZ = {
|
||||
.code = ABS_Z,
|
||||
.absinfo = {
|
||||
.value = 0,
|
||||
.minimum = 0,
|
||||
.maximum = 255,
|
||||
.resolution = 1,
|
||||
//.fuzz = 16,
|
||||
//.flat = 128,
|
||||
}
|
||||
};
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsZ) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_gamepad_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsRX = {
|
||||
.code = ABS_RX,
|
||||
.absinfo = {
|
||||
.value = 0,
|
||||
.minimum = -32768,
|
||||
.maximum = +32768,
|
||||
.resolution = 1,
|
||||
.fuzz = 16,
|
||||
.flat = 128,
|
||||
}
|
||||
};
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsRX) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_gamepad_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsRY = {
|
||||
.code = ABS_RY,
|
||||
.absinfo = {
|
||||
.value = -1,
|
||||
.minimum = -32768,
|
||||
.maximum = +32768,
|
||||
.resolution = 1,
|
||||
.fuzz = 16,
|
||||
.flat = 128,
|
||||
}
|
||||
};
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsRY) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_gamepad_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsRZ = {
|
||||
.code = ABS_RZ,
|
||||
.absinfo = {
|
||||
.value = 0,
|
||||
.minimum = 0,
|
||||
.maximum = 255,
|
||||
.resolution = 1,
|
||||
//.fuzz = 16,
|
||||
//.flat = 128,
|
||||
}
|
||||
};
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsRZ) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_gamepad_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsHat0X = {
|
||||
.code = ABS_HAT0X,
|
||||
.absinfo = {
|
||||
.value = 0,
|
||||
.minimum = -1,
|
||||
.maximum = 1,
|
||||
.resolution = 1,
|
||||
//.fuzz = 16,
|
||||
//.flat = 128,
|
||||
}
|
||||
};
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsHat0X) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_gamepad_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsHat0Y = {
|
||||
.code = ABS_HAT0Y,
|
||||
.absinfo = {
|
||||
.value = 0,
|
||||
.minimum = -1,
|
||||
.maximum = 1,
|
||||
.resolution = 1,
|
||||
//.fuzz = 16,
|
||||
//.flat = 128,
|
||||
}
|
||||
};
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsHat0Y) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_gamepad_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsHat2X = {
|
||||
.code = ABS_HAT2X,
|
||||
.absinfo = {
|
||||
.value = 0,
|
||||
.minimum = 0,
|
||||
.maximum = 255,
|
||||
.resolution = 51,
|
||||
//.fuzz = 16,
|
||||
//.flat = 128,
|
||||
}
|
||||
};
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsHat2X) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_gamepad_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsHat2Y = {
|
||||
.code = ABS_HAT2Y,
|
||||
.absinfo = {
|
||||
.value = 0,
|
||||
.minimum = 0,
|
||||
.maximum = 255,
|
||||
.resolution = 51,
|
||||
//.fuzz = 16,
|
||||
//.flat = 128,
|
||||
}
|
||||
};
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsHat2Y) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_gamepad_uinput_err;
|
||||
}
|
||||
|
||||
if(ioctl(fd, UI_DEV_SETUP, &dev) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_gamepad_uinput_err;
|
||||
}
|
||||
|
||||
if(ioctl(fd, UI_DEV_CREATE) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_gamepad_uinput_err;
|
||||
}
|
||||
|
||||
create_gamepad_uinput_err:
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int create_imu_uinput() {
|
||||
int fd = open(uinput_path, O_WRONLY | O_NONBLOCK);
|
||||
if(fd < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_imu_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_setup dev = {0};
|
||||
strncpy(dev.name, OUTPUT_DEV_NAME, UINPUT_MAX_NAME_SIZE-1);
|
||||
|
||||
#if defined(OUTPUT_DEV_BUS_TYPE)
|
||||
dev.id.bustype = OUTPUT_DEV_BUS_TYPE;
|
||||
#else
|
||||
dev.id.bustype = BUS_VIRTUAL;
|
||||
#endif
|
||||
dev.id.vendor = OUTPUT_DEV_VENDOR_ID;
|
||||
dev.id.product = OUTPUT_DEV_PRODUCT_ID;
|
||||
|
||||
#if defined(OUTPUT_DEV_VERSION)
|
||||
dev.id.version = OUTPUT_DEV_VERSION;
|
||||
#endif
|
||||
|
||||
//if (ioctl(fd, /*UI_SET_PHYS_STR*/ 18, PHYS_STR) != 0) {
|
||||
// fprintf(stderr, "Controller and gyroscope will NOT be recognized as a single device!\n");
|
||||
//}
|
||||
|
||||
if (ioctl(fd, UI_SET_PHYS, PHYS_STR) != 0) {
|
||||
fprintf(stderr, "Error setting the phys of the virtual controller.\n");
|
||||
}
|
||||
|
||||
#if !defined(UI_SET_PHYS_STR)
|
||||
#warning Will not change the PHYS
|
||||
#endif
|
||||
|
||||
#if !defined(UI_SET_UNIQ_STR)
|
||||
#warning Will not change the UNIQ
|
||||
#endif
|
||||
|
||||
#if defined(UI_SET_PHYS_STR)
|
||||
ioctl(fd, UI_SET_PHYS_STR(18), PHYS_STR);
|
||||
#else
|
||||
fprintf(stderr, "UI_SET_PHYS_STR unavailable.\n");
|
||||
#endif
|
||||
|
||||
#if defined(UI_SET_UNIQ_STR)
|
||||
ioctl(fd, UI_SET_UNIQ_STR(18), PHYS_STR);
|
||||
#else
|
||||
fprintf(stderr, "UI_SET_UNIQ_STR unavailable.\n");
|
||||
#endif
|
||||
|
||||
ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_ACCELEROMETER);
|
||||
ioctl(fd, UI_SET_EVBIT, EV_ABS);
|
||||
#if defined(INCLUDE_TIMESTAMP)
|
||||
ioctl(fd, UI_SET_EVBIT, EV_MSC);
|
||||
ioctl(fd, UI_SET_MSCBIT, MSC_TIMESTAMP);
|
||||
#endif
|
||||
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_X);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_Y);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_Z);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_RX);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_RY);
|
||||
ioctl(fd, UI_SET_ABSBIT, ABS_RZ);
|
||||
|
||||
//ioctl(fd, UI_SET_KEYBIT, BTN_TRIGGER);
|
||||
//ioctl(fd, UI_SET_KEYBIT, BTN_THUMB);
|
||||
|
||||
struct uinput_abs_setup devAbsX = {0};
|
||||
devAbsX.code = ABS_X;
|
||||
devAbsX.absinfo.minimum = -ACCEL_RANGE;
|
||||
devAbsX.absinfo.maximum = ACCEL_RANGE;
|
||||
devAbsX.absinfo.resolution = 255; // 255 units = 1g
|
||||
devAbsX.absinfo.fuzz = 5;
|
||||
devAbsX.absinfo.flat = 0;
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsX) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_imu_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsY = {0};
|
||||
devAbsY.code = ABS_Y;
|
||||
devAbsY.absinfo.minimum = -ACCEL_RANGE;
|
||||
devAbsY.absinfo.maximum = ACCEL_RANGE;
|
||||
devAbsY.absinfo.resolution = 255; // 255 units = 1g
|
||||
devAbsY.absinfo.fuzz = 5;
|
||||
devAbsY.absinfo.flat = 0;
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsY) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_imu_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsZ = {0};
|
||||
devAbsZ.code = ABS_Z;
|
||||
devAbsZ.absinfo.minimum = -ACCEL_RANGE;
|
||||
devAbsZ.absinfo.maximum = ACCEL_RANGE;
|
||||
devAbsZ.absinfo.resolution = 255; // 255 units = 1g
|
||||
devAbsZ.absinfo.fuzz = 5;
|
||||
devAbsZ.absinfo.flat = 0;
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsZ) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_imu_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsRX = {0};
|
||||
devAbsRX.code = ABS_RX;
|
||||
devAbsRX.absinfo.minimum = -GYRO_RANGE;
|
||||
devAbsRX.absinfo.maximum = GYRO_RANGE;
|
||||
devAbsRX.absinfo.resolution = 1; // 1 unit = 1 degree/s
|
||||
devAbsRX.absinfo.fuzz = 0;
|
||||
devAbsRX.absinfo.flat = GYRO_DEADZONE;
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsRX) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_imu_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsRY = {0};
|
||||
devAbsRY.code = ABS_RY;
|
||||
devAbsRY.absinfo.minimum = -GYRO_RANGE;
|
||||
devAbsRY.absinfo.maximum = GYRO_RANGE;
|
||||
devAbsRY.absinfo.resolution = 1; // 1 unit = 1 degree/s
|
||||
devAbsRY.absinfo.fuzz = 0;
|
||||
devAbsRY.absinfo.flat = GYRO_DEADZONE;
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsRY) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_imu_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_abs_setup devAbsRZ = {0};
|
||||
devAbsRZ.code = ABS_RZ;
|
||||
devAbsRZ.absinfo.minimum = -GYRO_RANGE;
|
||||
devAbsRZ.absinfo.maximum = GYRO_RANGE;
|
||||
devAbsRZ.absinfo.resolution = 1; // 1 unit = 1 degree/s
|
||||
devAbsRZ.absinfo.fuzz = 0;
|
||||
devAbsRZ.absinfo.flat = GYRO_DEADZONE;
|
||||
if(ioctl(fd, UI_ABS_SETUP, &devAbsRZ) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_imu_uinput_err;
|
||||
}
|
||||
|
||||
if(ioctl(fd, UI_DEV_SETUP, &dev) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_imu_uinput_err;
|
||||
}
|
||||
|
||||
if(ioctl(fd, UI_DEV_CREATE) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_imu_uinput_err;
|
||||
}
|
||||
|
||||
create_imu_uinput_err:
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
void *virt_evdev_thread_func(void *ptr) {
|
||||
devices_status_t *const stats = (devices_status_t*)ptr;
|
||||
|
||||
const int gamepad_fd = create_gamepad_uinput();
|
||||
if (gamepad_fd < 0) {
|
||||
fprintf(stderr, "Unable to create the virtual evdev gamepad device: %d\n", gamepad_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int imu_fd = create_imu_uinput();
|
||||
if (imu_fd < 0) {
|
||||
fprintf(stderr, "Unable to create the virtual evdev imu device: %d\n", gamepad_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
usleep(1250);
|
||||
|
||||
const int lock_res = pthread_mutex_lock(&stats->mutex);
|
||||
if (lock_res != 0) {
|
||||
printf("Unable to lock gamepad mutex: %d\n", lock_res);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// main virtual device logic
|
||||
{
|
||||
//event(fd, &stats->gamepad);
|
||||
|
||||
if (stats->gamepad.connected) {
|
||||
// TODO: do whatever it takes...
|
||||
} else {
|
||||
pthread_mutex_unlock(&stats->mutex);
|
||||
|
||||
printf("kbd&mouse has been terminated: closing the device.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&stats->mutex);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
static void emit_ev(output_dev_t *const out_dev, const in_message_t *const msg) {
|
||||
// if events are flagged as do not emit... Do NOT emit!
|
||||
if (msg->flags & INPUT_FILTER_FLAGS_DO_NOT_EMIT) {
|
||||
return;
|
||||
}
|
||||
|
||||
int fd = out_dev->gamepad_fd;
|
||||
const uint32_t msg_flags = msg->data.event.ev_flags;
|
||||
if ((msg_flags & EV_MESSAGE_FLAGS_IMU) != 0) {
|
||||
fd = out_dev->imu_fd;
|
||||
} else if ((msg_flags & EV_MESSAGE_FLAGS_MOUSE) != 0) {
|
||||
fd = out_dev->mouse_fd;
|
||||
} else {
|
||||
fd = out_dev->gamepad_fd;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < msg->data.event.ev_count; ++i) {
|
||||
struct input_event ev = {
|
||||
.code = msg->data.event.ev[i].code,
|
||||
.type = msg->data.event.ev[i].type,
|
||||
.value = msg->data.event.ev[i].value,
|
||||
.time = msg->data.event.ev[i].time,
|
||||
};
|
||||
|
||||
if ((msg_flags & EV_MESSAGE_FLAGS_PRESERVE_TIME) == 0) {
|
||||
gettimeofday(&ev.time, NULL);
|
||||
}
|
||||
|
||||
#if defined(INCLUDE_OUTPUT_DEBUG)
|
||||
printf(
|
||||
"Output: Received event %s (%s): %d\n",
|
||||
libevdev_event_type_get_name(ev.type),
|
||||
libevdev_event_code_get_name(ev.type, ev.code),
|
||||
ev.value
|
||||
);
|
||||
#endif
|
||||
|
||||
const ssize_t written = write(fd, (void*)&ev, sizeof(ev));
|
||||
if (written != sizeof(ev)) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Error writing event %s %s %d: written %ld bytes out of %ld\n",
|
||||
libevdev_event_type_get_name(ev.type),
|
||||
libevdev_event_code_get_name(ev.type, ev.code),
|
||||
ev.value,
|
||||
written,
|
||||
sizeof(ev)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(INCLUDE_TIMESTAMP)
|
||||
gettimeofday(&now, NULL);
|
||||
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
|
||||
|
||||
struct timeval now = {0};
|
||||
gettimeofday(&now, NULL);
|
||||
const struct input_event syn_ev = {
|
||||
.code = SYN_REPORT,
|
||||
.type = EV_SYN,
|
||||
.value = 0,
|
||||
.time = now,
|
||||
};
|
||||
const ssize_t sync_written = write(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));
|
||||
}
|
||||
}
|
||||
*/
|
||||
47
virt_evdev.h
47
virt_evdev.h
|
|
@ -1,47 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "rogue_enemy.h"
|
||||
|
||||
#undef VIRT_EVDEV_DEBUG
|
||||
|
||||
|
||||
// Emulates a "Generic" controller:
|
||||
#define OUTPUT_DEV_NAME "ROGueENEMY"
|
||||
#define OUTPUT_DEV_VENDOR_ID 0x108c
|
||||
#define OUTPUT_DEV_PRODUCT_ID 0x0323
|
||||
#define OUTPUT_DEV_VERSION 0x0111
|
||||
|
||||
/*
|
||||
// Emulates a steam controller
|
||||
#define OUTPUT_DEV_NAME "Steam Controller"
|
||||
#define OUTPUT_DEV_VENDOR_ID 0x28de
|
||||
#define OUTPUT_DEV_PRODUCT_ID 0x1102
|
||||
#define OUTPUT_DEV_VERSION 0x0111
|
||||
#define OUTPUT_DEV_BUS_TYPE BUS_USB
|
||||
*/
|
||||
|
||||
/*
|
||||
//Emulates an Xbox one wireless controller:
|
||||
#define OUTPUT_DEV_NAME "Xbox Wireless Controller"
|
||||
#define OUTPUT_DEV_VENDOR_ID 0x045e
|
||||
#define OUTPUT_DEV_PRODUCT_ID 0x028e
|
||||
#define OUTPUT_DEV_BUS_TYPE BUS_BLUETOOTH
|
||||
*/
|
||||
|
||||
/*
|
||||
// Emulates a DualShock controller
|
||||
#define OUTPUT_DEV_NAME "Sony Interactive Entertainment DualSense Wireless Controller"
|
||||
#define OUTPUT_DEV_VENDOR_ID 0x054c
|
||||
#define OUTPUT_DEV_PRODUCT_ID 0x0ce6
|
||||
#define OUTPUT_DEV_VERSION 0x8111
|
||||
#define OUTPUT_DEV_BUS_TYPE BUS_USB
|
||||
*/
|
||||
|
||||
#define PHYS_STR "00:11:22:33:44:55"
|
||||
|
||||
#define ACCEL_RANGE 512
|
||||
#define GYRO_RANGE 2000 // max range is +/- 35 radian/s
|
||||
|
||||
#define GYRO_DEADZONE 1 // degrees/s to count as zero movement
|
||||
|
||||
void *virt_evdev_thread_func(void *ptr);
|
||||
126
virt_mouse_kbd.c
126
virt_mouse_kbd.c
|
|
@ -1,126 +0,0 @@
|
|||
#include "virt_mouse_kbd.h"
|
||||
#include "devices_status.h"
|
||||
|
||||
static const char* uinput_path = "/dev/uinput";
|
||||
|
||||
static int create_mouse_uinput(void) {
|
||||
int fd = open(uinput_path, O_WRONLY | O_NONBLOCK);
|
||||
if(fd < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_mouse_uinput_err;
|
||||
}
|
||||
|
||||
struct uinput_setup dev = {0};
|
||||
strncpy(dev.name, OUTPUT_DEV_NAME, UINPUT_MAX_NAME_SIZE-1);
|
||||
|
||||
#if defined(OUTPUT_DEV_BUS_TYPE)
|
||||
dev.id.bustype = OUTPUT_DEV_BUS_TYPE;
|
||||
#else
|
||||
dev.id.bustype = BUS_VIRTUAL;
|
||||
#endif
|
||||
dev.id.vendor = OUTPUT_DEV_VENDOR_ID;
|
||||
dev.id.product = OUTPUT_DEV_PRODUCT_ID;
|
||||
|
||||
#if defined(OUTPUT_DEV_VERSION)
|
||||
dev.id.version = OUTPUT_DEV_VERSION;
|
||||
#endif
|
||||
|
||||
//if (ioctl(fd, /*UI_SET_PHYS_STR*/ 18, PHYS_STR) != 0) {
|
||||
// fprintf(stderr, "Controller and gyroscope will NOT be recognized as a single device!\n");
|
||||
//}
|
||||
|
||||
if (ioctl(fd, UI_SET_PHYS, PHYS_STR) != 0) {
|
||||
fprintf(stderr, "Error setting the phys of the virtual controller.\n");
|
||||
}
|
||||
|
||||
#if !defined(UI_SET_PHYS_STR)
|
||||
#warning Will not change the PHYS
|
||||
#endif
|
||||
|
||||
#if !defined(UI_SET_UNIQ_STR)
|
||||
#warning Will not change the UNIQ
|
||||
#endif
|
||||
|
||||
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);
|
||||
#if defined(INCLUDE_TIMESTAMP)
|
||||
ioctl(fd, UI_SET_MSCBIT, MSC_TIMESTAMP);
|
||||
#endif
|
||||
|
||||
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_KEYBIT, BTN_SIDE);
|
||||
//ioctl(fd, UI_SET_KEYBIT, BTN_EXTRA);
|
||||
|
||||
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);
|
||||
|
||||
if(ioctl(fd, UI_DEV_SETUP, &dev) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_mouse_uinput_err;
|
||||
}
|
||||
|
||||
if(ioctl(fd, UI_DEV_CREATE) < 0) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
goto create_mouse_uinput_err;
|
||||
}
|
||||
|
||||
create_mouse_uinput_err:
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int create_kb_uinput(void) {
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
void *virt_mouse_kbd_thread_func(void *ptr) {
|
||||
devices_status_t *const stats = (devices_status_t*)ptr;
|
||||
|
||||
const int mouse_fd = create_mouse_uinput();
|
||||
if (mouse_fd < 0) {
|
||||
fprintf(stderr, "Unable to create the mouse virtual evdev: %d\n", mouse_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
keyboard_status_t prev_kbd_stats;
|
||||
kbd_status_init(&prev_kbd_stats);
|
||||
|
||||
for (;;) {
|
||||
usleep(1250);
|
||||
|
||||
const int lock_res = pthread_mutex_lock(&stats->mutex);
|
||||
if (lock_res != 0) {
|
||||
printf("Unable to lock gamepad mutex: %d\n", lock_res);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// main virtual device logic
|
||||
{
|
||||
//event(fd, &stats->gamepad);
|
||||
|
||||
if (stats->kbd.connected) {
|
||||
// TODO: do whatever it takes...
|
||||
} else {
|
||||
pthread_mutex_unlock(&stats->mutex);
|
||||
|
||||
printf("kbd&mouse has been terminated: closing the device.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&stats->mutex);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "rogue_enemy.h"
|
||||
|
||||
#undef VIRT_EVDEV_DEBUG
|
||||
|
||||
// Emulates a "Generic" controller:
|
||||
#define OUTPUT_DEV_NAME "ROGueENEMY"
|
||||
#define OUTPUT_DEV_VENDOR_ID 0x108c
|
||||
#define OUTPUT_DEV_PRODUCT_ID 0x0323
|
||||
#define OUTPUT_DEV_VERSION 0x0111
|
||||
|
||||
#define PHYS_STR "00:11:22:33:44:55"
|
||||
|
||||
void *virt_mouse_kbd_thread_func(void *ptr);
|
||||
Loading…
Add table
Add a link
Reference in a new issue