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

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

unix.superglobalmegacorp.com

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