home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -screenplay- / otherstuff / adoomppc_src / wi_stuff.c < prev    next >
C/C++ Source or Header  |  1998-04-23  |  34KB  |  1,855 lines

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