Annotation of hatari/src/gui-osx/SDLMain.m, revision 1.1.1.7

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.