1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
5 * PrBoom a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 * Intermission screens.
30 *-----------------------------------------------------------------------------
46 // Data needed to add patches to full screen intermission pics.
47 // Patches are statistics messages, and animations.
48 // Loads of by-pixel layout and placement, offsets etc.
52 // Different vetween registered DOOM (1994) and
53 // Ultimate DOOM - Final edition (retail, 1995?).
54 // This is supposedly ignored for commercial
55 // release (aka DOOM II), which had 34 maps
56 // in one episode. So there.
63 //U #define PAUSELEN (TICRATE*2)
64 //U #define SCORESTEP 100
65 //U #define ANIMPERIOD 32
66 // pixel distance from "(YOU)" to "PLAYER N"
67 //U #define STARDIST 10
73 #define WI_SPACINGY 33
75 // SINGLE-PLAYER STUFF
80 // proff/nicolas 09/20/98 -- changed for hi-res
82 //#define SP_TIMEY (SCREENHEIGHT-32)
87 #define NG_STATSX (32 + V_NamePatchWidth(star)/2 + 32*!dofrags)
89 #define NG_SPACINGX 64
92 // Used to display the frags matrix at endgame
97 #define DM_SPACINGX 40
99 #define DM_TOTALSX 269
101 #define DM_KILLERSX 10
102 #define DM_KILLERSY 100
103 #define DM_VICTIMSX 5
104 #define DM_VICTIMSY 50
107 // These animation variables, structures, etc. are used for the
108 // DOOM/Ultimate DOOM intermission screen animations. This is
109 // totally different from any sprite or texture/flat animations
112 ANIM_ALWAYS
, // determined by patch entry
113 ANIM_RANDOM
, // occasional
114 ANIM_LEVEL
// continuous
116 typedef unsigned animenum_t
;
120 int x
; // x/y coordinate pair structure
127 // There is another anim_t used in p_spec.
133 // period in tics between animations
136 // number of animation frames
139 // location of animation
143 // RANDOM: period deviation (<256),
148 // RANDOM: random base period,
152 /* actual graphics for frames of animations
157 // following must be initialized to zero before use!
159 // next value of bcnt (used in conjunction with period)
162 // last drawn animation frame
165 // next frame number to animate
168 // used by RANDOM and LEVEL when animating
173 static point_t lnodes
[NUMEPISODES
][NUMMAPS
] =
175 // Episode 0 World Map
177 { 185, 164 }, // location of level 0 (CJ)
178 { 148, 143 }, // location of level 1 (CJ)
179 { 69, 122 }, // location of level 2 (CJ)
180 { 209, 102 }, // location of level 3 (CJ)
181 { 116, 89 }, // location of level 4 (CJ)
182 { 166, 55 }, // location of level 5 (CJ)
183 { 71, 56 }, // location of level 6 (CJ)
184 { 135, 29 }, // location of level 7 (CJ)
185 { 71, 24 } // location of level 8 (CJ)
188 // Episode 1 World Map should go here
190 { 254, 25 }, // location of level 0 (CJ)
191 { 97, 50 }, // location of level 1 (CJ)
192 { 188, 64 }, // location of level 2 (CJ)
193 { 128, 78 }, // location of level 3 (CJ)
194 { 214, 92 }, // location of level 4 (CJ)
195 { 133, 130 }, // location of level 5 (CJ)
196 { 208, 136 }, // location of level 6 (CJ)
197 { 148, 140 }, // location of level 7 (CJ)
198 { 235, 158 } // location of level 8 (CJ)
201 // Episode 2 World Map should go here
203 { 156, 168 }, // location of level 0 (CJ)
204 { 48, 154 }, // location of level 1 (CJ)
205 { 174, 95 }, // location of level 2 (CJ)
206 { 265, 75 }, // location of level 3 (CJ)
207 { 130, 48 }, // location of level 4 (CJ)
208 { 279, 23 }, // location of level 5 (CJ)
209 { 198, 48 }, // location of level 6 (CJ)
210 { 140, 25 }, // location of level 7 (CJ)
211 { 281, 136 } // location of level 8 (CJ)
218 // Animation locations for episode 0 (1).
219 // Using patches saves a lot of space,
220 // as they replace 320x200 full screen frames.
222 static anim_t epsd0animinfo
[] =
224 { ANIM_ALWAYS
, TICRATE
/3, 3, { 224, 104 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
225 { ANIM_ALWAYS
, TICRATE
/3, 3, { 184, 160 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
226 { ANIM_ALWAYS
, TICRATE
/3, 3, { 112, 136 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
227 { ANIM_ALWAYS
, TICRATE
/3, 3, { 72, 112 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
228 { ANIM_ALWAYS
, TICRATE
/3, 3, { 88, 96 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
229 { ANIM_ALWAYS
, TICRATE
/3, 3, { 64, 48 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
230 { ANIM_ALWAYS
, TICRATE
/3, 3, { 192, 40 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
231 { ANIM_ALWAYS
, TICRATE
/3, 3, { 136, 16 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
232 { ANIM_ALWAYS
, TICRATE
/3, 3, { 80, 16 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
233 { ANIM_ALWAYS
, TICRATE
/3, 3, { 64, 24 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 }
236 static anim_t epsd1animinfo
[] =
238 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 1, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
239 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 2, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
240 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 3, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
241 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 4, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
242 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 5, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
243 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 6, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
244 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 7, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
245 { ANIM_LEVEL
, TICRATE
/3, 3, { 192, 144 }, 8, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
246 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 8, 0, { 0, 0, 0 }, 0, 0, 0, 0 }
249 static anim_t epsd2animinfo
[] =
251 { ANIM_ALWAYS
, TICRATE
/3, 3, { 104, 168 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
252 { ANIM_ALWAYS
, TICRATE
/3, 3, { 40, 136 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
253 { ANIM_ALWAYS
, TICRATE
/3, 3, { 160, 96 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
254 { ANIM_ALWAYS
, TICRATE
/3, 3, { 104, 80 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
255 { ANIM_ALWAYS
, TICRATE
/3, 3, { 120, 32 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
256 { ANIM_ALWAYS
, TICRATE
/4, 3, { 40, 0 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 }
259 static int NUMANIMS
[NUMEPISODES
] =
261 sizeof(epsd0animinfo
)/sizeof(anim_t
),
262 sizeof(epsd1animinfo
)/sizeof(anim_t
),
263 sizeof(epsd2animinfo
)/sizeof(anim_t
)
266 static anim_t
*anims
[NUMEPISODES
] =
279 // Locally used stuff.
284 // States for single-player
290 #define SP_PAR ST_TIME
295 #define SHOWNEXTLOCDELAY 4
296 //#define SHOWLASTLOCDELAY SHOWNEXTLOCDELAY
299 // used to accelerate or skip a stage
300 int acceleratestage
; // killough 3/28/98: made global
305 // specifies current state
306 static stateenum_t state
;
308 // contains information passed into intermission
309 static wbstartstruct_t
* wbs
;
311 static wbplayerstruct_t
* plrs
; // wbs->plyr[]
313 // used for general timing
316 // used for timing of background animation
319 // signals to refresh everything for one frame
320 static int firstrefresh
;
323 static int cnt_total_time
;
325 static int cnt_pause
;
332 // You Are Here graphic
333 static const char* yah
[2] = { "WIURH0", "WIURH1" };
336 static const char* splat
= "WISPLAT";
339 static const char percent
[] = {"WIPCNT"};
340 static const char colon
[] = {"WICOLON"};
343 static const patch_t
* num
[10];
346 static const char wiminus
[] = {"WIMINUS"};
348 // "Finished!" graphics
349 static const char finished
[] = {"WIF"};
351 // "Entering" graphic
352 static const char entering
[] = {"WIENTER"};
355 static const char sp_secret
[] = {"WISCRT2"};
357 // "Kills", "Scrt", "Items", "Frags"
358 static const char kills
[] = {"WIOSTK"};
359 static const char secret
[] = {"WIOSTS"};
360 static const char items
[] = {"WIOSTI"};
361 static const char frags
[] = {"WIFRGS"};
364 static const char time1
[] = {"WITIME"};
365 static const char par
[] = {"WIPAR"};
366 static const char sucks
[] = {"WISUCKS"};
368 // "killers", "victims"
369 static const char killers
[] = {"WIKILRS"};
370 static const char victims
[] = {"WIVCTMS"};
372 // "Total", your face, your dead face
373 static const char total
[] = {"WIMSTT"};
374 static const char star
[] = {"STFST01"};
375 static const char bstar
[] = {"STFDEAD0"};
377 // "red P[1..MAXPLAYERS]"
378 static const char facebackp
[] = {"STPB0"};
385 static void WI_endDeathmatchStats(void);
386 static void WI_endNetgameStats(void);
387 void WI_unloadData(void);
388 #define WI_endStats WI_endNetgameStats
390 /* ====================================================================
392 * Purpore: Returns the name of the graphic lump containing the name of
394 * Args: Episode and level, and buffer (must by 9 chars) to write to
397 void WI_levelNameLump(int epis
, int map
, char* buf
, int bsize
)
399 if (gamemode
== commercial
) {
400 snprintf(buf
, bsize
,"CWILV%s%d",(map
/10>0?"":"0"), map
); //ANOTHER ROCKHACK "CWILV%2.2d"
401 //snprintf(buf,bsize, "CWILV%2.2d", map);
403 snprintf(buf
,bsize
, "WILV%d%d", epis
, map
);
407 // ====================================================================
409 // Purpose: Put the full-screen background up prior to patches
413 static void WI_slamBackground(void)
415 char name
[9]; // limited to 8 characters
417 if (gamemode
== commercial
|| (gamemode
== retail
&& wbs
->epsd
== 3))
418 strcpy(name
, "INTERPIC");
420 snprintf(name
, sizeof(name
), "WIMAP%d", wbs
->epsd
);
423 V_DrawNamePatch(0, 0, FB
, name
, CR_DEFAULT
, VPT_STRETCH
);
426 // ====================================================================
428 // Purpose: Draw animations on intermission background screen
429 // Args: ev -- event pointer, not actually used here.
430 // Returns: False -- dummy routine
432 // The ticker is used to detect keys
433 // because of timing issues in netgames.
434 boolean
WI_Responder(event_t
* ev
)
440 // ====================================================================
442 // Purpose: Draw the "Finished" level name before showing stats
452 /* cph - get the graphic lump name and use it */
453 WI_levelNameLump(wbs
->epsd
, wbs
->last
, lname
, sizeof(lname
));
454 // CPhipps - patch drawing updated
455 V_DrawNamePatch((320 - V_NamePatchWidth(lname
))/2, y
,
456 FB
, lname
, CR_DEFAULT
, VPT_STRETCH
);
459 y
+= (5*V_NamePatchHeight(lname
))/4;
461 // CPhipps - patch drawing updated
462 V_DrawNamePatch((320 - V_NamePatchWidth(finished
))/2, y
,
463 FB
, finished
, CR_DEFAULT
, VPT_STRETCH
);
466 // ====================================================================
468 // Purpose: Draw introductory "Entering" and level name
477 /* cph - get the graphic lump name */
478 WI_levelNameLump(wbs
->epsd
, wbs
->next
, lname
, sizeof(lname
));
481 // CPhipps - patch drawing updated
482 V_DrawNamePatch((320 - V_NamePatchWidth(entering
))/2,
483 y
, FB
, entering
, CR_DEFAULT
, VPT_STRETCH
);
486 y
+= (5*V_NamePatchHeight(lname
))/4;
488 // CPhipps - patch drawing updated
489 V_DrawNamePatch((320 - V_NamePatchWidth(lname
))/2, y
, FB
,
490 lname
, CR_DEFAULT
, VPT_STRETCH
);
494 /* ====================================================================
496 * Purpose: Draw patches at a location based on episode/map
497 * Args: n -- index to map# within episode
498 * c[] -- array of names of patches to be drawn
502 WI_drawOnLnode
// draw stuff at a location by episode/map#
504 const char* const c
[] )
507 boolean fits
= false;
516 int lump
= W_GetNumForName(c
[i
]);
517 const patch_t
* p
= W_CacheLumpNum(lump
);
519 left
= lnodes
[wbs
->epsd
][n
].x
- SHORT(p
->leftoffset
);
520 top
= lnodes
[wbs
->epsd
][n
].y
- SHORT(p
->topoffset
);
521 right
= left
+ SHORT(p
->width
);
522 bottom
= top
+ SHORT(p
->height
);
523 W_UnlockLumpNum(lump
);
536 } while (!fits
&& i
!=2);
540 // CPhipps - patch drawing updated
541 V_DrawNamePatch(lnodes
[wbs
->epsd
][n
].x
, lnodes
[wbs
->epsd
][n
].y
,
542 FB
, c
[i
], CR_DEFAULT
, VPT_STRETCH
);
547 //jff 8/3/98 use logical output routine
548 printf("Could not place patch on level %d", n
+1);
553 // ====================================================================
554 // WI_initAnimatedBack
555 // Purpose: Initialize pointers and styles for background animation
559 void WI_initAnimatedBack(void)
564 if (gamemode
== commercial
) // no animation for DOOM2
570 for (i
=0;i
<NUMANIMS
[wbs
->epsd
];i
++)
572 a
= &anims
[wbs
->epsd
][i
];
577 // specify the next time to draw it
578 if (a
->type
== ANIM_ALWAYS
)
579 a
->nexttic
= bcnt
+ 1 + (M_Random()%a
->period
);
581 if (a
->type
== ANIM_RANDOM
)
582 a
->nexttic
= bcnt
+ 1 + a
->data2
+(M_Random()%a
->data1
);
584 if (a
->type
== ANIM_LEVEL
)
585 a
->nexttic
= bcnt
+ 1;
590 // ====================================================================
591 // WI_updateAnimatedBack
592 // Purpose: Figure out what animation we do on this iteration
596 void WI_updateAnimatedBack(void)
601 if (gamemode
== commercial
)
607 for (i
=0;i
<NUMANIMS
[wbs
->epsd
];i
++)
609 a
= &anims
[wbs
->epsd
][i
];
611 if (bcnt
== a
->nexttic
)
616 if (++a
->ctr
>= a
->nanims
) a
->ctr
= 0;
617 a
->nexttic
= bcnt
+ a
->period
;
622 if (a
->ctr
== a
->nanims
)
625 a
->nexttic
= bcnt
+a
->data2
+(M_Random()%a
->data1
);
628 a
->nexttic
= bcnt
+ a
->period
;
632 // gawd-awful hack for level anims
633 if (!(state
== StatCount
&& i
== 7)
634 && wbs
->next
== a
->data1
)
637 if (a
->ctr
== a
->nanims
) a
->ctr
--;
638 a
->nexttic
= bcnt
+ a
->period
;
647 // ====================================================================
648 // WI_drawAnimatedBack
649 // Purpose: Actually do the animation (whew!)
653 void WI_drawAnimatedBack(void)
658 if (gamemode
==commercial
) //jff 4/25/98 Someone forgot commercial an enum
664 for (i
=0 ; i
<NUMANIMS
[wbs
->epsd
] ; i
++)
666 a
= &anims
[wbs
->epsd
][i
];
669 // CPhipps - patch drawing updated
670 V_DrawMemPatch(a
->loc
.x
, a
->loc
.y
, FB
, a
->p
[a
->ctr
], CR_DEFAULT
, VPT_STRETCH
);
675 // ====================================================================
677 // Purpose: Draws a number. If digits > 0, then use that many digits
678 // minimum, otherwise only use as many as necessary
679 // Args: x, y -- location
680 // n -- the number to be drawn
681 // digits -- number of digits minimum or zero
682 // Returns: new x position after drawing (note we are going to the left)
684 static int WI_drawNum (int x
, int y
, int n
, int digits
)
686 int fontwidth
= SHORT(num
[0]->width
);
694 // make variable-length zeros 1 digit long
699 // figure out # of digits in #
715 // if non-number, do not draw it
719 // draw the new number
723 // CPhipps - patch drawing updated
724 V_DrawMemPatch(x
, y
, FB
, num
[ n
% 10 ], CR_DEFAULT
, VPT_STRETCH
);
728 // draw a minus sign if necessary
730 // CPhipps - patch drawing updated
731 V_DrawNamePatch(x
-=8, y
, FB
, wiminus
, CR_DEFAULT
, VPT_STRETCH
);
737 // ====================================================================
739 // Purpose: Draws a percentage, really just a call to WI_drawNum
740 // after putting a percent sign out there
741 // Args: x, y -- location
742 // p -- the percentage value to be drawn, no negatives
745 static void WI_drawPercent(int x
, int y
, int p
)
750 // CPhipps - patch drawing updated
751 V_DrawNamePatch(x
, y
, FB
, percent
, CR_DEFAULT
, VPT_STRETCH
);
752 WI_drawNum(x
, y
, p
, -1);
756 // ====================================================================
758 // Purpose: Draws the level completion time or par time, or "Sucks"
760 // Args: x, y -- location
761 // t -- the time value to be drawn
765 // - largely rewritten to display hours and use slightly better algorithm
767 static void WI_drawTime(int x
, int y
, int t
)
778 x
= WI_drawNum(x
, y
, n
, (t
|| n
>9) ? 2 : 1) - V_NamePatchWidth(colon
);
782 // CPhipps - patch drawing updated
783 V_DrawNamePatch(x
, y
, FB
, colon
, CR_DEFAULT
, VPT_STRETCH
);
786 else // "sucks" (maybe should be "addicted", even I've never had a 100 hour game ;)
787 V_DrawNamePatch(x
- V_NamePatchWidth(sucks
),
788 y
, FB
, sucks
, CR_DEFAULT
, VPT_STRETCH
);
792 // ====================================================================
794 // Purpose: Unloads data structures (inverse of WI_Start)
803 WI_endDeathmatchStats();
805 WI_endNetgameStats();
811 // ====================================================================
813 // Purpose: Clear state, ready for end of level activity
817 void WI_initNoState(void)
825 // ====================================================================
827 // Purpose: Put the times on the screen
828 // Args: time, total time, par time, in seconds
831 // cph - pulled from WI_drawStats below
833 static void WI_drawTimeStats(int cnt_time
, int cnt_total_time
, int cnt_par
)
835 V_DrawNamePatch(SP_TIMEX
, SP_TIMEY
, FB
, time1
, CR_DEFAULT
, VPT_STRETCH
);
836 WI_drawTime(320/2 - SP_TIMEX
, SP_TIMEY
, cnt_time
);
838 V_DrawNamePatch(SP_TIMEX
, (SP_TIMEY
+200)/2, FB
, total
, CR_DEFAULT
, VPT_STRETCH
);
839 WI_drawTime(320/2 - SP_TIMEX
, (SP_TIMEY
+200)/2, cnt_total_time
);
841 // Ty 04/11/98: redid logic: should skip only if with pwad but
843 // killough 2/22/98: skip drawing par times on pwads
844 // Ty 03/17/98: unless pars changed with deh patch
846 if (!(modifiedgame
)) //&& !deh_pars))
850 V_DrawNamePatch(320/2 + SP_TIMEX
, SP_TIMEY
, FB
, par
, CR_DEFAULT
, VPT_STRETCH
);
851 WI_drawTime(320 - SP_TIMEX
, SP_TIMEY
, cnt_par
);
856 // ====================================================================
858 // Purpose: Cycle until end of level activity is done
862 void WI_updateNoState(void)
865 WI_updateAnimatedBack();
871 static boolean snl_pointeron
= false;
875 // ====================================================================
876 // WI_initShowNextLoc
877 // Purpose: Prepare to show the next level's location
881 void WI_initShowNextLoc(void)
883 if ((gamemode
!= commercial
) && (gamemap
== 8)) {
890 cnt
= SHOWNEXTLOCDELAY
* TICRATE
;
892 WI_initAnimatedBack();
895 // ====================================================================
896 // WI_updateShowNextLoc
897 // Purpose: Prepare to show the next level's location
901 void WI_updateShowNextLoc(void)
903 WI_updateAnimatedBack();
905 if (!--cnt
|| acceleratestage
)
908 snl_pointeron
= (cnt
& 31) < 20;
912 // ====================================================================
913 // WI_drawShowNextLoc
914 // Purpose: Show the next level's location on animated backgrounds
918 void WI_drawShowNextLoc(void)
925 // draw animated background
926 WI_drawAnimatedBack();
928 if ( gamemode
!= commercial
)
932 WI_drawEL(); // "Entering..." if not E1 or E2
936 last
= (wbs
->last
== 8) ? wbs
->next
- 1 : wbs
->last
;
938 // draw a splat on taken cities.
939 for (i
=0 ; i
<=last
; i
++)
940 WI_drawOnLnode(i
, &splat
);
942 // splat the secret level?
944 WI_drawOnLnode(8, &splat
);
948 WI_drawOnLnode(wbs
->next
, yah
);
951 // draws which level you are entering..
952 if ( (gamemode
!= commercial
)
953 || wbs
->next
!= 30) // check for MAP30 end game
957 // ====================================================================
959 // Purpose: Draw the pointer and next location
963 void WI_drawNoState(void)
965 snl_pointeron
= true;
966 WI_drawShowNextLoc();
970 // ====================================================================
972 // Purpose: Calculate frags for this player based on the current totals
973 // of all the other players. Subtract self-frags.
974 // Args: playernum -- the player to be calculated
975 // Returns: the total frags for this player
977 int WI_fragSum(int playernum
)
982 for (i
=0 ; i
<MAXPLAYERS
; i
++)
984 if (playeringame
[i
] // is this player playing?
985 && i
!=playernum
) // and it's not the player we're calculating
987 frags
+= plrs
[playernum
].frags
[i
];
992 // JDC hack - negative frags.
993 frags
-= plrs
[playernum
].frags
[playernum
];
1000 // CPhipps - short, dynamically allocated
1001 static short int **dm_frags
; // frags matrix
1002 static short int *dm_totals
; // totals by player
1004 // ====================================================================
1005 // WI_initDeathmatchStats
1006 // Purpose: Set up to display DM stats at end of level. Calculate
1007 // frags for all players.
1011 void WI_initDeathmatchStats(void)
1013 int i
; // looping variables
1015 // CPhipps - allocate data structures needed
1016 dm_frags
= calloc(MAXPLAYERS
, sizeof(*dm_frags
));
1017 dm_totals
= calloc(MAXPLAYERS
, sizeof(*dm_totals
));
1019 state
= StatCount
; // We're doing stats
1020 acceleratestage
= 0;
1021 dm_state
= 1; // count how many times we've done a complete stat
1023 cnt_pause
= TICRATE
;
1025 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1027 if (playeringame
[i
])
1029 // CPhipps - allocate frags line
1030 dm_frags
[i
] = calloc(MAXPLAYERS
, sizeof(**dm_frags
)); // set all counts to zero
1035 WI_initAnimatedBack();
1039 // ====================================================================
1040 // CPhipps - WI_endDeathmatchStats
1041 // Purpose: Deallocate dynamically allocated DM stats data
1046 void WI_endDeathmatchStats(void)
1049 for (i
=0; i
<MAXPLAYERS
; i
++)
1052 free(dm_frags
); free(dm_totals
);
1055 // ====================================================================
1056 // WI_updateDeathmatchStats
1057 // Purpose: Advance Deathmatch stats screen animation. Calculate
1058 // frags for all players. Lots of noise and drama around
1059 // the presentation.
1063 void WI_updateDeathmatchStats(void)
1068 boolean stillticking
;
1070 WI_updateAnimatedBack();
1072 if (acceleratestage
&& dm_state
!= 4) // still ticking
1074 acceleratestage
= 0;
1076 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1078 if (playeringame
[i
])
1080 for (j
=0 ; j
<MAXPLAYERS
; j
++)
1081 if (playeringame
[j
])
1082 dm_frags
[i
][j
] = plrs
[i
].frags
[j
];
1084 dm_totals
[i
] = WI_fragSum(i
);
1089 S_StartSound(0, sfx_barexp
); // bang
1090 dm_state
= 4; // we're done with all 4 (or all we have to do)
1097 S_StartSound(0, sfx_pistol
); // noise while counting
1099 stillticking
= false;
1101 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1103 if (playeringame
[i
])
1105 for (j
=0 ; j
<MAXPLAYERS
; j
++)
1108 && dm_frags
[i
][j
] != plrs
[i
].frags
[j
])
1110 if (plrs
[i
].frags
[j
] < 0)
1115 if (dm_frags
[i
][j
] > 999) // Ty 03/17/98 3-digit frag count
1116 dm_frags
[i
][j
] = 999;
1118 if (dm_frags
[i
][j
] < -999)
1119 dm_frags
[i
][j
] = -999;
1121 stillticking
= true;
1124 dm_totals
[i
] = WI_fragSum(i
);
1126 if (dm_totals
[i
] > 999)
1129 if (dm_totals
[i
] < -999)
1130 dm_totals
[i
] = -999; // Ty 03/17/98 end 3-digit frag count
1136 S_StartSound(0, sfx_barexp
);
1140 else if (dm_state
== 4)
1142 if (acceleratestage
)
1144 S_StartSound(0, sfx_slop
);
1146 if ( gamemode
== commercial
)
1149 WI_initShowNextLoc();
1152 else if (dm_state
& 1)
1157 cnt_pause
= TICRATE
;
1163 // ====================================================================
1164 // WI_drawDeathmatchStats
1165 // Purpose: Draw the stats on the screen in a matrix
1169 // proff/nicolas 09/20/98 -- changed for hi-res
1170 // CPhipps - patch drawing updated
1171 void WI_drawDeathmatchStats(void)
1179 int lh
; // line height
1180 int halfface
= V_NamePatchWidth(facebackp
)/2;
1184 WI_slamBackground();
1186 // draw animated background
1187 WI_drawAnimatedBack();
1190 // draw stat titles (top line)
1191 V_DrawNamePatch(DM_TOTALSX
-V_NamePatchWidth(total
)/2,
1192 DM_MATRIXY
-WI_SPACINGY
+10, FB
, total
, CR_DEFAULT
, VPT_STRETCH
);
1194 V_DrawNamePatch(DM_KILLERSX
, DM_KILLERSY
, FB
, killers
, CR_DEFAULT
, VPT_STRETCH
);
1195 V_DrawNamePatch(DM_VICTIMSX
, DM_VICTIMSY
, FB
, victims
, CR_DEFAULT
, VPT_STRETCH
);
1198 x
= DM_MATRIXX
+ DM_SPACINGX
;
1201 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1203 if (playeringame
[i
]) {
1204 //int trans = playernumtotrans[i];
1205 V_DrawNamePatch(x
-halfface
, DM_MATRIXY
- WI_SPACINGY
,
1206 FB
, facebackp
, i
? CR_LIMIT
+i
: CR_DEFAULT
,
1207 VPT_STRETCH
| (i
? VPT_TRANS
: 0));
1208 V_DrawNamePatch(DM_MATRIXX
-halfface
, y
,
1209 FB
, facebackp
, i
? CR_LIMIT
+i
: CR_DEFAULT
,
1210 VPT_STRETCH
| (i
? VPT_TRANS
: 0));
1214 V_DrawNamePatch(x
-halfface
, DM_MATRIXY
- WI_SPACINGY
,
1215 FB
, bstar
, CR_DEFAULT
, VPT_STRETCH
);
1216 V_DrawNamePatch(DM_MATRIXX
-halfface
, y
,
1217 FB
, star
, CR_DEFAULT
, VPT_STRETCH
);
1226 w
= SHORT(num
[0]->width
);
1228 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1230 x
= DM_MATRIXX
+ DM_SPACINGX
;
1232 if (playeringame
[i
])
1234 for (j
=0 ; j
<MAXPLAYERS
; j
++)
1236 if (playeringame
[j
])
1237 WI_drawNum(x
+w
, y
, dm_frags
[i
][j
], 2);
1241 WI_drawNum(DM_TOTALSX
+w
, y
, dm_totals
[i
], 2);
1249 // Note: The term "Netgame" means a coop game
1251 static short *cnt_kills
;
1252 static short *cnt_items
;
1253 static short *cnt_secret
;
1254 static short *cnt_frags
;
1256 static int ng_state
;
1258 // ====================================================================
1259 // CPhipps - WI_endNetgameStats
1260 // Purpose: Clean up coop game stats
1264 static void WI_endNetgameStats(void)
1272 // ====================================================================
1273 // WI_initNetgameStats
1274 // Purpose: Prepare for coop game stats
1278 void WI_initNetgameStats(void)
1283 acceleratestage
= 0;
1286 cnt_pause
= TICRATE
;
1288 // CPhipps - allocate these dynamically, blank with calloc
1289 cnt_kills
= calloc(MAXPLAYERS
, sizeof(*cnt_kills
));
1290 cnt_items
= calloc(MAXPLAYERS
, sizeof(*cnt_items
));
1291 cnt_secret
= calloc(MAXPLAYERS
, sizeof(*cnt_secret
));
1292 cnt_frags
= calloc(MAXPLAYERS
, sizeof(*cnt_frags
));
1294 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1295 if (playeringame
[i
])
1296 dofrags
+= WI_fragSum(i
);
1298 dofrags
= !!dofrags
; // set to true or false - did we have frags?
1300 WI_initAnimatedBack();
1304 // ====================================================================
1305 // WI_updateNetgameStats
1306 // Purpose: Calculate coop stats as we display them with noise and fury
1309 // Comment: This stuff sure is complicated for what it does
1311 void WI_updateNetgameStats(void)
1316 boolean stillticking
;
1318 WI_updateAnimatedBack();
1320 if (acceleratestage
&& ng_state
!= 10)
1322 acceleratestage
= 0;
1324 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1326 if (!playeringame
[i
])
1329 cnt_kills
[i
] = (plrs
[i
].skills
* 100) / wbs
->maxkills
;
1330 cnt_items
[i
] = (plrs
[i
].sitems
* 100) / wbs
->maxitems
;
1332 // killough 2/22/98: Make secrets = 100% if maxsecret = 0:
1333 cnt_secret
[i
] = wbs
->maxsecret
?
1334 (plrs
[i
].ssecret
* 100) / wbs
->maxsecret
: 100;
1336 cnt_frags
[i
] = WI_fragSum(i
); // we had frags
1338 S_StartSound(0, sfx_barexp
); // bang
1345 S_StartSound(0, sfx_pistol
); // pop
1347 stillticking
= false;
1349 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1351 if (!playeringame
[i
])
1356 if (cnt_kills
[i
] >= (plrs
[i
].skills
* 100) / wbs
->maxkills
)
1357 cnt_kills
[i
] = (plrs
[i
].skills
* 100) / wbs
->maxkills
;
1359 stillticking
= true; // still got stuff to tally
1364 S_StartSound(0, sfx_barexp
);
1368 else if (ng_state
== 4)
1371 S_StartSound(0, sfx_pistol
);
1373 stillticking
= false;
1375 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1377 if (!playeringame
[i
])
1381 if (cnt_items
[i
] >= (plrs
[i
].sitems
* 100) / wbs
->maxitems
)
1382 cnt_items
[i
] = (plrs
[i
].sitems
* 100) / wbs
->maxitems
;
1384 stillticking
= true;
1389 S_StartSound(0, sfx_barexp
);
1393 else if (ng_state
== 6)
1396 S_StartSound(0, sfx_pistol
);
1398 stillticking
= false;
1400 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1402 if (!playeringame
[i
])
1407 // killough 2/22/98: Make secrets = 100% if maxsecret = 0:
1409 if (cnt_secret
[i
] >= (wbs
->maxsecret
? (plrs
[i
].ssecret
* 100) / wbs
->maxsecret
: compatibility_level
< lxdoom_1_compatibility
? 0 : 100))
1410 cnt_secret
[i
] = wbs
->maxsecret
? (plrs
[i
].ssecret
* 100) / wbs
->maxsecret
: 100;
1412 stillticking
= true;
1417 S_StartSound(0, sfx_barexp
);
1418 ng_state
+= 1 + 2*!dofrags
;
1421 else if (ng_state
== 8)
1424 S_StartSound(0, sfx_pistol
);
1426 stillticking
= false;
1428 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1430 if (!playeringame
[i
])
1435 if (cnt_frags
[i
] >= (fsum
= WI_fragSum(i
)))
1436 cnt_frags
[i
] = fsum
;
1438 stillticking
= true;
1443 S_StartSound(0, sfx_pldeth
);
1447 else if (ng_state
== 10)
1449 if (acceleratestage
)
1451 S_StartSound(0, sfx_sgcock
);
1452 if ( gamemode
== commercial
)
1455 WI_initShowNextLoc();
1458 else if (ng_state
& 1)
1463 cnt_pause
= TICRATE
;
1469 // ====================================================================
1470 // WI_drawNetgameStats
1471 // Purpose: Put the coop stats on the screen
1475 // proff/nicolas 09/20/98 -- changed for hi-res
1476 // CPhipps - patch drawing updated
1477 void WI_drawNetgameStats(void)
1482 int pwidth
= V_NamePatchWidth(percent
);
1483 int fwidth
= V_NamePatchWidth(facebackp
);
1485 WI_slamBackground();
1487 // draw animated background
1488 WI_drawAnimatedBack();
1492 // draw stat titles (top line)
1493 V_DrawNamePatch(NG_STATSX
+NG_SPACINGX
-V_NamePatchWidth(kills
),
1494 NG_STATSY
, FB
, kills
, CR_DEFAULT
, VPT_STRETCH
);
1496 V_DrawNamePatch(NG_STATSX
+2*NG_SPACINGX
-V_NamePatchWidth(items
),
1497 NG_STATSY
, FB
, items
, CR_DEFAULT
, VPT_STRETCH
);
1499 V_DrawNamePatch(NG_STATSX
+3*NG_SPACINGX
-V_NamePatchWidth(secret
),
1500 NG_STATSY
, FB
, secret
, CR_DEFAULT
, VPT_STRETCH
);
1503 V_DrawNamePatch(NG_STATSX
+4*NG_SPACINGX
-V_NamePatchWidth(frags
),
1504 NG_STATSY
, FB
, frags
, CR_DEFAULT
, VPT_STRETCH
);
1507 y
= NG_STATSY
+ V_NamePatchHeight(kills
);
1509 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1511 //int trans = playernumtotrans[i];
1512 if (!playeringame
[i
])
1516 V_DrawNamePatch(x
-fwidth
, y
, FB
, facebackp
,
1517 i
? CR_LIMIT
+i
: CR_DEFAULT
,
1518 VPT_STRETCH
| (i
? VPT_TRANS
: 0));
1521 V_DrawNamePatch(x
-fwidth
, y
, FB
, star
, CR_DEFAULT
, VPT_STRETCH
);
1524 WI_drawPercent(x
-pwidth
, y
+10, cnt_kills
[i
]); x
+= NG_SPACINGX
;
1525 WI_drawPercent(x
-pwidth
, y
+10, cnt_items
[i
]); x
+= NG_SPACINGX
;
1526 WI_drawPercent(x
-pwidth
, y
+10, cnt_secret
[i
]); x
+= NG_SPACINGX
;
1529 WI_drawNum(x
, y
+10, cnt_frags
[i
], -1);
1535 // cph - show times in coop on the entering screen
1536 WI_drawTimeStats(plrs
[me
].stime
/ TICRATE
, wbs
->totaltimes
/ TICRATE
, wbs
->partime
/ TICRATE
);
1539 static int sp_state
;
1541 // ====================================================================
1543 // Purpose: Get ready for single player stats
1546 // Comment: Seems like we could do all these stats in a more generic
1547 // set of routines that weren't duplicated for dm, coop, sp
1549 void WI_initStats(void)
1552 acceleratestage
= 0;
1555 // CPhipps - allocate (awful code, I know, but saves changing it all) and initialise
1556 *(cnt_kills
= malloc(sizeof(*cnt_kills
))) =
1557 *(cnt_items
= malloc(sizeof(*cnt_items
))) =
1558 *(cnt_secret
= malloc(sizeof(*cnt_secret
))) = -1;
1559 cnt_time
= cnt_par
= cnt_total_time
= -1;
1560 cnt_pause
= TICRATE
;
1562 WI_initAnimatedBack();
1565 // ====================================================================
1567 // Purpose: Calculate solo stats
1571 void WI_updateStats(void)
1573 WI_updateAnimatedBack();
1575 if (acceleratestage
&& sp_state
!= 10)
1577 acceleratestage
= 0;
1578 cnt_kills
[0] = (plrs
[me
].skills
* 100) / wbs
->maxkills
;
1579 cnt_items
[0] = (plrs
[me
].sitems
* 100) / wbs
->maxitems
;
1581 // killough 2/22/98: Make secrets = 100% if maxsecret = 0:
1582 cnt_secret
[0] = (wbs
->maxsecret
?
1583 (plrs
[me
].ssecret
* 100) / wbs
->maxsecret
: 100);
1585 cnt_total_time
= wbs
->totaltimes
/ TICRATE
;
1586 cnt_time
= plrs
[me
].stime
/ TICRATE
;
1587 cnt_par
= wbs
->partime
/ TICRATE
;
1588 S_StartSound(0, sfx_barexp
);
1597 S_StartSound(0, sfx_pistol
);
1599 if (cnt_kills
[0] >= (plrs
[me
].skills
* 100) / wbs
->maxkills
)
1601 cnt_kills
[0] = (plrs
[me
].skills
* 100) / wbs
->maxkills
;
1602 S_StartSound(0, sfx_barexp
);
1606 else if (sp_state
== 4)
1611 S_StartSound(0, sfx_pistol
);
1613 if (cnt_items
[0] >= (plrs
[me
].sitems
* 100) / wbs
->maxitems
)
1615 cnt_items
[0] = (plrs
[me
].sitems
* 100) / wbs
->maxitems
;
1616 S_StartSound(0, sfx_barexp
);
1620 else if (sp_state
== 6)
1625 S_StartSound(0, sfx_pistol
);
1627 // killough 2/22/98: Make secrets = 100% if maxsecret = 0:
1628 if ((!wbs
->maxsecret
&& compatibility_level
< lxdoom_1_compatibility
) ||
1629 cnt_secret
[0] >= (wbs
->maxsecret
?
1630 (plrs
[me
].ssecret
* 100) / wbs
->maxsecret
: 100))
1632 cnt_secret
[0] = (wbs
->maxsecret
?
1633 (plrs
[me
].ssecret
* 100) / wbs
->maxsecret
: 100);
1634 S_StartSound(0, sfx_barexp
);
1638 else if (sp_state
== 8)
1641 S_StartSound(0, sfx_pistol
);
1645 if (cnt_time
>= plrs
[me
].stime
/ TICRATE
)
1646 cnt_time
= plrs
[me
].stime
/ TICRATE
;
1648 cnt_total_time
+= 3;
1650 if (cnt_total_time
>= wbs
->totaltimes
/ TICRATE
)
1651 cnt_total_time
= wbs
->totaltimes
/ TICRATE
;
1655 if (cnt_par
>= wbs
->partime
/ TICRATE
)
1657 cnt_par
= wbs
->partime
/ TICRATE
;
1659 if ((cnt_time
>= plrs
[me
].stime
/ TICRATE
) && (compatibility_level
< lxdoom_1_compatibility
|| cnt_total_time
>= wbs
->totaltimes
/ TICRATE
))
1661 S_StartSound(0, sfx_barexp
);
1666 else if (sp_state
== 10)
1668 if (acceleratestage
)
1670 S_StartSound(0, sfx_sgcock
);
1672 if (gamemode
== commercial
)
1675 WI_initShowNextLoc();
1678 else if (sp_state
& 1)
1683 cnt_pause
= TICRATE
;
1689 // ====================================================================
1691 // Purpose: Put the solo stats on the screen
1695 // proff/nicolas 09/20/98 -- changed for hi-res
1696 // CPhipps - patch drawing updated
1697 void WI_drawStats(void)
1702 lh
= (3*SHORT(num
[0]->height
))/2;
1704 WI_slamBackground();
1706 // draw animated background
1707 WI_drawAnimatedBack();
1711 V_DrawNamePatch(SP_STATSX
, SP_STATSY
, FB
, kills
, CR_DEFAULT
, VPT_STRETCH
);
1712 WI_drawPercent(320 - SP_STATSX
, SP_STATSY
, cnt_kills
[0]);
1714 V_DrawNamePatch(SP_STATSX
, SP_STATSY
+lh
, FB
, items
, CR_DEFAULT
, VPT_STRETCH
);
1715 WI_drawPercent(320 - SP_STATSX
, SP_STATSY
+lh
, cnt_items
[0]);
1717 V_DrawNamePatch(SP_STATSX
, SP_STATSY
+2*lh
, FB
, sp_secret
, CR_DEFAULT
, VPT_STRETCH
);
1718 WI_drawPercent(320 - SP_STATSX
, SP_STATSY
+2*lh
, cnt_secret
[0]);
1720 WI_drawTimeStats(cnt_time
, cnt_total_time
, cnt_par
);
1723 // ====================================================================
1724 // WI_checkForAccelerate
1725 // Purpose: See if the player has hit either the attack or use key
1726 // or mouse button. If so we set acceleratestage to 1 and
1727 // all those display routines above jump right to the end.
1731 void WI_checkForAccelerate(void)
1736 // check for button presses to skip delays
1737 for (i
=0, player
= players
; i
<MAXPLAYERS
; i
++, player
++)
1739 if (playeringame
[i
])
1741 if (player
->cmd
.buttons
& BT_ATTACK
)
1743 if (!player
->attackdown
)
1744 acceleratestage
= 1;
1745 player
->attackdown
= true;
1748 player
->attackdown
= false;
1750 if (player
->cmd
.buttons
& BT_USE
)
1752 if (!player
->usedown
)
1753 acceleratestage
= 1;
1754 player
->usedown
= true;
1757 player
->usedown
= false;
1762 // ====================================================================
1764 // Purpose: Do various updates every gametic, for stats, animation,
1765 // checking that intermission music is running, etc.
1769 void WI_Ticker(void)
1771 // counter for general background animation
1776 // intermission music
1777 if ( gamemode
== commercial
)
1778 S_ChangeMusic(mus_dm2int
, true);
1780 S_ChangeMusic(mus_inter
, true);
1783 WI_checkForAccelerate();
1788 if (deathmatch
) WI_updateDeathmatchStats();
1789 else if (netgame
) WI_updateNetgameStats();
1790 else WI_updateStats();
1794 WI_updateShowNextLoc();
1803 /* ====================================================================
1805 * Purpose: Initialize intermission data such as background graphics,
1806 * patches, map names, etc.
1810 * CPhipps - modified for new wad lump handling.
1811 * - no longer preload most graphics, other funcs can use
1815 void WI_loadData(void)
1819 char name
[9]; // limited to 8 characters
1822 if (gamemode
!= commercial
)
1826 for (j
=0;j
<NUMANIMS
[wbs
->epsd
];j
++)
1828 a
= &anims
[wbs
->epsd
][j
];
1829 for (i
=0;i
<a
->nanims
;i
++)
1832 if (wbs
->epsd
!= 1 || j
!= 8)
1835 snprintf(name
, sizeof(name
),"WIA%d%s%d%s%d", wbs
->epsd
, (j
/10>0?"":"0"), j
,(i
/10>0?"":"0"), i
); //ANOTHER ROCKHACK
1836 //snprintf(name, sizeof(name),"WIA%d%.2d%.2d", wbs->epsd, j, i);
1837 a
->p
[i
] = W_CacheLumpName(name
);
1842 a
->p
[i
] = anims
[1][4].p
[i
];
1852 snprintf(name
,sizeof(name
),"WINUM%d", i
);
1853 num
[i
] = W_CacheLumpName(name
);
1857 // ====================================================================
1859 // Purpose: Free up the space allocated during WI_loadData
1863 // CPhipps - reverse of WI_loadData, goes through the same lumps, but unlocking
1864 void WI_unloadData(void)
1867 char name
[9]; // limited to 8 characters
1869 // cph - unlock gamemode dependent stuff here
1870 if (gamemode
!= commercial
) {
1871 if (wbs
->epsd
< 3) {
1872 for (j
=0;j
<NUMANIMS
[wbs
->epsd
];j
++) {
1873 anim_t
* a
= &anims
[wbs
->epsd
][j
];
1874 for (i
=0; i
<a
->nanims
; i
++) {
1876 if (wbs
->epsd
!= 1 || j
!= 8) {
1878 snprintf(name
, sizeof(name
),"WIA%d%s%d%s%d", wbs
->epsd
, (j
/10>0?"":"0"), j
,(i
/10>0?"":"0"), i
); //ANOTHER ROCKHACK
1879 //snprintf(name,sizeof(name), "WIA%d%.2d%.2d", wbs->epsd, j, i);
1880 W_UnlockLumpName(name
);
1887 for (i
=0;i
<10;i
++) {
1889 snprintf(name
, sizeof(name
),"WINUM%d", i
);
1890 W_UnlockLumpName(name
);
1895 // ====================================================================
1897 // Purpose: Call the appropriate stats drawing routine depending on
1898 // what kind of game is being played (DM, coop, solo)
1902 void WI_Drawer (void)
1908 WI_drawDeathmatchStats();
1910 WI_drawNetgameStats();
1916 WI_drawShowNextLoc();
1925 // ====================================================================
1927 // Purpose: Initialize the intermission information structure
1928 // Note: wbstartstruct_t is defined in d_player.h
1929 // Args: wbstartstruct -- pointer to the structure with the data
1932 void WI_initVariables(wbstartstruct_t
* wbstartstruct
)
1935 wbs
= wbstartstruct
;
1937 #ifdef RANGECHECKING
1938 if (gamemode
!= commercial
)
1940 if ( gamemode
== retail
)
1941 RNGCHECK(wbs
->epsd
, 0, 3);
1943 RNGCHECK(wbs
->epsd
, 0, 2);
1947 RNGCHECK(wbs
->last
, 0, 8);
1948 RNGCHECK(wbs
->next
, 0, 8);
1950 RNGCHECK(wbs
->pnum
, 0, MAXPLAYERS
);
1951 RNGCHECK(wbs
->pnum
, 0, MAXPLAYERS
);
1954 acceleratestage
= 0;
1961 wbs
->maxkills
= 1; // probably only useful in MAP30
1966 if ( gamemode
!= retail
)
1971 // ====================================================================
1973 // Purpose: Call the various init routines
1974 // Note: wbstartstruct_t is defined in d_player.h
1975 // Args: wbstartstruct -- pointer to the structure with the
1976 // intermission data
1979 void WI_Start(wbstartstruct_t
* wbstartstruct
)
1981 WI_initVariables(wbstartstruct
);
1985 WI_initDeathmatchStats();
1987 WI_initNetgameStats();