diff --git a/desmume/ChangeLog b/desmume/ChangeLog index df46f66f5..4945b06ba 100644 --- a/desmume/ChangeLog +++ b/desmume/ChangeLog @@ -15,6 +15,8 @@ - New ROM Info and About DeSmuME windows have been added. [Jeff B] - Fixed several bugs in window resizing. [Jeff B] - Added FAT image support for homebrew games (thanks to TypeError). [Jeff B] + - Key config can be changed on the command line. Save/load hotkeys changed (so expose doesn't override). [Jeff B] + - Key bindings may work better on non-US keyboards now (needs testing). [Jeff B] general: - Fixed possible segfault in ROMReader on ia64 and amd64. [evilynux] - Fixed a crash bug with 2D background corrupting memory [shash] diff --git a/desmume/README.MAC b/desmume/README.MAC index 8cb671fb5..367b41251 100644 --- a/desmume/README.MAC +++ b/desmume/README.MAC @@ -6,8 +6,8 @@ 1) Compiling instructions...................................13 2) How to use DeSmuME.......................................31 -3) Contact information......................................76 -4) Disclaimer...............................................93 +3) Contact information......................................78 +4) Disclaimer...............................................95 1 Compiling instructions______________________________________ @@ -59,12 +59,14 @@ n - Right Trigger enter - Start button space - Select button -Shift + F1 (through F10) will save the state with the -corresponding number. F1 (through F10) will load the state -with the corresponding number. +Keys can be customized with command line: +DeSmuME.app/Contents/MacOS/DeSmuME -KeyA v -KeyB b ... -NOTE: These key bindings may not be correct on foreign -keyboards. +KeyA, KeyB, KeyX, KeyY, KeyL, KeyR, KeyUp, KeyDown +KeyLeft, KeyRight, KeyStart, and KeySelect are all accepted. + +States can be saved with shift + number keys. +States can be loaded with the number keys. To set up a FAT disk image (for homebrew apps) you can use the "Emulation > Set FAT Image File" option in the menu. You can diff --git a/desmume/src/cflash.c b/desmume/src/cflash.c index 4d6be20e3..dc6eab6aa 100644 --- a/desmume/src/cflash.c +++ b/desmume/src/cflash.c @@ -636,7 +636,7 @@ cflash_read(unsigned int address) { if ( use_disk_image_file) { if ( disk_image != -1) { u8 data[2]; -#if 1 +#if 0 if ( currLBA < buffered_start_index || currLBA >= (buffered_start_index + BUFFERED_BLOCK_SIZE)) { size_t read_bytes = 0; diff --git a/desmume/src/cocoa/input.m b/desmume/src/cocoa/input.m index e9e30f75a..0fb53904a 100644 --- a/desmume/src/cocoa/input.m +++ b/desmume/src/cocoa/input.m @@ -19,34 +19,7 @@ #import "input.h" #import "main_window.h" - -//Default key config (based on the windows version) -unsigned short ds_up = 126; //up arrow -unsigned short ds_down = 125; //down arrow -unsigned short ds_left = 123; //left arrow -unsigned short ds_right = 124; //right arrrow -unsigned short ds_a = 9 ; //v -unsigned short ds_b = 11 ; //b -unsigned short ds_x = 5 ; //g -unsigned short ds_y = 4 ; //h -unsigned short ds_l = 8 ; //c -unsigned short ds_r = 45 ; //n -unsigned short ds_select = 49 ; //space bar -unsigned short ds_start = 36 ; //enter - -// -unsigned short save_slot_1 = 122; //F1 -unsigned short save_slot_2 = 120; //F2 -unsigned short save_slot_3 = 99; //F3 -unsigned short save_slot_4 = 118; //F4 -unsigned short save_slot_5 = 96; //F5 -unsigned short save_slot_6 = 97; //F6 -unsigned short save_slot_7 = 98; //F7 -unsigned short save_slot_8 = 100; //F8 -unsigned short save_slot_9 = 101; //F9 -unsigned short save_slot_10 = 109; //F10 -//unsigned short save_slot_11 = 103; //F11 -//unsigned short save_slot_12 = 111; //F12 +#import "preferences.h" @implementation InputHandler @@ -70,125 +43,47 @@ unsigned short save_slot_10 = 109; //F10 - (void)keyDown:(NSEvent*)event { if([event isARepeat])return; + + NSUserDefaults *settings = [NSUserDefaults standardUserDefaults]; + NSString *chars = [event characters]; - unsigned short keycode = [event keyCode]; - - if(keycode == ds_a)[my_ds pressA]; - else if(keycode == ds_b)[my_ds pressB]; - else if(keycode == ds_select)[my_ds pressSelect]; - else if(keycode == ds_start)[my_ds pressStart]; - else if(keycode == ds_right)[my_ds pressRight]; - else if(keycode == ds_left)[my_ds pressLeft]; - else if(keycode == ds_up)[my_ds pressUp]; - else if(keycode == ds_down)[my_ds pressDown]; - else if(keycode == ds_r)[my_ds pressR]; - else if(keycode == ds_l)[my_ds pressL]; - else if(keycode == ds_x)[my_ds pressX]; - else if(keycode == ds_y)[my_ds pressY]; + if([chars rangeOfString:[settings stringForKey:PREF_KEY_A ]].location!=NSNotFound)[my_ds pressA]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_B ]].location!=NSNotFound)[my_ds pressB]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_SELECT]].location!=NSNotFound)[my_ds pressSelect]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_START ]].location!=NSNotFound)[my_ds pressStart]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_RIGHT ]].location!=NSNotFound)[my_ds pressRight]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_LEFT ]].location!=NSNotFound)[my_ds pressLeft]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_UP ]].location!=NSNotFound)[my_ds pressUp]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_DOWN ]].location!=NSNotFound)[my_ds pressDown]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_R ]].location!=NSNotFound)[my_ds pressR]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_L ]].location!=NSNotFound)[my_ds pressL]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_X ]].location!=NSNotFound)[my_ds pressX]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_Y ]].location!=NSNotFound)[my_ds pressY]; } - (void)keyUp:(NSEvent*)event { - unsigned short keycode = [event keyCode]; + NSUserDefaults *settings = [NSUserDefaults standardUserDefaults]; + NSString *chars = [event characters]; - if(keycode == ds_a)[my_ds liftA]; - else if(keycode == ds_b)[my_ds liftB]; - else if(keycode == ds_select)[my_ds liftSelect]; - else if(keycode == ds_start)[my_ds liftStart]; - else if(keycode == ds_right)[my_ds liftRight]; - else if(keycode == ds_left)[my_ds liftLeft]; - else if(keycode == ds_up)[my_ds liftUp]; - else if(keycode == ds_down)[my_ds liftDown]; - else if(keycode == ds_r)[my_ds liftR]; - else if(keycode == ds_l)[my_ds liftL]; - else if(keycode == ds_x)[my_ds liftX]; - else if(keycode == ds_y)[my_ds liftY]; -/* - else if(keycode == save_slot_1) - { - if([event modifierFlags] & NSShiftKeyMask) - savestate_slot(1); - else - loadstate_slot(1); - } - - else if(keycode == save_slot_2) - { - if([event modifierFlags] & NSShiftKeyMask) - savestate_slot(2); - else - loadstate_slot(2); - } - - else if(keycode == save_slot_3) - { - if([event modifierFlags] & NSShiftKeyMask) - savestate_slot(3); - else - loadstate_slot(3); - } - - else if(keycode == save_slot_4) - { - if([event modifierFlags] & NSShiftKeyMask) - savestate_slot(4); - else - loadstate_slot(4); - } - - else if(keycode == save_slot_5) - { - if([event modifierFlags] & NSShiftKeyMask) - savestate_slot(5); - else - loadstate_slot(5); - } - - else if(keycode == save_slot_6) - { - if([event modifierFlags] & NSShiftKeyMask) - savestate_slot(6); - else - loadstate_slot(6); - } - - else if(keycode == save_slot_7) - { - if([event modifierFlags] & NSShiftKeyMask) - savestate_slot(7); - else - loadstate_slot(7); - } - - else if(keycode == save_slot_8) - { - if([event modifierFlags] & NSShiftKeyMask) - savestate_slot(8); - else - loadstate_slot(8); - } - - else if(keycode == save_slot_9) - { - if([event modifierFlags] & NSShiftKeyMask) - savestate_slot(9); - else - loadstate_slot(9); - } - - else if(keycode == save_slot_10) - { - if([event modifierFlags] & NSShiftKeyMask) - savestate_slot(10); - else - loadstate_slot(10); - } -*/ + if([chars rangeOfString:[settings stringForKey:PREF_KEY_A ]].location!=NSNotFound)[my_ds liftA]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_B ]].location!=NSNotFound)[my_ds liftB]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_SELECT]].location!=NSNotFound)[my_ds liftSelect]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_START ]].location!=NSNotFound)[my_ds liftStart]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_RIGHT ]].location!=NSNotFound)[my_ds liftRight]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_LEFT ]].location!=NSNotFound)[my_ds liftLeft]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_UP ]].location!=NSNotFound)[my_ds liftUp]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_DOWN ]].location!=NSNotFound)[my_ds liftDown]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_R ]].location!=NSNotFound)[my_ds liftR]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_L ]].location!=NSNotFound)[my_ds liftL]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_X ]].location!=NSNotFound)[my_ds liftX]; + else if([chars rangeOfString:[settings stringForKey:PREF_KEY_Y ]].location!=NSNotFound)[my_ds liftY]; } - (void)mouseDown:(NSEvent*)event { - [my_ds touch:[my_ds windowPointToDSCoords:[event locationInWindow]]]; + NSPoint temp = [my_ds windowPointToDSCoords:[event locationInWindow]]; + if(temp.x >= 0 && temp.y>=0)[my_ds touch:temp]; } - (void)mouseDragged:(NSEvent*)event diff --git a/desmume/src/cocoa/main.m b/desmume/src/cocoa/main.m index 93962936a..79c2bcf76 100644 --- a/desmume/src/cocoa/main.m +++ b/desmume/src/cocoa/main.m @@ -184,8 +184,11 @@ void CreateMenu(AppDelegate *delegate) for(i = 0; i < SAVE_SLOTS; i++) { - saveSlot_item[i] = [save_state_menu addItemWithTitle:[NSString stringWithFormat:NSLocalizedString(@"Slot %d", nil), i] action:@selector(saveToSlot:) keyEquivalent:@""]; - loadSlot_item[i] = [load_state_menu addItemWithTitle:[saveSlot_item[i] title] action:@selector(loadFromSlot:) keyEquivalent:@""]; + saveSlot_item[i] = [save_state_menu addItemWithTitle:[NSString stringWithFormat:NSLocalizedString(@"Slot %d", nil), i+1] action:@selector(saveToSlot:) keyEquivalent:[NSString stringWithFormat:@"%d", i<9?i+1:0]]; + [saveSlot_item[i] setKeyEquivalentModifierMask:NSShiftKeyMask]; + + loadSlot_item[i] = [load_state_menu addItemWithTitle:[saveSlot_item[i] title] action:@selector(loadFromSlot:) keyEquivalent:[NSString stringWithFormat:@"%d", i<9?i+1:0]]; + [loadSlot_item[i] setKeyEquivalentModifierMask:0]; } //fixme changed save state item function names diff --git a/desmume/src/cocoa/main_window.h b/desmume/src/cocoa/main_window.h index 911231e9a..651463a91 100644 --- a/desmume/src/cocoa/main_window.h +++ b/desmume/src/cocoa/main_window.h @@ -77,7 +77,7 @@ - (void)resizeScreen3x; - (void)resizeScreen4x; -//converts window coords to DS coords +//converts window coords to DS coords (returns -1, -1 if invalid) - (NSPoint)windowPointToDSCoords:(NSPoint)location; // @@ -106,4 +106,4 @@ //delegate - (void)windowDidBecomeMain:(NSNotification*)notification; -@end +@end diff --git a/desmume/src/cocoa/main_window.m b/desmume/src/cocoa/main_window.m index 14aa28d93..68146190d 100644 --- a/desmume/src/cocoa/main_window.m +++ b/desmume/src/cocoa/main_window.m @@ -392,6 +392,7 @@ NSMenuItem *screenshot_to_file_item; - (BOOL)loadStateFrom { NSOpenPanel *panel = [NSOpenPanel openPanel]; + [panel setTitle:NSLocalizedString(@"Load State From...", nil)]; [panel setCanChooseFiles:YES]; [panel setCanChooseDirectories:NO]; [panel setAllowsMultipleSelection:NO]; @@ -533,31 +534,30 @@ NSMenuItem *screenshot_to_file_item; - (NSPoint)windowPointToDSCoords:(NSPoint)location { -//FIXME way to return that point is outside of the window? NSSize temp = [[window contentView] frame].size; CGFloat x_size = temp.width - WINDOW_BORDER_PADDING*2; CGFloat y_size = temp.height - status_bar_height; //If the click was to the left or under the opengl view, exit if((location.x < WINDOW_BORDER_PADDING) || (location.y < status_bar_height)) - return NSMakePoint(0,0); + return NSMakePoint(-1, -1); location.x -= WINDOW_BORDER_PADDING; location.y -= status_bar_height; //If the click was top or right of the view... - if(location.x >= x_size)return NSMakePoint(0,0); - if(location.y >= y_size)return NSMakePoint(0,0); + if(location.x >= x_size)return NSMakePoint(-1, -1); + if(location.y >= y_size)return NSMakePoint(-1, -1); if([video_output_view rotation] == ROTATION_0 || [video_output_view rotation] == ROTATION_180) { if([video_output_view rotation] == ROTATION_180) { - if(location.y < y_size / 2)return NSMakePoint(0,0); + if(location.y < y_size / 2)return NSMakePoint(-1, -1); location.x = x_size - location.x; location.y = y_size - location.y; } else - if(location.y >= y_size / 2)return NSMakePoint(0,0); + if(location.y >= y_size / 2)return NSMakePoint(-1, -1); //scale the coordinates location.x *= ((float)DS_SCREEN_WIDTH) / ((float)x_size); @@ -571,12 +571,12 @@ NSMenuItem *screenshot_to_file_item; if([video_output_view rotation] == ROTATION_270) { - if(location.x < x_size / 2)return NSMakePoint(0,0); + if(location.x < x_size / 2)return NSMakePoint(-1, -1); location.x = x_size - location.x; } else { - if(location.x >= x_size / 2)return NSMakePoint(0,0); + if(location.x >= x_size / 2)return NSMakePoint(-1, -1); location.y = y_size - location.y; } diff --git a/desmume/src/cocoa/nds_control.h b/desmume/src/cocoa/nds_control.h index ff3895c9f..da42583f2 100644 --- a/desmume/src/cocoa/nds_control.h +++ b/desmume/src/cocoa/nds_control.h @@ -46,6 +46,7 @@ SEL error_func; id error_object; + NSLock *execution_lock; NSLock *sound_lock; ScreenState * volatile current_screen; diff --git a/desmume/src/cocoa/nds_control.m b/desmume/src/cocoa/nds_control.m index 21bf56d6c..6f5cf83f7 100644 --- a/desmume/src/cocoa/nds_control.m +++ b/desmume/src/cocoa/nds_control.m @@ -73,6 +73,7 @@ struct NDS_fw_config_data firmware; gui_thread = [NSThread currentThread]; current_file = nil; flash_file = nil; + execution_lock = [[NSLock alloc] init]; sound_lock = [[NSLock alloc] init]; current_screen = nil; @@ -197,6 +198,7 @@ struct NDS_fw_config_data firmware; [current_file release]; [flash_file release]; [sound_lock release]; + [execution_lock release]; NDS_DeInit(); @@ -432,22 +434,15 @@ struct NDS_fw_config_data firmware; - (void)reset { - //stop execution - BOOL old_run = run; - run = false; - while (!paused) - { + [execution_lock lock]; - } + NDS_Reset(); + + [execution_lock unlock]; //set the execute variable incase //of a previous emulation error execute = true; - - NDS_Reset(); - - //resume execution - run = old_run; } - (void)setFrameSkip:(int)frameskip @@ -697,28 +692,26 @@ struct NDS_fw_config_data firmware; - (BOOL)saveState:(NSString*)file { - bool was_executing = !paused; - [self pause]; + [execution_lock lock]; BOOL result = NO; if(savestate_save([file cStringUsingEncoding:NSASCIIStringEncoding])) result = YES; - if(was_executing)[self execute]; + [execution_lock unlock]; return result; } - (BOOL)loadState:(NSString*)file { - bool was_executing = !paused; - [self pause]; + [execution_lock lock]; BOOL result = NO; if(savestate_load([file cStringUsingEncoding:NSASCIIStringEncoding])) result = YES; - if(was_executing)[self execute]; + [execution_lock unlock]; return result; } @@ -728,15 +721,14 @@ struct NDS_fw_config_data firmware; if(slot >= MAX_SLOTS)return NO; if(slot < 0)return NO; - bool was_executing = !paused; - [self pause]; + [execution_lock lock]; BOOL result = NO; savestate_slot(slot + 1);//no execption handling? result = YES; - if(was_executing)[self execute]; + [execution_lock unlock]; return result; } @@ -746,15 +738,14 @@ struct NDS_fw_config_data firmware; if(slot >= MAX_SLOTS)return NO; if(slot < 0)return NO; - bool was_executing = !paused; - [self pause]; - BOOL result = NO; + [execution_lock lock]; + loadstate_slot(slot + 1); //no exection handling? result = YES; - if(was_executing)[self execute]; + [execution_lock unlock]; return result; } @@ -983,11 +974,15 @@ struct NDS_fw_config_data firmware; Microseconds((struct UnsignedWide*)&frame_start_time); + [execution_lock lock]; + cycles = NDS_exec((560190<<1)-cycles, FALSE); [sound_lock lock]; SPU_Emulate(); [sound_lock unlock]; + + [execution_lock unlock]; if(frames_to_skip > 0) frames_to_skip--; @@ -1004,6 +999,7 @@ struct NDS_fw_config_data firmware; //how much longer the frame took than it should have, then set it to skip //that many frames. frames_to_skip = ((double)(frame_end_time - frame_start_time)) / ((double)DS_MICROSECONDS_PER_FRAME); + if(frames_to_skip > 10)frames_to_skip = 10; } else { diff --git a/desmume/src/cocoa/preferences.h b/desmume/src/cocoa/preferences.h index ae5cddb9a..f404045a7 100644 --- a/desmume/src/cocoa/preferences.h +++ b/desmume/src/cocoa/preferences.h @@ -18,5 +18,18 @@ */ #define PREF_FLASH_FILE @"FlashFile" +#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" + 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 b95b26cfa..ea3d97ad7 100644 --- a/desmume/src/cocoa/preferences.m +++ b/desmume/src/cocoa/preferences.m @@ -230,6 +230,12 @@ NSView *createPreferencesView(NSTabViewItem *tab, NSDictionary *options, id dele return view; } +unsigned char utf8_return = 0x0D; +unsigned char utf8_right[3] = { 0xEF, 0x9C, 0x83 }; +unsigned char utf8_up[3] = { 0xEF, 0x9C, 0x80 }; +unsigned char utf8_down[3] = { 0xEF, 0x9C, 0x81 }; +unsigned char utf8_left[3] = { 0xEF, 0x9C, 0x82 }; + void setAppDefaults() { desmume_defaults = [NSDictionary dictionaryWithObjectsAndKeys: @@ -243,7 +249,20 @@ void setAppDefaults() //Flash file default @"", PREF_FLASH_FILE, - + + //Key defaults + @"v", PREF_KEY_A, + @"b", PREF_KEY_B, + @"g", PREF_KEY_X, + @"h", PREF_KEY_Y, + @"c", PREF_KEY_L, + @"n", PREF_KEY_R, + @" ", PREF_KEY_SELECT, + [[[NSString alloc] initWithBytesNoCopy:utf8_up length:3 encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease], PREF_KEY_UP, + [[[NSString alloc] initWithBytesNoCopy:utf8_down length:3 encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease], PREF_KEY_DOWN, + [[[NSString alloc] initWithBytesNoCopy:utf8_left length:3 encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease], PREF_KEY_LEFT, + [[[NSString alloc] initWithBytesNoCopy:utf8_right length:3 encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease], PREF_KEY_RIGHT, + [[[NSString alloc] initWithBytesNoCopy:&utf8_return length:1 encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease], PREF_KEY_START, nil]; [desmume_defaults retain];