From 2c9fda17985ae7032da49b12af782815fd7fc775 Mon Sep 17 00:00:00 2001 From: greso Date: Tue, 7 Aug 2018 19:45:49 +0200 Subject: [PATCH] (macOS) Fix input issues For my Xbox One Controller the min input for the hat is 1 and not 0. 0 points to the default state that is called after each button press. On top of that the two axis for the trigger buttons were ignored. I added some additional axis that are not present on my controller but will probably help for other input devices. --- input/drivers_hid/iohidmanager_hid.c | 113 ++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 11 deletions(-) diff --git a/input/drivers_hid/iohidmanager_hid.c b/input/drivers_hid/iohidmanager_hid.c index c43ddf1358..77e9c6defd 100644 --- a/input/drivers_hid/iohidmanager_hid.c +++ b/input/drivers_hid/iohidmanager_hid.c @@ -43,7 +43,7 @@ typedef struct apple_hid IOHIDManagerRef ptr; joypad_connection_t *slots; uint32_t buttons[MAX_USERS]; - int16_t axes[MAX_USERS][6]; + int16_t axes[MAX_USERS][11]; int8_t hats[MAX_USERS][2]; /* MacOS only supports 1 hat AFAICT */ } iohidmanager_hid_t; @@ -201,7 +201,7 @@ static int16_t iohidmanager_hid_joypad_axis(void *data, if (joyaxis == AXIS_NONE) return 0; - if (AXIS_NEG_GET(joyaxis) < 6) + if (AXIS_NEG_GET(joyaxis) < 11) { val += hid->axes[port][AXIS_NEG_GET(joyaxis)]; val += pad_connection_get_axis(&hid->slots[port], @@ -210,7 +210,7 @@ static int16_t iohidmanager_hid_joypad_axis(void *data, if (val >= 0) val = 0; } - else if (AXIS_POS_GET(joyaxis) < 6) + else if (AXIS_POS_GET(joyaxis) < 11) { val += hid->axes[port][AXIS_POS_GET(joyaxis)]; val += pad_connection_get_axis(&hid->slots[port], @@ -290,12 +290,16 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result, if (tmp->cookie == (IOHIDElementCookie)cookie) { - CFIndex range = IOHIDElementGetLogicalMax(element) - IOHIDElementGetLogicalMin(element); + CFIndex min = IOHIDElementGetLogicalMin(element); + CFIndex range = IOHIDElementGetLogicalMax(element) - min; CFIndex val = IOHIDValueGetIntegerValue(value); if (range == 3) val *= 2; + if(min == 1) + val--; + switch(val) { case 0: @@ -383,6 +387,39 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result, break; } break; + case kHIDPage_Simulation: + switch (type) + { + case kIOHIDElementTypeInput_Misc: + switch (use) + { + default: + tmp = adapter->axes; + + while (tmp && tmp->cookie != (IOHIDElementCookie)cookie) + { + tmp = tmp->next; + } + if (tmp) + { + if (tmp->cookie == (IOHIDElementCookie)cookie) + { + CFIndex min = IOHIDElementGetPhysicalMin(element); + CFIndex state = IOHIDValueGetIntegerValue(value) - min; + CFIndex max = IOHIDElementGetPhysicalMax(element) - min; + float val = (float)state / (float)max; + + hid->axes[adapter->slot][tmp->id] = + ((val * 2.0f) - 1.0f) * 32767.0f; + } + } + else + pushed_button = 1; + break; + } + break; + } + break; } if (pushed_button) @@ -530,6 +567,21 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag /* get device unique id */ uint32_t deviceUniqueId = iohidmanager_hid_device_get_unique_id(device); + + static const uint32_t axis_use_ids[11] = + { + kHIDUsage_GD_X, + kHIDUsage_GD_Y, + kHIDUsage_GD_Rx, + kHIDUsage_GD_Ry, + kHIDUsage_GD_Z, + kHIDUsage_GD_Rz, + kHIDUsage_Sim_Rudder, + kHIDUsage_Sim_Throttle, + kHIDUsage_Sim_Steering, + kHIDUsage_Sim_Accelerator, + kHIDUsage_Sim_Brake + }; /* check if pad was already registered previously (by deterministic method) * if so do not re-add the pad */ @@ -548,8 +600,8 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag int count; CFMutableArrayRef elements; CFRange range; - bool found_axis[6] = - { false, false, false, false, false, false }; + bool found_axis[11] = + { false, false, false, false, false, false, false, false, false, false, false }; apple_input_rec_t *tmp = NULL; apple_input_rec_t *tmpButtons = NULL; apple_input_rec_t *tmpAxes = NULL; @@ -655,13 +707,11 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag default: { uint32_t i = 0; - static const uint32_t axis_use_ids[6] = - { 48, 49, 51, 52, 50, 53 }; - while (i < 6 && axis_use_ids[i] != use) + while (i < 11 && axis_use_ids[i] != use) i++; - if (i < 6) + if (i < 11) { apple_input_rec_t *axis = (apple_input_rec_t *)malloc(sizeof(apple_input_rec_t)); @@ -711,6 +761,47 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag break; } break; + + case kHIDPage_Simulation: + switch (use) + { + default: + { + uint32_t i = 0; + + while (i < 11 && axis_use_ids[i] != use) + i++; + + if (i < 11) + { + apple_input_rec_t *axis = (apple_input_rec_t *)malloc(sizeof(apple_input_rec_t)); + axis->id = i; + axis->cookie = (IOHIDElementCookie)cookie; + axis->next = NULL; + + if (iohidmanager_check_for_id(adapter->axes,i)) + { + /* axis ID already exists, save to tmp for appending later */ + if (tmpAxes) + iohidmanager_append_record(tmpAxes, axis); + else + tmpAxes = axis; + } + else + { + found_axis[axis->id] = true; + if (adapter->axes) + iohidmanager_append_record(adapter->axes, axis); + else + adapter->axes = axis; + } + } + else + detected_button = 1; + } + break; + } + break; } if (detected_button) @@ -738,7 +829,7 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag } /* take care of buttons/axes with duplicate 'use' values */ - for (i = 0; i < 6; i++) + for (i = 0; i < 11; i++) { if (found_axis[i] == false && tmpAxes) {