Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | pmbaty | 1 | /* |
| 2 | SDL - Simple DirectMedia Layer |
||
| 3 | Copyright (C) 1997-2004 Sam Lantinga |
||
| 4 | |||
| 5 | This library is free software; you can redistribute it and/or |
||
| 6 | modify it under the terms of the GNU Library General Public |
||
| 7 | License as published by the Free Software Foundation; either |
||
| 8 | version 2 of the License, or (at your option) any later version. |
||
| 9 | |||
| 10 | This library is distributed in the hope that it will be useful, |
||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
| 13 | Library General Public License for more details. |
||
| 14 | |||
| 15 | You should have received a copy of the GNU Library General Public |
||
| 16 | License along with this library; if not, write to the Free |
||
| 17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
| 18 | |||
| 19 | Sam Lantinga |
||
| 20 | slouken@libsdl.org |
||
| 21 | */ |
||
| 22 | |||
| 23 | #ifdef SAVE_RCSID |
||
| 24 | static char rcsid = |
||
| 25 | "@(#) $Id: SDL_main.c,v 1.1.1.1 2006/03/17 19:54:28 zicodxx Exp $"; |
||
| 26 | #endif |
||
| 27 | |||
| 28 | /* This file takes care of command line argument parsing, and stdio redirection |
||
| 29 | in the MacOS environment. |
||
| 30 | */ |
||
| 31 | |||
| 32 | #include <stdio.h> |
||
| 33 | #include <stdlib.h> |
||
| 34 | #include <string.h> |
||
| 35 | #include <ctype.h> |
||
| 36 | #if defined(__APPLE__) && defined(__MACH__) |
||
| 37 | #include <Carbon/Carbon.h> |
||
| 38 | #elif TARGET_API_MAC_CARBON |
||
| 39 | #include <Carbon.h> |
||
| 40 | #else |
||
| 41 | #include <Dialogs.h> |
||
| 42 | #include <Fonts.h> |
||
| 43 | #include <Events.h> |
||
| 44 | #include <Resources.h> |
||
| 45 | #include <Folders.h> |
||
| 46 | #endif |
||
| 47 | |||
| 48 | /* Include the SDL main definition header */ |
||
| 49 | #include <SDL.h> |
||
| 50 | #include "SDL_main.h" |
||
| 51 | #ifdef main |
||
| 52 | #undef main |
||
| 53 | #endif |
||
| 54 | |||
| 55 | /* The standard output files */ |
||
| 56 | #define STDOUT_FILE "stdout.txt" |
||
| 57 | #define STDERR_FILE "stderr.txt" |
||
| 58 | |||
| 59 | #if !defined(__MWERKS__) && !TARGET_API_MAC_CARBON |
||
| 60 | /* In MPW, the qd global has been removed from the libraries */ |
||
| 61 | QDGlobals qd; |
||
| 62 | #endif |
||
| 63 | |||
| 64 | /* Structure for keeping prefs in 1 variable */ |
||
| 65 | typedef struct { |
||
| 66 | Str255 command_line; |
||
| 67 | Str255 video_driver_name; |
||
| 68 | Boolean output_to_file; |
||
| 69 | } PrefsRecord; |
||
| 70 | |||
| 71 | /* See if the command key is held down at startup */ |
||
| 72 | static Boolean CommandKeyIsDown(void) |
||
| 73 | { |
||
| 74 | KeyMap theKeyMap; |
||
| 75 | |||
| 76 | GetKeys(theKeyMap); |
||
| 77 | |||
| 78 | if (((unsigned char *) theKeyMap)[6] & 0x80) { |
||
| 79 | return(true); |
||
| 80 | } |
||
| 81 | return(false); |
||
| 82 | } |
||
| 83 | |||
| 84 | /* Parse a command line buffer into arguments */ |
||
| 85 | static int ParseCommandLine(char *cmdline, char **argv) |
||
| 86 | { |
||
| 87 | char *bufp; |
||
| 88 | int argc; |
||
| 89 | |||
| 90 | argc = 0; |
||
| 91 | for ( bufp = cmdline; *bufp; ) { |
||
| 92 | /* Skip leading whitespace */ |
||
| 93 | while ( isspace(*bufp) ) { |
||
| 94 | ++bufp; |
||
| 95 | } |
||
| 96 | /* Skip over argument */ |
||
| 97 | if ( *bufp == '"' ) { |
||
| 98 | ++bufp; |
||
| 99 | if ( *bufp ) { |
||
| 100 | if ( argv ) { |
||
| 101 | argv[argc] = bufp; |
||
| 102 | } |
||
| 103 | ++argc; |
||
| 104 | } |
||
| 105 | /* Skip over word */ |
||
| 106 | while ( *bufp && (*bufp != '"') ) { |
||
| 107 | ++bufp; |
||
| 108 | } |
||
| 109 | } else { |
||
| 110 | if ( *bufp ) { |
||
| 111 | if ( argv ) { |
||
| 112 | argv[argc] = bufp; |
||
| 113 | } |
||
| 114 | ++argc; |
||
| 115 | } |
||
| 116 | /* Skip over word */ |
||
| 117 | while ( *bufp && ! isspace(*bufp) ) { |
||
| 118 | ++bufp; |
||
| 119 | } |
||
| 120 | } |
||
| 121 | if ( *bufp ) { |
||
| 122 | if ( argv ) { |
||
| 123 | *bufp = '\0'; |
||
| 124 | } |
||
| 125 | ++bufp; |
||
| 126 | } |
||
| 127 | } |
||
| 128 | if ( argv ) { |
||
| 129 | argv[argc] = NULL; |
||
| 130 | } |
||
| 131 | return(argc); |
||
| 132 | } |
||
| 133 | |||
| 134 | /* Remove the output files if there was no output written */ |
||
| 135 | static void cleanup_output(void) |
||
| 136 | { |
||
| 137 | FILE *file; |
||
| 138 | int empty; |
||
| 139 | |||
| 140 | /* Flush the output in case anything is queued */ |
||
| 141 | fclose(stdout); |
||
| 142 | fclose(stderr); |
||
| 143 | |||
| 144 | /* See if the files have any output in them */ |
||
| 145 | file = fopen(STDOUT_FILE, "rb"); |
||
| 146 | if ( file ) { |
||
| 147 | empty = (fgetc(file) == EOF) ? 1 : 0; |
||
| 148 | fclose(file); |
||
| 149 | if ( empty ) { |
||
| 150 | remove(STDOUT_FILE); |
||
| 151 | } |
||
| 152 | } |
||
| 153 | file = fopen(STDERR_FILE, "rb"); |
||
| 154 | if ( file ) { |
||
| 155 | empty = (fgetc(file) == EOF) ? 1 : 0; |
||
| 156 | fclose(file); |
||
| 157 | if ( empty ) { |
||
| 158 | remove(STDERR_FILE); |
||
| 159 | } |
||
| 160 | } |
||
| 161 | } |
||
| 162 | |||
| 163 | static int getCurrentAppName (StrFileName name) { |
||
| 164 | |||
| 165 | ProcessSerialNumber process; |
||
| 166 | ProcessInfoRec process_info; |
||
| 167 | FSSpec process_fsp; |
||
| 168 | |||
| 169 | process.highLongOfPSN = 0; |
||
| 170 | process.lowLongOfPSN = kCurrentProcess; |
||
| 171 | process_info.processInfoLength = sizeof (process_info); |
||
| 172 | process_info.processName = NULL; |
||
| 173 | process_info.processAppSpec = &process_fsp; |
||
| 174 | |||
| 175 | if ( noErr != GetProcessInformation (&process, &process_info) ) |
||
| 176 | return 0; |
||
| 177 | |||
| 178 | memcpy (name, process_fsp.name, process_fsp.name[0] + 1); |
||
| 179 | return 1; |
||
| 180 | } |
||
| 181 | |||
| 182 | static int getPrefsFile (FSSpec *prefs_fsp, int create) { |
||
| 183 | |||
| 184 | /* The prefs file name is the application name, possibly truncated, */ |
||
| 185 | /* plus " Preferences */ |
||
| 186 | |||
| 187 | #define SUFFIX " Preferences" |
||
| 188 | #define MAX_NAME 19 /* 31 - strlen (SUFFIX) */ |
||
| 189 | |||
| 190 | short volume_ref_number; |
||
| 191 | long directory_id; |
||
| 192 | StrFileName prefs_name; |
||
| 193 | StrFileName app_name; |
||
| 194 | |||
| 195 | /* Get Preferences folder - works with Multiple Users */ |
||
| 196 | if ( noErr != FindFolder ( kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder, |
||
| 197 | &volume_ref_number, &directory_id) ) |
||
| 198 | exit (-1); |
||
| 199 | |||
| 200 | if ( ! getCurrentAppName (app_name) ) |
||
| 201 | exit (-1); |
||
| 202 | |||
| 203 | /* Truncate if name is too long */ |
||
| 204 | if (app_name[0] > MAX_NAME ) |
||
| 205 | app_name[0] = MAX_NAME; |
||
| 206 | |||
| 207 | memcpy (prefs_name + 1, app_name + 1, app_name[0]); |
||
| 208 | memcpy (prefs_name + app_name[0] + 1, SUFFIX, strlen (SUFFIX)); |
||
| 209 | prefs_name[0] = app_name[0] + strlen (SUFFIX); |
||
| 210 | |||
| 211 | /* Make the file spec for prefs file */ |
||
| 212 | if ( noErr != FSMakeFSSpec (volume_ref_number, directory_id, prefs_name, prefs_fsp) ) |
||
| 213 | if ( !create ) |
||
| 214 | return 0; |
||
| 215 | else { |
||
| 216 | /* Create the prefs file */ |
||
| 217 | memcpy (prefs_fsp->name, prefs_name, prefs_name[0] + 1); |
||
| 218 | prefs_fsp->parID = directory_id; |
||
| 219 | prefs_fsp->vRefNum = volume_ref_number; |
||
| 220 | |||
| 221 | FSpCreateResFile (prefs_fsp, '????', 'pref', 0); |
||
| 222 | |||
| 223 | if ( noErr != ResError () ) |
||
| 224 | return 0; |
||
| 225 | } |
||
| 226 | |||
| 227 | return 1; |
||
| 228 | } |
||
| 229 | |||
| 230 | static int readPrefsResource (PrefsRecord *prefs) { |
||
| 231 | |||
| 232 | Handle prefs_handle; |
||
| 233 | |||
| 234 | prefs_handle = Get1Resource( 'CLne', 128 ); |
||
| 235 | |||
| 236 | if (prefs_handle != NULL) { |
||
| 237 | int offset = 0; |
||
| 238 | |||
| 239 | HLock(prefs_handle); |
||
| 240 | |||
| 241 | /* Get command line string */ |
||
| 242 | memcpy (prefs->command_line, *prefs_handle, (*prefs_handle)[0]+1); |
||
| 243 | |||
| 244 | /* Get video driver name */ |
||
| 245 | offset += (*prefs_handle)[0] + 1; |
||
| 246 | memcpy (prefs->video_driver_name, *prefs_handle + offset, (*prefs_handle)[offset] + 1); |
||
| 247 | |||
| 248 | /* Get save-to-file option (1 or 0) */ |
||
| 249 | offset += (*prefs_handle)[offset] + 1; |
||
| 250 | prefs->output_to_file = (*prefs_handle)[offset]; |
||
| 251 | |||
| 252 | ReleaseResource( prefs_handle ); |
||
| 253 | |||
| 254 | return ResError() == noErr; |
||
| 255 | } |
||
| 256 | |||
| 257 | return 0; |
||
| 258 | } |
||
| 259 | |||
| 260 | static int writePrefsResource (PrefsRecord *prefs, short resource_file) { |
||
| 261 | |||
| 262 | Handle prefs_handle; |
||
| 263 | |||
| 264 | UseResFile (resource_file); |
||
| 265 | |||
| 266 | prefs_handle = Get1Resource ( 'CLne', 128 ); |
||
| 267 | if (prefs_handle != NULL) |
||
| 268 | RemoveResource (prefs_handle); |
||
| 269 | |||
| 270 | prefs_handle = NewHandle ( prefs->command_line[0] + prefs->video_driver_name[0] + 4 ); |
||
| 271 | if (prefs_handle != NULL) { |
||
| 272 | |||
| 273 | int offset; |
||
| 274 | |||
| 275 | HLock (prefs_handle); |
||
| 276 | |||
| 277 | /* Command line text */ |
||
| 278 | offset = 0; |
||
| 279 | memcpy (*prefs_handle, prefs->command_line, prefs->command_line[0] + 1); |
||
| 280 | |||
| 281 | /* Video driver name */ |
||
| 282 | offset += prefs->command_line[0] + 1; |
||
| 283 | memcpy (*prefs_handle + offset, prefs->video_driver_name, prefs->video_driver_name[0] + 1); |
||
| 284 | |||
| 285 | /* Output-to-file option */ |
||
| 286 | offset += prefs->video_driver_name[0] + 1; |
||
| 287 | *( *((char**)prefs_handle) + offset) = (char)prefs->output_to_file; |
||
| 288 | *( *((char**)prefs_handle) + offset + 1) = 0; |
||
| 289 | |||
| 290 | AddResource (prefs_handle, 'CLne', 128, "\pCommand Line"); |
||
| 291 | WriteResource (prefs_handle); |
||
| 292 | UpdateResFile (resource_file); |
||
| 293 | DisposeHandle (prefs_handle); |
||
| 294 | |||
| 295 | return ResError() == noErr; |
||
| 296 | } |
||
| 297 | |||
| 298 | return 0; |
||
| 299 | } |
||
| 300 | |||
| 301 | static int readPreferences (PrefsRecord *prefs) { |
||
| 302 | |||
| 303 | int no_error = 1; |
||
| 304 | FSSpec prefs_fsp; |
||
| 305 | |||
| 306 | /* Check for prefs file first */ |
||
| 307 | if ( getPrefsFile (&prefs_fsp, 0) ) { |
||
| 308 | |||
| 309 | short prefs_resource; |
||
| 310 | |||
| 311 | prefs_resource = FSpOpenResFile (&prefs_fsp, fsRdPerm); |
||
| 312 | if ( prefs_resource == -1 ) /* this shouldn't happen, but... */ |
||
| 313 | return 0; |
||
| 314 | |||
| 315 | UseResFile (prefs_resource); |
||
| 316 | no_error = readPrefsResource (prefs); |
||
| 317 | CloseResFile (prefs_resource); |
||
| 318 | } |
||
| 319 | |||
| 320 | /* Fall back to application's resource fork (reading only, so this is safe) */ |
||
| 321 | else { |
||
| 322 | |||
| 323 | no_error = readPrefsResource (prefs); |
||
| 324 | } |
||
| 325 | |||
| 326 | return no_error; |
||
| 327 | } |
||
| 328 | |||
| 329 | static int writePreferences (PrefsRecord *prefs) { |
||
| 330 | |||
| 331 | int no_error = 1; |
||
| 332 | FSSpec prefs_fsp; |
||
| 333 | |||
| 334 | /* Get prefs file, create if it doesn't exist */ |
||
| 335 | if ( getPrefsFile (&prefs_fsp, 1) ) { |
||
| 336 | |||
| 337 | short prefs_resource; |
||
| 338 | |||
| 339 | prefs_resource = FSpOpenResFile (&prefs_fsp, fsRdWrPerm); |
||
| 340 | if (prefs_resource == -1) |
||
| 341 | return 0; |
||
| 342 | no_error = writePrefsResource (prefs, prefs_resource); |
||
| 343 | CloseResFile (prefs_resource); |
||
| 344 | } |
||
| 345 | |||
| 346 | return no_error; |
||
| 347 | } |
||
| 348 | |||
| 349 | /* This is where execution begins */ |
||
| 350 | int main(int argc, char *argv[]) |
||
| 351 | { |
||
| 352 | |||
| 353 | #pragma unused(argc, argv) |
||
| 354 | |||
| 355 | #define DEFAULT_ARGS "\p" /* pascal string for default args */ |
||
| 356 | #define DEFAULT_VIDEO_DRIVER "\ptoolbox" /* pascal string for default video driver name */ |
||
| 357 | #define DEFAULT_OUTPUT_TO_FILE 1 /* 1 == output to file, 0 == no output */ |
||
| 358 | |||
| 359 | #define VIDEO_ID_DRAWSPROCKET 1 /* these correspond to popup menu choices */ |
||
| 360 | #define VIDEO_ID_TOOLBOX 2 |
||
| 361 | |||
| 362 | PrefsRecord prefs = { DEFAULT_ARGS, DEFAULT_VIDEO_DRIVER, DEFAULT_OUTPUT_TO_FILE }; |
||
| 363 | |||
| 364 | int nargs; |
||
| 365 | char **args; |
||
| 366 | char *commandLine; |
||
| 367 | |||
| 368 | StrFileName appNameText; |
||
| 369 | int videodriver = VIDEO_ID_TOOLBOX; |
||
| 370 | int settingsChanged = 0; |
||
| 371 | |||
| 372 | long i; |
||
| 373 | |||
| 374 | /* Kyle's SDL command-line dialog code ... */ |
||
| 375 | #if !TARGET_API_MAC_CARBON |
||
| 376 | InitGraf (&qd.thePort); |
||
| 377 | InitFonts (); |
||
| 378 | InitWindows (); |
||
| 379 | InitMenus (); |
||
| 380 | InitDialogs (nil); |
||
| 381 | #endif |
||
| 382 | InitCursor (); |
||
| 383 | FlushEvents(everyEvent,0); |
||
| 384 | #if !TARGET_API_MAC_CARBON |
||
| 385 | MaxApplZone (); |
||
| 386 | #endif |
||
| 387 | MoreMasters (); |
||
| 388 | MoreMasters (); |
||
| 389 | #if 0 |
||
| 390 | /* Intialize SDL, and put up a dialog if we fail */ |
||
| 391 | if ( SDL_Init (0) < 0 ) { |
||
| 392 | |||
| 393 | #define kErr_OK 1 |
||
| 394 | #define kErr_Text 2 |
||
| 395 | |||
| 396 | DialogPtr errorDialog; |
||
| 397 | short dummyType; |
||
| 398 | Rect dummyRect; |
||
| 399 | Handle dummyHandle; |
||
| 400 | short itemHit; |
||
| 401 | |||
| 402 | errorDialog = GetNewDialog (1001, nil, (WindowPtr)-1); |
||
| 403 | DrawDialog (errorDialog); |
||
| 404 | |||
| 405 | GetDialogItem (errorDialog, kErr_Text, &dummyType, &dummyHandle, &dummyRect); |
||
| 406 | SetDialogItemText (dummyHandle, "\pError Initializing SDL"); |
||
| 407 | |||
| 408 | SetPort (errorDialog); |
||
| 409 | do { |
||
| 410 | ModalDialog (nil, &itemHit); |
||
| 411 | } while (itemHit != kErr_OK); |
||
| 412 | |||
| 413 | DisposeDialog (errorDialog); |
||
| 414 | exit (-1); |
||
| 415 | } |
||
| 416 | atexit(cleanup_output); |
||
| 417 | atexit(SDL_Quit); |
||
| 418 | #endif |
||
| 419 | |||
| 420 | /* Set up SDL's QuickDraw environment */ |
||
| 421 | #if !TARGET_API_MAC_CARBON |
||
| 422 | SDL_InitQuickDraw(&qd); |
||
| 423 | #endif |
||
| 424 | |||
| 425 | if ( readPreferences (&prefs) ) { |
||
| 426 | |||
| 427 | if (memcmp (prefs.video_driver_name+1, "DSp", 3) == 0) |
||
| 428 | videodriver = 1; |
||
| 429 | else if (memcmp (prefs.video_driver_name+1, "toolbox", 7) == 0) |
||
| 430 | videodriver = 2; |
||
| 431 | } |
||
| 432 | |||
| 433 | if ( CommandKeyIsDown() ) { |
||
| 434 | |||
| 435 | #define kCL_OK 1 |
||
| 436 | #define kCL_Cancel 2 |
||
| 437 | #define kCL_Text 3 |
||
| 438 | #define kCL_File 4 |
||
| 439 | #define kCL_Video 6 |
||
| 440 | |||
| 441 | DialogPtr commandDialog; |
||
| 442 | short dummyType; |
||
| 443 | Rect dummyRect; |
||
| 444 | Handle dummyHandle; |
||
| 445 | short itemHit; |
||
| 446 | |||
| 447 | /* Assume that they will change settings, rather than do exhaustive check */ |
||
| 448 | settingsChanged = 1; |
||
| 449 | |||
| 450 | /* Create dialog and display it */ |
||
| 451 | commandDialog = GetNewDialog (1000, nil, (WindowPtr)-1); |
||
| 452 | SetPortDialogPort (commandDialog); |
||
| 453 | |||
| 454 | /* Setup controls */ |
||
| 455 | GetDialogItem (commandDialog, kCL_File, &dummyType, &dummyHandle, &dummyRect); /* MJS */ |
||
| 456 | SetControlValue ((ControlHandle)dummyHandle, prefs.output_to_file ); |
||
| 457 | |||
| 458 | GetDialogItem (commandDialog, kCL_Text, &dummyType, &dummyHandle, &dummyRect); |
||
| 459 | SetDialogItemText (dummyHandle, prefs.command_line); |
||
| 460 | |||
| 461 | GetDialogItem (commandDialog, kCL_Video, &dummyType, &dummyHandle, &dummyRect); |
||
| 462 | SetControlValue ((ControlRef)dummyHandle, videodriver); |
||
| 463 | |||
| 464 | SetDialogDefaultItem (commandDialog, kCL_OK); |
||
| 465 | SetDialogCancelItem (commandDialog, kCL_Cancel); |
||
| 466 | |||
| 467 | do { |
||
| 468 | |||
| 469 | ModalDialog(nil, &itemHit); /* wait for user response */ |
||
| 470 | |||
| 471 | /* Toggle command-line output checkbox */ |
||
| 472 | if ( itemHit == kCL_File ) { |
||
| 473 | GetDialogItem(commandDialog, kCL_File, &dummyType, &dummyHandle, &dummyRect); /* MJS */ |
||
| 474 | SetControlValue((ControlHandle)dummyHandle, !GetControlValue((ControlHandle)dummyHandle) ); |
||
| 475 | } |
||
| 476 | |||
| 477 | } while (itemHit != kCL_OK && itemHit != kCL_Cancel); |
||
| 478 | |||
| 479 | /* Get control values, even if they did not change */ |
||
| 480 | GetDialogItem (commandDialog, kCL_Text, &dummyType, &dummyHandle, &dummyRect); /* MJS */ |
||
| 481 | GetDialogItemText (dummyHandle, prefs.command_line); |
||
| 482 | |||
| 483 | GetDialogItem (commandDialog, kCL_File, &dummyType, &dummyHandle, &dummyRect); /* MJS */ |
||
| 484 | prefs.output_to_file = GetControlValue ((ControlHandle)dummyHandle); |
||
| 485 | |||
| 486 | GetDialogItem (commandDialog, kCL_Video, &dummyType, &dummyHandle, &dummyRect); |
||
| 487 | videodriver = GetControlValue ((ControlRef)dummyHandle); |
||
| 488 | |||
| 489 | DisposeDialog (commandDialog); |
||
| 490 | |||
| 491 | if (itemHit == kCL_Cancel ) { |
||
| 492 | exit (0); |
||
| 493 | } |
||
| 494 | } |
||
| 495 | |||
| 496 | /* Set pseudo-environment variables for video driver, update prefs */ |
||
| 497 | switch ( videodriver ) { |
||
| 498 | case VIDEO_ID_DRAWSPROCKET: |
||
| 499 | SDL_putenv ("SDL_VIDEODRIVER=DSp"); |
||
| 500 | memcpy (prefs.video_driver_name, "\pDSp", 4); |
||
| 501 | break; |
||
| 502 | case VIDEO_ID_TOOLBOX: |
||
| 503 | SDL_putenv ("SDL_VIDEODRIVER=toolbox"); |
||
| 504 | memcpy (prefs.video_driver_name, "\ptoolbox", 8); |
||
| 505 | break; |
||
| 506 | } |
||
| 507 | /* Redirect standard I/O to files */ |
||
| 508 | if ( prefs.output_to_file ) { |
||
| 509 | freopen (STDOUT_FILE, "w", stdout); |
||
| 510 | freopen (STDERR_FILE, "w", stderr); |
||
| 511 | } else { |
||
| 512 | fclose (stdout); |
||
| 513 | fclose (stderr); |
||
| 514 | } |
||
| 515 | |||
| 516 | if (settingsChanged) { |
||
| 517 | /* Save the prefs, even if they might not have changed (but probably did) */ |
||
| 518 | if ( ! writePreferences (&prefs) ) |
||
| 519 | fprintf (stderr, "WARNING: Could not save preferences!\n"); |
||
| 520 | } |
||
| 521 | |||
| 522 | getCurrentAppName (appNameText); /* check for error here ? */ |
||
| 523 | |||
| 524 | commandLine = (char*) malloc (appNameText[0] + prefs.command_line[0] + 2); |
||
| 525 | if ( commandLine == NULL ) { |
||
| 526 | exit(-1); |
||
| 527 | } |
||
| 528 | |||
| 529 | /* Rather than rewrite ParseCommandLine method, let's replace */ |
||
| 530 | /* any spaces in application name with underscores, */ |
||
| 531 | /* so that the app name is only 1 argument */ |
||
| 532 | for (i = 1; i < 1+appNameText[0]; i++) |
||
| 533 | if ( appNameText[i] == ' ' ) appNameText[i] = '_'; |
||
| 534 | |||
| 535 | /* Copy app name & full command text to command-line C-string */ |
||
| 536 | memcpy (commandLine, appNameText + 1, appNameText[0]); |
||
| 537 | commandLine[appNameText[0]] = ' '; |
||
| 538 | memcpy (commandLine + appNameText[0] + 1, prefs.command_line + 1, prefs.command_line[0]); |
||
| 539 | commandLine[ appNameText[0] + 1 + prefs.command_line[0] ] = '\0'; |
||
| 540 | |||
| 541 | /* Parse C-string into argv and argc */ |
||
| 542 | nargs = ParseCommandLine (commandLine, NULL); |
||
| 543 | args = (char **)malloc((nargs+1)*(sizeof *args)); |
||
| 544 | if ( args == NULL ) { |
||
| 545 | exit(-1); |
||
| 546 | } |
||
| 547 | ParseCommandLine (commandLine, args); |
||
| 548 | |||
| 549 | /* Run the main application code */ |
||
| 550 | SDL_main(nargs, args); |
||
| 551 | free (args); |
||
| 552 | free (commandLine); |
||
| 553 | |||
| 554 | /* Remove useless stdout.txt and stderr.txt */ |
||
| 555 | cleanup_output (); |
||
| 556 | |||
| 557 | /* Exit cleanly, calling atexit() functions */ |
||
| 558 | exit (0); |
||
| 559 | |||
| 560 | /* Never reached, but keeps the compiler quiet */ |
||
| 561 | return (0); |
||
| 562 | } |