Cocoa Port:

- Add controls for frame advance, frame jump, and display mode toggle.
- Add new execution control panel. (Emulation > Show Execution Control)
- Reorganize several menu items in the Emulation and View menus.
This commit is contained in:
rogerman 2014-01-29 08:36:47 +00:00
parent db94b7c8a6
commit 47b2b6eac6
21 changed files with 3408 additions and 1240 deletions

View File

@ -1101,6 +1101,21 @@
ABBCE29715ACB1FF00A2C965 /* arm_jit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABBCE29515ACB1FF00A2C965 /* arm_jit.cpp */; };
ABBCE29815ACB1FF00A2C965 /* arm_jit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABBCE29515ACB1FF00A2C965 /* arm_jit.cpp */; };
ABBF04A614B515F300E505A0 /* AppIcon_ROMCheats.icns in Resources */ = {isa = PBXBuildFile; fileRef = ABBF04A414B515F300E505A0 /* AppIcon_ROMCheats.icns */; };
ABBFDFA71898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFA61898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png */; };
ABBFDFA81898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFA61898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png */; };
ABBFDFA91898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFA61898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png */; };
ABBFDFAA1898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFA61898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png */; };
ABBFDFAB1898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFA61898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png */; };
ABBFDFAE1898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFAC1898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png */; };
ABBFDFAF1898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFAD1898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png */; };
ABBFDFB01898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFAC1898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png */; };
ABBFDFB11898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFAD1898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png */; };
ABBFDFB21898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFAC1898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png */; };
ABBFDFB31898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFAD1898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png */; };
ABBFDFB41898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFAC1898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png */; };
ABBFDFB51898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFAD1898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png */; };
ABBFDFB61898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFAC1898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png */; };
ABBFDFB71898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABBFDFAD1898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png */; };
ABC3AF3314B7F06900D5B13D /* Icon_VolumeFull_16x16.png in Resources */ = {isa = PBXBuildFile; fileRef = ABC3AF2B14B7F06900D5B13D /* Icon_VolumeFull_16x16.png */; };
ABC3AF3414B7F06900D5B13D /* Icon_VolumeMute_16x16.png in Resources */ = {isa = PBXBuildFile; fileRef = ABC3AF2C14B7F06900D5B13D /* Icon_VolumeMute_16x16.png */; };
ABC3AF3514B7F06900D5B13D /* Icon_VolumeOneThird_16x16.png in Resources */ = {isa = PBXBuildFile; fileRef = ABC3AF2D14B7F06900D5B13D /* Icon_VolumeOneThird_16x16.png */; };
@ -1219,7 +1234,7 @@
29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
AB00E87A14205EAE00DE561F /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = translations/English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
AB00E87A14205EAE00DE561F /* English */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; lineEnding = 0; name = English; path = translations/English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
AB00E87D14205EBC00DE561F /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = translations/English.lproj/MainMenu.xib; sourceTree = "<group>"; };
AB00E89114205ECC00DE561F /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; lineEnding = 0; name = English; path = translations/English.lproj/Localizable.strings; sourceTree = "<group>"; };
AB02475B13886BF300E9F9AB /* KeyNames.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = KeyNames.plist; sourceTree = "<group>"; };
@ -1390,6 +1405,9 @@
ABBCE29D15ACB26100A2C965 /* instruction_attributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = instruction_attributes.h; path = ../instruction_attributes.h; sourceTree = SOURCE_ROOT; };
ABBCE29E15ACB26100A2C965 /* instructions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = instructions.h; path = ../instructions.h; sourceTree = SOURCE_ROOT; };
ABBF04A414B515F300E505A0 /* AppIcon_ROMCheats.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_ROMCheats.icns; sourceTree = "<group>"; };
ABBFDFA61898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_DisplayToggle_420x420.png; path = images/Icon_DisplayToggle_420x420.png; sourceTree = "<group>"; };
ABBFDFAC1898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_FrameAdvance_420x420.png; path = images/Icon_FrameAdvance_420x420.png; sourceTree = "<group>"; };
ABBFDFAD1898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_FrameJump_420x420.png; path = images/Icon_FrameJump_420x420.png; sourceTree = "<group>"; };
ABC3AF2B14B7F06900D5B13D /* Icon_VolumeFull_16x16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_VolumeFull_16x16.png; path = images/Icon_VolumeFull_16x16.png; sourceTree = "<group>"; };
ABC3AF2C14B7F06900D5B13D /* Icon_VolumeMute_16x16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_VolumeMute_16x16.png; path = images/Icon_VolumeMute_16x16.png; sourceTree = "<group>"; };
ABC3AF2D14B7F06900D5B13D /* Icon_VolumeOneThird_16x16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_VolumeOneThird_16x16.png; path = images/Icon_VolumeOneThird_16x16.png; sourceTree = "<group>"; };
@ -1993,6 +2011,7 @@
AB0F296C14BE705D009ABC6F /* Icon_CodeBreaker_128x128.png */,
ABB97874144E89CC00793FA3 /* Icon_CodeBreaker_32x32.png */,
ABB97875144E89CC00793FA3 /* Icon_DeSmuME_32x32.png */,
ABBFDFA61898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png */,
AB0F299414BE7213009ABC6F /* Icon_DoubleSpeed_420x420.png */,
AB0F299514BE7213009ABC6F /* Icon_DSButtonA_420x420.png */,
AB0F299614BE7213009ABC6F /* Icon_DSButtonB_420x420.png */,
@ -2004,6 +2023,8 @@
AB0F299C14BE7213009ABC6F /* Icon_DSButtonY_420x420.png */,
AB0F299D14BE7213009ABC6F /* Icon_Emulation_420x420.png */,
AB0F28FE14BE6E68009ABC6F /* Icon_Execute_420x420.png */,
ABBFDFAC1898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png */,
ABBFDFAD1898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png */,
ABD59813187D417900069403 /* Icon_GuitarGrip_Button_Blue_512x512.png */,
ABD59814187D417900069403 /* Icon_GuitarGrip_Button_Green_512x512.png */,
ABD59815187D417900069403 /* Icon_GuitarGrip_Button_Red_512x512.png */,
@ -2653,6 +2674,9 @@
ABD5982A187D417900069403 /* Icon_GuitarGrip_Button_Yellow_512x512.png in Resources */,
ABD5983B187D466700069403 /* Icon_Piano_256x256.png in Resources */,
ABD5984B187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */,
ABBFDFAB1898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png in Resources */,
ABBFDFB61898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png in Resources */,
ABBFDFB71898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2743,6 +2767,9 @@
ABD5981A187D417900069403 /* Icon_GuitarGrip_Button_Yellow_512x512.png in Resources */,
ABD59837187D466700069403 /* Icon_Piano_256x256.png in Resources */,
ABD59847187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */,
ABBFDFA81898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png in Resources */,
ABBFDFB01898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png in Resources */,
ABBFDFB11898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2833,6 +2860,9 @@
ABD5981E187D417900069403 /* Icon_GuitarGrip_Button_Yellow_512x512.png in Resources */,
ABD59838187D466700069403 /* Icon_Piano_256x256.png in Resources */,
ABD59848187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */,
ABBFDFA71898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png in Resources */,
ABBFDFAE1898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png in Resources */,
ABBFDFAF1898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2923,6 +2953,9 @@
ABD59826187D417900069403 /* Icon_GuitarGrip_Button_Yellow_512x512.png in Resources */,
ABD5983A187D466700069403 /* Icon_Piano_256x256.png in Resources */,
ABD5984A187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */,
ABBFDFAA1898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png in Resources */,
ABBFDFB41898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png in Resources */,
ABBFDFB51898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3013,6 +3046,9 @@
ABD59822187D417900069403 /* Icon_GuitarGrip_Button_Yellow_512x512.png in Resources */,
ABD59839187D466700069403 /* Icon_Piano_256x256.png in Resources */,
ABD59849187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */,
ABBFDFA91898EE3200A3FFA5 /* Icon_DisplayToggle_420x420.png in Resources */,
ABBFDFB21898EE4B00A3FFA5 /* Icon_FrameAdvance_420x420.png in Resources */,
ABBFDFB31898EE4B00A3FFA5 /* Icon_FrameJump_420x420.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -408,6 +408,12 @@
AB8967DE16D2ED2700F826F1 /* DisplayWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB8967DB16D2ED2700F826F1 /* DisplayWindow.xib */; };
AB901BDE1420706100348EEC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = AB901BDD1420706100348EEC /* Localizable.strings */; };
AB91D46B13BD013800462471 /* fs-linux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FEB21345AC8400AF11D1 /* fs-linux.cpp */; };
AB9A1F911898F0E7000DF924 /* Icon_DisplayToggle_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = AB9A1F901898F0E7000DF924 /* Icon_DisplayToggle_420x420.png */; };
AB9A1F921898F0E7000DF924 /* Icon_DisplayToggle_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = AB9A1F901898F0E7000DF924 /* Icon_DisplayToggle_420x420.png */; };
AB9A1F951898F0F7000DF924 /* Icon_FrameAdvance_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = AB9A1F931898F0F7000DF924 /* Icon_FrameAdvance_420x420.png */; };
AB9A1F961898F0F7000DF924 /* Icon_FrameAdvance_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = AB9A1F931898F0F7000DF924 /* Icon_FrameAdvance_420x420.png */; };
AB9A1F971898F0F7000DF924 /* Icon_FrameJump_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = AB9A1F941898F0F7000DF924 /* Icon_FrameJump_420x420.png */; };
AB9A1F981898F0F7000DF924 /* Icon_FrameJump_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = AB9A1F941898F0F7000DF924 /* Icon_FrameJump_420x420.png */; };
ABA6574B14511EC90077E5E9 /* cocoa_cheat.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABA6574A14511EC90077E5E9 /* cocoa_cheat.mm */; };
ABACB8DC1710B621003B845D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABACB8DB1710B621003B845D /* AudioToolbox.framework */; };
ABACB8DD1710B656003B845D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABACB8DB1710B621003B845D /* AudioToolbox.framework */; };
@ -888,6 +894,9 @@
AB901BE31420707D00348EEC /* Norwegian */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; lineEnding = 0; name = Norwegian; path = translations/Norwegian.lproj/Localizable.strings; sourceTree = "<group>"; };
AB901BE41420708200348EEC /* Romanian */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; lineEnding = 0; name = Romanian; path = translations/Romanian.lproj/Localizable.strings; sourceTree = "<group>"; };
AB9971CE134EDA0800531BA7 /* cocoa_globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_globals.h; sourceTree = "<group>"; };
AB9A1F901898F0E7000DF924 /* Icon_DisplayToggle_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_DisplayToggle_420x420.png; path = images/Icon_DisplayToggle_420x420.png; sourceTree = "<group>"; };
AB9A1F931898F0F7000DF924 /* Icon_FrameAdvance_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_FrameAdvance_420x420.png; path = images/Icon_FrameAdvance_420x420.png; sourceTree = "<group>"; };
AB9A1F941898F0F7000DF924 /* Icon_FrameJump_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_FrameJump_420x420.png; path = images/Icon_FrameJump_420x420.png; sourceTree = "<group>"; };
ABA6574914511EC90077E5E9 /* cocoa_cheat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_cheat.h; sourceTree = "<group>"; };
ABA6574A14511EC90077E5E9 /* cocoa_cheat.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_cheat.mm; sourceTree = "<group>"; };
ABACB8DB1710B621003B845D /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
@ -1539,6 +1548,7 @@
AB0F296C14BE705D009ABC6F /* Icon_CodeBreaker_128x128.png */,
ABB97874144E89CC00793FA3 /* Icon_CodeBreaker_32x32.png */,
ABB97875144E89CC00793FA3 /* Icon_DeSmuME_32x32.png */,
AB9A1F901898F0E7000DF924 /* Icon_DisplayToggle_420x420.png */,
AB0F299414BE7213009ABC6F /* Icon_DoubleSpeed_420x420.png */,
AB0F299514BE7213009ABC6F /* Icon_DSButtonA_420x420.png */,
AB0F299614BE7213009ABC6F /* Icon_DSButtonB_420x420.png */,
@ -1550,6 +1560,8 @@
AB0F299C14BE7213009ABC6F /* Icon_DSButtonY_420x420.png */,
AB0F299D14BE7213009ABC6F /* Icon_Emulation_420x420.png */,
AB0F28FE14BE6E68009ABC6F /* Icon_Execute_420x420.png */,
AB9A1F931898F0F7000DF924 /* Icon_FrameAdvance_420x420.png */,
AB9A1F941898F0F7000DF924 /* Icon_FrameJump_420x420.png */,
ABBCA20D187D4BED00383DBE /* Icon_GuitarGrip_Button_Blue_512x512.png */,
ABBCA20E187D4BED00383DBE /* Icon_GuitarGrip_Button_Green_512x512.png */,
ABBCA20F187D4BED00383DBE /* Icon_GuitarGrip_Button_Red_512x512.png */,
@ -2020,6 +2032,7 @@
ABC3AF3114B7F06900D5B13D /* Icon_VolumeOneThird_16x16.png in Resources */,
ABC3AF3214B7F06900D5B13D /* Icon_VolumeTwoThird_16x16.png in Resources */,
AB0F290214BE6E68009ABC6F /* Icon_Execute_420x420.png in Resources */,
AB9A1F981898F0F7000DF924 /* Icon_FrameJump_420x420.png in Resources */,
AB0F290314BE6E68009ABC6F /* Icon_Pause_420x420.png in Resources */,
AB0F290414BE6E68009ABC6F /* Icon_Speed1x_420x420.png in Resources */,
AB0F290514BE6E68009ABC6F /* Icon_Speed2x_420x420.png in Resources */,
@ -2051,11 +2064,13 @@
AB0F29A814BE7213009ABC6F /* Icon_DSButtonB_420x420.png in Resources */,
AB0F29A914BE7213009ABC6F /* Icon_DSButtonL_420x420.png in Resources */,
AB0F29AA14BE7213009ABC6F /* Icon_DSButtonR_420x420.png in Resources */,
AB9A1F921898F0E7000DF924 /* Icon_DisplayToggle_420x420.png in Resources */,
AB0F29AB14BE7213009ABC6F /* Icon_DSButtonSelect_420x420.png in Resources */,
AB0F29AC14BE7213009ABC6F /* Icon_DSButtonStart_420x420.png in Resources */,
AB0F29AD14BE7213009ABC6F /* Icon_DSButtonX_420x420.png in Resources */,
AB0F29AE14BE7213009ABC6F /* Icon_DSButtonY_420x420.png in Resources */,
AB0F29AF14BE7213009ABC6F /* Icon_Emulation_420x420.png in Resources */,
AB9A1F961898F0F7000DF924 /* Icon_FrameAdvance_420x420.png in Resources */,
AB0F29B014BE7213009ABC6F /* Icon_Input_420x420.png in Resources */,
AB0F29B114BE7213009ABC6F /* Icon_Microphone_420x420.png in Resources */,
AB0F29B214BE7213009ABC6F /* Icon_OpenROM_420x420.png in Resources */,
@ -2110,6 +2125,7 @@
AB796CB915CDCBA200C59155 /* Icon_VolumeOneThird_16x16.png in Resources */,
AB796CBA15CDCBA200C59155 /* Icon_VolumeTwoThird_16x16.png in Resources */,
AB796CBB15CDCBA200C59155 /* Icon_Execute_420x420.png in Resources */,
AB9A1F971898F0F7000DF924 /* Icon_FrameJump_420x420.png in Resources */,
AB796CBC15CDCBA200C59155 /* Icon_Pause_420x420.png in Resources */,
AB796CBD15CDCBA200C59155 /* Icon_Speed1x_420x420.png in Resources */,
AB796CBE15CDCBA200C59155 /* Icon_Speed2x_420x420.png in Resources */,
@ -2141,11 +2157,13 @@
AB796CD815CDCBA200C59155 /* Icon_DSButtonB_420x420.png in Resources */,
AB796CD915CDCBA200C59155 /* Icon_DSButtonL_420x420.png in Resources */,
AB796CDA15CDCBA200C59155 /* Icon_DSButtonR_420x420.png in Resources */,
AB9A1F911898F0E7000DF924 /* Icon_DisplayToggle_420x420.png in Resources */,
AB796CDB15CDCBA200C59155 /* Icon_DSButtonSelect_420x420.png in Resources */,
AB796CDC15CDCBA200C59155 /* Icon_DSButtonStart_420x420.png in Resources */,
AB796CDD15CDCBA200C59155 /* Icon_DSButtonX_420x420.png in Resources */,
AB796CDE15CDCBA200C59155 /* Icon_DSButtonY_420x420.png in Resources */,
AB796CDF15CDCBA200C59155 /* Icon_Emulation_420x420.png in Resources */,
AB9A1F951898F0F7000DF924 /* Icon_FrameAdvance_420x420.png in Resources */,
AB796CE015CDCBA200C59155 /* Icon_Input_420x420.png in Resources */,
AB796CE115CDCBA200C59155 /* Icon_Microphone_420x420.png in Resources */,
AB796CE215CDCBA200C59155 /* Icon_OpenROM_420x420.png in Resources */,

