summaryrefslogtreecommitdiff
path: root/macosx/plugins/HIDInput/src/KeyConfig.m
diff options
context:
space:
mode:
authorSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2009-10-24 03:15:42 +0000
committerSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2009-10-24 03:15:42 +0000
commit5408345d8b1cde19a19ddf324d3439ead6e80709 (patch)
treefd7934308384396b4ad92b547e8804a696c480e8 /macosx/plugins/HIDInput/src/KeyConfig.m
parentf2f1033882e0643f05f3027f2c812f425f67a879 (diff)
downloadpcsxr-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.m535
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