Subversion Repositories Kolibri OS

Rev

Rev 298 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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