View File

@ -672,6 +672,12 @@
ABD1FF9F1345ACFA00AF11D1 /* metaspu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF771345ACFA00AF11D1 /* metaspu.cpp */; };
ABD42047172319D1006A9B46 /* FileMigrationDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD42046172319D1006A9B46 /* FileMigrationDelegate.mm */; };
ABD42048172319D1006A9B46 /* FileMigrationDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD42046172319D1006A9B46 /* FileMigrationDelegate.mm */; };
ABDDF7C51898F024007583C1 /* Icon_DisplayToggle_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABDDF7C41898F024007583C1 /* Icon_DisplayToggle_420x420.png */; };
ABDDF7C61898F024007583C1 /* Icon_DisplayToggle_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABDDF7C41898F024007583C1 /* Icon_DisplayToggle_420x420.png */; };
ABDDF7C91898F032007583C1 /* Icon_FrameAdvance_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABDDF7C71898F032007583C1 /* Icon_FrameAdvance_420x420.png */; };
ABDDF7CA1898F032007583C1 /* Icon_FrameAdvance_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABDDF7C71898F032007583C1 /* Icon_FrameAdvance_420x420.png */; };
ABDDF7CB1898F032007583C1 /* Icon_FrameJump_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABDDF7C81898F032007583C1 /* Icon_FrameJump_420x420.png */; };
ABDDF7CC1898F032007583C1 /* Icon_FrameJump_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = ABDDF7C81898F032007583C1 /* Icon_FrameJump_420x420.png */; };
ABE5DE95143F781900835AD8 /* videofilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB817A35143EE2DB00A7DFE9 /* videofilter.cpp */; };
ABE5DFE5143FB1DA00835AD8 /* cocoa_videofilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABE5DFE4143FB1DA00835AD8 /* cocoa_videofilter.mm */; };
ABE6702B1415DE6C00E8E4C9 /* tinystr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABE670251415DE6C00E8E4C9 /* tinystr.cpp */; };
@ -703,7 +709,7 @@
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8D1107320486CEB800E47090 /* DeSmuME (Debug).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (Debug).app"; sourceTree = BUILT_PRODUCTS_DIR; };
AB0038A61872A96700B0B055 /* Image_PaddleController.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Image_PaddleController.png; path = images/Image_PaddleController.png; sourceTree = "<group>"; };
AB00E87A14205EAE00DE561F /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = translations/English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
AB00E87A14205EAE00DE561F /* English */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; name = English; path = translations/English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
AB00E87D14205EBC00DE561F /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = translations/English.lproj/MainMenu.xib; sourceTree = "<group>"; };
AB00E89114205ECC00DE561F /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; lineEnding = 0; name = English; path = translations/English.lproj/Localizable.strings; sourceTree = "<group>"; };
AB01005C170D07AF00D70FBE /* InputProfileController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputProfileController.h; sourceTree = "<group>"; };
@ -1141,6 +1147,9 @@
ABD1FF9B1345ACFA00AF11D1 /* Timestretcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timestretcher.cpp; sourceTree = "<group>"; };
ABD42045172319D1006A9B46 /* FileMigrationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileMigrationDelegate.h; sourceTree = "<group>"; };
ABD42046172319D1006A9B46 /* FileMigrationDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FileMigrationDelegate.mm; sourceTree = "<group>"; };
ABDDF7C41898F024007583C1 /* Icon_DisplayToggle_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_DisplayToggle_420x420.png; path = ../../../../../../../Volumes/rogerman/desmume/trunk/desmume/src/cocoa/images/Icon_DisplayToggle_420x420.png; sourceTree = "<group>"; };
ABDDF7C71898F032007583C1 /* Icon_FrameAdvance_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_FrameAdvance_420x420.png; path = ../../../../../../../Volumes/rogerman/desmume/trunk/desmume/src/cocoa/images/Icon_FrameAdvance_420x420.png; sourceTree = "<group>"; };
ABDDF7C81898F032007583C1 /* Icon_FrameJump_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_FrameJump_420x420.png; path = ../../../../../../../Volumes/rogerman/desmume/trunk/desmume/src/cocoa/images/Icon_FrameJump_420x420.png; sourceTree = "<group>"; };
ABE5DFE3143FB1DA00835AD8 /* cocoa_videofilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_videofilter.h; sourceTree = "<group>"; };
ABE5DFE4143FB1DA00835AD8 /* cocoa_videofilter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_videofilter.mm; sourceTree = "<group>"; };
ABE670251415DE6C00E8E4C9 /* tinystr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinystr.cpp; sourceTree = "<group>"; };
@ -1539,6 +1548,7 @@
AB0F296C14BE705D009ABC6F /* Icon_CodeBreaker_128x128.png */,
ABB97874144E89CC00793FA3 /* Icon_CodeBreaker_32x32.png */,
ABB97875144E89CC00793FA3 /* Icon_DeSmuME_32x32.png */,
ABDDF7C41898F024007583C1 /* Icon_DisplayToggle_420x420.png */,
AB0F299414BE7213009ABC6F /* Icon_DoubleSpeed_420x420.png */,
AB0F299514BE7213009ABC6F /* Icon_DSButtonA_420x420.png */,
AB0F299614BE7213009ABC6F /* Icon_DSButtonB_420x420.png */,
@ -1550,6 +1560,8 @@
AB0F299C14BE7213009ABC6F /* Icon_DSButtonY_420x420.png */,
AB0F299D14BE7213009ABC6F /* Icon_Emulation_420x420.png */,
AB0F28FE14BE6E68009ABC6F /* Icon_Execute_420x420.png */,
ABDDF7C71898F032007583C1 /* Icon_FrameAdvance_420x420.png */,
ABDDF7C81898F032007583C1 /* Icon_FrameJump_420x420.png */,
AB681013187D4AEF0049F2C2 /* Icon_GuitarGrip_Button_Blue_512x512.png */,
AB681014187D4AEF0049F2C2 /* Icon_GuitarGrip_Button_Green_512x512.png */,
AB681015187D4AEF0049F2C2 /* Icon_GuitarGrip_Button_Red_512x512.png */,
@ -2020,6 +2032,7 @@
ABC3AF3014B7F06900D5B13D /* Icon_VolumeMute_16x16.png in Resources */,
ABC3AF3114B7F06900D5B13D /* Icon_VolumeOneThird_16x16.png in Resources */,
ABC3AF3214B7F06900D5B13D /* Icon_VolumeTwoThird_16x16.png in Resources */,
ABDDF7CC1898F032007583C1 /* Icon_FrameJump_420x420.png in Resources */,
AB0F290214BE6E68009ABC6F /* Icon_Execute_420x420.png in Resources */,
AB0F290314BE6E68009ABC6F /* Icon_Pause_420x420.png in Resources */,
AB0F290414BE6E68009ABC6F /* Icon_Speed1x_420x420.png in Resources */,
@ -2051,11 +2064,13 @@
AB0F298C14BE71E0009ABC6F /* Icon_ArrowDown_420x420.png in Resources */,
AB0F298D14BE71E0009ABC6F /* Icon_ArrowLeft_420x420.png in Resources */,
AB0F298E14BE71E0009ABC6F /* Icon_ArrowRight_420x420.png in Resources */,
ABDDF7C61898F024007583C1 /* Icon_DisplayToggle_420x420.png in Resources */,
AB0F298F14BE71E0009ABC6F /* Icon_ArrowUp_420x420.png in Resources */,
AB0F29A614BE7213009ABC6F /* Icon_DoubleSpeed_420x420.png in Resources */,
AB0F29A714BE7213009ABC6F /* Icon_DSButtonA_420x420.png in Resources */,
AB0F29A814BE7213009ABC6F /* Icon_DSButtonB_420x420.png in Resources */,
AB681028187D4AEF0049F2C2 /* Icon_Piano_256x256.png in Resources */,
ABDDF7CA1898F032007583C1 /* Icon_FrameAdvance_420x420.png in Resources */,
AB0F29A914BE7213009ABC6F /* Icon_DSButtonL_420x420.png in Resources */,
AB0F29AA14BE7213009ABC6F /* Icon_DSButtonR_420x420.png in Resources */,
AB0F29AB14BE7213009ABC6F /* Icon_DSButtonSelect_420x420.png in Resources */,
@ -2110,6 +2125,7 @@
AB796CB815CDCBA200C59155 /* Icon_VolumeMute_16x16.png in Resources */,
AB796CB915CDCBA200C59155 /* Icon_VolumeOneThird_16x16.png in Resources */,
AB796CBA15CDCBA200C59155 /* Icon_VolumeTwoThird_16x16.png in Resources */,
ABDDF7CB1898F032007583C1 /* Icon_FrameJump_420x420.png in Resources */,
AB796CBB15CDCBA200C59155 /* Icon_Execute_420x420.png in Resources */,
AB796CBC15CDCBA200C59155 /* Icon_Pause_420x420.png in Resources */,
AB796CBD15CDCBA200C59155 /* Icon_Speed1x_420x420.png in Resources */,
@ -2141,11 +2157,13 @@
AB796CD215CDCBA200C59155 /* Icon_ArrowDown_420x420.png in Resources */,
AB796CD315CDCBA200C59155 /* Icon_ArrowLeft_420x420.png in Resources */,
AB796CD415CDCBA200C59155 /* Icon_ArrowRight_420x420.png in Resources */,
ABDDF7C51898F024007583C1 /* Icon_DisplayToggle_420x420.png in Resources */,
AB796CD515CDCBA200C59155 /* Icon_ArrowUp_420x420.png in Resources */,
AB796CD615CDCBA200C59155 /* Icon_DoubleSpeed_420x420.png in Resources */,
AB796CD715CDCBA200C59155 /* Icon_DSButtonA_420x420.png in Resources */,
AB796CD815CDCBA200C59155 /* Icon_DSButtonB_420x420.png in Resources */,
AB681027187D4AEF0049F2C2 /* Icon_Piano_256x256.png in Resources */,
ABDDF7C91898F032007583C1 /* Icon_FrameAdvance_420x420.png in Resources */,
AB796CD915CDCBA200C59155 /* Icon_DSButtonL_420x420.png in Resources */,
AB796CDA15CDCBA200C59155 /* Icon_DSButtonR_420x420.png in Resources */,
AB796CDB15CDCBA200C59155 /* Icon_DSButtonSelect_420x420.png in Resources */,

