home *** CD-ROM | disk | FTP | other *** search
/ 100 af Verdens Bedste Spil / 100Spil.iso / dos / wolf3d / source / wolfsrc.1 / WL_MAIN.C < prev    next >
C/C++ Source or Header  |  1994-04-13  |  34KB  |  1,617 lines

  1. // WL_MAIN.C
  2.  
  3. #include <conio.h>
  4. #include "WL_DEF.H"
  5. #pragma hdrstop
  6.  
  7.  
  8. /*
  9. =============================================================================
  10.  
  11.                            WOLFENSTEIN 3-D
  12.  
  13.                       An Id Software production
  14.  
  15.                            by John Carmack
  16.  
  17. =============================================================================
  18. */
  19.  
  20. /*
  21. =============================================================================
  22.  
  23.                          LOCAL CONSTANTS
  24.  
  25. =============================================================================
  26. */
  27.  
  28.  
  29. #define FOCALLENGTH     (0x5700l)               // in global coordinates
  30. #define VIEWGLOBAL      0x10000                 // globals visable flush to wall
  31.  
  32. #define VIEWWIDTH       256                     // size of view window
  33. #define VIEWHEIGHT      144
  34.  
  35. /*
  36. =============================================================================
  37.  
  38.                          GLOBAL VARIABLES
  39.  
  40. =============================================================================
  41. */
  42.  
  43. char            str[80],str2[20];
  44. int                tedlevelnum;
  45. boolean         tedlevel;
  46. boolean         nospr;
  47. boolean         IsA386;
  48. int                     dirangle[9] = {0,ANGLES/8,2*ANGLES/8,3*ANGLES/8,4*ANGLES/8,
  49.     5*ANGLES/8,6*ANGLES/8,7*ANGLES/8,ANGLES};
  50.  
  51. //
  52. // proejection variables
  53. //
  54. fixed           focallength;
  55. unsigned        screenofs;
  56. int             viewwidth;
  57. int             viewheight;
  58. int             centerx;
  59. int             shootdelta;                     // pixels away from centerx a target can be
  60. fixed           scale,maxslope;
  61. long            heightnumerator;
  62. int                     minheightdiv;
  63.  
  64.  
  65. void            Quit (char *error);
  66.  
  67. boolean         startgame,loadedgame,virtualreality;
  68. int             mouseadjustment;
  69.  
  70. char    configname[13]="CONFIG.";
  71.  
  72.  
  73. /*
  74. =============================================================================
  75.  
  76.                          LOCAL VARIABLES
  77.  
  78. =============================================================================
  79. */
  80.  
  81.  
  82. /*
  83. ====================
  84. =
  85. = ReadConfig
  86. =
  87. ====================
  88. */
  89.  
  90. void ReadConfig(void)
  91. {
  92.     int                     file;
  93.     SDMode          sd;
  94.     SMMode          sm;
  95.     SDSMode         sds;
  96.  
  97.  
  98.     if ( (file = open(configname,O_BINARY | O_RDONLY)) != -1)
  99.     {
  100.     //
  101.     // valid config file
  102.     //
  103.         read(file,Scores,sizeof(HighScore) * MaxScores);
  104.  
  105.         read(file,&sd,sizeof(sd));
  106.         read(file,&sm,sizeof(sm));
  107.         read(file,&sds,sizeof(sds));
  108.  
  109.         read(file,&mouseenabled,sizeof(mouseenabled));
  110.         read(file,&joystickenabled,sizeof(joystickenabled));
  111.         read(file,&joypadenabled,sizeof(joypadenabled));
  112.         read(file,&joystickprogressive,sizeof(joystickprogressive));
  113.         read(file,&joystickport,sizeof(joystickport));
  114.  
  115.         read(file,&dirscan,sizeof(dirscan));
  116.         read(file,&buttonscan,sizeof(buttonscan));
  117.         read(file,&buttonmouse,sizeof(buttonmouse));
  118.         read(file,&buttonjoy,sizeof(buttonjoy));
  119.  
  120.         read(file,&viewsize,sizeof(viewsize));
  121.         read(file,&mouseadjustment,sizeof(mouseadjustment));
  122.  
  123.         close(file);
  124.  
  125.         if (sd == sdm_AdLib && !AdLibPresent && !SoundBlasterPresent)
  126.         {
  127.             sd = sdm_PC;
  128.             sd = smm_Off;
  129.         }
  130.  
  131.         if ((sds == sds_SoundBlaster && !SoundBlasterPresent) ||
  132.             (sds == sds_SoundSource && !SoundSourcePresent))
  133.             sds = sds_Off;
  134.  
  135.         if (!MousePresent)
  136.             mouseenabled = false;
  137.         if (!JoysPresent[joystickport])
  138.             joystickenabled = false;
  139.  
  140.         MainMenu[6].active=1;
  141.         MainItems.curpos=0;
  142.     }
  143.     else
  144.     {
  145.     //
  146.     // no config file, so select by hardware
  147.     //
  148.         if (SoundBlasterPresent || AdLibPresent)
  149.         {
  150.             sd = sdm_AdLib;
  151.             sm = smm_AdLib;
  152.         }
  153.         else
  154.         {
  155.             sd = sdm_PC;
  156.             sm = smm_Off;
  157.         }
  158.  
  159.         if (SoundBlasterPresent)
  160.             sds = sds_SoundBlaster;
  161.         else if (SoundSourcePresent)
  162.             sds = sds_SoundSource;
  163.         else
  164.             sds = sds_Off;
  165.  
  166.         if (MousePresent)
  167.             mouseenabled = true;
  168.  
  169.         joystickenabled = false;
  170.         joypadenabled = false;
  171.         joystickport = 0;
  172.         joystickprogressive = false;
  173.  
  174.         viewsize = 15;
  175.         mouseadjustment=5;
  176.     }
  177.  
  178.     SD_SetMusicMode (sm);
  179.     SD_SetSoundMode (sd);
  180.     SD_SetDigiDevice (sds);
  181.  
  182. }
  183.  
  184.  
  185. /*
  186. ====================
  187. =
  188. = WriteConfig
  189. =
  190. ====================
  191. */
  192.  
  193. void WriteConfig(void)
  194. {
  195.     int                     file;
  196.  
  197.     file = open(configname,O_CREAT | O_BINARY | O_WRONLY,
  198.                 S_IREAD | S_IWRITE | S_IFREG);
  199.  
  200.     if (file != -1)
  201.     {
  202.         write(file,Scores,sizeof(HighScore) * MaxScores);
  203.  
  204.         write(file,&SoundMode,sizeof(SoundMode));
  205.         write(file,&MusicMode,sizeof(MusicMode));
  206.         write(file,&DigiMode,sizeof(DigiMode));
  207.  
  208.         write(file,&mouseenabled,sizeof(mouseenabled));
  209.         write(file,&joystickenabled,sizeof(joystickenabled));
  210.         write(file,&joypadenabled,sizeof(joypadenabled));
  211.         write(file,&joystickprogressive,sizeof(joystickprogressive));
  212.         write(file,&joystickport,sizeof(joystickport));
  213.  
  214.         write(file,&dirscan,sizeof(dirscan));
  215.         write(file,&buttonscan,sizeof(buttonscan));
  216.         write(file,&buttonmouse,sizeof(buttonmouse));
  217.         write(file,&buttonjoy,sizeof(buttonjoy));
  218.  
  219.         write(file,&viewsize,sizeof(viewsize));
  220.         write(file,&mouseadjustment,sizeof(mouseadjustment));
  221.  
  222.         close(file);
  223.     }
  224. }
  225.  
  226.  
  227. //===========================================================================
  228.  
  229.  
  230. /*
  231. ========================
  232. =
  233. = Patch386
  234. =
  235. = Patch ldiv to use 32 bit instructions
  236. =
  237. ========================
  238. */
  239.  
  240. char    *JHParmStrings[] = {"no386",nil};
  241. void Patch386 (void)
  242. {
  243. extern void far jabhack2(void);
  244. extern int far  CheckIs386(void);
  245.  
  246.     int     i;
  247.  
  248.     for (i = 1;i < _argc;i++)
  249.         if (US_CheckParm(_argv[i],JHParmStrings) == 0)
  250.         {
  251.             IsA386 = false;
  252.             return;
  253.         }
  254.  
  255.     if (CheckIs386())
  256.     {
  257.         IsA386 = true;
  258.         jabhack2();
  259.     }
  260.     else
  261.         IsA386 = false;
  262. }
  263.  
  264. //===========================================================================
  265.  
  266. /*
  267. =====================
  268. =
  269. = NewGame
  270. =
  271. = Set up new game to start from the beginning
  272. =
  273. =====================
  274. */
  275.  
  276. void NewGame (int difficulty,int episode)
  277. {
  278.     memset (&gamestate,0,sizeof(gamestate));
  279.     gamestate.difficulty = difficulty;
  280.     gamestate.weapon = gamestate.bestweapon
  281.         = gamestate.chosenweapon = wp_pistol;
  282.     gamestate.health = 100;
  283.     gamestate.ammo = STARTAMMO;
  284.     gamestate.lives = 3;
  285.     gamestate.nextextra = EXTRAPOINTS;
  286.     gamestate.episode=episode;
  287.  
  288.     startgame = true;
  289. }
  290.  
  291. //===========================================================================
  292.  
  293. void DiskFlopAnim(int x,int y)
  294. {
  295.  static char which=0;
  296.  if (!x && !y)
  297.    return;
  298.  VWB_DrawPic(x,y,C_DISKLOADING1PIC+which);
  299.  VW_UpdateScreen();
  300.  which^=1;
  301. }
  302.  
  303.  
  304. long DoChecksum(byte far *source,unsigned size,long checksum)
  305. {
  306.  unsigned i;
  307.  
  308.  for (i=0;i<size-1;i++)
  309.    checksum += source[i]^source[i+1];
  310.  
  311.  return checksum;
  312. }
  313.  
  314.  
  315. /*
  316. ==================
  317. =
  318. = SaveTheGame
  319. =
  320. ==================
  321. */
  322.  
  323. boolean SaveTheGame(int file,int x,int y)
  324. {
  325.     struct diskfree_t dfree;
  326.     long avail,size,checksum;
  327.     objtype *ob,nullobj;
  328.  
  329.  
  330.     if (_dos_getdiskfree(0,&dfree))
  331.       Quit("Error in _dos_getdiskfree call");
  332.  
  333.     avail = (long)dfree.avail_clusters *
  334.             dfree.bytes_per_sector *
  335.             dfree.sectors_per_cluster;
  336.  
  337.     size = 0;
  338.     for (ob = player; ob ; ob=ob->next)
  339.       size += sizeof(*ob);
  340.     size += sizeof(nullobj);
  341.  
  342.     size += sizeof(gamestate) +
  343.             sizeof(LRstruct)*8 +
  344.             sizeof(tilemap) +
  345.             sizeof(actorat) +
  346.             sizeof(laststatobj) +
  347.             sizeof(statobjlist) +
  348.             sizeof(doorposition) +
  349.             sizeof(pwallstate) +
  350.             sizeof(pwallx) +
  351.             sizeof(pwally) +
  352.             sizeof(pwalldir) +
  353.             sizeof(pwallpos);
  354.  
  355.     if (avail < size)
  356.     {
  357.      Message(STR_NOSPACE1"\n"
  358.              STR_NOSPACE2);
  359.      return false;
  360.     }
  361.  
  362.     checksum = 0;
  363.  
  364.  
  365.     DiskFlopAnim(x,y);
  366.     CA_FarWrite (file,(void far *)&gamestate,sizeof(gamestate));
  367.     checksum = DoChecksum((byte far *)&gamestate,sizeof(gamestate),checksum);
  368.  
  369.     DiskFlopAnim(x,y);
  370. #ifdef SPEAR
  371.     CA_FarWrite (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*20);
  372.     checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*20,checksum);
  373. #else
  374.     CA_FarWrite (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*8);
  375.     checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*8,checksum);
  376. #endif
  377.  
  378.     DiskFlopAnim(x,y);
  379.     CA_FarWrite (file,(void far *)tilemap,sizeof(tilemap));
  380.     checksum = DoChecksum((byte far *)tilemap,sizeof(tilemap),checksum);
  381.     DiskFlopAnim(x,y);
  382.     CA_FarWrite (file,(void far *)actorat,sizeof(actorat));
  383.     checksum = DoChecksum((byte far *)actorat,sizeof(actorat),checksum);
  384.  
  385.     CA_FarWrite (file,(void far *)areaconnect,sizeof(areaconnect));
  386.     CA_FarWrite (file,(void far *)areabyplayer,sizeof(areabyplayer));
  387.  
  388.     for (ob = player ; ob ; ob=ob->next)
  389.     {
  390.      DiskFlopAnim(x,y);
  391.      CA_FarWrite (file,(void far *)ob,sizeof(*ob));
  392.     }
  393.     nullobj.active = ac_badobject;          // end of file marker
  394.     DiskFlopAnim(x,y);
  395.     CA_FarWrite (file,(void far *)&nullobj,sizeof(nullobj));
  396.  
  397.  
  398.  
  399.     DiskFlopAnim(x,y);
  400.     CA_FarWrite (file,(void far *)&laststatobj,sizeof(laststatobj));
  401.     checksum = DoChecksum((byte far *)&laststatobj,sizeof(laststatobj),checksum);
  402.     DiskFlopAnim(x,y);
  403.     CA_FarWrite (file,(void far *)statobjlist,sizeof(statobjlist));
  404.     checksum = DoChecksum((byte far *)statobjlist,sizeof(statobjlist),checksum);
  405.  
  406.     DiskFlopAnim(x,y);
  407.     CA_FarWrite (file,(void far *)doorposition,sizeof(doorposition));
  408.     checksum = DoChecksum((byte far *)doorposition,sizeof(doorposition),checksum);
  409.     DiskFlopAnim(x,y);
  410.     CA_FarWrite (file,(void far *)doorobjlist,sizeof(doorobjlist));
  411.     checksum = DoChecksum((byte far *)doorobjlist,sizeof(doorobjlist),checksum);
  412.  
  413.     DiskFlopAnim(x,y);
  414.     CA_FarWrite (file,(void far *)&pwallstate,sizeof(pwallstate));
  415.     checksum = DoChecksum((byte far *)&pwallstate,sizeof(pwallstate),checksum);
  416.     CA_FarWrite (file,(void far *)&pwallx,sizeof(pwallx));
  417.     checksum = DoChecksum((byte far *)&pwallx,sizeof(pwallx),checksum);
  418.     CA_FarWrite (file,(void far *)&pwally,sizeof(pwally));
  419.     checksum = DoChecksum((byte far *)&pwally,sizeof(pwally),checksum);
  420.     CA_FarWrite (file,(void far *)&pwalldir,sizeof(pwalldir));
  421.     checksum = DoChecksum((byte far *)&pwalldir,sizeof(pwalldir),checksum);
  422.     CA_FarWrite (file,(void far *)&pwallpos,sizeof(pwallpos));
  423.     checksum = DoChecksum((byte far *)&pwallpos,sizeof(pwallpos),checksum);
  424.  
  425.     //
  426.     // WRITE OUT CHECKSUM
  427.     //
  428.     CA_FarWrite (file,(void far *)&checksum,sizeof(checksum));
  429.  
  430.     return(true);
  431. }
  432.  
  433. //===========================================================================
  434.  
  435. /*
  436. ==================
  437. =
  438. = LoadTheGame
  439. =
  440. ==================
  441. */
  442.  
  443. boolean LoadTheGame(int file,int x,int y)
  444. {
  445.     long checksum,oldchecksum;
  446.     objtype *ob,nullobj;
  447.  
  448.  
  449.     checksum = 0;
  450.  
  451.     DiskFlopAnim(x,y);
  452.     CA_FarRead (file,(void far *)&gamestate,sizeof(gamestate));
  453.     checksum = DoChecksum((byte far *)&gamestate,sizeof(gamestate),checksum);
  454.  
  455.     DiskFlopAnim(x,y);
  456. #ifdef SPEAR
  457.     CA_FarRead (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*20);
  458.     checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*20,checksum);
  459. #else
  460.     CA_FarRead (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*8);
  461.     checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*8,checksum);
  462. #endif
  463.  
  464.     DiskFlopAnim(x,y);
  465.     SetupGameLevel ();
  466.  
  467.     DiskFlopAnim(x,y);
  468.     CA_FarRead (file,(void far *)tilemap,sizeof(tilemap));
  469.     checksum = DoChecksum((byte far *)tilemap,sizeof(tilemap),checksum);
  470.     DiskFlopAnim(x,y);
  471.     CA_FarRead (file,(void far *)actorat,sizeof(actorat));
  472.     checksum = DoChecksum((byte far *)actorat,sizeof(actorat),checksum);
  473.  
  474.     CA_FarRead (file,(void far *)areaconnect,sizeof(areaconnect));
  475.     CA_FarRead (file,(void far *)areabyplayer,sizeof(areabyplayer));
  476.  
  477.  
  478.  
  479.     InitActorList ();
  480.     DiskFlopAnim(x,y);
  481.     CA_FarRead (file,(void far *)player,sizeof(*player));
  482.  
  483.     while (1)
  484.     {
  485.      DiskFlopAnim(x,y);
  486.         CA_FarRead (file,(void far *)&nullobj,sizeof(nullobj));
  487.         if (nullobj.active == ac_badobject)
  488.             break;
  489.         GetNewActor ();
  490.      // don't copy over the links
  491.         memcpy (new,&nullobj,sizeof(nullobj)-4);
  492.     }
  493.  
  494.  
  495.  
  496.     DiskFlopAnim(x,y);
  497.     CA_FarRead (file,(void far *)&laststatobj,sizeof(laststatobj));
  498.     checksum = DoChecksum((byte far *)&laststatobj,sizeof(laststatobj),checksum);
  499.     DiskFlopAnim(x,y);
  500.     CA_FarRead (file,(void far *)statobjlist,sizeof(statobjlist));
  501.     checksum = DoChecksum((byte far *)statobjlist,sizeof(statobjlist),checksum);
  502.  
  503.     DiskFlopAnim(x,y);
  504.     CA_FarRead (file,(void far *)doorposition,sizeof(doorposition));
  505.     checksum = DoChecksum((byte far *)doorposition,sizeof(doorposition),checksum);
  506.     DiskFlopAnim(x,y);
  507.     CA_FarRead (file,(void far *)doorobjlist,sizeof(doorobjlist));
  508.     checksum = DoChecksum((byte far *)doorobjlist,sizeof(doorobjlist),checksum);
  509.  
  510.     DiskFlopAnim(x,y);
  511.     CA_FarRead (file,(void far *)&pwallstate,sizeof(pwallstate));
  512.     checksum = DoChecksum((byte far *)&pwallstate,sizeof(pwallstate),checksum);
  513.     CA_FarRead (file,(void far *)&pwallx,sizeof(pwallx));
  514.     checksum = DoChecksum((byte far *)&pwallx,sizeof(pwallx),checksum);
  515.     CA_FarRead (file,(void far *)&pwally,sizeof(pwally));
  516.     checksum = DoChecksum((byte far *)&pwally,sizeof(pwally),checksum);
  517.     CA_FarRead (file,(void far *)&pwalldir,sizeof(pwalldir));
  518.     checksum = DoChecksum((byte far *)&pwalldir,sizeof(pwalldir),checksum);
  519.     CA_FarRead (file,(void far *)&pwallpos,sizeof(pwallpos));
  520.     checksum = DoChecksum((byte far *)&pwallpos,sizeof(pwallpos),checksum);
  521.  
  522.     CA_FarRead (file,(void far *)&oldchecksum,sizeof(oldchecksum));
  523.  
  524.     if (oldchecksum != checksum)
  525.     {
  526.      Message(STR_SAVECHT1"\n"
  527.              STR_SAVECHT2"\n"
  528.              STR_SAVECHT3"\n"
  529.              STR_SAVECHT4);
  530.  
  531.      IN_ClearKeysDown();
  532.      IN_Ack();
  533.  
  534.      gamestate.score = 0;
  535.      gamestate.lives = 1;
  536.      gamestate.weapon =
  537.        gamestate.chosenweapon =
  538.        gamestate.bestweapon = wp_pistol;
  539.      gamestate.ammo = 8;
  540.     }
  541.  
  542.     return true;
  543. }
  544.  
  545. //===========================================================================
  546.  
  547. /*
  548. ==========================
  549. =
  550. = ShutdownId
  551. =
  552. = Shuts down all ID_?? managers
  553. =
  554. ==========================
  555. */
  556.  
  557. void ShutdownId (void)
  558. {
  559.     US_Shutdown ();
  560.     SD_Shutdown ();
  561.     PM_Shutdown ();
  562.     IN_Shutdown ();
  563.     VW_Shutdown ();
  564.     CA_Shutdown ();
  565.     MM_Shutdown ();
  566. }
  567.  
  568.  
  569. //===========================================================================
  570.  
  571. /*
  572. ==================
  573. =
  574. = BuildTables
  575. =
  576. = Calculates:
  577. =
  578. = scale                 projection constant
  579. = sintable/costable     overlapping fractional tables
  580. =
  581. ==================
  582. */
  583.  
  584. const   float   radtoint = (float)FINEANGLES/2/PI;
  585.  
  586. void BuildTables (void)
  587. {
  588.   int           i;
  589.   float         angle,anglestep;
  590.   double        tang;
  591.   fixed         value;
  592.  
  593.  
  594. //
  595. // calculate fine tangents
  596. //
  597.  
  598.     for (i=0;i<FINEANGLES/8;i++)
  599.     {
  600.         tang = tan( (i+0.5)/radtoint);
  601.         finetangent[i] = tang*TILEGLOBAL;
  602.         finetangent[FINEANGLES/4-1-i] = 1/tang*TILEGLOBAL;
  603.     }
  604.  
  605. //
  606. // costable overlays sintable with a quarter phase shift
  607. // ANGLES is assumed to be divisable by four
  608. //
  609. // The low word of the value is the fraction, the high bit is the sign bit,
  610. // bits 16-30 should be 0
  611. //
  612.  
  613.   angle = 0;
  614.   anglestep = PI/2/ANGLEQUAD;
  615.   for (i=0;i<=ANGLEQUAD;i++)
  616.   {
  617.     value=GLOBAL1*sin(angle);
  618.     sintable[i]=
  619.       sintable[i+ANGLES]=
  620.       sintable[ANGLES/2-i] = value;
  621.     sintable[ANGLES-i]=
  622.       sintable[ANGLES/2+i] = value | 0x80000000l;
  623.     angle += anglestep;
  624.   }
  625.  
  626. }
  627.  
  628. //===========================================================================
  629.  
  630.  
  631. /*
  632. ====================
  633. =
  634. = CalcProjection
  635. =
  636. = Uses focallength
  637. =
  638. ====================
  639. */
  640.  
  641. void CalcProjection (long focal)
  642. {
  643.     int             i;
  644.     long            intang;
  645.     float   angle;
  646.     double  tang;
  647.     double  planedist;
  648.     double  globinhalf;
  649.     int             halfview;
  650.     double  halfangle,facedist;
  651.  
  652.  
  653.     focallength = focal;
  654.     facedist = focal+MINDIST;
  655.     halfview = viewwidth/2;                                 // half view in pixels
  656.  
  657. //
  658. // calculate scale value for vertical height calculations
  659. // and sprite x calculations
  660. //
  661.     scale = halfview*facedist/(VIEWGLOBAL/2);
  662.  
  663. //
  664. // divide heightnumerator by a posts distance to get the posts height for
  665. // the heightbuffer.  The pixel height is height>>2
  666. //
  667.     heightnumerator = (TILEGLOBAL*scale)>>6;
  668.     minheightdiv = heightnumerator/0x7fff +1;
  669.  
  670. //
  671. // calculate the angle offset from view angle of each pixel's ray
  672. //
  673.  
  674.     for (i=0;i<halfview;i++)
  675.     {
  676.     // start 1/2 pixel over, so viewangle bisects two middle pixels
  677.         tang = (long)i*VIEWGLOBAL/viewwidth/facedist;
  678.         angle = atan(tang);
  679.         intang = angle*radtoint;
  680.         pixelangle[halfview-1-i] = intang;
  681.         pixelangle[halfview+i] = -intang;
  682.     }
  683.  
  684. //
  685. // if a point's abs(y/x) is greater than maxslope, the point is outside
  686. // the view area
  687. //
  688.     maxslope = finetangent[pixelangle[0]];
  689.     maxslope >>= 8;
  690. }
  691.  
  692.  
  693.  
  694. //===========================================================================
  695.  
  696. /*
  697. ===================
  698. =
  699. = SetupWalls
  700. =
  701. = Map tile values to scaled pics
  702. =
  703. ===================
  704. */
  705.  
  706. void SetupWalls (void)
  707. {
  708.     int     i;
  709.  
  710.     for (i=1;i<MAXWALLTILES;i++)
  711.     {
  712.         horizwall[i]=(i-1)*2;
  713.         vertwall[i]=(i-1)*2+1;
  714.     }
  715. }
  716.  
  717. //===========================================================================
  718.  
  719. /*
  720. ==========================
  721. =
  722. = SignonScreen
  723. =
  724. ==========================
  725. */
  726.  
  727. void SignonScreen (void)                        // VGA version
  728. {
  729.     unsigned        segstart,seglength;
  730.  
  731.     VL_SetVGAPlaneMode ();
  732.     VL_TestPaletteSet ();
  733.     VL_SetPalette (&gamepal);
  734.  
  735.     if (!virtualreality)
  736.     {
  737.         VW_SetScreen(0x8000,0);
  738.         VL_MungePic (&introscn,320,200);
  739.         VL_MemToScreen (&introscn,320,200,0,0);
  740.         VW_SetScreen(0,0);
  741.     }
  742.  
  743. //
  744. // reclaim the memory from the linked in signon screen
  745. //
  746.     segstart = FP_SEG(&introscn);
  747.     seglength = 64000/16;
  748.     if (FP_OFF(&introscn))
  749.     {
  750.         segstart++;
  751.         seglength--;
  752.     }
  753.     MML_UseSpace (segstart,seglength);
  754. }
  755.  
  756.  
  757. /*
  758. ==========================
  759. =
  760. = FinishSignon
  761. =
  762. ==========================
  763. */
  764.  
  765. void FinishSignon (void)
  766. {
  767.  
  768. #ifndef SPEAR
  769.     VW_Bar (0,189,300,11,peekb(0xa000,0));
  770.     WindowX = 0;
  771.     WindowW = 320;
  772.     PrintY = 190;
  773.  
  774.     #ifndef JAPAN
  775.     SETFONTCOLOR(14,4);
  776.  
  777.     #ifdef SPANISH
  778.     US_CPrint ("Oprima una tecla");
  779.     #else
  780.     US_CPrint ("Press a key");
  781.     #endif
  782.  
  783.     #endif
  784.  
  785.     if (!NoWait)
  786.         IN_Ack ();
  787.  
  788.     #ifndef JAPAN
  789.     VW_Bar (0,189,300,11,peekb(0xa000,0));
  790.  
  791.     PrintY = 190;
  792.     SETFONTCOLOR(10,4);
  793.  
  794.     #ifdef SPANISH
  795.     US_CPrint ("pensando...");
  796.     #else
  797.     US_CPrint ("Working...");
  798.     #endif
  799.  
  800.     #endif
  801.  
  802.     SETFONTCOLOR(0,15);
  803. #else
  804.     if (!NoWait)
  805.         VW_WaitVBL(3*70);
  806. #endif
  807. }
  808.  
  809. //===========================================================================
  810.  
  811. /*
  812. =================
  813. =
  814. = MS_CheckParm
  815. =
  816. =================
  817. */
  818.  
  819. boolean MS_CheckParm (char far *check)
  820. {
  821.     int             i;
  822.     char    *parm;
  823.  
  824.     for (i = 1;i<_argc;i++)
  825.     {
  826.         parm = _argv[i];
  827.  
  828.         while ( !isalpha(*parm) )       // skip - / \ etc.. in front of parm
  829.             if (!*parm++)
  830.                 break;                          // hit end of string without an alphanum
  831.  
  832.         if ( !_fstricmp(check,parm) )
  833.             return true;
  834.     }
  835.  
  836.     return false;
  837. }
  838.  
  839. //===========================================================================
  840.  
  841. /*
  842. =====================
  843. =
  844. = InitDigiMap
  845. =
  846. =====================
  847. */
  848.  
  849. static  int     wolfdigimap[] =
  850.         {
  851.             // These first sounds are in the upload version
  852. #ifndef SPEAR
  853.             HALTSND,                0,
  854.             DOGBARKSND,             1,
  855.             CLOSEDOORSND,           2,
  856.             OPENDOORSND,            3,
  857.             ATKMACHINEGUNSND,       4,
  858.             ATKPISTOLSND,           5,
  859.             ATKGATLINGSND,          6,
  860.             SCHUTZADSND,            7,
  861.             GUTENTAGSND,            8,
  862.             MUTTISND,               9,
  863.             BOSSFIRESND,            10,
  864.             SSFIRESND,              11,
  865.             DEATHSCREAM1SND,        12,
  866.             DEATHSCREAM2SND,        13,
  867.             DEATHSCREAM3SND,        13,
  868.             TAKEDAMAGESND,          14,
  869.             PUSHWALLSND,            15,
  870.  
  871.             LEBENSND,               20,
  872.             NAZIFIRESND,            21,
  873.             SLURPIESND,             22,
  874.  
  875.             YEAHSND,                32,
  876.  
  877. #ifndef UPLOAD
  878.             // These are in all other episodes
  879.             DOGDEATHSND,            16,
  880.             AHHHGSND,               17,
  881.             DIESND,                 18,
  882.             EVASND,                 19,
  883.  
  884.             TOT_HUNDSND,            23,
  885.             MEINGOTTSND,            24,
  886.             SCHABBSHASND,           25,
  887.             HITLERHASND,            26,
  888.             SPIONSND,               27,
  889.             NEINSOVASSND,           28,
  890.             DOGATTACKSND,           29,
  891.             LEVELDONESND,           30,
  892.             MECHSTEPSND,            31,
  893.  
  894.             SCHEISTSND,                33,
  895.             DEATHSCREAM4SND,        34,        // AIIEEE
  896.             DEATHSCREAM5SND,        35,        // DEE-DEE
  897.             DONNERSND,                36,        // EPISODE 4 BOSS DIE
  898.             EINESND,                37,        // EPISODE 4 BOSS SIGHTING
  899.             ERLAUBENSND,            38,        // EPISODE 6 BOSS SIGHTING
  900.             DEATHSCREAM6SND,        39,        // FART
  901.             DEATHSCREAM7SND,        40,        // GASP
  902.             DEATHSCREAM8SND,        41,        // GUH-BOY!
  903.             DEATHSCREAM9SND,        42,        // AH GEEZ!
  904.             KEINSND,                43,        // EPISODE 5 BOSS SIGHTING
  905.             MEINSND,                44,        // EPISODE 6 BOSS DIE
  906.             ROSESND,                45,        // EPISODE 5 BOSS DIE
  907.  
  908. #endif
  909. #else
  910. //
  911. // SPEAR OF DESTINY DIGISOUNDS
  912. //
  913.             HALTSND,                0,
  914.             CLOSEDOORSND,           2,
  915.             OPENDOORSND,            3,
  916.             ATKMACHINEGUNSND,       4,
  917.             ATKPISTOLSND,           5,
  918.             ATKGATLINGSND,          6,
  919.             SCHUTZADSND,            7,
  920.             BOSSFIRESND,            8,
  921.             SSFIRESND,              9,
  922.             DEATHSCREAM1SND,        10,
  923.             DEATHSCREAM2SND,        11,
  924.             TAKEDAMAGESND,          12,
  925.             PUSHWALLSND,            13,
  926.             AHHHGSND,               15,
  927.             LEBENSND,               16,
  928.             NAZIFIRESND,            17,
  929.             SLURPIESND,             18,
  930.             LEVELDONESND,           22,
  931.             DEATHSCREAM4SND,        23,        // AIIEEE
  932.             DEATHSCREAM3SND,        23,        // DOUBLY-MAPPED!!!
  933.             DEATHSCREAM5SND,        24,        // DEE-DEE
  934.             DEATHSCREAM6SND,        25,        // FART
  935.             DEATHSCREAM7SND,        26,        // GASP
  936.             DEATHSCREAM8SND,        27,        // GUH-BOY!
  937.             DEATHSCREAM9SND,        28,        // AH GEEZ!
  938.             GETGATLINGSND,            38,        // Got Gat replacement
  939.  
  940. #ifndef SPEARDEMO
  941.             DOGBARKSND,             1,
  942.             DOGDEATHSND,            14,
  943.             SPIONSND,               19,
  944.             NEINSOVASSND,           20,
  945.             DOGATTACKSND,           21,
  946.             TRANSSIGHTSND,            29,        // Trans Sight
  947.             TRANSDEATHSND,            30,        // Trans Death
  948.             WILHELMSIGHTSND,        31,        // Wilhelm Sight
  949.             WILHELMDEATHSND,        32,        // Wilhelm Death
  950.             UBERDEATHSND,            33,        // Uber Death
  951.             KNIGHTSIGHTSND,            34,        // Death Knight Sight
  952.             KNIGHTDEATHSND,            35,        // Death Knight Death
  953.             ANGELSIGHTSND,            36,        // Angel Sight
  954.             ANGELDEATHSND,            37,        // Angel Death
  955.             GETSPEARSND,            39,        // Got Spear replacement
  956. #endif
  957. #endif
  958.             LASTSOUND
  959.         };
  960.  
  961.  
  962. void InitDigiMap (void)
  963. {
  964.     int                     *map;
  965.  
  966.     for (map = wolfdigimap;*map != LASTSOUND;map += 2)
  967.         DigiMap[map[0]] = map[1];
  968.  
  969.  
  970. }
  971.  
  972.  
  973. #ifndef SPEAR
  974. CP_iteminfo    MusicItems={CTL_X,CTL_Y,6,0,32};
  975. CP_itemtype far MusicMenu[]=
  976.     {
  977.         {1,"Get Them!",0},
  978.         {1,"Searching",0},
  979.         {1,"P.O.W.",0},
  980.         {1,"Suspense",0},
  981.         {1,"War March",0},
  982.         {1,"Around The Corner!",0},
  983.  
  984.         {1,"Nazi Anthem",0},
  985.         {1,"Lurking...",0},
  986.         {1,"Going After Hitler",0},
  987.         {1,"Pounding Headache",0},
  988.         {1,"Into the Dungeons",0},
  989.         {1,"Ultimate Conquest",0},
  990.  
  991.         {1,"Kill the S.O.B.",0},
  992.         {1,"The Nazi Rap",0},
  993.         {1,"Twelfth Hour",0},
  994.         {1,"Zero Hour",0},
  995.         {1,"Ultimate Conquest",0},
  996.         {1,"Wolfpack",0}
  997.     };
  998. #else
  999. CP_iteminfo MusicItems={CTL_X,CTL_Y-20,9,0,32};
  1000. CP_itemtype far MusicMenu[]=
  1001.    {
  1002.         {1,"Funky Colonel Bill",0},
  1003.         {1,"Death To The Nazis",0},
  1004.         {1,"Tiptoeing Around",0},
  1005.         {1,"Is This THE END?",0},
  1006.         {1,"Evil Incarnate",0},
  1007.         {1,"Jazzin' Them Nazis",0},
  1008.         {1,"Puttin' It To The Enemy",0},
  1009.         {1,"The SS Gonna Get You",0},
  1010.         {1,"Towering Above",0}
  1011.     };
  1012. #endif
  1013.  
  1014. #ifndef SPEARDEMO
  1015. void DoJukebox(void)
  1016. {
  1017.     int which,lastsong=-1;
  1018.     unsigned start,songs[]=
  1019.         {
  1020. #ifndef SPEAR
  1021.             GETTHEM_MUS,
  1022.             SEARCHN_MUS,
  1023.             POW_MUS,
  1024.             SUSPENSE_MUS,
  1025.             WARMARCH_MUS,
  1026.             CORNER_MUS,
  1027.  
  1028.             NAZI_OMI_MUS,
  1029.             PREGNANT_MUS,
  1030.             GOINGAFT_MUS,
  1031.             HEADACHE_MUS,
  1032.             DUNGEON_MUS,
  1033.             ULTIMATE_MUS,
  1034.  
  1035.             INTROCW3_MUS,
  1036.             NAZI_RAP_MUS,
  1037.             TWELFTH_MUS,
  1038.             ZEROHOUR_MUS,
  1039.             ULTIMATE_MUS,
  1040.             PACMAN_MUS
  1041. #else
  1042.             XFUNKIE_MUS,             // 0
  1043.             XDEATH_MUS,              // 2
  1044.             XTIPTOE_MUS,             // 4
  1045.             XTHEEND_MUS,             // 7
  1046.             XEVIL_MUS,               // 17
  1047.             XJAZNAZI_MUS,            // 18
  1048.             XPUTIT_MUS,              // 21
  1049.             XGETYOU_MUS,             // 22
  1050.             XTOWER2_MUS              // 23
  1051. #endif
  1052.         };
  1053.     struct dostime_t time;
  1054.  
  1055.  
  1056.  
  1057.     IN_ClearKeysDown();
  1058.     if (!AdLibPresent && !SoundBlasterPresent)
  1059.         return;
  1060.  
  1061.  
  1062.     MenuFadeOut();
  1063.  
  1064. #ifndef SPEAR
  1065. #ifndef UPLOAD
  1066.     _dos_gettime(&time);
  1067.     start = (time.hsecond%3)*6;
  1068. #else
  1069.     start = 0;
  1070. #endif
  1071. #else
  1072.     start = 0;
  1073. #endif
  1074.  
  1075.  
  1076.     CA_CacheGrChunk (STARTFONT+1);
  1077. #ifdef SPEAR
  1078.     CacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
  1079. #else
  1080.     CacheLump (CONTROLS_LUMP_START,CONTROLS_LUMP_END);
  1081. #endif
  1082.     CA_LoadAllSounds ();
  1083.  
  1084.     fontnumber=1;
  1085.     ClearMScreen ();
  1086.     VWB_DrawPic(112,184,C_MOUSELBACKPIC);
  1087.     DrawStripes (10);
  1088.     SETFONTCOLOR (TEXTCOLOR,BKGDCOLOR);
  1089.  
  1090. #ifndef SPEAR
  1091.     DrawWindow (CTL_X-2,CTL_Y-6,280,13*7,BKGDCOLOR);
  1092. #else
  1093.     DrawWindow (CTL_X-2,CTL_Y-26,280,13*10,BKGDCOLOR);
  1094. #endif
  1095.  
  1096.     DrawMenu (&MusicItems,&MusicMenu[start]);
  1097.  
  1098.     SETFONTCOLOR (READHCOLOR,BKGDCOLOR);
  1099.     PrintY=15;
  1100.     WindowX = 0;
  1101.     WindowY = 320;
  1102.     US_CPrint ("Robert's Jukebox");
  1103.  
  1104.     SETFONTCOLOR (TEXTCOLOR,BKGDCOLOR);
  1105.     VW_UpdateScreen();
  1106.     MenuFadeIn();
  1107.  
  1108.     do
  1109.     {
  1110.         which = HandleMenu(&MusicItems,&MusicMenu[start],NULL);
  1111.         if (which>=0)
  1112.         {
  1113.             if (lastsong >= 0)
  1114.                 MusicMenu[start+lastsong].active = 1;
  1115.  
  1116.             StartCPMusic(songs[start + which]);
  1117.             MusicMenu[start+which].active = 2;
  1118.             DrawMenu (&MusicItems,&MusicMenu[start]);
  1119.             VW_UpdateScreen();
  1120.             lastsong = which;
  1121.         }
  1122.     } while(which>=0);
  1123.  
  1124.     MenuFadeOut();
  1125.     IN_ClearKeysDown();
  1126. #ifdef SPEAR
  1127.     UnCacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
  1128. #else
  1129.     UnCacheLump (CONTROLS_LUMP_START,CONTROLS_LUMP_END);
  1130. #endif
  1131. }
  1132. #endif
  1133.  
  1134.  
  1135. /*
  1136. ==========================
  1137. =
  1138. = InitGame
  1139. =
  1140. = Load a few things right away
  1141. =
  1142. ==========================
  1143. */
  1144.  
  1145. void InitGame (void)
  1146. {
  1147.     int                     i,x,y;
  1148.     unsigned        *blockstart;
  1149.  
  1150.     if (MS_CheckParm ("virtual"))
  1151.         virtualreality = true;
  1152.     else
  1153.         virtualreality = false;
  1154.  
  1155.     MM_Startup ();                  // so the signon screen can be freed
  1156.  
  1157.     SignonScreen ();
  1158.  
  1159.     VW_Startup ();
  1160.     IN_Startup ();
  1161.     PM_Startup ();
  1162.     PM_UnlockMainMem ();
  1163.     SD_Startup ();
  1164.     CA_Startup ();
  1165.     US_Startup ();
  1166.  
  1167.  
  1168. #ifndef SPEAR
  1169.     if (mminfo.mainmem < 235000L)
  1170. #else
  1171.     if (mminfo.mainmem < 257000L && !MS_CheckParm("debugmode"))
  1172. #endif
  1173.     {
  1174.         memptr screen;
  1175.  
  1176.         CA_CacheGrChunk (ERRORSCREEN);
  1177.         screen = grsegs[ERRORSCREEN];
  1178.         ShutdownId();
  1179.         movedata ((unsigned)screen,7+7*160,0xb800,0,17*160);
  1180.         gotoxy (1,23);
  1181.         exit(1);
  1182.     }
  1183.  
  1184.  
  1185. //
  1186. // build some tables
  1187. //
  1188.     InitDigiMap ();
  1189.  
  1190.     for (i=0;i<MAPSIZE;i++)
  1191.     {
  1192.         nearmapylookup[i] = &tilemap[0][0]+MAPSIZE*i;
  1193.         farmapylookup[i] = i*64;
  1194.     }
  1195.  
  1196.     for (i=0;i<PORTTILESHIGH;i++)
  1197.         uwidthtable[i] = UPDATEWIDE*i;
  1198.  
  1199.     blockstart = &blockstarts[0];
  1200.     for (y=0;y<UPDATEHIGH;y++)
  1201.         for (x=0;x<UPDATEWIDE;x++)
  1202.             *blockstart++ = SCREENWIDTH*16*y+x*TILEWIDTH;
  1203.  
  1204.     updateptr = &update[0];
  1205.  
  1206.     bufferofs = 0;
  1207.     displayofs = 0;
  1208.     ReadConfig ();
  1209.  
  1210.  
  1211. //
  1212. // HOLDING DOWN 'M' KEY?
  1213. //
  1214. #ifndef SPEARDEMO
  1215.     if (Keyboard[sc_M])
  1216.       DoJukebox();
  1217.     else
  1218. #endif
  1219. //
  1220. // draw intro screen stuff
  1221. //
  1222.     if (!virtualreality)
  1223.         IntroScreen ();
  1224.  
  1225. //
  1226. // load in and lock down some basic chunks
  1227. //
  1228.  
  1229.     CA_CacheGrChunk(STARTFONT);
  1230.     MM_SetLock (&grsegs[STARTFONT],true);
  1231.  
  1232.     LoadLatchMem ();
  1233.     BuildTables ();          // trig tables
  1234.     SetupWalls ();
  1235.  
  1236. #if 0
  1237. {
  1238. int temp,i;
  1239. temp = viewsize;
  1240.     profilehandle = open("SCALERS.TXT", O_CREAT | O_WRONLY | O_TEXT);
  1241. for (i=1;i<20;i++)
  1242.     NewViewSize(i);
  1243. viewsize = temp;
  1244. close(profilehandle);
  1245. }
  1246. #endif
  1247.  
  1248.     NewViewSize (viewsize);
  1249.  
  1250.  
  1251. //
  1252. // initialize variables
  1253. //
  1254.     InitRedShifts ();
  1255.     if (!virtualreality)
  1256.         FinishSignon();
  1257.  
  1258.     displayofs = PAGE1START;
  1259.     bufferofs = PAGE2START;
  1260.  
  1261.     if (virtualreality)
  1262.     {
  1263.         NoWait = true;
  1264.         geninterrupt(0x60);
  1265.     }
  1266. }
  1267.  
  1268. //===========================================================================
  1269.  
  1270. /*
  1271. ==========================
  1272. =
  1273. = SetViewSize
  1274. =
  1275. ==========================
  1276. */
  1277.  
  1278. boolean SetViewSize (unsigned width, unsigned height)
  1279. {
  1280.     viewwidth = width&~15;                  // must be divisable by 16
  1281.     viewheight = height&~1;                 // must be even
  1282.     centerx = viewwidth/2-1;
  1283.     shootdelta = viewwidth/10;
  1284.     screenofs = ((200-STATUSLINES-viewheight)/2*SCREENWIDTH+(320-viewwidth)/8);
  1285.  
  1286. //
  1287. // calculate trace angles and projection constants
  1288. //
  1289.     CalcProjection (FOCALLENGTH);
  1290.  
  1291. //
  1292. // build all needed compiled scalers
  1293. //
  1294. //    MM_BombOnError (false);
  1295.     SetupScaling (viewwidth*1.5);
  1296. #if 0
  1297.     MM_BombOnError (true);
  1298.     if (mmerror)
  1299.     {
  1300.         Quit ("Can't build scalers!");
  1301.         mmerror = false;
  1302.         return false;
  1303.     }
  1304. #endif
  1305.     return true;
  1306. }
  1307.  
  1308.  
  1309. void ShowViewSize (int width)
  1310. {
  1311.     int     oldwidth,oldheight;
  1312.  
  1313.     oldwidth = viewwidth;
  1314.     oldheight = viewheight;
  1315.  
  1316.     viewwidth = width*16;
  1317.     viewheight = width*16*HEIGHTRATIO;
  1318.     DrawPlayBorder ();
  1319.  
  1320.     viewheight = oldheight;
  1321.     viewwidth = oldwidth;
  1322. }
  1323.  
  1324.  
  1325. void NewViewSize (int width)
  1326. {
  1327.     CA_UpLevel ();
  1328.     MM_SortMem ();
  1329.     viewsize = width;
  1330.     SetViewSize (width*16,width*16*HEIGHTRATIO);
  1331.     CA_DownLevel ();
  1332. }
  1333.  
  1334.  
  1335.  
  1336. //===========================================================================
  1337.  
  1338. /*
  1339. ==========================
  1340. =
  1341. = Quit
  1342. =
  1343. ==========================
  1344. */
  1345.  
  1346. void Quit (char *error)
  1347. {
  1348.     unsigned        finscreen;
  1349.     memptr    screen;
  1350.  
  1351.     if (virtualreality)
  1352.         geninterrupt(0x61);
  1353.  
  1354.     ClearMemory ();
  1355.     if (!*error)
  1356.     {
  1357.      #ifndef JAPAN
  1358.      CA_CacheGrChunk (ORDERSCREEN);
  1359.      screen = grsegs[ORDERSCREEN];
  1360.      #endif
  1361.      WriteConfig ();
  1362.     }
  1363.     else
  1364.     {
  1365.      CA_CacheGrChunk (ERRORSCREEN);
  1366.      screen = grsegs[ERRORSCREEN];
  1367.     }
  1368.  
  1369.     ShutdownId ();
  1370.  
  1371.     if (error && *error)
  1372.     {
  1373.       movedata ((unsigned)screen,7,0xb800,0,7*160);
  1374.       gotoxy (10,4);
  1375.       puts(error);
  1376.       gotoxy (1,8);
  1377.       exit(1);
  1378.     }
  1379.     else
  1380.     if (!error || !(*error))
  1381.     {
  1382.         clrscr();
  1383.         #ifndef JAPAN
  1384.         movedata ((unsigned)screen,7,0xb800,0,4000);
  1385.         gotoxy(1,24);
  1386.         #endif
  1387. //asm    mov    bh,0
  1388. //asm    mov    dh,23    // row
  1389. //asm    mov    dl,0    // collumn
  1390. //asm    mov ah,2
  1391. //asm    int    0x10
  1392.     }
  1393.  
  1394.     exit(0);
  1395. }
  1396.  
  1397. //===========================================================================
  1398.  
  1399.  
  1400.  
  1401. /*
  1402. =====================
  1403. =
  1404. = DemoLoop
  1405. =
  1406. =====================
  1407. */
  1408.  
  1409. static  char *ParmStrings[] = {"baby","easy","normal","hard",""};
  1410.  
  1411. void    DemoLoop (void)
  1412. {
  1413.     static int LastDemo;
  1414.     int     i,level;
  1415.     long nsize;
  1416.     memptr    nullblock;
  1417.  
  1418. //
  1419. // check for launch from ted
  1420. //
  1421.     if (tedlevel)
  1422.     {
  1423.         NoWait = true;
  1424.         NewGame(1,0);
  1425.  
  1426.         for (i = 1;i < _argc;i++)
  1427.         {
  1428.             if ( (level = US_CheckParm(_argv[i],ParmStrings)) != -1)
  1429.             {
  1430.              gamestate.difficulty=level;
  1431.              break;
  1432.             }
  1433.         }
  1434.  
  1435. #ifndef SPEAR
  1436.         gamestate.episode = tedlevelnum/10;
  1437.         gamestate.mapon = tedlevelnum%10;
  1438. #else
  1439.         gamestate.episode = 0;
  1440.         gamestate.mapon = tedlevelnum;
  1441. #endif
  1442.         GameLoop();
  1443.         Quit (NULL);
  1444.     }
  1445.  
  1446.  
  1447. //
  1448. // main game cycle
  1449. //
  1450.  
  1451.  
  1452. //    nsize = (long)40*1024;
  1453. //    MM_GetPtr(&nullblock,nsize);
  1454.  
  1455. #ifndef DEMOTEST
  1456.  
  1457.     #ifndef UPLOAD
  1458.  
  1459.         #ifndef GOODTIMES
  1460.         #ifndef SPEAR
  1461.         #ifndef JAPAN
  1462.         if (!NoWait)
  1463.             NonShareware();
  1464.         #endif
  1465.         #else
  1466.  
  1467.             #ifndef GOODTIMES
  1468.             #ifndef SPEARDEMO
  1469.             CopyProtection();
  1470.             #endif
  1471.             #endif
  1472.  
  1473.         #endif
  1474.         #endif
  1475.     #endif
  1476.  
  1477.     StartCPMusic(INTROSONG);
  1478.  
  1479. #ifndef JAPAN
  1480.     if (!NoWait)
  1481.         PG13 ();
  1482. #endif
  1483.  
  1484. #endif
  1485.  
  1486.     while (1)
  1487.     {
  1488.         while (!NoWait)
  1489.         {
  1490. //
  1491. // title page
  1492. //
  1493.             MM_SortMem ();
  1494. #ifndef DEMOTEST
  1495.  
  1496. #ifdef SPEAR
  1497.             CA_CacheGrChunk (TITLEPALETTE);
  1498.  
  1499.             CA_CacheGrChunk (TITLE1PIC);
  1500.             VWB_DrawPic (0,0,TITLE1PIC);
  1501.             UNCACHEGRCHUNK (TITLE1PIC);
  1502.  
  1503.             CA_CacheGrChunk (TITLE2PIC);
  1504.             VWB_DrawPic (0,80,TITLE2PIC);
  1505.             UNCACHEGRCHUNK (TITLE2PIC);
  1506.             VW_UpdateScreen ();
  1507.             VL_FadeIn(0,255,grsegs[TITLEPALETTE],30);
  1508.  
  1509.             UNCACHEGRCHUNK (TITLEPALETTE);
  1510. #else
  1511.             CA_CacheScreen (TITLEPIC);
  1512.             VW_UpdateScreen ();
  1513.             VW_FadeIn();
  1514. #endif
  1515.             if (IN_UserInput(TickBase*15))
  1516.                 break;
  1517.             VW_FadeOut();
  1518. //
  1519. // credits page
  1520. //
  1521.             CA_CacheScreen (CREDITSPIC);
  1522.             VW_UpdateScreen();
  1523.             VW_FadeIn ();
  1524.             if (IN_UserInput(TickBase*10))
  1525.                 break;
  1526.             VW_FadeOut ();
  1527. //
  1528. // high scores
  1529. //
  1530.             DrawHighScores ();
  1531.             VW_UpdateScreen ();
  1532.             VW_FadeIn ();
  1533.  
  1534.             if (IN_UserInput(TickBase*10))
  1535.                 break;
  1536. #endif
  1537. //
  1538. // demo
  1539. //
  1540.  
  1541.             #ifndef SPEARDEMO
  1542.             PlayDemo (LastDemo++%4);
  1543.             #else
  1544.             PlayDemo (0);
  1545.             #endif
  1546.  
  1547.             if (playstate == ex_abort)
  1548.                 break;
  1549.             StartCPMusic(INTROSONG);
  1550.         }
  1551.  
  1552.         VW_FadeOut ();
  1553.  
  1554. #ifndef SPEAR
  1555.         if (Keyboard[sc_Tab] && MS_CheckParm("goobers"))
  1556. #else
  1557.         if (Keyboard[sc_Tab] && MS_CheckParm("debugmode"))
  1558. #endif
  1559.             RecordDemo ();
  1560.         else
  1561.             US_ControlPanel (0);
  1562.  
  1563.         if (startgame || loadedgame)
  1564.         {
  1565.             GameLoop ();
  1566.             VW_FadeOut();
  1567.             StartCPMusic(INTROSONG);
  1568.         }
  1569.     }
  1570. }
  1571.  
  1572.  
  1573. //===========================================================================
  1574.  
  1575.  
  1576. /*
  1577. ==========================
  1578. =
  1579. = main
  1580. =
  1581. ==========================
  1582. */
  1583.  
  1584. char    *nosprtxt[] = {"nospr",nil};
  1585.  
  1586. void main (void)
  1587. {
  1588.     int     i;
  1589.  
  1590.  
  1591. #ifdef BETA
  1592.     //
  1593.     // THIS IS FOR BETA ONLY!
  1594.     //
  1595.     struct dosdate_t d;
  1596.  
  1597.     _dos_getdate(&d);
  1598.     if (d.year > YEAR ||
  1599.         (d.month >= MONTH && d.day >= DAY))
  1600.     {
  1601.      printf("Sorry, BETA-TESTING is over. Thanks for you help.\n");
  1602.      exit(1);
  1603.     }
  1604. #endif
  1605.  
  1606.     CheckForEpisodes();
  1607.  
  1608.     Patch386 ();
  1609.  
  1610.     InitGame ();
  1611.  
  1612.     DemoLoop();
  1613.  
  1614.     Quit("Demo loop exited???");
  1615. }
  1616.  
  1617.