1/*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * Interface to the Cocoa Mac OS X GUI
5 *
6 * Copyright 1996 Bernd Schmidt
7 * Copyright 2004,2010 Steven J. Saunders
8 *           2010,2011 Mustafa TUFAN
9 */
10
11#include <stdlib.h>
12#include <stdarg.h>
13
14#include "sysconfig.h"
15#include "sysdeps.h"
16
17#include "uae.h"
18#include "options.h"
19#include "gui.h"
20#include "inputdevice.h"
21#include "disk.h"
22#include "ar.h"
23
24#include "custom.h"
25#include "xwin.h"
26#include "drawing.h"
27#include "savestate.h"
28
29#ifdef USE_SDL
30#include "SDL.h"
31#endif
32
33// MacOSX < 10.5
34#ifndef NSINTEGER_DEFINED
35#define NSINTEGER_DEFINED
36#ifdef __LP64__ || NS_BUILD_32_LIKE_64
37typedef long           NSInteger;
38typedef unsigned long  NSUInteger;
39#define NSIntegerMin   LONG_MIN
40#define NSIntegerMax   LONG_MAX
41#define NSUIntegerMax  ULONG_MAX
42#else
43typedef int            NSInteger;
44typedef unsigned int   NSUInteger;
45#define NSIntegerMin   INT_MIN
46#define NSIntegerMax   INT_MAX
47#define NSUIntegerMax  UINT_MAX
48#endif
49#endif
50
51static unsigned long memsizes[] = {
52        /* 0 */ 0,
53        /* 1 */ 0x00040000, /* 256K */
54        /* 2 */ 0x00080000, /* 512K */
55        /* 3 */ 0x00100000, /* 1M */
56        /* 4 */ 0x00200000, /* 2M */
57        /* 5 */ 0x00400000, /* 4M */
58        /* 6 */ 0x00800000, /* 8M */
59        /* 7 */ 0x01000000, /* 16M */
60        /* 8 */ 0x02000000, /* 32M */
61        /* 9 */ 0x04000000, /* 64M */
62        /* 10*/ 0x08000000, //128M
63        /* 11*/ 0x10000000, //256M
64        /* 12*/ 0x20000000, //512M
65        /* 13*/ 0x40000000, //1GB
66        /* 14*/ 0x00180000, //1.5MB
67        /* 15*/ 0x001C0000, //1.8MB
68        /* 16*/ 0x80000000, //2GB
69        /* 17*/ 0x18000000, //384M
70        /* 18*/ 0x30000000, //768M
71        /* 19*/ 0x60000000, //1.5GB
72        /* 20*/ 0xA8000000, //2.5GB
73        /* 21*/ 0xC0000000, //3GB
74};
75
76int quickstart_model = 0, quickstart_conf = 0, quickstart_compa = 1;
77int quickstart_floppy = 1, quickstart_cd = 0, quickstart_ntsc = 0;
78int quickstart_cdtype = 0;
79char quickstart_cddrive[16];
80int quickstart_ok, quickstart_ok_floppy;
81extern TCHAR config_filename[256];
82//----------
83
84#import <Cocoa/Cocoa.h>
85
86#define COCOA_GUI_MAX_PATH MAX_DPATH
87
88/* These prototypes aren't declared in the sdlgfx header for some reason */
89extern void toggle_fullscreen (int mode);
90extern int is_fullscreen (void);
91
92/* Defined in SDLmain.m */
93extern NSString *getApplicationName(void);
94
95/* Prototypes */
96int ensureNotFullscreen (void);
97void restoreFullscreen (void);
98
99/* Globals */
100static BOOL wasFullscreen = NO; // used by ensureNotFullscreen() and restoreFullscreen()
101
102/* Objective-C class for an object to respond to events */
103@interface PuaeGui : NSObject
104{
105	NSString *applicationName;
106	NSArray *diskImageTypes;
107	NSArray *CDImageTypes;
108	NSArray *HDDFileTypes;
109	NSArray *KickRomTypes;
110	NSArray *FlashRamTypes;
111	NSArray *CartridgeTypes;
112	NSArray *SaveStateTypes;
113}
114+ (id) sharedInstance;
115- (void)createMenus;
116- (void)createMenuItemInMenu:(NSMenu *)menu withTitle:(NSString *)title action:(SEL)anAction tag:(int)tag;
117- (void)createMenuItemInMenu:(NSMenu *)menu withTitle:(NSString *)title action:(SEL)anAction tag:(int)tag keyEquivalent:(NSString *)keyEquiv keyEquivalentMask:(NSUInteger)mask;
118- (BOOL)validateMenuItem:(id <NSMenuItem>)item;
119- (void)insertDisk:(id)sender;
120- (void)ejectDisk:(id)sender;
121- (void)ejectAllDisks:(id)sender;
122- (void)changePort0:(id)sender;
123- (void)changePort1:(id)sender;
124- (void)swapGamePorts:(id)sender;
125- (void)displayOpenPanelForInsertIntoDriveNumber:(int)driveNumber;
126- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo;
127- (void)resetAmiga:(id)sender;
128- (void)pauseAmiga:(id)sender;
129#ifdef ACTION_REPLAY
130- (void)actionReplayFreeze:(id)sender;
131#endif
132- (void)grabMouse:(id)sender;
133- (void)goFullscreen:(id)sender;
134- (void)toggleInhibitDisplay:(id)sender;
135- (void)changeChipMem:(id)sender;
136- (void)changeBogoMem:(id)sender;
137- (void)changeFastMem:(id)sender;
138- (void)changeZ3FastMem:(id)sender;
139- (void)changeZ3ChipMem:(id)sender;
140//- (void)changeGfxMem:(id)sender;
141- (void)changeCPU:(id)sender;
142- (void)changeCPUSpeed:(id)sender;
143- (void)changeFPU:(id)sender;
144- (void)changeMonitoremu:(id)sender;
145- (void)changeBlitter:(id)sender;
146- (void)changeCollision:(id)sender;
147@end
148
149@implementation PuaeGui
150
151+ (id) sharedInstance
152{
153	static id sharedInstance = nil;
154	if (sharedInstance == nil) sharedInstance = [[self alloc] init];
155
156	return sharedInstance;
157}
158
159-(PuaeGui *) init
160{
161	self = [super init];
162
163	if (self) {
164		applicationName = [[NSString alloc] initWithString:getApplicationName()];
165		diskImageTypes =[[NSArray alloc] initWithObjects:@"adf", @"adz", @"gz", @"exe", @"zip", @"dms", @"fdi",
166#ifdef CAPS
167            @"ipf",
168#endif
169            nil]; // Note: Use lowercase for these
170
171		CDImageTypes =[[NSArray alloc] initWithObjects:@"cue", @"ccd", @"mds", @"iso", nil];
172		HDDFileTypes =[[NSArray alloc] initWithObjects:@"hdf", @"vhd", @"rdr", @"hdz", @"rdz", nil];
173		KickRomTypes =[[NSArray alloc] initWithObjects:@"rom", @"roz", nil];
174		FlashRamTypes =[[NSArray alloc] initWithObjects:@"nvr", nil];
175		CartridgeTypes =[[NSArray alloc] initWithObjects:@"crt", @"rom", @"roz", nil];
176		SaveStateTypes =[[NSArray alloc] initWithObjects:@"uss", nil];
177	}
178
179	return self;
180}
181
182-(void) dealloc
183{
184	[applicationName release];
185	[diskImageTypes release];
186	[super dealloc];
187}
188
189-(NSArray *) diskImageTypes
190{
191	return diskImageTypes;
192}
193
194-(NSString *)applicationName
195{
196	return applicationName;
197}
198
199- (void)createMenus
200{
201	int driveNumber;
202	NSMenuItem *menuItem;
203	NSString *menuTitle;
204
205	// Create a menu for manipulating the emulated amiga
206	NSMenu *vAmigaMenu = [[NSMenu alloc] initWithTitle:@"Machine"];
207
208	[self createMenuItemInMenu:vAmigaMenu withTitle:@"Reset" action:@selector(resetAmiga:) tag:0];
209	[self createMenuItemInMenu:vAmigaMenu withTitle:@"Hard Reset" action:@selector(resetAmiga:) tag:1];
210	[self createMenuItemInMenu:vAmigaMenu withTitle:@"Leds on Screen" action:@selector(LedsOnScreen:) tag:2];
211
212#ifdef ACTION_REPLAY
213	[self createMenuItemInMenu:vAmigaMenu withTitle:@"Action Replay Freeze" action:@selector(actionReplayFreeze:) tag:0];
214#endif
215	[vAmigaMenu addItem:[NSMenuItem separatorItem]];
216
217	// quick starts
218	NSMenu *quickstartMenu = [[NSMenu alloc] initWithTitle:@"QuickStart"];
219		[self createMenuItemInMenu:quickstartMenu withTitle:@"Amiga 500" action:@selector(QuickStart:) tag:0];
220		[self createMenuItemInMenu:quickstartMenu withTitle:@"Amiga 500+" action:@selector(QuickStart:) tag:1];
221		[self createMenuItemInMenu:quickstartMenu withTitle:@"Amiga 600" action:@selector(QuickStart:) tag:2];
222		[self createMenuItemInMenu:quickstartMenu withTitle:@"Amiga 1000" action:@selector(QuickStart:) tag:3];
223		[self createMenuItemInMenu:quickstartMenu withTitle:@"Amiga 1200" action:@selector(QuickStart:) tag:4];
224		[self createMenuItemInMenu:quickstartMenu withTitle:@"Amiga 3000" action:@selector(QuickStart:) tag:5];
225		[self createMenuItemInMenu:quickstartMenu withTitle:@"Amiga 4000" action:@selector(QuickStart:) tag:6];
226		[self createMenuItemInMenu:quickstartMenu withTitle:@"Amiga 4000T" action:@selector(QuickStart:) tag:7];
227		[self createMenuItemInMenu:quickstartMenu withTitle:@"CD32" action:@selector(QuickStart:) tag:8];
228		[self createMenuItemInMenu:quickstartMenu withTitle:@"CDTV" action:@selector(QuickStart:) tag:9];
229		[self createMenuItemInMenu:quickstartMenu withTitle:@"Arcadia" action:@selector(QuickStart:) tag:10];
230	menuItem = [[NSMenuItem alloc] initWithTitle:@"QuickStart" action:nil keyEquivalent:@""];
231	[menuItem setSubmenu:quickstartMenu];
232	[vAmigaMenu addItem:menuItem];
233	[menuItem release];
234	[quickstartMenu release];
235
236	[vAmigaMenu addItem:[NSMenuItem separatorItem]];
237
238	[self createMenuItemInMenu:vAmigaMenu withTitle:@"Save State" action:@selector(selectSaveState:) tag:0];
239	[self createMenuItemInMenu:vAmigaMenu withTitle:@"Load State" action:@selector(selectLoadState:) tag:0];
240
241	[vAmigaMenu addItem:[NSMenuItem separatorItem]];
242
243	[self createMenuItemInMenu:vAmigaMenu withTitle:@"Select Kick ROM" action:@selector(selectKickROM:) tag:0];
244	[self createMenuItemInMenu:vAmigaMenu withTitle:@"Select Cartridge ROM" action:@selector(selectCartridge:) tag:0];
245	[self createMenuItemInMenu:vAmigaMenu withTitle:@"Select Flash RAM" action:@selector(selectFlashRAM:) tag:0];
246
247	menuItem = [[NSMenuItem alloc] initWithTitle:@"Machine" action:nil keyEquivalent:@""];
248	[menuItem setSubmenu:vAmigaMenu];
249	[[NSApp mainMenu] insertItem:menuItem atIndex:1];
250	[menuItem release];
251	[vAmigaMenu release];
252
253	// DISK MENU START
254	NSMenu *dskMenu = [[NSMenu alloc] initWithTitle:@"Disk"];
255
256		// Add menu items for inserting into floppy drives 1 - 4
257		NSMenu *insertFloppyMenu = [[NSMenu alloc] initWithTitle:@"Insert Floppy"];
258			for (driveNumber=0; driveNumber<4; driveNumber++) {
259				[self createMenuItemInMenu:insertFloppyMenu withTitle:[NSString stringWithFormat:@"DF%d...",driveNumber] action:@selector(insertDisk:) tag:driveNumber];
260			}
261
262		menuItem = [[NSMenuItem alloc] initWithTitle:@"Insert Floppy" action:nil keyEquivalent:@""];
263		[menuItem setSubmenu:insertFloppyMenu];
264		[dskMenu addItem:menuItem];
265		[menuItem release];
266
267		[dskMenu addItem:[NSMenuItem separatorItem]];
268
269		// Add menu items for ejecting from floppy drives 1 - 4
270		NSMenu *ejectFloppyMenu = [[NSMenu alloc] initWithTitle:@"Eject Floppy"];
271			[self createMenuItemInMenu:ejectFloppyMenu withTitle:@"All" action:@selector(ejectAllDisks:) tag:0];
272			[ejectFloppyMenu addItem:[NSMenuItem separatorItem]];
273			for (driveNumber=0; driveNumber<4; driveNumber++) {
274				[self createMenuItemInMenu:ejectFloppyMenu withTitle:[NSString stringWithFormat:@"DF%d",driveNumber] action:@selector(ejectDisk:) tag:driveNumber];
275			}
276		menuItem = [[NSMenuItem alloc] initWithTitle:@"Eject Floppy" action:nil keyEquivalent:@""];
277		[menuItem setSubmenu:ejectFloppyMenu];
278		[dskMenu addItem:menuItem];
279		[menuItem release];
280
281		[dskMenu addItem:[NSMenuItem separatorItem]];
282
283		NSMenu *hddMenu = [[NSMenu alloc] initWithTitle:@"Mount HDF"];
284		menuItem = [[NSMenuItem alloc] initWithTitle:@"Mount HDF" action:nil keyEquivalent:@""];
285		[menuItem setSubmenu:hddMenu];
286		[dskMenu addItem:menuItem];
287		[menuItem release];
288
289		NSMenu *vhddMenu = [[NSMenu alloc] initWithTitle:@"Mount Folder as HDD"];
290		menuItem = [[NSMenuItem alloc] initWithTitle:@"Mount Folder as HDD" action:nil keyEquivalent:@""];
291		[menuItem setSubmenu:vhddMenu];
292		[dskMenu addItem:menuItem];
293		[menuItem release];
294
295		NSMenu *CDMenu = [[NSMenu alloc] initWithTitle:@"Mount CD Image"];
296		menuItem = [[NSMenuItem alloc] initWithTitle:@"Mount CD Image" action:nil keyEquivalent:@""];
297		[menuItem setSubmenu:CDMenu];
298		[dskMenu addItem:menuItem];
299		[menuItem release];
300
301		NSMenu *CDEMenu = [[NSMenu alloc] initWithTitle:@"Eject CD Image"];
302		menuItem = [[NSMenuItem alloc] initWithTitle:@"Eject CD Image" action:nil keyEquivalent:@""];
303		[menuItem setSubmenu:CDEMenu];
304		[dskMenu addItem:menuItem];
305		[menuItem release];
306
307	menuItem = [[NSMenuItem alloc] initWithTitle:@"Disk" action:nil keyEquivalent:@""];
308	[menuItem setSubmenu:dskMenu];
309	[[NSApp mainMenu] insertItem:menuItem atIndex:2];
310	[dskMenu release];
311	[menuItem release];
312	// DISK MENU END
313
314	// MEM MENU START
315	NSMenu *memMenu = [[NSMenu alloc] initWithTitle:@"Memory"];
316
317		NSMenu *chipMenu = [[NSMenu alloc] initWithTitle:@"Chip Mem"];
318			[self createMenuItemInMenu:chipMenu withTitle:@"256 KB" action:@selector(changeChipMem:) tag:1];
319			[self createMenuItemInMenu:chipMenu withTitle:@"512 KB" action:@selector(changeChipMem:) tag:2];
320			[self createMenuItemInMenu:chipMenu withTitle:@"1 MB" action:@selector(changeChipMem:) tag:3];
321			[self createMenuItemInMenu:chipMenu withTitle:@"1.5 MB" action:@selector(changeChipMem:) tag:14];
322			[self createMenuItemInMenu:chipMenu withTitle:@"2 MB" action:@selector(changeChipMem:) tag:4];
323			[self createMenuItemInMenu:chipMenu withTitle:@"4 MB" action:@selector(changeChipMem:) tag:5];
324			[self createMenuItemInMenu:chipMenu withTitle:@"8 MB" action:@selector(changeChipMem:) tag:6];
325		menuItem = [[NSMenuItem alloc] initWithTitle:@"Chip Mem" action:nil keyEquivalent:@""];
326		[menuItem setSubmenu:chipMenu];
327		[memMenu addItem:menuItem];
328		[menuItem release];
329
330		NSMenu *bogoMenu = [[NSMenu alloc] initWithTitle:@"Slow Mem"];
331			[self createMenuItemInMenu:bogoMenu withTitle:@"None" action:@selector(changeBogoMem:) tag:0];
332			[self createMenuItemInMenu:bogoMenu withTitle:@"512 KB" action:@selector(changeBogoMem:) tag:2];
333			[self createMenuItemInMenu:bogoMenu withTitle:@"1 MB" action:@selector(changeBogoMem:) tag:3];
334			[self createMenuItemInMenu:bogoMenu withTitle:@"1.5 MB" action:@selector(changeBogoMem:) tag:14];
335			[self createMenuItemInMenu:bogoMenu withTitle:@"1.8 MB" action:@selector(changeBogoMem:) tag:15];
336		menuItem = [[NSMenuItem alloc] initWithTitle:@"Slow Mem" action:nil keyEquivalent:@""];
337		[menuItem setSubmenu:bogoMenu];
338		[memMenu addItem:menuItem];
339		[menuItem release];
340
341		NSMenu *fastMenu = [[NSMenu alloc] initWithTitle:@"Fast Mem"];
342			[self createMenuItemInMenu:fastMenu withTitle:@"None" action:@selector(changeFastMem:) tag:0];
343			[self createMenuItemInMenu:fastMenu withTitle:@"1 MB" action:@selector(changeFastMem:) tag:3];
344			[self createMenuItemInMenu:fastMenu withTitle:@"2 MB" action:@selector(changeFastMem:) tag:4];
345			[self createMenuItemInMenu:fastMenu withTitle:@"4 MB" action:@selector(changeFastMem:) tag:5];
346			[self createMenuItemInMenu:fastMenu withTitle:@"8 MB" action:@selector(changeFastMem:) tag:6];
347		menuItem = [[NSMenuItem alloc] initWithTitle:@"Fast Mem" action:nil keyEquivalent:@""];
348		[menuItem setSubmenu:fastMenu];
349		[memMenu addItem:menuItem];
350		[menuItem release];
351
352		NSMenu *z3fastMenu = [[NSMenu alloc] initWithTitle:@"Z3 Fast Mem"];
353			[self createMenuItemInMenu:z3fastMenu withTitle:@"None" action:@selector(changeZ3FastMem:) tag:0];
354			[self createMenuItemInMenu:z3fastMenu withTitle:@"1 MB" action:@selector(changeZ3FastMem:) tag:3];
355			[self createMenuItemInMenu:z3fastMenu withTitle:@"2 MB" action:@selector(changeZ3FastMem:) tag:4];
356			[self createMenuItemInMenu:z3fastMenu withTitle:@"4 MB" action:@selector(changeZ3FastMem:) tag:5];
357			[self createMenuItemInMenu:z3fastMenu withTitle:@"8 MB" action:@selector(changeZ3FastMem:) tag:6];
358			[self createMenuItemInMenu:z3fastMenu withTitle:@"16 MB" action:@selector(changeZ3FastMem:) tag:7];
359			[self createMenuItemInMenu:z3fastMenu withTitle:@"32 MB" action:@selector(changeZ3FastMem:) tag:8];
360			[self createMenuItemInMenu:z3fastMenu withTitle:@"64 MB" action:@selector(changeZ3FastMem:) tag:9];
361			[self createMenuItemInMenu:z3fastMenu withTitle:@"128 MB" action:@selector(changeZ3FastMem:) tag:10];
362			[self createMenuItemInMenu:z3fastMenu withTitle:@"256 MB" action:@selector(changeZ3FastMem:) tag:11];
363			[self createMenuItemInMenu:z3fastMenu withTitle:@"384 MB" action:@selector(changeZ3FastMem:) tag:17];
364			[self createMenuItemInMenu:z3fastMenu withTitle:@"512 MB" action:@selector(changeZ3FastMem:) tag:12];
365			[self createMenuItemInMenu:z3fastMenu withTitle:@"768 MB" action:@selector(changeZ3FastMem:) tag:18];
366			[self createMenuItemInMenu:z3fastMenu withTitle:@"1 GB" action:@selector(changeZ3FastMem:) tag:13];
367			[self createMenuItemInMenu:z3fastMenu withTitle:@"1.5 GB" action:@selector(changeZ3FastMem:) tag:19];
368			[self createMenuItemInMenu:z3fastMenu withTitle:@"2 GB" action:@selector(changeZ3FastMem:) tag:16];
369			[self createMenuItemInMenu:z3fastMenu withTitle:@"2.5 GB" action:@selector(changeZ3FastMem:) tag:20];
370			[self createMenuItemInMenu:z3fastMenu withTitle:@"3 GB" action:@selector(changeZ3FastMem:) tag:21];
371		menuItem = [[NSMenuItem alloc] initWithTitle:@"Z3 Fast Mem" action:nil keyEquivalent:@""];
372		[menuItem setSubmenu:z3fastMenu];
373		[memMenu addItem:menuItem];
374		[menuItem release];
375
376		NSMenu *z3chipMenu = [[NSMenu alloc] initWithTitle:@"32bit Chip Mem"];
377			[self createMenuItemInMenu:z3chipMenu withTitle:@"None" action:@selector(changeZ3ChipMem:) tag:0];
378			[self createMenuItemInMenu:z3chipMenu withTitle:@"16 MB" action:@selector(changeZ3ChipMem:) tag:7];
379			[self createMenuItemInMenu:z3chipMenu withTitle:@"32 MB" action:@selector(changeZ3ChipMem:) tag:8];
380			[self createMenuItemInMenu:z3chipMenu withTitle:@"64 MB" action:@selector(changeZ3ChipMem:) tag:9];
381			[self createMenuItemInMenu:z3chipMenu withTitle:@"128 MB" action:@selector(changeZ3ChipMem:) tag:10];
382			[self createMenuItemInMenu:z3chipMenu withTitle:@"256 MB" action:@selector(changeZ3ChipMem:) tag:11];
383			[self createMenuItemInMenu:z3chipMenu withTitle:@"512 MB" action:@selector(changeZ3ChipMem:) tag:12];
384			[self createMenuItemInMenu:z3chipMenu withTitle:@"1 GB" action:@selector(changeZ3ChipMem:) tag:13];
385		menuItem = [[NSMenuItem alloc] initWithTitle:@"32bit Chip Mem" action:nil keyEquivalent:@""];
386		[menuItem setSubmenu:z3chipMenu];
387		[memMenu addItem:menuItem];
388		[menuItem release];
389
390/*		NSMenu *gfxMenu = [[NSMenu alloc] initWithTitle:@"Gfx Mem"];
391			[self createMenuItemInMenu:gfxMenu withTitle:@"None" action:@selector(changeGfxMem:) tag:0];
392			[self createMenuItemInMenu:gfxMenu withTitle:@"1 MB" action:@selector(changeGfxMem:) tag:3];
393			[self createMenuItemInMenu:gfxMenu withTitle:@"2 MB" action:@selector(changeGfxMem:) tag:4];
394			[self createMenuItemInMenu:gfxMenu withTitle:@"4 MB" action:@selector(changeGfxMem:) tag:5];
395			[self createMenuItemInMenu:gfxMenu withTitle:@"8 MB" action:@selector(changeGfxMem:) tag:6];
396			[self createMenuItemInMenu:gfxMenu withTitle:@"16 MB" action:@selector(changeGfxMem:) tag:7];
397			[self createMenuItemInMenu:gfxMenu withTitle:@"32 MB" action:@selector(changeGfxMem:) tag:8];
398			[self createMenuItemInMenu:gfxMenu withTitle:@"64 MB" action:@selector(changeGfxMem:) tag:9];
399			[self createMenuItemInMenu:gfxMenu withTitle:@"128 MB" action:@selector(changeGfxMem:) tag:10];
400			[self createMenuItemInMenu:gfxMenu withTitle:@"256 MB" action:@selector(changeGfxMem:) tag:11];
401			[self createMenuItemInMenu:gfxMenu withTitle:@"512 MB" action:@selector(changeGfxMem:) tag:12];
402			[self createMenuItemInMenu:gfxMenu withTitle:@"1 GB" action:@selector(changeGfxMem:) tag:13];
403		menuItem = [[NSMenuItem alloc] initWithTitle:@"Gfx Mem" action:nil keyEquivalent:@""];
404		[menuItem setSubmenu:gfxMenu];
405		[memMenu addItem:menuItem];
406		[menuItem release];*/
407
408	menuItem = [[NSMenuItem alloc] initWithTitle:@"Memory" action:nil keyEquivalent:@""];
409	[menuItem setSubmenu:memMenu];
410	[[NSApp mainMenu] insertItem:menuItem atIndex:3];
411	[memMenu release];
412	[menuItem release];
413	// MEM MENU END
414
415	// SYSTEM MENU START
416	NSMenu *systemMenu = [[NSMenu alloc] initWithTitle:@"System"];
417
418		NSMenu *cpuMenu = [[NSMenu alloc] initWithTitle:@"CPU"];
419			[self createMenuItemInMenu:cpuMenu withTitle:@"68000" action:@selector(changeCPU:) tag:0];
420			[self createMenuItemInMenu:cpuMenu withTitle:@"68010" action:@selector(changeCPU:) tag:1];
421			[self createMenuItemInMenu:cpuMenu withTitle:@"68020" action:@selector(changeCPU:) tag:2];
422			[self createMenuItemInMenu:cpuMenu withTitle:@"68030" action:@selector(changeCPU:) tag:3];
423			[self createMenuItemInMenu:cpuMenu withTitle:@"68040" action:@selector(changeCPU:) tag:4];
424			[self createMenuItemInMenu:cpuMenu withTitle:@"68060" action:@selector(changeCPU:) tag:6];
425			[cpuMenu addItem:[NSMenuItem separatorItem]];
426			[self createMenuItemInMenu:cpuMenu withTitle:@"24-bit Addressing" action:@selector(changeCPU:) tag:10];
427			[self createMenuItemInMenu:cpuMenu withTitle:@"More Compatible" action:@selector(changeCPU:) tag:11];
428#ifdef MMUEMU
429			[self createMenuItemInMenu:cpuMenu withTitle:@"68040 MMU" action:@selector(changeCPU:) tag:12];
430#endif
431		menuItem = [[NSMenuItem alloc] initWithTitle:@"CPU" action:nil keyEquivalent:@""];
432		[menuItem setSubmenu:cpuMenu];
433		[systemMenu addItem:menuItem];
434		[menuItem release];
435
436		NSMenu *cpuspeedMenu = [[NSMenu alloc] initWithTitle:@"CPU Speed"];
437			[self createMenuItemInMenu:cpuspeedMenu withTitle:@"Fastest Possible but maintain chipset timing" action:@selector(changeCPUSpeed:) tag:0];
438			[self createMenuItemInMenu:cpuspeedMenu withTitle:@"Approximate A500/A1200 Cycle Exact" action:@selector(changeCPUSpeed:) tag:1];
439			[self createMenuItemInMenu:cpuspeedMenu withTitle:@"Cycle Exact" action:@selector(changeCPUSpeed:) tag:2];
440		menuItem = [[NSMenuItem alloc] initWithTitle:@"CPU Speed" action:nil keyEquivalent:@""];
441		[menuItem setSubmenu:cpuspeedMenu];
442		[systemMenu addItem:menuItem];
443		[menuItem release];
444
445		NSMenu *fpuMenu = [[NSMenu alloc] initWithTitle:@"FPU"];
446			[self createMenuItemInMenu:fpuMenu withTitle:@"None" action:@selector(changeFPU:) tag:0];
447			[self createMenuItemInMenu:fpuMenu withTitle:@"68881" action:@selector(changeFPU:) tag:1];
448			[self createMenuItemInMenu:fpuMenu withTitle:@"68882" action:@selector(changeFPU:) tag:2];
449			[self createMenuItemInMenu:fpuMenu withTitle:@"CPU Internal" action:@selector(changeFPU:) tag:3];
450			[fpuMenu addItem:[NSMenuItem separatorItem]];
451			[self createMenuItemInMenu:fpuMenu withTitle:@"More Compatible" action:@selector(changeFPU:) tag:10];
452		menuItem = [[NSMenuItem alloc] initWithTitle:@"FPU" action:nil keyEquivalent:@""];
453		[menuItem setSubmenu:fpuMenu];
454		[systemMenu addItem:menuItem];
455		[menuItem release];
456
457		NSMenu *chipsetMenu = [[NSMenu alloc] initWithTitle:@"Chipset"];
458			[self createMenuItemInMenu:chipsetMenu withTitle:@"OCS" action:@selector(changeChipset:) tag:0];
459			[self createMenuItemInMenu:chipsetMenu withTitle:@"ECS Agnus" action:@selector(changeChipset:) tag:1];
460			[self createMenuItemInMenu:chipsetMenu withTitle:@"ECS Denise" action:@selector(changeChipset:) tag:2];
461			[self createMenuItemInMenu:chipsetMenu withTitle:@"ECS Full" action:@selector(changeChipset:) tag:3];
462			[self createMenuItemInMenu:chipsetMenu withTitle:@"AGA" action:@selector(changeChipset:) tag:4];
463			[chipsetMenu addItem:[NSMenuItem separatorItem]];
464			[self createMenuItemInMenu:chipsetMenu withTitle:@"NTSC" action:@selector(changeChipset:) tag:10];
465		menuItem = [[NSMenuItem alloc] initWithTitle:@"Chipset" action:nil keyEquivalent:@""];
466		[menuItem setSubmenu:chipsetMenu];
467		[systemMenu addItem:menuItem];
468		[menuItem release];
469
470		NSMenu *chipsetXMenu = [[NSMenu alloc] initWithTitle:@"Chipset Extra"];
471			[self createMenuItemInMenu:chipsetXMenu withTitle:@"" action:@selector(changeChipsetX:) tag:0];
472			[self createMenuItemInMenu:chipsetXMenu withTitle:@"Generic" action:@selector(changeChipsetX:) tag:1];
473			[self createMenuItemInMenu:chipsetXMenu withTitle:@"CDTV" action:@selector(changeChipsetX:) tag:2];
474			[self createMenuItemInMenu:chipsetXMenu withTitle:@"CD32" action:@selector(changeChipsetX:) tag:3];
475			[self createMenuItemInMenu:chipsetXMenu withTitle:@"A500" action:@selector(changeChipsetX:) tag:4];
476			[self createMenuItemInMenu:chipsetXMenu withTitle:@"A500+" action:@selector(changeChipsetX:) tag:5];
477			[self createMenuItemInMenu:chipsetXMenu withTitle:@"A600" action:@selector(changeChipsetX:) tag:6];
478			[self createMenuItemInMenu:chipsetXMenu withTitle:@"A1000" action:@selector(changeChipsetX:) tag:7];
479			[self createMenuItemInMenu:chipsetXMenu withTitle:@"A1200" action:@selector(changeChipsetX:) tag:8];
480			[self createMenuItemInMenu:chipsetXMenu withTitle:@"A2000" action:@selector(changeChipsetX:) tag:9];
481			[self createMenuItemInMenu:chipsetXMenu withTitle:@"A3000" action:@selector(changeChipsetX:) tag:10];
482			[self createMenuItemInMenu:chipsetXMenu withTitle:@"A3000T" action:@selector(changeChipsetX:) tag:11];
483			[self createMenuItemInMenu:chipsetXMenu withTitle:@"A4000" action:@selector(changeChipsetX:) tag:12];
484			[self createMenuItemInMenu:chipsetXMenu withTitle:@"A4000T" action:@selector(changeChipsetX:) tag:13];
485		menuItem = [[NSMenuItem alloc] initWithTitle:@"Chipset Extra" action:nil keyEquivalent:@""];
486		[menuItem setSubmenu:chipsetXMenu];
487		[systemMenu addItem:menuItem];
488		[menuItem release];
489
490		NSMenu *monitoremuMenu = [[NSMenu alloc] initWithTitle:@"Monitor"];
491			[self createMenuItemInMenu:monitoremuMenu withTitle:@"-" action:@selector(changeMonitoremu:) tag:0];
492			[self createMenuItemInMenu:monitoremuMenu withTitle:@"default" action:@selector(changeMonitoremu:) tag:1];
493			[self createMenuItemInMenu:monitoremuMenu withTitle:@"A2024" action:@selector(changeMonitoremu:) tag:2];
494			[self createMenuItemInMenu:monitoremuMenu withTitle:@"Graffiti" action:@selector(changeMonitoremu:) tag:3];
495		menuItem = [[NSMenuItem alloc] initWithTitle:@"Monitor" action:nil keyEquivalent:@""];
496		[menuItem setSubmenu:monitoremuMenu];
497		[systemMenu addItem:menuItem];
498		[menuItem release];
499
500		NSMenu *blitterMenu = [[NSMenu alloc] initWithTitle:@"Blitter"];
501			[self createMenuItemInMenu:blitterMenu withTitle:@"Immediate Blits" action:@selector(changeBlitter:) tag:0];
502			[self createMenuItemInMenu:blitterMenu withTitle:@"Cycle-exact Blitter" action:@selector(changeBlitter:) tag:1];
503		menuItem = [[NSMenuItem alloc] initWithTitle:@"Blitter" action:nil keyEquivalent:@""];
504		[menuItem setSubmenu:blitterMenu];
505		[systemMenu addItem:menuItem];
506		[menuItem release];
507
508		NSMenu *collisionMenu = [[NSMenu alloc] initWithTitle:@"Collision Level"];
509			[self createMenuItemInMenu:collisionMenu withTitle:@"None" action:@selector(changeCollision:) tag:0];
510			[self createMenuItemInMenu:collisionMenu withTitle:@"Sprites Only" action:@selector(changeCollision:) tag:1];
511			[self createMenuItemInMenu:collisionMenu withTitle:@"Sprites and Sprites vs. Playfield" action:@selector(changeCollision:) tag:2];
512			[self createMenuItemInMenu:collisionMenu withTitle:@"Full" action:@selector(changeCollision:) tag:3];
513		menuItem = [[NSMenuItem alloc] initWithTitle:@"Collision Level" action:nil keyEquivalent:@""];
514		[menuItem setSubmenu:collisionMenu];
515		[systemMenu addItem:menuItem];
516		[menuItem release];
517
518	menuItem = [[NSMenuItem alloc] initWithTitle:@"System" action:nil keyEquivalent:@""];
519	[menuItem setSubmenu:systemMenu];
520	[[NSApp mainMenu] insertItem:menuItem atIndex:4];
521	[systemMenu release];
522	[menuItem release];
523	// SYSTEM MENU END
524
525	// SOUND MENU START
526	NSMenu *soundMenu = [[NSMenu alloc] initWithTitle:@"Sound"];
527
528		NSMenu *semuMenu = [[NSMenu alloc] initWithTitle:@"Emulation"];
529			[self createMenuItemInMenu:semuMenu withTitle:@"Disabled" action:@selector(changeSound:) tag:0];
530			[self createMenuItemInMenu:semuMenu withTitle:@"Disabled, but emulated" action:@selector(changeSound:) tag:1];
531			[self createMenuItemInMenu:semuMenu withTitle:@"Enabled" action:@selector(changeSound:) tag:2];
532		menuItem = [[NSMenuItem alloc] initWithTitle:@"Emulation" action:nil keyEquivalent:@""];
533		[menuItem setSubmenu:semuMenu];
534		[soundMenu addItem:menuItem];
535		[menuItem release];
536
537		NSMenu *sfilterMenu = [[NSMenu alloc] initWithTitle:@"Filter"];
538			[self createMenuItemInMenu:sfilterMenu withTitle:@"Always Off" action:@selector(changeSoundFilter:) tag:0];
539			[self createMenuItemInMenu:sfilterMenu withTitle:@"Emulated (A500)" action:@selector(changeSoundFilter:) tag:1];
540			[self createMenuItemInMenu:sfilterMenu withTitle:@"Emulated (A1200)" action:@selector(changeSoundFilter:) tag:2];
541			[self createMenuItemInMenu:sfilterMenu withTitle:@"Always On (A500)" action:@selector(changeSoundFilter:) tag:3];
542			[self createMenuItemInMenu:sfilterMenu withTitle:@"Always On (A1200)" action:@selector(changeSoundFilter:) tag:4];
543		menuItem = [[NSMenuItem alloc] initWithTitle:@"Filter" action:nil keyEquivalent:@""];
544		[menuItem setSubmenu:sfilterMenu];
545		[soundMenu addItem:menuItem];
546		[menuItem release];
547
548		NSMenu *sinterMenu = [[NSMenu alloc] initWithTitle:@"Interpolation"];
549			[self createMenuItemInMenu:sinterMenu withTitle:@"" action:@selector(changeSoundInterpolation:) tag:0];
550			[self createMenuItemInMenu:sinterMenu withTitle:@"Anti" action:@selector(changeSoundInterpolation:) tag:1];
551			[self createMenuItemInMenu:sinterMenu withTitle:@"Sinc" action:@selector(changeSoundInterpolation:) tag:2];
552			[self createMenuItemInMenu:sinterMenu withTitle:@"RH" action:@selector(changeSoundInterpolation:) tag:3];
553			[self createMenuItemInMenu:sinterMenu withTitle:@"Crux" action:@selector(changeSoundInterpolation:) tag:4];
554		menuItem = [[NSMenuItem alloc] initWithTitle:@"Interpolation" action:nil keyEquivalent:@""];
555		[menuItem setSubmenu:sinterMenu];
556		[soundMenu addItem:menuItem];
557		[menuItem release];
558
559	menuItem = [[NSMenuItem alloc] initWithTitle:@"Sound" action:nil keyEquivalent:@""];
560	[menuItem setSubmenu:soundMenu];
561	[[NSApp mainMenu] insertItem:menuItem atIndex:5];
562	[soundMenu release];
563	[menuItem release];
564	// SOUND MENU END
565
566	// GFX MENU START
567	NSMenu *graphicsMenu = [[NSMenu alloc] initWithTitle:@"Graphics"];
568
569		NSMenu *lmodeMenu = [[NSMenu alloc] initWithTitle:@"Line Mode"];
570			[self createMenuItemInMenu:lmodeMenu withTitle:@"Normal" action:@selector(changeGfxLineMode:) tag:0];
571			[self createMenuItemInMenu:lmodeMenu withTitle:@"Double" action:@selector(changeGfxLineMode:) tag:1];
572			[self createMenuItemInMenu:lmodeMenu withTitle:@"Scanlines" action:@selector(changeGfxLineMode:) tag:2];
573		menuItem = [[NSMenuItem alloc] initWithTitle:@"Line Mode" action:nil keyEquivalent:@""];
574		[menuItem setSubmenu:lmodeMenu];
575		[graphicsMenu addItem:menuItem];
576		[menuItem release];
577
578		NSMenu *centeringMenu = [[NSMenu alloc] initWithTitle:@"Centering"];
579			[self createMenuItemInMenu:centeringMenu withTitle:@"Horizontal" action:@selector(changeGfxCentering:) tag:0];
580			[self createMenuItemInMenu:centeringMenu withTitle:@"Vertical" action:@selector(changeGfxCentering:) tag:1];
581		menuItem = [[NSMenuItem alloc] initWithTitle:@"Centering" action:nil keyEquivalent:@""];
582		[menuItem setSubmenu:centeringMenu];
583		[graphicsMenu addItem:menuItem];
584		[menuItem release];
585
586	menuItem = [[NSMenuItem alloc] initWithTitle:@"Graphics" action:nil keyEquivalent:@""];
587	[menuItem setSubmenu:graphicsMenu];
588	[[NSApp mainMenu] insertItem:menuItem atIndex:6];
589	[graphicsMenu release];
590	[menuItem release];
591	// GFX MENU END
592
593	// Create a menu for changing aspects of emulator control
594	NSMenu *controlMenu = [[NSMenu alloc] initWithTitle:@"Control"];
595
596		NSMenu *portMenu = [[NSMenu alloc] initWithTitle:@"Game Port 0"];
597			[self createMenuItemInMenu:portMenu withTitle:@"None" action:@selector(changePort0:) tag:JSEM_END];
598			[self createMenuItemInMenu:portMenu withTitle:@"Joystick 0" action:@selector(changePort0:) tag:JSEM_JOYS];
599			[self createMenuItemInMenu:portMenu withTitle:@"Joystick 1" action:@selector(changePort0:) tag:JSEM_JOYS+1];
600			[self createMenuItemInMenu:portMenu withTitle:@"Mouse" action:@selector(changePort0:) tag:JSEM_MICE];
601			[self createMenuItemInMenu:portMenu withTitle:@"Keyboard Layout A (NumPad, 0 & 5 = Fire)" action:@selector(changePort0:) tag:JSEM_KBDLAYOUT];
602			[self createMenuItemInMenu:portMenu withTitle:@"Keyboard Layout B (Cursor, RCtrl & Alt = Fire)" action:@selector(changePort0:) tag:JSEM_KBDLAYOUT+1];
603			[self createMenuItemInMenu:portMenu withTitle:@"Keyboard Layout C (WASD, LAlt = Fire)" action:@selector(changePort0:) tag:JSEM_KBDLAYOUT+2];
604#ifdef ARCADE
605			[self createMenuItemInMenu:portMenu withTitle:@"X-Arcade (Left)" action:@selector(changePort0:) tag:JSEM_KBDLAYOUT+3];
606			[self createMenuItemInMenu:portMenu withTitle:@"X-Arcade (Right)" action:@selector(changePort0:) tag:JSEM_KBDLAYOUT+4];
607#endif
608		menuItem = [[NSMenuItem alloc] initWithTitle:@"Game Port 0" action:nil keyEquivalent:@""];
609		[menuItem setSubmenu:portMenu];
610		[controlMenu addItem:menuItem];
611		[menuItem release];
612		[portMenu release];
613
614		portMenu = [[NSMenu alloc] initWithTitle:@"Game Port 1"];
615			[self createMenuItemInMenu:portMenu withTitle:@"None" action:@selector(changePort1:) tag:JSEM_END];
616			[self createMenuItemInMenu:portMenu withTitle:@"Joystick 0" action:@selector(changePort1:) tag:JSEM_JOYS];
617			[self createMenuItemInMenu:portMenu withTitle:@"Joystick 1" action:@selector(changePort1:) tag:JSEM_JOYS+1];
618			[self createMenuItemInMenu:portMenu withTitle:@"Mouse" action:@selector(changePort1:) tag:JSEM_MICE];
619			[self createMenuItemInMenu:portMenu withTitle:@"Keyboard Layout A (NumPad, 0 & 5 = Fire)" action:@selector(changePort1:) tag:JSEM_KBDLAYOUT];
620			[self createMenuItemInMenu:portMenu withTitle:@"Keyboard Layout B (Cursor, RCtrl & Alt = Fire)" action:@selector(changePort1:) tag:JSEM_KBDLAYOUT+1];
621			[self createMenuItemInMenu:portMenu withTitle:@"Keyboard Layout C (WASD, LAlt = Fire)" action:@selector(changePort1:) tag:JSEM_KBDLAYOUT+2];
622#ifdef ARCADE
623			[self createMenuItemInMenu:portMenu withTitle:@"X-Arcade (Left)" action:@selector(changePort1:) tag:JSEM_KBDLAYOUT+3];
624			[self createMenuItemInMenu:portMenu withTitle:@"X-Arcade (Right)" action:@selector(changePort1:) tag:JSEM_KBDLAYOUT+4];
625#endif
626		menuItem = [[NSMenuItem alloc] initWithTitle:@"Game Port 1" action:nil keyEquivalent:@""];
627		[menuItem setSubmenu:portMenu];
628		[controlMenu addItem:menuItem];
629		[menuItem release];
630		[portMenu release];
631
632	[self createMenuItemInMenu:controlMenu withTitle:@"Swap Port 0 and 1" action:@selector(swapGamePorts:) tag:0];
633
634	[controlMenu addItem:[NSMenuItem separatorItem]];
635
636	[self createMenuItemInMenu:controlMenu withTitle:@"Grab Mouse" action:@selector(grabMouse:) tag:0  keyEquivalent:@"g" keyEquivalentMask:NSCommandKeyMask|NSAlternateKeyMask];
637
638	menuItem = [[NSMenuItem alloc] initWithTitle:@"Control" action:nil keyEquivalent:@""];
639	[menuItem setSubmenu:controlMenu];
640	[[NSApp mainMenu] insertItem:menuItem atIndex:7];
641	[controlMenu release];
642	[menuItem release];
643
644	// Create a menu for changing aspects of emulator control
645	NSMenu *displayMenu = [[NSMenu alloc] initWithTitle:@"Display"];
646		[self createMenuItemInMenu:displayMenu withTitle:@"Fullscreen" action:@selector(goFullscreen:) tag:0  keyEquivalent:@"s" keyEquivalentMask:NSCommandKeyMask|NSAlternateKeyMask];
647		[self createMenuItemInMenu:displayMenu withTitle:@"Inhibit" action:@selector(toggleInhibitDisplay:) tag:0];
648	menuItem = [[NSMenuItem alloc] initWithTitle:@"Display" action:nil keyEquivalent:@""];
649	[menuItem setSubmenu:displayMenu];
650	[[NSApp mainMenu] insertItem:menuItem atIndex:8];
651	[displayMenu release];
652	[menuItem release];
653}
654
655- (void)createMenuItemInMenu:(NSMenu *)menu withTitle:(NSString *)title action:(SEL)anAction tag:(int)tag
656{
657	[self createMenuItemInMenu:menu withTitle:title action:anAction tag:tag keyEquivalent:@"" keyEquivalentMask:NSCommandKeyMask];
658}
659
660- (void)createMenuItemInMenu:(NSMenu *)menu withTitle:(NSString *)title action:(SEL)anAction tag:(int)tag keyEquivalent:(NSString *)keyEquiv keyEquivalentMask:(NSUInteger)mask
661{
662	NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:title action:anAction keyEquivalent:keyEquiv];
663	[menuItem setKeyEquivalentModifierMask:mask];
664	[menuItem setTag:tag];
665	[menuItem setTarget:self];
666	[menu addItem:menuItem];
667	[menuItem release];
668}
669
670- (BOOL)validateMenuItem:(id <NSMenuItem>)item
671{
672	NSMenuItem *menuItem = (NSMenuItem *)item;
673	BOOL canSetHidden = [menuItem respondsToSelector:@selector(setHidden:)];
674
675	SEL menuAction = [menuItem action];
676	int tag = [menuItem tag];
677
678	if (menuAction == @selector(LedsOnScreen:)) {
679		if (tag == 2) {
680			if (changed_prefs.leds_on_screen) [menuItem setState:NSOnState];
681			else [menuItem setState:NSOffState];
682		}
683	}
684
685	// Disabled drives can't have disks inserted or ejected
686	if ((menuAction == @selector(insertDisk:)) || (menuAction == @selector(ejectDisk:))) {
687		if (gui_data.drive_disabled[tag]) {
688			//if (canSetHidden) [menuItem setHidden:YES];
689			return NO;
690		} else {
691			//if (canSetHidden) [menuItem setHidden:NO];
692		}
693	}
694
695	// Eject DFx should be disabled if there's no disk in DFx
696	if (menuAction == @selector(ejectDisk:)) {
697		if (disk_empty(tag)) {
698			[menuItem setTitle:[NSString stringWithFormat:@"DF%d",tag]];
699			return NO;
700		}
701
702		// There's a disk in the drive, show its name in the menu item
703		NSString *diskImage = [[NSString stringWithCString:gui_data.df[tag] encoding:NSASCIIStringEncoding] lastPathComponent];
704		[menuItem setTitle:[NSString stringWithFormat:@"DF%d (%@)",tag,diskImage]];
705		return YES;
706	}
707
708	// The current settings for the joystick/mouse ports should be indicated
709	if (menuAction == @selector(changePort0:)) {
710		if (currprefs.jports[0].id == tag) [menuItem setState:NSOnState];
711		else [menuItem setState:NSOffState];
712
713		// and joystick options should be unavailable if there are no joysticks
714		if (((tag == JSEM_JOYS) || (tag == (JSEM_JOYS+1)))) {
715			if ((tag - JSEM_JOYS) >= inputdevice_get_device_total (IDTYPE_JOYSTICK))
716				return NO;
717		}
718
719		// and we should not allow both ports to be set to the same setting
720		if ((tag != JSEM_END) && (currprefs.jports[1].id == tag))
721			return NO;
722
723		return YES;
724	}
725
726	// Repeat the above for Port 1
727	if (menuAction == @selector(changePort1:)) {
728		if (currprefs.jports[1].id == tag) [menuItem setState:NSOnState];
729		else [menuItem setState:NSOffState];
730
731		if (((tag == JSEM_JOYS) || (tag == (JSEM_JOYS+1)))) {
732			if ((tag - JSEM_JOYS) >= inputdevice_get_device_total (IDTYPE_JOYSTICK))
733				return NO;
734		}
735
736		if ((tag != JSEM_END) && (currprefs.jports[0].id == tag))
737			return NO;
738
739		return YES;
740	}
741
742	long mem_size, v;
743	if (menuAction == @selector(changeChipMem:)) {
744		mem_size = 0;
745	        switch (changed_prefs.chipmem_size) {
746		        case 0x00040000: mem_size = 1; break;
747		        case 0x00080000: mem_size = 2; break;
748		        case 0x00100000: mem_size = 3; break;
749		        case 0x00180000: mem_size = 14; break;
750		        case 0x00200000: mem_size = 4; break;
751		        case 0x00400000: mem_size = 5; break;
752		        case 0x00800000: mem_size = 6; break;
753        	}
754		if (mem_size == tag) [menuItem setState:NSOnState];
755		else [menuItem setState:NSOffState];
756	}
757
758	if (menuAction == @selector(changeBogoMem:)) {
759		mem_size = 0;
760	        switch (changed_prefs.bogomem_size) {
761		        case 0x00000000: mem_size = 0; break;
762        		case 0x00080000: mem_size = 2; break;
763	        	case 0x00100000: mem_size = 3; break;
764        		case 0x00180000: mem_size = 14; break;
765		        case 0x001C0000: mem_size = 15; break;
766	        }
767		if (mem_size == tag) [menuItem setState:NSOnState];
768		else [menuItem setState:NSOffState];
769	}
770
771	if (menuAction == @selector(changeFastMem:)) {
772	        if (changed_prefs.chipmem_size > 0x200000) return NO;
773
774		mem_size = 0;
775        	switch (changed_prefs.fastmem_size) {
776		        case 0x00000000: mem_size = 0; break;
777		        case 0x00100000: mem_size = 3; break;
778	        	case 0x00200000: mem_size = 4; break;
779		        case 0x00400000: mem_size = 5; break;
780		        case 0x00800000: mem_size = 6; break;
781	        }
782		if (mem_size == tag) [menuItem setState:NSOnState];
783		else [menuItem setState:NSOffState];
784
785		return YES;
786	}
787
788	if (menuAction == @selector(changeZ3FastMem:)) {
789		if (changed_prefs.address_space_24) return NO;
790
791		mem_size = 0;
792        	v = changed_prefs.z3fastmem_size + changed_prefs.z3fastmem2_size;
793	        if      (v < 0x00100000)
794        	        mem_size = 0;
795	        else if (v < 0x00200000)
796        	        mem_size = 3;
797	        else if (v < 0x00400000)
798        	        mem_size = 4;
799	        else if (v < 0x00800000)
800        	        mem_size = 5;
801	        else if (v < 0x01000000)
802        	        mem_size = 6;
803	        else if (v < 0x02000000)
804        	        mem_size = 7;
805	        else if (v < 0x04000000)
806        	        mem_size = 8;
807	        else if (v < 0x08000000)
808        	        mem_size = 9;
809	        else if (v < 0x10000000)
810        	        mem_size = 10;
811	        else if (v < 0x18000000)
812        	        mem_size = 11;
813	        else if (v < 0x20000000)
814        	        mem_size = 17;
815	        else if (v < 0x30000000)
816        	        mem_size = 12;
817	        else if (v < 0x40000000) // 1GB
818        	        mem_size = 18;
819	        else if (v < 0x60000000) // 1.5GB
820        	        mem_size = 13;
821	        else if (v < 0x80000000) // 2GB
822        	        mem_size = 19;
823	        else if (v < 0xA8000000) // 2.5GB
824        	        mem_size = 16;
825	        else if (v < 0xC0000000) // 3GB
826                	mem_size = 20;
827        	else
828	                mem_size = 21;
829
830		if (mem_size == tag) [menuItem setState:NSOnState];
831		else [menuItem setState:NSOffState];
832
833		return YES;
834	}
835
836	if (menuAction == @selector(changeZ3ChipMem:)) {
837		if (changed_prefs.address_space_24) return NO;
838
839		mem_size = 0;
840        	v = changed_prefs.z3chipmem_size;
841	        if (v < 0x01000000)
842        	        mem_size = 0;
843	        else if (v < 0x02000000)
844        	        mem_size = 7;
845	        else if (v < 0x04000000)
846        	        mem_size = 8;
847	        else if (v < 0x08000000)
848        	        mem_size = 9;
849	        else if (v < 0x10000000)
850        	        mem_size = 10;
851	        else if (v < 0x20000000)
852        	        mem_size = 11;
853	        else if (v < 0x40000000)
854                	mem_size = 12;
855        	else
856	                mem_size = 13;
857
858		if (mem_size == tag) [menuItem setState:NSOnState];
859		else [menuItem setState:NSOffState];
860
861		return YES;
862	}
863/*
864	if (menuAction == @selector(changeGfxMem:)) {
865	        mem_size = 0;
866	        switch (changed_prefs.rtgmem_size) {
867        		case 0x00000000: mem_size = 0; break;
868	        	case 0x00100000: mem_size = 3; break;
869		        case 0x00200000: mem_size = 4; break;
870        		case 0x00400000: mem_size = 5; break;
871	        	case 0x00800000: mem_size = 6; break;
872	        	case 0x01000000: mem_size = 7; break;
873		        case 0x02000000: mem_size = 8; break;
874        		case 0x04000000: mem_size = 9; break;
875	        	case 0x08000000: mem_size = 10; break;
876		        case 0x10000000: mem_size = 11; break;
877	        	case 0x20000000: mem_size = 12; break;
878	        	case 0x40000000: mem_size = 13; break;
879	        }
880		if (mem_size == tag) [menuItem setState:NSOnState];
881		else [menuItem setState:NSOffState];
882	}
883*/
884	if (menuAction == @selector(changeChipset:)) {
885		v = 0;
886        	switch (changed_prefs.chipset_mask) {
887		        case 0: v = 0; break;
888        		case 1: v = 1; break;
889	        	case 2: v = 2; break;
890        		case 3: v = 3; break;
891		        case 4: v = 4; break;
892        		case 7: v = 4; break;
893	        }
894		if (v == tag) [menuItem setState:NSOnState];
895		else [menuItem setState:NSOffState];
896
897		if (tag == 10) {
898			if (changed_prefs.ntscmode) [menuItem setState:NSOnState];
899			else [menuItem setState:NSOffState];
900		}
901	}
902
903	if (menuAction == @selector(changeChipsetX:)) {
904		if (changed_prefs.cs_compatible == tag) [menuItem setState:NSOnState];
905		else [menuItem setState:NSOffState];
906	}
907
908	if (menuAction == @selector(changeCPU:)) {
909		v = (changed_prefs.cpu_model - 68000) / 10;
910		if (v == tag) [menuItem setState:NSOnState];
911		else [menuItem setState:NSOffState];
912
913		if (tag == 10) {
914			if (changed_prefs.cpu_model != 68020) return NO;
915			if (changed_prefs.address_space_24) [menuItem setState:NSOnState];
916			else [menuItem setState:NSOffState];
917		}
918		if (tag == 11) {
919			if (changed_prefs.cpu_compatible) [menuItem setState:NSOnState];
920			else [menuItem setState:NSOffState];
921		}
922#ifdef MMUEMU
923		if (tag == 12) {
924			if (changed_prefs.mmu_model) [menuItem setState:NSOnState];
925			else [menuItem setState:NSOffState];
926		}
927#endif
928		return YES;
929	}
930
931	if (menuAction == @selector(changeCPUSpeed:)) {
932		if (changed_prefs.cpu_cycle_exact == 1) {
933			v = 2;
934		} else {
935			if (changed_prefs.m68k_speed == -1) v = 0;
936			if (changed_prefs.m68k_speed == 0) v = 1;
937		}
938		if (v == tag) [menuItem setState:NSOnState];
939		else [menuItem setState:NSOffState];
940	}
941
942	if (menuAction == @selector(changeFPU:)) {
943		v = changed_prefs.fpu_model == 0 ? 0 : (changed_prefs.fpu_model == 68881 ? 1 : (changed_prefs.fpu_model == 68882 ? 2 : 3));
944		if (v == tag) [menuItem setState:NSOnState];
945		else [menuItem setState:NSOffState];
946
947#ifdef JIT
948		if (tag == 10) {
949			if (changed_prefs.fpu_strict) [menuItem setState:NSOnState];
950			else [menuItem setState:NSOffState];
951		}
952#endif
953
954		if (changed_prefs.cpu_model > 68030 || changed_prefs.cpu_compatible || changed_prefs.cpu_cycle_exact) {
955			if (tag < 3) return NO;
956		}
957		if (tag == 3) {
958			if (!changed_prefs.cpu_model >= 68040) {
959				return NO;
960			}
961		}
962		return YES;
963	}
964
965	if (menuAction == @selector(changeMonitoremu:)) {
966		if (changed_prefs.monitoremu == tag) [menuItem setState:NSOnState];
967		else [menuItem setState:NSOffState];
968	}
969
970	if (menuAction == @selector(changeBlitter:)) {
971		if (tag == 0) {
972			if (changed_prefs.immediate_blits) [menuItem setState:NSOnState];
973			else [menuItem setState:NSOffState];
974		}
975		if (tag == 1) {
976			if (changed_prefs.blitter_cycle_exact) [menuItem setState:NSOnState];
977			else [menuItem setState:NSOffState];
978		}
979	}
980
981	if (menuAction == @selector(changeCollision:)) {
982		if (changed_prefs.collision_level == tag) [menuItem setState:NSOnState];
983		else [menuItem setState:NSOffState];
984	}
985
986	if (menuAction == @selector(changeSound:)) {
987		v = changed_prefs.produce_sound;
988		if (v == 3) v = 2;
989		if (v == tag) [menuItem setState:NSOnState];
990		else [menuItem setState:NSOffState];
991	}
992
993	if (menuAction == @selector(changeSoundInterpolation:)) {
994		if (changed_prefs.sound_interpol == tag) [menuItem setState:NSOnState];
995		else [menuItem setState:NSOffState];
996	}
997
998	if (menuAction == @selector(changeSoundFilter:)) {
999        	v = 0;
1000		switch (changed_prefs.sound_filter) {
1001		case 0:
1002			v = 0;
1003			break;
1004		case 1:
1005			v = changed_prefs.sound_filter_type ? 2 : 1;
1006			break;
1007		case 2:
1008			v = changed_prefs.sound_filter_type ? 4 : 3;
1009			break;
1010		}
1011
1012		if (v == tag) [menuItem setState:NSOnState];
1013		else [menuItem setState:NSOffState];
1014	}
1015
1016	if (menuAction == @selector(changeGfxLineMode:)) {
1017		v = changed_prefs.gfx_scanlines;
1018		if (v == tag) [menuItem setState:NSOnState];
1019		else [menuItem setState:NSOffState];
1020	}
1021
1022	if (menuAction == @selector(changeGfxCentering:)) {
1023		if (tag == 0) {
1024			if (changed_prefs.gfx_xcenter) [menuItem setState:NSOnState];
1025			else [menuItem setState:NSOffState];
1026		}
1027		if (tag == 1) {
1028			if (changed_prefs.gfx_ycenter) [menuItem setState:NSOnState];
1029			else [menuItem setState:NSOffState];
1030		}
1031	}
1032
1033	if (menuAction == @selector(pauseAmiga:)) {
1034		if (pause_emulation)
1035			[menuItem setTitle:@"Resume"];
1036		else
1037			[menuItem setTitle:@"Pause"];
1038
1039		return YES;
1040	}
1041
1042	if (menuAction == @selector(toggleInhibitDisplay:)) {
1043		if (inhibit_frame) [menuItem setState:NSOnState];
1044		else [menuItem setState:NSOffState];
1045	}
1046
1047	if (menuAction == @selector(actionReplayFreeze:))
1048		return ( (hrtmon_flag == ACTION_REPLAY_IDLE) || (action_replay_flag == ACTION_REPLAY_IDLE) );
1049
1050	return YES;
1051}
1052
1053// Invoked when the user selects one of the 'Insert DFx:' menu items
1054- (void)insertDisk:(id)sender
1055{
1056	[self displayOpenPanelForInsertIntoDriveNumber:[((NSMenuItem*)sender) tag]];
1057}
1058
1059// Invoked when the user selects one of the 'Eject DFx:' menu items
1060- (void)ejectDisk:(id)sender
1061{
1062	disk_eject([((NSMenuItem*)sender) tag]);
1063}
1064
1065// Invoked when the user selects "Eject All Disks"
1066- (void)ejectAllDisks:(id)sender
1067{
1068	unsigned int i;
1069	for (i=0; i<4; i++)
1070		if ((!gui_data.drive_disabled[i]) && (!disk_empty(i)))
1071			disk_eject(i);
1072}
1073
1074// Invoked when the user selects an option from the 'Port 0' menu
1075- (void)changePort0:(id)sender
1076{
1077	changed_prefs.jports[0].id = [((NSMenuItem*)sender) tag];
1078
1079	if (changed_prefs.jports[0].id != currprefs.jports[0].id) {
1080		inputdevice_updateconfig (&changed_prefs, &currprefs);
1081		inputdevice_config_change();
1082	}
1083}
1084
1085// Invoked when the user selects an option from the 'Port 1' menu
1086- (void)changePort1:(id)sender
1087{
1088	changed_prefs.jports[1].id = [((NSMenuItem*)sender) tag];
1089
1090	if (changed_prefs.jports[1].id != currprefs.jports[1].id) {
1091		inputdevice_updateconfig (&changed_prefs, &currprefs);
1092		inputdevice_config_change();
1093	}
1094}
1095
1096- (void)swapGamePorts:(id)sender
1097{
1098	changed_prefs.jports[0].id = currprefs.jports[1].id;
1099	changed_prefs.jports[1].id = currprefs.jports[0].id;
1100	inputdevice_updateconfig (&changed_prefs, &currprefs);
1101	inputdevice_config_change();
1102}
1103
1104- (void)displayOpenPanelForInsertIntoDriveNumber:(int)driveNumber
1105{
1106    ensureNotFullscreen();
1107
1108    NSOpenPanel *oPanel = [NSOpenPanel openPanel];
1109    [oPanel setTitle:[NSString stringWithFormat:@"%@: Insert Disk Image",applicationName]];
1110
1111    // Make sure setMessage (OS X 10.3+) is available before calling it
1112    if ([oPanel respondsToSelector:@selector(setMessage:)])
1113        [oPanel setMessage:[NSString stringWithFormat:@"Select a Disk Image for DF%d:", driveNumber]];
1114
1115    [oPanel setPrompt:@"Choose"];
1116    NSString *contextInfo = [[NSString alloc] initWithFormat:@"%d",driveNumber];
1117
1118	// Recall the path of the disk image that was loaded last time
1119	NSString *nsfloppypath = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastUsedDiskImagePath"];
1120
1121	/* If the configuration includes a setting for the "floppy_path" attribute
1122	 * start the OpenPanel in that directory.. but only the first time. */
1123	static int run_once = 0;
1124	if (!run_once) {
1125		run_once++;
1126
1127		const char *floppy_path = currprefs.path_floppy.path[driveNumber];
1128
1129		if (floppy_path != NULL) {
1130			char homedir[MAX_PATH];
1131			snprintf(homedir, MAX_PATH, "%s/", getenv("HOME"));
1132
1133			/* The default value for floppy_path is "$HOME/". We only want to use it if the
1134			 * user provided an actual value though, so we don't use it if it equals "$HOME/" */
1135			if (strncmp(floppy_path, homedir, MAX_PATH) != 0)
1136				nsfloppypath = [NSString stringWithCString:floppy_path encoding:NSASCIIStringEncoding];
1137		}
1138	}
1139
1140    [oPanel beginSheetForDirectory:nsfloppypath file:nil
1141                             types:diskImageTypes
1142                    modalForWindow:[NSApp mainWindow]
1143                     modalDelegate:self
1144                    didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
1145                       contextInfo:contextInfo];
1146}
1147
1148// Called when a floppy selection panel ended
1149- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
1150{
1151#if 0 // This currently breaks
1152    restoreFullscreen();
1153#endif
1154
1155	if (returnCode != NSOKButton) return;
1156
1157	int drive = [((NSString*)contextInfo) intValue];
1158	[((NSString*)contextInfo) release];
1159
1160	if ((drive >= 0) && (drive < 4)) {
1161		NSArray *files = [sheet filenames];
1162		NSString *file = [files objectAtIndex:0];
1163		char *sfile = [file UTF8String];
1164		strcpy(changed_prefs.floppyslots[drive].df, sfile);
1165		write_log ("Selected Disk Image: %s for Drive: %d\n", sfile, drive);
1166
1167		// Save the path of this disk image so that future open panels can start in the same directory
1168		[[NSUserDefaults standardUserDefaults] setObject:[file stringByDeletingLastPathComponent] forKey:@"LastUsedDiskImagePath"];
1169	}
1170}
1171
1172// Eject CD
1173- (void)ejectCD:(id)sender
1174{
1175	changed_prefs.cdslots[0].name[0] = 0;
1176	changed_prefs.cdslots[0].inuse = false;
1177}
1178
1179// cd image
1180- (void)displayOpenPanelForCDImage:(int)foo
1181{
1182        ensureNotFullscreen();
1183
1184        NSOpenPanel *oPanel = [NSOpenPanel openPanel];
1185        [oPanel setTitle:@"Select CD Image"];
1186
1187        // make sure setMessage (OS X 10.3+) is available before calling it
1188        if ([oPanel respondsToSelector:@selector(setMessage:)])
1189                [oPanel setMessage:@"Select Kick ROM"];
1190
1191        [oPanel setPrompt:@"Select"];
1192        NSString *contextInfo = [[NSString alloc] initWithString:@"cdimage"];
1193
1194        // recall the path of kick rom that was loaded last time
1195        NSString *nscdpath = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastUsedCDPath"];
1196
1197        // If the configuration includes a setting for the "cd_path" attribute
1198        // start the OpenPanel in that directory.. but only the first time.
1199        static int cd_run_once = 0;
1200        if (!cd_run_once) {
1201                cd_run_once++;
1202
1203                const char *cd_path = currprefs.cdslots[0].name;
1204
1205                if (cd_path != NULL) {
1206                        char homedir[MAX_PATH];
1207                        snprintf(homedir, MAX_PATH, "%s/", getenv("HOME"));
1208
1209                        // default value for cd_path is "$HOME/"
1210                        if (strncmp(cd_path, homedir, MAX_PATH) != 0)
1211                                nscdpath = [NSString stringWithCString:cd_path encoding:NSASCIIStringEncoding];
1212                }
1213        }
1214
1215    [oPanel beginSheetForDirectory:nscdpath file:nil
1216                             types:CDImageTypes
1217                    modalForWindow:[NSApp mainWindow]
1218                     modalDelegate:self
1219                    didEndSelector:@selector(selectCDImagePanelDidEnd:returnCode:contextInfo:)
1220                       contextInfo:contextInfo];
1221}
1222
1223// called after cd image selection panel
1224- (void)selectCDImagePanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
1225{
1226        if (returnCode != NSOKButton) return;
1227
1228        NSArray *files = [sheet filenames];
1229        NSString *file = [files objectAtIndex:0];
1230        char *sfile = [file UTF8String];
1231        strcpy(changed_prefs.cdslots[0].name, sfile);
1232        write_log ("Selected CD Image: %s\n", sfile);
1233
1234        [[NSUserDefaults standardUserDefaults] setObject:[file stringByDeletingLastPathComponent] forKey:@"LastUsedCDPath"];
1235}
1236
1237// kick.rom
1238- (void)displayOpenPanelForKickROM:(int)foo
1239{
1240	ensureNotFullscreen();
1241
1242	NSOpenPanel *oPanel = [NSOpenPanel openPanel];
1243	[oPanel setTitle:@"Select Kick ROM"];
1244
1245	// make sure setMessage (OS X 10.3+) is available before calling it
1246	if ([oPanel respondsToSelector:@selector(setMessage:)])
1247		[oPanel setMessage:@"Select Kick ROM"];
1248
1249	[oPanel setPrompt:@"Select"];
1250	NSString *contextInfo = [[NSString alloc] initWithString:@"kick"];
1251
1252	// recall the path of kick rom that was loaded last time
1253	NSString *nskickpath = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastUsedKickPath"];
1254
1255	// If the configuration includes a setting for the "kick_path" attribute
1256	// start the OpenPanel in that directory.. but only the first time.
1257	static int kick_run_once = 0;
1258	if (!kick_run_once) {
1259		kick_run_once++;
1260
1261		const char *kick_path = currprefs.romfile;
1262
1263		if (kick_path != NULL) {
1264			char homedir[MAX_PATH];
1265			snprintf(homedir, MAX_PATH, "%s/", getenv("HOME"));
1266
1267			// default value for kick_path is "$HOME/"
1268			if (strncmp(kick_path, homedir, MAX_PATH) != 0)
1269				nskickpath = [NSString stringWithCString:kick_path encoding:NSASCIIStringEncoding];
1270		}
1271	}
1272
1273    [oPanel beginSheetForDirectory:nskickpath file:nil
1274                             types:KickRomTypes
1275                    modalForWindow:[NSApp mainWindow]
1276                     modalDelegate:self
1277                    didEndSelector:@selector(selectKickROMPanelDidEnd:returnCode:contextInfo:)
1278                       contextInfo:contextInfo];
1279}
1280
1281// called after kick rom selection panel
1282- (void)selectKickROMPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
1283{
1284	if (returnCode != NSOKButton) return;
1285
1286	NSArray *files = [sheet filenames];
1287	NSString *file = [files objectAtIndex:0];
1288	char *sfile = [file UTF8String];
1289	strcpy(changed_prefs.romfile, sfile);
1290	write_log ("Selected Kickrom: %s\n", sfile);
1291
1292	[[NSUserDefaults standardUserDefaults] setObject:[file stringByDeletingLastPathComponent] forKey:@"LastUsedKickPath"];
1293}
1294
1295// flash.rom
1296- (void)displayOpenPanelForFlashRAM:(int)foo
1297{
1298	ensureNotFullscreen();
1299
1300	NSOpenPanel *oPanel = [NSOpenPanel openPanel];
1301	[oPanel setTitle:@"Select Flash RAM"];
1302
1303	// make sure setMessage (OS X 10.3+) is available before calling it
1304	if ([oPanel respondsToSelector:@selector(setMessage:)])
1305		[oPanel setMessage:@"Select Flash RAM"];
1306
1307	[oPanel setPrompt:@"Select"];
1308	NSString *contextInfo = [[NSString alloc] initWithString:@"flash"];
1309
1310	// recall the path of flash ram that was loaded last time
1311	NSString *nsflashpath = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastUsedFlashPath"];
1312
1313	// If the configuration includes a setting for the "flash_path" attribute
1314	// start the OpenPanel in that directory.. but only the first time.
1315	static int flash_run_once = 0;
1316	if (!flash_run_once) {
1317		flash_run_once++;
1318
1319		const char *flash_path = currprefs.flashfile;
1320
1321		if (flash_path != NULL) {
1322			char homedir[MAX_PATH];
1323			snprintf(homedir, MAX_PATH, "%s/", getenv("HOME"));
1324
1325			// default value for flash_path is "$HOME/"
1326			if (strncmp(flash_path, homedir, MAX_PATH) != 0)
1327				nsflashpath = [NSString stringWithCString:flash_path encoding:NSASCIIStringEncoding];
1328		}
1329	}
1330
1331    [oPanel beginSheetForDirectory:nsflashpath file:nil
1332                             types:FlashRamTypes
1333                    modalForWindow:[NSApp mainWindow]
1334                     modalDelegate:self
1335                    didEndSelector:@selector(selectFlashRAMPanelDidEnd:returnCode:contextInfo:)
1336                       contextInfo:contextInfo];
1337}
1338
1339// called after flash ram selection panel
1340- (void)selectFlashRAMPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
1341{
1342	if (returnCode != NSOKButton) return;
1343
1344	NSArray *files = [sheet filenames];
1345	NSString *file = [files objectAtIndex:0];
1346	char *sfile = [file UTF8String];
1347	strcpy(changed_prefs.flashfile, sfile);
1348	write_log ("Selected Flash RAM: %s\n", sfile);
1349
1350	[[NSUserDefaults standardUserDefaults] setObject:[file stringByDeletingLastPathComponent] forKey:@"LastUsedFlashPath"];
1351}
1352
1353// cartridge rom
1354- (void)displayOpenPanelForCartridge:(int)foo
1355{
1356	ensureNotFullscreen();
1357
1358	NSOpenPanel *oPanel = [NSOpenPanel openPanel];
1359	[oPanel setTitle:@"Select Cartridge ROM"];
1360
1361	// make sure setMessage (OS X 10.3+) is available before calling it
1362	if ([oPanel respondsToSelector:@selector(setMessage:)])
1363		[oPanel setMessage:@"Select Cartridge ROM"];
1364
1365	[oPanel setPrompt:@"Select"];
1366	NSString *contextInfo = [[NSString alloc] initWithString:@"cart"];
1367
1368	// recall the path of cartridge that was loaded last time
1369	NSString *nscartpath = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastUsedCartPath"];
1370
1371	// If the configuration includes a setting for the "cart_path" attribute
1372	// start the OpenPanel in that directory.. but only the first time.
1373	static int cart_run_once = 0;
1374	if (!cart_run_once) {
1375		cart_run_once++;
1376
1377		const char *cart_path = currprefs.cartfile;
1378
1379		if (cart_path != NULL) {
1380			char homedir[MAX_PATH];
1381			snprintf(homedir, MAX_PATH, "%s/", getenv("HOME"));
1382
1383			// default value for cart_path is "$HOME/"
1384			if (strncmp(cart_path, homedir, MAX_PATH) != 0)
1385				nscartpath = [NSString stringWithCString:cart_path encoding:NSASCIIStringEncoding];
1386		}
1387	}
1388
1389    [oPanel beginSheetForDirectory:nscartpath file:nil
1390                             types:CartridgeTypes
1391                    modalForWindow:[NSApp mainWindow]
1392                     modalDelegate:self
1393                    didEndSelector:@selector(selectCartridgePanelDidEnd:returnCode:contextInfo:)
1394                       contextInfo:contextInfo];
1395}
1396
1397// called after cartridge rom selection panel
1398- (void)selectCartridgePanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
1399{
1400	if (returnCode != NSOKButton) return;
1401
1402	NSArray *files = [sheet filenames];
1403	NSString *file = [files objectAtIndex:0];
1404	char *sfile = [file UTF8String];
1405	strcpy(changed_prefs.cartfile, sfile);
1406	write_log ("Selected Cartridge: %s\n", sfile);
1407
1408	[[NSUserDefaults standardUserDefaults] setObject:[file stringByDeletingLastPathComponent] forKey:@"LastUsedCartPath"];
1409}
1410
1411// load savestate
1412- (void)displayOpenPanelForLoadState:(id)sender
1413{
1414	ensureNotFullscreen();
1415
1416	NSOpenPanel *oPanel = [NSOpenPanel openPanel];
1417	[oPanel setTitle:@"Select a SaveState to Load"];
1418
1419	// make sure setMessage (OS X 10.3+) is available before calling it
1420	if ([oPanel respondsToSelector:@selector(setMessage:)])
1421		[oPanel setMessage:@"Select a SaveState to Load"];
1422
1423	[oPanel setPrompt:@"Select"];
1424
1425	// recall the path of save state that was loaded last time
1426	NSString *nssavestatepath = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastUsedSaveStatePath"];
1427
1428	// If the configuration includes a setting for the "savestate_path" attribute
1429	// start the OpenPanel in that directory.. but only the first time.
1430	static int sstate_run_once = 0;
1431	if (!sstate_run_once) {
1432		sstate_run_once++;
1433
1434		const char *savestate_path = "./";
1435
1436		if (savestate_path != NULL) {
1437			char homedir[MAX_PATH];
1438			snprintf(homedir, MAX_PATH, "%s/", getenv("HOME"));
1439
1440			// default value for savestate_path is "$HOME/"
1441			if (strncmp(savestate_path, homedir, MAX_PATH) != 0)
1442				nssavestatepath = [NSString stringWithCString:savestate_path encoding:NSASCIIStringEncoding];
1443		}
1444	}
1445
1446    [oPanel beginSheetForDirectory:nssavestatepath file:@""
1447                    modalForWindow:[NSApp mainWindow]
1448                     modalDelegate:self
1449                    didEndSelector:@selector(selectLoadStatePanelDidEnd:returnCode:contextInfo:)
1450                       contextInfo:NULL];
1451}
1452
1453// called after load a savestate selection panel
1454- (void)selectLoadStatePanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
1455{
1456	if (returnCode != NSOKButton) return;
1457
1458	NSArray *files = [sheet filenames];
1459	NSString *file = [files objectAtIndex:0];
1460	char *sfile = [file UTF8String];
1461	write_log ("Loading SaveState from: %s ...", sfile);
1462
1463	[[NSUserDefaults standardUserDefaults] setObject:[file stringByDeletingLastPathComponent] forKey:@"LastUsedSaveStatePath"];
1464
1465	savestate_initsave (sfile, 0, 0, 0);
1466	savestate_state = STATE_DORESTORE;
1467	write_log ("done\n");
1468}
1469
1470// save savestate
1471- (void)displayOpenPanelForSaveState:(id)sender
1472{
1473	ensureNotFullscreen();
1474
1475	NSSavePanel *sPanel = [NSSavePanel savePanel];
1476	[sPanel setTitle:@"Select a SaveState to Save"];
1477	[sPanel setCanSelectHiddenExtension:true];
1478
1479	// make sure setMessage (OS X 10.3+) is available before calling it
1480	if ([sPanel respondsToSelector:@selector(setMessage:)])
1481		[sPanel setMessage:@"Select a SaveState to Save"];
1482
1483	[sPanel beginSheetForDirectory:NSHomeDirectory() file:nil
1484			modalForWindow:[NSApp mainWindow]
1485			 modalDelegate:self
1486			didEndSelector:@selector(selectSaveStatePanelDidEnd:returnCode:contextInfo:)
1487			   contextInfo:NULL];
1488}
1489
1490// called after save a savestate selection panel
1491- (void)selectSaveStatePanelDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
1492{
1493	if (returnCode != NSOKButton) return;
1494
1495	NSString *file = [sheet filename];
1496	char *sfile = [file UTF8String];
1497	write_log ("Saving SaveState to: %s ...", sfile);
1498
1499	[[NSUserDefaults standardUserDefaults] setObject:[file stringByDeletingLastPathComponent] forKey:@"LastUsedSaveStatePath"];
1500
1501//	savestate_initsave (sfile, 0, 0, 0);
1502	save_state (sfile, "puae");
1503	write_log ("done\n");
1504}
1505
1506
1507- (void)QuickStart:(id)sender
1508{
1509	unsigned int romcheck = 0;
1510	quickstart_model = [((NSMenuItem*)sender) tag];
1511
1512	changed_prefs.nr_floppies = quickstart_floppy;
1513	quickstart_ok = built_in_prefs (&changed_prefs, quickstart_model, quickstart_conf, quickstart_compa, romcheck);
1514	changed_prefs.ntscmode = quickstart_ntsc != 0;
1515	//quickstart_cd = chnaged_prefs.floppyslots[1].dfxtype == DRV_NONE && (quickstart_model == 8 || quickstart_model == 9);
1516    config_filename[0] = 0;
1517	//uae_reset(0);
1518}
1519
1520// leds_on_screen
1521- (void)LedsOnScreen:(id)sender
1522{
1523	changed_prefs.leds_on_screen = !changed_prefs.leds_on_screen;
1524	config_changed = 1;
1525	check_prefs_changed_gfx ();
1526}
1527
1528- (void)resetAmiga:(id)sender
1529{
1530	uae_reset([((NSMenuItem *)sender) tag], 0);
1531}
1532
1533- (void)pauseAmiga:(id)sender
1534{
1535	pausemode(-1); // Found in inputdevice.c -- toggles pause mode when arg is -1
1536}
1537
1538#ifdef ACTION_REPLAY
1539- (void)actionReplayFreeze:(id)sender
1540{
1541	action_replay_freeze();
1542}
1543#endif
1544
1545- (void)grabMouse:(id)sender
1546{
1547	toggle_mousegrab ();
1548}
1549
1550- (void)goFullscreen:(id)sender
1551{
1552	toggle_fullscreen(0);
1553}
1554
1555- (void)toggleInhibitDisplay:(id)sender
1556{
1557	toggle_inhibit_frame (IHF_SCROLLLOCK);
1558}
1559
1560// chip mem
1561- (void)changeChipMem:(id)sender
1562{
1563	changed_prefs.chipmem_size = memsizes[[((NSMenuItem*)sender) tag]];
1564        if (changed_prefs.chipmem_size > 0x200000)
1565                changed_prefs.fastmem_size = 0;
1566}
1567
1568// bogo mem
1569- (void)changeBogoMem:(id)sender
1570{
1571	changed_prefs.bogomem_size = memsizes[[((NSMenuItem*)sender) tag]];
1572}
1573
1574// fast mem
1575- (void)changeFastMem:(id)sender
1576{
1577	changed_prefs.fastmem_size = memsizes[[((NSMenuItem*)sender) tag]];
1578}
1579
1580// z3 fast mem
1581- (void)changeZ3FastMem:(id)sender
1582{
1583	changed_prefs.z3fastmem_size = memsizes[[((NSMenuItem*)sender) tag]];
1584}
1585
1586// z3 chip mem
1587- (void)changeZ3ChipMem:(id)sender
1588{
1589	changed_prefs.z3chipmem_size = memsizes[[((NSMenuItem*)sender) tag]];
1590}
1591
1592/* gfx mem
1593- (void)changeGfxMem:(id)sender
1594{
1595	changed_prefs.rtgmem_size = memsizes[[((NSMenuItem*)sender) tag]];
1596}*/
1597
1598// chipset
1599- (void)changeChipset:(id)sender
1600{
1601	if ([((NSMenuItem*)sender) tag] < 10) {
1602		changed_prefs.chipset_mask = [((NSMenuItem*)sender) tag];
1603	} else {
1604		changed_prefs.ntscmode = !changed_prefs.ntscmode;
1605	}
1606}
1607
1608// chipset extra
1609- (void)changeChipsetX:(id)sender
1610{
1611	changed_prefs.cs_compatible = [((NSMenuItem*)sender) tag];
1612	built_in_chipset_prefs (&changed_prefs);
1613}
1614
1615// monitor emu
1616- (void)changeMonitoremu:(id)sender
1617{
1618	changed_prefs.monitoremu = [((NSMenuItem*)sender) tag];
1619	config_changed = 1;
1620}
1621
1622// blitter
1623- (void)changeBlitter:(id)sender
1624{
1625	if ([((NSMenuItem*)sender) tag] == 0)
1626		changed_prefs.immediate_blits = !changed_prefs.immediate_blits;
1627	if ([((NSMenuItem*)sender) tag] == 1)
1628		changed_prefs.blitter_cycle_exact = !changed_prefs.blitter_cycle_exact;
1629	config_changed = 1;
1630}
1631
1632// collision
1633- (void)changeCollision:(id)sender
1634{
1635	changed_prefs.collision_level = [((NSMenuItem*)sender) tag];
1636	config_changed = 1;
1637}
1638
1639// cpu
1640- (void)changeCPU:(id)sender
1641{
1642 if ([((NSMenuItem*)sender) tag] < 10) {
1643	unsigned int newcpu, newfpu;
1644	newcpu = 68000 + ([((NSMenuItem*)sender) tag] * 10);
1645	newfpu = changed_prefs.fpu_model;
1646	changed_prefs.cpu_model = newcpu;
1647
1648        switch (newcpu) {
1649        case 68000:
1650        case 68010:
1651                changed_prefs.fpu_model = newfpu == 0 ? 0 : (newfpu == 2 ? 68882 : 68881);
1652                if (changed_prefs.cpu_compatible || changed_prefs.cpu_cycle_exact)
1653                        changed_prefs.fpu_model = 0;
1654                changed_prefs.address_space_24 = 1;
1655                if (newcpu == 0 && changed_prefs.cpu_cycle_exact)
1656                        changed_prefs.m68k_speed = 0;
1657                break;
1658        case 68020:
1659                changed_prefs.fpu_model = newfpu == 0 ? 0 : (newfpu == 2 ? 68882 : 68881);
1660                break;
1661        case 68030:
1662                changed_prefs.address_space_24 = 0;
1663                changed_prefs.fpu_model = newfpu == 0 ? 0 : (newfpu == 2 ? 68882 : 68881);
1664                break;
1665        case 68040:
1666                changed_prefs.fpu_model = newfpu ? 68040 : 0;
1667                changed_prefs.address_space_24 = 0;
1668                if (changed_prefs.fpu_model)
1669                        changed_prefs.fpu_model = 68040;
1670                break;
1671        case 68060:
1672                changed_prefs.fpu_model = newfpu ? 68060 : 0;
1673                changed_prefs.address_space_24 = 0;
1674                break;
1675        }
1676 } else {
1677	switch ([((NSMenuItem*)sender) tag]) {
1678	case 10:
1679		changed_prefs.address_space_24 = !changed_prefs.address_space_24;
1680		break;
1681	case 11:
1682		changed_prefs.cpu_compatible = !changed_prefs.cpu_compatible;
1683		break;
1684#ifdef MMUEMU
1685	case 12:
1686		changed_prefs.mmu_model = 68040;
1687		break;
1688#endif
1689	}
1690 }
1691}
1692
1693// cpu speed
1694- (void)changeCPUSpeed:(id)sender
1695{
1696	unsigned int v;
1697	v = [((NSMenuItem*)sender) tag];
1698	if (v == 0) {
1699		changed_prefs.m68k_speed = -1;
1700		changed_prefs.cpu_cycle_exact = 0;
1701	}
1702	if (v == 1) {
1703		changed_prefs.m68k_speed = 0;
1704		changed_prefs.cpu_cycle_exact = 0;
1705	}
1706	if (v == 2) {
1707		changed_prefs.m68k_speed = 0;
1708		changed_prefs.cpu_cycle_exact = 1;
1709	}
1710
1711	changed_prefs.blitter_cycle_exact = changed_prefs.cpu_cycle_exact;
1712	if (changed_prefs.cpu_cycle_exact) {
1713		if (changed_prefs.cpu_model == 68000)
1714			changed_prefs.cpu_compatible = 1;
1715		if (changed_prefs.cpu_model <= 68020)
1716			changed_prefs.m68k_speed = 0;
1717		changed_prefs.immediate_blits = 0;
1718		changed_prefs.gfx_framerate = 1;
1719		changed_prefs.cachesize = 0;
1720	}
1721}
1722
1723// fpu
1724- (void)changeFPU:(id)sender
1725{
1726	unsigned int v;
1727	v = [((NSMenuItem*)sender) tag];
1728	if (v < 10) {
1729	/*	if (v == 1) v = 68881;
1730		if (v == 2) v = 68882;*/
1731		changed_prefs.fpu_model = v;
1732#ifdef JIT
1733	} else {
1734		changed_prefs.fpu_strict = !changed_prefs.fpu_strict;
1735#endif
1736	}
1737}
1738
1739// sound
1740- (void)changeSound:(id)sender
1741{
1742	changed_prefs.produce_sound = [((NSMenuItem*)sender) tag];
1743	config_changed = 1;
1744}
1745
1746// sound interpolation
1747- (void)changeSoundInterpolation:(id)sender
1748{
1749	changed_prefs.sound_interpol = [((NSMenuItem*)sender) tag];
1750	config_changed = 1;
1751}
1752
1753// sound filter
1754- (void)changeSoundFilter:(id)sender
1755{
1756	switch ([((NSMenuItem*)sender) tag]) {
1757        case 0:
1758                changed_prefs.sound_filter = 0;
1759                break;
1760        case 1:
1761                changed_prefs.sound_filter = 1;
1762                changed_prefs.sound_filter_type = 0;
1763                break;
1764        case 2:
1765                changed_prefs.sound_filter = 1;
1766                changed_prefs.sound_filter_type = 1;
1767                break;
1768        case 3:
1769                changed_prefs.sound_filter = 2;
1770                changed_prefs.sound_filter_type = 0;
1771                break;
1772        case 4:
1773                changed_prefs.sound_filter = 2;
1774                changed_prefs.sound_filter_type = 1;
1775                break;
1776	}
1777	config_changed = 1;
1778}
1779
1780// gfx - line mode
1781- (void)changeGfxLineMode:(id)sender
1782{
1783	changed_prefs.gfx_scanlines = [((NSMenuItem*)sender) tag];
1784	config_changed = 1;
1785}
1786
1787// gfx - centering
1788- (void)changeGfxCentering:(id)sender
1789{
1790	if ([((NSMenuItem*)sender) tag] == 0)
1791		changed_prefs.gfx_xcenter = !changed_prefs.gfx_xcenter;
1792	if ([((NSMenuItem*)sender) tag] == 1)
1793		changed_prefs.gfx_ycenter = !changed_prefs.gfx_ycenter;
1794	config_changed = 1;
1795}
1796
1797// select kick rom
1798- (void)selectKickROM:(id)sender
1799{
1800	[self displayOpenPanelForKickROM:[((NSMenuItem*)sender) tag]];
1801}
1802
1803// select flash ram
1804- (void)selectFlashRAM:(id)sender
1805{
1806	[self displayOpenPanelForFlashRAM:[((NSMenuItem*)sender) tag]];
1807}
1808
1809// select cartridge rom
1810- (void)selectCartridge:(id)sender
1811{
1812	[self displayOpenPanelForCartridge:[((NSMenuItem*)sender) tag]];
1813}
1814
1815// select savestate to save
1816- (void)selectSaveState:(id)sender
1817{
1818	[self displayOpenPanelForSaveState:[((NSMenuItem*)sender) tag]];
1819}
1820
1821// select savestate to load
1822- (void)selectLoadState:(id)sender
1823{
1824	[self displayOpenPanelForLoadState:[((NSMenuItem*)sender) tag]];
1825}
1826@end
1827
1828/*
1829 * Revert to windowed mode if in fullscreen mode. Returns 1 if the
1830 * mode was initially fullscreen and was successfully changed. 0 otherwise.
1831 */
1832int ensureNotFullscreen (void)
1833{
1834	unsigned int result = 0;
1835
1836	if (is_fullscreen ()) {
1837		toggle_fullscreen (0);
1838
1839		if (is_fullscreen ()) {
1840			write_log ("Cannot activate GUI in full-screen mode\n");
1841		} else {
1842			result = 1;
1843			wasFullscreen = YES;
1844		}
1845	}
1846
1847#ifdef USE_SDL
1848	// Un-hide the mouse
1849	SDL_ShowCursor(SDL_ENABLE);
1850#endif
1851
1852	return result;
1853}
1854
1855void restoreFullscreen (void)
1856{
1857#ifdef USE_SDL
1858	// Re-hide the mouse
1859	SDL_ShowCursor(SDL_DISABLE);
1860#endif
1861	if ((!is_fullscreen ()) && (wasFullscreen == YES))
1862		toggle_fullscreen(0);
1863
1864	wasFullscreen = NO;
1865}
1866
1867/* This function is called from od-macosx/main.m
1868 * WARNING: This gets called *before* real_main(...)!
1869 */
1870void cocoa_gui_early_setup (void)
1871{
1872	[[PuaeGui sharedInstance] createMenus];
1873}
1874
1875int gui_init (void)
1876{
1877//        read_rom_list ();
1878        inputdevice_updateconfig (&changed_prefs, &currprefs);
1879
1880	return 1;
1881}
1882
1883int gui_update (void)
1884{
1885	return 1;
1886}
1887
1888void gui_exit (void)
1889{
1890}
1891
1892static void gui_flicker_led2 (int led, int unitnum, int status)
1893{
1894        static int resetcounter[LED_MAX];
1895        uae_u8 old;
1896        uae_u8 *p;
1897
1898        if (led == LED_HD)
1899                p = &gui_data.hd;
1900        else if (led == LED_CD)
1901                p = &gui_data.cd;
1902        else if (led == LED_MD)
1903                p = &gui_data.md;
1904        else
1905                return;
1906        old = *p;
1907        if (status == 0) {
1908                resetcounter[led]--;
1909                if (resetcounter[led] > 0)
1910                        return;
1911        }
1912
1913        *p = status;
1914        resetcounter[led] = 6;
1915        if (old != *p)
1916                gui_led (led, *p);
1917}
1918
1919void gui_flicker_led (int led, int unitnum, int status)
1920{
1921        if (led < 0) {
1922                gui_flicker_led2 (LED_HD, 0, 0);
1923                gui_flicker_led2 (LED_CD, 0, 0);
1924                gui_flicker_led2 (LED_MD, 0, 0);
1925        } else {
1926                gui_flicker_led2 (led, unitnum, status);
1927        }
1928}
1929
1930void gui_fps (int fps, int idle, int color)
1931{
1932	gui_data.fps  = 0; //LATER: fps
1933	gui_data.idle = 0; //LATER: idle
1934        gui_led (LED_FPS, 0);
1935        gui_led (LED_CPU, 0);
1936        gui_led (LED_SND, (gui_data.sndbuf_status > 1 || gui_data.sndbuf_status < 0) ? 0 : 1);
1937}
1938
1939void gui_led (int led, int on)
1940{
1941}
1942
1943void gui_filename (int num, const char *name)
1944{
1945}
1946
1947void gui_handle_events (void)
1948{
1949}
1950
1951void gui_display (int shortcut)
1952{
1953	//int result;
1954
1955	if ((shortcut >= 0) && (shortcut < 4)) {
1956		[[PuaeGui sharedInstance] displayOpenPanelForInsertIntoDriveNumber:shortcut];
1957	}
1958}
1959
1960void gui_message (const char *format,...)
1961{
1962	char msg[2048];
1963	va_list parms;
1964
1965	ensureNotFullscreen ();
1966
1967	va_start (parms,format);
1968	vsprintf (msg, format, parms);
1969	va_end (parms);
1970
1971	NSRunAlertPanel(nil, [NSString stringWithCString:msg encoding:NSASCIIStringEncoding], nil, nil, nil);
1972
1973	write_log ("%s", msg);
1974
1975	restoreFullscreen ();
1976}
1977void gui_disk_image_change (int unitnum, const TCHAR *name, bool writeprotected) {}
1978void gui_lock (void) {}
1979void gui_unlock (void) {}
1980
1981static int guijoybutton[MAX_JPORTS];
1982static int guijoyaxis[MAX_JPORTS][4];
1983static bool guijoychange;
1984
1985void gui_gameport_button_change (int port, int button, int onoff)
1986{
1987        //write_log ("%d %d %d\n", port, button, onoff);
1988#ifdef RETROPLATFORM
1989        int mask = 0;
1990        if (button == JOYBUTTON_CD32_PLAY)
1991                mask = RP_JOYSTICK_BUTTON5;
1992        if (button == JOYBUTTON_CD32_RWD)
1993                mask = RP_JOYSTICK_BUTTON6;
1994        if (button == JOYBUTTON_CD32_FFW)
1995                mask = RP_JOYSTICK_BUTTON7;
1996        if (button == JOYBUTTON_CD32_GREEN)
1997                mask = RP_JOYSTICK_BUTTON4;
1998        if (button == JOYBUTTON_3 || button == JOYBUTTON_CD32_YELLOW)
1999                mask = RP_JOYSTICK_BUTTON3;
2000        if (button == JOYBUTTON_1 || button == JOYBUTTON_CD32_RED)
2001                mask = RP_JOYSTICK_BUTTON1;
2002        if (button == JOYBUTTON_2 || button == JOYBUTTON_CD32_BLUE)
2003                mask = RP_JOYSTICK_BUTTON2;
2004        rp_update_gameport (port, mask, onoff);
2005#endif
2006        if (onoff)
2007                guijoybutton[port] |= 1 << button;
2008        else
2009                guijoybutton[port] &= ~(1 << button);
2010        guijoychange = true;
2011}
2012
2013void gui_gameport_axis_change (int port, int axis, int state, int max)
2014{
2015        int onoff = state ? 100 : 0;
2016        if (axis < 0 || axis > 3)
2017                return;
2018        if (max < 0) {
2019                if (guijoyaxis[port][axis] == 0)
2020                        return;
2021                if (guijoyaxis[port][axis] > 0)
2022                        guijoyaxis[port][axis]--;
2023        } else {
2024                if (state > max)
2025                        state = max;
2026                if (state < 0)
2027                        state = 0;
2028                guijoyaxis[port][axis] = max ? state * 127 / max : onoff;
2029#ifdef RETROPLATFORM
2030                if (axis == DIR_LEFT_BIT)
2031                        rp_update_gameport (port, RP_JOYSTICK_LEFT, onoff);
2032                if (axis == DIR_RIGHT_BIT)
2033                        rp_update_gameport (port, DIR_RIGHT_BIT, onoff);
2034                if (axis == DIR_UP_BIT)
2035                        rp_update_gameport (port, DIR_UP_BIT, onoff);
2036                if (axis == DIR_DOWN_BIT)
2037                        rp_update_gameport (port, DIR_DOWN_BIT, onoff);
2038#endif
2039        }
2040        guijoychange = true;
2041}
2042