View File

@ -39,6 +39,8 @@
<string>Piano: High C</string>
<string>Paddle</string>
<string>Execute/Pause</string>
<string>Frame Advance</string>
<string>Frame Jump</string>
<string>Reset</string>
<string>Mute/Unmute</string>
<string>Load State Slot</string>
@ -46,6 +48,7 @@
<string>Copy Screen</string>
<string>Rotate Display Left</string>
<string>Rotate Display Right</string>
<string>Toggle All Displays</string>
<string>Set Speed</string>
<string>Enable/Disable Speed Limiter</string>
<string>Enable/Disable Auto Frame Skip</string>
@ -622,6 +625,10 @@
<string>Forward Delete</string>
</dict>
</array>
<key>Frame Advance</key>
<array/>
<key>Frame Jump</key>
<array/>
<key>Reset</key>
<array>
<dict>
@ -679,6 +686,8 @@
<integer>90</integer>
</dict>
</array>
<key>Toggle All Displays</key>
<array/>
<key>Set Speed</key>
<array>
<dict>

View File

@ -164,6 +164,10 @@
<string>Forward Delete</string>
</dict>
</array>
<key>Frame Advance</key>
<array/>
<key>Frame Jump</key>
<array/>
<key>Guitar Grip: Blue</key>
<array>
<dict>
@ -611,6 +615,8 @@
<string>Return</string>
</dict>
</array>
<key>Toggle All Displays</key>
<array/>
<key>Touch</key>
<array>
<dict>

