X-Git-Url: https://git.yukkurigames.com/?p=enjoyable.git;a=blobdiff_plain;f=JoystickController.m;h=84366ef028e40e218d1448091c3667ac88b4b8b3;hp=c5ddcdc0cbe217b6f8d3b6655ceebc3e032d4e1a;hb=15a3aec049658f4a1c3c6e8c9f8a549fb8de0782;hpb=724979785b445dcba8a9861c2531ae0308bdf40a diff --git a/JoystickController.m b/JoystickController.m index c5ddcdc..84366ef 100644 --- a/JoystickController.m +++ b/JoystickController.m @@ -7,21 +7,22 @@ #import "JoystickController.h" +#import "Config.h" +#import "ConfigsController.h" +#import "Joystick.h" +#import "JSAction.h" +#import "Target.h" +#import "TargetController.h" + @implementation JoystickController { IOHIDManagerRef hidManager; - BOOL programmaticallySelecting; NSTimer *continuousTimer; + NSMutableArray *runningTargets; } -@synthesize joysticks; -@synthesize runningTargets; -@synthesize selectedAction; -@synthesize frontWindowOnly; -@synthesize mouseLoc; - - (id)init { if ((self = [super init])) { - joysticks = [[NSMutableArray alloc] initWithCapacity:16]; + _joysticks = [[NSMutableArray alloc] initWithCapacity:16]; runningTargets = [[NSMutableArray alloc] initWithCapacity:32]; } return self; @@ -40,8 +41,9 @@ } - (void)addRunningTarget:(Target *)target { - if (![runningTargets containsObject:target]) + if (![runningTargets containsObject:target]) { [runningTargets addObject:target]; + } if (!continuousTimer) { continuousTimer = [NSTimer scheduledTimerWithTimeInterval:1.f/60.f target:self @@ -57,48 +59,31 @@ static void input_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDVa IOHIDDeviceRef device = IOHIDQueueGetDevice(inSender); Joystick *js = [controller findJoystickByRef:device]; - if (((ApplicationController *)[NSApplication sharedApplication].delegate).active) { + if (controller.sendingRealEvents) { JSAction *mainAction = [js actionForEvent:value]; - if (!mainAction) - return; - [mainAction notifyEvent:value]; - NSArray *children = mainAction.children ? mainAction.children : @[mainAction]; + NSArray *children = mainAction.children ? mainAction.children : mainAction ? @[mainAction] : @[]; for (JSAction *subaction in children) { - Target *target = [[controller->configsController currentConfig] getTargetForAction:subaction]; - if (!target) - continue; - // TODO: Can we just trigger based on setRunning:? - if (target.running != subaction.active) { - if (subaction.active) - [target trigger:controller]; - else - [target untrigger:controller]; - target.running = subaction.active; - } - - // FIXME: Hack, should just expose analog info properly in continuous target. - if ([mainAction isKindOfClass:[JSActionAnalog class]]) { - double realValue = [(JSActionAnalog *)mainAction getRealValue:IOHIDValueGetIntegerValue(value)]; - [target setInputValue:realValue]; - if (target.isContinuous && target.running) - [controller addRunningTarget:target]; - } + Target *target = controller.currentConfig[subaction]; + target.magnitude = mainAction.magnitude; + target.running = subaction.active; + if (target.running && target.isContinuous) + [controller addRunningTarget:target]; } - } else if ([NSApplication sharedApplication].isActive && [NSApplication sharedApplication].mainWindow.isVisible) { - // joysticks not active, use it to select stuff + } else if ([NSApplication sharedApplication].isActive + && [NSApplication sharedApplication].mainWindow.isVisible) { JSAction *handler = [js handlerForEvent:value]; if (!handler) return; [controller expandRecursive:handler]; - controller->programmaticallySelecting = YES; [controller->outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:[controller->outlineView rowForItem:handler]] byExtendingSelection: NO]; + [controller->targetController focusKey]; } } static int findAvailableIndex(NSArray *list, Joystick *js) { - for (int index = 0; ; index++) { + for (int index = 1; ; index++) { BOOL available = YES; for (Joystick *used in list) { if ([used.productName isEqualToString:js.productName] && used.index == index) { @@ -121,7 +106,7 @@ static void add_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDDevi } - (Joystick *)findJoystickByRef:(IOHIDDeviceRef)device { - for (Joystick *js in joysticks) + for (Joystick *js in _joysticks) if (js.device == device) return js; return nil; @@ -139,11 +124,13 @@ static void remove_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDD - (void)updateContinuousActions:(NSTimer *)timer { self.mouseLoc = [NSEvent mouseLocation]; - for (Target *target in [self.runningTargets copy]) { - if (![target update:self]) - [self.runningTargets removeObject:target]; + for (Target *target in [runningTargets copy]) { + if (![target update:self]) { + [runningTargets removeObject:target]; + NSLog(@"Removing action, now running %lu.", runningTargets.count); + } } - if (!self.runningTargets.count) { + if (!runningTargets.count) { [continuousTimer invalidate]; continuousTimer = nil; NSLog(@"Unscheduled continuous target timer."); @@ -164,19 +151,33 @@ static void remove_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDD IOHIDManagerSetDeviceMatchingMultiple(hidManager, (__bridge CFArrayRef)criteria); IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); - IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone); // FIXME: If an error happens, report it! + IOReturn ret = IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone); + if (ret != kIOReturnSuccess) { + [[NSAlert alertWithMessageText:@"Input devices are unavailable" + defaultButton:nil + alternateButton:nil + otherButton:nil + informativeTextWithFormat:@"Error 0x%08x occured trying to access your devices. " + @"Input may not be correctly detected or mapped.", + ret] + runModal]; + } IOHIDManagerRegisterDeviceMatchingCallback(hidManager, add_callback, (__bridge void *)self); IOHIDManagerRegisterDeviceRemovalCallback(hidManager, remove_callback, (__bridge void *)self); } +- (Config *)currentConfig { + return configsController.currentConfig; +} + - (JSAction *)selectedAction { id item = [outlineView itemAtRow:outlineView.selectedRow]; return [item children] ? nil : item; } - (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item { - return item ? [[item children] count] : [joysticks count]; + return item ? [[item children] count] : _joysticks.count; } - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item { @@ -184,7 +185,7 @@ static void remove_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDD } - (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item { - return item ? [item children][index] : joysticks[index]; + return item ? [item children][index] : _joysticks[index]; } - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { @@ -196,9 +197,6 @@ static void remove_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDD - (void)outlineViewSelectionDidChange: (NSNotification*) notification { [targetController reset]; [targetController load]; - if (programmaticallySelecting) - [targetController focusKey]; - programmaticallySelecting = NO; } @end