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 link="1" />
|
||||
</Unit>
|
||||
<Unit filename="screenshot.h" />
|
||||
<Unit filename="screenshot.m">
|
||||
<Option compile="1" />
|
||||
<Option link="1" />
|
||||
</Unit>
|
||||
<Unit filename="../config.h" />
|
||||
<Unit filename="../cp15.c">
|
||||
<Option compilerVar="CC" />
|
||||
|
|
|
@ -37,6 +37,13 @@
|
|||
#define DS_SCREEN_X_RATIO (256.0 / (192.0 * 2.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------------------------------------------------------------------------------------
|
||||
//These are just useful little functions to help with stuff
|
||||
//defined in cocoa_util.m
|
||||
|
@ -135,6 +142,7 @@ extern NintendoDS *NDS;
|
|||
@class VideoOutputWindow;
|
||||
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;
|
||||
|
|
|
@ -42,9 +42,7 @@ FIXME: Apple+Q during open dialog = badness
|
|||
FIXME: Live resize needs to work without pausing emulator
|
||||
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: 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: 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: Traveling windows when constantly resizing with hotkey
|
||||
*/
|
||||
|
@ -74,10 +72,13 @@ NSMenu *menu;
|
|||
@interface NSApplication(delegate)
|
||||
|
||||
//delegate methods
|
||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
|
||||
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames;
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
|
||||
- (BOOL)application:(NSApplication*)sender openFile:(NSString*)filename;
|
||||
- (void)application:(NSApplication*)sender openFiles:(NSArray*)filenames;
|
||||
- (void)applicationWillFinishLaunching:(NSNotification*)aNotification;
|
||||
- (void)applicationDidFinishLaunching:(NSNotification*)aNotification;
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender;
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
@ -186,8 +187,8 @@ void CreateMenu()
|
|||
[application_menu addItem: [NSMenuItem separatorItem]];
|
||||
|
||||
//Add the preferences menu
|
||||
//temp = [application_menu addItemWithTitle:@"Preferences..." action:@selector(preferences) keyEquivalent:@","];
|
||||
//[temp setTarget:NSApp];
|
||||
temp = [application_menu addItemWithTitle:@"Preferences..." action:@selector(preferences) keyEquivalent:@","];
|
||||
[temp setTarget:NSApp];
|
||||
|
||||
//
|
||||
[application_menu addItem: [NSMenuItem separatorItem]];
|
||||
|
@ -240,13 +241,29 @@ void CreateMenu()
|
|||
[temp setTarget:NDS];
|
||||
|
||||
//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:@""];
|
||||
|
||||
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];
|
||||
|
||||
[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]];
|
||||
|
||||
rom_info_item = [file addItemWithTitle:@"ROM Info..." action:@selector(showRomInfo) keyEquivalent:@""];
|
||||
|
@ -277,7 +294,6 @@ void CreateMenu()
|
|||
[load_state_menu setAutoenablesItems:NO];
|
||||
[temp setSubmenu:load_state_menu];
|
||||
|
||||
int i;
|
||||
for(i = 0; i < SAVE_SLOTS; i++)
|
||||
{
|
||||
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] setEnabled:YES];
|
||||
|
||||
int i2;
|
||||
for(i2 = 1; i2 < MAX_FRAME_SKIP; i2++)
|
||||
for(i = 1; i < MAX_FRAME_SKIP; i++)
|
||||
{
|
||||
frame_skip_item[i2] = [frame_skip_menu addItemWithTitle:@"%d" withInt:i2 action:@selector(setFrameSkip:) keyEquivalent:@""];
|
||||
[frame_skip_item[i2] setTarget:NDS];
|
||||
[frame_skip_item[i2] setEnabled:YES];
|
||||
frame_skip_item[i] = [frame_skip_menu addItemWithTitle:@"%d" withInt:i action:@selector(setFrameSkip:) keyEquivalent:@""];
|
||||
[frame_skip_item[i] setTarget:NDS];
|
||||
[frame_skip_item[i] setEnabled:YES];
|
||||
}
|
||||
|
||||
//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 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 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"];
|
||||
[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 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 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 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 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 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
|
||||
/*
|
||||
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)];
|
||||
[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 = [help addItemWithTitle:@"Forums" action:@selector(launchForums) keyEquivalent: @""];
|
||||
temp = [help addItemWithTitle:@"Go to Forums" action:@selector(launchForums) keyEquivalent: @""];
|
||||
[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];
|
||||
|
||||
[NSApp setMainMenu: menu];
|
||||
|
@ -545,37 +569,61 @@ int main(int argc, char *argv[])
|
|||
//gdb stuff--------------------------------------------------------------------------------
|
||||
//don't know and don't care
|
||||
|
||||
void *
|
||||
createThread_gdb( void (*thread_function)( void *data),
|
||||
void *thread_data) {
|
||||
return NULL;
|
||||
void *createThread_gdb(void (*thread_function)(void *data), void *thread_data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
joinThread_gdb( void *thread_handle) {
|
||||
void joinThread_gdb(void *thread_handle)
|
||||
{
|
||||
}
|
||||
|
||||
//Implementations-------------------------------------------------------------------------
|
||||
|
||||
@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])
|
||||
return YES;
|
||||
|
||||
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
|
||||
[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)
|
||||
main_window = [[VideoOutputWindow alloc] init];
|
||||
|
||||
//start with a blank screen
|
||||
[main_window clearScreen];
|
||||
|
||||
//create the menus
|
||||
CreateMenu();
|
||||
|
||||
//init opengl 3d ness
|
||||
NDS_3D_SetDriver (GPU3D_OPENGL);
|
||||
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"];
|
||||
//^ above line breaks everything!?
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
|
||||
//Main program loop ----------------------------------------------------------------------------
|
||||
//Start the main program loop ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef MULTITHREADED
|
||||
|
||||
|
@ -627,4 +673,5 @@ joinThread_gdb( void *thread_handle) {
|
|||
//AskForQuit takes care of quitting, dont need cocoa to do it for us
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -34,8 +34,9 @@
|
|||
//this is the only method involving cocoa that should be called from the run() function
|
||||
- (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
|
||||
- (void)resetMinSize:(bool)resize;
|
||||
|
@ -74,6 +75,11 @@
|
|||
- (void)toggleSubBackground2;
|
||||
- (void)toggleSubBackground3;
|
||||
|
||||
//screenshots
|
||||
- (void)screenShotToFile;
|
||||
- (void)screenShotToWindow;
|
||||
- (const unsigned char *)getBuffer;//pause before calling
|
||||
|
||||
//keyboard input
|
||||
- (void)keyDown:(NSEvent*)event;
|
||||
- (void)keyUp:(NSEvent*)event;
|
||||
|
@ -82,6 +88,7 @@
|
|||
- (void)mouseDown:(NSEvent*)event;
|
||||
- (void)mouseDragged:(NSEvent*)event;
|
||||
- (void)mouseUp:(NSEvent*)event;
|
||||
|
||||
@end
|
||||
|
||||
#endif //MAIN_WINDOW_H
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#import "globals.h"
|
||||
#import "main_window.h"
|
||||
#import "nds_control.h"
|
||||
#import "screenshot.h"
|
||||
|
||||
//DeSmuME general includes
|
||||
#define OBJ_C
|
||||
|
@ -106,10 +107,6 @@ unsigned short save_slot_10 = 109; //F10
|
|||
NSOpenGLContext *gpu_context;
|
||||
|
||||
//rotation
|
||||
#define ROTATION_0 0
|
||||
#define ROTATION_90 1
|
||||
#define ROTATION_180 2
|
||||
#define ROTATION_270 3
|
||||
u8 rotation = ROTATION_0;
|
||||
|
||||
//extern unsigned char GPU_screen3D[256*256*4];
|
||||
|
@ -151,7 +148,7 @@ NSSize min_size;
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -172,14 +169,14 @@ NSSize min_size;
|
|||
NSOpenGLPixelFormat* pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
|
||||
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;
|
||||
}
|
||||
|
||||
context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext: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;
|
||||
}
|
||||
|
||||
|
@ -202,14 +199,14 @@ NSSize min_size;
|
|||
NSOpenGLPixelFormat* pixel_format2 = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs2];
|
||||
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;
|
||||
}
|
||||
|
||||
gpu_context = [[NSOpenGLContext alloc] initWithFormat:pixel_format2 shareContext: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;
|
||||
}
|
||||
|
||||
|
@ -346,7 +343,7 @@ NSSize min_size;
|
|||
|
||||
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)
|
||||
//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.height = DS_SCREEN_HEIGHT_COMBINED;
|
||||
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
|
||||
{
|
||||
[[self contentView] addSubview:video_output_view];
|
||||
|
@ -383,6 +380,9 @@ NSSize min_size;
|
|||
//Show the window
|
||||
[[[NSWindowController alloc] initWithWindow:self] showWindow:nil];
|
||||
|
||||
//start with a blank screen
|
||||
[self clearScreenBlack];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -410,7 +410,7 @@ NSSize min_size;
|
|||
[video_output_view draw];
|
||||
}
|
||||
|
||||
- (void)clearScreen
|
||||
- (void)clearScreenWhite
|
||||
{
|
||||
//fill our buffer with pure white
|
||||
memset(&correction_buffer, 255, DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT_COMBINED * 2);
|
||||
|
@ -418,6 +418,14 @@ NSSize min_size;
|
|||
[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
|
||||
{
|
||||
if(rotation == ROTATION_0 || rotation == ROTATION_180)
|
||||
|
@ -450,8 +458,6 @@ NSSize min_size;
|
|||
|
||||
- (void)toggleMinSize
|
||||
{
|
||||
static bool state = false;
|
||||
|
||||
if([min_size_item state] == NSOnState)
|
||||
{
|
||||
[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
|
||||
{
|
||||
if([event isARepeat])return;
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
//creation
|
||||
- (id)init;
|
||||
|
||||
//Firmware control
|
||||
- (void)setPlayerName:(NSString*)player_name;
|
||||
|
||||
//ROM control
|
||||
- (void)pickROM;
|
||||
- (BOOL)loadROM:(NSString*)filename;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#import "globals.h"
|
||||
#import "nds_control.h"
|
||||
#import "main_window.h"
|
||||
#import "preferences.h"
|
||||
|
||||
//DeSmuME general includes
|
||||
#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 u32 backupmemorysize=1;
|
||||
|
||||
struct NDS_fw_config_data firmware;
|
||||
|
||||
NSString *current_file;
|
||||
|
||||
@implementation NintendoDS
|
||||
|
@ -93,32 +96,28 @@ NSString *current_file;
|
|||
NDS_Init( arm9_memio, &arm9_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);
|
||||
[self setPlayerName:@"Joe"];
|
||||
NDS_CreateDummyFirmware(&firmware);
|
||||
|
||||
|
||||
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
|
||||
{
|
||||
BOOL was_paused = paused;
|
||||
|
@ -145,7 +144,7 @@ typedef struct {
|
|||
if(!NDS_LoadROM([filename cStringUsingEncoding:NSASCIIStringEncoding], backupmemorytype, backupmemorysize, "/Users/gecko/AAAA.sav") > 0)
|
||||
{
|
||||
//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
|
||||
if(!was_paused)[self execute];
|
||||
|
@ -153,6 +152,9 @@ typedef struct {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
//add the rom to the recent documents list
|
||||
[[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL fileURLWithPath:filename]];
|
||||
|
||||
//set current file var
|
||||
current_file = filename;
|
||||
|
||||
|
@ -191,8 +193,11 @@ typedef struct {
|
|||
//layers apparently get reset on rom load?
|
||||
//[set topBG2_item fixme
|
||||
|
||||
//if it worked, unpause (start)
|
||||
[self execute];
|
||||
//if it worked, check the execute upon load option
|
||||
if([[NSUserDefaults standardUserDefaults] boolForKey:PREF_EXECUTE_UPON_LOAD])
|
||||
[self execute];
|
||||
else
|
||||
[main_window clearScreenWhite];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -233,7 +238,7 @@ typedef struct {
|
|||
{
|
||||
[self closeROM];
|
||||
|
||||
[main_window clearScreen];
|
||||
[main_window clearScreenBlack];
|
||||
}
|
||||
else if(!was_paused)[NDS execute];
|
||||
}
|
||||
|
@ -395,8 +400,26 @@ typedef struct {
|
|||
}
|
||||
|
||||
- (void)saveStateAs
|
||||
{
|
||||
messageDialog(@"LOAD",@"DDSA");
|
||||
{//dst
|
||||
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
|
||||
|
|
|
@ -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 "preferences.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;
|
||||
NSDictionary *preferences_font_attribs;
|
||||
|
@ -15,18 +45,54 @@ NSTabViewItem *plugins_pane_tab;
|
|||
NSText *language_selection_text;
|
||||
NSPopUpButton *language_selection;
|
||||
|
||||
NSDictionary *desmume_defaults;
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
@interface PreferencesDelegate : NSObject {}
|
||||
- (void)windowWillClose:(NSNotification *)aNotification;
|
||||
- (void)windowWillClose:(NSNotification*)aNotification;
|
||||
@end
|
||||
|
||||
@implementation PreferencesDelegate
|
||||
- (void)windowWillClose:(NSNotification *)aNotification
|
||||
- (void)windowWillClose:(NSNotification*)aNotification
|
||||
{
|
||||
//[preferences_window saveFrameUsingName:@"DeSmuME Preferences Window"];
|
||||
[preferences_window setFrameAutosaveName:@"DeSmuME Preferences Window"];
|
||||
|
||||
[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
|
||||
{
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
||||
bool was_paused = paused;
|
||||
[NDS pause];
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
if(!preferences_window)
|
||||
{
|
||||
|
||||
//get the applications main bundle
|
||||
NSBundle* app_bundle = [NSBundle mainBundle];
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
//grab the list of languages
|
||||
NSArray *languages = [app_bundle localizations];
|
||||
//get the applications main bundle
|
||||
NSBundle* app_bundle = [NSBundle mainBundle];
|
||||
|
||||
//get a font for displaying text
|
||||
preferences_font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]];
|
||||
//grab the list of languages
|
||||
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
|
||||
PreferencesDelegate *delegate = [[PreferencesDelegate alloc] init];
|
||||
//
|
||||
int i; //general iterator
|
||||
preferences_font_attribs = [NSDictionary dictionaryWithObjectsAndKeys:preferences_font, NSFontAttributeName, nil];
|
||||
|
||||
//Create the window ------------------------------------------------------------------------------
|
||||
//create our delegate
|
||||
PreferencesDelegate *delegate = [[PreferencesDelegate alloc] init];
|
||||
|
||||
//create a preferences 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];
|
||||
//Create the window ------------------------------------------------------------------------------
|
||||
|
||||
//set the window title
|
||||
[preferences_window setTitle:localizedString(@"DeSmuME Preferences", nil)];
|
||||
//create a preferences 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 delegate
|
||||
[preferences_window setDelegate:delegate];
|
||||
//set the window title
|
||||
[preferences_window setTitle:localizedString(@"DeSmuME Preferences", nil)];
|
||||
|
||||
//create a tab view
|
||||
rect.size.width = 400 - 10;
|
||||
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];
|
||||
//set the window delegate
|
||||
[preferences_window setDelegate:delegate];
|
||||
|
||||
//Create the "Interface" pane
|
||||
interface_pane_tab = [[NSTabViewItem alloc] initWithIdentifier:nil];
|
||||
[interface_pane_tab setLabel:localizedString(@"Interface", nil)];
|
||||
[tab_view addTabViewItem:interface_pane_tab];
|
||||
//create a tab view
|
||||
rect.size.width = 400 - 10;
|
||||
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 interface view
|
||||
rect.size.width = 400 - 10;
|
||||
rect.size.height = 300 - 10;
|
||||
rect.origin.x = 0;
|
||||
rect.origin.y = 0;
|
||||
NSView *interface_view = [[NSView alloc] initWithFrame:rect];
|
||||
[interface_pane_tab setView:interface_view];
|
||||
//Create the "Interface" pane
|
||||
interface_pane_tab = [[NSTabViewItem alloc] initWithIdentifier:nil];
|
||||
[interface_pane_tab setLabel:localizedString(@"Interface", nil)];
|
||||
[tab_view addTabViewItem:interface_pane_tab];
|
||||
|
||||
//Create language selection text
|
||||
rect.size.width = 225;
|
||||
rect.size.height = 29 - [localizedString(@"Language",nil) sizeWithAttributes:preferences_font_attribs].height / 2;
|
||||
rect.origin.x = 0;
|
||||
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 interface view
|
||||
NSDictionary *interface_options = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSArray arrayWithObjects:@"Bool", [NSData dataWithBytes:&@selector(executeUponLoad:) length:sizeof(SEL)], @"Yes",@"No",nil], PREF_EXECUTE_UPON_LOAD,
|
||||
nil];
|
||||
|
||||
//Create language selection button
|
||||
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];
|
||||
NSView *interface_view = createPreferencesView(interface_pane_tab, interface_options, delegate);
|
||||
|
||||
//Create the "DS Firmware" pane
|
||||
firmware_pane_tab = [[NSTabViewItem alloc] initWithIdentifier:nil];
|
||||
[firmware_pane_tab setLabel:localizedString(@"DS Firmware", nil)];
|
||||
[tab_view addTabViewItem:firmware_pane_tab];
|
||||
//Create the firmware pane
|
||||
firmware_pane_tab = [[NSTabViewItem alloc] initWithIdentifier:nil];
|
||||
[firmware_pane_tab setLabel:localizedString(@"DS Firmware", nil)];
|
||||
[tab_view addTabViewItem:firmware_pane_tab];
|
||||
|
||||
//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 *firmware_options = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSArray arrayWithObjects:@"Text", [NSData dataWithBytes:&@selector(playerName:) length:sizeof(SEL)], nil], PREF_FIRMWARE_PLAYER_NAME,
|
||||
[NSArray arrayWithObjects:@"Array", [NSData dataWithBytes:&@selector(nonexisant:) length:sizeof(SEL)], @"Danish",@"English",@"French",nil], PREF_FIRMWARE_LANGUAGE,
|
||||
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
|
||||
[[[NSWindowController alloc] initWithWindow:preferences_window] showWindow:nil];
|
||||
[wc showWindow:nil];
|
||||
|
||||
|
||||
|
||||
[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