Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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