diff options
| author | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2009-10-24 03:15:42 +0000 |
|---|---|---|
| committer | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2009-10-24 03:15:42 +0000 |
| commit | 5408345d8b1cde19a19ddf324d3439ead6e80709 (patch) | |
| tree | fd7934308384396b4ad92b547e8804a696c480e8 /macosx/plugins/HIDInput/src/KeyConfig.m | |
| parent | f2f1033882e0643f05f3027f2c812f425f67a879 (diff) | |
| download | pcsxr-5408345d8b1cde19a19ddf324d3439ead6e80709.tar.gz | |
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@32699 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'macosx/plugins/HIDInput/src/KeyConfig.m')
| -rw-r--r-- | macosx/plugins/HIDInput/src/KeyConfig.m | 535 |
1 files changed, 535 insertions, 0 deletions
diff --git a/macosx/plugins/HIDInput/src/KeyConfig.m b/macosx/plugins/HIDInput/src/KeyConfig.m new file mode 100644 index 00000000..6b82665b --- /dev/null +++ b/macosx/plugins/HIDInput/src/KeyConfig.m @@ -0,0 +1,535 @@ +/*************************************************************************** + 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" + + +/* + <Set 1> - [Player 1] - [Current Type] + - <Type 1 Keys> + - <Type 2 Keys> + - ... + + - [Player 2] - ... + + <Set 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<len; i++) { + NSArray *mappings = [list defaultMappingsAtIndex:i type:type]; + + } +} + +- (void)setDefaultMappingsInSet:(NSString *)name +{ + NSArray *devices = [self systemDeviceList]; + + /* assign all keyboards to player 1 */ + //if ( + + /* assign the first joypad to player 1 */ + + /* assign second joypad to player 2 */ +} +#endif + +- (void)setCurrentSet:(NSString *)name +{ + [[NSUserDefaults standardUserDefaults] setObject:name forKey:@"net.pcsx.HIDInputPlugin Current Set"]; + + /* create the entry if neccesary */ + NSDictionary *dict = [keyValues objectForKey:name]; + if (nil == dict) { + dict = [NSMutableDictionary dictionaryWithCapacity:2]; + if (![keyValues respondsToSelector:@selector(setObject)]) { + [keyValues autorelease]; + keyValues = [[NSMutableDictionary alloc] initWithDictionary:keyValues]; + } + [(NSMutableDictionary *)keyValues setObject:dict forKey:name]; + } +} + +- (NSString *)currentSet +{ + NSString *set = [[NSUserDefaults standardUserDefaults] stringForKey:@"net.pcsx.HIDInputPlugin Current Set"]; + if (nil == set) { + //[self setDefaultMappingsInSet:@"Default"]; + return @"Default"; + } + + return set; +} + +- (NSDictionary *)players +{ + return [keyValues objectForKey:[self currentSet]]; +} +- (NSMutableDictionary *)mutablePlayers +{ + NSDictionary *players = [self players]; + + if (![players respondsToSelector:@selector(setObject)]) { + players = [NSMutableDictionary dictionaryWithDictionary:players]; + if (![keyValues respondsToSelector:@selector(setObject)]) { + [keyValues autorelease]; + keyValues = [[NSMutableDictionary alloc] initWithDictionary:keyValues]; + } + [(NSMutableDictionary *)keyValues setObject:players forKey:[self currentSet]]; + } + + return (NSMutableDictionary *)players; +} + + +- (NSDictionary *)typesForPlayer:(int)player +{ + NSDictionary *types = [[self players] objectForKey:[NSString stringWithFormat:@"Player %i", player+1]]; + if (nil == types) + return [NSDictionary dictionary]; + + return types; +} +- (NSMutableDictionary *)mutableTypesForPlayer:(int)player +{ + NSDictionary *types = [self typesForPlayer:player]; + + if (![types respondsToSelector:@selector(setObject)]) { + types = [NSMutableDictionary dictionaryWithDictionary:types]; + [[self mutablePlayers] setObject:types forKey:[NSString stringWithFormat:@"Player %i", player+1]]; + } + + return (NSMutableDictionary *)types; +} + +- (void)setCurrentType:(NSString *)type player:(int)player +{ +/* NSString *playerKey = [NSString stringWithFormat:@"Player %i", player+1]; + NSDictionary *types = [[self players] objectForKey:playerKey]; + if (nil == types) { + types = [NSMutableDictionary dictionaryWithCapacity:2]; + [[self mutablePlayers] setObject:types forKey:playerKey]; + }*/ + + if (![type isEqualToString:[self currentTypeForPlayer:player]]) { + NSMutableDictionary *types = [self mutableTypesForPlayer:player]; + + /* set the type */ + [types setObject:type forKey:@"Current Type"]; + + /* make sure its dictionary is created */ + NSDictionary *keys = [types objectForKey:type]; + if (nil == keys) { + keys = [NSMutableDictionary dictionaryWithCapacity:1]; + [types setObject:keys forKey:type]; + } + } +} + +- (NSString *)currentTypeForPlayer:(int)player +{ + return [[self typesForPlayer:player] objectForKey:@"Current Type"]; +} + + +- (NSDictionary*)currentKeysForPlayer:(int)player +{ + NSString *typeKey = [self currentTypeForPlayer:player]; + if (nil == typeKey) + return nil; + + return [[self typesForPlayer:player] objectForKey:typeKey]; +} +- (NSMutableDictionary *)mutableKeysForPlayer:(int)player +{ + NSDictionary *keys = [self currentKeysForPlayer:player]; + + if (![keys respondsToSelector:@selector(setObject)]) { + keys = [NSMutableDictionary dictionaryWithDictionary:keys]; + [[self mutableTypesForPlayer:player] setObject:keys forKey:[self currentTypeForPlayer:player]]; + } + + return (NSMutableDictionary *)keys; +} + + +- (void)addMapping:(NSString *)mappingId forElement:(NSString *)name player:(int)player +{ + NSMutableDictionary *keys = [self mutableKeysForPlayer:player]; + NSMutableArray *mappings = [keys objectForKey:name]; + if (nil == mappings) { + mappings = [NSMutableArray arrayWithCapacity:1]; + [keys setObject:mappings forKey:name]; + } else { + /* check if it's new */ + int i; + for (i=0; i<[mappings count]; i++) { + if ([[mappings objectAtIndex:i] isEqualToString:mappingId]) + return; + } + } + [mappings addObject:mappingId]; +} + +- (void)removeMappingsForElement:(NSString *)name player:(int)player +{ + NSMutableDictionary *keys = [self mutableKeysForPlayer:player]; + [keys removeObjectForKey:name]; +} + +- (NSArray *)currentMappingsForElement:(NSString *)name player:(int)player +{ + NSArray *mappings = [[self currentKeysForPlayer:player] objectForKey:name]; + if (nil == mappings) + return [NSArray array]; + + return mappings; +} + +- (NSString *)mappingNamesForElement:(NSString *)name player:(int)player +{ + NSMutableArray *mappings = [NSMutableArray arrayWithArray:[self currentMappingsForElement:name player:player]]; + NSMutableString *mappingName = [NSMutableString stringWithCapacity:256]; + int i; + + if (0 == [mappings count]) + return nil; + + while ([mappings count] > 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<MAX_NUM_PADS; i++) { + NSString *type = [self currentTypeForPlayer:i]; + + gControllerType[i] = [list controllerTypeIdForType:type]; + gNumKeys[i] = gNumAxes[i] = 0; + + for (j=0; j<[list elementCountForType:type]; j++) { + NSString *name = [list elementNameAtIndex:j type:type]; + NSArray *mappings = [self currentMappingsForElement:name player:i]; + int button = [list buttonIdAtIndex:j type:type]; + + if (-1 == button) { + int axis = [list axisIdAtIndex:j type:type]; + if (-1 != axis) { + BOOL positive = ([list axisDirectionAtIndex:j type:type] >= 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 |
