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

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:        
1.1.1.2 ! root      101:                Floppy_InsertDiskIntoDrive(0, szPath, cbPath);
1.1       root      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:        
1.1.1.2 ! root      124:                Floppy_InsertDiskIntoDrive(1, szPath, cbPath);
1.1       root      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
1.1.1.2 ! root      264:                MemorySnapShot_Capture(ConfigureParams.Memory.szMemoryCaptureFileName, TRUE);
1.1       root      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
1.1.1.2 ! root      304:                MemorySnapShot_Restore([path cString], TRUE);
1.1       root      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.