From 173e882c7d48393cb5011028a5b60c2f3c1d0188 Mon Sep 17 00:00:00 2001 From: George Talusan Date: Mon, 13 Jan 2020 00:00:05 -0500 Subject: [PATCH] Mac: make HID hat switches work --- macosx/mac-joypad.mm | 114 ++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 61 deletions(-) diff --git a/macosx/mac-joypad.mm b/macosx/mac-joypad.mm index 35a0388e..feca209d 100755 --- a/macosx/mac-joypad.mm +++ b/macosx/mac-joypad.mm @@ -34,31 +34,6 @@ #include "mac-os.h" #include "mac-joypad.h" -#define kUp(i) (i * 4) -#define kDn(i) (i * 4 + 1) -#define kLf(i) (i * 4 + 2) -#define kRt(i) (i * 4 + 3) - -#define kPadElemTypeNone 0 -#define kPadElemTypeHat4 1 -#define kPadElemTypeHat8 2 -#define kPadElemTypeAxis 3 -#define kPadElemTypeButton 4 -#define kPadElemTypeOtherHat4 5 -#define kPadElemTypeOtherHat8 6 - -#define kPadXAxis 1 -#define kPadYAxis 0 -#define kPadHat 0 - -#define kMaskUp 0x0800 -#define kMaskDn 0x0400 -#define kMaskLf 0x0200 -#define kMaskRt 0x0100 - -typedef hu_device_t *pRecDevice; -typedef hu_element_t *pRecElement; - std::unordered_set allDevices; std::unordered_map>> defaultAxes; std::unordered_map> defaultButtons; @@ -175,7 +150,7 @@ void gamepadAction(void *inContext, IOReturn inResult, void *inSender, IOHIDValu objcInput.value =inputStruct.value; pthread_mutex_unlock(&keyLock); - if (info.min != info.max) + if (info.usage != kHIDUsage_GD_Hatswitch && info.min != info.max) { if (inputStruct.value <= info.min || inputStruct.value >= info.max) { @@ -187,16 +162,19 @@ void gamepadAction(void *inContext, IOReturn inResult, void *inSender, IOHIDValu } else { - if ([inputDelegate handleInput:objcInput fromJoypad:objcJoypad]) + if (inputStruct.value >= info.min && inputStruct.value <= info.max) { - return; + if ([inputDelegate handleInput:objcInput fromJoypad:objcJoypad]) + { + return; + } } } pthread_mutex_lock(&keyLock); struct JoypadInput oppositeInputStruct = inputStruct; - if (info.min != info.max) + if (info.usage != kHIDUsage_GD_Hatswitch && info.min != info.max) { if (inputStruct.value < info.min) { @@ -230,28 +208,45 @@ void gamepadAction(void *inContext, IOReturn inResult, void *inSender, IOHIDValu { int32 value = inputStruct.value; - inputStruct.value = 1; - if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) + for (int i = info.min; i <= info.max; i++) { - pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = (value & inputStruct.value); + inputStruct.value = i; + if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) + { + pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = false; + } } - inputStruct.value = 2; - if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) + if (value >= info.min && value <= info.max) { - pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = (value & inputStruct.value); - } - - inputStruct.value = 4; - if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) - { - pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = (value & inputStruct.value); - } - - inputStruct.value = 8; - if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) - { - pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = (value & inputStruct.value); + if (value % 2 == 0) + { + inputStruct.value = value; + if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) + { + pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = true; + } + } + else + { + for (int i = value - 1; i <= value + 1; i++) + { + int button = i; + if (i < info.min) + { + button = info.max; + } + else if (i > info.max) + { + button = info.min; + } + inputStruct.value = button; + if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) + { + pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = true; + } + } + } } } else @@ -269,7 +264,7 @@ void gamepadAction(void *inContext, IOReturn inResult, void *inSender, IOHIDValu pthread_mutex_unlock(&keyLock); } -void findControls(struct JoypadDevice &device, NSDictionary *properties, NSMutableArray *buttons, NSMutableArray *axes, int64 *hat) +void findControls(struct JoypadDevice &device, NSDictionary *properties, NSMutableArray *buttons, NSMutableArray *axes, NSMutableDictionary *hat) { if (properties == nil) { @@ -288,10 +283,7 @@ void findControls(struct JoypadDevice &device, NSDictionary *properties, NSMutab } else if (usagePage == kHIDPage_GenericDesktop && usage == kHIDUsage_GD_Hatswitch) { - if (hat != NULL) - { - *hat = [properties[@kIOHIDElementCookieKey] intValue]; - } + [hat setDictionary:properties]; } else { @@ -506,7 +498,7 @@ void AddDevice (IOHIDDeviceRef device) NSMutableArray *buttons = [NSMutableArray new]; NSMutableArray *axes = [NSMutableArray new]; - int64 hat = -1; + NSMutableDictionary *hat = [NSMutableDictionary new]; struct JoypadDevice deviceStruct; deviceStruct.vendorID = vendor.unsignedIntValue; @@ -538,7 +530,7 @@ void AddDevice (IOHIDDeviceRef device) for ( NSDictionary *child in ((__bridge NSDictionary *)properties)[@kIOHIDElementKey] ) { - findControls(deviceStruct, child, buttons, axes, &hat); + findControls(deviceStruct, child, buttons, axes, hat); } NSComparisonResult (^comparitor)(NSDictionary *a, NSDictionary *b) = ^NSComparisonResult(NSDictionary *a, NSDictionary *b) @@ -626,17 +618,17 @@ void AddDevice (IOHIDDeviceRef device) infoByCookie[cookie] = info; } - if (hat >= 0) + if ([hat count] >= 0) { struct JoypadCookie cookie; struct JoypadCookieInfo info; cookie.device = deviceStruct; - cookie.cookie = (uint32)hat; + cookie.cookie = hat[@kIOHIDElementCookieKey].unsignedIntValue; info.usage = kHIDUsage_GD_Hatswitch; - info.min = 0; - info.max = 0; + info.min = hat[@kIOHIDElementMinKey].intValue; + info.max = hat[@kIOHIDElementMaxKey].intValue; info.midpoint = 0; if (defaultHatValues.find(defaultsKey) != defaultHatValues.end()) @@ -822,7 +814,7 @@ bool SetButtonCodeForJoypadControl(uint32 vendorID, uint32 productID, uint32 ind { auto info = infoByCookie[cookieStruct]; - if ( info.min != info.max ) + if (info.usage != kHIDUsage_GD_Hatswitch && info.min != info.max) { if (value <= info.min) { @@ -1017,7 +1009,7 @@ std::string LabelForInput(uint32 vendorID, uint32 productID, uint32 cookie, int3 } } - if (value == 1) + if (value == 0) { return "D-Pad Up"; } @@ -1029,7 +1021,7 @@ std::string LabelForInput(uint32 vendorID, uint32 productID, uint32 cookie, int3 { return "D-Pad Down"; } - else if (value == 8) + else if (value == 6) { return "D-Pad Left"; }