Initial Mac OS X interface commit

This commit is contained in:
gecko_reverse 2007-08-11 19:23:45 +00:00
parent e0c59580f8
commit 474b3203fa
15 changed files with 3533 additions and 91 deletions

View File

@ -18,6 +18,7 @@ Tim Seidel (Mighty Max)
Damien Nozay (damdoum)
Pascal Giard (evilynux)
Ben Jaques (masscat)
Jeff Bland
Contributors
------------

View File

@ -3,6 +3,8 @@
- Full localization using intltool/gettext. [evilynux]
general:
- Added a README.TRANSLATION documenting the localization process. [evilynux]
MacOS X:
- Initial version of the Mac interface added. [Jeff B]
0.7.1 -> 0.7.2
spu:

View File

@ -14,7 +14,7 @@ Developpers:
1 Supported UIs ________________________________________________________________
Although there are 4 UIs, only 2 currently support localization:
Although there are 4 UIs, only 3 currently support localization:
windows and gtk-glade.
To translate DeSmuME, see "Starting a new translation" below.
@ -32,6 +32,10 @@ To translate DeSmuME, see "Starting a new translation" below.
Localization is located in one single file: src/windows/resources.rc .
1.3 Mac OS X (Cocoa) UI
--------------------------------------------------------------
Localization is located within the application bundle (in Finder right click on DeSmuME and select "Show Package Contents"). Within the Contents/Resources folder there is a folder for each localization.
2 Starting a new translation ___________________________________________________
@ -54,6 +58,13 @@ To translate DeSmuME, see "Starting a new translation" below.
Translate the strings.
Send us your translation by getting in touch with us: see "Contact Us" below.
2.3 Max OS X UI
--------------------------------------------------------------
Copy one of the localization folders mentioned in section one, and paste it into the same folder.
Rename the part before ".lproj" to the language of the translation.
Within your newly created folder edit "Localizable.strings".
Send us your translation by getting in touch with us: see "Contact Us" below.
3 Editors ______________________________________________________________________
@ -128,4 +139,4 @@ To update po/desmume.pot, move to the po/ folder and execute "make update-po".
Add the new language to to the list in src/windows/resource.h .
Rebuild.
$Id: README.TRANSLATION,v 1.7 2007-07-19 06:50:57 evilynux Exp $
$Id: README.TRANSLATION,v 1.8 2007-08-11 19:23:44 gecko_reverse Exp $

View File

