From 91a5ff9dc37615ec98d6ffbdd0165ef135662d80 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sat, 31 Jul 2021 21:49:52 +0200 Subject: [PATCH] Fix Xbox controllers in Bluetooth mode on macOS This prevents the D-pad up arrow from being registered as pressed when it isn't, and pressing any direction from activating the next arrow clockwise of it. Co-authored-by: Scott Wadden --- platform/osx/joypad_osx.cpp | 16 ++++++++++++++-- platform/osx/joypad_osx.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp index d778271350f..e67d2b0e91e 100644 --- a/platform/osx/joypad_osx.cpp +++ b/platform/osx/joypad_osx.cpp @@ -143,6 +143,8 @@ void joypad::add_hid_element(IOHIDElementRef p_element) { switch (usage) { case kHIDUsage_Sim_Rudder: case kHIDUsage_Sim_Throttle: + case kHIDUsage_Sim_Accelerator: + case kHIDUsage_Sim_Brake: if (!has_element(cookie, &axis_elements)) { list = &axis_elements; } @@ -332,6 +334,13 @@ bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) { p_joy->add_hid_elements(array); CFRelease(array); } + // Xbox controller hat values start at 1 rather than 0. + p_joy->offset_hat = vendor == 0x45e && + (product_id == 0x0b05 || + product_id == 0x02e0 || + product_id == 0x02fd || + product_id == 0x0b13); + return true; } @@ -388,13 +397,16 @@ bool joypad::check_ff_features() { return false; } -static int process_hat_value(int p_min, int p_max, int p_value) { +static int process_hat_value(int p_min, int p_max, int p_value, bool p_offset_hat) { int range = (p_max - p_min + 1); int value = p_value - p_min; int hat_value = HatMask::HAT_MASK_CENTER; if (range == 4) { value *= 2; } + if (p_offset_hat) { + value -= 1; + } switch (value) { case 0: @@ -468,7 +480,7 @@ void JoypadOSX::process_joypads() { for (int j = 0; j < joy.hat_elements.size(); j++) { rec_element &elem = joy.hat_elements.write[j]; int value = joy.get_hid_element_state(&elem); - int hat_value = process_hat_value(elem.min, elem.max, value); + int hat_value = process_hat_value(elem.min, elem.max, value, joy.offset_hat); input->joy_hat(joy.id, (HatMask)hat_value); } diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h index bf7e8949df7..c060c3d523e 100644 --- a/platform/osx/joypad_osx.h +++ b/platform/osx/joypad_osx.h @@ -64,6 +64,7 @@ struct joypad { Vector hat_elements; int id = 0; + bool offset_hat = false; io_service_t ffservice = 0; /* Interface for force feedback, 0 = no ff */ FFCONSTANTFORCE ff_constant_force;