diff --git a/src/doomstat.h b/src/doomstat.h index 8050a1beb2562d50dc63fb1c1e5a753602225486..7f8b5fd6e0e81c030ad2f7ec150e3ccc30aa008f 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -131,6 +131,7 @@ extern UINT8 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor extern tic_t countdowntimer; extern boolean countdowntimeup; +extern boolean exitfadestarted; typedef struct { diff --git a/src/g_game.c b/src/g_game.c index 1e39bcdf7805fbfb499cfc320e8d2779f56e2e1a..b28ab775296d16870eda6f93696c5cf441b8c389 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -131,6 +131,7 @@ UINT8 skincolor_bluering = SKINCOLOR_STEELBLUE; tic_t countdowntimer = 0; boolean countdowntimeup = false; +boolean exitfadestarted = false; cutscene_t *cutscenes[128]; @@ -3701,7 +3702,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean { // Clear a bunch of variables tokenlist = token = sstimer = redscore = bluescore = lastmap = 0; - countdown = countdown2 = 0; + countdown = countdown2 = exitfadestarted = 0; for (i = 0; i < MAXPLAYERS; i++) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 850ec2987f5de2513e59e00ded0824c9fb0a2dbd..e2543f553aa95cbe0e7ed2a719f926ef1e8454a2 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6033,7 +6033,7 @@ void P_RunOverlays(void) { angle_t viewingangle; - if (players[displayplayer].awayviewtics) + if (players[displayplayer].awayviewtics && players[displayplayer].awayviewmobj != NULL && !P_MobjWasRemoved(players[displayplayer].awayviewmobj)) viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y); else if (!camera.chase && players[displayplayer].mo) viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y); diff --git a/src/p_setup.c b/src/p_setup.c index 033e99f10b64dd4260dd08770dffe0301f010c87..b2636c3505f0efb327c07ff92caf1b3ef8ee2086 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2311,7 +2311,7 @@ static void P_LevelInitStuff(void) players[i].lives = cv_startinglives.value; } - players[i].realtime = countdown = countdown2 = 0; + players[i].realtime = countdown = countdown2 = exitfadestarted = 0; players[i].gotcontinue = false; diff --git a/src/p_user.c b/src/p_user.c index f04386fec64bb35fd5ef6bd14b80e100f5bf63c2..03e1e4e23605efd0a04d7d430765fc5b6443b5b8 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8741,14 +8741,8 @@ void P_PlayerThink(player_t *player) if (player->flashcount) player->flashcount--; - // Re-fixed by Jimita (11-12-2018) - if (player->awayviewtics) - { + if (player->awayviewtics && player->awayviewtics != -1) player->awayviewtics--; - if (!player->awayviewtics) - player->awayviewtics = -1; - // The timer might've reached zero, but we'll run the remote view camera anyway by setting it to -1. - } /// \note do this in the cheat code if (player->pflags & PF_NOCLIP) @@ -8824,6 +8818,44 @@ void P_PlayerThink(player_t *player) if (player->exiting && countdown2) player->exiting = 5; + // Same check as below, just at 1 second before + // so we can fade music + if (!exitfadestarted && + player->exiting > 0 && player->exiting <= 1*TICRATE && + (!multiplayer || gametype == GT_COOP ? !mapheaderinfo[gamemap-1]->musinterfadeout : true) && + // don't fade if we're fading during intermission. follows Y_StartIntermission intertype = int_coop + (gametype == GT_RACE || gametype == GT_COMPETITION ? countdown2 == 0 : true) && // don't fade on timeout + player->lives > 0 && // don't fade on game over (competition) + P_IsLocalPlayer(player)) + { + if (cv_playersforexit.value) + { + INT32 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator || players[i].bot) + continue; + if (players[i].lives <= 0) + continue; + + if (!players[i].exiting || players[i].exiting > 1*TICRATE) + break; + } + + if (i == MAXPLAYERS) + { + exitfadestarted = true; + S_FadeOutStopMusic(1*MUSICRATE); + } + } + else + { + exitfadestarted = true; + S_FadeOutStopMusic(1*MUSICRATE); + } + } + if (player->exiting == 2 || countdown2 == 2) { if (cv_playersforexit.value) // Count to be sure everyone's exited @@ -9526,9 +9558,6 @@ void P_PlayerAfterThink(player_t *player) } } - if (player->awayviewtics < 0) - player->awayviewtics = 0; - // spectator invisibility and nogravity. if ((netgame || multiplayer) && player->spectator) { diff --git a/src/r_data.c b/src/r_data.c index 29a9c52bb97d9186db926e390d45eb67c9aa2e8b..bd12eb248012b2bbee3649a783b4799cf3a54a61 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -404,6 +404,17 @@ void R_LoadTextures(void) // but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures. for (w = 0, numtextures = 0; w < numwadfiles; w++) { + // Count the textures from TEXTURES lumps + + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); + while (texturesLumpPos != INT16_MAX) + { + numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); + } + + // Count single-patch textures + if (wadfiles[w]->type == RET_PK3) { texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); @@ -411,30 +422,34 @@ void R_LoadTextures(void) } else { - texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; + texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0); texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); } - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); - while (texturesLumpPos != INT16_MAX) - { - numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos); - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); - } + if (texstart == INT16_MAX || texend == INT16_MAX) + continue; - // Add all the textures between TX_START and TX_END - if (texstart != INT16_MAX && texend != INT16_MAX) + texstart++; // Do not count the first marker + + // PK3s have subfolders, so we can't just make a simple sum + if (wadfiles[w]->type == RET_PK3) { - numtextures += (UINT32)(texend - texstart); + for (j = texstart; j < texend; j++) + { + if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it + numtextures++; + } } - - // If no textures found by this point, bomb out - if (!numtextures && w == (numwadfiles - 1)) + else // Add all the textures between TX_START and TX_END { - I_Error("No textures detected in any WADs!\n"); + numtextures += (UINT32)(texend - texstart); } } + // If no textures found by this point, bomb out + if (!numtextures) + I_Error("No textures detected in any WADs!\n"); + // Allocate memory and initialize to 0 for all the textures we are initialising. // There are actually 5 buffers allocated in one for convenience. textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL); @@ -469,7 +484,7 @@ void R_LoadTextures(void) } else { - texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; + texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0); texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); if (texturesLumpPos != INT16_MAX) @@ -479,9 +494,16 @@ void R_LoadTextures(void) if (texstart == INT16_MAX || texend == INT16_MAX) continue; + texstart++; // Do not count the first marker + // Work through each lump between the markers in the WAD. - for (j = 0; j < (texend - texstart); i++, j++) + for (j = 0; j < (texend - texstart); j++) { + if (wadfiles[w]->type == RET_PK3) + { + if (W_IsLumpFolder((UINT16)w, texstart + j)) // Check if lump is a folder + continue; // If it is then SKIP IT + } patchlump = W_CacheLumpNumPwad((UINT16)w, texstart + j, PU_CACHE); //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height); @@ -506,9 +528,9 @@ void R_LoadTextures(void) k = 1; while (k << 1 <= texture->width) k <<= 1; - texturewidthmask[i] = k - 1; textureheight[i] = texture->height << FRACBITS; + i++; } } } diff --git a/src/w_wad.c b/src/w_wad.c index f19070047138543eb9b73cb5b6b67450c3e48d92..26a98bfdff0420a0e07fb4a49bd17170fbb7c52a 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1159,6 +1159,22 @@ boolean W_IsLumpWad(lumpnum_t lumpnum) return false; // WADs should never be inside non-PK3s as far as SRB2 is concerned } +// +// W_IsLumpFolder +// Is the lump a folder? (in a PK3 obviously) +// +boolean W_IsLumpFolder(UINT16 wad, UINT16 lump) +{ + if (wadfiles[wad]->type == RET_PK3) + { + const char *name = wadfiles[wad]->lumpinfo[lump].name2; + + return (name[strlen(name)-1] == '/'); // folders end in '/' + } + + return false; // non-PK3s don't have folders +} + #ifdef HAVE_ZLIB /* report a zlib or i/o error */ void zerr(int ret) diff --git a/src/w_wad.h b/src/w_wad.h index e2e17740f76fc24ed7d02a60fc5f854824888296..87566c3ee8c103d33d554199d520cee4a501c91b 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -154,6 +154,7 @@ size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump); size_t W_LumpLength(lumpnum_t lumpnum); boolean W_IsLumpWad(lumpnum_t lumpnum); // for loading maps from WADs in PK3s +boolean W_IsLumpFolder(UINT16 wad, UINT16 lump); // for detecting folder "lumps" #ifdef HAVE_ZLIB void zerr(int ret); // zlib error checking