/*************************************************************************** KeyConfig.h HIDInput Created by Gil Pedersen on Sat May 29 2004. Copyright (c) 2004 Gil Pedersen. ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. See also the license.txt file for * * additional informations. * * * ***************************************************************************/ #import "KeyConfig.h" #include "PlugPAD.h" /* - [Player 1] - [Current Type] - - - ... - [Player 2] - ... - ... ... */ static KeyConfig *sKeyconfig; int LoadConfig() { if (!sKeyconfig) sKeyconfig = [[KeyConfig alloc] init]; return 0; } // get name of element for display in window; // try names first then default to more generic derived names if device does not provide explicit names static void GetDeviceElementNameString(pRecDevice pDevice, pRecElement pElement, char * cstr) { char cstrElement[256] = "----", cstrDevice[256] = "----"; if (!HIDIsValidElement(pDevice, pElement)) return; if (HIDGetElementNameFromVendorProductUsage (pDevice->vendorID, pDevice->productID, pElement->usagePage, pElement->usage, cstr)) return; if (*(pDevice->product)) BlockMoveData(pDevice->product, cstrDevice, 256); else { HIDGetUsageName(pDevice->usagePage, pDevice->usage, cstrDevice); if (!*cstrDevice) // if usage sprintf(cstrDevice, "Device"); } if (*(pElement->name)) BlockMoveData(pElement->name, cstrElement, 256); else // if no name { HIDGetUsageName(pElement->usagePage, pElement->usage, cstrElement); if (!*cstrElement) // if not usage sprintf(cstrElement, "Element"); } sprintf(cstr, "%s: %s", cstrDevice, cstrElement); } @implementation KeyConfig - (id)init { if ((self = [super init]) == nil) return nil; /* Using the defaults system means that we will effectively piggy-back on the parent process' preferences. This behaviour is ok, since it allows for seperate preferences for each application that will use the plugin */ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys: @"Default", @"net.pcsx.HIDInputPlugin Current Set", [[NSMutableDictionary alloc] initWithCapacity:1], @"net.pcsx.HIDInputPlugin Pad Settings", nil]]; /* load from preferences */ keyValues = [[defaults dictionaryForKey:@"net.pcsx.HIDInputPlugin Pad Settings"] retain]; list = [[ControllerList alloc] initWithConfig:self]; [self setCurrentSet:[self currentSet]]; [self updateKeys]; return self; } - (void)dealloc { [keyValues release]; [list release]; } + (KeyConfig *)current { if (!sKeyconfig) LoadConfig(); return sKeyconfig; } - (ControllerList *)controllerList { return list; } #if 0 - (void)setDefaultMappingsWithType:(NSString *)type device:(NSString *)device player:(int)player { int len = [list elementCountForType:type]; int i; for (i=0; i 0) { NSString *deviceName = [KeyConfig deviceNameFromMapping:[mappings objectAtIndex:0]]; if (0 != [mappingName length]) [mappingName appendString:@" and "]; [mappingName appendString:deviceName]; [mappingName appendString:@": "]; [mappingName appendString:[KeyConfig nameFromMapping:[mappings objectAtIndex:0]]]; [mappings removeObjectAtIndex:0]; for (i=0; i<[mappings count]; i++) { if ([deviceName isEqualToString:[KeyConfig deviceNameFromMapping:[mappings objectAtIndex:0]]]) { [mappingName appendString:@", "]; [mappingName appendString:[KeyConfig nameFromMapping:[mappings objectAtIndex:i]]]; [mappings removeObjectAtIndex:i]; i--; } } } return [NSString stringWithString:mappingName]; } + (NSString *)mappingIdForElement:(pRecElement)element onDevice:(pRecDevice)device reverse:(BOOL)reverse { return [NSString stringWithFormat:@"d:{v:%ld, p:%ld, l:%ld, p:%ld, u:%ld}, e:{t:%ld, p:%ld, u:%ld, c:%ld, r:%ld}", device->vendorID, device->productID, device->locID, device->usagePage, device->usage, element->type, element->usagePage, element->usage, element->cookie, reverse]; } + (BOOL)reverseMappingForId:(NSString *)mappingId outElement:(pRecElement *)element outDevice:(pRecDevice *)device { recDevice searchDevice; recElement searchElement; long reverse; int count = sscanf([mappingId cString], "d:{v:%ld, p:%ld, l:%ld, p:%ld, u:%ld}, e:{t:%ld, p:%ld, u:%ld, c:%ld, r:%ld}", &searchDevice.vendorID, &searchDevice.productID, &searchDevice.locID, &searchDevice.usagePage, &searchDevice.usage, &searchElement.type, &searchElement.usagePage, &searchElement.usage, (long*)&searchElement.cookie, &reverse); if (9 == count || 10 == count) { if (HIDFindActionDeviceAndElement(&searchDevice, &searchElement,device, element)) { return YES; } } return NO; } + (BOOL)mappingIsReverse:(NSString *)mappingId { recDevice searchDevice; recElement searchElement; long reverse; int count = sscanf([mappingId cString], "d:{v:%ld, p:%ld, l:%ld, p:%ld, u:%ld}, e:{t:%ld, p:%ld, u:%ld, c:%ld, r:%ld}", &searchDevice.vendorID, &searchDevice.productID, &searchDevice.locID, &searchDevice.usagePage, &searchDevice.usage, &searchElement.type, &searchElement.usagePage, &searchElement.usage, (long*)&searchElement.cookie, &reverse); if (10 == count) { return (reverse != 0); } return NO; } + (NSString *)nameFromMapping:(NSString *)mappingId { pRecElement element; pRecDevice device; if ([self reverseMappingForId:mappingId outElement:&element outDevice:&device]) { if (device->usagePage == kHIDPage_GenericDesktop && device->usage == kHIDUsage_GD_Mouse) { if (element->usagePage == kHIDPage_Button) { return [NSString stringWithFormat:@"Button %i", element->usage]; } } else if (element->usagePage == kHIDPage_KeyboardOrKeypad) { int key = element->usage; if (key >= kHIDUsage_KeyboardA && key <= kHIDUsage_KeyboardZ) { return [NSString stringWithFormat:@"%c", (key-kHIDUsage_KeyboardA)+'A']; } else if (key >= kHIDUsage_Keyboard1 && key <= kHIDUsage_Keyboard0) { if (key == kHIDUsage_Keyboard0) return [NSString stringWithFormat:@"%c", '0']; return [NSString stringWithFormat:@"%c", (key-kHIDUsage_Keyboard1)+'1']; } else if (key >= kHIDUsage_KeyboardF1 && key <= kHIDUsage_KeyboardF12) { return [NSString stringWithFormat:@"F%i", (key-kHIDUsage_KeyboardF1)+1]; } else if (key >= kHIDUsage_Keypad1 && key <= kHIDUsage_Keypad9) { return [NSString stringWithFormat:@"Keypad %i", (key-kHIDUsage_Keypad1)+1]; } else { NSString *s = nil; switch (key) { case kHIDUsage_KeyboardReturnOrEnter: s=@"Return"; break; case kHIDUsage_KeyboardEscape: s=@"Escape"; break; case kHIDUsage_KeyboardDeleteOrBackspace: s=@"Delete"; break; case kHIDUsage_KeyboardTab: s=@"Tab"; break; case kHIDUsage_KeyboardSpacebar: s=@"Space"; break; case kHIDUsage_KeyboardHyphen: s=@"-"; break; case kHIDUsage_KeyboardEqualSign: s=@"="; break; case kHIDUsage_KeyboardOpenBracket: s=@"["; break; case kHIDUsage_KeyboardCloseBracket: s=@"]"; break; case kHIDUsage_KeyboardBackslash: s=@"\\"; break; case kHIDUsage_KeyboardSemicolon: s=@";"; break; case kHIDUsage_KeyboardQuote: s=@"'"; break; case kHIDUsage_KeyboardGraveAccentAndTilde: s=@"ยด"; break; case kHIDUsage_KeyboardComma: s=@","; break; case kHIDUsage_KeyboardPeriod: s=@"."; break; case kHIDUsage_KeyboardSlash: s=@"/"; break; case kHIDUsage_KeyboardCapsLock: s=@"Caps Lock"; break; case kHIDUsage_KeyboardRightArrow: s=@"Right Arrow"; break; case kHIDUsage_KeyboardLeftArrow: s=@"Left Arrow"; break; case kHIDUsage_KeyboardDownArrow: s=@"Down Arrow"; break; case kHIDUsage_KeyboardUpArrow: s=@"Up Arrow"; break; case kHIDUsage_KeypadNumLock: s=@"NumLock"; break; case kHIDUsage_KeypadSlash: s=@"Keypad /"; break; case kHIDUsage_KeypadAsterisk: s=@"Keypad *"; break; case kHIDUsage_KeypadHyphen: s=@"Keypad -"; break; case kHIDUsage_KeypadPlus: s=@"Keypad +"; break; case kHIDUsage_KeypadEnter: s=@"Keypad Enter"; break; case kHIDUsage_Keypad0: s=@"Keypad 0"; break; case kHIDUsage_KeypadPeriod: s=@"Keypad ."; break; case kHIDUsage_KeypadEqualSign: s=@"Keypad ="; break; case kHIDUsage_KeyboardLeftControl: s=@"Left Control"; break; case kHIDUsage_KeyboardLeftShift: s=@"Left Shift"; break; case kHIDUsage_KeyboardLeftAlt: s=@"Left Option"; break; case kHIDUsage_KeyboardLeftGUI: s=@"Left Command"; break; case kHIDUsage_KeyboardRightControl: s=@"Right Control"; break; case kHIDUsage_KeyboardRightShift: s=@"Right Shift"; break; case kHIDUsage_KeyboardRightAlt: s=@"Right Option"; break; case kHIDUsage_KeyboardRightGUI: s=@"Right Command"; break; } if (s) { return s; } } } char name[256]; if (HIDGetElementNameFromVendorProductUsage (device->vendorID, device->productID, element->usagePage, element->usage, name)) return [NSString stringWithCString:name]; return [NSString stringWithCString:element->name]; } else { return NSLocalizedString(@"Unknown Key", @""); } } + (NSString *)deviceNameFromMapping:(NSString *)mappingId { pRecElement element; pRecDevice device; if ([self reverseMappingForId:mappingId outElement:&element outDevice:&device]) { return [NSString stringWithCString:device->product]; } else { return NSLocalizedString(@"Unknown Device", @""); } } /* called when ok is pressed */ - (void)updateKeys { int i, j, k; /* transfer to working set */ for (i=0; i= 0); for (k=0; k<[mappings count]; k++) { NSString *mapId = [mappings objectAtIndex:k]; if (gNumAxes[i] >= MAX_NUM_AXES) break; if ([KeyConfig reverseMappingForId:mapId outElement:&gAxes[i][gNumAxes[i]].element outDevice:&gAxes[i][gNumAxes[i]].device]) { gAxes[i][gNumAxes[i]].axis = axis; gAxes[i][gNumAxes[i]].reverse = [KeyConfig mappingIsReverse:mapId]; gAxes[i][gNumAxes[i]].positive = positive; gAxes[i][gNumAxes[i]].lastValue = 127; gNumAxes[i]++; } } } } else { for (k=0; k<[mappings count]; k++) { NSString *mapId = [mappings objectAtIndex:k]; if (gNumKeys[i] >= MAX_NUM_KEYS) break; if ([KeyConfig reverseMappingForId:mapId outElement:&gKeys[i][gNumKeys[i]].element outDevice:&gKeys[i][gNumKeys[i]].device]) { gKeys[i][gNumKeys[i]].button = button; gKeys[i][gNumKeys[i]].reverse = [KeyConfig mappingIsReverse:mapId]; gNumKeys[i]++; } } } } } /* save to preferences */ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:keyValues forKey:@"net.pcsx.HIDInputPlugin Pad Settings"]; [defaults synchronize]; } /* called when cancel button is pressed */ - (void)releaseKeys { [keyValues release]; keyValues = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"net.pcsx.HIDInputPlugin Pad Settings"] retain]; } @end