1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
6 // Copyright (C) 1993-1996 by id Software, Inc.
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.
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
20 // Intermission screens.
22 //-----------------------------------------------------------------------------
25 rcsid[] = "$Id: wi_stuff.c,v 1.7 1997/02/03 22:45:13 b1 Exp $";
46 // Needs access to LFB.
52 // Data needed to add patches to full screen intermission pics.
53 // Patches are statistics messages, and animations.
54 // Loads of by-pixel layout and placement, offsets etc.
59 // Different vetween registered DOOM (1994) and
60 // Ultimate DOOM - Final edition (retail, 1995?).
61 // This is supposedly ignored for commercial
62 // release (aka DOOM II), which had 34 maps
63 // in one episode. So there.
69 //U #define PAUSELEN (TICRATE*2)
70 //U #define SCORESTEP 100
71 //U #define ANIMPERIOD 32
72 // pixel distance from "(YOU)" to "PLAYER N"
73 //U #define STARDIST 10
79 #define WI_SPACINGY 33
81 // SINGPLE-PLAYER STUFF
86 #define SP_TIMEY (SCREENHEIGHT-32)
91 #define NG_STATSX (32 + SHORT(star->width)/2 + 32*!dofrags)
93 #define NG_SPACINGX 64
100 #define DM_SPACINGX 40
102 #define DM_TOTALSX 269
104 #define DM_KILLERSX 10
105 #define DM_KILLERSY 100
106 #define DM_VICTIMSX 5
107 #define DM_VICTIMSY 50
130 // There is another anim_t used in p_spec.
136 // period in tics between animations
139 // number of animation frames
142 // location of animation
146 // RANDOM: period deviation (<256),
151 // RANDOM: random base period,
155 // actual graphics for frames of animations
158 // following must be initialized to zero before use!
160 // next value of bcnt (used in conjunction with period)
163 // last drawn animation frame
166 // next frame number to animate
169 // used by RANDOM and LEVEL when animating
175 static point_t lnodes[NUMEPISODES][NUMMAPS] =
177 // Episode 0 World Map
179 { 185, 164 }, // location of level 0 (CJ)
180 { 148, 143 }, // location of level 1 (CJ)
181 { 69, 122 }, // location of level 2 (CJ)
182 { 209, 102 }, // location of level 3 (CJ)
183 { 116, 89 }, // location of level 4 (CJ)
184 { 166, 55 }, // location of level 5 (CJ)
185 { 71, 56 }, // location of level 6 (CJ)
186 { 135, 29 }, // location of level 7 (CJ)
187 { 71, 24 } // location of level 8 (CJ)
190 // Episode 1 World Map should go here
192 { 254, 25 }, // location of level 0 (CJ)
193 { 97, 50 }, // location of level 1 (CJ)
194 { 188, 64 }, // location of level 2 (CJ)
195 { 128, 78 }, // location of level 3 (CJ)
196 { 214, 92 }, // location of level 4 (CJ)
197 { 133, 130 }, // location of level 5 (CJ)
198 { 208, 136 }, // location of level 6 (CJ)
199 { 148, 140 }, // location of level 7 (CJ)
200 { 235, 158 } // location of level 8 (CJ)
203 // Episode 2 World Map should go here
205 { 156, 168 }, // location of level 0 (CJ)
206 { 48, 154 }, // location of level 1 (CJ)
207 { 174, 95 }, // location of level 2 (CJ)
208 { 265, 75 }, // location of level 3 (CJ)
209 { 130, 48 }, // location of level 4 (CJ)
210 { 279, 23 }, // location of level 5 (CJ)
211 { 198, 48 }, // location of level 6 (CJ)
212 { 140, 25 }, // location of level 7 (CJ)
213 { 281, 136 } // location of level 8 (CJ)
220 // Animation locations for episode 0 (1).
221 // Using patches saves a lot of space,
222 // as they replace 320x200 full screen frames.
224 static anim_t epsd0animinfo[] =
226 { ANIM_ALWAYS, TICRATE/3, 3, { 224, 104 } },
227 { ANIM_ALWAYS, TICRATE/3, 3, { 184, 160 } },
228 { ANIM_ALWAYS, TICRATE/3, 3, { 112, 136 } },
229 { ANIM_ALWAYS, TICRATE/3, 3, { 72, 112 } },
230 { ANIM_ALWAYS, TICRATE/3, 3, { 88, 96 } },
231 { ANIM_ALWAYS, TICRATE/3, 3, { 64, 48 } },
232 { ANIM_ALWAYS, TICRATE/3, 3, { 192, 40 } },
233 { ANIM_ALWAYS, TICRATE/3, 3, { 136, 16 } },
234 { ANIM_ALWAYS, TICRATE/3, 3, { 80, 16 } },
235 { ANIM_ALWAYS, TICRATE/3, 3, { 64, 24 } }
238 static anim_t epsd1animinfo[] =
240 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 1 },
241 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 2 },
242 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 3 },
243 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 4 },
244 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 5 },
245 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 6 },
246 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 7 },
247 { ANIM_LEVEL, TICRATE/3, 3, { 192, 144 }, 8 },
248 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 8 }
251 static anim_t epsd2animinfo[] =
253 { ANIM_ALWAYS, TICRATE/3, 3, { 104, 168 } },
254 { ANIM_ALWAYS, TICRATE/3, 3, { 40, 136 } },
255 { ANIM_ALWAYS, TICRATE/3, 3, { 160, 96 } },
256 { ANIM_ALWAYS, TICRATE/3, 3, { 104, 80 } },
257 { ANIM_ALWAYS, TICRATE/3, 3, { 120, 32 } },
258 { ANIM_ALWAYS, TICRATE/4, 3, { 40, 0 } }
261 static int NUMANIMS[NUMEPISODES] =
263 sizeof(epsd0animinfo)/sizeof(anim_t),
264 sizeof(epsd1animinfo)/sizeof(anim_t),
265 sizeof(epsd2animinfo)/sizeof(anim_t)
268 static anim_t *anims[NUMEPISODES] =
281 // Locally used stuff.
286 // States for single-player
292 #define SP_PAR ST_TIME
297 #define SHOWNEXTLOCDELAY 4
298 //#define SHOWLASTLOCDELAY SHOWNEXTLOCDELAY
301 // used to accelerate or skip a stage
302 static int acceleratestage;
307 // specifies current state
308 static stateenum_t state;
310 // contains information passed into intermission
311 static wbstartstruct_t* wbs;
313 static wbplayerstruct_t* plrs; // wbs->plyr[]
315 // used for general timing
318 // used for timing of background animation
321 // signals to refresh everything for one frame
322 static int firstrefresh;
324 static int cnt_kills[MAXPLAYERS];
325 static int cnt_items[MAXPLAYERS];
326 static int cnt_secret[MAXPLAYERS];
329 static int cnt_pause;
331 // # of commercial levels
339 // background (map of levels).
342 // You Are Here graphic
343 static patch_t* yah[2];
346 static patch_t* splat;
349 static patch_t* percent;
350 static patch_t* colon;
353 static patch_t* num[10];
356 static patch_t* wiminus;
358 // "Finished!" graphics
359 static patch_t* finished;
361 // "Entering" graphic
362 static patch_t* entering;
365 static patch_t* sp_secret;
367 // "Kills", "Scrt", "Items", "Frags"
368 static patch_t* kills;
369 static patch_t* secret;
370 static patch_t* items;
371 static patch_t* frags;
374 static patch_t* Time;
376 static patch_t* sucks;
378 // "killers", "victims"
379 static patch_t* killers;
380 static patch_t* victims;
382 // "Total", your face, your dead face
383 static patch_t* total;
384 static patch_t* star;
385 static patch_t* bstar;
387 // "red P[1..MAXPLAYERS]"
388 static patch_t* p[MAXPLAYERS];
390 // "gray P[1..MAXPLAYERS]"
391 static patch_t* bp[MAXPLAYERS];
393 // Name graphics of each level (centered)
394 static patch_t** lnames;
401 // UNUSED static unsigned char *background=0;
404 void WI_slamBackground(void)
406 memcpy(screens[0], screens[1], SCREENWIDTH * SCREENHEIGHT);
407 V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
410 // The ticker is used to detect keys
411 // because of timing issues in netgames.
412 boolean WI_Responder(event_t* /*ev*/)
418 // Draws "<Levelname> Finished!"
424 V_DrawPatch((SCREENWIDTH - SHORT(lnames[wbs->last]->width))/2,
425 y, FB, lnames[wbs->last]);
428 y += (5*SHORT(lnames[wbs->last]->height))/4;
430 V_DrawPatch((SCREENWIDTH - SHORT(finished->width))/2,
436 // Draws "Entering <LevelName>"
442 V_DrawPatch((SCREENWIDTH - SHORT(entering->width))/2,
446 y += (5*SHORT(lnames[wbs->next]->height))/4;
448 V_DrawPatch((SCREENWIDTH - SHORT(lnames[wbs->next]->width))/2,
449 y, FB, lnames[wbs->next]);
464 boolean fits = false;
469 left = lnodes[wbs->epsd][n].x - SHORT(c[i]->leftoffset);
470 top = lnodes[wbs->epsd][n].y - SHORT(c[i]->topoffset);
471 right = left + SHORT(c[i]->width);
472 bottom = top + SHORT(c[i]->height);
475 && right < SCREENWIDTH
477 && bottom < SCREENHEIGHT)
485 } while (!fits && i!=2);
489 V_DrawPatch(lnodes[wbs->epsd][n].x, lnodes[wbs->epsd][n].y,
495 printf("Could not place patch on level %d", n+1);
501 void WI_initAnimatedBack(void)
506 if (gamemode == commercial)
512 for (i=0;i<NUMANIMS[wbs->epsd];i++)
514 a = &anims[wbs->epsd][i];
519 // specify the next time to draw it
520 if (a->type == ANIM_ALWAYS)
521 a->nexttic = bcnt + 1 + (M_Random()%a->period);
522 else if (a->type == ANIM_RANDOM)
523 a->nexttic = bcnt + 1 + a->data2+(M_Random()%a->data1);
524 else if (a->type == ANIM_LEVEL)
525 a->nexttic = bcnt + 1;
530 void WI_updateAnimatedBack(void)
535 if (gamemode == commercial)
541 for (i=0;i<NUMANIMS[wbs->epsd];i++)
543 a = &anims[wbs->epsd][i];
545 if (bcnt == a->nexttic)
550 if (++a->ctr >= a->nanims) a->ctr = 0;
551 a->nexttic = bcnt + a->period;
556 if (a->ctr == a->nanims)
559 a->nexttic = bcnt+a->data2+(M_Random()%a->data1);
561 else a->nexttic = bcnt + a->period;
565 // gawd-awful hack for level anims
566 if (!(state == StatCount && i == 7)
567 && wbs->next == a->data1)
570 if (a->ctr == a->nanims) a->ctr--;
571 a->nexttic = bcnt + a->period;
581 void WI_drawAnimatedBack(void)
592 for (i=0 ; i<NUMANIMS[wbs->epsd] ; i++)
594 a = &anims[wbs->epsd][i];
597 V_DrawPatch(a->loc.x, a->loc.y, FB, a->p[a->ctr]);
604 // If digits > 0, then use that many digits minimum,
605 // otherwise only use as many as necessary.
606 // Returns new x position.
617 int fontwidth = SHORT(num[0]->width);
625 // make variable-length zeros 1 digit long
630 // figure out # of digits in #
646 // if non-number, do not draw it
650 // draw the new number
654 V_DrawPatch(x, y, FB, num[ n % 10 ]);
658 // draw a minus sign if necessary
660 V_DrawPatch(x-=8, y, FB, wiminus);
675 V_DrawPatch(x, y, FB, percent);
676 WI_drawNum(x, y, p, -1);
682 // Display level completion time and par,
683 // or "sucks" message if overflow.
705 x = WI_drawNum(x, y, n, 2) - SHORT(colon->width);
709 if (div==60 || t / div)
710 V_DrawPatch(x, y, FB, colon);
717 V_DrawPatch(x - SHORT(sucks->width), y, FB, sucks);
724 void WI_unloadData(void);
728 void WI_initNoState(void)
735 void WI_updateNoState(void) {
737 WI_updateAnimatedBack();
747 static boolean snl_pointeron = false;
750 void WI_initShowNextLoc(void)
754 cnt = SHOWNEXTLOCDELAY * TICRATE;
756 WI_initAnimatedBack();
759 void WI_updateShowNextLoc(void)
761 WI_updateAnimatedBack();
763 if (!--cnt || acceleratestage)
766 snl_pointeron = (cnt & 31) < 20;
769 void WI_drawShowNextLoc(void)
777 // draw animated background
778 WI_drawAnimatedBack();
780 if ( gamemode != commercial)
788 last = (wbs->last == 8) ? wbs->next - 1 : wbs->last;
790 // draw a splat on taken cities.
791 for (i=0 ; i<=last ; i++)
792 WI_drawOnLnode(i, &splat);
794 // splat the secret level?
796 WI_drawOnLnode(8, &splat);
800 WI_drawOnLnode(wbs->next, yah);
803 // draws which level you are entering..
804 if ( (gamemode != commercial)
810 void WI_drawNoState(void)
812 snl_pointeron = true;
813 WI_drawShowNextLoc();
816 int WI_fragSum(int playernum)
821 for (i=0 ; i<MAXPLAYERS ; i++)
826 frags += plrs[playernum].frags[i];
831 // JDC hack - negative frags.
832 frags -= plrs[playernum].frags[playernum];
833 // UNUSED if (frags < 0)
842 static int dm_frags[MAXPLAYERS][MAXPLAYERS];
843 static int dm_totals[MAXPLAYERS];
847 void WI_initDeathmatchStats(void)
859 for (i=0 ; i<MAXPLAYERS ; i++)
863 for (j=0 ; j<MAXPLAYERS ; j++)
871 WI_initAnimatedBack();
876 void WI_updateDeathmatchStats(void)
882 boolean stillticking;
884 WI_updateAnimatedBack();
886 if (acceleratestage && dm_state != 4)
890 for (i=0 ; i<MAXPLAYERS ; i++)
894 for (j=0 ; j<MAXPLAYERS ; j++)
896 dm_frags[i][j] = plrs[i].frags[j];
898 dm_totals[i] = WI_fragSum(i);
903 S_StartSound(0, sfx_barexp);
911 S_StartSound(0, sfx_pistol);
913 stillticking = false;
915 for (i=0 ; i<MAXPLAYERS ; i++)
919 for (j=0 ; j<MAXPLAYERS ; j++)
922 && dm_frags[i][j] != plrs[i].frags[j])
924 if (plrs[i].frags[j] < 0)
929 if (dm_frags[i][j] > 99)
932 if (dm_frags[i][j] < -99)
933 dm_frags[i][j] = -99;
938 dm_totals[i] = WI_fragSum(i);
940 if (dm_totals[i] > 99)
943 if (dm_totals[i] < -99)
950 S_StartSound(0, sfx_barexp);
955 else if (dm_state == 4)
959 S_StartSound(0, sfx_slop);
961 if ( gamemode == commercial)
964 WI_initShowNextLoc();
967 else if (dm_state & 1)
979 void WI_drawDeathmatchStats(void)
990 // draw animated background
991 WI_drawAnimatedBack();
994 // draw stat titles (top line)
995 V_DrawPatch(DM_TOTALSX-SHORT(total->width)/2,
996 DM_MATRIXY-WI_SPACINGY+10,
1000 V_DrawPatch(DM_KILLERSX, DM_KILLERSY, FB, killers);
1001 V_DrawPatch(DM_VICTIMSX, DM_VICTIMSY, FB, victims);
1004 x = DM_MATRIXX + DM_SPACINGX;
1007 for (i=0 ; i<MAXPLAYERS ; i++)
1009 if (playeringame[i])
1011 V_DrawPatch(x-SHORT(p[i]->width)/2,
1012 DM_MATRIXY - WI_SPACINGY,
1016 V_DrawPatch(DM_MATRIXX-SHORT(p[i]->width)/2,
1023 V_DrawPatch(x-SHORT(p[i]->width)/2,
1024 DM_MATRIXY - WI_SPACINGY,
1028 V_DrawPatch(DM_MATRIXX-SHORT(p[i]->width)/2,
1036 // V_DrawPatch(x-SHORT(bp[i]->width)/2,
1037 // DM_MATRIXY - WI_SPACINGY, FB, bp[i]);
1038 // V_DrawPatch(DM_MATRIXX-SHORT(bp[i]->width)/2,
1047 w = SHORT(num[0]->width);
1049 for (i=0 ; i<MAXPLAYERS ; i++)
1051 x = DM_MATRIXX + DM_SPACINGX;
1053 if (playeringame[i])
1055 for (j=0 ; j<MAXPLAYERS ; j++)
1057 if (playeringame[j])
1058 WI_drawNum(x+w, y, dm_frags[i][j], 2);
1062 WI_drawNum(DM_TOTALSX+w, y, dm_totals[i], 2);
1068 static int cnt_frags[MAXPLAYERS];
1070 static int ng_state;
1072 void WI_initNetgameStats(void)
1078 acceleratestage = 0;
1081 cnt_pause = TICRATE;
1083 for (i=0 ; i<MAXPLAYERS ; i++)
1085 if (!playeringame[i])
1088 cnt_kills[i] = cnt_items[i] = cnt_secret[i] = cnt_frags[i] = 0;
1090 dofrags += WI_fragSum(i);
1093 dofrags = !!dofrags;
1095 WI_initAnimatedBack();
1100 void WI_updateNetgameStats(void)
1106 boolean stillticking;
1108 WI_updateAnimatedBack();
1110 if (acceleratestage && ng_state != 10)
1112 acceleratestage = 0;
1114 for (i=0 ; i<MAXPLAYERS ; i++)
1116 if (!playeringame[i])
1119 cnt_kills[i] = (plrs[i].skills * 100) / wbs->maxkills;
1120 cnt_items[i] = (plrs[i].sitems * 100) / wbs->maxitems;
1121 cnt_secret[i] = (plrs[i].ssecret * 100) / wbs->maxsecret;
1124 cnt_frags[i] = WI_fragSum(i);
1126 S_StartSound(0, sfx_barexp);
1133 S_StartSound(0, sfx_pistol);
1135 stillticking = false;
1137 for (i=0 ; i<MAXPLAYERS ; i++)
1139 if (!playeringame[i])
1144 if (cnt_kills[i] >= (plrs[i].skills * 100) / wbs->maxkills)
1145 cnt_kills[i] = (plrs[i].skills * 100) / wbs->maxkills;
1147 stillticking = true;
1152 S_StartSound(0, sfx_barexp);
1156 else if (ng_state == 4)
1159 S_StartSound(0, sfx_pistol);
1161 stillticking = false;
1163 for (i=0 ; i<MAXPLAYERS ; i++)
1165 if (!playeringame[i])
1169 if (cnt_items[i] >= (plrs[i].sitems * 100) / wbs->maxitems)
1170 cnt_items[i] = (plrs[i].sitems * 100) / wbs->maxitems;
1172 stillticking = true;
1176 S_StartSound(0, sfx_barexp);
1180 else if (ng_state == 6)
1183 S_StartSound(0, sfx_pistol);
1185 stillticking = false;
1187 for (i=0 ; i<MAXPLAYERS ; i++)
1189 if (!playeringame[i])
1194 if (cnt_secret[i] >= (plrs[i].ssecret * 100) / wbs->maxsecret)
1195 cnt_secret[i] = (plrs[i].ssecret * 100) / wbs->maxsecret;
1197 stillticking = true;
1202 S_StartSound(0, sfx_barexp);
1203 ng_state += 1 + 2*!dofrags;
1206 else if (ng_state == 8)
1209 S_StartSound(0, sfx_pistol);
1211 stillticking = false;
1213 for (i=0 ; i<MAXPLAYERS ; i++)
1215 if (!playeringame[i])
1220 if (cnt_frags[i] >= (fsum = WI_fragSum(i)))
1221 cnt_frags[i] = fsum;
1223 stillticking = true;
1228 S_StartSound(0, sfx_pldeth);
1232 else if (ng_state == 10)
1234 if (acceleratestage)
1236 S_StartSound(0, sfx_sgcock);
1237 if ( gamemode == commercial )
1240 WI_initShowNextLoc();
1243 else if (ng_state & 1)
1248 cnt_pause = TICRATE;
1255 void WI_drawNetgameStats(void)
1260 int pwidth = SHORT(percent->width);
1262 WI_slamBackground();
1264 // draw animated background
1265 WI_drawAnimatedBack();
1269 // draw stat titles (top line)
1270 V_DrawPatch(NG_STATSX+NG_SPACINGX-SHORT(kills->width),
1271 NG_STATSY, FB, kills);
1273 V_DrawPatch(NG_STATSX+2*NG_SPACINGX-SHORT(items->width),
1274 NG_STATSY, FB, items);
1276 V_DrawPatch(NG_STATSX+3*NG_SPACINGX-SHORT(secret->width),
1277 NG_STATSY, FB, secret);
1280 V_DrawPatch(NG_STATSX+4*NG_SPACINGX-SHORT(frags->width),
1281 NG_STATSY, FB, frags);
1284 y = NG_STATSY + SHORT(kills->height);
1286 for (i=0 ; i<MAXPLAYERS ; i++)
1288 if (!playeringame[i])
1292 V_DrawPatch(x-SHORT(p[i]->width), y, FB, p[i]);
1295 V_DrawPatch(x-SHORT(p[i]->width), y, FB, star);
1298 WI_drawPercent(x-pwidth, y+10, cnt_kills[i]); x += NG_SPACINGX;
1299 WI_drawPercent(x-pwidth, y+10, cnt_items[i]); x += NG_SPACINGX;
1300 WI_drawPercent(x-pwidth, y+10, cnt_secret[i]); x += NG_SPACINGX;
1303 WI_drawNum(x, y+10, cnt_frags[i], -1);
1310 static int sp_state;
1312 void WI_initStats(void)
1315 acceleratestage = 0;
1317 cnt_kills[0] = cnt_items[0] = cnt_secret[0] = -1;
1318 cnt_time = cnt_par = -1;
1319 cnt_pause = TICRATE;
1321 WI_initAnimatedBack();
1324 void WI_updateStats(void)
1327 WI_updateAnimatedBack();
1329 if (acceleratestage && sp_state != 10)
1331 acceleratestage = 0;
1332 cnt_kills[0] = (plrs[me].skills * 100) / wbs->maxkills;
1333 cnt_items[0] = (plrs[me].sitems * 100) / wbs->maxitems;
1334 cnt_secret[0] = (plrs[me].ssecret * 100) / wbs->maxsecret;
1335 cnt_time = plrs[me].stime / TICRATE;
1336 cnt_par = wbs->partime / TICRATE;
1337 S_StartSound(0, sfx_barexp);
1346 S_StartSound(0, sfx_pistol);
1348 if (cnt_kills[0] >= (plrs[me].skills * 100) / wbs->maxkills)
1350 cnt_kills[0] = (plrs[me].skills * 100) / wbs->maxkills;
1351 S_StartSound(0, sfx_barexp);
1355 else if (sp_state == 4)
1360 S_StartSound(0, sfx_pistol);
1362 if (cnt_items[0] >= (plrs[me].sitems * 100) / wbs->maxitems)
1364 cnt_items[0] = (plrs[me].sitems * 100) / wbs->maxitems;
1365 S_StartSound(0, sfx_barexp);
1369 else if (sp_state == 6)
1374 S_StartSound(0, sfx_pistol);
1376 if (cnt_secret[0] >= (plrs[me].ssecret * 100) / wbs->maxsecret)
1378 cnt_secret[0] = (plrs[me].ssecret * 100) / wbs->maxsecret;
1379 S_StartSound(0, sfx_barexp);
1384 else if (sp_state == 8)
1387 S_StartSound(0, sfx_pistol);
1391 if (cnt_time >= plrs[me].stime / TICRATE)
1392 cnt_time = plrs[me].stime / TICRATE;
1396 if (cnt_par >= wbs->partime / TICRATE)
1398 cnt_par = wbs->partime / TICRATE;
1400 if (cnt_time >= plrs[me].stime / TICRATE)
1402 S_StartSound(0, sfx_barexp);
1407 else if (sp_state == 10)
1409 if (acceleratestage)
1411 S_StartSound(0, sfx_sgcock);
1413 if (gamemode == commercial)
1416 WI_initShowNextLoc();
1419 else if (sp_state & 1)
1424 cnt_pause = TICRATE;
1430 void WI_drawStats(void)
1435 lh = (3*SHORT(num[0]->height))/2;
1437 WI_slamBackground();
1439 // draw animated background
1440 WI_drawAnimatedBack();
1444 V_DrawPatch(SP_STATSX, SP_STATSY, FB, kills);
1445 WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY, cnt_kills[0]);
1447 V_DrawPatch(SP_STATSX, SP_STATSY+lh, FB, items);
1448 WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY+lh, cnt_items[0]);
1450 V_DrawPatch(SP_STATSX, SP_STATSY+2*lh, FB, sp_secret);
1451 WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY+2*lh, cnt_secret[0]);
1453 V_DrawPatch(SP_TIMEX, SP_TIMEY, FB, Time);
1454 WI_drawTime(SCREENWIDTH/2 - SP_TIMEX, SP_TIMEY, cnt_time);
1458 V_DrawPatch(SCREENWIDTH/2 + SP_TIMEX, SP_TIMEY, FB, par);
1459 WI_drawTime(SCREENWIDTH - SP_TIMEX, SP_TIMEY, cnt_par);
1464 void WI_checkForAccelerate(void)
1469 // check for button presses to skip delays
1470 for (i=0, player = players ; i<MAXPLAYERS ; i++, player++)
1472 if (playeringame[i])
1474 if (player->cmd.buttons & BT_ATTACK)
1476 if (!player->attackdown)
1477 acceleratestage = 1;
1478 player->attackdown = true;
1481 player->attackdown = false;
1482 if (player->cmd.buttons & BT_USE)
1484 if (!player->usedown)
1485 acceleratestage = 1;
1486 player->usedown = true;
1489 player->usedown = false;
1496 // Updates stuff each tick
1497 void WI_Ticker(void)
1499 // counter for general background animation
1504 // intermission music
1505 if ( gamemode == commercial )
1506 S_ChangeMusic(mus_dm2int, true);
1508 S_ChangeMusic(mus_inter, true);
1511 WI_checkForAccelerate();
1516 if (deathmatch) WI_updateDeathmatchStats();
1517 else if (netgame) WI_updateNetgameStats();
1518 else WI_updateStats();
1522 WI_updateShowNextLoc();
1532 void WI_loadData(void)
1539 if (gamemode == commercial)
1540 strcpy(name, "INTERPIC");
1542 sprintf(name, "WIMAP%d", wbs->epsd);
1544 if ( gamemode == retail )
1547 strcpy(name,"INTERPIC");
1551 bg = W_CacheLumpName(name, PU_CACHE);
1552 V_DrawPatch(0, 0, 1, bg);
1555 // UNUSED unsigned char *pic = screens[1];
1556 // if (gamemode == commercial)
1558 // darken the background image
1559 // while (pic != screens[1] + SCREENHEIGHT*SCREENWIDTH)
1561 // *pic = colormaps[256*25 + *pic];
1566 if (gamemode == commercial)
1569 lnames = (patch_t **) Z_Malloc(sizeof(patch_t*) * NUMCMAPS,
1571 for (i=0 ; i<NUMCMAPS ; i++)
1573 sprintf(name, "CWILV%2.2d", i);
1574 lnames[i] = W_CacheLumpName(name, PU_STATIC);
1579 lnames = (patch_t **) Z_Malloc(sizeof(patch_t*) * NUMMAPS,
1581 for (i=0 ; i<NUMMAPS ; i++)
1583 sprintf(name, "WILV%d%d", wbs->epsd, i);
1584 lnames[i] = W_CacheLumpName(name, PU_STATIC);
1588 yah[0] = W_CacheLumpName("WIURH0", PU_STATIC);
1590 // you are here (alt.)
1591 yah[1] = W_CacheLumpName("WIURH1", PU_STATIC);
1594 splat = W_CacheLumpName("WISPLAT", PU_STATIC);
1598 for (j=0;j<NUMANIMS[wbs->epsd];j++)
1600 a = &anims[wbs->epsd][j];
1601 for (i=0;i<a->nanims;i++)
1604 if (wbs->epsd != 1 || j != 8)
1607 sprintf(name, "WIA%d%.2d%.2d", wbs->epsd, j, i);
1608 a->p[i] = W_CacheLumpName(name, PU_STATIC);
1613 a->p[i] = anims[1][4].p[i];
1620 // More hacks on minus sign.
1621 wiminus = W_CacheLumpName("WIMINUS", PU_STATIC);
1626 sprintf(name, "WINUM%d", i);
1627 num[i] = W_CacheLumpName(name, PU_STATIC);
1631 percent = W_CacheLumpName("WIPCNT", PU_STATIC);
1634 finished = W_CacheLumpName("WIF", PU_STATIC);
1637 entering = W_CacheLumpName("WIENTER", PU_STATIC);
1640 kills = W_CacheLumpName("WIOSTK", PU_STATIC);
1643 secret = W_CacheLumpName("WIOSTS", PU_STATIC);
1646 sp_secret = W_CacheLumpName("WISCRT2", PU_STATIC);
1649 if (language == french)
1652 if (netgame && !deathmatch)
1653 items = W_CacheLumpName("WIOBJ", PU_STATIC);
1655 items = W_CacheLumpName("WIOSTI", PU_STATIC);
1657 items = W_CacheLumpName("WIOSTI", PU_STATIC);
1660 frags = W_CacheLumpName("WIFRGS", PU_STATIC);
1663 colon = W_CacheLumpName("WICOLON", PU_STATIC);
1666 Time = W_CacheLumpName("WITIME", PU_STATIC);
1669 sucks = W_CacheLumpName("WISUCKS", PU_STATIC);
1672 par = W_CacheLumpName("WIPAR", PU_STATIC);
1674 // "killers" (vertical)
1675 killers = W_CacheLumpName("WIKILRS", PU_STATIC);
1677 // "victims" (horiz)
1678 victims = W_CacheLumpName("WIVCTMS", PU_STATIC);
1681 total = W_CacheLumpName("WIMSTT", PU_STATIC);
1684 star = W_CacheLumpName("STFST01", PU_STATIC);
1687 bstar = W_CacheLumpName("STFDEAD0", PU_STATIC);
1689 for (i=0 ; i<MAXPLAYERS ; i++)
1692 sprintf(name, "STPB%d", i);
1693 p[i] = W_CacheLumpName(name, PU_STATIC);
1696 sprintf(name, "WIBP%d", i+1);
1697 bp[i] = W_CacheLumpName(name, PU_STATIC);
1702 void WI_unloadData(void)
1707 Z_ChangeTag(wiminus, PU_CACHE);
1709 for (i=0 ; i<10 ; i++)
1710 Z_ChangeTag(num[i], PU_CACHE);
1712 if (gamemode == commercial)
1714 for (i=0 ; i<NUMCMAPS ; i++)
1715 Z_ChangeTag(lnames[i], PU_CACHE);
1719 Z_ChangeTag(yah[0], PU_CACHE);
1720 Z_ChangeTag(yah[1], PU_CACHE);
1722 Z_ChangeTag(splat, PU_CACHE);
1724 for (i=0 ; i<NUMMAPS ; i++)
1725 Z_ChangeTag(lnames[i], PU_CACHE);
1729 for (j=0;j<NUMANIMS[wbs->epsd];j++)
1731 if (wbs->epsd != 1 || j != 8)
1732 for (i=0;i<anims[wbs->epsd][j].nanims;i++)
1733 Z_ChangeTag(anims[wbs->epsd][j].p[i], PU_CACHE);
1740 Z_ChangeTag(percent, PU_CACHE);
1741 Z_ChangeTag(colon, PU_CACHE);
1742 Z_ChangeTag(finished, PU_CACHE);
1743 Z_ChangeTag(entering, PU_CACHE);
1744 Z_ChangeTag(kills, PU_CACHE);
1745 Z_ChangeTag(secret, PU_CACHE);
1746 Z_ChangeTag(sp_secret, PU_CACHE);
1747 Z_ChangeTag(items, PU_CACHE);
1748 Z_ChangeTag(frags, PU_CACHE);
1749 Z_ChangeTag(Time, PU_CACHE);
1750 Z_ChangeTag(sucks, PU_CACHE);
1751 Z_ChangeTag(par, PU_CACHE);
1753 Z_ChangeTag(victims, PU_CACHE);
1754 Z_ChangeTag(killers, PU_CACHE);
1755 Z_ChangeTag(total, PU_CACHE);
1756 // Z_ChangeTag(star, PU_CACHE);
1757 // Z_ChangeTag(bstar, PU_CACHE);
1759 for (i=0 ; i<MAXPLAYERS ; i++)
1760 Z_ChangeTag(p[i], PU_CACHE);
1762 for (i=0 ; i<MAXPLAYERS ; i++)
1763 Z_ChangeTag(bp[i], PU_CACHE);
1766 void WI_Drawer (void)
1772 WI_drawDeathmatchStats();
1774 WI_drawNetgameStats();
1780 WI_drawShowNextLoc();
1790 void WI_initVariables(wbstartstruct_t* wbstartstruct)
1793 wbs = wbstartstruct;
1795 #ifdef RANGECHECKING
1796 if (gamemode != commercial)
1798 if ( gamemode == retail )
1799 RNGCHECK(wbs->epsd, 0, 3);
1801 RNGCHECK(wbs->epsd, 0, 2);
1805 RNGCHECK(wbs->last, 0, 8);
1806 RNGCHECK(wbs->next, 0, 8);
1808 RNGCHECK(wbs->pnum, 0, MAXPLAYERS);
1809 RNGCHECK(wbs->pnum, 0, MAXPLAYERS);
1812 acceleratestage = 0;
1824 if (!wbs->maxsecret)
1827 if ( gamemode != retail )
1832 void WI_Start(wbstartstruct_t* wbstartstruct)
1835 WI_initVariables(wbstartstruct);
1839 WI_initDeathmatchStats();
1841 WI_initNetgameStats();