@ -30,6 +30,7 @@
#include "mem.h"
#include "registers.h"
#include "FIFO.h"
#include "MMU.h"
#ifdef __cplusplus
extern "C" {
@ -44,7 +45,7 @@ extern "C" {
#ifdef WORDS_BIGENDIAN
struct _DISPCNT
{
/* 7*/ u8 ForceBlank:1; // A+B:
/* 7*/ u8 ForceBlank:1; // A+B:
/* 6*/ u8 OBJ_BMP_mapping:1; // A+B: 0=2D (128KB), 1=1D (128..256KB)
/* 5*/ u8 OBJ_BMP_2D_dim:1; // A+B: 0=128x512, 1=256x256 pixels
/* 4*/ u8 OBJ_Tile_1D:1; // A+B: 0=2D (32KB), 1=1D (32..256KB)
@ -59,8 +60,8 @@ struct _DISPCNT
/* 9*/ u8 BG1_Enable:1; // A+B: 0=disable, 1=Enable
/* 8*/ u8 BG0_Enable:1; // A+B: 0=disable, 1=Enable
/*23*/ u8 OBJ_HBlank_process:1; // A+B: OBJ processed during HBlank (GBA bit5)
/*22*/ u8 OBJ_BMP_1D_Bound:1; // A :
/*20*/ u8 OBJ_Tile_1D_Bound:2; // A+B:
/*22*/ u8 OBJ_BMP_1D_Bound:1; // A :
/*20*/ u8 OBJ_Tile_1D_Bound:2; // A+B:
/*18*/ u8 VRAM_Block:2; // A : VRAM block (0..3=A..D)
/*16*/ u8 DisplayMode:2; // A+B: coreA(0..3) coreB(0..1) GBA(Green Swap)
@ -73,7 +74,7 @@ struct _DISPCNT
/*30*/ u8 ExBGxPalette_Enable:1; // A+B: 0=disable, 1=Enable BG extended Palette
/*27*/ u8 ScreenBase_Block:3; // A : Screen Base (64K step)
/*24*/ u8 CharacBase_Block:3; // A : Character Base (64K step)
};
};
#else
struct _DISPCNT
{
@ -84,7 +85,7 @@ struct _DISPCNT
/* 6*/ u8 OBJ_BMP_mapping:1; // A+B: 0=2D (128KB), 1=1D (128..256KB)
// 7-15 same as GBA
/* 7*/ u8 ForceBlank:1; // A+B:
/* 7*/ u8 ForceBlank:1; // A+B:
/* 8*/ u8 BG0_Enable:1; // A+B: 0=disable, 1=Enable
/* 9*/ u8 BG1_Enable:1; // A+B: 0=disable, 1=Enable
/*10*/ u8 BG2_Enable:1; // A+B: 0=disable, 1=Enable
@ -99,23 +100,23 @@ struct _DISPCNT
// 1=on (normal BG & OBJ layers)
// 2=VRAM display (coreA only)
// 3=RAM display (coreA only, DMA transfers)
/*18*/ u8 VRAM_Block:2; // A : VRAM block (0..3=A..D)
/*20*/ u8 OBJ_Tile_1D_Bound:2; // A+B:
/*22*/ u8 OBJ_BMP_1D_Bound:1; // A :
/*20*/ u8 OBJ_Tile_1D_Bound:2; // A+B:
/*22*/ u8 OBJ_BMP_1D_Bound:1; // A :
/*23*/ u8 OBJ_HBlank_process:1; // A+B: OBJ processed during HBlank (GBA bit5)
/*24*/ u8 CharacBase_Block:3; // A : Character Base (64K step)
/*27*/ u8 ScreenBase_Block:3; // A : Screen Base (64K step)
/*30*/ u8 ExBGxPalette_Enable:1; // A+B: 0=disable, 1=Enable BG extended Palette
/*31*/ u8 ExOBJPalette_Enable:1; // A+B: 0=disable, 1=Enable OBJ extended Palette
};
};
#endif
typedef union
typedef union
{
struct _DISPCNT bits;
u32 val;
} DISPCNT;
} DISPCNT;
#define BGxENABLED(cnt,num) ((num<8)? ((cnt.val>>8) & num):0)
@ -129,7 +130,7 @@ typedef union
*******************************************************************************/
#ifdef WORDS_BIGENDIAN
struct _BGxCNT
struct _BGxCNT
{
/* 7*/ u8 Palette_256:1; // 0=16x16, 1=1*256 palette
/* 6*/ u8 Mosaic_Enable:1; // 0=disable, 1=Enable mosaic
@ -144,9 +145,9 @@ struct _BGxCNT
// BG2 overflow area wraparound 0=off, 1=wrap
// BG3 overflow area wraparound 0=off, 1=wrap
/* 8*/ u8 ScreenBase_Block:5; // individual screen base offset (text n*2KB, BMP n*16KB)
};
};
#else
struct _BGxCNT
struct _BGxCNT
{
/* 0*/ u8 Priority:2; // 0..3=high..low
/* 2*/ u8 CharacBase_Block:4; // individual character base offset (n*16KB)
@ -161,15 +162,15 @@ struct _BGxCNT
// x/rot/s : 128x128 256x256 512x512 1024x1024
// bmp : 128x128 256x256 512x256 512x512
// large : 512x1024 1024x512 - -
};
};
#endif
typedef union
typedef union
{
struct _BGxCNT bits;
u16 val;
} BGxCNT;
} BGxCNT;
/*******************************************************************************
this structure is for background offset
@ -178,7 +179,7 @@ typedef union
typedef struct {
u16 BGxHOFS;
u16 BGxVOFS;
} BGxOFS;
} BGxOFS;
/*******************************************************************************
this structure is for rotoscale parameters
@ -191,7 +192,7 @@ typedef struct {
s16 BGxPD;
s32 BGxX;
s32 BGxY;
} BGxPARMS;
} BGxPARMS;
/*******************************************************************************
@ -282,7 +283,7 @@ typedef struct {
WINxDIM WIN1V;
WINxCNT WININ;
WINxCNT WINOUT;
} WINCNT;
} WINCNT;
*/
/*******************************************************************************
@ -303,7 +304,7 @@ typedef struct {
u16 unused8;
u16 unused9;
*/
} MISCCNT;
} MISCCNT;
/*******************************************************************************
@ -319,20 +320,20 @@ struct _DISP3DCNT
/* 4*/ u8 EnableAntiAliasing:1; //
/* 5*/ u8 EnableEdgeMarking:1; // see EDGE_COLOR
/* 6*/ u8 FogOnlyAlpha:1; // 0=Alpha and Color, 1=Only Alpha (see FOG_COLOR)
/* 7*/ u8 EnableFog:1; // Fog Master Enable
/* 7*/ u8 EnableFog:1; // Fog Master Enable
/* 8*/ u8 FogShiftSHR:4; // 0..10 SHR-Divider (see FOG_OFFSET)
/*12*/ u8 AckColorBufferUnderflow:1; // Color Buffer RDLINES Underflow (0=None, 1=Underflow/Acknowledge)
/*13*/ u8 AckVertexRAMOverflow:1; // Polygon/Vertex RAM Overflow (0=None, 1=Overflow/Acknowledge)
/*14*/ u8 RearPlaneMode:1; // 0=Blank, 1=Bitmap
/*15*/ u8 :1;
/*16*/ u16 :16;
};
};
typedef union
typedef union
{
struct _DISP3DCNT bits;
u32 val;
} DISP3DCNT;
} DISP3DCNT;
/*******************************************************************************
this structure is for capture control (core A only)
@ -357,13 +358,13 @@ struct _DISPCAPCNT
/*28*/ u8 :1; //
/*29*/ u8 Capture_Source:2; // 0=Source A, 1=Source B, 2/3=Sources A+B blended
/*31*/ u8 Capture_Enable:1; // 0=Disable/Ready, 1=Enable/Busy
};
};
typedef union
typedef union
{
struct _DISPCAPCNT bits;
u32 val;
} DISPCAPCNT;
} DISPCAPCNT;
/*******************************************************************************
@ -374,7 +375,7 @@ typedef union
typedef struct _reg_dispx {
DISPCNT dispx_DISPCNT; // 0x0400x000
u16 dispA_DISPSTAT; // 0x04000004
u16 dispA_DISPSTAT; // 0x04000004
u16 dispx_VCOUNT; // 0x0400x006
BGxCNT dispx_BGxCNT[4]; // 0x0400x008
BGxOFS dispx_BGxOFS[4]; // 0x0400x010
@ -385,7 +386,7 @@ typedef struct _reg_dispx {
DISP3DCNT dispA_DISP3DCNT; // 0x04000060
DISPCAPCNT dispA_DISPCAPCNT; // 0x04000064
u32 dispA_DISPMMEMFIFO; // 0x04000068
} REG_DISPx ;
} REG_DISPx ;
@ -405,7 +406,7 @@ typedef struct _reg_dispx {
typedef BOOL (*fun_gl_Begin) (int screen);
typedef void (*fun_gl_End) (int screen);
// the GUI should use this function prior to all gl calls
// if call to beg succeeds opengl draw
// if call to beg succeeds opengl draw
void register_gl_fun(fun_gl_Begin beg,fun_gl_End end);
#define GPU_MAIN 0
@ -438,7 +439,7 @@ struct _TILEENTRY
/*14*/ unsigned Palette:4;
};
#endif
typedef union
typedef union
{
struct _TILEENTRY bits;
u16 val;
@ -450,7 +451,7 @@ struct _ROTOCOORD
/* 8*/ signed Integer:24;
// /*28*/ unsigned :4;
};
typedef union
typedef union
{
struct _ROTOCOORD bits;
s32 val;
@ -475,7 +476,7 @@ struct _COLORx { // abgr x555
unsigned alpha:1; // sometimes it is unused (pad)
};
typedef union
typedef union
{
struct _COLOR bits;
struct _COLORx bitx;
@ -493,7 +494,7 @@ struct _COLOR32 { // ARGB
unsigned alpha:1; // sometimes it is unused (pad)
};
typedef union
typedef union
{
struct _COLOR32 bits;
u32 val;
@ -529,7 +530,7 @@ typedef struct
/*14*/ unsigned Shape:2; // (00: Square, 01: Wide, 10: Tall, 11: Illegal)
// attr1
/* 0*/ signed X:9;
/* 9*/ unsigned RotScalIndex:3; // Rot/scale matrix index
/* 9*/ unsigned RotScalIndex:3; // Rot/scale matrix index
/*12*/ unsigned HFlip:1;
/*13*/ unsigned VFlip:1;
/*14*/ unsigned Size:2;
@ -567,7 +568,7 @@ typedef struct
#define NB_PRIORITIES 4
#define NB_BG 4
typedef struct
typedef struct
{
u8 BGs[NB_BG], nbBGs;
u8 PixelsX[256];
@ -583,7 +584,7 @@ struct _GPU
// some structs are becoming redundant
// some functions too (no need to recopy some vars as it is done by MMU)
REG_DISPx * dispx_st;
DISPCAPCNT dispCapCnt;
BOOL LayersEnable[5];
itemsForPriority_t itemsForPriority[NB_PRIORITIES];
@ -591,23 +592,23 @@ struct _GPU
#define BGBmpBB BG_bmp_ram
#define BGChBB BG_tile_ram
u8 *(BG_bmp_ram[4]);
u8 *(BG_tile_ram[4]);
u8 *(BG_map_ram[4]);
u8 BGExtPalSlot[4];
u32 BGSize[4][2];
u8 lcd;
u8 core;
u8 dispMode;
u8 vramBlock;
BOOL dispBG[4];
BOOL dispOBJ;
OAM * oam;
u8 * sprMem;
u8 sprBoundary;
@ -651,7 +652,7 @@ struct _GPU
void (*spriteRender) (GPU * gpu, u16 l, u8 * dst, u8 * prioTab);
};
/*
// normally should have same addresses
// normally should have same addresses
static void REG_DISPx_pack_test(GPU * gpu)
{
REG_DISPx * r = gpu->dispx_st;
@ -717,7 +718,7 @@ typedef struct
int (*Init)(); // Initializes stuff related to core
void (*DeInit)(); // Deinitializes stuff related to core
void (*Resize)(int width, int height, BOOL fullscreen); // Resizes window or fullscreen
void (*OnScreenText)(char *string, ...); // For handling save state messages, etc.
void (*OnScreenText)(char *string, ...); // For handling save state messages, etc.
} GraphicsInterface_struct;
extern GraphicsInterface_struct GFXDummy;

View File

@ -0,0 +1,173 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="DeSmuME Cocoa" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Cocoa">
<Option platforms="Mac;" />
<Option output="DeSmuME.app/Contents/MacOS/DeSmuME" prefix_auto="0" extension_auto="0" />
<Option object_output="obj/Release/" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
<Add option="-march=pentium-m" />
<Add option="-DDESMUME_COCOA" />
</Compiler>
<Linker>
<Add option="-framework Cocoa" />
<Add option="-framework OpenGL" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-fexpensive-optimizations" />
<Add option="-O3" />
<Add option="-Wall" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
<Unit filename="../ARM9.h" />
<Unit filename="../Disassembler.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../Disassembler.h" />
<Unit filename="../FIFO.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../FIFO.h" />
<Unit filename="../GPU.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../GPU.h" />
<Unit filename="../MMU.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../MMU.h" />
<Unit filename="../NDSSystem.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../NDSSystem.h" />
<Unit filename="../ROMReader.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../ROMReader.h" />
<Unit filename="../SPU.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../SPU.h" />
<Unit filename="../arm_instructions.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../arm_instructions.h" />
<Unit filename="../armcpu.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../armcpu.h" />
<Unit filename="../bios.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../bios.h" />
<Unit filename="../bits.h" />
<Unit filename="../cflash.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../cflash.h" />
<Unit filename="cocoa_util.m">
<Option compile="1" />
<Option link="1" />
</Unit>
<Unit filename="globals.h" />
<Unit filename="main.m">
<Option compile="1" />
<Option link="1" />
</Unit>
<Unit filename="main_window.h" />
<Unit filename="main_window.m">
<Option compile="1" />
<Option link="1" />
</Unit>
<Unit filename="nds_control.h" />
<Unit filename="nds_control.m">
<Option compile="1" />
<Option link="1" />
</Unit>
<Unit filename="preferences.m">
<Option compile="1" />
<Option link="1" />
</Unit>
<Unit filename="../config.h" />
<Unit filename="../cp15.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../cp15.h" />
<Unit filename="../debug.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../debug.h" />
<Unit filename="../dscard.h" />
<Unit filename="../fat.h" />
<Unit filename="../fs-linux.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../fs.h" />
<Unit filename="../gdbstub.h" />
<Unit filename="../gl_vertex.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../gl_vertex.h" />
<Unit filename="../matrix.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../matrix.h" />
<Unit filename="../mc.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../mc.h" />
<Unit filename="../mem.h" />
<Unit filename="../opengl_collector_3Demu.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../opengl_collector_3Demu.h" />
<Unit filename="../registers.h" />
<Unit filename="../render3D.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../render3D.h" />
<Unit filename="../saves.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../saves.h" />
<Unit filename="../thumb_instructions.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../thumb_instructions.h" />
<Unit filename="../types.h" />
<Unit filename="../wifi.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../wifi.h" />
<Unit filename="../windows/OGLRender.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../windows/OGLRender.h" />
<Unit filename="../windows/ginfo.c">
<Option compilerVar="CC" />
<Option compile="0" />
<Option link="0" />
</Unit>
<Unit filename="../windows/ginfo.h" />
<Unit filename="../windows/main.c">
<Option compilerVar="CC" />
<Option compile="0" />
<Option link="0" />
</Unit>
<Extensions>
<code_completion />
<envvars />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -0,0 +1,96 @@
/* 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"
////////////////////////////////////////////////////////////////
//Menu Item implementation--------------------------------------
////////////////////////////////////////////////////////////////
@implementation NSMenu (localization)
- (id <NSMenuItem>)addItemWithTitle:(NSString *)aString action:(SEL)aSelector keyEquivalent:(NSString *)keyEquiv
{
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:localizedString(aString, nil) action:aSelector keyEquivalent:keyEquiv];
[self addItem:item];
return item;
}
- (id <NSMenuItem>)addItemWithTitle:(NSString *)aString withInt:(int)number action:(SEL)aSelector keyEquivalent:(NSString *)keyEquiv
{
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[NSString stringWithFormat:localizedString(aString, nil),number] action:aSelector keyEquivalent:keyEquiv];
[self addItem:item];
return item;
}
@end
////////////////////////////////////////////////////////////////
//Dialog Boxes-------------------------------------------------
////////////////////////////////////////////////////////////////
void messageDialogBlank()
{
NSRunAlertPanel(@"Click OK", @" ", nil/*OK*/, nil, nil);
}
void messageDialog(NSString *title, NSString *text)
{
NSRunAlertPanel(title, text, nil/*OK*/, nil, nil);
}
BOOL messageDialogYN(NSString *title, NSString *text)
{
return NSRunAlertPanel(title, text, @"Yes", @"No", nil) != 0;
}
//does an open dialog to choose an NDS file
//returns the filename or NULL if the user selected cancel
NSOpenPanel* panel;
NSString* openDialog(NSArray *file_types)
{
panel = [NSOpenPanel openPanel];
[panel setCanChooseDirectories:NO];
[panel setCanChooseFiles:YES];
[panel setAllowsMultipleSelection:NO];
if([panel runModalForDirectory:@"/Users/gecko/nds" file:nil types:file_types] == NSOKButton)
{
//a file was selected
id selected_file = [[panel filenames] lastObject]; //hopefully also the first object
return selected_file;
}
//a file wasn't selected
return NULL;
}
////////////////////////////////////////////////////////////////
//Language Stuff-----------------------------------------------
////////////////////////////////////////////////////////////////
NSString *localizedString(NSString *string, NSString *comment)
{
return NSLocalizedString(string,nil);
}

145
desmume/src/cocoa/globals.h Normal file
View File

@ -0,0 +1,145 @@
/* 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
*/
//fixme headers conform to desmume?
#ifndef GLOBALS_H_INCLUDED
#define GLOBALS_H_INCLUDED
#import <Cocoa/cocoa.h>
//fixme
#define desmume_TRUE TRUE
//Nintendo DS constants---------------------------------------------------------------------------
//This just improves legibility throughut the code
//by showing you names instead of numbers
#define DS_SCREEN_WIDTH 256
#define DS_SCREEN_HEIGHT 192
#define DS_SCREEN_HEIGHT_COMBINED (192*2) /*height of the two screens*/
#define DS_SCREEN_X_RATIO (256.0 / (192.0 * 2.0))
#define DS_SCREEN_Y_RATIO ((192.0 * 2.0) / 256.0)
//Cocoa Util------------------------------------------------------------------------------------
//These are just useful little functions to help with stuff
//defined in cocoa_util.m
//c string to NSString
#define NSSTRc(x) ([[NSString alloc] initWithCString:(x) encoding:NSASCIIStringEncoding])
//these class extensions do the localstring lookup so we dont have to type it over and over again
/*
@interface NSMenuItem (localization)
- (id)initWithTitle:(NSString *)not_localized_name action:(SEL)action keyEquivalent:(NSString*)key;
@end
*/
@interface NSMenu (localization)
- (id <NSMenuItem>)addItemWithTitle:(NSString *)aString action:(SEL)aSelector keyEquivalent:(NSString *)keyEquiv;
- (id <NSMenuItem>)addItemWithTitle:(NSString *)aString withInt:(int)number action:(SEL)aSelector keyEquivalent:(NSString *)keyEquiv;
@end
//dialogs
void messageDialogBlank();
void messageDialog(NSString *title, NSString *text);
BOOL messageDialogYN(NSString *title, NSString *text);
NSString* openDialog(NSArray *file_types);
//
NSString* localizedString(NSString *stuff, NSString *comment);
//Menus -------------------------------------------------------------------------------------------
//These are all the menu items that need checkmarks
//or their enabled status managed
//global menu (defined in main.m)
extern NSMenu *menu;
//view (defined/managed in main_window.m)
extern NSMenuItem *resize1x;
extern NSMenuItem *resize2x;
extern NSMenuItem *resize3x;
extern NSMenuItem *resize4x;
extern NSMenuItem *allows_resize_item;
extern NSMenuItem *constrain_item;
extern NSMenuItem *min_size_item;
extern NSMenuItem *rotation0_item;
extern NSMenuItem *rotation90_item;
extern NSMenuItem *rotation180_item;
extern NSMenuItem *rotation270_item;
extern NSMenuItem *topBG0_item;
extern NSMenuItem *topBG1_item;
extern NSMenuItem *topBG2_item;
extern NSMenuItem *topBG3_item;
extern NSMenuItem *subBG0_item;
extern NSMenuItem *subBG1_item;
extern NSMenuItem *subBG2_item;
extern NSMenuItem *subBG3_item;
//execution control (defined/managed in nds_control.m)
extern NSMenuItem *close_rom_item;
extern NSMenuItem *execute_item;
extern NSMenuItem *pause_item;
extern NSMenuItem *reset_item;
extern NSMenuItem *save_state_as_item;
extern NSMenuItem *load_state_from_item;
#define SAVE_SLOTS 10 //this should never be more than NB_SAVES in saves.h
extern NSMenuItem *saveSlot_item[SAVE_SLOTS];
extern NSMenuItem *loadSlot_item[SAVE_SLOTS];
#define MAX_FRAME_SKIP 10 //this is actually 1 more than the highest frame skip
extern NSMenuItem *frame_skip_auto_item;
extern NSMenuItem *frame_skip_item[SAVE_SLOTS];
//extern NSMenuItem *clear_all_saves_item; waiting for more functionality from saves.h
extern NSMenuItem *rom_info_item;
//Cocoa Port Stuff ---------------------------------------------------------------------------------
//Enable this to multithread the program
//#define MULTITHREADED
//prototype for our NintendoDS class (defined in nds_control.h)
//
@class NintendoDS;
//Here's our global DS object
//which controls things like pausing and whatnot
extern NintendoDS *NDS;
@class VideoOutputWindow;
extern VideoOutputWindow *main_window;
//--------------------------------------------------------------------------------------------------
extern volatile int /*desmume_BOOL*/ execute;
extern volatile BOOL finished;
extern volatile BOOL paused;
#endif // GLOBALS_H_INCLUDED

620
desmume/src/cocoa/main.m Normal file
View File

@ -0,0 +1,620 @@
/* 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
*/
/*
This file is part of the Cocoa (Mac OS X) port of DeSmuME emulator
By Jeff Bland (reversegecko@gmail.com)
Based on work by yopyop and the DeSmuME team!
*/
//DeSmuME Cocoa includes
#import "globals.h"
#import "main_window.h"
#import "nds_control.h"
//DeSmuME general includes
#define OBJ_C
#include "../SPU.h"
#include "../render3D.h"
#include "../GPU.h"
#include "../Windows/OGLRender.h"
#include "../NDSSystem.h"
#undef BOOL
/*
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
*/
//Globals----------------------------------------------------------------------------------------
NSMenu *menu;
//Interfaces--------------------------------------------------------------------------------------
@interface NSApplication(custom)
//this prototype was removed from the mac os headers
- (void)setAppleMenu:(NSMenu*)menu;
//here we extend NSApplication
- (void)about;
- (void)preferences;
@end
@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;
@end
//Global access gui constructs
VideoOutputWindow *main_window;
//Desmume globals---------------------------------------------------------------------------------------
//accessed from other files
volatile desmume_BOOL execute = FALSE;
//
volatile BOOL finished = FALSE;
volatile BOOL paused = TRUE;
SoundInterface_struct *SNDCoreList[] = {
&SNDDummy,
//&SNDFile,
//&SNDDIRECTX,
NULL
};
GPU3DInterface *core3DList[] = {
&gpu3DNull,
&gpu3Dgl
};
//NDS/Emulator control-----------------------------------------------------------------------------------------
//These functions should be called by GUI handling mechanisms to change the state of the emulator or emulation
NintendoDS *NDS;
void Quit()
{
//stop emulation if it's going
[NDS pause];
//
finished = true;
//
[NSApp stop:NSApp];
}
void AskForQuit()
{
BOOL was_paused = paused;
//pause while we prompt the user
[NDS pause];
//ask the user if quitting is acceptable
if(messageDialogYN(localizedString(@"DeSmuME Emulator", nil), localizedString(@"Are you sure you want to quit?", nil)))
Quit();
else
if(!was_paused)[NDS execute]; //unpaused if we weren't paused before
}
NSEvent *current_event;
//if wait is true then it will sit around waiting for an
//event for a short period of time taking up very little CPU
//(use when game is not running)
inline void clearEvents(bool wait)
{
//wait for the next event
while((current_event = [NSApp nextEventMatchingMask:0 untilDate:wait?[NSDate dateWithTimeIntervalSinceNow:.2]:nil inMode:NSDefaultRunLoopMode dequeue:YES]))
[NSApp sendEvent: current_event];
}
///////////////////////////////
//This generates and sets the entire menubar (and sets defaults)
//call after objects (ie NDS main_window) are inited
void CreateMenu()
{
NSMenuItem *temp;
NSMenu* application_menu;
NSMenu* services_menu;
NSMenu* file;
NSMenu* emulation;
NSMenu* view;
//NSMenu* window;
NSMenu* help;
NSMenu* frame_skip_menu;
SEL action = nil;//@selector(method:);
//Create the outermost menu that contains all the others
menu = [[NSMenu alloc] initWithTitle:@"DeSmuME"];
//Create the "DeSmuME" (application) menu
application_menu = [[NSMenu alloc] initWithTitle:@"DeSmuME"];
//Create the sevices menu
services_menu = [[NSMenu alloc] initWithTitle:@"Services"];
[NSApp setServicesMenu:services_menu];
//Add the about menu
temp = [application_menu addItemWithTitle:@"About DeSmuME" action:@selector(about) keyEquivalent:@""];
[temp setTarget:NSApp];
//
[application_menu addItem: [NSMenuItem separatorItem]];
//Add the preferences menu
//temp = [application_menu addItemWithTitle:@"Preferences..." action:@selector(preferences) keyEquivalent:@","];
//[temp setTarget:NSApp];
//
[application_menu addItem: [NSMenuItem separatorItem]];
//add the services menu to the application menu (after preferences)
temp = [application_menu addItemWithTitle:@"Services" action:nil keyEquivalent:@""];
[temp setSubmenu:services_menu];
//
[application_menu addItem: [NSMenuItem separatorItem]];
//standard hide option
temp = [application_menu addItemWithTitle:@"Hide DeSmuME" action:@selector(hide:) keyEquivalent:@""];
[temp setTarget:NSApp];
//standard hide others option
temp = [application_menu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@""];
[temp setTarget:NSApp];
//standard show all option
temp = [application_menu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
[temp setTarget:NSApp];
//
[application_menu addItem: [NSMenuItem separatorItem]];
//standard quit option
temp = [application_menu addItemWithTitle:@"Quit DeSmuME" action:@selector(terminate:) keyEquivalent:@"q"];
[temp setTarget: NSApp];
//finally call setAppleMenu to have all our stuff working
[NSApp setAppleMenu:application_menu];
temp = [menu addItemWithTitle:@"" action:nil keyEquivalent:@""];
[temp setSubmenu:application_menu];
[temp release];
NSMenuItem *file_item = [menu addItemWithTitle:@"File" action:action keyEquivalent:@""];
NSMenuItem *emulation_item = [menu addItemWithTitle:@"Emulation" action:action keyEquivalent:@""];
NSMenuItem *view_item = [menu addItemWithTitle:@"View" action:action keyEquivalent:@""];
//NSMenuItem *window_item = [menu addItemWithTitle:@"Window" action:action keyEquivalent:@""];
NSMenuItem *help_item = [menu addItemWithTitle:@"Help" action:action keyEquivalent:@""];
//Create the File Menu
file = [[NSMenu alloc] initWithTitle:@"File"];
[file setAutoenablesItems:NO];
[menu setSubmenu:file forItem:file_item];
temp = [file addItemWithTitle:@"Open ROM..." action:@selector(pickROM) keyEquivalent:@"o"];
[temp setTarget:NDS];
//recent items menu
temp = [file addItemWithTitle:@"Open Recent" action:nil keyEquivalent:@""];
NSMenu *recent_menu = [[NSMenu alloc] initWithTitle:@""];
[temp setSubmenu:recent_menu];
[recent_menu addItemWithTitle:@"Blar" action:nil keyEquivalent:@""];
[file addItem:[NSMenuItem separatorItem]];
rom_info_item = [file addItemWithTitle:@"ROM Info..." action:@selector(showRomInfo) keyEquivalent:@""];
[rom_info_item setEnabled:NO];
[rom_info_item setTarget:NDS];
#ifdef HAVE_LIBZ //internally, save states only work when zlib is there
[file addItem:[NSMenuItem separatorItem]];
save_state_as_item = [file addItemWithTitle:@"Save State As..." action:@selector(saveStateAs) keyEquivalent:@""];
[save_state_as_item setEnabled:NO];
[save_state_as_item setTarget:NDS];
load_state_from_item = [file addItemWithTitle:@"Load State From..." action:@selector(loadStateFrom) keyEquivalent:@""];
[load_state_from_item setEnabled:NO];
[load_state_from_item setTarget:NDS];
[file addItem:[NSMenuItem separatorItem]];
temp = [file addItemWithTitle:@"Save State" action:@selector(saveTo:) keyEquivalent:@""];
NSMenu *save_state_menu = [[NSMenu alloc] initWithTitle:@"Save State"];
[save_state_menu setAutoenablesItems:NO];
[temp setSubmenu:save_state_menu];
temp = [file addItemWithTitle:@"Load State" action:nil keyEquivalent:@""];
NSMenu *load_state_menu = [[NSMenu alloc] initWithTitle:@"Load State"];
[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:@""];
[saveSlot_item[i] setEnabled:NO];
[saveSlot_item[i] setTarget:NDS];
loadSlot_item[i] = [load_state_menu addItemWithTitle:@"Slot %d" withInt:i action:@selector(loadFromSlot:) keyEquivalent:@""];
[loadSlot_item[i] setEnabled:NO];
[loadSlot_item[i] setTarget:NDS];
}
/* To be implemented when saves.h provides
a way to get the time of a save that's not string/human formatted...
[save_state_menu addItem:[NSMenuItem separatorItem]];
temp = [save_state_menu addItemWithTitle:@"Save Over Oldest" action:nil keyEquivalent:@""];
[temp setEnabled:NO];
[temp setTarget:NDS];
temp = [save_state_menu addItemWithTitle:@"Save Over Latest" action:nil keyEquivalent:@""];
[temp setEnabled:NO];
[temp setTarget:NDS];
*/
/* to be implemented after saves.h provides a way to delete saves...
[save_state_menu addItem:[NSMenuItem separatorItem]];
clear_all_saves_item = [save_state_menu addItemWithTitle:@"Clear All" action:@selector(askAndClearStates) keyEquivalent:@""];
[clear_all_saves_item setEnabled:NO];
[clear_all_saves_item setTarget:NDS];
*/
/*
[save_state_menu addItem:[NSMenuItem separatorItem]];
temp = [save_state_menu addItemWithTitle:@"View States" action:nil keyEquivalent:@""];
[temp setEnabled:NO];
[temp setTarget:NDS];
*/
/* To be implemented when saves.h provides
a way to get the time of a save that's not a string / human formatted...
[load_state_menu addItem:[NSMenuItem separatorItem]];
temp = [load_state_menu addItemWithTitle:@"Load Oldest" action:nil keyEquivalent:@""];
[temp setEnabled:NO];
[temp setTarget:NDS];
temp = [load_state_menu addItemWithTitle:@"Load Latest" action:nil keyEquivalent:@""];
[temp setEnabled:NO];
[temp setTarget:NDS];
*/
/*
[load_state_menu addItem:[NSMenuItem separatorItem]];
temp = [load_state_menu addItemWithTitle:@"View States" action:nil keyEquivalent:@""];
[temp setEnabled:NO];
[temp setTarget:NDS];
*/
#endif
[file addItem:[NSMenuItem separatorItem]];
close_rom_item = [file addItemWithTitle:@"Close ROM" action:@selector(askAndCloseROM) keyEquivalent:@"w"];
[close_rom_item setEnabled:NO];
[close_rom_item setTarget:NDS];
//Create the Emulation Menu
emulation = [[NSMenu alloc] initWithTitle:localizedString(@"Emulation", nil)];
[emulation setAutoenablesItems:NO];
[menu setSubmenu:emulation forItem:emulation_item];
execute_item = [emulation addItemWithTitle:@"Execute" action:@selector(execute) keyEquivalent:@""];
[execute_item setTarget:NDS];
[execute_item setEnabled:NO];
pause_item = [emulation addItemWithTitle:@"Pause" action:@selector(pause) keyEquivalent:@""];
[pause_item setTarget:NDS];
[pause_item setEnabled:NO];
reset_item = [emulation addItemWithTitle:@"Reset" action:@selector(reset) keyEquivalent:@""];
[reset_item setTarget:NDS];
[reset_item setEnabled:NO];
[emulation addItem:[NSMenuItem separatorItem]];
temp = [emulation addItemWithTitle:@"Frame Skip" action:nil keyEquivalent:@""];
frame_skip_menu = [[NSMenu alloc] initWithTitle:localizedString(@"Frame Skip", nil)];
[temp setSubmenu:frame_skip_menu];
frame_skip_auto_item = [frame_skip_menu addItemWithTitle:@"Auto" action:@selector(setFrameSkip:) keyEquivalent:@""];
[frame_skip_auto_item setTarget:NDS];
[frame_skip_auto_item setState:NSOnState];
[frame_skip_auto_item setEnabled:YES];
[frame_skip_menu addItem:[NSMenuItem separatorItem]];
frame_skip_item[0] = [frame_skip_menu addItemWithTitle:@"Off" action:@selector(setFrameSkip:) keyEquivalent:@""];
[frame_skip_item[0] setTarget:NDS];
[frame_skip_item[0] setEnabled:YES];
int i2;
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[i2] setTarget:NDS];
[frame_skip_item[i2] setEnabled:YES];
}
//Create the screens menu
view = [[NSMenu alloc] initWithTitle:localizedString(@"View", nil)];
[menu setSubmenu:view forItem:view_item];
resize1x = [view addItemWithTitle:@"Size 1x" action:@selector(resizeScreen1x) keyEquivalent:@"1"];
[resize1x setState:NSOnState];
[resize1x setTarget:main_window];
resize2x = [view addItemWithTitle:@"Size 2x" action:@selector(resizeScreen2x) keyEquivalent:@"2"];
[resize2x setTarget:main_window];
resize3x = [view addItemWithTitle:@"Size 3x" action:@selector(resizeScreen3x) keyEquivalent:@"3"];
[resize3x setTarget:main_window];
resize4x = [view addItemWithTitle:@"Size 4x" action:@selector(resizeScreen4x) keyEquivalent:@"4"];
[resize4x setTarget:main_window];
/*
[view addItem:[NSMenuItem separatorItem]];
[view addItemWithTitle:@"Full Screen" action:nil keyEquivalent:@"f"];
*/
[view addItem:[NSMenuItem separatorItem]];
allows_resize_item = [view addItemWithTitle:@"Allow Resize" action:@selector(toggleAllowsResize) keyEquivalent:@""];
[allows_resize_item setState:NSOnState];
[allows_resize_item setTarget:main_window];
constrain_item = [view addItemWithTitle:@"Constrain Proportions" action:@selector(toggleConstrainProportions) keyEquivalent:@""];
[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 setState:NSOnState];
[min_size_item setTarget:main_window];
[view addItem:[NSMenuItem separatorItem]];
temp = [view addItemWithTitle: @"Rotation" action:nil keyEquivalent:@""];
NSMenu *rotation_menu = [[NSMenu alloc] initWithTitle:@"Rotation"];
[temp setSubmenu: rotation_menu];
rotation0_item = [rotation_menu addItemWithTitle:@"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 setState:NSOffState];
[rotation90_item setTarget:main_window];
rotation180_item = [rotation_menu addItemWithTitle:@"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 setState:NSOffState];
[rotation270_item setTarget:main_window];
[view addItem:[NSMenuItem separatorItem]];
temp = [view addItemWithTitle:@"Layers" action:nil keyEquivalent:@""];
NSMenu *layer_menu = [[NSMenu alloc] initWithTitle:@"Layers"];
[temp setSubmenu: layer_menu];
topBG0_item = [layer_menu addItemWithTitle:@"Top BG0" action:@selector(toggleTopBackground0) keyEquivalent:@""];
[topBG0_item setState:NSOnState];
[topBG0_item setTarget:main_window];
topBG1_item = [layer_menu addItemWithTitle:@"Top BG1" action:@selector(toggleTopBackground1) keyEquivalent:@""];
[topBG1_item setState:NSOnState];
[topBG1_item setTarget:main_window];
topBG2_item = [layer_menu addItemWithTitle:@"Top BG2" action:@selector(toggleTopBackground2) keyEquivalent:@""];
[topBG2_item setState:NSOnState];
[topBG2_item setTarget:main_window];
topBG3_item = [layer_menu addItemWithTitle:@"Top BG3" action:@selector(toggleTopBackground3) keyEquivalent:@""];
[topBG3_item setState:NSOnState];
[topBG3_item setTarget:main_window];
[layer_menu addItem:[NSMenuItem separatorItem]];
subBG0_item = [layer_menu addItemWithTitle:@"Sub BG0" action:@selector(toggleSubBackground0) keyEquivalent:@""];
[subBG0_item setState:NSOnState];
[subBG0_item setTarget:main_window];
subBG1_item = [layer_menu addItemWithTitle:@"Sub BG1" action:@selector(toggleSubBackground1) keyEquivalent:@""];
[subBG1_item setState:NSOnState];
[subBG1_item setTarget:main_window];
subBG2_item = [layer_menu addItemWithTitle:@"Sub BG2" action:@selector(toggleSubBackground2) keyEquivalent:@""];
[subBG2_item setState:NSOnState];
[subBG2_item setTarget:main_window];
subBG3_item = [layer_menu addItemWithTitle:@"Sub BG3" action:@selector(toggleSubBackground3) keyEquivalent:@""];
[subBG3_item setState:NSOnState];
[subBG3_item setTarget:main_window];
//Create the window menu
/*
window = [[NSMenu alloc] initWithTitle:localizedString(@"Window", nil)];
[menu setSubmenu:window forItem:window_item];
[window addItemWithTitle:@"Minimize" action:nil keyEquivalent:@""];
[window addItemWithTitle:@"Zoom" action:nil keyEquivalent:@""];
[window addItem:[NSMenuItem separatorItem]];
[window addItemWithTitle:@"Bring All to Front" action:nil keyEquivalent:@""];
[window addItem:[NSMenuItem separatorItem]];
[window addItemWithTitle:@"DS Display" action:nil keyEquivalent:@""];
//[window addItemWithTitle:@"Save State Viewer" action:nil keyEquivalent:@""];
//[window addItemWithTitle:@"Debugger" action:nil keyEquivalent:@""];
//[window addItem:[NSMenuItem separatorItem]];
//[window addItemWithTitle:@"(screenshots)" action:nil keyEquivalent:@""];
*/
//Create the help menu
help = [[NSMenu alloc] initWithTitle:localizedString(@"Help", nil)];
[menu setSubmenu:help forItem:help_item];
[help addItemWithTitle:@"Website" action:nil keyEquivalent: @""];
[help addItemWithTitle:@"Forums" action:nil keyEquivalent: @""];
[help addItemWithTitle:@"Submit A Bug Report" action:nil keyEquivalent: @""];
[NSApp setMainMenu: menu];
[menu update];
}
//Main Function--------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
srand(time(NULL));
//Application Init Stuff----------------------------------------------------------------------
//Get the application instance (global variable called NSApp)
[NSApplication sharedApplication];
//Set the application delegate
[NSApp setDelegate:NSApp];
[NSApp run];
//Program Exit ---------------------------------------------------------------------------------------
return 0;
}
//gdb stuff--------------------------------------------------------------------------------
//don't know and don't care
void *
createThread_gdb( void (*thread_function)( void *data),
void *thread_data) {
return NULL;
}
void
joinThread_gdb( void *thread_handle) {
}
//Implementations-------------------------------------------------------------------------
@implementation NSApplication(delegate)
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
if([NDS loadROM:filename])
return YES;
return NO;
}
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
{
//messageDialog(@"Openfiles",@"");
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
//More app Init ------------------------------------------------------------------------------
//Bring the application to the front
[NSApp activateIgnoringOtherApps:TRUE];
//create the global ds object
NDS = [[NintendoDS alloc] init];
//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");
//[NDS LoadROM:@"/Users/gecko/nds/0004 - Feel the Magic - XY-XX (U) (Trashman).nds"];
//^ above line breaks everything!?
//Main program loop ----------------------------------------------------------------------------
#ifdef MULTITHREADED
//Breakoff a thread to run
[NSApplication detachDrawingThread:@selector(run) toTarget:NDS withObject:nil];
#else
[NDS run];
//it seems we need an event before it will quit
//(probably has something to do with calling run from applicationDidFinishLaunching?)
[NSEvent startPeriodicEventsAfterDelay:0 withPeriod:1];
#endif
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
//Ask user if he wants to quit
AskForQuit();
//AskForQuit takes care of quitting, dont need cocoa to do it for us
return NSTerminateCancel;
}
@end

