From 8cd636c2135f65fa1ab4fecae380b4610ef55273 Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 14 Feb 2025 21:22:42 +0100 Subject: [PATCH 01/18] precache level flats and textures on mapload in opengl not entirely sure if this works correctly with encore, have to test a little TODO: move this into hwr file or smth --- src/r_data.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/r_data.c b/src/r_data.c index 98431510d..59698fff7 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1618,6 +1618,79 @@ INT32 R_TextureNumForName(const char *name) return i; } +static size_t P_PrecacheHWRLevelFlats(void) +{ + lumpnum_t lump; + size_t i, flatmem = 0; + + //SoM: 4/18/2000: New flat code to make use of levelflats. + for (i = 0; i < numlevelflats; i++) + { + lump = levelflats[i].lumpnum; + if (devparm) + flatmem += W_LumpLength(lump); + HWR_GetFlat(lump, false); + } + + return flatmem; +} + +static void HWR_PrecacheLevel(void) +{ + char *texturepresent; + size_t j; + + if (demo.playback) + return; + + // do not flush the memory, Z_Malloc twice with same user will cause error in Z_CheckHeap() + if (rendermode != render_opengl) + return; + + // Precache flats. + flatmemory = P_PrecacheHWRLevelFlats(); + + // + // Precache textures. + // + // no need to precache all software textures in 3D mode + // (note they are still used with the reference software view) + texturepresent = calloc(numtextures, sizeof (*texturepresent)); + if (texturepresent == NULL) I_Error("%s: Out of memory looking up textures", "R_PrecacheLevel"); + + for (j = 0; j < numsides; j++) + { + // huh, a potential bug here???? + if (sides[j].toptexture >= 0 && sides[j].toptexture < numtextures) + texturepresent[sides[j].toptexture] = 1; + if (sides[j].midtexture >= 0 && sides[j].midtexture < numtextures) + texturepresent[sides[j].midtexture] = 1; + if (sides[j].bottomtexture >= 0 && sides[j].bottomtexture < numtextures) + texturepresent[sides[j].bottomtexture] = 1; + } + + // Sky texture is always present. + // Note that F_SKY1 is the name used to indicate a sky floor/ceiling as a flat, + // while the sky texture is stored like a wall texture, with a skynum dependent name. + texturepresent[skytexture] = 1; + + texturememory = 0; + for (j = 0; j < (unsigned)numtextures; j++) + { + if (!texturepresent[j]) + continue; + + HWR_GetTexture(j, false); + } + free(texturepresent); + + //TODO: precache sprites too + + CONS_Debug(DBG_SETUP, "Precache level done:\n" + "flatmemory: %s k\n" + "texturememory: %s k\n", sizeu1(flatmemory>>10), sizeu2(texturememory>>10)); +} + // // R_PrecacheLevel // @@ -1635,6 +1708,12 @@ void R_PrecacheLevel(void) if (demo.playback) return; + if (rendermode == render_opengl) + { + HWR_PrecacheLevel(); + return; + } + // do not flush the memory, Z_Malloc twice with same user will cause error in Z_CheckHeap() if (rendermode != render_soft) return; -- 2.54.0 From 19dd5ddbaef04f84ebd7be895edf17de490c5cb1 Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 14 Feb 2025 21:31:22 +0100 Subject: [PATCH 02/18] disable ogl precaching on encore mode noencore things need to be handled for now just disable it until i figure out how to check for lineflags here --- src/r_data.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/r_data.c b/src/r_data.c index 59698fff7..997c4c4d8 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1647,6 +1647,11 @@ static void HWR_PrecacheLevel(void) if (rendermode != render_opengl) return; + // TODO: handle encoremode + // lines flagged with ML_TFERLINE should not be remapped, not sure how to properly check for that + if (encoremode) + return; + // Precache flats. flatmemory = P_PrecacheHWRLevelFlats(); -- 2.54.0 From 9bed58a8634c7e08eaa152a7284c62847a032172 Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 14 Feb 2025 21:57:57 +0100 Subject: [PATCH 03/18] this is incorrect, dont need it anyways --- src/r_data.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index 997c4c4d8..8028bd198 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1618,21 +1618,17 @@ INT32 R_TextureNumForName(const char *name) return i; } -static size_t P_PrecacheHWRLevelFlats(void) +static void P_PrecacheHWRLevelFlats(void) { lumpnum_t lump; - size_t i, flatmem = 0; + size_t i; //SoM: 4/18/2000: New flat code to make use of levelflats. for (i = 0; i < numlevelflats; i++) { lump = levelflats[i].lumpnum; - if (devparm) - flatmem += W_LumpLength(lump); HWR_GetFlat(lump, false); } - - return flatmem; } static void HWR_PrecacheLevel(void) @@ -1653,7 +1649,7 @@ static void HWR_PrecacheLevel(void) return; // Precache flats. - flatmemory = P_PrecacheHWRLevelFlats(); + P_PrecacheHWRLevelFlats(); // // Precache textures. @@ -1679,7 +1675,6 @@ static void HWR_PrecacheLevel(void) // while the sky texture is stored like a wall texture, with a skynum dependent name. texturepresent[skytexture] = 1; - texturememory = 0; for (j = 0; j < (unsigned)numtextures; j++) { if (!texturepresent[j]) @@ -1690,10 +1685,6 @@ static void HWR_PrecacheLevel(void) free(texturepresent); //TODO: precache sprites too - - CONS_Debug(DBG_SETUP, "Precache level done:\n" - "flatmemory: %s k\n" - "texturememory: %s k\n", sizeu1(flatmemory>>10), sizeu2(texturememory>>10)); } // -- 2.54.0 From 15a0b9ab930e0c9ac39860a98ce174d6db3e3523 Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 14 Feb 2025 22:57:25 +0100 Subject: [PATCH 04/18] handle encore in ogl precaching thx indev for help <3 --- src/r_data.c | 82 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index 8028bd198..99ec720d2 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1621,53 +1621,73 @@ INT32 R_TextureNumForName(const char *name) static void P_PrecacheHWRLevelFlats(void) { lumpnum_t lump; - size_t i; + size_t i, j; - //SoM: 4/18/2000: New flat code to make use of levelflats. - for (i = 0; i < numlevelflats; i++) + // special case for encore remapping + if (encoremode) { - lump = levelflats[i].lumpnum; - HWR_GetFlat(lump, false); + // this does not account for fofs and polyobjects + // TODO: handle atleast fofs + for (i = 0; i < numsectors; i++) + { + for (j = 0; j < 2; j++) + { + boolean ceiling = (j == 1); + INT32 pic = ceiling ? sectors[i].ceilingpic : sectors[i].floorpic; + + lump = levelflats[pic].lumpnum; + HWR_GetFlat(lump, R_NoEncore(§ors[i], ceiling)); + } + } + } + else + { + // on non encore we have it simple + // just load every flat + for (i = 0; i < numlevelflats; i++) + { + lump = levelflats[i].lumpnum; + HWR_GetFlat(lump, false); + } } } static void HWR_PrecacheLevel(void) { char *texturepresent; - size_t j; + size_t i, j; - if (demo.playback) - return; - - // do not flush the memory, Z_Malloc twice with same user will cause error in Z_CheckHeap() if (rendermode != render_opengl) return; - // TODO: handle encoremode - // lines flagged with ML_TFERLINE should not be remapped, not sure how to properly check for that - if (encoremode) - return; - // Precache flats. P_PrecacheHWRLevelFlats(); - // // Precache textures. - // - // no need to precache all software textures in 3D mode - // (note they are still used with the reference software view) texturepresent = calloc(numtextures, sizeof (*texturepresent)); - if (texturepresent == NULL) I_Error("%s: Out of memory looking up textures", "R_PrecacheLevel"); + if (texturepresent == NULL) I_Error("%s: Out of memory looking up textures", "HWR_PrecacheLevel"); - for (j = 0; j < numsides; j++) + for (i = 0; i < numlines; i++) { - // huh, a potential bug here???? - if (sides[j].toptexture >= 0 && sides[j].toptexture < numtextures) - texturepresent[sides[j].toptexture] = 1; - if (sides[j].midtexture >= 0 && sides[j].midtexture < numtextures) - texturepresent[sides[j].midtexture] = 1; - if (sides[j].bottomtexture >= 0 && sides[j].bottomtexture < numtextures) - texturepresent[sides[j].bottomtexture] = 1; + line_t *line = &lines[i]; + boolean noencoremap = (line->flags & ML_TFERLINE); + + // two sides + for (j = 0; j < 2; j++) + { + side_t *side = &sides[line->sidenum[j]]; + + // Single-side linedef + if (line->sidenum[j] == 0xffff) + continue; + + if (side->toptexture >= 0 && side->toptexture < numtextures) + texturepresent[side->toptexture] = noencoremap ? 2 : 1; + if (side->midtexture >= 0 && side->midtexture < numtextures) + texturepresent[side->midtexture] = noencoremap ? 2 : 1; + if (side->bottomtexture >= 0 && side->bottomtexture < numtextures) + texturepresent[side->bottomtexture] = noencoremap ? 2 : 1; + } } // Sky texture is always present. @@ -1675,12 +1695,12 @@ static void HWR_PrecacheLevel(void) // while the sky texture is stored like a wall texture, with a skynum dependent name. texturepresent[skytexture] = 1; - for (j = 0; j < (unsigned)numtextures; j++) + for (i = 0; i < (unsigned)numtextures; i++) { - if (!texturepresent[j]) + if (!texturepresent[i]) continue; - HWR_GetTexture(j, false); + HWR_GetTexture(i, (texturepresent[i] == 2)); } free(texturepresent); -- 2.54.0 From a75bf1b2bb220ff998a684d402c9035c2d885d75 Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 14 Feb 2025 23:02:13 +0100 Subject: [PATCH 05/18] move precache into hw_cache.c --- src/hardware/hw_cache.c | 91 +++++++++++++++++++++++++++++++++++++++++ src/hardware/hw_glob.h | 5 ++- src/r_data.c | 91 +---------------------------------------- 3 files changed, 97 insertions(+), 90 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index af06ecba6..7ac8aa631 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -29,6 +29,8 @@ #include "../r_draw.h" #include "../r_main.h" #include "../r_patch.h" // patch rotation +#include "../p_setup.h" // levelflats +#include "../r_sky.h" INT32 patchformat = GL_TEXFMT_AP_88; // use alpha for holes INT32 textureformat = GL_TEXFMT_P_8; // use chromakey for hole @@ -546,6 +548,95 @@ void HWR_FreeTextureCache(void) gl_numtextures = 0; } +static void P_PrecacheHWRLevelFlats(void) +{ + lumpnum_t lump; + size_t i, j; + + // special case for encore remapping + if (encoremode) + { + // this does not account for fofs and polyobjects + // TODO: handle atleast fofs + for (i = 0; i < numsectors; i++) + { + for (j = 0; j < 2; j++) + { + boolean ceiling = (j == 1); + INT32 pic = ceiling ? sectors[i].ceilingpic : sectors[i].floorpic; + + lump = levelflats[pic].lumpnum; + HWR_GetFlat(lump, R_NoEncore(§ors[i], ceiling)); + } + } + } + else + { + // on non encore we have it simple + // just load every flat + for (i = 0; i < numlevelflats; i++) + { + lump = levelflats[i].lumpnum; + HWR_GetFlat(lump, false); + } + } +} + +void HWR_PrecacheLevel(void) +{ + char *texturepresent; + size_t i, j; + + if (rendermode != render_opengl) + return; + + // Precache flats. + P_PrecacheHWRLevelFlats(); + + // Precache textures. + texturepresent = calloc(numtextures, sizeof (*texturepresent)); + if (texturepresent == NULL) I_Error("%s: Out of memory looking up textures", "HWR_PrecacheLevel"); + + for (i = 0; i < numlines; i++) + { + line_t *line = &lines[i]; + boolean noencoremap = (line->flags & ML_TFERLINE); + + // two sides + for (j = 0; j < 2; j++) + { + side_t *side = &sides[line->sidenum[j]]; + + // Single-side linedef + if (line->sidenum[j] == 0xffff) + continue; + + if (side->toptexture >= 0 && side->toptexture < numtextures) + texturepresent[side->toptexture] = noencoremap ? 2 : 1; + if (side->midtexture >= 0 && side->midtexture < numtextures) + texturepresent[side->midtexture] = noencoremap ? 2 : 1; + if (side->bottomtexture >= 0 && side->bottomtexture < numtextures) + texturepresent[side->bottomtexture] = noencoremap ? 2 : 1; + } + } + + // Sky texture is always present. + // Note that F_SKY1 is the name used to indicate a sky floor/ceiling as a flat, + // while the sky texture is stored like a wall texture, with a skynum dependent name. + texturepresent[skytexture] = 1; + + for (i = 0; i < (unsigned)numtextures; i++) + { + if (!texturepresent[i]) + continue; + + HWR_GetTexture(i, (texturepresent[i] == 2)); + } + free(texturepresent); + + //TODO: precache sprites too +} + void HWR_LoadTextures(size_t pnumtextures) { // we must free it since numtextures changed diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index fe346f4c9..edba8a025 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -49,13 +49,16 @@ typedef struct gl_vissprite_s extern extrasubsector_t *extrasubsectors; extern size_t addsubsector; +void HWR_FreeExtraSubsectors(void); + // -------- // hw_cache.c // -------- void HWR_InitTextureCache(void); void HWR_FreeTextureCache(void); void HWR_FreeMipmapCache(void); -void HWR_FreeExtraSubsectors(void); + +void HWR_PrecacheLevel(void); void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap); // ^ some flats must NOT be remapped to encore, since we remap them as we cache them for ease, adding a toggle here seems wise. diff --git a/src/r_data.c b/src/r_data.c index 99ec720d2..48678863e 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1618,95 +1618,6 @@ INT32 R_TextureNumForName(const char *name) return i; } -static void P_PrecacheHWRLevelFlats(void) -{ - lumpnum_t lump; - size_t i, j; - - // special case for encore remapping - if (encoremode) - { - // this does not account for fofs and polyobjects - // TODO: handle atleast fofs - for (i = 0; i < numsectors; i++) - { - for (j = 0; j < 2; j++) - { - boolean ceiling = (j == 1); - INT32 pic = ceiling ? sectors[i].ceilingpic : sectors[i].floorpic; - - lump = levelflats[pic].lumpnum; - HWR_GetFlat(lump, R_NoEncore(§ors[i], ceiling)); - } - } - } - else - { - // on non encore we have it simple - // just load every flat - for (i = 0; i < numlevelflats; i++) - { - lump = levelflats[i].lumpnum; - HWR_GetFlat(lump, false); - } - } -} - -static void HWR_PrecacheLevel(void) -{ - char *texturepresent; - size_t i, j; - - if (rendermode != render_opengl) - return; - - // Precache flats. - P_PrecacheHWRLevelFlats(); - - // Precache textures. - texturepresent = calloc(numtextures, sizeof (*texturepresent)); - if (texturepresent == NULL) I_Error("%s: Out of memory looking up textures", "HWR_PrecacheLevel"); - - for (i = 0; i < numlines; i++) - { - line_t *line = &lines[i]; - boolean noencoremap = (line->flags & ML_TFERLINE); - - // two sides - for (j = 0; j < 2; j++) - { - side_t *side = &sides[line->sidenum[j]]; - - // Single-side linedef - if (line->sidenum[j] == 0xffff) - continue; - - if (side->toptexture >= 0 && side->toptexture < numtextures) - texturepresent[side->toptexture] = noencoremap ? 2 : 1; - if (side->midtexture >= 0 && side->midtexture < numtextures) - texturepresent[side->midtexture] = noencoremap ? 2 : 1; - if (side->bottomtexture >= 0 && side->bottomtexture < numtextures) - texturepresent[side->bottomtexture] = noencoremap ? 2 : 1; - } - } - - // Sky texture is always present. - // Note that F_SKY1 is the name used to indicate a sky floor/ceiling as a flat, - // while the sky texture is stored like a wall texture, with a skynum dependent name. - texturepresent[skytexture] = 1; - - for (i = 0; i < (unsigned)numtextures; i++) - { - if (!texturepresent[i]) - continue; - - HWR_GetTexture(i, (texturepresent[i] == 2)); - } - free(texturepresent); - - //TODO: precache sprites too -} - // // R_PrecacheLevel // @@ -1724,11 +1635,13 @@ void R_PrecacheLevel(void) if (demo.playback) return; +#ifdef HWRENDER if (rendermode == render_opengl) { HWR_PrecacheLevel(); return; } +#endif // do not flush the memory, Z_Malloc twice with same user will cause error in Z_CheckHeap() if (rendermode != render_soft) -- 2.54.0 From ccefafd172a77c5f60f9c5ddb0f4a9299d1528bc Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 14 Feb 2025 23:24:58 +0100 Subject: [PATCH 06/18] load both encore and non encore tex --- src/hardware/hw_cache.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 7ac8aa631..d11a5c5e0 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -612,11 +612,20 @@ void HWR_PrecacheLevel(void) continue; if (side->toptexture >= 0 && side->toptexture < numtextures) - texturepresent[side->toptexture] = noencoremap ? 2 : 1; + { + texturepresent[side->toptexture] = 1; + texturepresent[side->toptexture] |= noencoremap ? 2 : 1; + } if (side->midtexture >= 0 && side->midtexture < numtextures) - texturepresent[side->midtexture] = noencoremap ? 2 : 1; + { + texturepresent[side->midtexture] = 1; + texturepresent[side->midtexture] |= noencoremap ? 2 : 1; + } if (side->bottomtexture >= 0 && side->bottomtexture < numtextures) - texturepresent[side->bottomtexture] = noencoremap ? 2 : 1; + { + texturepresent[side->bottomtexture] = 1; + texturepresent[side->bottomtexture] |= noencoremap ? 2 : 1; + } } } @@ -630,7 +639,11 @@ void HWR_PrecacheLevel(void) if (!texturepresent[i]) continue; - HWR_GetTexture(i, (texturepresent[i] == 2)); + if (texturepresent[j] & 1) + HWR_GetTexture(j, false); + + if (texturepresent[j] & 2) + HWR_GetTexture(j, true); } free(texturepresent); -- 2.54.0 From 119b18521f4a6ffbc9ca567e4085f14156c3f9ac Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 15 Feb 2025 00:35:34 +0100 Subject: [PATCH 07/18] oops should be i --- src/hardware/hw_cache.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index d11a5c5e0..9a7357c0c 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -639,11 +639,11 @@ void HWR_PrecacheLevel(void) if (!texturepresent[i]) continue; - if (texturepresent[j] & 1) - HWR_GetTexture(j, false); + if (texturepresent[i] & 1) + HWR_GetTexture(i, false); - if (texturepresent[j] & 2) - HWR_GetTexture(j, true); + if (texturepresent[i] & 2) + HWR_GetTexture(i, true); } free(texturepresent); -- 2.54.0 From 4417eabdc740d6a644e1d2266af6f546ca2de572 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 15 Feb 2025 01:05:44 +0100 Subject: [PATCH 08/18] move texture precache into own function unnesting stuff --- src/hardware/hw_cache.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 9a7357c0c..be6a7056e 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -548,7 +548,7 @@ void HWR_FreeTextureCache(void) gl_numtextures = 0; } -static void P_PrecacheHWRLevelFlats(void) +static void HWR_PrecacheLevelFlats(void) { lumpnum_t lump; size_t i, j; @@ -582,18 +582,11 @@ static void P_PrecacheHWRLevelFlats(void) } } -void HWR_PrecacheLevel(void) +static void HWR_PrecacheLevelTextures(void) { char *texturepresent; size_t i, j; - if (rendermode != render_opengl) - return; - - // Precache flats. - P_PrecacheHWRLevelFlats(); - - // Precache textures. texturepresent = calloc(numtextures, sizeof (*texturepresent)); if (texturepresent == NULL) I_Error("%s: Out of memory looking up textures", "HWR_PrecacheLevel"); @@ -646,6 +639,18 @@ void HWR_PrecacheLevel(void) HWR_GetTexture(i, true); } free(texturepresent); +} + +void HWR_PrecacheLevel(void) +{ + if (rendermode != render_opengl) + return; + + // Precache flats. + HWR_PrecacheLevelFlats(); + + // Precache textures. + HWR_PrecacheLevelTextures(); //TODO: precache sprites too } -- 2.54.0 From 7808dc57407af130dc27f44dd72c7c644d2db5a9 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 15 Feb 2025 02:07:50 +0100 Subject: [PATCH 09/18] precache (most) sprites on ogl leveload --- src/hardware/hw_cache.c | 50 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index be6a7056e..186b00c6d 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -641,6 +641,53 @@ static void HWR_PrecacheLevelTextures(void) free(texturepresent); } +static void HWR_PrecacheLevelSprites(void) +{ + char *spritepresent; + size_t i, j, k; + lumpnum_t lump; + + thinker_t *th; + mobj_t *mo; + spriteframe_t *sf; + + spritepresent = calloc(numsprites, sizeof (*spritepresent)); + if (spritepresent == NULL) I_Error("%s: Out of memory looking up sprites", "HWR_PrecacheLevel"); + + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + mo = (mobj_t *)th; + + //FIXME: cant really precache colorized sprites without a colormap + if (mo->color || mo->colorized) + continue; + + spritepresent[mo->sprite] = 1; + } + + for (i = 0; i < numsprites; i++) + { + if (!spritepresent[i]) + continue; + + for (j = 0; j < sprites[i].numframes; j++) + { + sf = &sprites[i].spriteframes[j]; + for (k = 0; k < 8; k++) + { + // see R_InitSprites for more about lumppat,lumpid + lump = sf->lumppat[k]; + + HWR_GetMappedPatch((GLPatch_t *)W_CachePatchNum(lump, PU_CACHE), NULL); + } + } + } + free(spritepresent); +} + void HWR_PrecacheLevel(void) { if (rendermode != render_opengl) @@ -652,7 +699,8 @@ void HWR_PrecacheLevel(void) // Precache textures. HWR_PrecacheLevelTextures(); - //TODO: precache sprites too + // Precache sprites. + HWR_PrecacheLevelSprites(); } void HWR_LoadTextures(size_t pnumtextures) -- 2.54.0 From c1a187084d14371c4ab26c43aedaff054ed3b228 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 15 Feb 2025 02:15:04 +0100 Subject: [PATCH 10/18] dedicated server does not need to call texture precaching prob leftover from back in the day, it doesent do anything at all anyways also gives it a less ambigous name --- src/d_netcmd.c | 4 ++-- src/doomstat.h | 2 +- src/g_game.c | 2 +- src/p_setup.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 0168acc0e..0252e9916 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2969,7 +2969,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) } if (demo.playback && !demo.timing) - precache = false; + precachetextures = false; if (resetplayer) { @@ -2987,7 +2987,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) demo.savebutton = 0; G_InitNew(pencoremode, mapname, resetplayer, skipprecutscene); if (demo.playback && !demo.timing) - precache = true; + precachetextures = true; if (demo.timing) G_DoneLevelLoad(); diff --git a/src/doomstat.h b/src/doomstat.h index f70f97059..35527c581 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -542,7 +542,7 @@ extern INT32 debugload; #endif // if true, load all graphics at level load -extern boolean precache; +extern boolean precachetextures; // wipegamestate can be set to -1 // to force a wipe on the next draw diff --git a/src/g_game.c b/src/g_game.c index 86be0e159..6944565a3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -330,7 +330,7 @@ static struct { // There is no conflict here. demoghost *ghosts = NULL; -boolean precache = true; // if true, load all graphics at start +boolean precachetextures = true; // if true, load all graphics at start INT16 prevmap, nextmap; diff --git a/src/p_setup.c b/src/p_setup.c index 633c4094e..ff4b5384d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2970,7 +2970,7 @@ boolean P_SetupLevel(boolean skipprecip, boolean reloadinggamestate) if (rendermode != render_none && !reloadinggamestate) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); - if (precache || dedicated) + if (precachetextures) R_PrecacheLevel(); nextmapoverride = 0; -- 2.54.0 From a403d96204e2f292c34871487c88ce01474044cf Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 15 Feb 2025 14:27:52 +0100 Subject: [PATCH 11/18] also precache animated flats i have no clue how tf animated textures work --- src/hardware/hw_cache.c | 34 +++++++++++++++++++++++++++++----- src/p_setup.c | 2 ++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 186b00c6d..5a7cd8b33 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -550,14 +550,14 @@ void HWR_FreeTextureCache(void) static void HWR_PrecacheLevelFlats(void) { + levelflat_t levelflat; lumpnum_t lump; size_t i, j; + INT32 k; // special case for encore remapping if (encoremode) { - // this does not account for fofs and polyobjects - // TODO: handle atleast fofs for (i = 0; i < numsectors; i++) { for (j = 0; j < 2; j++) @@ -565,8 +565,20 @@ static void HWR_PrecacheLevelFlats(void) boolean ceiling = (j == 1); INT32 pic = ceiling ? sectors[i].ceilingpic : sectors[i].floorpic; - lump = levelflats[pic].lumpnum; + levelflat = levelflats[pic]; + + lump = levelflat.lumpnum; HWR_GetFlat(lump, R_NoEncore(§ors[i], ceiling)); + + if (levelflat.speed) // it is an animated flat + { + for (k = 0; k < levelflat.numpics; k++) + { + levelflat.lumpnum = levelflat.baselumpnum + k; + lump = levelflat.lumpnum; + HWR_GetFlat(lump, R_NoEncore(§ors[i], ceiling)); + } + } } } } @@ -576,8 +588,20 @@ static void HWR_PrecacheLevelFlats(void) // just load every flat for (i = 0; i < numlevelflats; i++) { - lump = levelflats[i].lumpnum; + levelflat = levelflats[i]; + lump = levelflat.lumpnum; + HWR_GetFlat(lump, false); + + if (levelflat.speed) // it is an animated flat + { + for (k = 0; k < levelflat.numpics; k++) + { + levelflat.lumpnum = levelflat.baselumpnum + k; + lump = levelflat.lumpnum; + HWR_GetFlat(lump, false); + } + } } } } @@ -661,7 +685,7 @@ static void HWR_PrecacheLevelSprites(void) mo = (mobj_t *)th; - //FIXME: cant really precache colorized sprites without a colormap + // ogl is weird if (mo->color || mo->colorized) continue; diff --git a/src/p_setup.c b/src/p_setup.c index ff4b5384d..92abf44b6 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -624,6 +624,7 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat) // store the flat lump number levelflat->lumpnum = R_GetFlatNumForName(flatname); + levelflat->baselumpnum = LUMPERROR; #ifndef ZDEBUG CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); @@ -668,6 +669,7 @@ INT32 P_AddLevelFlatRuntime(const char *flatname) // store the flat lump number levelflat->lumpnum = R_GetFlatNumForName(flatname); + levelflat->baselumpnum = LUMPERROR; #ifndef ZDEBUG CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); -- 2.54.0 From 29b93f63f7afdb625fb28047ef2b7f7b50fba8f7 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 15 Feb 2025 16:22:16 +0100 Subject: [PATCH 12/18] precache animated textures too --- src/hardware/hw_cache.c | 32 ++++++++++++++++++++++++++++++++ src/p_spec.c | 17 ++--------------- src/p_spec.h | 16 ++++++++++++++++ 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 5a7cd8b33..991032ac5 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -30,6 +30,7 @@ #include "../r_main.h" #include "../r_patch.h" // patch rotation #include "../p_setup.h" // levelflats +#include "../p_spec.h" // anim_t #include "../r_sky.h" INT32 patchformat = GL_TEXFMT_AP_88; // use alpha for holes @@ -610,6 +611,8 @@ static void HWR_PrecacheLevelTextures(void) { char *texturepresent; size_t i, j; + INT32 h; + anim_t *anim; texturepresent = calloc(numtextures, sizeof (*texturepresent)); if (texturepresent == NULL) I_Error("%s: Out of memory looking up textures", "HWR_PrecacheLevel"); @@ -646,6 +649,31 @@ static void HWR_PrecacheLevelTextures(void) } } + for (anim = anims; anim < lastanim; anim++) + { + if (!anim->istexture) + continue; + + if (!texturepresent[anim->basepic]) + continue; + + if (texturepresent[anim->basepic] & 1) + { + for (h = 0; h < anim->numpics; h++) + { + HWR_GetTexture(anim->basepic+h, false); + } + } + + if (texturepresent[anim->basepic] & 2) + { + for (h = 0; h < anim->numpics; h++) + { + HWR_GetTexture(anim->basepic+h, true); + } + } + } + // Sky texture is always present. // Note that F_SKY1 is the name used to indicate a sky floor/ceiling as a flat, // while the sky texture is stored like a wall texture, with a skynum dependent name. @@ -657,10 +685,14 @@ static void HWR_PrecacheLevelTextures(void) continue; if (texturepresent[i] & 1) + { HWR_GetTexture(i, false); + } if (texturepresent[i] & 2) + { HWR_GetTexture(i, true); + } } free(texturepresent); } diff --git a/src/p_spec.c b/src/p_spec.c index 3f9dfd626..4eb380df0 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -51,19 +51,6 @@ mobj_t *skyboxmo[2]; // This must be updated whenever we up the max flat size - quicker to assume rather than figuring out the sqrt of the specific flat's filesize. #define MAXFLATSIZE (2048<> ((j-1)*4))&15) +/** Animated texture descriptor + * This keeps track of an animated texture or an animated flat. + * \sa P_UpdateSpecials, P_InitPicAnims, animdef_t + */ +typedef struct +{ + SINT8 istexture; ///< ::true for a texture, ::false for a flat + INT32 picnum; ///< The end flat number + INT32 basepic; ///< The start flat number + INT32 numpics; ///< Number of frames in the animation + tic_t speed; ///< Number of tics for which each frame is shown +} anim_t; + +extern anim_t *lastanim; +extern anim_t *anims; + // at game start void P_InitPicAnims(void); -- 2.54.0 From 4ef6c2ea349d8fbdc0aa98972f8860a0ae68d4ee Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 16 Feb 2025 15:33:58 +0100 Subject: [PATCH 13/18] guard this in sprite precache --- src/hardware/hw_cache.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 991032ac5..48af24ca9 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -699,6 +699,7 @@ static void HWR_PrecacheLevelTextures(void) static void HWR_PrecacheLevelSprites(void) { + GLPatch_t *spritepatch; char *spritepresent; size_t i, j, k; lumpnum_t lump; @@ -718,6 +719,8 @@ static void HWR_PrecacheLevelSprites(void) mo = (mobj_t *)th; // ogl is weird + // for some reason it does not want to preload sprites with colormaps + // so just save us the work if (mo->color || mo->colorized) continue; @@ -732,12 +735,16 @@ static void HWR_PrecacheLevelSprites(void) for (j = 0; j < sprites[i].numframes; j++) { sf = &sprites[i].spriteframes[j]; + for (k = 0; k < 8; k++) { // see R_InitSprites for more about lumppat,lumpid lump = sf->lumppat[k]; + spritepatch = (GLPatch_t *)W_CachePatchNum(lump, PU_CACHE); - HWR_GetMappedPatch((GLPatch_t *)W_CachePatchNum(lump, PU_CACHE), NULL); + // yes this may be NULL + if (spritepatch != NULL) + HWR_GetPatch(spritepatch); // no colormapped sprites for us } } } -- 2.54.0 From 83b242a727d2e8c9cd3c96caee24d5c4493b33de Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 16 Feb 2025 15:34:54 +0100 Subject: [PATCH 14/18] make texture precache toggable --- src/d_netcmd.c | 6 +----- src/doomstat.h | 3 --- src/g_game.c | 2 -- src/p_setup.c | 2 +- src/r_data.c | 8 ++++---- src/r_main.c | 5 +++++ src/r_main.h | 1 + 7 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 0252e9916..df5670f7c 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2968,9 +2968,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) CON_LogMessage(M_GetText("Speeding off to level...\n")); } - if (demo.playback && !demo.timing) - precachetextures = false; - if (resetplayer) { if (!FLS || (netgame || multiplayer)) @@ -2986,8 +2983,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) demo.savemode = (cv_recordmultiplayerdemos.value == 2) ? DSM_WILLAUTOSAVE : DSM_NOTSAVING; demo.savebutton = 0; G_InitNew(pencoremode, mapname, resetplayer, skipprecutscene); - if (demo.playback && !demo.timing) - precachetextures = true; + if (demo.timing) G_DoneLevelLoad(); diff --git a/src/doomstat.h b/src/doomstat.h index 35527c581..1d487d2f4 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -541,9 +541,6 @@ extern FILE *debugfile; extern INT32 debugload; #endif -// if true, load all graphics at level load -extern boolean precachetextures; - // wipegamestate can be set to -1 // to force a wipe on the next draw extern gamestate_t wipegamestate; diff --git a/src/g_game.c b/src/g_game.c index 6944565a3..9b52b8680 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -330,8 +330,6 @@ static struct { // There is no conflict here. demoghost *ghosts = NULL; -boolean precachetextures = true; // if true, load all graphics at start - INT16 prevmap, nextmap; // save if director is enabled diff --git a/src/p_setup.c b/src/p_setup.c index 92abf44b6..404b0236d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2972,7 +2972,7 @@ boolean P_SetupLevel(boolean skipprecip, boolean reloadinggamestate) if (rendermode != render_none && !reloadinggamestate) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); - if (precachetextures) + if (cv_precachetextures.value) R_PrecacheLevel(); nextmapoverride = 0; diff --git a/src/r_data.c b/src/r_data.c index 48678863e..cc832f8c9 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1632,6 +1632,10 @@ void R_PrecacheLevel(void) thinker_t *th; spriteframe_t *sf; + // do not flush the memory, Z_Malloc twice with same user will cause error in Z_CheckHeap() + if (rendermode == render_none) + return; + if (demo.playback) return; @@ -1643,10 +1647,6 @@ void R_PrecacheLevel(void) } #endif - // do not flush the memory, Z_Malloc twice with same user will cause error in Z_CheckHeap() - if (rendermode != render_soft) - return; - // Precache flats. flatmemory = P_PrecacheLevelFlats(); diff --git a/src/r_main.c b/src/r_main.c index ba60d2553..b39b58749 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -164,6 +164,9 @@ static void Precipstuff_OnChange(void); consvar_t cv_tailspickup = {"tailspickup", "On", CV_NETVAR|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +// if enabled, load all graphics at level load +consvar_t cv_precachetextures = {"precachetextures", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + consvar_t cv_chasecam[MAXSPLITSCREENPLAYERS] = { {"chasecam", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, {"chasecam2", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, @@ -1532,6 +1535,8 @@ void R_RegisterEngineStuff(void) if (dedicated) return; + CV_RegisterVar(&cv_precachetextures); + CV_RegisterVar(&cv_translucency); CV_RegisterVar(&cv_drawdist); CV_RegisterVar(&cv_drawdist_precip); diff --git a/src/r_main.h b/src/r_main.h index 9a976d659..1b8d8c71c 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -174,6 +174,7 @@ extern ps_metric_t ps_numpolyobjects; // REFRESH - the actual rendering functions. // +extern consvar_t cv_precachetextures; extern consvar_t cv_showhud, cv_translucenthud, cv_uncappedhud; extern consvar_t cv_homremoval; extern consvar_t cv_chasecam[MAXSPLITSCREENPLAYERS]; -- 2.54.0 From 255c8437d7f9d0981b31e9bf4d7449dacbc8e9e8 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 16 Feb 2025 15:37:18 +0100 Subject: [PATCH 15/18] slightly optimize ogl precaching cleanup too --- src/hardware/hw_cache.c | 72 ++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 48af24ca9..dbf97a159 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -556,37 +556,42 @@ static void HWR_PrecacheLevelFlats(void) size_t i, j; INT32 k; - // special case for encore remapping + // special case for encore +#ifdef GLENCORE if (encoremode) { + // go through all sectors to determine if it should be remapped for encore for (i = 0; i < numsectors; i++) { + sector_t *sec = §ors[i]; + + // gotta check sector floor and ceiling for (j = 0; j < 2; j++) { - boolean ceiling = (j == 1); - INT32 pic = ceiling ? sectors[i].ceilingpic : sectors[i].floorpic; + const boolean ceiling = (j == 1); + INT32 pic = ceiling ? sec->ceilingpic : sec->floorpic; levelflat = levelflats[pic]; lump = levelflat.lumpnum; - HWR_GetFlat(lump, R_NoEncore(§ors[i], ceiling)); + HWR_GetFlat(lump, R_NoEncore(sec, ceiling)); if (levelflat.speed) // it is an animated flat { - for (k = 0; k < levelflat.numpics; k++) + for (k = 1; k < levelflat.numpics; k++) { - levelflat.lumpnum = levelflat.baselumpnum + k; - lump = levelflat.lumpnum; - HWR_GetFlat(lump, R_NoEncore(§ors[i], ceiling)); + lump = levelflat.baselumpnum + k; + HWR_GetFlat(lump, R_NoEncore(sec, ceiling)); } } } } } else +#endif { // on non encore we have it simple - // just load every flat + // just load every flat in the level for (i = 0; i < numlevelflats; i++) { levelflat = levelflats[i]; @@ -596,10 +601,9 @@ static void HWR_PrecacheLevelFlats(void) if (levelflat.speed) // it is an animated flat { - for (k = 0; k < levelflat.numpics; k++) + for (k = 1; k < levelflat.numpics; k++) { - levelflat.lumpnum = levelflat.baselumpnum + k; - lump = levelflat.lumpnum; + lump = levelflat.baselumpnum + k; HWR_GetFlat(lump, false); } } @@ -610,9 +614,9 @@ static void HWR_PrecacheLevelFlats(void) static void HWR_PrecacheLevelTextures(void) { char *texturepresent; + anim_t *anim; size_t i, j; INT32 h; - anim_t *anim; texturepresent = calloc(numtextures, sizeof (*texturepresent)); if (texturepresent == NULL) I_Error("%s: Out of memory looking up textures", "HWR_PrecacheLevel"); @@ -620,7 +624,11 @@ static void HWR_PrecacheLevelTextures(void) for (i = 0; i < numlines; i++) { line_t *line = &lines[i]; - boolean noencoremap = (line->flags & ML_TFERLINE); +#ifdef GLENCORE + const int noencoremap = ((line->flags & ML_TFERLINE) ? 2 : 1); +#else + const int noencoremap = 1; +#endif // two sides for (j = 0; j < 2; j++) @@ -633,45 +641,46 @@ static void HWR_PrecacheLevelTextures(void) if (side->toptexture >= 0 && side->toptexture < numtextures) { - texturepresent[side->toptexture] = 1; - texturepresent[side->toptexture] |= noencoremap ? 2 : 1; + texturepresent[side->toptexture] = 1|noencoremap; } if (side->midtexture >= 0 && side->midtexture < numtextures) { - texturepresent[side->midtexture] = 1; - texturepresent[side->midtexture] |= noencoremap ? 2 : 1; + texturepresent[side->midtexture] = 1|noencoremap; } if (side->bottomtexture >= 0 && side->bottomtexture < numtextures) { - texturepresent[side->bottomtexture] = 1; - texturepresent[side->bottomtexture] |= noencoremap ? 2 : 1; + texturepresent[side->bottomtexture] = 1|noencoremap; } } } + // check for animated textures for (anim = anims; anim < lastanim; anim++) { if (!anim->istexture) continue; - if (!texturepresent[anim->basepic]) + const char texpresent = texturepresent[anim->basepic]; + + if (!texpresent) continue; - if (texturepresent[anim->basepic] & 1) + if (texpresent & 1) { - for (h = 0; h < anim->numpics; h++) + for (h = 1; h < anim->numpics; h++) { HWR_GetTexture(anim->basepic+h, false); } } - - if (texturepresent[anim->basepic] & 2) +#ifdef GLENCORE + if (texpresent & 2) { - for (h = 0; h < anim->numpics; h++) + for (h = 1; h < anim->numpics; h++) { HWR_GetTexture(anim->basepic+h, true); } } +#endif } // Sky texture is always present. @@ -681,18 +690,21 @@ static void HWR_PrecacheLevelTextures(void) for (i = 0; i < (unsigned)numtextures; i++) { - if (!texturepresent[i]) + const char texpresent = texturepresent[i]; + + if (!texpresent) continue; - if (texturepresent[i] & 1) + if (texpresent & 1) { HWR_GetTexture(i, false); } - - if (texturepresent[i] & 2) +#ifdef GLENCORE + if (texpresent & 2) { HWR_GetTexture(i, true); } +#endif } free(texturepresent); } -- 2.54.0 From 5b0a662b406b376f34538205231d7833abb16f4b Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 16 Feb 2025 15:37:43 +0100 Subject: [PATCH 16/18] skip checking sectors and lines multiple times --- src/hardware/hw_cache.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index dbf97a159..6f8b98745 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -565,6 +565,12 @@ static void HWR_PrecacheLevelFlats(void) { sector_t *sec = §ors[i]; + // sector checked already? + if (sec->validcount == validcount) + continue; + + sec->validcount = validcount; + // gotta check sector floor and ceiling for (j = 0; j < 2; j++) { @@ -630,6 +636,12 @@ static void HWR_PrecacheLevelTextures(void) const int noencoremap = 1; #endif + // line checked already? + if (line->validcount == validcount) + continue; + + line->validcount = validcount; + // two sides for (j = 0; j < 2; j++) { -- 2.54.0 From fcd8cfc4d56bb88813e72e095825387788ccdc75 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 16 Feb 2025 16:38:42 +0100 Subject: [PATCH 17/18] better handling of sprite angles in precache only cache stuff that we need --- src/hardware/hw_cache.c | 31 ++++++++++++++++++++++--------- src/r_data.c | 36 ++++++++++++++++++++++++++++-------- 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 6f8b98745..eccf09af4 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -760,16 +760,29 @@ static void HWR_PrecacheLevelSprites(void) { sf = &sprites[i].spriteframes[j]; - for (k = 0; k < 8; k++) - { - // see R_InitSprites for more about lumppat,lumpid - lump = sf->lumppat[k]; - spritepatch = (GLPatch_t *)W_CachePatchNum(lump, PU_CACHE); - - // yes this may be NULL - if (spritepatch != NULL) - HWR_GetPatch(spritepatch); // no colormapped sprites for us +#define cacheang(a) {\ + lump = sf->lumppat[a];\ + spritepatch = (GLPatch_t *)W_CachePatchNum(lump, PU_CACHE);\ + if (spritepatch != NULL)\ + HWR_GetPatch(spritepatch);\ } + // see R_InitSprites for more about lumppat,lumpid + switch (sf->rotate) + { + case SRF_SINGLE: + cacheang(0); + break; + case SRF_2D: + cacheang(2); + cacheang(6); + break; + default: + k = 8; + while (k--) + cacheang(k); + break; + } +#undef cacheang } } free(spritepresent); diff --git a/src/r_data.c b/src/r_data.c index cc832f8c9..1ed4b34ee 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1694,8 +1694,12 @@ void R_PrecacheLevel(void) if (spritepresent == NULL) I_Error("%s: Out of memory looking up sprites", "R_PrecacheLevel"); for (th = thinkercap.next; th != &thinkercap; th = th->next) - if (th->function.acp1 == (actionf_p1)P_MobjThinker) - spritepresent[((mobj_t *)th)->sprite] = 1; + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + spritepresent[((mobj_t *)th)->sprite] = 1; + } spritememory = 0; for (i = 0; i < numsprites; i++) @@ -1706,16 +1710,32 @@ void R_PrecacheLevel(void) for (j = 0; j < sprites[i].numframes; j++) { sf = &sprites[i].spriteframes[j]; - for (k = 0; k < 8; k++) +#define cacheang(a) {\ + lump = sf->lumppat[a];\ + if (devparm)\ + spritememory += W_LumpLength(lump);\ + W_CachePatchNum(lump, PU_CACHE);\ + } + // see R_InitSprites for more about lumppat,lumpid + switch (sf->rotate) { - // see R_InitSprites for more about lumppat,lumpid - lump = sf->lumppat[k]; - if (devparm) - spritememory += W_LumpLength(lump); - W_CachePatchNum(lump, PU_CACHE); + case SRF_SINGLE: + cacheang(0); + break; + case SRF_2D: + cacheang(2); + cacheang(6); + break; + default: + k = 8; + while (k--) + cacheang(k); + break; } +#undef cacheang } } + free(spritepresent); // FIXME: this is no longer correct with OpenGL render mode -- 2.54.0 From 7bf50c69e229e788ef20251d3cd5a7f815382917 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 16 Feb 2025 16:47:06 +0100 Subject: [PATCH 18/18] update software precache spit stuff into functions handle animated textures and flats too --- src/p_setup.c | 16 +++++++- src/r_data.c | 109 +++++++++++++++++++++++++++++++------------------- 2 files changed, 83 insertions(+), 42 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 404b0236d..a98aa594d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -586,16 +586,30 @@ levelflat_t *levelflats; //SoM: Other files want this info. size_t P_PrecacheLevelFlats(void) { + levelflat_t levelflat; lumpnum_t lump; size_t i, flatmem = 0; + INT32 k; //SoM: 4/18/2000: New flat code to make use of levelflats. for (i = 0; i < numlevelflats; i++) { - lump = levelflats[i].lumpnum; + levelflat = levelflats[i]; + lump = levelflat.lumpnum; if (devparm) flatmem += W_LumpLength(lump); R_GetFlat(lump); + + if (levelflat.speed) // it is an animated flat + { + for (k = 1; k < levelflat.numpics; k++) + { + lump = levelflat.baselumpnum + k; + if (devparm) + flatmem += W_LumpLength(lump); + R_GetFlat(lump); + } + } } return flatmem; diff --git a/src/r_data.c b/src/r_data.c index 1ed4b34ee..5070107be 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1618,41 +1618,13 @@ INT32 R_TextureNumForName(const char *name) return i; } -// -// R_PrecacheLevel -// -// Preloads all relevant graphics for the level. -// -void R_PrecacheLevel(void) +static void R_PrecacheLevelTextures(void) { - char *texturepresent, *spritepresent; - size_t i, j, k; - lumpnum_t lump; + char *texturepresent; + anim_t *anim; + size_t j; + INT32 h; - thinker_t *th; - spriteframe_t *sf; - - // do not flush the memory, Z_Malloc twice with same user will cause error in Z_CheckHeap() - if (rendermode == render_none) - return; - - if (demo.playback) - return; - -#ifdef HWRENDER - if (rendermode == render_opengl) - { - HWR_PrecacheLevel(); - return; - } -#endif - - // Precache flats. - flatmemory = P_PrecacheLevelFlats(); - - // - // Precache textures. - // // no need to precache all software textures in 3D mode // (note they are still used with the reference software view) texturepresent = calloc(numtextures, sizeof (*texturepresent)); @@ -1669,6 +1641,22 @@ void R_PrecacheLevel(void) texturepresent[sides[j].bottomtexture] = 1; } + // check for animated textures + for (anim = anims; anim < lastanim; anim++) + { + if (!anim->istexture) + continue; + + if (!texturepresent[anim->basepic]) + continue; + + for (h = 1; h < anim->numpics; h++) + { + if (!texturecache[anim->basepic+h]) + R_GenerateTexture(anim->basepic+h); + } + } + // Sky texture is always present. // Note that F_SKY1 is the name used to indicate a sky floor/ceiling as a flat, // while the sky texture is stored like a wall texture, with a skynum dependent name. @@ -1686,10 +1674,17 @@ void R_PrecacheLevel(void) // since we cache entire composite textures } free(texturepresent); +} + +static void R_PrecacheLevelSprites(void) +{ + char *spritepresent; + size_t i, j, k; + lumpnum_t lump; + + thinker_t *th; + spriteframe_t *sf; - // - // Precache sprites. - // spritepresent = calloc(numsprites, sizeof (*spritepresent)); if (spritepresent == NULL) I_Error("%s: Out of memory looking up sprites", "R_PrecacheLevel"); @@ -1711,11 +1706,11 @@ void R_PrecacheLevel(void) { sf = &sprites[i].spriteframes[j]; #define cacheang(a) {\ - lump = sf->lumppat[a];\ - if (devparm)\ - spritememory += W_LumpLength(lump);\ - W_CachePatchNum(lump, PU_CACHE);\ - } + lump = sf->lumppat[a];\ + if (devparm)\ + spritememory += W_LumpLength(lump);\ + W_CachePatchNum(lump, PU_CACHE);\ + } // see R_InitSprites for more about lumppat,lumpid switch (sf->rotate) { @@ -1737,6 +1732,38 @@ void R_PrecacheLevel(void) } free(spritepresent); +} + +// +// R_PrecacheLevel +// +// Preloads all relevant graphics for the level. +// +void R_PrecacheLevel(void) +{ + // do not flush the memory, Z_Malloc twice with same user will cause error in Z_CheckHeap() + if (rendermode == render_none) + return; + + if (demo.playback) + return; + +#ifdef HWRENDER + if (rendermode == render_opengl) + { + HWR_PrecacheLevel(); + return; + } +#endif + + // Precache flats. + flatmemory = P_PrecacheLevelFlats(); + + // Precache textures. + R_PrecacheLevelTextures(); + + // Precache sprites. + R_PrecacheLevelSprites(); // FIXME: this is no longer correct with OpenGL render mode CONS_Debug(DBG_SETUP, "Precache level done:\n" -- 2.54.0