From 35af4c4ede2b5afa3712ece77c8c97c854db584a Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 25 Jul 2021 16:47:06 -0500 Subject: [PATCH] Add half-axis support for triggers --- src/input/evdev.c | 37 ++++++++++++++++++++++++++----------- src/input/mapping.c | 21 +++++++++++++++------ src/input/mapping.h | 1 + 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/input/evdev.c b/src/input/evdev.c index 46c6ca5..93aa3ad 100644 --- a/src/input/evdev.c +++ b/src/input/evdev.c @@ -166,18 +166,28 @@ static short evdev_convert_value(struct input_event *ev, struct input_device *de return (long long)(ev->value - (ev->value>parms->avg?parms->flat*2:0) - parms->min) * (SHRT_MAX-SHRT_MIN) / (parms->max-parms->min-parms->flat*2) + SHRT_MIN; } -static char evdev_convert_value_byte(struct input_event *ev, struct input_device *dev, struct input_abs_parms *parms) { +static char evdev_convert_value_byte(struct input_event *ev, struct input_device *dev, struct input_abs_parms *parms, char halfaxis) { if (parms->max == 0 && parms->min == 0) { fprintf(stderr, "Axis not found: %d\n", ev->code); return 0; } - if (abs(ev->value-parms->min)flat) - return 0; - else if (ev->value>parms->max) - return UCHAR_MAX; - else - return (ev->value - parms->flat - parms->min) * UCHAR_MAX / (parms->diff - parms->flat); + if (halfaxis == 0) { + if (abs(ev->value-parms->min)flat) + return 0; + else if (ev->value>parms->max) + return UCHAR_MAX; + else + return (ev->value - parms->flat - parms->min) * UCHAR_MAX / (parms->diff - parms->flat); + } else { + short val = evdev_convert_value(ev, dev, parms, false); + if (halfaxis == '-' && val < 0) + return -(int)val * UCHAR_MAX / (SHRT_MAX-SHRT_MIN); + else if (halfaxis == '+' && val > 0) + return (int)val * UCHAR_MAX / (SHRT_MAX-SHRT_MIN); + else + return 0; + } } static bool evdev_handle_event(struct input_event *ev, struct input_device *dev) { @@ -437,12 +447,17 @@ static bool evdev_handle_event(struct input_event *ev, struct input_device *dev) dev->rightStickX = evdev_convert_value(ev, dev, &dev->rxParms, dev->map->reverse_rightx); else if (index == dev->map->abs_righty) dev->rightStickY = evdev_convert_value(ev, dev, &dev->ryParms, !dev->map->reverse_righty); - else if (index == dev->map->abs_lefttrigger) - dev->leftTrigger = evdev_convert_value_byte(ev, dev, &dev->zParms); - else if (index == dev->map->abs_righttrigger) - dev->rightTrigger = evdev_convert_value_byte(ev, dev, &dev->rzParms); else gamepadModified = false; + + if (index == dev->map->abs_lefttrigger) { + dev->leftTrigger = evdev_convert_value_byte(ev, dev, &dev->zParms, dev->map->halfaxis_lefttrigger); + gamepadModified = true; + } + if (index == dev->map->abs_righttrigger) { + dev->rightTrigger = evdev_convert_value_byte(ev, dev, &dev->rzParms, dev->map->halfaxis_righttrigger); + gamepadModified = true; + } } } diff --git a/src/input/mapping.c b/src/input/mapping.c index 5371002..166ba3d 100644 --- a/src/input/mapping.c +++ b/src/input/mapping.c @@ -43,11 +43,17 @@ struct mapping* mapping_parse(char* mapping) { char* option; while ((option = strtok_r(NULL, ",", &strpoint)) != NULL) { - char *key = NULL, *value = NULL; + char *key = NULL, *orig_value = NULL; int ret; - if ((ret = sscanf(option, "%m[^:]:%ms", &key, &value)) == 2) { + if ((ret = sscanf(option, "%m[^:]:%ms", &key, &orig_value)) == 2) { int int_value, direction_value; + char *value = orig_value; char flag = 0; + char half_axis = 0; + if (value[0] == '-' || value[0] == '+') { + half_axis = value[0]; + value++; + } if (strcmp("platform", key) == 0) strncpy(map->platform, value, sizeof(map->platform)); else if (sscanf(value, "b%d", &int_value) == 1) { @@ -98,10 +104,13 @@ struct mapping* mapping_parse(char* mapping) { } else if (strcmp("righty", key) == 0) { map->abs_righty = int_value; map->reverse_righty = flag == '~'; - } else if (strcmp("lefttrigger", key) == 0) + } else if (strcmp("lefttrigger", key) == 0) { map->abs_lefttrigger = int_value; - else if (strcmp("righttrigger", key) == 0) + map->halfaxis_lefttrigger = half_axis; + } else if (strcmp("righttrigger", key) == 0) { map->abs_righttrigger = int_value; + map->halfaxis_righttrigger = half_axis; + } } else if (sscanf(value, "h%d.%d", &int_value, &direction_value) == 2) { if (strcmp("dpright", key) == 0) { map->hat_dpright = int_value; @@ -124,8 +133,8 @@ struct mapping* mapping_parse(char* mapping) { if (key != NULL) free(key); - if (value != NULL) - free(value); + if (orig_value != NULL) + free(orig_value); } map->guid[32] = '\0'; map->name[256] = '\0'; diff --git a/src/input/mapping.h b/src/input/mapping.h index b450c14..7604845 100644 --- a/src/input/mapping.h +++ b/src/input/mapping.h @@ -28,6 +28,7 @@ struct mapping { bool reverse_leftx, reverse_lefty; bool reverse_rightx, reverse_righty; + bool halfaxis_lefttrigger, halfaxis_righttrigger; short abs_leftx, abs_lefty; short abs_rightx, abs_righty;