Rumble on mode switch

This commit is contained in:
Denis 2023-12-18 23:12:59 +01:00
parent 4623413b5a
commit 89f32b5eb1
No known key found for this signature in database
GPG key ID: DD9B63F805CF5C03
5 changed files with 131 additions and 14 deletions

View file

@ -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
);
}
}
}

View file

@ -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 {

View file

@ -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,
}
}
};

View file

@ -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) {

View file

@ -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;