2 //**************************************************************************
4 //** in_lude.c : Heretic 2 : Raven Software, Corp.
11 //**************************************************************************
16 // MACROS ------------------------------------------------------------------
21 // TYPES -------------------------------------------------------------------
30 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
32 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
38 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
40 static void WaitStop(void);
41 static void Stop(void);
42 static void LoadPics(void);
43 static void UnloadPics(void);
44 static void CheckForSkip(void);
45 static void InitStats(void);
46 static void DrDeathTally(void);
47 static void DrNumber(int val, int x, int y, int wrapThresh);
48 static void DrNumberBold(int val, int x, int y, int wrapThresh);
49 static void DrawHubText(void);
51 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
53 // PUBLIC DATA DECLARATIONS ------------------------------------------------
56 char ClusterMessage[MAX_INTRMSN_MESSAGE_SIZE];
58 // PRIVATE DATA DEFINITIONS ------------------------------------------------
60 static boolean skipintermission;
61 static int interstate = 0;
62 static int intertime = -1;
63 static gametype_t gametype;
65 static int slaughterboy; // in DM, the player with the most kills
66 static patch_t *patchINTERPIC;
67 static patch_t *FontBNumbers[10];
68 static patch_t *FontBNegative;
69 static patch_t *FontBSlash;
70 static patch_t *FontBPercent;
71 static int FontABaseLump;
73 static int FontBLumpBase;
75 static signed int totalFrags[MAXPLAYERS];
80 // CODE --------------------------------------------------------------------
82 //========================================================================
86 //========================================================================
88 extern void AM_Stop (void);
93 I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE));
98 skipintermission = false;
101 for(i = 0; i < MAXPLAYERS; i++)
103 players[i].messageTics = 0;
104 players[i].message[0] = 0;
106 SN_StopAllSequences();
109 //========================================================================
113 //========================================================================
120 // gamestate = GS_LEVEL;
122 gameaction = ga_leavemap;
127 //========================================================================
131 //========================================================================
133 static void Stop(void)
135 intermission = false;
138 BorderNeedRefresh = true;
141 //========================================================================
145 // Initializes the stats for single player mode
146 //========================================================================
148 static char *ClusMsgLumpNames[] =
157 static void InitStats(void)
162 signed int slaughterfrags;
176 oldCluster = P_GetMapCluster(gamemap);
177 if(oldCluster != P_GetMapCluster(LeaveMap))
179 if(oldCluster >= 1 && oldCluster <= 5)
181 msgLumpName = ClusMsgLumpNames[oldCluster-1];
182 msgLump = W_GetNumForName(msgLumpName);
183 msgSize = W_LumpLength(msgLump);
184 if(msgSize >= MAX_INTRMSN_MESSAGE_SIZE)
186 I_Error("Cluster message too long (%s)", msgLumpName);
188 W_ReadLump(msgLump, ClusterMessage);
189 ClusterMessage[msgSize] = 0; // Append terminator
190 HubText = ClusterMessage;
191 HubCount = strlen(HubText)*TEXTSPEED+TEXTWAIT;
192 S_StartSongName("hub", true);
198 gametype = DEATHMATCH;
200 slaughterfrags = -9999;
204 for(i=0; i<MAXPLAYERS; i++)
210 for(j=0; j<MAXPLAYERS; j++)
214 totalFrags[i] += players[i].frags[j];
219 if(totalFrags[i] > slaughterfrags)
222 slaughterfrags = totalFrags[i];
225 else if(totalFrags[i] == slaughterfrags)
227 slaughterboy |= 1<<i;
231 if(playercount == slaughtercount)
232 { // don't do the slaughter stuff if everyone is equal
235 S_StartSongName("hub", true);
239 //========================================================================
243 //========================================================================
245 static void LoadPics(void)
249 if(HubCount || gametype == DEATHMATCH)
251 patchINTERPIC = W_CacheLumpName("INTERPIC", PU_STATIC);
252 FontBLumpBase = W_GetNumForName("FONTB16");
255 FontBNumbers[i] = W_CacheLumpNum(FontBLumpBase+i, PU_STATIC);
257 FontBLump = W_GetNumForName("FONTB_S")+1;
258 FontBNegative = W_CacheLumpName("FONTB13", PU_STATIC);
259 FontABaseLump = W_GetNumForName("FONTA_S")+1;
261 FontBSlash = W_CacheLumpName("FONTB15", PU_STATIC);
262 FontBPercent = W_CacheLumpName("FONTB05", PU_STATIC);
266 //========================================================================
270 //========================================================================
272 static void UnloadPics(void)
276 if(HubCount || gametype == DEATHMATCH)
278 Z_ChangeTag(patchINTERPIC, PU_CACHE);
281 Z_ChangeTag(FontBNumbers[i], PU_CACHE);
283 Z_ChangeTag(FontBNegative, PU_CACHE);
284 Z_ChangeTag(FontBSlash, PU_CACHE);
285 Z_ChangeTag(FontBPercent, PU_CACHE);
289 //========================================================================
293 //========================================================================
306 skipintermission = false;
309 if(skipintermission || (gametype == SINGLE && !HubCount))
313 skipintermission = false;
314 //S_StartSound(NULL, sfx_dorcls);
318 //========================================================================
322 // Check to see if any player hit a key
323 //========================================================================
325 static void CheckForSkip(void)
329 static boolean triedToSkip;
331 for(i = 0, player = players; i < MAXPLAYERS; i++, player++)
335 if(player->cmd.buttons&BT_ATTACK)
337 if(!player->attackdown)
339 skipintermission = 1;
341 player->attackdown = true;
345 player->attackdown = false;
347 if(player->cmd.buttons&BT_USE)
351 skipintermission = 1;
353 player->usedown = true;
357 player->usedown = false;
361 if(deathmatch && intertime < 140)
362 { // wait for 4 seconds before allowing a skip
363 if(skipintermission == 1)
366 skipintermission = 0;
373 skipintermission = 1;
379 //========================================================================
383 //========================================================================
395 UpdateState |= I_FULLSCRN;
396 memcpy(screen, (byte *)patchINTERPIC, SCREENWIDTH*SCREENHEIGHT);
398 if(gametype == SINGLE)
411 //========================================================================
415 //========================================================================
417 #define TALLY_EFFECT_TICKS 20
418 #define TALLY_FINAL_X_DELTA (23*FRACUNIT)
419 #define TALLY_FINAL_Y_DELTA (13*FRACUNIT)
420 #define TALLY_START_XPOS (178*FRACUNIT)
421 #define TALLY_STOP_XPOS (90*FRACUNIT)
422 #define TALLY_START_YPOS (132*FRACUNIT)
423 #define TALLY_STOP_YPOS (83*FRACUNIT)
424 #define TALLY_TOP_X 85
425 #define TALLY_TOP_Y 9
426 #define TALLY_LEFT_X 7
427 #define TALLY_LEFT_Y 71
428 #define TALLY_TOTALS_X 291
430 static void DrDeathTally(void)
434 fixed_t xDelta, yDelta;
435 fixed_t xStart, scale;
438 static boolean showTotals;
441 V_DrawPatch(TALLY_TOP_X, TALLY_TOP_Y,
442 W_CacheLumpName("tallytop", PU_CACHE));
443 V_DrawPatch(TALLY_LEFT_X, TALLY_LEFT_Y,
444 W_CacheLumpName("tallylft", PU_CACHE));
445 if(intertime < TALLY_EFFECT_TICKS)
448 scale = (intertime*FRACUNIT)/TALLY_EFFECT_TICKS;
449 xDelta = FixedMul(scale, TALLY_FINAL_X_DELTA);
450 yDelta = FixedMul(scale, TALLY_FINAL_Y_DELTA);
451 xStart = TALLY_START_XPOS-FixedMul(scale,
452 TALLY_START_XPOS-TALLY_STOP_XPOS);
453 yPos = TALLY_START_YPOS-FixedMul(scale,
454 TALLY_START_YPOS-TALLY_STOP_YPOS);
458 xDelta = TALLY_FINAL_X_DELTA;
459 yDelta = TALLY_FINAL_Y_DELTA;
460 xStart = TALLY_STOP_XPOS;
461 yPos = TALLY_STOP_YPOS;
463 if(intertime >= TALLY_EFFECT_TICKS && showTotals == false)
466 S_StartSound(NULL, SFX_PLATFORM_STOP);
469 for(i = 0; i < MAXPLAYERS; i++)
472 for(j = 0; j < MAXPLAYERS; j++, xPos += xDelta)
475 bold = (i == consoleplayer || j == consoleplayer);
476 if(playeringame[i] && playeringame[j])
480 DrNumberBold(players[i].frags[j], x, y, 100);
484 DrNumber(players[i].frags[j], x, y, 100);
489 temp = MN_TextAWidth("--")/2;
492 MN_DrTextAYellow("--", x-temp, y);
496 MN_DrTextA("--", x-temp, y);
500 if(showTotals && playeringame[i]
501 && !((slaughterboy&(1<<i)) && !(intertime&16)))
503 DrNumber(totalFrags[i], TALLY_TOTALS_X, y, 1000);
510 //==========================================================================
514 //==========================================================================
516 static void DrNumber(int val, int x, int y, int wrapThresh)
520 if(!(val < -9 && wrapThresh < 1000))
522 sprintf(buff, "%d", val >= wrapThresh ? val%wrapThresh : val);
524 MN_DrTextA(buff, x-MN_TextAWidth(buff)/2, y);
527 //==========================================================================
531 //==========================================================================
533 static void DrNumberBold(int val, int x, int y, int wrapThresh)
537 if(!(val < -9 && wrapThresh < 1000))
539 sprintf(buff, "%d", val >= wrapThresh ? val%wrapThresh : val);
541 MN_DrTextAYellow(buff, x-MN_TextAWidth(buff)/2, y);
544 //===========================================================================
548 //===========================================================================
550 static void DrawHubText(void)
561 count = (intertime-10)/TEXTSPEED;
566 for(; count; count--)
589 w = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
590 if(cx+w->width > SCREENWIDTH)
594 V_DrawPatch(cx, cy, w);