From d542c2440dfd93c853e7c16b2c611f105671c973 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 18 Sep 2018 15:50:12 -0400 Subject: [PATCH 01/15] musicplus-feature-endoflevel 2.2 -> 2.1 backport --- src/dehacked.c | 2 ++ src/doomstat.h | 3 +++ src/g_game.c | 2 +- src/lua_maplib.c | 4 +++- src/p_setup.c | 3 ++- src/p_user.c | 39 +++++++++++++++++++++++++++++++++++++++ src/s_sound.h | 6 ++++++ src/y_inter.c | 10 ++++++++-- 8 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index e2df11142..002ad8071 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1205,6 +1205,8 @@ static void readlevelheader(MYFILE *f, INT32 num) mapheaderinfo[num-1]->skynum = (INT16)i; else if (fastcmp(word, "INTERSCREEN")) strncpy(mapheaderinfo[num-1]->interscreen, word2, 8); + else if (fastcmp(word, "MUSICINTERFADEOUT")) + mapheaderinfo[num-1]->musicinterfadeout = (UINT32)get_number(word2); else if (fastcmp(word, "PRECUTSCENENUM")) mapheaderinfo[num-1]->precutscenenum = (UINT8)i; else if (fastcmp(word, "CUTSCENENUM")) diff --git a/src/doomstat.h b/src/doomstat.h index d6fd046b4..cbeb4de42 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -246,6 +246,9 @@ typedef struct UINT8 numGradedMares; ///< Internal. For grade support. nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful. + // Music stuff. + UINT32 musicinterfadeout; ///< Fade out level music on intermission screen in milliseconds + // Lua stuff. // (This is not ifdeffed so the map header structure can stay identical, just in case.) UINT8 numCustomOptions; ///< Internal. For Lua custom value support. diff --git a/src/g_game.c b/src/g_game.c index 6be4cf96e..0c53d17ff 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3541,7 +3541,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/lua_maplib.c b/src/lua_maplib.c index a1d7994bf..b68574a7f 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1211,7 +1211,9 @@ static int mapheaderinfo_get(lua_State *L) if (!header->interscreen[i]) break; lua_pushlstring(L, header->interscreen, i); - } else if (fastcmp(field,"runsoc")) + } else if (fastcmp(field,"musicinterfadeout")) + lua_pushinteger(L, header->musicinterfadeout); + else if (fastcmp(field,"runsoc")) lua_pushstring(L, header->runsoc); else if (fastcmp(field,"scriptname")) lua_pushstring(L, header->scriptname); diff --git a/src/p_setup.c b/src/p_setup.c index 6c6b9153d..424aed5bc 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -227,6 +227,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->menuflags = 0; // TODO grades support for delfile (pfft yeah right) P_DeleteGrades(num); + mapheaderinfo[num]->musicinterfadeout = 0; // an even further impossibility, delfile custom opts support mapheaderinfo[num]->customopts = NULL; mapheaderinfo[num]->numCustomOptions = 0; @@ -2189,7 +2190,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 03b037fed..1d34ba5f1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8789,6 +8789,45 @@ 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 <= 1*TICRATE && + (!multiplayer || gametype == GT_COOP ? !mapheaderinfo[gamemap-1]->musicinterfadeout : 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, total = 0, exiting = 0; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator || players[i].bot) + continue; + if (players[i].lives <= 0) + continue; + + total++; + if (players[i].exiting && players[i].exiting < 1*TICRATE+1) + exiting++; + } + + if (!total || ((4*exiting)/total) >= cv_playersforexit.value) + { + 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 diff --git a/src/s_sound.h b/src/s_sound.h index 538707ffb..852ed4c27 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -23,6 +23,12 @@ // mask used to indicate sound origin is player item pickup #define PICKUP_SOUND 0x8000 +// Game state stuff + +boolean exitfadestarted; + +// Sound stuff + extern consvar_t stereoreverse; extern consvar_t cv_soundvolume, cv_digmusicvolume, cv_midimusicvolume; extern consvar_t cv_numChannels; diff --git a/src/y_inter.c b/src/y_inter.c index e7df165bf..1f4b49ddf 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -696,7 +696,10 @@ void Y_Ticker(void) boolean anybonuses = false; if (!intertic) // first time only - S_ChangeMusicInternal("lclear", false); // don't loop it + if (mapheaderinfo[gamemap-1]->musicinterfadeout) + S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musicinterfadeout); + else + S_ChangeMusicInternal("_clear", false); // don't loop it if (intertic < TICRATE) // one second pause before tally begins return; @@ -757,7 +760,10 @@ void Y_Ticker(void) if (!intertic) // first time only { - S_ChangeMusicInternal("lclear", false); // don't loop it + if (mapheaderinfo[gamemap-1]->musicinterfadeout) + S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musicinterfadeout); + else + S_ChangeMusicInternal("_clear", false); // don't loop it tallydonetic = 0; } From 1dd47e850b976ece7b01ef22d6573bcadc6bac94 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 18 Sep 2018 23:27:00 -0400 Subject: [PATCH 02/15] EndOfLevel: Check player->exiting > 0 && <= TICRATE, fixes start-of-level fading in 2.1 Braces in y_inter.c --- src/p_user.c | 2 +- src/y_inter.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 1d34ba5f1..ae7bba582 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8792,7 +8792,7 @@ void P_PlayerThink(player_t *player) // Same check as below, just at 1 second before // so we can fade music if (!exitfadestarted && - player->exiting <= 1*TICRATE && + player->exiting > 0 && player->exiting <= 1*TICRATE && (!multiplayer || gametype == GT_COOP ? !mapheaderinfo[gamemap-1]->musicinterfadeout : 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 diff --git a/src/y_inter.c b/src/y_inter.c index 1f4b49ddf..5e9cb7112 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -696,10 +696,12 @@ void Y_Ticker(void) boolean anybonuses = false; if (!intertic) // first time only + { if (mapheaderinfo[gamemap-1]->musicinterfadeout) S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musicinterfadeout); else S_ChangeMusicInternal("_clear", false); // don't loop it + } if (intertic < TICRATE) // one second pause before tally begins return; From b057b2932df1eede66e45c9eafb09108d4aa20fe Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 18 Sep 2018 23:28:39 -0400 Subject: [PATCH 03/15] EndOfLevel: 2.1 dehacked setup fix --- src/p_setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 424aed5bc..38182ecb6 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -187,6 +187,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->mustrack = 0; DEH_WriteUndoline("MUSICPOS", va("%d", mapheaderinfo[num]->mustrack), UNDO_NONE); mapheaderinfo[num]->muspos = 0; + DEH_WriteUndoline("MUSICINTERFADEOUT", va("%d", mapheaderinfo[num]->musicinterfadeout), UNDO_NONE); + mapheaderinfo[num]->musicinterfadeout = 0; DEH_WriteUndoline("FORCECHARACTER", va("%d", mapheaderinfo[num]->forcecharacter), UNDO_NONE); mapheaderinfo[num]->forcecharacter[0] = '\0'; DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE); @@ -227,7 +229,6 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->menuflags = 0; // TODO grades support for delfile (pfft yeah right) P_DeleteGrades(num); - mapheaderinfo[num]->musicinterfadeout = 0; // an even further impossibility, delfile custom opts support mapheaderinfo[num]->customopts = NULL; mapheaderinfo[num]->numCustomOptions = 0; From 481c0d7623f77fe405401bfeaa5e645e108c9093 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 18 Sep 2018 23:32:00 -0400 Subject: [PATCH 04/15] EndOfLevel: 2.1 _clear -> lclear music in y_inter --- src/y_inter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 5e9cb7112..c20753e83 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -700,7 +700,7 @@ void Y_Ticker(void) if (mapheaderinfo[gamemap-1]->musicinterfadeout) S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musicinterfadeout); else - S_ChangeMusicInternal("_clear", false); // don't loop it + S_ChangeMusicInternal("lclear", false); // don't loop it } if (intertic < TICRATE) // one second pause before tally begins @@ -765,7 +765,7 @@ void Y_Ticker(void) if (mapheaderinfo[gamemap-1]->musicinterfadeout) S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musicinterfadeout); else - S_ChangeMusicInternal("_clear", false); // don't loop it + S_ChangeMusicInternal("lclear", false); // don't loop it tallydonetic = 0; } From 0186f6784b800c8d1edba5d78e331b9522104bbc Mon Sep 17 00:00:00 2001 From: Jimita the Cat Date: Wed, 6 Mar 2019 21:40:38 -0300 Subject: [PATCH 05/15] a --- src/p_mobj.c | 2 +- src/p_user.c | 11 +---------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 850ec2987..e2543f553 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_user.c b/src/p_user.c index 285d36ca9..b0d716cea 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) @@ -9526,9 +9520,6 @@ void P_PlayerAfterThink(player_t *player) } } - if (player->awayviewtics < 0) - player->awayviewtics = 0; - // spectator invisibility and nogravity. if ((netgame || multiplayer) && player->spectator) { From b5fc27c5450845f724c394524fc88a918bceb420 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 15 Mar 2019 01:00:50 -0400 Subject: [PATCH 06/15] Implement MUSICINTERFADEOUT level header --- src/dehacked.c | 2 ++ src/doomstat.h | 1 + src/lua_maplib.c | 4 +++- src/p_setup.c | 2 ++ src/y_inter.c | 8 ++++++-- 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 6978dd16a..a5fddfea2 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1198,6 +1198,8 @@ static void readlevelheader(MYFILE *f, INT32 num) mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1); else if (fastcmp(word, "MUSICPOS")) mapheaderinfo[num-1]->muspos = (UINT32)get_number(word2); + else if (fastcmp(word, "MUSICINTERFADEOUT")) + mapheaderinfo[num-1]->musicinterfadeout = (UINT32)get_number(word2); else if (fastcmp(word, "MUSICINTER")) deh_strlcpy(mapheaderinfo[num-1]->musintername, word2, sizeof(mapheaderinfo[num-1]->musintername), va("Level header %d: intermission music", num)); diff --git a/src/doomstat.h b/src/doomstat.h index 716c4d654..82654ba1a 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -248,6 +248,7 @@ typedef struct nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful. // Music stuff. + UINT32 musicinterfadeout; ///< Fade out level music on intermission screen in milliseconds char musintername[7]; ///< Intermission screen music. // Lua stuff. diff --git a/src/lua_maplib.c b/src/lua_maplib.c index d77e636b3..2715f807f 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1489,7 +1489,9 @@ static int mapheaderinfo_get(lua_State *L) if (!header->interscreen[i]) break; lua_pushlstring(L, header->interscreen, i); - } else if (fastcmp(field,"runsoc")) + } else if (fastcmp(field,"musicinterfadeout")) + lua_pushinteger(L, header->musicinterfadeout); + else if (fastcmp(field,"runsoc")) lua_pushstring(L, header->runsoc); else if (fastcmp(field,"scriptname")) lua_pushstring(L, header->scriptname); diff --git a/src/p_setup.c b/src/p_setup.c index 4409ec356..e6aa635e5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -189,6 +189,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->mustrack = 0; DEH_WriteUndoline("MUSICPOS", va("%d", mapheaderinfo[num]->muspos), UNDO_NONE); mapheaderinfo[num]->muspos = 0; + DEH_WriteUndoline("MUSICINTERFADEOUT", va("%d", mapheaderinfo[num]->musicinterfadeout), UNDO_NONE); + mapheaderinfo[num]->musicinterfadeout = 0; DEH_WriteUndoline("MUSICINTER", mapheaderinfo[num]->musintername, UNDO_NONE); mapheaderinfo[num]->musintername[0] = '\0'; DEH_WriteUndoline("FORCECHARACTER", va("%d", mapheaderinfo[num]->forcecharacter), UNDO_NONE); diff --git a/src/y_inter.c b/src/y_inter.c index e6e5a1d22..ab4c21692 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -697,7 +697,9 @@ void Y_Ticker(void) if (!intertic) // first time only { - if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled)) + if (mapheaderinfo[gamemap-1]->musicinterfadeout) + S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musicinterfadeout); + else if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled)) S_ChangeMusicInternal(mapheaderinfo[gamemap-1]->musintername, false); // don't loop it else S_ChangeMusicInternal("lclear", false); // don't loop it @@ -762,7 +764,9 @@ void Y_Ticker(void) if (!intertic) // first time only { - if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled)) + if (mapheaderinfo[gamemap-1]->musicinterfadeout) + S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musicinterfadeout); + else if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled)) S_ChangeMusicInternal(mapheaderinfo[gamemap-1]->musintername, false); // don't loop it else S_ChangeMusicInternal("lclear", false); // don't loop it From 587a51a95786d982d65dd22f2ea1741cb0a5e519 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 15 Mar 2019 03:47:30 -0400 Subject: [PATCH 07/15] Fix end-of-level fading for cv_playersforexit (Code in p_user.c was from 2.2, where cv_playersforexit has different values so that the player exit check works differently) --- src/p_user.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 97ee04a28..edc4d8a58 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8836,7 +8836,7 @@ void P_PlayerThink(player_t *player) { if (cv_playersforexit.value) { - INT32 i, total = 0, exiting = 0; + INT32 i; for (i = 0; i < MAXPLAYERS; i++) { @@ -8845,12 +8845,11 @@ void P_PlayerThink(player_t *player) if (players[i].lives <= 0) continue; - total++; - if (players[i].exiting && players[i].exiting < 1*TICRATE+1) - exiting++; + if (!players[i].exiting || players[i].exiting > 1*TICRATE) + break; } - if (!total || ((4*exiting)/total) >= cv_playersforexit.value) + if (i == MAXPLAYERS) { exitfadestarted = true; S_FadeOutStopMusic(1*MUSICRATE); From f18103a473dbd0f52d5cf293d6a04496547fc2a8 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 15 Mar 2019 11:01:41 -0400 Subject: [PATCH 08/15] Declare exitfadestarted properly --- src/doomstat.h | 1 + src/g_game.c | 1 + src/s_sound.h | 6 ------ 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index d9132798f..4511cf297 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 cba9c6575..ac814fa64 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -130,6 +130,7 @@ UINT8 skincolor_bluering = SKINCOLOR_STEELBLUE; tic_t countdowntimer = 0; boolean countdowntimeup = false; +boolean exitfadestarted = false; cutscene_t *cutscenes[128]; diff --git a/src/s_sound.h b/src/s_sound.h index 3a5188c2f..157b8b1cc 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -23,12 +23,6 @@ // mask used to indicate sound origin is player item pickup #define PICKUP_SOUND 0x8000 -// Game state stuff - -boolean exitfadestarted; - -// Sound stuff - extern consvar_t stereoreverse; extern consvar_t cv_soundvolume, cv_digmusicvolume, cv_midimusicvolume; extern consvar_t cv_numChannels; From 45922f80d1e35aadc9da6e20fa32fa78c1044dfd Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 23 Jun 2019 12:26:52 +0100 Subject: [PATCH 09/15] Don't read from a per-map COLORMAP if it is too big. Could this be changed to only read the first so many bytes? --- src/r_data.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/r_data.c b/src/r_data.c index a21ba49ae..bf570e3ab 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1073,6 +1073,15 @@ void R_ReInitColormaps(UINT16 num) lump = W_GetNumForName(colormap); if (lump == LUMPERROR) lump = W_GetNumForName("COLORMAP"); + else + { + if (W_LumpLength(lump) > W_LumpLength(W_GetNumForName("COLORMAP"))) + { + CONS_Alert(CONS_WARNING, "%s lump size is too big, using COLORMAP.\n", colormap); + lump = W_GetNumForName("COLORMAP"); + } + } + W_ReadLump(lump, colormaps); // Init Boom colormaps. From bc254d9cf7ca36985481f988af0e8daa4741c7cd Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 23 Jun 2019 13:48:29 +0100 Subject: [PATCH 10/15] Kill Texture SOC feature. As far as I know it's basically unused, and the strstr is inherently unsafe because there's no guarantee that a patch's contents are NULL terminated. --- src/r_data.c | 49 +++++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index bf570e3ab..c50cbf209 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -484,42 +484,31 @@ void R_LoadTextures(void) { patchlump = W_CacheLumpNumPwad((UINT16)w, texstart + j, PU_CACHE); - // Then, check the lump directly to see if it's a texture SOC, - // and if it is, load it using dehacked instead. - if (strstr((const char *)patchlump, "TEXTURE")) - { - CONS_Alert(CONS_WARNING, "%s is a Texture SOC.\n", W_CheckNameForNumPwad((UINT16)w,texstart+j)); - Z_Unlock(patchlump); - DEH_LoadDehackedLumpPwad((UINT16)w, texstart + j); - } - else - { - //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height); - texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL); + //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height); + texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL); - // Set texture properties. - M_Memcpy(texture->name, W_CheckNameForNumPwad((UINT16)w, texstart + j), sizeof(texture->name)); - texture->width = SHORT(patchlump->width); - texture->height = SHORT(patchlump->height); - texture->patchcount = 1; - texture->holes = false; + // Set texture properties. + M_Memcpy(texture->name, W_CheckNameForNumPwad((UINT16)w, texstart + j), sizeof(texture->name)); + texture->width = SHORT(patchlump->width); + texture->height = SHORT(patchlump->height); + texture->patchcount = 1; + texture->holes = false; - // Allocate information for the texture's patches. - patch = &texture->patches[0]; + // Allocate information for the texture's patches. + patch = &texture->patches[0]; - patch->originx = patch->originy = 0; - patch->wad = (UINT16)w; - patch->lump = texstart + j; + patch->originx = patch->originy = 0; + patch->wad = (UINT16)w; + patch->lump = texstart + j; - Z_Unlock(patchlump); + Z_Unlock(patchlump); - k = 1; - while (k << 1 <= texture->width) - k <<= 1; + k = 1; + while (k << 1 <= texture->width) + k <<= 1; - texturewidthmask[i] = k - 1; - textureheight[i] = texture->height << FRACBITS; - } + texturewidthmask[i] = k - 1; + textureheight[i] = texture->height << FRACBITS; } } } From bb9b1b3b1f0f133feef8395cefa3a9cc3939a6e1 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 23 Jun 2019 13:49:39 +0100 Subject: [PATCH 11/15] Change COLORMAP lump size check to be exact A lower size could technically be valid, but could easily run into strange issues. --- src/r_data.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index c50cbf209..be7a5dc98 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1064,9 +1064,9 @@ void R_ReInitColormaps(UINT16 num) lump = W_GetNumForName("COLORMAP"); else { - if (W_LumpLength(lump) > W_LumpLength(W_GetNumForName("COLORMAP"))) + if (W_LumpLength(lump) != W_LumpLength(W_GetNumForName("COLORMAP"))) { - CONS_Alert(CONS_WARNING, "%s lump size is too big, using COLORMAP.\n", colormap); + CONS_Alert(CONS_WARNING, "%s lump size does not match COLORMAP, using COLORMAP instead.\n", colormap); lump = W_GetNumForName("COLORMAP"); } } From 5f339fc2a922aa00a94027e885c29173e43edac7 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 23 Jun 2019 14:52:49 +0100 Subject: [PATCH 12/15] Don't overlap strncpy in WAD file load --- src/w_wad.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 8d96449f1..e18c5a084 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -149,9 +149,15 @@ FILE *W_OpenWadFile(const char **filename, boolean useerrors) { FILE *handle; - strncpy(filenamebuf, *filename, MAX_WADPATH); - filenamebuf[MAX_WADPATH - 1] = '\0'; - *filename = filenamebuf; + // Officially, strncpy should not have overlapping buffers, since W_VerifyNMUSlumps is called after this, and it + // changes filename to point at filenamebuf, it would technically be doing that. I doubt any issue will occur since + // they point to the same location, but it's better to be safe and this is a simple change. + if (filenamebuf != *filename) + { + strncpy(filenamebuf, *filename, MAX_WADPATH); + filenamebuf[MAX_WADPATH - 1] = '\0'; + *filename = filenamebuf; + } // open wad file if ((handle = fopen(*filename, "rb")) == NULL) From 8a778a407001c6cf861c87ecfedbb8ed8f09860d Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 23 Jun 2019 15:02:32 +0100 Subject: [PATCH 13/15] Simply truncate the per-map COLORMAP lump instead of not reading it at all. Keep the warning though. --- src/r_data.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index be7a5dc98..29a9c52bb 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1054,6 +1054,7 @@ void R_ReInitColormaps(UINT16 num) { char colormap[9] = "COLORMAP"; lumpnum_t lump; + const lumpnum_t basecolormaplump = W_GetNumForName(colormap); if (num > 0 && num <= 10000) snprintf(colormap, 8, "CLM%04u", num-1); @@ -1061,17 +1062,16 @@ void R_ReInitColormaps(UINT16 num) // Load in the light tables, now 64k aligned for smokie... lump = W_GetNumForName(colormap); if (lump == LUMPERROR) - lump = W_GetNumForName("COLORMAP"); + lump = basecolormaplump; else { - if (W_LumpLength(lump) != W_LumpLength(W_GetNumForName("COLORMAP"))) + if (W_LumpLength(lump) != W_LumpLength(basecolormaplump)) { - CONS_Alert(CONS_WARNING, "%s lump size does not match COLORMAP, using COLORMAP instead.\n", colormap); - lump = W_GetNumForName("COLORMAP"); + CONS_Alert(CONS_WARNING, "%s lump size does not match COLORMAP, results may be unexpected.\n", colormap); } } - W_ReadLump(lump, colormaps); + W_ReadLumpHeader(lump, colormaps, W_LumpLength(basecolormaplump), 0U); // Init Boom colormaps. R_ClearColormaps(); From d9ca8b45d316d3573201604ef506bcea8abf055a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 3 Mar 2019 22:09:34 +0000 Subject: [PATCH 14/15] Saving work so far, UNTESTED # Conflicts: # src/r_data.c --- src/r_data.c | 63 +++++++++++++++++++++++++++++++++++----------------- src/w_wad.c | 16 +++++++++++++ src/w_wad.h | 1 + 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index a21ba49ae..f9088a8d5 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -404,16 +404,7 @@ 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++) { - if (wadfiles[w]->type == RET_PK3) - { - texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); - texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); - } - else - { - texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; - texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); - } + // Count the textures from TEXTURES lumps texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); while (texturesLumpPos != INT16_MAX) @@ -422,19 +413,43 @@ void R_LoadTextures(void) texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); } - // Add all the textures between TX_START and TX_END - if (texstart != INT16_MAX && texend != INT16_MAX) + // Count single-patch textures + + if (wadfiles[w]->type == RET_PK3) + { + texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); + texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); + } + else + { + texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0); + texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); + } + + if (texstart == INT16_MAX || texend == INT16_MAX) + continue; + + 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) + { + for (j = texstart; j < texend; j++) + { + if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it + numtextures++; + } + } + else // Add all the textures between TX_START and TX_END { numtextures += (UINT32)(texend - texstart); } - - // If no textures found by this point, bomb out - if (!numtextures && w == (numwadfiles - 1)) - { - I_Error("No textures detected in any WADs!\n"); - } } + // 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); // Then, check the lump directly to see if it's a texture SOC, @@ -520,6 +542,7 @@ void R_LoadTextures(void) texturewidthmask[i] = k - 1; textureheight[i] = texture->height << FRACBITS; } + i++; } } } diff --git a/src/w_wad.c b/src/w_wad.c index 8d96449f1..9c8fccc6e 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1153,6 +1153,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 e2e17740f..87566c3ee 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 From 826e8e1aaf3d84ef96a8bb76ee640f13a01918bc Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 23 Jun 2019 17:07:20 +0100 Subject: [PATCH 15/15] Fixed goofups I missed back 3 months ago --- src/w_wad.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 9c8fccc6e..e06337810 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1157,13 +1157,13 @@ boolean W_IsLumpWad(lumpnum_t lumpnum) // W_IsLumpFolder // Is the lump a folder? (in a PK3 obviously) // -boolean W_IsLumpFolder(UINT16 wad, UINT16 lump); +boolean W_IsLumpFolder(UINT16 wad, UINT16 lump) { if (wadfiles[wad]->type == RET_PK3) { - const char *name = wadfiles[wad]->lumpinfo[lump]->name2; + const char *name = wadfiles[wad]->lumpinfo[lump].name2; - return (name[strlen(name)-1] == '/') // folders end in '/' + return (name[strlen(name)-1] == '/'); // folders end in '/' } return false; // non-PK3s don't have folders