/* ======================== = = IN_lude.c = ======================== */ #include "DoomDef.h" #include "soundst.h" typedef enum { SINGLE, COOPERATIVE, DEATHMATCH } gametype_t; // Public functions void IN_Start(void); void IN_Ticker(void); void IN_Drawer(void); boolean intermission; // Private functions void IN_WaitStop(void); void IN_Stop(void); void IN_LoadPics(void); void IN_UnloadPics(void); void IN_CheckForSkip(void); void IN_InitStats(void); void IN_InitDeathmatchStats(void); void IN_InitNetgameStats(void); void IN_DrawOldLevel(void); void IN_DrawYAH(void); void IN_DrawStatBack(void); void IN_DrawSingleStats(void); void IN_DrawCoopStats(void); void IN_DrawDMStats(void); void IN_DrawNumber(int val, int x, int y, int digits); void IN_DrawTime(int x, int y, int h, int m, int s); void IN_DrTextB(char *text, int x, int y); static boolean skipintermission; static int interstate = 0; static int intertime = -1; static int oldintertime = 0; static gametype_t gametype; static int cnt; static int time; static int hours; static int minutes; static int seconds; static int slaughterboy; // in DM, the player with the most kills static int killPercent[MAXPLAYERS]; static int bonusPercent[MAXPLAYERS]; static int secretPercent[MAXPLAYERS]; static patch_t *patchINTERPIC; static patch_t *patchBEENTHERE; static patch_t *patchGOINGTHERE; static patch_t *FontBNumbers[10]; static patch_t *FontBNegative; static patch_t *FontBSlash; static patch_t *FontBPercent; static int FontBLump; static int FontBLumpBase; static int patchFaceOkayBase; static int patchFaceDeadBase; static signed int totalFrags[MAXPLAYERS]; static fixed_t dSlideX[MAXPLAYERS]; static fixed_t dSlideY[MAXPLAYERS]; static char *KillersText[] = { "K", "I", "L", "L", "E", "R", "S" }; extern char *LevelNames[]; typedef struct { int x; int y; } yahpt_t; static yahpt_t YAHspot[3][9] = { { { 172, 78 }, { 86, 90 }, { 73, 66 }, { 159, 95 }, { 148, 126 }, { 132, 54 }, { 131, 74 }, { 208, 138 }, { 52, 101 } }, { { 218, 57 }, { 137, 81 }, { 155, 124 }, { 171, 68 }, { 250, 86 }, { 136, 98 }, { 203, 90 }, { 220, 140 }, { 279, 106 } }, { { 86, 99 }, { 124, 103 }, { 154, 79 }, { 202, 83 }, { 178, 59 }, { 142, 58 }, { 219, 66 }, { 247, 57 }, { 107, 80 } } }; //======================================================================== // // IN_Start // //======================================================================== extern void AM_Stop (void); void IN_Start(void) { I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE)); IN_LoadPics(); IN_InitStats(); intermission = true; interstate = -1; skipintermission = false; intertime = 0; oldintertime = 0; AM_Stop(); S_StartSong(mus_intr, true); } //======================================================================== // // IN_WaitStop // //======================================================================== void IN_WaitStop(void) { if(!--cnt) { IN_Stop(); G_WorldDone(); } } //======================================================================== // // IN_Stop // //======================================================================== void IN_Stop(void) { intermission = false; IN_UnloadPics(); SB_state = -1; BorderNeedRefresh = true; } //======================================================================== // // IN_InitStats // // Initializes the stats for single player mode //======================================================================== void IN_InitStats(void) { int i; int j; signed int slaughterfrags; int posnum; int slaughtercount; int playercount; if(!netgame) { gametype = SINGLE; time = leveltime/35; hours = time/3600; time -= hours*3600; minutes = time/60; time -= minutes*60; seconds = time; } else if(netgame && !deathmatch) { gametype = COOPERATIVE; memset(killPercent, 0, MAXPLAYERS*sizeof(int)); memset(bonusPercent, 0, MAXPLAYERS*sizeof(int)); memset(secretPercent, 0, MAXPLAYERS*sizeof(int)); for(i=0; i slaughterfrags) { slaughterboy = 1< 3 && interstate >= 1) { // Extended Wad levels: skip directly to the next level interstate = 3; } switch(interstate) { case 0: oldintertime = intertime+300; if(gameepisode > 3) { oldintertime = intertime+1200; } break; case 1: oldintertime = intertime+200; break; case 2: oldintertime = MAXINT; break; case 3: cnt = 10; break; default: break; } } if(skipintermission) { if(interstate == 0 && intertime < 150) { intertime = 150; skipintermission = false; return; } else if(interstate < 2 && gameepisode < 4) { interstate = 2; skipintermission = false; S_StartSound(NULL, sfx_dorcls); return; } interstate = 3; cnt = 10; skipintermission = false; S_StartSound(NULL, sfx_dorcls); } } //======================================================================== // // IN_CheckForSkip // // Check to see if any player hit a key //======================================================================== void IN_CheckForSkip(void) { int i; player_t *player; for (i=0, player = players ; icmd.buttons&BT_ATTACK) { if (!player->attackdown) { skipintermission = 1; } player->attackdown = true; } else { player->attackdown = false; } if (player->cmd.buttons&BT_USE) { if (!player->usedown) { skipintermission = 1; } player->usedown = true; } else { player->usedown = false; } } } } //======================================================================== // // IN_Drawer // //======================================================================== void IN_Drawer(void) { static int oldinterstate; if(!intermission) { return; } if(interstate == 3) { return; } UpdateState |= I_FULLSCRN; if(oldinterstate != 2 && interstate == 2) { S_StartSound(NULL, sfx_pstop); } oldinterstate = interstate; switch(interstate) { case 0: // draw stats IN_DrawStatBack(); switch(gametype) { case SINGLE: IN_DrawSingleStats(); break; case COOPERATIVE: IN_DrawCoopStats(); break; case DEATHMATCH: IN_DrawDMStats(); break; } break; case 1: // leaving old level if(gameepisode < 4) { V_DrawPatch(0, 0, patchINTERPIC); IN_DrawOldLevel(); } break; case 2: // going to the next level if(gameepisode < 4) { V_DrawPatch(0, 0, patchINTERPIC); IN_DrawYAH(); } break; case 3: // waiting before going to the next level if(gameepisode < 4) { V_DrawPatch(0, 0, patchINTERPIC); } break; default: I_Error("IN_lude: Intermission state out of range.\n"); break; } } //======================================================================== // // IN_DrawStatBack // //======================================================================== void IN_DrawStatBack(void) { int x; int y; byte *src; byte *dest; src = W_CacheLumpName ("FLOOR16", PU_CACHE); dest = screen; for (y=0 ; y= 30) { S_StartSound(NULL, sfx_dorcls); sounds++; } IN_DrawNumber(players[consoleplayer].killcount, 200, 65, 3); V_DrawShadowedPatch(237, 65, FontBSlash); IN_DrawNumber(totalkills, 248, 65, 3); if(intertime < 60) { return; } if(sounds < 2 && intertime >= 60) { S_StartSound(NULL, sfx_dorcls); sounds++; } IN_DrawNumber(players[consoleplayer].itemcount, 200, 90, 3); V_DrawShadowedPatch(237, 90, FontBSlash); IN_DrawNumber(totalitems, 248, 90, 3); if(intertime < 90) { return; } if(sounds < 3 && intertime >= 90) { S_StartSound(NULL, sfx_dorcls); sounds++; } IN_DrawNumber(players[consoleplayer].secretcount, 200, 115, 3); V_DrawShadowedPatch(237, 115, FontBSlash); IN_DrawNumber(totalsecret, 248, 115, 3); if(intertime < 150) { return; } if(sounds < 4 && intertime >= 150) { S_StartSound(NULL, sfx_dorcls); sounds++; } if(!ExtendedWAD || gameepisode < 4) { IN_DrTextB("TIME", 85, 160); IN_DrawTime(155, 160, hours, minutes, seconds); } else { x = 160-MN_TextAWidth("NOW ENTERING:")/2; MN_DrTextA("NOW ENTERING:", x, 160); x = 160-MN_TextBWidth(LevelNames[(gameepisode-1)*9+gamemap-1]+7)/2; IN_DrTextB(LevelNames[(gameepisode-1)*9+gamemap-1]+7, x, 170); skipintermission = false; } } //======================================================================== // // IN_DrawCoopStats // //======================================================================== void IN_DrawCoopStats(void) { int i; int x; int ypos; static int sounds; IN_DrTextB("KILLS", 95, 35); IN_DrTextB("BONUS", 155, 35); IN_DrTextB("SECRET", 232, 35); x = 160-MN_TextBWidth(LevelNames[(gameepisode-1)*9+prevmap-1]+7)/2; IN_DrTextB(LevelNames[(gameepisode-1)*9+prevmap-1]+7, x, 3); x = 160-MN_TextAWidth("FINISHED")/2; MN_DrTextA("FINISHED", x, 25); ypos = 50; for(i=0; i= 40 && sounds < 1) { S_StartSound(NULL, sfx_dorcls); sounds++; } IN_DrawNumber(killPercent[i], 85, ypos+10, 3); V_DrawShadowedPatch(121, ypos+10, FontBPercent); IN_DrawNumber(bonusPercent[i], 160, ypos+10, 3); V_DrawShadowedPatch(196, ypos+10, FontBPercent); IN_DrawNumber(secretPercent[i], 237, ypos+10, 3); V_DrawShadowedPatch(273, ypos+10, FontBPercent); ypos += 37; } } } //======================================================================== // // IN_DrawDMStats // //======================================================================== void IN_DrawDMStats(void) { int i; int j; int ypos; int xpos; int kpos; int x; static int sounds; xpos = 90; ypos = 55; IN_DrTextB("TOTAL", 265, 30); MN_DrTextA("VICTIMS", 140, 8); for(i=0; i<7; i++) { MN_DrTextA(KillersText[i], 10, 80+9*i); } if(intertime < 20) { for(i=0; i>FRACBITS, W_CacheLumpNum(patchFaceOkayBase+i, PU_CACHE)); V_DrawShadowedPatch(((xpos<>FRACBITS, 18, W_CacheLumpNum(patchFaceDeadBase+i, PU_CACHE)); } } sounds = 0; return; } if(intertime >= 20 && sounds < 1) { S_StartSound(NULL, sfx_dorcls); sounds++; } if(intertime >= 100 && slaughterboy && sounds < 2) { S_StartSound(NULL, sfx_wpnup); sounds++; } for(i=0; i 99) { val = 99; } } if(val > 9) { realdigits++; if(digits < realdigits) { realdigits = digits; val = 9; } } if(val > 99) { realdigits++; if(digits < realdigits) { realdigits = digits; val = 99; } } if(val > 999) { realdigits++; if(digits < realdigits) { realdigits = digits; val = 999; } } if(digits == 4) { patch = FontBNumbers[val/1000]; V_DrawShadowedPatch(xpos+6-patch->width/2-12, y, patch); } if(digits > 2) { if(realdigits > 2) { patch = FontBNumbers[val/100]; V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch); } xpos += 12; } val = val%100; if(digits > 1) { if(val > 9) { patch = FontBNumbers[val/10]; V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch); } else if(digits == 2 || oldval > 99) { V_DrawShadowedPatch(xpos, y, FontBNumbers[0]); } xpos += 12; } val = val%10; patch = FontBNumbers[val]; V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch); if(neg) { patch = FontBNegative; V_DrawShadowedPatch(xpos+6-patch->width/2-12*(realdigits), y, patch); } } //======================================================================== // // IN_DrTextB // //======================================================================== void IN_DrTextB(char *text, int x, int y) { char c; patch_t *p; while((c = *text++) != 0) { if(c < 33) { x += 8; } else { p = W_CacheLumpNum(FontBLump+c-33, PU_CACHE); V_DrawShadowedPatch(x, y, p); x += p->width-1; } } }