View File

@ -0,0 +1,87 @@
/* 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 MAIN_WINDOW_H
#define MAIN_WINDOW_H
#import <Cocoa/Cocoa.h>
//This interface is to create and manaage the window
//that displays DS video output and takes keyboard/mouse input
//do not instanciate more than one of these
@interface VideoOutputWindow : NSWindow {}
//initialization
- (id)init;
//call this function to read the screen from the emulator and update the window
//this is the only method involving cocoa that should be called from the run() function
- (void)updateScreen;
//makes the screen white
- (void)clearScreen;
//resets the min size internalls (when rotation changes), shouldn't be used from outside
- (void)resetMinSize:(bool)resize;
//toggles between allowing tiny sizes and only being as small as DS
- (void)toggleMinSize;
//this method will contrain the size as well
//this is screen size not window size
- (void)resizeScreen:(NSSize)size;
//like resizeScreen but does a size in relation to DS pixels
- (void)resizeScreen1x;
- (void)resizeScreen2x;
- (void)resizeScreen3x;
- (void)resizeScreen4x;
//
- (void)toggleAllowsResize;
- (void)toggleConstrainProportions;
//rotation
- (void)setRotation0;
- (void)setRotation90;
- (void)setRotation180;
- (void)setRotation270;
//layers
- (void)toggleTopBackground0;
- (void)toggleTopBackground1;
- (void)toggleTopBackground2;
- (void)toggleTopBackground3;
- (void)toggleSubBackground0;
- (void)toggleSubBackground1;
- (void)toggleSubBackground2;
- (void)toggleSubBackground3;
//keyboard input
- (void)keyDown:(NSEvent*)event;
- (void)keyUp:(NSEvent*)event;
//mouse input
- (void)mouseDown:(NSEvent*)event;
- (void)mouseDragged:(NSEvent*)event;
- (void)mouseUp:(NSEvent*)event;
@end
#endif //MAIN_WINDOW_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,59 @@
/* 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 NDS_CONTROL_H_INCLUDED
#define NDS_CONTROL_H_INCLUDED
#include <Cocoa/Cocoa.h>
//This class manages emulation
//dont instanciate more than once!
@interface NintendoDS : NSObject {}
//creation
- (id)init;
//ROM control
- (void)pickROM;
- (BOOL)loadROM:(NSString*)filename;
- (void)closeROM;
- (void)askAndCloseROM;
//execution control
- (void)execute;
- (void)pause;
- (void)reset;
- (void)setFrameSkip:(id)sender;
//run function (should be called at the start of the program)
- (void)run;
//save states
- (void)saveStateAs;
- (void)loadStateFrom;
- (void)saveToSlot:(id)sender;
- (void)loadFromSlot:(id)sender;
//- (void)askAndClearStates;
//
- (void)showRomInfo;
@end
#endif // NDS_CONTROL_H_INCLUDED

View File

@ -0,0 +1,711 @@
/* 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
*/
//DeSmuME Cocoa includes
#import "globals.h"
#import "nds_control.h"
#import "main_window.h"
//DeSmuME general includes
#define OBJ_C
#include "../NDSSystem.h"
#include "../saves.h"
#undef BOOL
//ds screens are 59.8 frames per sec, so 1/59.8 seconds per frame
//times one million for microseconds per frame
#define DS_MICROSECONDS_PER_FRAME (1.0 / 59.8) * 1000000.0
//fixme bug when hitting apple+Q during the open dialog
@interface TableHelper : NSObject
{
NSTableView *table;
NSTableColumn *type_column;
NSTableColumn *value_column;
NDS_header *header;
}
//init
- (id)initWithWindow:(NSWindow*)window;
//table data protocol
- (int)numberOfRowsInTableView:(NSTableView *)aTableView;
- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info row:(int)row dropOperation:(NSTableViewDropOperation)operation;
- (NSArray *)tableView:(NSTableView *)aTableView namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination forDraggedRowsWithIndexes:(NSIndexSet *)indexSet;
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex;
- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex;
- (void)tableView:(NSTableView *)aTableView sortDescriptorsDidChange:(NSArray *)oldDescriptors;
- (NSDragOperation)tableView:(NSTableView *)aTableView validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)operation;
- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pboard;
//window delegate stuff
- (void)windowWillClose:(NSNotification *)aNotification;
- (void)windowDidResize:(NSNotification *)aNotification;
@end
/////////////////////////
NSMenuItem *close_rom_item;
NSMenuItem *execute_item;
NSMenuItem *pause_item;
NSMenuItem *reset_item;
NSMenuItem *save_state_as_item;
NSMenuItem *load_state_from_item;
NSMenuItem *saveSlot_item[SAVE_SLOTS];
NSMenuItem *loadSlot_item[SAVE_SLOTS];
//NSMenuItem *clear_all_saves_item;
NSMenuItem *rom_info_item;
NSMenuItem *frame_skip_auto_item;
NSMenuItem *frame_skip_item[MAX_FRAME_SKIP];
volatile u8 frame_skip = 0; //this is one more than the acutal frame skip, a value of 0 signifies auto frame skip
static int backupmemorytype=MC_TYPE_AUTODETECT;
static u32 backupmemorysize=1;
NSString *current_file;
@implementation NintendoDS
- (id)init
{
struct armcpu_memory_iface *arm9_memio = &arm9_base_memory_iface;
struct armcpu_memory_iface *arm7_memio = &arm7_base_memory_iface;
struct armcpu_ctrl_iface *arm9_ctrl_iface;
struct armcpu_ctrl_iface *arm7_ctrl_iface;
//struct configured_features my_config;
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);
NDS_CreateDummyFirmware(&firmware);
return self;
}
- (void)pickROM
{
BOOL was_paused = paused;
[self pause];
NSString *temp = openDialog([NSArray arrayWithObjects:@"NDS", @"ds.GBA", nil]);
if(temp)
{
[self loadROM:temp];
return;
}
if(!was_paused)[self execute];
}
- (BOOL)loadROM:(NSString*)filename
{
//pause if not already paused
bool was_paused = paused;
[self pause];
//load the rom
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");
//continue playing if load didn't work
if(!was_paused)[self execute];
return FALSE;
}
//set current file var
current_file = filename;
//enable execution control menu
[execute_item setEnabled:YES];
[pause_item setEnabled:YES];
[reset_item setEnabled:YES];
[close_rom_item setEnabled:YES];
[rom_info_item setEnabled:YES];
[save_state_as_item setEnabled:YES];
[load_state_from_item setEnabled:YES];
//
bool atleast_one_save_exists = false;
scan_savestates();
int i;
for(i = 0; i < SAVE_SLOTS; i++)
{
[saveSlot_item[i] setEnabled:YES];
if(savestates[i].exists == desmume_TRUE)
{
atleast_one_save_exists = true;
[saveSlot_item[i] setState:NSOnState];
[loadSlot_item[i] setEnabled:YES];
} else
{
[saveSlot_item[i] setState:NSOffState];
[loadSlot_item[i] setEnabled:NO];
}
}
//if(atleast_one_save_exists)
//[clear_all_saves_item setEnabled:YES];
//layers apparently get reset on rom load?
//[set topBG2_item fixme
//if it worked, unpause (start)
[self execute];
return true;
}
- (void)closeROM
{
[self pause];
NDS_FreeROM();
//set menu item states
[execute_item setEnabled:NO];
[pause_item setEnabled:NO];
[reset_item setEnabled:NO];
[close_rom_item setEnabled:NO];
[rom_info_item setEnabled:NO];
[save_state_as_item setEnabled:NO];
[load_state_from_item setEnabled:NO];
//disable all save slots
int i;
for(i = 0; i < SAVE_SLOTS; i++)
{
[saveSlot_item[i] setEnabled:NO];
[saveSlot_item[i] setState:NSOffState];
[loadSlot_item[i] setEnabled:NO];
}
//[clear_all_saves_item setEnabled:NO];
}
- (void)askAndCloseROM
{
bool was_paused = paused;
[NDS pause];
if(messageDialogYN(localizedString(@"DeSmuME Emulator", nil), localizedString(@"Are you sure you want to close the ROM?", nil)))
{
[self closeROM];
[main_window clearScreen];
}
else if(!was_paused)[NDS execute];
}
- (void)execute
{
paused = FALSE;
execute = TRUE;
//SPU_Pause(0);
[pause_item setState:NSOffState];
[execute_item setState:NSOnState];
}
- (void)pause
{
if(paused)return;
execute = FALSE;
//SPU_Pause(1);
#ifndef MULTITHREADED
paused = TRUE;
#else
//wait for the other thread to stop execution
while (!paused) {}
#endif
[pause_item setState:NSOnState];
[execute_item setState:NSOffState];
}
- (void)reset
{
NDS_Reset();
[self execute];
}
- (void)setFrameSkip:(id)sender
{
int i;
//see if this was sent from the autoskip menu item
if(sender == frame_skip_auto_item)
{
//set the frame skip to auto
frame_skip = 0;
//check auto
[frame_skip_auto_item setState:NSOnState];
//uncheck the others
for(i = 0; i < MAX_FRAME_SKIP; i++)[frame_skip_item[i] setState:NSOffState];
return;
}
//search through the frame skip menu items to find out which one called this function
for(i = 0; i < MAX_FRAME_SKIP; i++)
if(sender == frame_skip_item[i])break;
if(i == MAX_FRAME_SKIP)return; //not a known sender
//set the frame skip value
frame_skip = i + 1;
//check the selected frame skip value
[frame_skip_item[i] setState:NSOnState];
//uncheck the others
int i2;
for(i2 = 0; i2 < MAX_FRAME_SKIP; i2++)
if(i2 != i)
[frame_skip_item[i2] setState:NSOffState];
[frame_skip_auto_item setState:NSOffState];
}
- (void)run
{
u32 cycles = 0;
//this flag is so we can set the pause state to true
//ONCE after the inner run loop breaks (ie when you pause)
//to avoid some slight chance that the other thread sets pause to false
//and this thread re
bool was_running = false; //initialized here to avoid a warning
unsigned long long frame_start_time, frame_end_time;
unsigned long long microseconds_per_frame;
int frames_to_skip = 0;
//program main loop
while(!finished)
{
#ifndef MULTITHREADED
//keep the GUI responsive even while not running a gme
if(!execute)clearEvents(true);
#endif
//run the emulator
while(execute && !finished)
{
was_running = true;
//clear the event queue so the GUI elements are responsive when the game is running
//needs to happen before frame_start_time is recieved incase the user does a live resize
//or something that will pause everything
#ifndef MULTITHREADED
if(frames_to_skip == 0)
clearEvents(false);
#endif
Microseconds((struct UnsignedWide*)&frame_start_time);
cycles = NDS_exec((560190<<1)-cycles, FALSE);
if(frames_to_skip != 0)
frames_to_skip--;
else
{
Microseconds((struct UnsignedWide*)&frame_end_time);
if(frame_skip == 0)
{ //automatic
//i don't know if theres a standard strategy, but here we calculate
//how much longer the frame took than it should have, then set it to skip
//that many frames.
frames_to_skip = ((double)(frame_end_time - frame_start_time)) / ((double)DS_MICROSECONDS_PER_FRAME);
} else
{
frames_to_skip = frame_skip;
}
#ifndef MULTITHREADED
if(!paused) //so the screen doesnt update after being cleared to white (when closing rom)
#endif
[main_window updateScreen];
}
}
//
if(was_running)
{
paused = TRUE; //for the multithreaded version (avoid forever loop in the pause method)
was_running = false; //
//set some kind of checkmarks or something?
}
}
}
- (void)saveStateAs
{
messageDialog(@"LOAD",@"DDSA");
}
- (void)loadStateFrom
{
NSString *file = openDialog([NSArray arrayWithObject:@"DST"]);
if(file)
{
[NDS pause];
savestate_load([file cStringUsingEncoding:NSASCIIStringEncoding]);
[NDS execute];
}
}
- (void)saveToSlot:(id)sender
{
//get the save slot by detecting which menu item sent the message
int i;
for(i = 0; i < SAVE_SLOTS; i++)
if(sender == saveSlot_item[i])break;
//quit if the message wasn't sent by a save state menu item
if(i == SAVE_SLOTS)return;
bool was_paused = paused;
[NDS pause];
savestate_slot(i + 1);
[saveSlot_item[i] setState:NSOnState];
[loadSlot_item[i] setEnabled:YES];
//[clear_all_saves_item setEnabled:YES];
if(!was_paused)[NDS execute];
}
- (void)loadFromSlot:(id)sender
{
//get the load slot
int i;
for(i = 0; i < SAVE_SLOTS; i++)
if(sender == loadSlot_item[i])break;
//quit if the message wasn't sent by a save state menu item
if(i == SAVE_SLOTS)return;
bool was_paused = paused;
[NDS pause];
loadstate_slot(i + 1);
if(!was_paused)[NDS execute];
}
/*
- (void)askAndClearStates
{
BOOL was_paused = paused;
[NDS pause];
if(messageDialogYN(localizedString(@"DeSmuME Emulator", nil),
localizedString(@"Are you sure you want to clear all save slots?", nil)))
{
to be implemented after saves.h provides a way to delete saves...
int i;
for(i = 0; i < SAVE_SLOTS; i++)
{
[saveSlot_item[i] setState:NSOffState];
[loadSlot_item[i] setEnabled:NO];
}
[clear_all_saves_item setEnabled:NO];
}
if(!was_paused)[NDS execute];
}
*/
- (void)showRomInfo
{
BOOL was_paused = paused;
[self pause];
//create a window
NSRect rect;
rect.size.width = 400;
rect.size.height = 200; //fixme;
rect.origin.x = 200;
rect.origin.y = 200;
NSWindow *rom_info_window = [[NSWindow alloc] initWithContentRect:rect styleMask:
NSTitledWindowMask|NSClosableWindowMask|NSResizableWindowMask backing:NSBackingStoreBuffered defer:NO screen:nil];
//set the window title
[rom_info_window setTitle:localizedString(@"ROM Info", nil)];
//create an NSTableView to display the stuff
TableHelper *helper = [[TableHelper alloc] initWithWindow:rom_info_window];
//set the window delegate
[rom_info_window setDelegate:helper];
//min size is starting size
[rom_info_window setMinSize:[rom_info_window frame].size];
//show the window
[[[NSWindowController alloc] initWithWindow:rom_info_window] showWindow:nil];
//run the window
[NSApp runModalForWindow:rom_info_window];
if(!was_paused)[self execute];
}
@end
#define ROM_INFO_ROWS 9
#define ROM_INFO_WIDTH 400
@implementation TableHelper
- (id)initWithWindow:(NSWindow*)window
{
self = [super init];
type_column = [[NSTableColumn alloc] initWithIdentifier:@""];
[type_column setEditable:NO];
[value_column setResizable:YES];
[[type_column headerCell] setStringValue:@"Attribute"];
[type_column setMinWidth: 1];
value_column = [[NSTableColumn alloc] initWithIdentifier:@""];
[value_column setEditable:NO];
[value_column setResizable:YES];
[[value_column headerCell] setStringValue:@"Value"];
[value_column setMinWidth: 1];
NSRect rect;
rect.size.width = rect.size.height = rect.origin.x = rect.origin.y = 0;
table = [[NSTableView alloc] initWithFrame:rect];
[table setDrawsGrid:NO];
[table setAllowsColumnSelection:YES];
[table setAllowsColumnReordering:YES];
[table setAllowsEmptySelection:YES];
[table setAllowsMultipleSelection:NO];
[table addTableColumn:type_column];
[table addTableColumn:value_column];
[table setDataSource:self];
//[table setDelegate:self];
//[table setTarget: _parent];
//[table setDoubleAction: @selector(editClicked:)];
[table setUsesAlternatingRowBackgroundColors:YES];
//
//[table setHeaderView:[[NSTableHeaderView alloc] initWithFrame:NSMakeRect(0,0,0,0)]];
if([table headerView] == nil)messageDialogBlank();
//resize the window to fit enough rows
rect.size.width = ROM_INFO_WIDTH;
rect.size.height = [table rowHeight] * ROM_INFO_ROWS + [table intercellSpacing].height * (ROM_INFO_ROWS - 1) + 2 /*dunno what the 2 is for*/;
[window setContentSize:rect.size];
//resize the left column to take up only as much space as needed
//[type_column sizeToFit];
//resize the right column to take up the rest of the window
[value_column setWidth:ROM_INFO_WIDTH - [type_column width]];
//
[window setContentView:table];
//grab the header to read data from
header = NDS_getROMHeader();
return self;
}
- (int)numberOfRowsInTableView:(NSTableView *)aTableView;
{
return ROM_INFO_ROWS;
}
- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info row:(int)row dropOperation:(NSTableViewDropOperation)operation
{
return NO;
}
- (NSArray *)tableView:(NSTableView *)aTableView namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination forDraggedRowsWithIndexes:(NSIndexSet *)indexSet
{
return [NSArray array];
}
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
if(aTableColumn == type_column)
{
if(rowIndex == 0)
return localizedString(@"File on Disc", @" ROM Info ");
if(rowIndex == 1)
return localizedString(@"ROM Title", @" ROM Info ");
if(rowIndex == 2)
return localizedString(@"Maker Code", @" ROM Info ");
if(rowIndex == 3)
return localizedString(@"Unit Code", @" ROM Info ");
if(rowIndex == 4)
return localizedString(@"Card Size", @" ROM Info ");
if(rowIndex == 5)
return localizedString(@"Flags", @" ROM Info ");
if(rowIndex == 6)
return localizedString(@"Size of ARM9 Binary", @" ROM Info ");
if(rowIndex == 7)
return localizedString(@"Size of ARM7 Size", @" ROM Info ");
if(rowIndex == 8)
return localizedString(@"Size of Data", @" ROM Info ");
} else
{
if(rowIndex == 0)return current_file;
if(rowIndex == 1)
return NSSTRc(header->gameTile);
if(rowIndex == 2)
{
return [NSString localizedStringWithFormat:@"%u", header->makerCode];
}
if(rowIndex == 3)
{
return [NSString localizedStringWithFormat:@"%u", header->unitCode];
}
if(rowIndex == 4)
{//fixe: should show units?
return [NSString localizedStringWithFormat:@"%u", header->cardSize];
}
if(rowIndex == 5)
{//always seems to be empty?
return [NSString localizedStringWithFormat:@"%u%u%u%u%u%u%u%u",
((header->flags) & 0x01) >> 0,
((header->flags) & 0x02) >> 1,
((header->flags) & 0x04) >> 2,
((header->flags) & 0x08) >> 3,
((header->flags) & 0x10) >> 4,
((header->flags) & 0x20) >> 5,
((header->flags) & 0x40) >> 6,
((header->flags) & 0x80) >> 7];
}
if(rowIndex == 6)
{//fixe: should show units?
return [NSString localizedStringWithFormat:@"%u", header->ARM9binSize];
}
if(rowIndex == 7)
{//fixe: should show units?
return [NSString localizedStringWithFormat:@"%u", header->ARM7binSize];
}
if(rowIndex == 8)
{//fixe: should show units?
return [NSString localizedStringWithFormat:@"%u", header->ARM7binSize + header->ARM7src];
}
}
return @"If you see this, there is a bug";
}
- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex;
{
}
- (void)tableView:(NSTableView *)aTableView sortDescriptorsDidChange:(NSArray *)oldDescriptors;
{
}
- (NSDragOperation)tableView:(NSTableView *)aTableView validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)operation
{
return NSDragOperationNone;
}
- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pboard;
{
return NO;
}
- (void)windowWillClose:(NSNotification *)aNotification
{
[NSApp stopModal];
}
- (void)windowDidResize:(NSNotification *)aNotification
{
//we have this because the tableview doesn't change clipped text size
int i;
for(i = 0; i < ROM_INFO_ROWS; i++)
{
[table drawRow:i clipRect:[table frame]];
}
}
@end

