|
|
1.1 ! root 1: // Emacs style mode select -*- C++ -*- ! 2: //----------------------------------------------------------------------------- ! 3: // ! 4: // $Id:$ ! 5: // ! 6: // Copyright (C) 1993-1996 by id Software, Inc. ! 7: // ! 8: // This program is free software; you can redistribute it and/or ! 9: // modify it under the terms of the GNU General Public License ! 10: // as published by the Free Software Foundation; either version 2 ! 11: // of the License, or (at your option) any later version. ! 12: // ! 13: // This program is distributed in the hope that it will be useful, ! 14: // but WITHOUT ANY WARRANTY; without even the implied warranty of ! 15: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 16: // GNU General Public License for more details. ! 17: // ! 18: // $Log:$ ! 19: // ! 20: // DESCRIPTION: ! 21: // DOOM main program (D_DoomMain) and game loop (D_DoomLoop), ! 22: // plus functions to determine game mode (shareware, registered), ! 23: // parse command line parameters, configure game parameters (turbo), ! 24: // and call the startup functions. ! 25: // ! 26: //----------------------------------------------------------------------------- ! 27: ! 28: ! 29: static const char rcsid[] = "$Id: d_main.c,v 1.8 1997/02/03 22:45:09 b1 Exp $"; ! 30: ! 31: #define BGCOLOR 7 ! 32: #define FGCOLOR 8 ! 33: ! 34: ! 35: #ifdef NORMALUNIX ! 36: #include <stdio.h> ! 37: #include <stdlib.h> ! 38: #include <unistd.h> ! 39: #include <sys/types.h> ! 40: #include <sys/stat.h> ! 41: #include <fcntl.h> ! 42: #endif ! 43: ! 44: ! 45: #include "doomdef.h" ! 46: #include "doomstat.h" ! 47: ! 48: #include "dstrings.h" ! 49: #include "sounds.h" ! 50: ! 51: ! 52: #include "z_zone.h" ! 53: #include "w_wad.h" ! 54: #include "s_sound.h" ! 55: #include "v_video.h" ! 56: ! 57: #include "f_finale.h" ! 58: #include "f_wipe.h" ! 59: ! 60: #include "m_argv.h" ! 61: #include "m_misc.h" ! 62: #include "m_menu.h" ! 63: ! 64: #include "i_system.h" ! 65: #include "i_sound.h" ! 66: #include "i_video.h" ! 67: ! 68: #include "g_game.h" ! 69: ! 70: #include "hu_stuff.h" ! 71: #include "wi_stuff.h" ! 72: #include "st_stuff.h" ! 73: #include "am_map.h" ! 74: ! 75: #include "p_setup.h" ! 76: #include "r_local.h" ! 77: ! 78: ! 79: #include "d_main.h" ! 80: ! 81: // ! 82: // D-DoomLoop() ! 83: // Not a globally visible function, ! 84: // just included for source reference, ! 85: // called by D_DoomMain, never exits. ! 86: // Manages timing and IO, ! 87: // calls all ?_Responder, ?_Ticker, and ?_Drawer, ! 88: // calls I_GetTime, I_StartFrame, and I_StartTic ! 89: // ! 90: void D_DoomLoop (void); ! 91: ! 92: ! 93: char* wadfiles[MAXWADFILES]; ! 94: ! 95: ! 96: boolean devparm; // started game with -devparm ! 97: boolean nomonsters; // checkparm of -nomonsters ! 98: boolean respawnparm; // checkparm of -respawn ! 99: boolean fastparm; // checkparm of -fast ! 100: ! 101: boolean drone; ! 102: ! 103: boolean singletics = false; // debug flag to cancel adaptiveness ! 104: ! 105: ! 106: ! 107: //extern int soundVolume; ! 108: //extern int sfxVolume; ! 109: //extern int musicVolume; ! 110: ! 111: extern boolean inhelpscreens; ! 112: ! 113: skill_t startskill; ! 114: int startepisode; ! 115: int startmap; ! 116: boolean autostart; ! 117: ! 118: FILE* debugfile; ! 119: ! 120: boolean advancedemo; ! 121: ! 122: ! 123: ! 124: ! 125: char wadfile[1024]; // primary wad file ! 126: char mapdir[1024]; // directory of development maps ! 127: char basedefault[1024]; // default file ! 128: ! 129: ! 130: void D_CheckNetGame (void); ! 131: void D_ProcessEvents (void); ! 132: void G_BuildTiccmd (ticcmd_t* cmd); ! 133: void D_DoAdvanceDemo (void); ! 134: ! 135: ! 136: // ! 137: // EVENT HANDLING ! 138: // ! 139: // Events are asynchronous inputs generally generated by the game user. ! 140: // Events can be discarded if no responder claims them ! 141: // ! 142: event_t events[MAXEVENTS]; ! 143: int eventhead; ! 144: int eventtail; ! 145: ! 146: ! 147: // ! 148: // D_PostEvent ! 149: // Called by the I/O functions when input is detected ! 150: // ! 151: void D_PostEvent (event_t* ev) ! 152: { ! 153: events[eventhead] = *ev; ! 154: eventhead = (++eventhead)&(MAXEVENTS-1); ! 155: } ! 156: ! 157: ! 158: // ! 159: // D_ProcessEvents ! 160: // Send all the events of the given timestamp down the responder chain ! 161: // ! 162: void D_ProcessEvents (void) ! 163: { ! 164: event_t* ev; ! 165: ! 166: // IF STORE DEMO, DO NOT ACCEPT INPUT ! 167: if ( ( gamemode == commercial ) ! 168: && (W_CheckNumForName("map01")<0) ) ! 169: return; ! 170: ! 171: for ( ; eventtail != eventhead ; eventtail = (++eventtail)&(MAXEVENTS-1) ) ! 172: { ! 173: ev = &events[eventtail]; ! 174: if (M_Responder (ev)) ! 175: continue; // menu ate the event ! 176: G_Responder (ev); ! 177: } ! 178: } ! 179: ! 180: ! 181: ! 182: ! 183: // ! 184: // D_Display ! 185: // draw current display, possibly wiping it from the previous ! 186: // ! 187: ! 188: // wipegamestate can be set to -1 to force a wipe on the next draw ! 189: gamestate_t wipegamestate = GS_DEMOSCREEN; ! 190: extern boolean setsizeneeded; ! 191: extern int showMessages; ! 192: void R_ExecuteSetViewSize (void); ! 193: ! 194: void D_Display (void) ! 195: { ! 196: static boolean viewactivestate = false; ! 197: static boolean menuactivestate = false; ! 198: static boolean inhelpscreensstate = false; ! 199: static boolean fullscreen = false; ! 200: static gamestate_t oldgamestate = -1; ! 201: static int borderdrawcount; ! 202: int nowtime; ! 203: int tics; ! 204: int wipestart; ! 205: int y; ! 206: boolean done; ! 207: boolean wipe; ! 208: boolean redrawsbar; ! 209: ! 210: if (nodrawers) ! 211: return; // for comparative timing / profiling ! 212: ! 213: redrawsbar = false; ! 214: ! 215: // change the view size if needed ! 216: if (setsizeneeded) ! 217: { ! 218: R_ExecuteSetViewSize (); ! 219: oldgamestate = -1; // force background redraw ! 220: borderdrawcount = 3; ! 221: } ! 222: ! 223: // save the current screen if about to wipe ! 224: if (gamestate != wipegamestate) ! 225: { ! 226: wipe = true; ! 227: wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); ! 228: } ! 229: else ! 230: wipe = false; ! 231: ! 232: if (gamestate == GS_LEVEL && gametic) ! 233: HU_Erase(); ! 234: ! 235: // do buffered drawing ! 236: switch (gamestate) ! 237: { ! 238: case GS_LEVEL: ! 239: if (!gametic) ! 240: break; ! 241: if (automapactive) ! 242: AM_Drawer (); ! 243: if (wipe || (viewheight != 200 && fullscreen) ) ! 244: redrawsbar = true; ! 245: if (inhelpscreensstate && !inhelpscreens) ! 246: redrawsbar = true; // just put away the help screen ! 247: ST_Drawer (viewheight == 200, redrawsbar ); ! 248: fullscreen = viewheight == 200; ! 249: break; ! 250: ! 251: case GS_INTERMISSION: ! 252: WI_Drawer (); ! 253: break; ! 254: ! 255: case GS_FINALE: ! 256: F_Drawer (); ! 257: break; ! 258: ! 259: case GS_DEMOSCREEN: ! 260: D_PageDrawer (); ! 261: break; ! 262: } ! 263: ! 264: // draw buffered stuff to screen ! 265: I_UpdateNoBlit (); ! 266: ! 267: // draw the view directly ! 268: if (gamestate == GS_LEVEL && !automapactive && gametic) ! 269: R_RenderPlayerView (&players[displayplayer]); ! 270: ! 271: if (gamestate == GS_LEVEL && gametic) ! 272: HU_Drawer (); ! 273: ! 274: // clean up border stuff ! 275: if (gamestate != oldgamestate && gamestate != GS_LEVEL) ! 276: I_SetPalette (W_CacheLumpName ("PLAYPAL",PU_CACHE)); ! 277: ! 278: // see if the border needs to be initially drawn ! 279: if (gamestate == GS_LEVEL && oldgamestate != GS_LEVEL) ! 280: { ! 281: viewactivestate = false; // view was not active ! 282: R_FillBackScreen (); // draw the pattern into the back screen ! 283: } ! 284: ! 285: // see if the border needs to be updated to the screen ! 286: if (gamestate == GS_LEVEL && !automapactive && scaledviewwidth != 320) ! 287: { ! 288: if (menuactive || menuactivestate || !viewactivestate) ! 289: borderdrawcount = 3; ! 290: if (borderdrawcount) ! 291: { ! 292: R_DrawViewBorder (); // erase old menu stuff ! 293: borderdrawcount--; ! 294: } ! 295: ! 296: } ! 297: ! 298: menuactivestate = menuactive; ! 299: viewactivestate = viewactive; ! 300: inhelpscreensstate = inhelpscreens; ! 301: oldgamestate = wipegamestate = gamestate; ! 302: ! 303: // draw pause pic ! 304: if (paused) ! 305: { ! 306: if (automapactive) ! 307: y = 4; ! 308: else ! 309: y = viewwindowy+4; ! 310: V_DrawPatchDirect(viewwindowx+(scaledviewwidth-68)/2, ! 311: y,0,W_CacheLumpName ("M_PAUSE", PU_CACHE)); ! 312: } ! 313: ! 314: ! 315: // menus go directly to the screen ! 316: M_Drawer (); // menu is drawn even on top of everything ! 317: NetUpdate (); // send out any new accumulation ! 318: ! 319: ! 320: // normal update ! 321: if (!wipe) ! 322: { ! 323: I_FinishUpdate (); // page flip or blit buffer ! 324: return; ! 325: } ! 326: ! 327: // wipe update ! 328: wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); ! 329: ! 330: wipestart = I_GetTime () - 1; ! 331: ! 332: do ! 333: { ! 334: do ! 335: { ! 336: nowtime = I_GetTime (); ! 337: tics = nowtime - wipestart; ! 338: } while (!tics); ! 339: wipestart = nowtime; ! 340: done = wipe_ScreenWipe(wipe_Melt ! 341: , 0, 0, SCREENWIDTH, SCREENHEIGHT, tics); ! 342: I_UpdateNoBlit (); ! 343: M_Drawer (); // menu is drawn even on top of wipes ! 344: I_FinishUpdate (); // page flip or blit buffer ! 345: } while (!done); ! 346: } ! 347: ! 348: ! 349: ! 350: // ! 351: // D_DoomLoop ! 352: // ! 353: extern boolean demorecording; ! 354: ! 355: void D_DoomLoop (void) ! 356: { ! 357: if (demorecording) ! 358: G_BeginRecording (); ! 359: ! 360: if (M_CheckParm ("-debugfile")) ! 361: { ! 362: char filename[20]; ! 363: sprintf (filename,"debug%i.txt",consoleplayer); ! 364: printf ("debug output to: %s\n",filename); ! 365: debugfile = fopen (filename,"w"); ! 366: } ! 367: ! 368: I_InitGraphics (); ! 369: ! 370: while (1) ! 371: { ! 372: // frame syncronous IO operations ! 373: I_StartFrame (); ! 374: ! 375: // process one or more tics ! 376: if (singletics) ! 377: { ! 378: I_StartTic (); ! 379: D_ProcessEvents (); ! 380: G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]); ! 381: if (advancedemo) ! 382: D_DoAdvanceDemo (); ! 383: M_Ticker (); ! 384: G_Ticker (); ! 385: gametic++; ! 386: maketic++; ! 387: } ! 388: else ! 389: { ! 390: TryRunTics (); // will run at least one tic ! 391: } ! 392: ! 393: S_UpdateSounds (players[consoleplayer].mo);// move positional sounds ! 394: ! 395: // Update display, next frame, with current state. ! 396: D_Display (); ! 397: ! 398: #ifndef SNDSERV ! 399: // Sound mixing for the buffer is snychronous. ! 400: I_UpdateSound(); ! 401: #endif ! 402: // Synchronous sound output is explicitly called. ! 403: #ifndef SNDINTR ! 404: // Update sound output. ! 405: I_SubmitSound(); ! 406: #endif ! 407: } ! 408: } ! 409: ! 410: ! 411: ! 412: // ! 413: // DEMO LOOP ! 414: // ! 415: int demosequence; ! 416: int pagetic; ! 417: char *pagename; ! 418: ! 419: ! 420: // ! 421: // D_PageTicker ! 422: // Handles timing for warped projection ! 423: // ! 424: void D_PageTicker (void) ! 425: { ! 426: if (--pagetic < 0) ! 427: D_AdvanceDemo (); ! 428: } ! 429: ! 430: ! 431: ! 432: // ! 433: // D_PageDrawer ! 434: // ! 435: void D_PageDrawer (void) ! 436: { ! 437: V_DrawPatch (0,0, 0, W_CacheLumpName(pagename, PU_CACHE)); ! 438: } ! 439: ! 440: ! 441: // ! 442: // D_AdvanceDemo ! 443: // Called after each demo or intro demosequence finishes ! 444: // ! 445: void D_AdvanceDemo (void) ! 446: { ! 447: advancedemo = true; ! 448: } ! 449: ! 450: ! 451: // ! 452: // This cycles through the demo sequences. ! 453: // FIXME - version dependend demo numbers? ! 454: // ! 455: void D_DoAdvanceDemo (void) ! 456: { ! 457: players[consoleplayer].playerstate = PST_LIVE; // not reborn ! 458: advancedemo = false; ! 459: usergame = false; // no save / end game here ! 460: paused = false; ! 461: gameaction = ga_nothing; ! 462: ! 463: if ( gamemode == retail ) ! 464: demosequence = (demosequence+1)%7; ! 465: else ! 466: demosequence = (demosequence+1)%6; ! 467: ! 468: switch (demosequence) ! 469: { ! 470: case 0: ! 471: if ( gamemode == commercial ) ! 472: pagetic = 35 * 11; ! 473: else ! 474: pagetic = 170; ! 475: gamestate = GS_DEMOSCREEN; ! 476: pagename = "TITLEPIC"; ! 477: if ( gamemode == commercial ) ! 478: S_StartMusic(mus_dm2ttl); ! 479: else ! 480: S_StartMusic (mus_intro); ! 481: break; ! 482: case 1: ! 483: G_DeferedPlayDemo ("demo1"); ! 484: break; ! 485: case 2: ! 486: pagetic = 200; ! 487: gamestate = GS_DEMOSCREEN; ! 488: pagename = "CREDIT"; ! 489: break; ! 490: case 3: ! 491: G_DeferedPlayDemo ("demo2"); ! 492: break; ! 493: case 4: ! 494: gamestate = GS_DEMOSCREEN; ! 495: if ( gamemode == commercial) ! 496: { ! 497: pagetic = 35 * 11; ! 498: pagename = "TITLEPIC"; ! 499: S_StartMusic(mus_dm2ttl); ! 500: } ! 501: else ! 502: { ! 503: pagetic = 200; ! 504: ! 505: if ( gamemode == retail ) ! 506: pagename = "CREDIT"; ! 507: else ! 508: pagename = "HELP2"; ! 509: } ! 510: break; ! 511: case 5: ! 512: G_DeferedPlayDemo ("demo3"); ! 513: break; ! 514: // THE DEFINITIVE DOOM Special Edition demo ! 515: case 6: ! 516: G_DeferedPlayDemo ("demo4"); ! 517: break; ! 518: } ! 519: } ! 520: ! 521: ! 522: ! 523: // ! 524: // D_StartTitle ! 525: // ! 526: void D_StartTitle (void) ! 527: { ! 528: gameaction = ga_nothing; ! 529: demosequence = -1; ! 530: D_AdvanceDemo (); ! 531: } ! 532: ! 533: ! 534: ! 535: ! 536: // print title for every printed line ! 537: char title[128]; ! 538: ! 539: ! 540: ! 541: // ! 542: // D_AddFile ! 543: // ! 544: void D_AddFile (char *file) ! 545: { ! 546: int numwadfiles; ! 547: char *newfile; ! 548: ! 549: for (numwadfiles = 0 ; wadfiles[numwadfiles] ; numwadfiles++) ! 550: ; ! 551: ! 552: newfile = malloc (strlen(file)+1); ! 553: strcpy (newfile, file); ! 554: ! 555: wadfiles[numwadfiles] = newfile; ! 556: } ! 557: ! 558: // ! 559: // IdentifyVersion ! 560: // Checks availability of IWAD files by name, ! 561: // to determine whether registered/commercial features ! 562: // should be executed (notably loading PWAD's). ! 563: // ! 564: void IdentifyVersion (void) ! 565: { ! 566: ! 567: char* doom1wad; ! 568: char* doomwad; ! 569: char* doomuwad; ! 570: char* doom2wad; ! 571: ! 572: char* doom2fwad; ! 573: char* plutoniawad; ! 574: char* tntwad; ! 575: ! 576: #ifdef NORMALUNIX ! 577: char *home; ! 578: char *doomwaddir; ! 579: doomwaddir = getenv("DOOMWADDIR"); ! 580: if (!doomwaddir) ! 581: doomwaddir = "."; ! 582: ! 583: // Commercial. ! 584: doom2wad = malloc(strlen(doomwaddir)+1+9+1); ! 585: sprintf(doom2wad, "%s/doom2.wad", doomwaddir); ! 586: ! 587: // Retail. ! 588: doomuwad = malloc(strlen(doomwaddir)+1+8+1); ! 589: sprintf(doomuwad, "%s/doomu.wad", doomwaddir); ! 590: ! 591: // Registered. ! 592: doomwad = malloc(strlen(doomwaddir)+1+8+1); ! 593: sprintf(doomwad, "%s/doom.wad", doomwaddir); ! 594: ! 595: // Shareware. ! 596: doom1wad = malloc(strlen(doomwaddir)+1+9+1); ! 597: sprintf(doom1wad, "%s/doom1.wad", doomwaddir); ! 598: ! 599: // Bug, dear Shawn. ! 600: // Insufficient malloc, caused spurious realloc errors. ! 601: plutoniawad = malloc(strlen(doomwaddir)+1+/*9*/12+1); ! 602: sprintf(plutoniawad, "%s/plutonia.wad", doomwaddir); ! 603: ! 604: tntwad = malloc(strlen(doomwaddir)+1+9+1); ! 605: sprintf(tntwad, "%s/tnt.wad", doomwaddir); ! 606: ! 607: ! 608: // French stuff. ! 609: doom2fwad = malloc(strlen(doomwaddir)+1+10+1); ! 610: sprintf(doom2fwad, "%s/doom2f.wad", doomwaddir); ! 611: ! 612: home = getenv("HOME"); ! 613: if (!home) ! 614: I_Error("Please set $HOME to your home directory"); ! 615: sprintf(basedefault, "%s/.doomrc", home); ! 616: #endif ! 617: ! 618: if (M_CheckParm ("-shdev")) ! 619: { ! 620: gamemode = shareware; ! 621: devparm = true; ! 622: D_AddFile (DEVDATA"doom1.wad"); ! 623: D_AddFile (DEVMAPS"data_se/texture1.lmp"); ! 624: D_AddFile (DEVMAPS"data_se/pnames.lmp"); ! 625: strcpy (basedefault,DEVDATA"default.cfg"); ! 626: return; ! 627: } ! 628: ! 629: if (M_CheckParm ("-regdev")) ! 630: { ! 631: gamemode = registered; ! 632: devparm = true; ! 633: D_AddFile (DEVDATA"doom.wad"); ! 634: D_AddFile (DEVMAPS"data_se/texture1.lmp"); ! 635: D_AddFile (DEVMAPS"data_se/texture2.lmp"); ! 636: D_AddFile (DEVMAPS"data_se/pnames.lmp"); ! 637: strcpy (basedefault,DEVDATA"default.cfg"); ! 638: return; ! 639: } ! 640: ! 641: if (M_CheckParm ("-comdev")) ! 642: { ! 643: gamemode = commercial; ! 644: devparm = true; ! 645: /* I don't bother ! 646: if(plutonia) ! 647: D_AddFile (DEVDATA"plutonia.wad"); ! 648: else if(tnt) ! 649: D_AddFile (DEVDATA"tnt.wad"); ! 650: else*/ ! 651: D_AddFile (DEVDATA"doom2.wad"); ! 652: ! 653: D_AddFile (DEVMAPS"cdata/texture1.lmp"); ! 654: D_AddFile (DEVMAPS"cdata/pnames.lmp"); ! 655: strcpy (basedefault,DEVDATA"default.cfg"); ! 656: return; ! 657: } ! 658: ! 659: if ( !access (doom2fwad,R_OK) ) ! 660: { ! 661: gamemode = commercial; ! 662: // C'est ridicule! ! 663: // Let's handle languages in config files, okay? ! 664: language = french; ! 665: printf("French version\n"); ! 666: D_AddFile (doom2fwad); ! 667: return; ! 668: } ! 669: ! 670: if ( !access (doom2wad,R_OK) ) ! 671: { ! 672: gamemode = commercial; ! 673: D_AddFile (doom2wad); ! 674: return; ! 675: } ! 676: ! 677: if ( !access (plutoniawad, R_OK ) ) ! 678: { ! 679: gamemode = commercial; ! 680: D_AddFile (plutoniawad); ! 681: return; ! 682: } ! 683: ! 684: if ( !access ( tntwad, R_OK ) ) ! 685: { ! 686: gamemode = commercial; ! 687: D_AddFile (tntwad); ! 688: return; ! 689: } ! 690: ! 691: if ( !access (doomuwad,R_OK) ) ! 692: { ! 693: gamemode = retail; ! 694: D_AddFile (doomuwad); ! 695: return; ! 696: } ! 697: ! 698: if ( !access (doomwad,R_OK) ) ! 699: { ! 700: gamemode = registered; ! 701: D_AddFile (doomwad); ! 702: return; ! 703: } ! 704: ! 705: if ( !access (doom1wad,R_OK) ) ! 706: { ! 707: gamemode = shareware; ! 708: D_AddFile (doom1wad); ! 709: return; ! 710: } ! 711: ! 712: printf("Game mode indeterminate.\n"); ! 713: gamemode = indetermined; ! 714: ! 715: // We don't abort. Let's see what the PWAD contains. ! 716: //exit(1); ! 717: //I_Error ("Game mode indeterminate\n"); ! 718: } ! 719: ! 720: // ! 721: // Find a Response File ! 722: // ! 723: void FindResponseFile (void) ! 724: { ! 725: int i; ! 726: #define MAXARGVS 100 ! 727: ! 728: for (i = 1;i < myargc;i++) ! 729: if (myargv[i][0] == '@') ! 730: { ! 731: FILE * handle; ! 732: int size; ! 733: int k; ! 734: int index; ! 735: int indexinfile; ! 736: char *infile; ! 737: char *file; ! 738: char *moreargs[20]; ! 739: char *firstargv; ! 740: ! 741: // READ THE RESPONSE FILE INTO MEMORY ! 742: handle = fopen (&myargv[i][1],"rb"); ! 743: if (!handle) ! 744: { ! 745: printf ("\nNo such response file!"); ! 746: exit(1); ! 747: } ! 748: printf("Found response file %s!\n",&myargv[i][1]); ! 749: fseek (handle,0,SEEK_END); ! 750: size = ftell(handle); ! 751: fseek (handle,0,SEEK_SET); ! 752: file = malloc (size); ! 753: fread (file,size,1,handle); ! 754: fclose (handle); ! 755: ! 756: // KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG ! 757: for (index = 0,k = i+1; k < myargc; k++) ! 758: moreargs[index++] = myargv[k]; ! 759: ! 760: firstargv = myargv[0]; ! 761: myargv = malloc(sizeof(char *)*MAXARGVS); ! 762: memset(myargv,0,sizeof(char *)*MAXARGVS); ! 763: myargv[0] = firstargv; ! 764: ! 765: infile = file; ! 766: indexinfile = k = 0; ! 767: indexinfile++; // SKIP PAST ARGV[0] (KEEP IT) ! 768: do ! 769: { ! 770: myargv[indexinfile++] = infile+k; ! 771: while(k < size && ! 772: ((*(infile+k)>= ' '+1) && (*(infile+k)<='z'))) ! 773: k++; ! 774: *(infile+k) = 0; ! 775: while(k < size && ! 776: ((*(infile+k)<= ' ') || (*(infile+k)>'z'))) ! 777: k++; ! 778: } while(k < size); ! 779: ! 780: for (k = 0;k < index;k++) ! 781: myargv[indexinfile++] = moreargs[k]; ! 782: myargc = indexinfile; ! 783: ! 784: // DISPLAY ARGS ! 785: printf("%d command-line args:\n",myargc); ! 786: for (k=1;k<myargc;k++) ! 787: printf("%s\n",myargv[k]); ! 788: ! 789: break; ! 790: } ! 791: } ! 792: ! 793: ! 794: // ! 795: // D_DoomMain ! 796: // ! 797: void D_DoomMain (void) ! 798: { ! 799: int p; ! 800: char file[256]; ! 801: ! 802: FindResponseFile (); ! 803: ! 804: IdentifyVersion (); ! 805: ! 806: setbuf (stdout, NULL); ! 807: modifiedgame = false; ! 808: ! 809: nomonsters = M_CheckParm ("-nomonsters"); ! 810: respawnparm = M_CheckParm ("-respawn"); ! 811: fastparm = M_CheckParm ("-fast"); ! 812: devparm = M_CheckParm ("-devparm"); ! 813: if (M_CheckParm ("-altdeath")) ! 814: deathmatch = 2; ! 815: else if (M_CheckParm ("-deathmatch")) ! 816: deathmatch = 1; ! 817: ! 818: switch ( gamemode ) ! 819: { ! 820: case retail: ! 821: sprintf (title, ! 822: " " ! 823: "The Ultimate DOOM Startup v%i.%i" ! 824: " ", ! 825: VERSION/100,VERSION%100); ! 826: break; ! 827: case shareware: ! 828: sprintf (title, ! 829: " " ! 830: "DOOM Shareware Startup v%i.%i" ! 831: " ", ! 832: VERSION/100,VERSION%100); ! 833: break; ! 834: case registered: ! 835: sprintf (title, ! 836: " " ! 837: "DOOM Registered Startup v%i.%i" ! 838: " ", ! 839: VERSION/100,VERSION%100); ! 840: break; ! 841: case commercial: ! 842: sprintf (title, ! 843: " " ! 844: "DOOM 2: Hell on Earth v%i.%i" ! 845: " ", ! 846: VERSION/100,VERSION%100); ! 847: break; ! 848: /*FIXME ! 849: case pack_plut: ! 850: sprintf (title, ! 851: " " ! 852: "DOOM 2: Plutonia Experiment v%i.%i" ! 853: " ", ! 854: VERSION/100,VERSION%100); ! 855: break; ! 856: case pack_tnt: ! 857: sprintf (title, ! 858: " " ! 859: "DOOM 2: TNT - Evilution v%i.%i" ! 860: " ", ! 861: VERSION/100,VERSION%100); ! 862: break; ! 863: */ ! 864: default: ! 865: sprintf (title, ! 866: " " ! 867: "Public DOOM - v%i.%i" ! 868: " ", ! 869: VERSION/100,VERSION%100); ! 870: break; ! 871: } ! 872: ! 873: printf ("%s\n",title); ! 874: ! 875: if (devparm) ! 876: printf(D_DEVSTR); ! 877: ! 878: if (M_CheckParm("-cdrom")) ! 879: { ! 880: printf(D_CDROM); ! 881: mkdir("c:\\doomdata",0); ! 882: strcpy (basedefault,"c:/doomdata/default.cfg"); ! 883: } ! 884: ! 885: // turbo option ! 886: if ( (p=M_CheckParm ("-turbo")) ) ! 887: { ! 888: int scale = 200; ! 889: extern int forwardmove[2]; ! 890: extern int sidemove[2]; ! 891: ! 892: if (p<myargc-1) ! 893: scale = atoi (myargv[p+1]); ! 894: if (scale < 10) ! 895: scale = 10; ! 896: if (scale > 400) ! 897: scale = 400; ! 898: printf ("turbo scale: %i%%\n",scale); ! 899: forwardmove[0] = forwardmove[0]*scale/100; ! 900: forwardmove[1] = forwardmove[1]*scale/100; ! 901: sidemove[0] = sidemove[0]*scale/100; ! 902: sidemove[1] = sidemove[1]*scale/100; ! 903: } ! 904: ! 905: // add any files specified on the command line with -file wadfile ! 906: // to the wad list ! 907: // ! 908: // convenience hack to allow -wart e m to add a wad file ! 909: // prepend a tilde to the filename so wadfile will be reloadable ! 910: p = M_CheckParm ("-wart"); ! 911: if (p) ! 912: { ! 913: myargv[p][4] = 'p'; // big hack, change to -warp ! 914: ! 915: // Map name handling. ! 916: switch (gamemode ) ! 917: { ! 918: case shareware: ! 919: case retail: ! 920: case registered: ! 921: sprintf (file,"~"DEVMAPS"E%cM%c.wad", ! 922: myargv[p+1][0], myargv[p+2][0]); ! 923: printf("Warping to Episode %s, Map %s.\n", ! 924: myargv[p+1],myargv[p+2]); ! 925: break; ! 926: ! 927: case commercial: ! 928: default: ! 929: p = atoi (myargv[p+1]); ! 930: if (p<10) ! 931: sprintf (file,"~"DEVMAPS"cdata/map0%i.wad", p); ! 932: else ! 933: sprintf (file,"~"DEVMAPS"cdata/map%i.wad", p); ! 934: break; ! 935: } ! 936: D_AddFile (file); ! 937: } ! 938: ! 939: p = M_CheckParm ("-file"); ! 940: if (p) ! 941: { ! 942: // the parms after p are wadfile/lump names, ! 943: // until end of parms or another - preceded parm ! 944: modifiedgame = true; // homebrew levels ! 945: while (++p != myargc && myargv[p][0] != '-') ! 946: D_AddFile (myargv[p]); ! 947: } ! 948: ! 949: p = M_CheckParm ("-playdemo"); ! 950: ! 951: if (!p) ! 952: p = M_CheckParm ("-timedemo"); ! 953: ! 954: if (p && p < myargc-1) ! 955: { ! 956: sprintf (file,"%s.lmp", myargv[p+1]); ! 957: D_AddFile (file); ! 958: printf("Playing demo %s.lmp.\n",myargv[p+1]); ! 959: } ! 960: ! 961: // get skill / episode / map from parms ! 962: startskill = sk_medium; ! 963: startepisode = 1; ! 964: startmap = 1; ! 965: autostart = false; ! 966: ! 967: ! 968: p = M_CheckParm ("-skill"); ! 969: if (p && p < myargc-1) ! 970: { ! 971: startskill = myargv[p+1][0]-'1'; ! 972: autostart = true; ! 973: } ! 974: ! 975: p = M_CheckParm ("-episode"); ! 976: if (p && p < myargc-1) ! 977: { ! 978: startepisode = myargv[p+1][0]-'0'; ! 979: startmap = 1; ! 980: autostart = true; ! 981: } ! 982: ! 983: p = M_CheckParm ("-timer"); ! 984: if (p && p < myargc-1 && deathmatch) ! 985: { ! 986: int time; ! 987: time = atoi(myargv[p+1]); ! 988: printf("Levels will end after %d minute",time); ! 989: if (time>1) ! 990: printf("s"); ! 991: printf(".\n"); ! 992: } ! 993: ! 994: p = M_CheckParm ("-avg"); ! 995: if (p && p < myargc-1 && deathmatch) ! 996: printf("Austin Virtual Gaming: Levels will end after 20 minutes\n"); ! 997: ! 998: p = M_CheckParm ("-warp"); ! 999: if (p && p < myargc-1) ! 1000: { ! 1001: if (gamemode == commercial) ! 1002: startmap = atoi (myargv[p+1]); ! 1003: else ! 1004: { ! 1005: startepisode = myargv[p+1][0]-'0'; ! 1006: startmap = myargv[p+2][0]-'0'; ! 1007: } ! 1008: autostart = true; ! 1009: } ! 1010: ! 1011: // init subsystems ! 1012: printf ("V_Init: allocate screens.\n"); ! 1013: V_Init (); ! 1014: ! 1015: printf ("M_LoadDefaults: Load system defaults.\n"); ! 1016: M_LoadDefaults (); // load before initing other systems ! 1017: ! 1018: printf ("Z_Init: Init zone memory allocation daemon. \n"); ! 1019: Z_Init (); ! 1020: ! 1021: printf ("W_Init: Init WADfiles.\n"); ! 1022: W_InitMultipleFiles (wadfiles); ! 1023: ! 1024: ! 1025: // Check for -file in shareware ! 1026: if (modifiedgame) ! 1027: { ! 1028: // These are the lumps that will be checked in IWAD, ! 1029: // if any one is not present, execution will be aborted. ! 1030: char name[23][8]= ! 1031: { ! 1032: "e2m1","e2m2","e2m3","e2m4","e2m5","e2m6","e2m7","e2m8","e2m9", ! 1033: "e3m1","e3m3","e3m3","e3m4","e3m5","e3m6","e3m7","e3m8","e3m9", ! 1034: "dphoof","bfgga0","heada1","cybra1","spida1d1" ! 1035: }; ! 1036: int i; ! 1037: ! 1038: if ( gamemode == shareware) ! 1039: I_Error("\nYou cannot -file with the shareware " ! 1040: "version. Register!"); ! 1041: ! 1042: // Check for fake IWAD with right name, ! 1043: // but w/o all the lumps of the registered version. ! 1044: if (gamemode == registered) ! 1045: for (i = 0;i < 23; i++) ! 1046: if (W_CheckNumForName(name[i])<0) ! 1047: I_Error("\nThis is not the registered version."); ! 1048: } ! 1049: ! 1050: // Iff additonal PWAD files are used, print modified banner ! 1051: if (modifiedgame) ! 1052: { ! 1053: /*m*/printf ( ! 1054: "===========================================================================\n" ! 1055: "ATTENTION: This version of DOOM has been modified. If you would like to\n" ! 1056: "get a copy of the original game, call 1-800-IDGAMES or see the readme file.\n" ! 1057: " You will not receive technical support for modified games.\n" ! 1058: " press enter to continue\n" ! 1059: "===========================================================================\n" ! 1060: ); ! 1061: getchar (); ! 1062: } ! 1063: ! 1064: ! 1065: // Check and print which version is executed. ! 1066: switch ( gamemode ) ! 1067: { ! 1068: case shareware: ! 1069: case indetermined: ! 1070: printf ( ! 1071: "===========================================================================\n" ! 1072: " Shareware!\n" ! 1073: "===========================================================================\n" ! 1074: ); ! 1075: break; ! 1076: case registered: ! 1077: case retail: ! 1078: case commercial: ! 1079: printf ( ! 1080: "===========================================================================\n" ! 1081: " Commercial product - do not distribute!\n" ! 1082: " Please report software piracy to the SPA: 1-800-388-PIR8\n" ! 1083: "===========================================================================\n" ! 1084: ); ! 1085: break; ! 1086: ! 1087: default: ! 1088: // Ouch. ! 1089: break; ! 1090: } ! 1091: ! 1092: printf ("M_Init: Init miscellaneous info.\n"); ! 1093: M_Init (); ! 1094: ! 1095: printf ("R_Init: Init DOOM refresh daemon - "); ! 1096: R_Init (); ! 1097: ! 1098: printf ("\nP_Init: Init Playloop state.\n"); ! 1099: P_Init (); ! 1100: ! 1101: printf ("I_Init: Setting up machine state.\n"); ! 1102: I_Init (); ! 1103: ! 1104: printf ("D_CheckNetGame: Checking network game status.\n"); ! 1105: D_CheckNetGame (); ! 1106: ! 1107: printf ("S_Init: Setting up sound.\n"); ! 1108: S_Init (snd_SfxVolume /* *8 */, snd_MusicVolume /* *8*/ ); ! 1109: ! 1110: printf ("HU_Init: Setting up heads up display.\n"); ! 1111: HU_Init (); ! 1112: ! 1113: printf ("ST_Init: Init status bar.\n"); ! 1114: ST_Init (); ! 1115: ! 1116: // check for a driver that wants intermission stats ! 1117: p = M_CheckParm ("-statcopy"); ! 1118: if (p && p<myargc-1) ! 1119: { ! 1120: // for statistics driver ! 1121: extern void* statcopy; ! 1122: ! 1123: statcopy = (void*)atoi(myargv[p+1]); ! 1124: printf ("External statistics registered.\n"); ! 1125: } ! 1126: ! 1127: // start the apropriate game based on parms ! 1128: p = M_CheckParm ("-record"); ! 1129: ! 1130: if (p && p < myargc-1) ! 1131: { ! 1132: G_RecordDemo (myargv[p+1]); ! 1133: autostart = true; ! 1134: } ! 1135: ! 1136: p = M_CheckParm ("-playdemo"); ! 1137: if (p && p < myargc-1) ! 1138: { ! 1139: singledemo = true; // quit after one demo ! 1140: G_DeferedPlayDemo (myargv[p+1]); ! 1141: D_DoomLoop (); // never returns ! 1142: } ! 1143: ! 1144: p = M_CheckParm ("-timedemo"); ! 1145: if (p && p < myargc-1) ! 1146: { ! 1147: G_TimeDemo (myargv[p+1]); ! 1148: D_DoomLoop (); // never returns ! 1149: } ! 1150: ! 1151: p = M_CheckParm ("-loadgame"); ! 1152: if (p && p < myargc-1) ! 1153: { ! 1154: if (M_CheckParm("-cdrom")) ! 1155: sprintf(file, "c:\\doomdata\\"SAVEGAMENAME"%c.dsg",myargv[p+1][0]); ! 1156: else ! 1157: sprintf(file, SAVEGAMENAME"%c.dsg",myargv[p+1][0]); ! 1158: G_LoadGame (file); ! 1159: } ! 1160: ! 1161: ! 1162: if ( gameaction != ga_loadgame ) ! 1163: { ! 1164: if (autostart || netgame) ! 1165: G_InitNew (startskill, startepisode, startmap); ! 1166: else ! 1167: D_StartTitle (); // start up intro loop ! 1168: ! 1169: } ! 1170: ! 1171: D_DoomLoop (); // never returns ! 1172: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.