View File

@ -35,6 +35,7 @@ typedef struct
int state;
bool isFrameSkipEnabled;
size_t frameCount;
NSUInteger frameJumpTarget;
int framesToSkip;
uint64_t timeBudgetMachAbsTime;
bool exitThread;
@ -72,6 +73,8 @@ typedef struct
NSInteger cpuEmulationEngine;
NSInteger slot1DeviceType;
NSString *slot1StatusText;
NSString *frameStatus;
NSString *executionSpeedStatus;
NSURL *slot1R4URL;
@ -110,6 +113,8 @@ typedef struct
@property (assign) NSInteger maxJITBlockSize;
@property (assign) NSInteger slot1DeviceType;
@property (assign) NSString *slot1StatusText;
@property (assign) NSString *frameStatus;
@property (assign) NSString *executionSpeedStatus;
@property (copy) NSURL *arm9ImageURL;
@property (copy) NSURL *arm7ImageURL;
@ -133,6 +138,9 @@ typedef struct
- (void) restoreCoreState;
- (void) reset;
- (NSUInteger) frameNumber;
- (void) frameJumpTo:(NSUInteger)targetFrameNum;
- (void) frameJump:(NSUInteger)relativeFrameNum;
- (void) addOutput:(CocoaDSOutput *)theOutput;
- (void) removeOutput:(CocoaDSOutput *)theOutput;

View File

