From d67e5f375d3268c306ecc777396e0988b97d12ad Mon Sep 17 00:00:00 2001 From: gecko_reverse Date: Mon, 28 Jul 2008 03:54:10 +0000 Subject: [PATCH] =?UTF-8?q?Added=20key=20config=20options=20panel=20and=20?= =?UTF-8?q?hotkeys=20for=20pause/execute/reset=20thanks=20to=20Julio=20Gor?= =?UTF-8?q?g=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- desmume/ChangeLog | 2 + .../cocoa/DeSmuME.xcodeproj/project.pbxproj | 4 +- desmume/src/cocoa/main.m | 6 +- desmume/src/cocoa/preferences.h | 26 +-- desmume/src/cocoa/preferences.m | 172 +++++++++++++++++- 5 files changed, 187 insertions(+), 23 deletions(-) diff --git a/desmume/ChangeLog b/desmume/ChangeLog index 6bd47e3d9..df7598cae 100644 --- a/desmume/ChangeLog +++ b/desmume/ChangeLog @@ -12,6 +12,8 @@ - Fixed: Frozen video output (and/or messed 3d emulation) after loading a state. [Jeff] - Added option to load the most recent file upon launching the program. [Jeff] - Added French translation (thanks to Pierre Rudloff). [Jeff] + - Added basic key mapping configuration to application preferences (thanks to Julio Gorgˇ). [Jeff] + - Added keyboard shortcuts for Execute, Pause and Reset command (thanks to Julio Gorgˇ). [Jeff] Windows port: - Removed the bug report link with a define, to avoid reports from betas/external builds [shash] - Added the version on window bar to recognize versions from screenshots [shash] diff --git a/desmume/src/cocoa/DeSmuME.xcodeproj/project.pbxproj b/desmume/src/cocoa/DeSmuME.xcodeproj/project.pbxproj index 649c05f86..eb6b84d70 100644 --- a/desmume/src/cocoa/DeSmuME.xcodeproj/project.pbxproj +++ b/desmume/src/cocoa/DeSmuME.xcodeproj/project.pbxproj @@ -211,8 +211,6 @@ 29B97314FDCFA39411CA2CEA /* DeSmuME */ = { isa = PBXGroup; children = ( - 726D68AA0E310B1800800002 /* French.nib */, - 726D68AB0E310B1800800002 /* French.strings */, 72C000010D9D59E60046B7EA /* Info.plist */, 72C000020D9D59E60046B7EA /* InfoPlist.strings */, 729BECEF0D9D581900ED561B /* AudioUnit.framework */, @@ -288,6 +286,8 @@ 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( + 726D68AA0E310B1800800002 /* French.nib */, + 726D68AB0E310B1800800002 /* French.strings */, 7277B6DF0D9E045700D283BD /* English.nib */, 7277B6E00D9E045700D283BD /* English.strings */, 7277B6E10D9E045700D283BD /* Japanese.nib */, diff --git a/desmume/src/cocoa/main.m b/desmume/src/cocoa/main.m index 9d5105487..8292c2f27 100644 --- a/desmume/src/cocoa/main.m +++ b/desmume/src/cocoa/main.m @@ -245,11 +245,11 @@ a way to get the time of a save that's not a string / human formatted... emulation = [[NSMenu alloc] initWithTitle:NSLocalizedString(@"Emulation", nil)]; [menu setSubmenu:emulation forItem:emulation_item]; - execute_item = [emulation addItemWithTitle:NSLocalizedString(@"Execute", nil) action:@selector(execute) keyEquivalent:@""]; + execute_item = [emulation addItemWithTitle:NSLocalizedString(@"Execute", nil) action:@selector(execute) keyEquivalent:@"e"]; - pause_item = [emulation addItemWithTitle:NSLocalizedString(@"Pause", nil) action:@selector(pause) keyEquivalent:@""]; + pause_item = [emulation addItemWithTitle:NSLocalizedString(@"Pause", nil) action:@selector(pause) keyEquivalent:@"p"]; - reset_item = [emulation addItemWithTitle:NSLocalizedString(@"Reset", nil) action:@selector(reset) keyEquivalent:@""]; + reset_item = [emulation addItemWithTitle:NSLocalizedString(@"Reset", nil) action:@selector(reset) keyEquivalent:@"r"]; [emulation addItem:[NSMenuItem separatorItem]]; diff --git a/desmume/src/cocoa/preferences.h b/desmume/src/cocoa/preferences.h index 2dc79a26e..514a27362 100644 --- a/desmume/src/cocoa/preferences.h +++ b/desmume/src/cocoa/preferences.h @@ -23,20 +23,20 @@ #define PREF_AFTER_LAUNCHED_OPTION_NOTHING @"Load Nothing" #define PREF_AFTER_LAUNCHED_OPTION_LAST_ROM @"Load Last ROM" -#define PREF_FLASH_FILE @"FlashFile" +#define PREF_FLASH_FILE @"Flash File" -#define PREF_KEY_A @"KeyA" -#define PREF_KEY_B @"KeyB" -#define PREF_KEY_X @"KeyX" -#define PREF_KEY_Y @"KeyY" -#define PREF_KEY_L @"KeyL" -#define PREF_KEY_R @"KeyR" -#define PREF_KEY_UP @"KeyUp" -#define PREF_KEY_DOWN @"KeyDown" -#define PREF_KEY_LEFT @"KeyLeft" -#define PREF_KEY_RIGHT @"KeyRight" -#define PREF_KEY_START @"KeyStart" -#define PREF_KEY_SELECT @"KeySelect" +#define PREF_KEY_A @"Key A" +#define PREF_KEY_B @"Key B" +#define PREF_KEY_X @"Key X" +#define PREF_KEY_Y @"Key Y" +#define PREF_KEY_L @"Key L" +#define PREF_KEY_R @"Key R" +#define PREF_KEY_UP @"Key Up" +#define PREF_KEY_DOWN @"Key Down" +#define PREF_KEY_LEFT @"Key Left" +#define PREF_KEY_RIGHT @"Key Right" +#define PREF_KEY_START @"Key Start" +#define PREF_KEY_SELECT @"Key Select" void setAppDefaults(); //this is defined in preferences.m and should be called at app launch diff --git a/desmume/src/cocoa/preferences.m b/desmume/src/cocoa/preferences.m index f866257e6..ef5685b66 100644 --- a/desmume/src/cocoa/preferences.m +++ b/desmume/src/cocoa/preferences.m @@ -44,6 +44,8 @@ NSDictionary *preferences_font_attribs; NSDictionary *desmume_defaults; +NSDictionary *keyboardMap; // TODO: name it something else + /////////////////////////////// unsigned char utf8_return = 0x0D; @@ -96,6 +98,33 @@ void setAppDefaults() [[NSUserDefaults standardUserDefaults] registerDefaults:desmume_defaults]; } + +void setKeyboardMap() +{ + // Create a dictionary mapping the keyboard + + NSArray *keys = [NSArray arrayWithObjects: + @"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", + @"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I", @"J", @"K", @"L", + @"M", @"N", @"O", @"P", @"Q", @"R", @"S", @"T", @"V", @"W", @"X", @"Y", @"Z", + @"[UP]", @"[DOWN]", @"[LEFT]", @"[RIGHT]", @"[SPACE]", @"[RETURN]", nil]; + + NSArray *objects = [NSArray arrayWithObjects: + @"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", + @"a", @"b", @"c", @"d", @"e", @"f", @"g", @"h", @"i", @"j", @"k", @"l", + @"m", @"n", @"o", @"p", @"q", @"r", @"s", @"t", @"v", @"w", @"x", @"y", @"z", + [[[NSString alloc] initWithBytesNoCopy:utf8_up length:3 encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease], + [[[NSString alloc] initWithBytesNoCopy:utf8_down length:3 encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease], + [[[NSString alloc] initWithBytesNoCopy:utf8_left length:3 encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease], + [[[NSString alloc] initWithBytesNoCopy:utf8_right length:3 encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease], + @" ", + [[[NSString alloc] initWithBytesNoCopy:&utf8_return length:1 encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease], + nil]; + + + keyboardMap = [NSDictionary dictionaryWithObjects:objects forKeys:keys]; +} + /////////////////////////////// @interface PreferencesDelegate : NSObject {} @@ -130,6 +159,79 @@ void setAppDefaults() else [[NSUserDefaults standardUserDefaults] setObject:PREF_AFTER_LAUNCHED_OPTION_LAST_ROM forKey:PREF_AFTER_LAUNCHED]; } + +- (void)bindingForKeyA:(id)sender +{ + NSString* key = [sender titleOfSelectedItem]; + [[NSUserDefaults standardUserDefaults] setValue:[keyboardMap valueForKey:key] forKey:PREF_KEY_A]; +} + +- (void)bindingForKeyB:(id)sender +{ + NSString* key = [sender titleOfSelectedItem]; + [[NSUserDefaults standardUserDefaults] setValue:[keyboardMap valueForKey:key] forKey:PREF_KEY_B]; +} + +- (void)bindingForKeyX:(id)sender +{ + NSString* key = [sender titleOfSelectedItem]; + [[NSUserDefaults standardUserDefaults] setValue:[keyboardMap valueForKey:key] forKey:PREF_KEY_X]; +} + +- (void)bindingForKeyY:(id)sender +{ + NSString* key = [sender titleOfSelectedItem]; + [[NSUserDefaults standardUserDefaults] setValue:[keyboardMap valueForKey:key] forKey:PREF_KEY_Y]; +} + +- (void)bindingForKeyL:(id)sender +{ + NSString* key = [sender titleOfSelectedItem]; + [[NSUserDefaults standardUserDefaults] setValue:[keyboardMap valueForKey:key] forKey:PREF_KEY_L]; +} + +- (void)bindingForKeyR:(id)sender +{ + NSString* key = [sender titleOfSelectedItem]; + [[NSUserDefaults standardUserDefaults] setValue:[keyboardMap valueForKey:key] forKey:PREF_KEY_R]; +} + +- (void)bindingForKeyUp:(id)sender +{ + NSString* key = [sender titleOfSelectedItem]; + [[NSUserDefaults standardUserDefaults] setValue:[keyboardMap valueForKey:key] forKey:PREF_KEY_UP]; +} + +- (void)bindingForKeyDown:(id)sender +{ + NSString* key = [sender titleOfSelectedItem]; + [[NSUserDefaults standardUserDefaults] setValue:[keyboardMap valueForKey:key] forKey:PREF_KEY_DOWN]; +} + +- (void)bindingForKeyLeft:(id)sender +{ + NSString* key = [sender titleOfSelectedItem]; + [[NSUserDefaults standardUserDefaults] setValue:[keyboardMap valueForKey:key] forKey:PREF_KEY_LEFT]; +} + +- (void)bindingForKeyRight:(id)sender +{ + NSString* key = [sender titleOfSelectedItem]; + [[NSUserDefaults standardUserDefaults] setValue:[keyboardMap valueForKey:key] forKey:PREF_KEY_RIGHT]; +} + +- (void)bindingForKeyStart:(id)sender +{ + NSString* key = [sender titleOfSelectedItem]; + [[NSUserDefaults standardUserDefaults] setValue:[keyboardMap valueForKey:key] forKey:PREF_KEY_START]; +} + +- (void)bindingForKeySelect:(id)sender +{ + NSString* key = [sender titleOfSelectedItem]; + [[NSUserDefaults standardUserDefaults] setValue:[keyboardMap valueForKey:key] forKey:PREF_KEY_SELECT]; +} + @end //////////////////////////////////////////////////// @@ -251,7 +353,7 @@ void setAppDefaults() - (NSArray*)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar { - return [NSArray arrayWithObjects:INTERFACE_INTERNAL_NAME, /*CONTROLS_INTERNAL_NAME, FIRMWARE_INTERNAL_NAME, */nil]; + return [NSArray arrayWithObjects:INTERFACE_INTERNAL_NAME, CONTROLS_INTERNAL_NAME, /*FIRMWARE_INTERNAL_NAME, */nil]; } - (NSArray*)toolbarSelectableItemIdentifiers:(NSToolbar*)toolbar @@ -326,7 +428,10 @@ NSView *createPreferencesView(NSString *helpinfo, NSDictionary *options, id dele //loop through each option in the options list //this is done backwards since we build the view upwards - NSArray *keys = [options allKeys]; + +// NSArray *keys = [options allKeys]; +NSArray* keys = [[options allKeys] sortedArrayUsingSelector:@selector(localizedCompare:)]; + NSEnumerator *key_enumerator = [keys reverseObjectEnumerator]; id key, key_raw, object; NSRect text_rect = NSMakeRect(5, 5, 220, 29); @@ -407,7 +512,8 @@ NSView *createPreferencesView(NSString *helpinfo, NSDictionary *options, id dele [view addSubview:button]; - } else if ([[object objectAtIndex:0] caseInsensitiveCompare:@"Text"] == NSOrderedSame) + } + else if ([[object objectAtIndex:0] caseInsensitiveCompare:@"Text"] == NSOrderedSame) { //if this preference is a text field @@ -426,6 +532,37 @@ NSView *createPreferencesView(NSString *helpinfo, NSDictionary *options, id dele [view addSubview:text]; } + else if([[object objectAtIndex:0] compare:@"Dictionary"] == NSOrderedSame) + { + //Create the button for this option + NSPopUpButton *button = [[NSPopUpButton alloc] initWithFrame:button_rect pullsDown:NO]; + + //button callback + SEL action; + [[object objectAtIndex:1] getBytes:&action]; + [button setAction:action]; + [button setTarget:delegate]; + + NSDictionary* keymap = [object objectAtIndex:2]; + + // Sort elements by name + NSArray* keys = [[keymap allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; + + int i; + + for(i = 0; i < [keys count]; i++) + { + //add the item to the popup buttons list + NSString* key = [keys objectAtIndex:i]; + [button addItemWithTitle:NSLocalizedString(key,nil)]; + + if ( [current_setting compare:[keymap valueForKey:key] ] == NSOrderedSame ) { + [button selectItemAtIndex:i]; + } + } + + [view addSubview:button]; + } //Create text for this option text_rect.size.height = [key sizeWithAttributes:preferences_font_attribs].height; @@ -497,8 +634,33 @@ NSView *createPreferencesView(NSString *helpinfo, NSDictionary *options, id dele NSView *interface_view = createPreferencesView(@"Use the popup buttons on the right to change settings", interface_options, delegate); - //Create the controls view (to be implemented in the future) - NSView *controls_view = nil; + + //Create the controls view + + setKeyboardMap(); + + NSDictionary *controls_options = [NSDictionary dictionaryWithObjectsAndKeys: + + [NSMutableArray arrayWithObjects:@"Dictionary", [NSData dataWithBytes:&@selector(bindingForKeyA:) length:sizeof(SEL)], keyboardMap , nil] , PREF_KEY_A, + [NSMutableArray arrayWithObjects:@"Dictionary", [NSData dataWithBytes:&@selector(bindingForKeyB:) length:sizeof(SEL)], keyboardMap , nil] , PREF_KEY_B, + [NSMutableArray arrayWithObjects:@"Dictionary", [NSData dataWithBytes:&@selector(bindingForKeyX:) length:sizeof(SEL)], keyboardMap , nil] , PREF_KEY_X, + [NSMutableArray arrayWithObjects:@"Dictionary", [NSData dataWithBytes:&@selector(bindingForKeyY:) length:sizeof(SEL)], keyboardMap , nil] , PREF_KEY_Y, + [NSMutableArray arrayWithObjects:@"Dictionary", [NSData dataWithBytes:&@selector(bindingForKeyL:) length:sizeof(SEL)], keyboardMap , nil] , PREF_KEY_L, + [NSMutableArray arrayWithObjects:@"Dictionary", [NSData dataWithBytes:&@selector(bindingForKeyR:) length:sizeof(SEL)], keyboardMap , nil] , PREF_KEY_R, + [NSMutableArray arrayWithObjects:@"Dictionary", [NSData dataWithBytes:&@selector(bindingForKeyUp:) length:sizeof(SEL)], keyboardMap , nil] , PREF_KEY_UP, + [NSMutableArray arrayWithObjects:@"Dictionary", [NSData dataWithBytes:&@selector(bindingForKeyDown:) length:sizeof(SEL)], keyboardMap , nil] , PREF_KEY_DOWN, + [NSMutableArray arrayWithObjects:@"Dictionary", [NSData dataWithBytes:&@selector(bindingForKeyLeft:) length:sizeof(SEL)], keyboardMap , nil] , PREF_KEY_LEFT, + [NSMutableArray arrayWithObjects:@"Dictionary", [NSData dataWithBytes:&@selector(bindingForKeyRight:) length:sizeof(SEL)], keyboardMap , nil] , PREF_KEY_RIGHT, + [NSMutableArray arrayWithObjects:@"Dictionary", [NSData dataWithBytes:&@selector(bindingForKeyStart:) length:sizeof(SEL)], keyboardMap , nil] , PREF_KEY_START, + [NSMutableArray arrayWithObjects:@"Dictionary", [NSData dataWithBytes:&@selector(bindingForKeySelect:) length:sizeof(SEL)], keyboardMap , nil] , PREF_KEY_SELECT, + + nil]; + + NSView *controls_view = createPreferencesView(@"Use the popup buttons on the right to change settings", controls_options, delegate); + + + + //create the preferences window NSWindow *preferences_window = [[NSWindow alloc] initWithContentRect:[interface_view frame] styleMask: