X-Git-Url: https://git.yukkurigames.com/?p=enjoyable.git;a=blobdiff_plain;f=Joystick.m;fp=Joystick.m;h=8fa67919789fde788b7c9bd807e787d63f21146a;hp=0000000000000000000000000000000000000000;hb=530009447c5bbd360ac5023979cffc6d32a28df3;hpb=5f07baa8cb03a2f6aa06338bfeb31dad3c3ca29f diff --git a/Joystick.m b/Joystick.m new file mode 100644 index 0000000..8fa6791 --- /dev/null +++ b/Joystick.m @@ -0,0 +1,116 @@ +// +// Joystick.m +// Enjoy +// +// Created by Sam McCall on 4/05/09. +// + +@implementation Joystick + + +@synthesize vendorId, productId, productName, name, index, device, children; + +-(id)initWithDevice: (IOHIDDeviceRef) newDevice { + if(self=[super init]) { + children = [[NSMutableArray alloc]init]; + + device = newDevice; + productName = (NSString*)IOHIDDeviceGetProperty( device, CFSTR(kIOHIDProductKey) ); + vendorId = [(NSNumber*)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)) intValue]; + productId = [(NSNumber*)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)) intValue]; + + name = productName; + } + return self; +} + +-(void) setIndex: (int) newIndex { + index = newIndex; + name = [[NSString alloc] initWithFormat: @"%@ #%d", productName, (index+1)]; +} +-(int) index { + return index; +} + +-(void) invalidate { + IOHIDDeviceClose(device, kIOHIDOptionsTypeNone); + NSLog(@"Removed a device: %@", [self name]); +} + +-(id) base { + return NULL; +} + +-(void) populateActions { + NSArray* elements = (NSArray*)IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone); + + int buttons = 0; + int axes = 0; + + for(int i=0; i<[elements count]; i++) { + IOHIDElementRef element = (IOHIDElementRef)[elements objectAtIndex: i]; + int type = IOHIDElementGetType(element); + int usage = IOHIDElementGetUsage(element); + int usagePage = IOHIDElementGetUsagePage(element); + int max = IOHIDElementGetPhysicalMax(element); + int min = IOHIDElementGetPhysicalMin(element); + CFStringRef elName = IOHIDElementGetName(element); + +// if(usagePage != 1 || usagePage == 9) { +// NSLog(@"Skipping usage page %x usage %x", usagePage, usage); +// continue; +// } + + JSAction* action = NULL; + + 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: (NSString *)elName]; + [(JSActionButton*)action setMax: max]; + } else if(usage == 0x39) + action = [[JSActionHat alloc] init]; + else { + if(usage >= 0x30 && usage < 0x36) { + action = [[JSActionAnalog alloc] initWithIndex: axes++]; + [(JSActionAnalog*)action setOffset: (double)-1.0]; + [(JSActionAnalog*)action setScale: (double)2.0/(max - min)]; + } else + continue; + } + + [action setBase: self]; + [action setUsage: usage]; + [action setCookie: IOHIDElementGetCookie(element)]; + [children addObject:action]; + } +} + +-(NSString*) stringify { + return [[NSString alloc] initWithFormat: @"%d~%d~%d", vendorId, productId, index]; +} + +- (JSAction*) findActionByCookie: (void*) cookie { + for(int i=0; i<[children count]; i++) + if([[children objectAtIndex:i]cookie] == cookie) + return (JSAction*)[children objectAtIndex:i]; + return NULL; +} + +-(id) handlerForEvent: (IOHIDValueRef) value { + JSAction* mainAction = [self actionForEvent: value]; + if(!mainAction) + return NULL; + return [mainAction findSubActionForValue: value]; +} +-(JSAction*) actionForEvent: (IOHIDValueRef) value { + IOHIDElementRef elt = IOHIDValueGetElement(value); + void* cookie = IOHIDElementGetCookie(elt); + return [self findActionByCookie: cookie]; +} + +@end