View File

@ -0,0 +1,174 @@
#import "globals.h"
#import "nds_control.h"
///////////////////////////////
NSWindow *preferences_window;
NSFont *preferences_font;
NSDictionary *preferences_font_attribs;
NSTabViewItem *interface_pane_tab;
NSTabViewItem *firmware_pane_tab;
NSTabViewItem *plugins_pane_tab;
NSText *language_selection_text;
NSPopUpButton *language_selection;
///////////////////////////////
@interface PreferencesDelegate : NSObject {}
- (void)windowWillClose:(NSNotification *)aNotification;
@end
@implementation PreferencesDelegate
- (void)windowWillClose:(NSNotification *)aNotification
{
[NSApp stopModal];
}
- (void)languageChange:(id)sender
{
}
@end
////////////////////////////////////////////////////
@implementation NSApplication(custom_extensions)
- (void)about
{
bool was_paused = paused;
[NDS pause];
NSRunAlertPanel(localizedString(@"About DeSmuME", nil),
@"DeSmuME is an open source Nintendo DS emulator.\n\nBased off of YopYop's original work, and continued by the DeSmuME team.\n\
\nhttp://www.desmume.org\n\n\n\
This program 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. \
\n\n\
This program 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. \
\n\n\
You should have received a copy of the GNU General Public \
License along with this program; if not, write to the Free \
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, \
MA 02111-1307 USA\
\n\n\
See the GNU General Public License details in COPYING.", nil/*OK*/, nil, nil);
if(!was_paused)[NDS execute];
}
///////////////////////////////////////////////////
- (void)preferences
{
bool was_paused = paused;
[NDS pause];
//----------------------------------------------------------------------------------------------
//get the applications main bundle
NSBundle* app_bundle = [NSBundle mainBundle];
//grab the list of languages
NSArray *languages = [app_bundle localizations];
//get a font for displaying text
preferences_font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]];
preferences_font_attribs = [NSDictionary dictionaryWithObjectsAndKeys:preferences_font, NSFontAttributeName, nil];
//create our delegate
PreferencesDelegate *delegate = [[PreferencesDelegate alloc] init];
//
int i; //general iterator
//Create the window ------------------------------------------------------------------------------
//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 title
[preferences_window setTitle:localizedString(@"DeSmuME Preferences", nil)];
//set the window delegate
[preferences_window setDelegate:delegate];
//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 the "Interface" pane
interface_pane_tab = [[NSTabViewItem alloc] initWithIdentifier:nil];
[interface_pane_tab setLabel:localizedString(@"Interface", nil)];
[tab_view addTabViewItem:interface_pane_tab];
//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 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 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];
//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 "Plugins" pane
plugins_pane_tab = [[NSTabViewItem alloc] initWithIdentifier:nil];
[plugins_pane_tab setLabel:localizedString(@"Plugins", nil)];
[tab_view addTabViewItem:plugins_pane_tab];
//show the window
[[[NSWindowController alloc] initWithWindow:preferences_window] showWindow:nil];
[NSApp runModalForWindow:preferences_window];
if(!was_paused)[NDS execute];
}
@end

