X-Git-Url: https://git.yukkurigames.com/?p=enjoyable.git;a=blobdiff_plain;f=Joystick.m;h=4753caffa7b9171a83f43b483873867d86410b6b;hp=9f3c8265688564acc0d6c1df615e55fc7b7cb2a4;hb=0238d141f06420e1a73eccd14ca73a7e29ad2a69;hpb=fad073260e61084c4962e172c58a0595261bd811 diff --git a/Joystick.m b/Joystick.m index 9f3c826..4753caf 100644 --- a/Joystick.m +++ b/Joystick.m @@ -5,99 +5,104 @@ // Created by Sam McCall on 4/05/09. // +#import "Joystick.h" + +#import "JSAction.h" +#import "JSActionAnalog.h" +#import "JSActionButton.h" +#import "JSActionHat.h" + static NSArray *ActionsForElement(IOHIDDeviceRef device, id base) { CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone); NSMutableArray *children = [NSMutableArray arrayWithCapacity:CFArrayGetCount(elements)]; int buttons = 0; int axes = 0; + int hats = 0; for (int i = 0; i < CFArrayGetCount(elements); i++) { IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i); int type = IOHIDElementGetType(element); - int usage = IOHIDElementGetUsage(element); - int usagePage = IOHIDElementGetUsagePage(element); - int max = IOHIDElementGetPhysicalMax(element); - int min = IOHIDElementGetPhysicalMin(element); + unsigned usage = IOHIDElementGetUsage(element); + unsigned usagePage = IOHIDElementGetUsagePage(element); + long max = IOHIDElementGetPhysicalMax(element); + long min = IOHIDElementGetPhysicalMin(element); CFStringRef elName = IOHIDElementGetName(element); - JSAction *action = NULL; + JSAction *action = nil; - if(!(type == kIOHIDElementTypeInput_Misc - || type == kIOHIDElementTypeInput_Axis - || type == kIOHIDElementTypeInput_Button)) - continue; + if (!(type == kIOHIDElementTypeInput_Misc + || type == kIOHIDElementTypeInput_Axis + || type == kIOHIDElementTypeInput_Button)) + continue; if (max - min == 1 || usagePage == kHIDPage_Button || type == kIOHIDElementTypeInput_Button) { - action = [[JSActionButton alloc] initWithIndex:buttons++ andName:(__bridge NSString *)elName]; - [(JSActionButton*)action setMax:max]; + action = [[JSActionButton alloc] initWithName:(__bridge NSString *)elName + idx:++buttons + max:max]; } else if (usage == kHIDUsage_GD_Hatswitch) { - action = [[JSActionHat alloc] init]; + action = [[JSActionHat alloc] initWithIndex:++hats]; + } else if (usage >= kHIDUsage_GD_X && usage <= kHIDUsage_GD_Rz) { + action = [[JSActionAnalog alloc] initWithIndex:++axes + rawMin:min + rawMax:max]; } else { - if (usage >= kHIDUsage_GD_X && usage <= kHIDUsage_GD_Rz) { - action = [[JSActionAnalog alloc] initWithIndex: axes++]; - [(JSActionAnalog*)action setOffset:(double)-1.0]; - [(JSActionAnalog*)action setScale:(double)2.0/(max - min)]; - } else - continue; + continue; } - [action setBase:base]; - [action setUsage:usage]; - [action setCookie:IOHIDElementGetCookie(element)]; + // TODO(jfw): Should be moved into better constructors. + action.base = base; + action.cookie = IOHIDElementGetCookie(element); [children addObject:action]; } + + CFRelease(elements); return children; } -@implementation Joystick - -@synthesize vendorId; -@synthesize productId; -@synthesize productName; -@synthesize index; -@synthesize device; -@synthesize children; +@implementation Joystick { + int vendorId; + int productId; +} - (id)initWithDevice:(IOHIDDeviceRef)dev { if ((self = [super init])) { self.device = dev; self.productName = (__bridge NSString *)IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDProductKey)); - self.vendorId = [(__bridge NSNumber *)IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDVendorIDKey)) intValue]; - self.productId = [(__bridge NSNumber *)IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDProductIDKey)) intValue]; + vendorId = [(__bridge NSNumber *)IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDVendorIDKey)) intValue]; + productId = [(__bridge NSNumber *)IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDProductIDKey)) intValue]; self.children = ActionsForElement(dev, self); } return self; } - (NSString *)name { - return [NSString stringWithFormat:@"%@ #%d", productName, index + 1]; + return [NSString stringWithFormat:@"%@ #%d", _productName, _index]; } - (id)base { - // FIXME(jfw): This is a hack because actions get joysticks as their base. return nil; } -- (NSString *)stringify { - return [[NSString alloc] initWithFormat: @"%d~%d~%d", vendorId, productId, index]; +- (NSString *)uid { + return [NSString stringWithFormat: @"%d:%d:%d", vendorId, productId, _index]; } -- (JSAction *)findActionByCookie:(void *)cookie { - for (JSAction *child in children) +- (JSAction *)findActionByCookie:(IOHIDElementCookie)cookie { + for (JSAction *child in _children) if (child.cookie == cookie) return child; return nil; } -- (id)handlerForEvent:(IOHIDValueRef) value { +- (JSAction *)handlerForEvent:(IOHIDValueRef)value { JSAction *mainAction = [self actionForEvent:value]; return [mainAction findSubActionForValue:value]; } - (JSAction *)actionForEvent:(IOHIDValueRef)value { IOHIDElementRef elt = IOHIDValueGetElement(value); - void *cookie = IOHIDElementGetCookie(elt); + IOHIDElementCookie cookie = IOHIDElementGetCookie(elt); return [self findActionByCookie:cookie]; }