|
|
1.1 root 1: /* SDLMain.m - main entry point for our Cocoa-ized SDL app
2: Initial Version: Darrell Walisser <[email protected]>
3: Non-NIB-Code & other changes: Max Horn <[email protected]>
4:
5: Feel free to customize this file to suit your needs
6: */
7:
1.1.1.6 ! root 8: #include "SDL.h"
! 9: #include "SDLMain.h"
! 10: #include <sys/param.h> /* for MAXPATHLEN */
! 11: #include <unistd.h>
! 12:
! 13: // for Hatari
1.1 root 14:
15: #include "dialog.h"
16: #include "floppy.h"
17: #include "reset.h"
18: #include "screenSnapShot.h"
19: #include "memorySnapShot.h"
20: #include "sound.h"
1.1.1.6 ! root 21: #include "video.h"
! 22: #include "avi_record.h"
! 23:
! 24: // for Hatari
! 25:
! 26:
! 27: /* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
! 28: but the method still is there and works. To avoid warnings, we declare
! 29: it ourselves here. */
! 30: @interface NSApplication(SDL_Missing_Methods)
! 31: - (void)setAppleMenu:(NSMenu *)menu;
! 32: @end
! 33:
! 34: /* Use this flag to determine whether we use SDLMain.nib or not */
! 35: #define SDL_USE_NIB_FILE 1
! 36:
! 37: /* Use this flag to determine whether we use CPS (docking) or not */
! 38: #define SDL_USE_CPS 1
! 39: #ifdef SDL_USE_CPS
! 40: /* Portions of CPS.h */
! 41: typedef struct CPSProcessSerNum
! 42: {
! 43: UInt32 lo;
! 44: UInt32 hi;
! 45: } CPSProcessSerNum;
! 46:
! 47: extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
! 48: extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
! 49: extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
! 50:
! 51: #endif /* SDL_USE_CPS */
1.1 root 52:
53: static int gArgc;
54: static char **gArgv;
55: static BOOL gFinderLaunch;
1.1.1.6 ! root 56: static BOOL gCalledAppMainline = FALSE;
! 57:
! 58: static NSString *getApplicationName(void)
! 59: {
! 60: const NSDictionary *dict;
! 61: NSString *appName = 0;
1.1 root 62:
1.1.1.6 ! root 63: /* Determine the application name */
! 64: dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
! 65: if (dict)
! 66: appName = [dict objectForKey: @"CFBundleName"];
! 67:
! 68: if (![appName length])
! 69: appName = [[NSProcessInfo processInfo] processName];
! 70:
! 71: return appName;
! 72: }
! 73:
! 74: #if SDL_USE_NIB_FILE
! 75: /* A helper category for NSString */
! 76: @interface NSString (ReplaceSubString)
! 77: - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
1.1 root 78: @end
1.1.1.6 ! root 79: #endif
1.1 root 80:
1.1.1.6 ! root 81: @interface NSApplication (SDLApplication)
! 82: @end
! 83:
! 84: @implementation NSApplication (SDLApplication)
1.1 root 85: /* Invoked from the Quit menu item */
86: - (void)terminate:(id)sender
87: {
88: /* Post a SDL_QUIT event */
89: SDL_Event event;
90: event.type = SDL_QUIT;
91: SDL_PushEvent(&event);
92: }
93: @end
94:
95: /* The main class of the application, the application's delegate */
96: @implementation SDLMain
97:
1.1.1.6 ! root 98: /* Set the working directory to the .app's parent directory */
! 99: - (void) setupWorkingDirectory:(BOOL)shouldChdir
! 100: {
! 101: if (shouldChdir)
! 102: {
! 103: char parentdir[MAXPATHLEN];
! 104: CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
! 105: CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
! 106: if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) {
! 107: chdir(parentdir); /* chdir to the binary app's parent */
! 108: }
! 109: CFRelease(url);
! 110: CFRelease(url2);
! 111: }
! 112: }
! 113:
! 114: #if SDL_USE_NIB_FILE
! 115:
! 116: /* Fix menu to contain the real app name instead of "SDL App" */
! 117: - (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
! 118: {
! 119: NSRange aRange;
! 120: NSEnumerator *enumerator;
! 121: NSMenuItem *menuItem;
! 122:
! 123: aRange = [[aMenu title] rangeOfString:@"SDL App"];
! 124: if (aRange.length != 0)
! 125: [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
! 126:
! 127: enumerator = [[aMenu itemArray] objectEnumerator];
! 128: while ((menuItem = [enumerator nextObject]))
! 129: {
! 130: aRange = [[menuItem title] rangeOfString:@"SDL App"];
! 131: if (aRange.length != 0)
! 132: [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
! 133: if ([menuItem hasSubmenu])
! 134: [self fixMenu:[menuItem submenu] withAppName:appName];
! 135: }
! 136: }
! 137:
! 138: #else
! 139:
! 140: static void setApplicationMenu(void)
! 141: {
! 142: /* warning: this code is very odd */
! 143: NSMenu *appleMenu;
! 144: NSMenuItem *menuItem;
! 145: NSString *title;
! 146: NSString *appName;
! 147:
! 148: appName = getApplicationName();
! 149: appleMenu = [[NSMenu alloc] initWithTitle:@""];
! 150:
! 151: /* Add menu items */
! 152: title = [@"About " stringByAppendingString:appName];
! 153: [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
! 154:
! 155: [appleMenu addItem:[NSMenuItem separatorItem]];
! 156:
! 157: title = [@"Hide " stringByAppendingString:appName];
! 158: [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
! 159:
! 160: menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
! 161: [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
! 162:
! 163: [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
! 164:
! 165: [appleMenu addItem:[NSMenuItem separatorItem]];
! 166:
! 167: title = [@"Quit " stringByAppendingString:appName];
! 168: [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
! 169:
! 170:
! 171: /* Put menu into the menubar */
! 172: menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
! 173: [menuItem setSubmenu:appleMenu];
! 174: [[NSApp mainMenu] addItem:menuItem];
! 175:
! 176: /* Tell the application object that this is now the application menu */
! 177: [NSApp setAppleMenu:appleMenu];
! 178:
! 179: /* Finally give up our references to the objects */
! 180: [appleMenu release];
! 181: [menuItem release];
! 182: }
! 183:
! 184: /* Create a window menu */
! 185: static void setupWindowMenu(void)
! 186: {
! 187: NSMenu *windowMenu;
! 188: NSMenuItem *windowMenuItem;
! 189: NSMenuItem *menuItem;
! 190:
! 191: windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
! 192:
! 193: /* "Minimize" item */
! 194: menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
! 195: [windowMenu addItem:menuItem];
! 196: [menuItem release];
! 197:
! 198: /* Put menu into the menubar */
! 199: windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
! 200: [windowMenuItem setSubmenu:windowMenu];
! 201: [[NSApp mainMenu] addItem:windowMenuItem];
! 202:
! 203: /* Tell the application object that this is now the window menu */
! 204: [NSApp setWindowsMenu:windowMenu];
! 205:
! 206: /* Finally give up our references to the objects */
! 207: [windowMenu release];
! 208: [windowMenuItem release];
! 209: }
! 210:
! 211: /* Replacement for NSApplicationMain */
! 212: static void CustomApplicationMain (int argc, char **argv)
! 213: {
! 214: NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
! 215: SDLMain *sdlMain;
! 216:
! 217: /* Ensure the application object is initialised */
! 218: [NSApplication sharedApplication];
! 219:
! 220: #ifdef SDL_USE_CPS
! 221: {
! 222: CPSProcessSerNum PSN;
! 223: /* Tell the dock about us */
! 224: if (!CPSGetCurrentProcess(&PSN))
! 225: if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
! 226: if (!CPSSetFrontProcess(&PSN))
! 227: [NSApplication sharedApplication];
! 228: }
! 229: #endif /* SDL_USE_CPS */
! 230:
! 231: /* Set up the menubar */
! 232: [NSApp setMainMenu:[[NSMenu alloc] init]];
! 233: setApplicationMenu();
! 234: setupWindowMenu();
! 235:
! 236: /* Create SDLMain and make it the app delegate */
! 237: sdlMain = [[SDLMain alloc] init];
! 238: [NSApp setDelegate:sdlMain];
! 239:
! 240: /* Start the main event loop */
! 241: [NSApp run];
! 242:
! 243: [sdlMain release];
! 244: [pool release];
! 245: }
! 246:
! 247: #endif
! 248:
! 249:
! 250: /*
! 251: * Catch document open requests...this lets us notice files when the app
! 252: * was launched by double-clicking a document, or when a document was
! 253: * dragged/dropped on the app's icon. You need to have a
! 254: * CFBundleDocumentsType section in your Info.plist to get this message,
! 255: * apparently.
! 256: *
! 257: * Files are added to gArgv, so to the app, they'll look like command line
! 258: * arguments. Previously, apps launched from the finder had nothing but
! 259: * an argv[0].
! 260: *
! 261: * This message may be received multiple times to open several docs on launch.
! 262: *
! 263: * This message is ignored once the app's mainline has been called.
! 264: */
! 265: - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
! 266: {
! 267: const char *temparg;
! 268: size_t arglen;
! 269: char *arg;
! 270: char **newargv;
! 271:
! 272: if (!gFinderLaunch) /* MacOS is passing command line args. */
! 273: return FALSE;
! 274:
! 275: if (gCalledAppMainline) /* app has started, ignore this document. */
! 276: return FALSE;
! 277:
! 278: temparg = [filename UTF8String];
! 279: arglen = SDL_strlen(temparg) + 1;
! 280: arg = (char *) SDL_malloc(arglen);
! 281: if (arg == NULL)
! 282: return FALSE;
! 283:
! 284: newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
! 285: if (newargv == NULL)
! 286: {
! 287: SDL_free(arg);
! 288: return FALSE;
! 289: }
! 290: gArgv = newargv;
! 291:
! 292: SDL_strlcpy(arg, temparg, arglen);
! 293: gArgv[gArgc++] = arg;
! 294: gArgv[gArgc] = NULL;
! 295: return TRUE;
! 296: }
! 297:
! 298:
! 299: /* Called when the internal event loop has just started running */
! 300: - (void) applicationDidFinishLaunching: (NSNotification *) note
! 301: {
! 302: int status;
! 303:
! 304: /* Set the working directory to the .app's parent directory */
! 305: [self setupWorkingDirectory:gFinderLaunch];
! 306:
! 307: #if SDL_USE_NIB_FILE
! 308: /* Set the main menu to contain the real app name instead of "SDL App" */
! 309: [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
! 310: #endif
! 311:
! 312: /* Hand off to main application code */
! 313: gCalledAppMainline = TRUE;
! 314: status = SDL_main (gArgc, gArgv);
! 315:
! 316: /* We're done, thank you for playing */
! 317: exit(status);
! 318: }
! 319:
! 320: // Hatari Stuff
1.1 root 321: - (IBAction)prefsMenu:(id)sender
322: {
323: static int in_propdialog = 0;
1.1.1.6 ! root 324:
1.1 root 325: if (in_propdialog)
326: return;
327: ++in_propdialog;
1.1.1.6 ! root 328: Dialog_DoProperty();
1.1 root 329: --in_propdialog;
330: }
331:
1.1.1.6 ! root 332: - (IBAction)debugUI:(id)sender
! 333: {
! 334: DebugUI();
! 335: }
! 336:
1.1 root 337: - (IBAction)warmReset:(id)sender
338: {
339: int b;
1.1.1.6 ! root 340:
! 341: b = NSRunAlertPanel (
! 342: NSLocalizedStringFromTable(@"Warm reset",@"Localizable",@"comment"),
! 343: NSLocalizedStringFromTable(@"Really reset the emulator?",@"Localizable",@"comment"),
! 344: NSLocalizedStringFromTable(@"OK",@"Localizable",@"comment"),
! 345: NSLocalizedStringFromTable(@"Cancel",@"Localizable",@"comment"), nil);
1.1 root 346: //printf("b=%i\n",b);
347: if (b == 1)
348: Reset_Warm();
349: }
350:
351: - (IBAction)coldReset:(id)sender
352: {
353: int b;
1.1.1.6 ! root 354:
! 355: b = NSRunAlertPanel (
! 356: NSLocalizedStringFromTable(@"Cold reset!",@"Localizable",@"comment"),
! 357: NSLocalizedStringFromTable(@"Really reset the emulator?",@"Localizable",@"comment") ,
! 358: NSLocalizedStringFromTable(@"OK",@"Localizable",@"comment"),
! 359: NSLocalizedStringFromTable(@"Cancel",@"Localizable",@"comment"), nil);
1.1 root 360: //printf("b=%i\n",b);
361: if (b == 1)
362: Reset_Cold();
363: }
364:
365: - (IBAction)insertDiskA:(id)sender
366: {
1.1.1.6 ! root 367: NSString *path = nil;
! 368: NSOpenPanel *openPanel = [ NSOpenPanel openPanel ];
! 369:
! 370: if ( [ openPanel runModalForDirectory:nil
! 371: file:@"SavedGame" types:nil ] )
! 372: {
! 373: path = [ [ openPanel filenames ] objectAtIndex:0 ];
! 374: }
! 375:
1.1 root 376: if (path != nil)
377: {
378: // Make a non-const C string out of it
1.1.1.6 ! root 379: const char* constSzPath = [path cStringUsingEncoding:NSASCIIStringEncoding];
1.1 root 380: size_t cbPath = strlen(constSzPath) + 1;
381: char szPath[cbPath];
1.1.1.6 ! root 382: strncpy(szPath, constSzPath, cbPath);
1.1.1.3 root 383:
384: Floppy_SetDiskFileName(0, szPath, NULL);
385: Floppy_InsertDiskIntoDrive(0);
1.1 root 386: }
387: }
388:
389: - (IBAction)insertDiskB:(id)sender
390: {
1.1.1.6 ! root 391: NSString *path = nil;
! 392: NSOpenPanel *openPanel = [ NSOpenPanel openPanel ];
! 393:
! 394: if ( [ openPanel runModalForDirectory:nil
! 395: file:@"SavedGame" types:nil ] )
! 396: {
! 397: path = [ [ openPanel filenames ] objectAtIndex:0 ];
! 398: }
! 399:
1.1 root 400: if (path != nil)
401: {
402: // Make a non-const C string out of it
1.1.1.6 ! root 403: const char* constSzPath = [path cStringUsingEncoding:NSASCIIStringEncoding];
1.1 root 404: size_t cbPath = strlen(constSzPath) + 1;
405: char szPath[cbPath];
406: strncpy(szPath, constSzPath, cbPath);
1.1.1.6 ! root 407:
1.1.1.3 root 408: Floppy_SetDiskFileName(1, szPath, NULL);
409: Floppy_InsertDiskIntoDrive(1);
1.1 root 410: }
411: }
412:
413: /*-----------------------------------------------------------------------*/
414: /*
1.1.1.6 ! root 415: Controls the enabled state of the menu items
! 416: */
1.1 root 417: - (BOOL)validateMenuItem:(NSMenuItem*)item
418: {
419: if (item == beginCaptureAnim)
420: {
1.1.1.6 ! root 421: return !Avi_AreWeRecording();
1.1 root 422: }
423: if (item == endCaptureAnim)
424: {
1.1.1.6 ! root 425: return Avi_AreWeRecording();
1.1 root 426: }
427: if (item == beginCaptureSound)
428: {
429: return !Sound_AreWeRecording();
430: }
431: if (item == endCaptureSound)
432: {
433: return Sound_AreWeRecording();
434: }
435:
436: return YES;
437: }
438:
439: - (IBAction)captureScreen:(id)sender
440: {
1.1.1.5 root 441: GuiOsx_Pause();
1.1 root 442: ScreenSnapShot_SaveScreen();
1.1.1.5 root 443: GuiOsx_Resume();
1.1 root 444: }
445:
446: - (IBAction)captureAnimation:(id)sender
447: {
1.1.1.5 root 448: GuiOsx_Pause();
1.1.1.6 ! root 449: Avi_StartRecording ( AviRecordFile , AviRecordDefaultCrop , nScreenRefreshRate , AviRecordDefaultVcodec );
1.1.1.5 root 450: GuiOsx_Resume();
1.1 root 451: }
452:
453: - (IBAction)endCaptureAnimation:(id)sender
454: {
1.1.1.5 root 455: GuiOsx_Pause();
1.1.1.6 ! root 456: Avi_StopRecording();
1.1.1.5 root 457: GuiOsx_Resume();
1.1 root 458: }
459:
460: - (IBAction)captureSound:(id)sender
461: {
1.1.1.5 root 462: GuiOsx_Pause();
1.1 root 463:
464: // Get the path from the user settings
1.1.1.6 ! root 465: NSString *preferredPath = [[NSString stringWithCString:(ConfigureParams.Sound.szYMCaptureFileName) encoding:NSASCIIStringEncoding] stringByAbbreviatingWithTildeInPath];
1.1 root 466:
467: // Determine the directory and filename
468: NSString *directoryToOpen;
469: NSString *fileToPreselect;
470: if ((preferredPath != nil) && ([preferredPath length] > 0))
471: {
472: // There is existing path: we will open its directory with its file pre-selected.
473: directoryToOpen = [preferredPath stringByDeletingLastPathComponent];
474: fileToPreselect = [preferredPath lastPathComponent];
475: }
476: else
477: {
478: // Currently no path: we will open the user's directory with no file selected.
479: directoryToOpen = [@"~" stringByExpandingTildeInPath];
480: fileToPreselect = @"hatari.wav";
481: }
482:
483: // Create and configure a SavePanel for choosing what file to write
484: NSSavePanel *savePanel = [NSSavePanel savePanel];
485: [savePanel setAllowedFileTypes:[NSArray arrayWithObjects:@"ym", @"wav", nil]];
486: [savePanel setExtensionHidden:NO];
487: [savePanel setMessage:@"Please specify an .ym or a .wav file."]; // TODO: Move to localizable resources
488:
489: // Run the SavePanel, then check if the user clicked OK and selected at least one file
1.1.1.6 ! root 490: if (NSFileHandlingPanelOKButton == [savePanel runModalForDirectory:directoryToOpen file:fileToPreselect] )
1.1 root 491: {
492: // Get the path to the selected file
493: NSString *path = [savePanel filename];
494:
495: // Store the path in the user settings
496: GuiOsx_ExportPathString(path, ConfigureParams.Sound.szYMCaptureFileName, sizeof(ConfigureParams.Sound.szYMCaptureFileName));
1.1.1.6 ! root 497:
1.1 root 498: // Begin capture
499: Sound_BeginRecording(ConfigureParams.Sound.szYMCaptureFileName);
1.1.1.6 ! root 500: }
1.1 root 501:
1.1.1.5 root 502: GuiOsx_Resume();
1.1 root 503: }
504:
505: - (IBAction)endCaptureSound:(id)sender
506: {
1.1.1.5 root 507: GuiOsx_Pause();
1.1 root 508: Sound_EndRecording();
1.1.1.5 root 509: GuiOsx_Resume();
1.1 root 510: }
511:
512: - (IBAction)saveMemorySnap:(id)sender
513: {
1.1.1.5 root 514: GuiOsx_Pause();
1.1 root 515:
516: // Get the path from the user settings
1.1.1.6 ! root 517: NSString *preferredPath = [[NSString stringWithCString:(ConfigureParams.Memory.szMemoryCaptureFileName) encoding:NSASCIIStringEncoding] stringByAbbreviatingWithTildeInPath];
1.1 root 518:
519: // Determine the directory and filename
520: NSString *directoryToOpen;
521: NSString *fileToPreselect;
522: if ((preferredPath != nil) && ([preferredPath length] > 0))
523: {
524: // There is existing path: we will open its directory with its file pre-selected.
525: directoryToOpen = [preferredPath stringByDeletingLastPathComponent];
526: fileToPreselect = [preferredPath lastPathComponent];
527: }
528: else
529: {
530: // Currently no path: we will open the user's directory with the default filename.
531: directoryToOpen = [@"~" stringByExpandingTildeInPath];
532: fileToPreselect = @"hatari.sav";
1.1.1.6 ! root 533: }
1.1 root 534:
535: // Create and configure a SavePanel for choosing what file to write
536: NSSavePanel *savePanel = [NSSavePanel savePanel];
537: [savePanel setExtensionHidden:NO];
1.1.1.6 ! root 538:
1.1 root 539: // Run the SavePanel, then check if the user clicked OK and selected at least one file
1.1.1.6 ! root 540: if (NSFileHandlingPanelOKButton == [savePanel runModalForDirectory:directoryToOpen file:fileToPreselect] )
1.1 root 541: {
542: // Get the path to the selected file
543: NSString *path = [savePanel filename];
1.1.1.6 ! root 544:
1.1 root 545: // Store the path in the user settings
546: GuiOsx_ExportPathString(path, ConfigureParams.Memory.szMemoryCaptureFileName, sizeof(ConfigureParams.Memory.szMemoryCaptureFileName));
1.1.1.6 ! root 547:
1.1 root 548: // Perform the memory snapshot save
1.1.1.2 root 549: MemorySnapShot_Capture(ConfigureParams.Memory.szMemoryCaptureFileName, TRUE);
1.1.1.6 ! root 550: }
1.1 root 551:
1.1.1.5 root 552: GuiOsx_Resume();
1.1 root 553: }
554:
555: - (IBAction)restoreMemorySnap:(id)sender
556: {
1.1.1.5 root 557: GuiOsx_Pause();
1.1 root 558:
559: // Create and configure an OpenPanel
1.1.1.6 ! root 560: NSOpenPanel *openPanel = [NSOpenPanel openPanel];
1.1 root 561:
562: // Get the path from the user settings
1.1.1.6 ! root 563: NSString *oldPath = [NSString stringWithCString:(ConfigureParams.Memory.szMemoryCaptureFileName) encoding:NSASCIIStringEncoding];
1.1 root 564:
565: // Determine the directory and filename
566: NSString *directoryToOpen;
567: NSString *fileToPreselect;
568: if ((oldPath != nil) && ([oldPath length] > 0))
569: {
570: // There is existing path: we will open its directory with its file pre-selected.
571: directoryToOpen = [oldPath stringByDeletingLastPathComponent];
572: fileToPreselect = [oldPath lastPathComponent];
573: }
574: else
575: {
576: // Currently no path: we will open the user's directory with no file selected.
577: directoryToOpen = [@"~" stringByExpandingTildeInPath];
578: fileToPreselect = nil;
579: }
1.1.1.6 ! root 580:
1.1 root 581: // Run the OpenPanel, then check if the user clicked OK and selected at least one file
1.1.1.6 ! root 582: if ( (NSOKButton == [openPanel runModalForDirectory:directoryToOpen file:fileToPreselect types:nil] )
1.1 root 583: && ([[openPanel filenames] count] > 0) )
584: {
585: // Get the path to the selected file
586: NSString *path = [[openPanel filenames] objectAtIndex:0];
587:
588: // Perform the memory snapshot load
1.1.1.6 ! root 589: MemorySnapShot_Restore([path cStringUsingEncoding:NSASCIIStringEncoding], TRUE);
! 590: }
! 591:
1.1.1.5 root 592: GuiOsx_Resume();
1.1 root 593: }
594:
595: - (IBAction)doFullScreen:(id)sender
596: {
597: // A call to Screen_EnterFullScreen() would be required, but this causes a crash when using SDL runtime 1.2.11, probably due to conflicts between Cocoa and SDL.
598: // Therefore we simulate the fullscreen key press instead
599:
600: SDL_KeyboardEvent event;
1.1.1.6 ! root 601: event.type = SDL_KEYDOWN;
! 602: event.which = 0;
! 603: event.state = SDL_PRESSED;
! 604: event.keysym.sym = SDLK_F11;
! 605: SDL_PushEvent((SDL_Event*)&event); // Send the F11 key press
! 606: event.type = SDL_KEYUP;
! 607: event.state = SDL_RELEASED;
! 608: SDL_PushEvent((SDL_Event*)&event); // Send the F11 key release
1.1 root 609: }
610:
611: - (IBAction)help:(id)sender
612: {
1.1.1.6 ! root 613: [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://hatari.berlios.de/docs.html"]];
1.1 root 614: }
615:
616:
1.1.1.6 ! root 617: - (IBAction)openConfig:(id)sender {
1.1 root 618: }
619:
1.1.1.6 ! root 620: - (IBAction)saveConfig:(id)sender {
1.1 root 621: }
622:
623: @end
624:
625:
626: @implementation NSString (ReplaceSubString)
627:
628: - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
629: {
630: unsigned int bufferSize;
631: unsigned int selfLen = [self length];
632: unsigned int aStringLen = [aString length];
633: unichar *buffer;
634: NSRange localRange;
635: NSString *result;
636:
637: bufferSize = selfLen + aStringLen - aRange.length;
1.1.1.6 ! root 638: buffer = (unichar *)NSAllocateMemoryPages(bufferSize*sizeof(unichar));
1.1 root 639:
640: /* Get first part into buffer */
641: localRange.location = 0;
642: localRange.length = aRange.location;
643: [self getCharacters:buffer range:localRange];
644:
645: /* Get middle part into buffer */
646: localRange.location = 0;
647: localRange.length = aStringLen;
648: [aString getCharacters:(buffer+aRange.location) range:localRange];
649:
650: /* Get last part into buffer */
651: localRange.location = aRange.location + aRange.length;
652: localRange.length = selfLen - localRange.location;
653: [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
654:
655: /* Build output string */
656: result = [NSString stringWithCharacters:buffer length:bufferSize];
657:
658: NSDeallocateMemoryPages(buffer, bufferSize);
659:
660: return result;
661: }
662:
663: @end
664:
665:
666:
667: #ifdef main
668: # undef main
669: #endif
670:
671:
672: /* Main entry point to executable - should *not* be SDL_main! */
673: int main (int argc, char **argv)
674: {
675: /* Copy the arguments into a global variable */
676: /* This is passed if we are launched by double-clicking */
677: if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
1.1.1.6 ! root 678: gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
! 679: gArgv[0] = argv[0];
! 680: gArgv[1] = NULL;
1.1 root 681: gArgc = 1;
1.1.1.6 ! root 682: gFinderLaunch = YES;
1.1 root 683: } else {
1.1.1.6 ! root 684: int i;
1.1 root 685: gArgc = argc;
1.1.1.6 ! root 686: gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
! 687: for (i = 0; i <= argc; i++)
! 688: gArgv[i] = argv[i];
! 689: gFinderLaunch = NO;
1.1 root 690: }
691:
1.1.1.6 ! root 692: #if SDL_USE_NIB_FILE
! 693: NSApplicationMain (argc, argv);
! 694: #else
! 695: CustomApplicationMain (argc, argv);
! 696: #endif
1.1 root 697: return 0;
698: }
1.1.1.6 ! root 699:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.