wi_stuff.c
上传用户:xuyinpeng
上传日期:2021-05-12
资源大小:455k
文件大小:36k
源码类别:

射击游戏

开发平台:

Visual C++

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