various updates to cocoa port (see change log)
This commit is contained in:
parent
214321d03e
commit
7114abee25
|
@ -99,6 +99,11 @@
|
||||||
<Option compile="1" />
|
<Option compile="1" />
|
||||||
<Option link="1" />
|
<Option link="1" />
|
||||||
</Unit>
|
</Unit>
|
||||||
|
<Unit filename="screenshot.h" />
|
||||||
|
<Unit filename="screenshot.m">
|
||||||
|
<Option compile="1" />
|
||||||
|
<Option link="1" />
|
||||||
|
</Unit>
|
||||||
<Unit filename="../config.h" />
|
<Unit filename="../config.h" />
|
||||||
<Unit filename="../cp15.c">
|
<Unit filename="../cp15.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
|
|
|
@ -37,6 +37,13 @@
|
||||||
#define DS_SCREEN_X_RATIO (256.0 / (192.0 * 2.0))
|
#define DS_SCREEN_X_RATIO (256.0 / (192.0 * 2.0))
|
||||||
#define DS_SCREEN_Y_RATIO ((192.0 * 2.0) / 256.0)
|
#define DS_SCREEN_Y_RATIO ((192.0 * 2.0) / 256.0)
|
||||||
|
|
||||||
|
//Port Specific constants ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define ROTATION_0 0
|
||||||
|
#define ROTATION_90 1
|
||||||
|
#define ROTATION_180 2
|
||||||
|
#define ROTATION_270 3
|
||||||
|
|
||||||
//Cocoa Util------------------------------------------------------------------------------------
|
//Cocoa Util------------------------------------------------------------------------------------
|
||||||
//These are just useful little functions to help with stuff
|
//These are just useful little functions to help with stuff
|
||||||
//defined in cocoa_util.m
|
//defined in cocoa_util.m
|
||||||
|
@ -135,6 +142,7 @@ extern NintendoDS *NDS;
|
||||||
@class VideoOutputWindow;
|
@class VideoOutputWindow;
|
||||||
extern VideoOutputWindow *main_window;
|
extern VideoOutputWindow *main_window;
|
||||||
|
|
||||||
|
void setAppDefaults(); //this is defined in preferences.m and should be called at app launch
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
extern volatile int /*desmume_BOOL*/ execute;
|
extern volatile int /*desmume_BOOL*/ execute;
|
||||||
|
|
|
@ -42,9 +42,7 @@ FIXME: Apple+Q during open dialog = badness
|
||||||
FIXME: Live resize needs to work without pausing emulator
|
FIXME: Live resize needs to work without pausing emulator
|
||||||
FIXME: Hardware acceleration for openglrender.c ??
|
FIXME: Hardware acceleration for openglrender.c ??
|
||||||
FIXME: When cross-platform (core) components end emulation due to error - pause should be called (set the menu checkmark)
|
FIXME: When cross-platform (core) components end emulation due to error - pause should be called (set the menu checkmark)
|
||||||
FIXME: Multi-threaded version needs to do some sleep()-ing when not running game
|
|
||||||
FIXME: Some bug where states get messed up and hitting execute does nothing......
|
FIXME: Some bug where states get messed up and hitting execute does nothing......
|
||||||
FIXME: single threaded version requires an additional event to quit (after you tell the program to exit you gotta click or press something)
|
|
||||||
FIXME: .nds.gba extensions don't work in open panels
|
FIXME: .nds.gba extensions don't work in open panels
|
||||||
FIXME: Traveling windows when constantly resizing with hotkey
|
FIXME: Traveling windows when constantly resizing with hotkey
|
||||||
*/
|
*/
|
||||||
|
@ -74,10 +72,13 @@ NSMenu *menu;
|
||||||
@interface NSApplication(delegate)
|
@interface NSApplication(delegate)
|
||||||
|
|
||||||
//delegate methods
|
//delegate methods
|
||||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
|
- (BOOL)application:(NSApplication*)sender openFile:(NSString*)filename;
|
||||||
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames;
|
- (void)application:(NSApplication*)sender openFiles:(NSArray*)filenames;
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
|
- (void)applicationWillFinishLaunching:(NSNotification*)aNotification;
|
||||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
|
- (void)applicationDidFinishLaunching:(NSNotification*)aNotification;
|
||||||
|
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -186,8 +187,8 @@ void CreateMenu()
|
||||||
[application_menu addItem: [NSMenuItem separatorItem]];
|
[application_menu addItem: [NSMenuItem separatorItem]];
|
||||||
|
|
||||||
//Add the preferences menu
|
//Add the preferences menu
|
||||||
//temp = [application_menu addItemWithTitle:@"Preferences..." action:@selector(preferences) keyEquivalent:@","];
|
temp = [application_menu addItemWithTitle:@"Preferences..." action:@selector(preferences) keyEquivalent:@","];
|
||||||
//[temp setTarget:NSApp];
|
[temp setTarget:NSApp];
|
||||||
|
|
||||||
//
|
//
|
||||||
[application_menu addItem: [NSMenuItem separatorItem]];
|
[application_menu addItem: [NSMenuItem separatorItem]];
|
||||||
|
@ -240,13 +241,29 @@ void CreateMenu()
|
||||||
[temp setTarget:NDS];
|
[temp setTarget:NDS];
|
||||||
|
|
||||||
//recent items menu
|
//recent items menu
|
||||||
|
/* Thanks to Jeff Johnson and the Lap Cat Software Blog for their information on the Open Recent menu in Cocoa*/
|
||||||
|
/* http://lapcatsoftware.com/blog/ */
|
||||||
|
|
||||||
temp = [file addItemWithTitle:@"Open Recent" action:nil keyEquivalent:@""];
|
temp = [file addItemWithTitle:@"Open Recent" action:nil keyEquivalent:@""];
|
||||||
|
|
||||||
NSMenu *recent_menu = [[NSMenu alloc] initWithTitle:@""];
|
NSMenu *recent_menu = [[NSMenu alloc] initWithTitle:@"Open Recent"];
|
||||||
|
[recent_menu performSelector:@selector(_setMenuName:) withObject:@"NSRecentDocumentsMenu"];
|
||||||
[temp setSubmenu:recent_menu];
|
[temp setSubmenu:recent_menu];
|
||||||
|
|
||||||
[recent_menu addItemWithTitle:@"Blar" action:nil keyEquivalent:@""];
|
NSArray *recent_documents = [[NSDocumentController sharedDocumentController] recentDocumentURLs];
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < [recent_documents count]; i++)
|
||||||
|
{
|
||||||
|
// [recent_menu addItemWithTitle:[[recent_documents objectAtIndex:i] absoluteString] action:nil keyEquivalent:@""];
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
[recent_menu addItem:[NSMenuItem separatorItem]];
|
||||||
|
|
||||||
|
temp = [recent_menu addItemWithTitle:@"Clear" action:@selector(clearRecentDocuments:) keyEquivalent:@""];
|
||||||
|
if(i == 0)[temp setEnabled:NO];
|
||||||
|
else [temp setEnabled:YES];
|
||||||
|
[temp setTarget:[NSDocumentController sharedDocumentController]];
|
||||||
|
*/
|
||||||
[file addItem:[NSMenuItem separatorItem]];
|
[file addItem:[NSMenuItem separatorItem]];
|
||||||
|
|
||||||
rom_info_item = [file addItemWithTitle:@"ROM Info..." action:@selector(showRomInfo) keyEquivalent:@""];
|
rom_info_item = [file addItemWithTitle:@"ROM Info..." action:@selector(showRomInfo) keyEquivalent:@""];
|
||||||
|
@ -277,7 +294,6 @@ void CreateMenu()
|
||||||
[load_state_menu setAutoenablesItems:NO];
|
[load_state_menu setAutoenablesItems:NO];
|
||||||
[temp setSubmenu:load_state_menu];
|
[temp setSubmenu:load_state_menu];
|
||||||
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < SAVE_SLOTS; i++)
|
for(i = 0; i < SAVE_SLOTS; i++)
|
||||||
{
|
{
|
||||||
saveSlot_item[i] = [save_state_menu addItemWithTitle:@"Slot %d" withInt:i action:@selector(saveToSlot:) keyEquivalent:@""];
|
saveSlot_item[i] = [save_state_menu addItemWithTitle:@"Slot %d" withInt:i action:@selector(saveToSlot:) keyEquivalent:@""];
|
||||||
|
@ -379,12 +395,11 @@ a way to get the time of a save that's not a string / human formatted...
|
||||||
[frame_skip_item[0] setTarget:NDS];
|
[frame_skip_item[0] setTarget:NDS];
|
||||||
[frame_skip_item[0] setEnabled:YES];
|
[frame_skip_item[0] setEnabled:YES];
|
||||||
|
|
||||||
int i2;
|
for(i = 1; i < MAX_FRAME_SKIP; i++)
|
||||||
for(i2 = 1; i2 < MAX_FRAME_SKIP; i2++)
|
|
||||||
{
|
{
|
||||||
frame_skip_item[i2] = [frame_skip_menu addItemWithTitle:@"%d" withInt:i2 action:@selector(setFrameSkip:) keyEquivalent:@""];
|
frame_skip_item[i] = [frame_skip_menu addItemWithTitle:@"%d" withInt:i action:@selector(setFrameSkip:) keyEquivalent:@""];
|
||||||
[frame_skip_item[i2] setTarget:NDS];
|
[frame_skip_item[i] setTarget:NDS];
|
||||||
[frame_skip_item[i2] setEnabled:YES];
|
[frame_skip_item[i] setEnabled:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create the screens menu
|
//Create the screens menu
|
||||||
|
@ -418,7 +433,7 @@ a way to get the time of a save that's not a string / human formatted...
|
||||||
[constrain_item setState:NSOnState];
|
[constrain_item setState:NSOnState];
|
||||||
[constrain_item setTarget:main_window];
|
[constrain_item setTarget:main_window];
|
||||||
|
|
||||||
min_size_item = [view addItemWithTitle: @"No smaller than DS" action:@selector(toggleMinSize) keyEquivalent:@""];
|
min_size_item = [view addItemWithTitle: @"No Smaller Than DS" action:@selector(toggleMinSize) keyEquivalent:@""];
|
||||||
[min_size_item setState:NSOnState];
|
[min_size_item setState:NSOnState];
|
||||||
[min_size_item setTarget:main_window];
|
[min_size_item setTarget:main_window];
|
||||||
|
|
||||||
|
@ -429,19 +444,19 @@ a way to get the time of a save that's not a string / human formatted...
|
||||||
NSMenu *rotation_menu = [[NSMenu alloc] initWithTitle:@"Rotation"];
|
NSMenu *rotation_menu = [[NSMenu alloc] initWithTitle:@"Rotation"];
|
||||||
[temp setSubmenu: rotation_menu];
|
[temp setSubmenu: rotation_menu];
|
||||||
|
|
||||||
rotation0_item = [rotation_menu addItemWithTitle:@"0" action:@selector(setRotation0) keyEquivalent:@""];
|
rotation0_item = [rotation_menu addItemWithTitle:@"Rotation 0" action:@selector(setRotation0) keyEquivalent:@""];
|
||||||
[rotation0_item setState:NSOnState];
|
[rotation0_item setState:NSOnState];
|
||||||
[rotation0_item setTarget:main_window];
|
[rotation0_item setTarget:main_window];
|
||||||
|
|
||||||
rotation90_item = [rotation_menu addItemWithTitle:@"90" action:@selector(setRotation90) keyEquivalent:@""];
|
rotation90_item = [rotation_menu addItemWithTitle:@"Rotation 90" action:@selector(setRotation90) keyEquivalent:@""];
|
||||||
[rotation90_item setState:NSOffState];
|
[rotation90_item setState:NSOffState];
|
||||||
[rotation90_item setTarget:main_window];
|
[rotation90_item setTarget:main_window];
|
||||||
|
|
||||||
rotation180_item = [rotation_menu addItemWithTitle:@"180" action:@selector(setRotation180) keyEquivalent:@""];
|
rotation180_item = [rotation_menu addItemWithTitle:@"Rotation 180" action:@selector(setRotation180) keyEquivalent:@""];
|
||||||
[rotation180_item setState:NSOffState];
|
[rotation180_item setState:NSOffState];
|
||||||
[rotation180_item setTarget:main_window];
|
[rotation180_item setTarget:main_window];
|
||||||
|
|
||||||
rotation270_item = [rotation_menu addItemWithTitle:@"270" action:@selector(setRotation270) keyEquivalent:@""];
|
rotation270_item = [rotation_menu addItemWithTitle:@"Rotation 270" action:@selector(setRotation270) keyEquivalent:@""];
|
||||||
[rotation270_item setState:NSOffState];
|
[rotation270_item setState:NSOffState];
|
||||||
[rotation270_item setTarget:main_window];
|
[rotation270_item setTarget:main_window];
|
||||||
|
|
||||||
|
@ -485,6 +500,15 @@ a way to get the time of a save that's not a string / human formatted...
|
||||||
[subBG3_item setState:NSOnState];
|
[subBG3_item setState:NSOnState];
|
||||||
[subBG3_item setTarget:main_window];
|
[subBG3_item setTarget:main_window];
|
||||||
|
|
||||||
|
[view addItem:[NSMenuItem separatorItem]];
|
||||||
|
|
||||||
|
allows_resize_item = [view addItemWithTitle:@"Screenshot to File" action:@selector(screenShotToFile) keyEquivalent:@""];
|
||||||
|
[allows_resize_item setTarget:main_window];
|
||||||
|
|
||||||
|
allows_resize_item = [view addItemWithTitle:@"Screenshot to Window" action:@selector(screenShotToWindow) keyEquivalent:@""];
|
||||||
|
[allows_resize_item setTarget:main_window];
|
||||||
|
|
||||||
|
|
||||||
//Create the window menu
|
//Create the window menu
|
||||||
/*
|
/*
|
||||||
window = [[NSMenu alloc] initWithTitle:localizedString(@"Window", nil)];
|
window = [[NSMenu alloc] initWithTitle:localizedString(@"Window", nil)];
|
||||||
|
@ -506,13 +530,13 @@ a way to get the time of a save that's not a string / human formatted...
|
||||||
help = [[NSMenu alloc] initWithTitle:localizedString(@"Help", nil)];
|
help = [[NSMenu alloc] initWithTitle:localizedString(@"Help", nil)];
|
||||||
[menu setSubmenu:help forItem:help_item];
|
[menu setSubmenu:help forItem:help_item];
|
||||||
|
|
||||||
temp = [help addItemWithTitle:@"Website" action:@selector(launchWebsite) keyEquivalent: @""];
|
temp = [help addItemWithTitle:@"Go to Website" action:@selector(launchWebsite) keyEquivalent: @""];
|
||||||
[temp setTarget:NSApp];
|
[temp setTarget:NSApp];
|
||||||
|
|
||||||
temp = [help addItemWithTitle:@"Forums" action:@selector(launchForums) keyEquivalent: @""];
|
temp = [help addItemWithTitle:@"Go to Forums" action:@selector(launchForums) keyEquivalent: @""];
|
||||||
[temp setTarget:NSApp];
|
[temp setTarget:NSApp];
|
||||||
|
|
||||||
temp = [help addItemWithTitle:@"Submit A Bug Report" action:@selector(bugReport) keyEquivalent: @""];
|
temp = [help addItemWithTitle:@"Submit a Bug Report" action:@selector(bugReport) keyEquivalent: @""];
|
||||||
[temp setTarget:NSApp];
|
[temp setTarget:NSApp];
|
||||||
|
|
||||||
[NSApp setMainMenu: menu];
|
[NSApp setMainMenu: menu];
|
||||||
|
@ -545,37 +569,61 @@ int main(int argc, char *argv[])
|
||||||
//gdb stuff--------------------------------------------------------------------------------
|
//gdb stuff--------------------------------------------------------------------------------
|
||||||
//don't know and don't care
|
//don't know and don't care
|
||||||
|
|
||||||
void *
|
void *createThread_gdb(void (*thread_function)(void *data), void *thread_data)
|
||||||
createThread_gdb( void (*thread_function)( void *data),
|
{
|
||||||
void *thread_data) {
|
return NULL;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void joinThread_gdb(void *thread_handle)
|
||||||
joinThread_gdb( void *thread_handle) {
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//Implementations-------------------------------------------------------------------------
|
//Implementations-------------------------------------------------------------------------
|
||||||
|
|
||||||
@implementation NSApplication(delegate)
|
@implementation NSApplication(delegate)
|
||||||
|
|
||||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
|
- (BOOL)application:(NSApplication*)sender openFile:(NSString*)filename
|
||||||
{
|
{
|
||||||
|
//verify everything
|
||||||
|
if(sender != NSApp)return NO;
|
||||||
|
if(!filename)return NO;
|
||||||
|
if([filename length] == 0)return NO;
|
||||||
|
|
||||||
if([NDS loadROM:filename])
|
if([NDS loadROM:filename])
|
||||||
return YES;
|
return YES;
|
||||||
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
|
- (void)application:(NSApplication*)sender openFiles:(NSArray*)filenames
|
||||||
{
|
{
|
||||||
//messageDialog(@"Openfiles",@"");
|
//verify everything
|
||||||
|
if(sender != NSApp)goto fail;
|
||||||
|
if(!filenames)goto fail;
|
||||||
|
if([filenames count] == 0)goto fail;
|
||||||
|
NSString *filename = [filenames lastObject];
|
||||||
|
if(!filename)goto fail;
|
||||||
|
if([filename length] == 0)goto fail;
|
||||||
|
|
||||||
|
if([NDS loadROM:filename])
|
||||||
|
{
|
||||||
|
[sender replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
[sender replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
|
//Set default values for all preferences
|
||||||
|
//(this wont override saved preferences as
|
||||||
|
//they work in different preference domains)
|
||||||
|
setAppDefaults();
|
||||||
|
|
||||||
//More app Init ------------------------------------------------------------------------------
|
//App Init ------------------------------------------------------------------------------
|
||||||
|
|
||||||
//Bring the application to the front
|
//Bring the application to the front
|
||||||
[NSApp activateIgnoringOtherApps:TRUE];
|
[NSApp activateIgnoringOtherApps:TRUE];
|
||||||
|
@ -586,21 +634,19 @@ joinThread_gdb( void *thread_handle) {
|
||||||
//create the video output window (the only window that opens with the app)
|
//create the video output window (the only window that opens with the app)
|
||||||
main_window = [[VideoOutputWindow alloc] init];
|
main_window = [[VideoOutputWindow alloc] init];
|
||||||
|
|
||||||
//start with a blank screen
|
|
||||||
[main_window clearScreen];
|
|
||||||
|
|
||||||
//create the menus
|
//create the menus
|
||||||
CreateMenu();
|
CreateMenu();
|
||||||
|
|
||||||
//init opengl 3d ness
|
//init opengl 3d ness
|
||||||
NDS_3D_SetDriver (GPU3D_OPENGL);
|
NDS_3D_SetDriver (GPU3D_OPENGL);
|
||||||
if(!gpu3D->NDS_3D_Init())
|
if(!gpu3D->NDS_3D_Init())
|
||||||
messageDialog(@"Error", @"Unable to initialize OpenGL components");
|
messageDialog(localizedString(@"Error", nil), @"Unable to initialize OpenGL components");
|
||||||
|
}
|
||||||
|
|
||||||
//[NDS LoadROM:@"/Users/gecko/nds/0004 - Feel the Magic - XY-XX (U) (Trashman).nds"];
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||||
//^ above line breaks everything!?
|
{
|
||||||
|
|
||||||
//Main program loop ----------------------------------------------------------------------------
|
//Start the main program loop ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef MULTITHREADED
|
#ifdef MULTITHREADED
|
||||||
|
|
||||||
|
@ -627,4 +673,5 @@ joinThread_gdb( void *thread_handle) {
|
||||||
//AskForQuit takes care of quitting, dont need cocoa to do it for us
|
//AskForQuit takes care of quitting, dont need cocoa to do it for us
|
||||||
return NSTerminateCancel;
|
return NSTerminateCancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -34,8 +34,9 @@
|
||||||
//this is the only method involving cocoa that should be called from the run() function
|
//this is the only method involving cocoa that should be called from the run() function
|
||||||
- (void)updateScreen;
|
- (void)updateScreen;
|
||||||
|
|
||||||
//makes the screen white
|
//
|
||||||
- (void)clearScreen;
|
- (void)clearScreenWhite; //for when a rom is loaded but stopped
|
||||||
|
- (void)clearScreenBlack; //for when the emulator is not loaded
|
||||||
|
|
||||||
//resets the min size internalls (when rotation changes), shouldn't be used from outside
|
//resets the min size internalls (when rotation changes), shouldn't be used from outside
|
||||||
- (void)resetMinSize:(bool)resize;
|
- (void)resetMinSize:(bool)resize;
|
||||||
|
@ -74,6 +75,11 @@
|
||||||
- (void)toggleSubBackground2;
|
- (void)toggleSubBackground2;
|
||||||
- (void)toggleSubBackground3;
|
- (void)toggleSubBackground3;
|
||||||
|
|
||||||
|
//screenshots
|
||||||
|
- (void)screenShotToFile;
|
||||||
|
- (void)screenShotToWindow;
|
||||||
|
- (const unsigned char *)getBuffer;//pause before calling
|
||||||
|
|
||||||
//keyboard input
|
//keyboard input
|
||||||
- (void)keyDown:(NSEvent*)event;
|
- (void)keyDown:(NSEvent*)event;
|
||||||
- (void)keyUp:(NSEvent*)event;
|
- (void)keyUp:(NSEvent*)event;
|
||||||
|
@ -82,6 +88,7 @@
|
||||||
- (void)mouseDown:(NSEvent*)event;
|
- (void)mouseDown:(NSEvent*)event;
|
||||||
- (void)mouseDragged:(NSEvent*)event;
|
- (void)mouseDragged:(NSEvent*)event;
|
||||||
- (void)mouseUp:(NSEvent*)event;
|
- (void)mouseUp:(NSEvent*)event;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif //MAIN_WINDOW_H
|
#endif //MAIN_WINDOW_H
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#import "globals.h"
|
#import "globals.h"
|
||||||
#import "main_window.h"
|
#import "main_window.h"
|
||||||
#import "nds_control.h"
|
#import "nds_control.h"
|
||||||
|
#import "screenshot.h"
|
||||||
|
|
||||||
//DeSmuME general includes
|
//DeSmuME general includes
|
||||||
#define OBJ_C
|
#define OBJ_C
|
||||||
|
@ -106,10 +107,6 @@ unsigned short save_slot_10 = 109; //F10
|
||||||
NSOpenGLContext *gpu_context;
|
NSOpenGLContext *gpu_context;
|
||||||
|
|
||||||
//rotation
|
//rotation
|
||||||
#define ROTATION_0 0
|
|
||||||
#define ROTATION_90 1
|
|
||||||
#define ROTATION_180 2
|
|
||||||
#define ROTATION_270 3
|
|
||||||
u8 rotation = ROTATION_0;
|
u8 rotation = ROTATION_0;
|
||||||
|
|
||||||
//extern unsigned char GPU_screen3D[256*256*4];
|
//extern unsigned char GPU_screen3D[256*256*4];
|
||||||
|
@ -151,7 +148,7 @@ NSSize min_size;
|
||||||
|
|
||||||
if(self==nil)
|
if(self==nil)
|
||||||
{
|
{
|
||||||
messageDialog(@"Error", @"Could not init frame for OpenGL display");
|
messageDialog(localizedString(@"Error", nil), @"Could not init frame for OpenGL display");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,14 +169,14 @@ NSSize min_size;
|
||||||
NSOpenGLPixelFormat* pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
|
NSOpenGLPixelFormat* pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
|
||||||
if(pixel_format == nil)
|
if(pixel_format == nil)
|
||||||
{
|
{
|
||||||
messageDialog(@"Error", @"Couldn't create OpenGL pixel format for video output");
|
messageDialog(localizedString(@"Error", nil), @"Couldn't create OpenGL pixel format for video output");
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:nil];
|
context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:nil];
|
||||||
if(context == nil)
|
if(context == nil)
|
||||||
{
|
{
|
||||||
messageDialog(@"Error", @"Couldn't create OpenGL context for video output");
|
messageDialog(localizedString(@"Error", nil), @"Couldn't create OpenGL context for video output");
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,14 +199,14 @@ NSSize min_size;
|
||||||
NSOpenGLPixelFormat* pixel_format2 = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs2];
|
NSOpenGLPixelFormat* pixel_format2 = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs2];
|
||||||
if(pixel_format2 == nil)
|
if(pixel_format2 == nil)
|
||||||
{
|
{
|
||||||
messageDialog(@"Error", @"Couldn't create OpenGL pixel format for GPU");
|
messageDialog(localizedString(@"Error", nil), @"Couldn't create OpenGL pixel format for GPU");
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu_context = [[NSOpenGLContext alloc] initWithFormat:pixel_format2 shareContext:nil];
|
gpu_context = [[NSOpenGLContext alloc] initWithFormat:pixel_format2 shareContext:nil];
|
||||||
if(gpu_context == nil)
|
if(gpu_context == nil)
|
||||||
{
|
{
|
||||||
messageDialog(@"Error", @"Couldn't create OpenGL context for GPU");
|
messageDialog(localizedString(@"Error", nil), @"Couldn't create OpenGL context for GPU");
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +343,7 @@ NSSize min_size;
|
||||||
|
|
||||||
backing:NSBackingStoreBuffered defer:NO screen:nil];
|
backing:NSBackingStoreBuffered defer:NO screen:nil];
|
||||||
|
|
||||||
[self setTitle:@"DeSmuME Emulator"];
|
[self setTitle:localizedString(@"DeSmuME Emulator", nil)];
|
||||||
|
|
||||||
//set minimum window size (to the starting size, pixel-for-pixel to DS)
|
//set minimum window size (to the starting size, pixel-for-pixel to DS)
|
||||||
//this re-gets the window rect to include the title bar size
|
//this re-gets the window rect to include the title bar size
|
||||||
|
@ -373,7 +370,7 @@ NSSize min_size;
|
||||||
rect.size.width = DS_SCREEN_WIDTH;
|
rect.size.width = DS_SCREEN_WIDTH;
|
||||||
rect.size.height = DS_SCREEN_HEIGHT_COMBINED;
|
rect.size.height = DS_SCREEN_HEIGHT_COMBINED;
|
||||||
if((video_output_view = [[VideoOutputView alloc] initWithFrame:rect]) == nil)
|
if((video_output_view = [[VideoOutputView alloc] initWithFrame:rect]) == nil)
|
||||||
messageDialog(@"Error", @"Couldn't create OpenGL view to display screens");
|
messageDialog(localizedString(@"Error", nil), @"Couldn't create OpenGL view to display screens");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[[self contentView] addSubview:video_output_view];
|
[[self contentView] addSubview:video_output_view];
|
||||||
|
@ -383,6 +380,9 @@ NSSize min_size;
|
||||||
//Show the window
|
//Show the window
|
||||||
[[[NSWindowController alloc] initWithWindow:self] showWindow:nil];
|
[[[NSWindowController alloc] initWithWindow:self] showWindow:nil];
|
||||||
|
|
||||||
|
//start with a blank screen
|
||||||
|
[self clearScreenBlack];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +410,7 @@ NSSize min_size;
|
||||||
[video_output_view draw];
|
[video_output_view draw];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clearScreen
|
- (void)clearScreenWhite
|
||||||
{
|
{
|
||||||
//fill our buffer with pure white
|
//fill our buffer with pure white
|
||||||
memset(&correction_buffer, 255, DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT_COMBINED * 2);
|
memset(&correction_buffer, 255, DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT_COMBINED * 2);
|
||||||
|
@ -418,6 +418,14 @@ NSSize min_size;
|
||||||
[video_output_view draw];
|
[video_output_view draw];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)clearScreenBlack
|
||||||
|
{
|
||||||
|
//fill our buffer with pure white
|
||||||
|
memset(&correction_buffer, 0, DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT_COMBINED * 2);
|
||||||
|
|
||||||
|
[video_output_view draw];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)resetMinSize:(bool)resize
|
- (void)resetMinSize:(bool)resize
|
||||||
{
|
{
|
||||||
if(rotation == ROTATION_0 || rotation == ROTATION_180)
|
if(rotation == ROTATION_0 || rotation == ROTATION_180)
|
||||||
|
@ -450,8 +458,6 @@ NSSize min_size;
|
||||||
|
|
||||||
- (void)toggleMinSize
|
- (void)toggleMinSize
|
||||||
{
|
{
|
||||||
static bool state = false;
|
|
||||||
|
|
||||||
if([min_size_item state] == NSOnState)
|
if([min_size_item state] == NSOnState)
|
||||||
{
|
{
|
||||||
[min_size_item setState:NSOffState];
|
[min_size_item setState:NSOffState];
|
||||||
|
@ -881,6 +887,31 @@ NSSize min_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)screenShotToFile
|
||||||
|
{
|
||||||
|
BOOL was_paused = paused;
|
||||||
|
[NDS pause];
|
||||||
|
|
||||||
|
[[Screenshot alloc] initWithBuffer:correction_buffer rotation:rotation saveOnly:YES];
|
||||||
|
|
||||||
|
if(!was_paused)[NDS execute];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)screenShotToWindow
|
||||||
|
{
|
||||||
|
BOOL was_paused = paused;
|
||||||
|
[NDS pause];
|
||||||
|
|
||||||
|
[[Screenshot alloc] initWithBuffer:correction_buffer rotation:rotation saveOnly:NO];
|
||||||
|
|
||||||
|
if(!was_paused)[NDS execute];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (const u8*)getBuffer
|
||||||
|
{
|
||||||
|
return (const u8*)correction_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)keyDown:(NSEvent*)event
|
- (void)keyDown:(NSEvent*)event
|
||||||
{
|
{
|
||||||
if([event isARepeat])return;
|
if([event isARepeat])return;
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
//creation
|
//creation
|
||||||
- (id)init;
|
- (id)init;
|
||||||
|
|
||||||
|
//Firmware control
|
||||||
|
- (void)setPlayerName:(NSString*)player_name;
|
||||||
|
|
||||||
//ROM control
|
//ROM control
|
||||||
- (void)pickROM;
|
- (void)pickROM;
|
||||||
- (BOOL)loadROM:(NSString*)filename;
|
- (BOOL)loadROM:(NSString*)filename;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#import "globals.h"
|
#import "globals.h"
|
||||||
#import "nds_control.h"
|
#import "nds_control.h"
|
||||||
#import "main_window.h"
|
#import "main_window.h"
|
||||||
|
#import "preferences.h"
|
||||||
|
|
||||||
//DeSmuME general includes
|
//DeSmuME general includes
|
||||||
#define OBJ_C
|
#define OBJ_C
|
||||||
|
@ -79,6 +80,8 @@ volatile u8 frame_skip = 0; //this is one more than the acutal frame skip, a val
|
||||||
static int backupmemorytype=MC_TYPE_AUTODETECT;
|
static int backupmemorytype=MC_TYPE_AUTODETECT;
|
||||||
static u32 backupmemorysize=1;
|
static u32 backupmemorysize=1;
|
||||||
|
|
||||||
|
struct NDS_fw_config_data firmware;
|
||||||
|
|
||||||
NSString *current_file;
|
NSString *current_file;
|
||||||
|
|
||||||
@implementation NintendoDS
|
@implementation NintendoDS
|
||||||
|
@ -93,32 +96,28 @@ NSString *current_file;
|
||||||
NDS_Init( arm9_memio, &arm9_ctrl_iface,
|
NDS_Init( arm9_memio, &arm9_ctrl_iface,
|
||||||
arm7_memio, &arm7_ctrl_iface);
|
arm7_memio, &arm7_ctrl_iface);
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
enum nds_fw_ds_type ds_type;
|
|
||||||
|
|
||||||
u8 fav_colour;
|
|
||||||
u8 birth_month;
|
|
||||||
u8 birth_day;
|
|
||||||
|
|
||||||
u16 nickname[MAX_FW_NICKNAME_LENGTH];
|
|
||||||
u8 nickname_len;
|
|
||||||
|
|
||||||
u16 message[MAX_FW_MESSAGE_LENGTH];
|
|
||||||
u8 message_len;
|
|
||||||
|
|
||||||
u8 language;
|
|
||||||
|
|
||||||
/* touchscreen calibration */
|
|
||||||
struct NDS_fw_touchscreen_cal touch_cal[2];
|
|
||||||
} NDS_fw_config_data;
|
|
||||||
|
|
||||||
NDS_fw_config_data firmware;
|
|
||||||
NDS_FillDefaultFirmwareConfigData(&firmware);
|
NDS_FillDefaultFirmwareConfigData(&firmware);
|
||||||
|
[self setPlayerName:@"Joe"];
|
||||||
NDS_CreateDummyFirmware(&firmware);
|
NDS_CreateDummyFirmware(&firmware);
|
||||||
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setPlayerName:(NSString*)player_name
|
||||||
|
{
|
||||||
|
//first we convert to UTF-16 which the DS uses to store the nickname
|
||||||
|
NSData *string_chars = [player_name dataUsingEncoding:NSUnicodeStringEncoding];
|
||||||
|
|
||||||
|
//copy the bytes
|
||||||
|
firmware.nickname_len = MIN([string_chars length],MAX_FW_NICKNAME_LENGTH);
|
||||||
|
[string_chars getBytes:firmware.nickname length:firmware.nickname_len];
|
||||||
|
firmware.nickname[firmware.nickname_len / 2] = 0;
|
||||||
|
|
||||||
|
//set the firmware
|
||||||
|
//NDS_CreateDummyFirmware(&firmware);
|
||||||
|
}
|
||||||
|
|
||||||
- (void)pickROM
|
- (void)pickROM
|
||||||
{
|
{
|
||||||
BOOL was_paused = paused;
|
BOOL was_paused = paused;
|
||||||
|
@ -145,7 +144,7 @@ typedef struct {
|
||||||
if(!NDS_LoadROM([filename cStringUsingEncoding:NSASCIIStringEncoding], backupmemorytype, backupmemorysize, "/Users/gecko/AAAA.sav") > 0)
|
if(!NDS_LoadROM([filename cStringUsingEncoding:NSASCIIStringEncoding], backupmemorytype, backupmemorysize, "/Users/gecko/AAAA.sav") > 0)
|
||||||
{
|
{
|
||||||
//if it didn't work give an error and dont unpause
|
//if it didn't work give an error and dont unpause
|
||||||
messageDialog(@"Error", @"Could not open file");
|
messageDialog(localizedString(@"Error", nil), @"Could not open file");
|
||||||
|
|
||||||
//continue playing if load didn't work
|
//continue playing if load didn't work
|
||||||
if(!was_paused)[self execute];
|
if(!was_paused)[self execute];
|
||||||
|
@ -153,6 +152,9 @@ typedef struct {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add the rom to the recent documents list
|
||||||
|
[[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL fileURLWithPath:filename]];
|
||||||
|
|
||||||
//set current file var
|
//set current file var
|
||||||
current_file = filename;
|
current_file = filename;
|
||||||
|
|
||||||
|
@ -191,8 +193,11 @@ typedef struct {
|
||||||
//layers apparently get reset on rom load?
|
//layers apparently get reset on rom load?
|
||||||
//[set topBG2_item fixme
|
//[set topBG2_item fixme
|
||||||
|
|
||||||
//if it worked, unpause (start)
|
//if it worked, check the execute upon load option
|
||||||
[self execute];
|
if([[NSUserDefaults standardUserDefaults] boolForKey:PREF_EXECUTE_UPON_LOAD])
|
||||||
|
[self execute];
|
||||||
|
else
|
||||||
|
[main_window clearScreenWhite];
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -233,7 +238,7 @@ typedef struct {
|
||||||
{
|
{
|
||||||
[self closeROM];
|
[self closeROM];
|
||||||
|
|
||||||
[main_window clearScreen];
|
[main_window clearScreenBlack];
|
||||||
}
|
}
|
||||||
else if(!was_paused)[NDS execute];
|
else if(!was_paused)[NDS execute];
|
||||||
}
|
}
|
||||||
|
@ -395,8 +400,26 @@ typedef struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)saveStateAs
|
- (void)saveStateAs
|
||||||
{
|
{//dst
|
||||||
messageDialog(@"LOAD",@"DDSA");
|
BOOL was_paused = paused;
|
||||||
|
[NDS pause];
|
||||||
|
|
||||||
|
NSSavePanel *panel = [NSSavePanel savePanel];
|
||||||
|
|
||||||
|
[panel setTitle:localizedString(@"Save State to File...", nil)];
|
||||||
|
[panel setAllowedFileTypes:[NSArray arrayWithObjects:@"dst",nil]];
|
||||||
|
|
||||||
|
if([panel runModal] == NSOKButton)
|
||||||
|
{
|
||||||
|
|
||||||
|
NSString *filename = [panel filename];
|
||||||
|
|
||||||
|
if(filename)
|
||||||
|
savestate_save([filename cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!was_paused)[NDS execute];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)loadStateFrom
|
- (void)loadStateFrom
|
||||||
|
|
|
@ -1,9 +1,39 @@
|
||||||
|
/* Copyright (C) 2007 Jeff Bland
|
||||||
|
|
||||||
|
This file is part of DeSmuME
|
||||||
|
|
||||||
|
DeSmuME 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.
|
||||||
|
|
||||||
|
DeSmuME is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with DeSmuME; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
#import "globals.h"
|
#import "globals.h"
|
||||||
|
#import "preferences.h"
|
||||||
#import "nds_control.h"
|
#import "nds_control.h"
|
||||||
|
|
||||||
|
/* Preference settings are stored using NSUserDefaults
|
||||||
|
which should put them in a propert list in /Users/username/Library/Preferences
|
||||||
|
|
||||||
|
For the keys we use the same strings you see in the preference menu
|
||||||
|
such as "Language" to keep things simple, of course the unlocalized version
|
||||||
|
of the strings are used so that when you change language it will still
|
||||||
|
finds the settings from before. Also theres no guarantee that localized
|
||||||
|
strings will be unique.
|
||||||
|
*/
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
NSWindow *preferences_window;
|
NSWindow *preferences_window = NULL;
|
||||||
|
|
||||||
NSFont *preferences_font;
|
NSFont *preferences_font;
|
||||||
NSDictionary *preferences_font_attribs;
|
NSDictionary *preferences_font_attribs;
|
||||||
|
@ -15,18 +45,54 @@ NSTabViewItem *plugins_pane_tab;
|
||||||
NSText *language_selection_text;
|
NSText *language_selection_text;
|
||||||
NSPopUpButton *language_selection;
|
NSPopUpButton *language_selection;
|
||||||
|
|
||||||
|
NSDictionary *desmume_defaults;
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
@interface PreferencesDelegate : NSObject {}
|
@interface PreferencesDelegate : NSObject {}
|
||||||
- (void)windowWillClose:(NSNotification *)aNotification;
|
- (void)windowWillClose:(NSNotification*)aNotification;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation PreferencesDelegate
|
@implementation PreferencesDelegate
|
||||||
- (void)windowWillClose:(NSNotification *)aNotification
|
- (void)windowWillClose:(NSNotification*)aNotification
|
||||||
{
|
{
|
||||||
|
//[preferences_window saveFrameUsingName:@"DeSmuME Preferences Window"];
|
||||||
|
[preferences_window setFrameAutosaveName:@"DeSmuME Preferences Window"];
|
||||||
|
|
||||||
[NSApp stopModal];
|
[NSApp stopModal];
|
||||||
|
|
||||||
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)textDidChange:(NSNotification*)notification
|
||||||
|
{
|
||||||
|
NSText *text_field = [notification object];
|
||||||
|
NSString *text = [text_field string];
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)executeUponLoad:(id)sender
|
||||||
|
{
|
||||||
|
BOOL value = ([sender indexOfSelectedItem] == 0) ? YES : NO;
|
||||||
|
|
||||||
|
[[NSUserDefaults standardUserDefaults] setBool:value forKey:PREF_EXECUTE_UPON_LOAD];
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
- (void)numRecentItems:(id)sender
|
||||||
|
{
|
||||||
|
NSString *value = @"invalid";
|
||||||
|
|
||||||
|
if([sender indexOfSelectedItem] == 0)
|
||||||
|
value = @"5";
|
||||||
|
if([sender indexOfSelectedItem] == 1)
|
||||||
|
value = @"10";
|
||||||
|
if([sender indexOfSelectedItem] == 2)
|
||||||
|
value = @"15";
|
||||||
|
|
||||||
|
[[NSUserDefaults standardUserDefaults] setObject:value forKey:PREF_NUM_RECENT_ITEMS];
|
||||||
|
}*/
|
||||||
|
|
||||||
- (void)languageChange:(id)sender
|
- (void)languageChange:(id)sender
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -82,104 +148,267 @@ See the GNU General Public License details in COPYING.", nil/*OK*/, nil, nil);
|
||||||
|
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
|
|
||||||
|
NSView *createPreferencesView(NSTabViewItem *tab, NSDictionary *options, id delegate)
|
||||||
|
{
|
||||||
|
//create the view
|
||||||
|
NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(0,0,400-10,300-10)];
|
||||||
|
[tab setView:view];
|
||||||
|
|
||||||
|
//loop through each option in the options list
|
||||||
|
NSEnumerator *key_enumerator = [options keyEnumerator];
|
||||||
|
NSEnumerator *object_enumerator = [options objectEnumerator];
|
||||||
|
id key, key_raw, object;
|
||||||
|
NSRect text_rect = NSMakeRect(0, 230, 255, 29);
|
||||||
|
NSRect button_rect = NSMakeRect(230, 230, 130, 26);
|
||||||
|
while ((key_raw = [key_enumerator nextObject]))
|
||||||
|
{
|
||||||
|
object = [object_enumerator nextObject];
|
||||||
|
|
||||||
|
key = localizedString(key_raw, nil);
|
||||||
|
|
||||||
|
NSString *current_setting = [[NSUserDefaults standardUserDefaults] objectForKey:key_raw];
|
||||||
|
|
||||||
|
button_rect.origin.y -= 29;
|
||||||
|
|
||||||
|
if([[object objectAtIndex:0] compare:@"Bool"] == NSOrderedSame)
|
||||||
|
{
|
||||||
|
//Create the button for this option
|
||||||
|
NSPopUpButton *button = [[NSPopUpButton alloc] initWithFrame:button_rect pullsDown:NO];
|
||||||
|
|
||||||
|
//Setup the button callback
|
||||||
|
//the items array should have a selector encoded in an NSData
|
||||||
|
//since we can't stick a selector directly in an NSArray
|
||||||
|
SEL action;
|
||||||
|
[[object objectAtIndex:1] getBytes:&action];
|
||||||
|
[button setAction:action];
|
||||||
|
[button setTarget:delegate];
|
||||||
|
|
||||||
|
[button addItemWithTitle:localizedString(@"Yes",nil)];
|
||||||
|
[button addItemWithTitle:localizedString(@"No",nil)];
|
||||||
|
|
||||||
|
[button selectItemAtIndex:([[NSUserDefaults standardUserDefaults] boolForKey:PREF_EXECUTE_UPON_LOAD] == YES) ? 0 : 1];
|
||||||
|
|
||||||
|
[view addSubview:button];
|
||||||
|
|
||||||
|
}
|
||||||
|
else if([[object objectAtIndex:0] compare:@"Array"] == 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];
|
||||||
|
|
||||||
|
int i;
|
||||||
|
bool found = false;
|
||||||
|
for(i = 2; i < [object count]; i++)
|
||||||
|
{
|
||||||
|
//add the item to the popup buttons list
|
||||||
|
[button addItemWithTitle:localizedString([object objectAtIndex:i],nil)];
|
||||||
|
|
||||||
|
//if this is the currently selected or default item
|
||||||
|
if([current_setting compare:[object objectAtIndex:i]] == NSOrderedSame)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
[button selectItemAtIndex:i - 2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found)
|
||||||
|
{ //the user setting for this option was not found
|
||||||
|
|
||||||
|
//get the default value
|
||||||
|
current_setting = [desmume_defaults objectForKey:key_raw];
|
||||||
|
|
||||||
|
//show an error
|
||||||
|
messageDialog(localizedString(@"Error",nil), [NSString stringWithFormat:localizedString(@"%@ setting corrupt, resetting to default (%@)",nil),key, localizedString(current_setting, nil)]);
|
||||||
|
|
||||||
|
//set the setting to default
|
||||||
|
[[NSUserDefaults standardUserDefaults] setObject:current_setting forKey:key_raw];
|
||||||
|
|
||||||
|
//show the default setting in the button
|
||||||
|
for(i = 2; i < [object count]; i++)
|
||||||
|
if([current_setting compare:[object objectAtIndex:i]] == NSOrderedSame)
|
||||||
|
;//[button selectItemAtIndex:i - 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
[view addSubview:button];
|
||||||
|
|
||||||
|
} else if ([[object objectAtIndex:0] caseInsensitiveCompare:@"Text"] == NSOrderedSame)
|
||||||
|
{
|
||||||
|
|
||||||
|
//if this preference is a text field
|
||||||
|
//we will create a text field and add it to the view
|
||||||
|
NSRect temp = button_rect;
|
||||||
|
temp.size.height = [current_setting sizeWithAttributes:preferences_font_attribs].height + 2;
|
||||||
|
temp.origin.y += (26. - temp.size.height) / 2.;
|
||||||
|
NSText *text = [[NSText alloc] initWithFrame:temp];
|
||||||
|
[text setMinSize:temp.size];
|
||||||
|
[text setMaxSize:temp.size];
|
||||||
|
[text setFont:preferences_font];
|
||||||
|
[text setString:current_setting];
|
||||||
|
[text setEditable:YES];
|
||||||
|
[text setDrawsBackground:YES];
|
||||||
|
[text setDelegate:delegate];
|
||||||
|
[view addSubview:text];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create text for this option
|
||||||
|
text_rect.size.height = [key sizeWithAttributes:preferences_font_attribs].height;
|
||||||
|
text_rect.origin.y = button_rect.origin.y + (26. - [key sizeWithAttributes:preferences_font_attribs].height) / 2.;
|
||||||
|
NSText *text = [[NSText alloc] initWithFrame:text_rect];
|
||||||
|
[text setFont:preferences_font];
|
||||||
|
[text setString:key];
|
||||||
|
[text setEditable:NO];
|
||||||
|
[text setDrawsBackground:NO];
|
||||||
|
[text setSelectable:NO];
|
||||||
|
[text setVerticallyResizable:NO];
|
||||||
|
[view addSubview:text];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//set the view
|
||||||
|
[tab setView:view];
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAppDefaults()
|
||||||
|
{
|
||||||
|
|
||||||
|
desmume_defaults = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
|
||||||
|
//Interface defaults
|
||||||
|
@"Yes", PREF_EXECUTE_UPON_LOAD,
|
||||||
|
|
||||||
|
//Firmware defaults
|
||||||
|
@"DeSmuME User", PREF_FIRMWARE_PLAYER_NAME,
|
||||||
|
@"English", PREF_FIRMWARE_LANGUAGE,
|
||||||
|
|
||||||
|
//Plugin defaults
|
||||||
|
@"OpenGL 3D", PREF_3D_PLUGIN,
|
||||||
|
@"None", PREF_SOUND_PLUGIN,
|
||||||
|
|
||||||
|
nil];
|
||||||
|
[desmume_defaults retain];
|
||||||
|
|
||||||
|
//window size defaults
|
||||||
|
NSRect temp;
|
||||||
|
temp.origin.x = 600;
|
||||||
|
temp.origin.y = 600;
|
||||||
|
temp.size.width = 500;
|
||||||
|
temp.size.height = 600;
|
||||||
|
//[NSData dataWithBytes:&temp length:sizeof(NSRect)], @"DeSmuME Preferences Window", nil];
|
||||||
|
|
||||||
|
[[NSUserDefaults standardUserDefaults] registerDefaults:desmume_defaults];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
- (void)preferences
|
- (void)preferences
|
||||||
{
|
{
|
||||||
|
|
||||||
bool was_paused = paused;
|
bool was_paused = paused;
|
||||||
[NDS pause];
|
[NDS pause];
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------
|
if(!preferences_window)
|
||||||
|
{
|
||||||
|
|
||||||
//get the applications main bundle
|
//----------------------------------------------------------------------------------------------
|
||||||
NSBundle* app_bundle = [NSBundle mainBundle];
|
|
||||||
|
|
||||||
//grab the list of languages
|
//get the applications main bundle
|
||||||
NSArray *languages = [app_bundle localizations];
|
NSBundle* app_bundle = [NSBundle mainBundle];
|
||||||
|
|
||||||
//get a font for displaying text
|
//grab the list of languages
|
||||||
preferences_font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]];
|
NSArray *languages = [app_bundle localizations];
|
||||||
|
|
||||||
preferences_font_attribs = [NSDictionary dictionaryWithObjectsAndKeys:preferences_font, NSFontAttributeName, nil];
|
//get a font for displaying text
|
||||||
|
preferences_font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]];
|
||||||
|
|
||||||
//create our delegate
|
preferences_font_attribs = [NSDictionary dictionaryWithObjectsAndKeys:preferences_font, NSFontAttributeName, nil];
|
||||||
PreferencesDelegate *delegate = [[PreferencesDelegate alloc] init];
|
|
||||||
//
|
|
||||||
int i; //general iterator
|
|
||||||
|
|
||||||
//Create the window ------------------------------------------------------------------------------
|
//create our delegate
|
||||||
|
PreferencesDelegate *delegate = [[PreferencesDelegate alloc] init];
|
||||||
|
|
||||||
//create a preferences window
|
//Create the window ------------------------------------------------------------------------------
|
||||||
NSRect rect;
|
|
||||||
rect.size.width = 400;
|
|
||||||
rect.size.height = 300;
|
|
||||||
rect.origin.x = 200;
|
|
||||||
rect.origin.y = 200;
|
|
||||||
preferences_window = [[NSWindow alloc] initWithContentRect:rect styleMask:
|
|
||||||
NSTitledWindowMask|NSClosableWindowMask backing:NSBackingStoreBuffered defer:NO screen:nil];
|
|
||||||
|
|
||||||
//set the window title
|
//create a preferences window
|
||||||
[preferences_window setTitle:localizedString(@"DeSmuME Preferences", nil)];
|
NSRect rect;
|
||||||
|
rect.size.width = 400;
|
||||||
|
rect.size.height = 300;
|
||||||
|
rect.origin.x = 200;
|
||||||
|
rect.origin.y = 200;
|
||||||
|
preferences_window = [[NSWindow alloc] initWithContentRect:rect styleMask:
|
||||||
|
NSTitledWindowMask|NSClosableWindowMask backing:NSBackingStoreBuffered defer:NO screen:nil];
|
||||||
|
|
||||||
//set the window delegate
|
//set the window title
|
||||||
[preferences_window setDelegate:delegate];
|
[preferences_window setTitle:localizedString(@"DeSmuME Preferences", nil)];
|
||||||
|
|
||||||
//create a tab view
|
//set the window delegate
|
||||||
rect.size.width = 400 - 10;
|
[preferences_window setDelegate:delegate];
|
||||||
rect.size.height = 300 - 10;
|
|
||||||
rect.origin.x = 5;
|
|
||||||
rect.origin.y = 5;
|
|
||||||
NSTabView *tab_view = [[NSTabView alloc] initWithFrame:rect];
|
|
||||||
[[preferences_window contentView] addSubview:tab_view];
|
|
||||||
|
|
||||||
//Create the "Interface" pane
|
//create a tab view
|
||||||
interface_pane_tab = [[NSTabViewItem alloc] initWithIdentifier:nil];
|
rect.size.width = 400 - 10;
|
||||||
[interface_pane_tab setLabel:localizedString(@"Interface", nil)];
|
rect.size.height = 300 - 10;
|
||||||
[tab_view addTabViewItem:interface_pane_tab];
|
rect.origin.x = 5;
|
||||||
|
rect.origin.y = 5;
|
||||||
|
NSTabView *tab_view = [[NSTabView alloc] initWithFrame:rect];
|
||||||
|
[[preferences_window contentView] addSubview:tab_view];
|
||||||
|
|
||||||
//Create interface view
|
//Create the "Interface" pane
|
||||||
rect.size.width = 400 - 10;
|
interface_pane_tab = [[NSTabViewItem alloc] initWithIdentifier:nil];
|
||||||
rect.size.height = 300 - 10;
|
[interface_pane_tab setLabel:localizedString(@"Interface", nil)];
|
||||||
rect.origin.x = 0;
|
[tab_view addTabViewItem:interface_pane_tab];
|
||||||
rect.origin.y = 0;
|
|
||||||
NSView *interface_view = [[NSView alloc] initWithFrame:rect];
|
|
||||||
[interface_pane_tab setView:interface_view];
|
|
||||||
|
|
||||||
//Create language selection text
|
//Create interface view
|
||||||
rect.size.width = 225;
|
NSDictionary *interface_options = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
rect.size.height = 29 - [localizedString(@"Language",nil) sizeWithAttributes:preferences_font_attribs].height / 2;
|
[NSArray arrayWithObjects:@"Bool", [NSData dataWithBytes:&@selector(executeUponLoad:) length:sizeof(SEL)], @"Yes",@"No",nil], PREF_EXECUTE_UPON_LOAD,
|
||||||
rect.origin.x = 0;
|
nil];
|
||||||
rect.origin.y = 200;// + [localizedString(@"Language",nil) sizeWithAttributes:preferences_font_attribs].height / 2;
|
|
||||||
language_selection_text = [[NSText alloc] initWithFrame:rect];
|
|
||||||
[language_selection_text setFont: preferences_font];
|
|
||||||
[language_selection_text setString:localizedString(@"Language",nil)];
|
|
||||||
[language_selection_text setEditable:NO];
|
|
||||||
[language_selection_text setDrawsBackground:NO];
|
|
||||||
[interface_view addSubview:language_selection_text];
|
|
||||||
|
|
||||||
//Create language selection button
|
NSView *interface_view = createPreferencesView(interface_pane_tab, interface_options, delegate);
|
||||||
rect.size.width = 130;
|
|
||||||
rect.size.height = 26;
|
|
||||||
rect.origin.x = 230;
|
|
||||||
rect.origin.y = 200;
|
|
||||||
language_selection = [[NSPopUpButton alloc] initWithFrame:rect pullsDown:NO];
|
|
||||||
[language_selection addItemWithTitle:@"Default"];
|
|
||||||
for(i = 0; i < [languages count]; i++)
|
|
||||||
[language_selection addItemWithTitle:[languages objectAtIndex:i]];
|
|
||||||
[language_selection setAction:@selector(languageChange:)];
|
|
||||||
[language_selection setTarget:delegate];
|
|
||||||
[interface_view addSubview:language_selection];
|
|
||||||
|
|
||||||
//Create the "DS Firmware" pane
|
//Create the firmware pane
|
||||||
firmware_pane_tab = [[NSTabViewItem alloc] initWithIdentifier:nil];
|
firmware_pane_tab = [[NSTabViewItem alloc] initWithIdentifier:nil];
|
||||||
[firmware_pane_tab setLabel:localizedString(@"DS Firmware", nil)];
|
[firmware_pane_tab setLabel:localizedString(@"DS Firmware", nil)];
|
||||||
[tab_view addTabViewItem:firmware_pane_tab];
|
[tab_view addTabViewItem:firmware_pane_tab];
|
||||||
|
|
||||||
//Create the "Plugins" pane
|
NSDictionary *firmware_options = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
plugins_pane_tab = [[NSTabViewItem alloc] initWithIdentifier:nil];
|
[NSArray arrayWithObjects:@"Text", [NSData dataWithBytes:&@selector(playerName:) length:sizeof(SEL)], nil], PREF_FIRMWARE_PLAYER_NAME,
|
||||||
[plugins_pane_tab setLabel:localizedString(@"Plugins", nil)];
|
[NSArray arrayWithObjects:@"Array", [NSData dataWithBytes:&@selector(nonexisant:) length:sizeof(SEL)], @"Danish",@"English",@"French",nil], PREF_FIRMWARE_LANGUAGE,
|
||||||
[tab_view addTabViewItem:plugins_pane_tab];
|
nil];
|
||||||
|
|
||||||
|
NSView *firmware_view = createPreferencesView(firmware_pane_tab, firmware_options, delegate);
|
||||||
|
|
||||||
|
//Create the "Plugins" pane
|
||||||
|
plugins_pane_tab = [[NSTabViewItem alloc] initWithIdentifier:nil];
|
||||||
|
[plugins_pane_tab setLabel:localizedString(@"Plugins", nil)];
|
||||||
|
[tab_view addTabViewItem:plugins_pane_tab];
|
||||||
|
|
||||||
|
NSDictionary *plugin_options = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
[NSArray arrayWithObjects:@"Array", [NSData dataWithBytes:&@selector(nonexisant:) length:sizeof(SEL)], @"OpenGL 3D",nil], PREF_3D_PLUGIN,
|
||||||
|
[NSArray arrayWithObjects:@"Array", [NSData dataWithBytes:&@selector(nonexisant:) length:sizeof(SEL)], @"None",nil], PREF_SOUND_PLUGIN,
|
||||||
|
nil];
|
||||||
|
|
||||||
|
NSView *plugins_view = createPreferencesView(plugins_pane_tab, plugin_options, delegate);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//make the window controller
|
||||||
|
NSWindowController *wc = [[NSWindowController alloc] initWithWindow:preferences_window];
|
||||||
|
[wc setShouldCascadeWindows:NO];
|
||||||
|
|
||||||
|
//tell it to store/retrieve window frame from/to previous/later sessions
|
||||||
|
[preferences_window setFrameUsingName:@"DeSmuME Preferences Window" force:YES];
|
||||||
|
//[preferences_window setFrameAutosaveName:@"DeSmuME Preferences Window"];
|
||||||
|
//messageDialog([preferences_window frameAutosaveName],@"");
|
||||||
|
|
||||||
//show the window
|
//show the window
|
||||||
[[[NSWindowController alloc] initWithWindow:preferences_window] showWindow:nil];
|
[wc showWindow:nil];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[NSApp runModalForWindow:preferences_window];
|
[NSApp runModalForWindow:preferences_window];
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/* Copyright (C) 2007 Jeff Bland
|
||||||
|
|
||||||
|
This file is part of DeSmuME
|
||||||
|
|
||||||
|
DeSmuME 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.
|
||||||
|
|
||||||
|
DeSmuME is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with DeSmuME; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SCREENSHOT_H
|
||||||
|
#define SCREENSHOT_H
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
#define OBJ_C
|
||||||
|
#include "../types.h"
|
||||||
|
#undef BOOL
|
||||||
|
|
||||||
|
@interface Screenshot : NSObject
|
||||||
|
{
|
||||||
|
NSWindow *window;
|
||||||
|
NSImage *image;
|
||||||
|
NSImageView *image_view;
|
||||||
|
NSButton *save_button;
|
||||||
|
NSButton *update_button;
|
||||||
|
NSBitmapImageRep *image_rep;
|
||||||
|
NSView *format_selection;
|
||||||
|
NSPopUpButton *format_button;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)initWithBuffer:(u8*)buffer rotation:(u8)rotation saveOnly:(BOOL)save_only;
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,352 @@
|
||||||
|
/* Copyright (C) 2007 Jeff Bland
|
||||||
|
|
||||||
|
This file is part of DeSmuME
|
||||||
|
|
||||||
|
DeSmuME 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.
|
||||||
|
|
||||||
|
DeSmuME is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with DeSmuME; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
//DeSmuME Cocoa includes
|
||||||
|
#import "globals.h"
|
||||||
|
#import "screenshot.h"
|
||||||
|
#import "main_window.h"
|
||||||
|
#import "nds_control.h"
|
||||||
|
|
||||||
|
//DeSmuME general includes
|
||||||
|
#define OBJ_C
|
||||||
|
#include "../MMU.h"
|
||||||
|
#include "../GPU.h"
|
||||||
|
#undef BOOL
|
||||||
|
|
||||||
|
#define BUTTON_HEIGHT 26.
|
||||||
|
#define RESIZE_CONTROL_WIDTH 12.
|
||||||
|
#define NUM_BUTTONS 2.
|
||||||
|
|
||||||
|
@interface Screenshot (delegate)
|
||||||
|
- (void)windowDidResize:(NSNotification*)aNotification;
|
||||||
|
- (void)saveButtonPressed;
|
||||||
|
- (void)updateButtonPressed;
|
||||||
|
- (BOOL)panel:(id)sender isValidFilename:(NSString*)filename;
|
||||||
|
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation Screenshot (delegate)
|
||||||
|
- (void)windowDidResize:(NSNotification*)aNotification
|
||||||
|
{
|
||||||
|
NSRect content_frame = [[window contentView] frame];
|
||||||
|
[image_view setFrame:NSMakeRect(0, BUTTON_HEIGHT, content_frame.size.width, content_frame.size.height - BUTTON_HEIGHT)];
|
||||||
|
|
||||||
|
float button_width = (content_frame.size.width - RESIZE_CONTROL_WIDTH) / NUM_BUTTONS;
|
||||||
|
[save_button setFrame:NSMakeRect(0, 0, button_width, BUTTON_HEIGHT)];
|
||||||
|
[update_button setFrame:NSMakeRect(button_width, 0, button_width, BUTTON_HEIGHT)];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)saveButtonPressed
|
||||||
|
{//localize
|
||||||
|
NSSavePanel *panel = [NSSavePanel savePanel];
|
||||||
|
|
||||||
|
//Create format selection list
|
||||||
|
NSRect rect;
|
||||||
|
rect.size.width = 130;
|
||||||
|
rect.size.height = 26;
|
||||||
|
rect.origin.x = 230;
|
||||||
|
rect.origin.y = 200;
|
||||||
|
|
||||||
|
[panel setTitle:localizedString(@"Save Screenshot to File", nil)];
|
||||||
|
//[panel setAllowedFileTypes:[NSArray arrayWithObjects:@"bmp",@"gif",nil]];
|
||||||
|
|
||||||
|
if(!format_selection)
|
||||||
|
{
|
||||||
|
NSFont *font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]];
|
||||||
|
|
||||||
|
NSTextView *format_text = [[NSTextView alloc] initWithFrame:NSMakeRect(0,0,500,500)];
|
||||||
|
[format_text setFont:font];
|
||||||
|
[format_text setEditable:NO];
|
||||||
|
[format_text setDrawsBackground:NO];
|
||||||
|
[format_text setMaxSize:NSMakeSize(500,26)];
|
||||||
|
[format_text setMinSize:NSMakeSize(1,1)];
|
||||||
|
[format_text setHorizontallyResizable:YES];
|
||||||
|
[format_text setVerticallyResizable:YES];
|
||||||
|
[format_text setString:localizedString(@"Select Image Format: ", nil)];
|
||||||
|
[format_text sizeToFit];
|
||||||
|
|
||||||
|
//center vertically
|
||||||
|
NSRect temp = [format_text frame];
|
||||||
|
temp.origin.y = 26.0 / 2.0 - (float)[format_text frame].size.height / 2.0;
|
||||||
|
[format_text setFrame:temp];
|
||||||
|
|
||||||
|
format_button = [[NSPopUpButton alloc] initWithFrame:NSMakeRect([format_text frame].size.width,0,200,26) pullsDown:NO];
|
||||||
|
[format_button addItemWithTitle:localizedString(@"Pick by Extension", nil)];
|
||||||
|
[format_button addItemWithTitle:localizedString(@"BMP", nil)];
|
||||||
|
[format_button addItemWithTitle:localizedString(@"GIF", nil)];
|
||||||
|
[format_button addItemWithTitle:localizedString(@"JPG", nil)];
|
||||||
|
[format_button addItemWithTitle:localizedString(@"PNG", nil)];
|
||||||
|
[format_button addItemWithTitle:localizedString(@"TIFF", nil)];
|
||||||
|
//[format_button setAction:@selector(??)];
|
||||||
|
//[format_button setTarget:self];
|
||||||
|
|
||||||
|
format_selection = [[NSView alloc] initWithFrame:NSMakeRect(0,0,[format_text frame].size.width + [format_button frame].size.width,26)];
|
||||||
|
[format_selection addSubview:format_button];
|
||||||
|
[format_selection addSubview:format_text];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[panel setAccessoryView:format_selection];
|
||||||
|
|
||||||
|
[panel setDelegate:self];
|
||||||
|
|
||||||
|
if(window)
|
||||||
|
[panel beginSheetForDirectory:@"" file:@"Screenshot.bmp" modalForWindow:window modalDelegate:self
|
||||||
|
didEndSelector:nil contextInfo:nil];
|
||||||
|
else
|
||||||
|
[panel runModal];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateButtonPressed
|
||||||
|
{
|
||||||
|
BOOL was_paused = paused;
|
||||||
|
[NDS pause];
|
||||||
|
|
||||||
|
u8 *bitmap_data = [image_rep bitmapData];
|
||||||
|
|
||||||
|
const u16 *buffer_16 = (const u16*)[main_window getBuffer];
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < [image_rep size].width * [image_rep size].height; i++)
|
||||||
|
{ //this loop we go through pixel by pixel and convert from 16bit to 24bit for the NSImage
|
||||||
|
*(bitmap_data++) = (*buffer_16 & 0x001F) << 3;
|
||||||
|
*(bitmap_data++) = (*buffer_16 & 0x03E0) >> 5 << 3;
|
||||||
|
*(bitmap_data++) = (*buffer_16 & 0x7C00) >> 10 << 3;
|
||||||
|
buffer_16++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//there seems to be issues updating the image when
|
||||||
|
//it is scaled, probably due to some internal caching of the scaled version.
|
||||||
|
//resetting the image here to ensure that it updates properly.
|
||||||
|
[image_view setImage:nil];
|
||||||
|
[image_view setImage:image];
|
||||||
|
|
||||||
|
//tell the image to redraw [soon]
|
||||||
|
[image_view setNeedsDisplay:YES];
|
||||||
|
|
||||||
|
if(!was_paused)[NDS execute];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)panel:(id)sender isValidFilename:(NSString*)filename
|
||||||
|
{
|
||||||
|
NSBitmapImageFileType type = NSBMPFileType;
|
||||||
|
|
||||||
|
if([format_button indexOfSelectedItem] == 0)
|
||||||
|
{
|
||||||
|
NSString *ext = [filename pathExtension];
|
||||||
|
|
||||||
|
if([ext caseInsensitiveCompare:@"gif"] == NSOrderedSame)
|
||||||
|
type = NSGIFFileType;
|
||||||
|
else if([ext caseInsensitiveCompare:@"jpg"] == NSOrderedSame)
|
||||||
|
type = NSJPEGFileType;
|
||||||
|
else if([ext caseInsensitiveCompare:@"jpeg"] == NSOrderedSame)
|
||||||
|
type = NSJPEGFileType;
|
||||||
|
else if([ext caseInsensitiveCompare:@"png"] == NSOrderedSame)
|
||||||
|
type = NSPNGFileType;
|
||||||
|
else if([ext caseInsensitiveCompare:@"tiff"] == NSOrderedSame)
|
||||||
|
type = NSTIFFFileType;
|
||||||
|
|
||||||
|
}
|
||||||
|
if([format_button indexOfSelectedItem] == 2)
|
||||||
|
type = NSGIFFileType;
|
||||||
|
if([format_button indexOfSelectedItem] == 3)
|
||||||
|
type = NSJPEGFileType;
|
||||||
|
if([format_button indexOfSelectedItem] == 4)
|
||||||
|
type = NSPNGFileType;
|
||||||
|
if([format_button indexOfSelectedItem] == 5)
|
||||||
|
type = NSTIFFFileType;
|
||||||
|
|
||||||
|
[[image_rep representationUsingType:type properties:[NSDictionary dictionary]]
|
||||||
|
writeToFile:filename atomically:NO];
|
||||||
|
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename
|
||||||
|
{
|
||||||
|
NSString *ext = [filename pathExtension];
|
||||||
|
int index = [format_button indexOfSelectedItem];
|
||||||
|
|
||||||
|
if((index == 1) || (index == 0))
|
||||||
|
if([ext caseInsensitiveCompare:@"bmp"] == NSOrderedSame)
|
||||||
|
return YES;
|
||||||
|
|
||||||
|
if((index == 2) || (index == 0))
|
||||||
|
if([ext caseInsensitiveCompare:@"gif"] == NSOrderedSame)
|
||||||
|
return YES;
|
||||||
|
|
||||||
|
if((index == 3) || (index == 0))
|
||||||
|
if(([ext caseInsensitiveCompare:@"jpg"] == NSOrderedSame) || ([ext caseInsensitiveCompare:@"jpeg"] == NSOrderedSame))
|
||||||
|
return YES;
|
||||||
|
|
||||||
|
if((index == 4) || (index == 0))
|
||||||
|
if([ext caseInsensitiveCompare:@"png"] == NSOrderedSame)
|
||||||
|
return YES;
|
||||||
|
|
||||||
|
if((index == 5) || (index == 0))
|
||||||
|
if([ext caseInsensitiveCompare:@"tiff"] == NSOrderedSame)
|
||||||
|
return YES;
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation Screenshot
|
||||||
|
|
||||||
|
- (id)initWithBuffer:(u8*)buffer rotation:(u8)rotation saveOnly:(BOOL)save_only
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
|
||||||
|
//this gets set upon the first save panel
|
||||||
|
format_selection = nil;
|
||||||
|
window = nil;
|
||||||
|
|
||||||
|
NSRect rect;
|
||||||
|
if(rotation == ROTATION_0 || rotation == ROTATION_180)
|
||||||
|
{
|
||||||
|
rect.size.width = DS_SCREEN_WIDTH;
|
||||||
|
rect.size.height = DS_SCREEN_HEIGHT_COMBINED;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
rect.size.width = DS_SCREEN_HEIGHT_COMBINED;
|
||||||
|
rect.size.height = DS_SCREEN_WIDTH;
|
||||||
|
}
|
||||||
|
rect.origin.x = 200;
|
||||||
|
rect.origin.y = 200;
|
||||||
|
|
||||||
|
//create the image
|
||||||
|
image_rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
|
||||||
|
pixelsWide:rect.size.width
|
||||||
|
pixelsHigh:rect.size.height
|
||||||
|
bitsPerSample:8
|
||||||
|
samplesPerPixel:3
|
||||||
|
hasAlpha:NO
|
||||||
|
isPlanar:NO
|
||||||
|
colorSpaceName:NSCalibratedRGBColorSpace
|
||||||
|
bytesPerRow:rect.size.width * 3
|
||||||
|
bitsPerPixel:24];
|
||||||
|
|
||||||
|
if(!image_rep)
|
||||||
|
{
|
||||||
|
messageDialog(localizedString(@"Error", nil), @"Could not create NSBitmapImageRep for screenshot");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 *bitmap_data = [image_rep bitmapData];
|
||||||
|
|
||||||
|
u16 *buffer_16 = (u16*)buffer;
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < rect.size.width * rect.size.height; i++)
|
||||||
|
{ //this loop we go through pixel by pixel and convert from 16bit to 24bit for the NSImage
|
||||||
|
*(bitmap_data++) = (*buffer_16 & 0x001F) << 3;
|
||||||
|
*(bitmap_data++) = (*buffer_16 & 0x03E0) >> 5 << 3;
|
||||||
|
*(bitmap_data++) = (*buffer_16 & 0x7C00) >> 10 << 3;
|
||||||
|
buffer_16++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(save_only)
|
||||||
|
{
|
||||||
|
[self saveButtonPressed];
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
|
||||||
|
//create the image
|
||||||
|
image = [[NSImage alloc] initWithSize:NSMakeSize(rect.size.width, rect.size.height)];
|
||||||
|
|
||||||
|
if(!image)
|
||||||
|
{
|
||||||
|
messageDialog(localizedString(@"Error", nil), @"Could not create NSImage for screenshot window");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
[image setBackgroundColor:[NSColor whiteColor]];
|
||||||
|
[image addRepresentation:image_rep];
|
||||||
|
|
||||||
|
//create the image view
|
||||||
|
image_view = [[NSImageView alloc] initWithFrame:rect];
|
||||||
|
|
||||||
|
if(!image_view)
|
||||||
|
{
|
||||||
|
messageDialog(localizedString(@"Error", nil), @"Could not create NSImageView for screenshot window");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
[image_view setImage:image];
|
||||||
|
[image_view setImageScaling:NSScaleToFit];
|
||||||
|
|
||||||
|
//create the save button
|
||||||
|
save_button = [[NSButton alloc] initWithFrame:rect];
|
||||||
|
|
||||||
|
if(!save_button)
|
||||||
|
{
|
||||||
|
messageDialog(localizedString(@"Error", nil), @"Could not create save button for screenshot window");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
[save_button setBezelStyle:NSRoundedBezelStyle];
|
||||||
|
[save_button setTitle:localizedString(@"Save Screenshot", nil)];
|
||||||
|
[save_button setAction:@selector(saveButtonPressed)];
|
||||||
|
[save_button setTarget:self];
|
||||||
|
|
||||||
|
//update
|
||||||
|
update_button = [[NSButton alloc] initWithFrame:rect];
|
||||||
|
|
||||||
|
if(!update_button)
|
||||||
|
{
|
||||||
|
messageDialog(localizedString(@"Error", nil), @"Could not create update button for screenshot window");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
[update_button setBezelStyle:NSRoundedBezelStyle];
|
||||||
|
[update_button setTitle:localizedString(@"Update Screenshot", nil)];
|
||||||
|
[update_button setAction:@selector(updateButtonPressed)];
|
||||||
|
[update_button setTarget:self];
|
||||||
|
|
||||||
|
//create a window
|
||||||
|
rect.size.height += BUTTON_HEIGHT;
|
||||||
|
window = [[NSWindow alloc] initWithContentRect:rect styleMask:
|
||||||
|
NSTitledWindowMask|NSClosableWindowMask|NSResizableWindowMask backing:NSBackingStoreBuffered defer:NO screen:nil];
|
||||||
|
|
||||||
|
//set the window title
|
||||||
|
[window setTitle:localizedString(@"DeSmuME Screenshot", nil)];
|
||||||
|
|
||||||
|
//set the window delegate
|
||||||
|
[window setDelegate:self];
|
||||||
|
|
||||||
|
//add the items to the window
|
||||||
|
[[window contentView] addSubview:image_view];
|
||||||
|
[[window contentView] addSubview:save_button];
|
||||||
|
[[window contentView] addSubview:update_button];
|
||||||
|
|
||||||
|
//size the stuff (by invoking our resize callback)
|
||||||
|
[self windowDidResize:nil];
|
||||||
|
|
||||||
|
//show the window
|
||||||
|
[[[NSWindowController alloc] initWithWindow:window] showWindow:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
Loading…
Reference in New Issue