@ -31,6 +31,7 @@
#include "../NDSSystem.h"
#include "../slot1.h"
#include "../slot2.h"
#include "../movie.h"
#undef BOOL
@ -65,6 +66,8 @@ volatile bool execute = true;
@dynamic maxJITBlockSize;
@synthesize slot1DeviceType;
@synthesize slot1StatusText;
@synthesize frameStatus;
@synthesize executionSpeedStatus;
@dynamic arm9ImageURL;
@dynamic arm7ImageURL;
@ -122,6 +125,7 @@ static BOOL isCoreStarted = NO;
threadParam.isFrameSkipEnabled = true;
threadParam.frameCount = 0;
threadParam.framesToSkip = 0;
threadParam.frameJumpTarget = 0;
uint64_t timeBudgetNanoseconds = (uint64_t)(DS_SECONDS_PER_FRAME * 1000000000.0 / speedScalar);
AbsoluteTime timeBudgetAbsTime = NanosecondsToAbsolute(*(Nanoseconds *)&timeBudgetNanoseconds);
@ -136,6 +140,9 @@ static BOOL isCoreStarted = NO;
[cdsGPU setMutexProducer:self.mutexCoreExecute];
frameStatus = @"---";
executionSpeedStatus = @"1.00x";
return self;
}
@ -497,16 +504,33 @@ static BOOL isCoreStarted = NO;
{
pthread_mutex_lock(&threadParam.mutexThreadExecute);
if (threadParam.state == CORESTATE_PAUSE)
if (threadParam.state == CORESTATE_EXECUTE || threadParam.state == CORESTATE_PAUSE)
{
prevCoreState = CORESTATE_PAUSE;
}
else
{
prevCoreState = CORESTATE_EXECUTE;
prevCoreState = threadParam.state;
}
threadParam.state = coreState;
threadParam.framesToSkip = 0;
switch (coreState)
{
case CORESTATE_PAUSE:
case CORESTATE_FRAMEADVANCE:
[self setFrameStatus:[NSString stringWithFormat:@"%lld", (unsigned long)[self frameNumber]]];
break;
case CORESTATE_EXECUTE:
[self setFrameStatus:@"Executing..."];
break;
case CORESTATE_FRAMEJUMP:
[self setFrameStatus:[NSString stringWithFormat:@"Jumping to frame %lld.", (unsigned long)threadParam.frameJumpTarget]];
break;
default:
break;
}
pthread_cond_signal(&threadParam.condThreadExecute);
pthread_mutex_unlock(&threadParam.mutexThreadExecute);
}
@ -622,12 +646,16 @@ static BOOL isCoreStarted = NO;
pthread_mutex_lock(&threadParam.mutexThreadExecute);
threadParam.timeBudgetMachAbsTime = GetFrameAbsoluteTime(1.0/theSpeed);
pthread_mutex_unlock(&threadParam.mutexThreadExecute);
[self setExecutionSpeedStatus:[NSString stringWithFormat:@"%1.2fx", theSpeed]];
}
else
{
pthread_mutex_lock(&threadParam.mutexThreadExecute);
threadParam.timeBudgetMachAbsTime = 0;
pthread_mutex_unlock(&threadParam.mutexThreadExecute);
[self setExecutionSpeedStatus:@"Unlimited"];
}
}
@ -721,6 +749,36 @@ static BOOL isCoreStarted = NO;
self.masterExecute = YES;
}
- (NSUInteger) frameNumber
{
pthread_mutex_lock(&threadParam.mutexCoreExecute);
const NSUInteger currFrameNum = currFrameCounter;
pthread_mutex_unlock(&threadParam.mutexCoreExecute);
return currFrameNum;
}
- (void) frameJumpTo:(NSUInteger)targetFrameNum
{
pthread_mutex_lock(&threadParam.mutexThreadExecute);
threadParam.frameJumpTarget = targetFrameNum;
if (targetFrameNum <= (NSUInteger)currFrameCounter)
{
pthread_mutex_unlock(&threadParam.mutexThreadExecute);
return;
}
pthread_mutex_unlock(&threadParam.mutexThreadExecute);
[self setCoreState:CORESTATE_FRAMEJUMP];
}
- (void) frameJump:(NSUInteger)relativeFrameNum
{
[self frameJumpTo:[self frameNumber] + relativeFrameNum];
}
- (void) addOutput:(CocoaDSOutput *)theOutput
{
pthread_mutex_lock(&threadParam.mutexOutputList);
@ -818,6 +876,7 @@ static void* RunCoreThread(void *arg)
CoreThreadParam *param = (CoreThreadParam *)arg;
CocoaDSCore *cdsCore = (CocoaDSCore *)param->cdsCore;
NSMutableArray *cdsOutputList = [cdsCore cdsOutputList];
NSUInteger frameNum = 0;
uint64_t startTime = 0;
uint64_t timeBudget = 0; // Need local variable to ensure that param->timeBudgetMachAbsTime is thread-safe.
@ -827,7 +886,7 @@ static void* RunCoreThread(void *arg)
pthread_mutex_lock(&param->mutexThreadExecute);
timeBudget = param->timeBudgetMachAbsTime;
while (!(param->state == CORESTATE_EXECUTE && execute && !param->exitThread))
while (!(param->state != CORESTATE_PAUSE && execute && !param->exitThread))
{
pthread_cond_wait(&param->condThreadExecute, &param->mutexThreadExecute);
startTime = mach_absolute_time();
@ -840,9 +899,14 @@ static void* RunCoreThread(void *arg)
break;
}
// Get the user's input, execute a single emulation frame, and generate
// the frame output.
if (param->state != CORESTATE_FRAMEJUMP)
{
[(CocoaDSController *)param->cdsController flush];
}
else
{
[(CocoaDSController *)param->cdsController flushEmpty];
}
NDS_beginProcessingInput();
// Shouldn't need to do any special processing steps in between.
@ -852,6 +916,7 @@ static void* RunCoreThread(void *arg)
// Execute the frame and increment the frame counter.
pthread_mutex_lock(&param->mutexCoreExecute);
NDS_exec<false>();
frameNum = currFrameCounter;
pthread_mutex_unlock(&param->mutexCoreExecute);
// Check if an internal execution error occurred that halted the emulation.
@ -869,6 +934,11 @@ static void* RunCoreThread(void *arg)
}
pthread_mutex_lock(&param->mutexOutputList);
switch (param->state)
{
case CORESTATE_EXECUTE:
{
for(CocoaDSOutput *cdsOutput in cdsOutputList)
{
if (param->framesToSkip > 0 && [cdsOutput isKindOfClass:[CocoaDSDisplay class]])
@ -878,8 +948,38 @@ static void* RunCoreThread(void *arg)
[cdsOutput doCoreEmuFrame];
}
break;
}
case CORESTATE_FRAMEADVANCE:
for(CocoaDSOutput *cdsOutput in cdsOutputList)
{
[cdsOutput doCoreEmuFrame];
}
break;
case CORESTATE_FRAMEJUMP:
{
for(CocoaDSOutput *cdsOutput in cdsOutputList)
{
if ([cdsOutput isKindOfClass:[CocoaDSDisplay class]] && (param->framesToSkip == 0 || frameNum >= param->frameJumpTarget))
{
[cdsOutput doCoreEmuFrame];
}
}
break;
}
default:
break;
}
pthread_mutex_unlock(&param->mutexOutputList);
switch (param->state)
{
case CORESTATE_EXECUTE:
{
// Determine the number of frames to skip based on how much time "debt"
// we owe on timeBudget.
if (param->isFrameSkipEnabled)
@ -894,11 +994,47 @@ static void* RunCoreThread(void *arg)
param->framesToSkip = CalculateFrameSkip(timeBudget, startTime);
}
}
break;
}
case CORESTATE_FRAMEJUMP:
{
if (param->framesToSkip > 0)
{
NDS_SkipNextFrame();
param->framesToSkip--;
}
else
{
param->framesToSkip = (int)((DS_FRAMES_PER_SECOND * 1.0) + 0.85);
}
break;
}
default:
break;
}
pthread_mutex_unlock(&param->mutexThreadExecute);
// If we doing a frame advance, switch back to pause state immediately
// after we're done with the frame.
if (param->state == CORESTATE_FRAMEADVANCE)
{
[cdsCore setCoreState:CORESTATE_PAUSE];
}
else if (param->state == CORESTATE_FRAMEJUMP)
{
if (frameNum >= param->frameJumpTarget)
{
[cdsCore restoreCoreState];
}
}
else
{
// If there is any time left in the loop, go ahead and pad it.
mach_wait_until(startTime + timeBudget);
}
} while (!param->exitThread);

