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

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: {
1.1.1.5 ! root      158:        GuiOsx_Pause();
1.1       root      159:        ScreenSnapShot_SaveScreen();
1.1.1.5 ! root      160:        GuiOsx_Resume();
1.1       root      161: }
                    162: 
                    163: - (IBAction)captureAnimation:(id)sender
                    164: {
1.1.1.5 ! root      165:        GuiOsx_Pause();
1.1.1.3   root      166:        ScreenSnapShot_BeginRecording(ConfigureParams.Screen.bCaptureChange);
1.1.1.5 ! root      167:        GuiOsx_Resume();
1.1       root      168: }
                    169: 
                    170: - (IBAction)endCaptureAnimation:(id)sender
                    171: {
1.1.1.5 ! root      172:        GuiOsx_Pause();
1.1       root      173:        ScreenSnapShot_EndRecording();
1.1.1.5 ! root      174:        GuiOsx_Resume();
1.1       root      175: }
                    176: 
                    177: - (IBAction)captureSound:(id)sender
                    178: {
1.1.1.5 ! root      179:        GuiOsx_Pause();
1.1       root      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: 
1.1.1.5 ! root      219:        GuiOsx_Resume();
1.1       root      220: }
                    221: 
                    222: - (IBAction)endCaptureSound:(id)sender
                    223: {
1.1.1.5 ! root      224:        GuiOsx_Pause();
1.1       root      225:        Sound_EndRecording();
1.1.1.5 ! root      226:        GuiOsx_Resume();
1.1       root      227: }
                    228: 
                    229: - (IBAction)saveMemorySnap:(id)sender
                    230: {
1.1.1.5 ! root      231:        GuiOsx_Pause();
1.1       root      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: 
1.1.1.5 ! root      269:        GuiOsx_Resume();
1.1       root      270: }
                    271: 
                    272: - (IBAction)restoreMemorySnap:(id)sender
                    273: {
1.1.1.5 ! root      274:        GuiOsx_Pause();
1.1       root      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:        
1.1.1.5 ! root      309:        GuiOsx_Resume();
1.1       root      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: {
1.1.1.4   root      330:        [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://hatari.berlios.de/"]];
1.1       root      331: }
                    332: 
                    333: 
                    334: /* Set the working directory to the .app's parent directory */
                    335: - (void) setupWorkingDirectory:(BOOL)shouldChdir
                    336: {
                    337:     char parentdir[MAXPATHLEN];
                    338:     char *c;
                    339:     
                    340:     strncpy ( parentdir, gArgv[0], sizeof(parentdir) );
                    341:     c = (char*) parentdir;
                    342: 
                    343:     while (*c != '\0')     /* go to end */
                    344:         c++;
                    345:     
                    346:     while (*c != '/')      /* back up to parent */
                    347:         c--;
                    348:     
                    349:     *c++ = '\0';             /* cut off last part (binary name) */
                    350:   
                    351:     if (shouldChdir)
                    352:     {
                    353:       assert ( chdir (parentdir) == 0 );   /* chdir to the binary app's parent */
                    354:       assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */
                    355:     }
                    356: }
                    357: 
                    358: 
                    359: /* Called when the internal event loop has just started running */
                    360: - (void) applicationDidFinishLaunching: (NSNotification *) note
                    361: {
                    362:     int status;
                    363: 
                    364:     /* Set the working directory to the .app's parent directory */
                    365:     [self setupWorkingDirectory:gFinderLaunch];
                    366: 
                    367:     /* Hand off to main application code */
                    368:     status = SDL_main (gArgc, gArgv);
                    369: 
                    370:     /* We're done, thank you for playing */
                    371:     exit(status);
                    372: }
                    373: 
                    374: @end
                    375: 
                    376: 
                    377: @implementation NSString (ReplaceSubString)
                    378: 
                    379: - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
                    380: {
                    381:     unsigned int bufferSize;
                    382:     unsigned int selfLen = [self length];
                    383:     unsigned int aStringLen = [aString length];
                    384:     unichar *buffer;
                    385:     NSRange localRange;
                    386:     NSString *result;
                    387: 
                    388:     bufferSize = selfLen + aStringLen - aRange.length;
                    389:     buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
                    390:     
                    391:     /* Get first part into buffer */
                    392:     localRange.location = 0;
                    393:     localRange.length = aRange.location;
                    394:     [self getCharacters:buffer range:localRange];
                    395:     
                    396:     /* Get middle part into buffer */
                    397:     localRange.location = 0;
                    398:     localRange.length = aStringLen;
                    399:     [aString getCharacters:(buffer+aRange.location) range:localRange];
                    400:      
                    401:     /* Get last part into buffer */
                    402:     localRange.location = aRange.location + aRange.length;
                    403:     localRange.length = selfLen - localRange.location;
                    404:     [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
                    405:     
                    406:     /* Build output string */
                    407:     result = [NSString stringWithCharacters:buffer length:bufferSize];
                    408:     
                    409:     NSDeallocateMemoryPages(buffer, bufferSize);
                    410:     
                    411:     return result;
                    412: }
                    413: 
                    414: @end
                    415: 
                    416: 
                    417: 
                    418: #ifdef main
                    419: #  undef main
                    420: #endif
                    421: 
                    422: 
                    423: /* Main entry point to executable - should *not* be SDL_main! */
                    424: int main (int argc, char **argv)
                    425: {
                    426: 
                    427:     /* Copy the arguments into a global variable */
                    428:     int i;
                    429:     
                    430:     /* This is passed if we are launched by double-clicking */
                    431:     if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
                    432:         gArgc = 1;
                    433:        gFinderLaunch = YES;
                    434:     } else {
                    435:         gArgc = argc;
                    436:        gFinderLaunch = NO;
                    437:     }
                    438:     gArgv = (char**) malloc (sizeof(*gArgv) * (gArgc+1));
                    439:     assert (gArgv != NULL);
                    440:     for (i = 0; i < gArgc; i++)
                    441:         gArgv[i] = argv[i];
                    442:     gArgv[i] = NULL;
                    443: 
                    444:     [SDLApplication poseAsClass:[NSApplication class]];
                    445:     NSApplicationMain (argc, (const char**)argv);
                    446: 
                    447:     return 0;
                    448: }

unix.superglobalmegacorp.com

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