Subversion Repositories Kolibri OS

Rev

Rev 298 | Blame | 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. //      Intermission screens.
  21. //
  22. //-----------------------------------------------------------------------------
  23.  
  24. static const char
  25. rcsid[] = "$Id: wi_stuff.c,v 1.7 1997/02/03 22:45:13 b1 Exp $";
  26.  
  27. #include <stdio.h>
  28.  
  29. #include "z_zone.h"
  30.  
  31. #include "m_random.h"
  32. #include "m_swap.h"
  33.  
  34. #include "i_system.h"
  35.  
  36. #include "w_wad.h"
  37.  
  38. #include "g_game.h"
  39.  
  40. #include "r_local.h"
  41. #include "s_sound.h"
  42.  
  43. #include "doomstat.h"
  44.  
  45. // Data.
  46. #include "sounds.h"
  47.  
  48. // Needs access to LFB.
  49. #include "v_video.h"
  50.  
  51. #include "wi_stuff.h"
  52.  
  53. //
  54. // Data needed to add patches to full screen intermission pics.
  55. // Patches are statistics messages, and animations.
  56. // Loads of by-pixel layout and placement, offsets etc.
  57. //
  58.  
  59.  
  60. //
  61. // Different vetween registered DOOM (1994) and
  62. //  Ultimate DOOM - Final edition (retail, 1995?).
  63. // This is supposedly ignored for commercial
  64. //  release (aka DOOM II), which had 34 maps
  65. //  in one episode. So there.
  66. #define NUMEPISODES     4
  67. #define NUMMAPS         9
  68.  
  69.  
  70. // in tics
  71. //U #define PAUSELEN            (TICRATE*2)
  72. //U #define SCORESTEP           100
  73. //U #define ANIMPERIOD          32
  74. // pixel distance from "(YOU)" to "PLAYER N"
  75. //U #define STARDIST            10
  76. //U #define WK 1
  77.  
  78.  
  79. // GLOBAL LOCATIONS
  80. #define WI_TITLEY               2
  81. #define WI_SPACINGY             33
  82.  
  83. // SINGPLE-PLAYER STUFF
  84. #define SP_STATSX               50
  85. #define SP_STATSY               50
  86.  
  87. #define SP_TIMEX                16
  88. #define SP_TIMEY                (SCREENHEIGHT-32)
  89.  
  90.  
  91. // NET GAME STUFF
  92. #define NG_STATSY               50
  93. #define NG_STATSX               (32 + SHORT(star->width)/2 + 32*!dofrags)
  94.  
  95. #define NG_SPACINGX             64
  96.  
  97.  
  98. // DEATHMATCH STUFF
  99. #define DM_MATRIXX              42
  100. #define DM_MATRIXY              68
  101.  
  102. #define DM_SPACINGX             40
  103.  
  104. #define DM_TOTALSX              269
  105.  
  106. #define DM_KILLERSX             10
  107. #define DM_KILLERSY             100
  108. #define DM_VICTIMSX             5
  109. #define DM_VICTIMSY             50
  110.  
  111.  
  112.  
  113.  
  114. typedef enum
  115. {
  116.     ANIM_ALWAYS,
  117.     ANIM_RANDOM,
  118.     ANIM_LEVEL
  119.  
  120. } animenum_t;
  121.  
  122. typedef struct
  123. {
  124.     int         x;
  125.     int         y;
  126.    
  127. } point_t;
  128.  
  129.  
  130. //
  131. // Animation.
  132. // There is another anim_t used in p_spec.
  133. //
  134. typedef struct
  135. {
  136.     animenum_t  type;
  137.  
  138.     // period in tics between animations
  139.     int         period;
  140.  
  141.     // number of animation frames
  142.     int         nanims;
  143.  
  144.     // location of animation
  145.     point_t     loc;
  146.  
  147.     // ALWAYS: n/a,
  148.     // RANDOM: period deviation (<256),
  149.     // LEVEL: level
  150.     int         data1;
  151.  
  152.     // ALWAYS: n/a,
  153.     // RANDOM: random base period,
  154.     // LEVEL: n/a
  155.     int         data2;
  156.  
  157.     // actual graphics for frames of animations
  158.     patch_t*    p[3];
  159.  
  160.     // following must be initialized to zero before use!
  161.  
  162.     // next value of bcnt (used in conjunction with period)
  163.     int         nexttic;
  164.  
  165.     // last drawn animation frame
  166.     int         lastdrawn;
  167.  
  168.     // next frame number to animate
  169.     int         ctr;
  170.    
  171.     // used by RANDOM and LEVEL when animating
  172.     int         state;  
  173.  
  174. } anim_t;
  175.  
  176.  
  177. static point_t lnodes[NUMEPISODES][NUMMAPS] =
  178. {
  179.     // Episode 0 World Map
  180.     {
  181.         { 185, 164 },   // location of level 0 (CJ)
  182.         { 148, 143 },   // location of level 1 (CJ)
  183.         { 69, 122 },    // location of level 2 (CJ)
  184.         { 209, 102 },   // location of level 3 (CJ)
  185.         { 116, 89 },    // location of level 4 (CJ)
  186.         { 166, 55 },    // location of level 5 (CJ)
  187.         { 71, 56 },     // location of level 6 (CJ)
  188.         { 135, 29 },    // location of level 7 (CJ)
  189.         { 71, 24 }      // location of level 8 (CJ)
  190.     },
  191.  
  192.     // Episode 1 World Map should go here
  193.     {
  194.         { 254, 25 },    // location of level 0 (CJ)
  195.         { 97, 50 },     // location of level 1 (CJ)
  196.         { 188, 64 },    // location of level 2 (CJ)
  197.         { 128, 78 },    // location of level 3 (CJ)
  198.         { 214, 92 },    // location of level 4 (CJ)
  199.         { 133, 130 },   // location of level 5 (CJ)
  200.         { 208, 136 },   // location of level 6 (CJ)
  201.         { 148, 140 },   // location of level 7 (CJ)
  202.         { 235, 158 }    // location of level 8 (CJ)
  203.     },
  204.  
  205.     // Episode 2 World Map should go here
  206.     {
  207.         { 156, 168 },   // location of level 0 (CJ)
  208.         { 48, 154 },    // location of level 1 (CJ)
  209.         { 174, 95 },    // location of level 2 (CJ)
  210.         { 265, 75 },    // location of level 3 (CJ)
  211.         { 130, 48 },    // location of level 4 (CJ)
  212.         { 279, 23 },    // location of level 5 (CJ)
  213.         { 198, 48 },    // location of level 6 (CJ)
  214.         { 140, 25 },    // location of level 7 (CJ)
  215.         { 281, 136 }    // location of level 8 (CJ)
  216.     }
  217.  
  218. };
  219.  
  220.  
  221. //
  222. // Animation locations for episode 0 (1).
  223. // Using patches saves a lot of space,
  224. //  as they replace 320x200 full screen frames.
  225. //
  226. static anim_t epsd0animinfo[] =
  227. {
  228.     { ANIM_ALWAYS, TICRATE/3, 3, { 224, 104 } },
  229.     { ANIM_ALWAYS, TICRATE/3, 3, { 184, 160 } },
  230.     { ANIM_ALWAYS, TICRATE/3, 3, { 112, 136 } },
  231.     { ANIM_ALWAYS, TICRATE/3, 3, { 72, 112 } },
  232.     { ANIM_ALWAYS, TICRATE/3, 3, { 88, 96 } },
  233.     { ANIM_ALWAYS, TICRATE/3, 3, { 64, 48 } },
  234.     { ANIM_ALWAYS, TICRATE/3, 3, { 192, 40 } },
  235.     { ANIM_ALWAYS, TICRATE/3, 3, { 136, 16 } },
  236.     { ANIM_ALWAYS, TICRATE/3, 3, { 80, 16 } },
  237.     { ANIM_ALWAYS, TICRATE/3, 3, { 64, 24 } }
  238. };
  239.  
  240. static anim_t epsd1animinfo[] =
  241. {
  242.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 1 },
  243.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 2 },
  244.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 3 },
  245.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 4 },
  246.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 5 },
  247.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 6 },
  248.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 7 },
  249.     { ANIM_LEVEL, TICRATE/3, 3, { 192, 144 }, 8 },
  250.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 8 }
  251. };
  252.  
  253. static anim_t epsd2animinfo[] =
  254. {
  255.     { ANIM_ALWAYS, TICRATE/3, 3, { 104, 168 } },
  256.     { ANIM_ALWAYS, TICRATE/3, 3, { 40, 136 } },
  257.     { ANIM_ALWAYS, TICRATE/3, 3, { 160, 96 } },
  258.     { ANIM_ALWAYS, TICRATE/3, 3, { 104, 80 } },
  259.     { ANIM_ALWAYS, TICRATE/3, 3, { 120, 32 } },
  260.     { ANIM_ALWAYS, TICRATE/4, 3, { 40, 0 } }
  261. };
  262.  
  263. static int NUMANIMS[NUMEPISODES] =
  264. {
  265.     sizeof(epsd0animinfo)/sizeof(anim_t),
  266.     sizeof(epsd1animinfo)/sizeof(anim_t),
  267.     sizeof(epsd2animinfo)/sizeof(anim_t)
  268. };
  269.  
  270. static anim_t *anims[NUMEPISODES] =
  271. {
  272.     epsd0animinfo,
  273.     epsd1animinfo,
  274.     epsd2animinfo
  275. };
  276.  
  277.  
  278. //
  279. // GENERAL DATA
  280. //
  281.  
  282. //
  283. // Locally used stuff.
  284. //
  285. #define FB 0
  286.  
  287.  
  288. // States for single-player
  289. #define SP_KILLS                0
  290. #define SP_ITEMS                2
  291. #define SP_SECRET               4
  292. #define SP_FRAGS                6
  293. #define SP_TIME                 8
  294. #define SP_PAR                  ST_TIME
  295.  
  296. #define SP_PAUSE                1
  297.  
  298. // in seconds
  299. #define SHOWNEXTLOCDELAY        4
  300. //#define SHOWLASTLOCDELAY      SHOWNEXTLOCDELAY
  301.  
  302.  
  303. // used to accelerate or skip a stage
  304. static int              acceleratestage;
  305.  
  306. // wbs->pnum
  307. static int              me;
  308.  
  309.  // specifies current state
  310. static stateenum_t      state;
  311.  
  312. // contains information passed into intermission
  313. static wbstartstruct_t* wbs;
  314.  
  315. static wbplayerstruct_t* plrs;  // wbs->plyr[]
  316.  
  317. // used for general timing
  318. static int              cnt;  
  319.  
  320. // used for timing of background animation
  321. static int              bcnt;
  322.  
  323. // signals to refresh everything for one frame
  324. static int              firstrefresh;
  325.  
  326. static int              cnt_kills[MAXPLAYERS];
  327. static int              cnt_items[MAXPLAYERS];
  328. static int              cnt_secret[MAXPLAYERS];
  329. static int              cnt_time;
  330. static int              cnt_par;
  331. static int              cnt_pause;
  332.  
  333. // # of commercial levels
  334. static int              NUMCMAPS;
  335.  
  336.  
  337. //
  338. //      GRAPHICS
  339. //
  340.  
  341. // background (map of levels).
  342. static patch_t*         bg;
  343.  
  344. // You Are Here graphic
  345. static patch_t*         yah[2];
  346.  
  347. // splat
  348. static patch_t*         splat;
  349.  
  350. // %, : graphics
  351. static patch_t*         percent;
  352. static patch_t*         colon;
  353.  
  354. // 0-9 graphic
  355. static patch_t*         num[10];
  356.  
  357. // minus sign
  358. static patch_t*         wiminus;
  359.  
  360. // "Finished!" graphics
  361. static patch_t*         finished;
  362.  
  363. // "Entering" graphic
  364. static patch_t*         entering;
  365.  
  366. // "secret"
  367. static patch_t*         sp_secret;
  368.  
  369.  // "Kills", "Scrt", "Items", "Frags"
  370. static patch_t*         kills;
  371. static patch_t*         secret;
  372. static patch_t*         items;
  373. static patch_t*         frags;
  374.  
  375. // Time sucks.
  376. static patch_t*         d_time;
  377. static patch_t*         par;
  378. static patch_t*         sucks;
  379.  
  380. // "killers", "victims"
  381. static patch_t*         killers;
  382. static patch_t*         victims;
  383.  
  384. // "Total", your face, your dead face
  385. static patch_t*         total;
  386. static patch_t*         star;
  387. static patch_t*         bstar;
  388.  
  389. // "red P[1..MAXPLAYERS]"
  390. static patch_t*         p[MAXPLAYERS];
  391.  
  392. // "gray P[1..MAXPLAYERS]"
  393. static patch_t*         bp[MAXPLAYERS];
  394.  
  395.  // Name graphics of each level (centered)
  396. static patch_t**        lnames;
  397.  
  398. //
  399. // CODE
  400. //
  401.  
  402. // slam background
  403. // UNUSED static unsigned char *background=0;
  404.  
  405.  
  406. void WI_slamBackground(void)
  407. {
  408.     memcpy(screens[0], screens[1], SCREENWIDTH * SCREENHEIGHT);
  409.     V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
  410. }
  411.  
  412. // The ticker is used to detect keys
  413. //  because of timing issues in netgames.
  414. boolean WI_Responder(event_t* ev)
  415. {
  416.     return false;
  417. }
  418.  
  419.  
  420. // Draws "<Levelname> Finished!"
  421. void WI_drawLF(void)
  422. {
  423.     int y = WI_TITLEY;
  424.  
  425.     // draw <LevelName>
  426.     V_DrawPatch((SCREENWIDTH - SHORT(lnames[wbs->last]->width))/2,
  427.                 y, FB, lnames[wbs->last]);
  428.  
  429.     // draw "Finished!"
  430.     y += (5*SHORT(lnames[wbs->last]->height))/4;
  431.    
  432.     V_DrawPatch((SCREENWIDTH - SHORT(finished->width))/2,
  433.                 y, FB, finished);
  434. }
  435.  
  436.  
  437.  
  438. // Draws "Entering <LevelName>"
  439. void WI_drawEL(void)
  440. {
  441.     int y = WI_TITLEY;
  442.  
  443.     // draw "Entering"
  444.     V_DrawPatch((SCREENWIDTH - SHORT(entering->width))/2,
  445.                 y, FB, entering);
  446.  
  447.     // draw level
  448.     y += (5*SHORT(lnames[wbs->next]->height))/4;
  449.  
  450.     V_DrawPatch((SCREENWIDTH - SHORT(lnames[wbs->next]->width))/2,
  451.                 y, FB, lnames[wbs->next]);
  452.  
  453. }
  454.  
  455. void
  456. WI_drawOnLnode
  457. ( int           n,
  458.   patch_t*      c[] )
  459. {
  460.  
  461.     int         i;
  462.     int         left;
  463.     int         top;
  464.     int         right;
  465.     int         bottom;
  466.     boolean     fits = false;
  467.  
  468.     i = 0;
  469.     do
  470.     {
  471.         left = lnodes[wbs->epsd][n].x - SHORT(c[i]->leftoffset);
  472.         top = lnodes[wbs->epsd][n].y - SHORT(c[i]->topoffset);
  473.         right = left + SHORT(c[i]->width);
  474.         bottom = top + SHORT(c[i]->height);
  475.  
  476.         if (left >= 0
  477.             && right < SCREENWIDTH
  478.             && top >= 0
  479.             && bottom < SCREENHEIGHT)
  480.         {
  481.             fits = true;
  482.         }
  483.         else
  484.         {
  485.             i++;
  486.         }
  487.     } while (!fits && i!=2);
  488.  
  489.     if (fits && i<2)
  490.     {
  491.         V_DrawPatch(lnodes[wbs->epsd][n].x, lnodes[wbs->epsd][n].y,
  492.                     FB, c[i]);
  493.     }
  494.     else
  495.     {
  496.         // DEBUG
  497.           printf("Could not place patch on level %d", n+1);
  498.     }
  499. }
  500.  
  501.  
  502.  
  503. void WI_initAnimatedBack(void)
  504. {
  505.     int         i;
  506.     anim_t*     a;
  507.  
  508.     if (gamemode == commercial)
  509.         return;
  510.  
  511.     if (wbs->epsd > 2)
  512.         return;
  513.  
  514.     for (i=0;i<NUMANIMS[wbs->epsd];i++)
  515.     {
  516.         a = &anims[wbs->epsd][i];
  517.  
  518.         // init variables
  519.         a->ctr = -1;
  520.  
  521.         // specify the next time to draw it
  522.         if (a->type == ANIM_ALWAYS)
  523.             a->nexttic = bcnt + 1 + (M_Random()%a->period);
  524.         else if (a->type == ANIM_RANDOM)
  525.             a->nexttic = bcnt + 1 + a->data2+(M_Random()%a->data1);
  526.         else if (a->type == ANIM_LEVEL)
  527.             a->nexttic = bcnt + 1;
  528.     }
  529.  
  530. }
  531.  
  532. void WI_updateAnimatedBack(void)
  533. {
  534.     int         i;
  535.     anim_t*     a;
  536.  
  537.     if (gamemode == commercial)
  538.         return;
  539.  
  540.     if (wbs->epsd > 2)
  541.         return;
  542.  
  543.     for (i=0;i<NUMANIMS[wbs->epsd];i++)
  544.     {
  545.         a = &anims[wbs->epsd][i];
  546.  
  547.         if (bcnt == a->nexttic)
  548.         {
  549.             switch (a->type)
  550.             {
  551.               case ANIM_ALWAYS:
  552.                 if (++a->ctr >= a->nanims) a->ctr = 0;
  553.                 a->nexttic = bcnt + a->period;
  554.                 break;
  555.  
  556.               case ANIM_RANDOM:
  557.                 a->ctr++;
  558.                 if (a->ctr == a->nanims)
  559.                 {
  560.                     a->ctr = -1;
  561.                     a->nexttic = bcnt+a->data2+(M_Random()%a->data1);
  562.                 }
  563.                 else a->nexttic = bcnt + a->period;
  564.                 break;
  565.                
  566.               case ANIM_LEVEL:
  567.                 // gawd-awful hack for level anims
  568.                 if (!(state == StatCount && i == 7)
  569.                     && wbs->next == a->data1)
  570.                 {
  571.                     a->ctr++;
  572.                     if (a->ctr == a->nanims) a->ctr--;
  573.                     a->nexttic = bcnt + a->period;
  574.                 }
  575.                 break;
  576.             }
  577.         }
  578.  
  579.     }
  580.  
  581. }
  582.  
  583. void WI_drawAnimatedBack(void)
  584. {
  585.     int                 i;
  586.     anim_t*             a;
  587.  
  588.     if (commercial)
  589.         return;
  590.  
  591.     if (wbs->epsd > 2)
  592.         return;
  593.  
  594.     for (i=0 ; i<NUMANIMS[wbs->epsd] ; i++)
  595.     {
  596.         a = &anims[wbs->epsd][i];
  597.  
  598.         if (a->ctr >= 0)
  599.             V_DrawPatch(a->loc.x, a->loc.y, FB, a->p[a->ctr]);
  600.     }
  601.  
  602. }
  603.  
  604. //
  605. // Draws a number.
  606. // If digits > 0, then use that many digits minimum,
  607. //  otherwise only use as many as necessary.
  608. // Returns new x position.
  609. //
  610.  
  611. int
  612. WI_drawNum
  613. ( int           x,
  614.   int           y,
  615.   int           n,
  616.   int           digits )
  617. {
  618.  
  619.     int         fontwidth = SHORT(num[0]->width);
  620.     int         neg;
  621.     int         temp;
  622.  
  623.     if (digits < 0)
  624.     {
  625.         if (!n)
  626.         {
  627.             // make variable-length zeros 1 digit long
  628.             digits = 1;
  629.         }
  630.         else
  631.         {
  632.             // figure out # of digits in #
  633.             digits = 0;
  634.             temp = n;
  635.  
  636.             while (temp)
  637.             {
  638.                 temp /= 10;
  639.                 digits++;
  640.             }
  641.         }
  642.     }
  643.  
  644.     neg = n < 0;
  645.     if (neg)
  646.         n = -n;
  647.  
  648.     // if non-number, do not draw it
  649.     if (n == 1994)
  650.         return 0;
  651.  
  652.     // draw the new number
  653.     while (digits--)
  654.     {
  655.         x -= fontwidth;
  656.         V_DrawPatch(x, y, FB, num[ n % 10 ]);
  657.         n /= 10;
  658.     }
  659.  
  660.     // draw a minus sign if necessary
  661.     if (neg)
  662.         V_DrawPatch(x-=8, y, FB, wiminus);
  663.  
  664.     return x;
  665.  
  666. }
  667.  
  668. void
  669. WI_drawPercent
  670. ( int           x,
  671.   int           y,
  672.   int           p )
  673. {
  674.     if (p < 0)
  675.         return;
  676.  
  677.     V_DrawPatch(x, y, FB, percent);
  678.     WI_drawNum(x, y, p, -1);
  679. }
  680.  
  681.  
  682.  
  683. //
  684. // Display level completion time and par,
  685. //  or "sucks" message if overflow.
  686. //
  687. void
  688. WI_drawTime
  689. ( int           x,
  690.   int           y,
  691.   int           t )
  692. {
  693.  
  694.     int         div;
  695.     int         n;
  696.  
  697.     if (t<0)
  698.         return;
  699.  
  700.     if (t <= 61*59)
  701.     {
  702.         div = 1;
  703.  
  704.         do
  705.         {
  706.             n = (t / div) % 60;
  707.             x = WI_drawNum(x, y, n, 2) - SHORT(colon->width);
  708.             div *= 60;
  709.  
  710.             // draw
  711.             if (div==60 || t / div)
  712.                 V_DrawPatch(x, y, FB, colon);
  713.            
  714.         } while (t / div);
  715.     }
  716.     else
  717.     {
  718.         // "sucks"
  719.         V_DrawPatch(x - SHORT(sucks->width), y, FB, sucks);
  720.     }
  721. }
  722.  
  723.  
  724. void WI_End(void)
  725. {
  726.     void WI_unloadData(void);
  727.     WI_unloadData();
  728. }
  729.  
  730. void WI_initNoState(void)
  731. {
  732.     state = NoState;
  733.     acceleratestage = 0;
  734.     cnt = 10;
  735. }
  736.  
  737. void WI_updateNoState(void) {
  738.  
  739.     WI_updateAnimatedBack();
  740.  
  741.     if (!--cnt)
  742.     {
  743.         WI_End();
  744.         G_WorldDone();
  745.     }
  746.  
  747. }
  748.  
  749. static boolean          snl_pointeron = false;
  750.  
  751.  
  752. void WI_initShowNextLoc(void)
  753. {
  754.     state = ShowNextLoc;
  755.     acceleratestage = 0;
  756.     cnt = SHOWNEXTLOCDELAY * TICRATE;
  757.  
  758.     WI_initAnimatedBack();
  759. }
  760.  
  761. void WI_updateShowNextLoc(void)
  762. {
  763.     WI_updateAnimatedBack();
  764.  
  765.     if (!--cnt || acceleratestage)
  766.         WI_initNoState();
  767.     else
  768.         snl_pointeron = (cnt & 31) < 20;
  769. }
  770.  
  771. void WI_drawShowNextLoc(void)
  772. {
  773.  
  774.     int         i;
  775.     int         last;
  776.  
  777.     WI_slamBackground();
  778.  
  779.     // draw animated background
  780.     WI_drawAnimatedBack();
  781.  
  782.     if ( gamemode != commercial)
  783.     {
  784.         if (wbs->epsd > 2)
  785.         {
  786.             WI_drawEL();
  787.             return;
  788.         }
  789.        
  790.         last = (wbs->last == 8) ? wbs->next - 1 : wbs->last;
  791.  
  792.         // draw a splat on taken cities.
  793.         for (i=0 ; i<=last ; i++)
  794.             WI_drawOnLnode(i, &splat);
  795.  
  796.         // splat the secret level?
  797.         if (wbs->didsecret)
  798.             WI_drawOnLnode(8, &splat);
  799.  
  800.         // draw flashing ptr
  801.         if (snl_pointeron)
  802.             WI_drawOnLnode(wbs->next, yah);
  803.     }
  804.  
  805.     // draws which level you are entering..
  806.     if ( (gamemode != commercial)
  807.          || wbs->next != 30)
  808.         WI_drawEL();  
  809.  
  810. }
  811.  
  812. void WI_drawNoState(void)
  813. {
  814.     snl_pointeron = true;
  815.     WI_drawShowNextLoc();
  816. }
  817.  
  818. int WI_fragSum(int playernum)
  819. {
  820.     int         i;
  821.     int         frags = 0;
  822.    
  823.     for (i=0 ; i<MAXPLAYERS ; i++)
  824.     {
  825.         if (playeringame[i]
  826.             && i!=playernum)
  827.         {
  828.             frags += plrs[playernum].frags[i];
  829.         }
  830.     }
  831.  
  832.        
  833.     // JDC hack - negative frags.
  834.     frags -= plrs[playernum].frags[playernum];
  835.     // UNUSED if (frags < 0)
  836.     //  frags = 0;
  837.  
  838.     return frags;
  839. }
  840.  
  841.  
  842.  
  843. static int              dm_state;
  844. static int              dm_frags[MAXPLAYERS][MAXPLAYERS];
  845. static int              dm_totals[MAXPLAYERS];
  846.  
  847.  
  848.  
  849. void WI_initDeathmatchStats(void)
  850. {
  851.  
  852.     int         i;
  853.     int         j;
  854.  
  855.     state = StatCount;
  856.     acceleratestage = 0;
  857.     dm_state = 1;
  858.  
  859.     cnt_pause = TICRATE;
  860.  
  861.     for (i=0 ; i<MAXPLAYERS ; i++)
  862.     {
  863.         if (playeringame[i])
  864.         {
  865.             for (j=0 ; j<MAXPLAYERS ; j++)
  866.                 if (playeringame[j])
  867.                     dm_frags[i][j] = 0;
  868.  
  869.             dm_totals[i] = 0;
  870.         }
  871.     }
  872.    
  873.     WI_initAnimatedBack();
  874. }
  875.  
  876.  
  877.  
  878. void WI_updateDeathmatchStats(void)
  879. {
  880.  
  881.     int         i;
  882.     int         j;
  883.    
  884.     boolean     stillticking;
  885.  
  886.     WI_updateAnimatedBack();
  887.  
  888.     if (acceleratestage && dm_state != 4)
  889.     {
  890.         acceleratestage = 0;
  891.  
  892.         for (i=0 ; i<MAXPLAYERS ; i++)
  893.         {
  894.             if (playeringame[i])
  895.             {
  896.                 for (j=0 ; j<MAXPLAYERS ; j++)
  897.                     if (playeringame[j])
  898.                         dm_frags[i][j] = plrs[i].frags[j];
  899.  
  900.                 dm_totals[i] = WI_fragSum(i);
  901.             }
  902.         }
  903.        
  904.  
  905.         S_StartSound(0, sfx_barexp);
  906.         dm_state = 4;
  907.     }
  908.  
  909.    
  910.     if (dm_state == 2)
  911.     {
  912.         if (!(bcnt&3))
  913.             S_StartSound(0, sfx_pistol);
  914.        
  915.         stillticking = false;
  916.  
  917.         for (i=0 ; i<MAXPLAYERS ; i++)
  918.         {
  919.             if (playeringame[i])
  920.             {
  921.                 for (j=0 ; j<MAXPLAYERS ; j++)
  922.                 {
  923.                     if (playeringame[j]
  924.                         && dm_frags[i][j] != plrs[i].frags[j])
  925.                     {
  926.                         if (plrs[i].frags[j] < 0)
  927.                             dm_frags[i][j]--;
  928.                         else
  929.                             dm_frags[i][j]++;
  930.  
  931.                         if (dm_frags[i][j] > 99)
  932.                             dm_frags[i][j] = 99;
  933.  
  934.                         if (dm_frags[i][j] < -99)
  935.                             dm_frags[i][j] = -99;
  936.                        
  937.                         stillticking = true;
  938.                     }
  939.                 }
  940.                 dm_totals[i] = WI_fragSum(i);
  941.  
  942.                 if (dm_totals[i] > 99)
  943.                     dm_totals[i] = 99;
  944.                
  945.                 if (dm_totals[i] < -99)
  946.                     dm_totals[i] = -99;
  947.             }
  948.            
  949.         }
  950.         if (!stillticking)
  951.         {
  952.             S_StartSound(0, sfx_barexp);
  953.             dm_state++;
  954.         }
  955.  
  956.     }
  957.     else if (dm_state == 4)
  958.     {
  959.         if (acceleratestage)
  960.         {
  961.             S_StartSound(0, sfx_slop);
  962.  
  963.             if ( gamemode == commercial)
  964.                 WI_initNoState();
  965.             else
  966.                 WI_initShowNextLoc();
  967.         }
  968.     }
  969.     else if (dm_state & 1)
  970.     {
  971.         if (!--cnt_pause)
  972.         {
  973.             dm_state++;
  974.             cnt_pause = TICRATE;
  975.         }
  976.     }
  977. }
  978.  
  979.  
  980.  
  981. void WI_drawDeathmatchStats(void)
  982. {
  983.  
  984.     int         i;
  985.     int         j;
  986.     int         x;
  987.     int         y;
  988.     int         w;
  989.    
  990.     int         lh;     // line height
  991.  
  992.     lh = WI_SPACINGY;
  993.  
  994.     WI_slamBackground();
  995.    
  996.     // draw animated background
  997.     WI_drawAnimatedBack();
  998.     WI_drawLF();
  999.  
  1000.     // draw stat titles (top line)
  1001.     V_DrawPatch(DM_TOTALSX-SHORT(total->width)/2,
  1002.                 DM_MATRIXY-WI_SPACINGY+10,
  1003.                 FB,
  1004.                 total);
  1005.    
  1006.     V_DrawPatch(DM_KILLERSX, DM_KILLERSY, FB, killers);
  1007.     V_DrawPatch(DM_VICTIMSX, DM_VICTIMSY, FB, victims);
  1008.  
  1009.     // draw P?
  1010.     x = DM_MATRIXX + DM_SPACINGX;
  1011.     y = DM_MATRIXY;
  1012.  
  1013.     for (i=0 ; i<MAXPLAYERS ; i++)
  1014.     {
  1015.         if (playeringame[i])
  1016.         {
  1017.             V_DrawPatch(x-SHORT(p[i]->width)/2,
  1018.                         DM_MATRIXY - WI_SPACINGY,
  1019.                         FB,
  1020.                         p[i]);
  1021.            
  1022.             V_DrawPatch(DM_MATRIXX-SHORT(p[i]->width)/2,
  1023.                         y,
  1024.                         FB,
  1025.                         p[i]);
  1026.  
  1027.             if (i == me)
  1028.             {
  1029.                 V_DrawPatch(x-SHORT(p[i]->width)/2,
  1030.                             DM_MATRIXY - WI_SPACINGY,
  1031.                             FB,
  1032.                             bstar);
  1033.  
  1034.                 V_DrawPatch(DM_MATRIXX-SHORT(p[i]->width)/2,
  1035.                             y,
  1036.                             FB,
  1037.                             star);
  1038.             }
  1039.         }
  1040.         else
  1041.         {
  1042.             // V_DrawPatch(x-SHORT(bp[i]->width)/2,
  1043.             //   DM_MATRIXY - WI_SPACINGY, FB, bp[i]);
  1044.             // V_DrawPatch(DM_MATRIXX-SHORT(bp[i]->width)/2,
  1045.             //   y, FB, bp[i]);
  1046.         }
  1047.         x += DM_SPACINGX;
  1048.         y += WI_SPACINGY;
  1049.     }
  1050.  
  1051.     // draw stats
  1052.     y = DM_MATRIXY+10;
  1053.     w = SHORT(num[0]->width);
  1054.  
  1055.     for (i=0 ; i<MAXPLAYERS ; i++)
  1056.     {
  1057.         x = DM_MATRIXX + DM_SPACINGX;
  1058.  
  1059.         if (playeringame[i])
  1060.         {
  1061.             for (j=0 ; j<MAXPLAYERS ; j++)
  1062.             {
  1063.                 if (playeringame[j])
  1064.                     WI_drawNum(x+w, y, dm_frags[i][j], 2);
  1065.  
  1066.                 x += DM_SPACINGX;
  1067.             }
  1068.             WI_drawNum(DM_TOTALSX+w, y, dm_totals[i], 2);
  1069.         }
  1070.         y += WI_SPACINGY;
  1071.     }
  1072. }
  1073.  
  1074. static int      cnt_frags[MAXPLAYERS];
  1075. static int      dofrags;
  1076. static int      ng_state;
  1077.  
  1078. void WI_initNetgameStats(void)
  1079. {
  1080.  
  1081.     int i;
  1082.  
  1083.     state = StatCount;
  1084.     acceleratestage = 0;
  1085.     ng_state = 1;
  1086.  
  1087.     cnt_pause = TICRATE;
  1088.  
  1089.     for (i=0 ; i<MAXPLAYERS ; i++)
  1090.     {
  1091.         if (!playeringame[i])
  1092.             continue;
  1093.  
  1094.         cnt_kills[i] = cnt_items[i] = cnt_secret[i] = cnt_frags[i] = 0;
  1095.  
  1096.         dofrags += WI_fragSum(i);
  1097.     }
  1098.  
  1099.     dofrags = !!dofrags;
  1100.  
  1101.     WI_initAnimatedBack();
  1102. }
  1103.  
  1104.  
  1105.  
  1106. void WI_updateNetgameStats(void)
  1107. {
  1108.  
  1109.     int         i;
  1110.     int         fsum;
  1111.    
  1112.     boolean     stillticking;
  1113.  
  1114.     WI_updateAnimatedBack();
  1115.  
  1116.     if (acceleratestage && ng_state != 10)
  1117.     {
  1118.         acceleratestage = 0;
  1119.  
  1120.         for (i=0 ; i<MAXPLAYERS ; i++)
  1121.         {
  1122.             if (!playeringame[i])
  1123.                 continue;
  1124.  
  1125.             cnt_kills[i] = (plrs[i].skills * 100) / wbs->maxkills;
  1126.             cnt_items[i] = (plrs[i].sitems * 100) / wbs->maxitems;
  1127.             cnt_secret[i] = (plrs[i].ssecret * 100) / wbs->maxsecret;
  1128.  
  1129.             if (dofrags)
  1130.                 cnt_frags[i] = WI_fragSum(i);
  1131.         }
  1132.         S_StartSound(0, sfx_barexp);
  1133.         ng_state = 10;
  1134.     }
  1135.  
  1136.     if (ng_state == 2)
  1137.     {
  1138.         if (!(bcnt&3))
  1139.             S_StartSound(0, sfx_pistol);
  1140.  
  1141.         stillticking = false;
  1142.  
  1143.         for (i=0 ; i<MAXPLAYERS ; i++)
  1144.         {
  1145.             if (!playeringame[i])
  1146.                 continue;
  1147.  
  1148.             cnt_kills[i] += 2;
  1149.  
  1150.             if (cnt_kills[i] >= (plrs[i].skills * 100) / wbs->maxkills)
  1151.                 cnt_kills[i] = (plrs[i].skills * 100) / wbs->maxkills;
  1152.             else
  1153.                 stillticking = true;
  1154.         }
  1155.        
  1156.         if (!stillticking)
  1157.         {
  1158.             S_StartSound(0, sfx_barexp);
  1159.             ng_state++;
  1160.         }
  1161.     }
  1162.     else if (ng_state == 4)
  1163.     {
  1164.         if (!(bcnt&3))
  1165.             S_StartSound(0, sfx_pistol);
  1166.  
  1167.         stillticking = false;
  1168.  
  1169.         for (i=0 ; i<MAXPLAYERS ; i++)
  1170.         {
  1171.             if (!playeringame[i])
  1172.                 continue;
  1173.  
  1174.             cnt_items[i] += 2;
  1175.             if (cnt_items[i] >= (plrs[i].sitems * 100) / wbs->maxitems)
  1176.                 cnt_items[i] = (plrs[i].sitems * 100) / wbs->maxitems;
  1177.             else
  1178.                 stillticking = true;
  1179.         }
  1180.         if (!stillticking)
  1181.         {
  1182.             S_StartSound(0, sfx_barexp);
  1183.             ng_state++;
  1184.         }
  1185.     }
  1186.     else if (ng_state == 6)
  1187.     {
  1188.         if (!(bcnt&3))
  1189.             S_StartSound(0, sfx_pistol);
  1190.  
  1191.         stillticking = false;
  1192.  
  1193.         for (i=0 ; i<MAXPLAYERS ; i++)
  1194.         {
  1195.             if (!playeringame[i])
  1196.                 continue;
  1197.  
  1198.             cnt_secret[i] += 2;
  1199.  
  1200.             if (cnt_secret[i] >= (plrs[i].ssecret * 100) / wbs->maxsecret)
  1201.                 cnt_secret[i] = (plrs[i].ssecret * 100) / wbs->maxsecret;
  1202.             else
  1203.                 stillticking = true;
  1204.         }
  1205.        
  1206.         if (!stillticking)
  1207.         {
  1208.             S_StartSound(0, sfx_barexp);
  1209.             ng_state += 1 + 2*!dofrags;
  1210.         }
  1211.     }
  1212.     else if (ng_state == 8)
  1213.     {
  1214.         if (!(bcnt&3))
  1215.             S_StartSound(0, sfx_pistol);
  1216.  
  1217.         stillticking = false;
  1218.  
  1219.         for (i=0 ; i<MAXPLAYERS ; i++)
  1220.         {
  1221.             if (!playeringame[i])
  1222.                 continue;
  1223.  
  1224.             cnt_frags[i] += 1;
  1225.  
  1226.             if (cnt_frags[i] >= (fsum = WI_fragSum(i)))
  1227.                 cnt_frags[i] = fsum;
  1228.             else
  1229.                 stillticking = true;
  1230.         }
  1231.        
  1232.         if (!stillticking)
  1233.         {
  1234.             S_StartSound(0, sfx_pldeth);
  1235.             ng_state++;
  1236.         }
  1237.     }
  1238.     else if (ng_state == 10)
  1239.     {
  1240.         if (acceleratestage)
  1241.         {
  1242.             S_StartSound(0, sfx_sgcock);
  1243.             if ( gamemode == commercial )
  1244.                 WI_initNoState();
  1245.             else
  1246.                 WI_initShowNextLoc();
  1247.         }
  1248.     }
  1249.     else if (ng_state & 1)
  1250.     {
  1251.         if (!--cnt_pause)
  1252.         {
  1253.             ng_state++;
  1254.             cnt_pause = TICRATE;
  1255.         }
  1256.     }
  1257. }
  1258.  
  1259.  
  1260.  
  1261. void WI_drawNetgameStats(void)
  1262. {
  1263.     int         i;
  1264.     int         x;
  1265.     int         y;
  1266.     int         pwidth = SHORT(percent->width);
  1267.  
  1268.     WI_slamBackground();
  1269.    
  1270.     // draw animated background
  1271.     WI_drawAnimatedBack();
  1272.  
  1273.     WI_drawLF();
  1274.  
  1275.     // draw stat titles (top line)
  1276.     V_DrawPatch(NG_STATSX+NG_SPACINGX-SHORT(kills->width),
  1277.                 NG_STATSY, FB, kills);
  1278.  
  1279.     V_DrawPatch(NG_STATSX+2*NG_SPACINGX-SHORT(items->width),
  1280.                 NG_STATSY, FB, items);
  1281.  
  1282.     V_DrawPatch(NG_STATSX+3*NG_SPACINGX-SHORT(secret->width),
  1283.                 NG_STATSY, FB, secret);
  1284.    
  1285.     if (dofrags)
  1286.         V_DrawPatch(NG_STATSX+4*NG_SPACINGX-SHORT(frags->width),
  1287.                     NG_STATSY, FB, frags);
  1288.  
  1289.     // draw stats
  1290.     y = NG_STATSY + SHORT(kills->height);
  1291.  
  1292.     for (i=0 ; i<MAXPLAYERS ; i++)
  1293.     {
  1294.         if (!playeringame[i])
  1295.             continue;
  1296.  
  1297.         x = NG_STATSX;
  1298.         V_DrawPatch(x-SHORT(p[i]->width), y, FB, p[i]);
  1299.  
  1300.         if (i == me)
  1301.             V_DrawPatch(x-SHORT(p[i]->width), y, FB, star);
  1302.  
  1303.         x += NG_SPACINGX;
  1304.         WI_drawPercent(x-pwidth, y+10, cnt_kills[i]);   x += NG_SPACINGX;
  1305.         WI_drawPercent(x-pwidth, y+10, cnt_items[i]);   x += NG_SPACINGX;
  1306.         WI_drawPercent(x-pwidth, y+10, cnt_secret[i]);  x += NG_SPACINGX;
  1307.  
  1308.         if (dofrags)
  1309.             WI_drawNum(x, y+10, cnt_frags[i], -1);
  1310.  
  1311.         y += WI_SPACINGY;
  1312.     }
  1313.  
  1314. }
  1315.  
  1316. static int      sp_state;
  1317.  
  1318. void WI_initStats(void)
  1319. {
  1320.     state = StatCount;
  1321.     acceleratestage = 0;
  1322.     sp_state = 1;
  1323.     cnt_kills[0] = cnt_items[0] = cnt_secret[0] = -1;
  1324.     cnt_time = cnt_par = -1;
  1325.     cnt_pause = TICRATE;
  1326.  
  1327.     WI_initAnimatedBack();
  1328. }
  1329.  
  1330. void WI_updateStats(void)
  1331. {
  1332.  
  1333.     WI_updateAnimatedBack();
  1334.  
  1335.     if (acceleratestage && sp_state != 10)
  1336.     {
  1337.         acceleratestage = 0;
  1338.         cnt_kills[0] = (plrs[me].skills * 100) / wbs->maxkills;
  1339.         cnt_items[0] = (plrs[me].sitems * 100) / wbs->maxitems;
  1340.         cnt_secret[0] = (plrs[me].ssecret * 100) / wbs->maxsecret;
  1341.         cnt_time = plrs[me].stime / TICRATE;
  1342.         cnt_par = wbs->partime / TICRATE;
  1343.         S_StartSound(0, sfx_barexp);
  1344.         sp_state = 10;
  1345.     }
  1346.  
  1347.     if (sp_state == 2)
  1348.     {
  1349.         cnt_kills[0] += 2;
  1350.  
  1351.         if (!(bcnt&3))
  1352.             S_StartSound(0, sfx_pistol);
  1353.  
  1354.         if (cnt_kills[0] >= (plrs[me].skills * 100) / wbs->maxkills)
  1355.         {
  1356.             cnt_kills[0] = (plrs[me].skills * 100) / wbs->maxkills;
  1357.             S_StartSound(0, sfx_barexp);
  1358.             sp_state++;
  1359.         }
  1360.     }
  1361.     else if (sp_state == 4)
  1362.     {
  1363.         cnt_items[0] += 2;
  1364.  
  1365.         if (!(bcnt&3))
  1366.             S_StartSound(0, sfx_pistol);
  1367.  
  1368.         if (cnt_items[0] >= (plrs[me].sitems * 100) / wbs->maxitems)
  1369.         {
  1370.             cnt_items[0] = (plrs[me].sitems * 100) / wbs->maxitems;
  1371.             S_StartSound(0, sfx_barexp);
  1372.             sp_state++;
  1373.         }
  1374.     }
  1375.     else if (sp_state == 6)
  1376.     {
  1377.         cnt_secret[0] += 2;
  1378.  
  1379.         if (!(bcnt&3))
  1380.             S_StartSound(0, sfx_pistol);
  1381.  
  1382.         if (cnt_secret[0] >= (plrs[me].ssecret * 100) / wbs->maxsecret)
  1383.         {
  1384.             cnt_secret[0] = (plrs[me].ssecret * 100) / wbs->maxsecret;
  1385.             S_StartSound(0, sfx_barexp);
  1386.             sp_state++;
  1387.         }
  1388.     }
  1389.  
  1390.     else if (sp_state == 8)
  1391.     {
  1392.         if (!(bcnt&3))
  1393.             S_StartSound(0, sfx_pistol);
  1394.  
  1395.         cnt_time += 3;
  1396.  
  1397.         if (cnt_time >= plrs[me].stime / TICRATE)
  1398.             cnt_time = plrs[me].stime / TICRATE;
  1399.  
  1400.         cnt_par += 3;
  1401.  
  1402.         if (cnt_par >= wbs->partime / TICRATE)
  1403.         {
  1404.             cnt_par = wbs->partime / TICRATE;
  1405.  
  1406.             if (cnt_time >= plrs[me].stime / TICRATE)
  1407.             {
  1408.                 S_StartSound(0, sfx_barexp);
  1409.                 sp_state++;
  1410.             }
  1411.         }
  1412.     }
  1413.     else if (sp_state == 10)
  1414.     {
  1415.         if (acceleratestage)
  1416.         {
  1417.             S_StartSound(0, sfx_sgcock);
  1418.  
  1419.             if (gamemode == commercial)
  1420.                 WI_initNoState();
  1421.             else
  1422.                 WI_initShowNextLoc();
  1423.         }
  1424.     }
  1425.     else if (sp_state & 1)
  1426.     {
  1427.         if (!--cnt_pause)
  1428.         {
  1429.             sp_state++;
  1430.             cnt_pause = TICRATE;
  1431.         }
  1432.     }
  1433.  
  1434. }
  1435.  
  1436. void WI_drawStats(void)
  1437. {
  1438.     // line height
  1439.     int lh;    
  1440.  
  1441.     lh = (3*SHORT(num[0]->height))/2;
  1442.  
  1443.     WI_slamBackground();
  1444.  
  1445.     // draw animated background
  1446.     WI_drawAnimatedBack();
  1447.    
  1448.     WI_drawLF();
  1449.  
  1450.     V_DrawPatch(SP_STATSX, SP_STATSY, FB, kills);
  1451.     WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY, cnt_kills[0]);
  1452.  
  1453.     V_DrawPatch(SP_STATSX, SP_STATSY+lh, FB, items);
  1454.     WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY+lh, cnt_items[0]);
  1455.  
  1456.     V_DrawPatch(SP_STATSX, SP_STATSY+2*lh, FB, sp_secret);
  1457.     WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY+2*lh, cnt_secret[0]);
  1458.  
  1459.     V_DrawPatch(SP_TIMEX, SP_TIMEY, FB, d_time);
  1460.     WI_drawTime(SCREENWIDTH/2 - SP_TIMEX, SP_TIMEY, cnt_time);
  1461.  
  1462.     if (wbs->epsd < 3)
  1463.     {
  1464.         V_DrawPatch(SCREENWIDTH/2 + SP_TIMEX, SP_TIMEY, FB, par);
  1465.         WI_drawTime(SCREENWIDTH - SP_TIMEX, SP_TIMEY, cnt_par);
  1466.     }
  1467.  
  1468. }
  1469.  
  1470. void WI_checkForAccelerate(void)
  1471. {
  1472.     int   i;
  1473.     player_t  *player;
  1474.  
  1475.     // check for button presses to skip delays
  1476.     for (i=0, player = players ; i<MAXPLAYERS ; i++, player++)
  1477.     {
  1478.         if (playeringame[i])
  1479.         {
  1480.             if (player->cmd.buttons & BT_ATTACK)
  1481.             {
  1482.                 if (!player->attackdown)
  1483.                     acceleratestage = 1;
  1484.                 player->attackdown = true;
  1485.             }
  1486.             else
  1487.                 player->attackdown = false;
  1488.             if (player->cmd.buttons & BT_USE)
  1489.             {
  1490.                 if (!player->usedown)
  1491.                     acceleratestage = 1;
  1492.                 player->usedown = true;
  1493.             }
  1494.             else
  1495.                 player->usedown = false;
  1496.         }
  1497.     }
  1498. }
  1499.  
  1500.  
  1501.  
  1502. // Updates stuff each tick
  1503. void WI_Ticker(void)
  1504. {
  1505.     // counter for general background animation
  1506.     bcnt++;  
  1507.  
  1508.     if (bcnt == 1)
  1509.     {
  1510.         // intermission music
  1511.         if ( gamemode == commercial )
  1512.           S_ChangeMusic(mus_dm2int, true);
  1513.         else
  1514.           S_ChangeMusic(mus_inter, true);
  1515.     }
  1516.  
  1517.     WI_checkForAccelerate();
  1518.  
  1519.     switch (state)
  1520.     {
  1521.       case StatCount:
  1522.         if (deathmatch) WI_updateDeathmatchStats();
  1523.         else if (netgame) WI_updateNetgameStats();
  1524.         else WI_updateStats();
  1525.         break;
  1526.        
  1527.       case ShowNextLoc:
  1528.         WI_updateShowNextLoc();
  1529.         break;
  1530.        
  1531.       case NoState:
  1532.         WI_updateNoState();
  1533.         break;
  1534.     }
  1535.  
  1536. }
  1537.  
  1538. void WI_loadData(void)
  1539. {
  1540.     int         i;
  1541.     int         j;
  1542.     char        name[9];
  1543.     anim_t*     a;
  1544.  
  1545.     if (gamemode == commercial)
  1546.         strcpy(name, "INTERPIC");
  1547.     else
  1548.         sprintf(name, "WIMAP%d", wbs->epsd);
  1549.    
  1550.     if ( gamemode == retail )
  1551.     {
  1552.       if (wbs->epsd == 3)
  1553.         strcpy(name,"INTERPIC");
  1554.     }
  1555.  
  1556.     // background
  1557.     bg = W_CacheLumpName(name, PU_CACHE);    
  1558.     V_DrawPatch(0, 0, 1, bg);
  1559.  
  1560.  
  1561.     // UNUSED unsigned char *pic = screens[1];
  1562.     // if (gamemode == commercial)
  1563.     // {
  1564.     // darken the background image
  1565.     // while (pic != screens[1] + SCREENHEIGHT*SCREENWIDTH)
  1566.     // {
  1567.     //   *pic = colormaps[256*25 + *pic];
  1568.     //   pic++;
  1569.     // }
  1570.     //}
  1571.  
  1572.     if (gamemode == commercial)
  1573.     {
  1574.         NUMCMAPS = 32;                                                         
  1575.         lnames = (patch_t **) Z_Malloc(sizeof(patch_t*) * NUMCMAPS,
  1576.                                        PU_STATIC, 0);
  1577.         for (i=0 ; i<NUMCMAPS ; i++)
  1578.         {                                                              
  1579.             sprintf(name, "CWILV%2.2d", i);
  1580.             lnames[i] = W_CacheLumpName(name, PU_STATIC);
  1581.         }                                      
  1582.     }
  1583.     else
  1584.     {
  1585.         lnames = (patch_t **) Z_Malloc(sizeof(patch_t*) * NUMMAPS,
  1586.                                        PU_STATIC, 0);
  1587.         for (i=0 ; i<NUMMAPS ; i++)
  1588.         {
  1589.             sprintf(name, "WILV%d%d", wbs->epsd, i);
  1590.             lnames[i] = W_CacheLumpName(name, PU_STATIC);
  1591.         }
  1592.  
  1593.         // you are here
  1594.         yah[0] = W_CacheLumpName("WIURH0", PU_STATIC);
  1595.  
  1596.         // you are here (alt.)
  1597.         yah[1] = W_CacheLumpName("WIURH1", PU_STATIC);
  1598.  
  1599.         // splat
  1600.         splat = W_CacheLumpName("WISPLAT", PU_STATIC);
  1601.        
  1602.         if (wbs->epsd < 3)
  1603.         {
  1604.             for (j=0;j<NUMANIMS[wbs->epsd];j++)
  1605.             {
  1606.                 a = &anims[wbs->epsd][j];
  1607.                 for (i=0;i<a->nanims;i++)
  1608.                 {
  1609.                     // MONDO HACK!
  1610.                     if (wbs->epsd != 1 || j != 8)
  1611.                     {
  1612.                         // animations
  1613.                         sprintf(name, "WIA%d%.2d%.2d", wbs->epsd, j, i);  
  1614.                         a->p[i] = W_CacheLumpName(name, PU_STATIC);
  1615.                     }
  1616.                     else
  1617.                     {
  1618.                         // HACK ALERT!
  1619.                         a->p[i] = anims[1][4].p[i];
  1620.                     }
  1621.                 }
  1622.             }
  1623.         }
  1624.     }
  1625.  
  1626.     // More hacks on minus sign.
  1627.     wiminus = W_CacheLumpName("WIMINUS", PU_STATIC);
  1628.  
  1629.     for (i=0;i<10;i++)
  1630.     {
  1631.          // numbers 0-9
  1632.         sprintf(name, "WINUM%d", i);    
  1633.         num[i] = W_CacheLumpName(name, PU_STATIC);
  1634.     }
  1635.  
  1636.     // percent sign
  1637.     percent = W_CacheLumpName("WIPCNT", PU_STATIC);
  1638.  
  1639.     // "finished"
  1640.     finished = W_CacheLumpName("WIF", PU_STATIC);
  1641.  
  1642.     // "entering"
  1643.     entering = W_CacheLumpName("WIENTER", PU_STATIC);
  1644.  
  1645.     // "kills"
  1646.     kills = W_CacheLumpName("WIOSTK", PU_STATIC);  
  1647.  
  1648.     // "scrt"
  1649.     secret = W_CacheLumpName("WIOSTS", PU_STATIC);
  1650.  
  1651.      // "secret"
  1652.     sp_secret = W_CacheLumpName("WISCRT2", PU_STATIC);
  1653.  
  1654.     // Yuck.
  1655.     if (french)
  1656.     {
  1657.         // "items"
  1658.         if (netgame && !deathmatch)
  1659.             items = W_CacheLumpName("WIOBJ", PU_STATIC);    
  1660.         else
  1661.             items = W_CacheLumpName("WIOSTI", PU_STATIC);
  1662.     } else
  1663.         items = W_CacheLumpName("WIOSTI", PU_STATIC);
  1664.  
  1665.     // "frgs"
  1666.     frags = W_CacheLumpName("WIFRGS", PU_STATIC);    
  1667.  
  1668.     // ":"
  1669.     colon = W_CacheLumpName("WICOLON", PU_STATIC);
  1670.  
  1671.     // "time"
  1672.     d_time = W_CacheLumpName("WITIME", PU_STATIC);  
  1673.  
  1674.     // "sucks"
  1675.     sucks = W_CacheLumpName("WISUCKS", PU_STATIC);  
  1676.  
  1677.     // "par"
  1678.     par = W_CacheLumpName("WIPAR", PU_STATIC);  
  1679.  
  1680.     // "killers" (vertical)
  1681.     killers = W_CacheLumpName("WIKILRS", PU_STATIC);
  1682.  
  1683.     // "victims" (horiz)
  1684.     victims = W_CacheLumpName("WIVCTMS", PU_STATIC);
  1685.  
  1686.     // "total"
  1687.     total = W_CacheLumpName("WIMSTT", PU_STATIC);  
  1688.  
  1689.     // your face
  1690.     star = W_CacheLumpName("STFST01", PU_STATIC);
  1691.  
  1692.     // dead face
  1693.     bstar = W_CacheLumpName("STFDEAD0", PU_STATIC);    
  1694.  
  1695.     for (i=0 ; i<MAXPLAYERS ; i++)
  1696.     {
  1697.         // "1,2,3,4"
  1698.         sprintf(name, "STPB%d", i);      
  1699.         p[i] = W_CacheLumpName(name, PU_STATIC);
  1700.  
  1701.         // "1,2,3,4"
  1702.         sprintf(name, "WIBP%d", i+1);    
  1703.         bp[i] = W_CacheLumpName(name, PU_STATIC);
  1704.     }
  1705.  
  1706. }
  1707.  
  1708. void WI_unloadData(void)
  1709. {
  1710.     int         i;
  1711.     int         j;
  1712.  
  1713.     Z_ChangeTag(wiminus, PU_CACHE);
  1714.  
  1715.     for (i=0 ; i<10 ; i++)
  1716.         Z_ChangeTag(num[i], PU_CACHE);
  1717.    
  1718.     if (gamemode == commercial)
  1719.     {
  1720.         for (i=0 ; i<NUMCMAPS ; i++)
  1721.             Z_ChangeTag(lnames[i], PU_CACHE);
  1722.     }
  1723.     else
  1724.     {
  1725.         Z_ChangeTag(yah[0], PU_CACHE);
  1726.         Z_ChangeTag(yah[1], PU_CACHE);
  1727.  
  1728.         Z_ChangeTag(splat, PU_CACHE);
  1729.  
  1730.         for (i=0 ; i<NUMMAPS ; i++)
  1731.             Z_ChangeTag(lnames[i], PU_CACHE);
  1732.        
  1733.         if (wbs->epsd < 3)
  1734.         {
  1735.             for (j=0;j<NUMANIMS[wbs->epsd];j++)
  1736.             {
  1737.                 if (wbs->epsd != 1 || j != 8)
  1738.                     for (i=0;i<anims[wbs->epsd][j].nanims;i++)
  1739.                         Z_ChangeTag(anims[wbs->epsd][j].p[i], PU_CACHE);
  1740.             }
  1741.         }
  1742.     }
  1743.    
  1744.     Z_Free(lnames);
  1745.  
  1746.     Z_ChangeTag(percent, PU_CACHE);
  1747.     Z_ChangeTag(colon, PU_CACHE);
  1748.     Z_ChangeTag(finished, PU_CACHE);
  1749.     Z_ChangeTag(entering, PU_CACHE);
  1750.     Z_ChangeTag(kills, PU_CACHE);
  1751.     Z_ChangeTag(secret, PU_CACHE);
  1752.     Z_ChangeTag(sp_secret, PU_CACHE);
  1753.     Z_ChangeTag(items, PU_CACHE);
  1754.     Z_ChangeTag(frags, PU_CACHE);
  1755.     Z_ChangeTag(d_time, PU_CACHE);
  1756.     Z_ChangeTag(sucks, PU_CACHE);
  1757.     Z_ChangeTag(par, PU_CACHE);
  1758.  
  1759.     Z_ChangeTag(victims, PU_CACHE);
  1760.     Z_ChangeTag(killers, PU_CACHE);
  1761.     Z_ChangeTag(total, PU_CACHE);
  1762.     //  Z_ChangeTag(star, PU_CACHE);
  1763.     //  Z_ChangeTag(bstar, PU_CACHE);
  1764.    
  1765.     for (i=0 ; i<MAXPLAYERS ; i++)
  1766.         Z_ChangeTag(p[i], PU_CACHE);
  1767.  
  1768.     for (i=0 ; i<MAXPLAYERS ; i++)
  1769.         Z_ChangeTag(bp[i], PU_CACHE);
  1770. }
  1771.  
  1772. void WI_Drawer (void)
  1773. {
  1774.     switch (state)
  1775.     {
  1776.       case StatCount:
  1777.         if (deathmatch)
  1778.             WI_drawDeathmatchStats();
  1779.         else if (netgame)
  1780.             WI_drawNetgameStats();
  1781.         else
  1782.             WI_drawStats();
  1783.         break;
  1784.        
  1785.       case ShowNextLoc:
  1786.         WI_drawShowNextLoc();
  1787.         break;
  1788.        
  1789.       case NoState:
  1790.         WI_drawNoState();
  1791.         break;
  1792.     }
  1793. }
  1794.  
  1795.  
  1796. void WI_initVariables(wbstartstruct_t* wbstartstruct)
  1797. {
  1798.  
  1799.     wbs = wbstartstruct;
  1800.  
  1801. #ifdef RANGECHECKING
  1802.     if (gamemode != commercial)
  1803.     {
  1804.       if ( gamemode == retail )
  1805.         RNGCHECK(wbs->epsd, 0, 3);
  1806.       else
  1807.         RNGCHECK(wbs->epsd, 0, 2);
  1808.     }
  1809.     else
  1810.     {
  1811.         RNGCHECK(wbs->last, 0, 8);
  1812.         RNGCHECK(wbs->next, 0, 8);
  1813.     }
  1814.     RNGCHECK(wbs->pnum, 0, MAXPLAYERS);
  1815.     RNGCHECK(wbs->pnum, 0, MAXPLAYERS);
  1816. #endif
  1817.  
  1818.     acceleratestage = 0;
  1819.     cnt = bcnt = 0;
  1820.     firstrefresh = 1;
  1821.     me = wbs->pnum;
  1822.     plrs = wbs->plyr;
  1823.  
  1824.     if (!wbs->maxkills)
  1825.         wbs->maxkills = 1;
  1826.  
  1827.     if (!wbs->maxitems)
  1828.         wbs->maxitems = 1;
  1829.  
  1830.     if (!wbs->maxsecret)
  1831.         wbs->maxsecret = 1;
  1832.  
  1833.     if ( gamemode != retail )
  1834.       if (wbs->epsd > 2)
  1835.         wbs->epsd -= 3;
  1836. }
  1837.  
  1838. void WI_Start(wbstartstruct_t* wbstartstruct)
  1839. {
  1840.  
  1841.     WI_initVariables(wbstartstruct);
  1842.     WI_loadData();
  1843.  
  1844.     if (deathmatch)
  1845.         WI_initDeathmatchStats();
  1846.     else if (netgame)
  1847.         WI_initNetgameStats();
  1848.     else
  1849.         WI_initStats();
  1850. }
  1851.