Subversion Repositories Kolibri OS

Rev

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