From ab872f2f3629dab54e0a417462399ce5e554f7a7 Mon Sep 17 00:00:00 2001 From: Ken Thomases Date: Sun, 13 Apr 2014 18:34:16 -0500 Subject: [PATCH] dinput: Overhaul how the array of Mac device elements is built and sorted. Use three separate arrays instead of one array with three sections that are separately tracked. Use the Core Foundation sort function rather than implementing a clumsy sort of our own. --- dlls/dinput/joystick_osx.c | 88 ++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 49 deletions(-) diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c index 1d7e9705462..a98c1eae139 100644 --- a/dlls/dinput/joystick_osx.c +++ b/dlls/dinput/joystick_osx.c @@ -108,7 +108,7 @@ struct JoystickImpl /* osx private */ int id; - CFMutableArrayRef elements; + CFArrayRef elements; ObjProps **propmap; FFDeviceObjectReference ff; struct list effects; @@ -434,35 +434,23 @@ static int get_osx_device_name(int id, char *name, int length) return 0; } -static void insert_sort_button(int header, IOHIDElementRef element, - CFMutableArrayRef elements, int index, - int target) +static CFComparisonResult button_usage_comparator(const void *val1, const void *val2, void *context) { - IOHIDElementRef targetElement; - int usage; - - CFArraySetValueAtIndex(elements, header+index, NULL); - targetElement = ( IOHIDElementRef ) CFArrayGetValueAtIndex( elements, header+target); - if (targetElement == NULL) - { - CFArraySetValueAtIndex(elements, header+target,element); - return; - } - usage = IOHIDElementGetUsage( targetElement ); - usage --; /* usage 1 based index */ - - insert_sort_button(header, targetElement, elements, target, usage); - CFArraySetValueAtIndex(elements, header+target,element); + IOHIDElementRef element1 = (IOHIDElementRef)val1, element2 = (IOHIDElementRef)val2; + int usage1 = IOHIDElementGetUsage(element1), usage2 = IOHIDElementGetUsage(element2); + + if (usage1 < usage2) + return kCFCompareLessThan; + if (usage1 > usage2) + return kCFCompareGreaterThan; + return kCFCompareEqualTo; } static void get_osx_device_elements(JoystickImpl *device, int axis_map[8]) { IOHIDElementRef device_main_element; CFMutableArrayRef elements; - DWORD axes = 0; DWORD sliders = 0; - DWORD buttons = 0; - DWORD povs = 0; device->elements = NULL; @@ -480,8 +468,9 @@ static void get_osx_device_elements(JoystickImpl *device, int axis_map[8]) if (elements) { CFIndex idx, cnt = CFArrayGetCount( elements ); - /* build our element array in the order that dinput expects */ - device->elements = CFArrayCreateMutable(NULL,0,NULL); + CFMutableArrayRef axes = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + CFMutableArrayRef buttons = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + CFMutableArrayRef povs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); for ( idx = 0; idx < cnt; idx++ ) { @@ -498,17 +487,13 @@ static void get_osx_device_elements(JoystickImpl *device, int axis_map[8]) continue; } - if (buttons < 128) - { - CFArrayInsertValueAtIndex(device->elements, (axes+povs+buttons), element); - buttons++; - } + if (CFArrayGetCount(buttons) < 128) + CFArrayAppendValue(buttons, element); break; } case kIOHIDElementTypeInput_Axis: { - CFArrayInsertValueAtIndex(device->elements, axes, element); - axes++; + CFArrayAppendValue(axes, element); break; } case kIOHIDElementTypeInput_Misc: @@ -518,8 +503,7 @@ static void get_osx_device_elements(JoystickImpl *device, int axis_map[8]) { case kHIDUsage_GD_Hatswitch: { - CFArrayInsertValueAtIndex(device->elements, (axes+povs), element); - povs++; + CFArrayAppendValue(povs, element); break; } case kHIDUsage_GD_Slider: @@ -534,9 +518,8 @@ static void get_osx_device_elements(JoystickImpl *device, int axis_map[8]) case kHIDUsage_GD_Ry: case kHIDUsage_GD_Rz: { - CFArrayInsertValueAtIndex(device->elements, axes, element); - axis_map[axes]=usage; - axes++; + axis_map[CFArrayGetCount(axes)]=usage; + CFArrayAppendValue(axes, element); break; } default: @@ -548,22 +531,29 @@ static void get_osx_device_elements(JoystickImpl *device, int axis_map[8]) FIXME("Unhandled type %i\n",type); } } - } - device->generic.devcaps.dwAxes = axes; - device->generic.devcaps.dwButtons = buttons; - device->generic.devcaps.dwPOVs = povs; + /* Sort buttons into correct order */ + CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)), button_usage_comparator, NULL); - /* Sort buttons into correct order */ - for (buttons = 0; buttons < device->generic.devcaps.dwButtons; buttons++) - { - IOHIDElementRef element = ( IOHIDElementRef ) CFArrayGetValueAtIndex( device->elements, axes+povs+buttons); - uint32_t usage = IOHIDElementGetUsage( element ); - usage --; /* usage is 1 indexed we need 0 indexed */ - if (usage == buttons) - continue; + device->generic.devcaps.dwAxes = CFArrayGetCount(axes); + device->generic.devcaps.dwButtons = CFArrayGetCount(buttons); + device->generic.devcaps.dwPOVs = CFArrayGetCount(povs); - insert_sort_button(axes+povs, element, device->elements,buttons,usage); + /* build our element array in the order that dinput expects */ + CFArrayAppendArray(axes, povs, CFRangeMake(0, device->generic.devcaps.dwPOVs)); + CFArrayAppendArray(axes, buttons, CFRangeMake(0, device->generic.devcaps.dwButtons)); + device->elements = axes; + axes = NULL; + + CFRelease(povs); + CFRelease(buttons); + CFRelease(elements); + } + else + { + device->generic.devcaps.dwAxes = 0; + device->generic.devcaps.dwButtons = 0; + device->generic.devcaps.dwPOVs = 0; } } -- 2.11.4.GIT