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[] =
165 static void InitStats(void)
170 signed int slaughterfrags;
184 oldCluster = P_GetMapCluster(gamemap);
185 if(oldCluster != P_GetMapCluster(LeaveMap))
187 if(oldCluster >= 1 && oldCluster <= 5)
190 HubText = ClusMsgLumpNames[oldCluster-1];
192 msgLumpName = ClusMsgLumpNames[oldCluster-1];
193 msgLump = W_GetNumForName(msgLumpName);
194 msgSize = W_LumpLength(msgLump);
195 if(msgSize >= MAX_INTRMSN_MESSAGE_SIZE)
197 I_Error("Cluster message too long (%s)", msgLumpName);
199 W_ReadLump(msgLump, ClusterMessage);
200 ClusterMessage[msgSize] = 0; // Append terminator
201 HubText = ClusterMessage;
203 HubCount = strlen(HubText)*TEXTSPEED+TEXTWAIT;
204 S_StartSongName("hub", true);
210 gametype = DEATHMATCH;
212 slaughterfrags = -9999;
216 for(i=0; i<MAXPLAYERS; i++)
222 for(j=0; j<MAXPLAYERS; j++)
226 totalFrags[i] += players[i].frags[j];
231 if(totalFrags[i] > slaughterfrags)
234 slaughterfrags = totalFrags[i];
237 else if(totalFrags[i] == slaughterfrags)
239 slaughterboy |= 1<<i;
243 if(playercount == slaughtercount)
244 { // don't do the slaughter stuff if everyone is equal
247 S_StartSongName("hub", true);
251 //========================================================================
255 //========================================================================
257 static void LoadPics(void)
261 if(HubCount || gametype == DEATHMATCH)
263 patchINTERPIC = W_CacheLumpName("INTERPIC", PU_STATIC);
264 FontBLumpBase = W_GetNumForName("FONTB16");
267 FontBNumbers[i] = W_CacheLumpNum(FontBLumpBase+i, PU_STATIC);
269 FontBLump = W_GetNumForName("FONTB_S")+1;
270 FontBNegative = W_CacheLumpName("FONTB13", PU_STATIC);
271 FontABaseLump = W_GetNumForName("FONTA_S")+1;
273 FontBSlash = W_CacheLumpName("FONTB15", PU_STATIC);
274 FontBPercent = W_CacheLumpName("FONTB05", PU_STATIC);
278 //========================================================================
282 //========================================================================
284 static void UnloadPics(void)
288 if(HubCount || gametype == DEATHMATCH)
290 Z_ChangeTag(patchINTERPIC, PU_CACHE);
293 Z_ChangeTag(FontBNumbers[i], PU_CACHE);
295 Z_ChangeTag(FontBNegative, PU_CACHE);
296 Z_ChangeTag(FontBSlash, PU_CACHE);
297 Z_ChangeTag(FontBPercent, PU_CACHE);
301 //========================================================================
305 //========================================================================
318 skipintermission = false;
321 if(skipintermission || (gametype == SINGLE && !HubCount))
325 skipintermission = false;
326 //S_StartSound(NULL, sfx_dorcls);
330 //========================================================================
334 // Check to see if any player hit a key
335 //========================================================================
337 static void CheckForSkip(void)
341 static boolean triedToSkip;
343 for(i = 0, player = players; i < MAXPLAYERS; i++, player++)
347 if(player->cmd.buttons&BT_ATTACK)
349 if(!player->attackdown)
351 skipintermission = 1;
353 player->attackdown = true;
357 player->attackdown = false;
359 if(player->cmd.buttons&BT_USE)
363 skipintermission = 1;
365 player->usedown = true;
369 player->usedown = false;
373 if(deathmatch && intertime < 140)
374 { // wait for 4 seconds before allowing a skip
375 if(skipintermission == 1)
378 skipintermission = 0;
385 skipintermission = 1;
391 //========================================================================
395 //========================================================================
407 UpdateState |= I_FULLSCRN;
408 memcpy(screen, (byte *)patchINTERPIC, SCREENWIDTH*SCREENHEIGHT);
410 if(gametype == SINGLE)
423 //========================================================================
427 //========================================================================
429 #define TALLY_EFFECT_TICKS 20
430 #define TALLY_FINAL_X_DELTA (23*FRACUNIT)
431 #define TALLY_FINAL_Y_DELTA (13*FRACUNIT)
432 #define TALLY_START_XPOS (178*FRACUNIT)
433 #define TALLY_STOP_XPOS (90*FRACUNIT)
434 #define TALLY_START_YPOS (132*FRACUNIT)
435 #define TALLY_STOP_YPOS (83*FRACUNIT)
436 #define TALLY_TOP_X 85
437 #define TALLY_TOP_Y 9
438 #define TALLY_LEFT_X 7
439 #define TALLY_LEFT_Y 71
440 #define TALLY_TOTALS_X 291
442 static void DrDeathTally(void)
446 fixed_t xDelta, yDelta;
447 fixed_t xStart, scale;
450 static boolean showTotals;
453 V_DrawPatch(TALLY_TOP_X, TALLY_TOP_Y,
454 W_CacheLumpName("tallytop", PU_CACHE));
455 V_DrawPatch(TALLY_LEFT_X, TALLY_LEFT_Y,
456 W_CacheLumpName("tallylft", PU_CACHE));
457 if(intertime < TALLY_EFFECT_TICKS)
460 scale = (intertime*FRACUNIT)/TALLY_EFFECT_TICKS;
461 xDelta = FixedMul(scale, TALLY_FINAL_X_DELTA);
462 yDelta = FixedMul(scale, TALLY_FINAL_Y_DELTA);
463 xStart = TALLY_START_XPOS-FixedMul(scale,
464 TALLY_START_XPOS-TALLY_STOP_XPOS);
465 yPos = TALLY_START_YPOS-FixedMul(scale,
466 TALLY_START_YPOS-TALLY_STOP_YPOS);
470 xDelta = TALLY_FINAL_X_DELTA;
471 yDelta = TALLY_FINAL_Y_DELTA;
472 xStart = TALLY_STOP_XPOS;
473 yPos = TALLY_STOP_YPOS;
475 if(intertime >= TALLY_EFFECT_TICKS && showTotals == false)
478 S_StartSound(NULL, SFX_PLATFORM_STOP);
481 for(i = 0; i < MAXPLAYERS; i++)
484 for(j = 0; j < MAXPLAYERS; j++, xPos += xDelta)
487 bold = (i == consoleplayer || j == consoleplayer);
488 if(playeringame[i] && playeringame[j])
492 DrNumberBold(players[i].frags[j], x, y, 100);
496 DrNumber(players[i].frags[j], x, y, 100);
501 temp = MN_TextAWidth("--")/2;
504 MN_DrTextAYellow("--", x-temp, y);
508 MN_DrTextA("--", x-temp, y);
512 if(showTotals && playeringame[i]
513 && !((slaughterboy&(1<<i)) && !(intertime&16)))
515 DrNumber(totalFrags[i], TALLY_TOTALS_X, y, 1000);
522 //==========================================================================
526 //==========================================================================
528 static void DrNumber(int val, int x, int y, int wrapThresh)
532 if(!(val < -9 && wrapThresh < 1000))
534 sprintf(buff, "%d", val >= wrapThresh ? val%wrapThresh : val);
536 MN_DrTextA(buff, x-MN_TextAWidth(buff)/2, y);
539 //==========================================================================
543 //==========================================================================
545 static void DrNumberBold(int val, int x, int y, int wrapThresh)
549 if(!(val < -9 && wrapThresh < 1000))
551 sprintf(buff, "%d", val >= wrapThresh ? val%wrapThresh : val);
553 MN_DrTextAYellow(buff, x-MN_TextAWidth(buff)/2, y);
556 //===========================================================================
560 //===========================================================================
562 static void DrawHubText(void)
573 count = (intertime-10)/TEXTSPEED;
578 for(; count; count--)
601 w = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
602 if(cx+w->width > SCREENWIDTH)
606 V_DrawPatch(cx, cy, w);