View File

@ -105,7 +105,13 @@ typedef s16 v10;
/*----------------------*/
#ifndef OBJ_C
typedef int BOOL;
#else
//apple defines BOOL so this is to avoid conflicts
typedef int desmume_BOOL;
#define BOOL desmume_BOOL
#endif
#ifndef TRUE
#define TRUE 1

View File

@ -1,4 +1,4 @@
/*
/*
Copyright (C) 2006 yopyop
Copyright (C) 2006-2007 shash
@ -19,6 +19,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DESMUME_COCOA
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <gl\gl.h>
@ -29,6 +31,19 @@
#include "..\MMU.h"
#include "..\bits.h"
#include "..\matrix.h"
#else
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#include "../debug.h"
#include "../MMU.h"
#include "../bits.h"
#include "../matrix.h"
#endif
#include "OGLRender.h"
@ -99,13 +114,17 @@ static unsigned int vtxFormat;
static unsigned int textureFormat=0, texturePalette=0;
static unsigned int lastTextureFormat=0, lastTexturePalette=0;
#ifndef DESMUME_COCOA
extern HWND hwnd;
#endif
char NDS_glInit(void)
{
int i;
#ifndef DESMUME_COCOA
HDC oglDC = NULL;
HGLRC hRC = NULL;
int pixelFormat, i;
int pixelFormat;
PIXELFORMATDESCRIPTOR pfd;
oglDC = GetDC (hwnd);
@ -121,18 +140,19 @@ char NDS_glInit(void)
pfd.iLayerType = PFD_MAIN_PLANE ;
pixelFormat = ChoosePixelFormat(oglDC, &pfd);
if (pixelFormat == 0)
if (pixelFormat == 0)
return 0;
if(!SetPixelFormat(oglDC, pixelFormat, &pfd))
if(!SetPixelFormat(oglDC, pixelFormat, &pfd))
return 0;
hRC = wglCreateContext(oglDC);
if (!hRC)
if (!hRC)
return 0;
if(!wglMakeCurrent(oglDC, hRC))
return 0;
#endif
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
@ -194,8 +214,8 @@ void NDS_glViewPort(unsigned long v)
void NDS_glClearColor(unsigned long v)
{
glClearColor( ((float)(v&0x1F))/31.0f,
((float)((v>>5)&0x1F))/31.0f,
((float)((v>>10)&0x1F))/31.0f,
((float)((v>>5)&0x1F))/31.0f,
((float)((v>>10)&0x1F))/31.0f,
((float)((v>>16)&0x1F))/31.0f);
}
@ -346,7 +366,7 @@ void NDS_glScale(signed long v)
++scaleind;
if(scaleind<3)
if(scaleind<3)
return;
scaleind = 0;
@ -600,7 +620,7 @@ static __inline void SetupTexture (unsigned int format, unsigned int palette)
u32 yAbs = ((y<<2) + sy);
u32 currentPos = xAbs + yAbs*sizeX;
// Palette
// Palette
u8 currRow = (u8)((currBlock >> (sy*8)) & 0xFF);
#define RGB16TO32(col,alpha) (((alpha)<<24) | ((((col) & 0x7C00)>>7)<<16) | ((((col) & 0x3E0)>>2)<<8) | (((col) & 0x1F)<<3))
#define RGB32(r,g,b,a) (((a)<<24) | ((r)<<16) | ((g)<<8) | (b))
@ -717,7 +737,7 @@ static __inline void SetupTexture (unsigned int format, unsigned int palette)
}
}
}
break;
}
case 6:
@ -749,9 +769,9 @@ static __inline void SetupTexture (unsigned int format, unsigned int palette)
break;
}
glBindTexture(GL_TEXTURE_2D, oglTextureID);
glBindTexture(GL_TEXTURE_2D, oglTextureID);
switch ((format>>18)&3)
{
case 0:
@ -818,7 +838,7 @@ static __inline void SetupTexture (unsigned int format, unsigned int palette)
invTexWidth = 1.f/((float)sizeX*(1<<4));
invTexHeight = 1.f/((float)sizeY*(1<<4));
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
@ -877,7 +897,7 @@ void NDS_glBegin(unsigned long v)
{
glEnable(GL_CULL_FACE);
glCullFace(map3d_cull[cullingMask>>6]);
}
}
else
{
glDisable(GL_CULL_FACE);
@ -900,7 +920,7 @@ void NDS_glBegin(unsigned long v)
else
{
glPolygonMode (GL_FRONT, GL_LINE);
glPolygonMode (GL_BACK, GL_LINE);
glPolygonMode (GL_BACK, GL_LINE);
}
if (textureFormat != lastTextureFormat ||
@ -948,21 +968,21 @@ static __inline void SetVertex()
{
float coordTransformed[3] = { coord[0], coord[1], coord[2] };
if (texCoordinateTransform == 3)
if (texCoordinateTransform == 3)
{
int s2 = (int)(( coord[0]*mtxCurrent[3][0] +
coord[1]*mtxCurrent[3][4] +
int s2 = (int)(( coord[0]*mtxCurrent[3][0] +
coord[1]*mtxCurrent[3][4] +
coord[2]*mtxCurrent[3][8]) + s);
int t2 = (int)(( coord[0]*mtxCurrent[3][1] +
coord[1]*mtxCurrent[3][5] +
coord[2]*mtxCurrent[3][9]) + t);
int t2 = (int)(( coord[0]*mtxCurrent[3][1] +
coord[1]*mtxCurrent[3][5] +
coord[2]*mtxCurrent[3][9]) + t);
glTexCoord2i (s2, t2);
}
glTexCoord2i (s2, t2);
}
MatrixMultVec4x4 (mtxCurrent[1], coordTransformed);
glVertex3fv (coordTransformed);
glVertex3fv (coordTransformed);
numVertex++;
}
@ -972,7 +992,7 @@ void NDS_glVertex16b(unsigned int v)
if(coordind==0)
{
coord[0] = float16table[v&0xFFFF];
coord[1] = float16table[v>>16];
coord[1] = float16table[v>>16];
++coordind;
return;
@ -997,7 +1017,7 @@ void NDS_glVertex3_cord(unsigned int one, unsigned int two, unsigned int v)
{
coord[one] = float16table[v&0xffff];
coord[two] = float16table[v>>16];
SetVertex ();
}
@ -1184,9 +1204,9 @@ void NDS_glTexCoord(unsigned long val)
if (texCoordinateTransform == 1)
{
int s2 =(int)( s* mtxCurrent[3][0] + t* mtxCurrent[3][4] +
int s2 =(int)( s* mtxCurrent[3][0] + t* mtxCurrent[3][4] +
(1.f/16.f)* mtxCurrent[3][8] + (1.f/16.f)* mtxCurrent[3][12]);
int t2 =(int)( s* mtxCurrent[3][1] + t* mtxCurrent[3][5] +
int t2 =(int)( s* mtxCurrent[3][1] + t* mtxCurrent[3][5] +
(1.f/16.f)* mtxCurrent[3][9] + (1.f/16.f)* mtxCurrent[3][13]);
glTexCoord2i (s2, t2);
@ -1243,9 +1263,9 @@ void NDS_glLightDirection (unsigned long v)
void NDS_glLightColor (unsigned long v)
{
int lightColor[4] = { ((v) &0x1F)<<26,
((v>> 5)&0x1F)<<26,
((v>>10)&0x1F)<<26,
int lightColor[4] = { ((v) &0x1F)<<26,
((v>> 5)&0x1F)<<26,
((v>>10)&0x1F)<<26,
0x7fffffff};
if (beginCalled)
@ -1335,9 +1355,9 @@ void NDS_glNormal(unsigned long v)
if (texCoordinateTransform == 2)
{
int s2 =(int)( (normal[0] *mtxCurrent[3][0] + normal[1] *mtxCurrent[3][4] +
int s2 =(int)( (normal[0] *mtxCurrent[3][0] + normal[1] *mtxCurrent[3][4] +
normal[2] *mtxCurrent[3][8]) + s);
int t2 =(int)( (normal[0] *mtxCurrent[3][1] + normal[1] *mtxCurrent[3][5] +
int t2 =(int)( (normal[0] *mtxCurrent[3][1] + normal[1] *mtxCurrent[3][5] +
normal[2] *mtxCurrent[3][9]) + t);
glTexCoord2i (s2, t2);
@ -1394,7 +1414,7 @@ void NDS_glCallList(unsigned long v)
case 0x41:
{
NDS_glEnd();
NDS_glEnd();
--clInd;
clCmd>>=8;
continue;
@ -1429,7 +1449,7 @@ void NDS_glCallList(unsigned long v)
NDS_glPopMatrix(v);
--clInd;
clCmd>>=8;
break;
break;
}
case 0x13:
@ -1438,7 +1458,7 @@ void NDS_glCallList(unsigned long v)
NDS_glStoreMatrix(v);
--clInd;
clCmd>>=8;
break;
break;
}
case 0x14:
@ -1583,7 +1603,7 @@ void NDS_glCallList(unsigned long v)
if(clInd2==2)
{
--clInd;
clCmd>>=8;
clCmd>>=8;
clInd2 = 0;
}
break;
@ -1610,7 +1630,7 @@ void NDS_glCallList(unsigned long v)
case 0x26:// GFX_VERTEX_XZ
{
((unsigned long *)ARM9Mem.ARM9_REG)[0x498>>2] = v;
NDS_glVertex3_cord(0,2,v);
NDS_glVertex3_cord(0,2,v);
--clInd;
clCmd>>=8;
break;
@ -1619,7 +1639,7 @@ void NDS_glCallList(unsigned long v)
case 0x27:// GFX_VERTEX_YZ
{
((unsigned long *)ARM9Mem.ARM9_REG)[0x49C>>2] = v;
NDS_glVertex3_cord(1,2,v);
NDS_glVertex3_cord(1,2,v);
--clInd;
clCmd>>=8;
break;
@ -1669,7 +1689,7 @@ void NDS_glCallList(unsigned long v)
clCmd>>=8;
break;
}
case 0x31: // GFX_SPECULAR_EMISSION
{
((unsigned long *)ARM9Mem.ARM9_REG)[0x4C4>>2] = v;
@ -1711,7 +1731,7 @@ void NDS_glCallList(unsigned long v)
break;
}
case 0x40 :
case 0x40 :
{
((unsigned long *)ARM9Mem.ARM9_REG)[0x500>>2] = v;
NDS_glBegin(v);
@ -1761,7 +1781,7 @@ void NDS_glCallList(unsigned long v)
}
if((clCmd&0xFF)==0x41)
{
glEnd();
glEnd();
--clInd;
clCmd>>=8;
}
@ -1811,8 +1831,8 @@ GPU3DInterface gpu3Dgl = { NDS_glInit,
NDS_glControl,
NDS_glNormal,
NDS_glCallList,
NDS_glGetClipMatrix,
NDS_glGetDirectionalMatrix,
NDS_glGetLine};