View File

@ -487,8 +487,10 @@ enum
*/
enum
{
CORESTATE_EXECUTE = 0,
CORESTATE_PAUSE
CORESTATE_PAUSE = 0,
CORESTATE_EXECUTE,
CORESTATE_FRAMEADVANCE,
CORESTATE_FRAMEJUMP
};
/*
@ -514,6 +516,13 @@ enum
MICMODE_SINE_WAVE
};
enum
{
FRAMEJUMP_TYPE_FORWARD = 0,
FRAMEJUMP_TYPE_TOFRAME = 1,
FRAMEJUMP_TYPE_NEXTMARKER = 2
};
enum
{
PADDLE_CONTROL_RELATIVE = 0,

View File

@ -83,5 +83,6 @@ enum
- (void) setMicrophoneState:(BOOL)theState inputMode:(const NSInteger)inputMode;
- (void) setSineWaveGeneratorFrequency:(const double)freq;
- (void) flush;
- (void) flushEmpty;
@end

View File

@ -235,4 +235,87 @@
}
}
- (void) flushEmpty
{
// Setup the DS pad.
NDS_setPad(false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false);
// Setup the DS touch pad.
NDS_releaseTouch();
// Setup the inputs from SLOT-2 devices.
const NDS_SLOT2_TYPE slot2DeviceType = slot2_GetSelectedType();
switch (slot2DeviceType)
{
case NDS_SLOT2_GUITARGRIP:
guitarGrip_setKey(false,
false,
false,
false);
break;
case NDS_SLOT2_EASYPIANO:
piano_setKey(false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false);
break;
case NDS_SLOT2_PADDLE:
// Do nothing.
break;
default:
break;
}
// Setup the DS mic.
AudioGenerator *selectedGenerator = &nullSampleGenerator;
NDS_setMic(false);
static const bool useBufferedSource = false;
Mic_SetUseBufferedSource(useBufferedSource);
if (useBufferedSource)
{
static u8 generatedSampleBuffer[(size_t)(MIC_MAX_BUFFER_SAMPLES + 0.5)] = {0};
static const size_t requestedSamples = MIC_MAX_BUFFER_SAMPLES;
const size_t availableSamples = micInputBuffer.getAvailableElements();
if (availableSamples < requestedSamples)
{
micInputBuffer.drop(requestedSamples - availableSamples);
}
selectedGenerator->generateSampleBlock(requestedSamples, generatedSampleBuffer);
micInputBuffer.write(generatedSampleBuffer, requestedSamples);
}
else
{
Mic_SetSelectedDirectSampleGenerator(selectedGenerator);
}
}
@end

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

File diff suppressed because it is too large Load Diff

View File

@ -103,6 +103,8 @@
@interface DisplayWindowController : NSWindowController
#endif
{
NSObject *dummyObject;
DisplayView *view;
NSView *saveScreenshotPanelAccessoryView;
@ -140,6 +142,8 @@
OSSpinLock spinlockVideoFilterType;
}
@property (readonly) IBOutlet NSObject *dummyObject;
@property (readonly) IBOutlet DisplayView *view;
@property (readonly) IBOutlet NSView *saveScreenshotPanelAccessoryView;

View File

@ -85,6 +85,7 @@ enum OGLVertexAttributeID
@implementation DisplayWindowController
@synthesize dummyObject;
@synthesize emuControl;
@synthesize cdsVideoOutput;
@synthesize assignedScreen;

View File

@ -48,6 +48,7 @@ class AudioSampleBlockGenerator;
NSArrayController *cheatListController;
NSArrayController *cheatDatabaseController;
NSWindow *executionControlWindow;
NSWindow *slot1ManagerWindow;
NSWindow *saveFileMigrationSheet;
NSWindow *saveStatePrecloseSheet;
@ -66,6 +67,9 @@ class AudioSampleBlockGenerator;
NSURL *currentSaveStateURL;
NSInteger selectedExportRomSaveID;
NSInteger selectedRomSaveTypeID;
NSInteger frameJumpType;
NSInteger frameJumpFramesForward;
NSInteger frameJumpToFrame;
CGFloat lastSetSpeedScalar;
BOOL isSoundMuted;
@ -104,6 +108,7 @@ class AudioSampleBlockGenerator;
@property (readonly) IBOutlet NSArrayController *cheatListController;
@property (readonly) IBOutlet NSArrayController *cheatDatabaseController;
@property (readonly) IBOutlet NSWindow *executionControlWindow;
@property (readonly) IBOutlet NSWindow *slot1ManagerWindow;
@property (readonly) IBOutlet NSWindow *saveFileMigrationSheet;
@property (readonly) IBOutlet NSWindow *saveStatePrecloseSheet;
@ -130,6 +135,9 @@ class AudioSampleBlockGenerator;
@property (retain) NSURL *currentSaveStateURL;
@property (assign) NSInteger selectedExportRomSaveID;
@property (assign) NSInteger selectedRomSaveTypeID;
@property (assign) NSInteger frameJumpType;
@property (assign) NSInteger frameJumpFramesForward;
@property (assign) NSInteger frameJumpToFrame;
@property (assign) NSInteger render3DRenderingEngine;
@property (assign) BOOL render3DHighPrecisionColorInterpolation;
@ -165,9 +173,16 @@ class AudioSampleBlockGenerator;
- (IBAction) toggleAutoFrameSkip:(id)sender;
- (IBAction) toggleCheats:(id)sender;
- (IBAction) toggleExecutePause:(id)sender;
- (IBAction) coreExecute:(id)sender;
- (IBAction) corePause:(id)sender;
- (IBAction) frameAdvance:(id)sender;
- (IBAction) frameJump:(id)sender;
- (IBAction) reset:(id)sender;
- (IBAction) changeRomSaveType:(id)sender;
// View Menu
- (IBAction) toggleAllDisplays:(id)sender;
// Tools Menu
- (IBAction) toggleGPUState:(id)sender;
@ -199,12 +214,17 @@ class AudioSampleBlockGenerator;
- (void) cmdCopyScreen:(NSValue *)cmdAttrValue;
- (void) cmdRotateDisplayRelative:(NSValue *)cmdAttrValue;
- (void) cmdToggleAllDisplays:(NSValue *)cmdAttrValue;
- (void) cmdHoldToggleSpeedScalar:(NSValue *)cmdAttrValue;
- (void) cmdToggleSpeedLimiter:(NSValue *)cmdAttrValue;
- (void) cmdToggleAutoFrameSkip:(NSValue *)cmdAttrValue;
- (void) cmdToggleCheats:(NSValue *)cmdAttrValue;
- (void) cmdToggleExecutePause:(NSValue *)cmdAttrValue;
- (void) cmdCoreExecute:(NSValue *)cmdAttrValue;
- (void) cmdCorePause:(NSValue *)cmdAttrValue;
- (void) cmdFrameAdvance:(NSValue *)cmdAttrValue;
- (void) cmdFrameJump:(NSValue *)cmdAttrValue;
- (void) cmdReset:(NSValue *)cmdAttrValue;
- (void) cmdToggleGPUState:(NSValue *)cmdAttrValue;

View File

@ -52,6 +52,7 @@
@synthesize cheatDatabaseController;
@synthesize slot2WindowController;
@synthesize executionControlWindow;
@synthesize slot1ManagerWindow;
@synthesize saveFileMigrationSheet;
@synthesize saveStatePrecloseSheet;
@ -80,6 +81,9 @@
@synthesize currentSaveStateURL;
@synthesize selectedExportRomSaveID;
@synthesize selectedRomSaveTypeID;
@synthesize frameJumpType;
@synthesize frameJumpFramesForward;
@synthesize frameJumpToFrame;
@dynamic render3DRenderingEngine;
@dynamic render3DHighPrecisionColorInterpolation;
@ -122,6 +126,9 @@
currentSaveStateURL = nil;
selectedRomSaveTypeID = ROMSAVETYPE_AUTOMATIC;
selectedExportRomSaveID = 0;
frameJumpType = FRAMEJUMP_TYPE_FORWARD;
frameJumpFramesForward = 60;
frameJumpToFrame = 0;
lastSetSpeedScalar = 1.0f;
isSoundMuted = NO;
@ -736,6 +743,26 @@
[inputManager dispatchCommandUsingIBAction:_cmd sender:sender];
}
- (IBAction) coreExecute:(id)sender
{
[inputManager dispatchCommandUsingIBAction:_cmd sender:sender];
}
- (IBAction) corePause:(id)sender
{
[inputManager dispatchCommandUsingIBAction:_cmd sender:sender];
}
- (IBAction) frameAdvance:(id)sender
{
[inputManager dispatchCommandUsingIBAction:_cmd sender:sender];
}
- (IBAction) frameJump:(id)sender
{
[inputManager dispatchCommandUsingIBAction:_cmd sender:sender];
}
- (IBAction) reset:(id)sender
{
[inputManager dispatchCommandUsingIBAction:_cmd sender:sender];
@ -849,6 +876,11 @@
[CocoaDSUtil messageSendOneWayWithInteger:[cdsSpeaker receivePort] msgID:MESSAGE_SET_SPU_SYNC_METHOD integerValue:[CocoaDSUtil getIBActionSenderTag:sender]];
}
- (IBAction) toggleAllDisplays:(id)sender
{
[inputManager dispatchCommandUsingIBAction:_cmd sender:sender];
}
- (IBAction) chooseSlot1R4Directory:(id)sender
{
NSOpenPanel *panel = [NSOpenPanel openPanel];
@ -1124,6 +1156,49 @@
[mainWindow setDisplayRotation:angleDegrees];
}
- (void) cmdToggleAllDisplays:(NSValue *)cmdAttrValue
{
CommandAttributes cmdAttr;
[cmdAttrValue getValue:&cmdAttr];
if (cmdAttr.input.state == INPUT_ATTRIBUTE_STATE_OFF)
{
return;
}
for (DisplayWindowController *theWindow in windowList)
{
const NSInteger displayMode = [theWindow displayMode];
switch (displayMode)
{
case DS_DISPLAY_TYPE_MAIN:
[theWindow setDisplayMode:DS_DISPLAY_TYPE_TOUCH];
break;
case DS_DISPLAY_TYPE_TOUCH:
[theWindow setDisplayMode:DS_DISPLAY_TYPE_MAIN];
break;
case DS_DISPLAY_TYPE_DUAL:
{
const NSInteger displayOrder = [theWindow displayOrder];
if (displayOrder == DS_DISPLAY_ORDER_MAIN_FIRST)
{
[theWindow setDisplayOrder:DS_DISPLAY_ORDER_TOUCH_FIRST];
}
else
{
[theWindow setDisplayOrder:DS_DISPLAY_ORDER_MAIN_FIRST];
}
break;
}
default:
break;
}
}
}
- (void) cmdHoldToggleSpeedScalar:(NSValue *)cmdAttrValue
{
CommandAttributes cmdAttr;
@ -1234,6 +1309,82 @@
}
}
- (void) cmdCoreExecute:(NSValue *)cmdAttrValue
{
CommandAttributes cmdAttr;
[cmdAttrValue getValue:&cmdAttr];
if (cmdAttr.input.state == INPUT_ATTRIBUTE_STATE_OFF || [self currentRom] == nil)
{
return;
}
[self executeCore];
}
- (void) cmdCorePause:(NSValue *)cmdAttrValue
{
CommandAttributes cmdAttr;
[cmdAttrValue getValue:&cmdAttr];
if (cmdAttr.input.state == INPUT_ATTRIBUTE_STATE_OFF || [self currentRom] == nil)
{
return;
}
[self pauseCore];
}
- (void) cmdFrameAdvance:(NSValue *)cmdAttrValue
{
CommandAttributes cmdAttr;
[cmdAttrValue getValue:&cmdAttr];
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
if (cmdAttr.input.state == INPUT_ATTRIBUTE_STATE_OFF || [cdsCore coreState] != CORESTATE_PAUSE || [self currentRom] == nil)
{
return;
}
[cdsCore setCoreState:CORESTATE_FRAMEADVANCE];
}
- (void) cmdFrameJump:(NSValue *)cmdAttrValue
{
CommandAttributes cmdAttr;
[cmdAttrValue getValue:&cmdAttr];
if (cmdAttr.input.state == INPUT_ATTRIBUTE_STATE_OFF || [self currentRom] == nil)
{
return;
}
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
[executionControlWindow makeFirstResponder:nil];
NSUInteger jumpFrames = 0;
switch ([self frameJumpType])
{
case FRAMEJUMP_TYPE_FORWARD:
jumpFrames = [self frameJumpFramesForward];
[cdsCore frameJump:jumpFrames];
break;
case FRAMEJUMP_TYPE_TOFRAME:
jumpFrames = [self frameJumpToFrame];
[cdsCore frameJumpTo:jumpFrames];
break;
case FRAMEJUMP_TYPE_NEXTMARKER:
// TODO: Support when replay markers are implemented.
break;
default:
break;
}
}
- (void) cmdReset:(NSValue *)cmdAttrValue
{
CommandAttributes cmdAttr;
@ -1917,7 +2068,7 @@
{
[(NSMenuItem*)theItem setTitle:NSSTRING_TITLE_EXECUTE_CONTROL];
}
else
else if ([cdsCore coreState] == CORESTATE_EXECUTE)
{
[(NSMenuItem*)theItem setTitle:NSSTRING_TITLE_PAUSE_CONTROL];
}
@ -1929,15 +2080,29 @@
[(NSToolbarItem*)theItem setLabel:NSSTRING_TITLE_EXECUTE_CONTROL];
[(NSToolbarItem*)theItem setImage:iconExecute];
}
else
else if ([cdsCore coreState] == CORESTATE_EXECUTE)
{
[(NSToolbarItem*)theItem setLabel:NSSTRING_TITLE_PAUSE_CONTROL];
[(NSToolbarItem*)theItem setImage:iconPause];
}
}
}
else if (theAction == @selector(executeCore) ||
theAction == @selector(pauseCore))
else if (theAction == @selector(frameAdvance:))
{
if ([cdsCore coreState] != CORESTATE_PAUSE)
{
enable = NO;
}
if ([cdsCore coreState] != CORESTATE_PAUSE ||
![cdsCore masterExecute] ||
[self currentRom] == nil ||
[self isShowingSaveStateDialog])
{
enable = NO;
}
}
else if (theAction == @selector(frameJump:))
{
if (![cdsCore masterExecute] ||
[self currentRom] == nil ||
@ -1945,6 +2110,27 @@
{
enable = NO;
}
}
else if (theAction == @selector(coreExecute:))
{
if ([cdsCore coreState] == CORESTATE_EXECUTE ||
[cdsCore coreState] == CORESTATE_FRAMEADVANCE ||
![cdsCore masterExecute] ||
[self currentRom] == nil ||
[self isShowingSaveStateDialog])
{
enable = NO;
}
}
else if (theAction == @selector(corePause:))
{
if ([cdsCore coreState] == CORESTATE_PAUSE ||
![cdsCore masterExecute] ||
[self currentRom] == nil ||
[self isShowingSaveStateDialog])
{
enable = NO;
}
}
else if (theAction == @selector(reset:))
{

View File

@ -1044,6 +1044,7 @@ static std::tr1::unordered_map<unsigned short, std::string> keyboardNameTable; /
[[[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Icon_Piano_256x256" ofType:@"png"]] autorelease], @"Piano: B",
[[[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Icon_Piano_256x256" ofType:@"png"]] autorelease], @"Piano: High C",
[[[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Icon_PaddleKnob_256x256" ofType:@"png"]] autorelease], @"Paddle",
[[[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Icon_DisplayToggle_420x420" ofType:@"png"]] autorelease], @"Toggle All Displays",
[[[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Icon_RotateCCW_420x420" ofType:@"png"]] autorelease], @"Rotate Display Left",
[[[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Icon_RotateCW_420x420" ofType:@"png"]] autorelease], @"Rotate Display Right",
[[[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Icon_ShowHUD_420x420" ofType:@"png"]] autorelease], @"HUD",
@ -1096,11 +1097,16 @@ static std::tr1::unordered_map<unsigned short, std::string> keyboardNameTable; /
commandSelector["Save State Slot"] = @selector(cmdSaveEmuSaveStateSlot:);
commandSelector["Copy Screen"] = @selector(cmdCopyScreen:);
commandSelector["Rotate Display Relative"] = @selector(cmdRotateDisplayRelative:);
commandSelector["Toggle All Displays"] = @selector(cmdToggleAllDisplays:);
commandSelector["Set Speed"] = @selector(cmdHoldToggleSpeedScalar:);
commandSelector["Enable/Disable Speed Limiter"] = @selector(cmdToggleSpeedLimiter:);
commandSelector["Enable/Disable Auto Frame Skip"] = @selector(cmdToggleAutoFrameSkip:);
commandSelector["Enable/Disable Cheats"] = @selector(cmdToggleCheats:);
commandSelector["Execute"] = @selector(cmdCoreExecute:);
commandSelector["Pause"] = @selector(cmdCorePause:);
commandSelector["Execute/Pause"] = @selector(cmdToggleExecutePause:);
commandSelector["Frame Advance"] = @selector(cmdFrameAdvance:);
commandSelector["Frame Jump"] = @selector(cmdFrameJump:);
commandSelector["Reset"] = @selector(cmdReset:);
commandSelector["Mute/Unmute"] = @selector(cmdToggleMute:);
commandSelector["Enable/Disable GPU State"] = @selector(cmdToggleGPUState:);
@ -1164,13 +1170,19 @@ static std::tr1::unordered_map<unsigned short, std::string> keyboardNameTable; /
CommandAttributes cmdRotateDisplayRight = NewCommandAttributesForSelector("Rotate Display Right", commandSelector["Rotate Display Relative"]);
cmdRotateDisplayRight.intValue[0] = 90;
CommandAttributes cmdToggleAllDisplays = NewCommandAttributesForSelector("Toggle All Displays", commandSelector["Toggle All Displays"]);
CommandAttributes cmdToggleSpeed = NewCommandAttributesForSelector("Set Speed", commandSelector["Set Speed"]);
cmdToggleSpeed.floatValue[0] = 1.0f;
CommandAttributes cmdToggleSpeedLimiter = NewCommandAttributesForSelector("Enable/Disable Speed Limiter", commandSelector["Enable/Disable Speed Limiter"]);
CommandAttributes cmdToggleAutoFrameSkip = NewCommandAttributesForSelector("Enable/Disable Auto Frame Skip", commandSelector["Enable/Disable Auto Frame Skip"]);
CommandAttributes cmdToggleCheats = NewCommandAttributesForSelector("Enable/Disable Cheats", commandSelector["Enable/Disable Cheats"]);
CommandAttributes cmdCoreExecute = NewCommandAttributesForSelector("Execute", commandSelector["Execute"]);
CommandAttributes cmdCorePause = NewCommandAttributesForSelector("Pause", commandSelector["Pause"]);
CommandAttributes cmdToggleExecutePause = NewCommandAttributesForSelector("Execute/Pause", commandSelector["Execute/Pause"]);
CommandAttributes cmdFrameAdvance = NewCommandAttributesForSelector("Frame Advance", commandSelector["Frame Advance"]);
CommandAttributes cmdFrameJump = NewCommandAttributesForSelector("Frame Jump", commandSelector["Frame Jump"]);
CommandAttributes cmdReset = NewCommandAttributesForSelector("Reset", commandSelector["Reset"]);
CommandAttributes cmdToggleMute = NewCommandAttributesForSelector("Mute/Unmute", commandSelector["Mute/Unmute"]);
CommandAttributes cmdToggleGPUState = NewCommandAttributesForSelector("Enable/Disable GPU State", commandSelector["Enable/Disable GPU State"]);
@ -1216,11 +1228,16 @@ static std::tr1::unordered_map<unsigned short, std::string> keyboardNameTable; /
defaultCommandAttributes["Copy Screen"] = cmdCopyScreen;
defaultCommandAttributes["Rotate Display Left"] = cmdRotateDisplayLeft;
defaultCommandAttributes["Rotate Display Right"] = cmdRotateDisplayRight;
defaultCommandAttributes["Toggle All Displays"] = cmdToggleAllDisplays;
defaultCommandAttributes["Set Speed"] = cmdToggleSpeed;
defaultCommandAttributes["Enable/Disable Speed Limiter"] = cmdToggleSpeedLimiter;
defaultCommandAttributes["Enable/Disable Auto Frame Skip"] = cmdToggleAutoFrameSkip;
defaultCommandAttributes["Enable/Disable Cheats"] = cmdToggleCheats;
defaultCommandAttributes["Execute"] = cmdCoreExecute;
defaultCommandAttributes["Pause"] = cmdCorePause;
defaultCommandAttributes["Execute/Pause"] = cmdToggleExecutePause;
defaultCommandAttributes["Frame Advance"] = cmdFrameAdvance;
defaultCommandAttributes["Frame Jump"] = cmdFrameJump;
defaultCommandAttributes["Reset"] = cmdReset;
defaultCommandAttributes["Mute/Unmute"] = cmdToggleMute;
defaultCommandAttributes["Enable/Disable GPU State"] = cmdToggleGPUState;
@ -1229,11 +1246,16 @@ static std::tr1::unordered_map<unsigned short, std::string> keyboardNameTable; /
[self addMappingForIBAction:@selector(loadEmuSaveStateSlot:) commandAttributes:&cmdLoadEmuSaveStateSlot];
[self addMappingForIBAction:@selector(saveEmuSaveStateSlot:) commandAttributes:&cmdSaveEmuSaveStateSlot];
[self addMappingForIBAction:@selector(copy:) commandAttributes:&cmdCopyScreen];
[self addMappingForIBAction:@selector(toggleAllDisplays:) commandAttributes:&cmdToggleAllDisplays];
[self addMappingForIBAction:@selector(changeRotationRelative:) commandAttributes:&cmdRotateDisplayRelative];
[self addMappingForIBAction:@selector(toggleSpeedLimiter:) commandAttributes:&cmdToggleSpeedLimiter];
[self addMappingForIBAction:@selector(toggleAutoFrameSkip:) commandAttributes:&cmdToggleAutoFrameSkip];
[self addMappingForIBAction:@selector(toggleCheats:) commandAttributes:&cmdToggleCheats];
[self addMappingForIBAction:@selector(coreExecute:) commandAttributes:&cmdCoreExecute];
[self addMappingForIBAction:@selector(corePause:) commandAttributes:&cmdCorePause];
[self addMappingForIBAction:@selector(toggleExecutePause:) commandAttributes:&cmdToggleExecutePause];
[self addMappingForIBAction:@selector(frameAdvance:) commandAttributes:&cmdFrameAdvance];
[self addMappingForIBAction:@selector(frameJump:) commandAttributes:&cmdFrameJump];
[self addMappingForIBAction:@selector(reset:) commandAttributes:&cmdReset];
[self addMappingForIBAction:@selector(toggleGPUState:) commandAttributes:&cmdToggleGPUState];