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

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:        Feb-Mar 2006, S�bastien Molines - Added prefs & create floppy
        !             6:        June 2006, S�bastien Molines - Added capture and memory snapshot
        !             7: 
        !             8:     Feel free to customize this file to suit your needs
        !             9: */
        !            10: 
        !            11: #import "SDL.h"
        !            12: #import "SDLMain.h"
        !            13: #import "SDL_events.h"
        !            14: #import "Shared.h"
        !            15: #import <sys/param.h> /* for MAXPATHLEN */
        !            16: #import <unistd.h>
        !            17: 
        !            18: #include "dialog.h"
        !            19: #include "floppy.h"
        !            20: #include "reset.h"
        !            21: #include "screenSnapShot.h"
        !            22: #include "memorySnapShot.h"
        !            23: #include "sound.h"
        !            24: 
        !            25: static int    gArgc;
        !            26: static char  **gArgv;
        !            27: static BOOL   gFinderLaunch;
        !            28: 
        !            29: @interface SDLApplication : NSApplication
        !            30: @end
        !            31: 
        !            32: @implementation SDLApplication
        !            33: /* Invoked from the Quit menu item */
        !            34: - (void)terminate:(id)sender
        !            35: {
        !            36:     /* Post a SDL_QUIT event */
        !            37:     SDL_Event event;
        !            38:     event.type = SDL_QUIT;
        !            39:     SDL_PushEvent(&event);
        !            40: }
        !            41: @end
        !            42: 
        !            43: 
        !            44: /* The main class of the application, the application's delegate */
        !            45: @implementation SDLMain
        !            46: 
        !            47: - (IBAction)prefsMenu:(id)sender
        !            48: {
        !            49:        static int in_propdialog =  0;
        !            50:        
        !            51:        if (in_propdialog)
        !            52:                return;
        !            53:        ++in_propdialog;
        !            54:     Dialog_DoProperty();
        !            55:        --in_propdialog;
        !            56: }
        !            57: 
        !            58: - (IBAction)warmReset:(id)sender
        !            59: {
        !            60:        int b;
        !            61:     
        !            62:        b = NSRunAlertPanel (@"Warm reset!", 
        !            63:                        @"Really reset the emulator? All current work will be lost. Click Cancel to continue without reset.",
        !            64:                        @"OK", @"Cancel", nil);
        !            65:        //printf("b=%i\n",b);
        !            66:        if (b == 1)
        !            67:                Reset_Warm();
        !            68: }
        !            69: 
        !            70: - (IBAction)coldReset:(id)sender
        !            71: {
        !            72:        int b;
        !            73:     
        !            74:        b = NSRunAlertPanel (@"Cold reset!", 
        !            75:                        @"Really reset the emulator? All current work will be lost. Click Cancel to continue without reset.",
        !            76:                        @"OK", @"Cancel", nil);
        !            77:        //printf("b=%i\n",b);
        !            78:        if (b == 1)
        !            79:                Reset_Cold();
        !            80: }
        !            81: 
        !            82: - (IBAction)insertDiskA:(id)sender
        !            83: {
        !            84:     NSString *path = nil;
        !            85:     NSOpenPanel *openPanel = [ NSOpenPanel openPanel ];
        !            86:     
        !            87:     if ( [ openPanel runModalForDirectory:nil
        !            88:              file:@"SavedGame" types:nil ] ) {
        !            89:              
        !            90:         path = [ [ openPanel filenames ] objectAtIndex:0 ];
        !            91:     }
        !            92:     
        !            93:        if (path != nil)
        !            94:        {
        !            95:                // Make a non-const C string out of it
        !            96:                const char* constSzPath = [path cString];
        !            97:                size_t cbPath = strlen(constSzPath) + 1;
        !            98:                char szPath[cbPath];
        !            99:                strncpy(szPath, constSzPath, cbPath);   
        !           100:        
        !           101:                Floppy_InsertDiskIntoDrive(0, szPath);
        !           102:        }
        !           103: }
        !           104: 
        !           105: - (IBAction)insertDiskB:(id)sender
        !           106: {
        !           107:     NSString *path = nil;
        !           108:     NSOpenPanel *openPanel = [ NSOpenPanel openPanel ];
        !           109:     
        !           110:     if ( [ openPanel runModalForDirectory:nil
        !           111:              file:@"SavedGame" types:nil ] ) {
        !           112:              
        !           113:         path = [ [ openPanel filenames ] objectAtIndex:0 ];
        !           114:     }
        !           115:     
        !           116:        if (path != nil)
        !           117:        {
        !           118:                // Make a non-const C string out of it
        !           119:                const char* constSzPath = [path cString];
        !           120:                size_t cbPath = strlen(constSzPath) + 1;
        !           121:                char szPath[cbPath];
        !           122:                strncpy(szPath, constSzPath, cbPath);   
        !           123:        
        !           124:                Floppy_InsertDiskIntoDrive(1, szPath);
        !           125:        }
        !           126: }
        !           127: 
        !           128: /*-----------------------------------------------------------------------*/
        !           129: /*
        !           130:   Controls the enabled state of the menu items
        !           131: */
        !           132: - (BOOL)validateMenuItem:(NSMenuItem*)item
        !           133: {
        !           134:        if (item == beginCaptureAnim)
        !           135:        {
        !           136:                return !ScreenSnapShot_AreWeRecording();
        !           137:        }
        !           138:        if (item == endCaptureAnim)
        !           139:        {
        !           140:                return ScreenSnapShot_AreWeRecording();
        !           141:        }
        !           142:        if (item == beginCaptureSound)
        !           143:        {
        !           144:                return !Sound_AreWeRecording();
        !           145:        }
        !           146:        if (item == endCaptureSound)
        !           147:        {
        !           148:                return Sound_AreWeRecording();
        !           149:        }
        !           150: 
        !           151:        return YES;
        !           152: }
        !           153: 
        !           154: - (IBAction)captureScreen:(id)sender
        !           155: {
        !           156:        GuiOsx_PauseAndSwitchToCocoaUI();
        !           157:        ScreenSnapShot_SaveScreen();
        !           158:        GuiOsx_ResumeFromCocoaUI();
        !           159: }
        !           160: 
        !           161: - (IBAction)captureAnimation:(id)sender
        !           162: {
        !           163:        GuiOsx_PauseAndSwitchToCocoaUI();
        !           164:        ScreenSnapShot_BeginRecording(DialogParams.Screen.bCaptureChange, 25);
        !           165:        GuiOsx_ResumeFromCocoaUI();
        !           166: }
        !           167: 
        !           168: - (IBAction)endCaptureAnimation:(id)sender
        !           169: {
        !           170:        GuiOsx_PauseAndSwitchToCocoaUI();
        !           171:        ScreenSnapShot_EndRecording();
        !           172:        GuiOsx_ResumeFromCocoaUI();
        !           173: }
        !           174: 
        !           175: - (IBAction)captureSound:(id)sender
        !           176: {
        !           177:        GuiOsx_PauseAndSwitchToCocoaUI();
        !           178: 
        !           179:        // Get the path from the user settings
        !           180:        NSString *preferredPath = [[NSString stringWithCString:(ConfigureParams.Sound.szYMCaptureFileName)] stringByAbbreviatingWithTildeInPath];
        !           181: 
        !           182:        // Determine the directory and filename
        !           183:        NSString *directoryToOpen;
        !           184:        NSString *fileToPreselect;
        !           185:        if ((preferredPath != nil) && ([preferredPath length] > 0))
        !           186:        {
        !           187:                // There is existing path: we will open its directory with its file pre-selected.
        !           188:                directoryToOpen = [preferredPath stringByDeletingLastPathComponent];
        !           189:                fileToPreselect = [preferredPath lastPathComponent];
        !           190:        }
        !           191:        else
        !           192:        {
        !           193:                // Currently no path: we will open the user's directory with no file selected.
        !           194:                directoryToOpen = [@"~" stringByExpandingTildeInPath];
        !           195:                fileToPreselect = @"hatari.wav";
        !           196:        }       
        !           197: 
        !           198:        // Create and configure a SavePanel for choosing what file to write
        !           199:        NSSavePanel *savePanel = [NSSavePanel savePanel];
        !           200:        [savePanel setAllowedFileTypes:[NSArray arrayWithObjects:@"ym", @"wav", nil]];
        !           201:        [savePanel setExtensionHidden:NO];
        !           202:        [savePanel setMessage:@"Please specify an .ym or a .wav file."];        // TODO: Move to localizable resources
        !           203:        
        !           204:        // Run the SavePanel, then check if the user clicked OK and selected at least one file
        !           205:     if (NSFileHandlingPanelOKButton == [savePanel runModalForDirectory:directoryToOpen file:fileToPreselect] )
        !           206:        {
        !           207:                // Get the path to the selected file
        !           208:                NSString *path = [savePanel filename];
        !           209:                
        !           210:                // Store the path in the user settings
        !           211:                GuiOsx_ExportPathString(path, ConfigureParams.Sound.szYMCaptureFileName, sizeof(ConfigureParams.Sound.szYMCaptureFileName));
        !           212: 
        !           213:                // Begin capture
        !           214:                Sound_BeginRecording(ConfigureParams.Sound.szYMCaptureFileName);
        !           215:     }  
        !           216: 
        !           217:        GuiOsx_ResumeFromCocoaUI();
        !           218: }
        !           219: 
        !           220: - (IBAction)endCaptureSound:(id)sender
        !           221: {
        !           222:        GuiOsx_PauseAndSwitchToCocoaUI();
        !           223:        Sound_EndRecording();
        !           224:        GuiOsx_ResumeFromCocoaUI();
        !           225: }
        !           226: 
        !           227: - (IBAction)saveMemorySnap:(id)sender
        !           228: {
        !           229:        GuiOsx_PauseAndSwitchToCocoaUI();
        !           230: 
        !           231:        // Get the path from the user settings
        !           232:        NSString *preferredPath = [[NSString stringWithCString:(ConfigureParams.Memory.szMemoryCaptureFileName)] stringByAbbreviatingWithTildeInPath];
        !           233: 
        !           234:        // Determine the directory and filename
        !           235:        NSString *directoryToOpen;
        !           236:        NSString *fileToPreselect;
        !           237:        if ((preferredPath != nil) && ([preferredPath length] > 0))
        !           238:        {
        !           239:                // There is existing path: we will open its directory with its file pre-selected.
        !           240:                directoryToOpen = [preferredPath stringByDeletingLastPathComponent];
        !           241:                fileToPreselect = [preferredPath lastPathComponent];
        !           242:        }
        !           243:        else
        !           244:        {
        !           245:                // Currently no path: we will open the user's directory with the default filename.
        !           246:                directoryToOpen = [@"~" stringByExpandingTildeInPath];
        !           247:                fileToPreselect = @"hatari.sav";
        !           248:        }       
        !           249: 
        !           250:        // Create and configure a SavePanel for choosing what file to write
        !           251:        NSSavePanel *savePanel = [NSSavePanel savePanel];
        !           252:        [savePanel setExtensionHidden:NO];
        !           253:        
        !           254:        // Run the SavePanel, then check if the user clicked OK and selected at least one file
        !           255:     if (NSFileHandlingPanelOKButton == [savePanel runModalForDirectory:directoryToOpen file:fileToPreselect] )
        !           256:        {
        !           257:                // Get the path to the selected file
        !           258:                NSString *path = [savePanel filename];
        !           259:                
        !           260:                // Store the path in the user settings
        !           261:                GuiOsx_ExportPathString(path, ConfigureParams.Memory.szMemoryCaptureFileName, sizeof(ConfigureParams.Memory.szMemoryCaptureFileName));
        !           262: 
        !           263:                // Perform the memory snapshot save
        !           264:                MemorySnapShot_Capture(ConfigureParams.Memory.szMemoryCaptureFileName);
        !           265:     }  
        !           266: 
        !           267:        GuiOsx_ResumeFromCocoaUI();
        !           268: }
        !           269: 
        !           270: - (IBAction)restoreMemorySnap:(id)sender
        !           271: {
        !           272:        GuiOsx_PauseAndSwitchToCocoaUI();
        !           273: 
        !           274:        // Create and configure an OpenPanel
        !           275:     NSOpenPanel *openPanel = [NSOpenPanel openPanel];
        !           276: 
        !           277:        // Get the path from the user settings
        !           278:        NSString *oldPath = [NSString stringWithCString:(ConfigureParams.Memory.szMemoryCaptureFileName)];
        !           279: 
        !           280:        // Determine the directory and filename
        !           281:        NSString *directoryToOpen;
        !           282:        NSString *fileToPreselect;
        !           283:        if ((oldPath != nil) && ([oldPath length] > 0))
        !           284:        {
        !           285:                // There is existing path: we will open its directory with its file pre-selected.
        !           286:                directoryToOpen = [oldPath stringByDeletingLastPathComponent];
        !           287:                fileToPreselect = [oldPath lastPathComponent];
        !           288:        }
        !           289:        else
        !           290:        {
        !           291:                // Currently no path: we will open the user's directory with no file selected.
        !           292:                directoryToOpen = [@"~" stringByExpandingTildeInPath];
        !           293:                fileToPreselect = nil;
        !           294:        }
        !           295:        
        !           296:        // Run the OpenPanel, then check if the user clicked OK and selected at least one file
        !           297:     if ( (NSOKButton == [openPanel runModalForDirectory:directoryToOpen file:fileToPreselect types:nil] )
        !           298:            && ([[openPanel filenames] count] > 0) )
        !           299:        {
        !           300:                // Get the path to the selected file
        !           301:                NSString *path = [[openPanel filenames] objectAtIndex:0];
        !           302:                
        !           303:                // Perform the memory snapshot load
        !           304:                MemorySnapShot_Restore([path cString]);
        !           305:     }
        !           306:        
        !           307:        GuiOsx_ResumeFromCocoaUI();
        !           308: }
        !           309: 
        !           310: - (IBAction)doFullScreen:(id)sender
        !           311: {
        !           312:        // 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.
        !           313:        // Therefore we simulate the fullscreen key press instead
        !           314:        
        !           315:        SDL_KeyboardEvent event;
        !           316:     event.type = SDL_KEYDOWN;
        !           317:     event.which = 0;
        !           318:     event.state = SDL_PRESSED;
        !           319:     event.keysym.sym = SDLK_F11;
        !           320:     SDL_PushEvent((SDL_Event*)&event); // Send the F11 key press
        !           321:     event.type = SDL_KEYUP;
        !           322:     event.state = SDL_RELEASED;
        !           323:     SDL_PushEvent((SDL_Event*)&event); // Send the F11 key release
        !           324: }
        !           325: 
        !           326: - (IBAction)help:(id)sender
        !           327: {
        !           328:        [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://hatari.sourceforge.net/"]];
        !           329:        /*
        !           330:        NSRunAlertPanel (@"Help", 
        !           331:                        @"Sorry, there is no built-in help available.\n\nPlease visit http://hatari.sourceforge.net/ for more information.\n\n",
        !           332:                        @"OK", nil, nil);
        !           333:        */
        !           334: }
        !           335: 
        !           336: 
        !           337: /* Set the working directory to the .app's parent directory */
        !           338: - (void) setupWorkingDirectory:(BOOL)shouldChdir
        !           339: {
        !           340:     char parentdir[MAXPATHLEN];
        !           341:     char *c;
        !           342:     
        !           343:     strncpy ( parentdir, gArgv[0], sizeof(parentdir) );
        !           344:     c = (char*) parentdir;
        !           345: 
        !           346:     while (*c != '\0')     /* go to end */
        !           347:         c++;
        !           348:     
        !           349:     while (*c != '/')      /* back up to parent */
        !           350:         c--;
        !           351:     
        !           352:     *c++ = '\0';             /* cut off last part (binary name) */
        !           353:   
        !           354:     if (shouldChdir)
        !           355:     {
        !           356:       assert ( chdir (parentdir) == 0 );   /* chdir to the binary app's parent */
        !           357:       assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */
        !           358:     }
        !           359: }
        !           360: 
        !           361: 
        !           362: /* Called when the internal event loop has just started running */
        !           363: - (void) applicationDidFinishLaunching: (NSNotification *) note
        !           364: {
        !           365:     int status;
        !           366: 
        !           367:     /* Set the working directory to the .app's parent directory */
        !           368:     [self setupWorkingDirectory:gFinderLaunch];
        !           369: 
        !           370:     /* Hand off to main application code */
        !           371:     status = SDL_main (gArgc, gArgv);
        !           372: 
        !           373:     /* We're done, thank you for playing */
        !           374:     exit(status);
        !           375: }
        !           376: 
        !           377: @end
        !           378: 
        !           379: 
        !           380: @implementation NSString (ReplaceSubString)
        !           381: 
        !           382: - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
        !           383: {
        !           384:     unsigned int bufferSize;
        !           385:     unsigned int selfLen = [self length];
        !           386:     unsigned int aStringLen = [aString length];
        !           387:     unichar *buffer;
        !           388:     NSRange localRange;
        !           389:     NSString *result;
        !           390: 
        !           391:     bufferSize = selfLen + aStringLen - aRange.length;
        !           392:     buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
        !           393:     
        !           394:     /* Get first part into buffer */
        !           395:     localRange.location = 0;
        !           396:     localRange.length = aRange.location;
        !           397:     [self getCharacters:buffer range:localRange];
        !           398:     
        !           399:     /* Get middle part into buffer */
        !           400:     localRange.location = 0;
        !           401:     localRange.length = aStringLen;
        !           402:     [aString getCharacters:(buffer+aRange.location) range:localRange];
        !           403:      
        !           404:     /* Get last part into buffer */
        !           405:     localRange.location = aRange.location + aRange.length;
        !           406:     localRange.length = selfLen - localRange.location;
        !           407:     [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
        !           408:     
        !           409:     /* Build output string */
        !           410:     result = [NSString stringWithCharacters:buffer length:bufferSize];
        !           411:     
        !           412:     NSDeallocateMemoryPages(buffer, bufferSize);
        !           413:     
        !           414:     return result;
        !           415: }
        !           416: 
        !           417: @end
        !           418: 
        !           419: 
        !           420: 
        !           421: #ifdef main
        !           422: #  undef main
        !           423: #endif
        !           424: 
        !           425: 
        !           426: /* Main entry point to executable - should *not* be SDL_main! */
        !           427: int main (int argc, char **argv)
        !           428: {
        !           429: 
        !           430:     /* Copy the arguments into a global variable */
        !           431:     int i;
        !           432:     
        !           433:     /* This is passed if we are launched by double-clicking */
        !           434:     if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
        !           435:         gArgc = 1;
        !           436:        gFinderLaunch = YES;
        !           437:     } else {
        !           438:         gArgc = argc;
        !           439:        gFinderLaunch = NO;
        !           440:     }
        !           441:     gArgv = (char**) malloc (sizeof(*gArgv) * (gArgc+1));
        !           442:     assert (gArgv != NULL);
        !           443:     for (i = 0; i < gArgc; i++)
        !           444:         gArgv[i] = argv[i];
        !           445:     gArgv[i] = NULL;
        !           446: 
        !           447:     [SDLApplication poseAsClass:[NSApplication class]];
        !           448:     NSApplicationMain (argc, (const char**)argv);
        !           449: 
        !           450:     return 0;
        !           451: }

unix.superglobalmegacorp.com

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