Merge branch 'ignore-flats-when-loading-patches' into 'next'

Ignore flats when loading patches

See merge request STJr/SRB2!2457
This commit is contained in:
Lactozilla 2024-06-02 19:45:40 +00:00
commit 0aca694f1e
8 changed files with 256 additions and 57 deletions

View file

@ -1728,12 +1728,12 @@ static void CON_DrawBackpic(void)
// Get the lumpnum for CONSBACK, STARTUP (Only during game startup) or fallback into MISSING. // Get the lumpnum for CONSBACK, STARTUP (Only during game startup) or fallback into MISSING.
if (con_startup) if (con_startup)
piclump = W_CheckNumForName("STARTUP"); piclump = W_CheckNumForPatchName("STARTUP");
else else
piclump = W_CheckNumForName("CONSBACK"); piclump = W_CheckNumForPatchName("CONSBACK");
if (piclump == LUMPERROR) if (piclump == LUMPERROR)
piclump = W_GetNumForName("MISSING"); piclump = W_GetNumForPatchName("MISSING");
// Cache the patch. // Cache the patch.
con_backpic = W_CachePatchNum(piclump, PU_PATCH); con_backpic = W_CachePatchNum(piclump, PU_PATCH);

View file

@ -758,9 +758,9 @@ void D_SRB2Loop(void)
/* Smells like a hack... Don't fade Sonic's ass into the title screen. */ /* Smells like a hack... Don't fade Sonic's ass into the title screen. */
if (gamestate != GS_TITLESCREEN) if (gamestate != GS_TITLESCREEN)
{ {
gstartuplumpnum = W_CheckNumForName("STARTUP"); gstartuplumpnum = W_CheckNumForPatchName("STARTUP");
if (gstartuplumpnum == LUMPERROR) if (gstartuplumpnum == LUMPERROR)
gstartuplumpnum = W_GetNumForName("MISSING"); gstartuplumpnum = W_GetNumForPatchName("MISSING");
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(gstartuplumpnum, PU_PATCH)); V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(gstartuplumpnum, PU_PATCH));
} }

View file

@ -2336,7 +2336,7 @@ void F_SkyScroll(const char *patchname)
} }
#define LOADTTGFX(arr, name, maxf) \ #define LOADTTGFX(arr, name, maxf) \
lumpnum = W_CheckNumForName(name); \ lumpnum = W_CheckNumForPatchName(name); \
if (lumpnum != LUMPERROR) \ if (lumpnum != LUMPERROR) \
{ \ { \
arr[0] = W_CachePatchName(name, PU_PATCH_LOWPRIORITY); \ arr[0] = W_CachePatchName(name, PU_PATCH_LOWPRIORITY); \
@ -2350,7 +2350,7 @@ else if (strlen(name) <= 6) \
{ \ { \
sprintf(&lumpname[cnt], "%.2hu", (UINT16)(i+1)); \ sprintf(&lumpname[cnt], "%.2hu", (UINT16)(i+1)); \
lumpname[8] = 0; \ lumpname[8] = 0; \
lumpnum = W_CheckNumForName(lumpname); \ lumpnum = W_CheckNumForPatchName(lumpname); \
if (lumpnum != LUMPERROR) \ if (lumpnum != LUMPERROR) \
arr[i] = W_CachePatchName(lumpname, PU_PATCH_LOWPRIORITY); \ arr[i] = W_CachePatchName(lumpname, PU_PATCH_LOWPRIORITY); \
else \ else \
@ -4116,7 +4116,7 @@ static void F_GetPageTextGeometry(UINT8 *pagelines, boolean *rightside, INT32 *b
// reuse: // reuse:
// cutnum -> promptnum // cutnum -> promptnum
// scenenum -> pagenum // scenenum -> pagenum
lumpnum_t iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); lumpnum_t iconlump = W_CheckNumForPatchName(textprompts[cutnum]->page[scenenum].iconname);
*pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4; *pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4;
*rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside); *rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside);
@ -4508,7 +4508,7 @@ void F_TextPromptDrawer(void)
if (!promptactive) if (!promptactive)
return; return;
iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); iconlump = W_CheckNumForPatchName(textprompts[cutnum]->page[scenenum].iconname);
F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr); F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr);
// Draw gfx first // Draw gfx first

View file

@ -272,7 +272,7 @@ void HU_LoadFontCharacters(fontdef_t *font, const char *prefix)
for (i = 0; i < FONTSIZE; i++, j++) for (i = 0; i < FONTSIZE; i++, j++)
{ {
sprintf(buffer, "%.5s%.3d", prefix, j); sprintf(buffer, "%.5s%.3d", prefix, j);
if (W_CheckNumForName(buffer) == LUMPERROR) if (W_CheckNumForPatchName(buffer) == LUMPERROR)
font->chars[i] = NULL; font->chars[i] = NULL;
else else
font->chars[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); font->chars[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);

View file

@ -4030,11 +4030,11 @@ static void M_DrawThermo(INT32 x, INT32 y, consvar_t *cv)
lumpnum_t leftlump, rightlump, centerlump[2], cursorlump; lumpnum_t leftlump, rightlump, centerlump[2], cursorlump;
patch_t *p; patch_t *p;
leftlump = W_GetNumForName("M_THERML"); leftlump = W_GetNumForPatchName("M_THERML");
rightlump = W_GetNumForName("M_THERMR"); rightlump = W_GetNumForPatchName("M_THERMR");
centerlump[0] = W_GetNumForName("M_THERMM"); centerlump[0] = W_GetNumForPatchName("M_THERMM");
centerlump[1] = W_GetNumForName("M_THERMM"); centerlump[1] = W_GetNumForPatchName("M_THERMM");
cursorlump = W_GetNumForName("M_THERMO"); cursorlump = W_GetNumForPatchName("M_THERMO");
V_DrawScaledPatch(xx, y, 0, p = W_CachePatchNum(leftlump,PU_PATCH)); V_DrawScaledPatch(xx, y, 0, p = W_CachePatchNum(leftlump,PU_PATCH));
xx += p->width - p->leftoffset; xx += p->width - p->leftoffset;

View file

@ -1269,19 +1269,19 @@ tic_t lt_exitticker = 0, lt_endtime = 0;
// //
static void ST_cacheLevelTitle(void) static void ST_cacheLevelTitle(void)
{ {
#define SETPATCH(default, warning, custom, idx) \ #define SETPATCH(def, warning, custom, idx) \
{ \ { \
lumpnum_t patlumpnum = LUMPERROR; \ lumpnum_t patlumpnum = LUMPERROR; \
if (mapheaderinfo[gamemap-1]->custom[0] != '\0') \ if (mapheaderinfo[gamemap-1]->custom[0] != '\0') \
{ \ { \
patlumpnum = W_CheckNumForName(mapheaderinfo[gamemap-1]->custom); \ patlumpnum = W_CheckNumForPatchName(mapheaderinfo[gamemap-1]->custom); \
if (patlumpnum != LUMPERROR) \ if (patlumpnum != LUMPERROR) \
lt_patches[idx] = (patch_t *)W_CachePatchNum(patlumpnum, PU_HUDGFX); \ lt_patches[idx] = (patch_t *)W_CachePatchNum(patlumpnum, PU_HUDGFX); \
} \ } \
if (patlumpnum == LUMPERROR) \ if (patlumpnum == LUMPERROR) \
{ \ { \
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_WARNINGTITLE)) \ if (!(mapheaderinfo[gamemap-1]->levelflags & LF_WARNINGTITLE)) \
lt_patches[idx] = (patch_t *)W_CachePatchName(default, PU_HUDGFX); \ lt_patches[idx] = (patch_t *)W_CachePatchName(def, PU_HUDGFX); \
else \ else \
lt_patches[idx] = (patch_t *)W_CachePatchName(warning, PU_HUDGFX); \ lt_patches[idx] = (patch_t *)W_CachePatchName(warning, PU_HUDGFX); \
} \ } \

View file

@ -98,6 +98,7 @@ typedef struct lumpnum_cache_s
{ {
char lumpname[32]; char lumpname[32];
lumpnum_t lumpnum; lumpnum_t lumpnum;
UINT32 hash;
} lumpnum_cache_t; } lumpnum_cache_t;
static lumpnum_cache_t lumpnumcache[LUMPNUMCACHESIZE]; static lumpnum_cache_t lumpnumcache[LUMPNUMCACHESIZE];
@ -1475,6 +1476,63 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump)
return INT16_MAX; return INT16_MAX;
} }
static lumpnum_t CheckLumpInCache(const char *name, boolean longname)
{
if (longname)
{
UINT32 hash = quickncasehash(name, 32);
// Loop backwards so that we check most recent entries first
for (INT32 i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
{
if (lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].hash == hash
&& stricmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0)
{
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
return lumpnumcache[lumpnumcacheindex].lumpnum;
}
}
}
else
{
UINT32 hash = quickncasehash(name, 8);
// Loop backwards so that we check most recent entries first
for (INT32 i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
{
if (lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].hash == hash
&& lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname[8] == '\0'
&& strnicmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0)
{
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
return lumpnumcache[lumpnumcacheindex].lumpnum;
}
}
}
return LUMPERROR;
}
static void AddLumpToCache(lumpnum_t lumpnum, const char *name, boolean longname)
{
if (longname && strlen(name) >= 32)
return;
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1);
memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32);
if (longname)
{
strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32);
lumpnumcache[lumpnumcacheindex].hash = quickncasehash(name, 32);
}
else
{
strncpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 8);
lumpnumcache[lumpnumcacheindex].hash = quickncasehash(name, 8);
}
lumpnumcache[lumpnumcacheindex].lumpnum = lumpnum;
}
// //
// W_CheckNumForName // W_CheckNumForName
// Returns LUMPERROR if name not found. // Returns LUMPERROR if name not found.
@ -1487,17 +1545,10 @@ lumpnum_t W_CheckNumForName(const char *name)
if (!*name) // some doofus gave us an empty string? if (!*name) // some doofus gave us an empty string?
return LUMPERROR; return LUMPERROR;
// Check the lumpnumcache first. Loop backwards so that we check // Check the lumpnumcache first.
// most recent entries first lumpnum_t cachenum = CheckLumpInCache(name, false);
for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--) if (cachenum != LUMPERROR)
{ return cachenum;
if (!lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname[8]
&& strncmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0)
{
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
return lumpnumcache[lumpnumcacheindex].lumpnum;
}
}
// scan wad files backwards so patch lump files take precedence // scan wad files backwards so patch lump files take precedence
for (i = numwadfiles - 1; i >= 0; i--) for (i = numwadfiles - 1; i >= 0; i--)
@ -1511,12 +1562,11 @@ lumpnum_t W_CheckNumForName(const char *name)
else else
{ {
// Update the cache. // Update the cache.
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1); lumpnum_t lumpnum = (i << 16) + check;
memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32);
strncpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 8);
lumpnumcache[lumpnumcacheindex].lumpnum = (i<<16)+check;
return lumpnumcache[lumpnumcacheindex].lumpnum; AddLumpToCache(lumpnum, name, false);
return lumpnum;
} }
} }
@ -1534,16 +1584,10 @@ lumpnum_t W_CheckNumForLongName(const char *name)
if (!*name) // some doofus gave us an empty string? if (!*name) // some doofus gave us an empty string?
return LUMPERROR; return LUMPERROR;
// Check the lumpnumcache first. Loop backwards so that we check // Check the lumpnumcache first.
// most recent entries first lumpnum_t cachenum = CheckLumpInCache(name, true);
for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--) if (cachenum != LUMPERROR)
{ return cachenum;
if (strcmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0)
{
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
return lumpnumcache[lumpnumcacheindex].lumpnum;
}
}
// scan wad files backwards so patch lump files take precedence // scan wad files backwards so patch lump files take precedence
for (i = numwadfiles - 1; i >= 0; i--) for (i = numwadfiles - 1; i >= 0; i--)
@ -1556,16 +1600,12 @@ lumpnum_t W_CheckNumForLongName(const char *name)
if (check == INT16_MAX) return LUMPERROR; if (check == INT16_MAX) return LUMPERROR;
else else
{ {
if (strlen(name) < 32) // Update the cache.
{ lumpnum_t lumpnum = (i << 16) + check;
// Update the cache.
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1);
memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32);
strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32);
lumpnumcache[lumpnumcacheindex].lumpnum = (i << 16) + check;
}
return (i << 16) + check; AddLumpToCache(lumpnum, name, true);
return lumpnum;
} }
} }
@ -1647,6 +1687,159 @@ lumpnum_t W_GetNumForLongName(const char *name)
return i; return i;
} }
//
// Same as W_CheckNumForNamePwad, but handles namespaces.
//
static UINT16 W_CheckNumForPatchNamePwad(const char *name, UINT16 wad, boolean longname)
{
UINT16 i, start, end;
static char uname[8 + 1] = { 0 };
UINT32 hash = 0;
lumpinfo_t *lump_p;
if (!TestValidLump(wad,0))
return INT16_MAX;
if (!longname)
{
strlcpy(uname, name, sizeof uname);
strupr(uname);
hash = quickncasehash(uname, 8);
}
// SRB2 doesn't have a specific namespace for graphics, which means someone can do weird things
// like placing graphics inside a namespace it doesn't make sense for them to be in, like Sounds/ or SOC/
// So for now, this checks for lumps OUTSIDE of the flats namespace.
// When this situation changes, change the loops below to check for lumps INSIDE the namespaces to look in.
// TODO: cache namespace lump IDs
if (W_FileHasFolders(wadfiles[wad]))
{
start = W_CheckNumForFolderStartPK3("Flats/", wad, 0);
end = W_CheckNumForFolderEndPK3("Flats/", wad, start);
}
else
{
start = W_CheckNumForMarkerStartPwad("F_START", wad, 0);
end = W_CheckNumForNamePwad("F_END", wad, start);
if (end != INT16_MAX)
end++;
}
lump_p = wadfiles[wad]->lumpinfo;
if (start == INT16_MAX)
start = wadfiles[wad]->numlumps;
for (i = 0; i < start; i++, lump_p++)
{
if ((!longname && lump_p->hash == hash && !strncmp(lump_p->name, uname, sizeof(uname) - 1))
|| (longname && stricmp(lump_p->longname, name) == 0))
return i;
}
if (end != INT16_MAX && start < end)
{
lump_p = wadfiles[wad]->lumpinfo + end;
for (i = end; i < wadfiles[wad]->numlumps; i++, lump_p++)
{
if ((!longname && lump_p->hash == hash && !strncmp(lump_p->name, uname, sizeof(uname) - 1))
|| (longname && stricmp(lump_p->longname, name) == 0))
return i;
}
}
// not found.
return INT16_MAX;
}
//
// W_CheckNumForPatchNameInternal
// Gets a lump number out of a patch name. Returns LUMPERROR if name not found.
//
static lumpnum_t W_CheckNumForPatchNameInternal(const char *name, boolean longname)
{
INT32 i;
lumpnum_t check = INT16_MAX;
if (!*name) // some doofus gave us an empty string?
return LUMPERROR;
// Check the lumpnumcache first.
lumpnum_t cachenum = CheckLumpInCache(name, longname);
if (cachenum != LUMPERROR)
return cachenum;
// scan wad files backwards so patch lump files take precedence
for (i = numwadfiles - 1; i >= 0; i--)
{
check = W_CheckNumForPatchNamePwad(name,(UINT16)i,longname);
if (check != INT16_MAX)
break; //found it
}
if (check == INT16_MAX) return LUMPERROR;
else
{
// Update the cache.
lumpnum_t lumpnum = (i << 16) + check;
AddLumpToCache(lumpnum, name, longname);
return lumpnum;
}
}
//
// W_CheckNumForPatchName
// Wrapper for W_CheckNumForPatchNameInternal(name, false). Returns LUMPERROR if name not found.
//
lumpnum_t W_CheckNumForPatchName(const char *name)
{
return W_CheckNumForPatchNameInternal(name, false);
}
//
// Like W_CheckNumForPatchName, but can find entries with long names.
// Wrapper for W_CheckNumForPatchNameInternal(name, true). Returns LUMPERROR if name not found.
//
lumpnum_t W_CheckNumForLongPatchName(const char *name)
{
return W_CheckNumForPatchNameInternal(name, true);
}
//
// W_GetNumForPatchName
//
// Calls W_CheckNumForPatchName, but bombs out if not found.
//
lumpnum_t W_GetNumForPatchName(const char *name)
{
lumpnum_t i;
i = W_CheckNumForPatchName(name);
if (i == LUMPERROR)
I_Error("W_CheckNumForPatchName: %s not found!\n", name);
return i;
}
//
// Like W_GetNumForPatchName, but can find entries with long names
//
lumpnum_t W_GetNumForLongPatchName(const char *name)
{
lumpnum_t i;
i = W_CheckNumForLongPatchName(name);
if (i == LUMPERROR)
I_Error("W_GetNumForLongPatchName: %s not found!\n", name);
return i;
}
// //
// W_CheckNumForNameInBlock // W_CheckNumForNameInBlock
// Checks only in blocks from blockstart lump to blockend lump // Checks only in blocks from blockstart lump to blockend lump
@ -2291,10 +2484,10 @@ void *W_CachePatchName(const char *name, INT32 tag)
{ {
lumpnum_t num; lumpnum_t num;
num = W_CheckNumForName(name); num = W_CheckNumForPatchName(name);
if (num == LUMPERROR) if (num == LUMPERROR)
return W_CachePatchNum(W_GetNumForName("MISSING"), tag); return W_CachePatchNum(W_GetNumForPatchName("MISSING"), tag);
return W_CachePatchNum(num, tag); return W_CachePatchNum(num, tag);
} }
@ -2302,10 +2495,10 @@ void *W_CachePatchLongName(const char *name, INT32 tag)
{ {
lumpnum_t num; lumpnum_t num;
num = W_CheckNumForLongName(name); num = W_CheckNumForLongPatchName(name);
if (num == LUMPERROR) if (num == LUMPERROR)
return W_CachePatchNum(W_GetNumForLongName("MISSING"), tag); return W_CachePatchNum(W_GetNumForLongPatchName("MISSING"), tag);
return W_CachePatchNum(num, tag); return W_CachePatchNum(num, tag);
} }
#ifndef NOMD5 #ifndef NOMD5

View file

@ -193,6 +193,12 @@ lumpnum_t W_CheckNumForName(const char *name);
lumpnum_t W_CheckNumForLongName(const char *name); lumpnum_t W_CheckNumForLongName(const char *name);
lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR
lumpnum_t W_GetNumForLongName(const char *name); lumpnum_t W_GetNumForLongName(const char *name);
lumpnum_t W_CheckNumForPatchName(const char *name);
lumpnum_t W_CheckNumForLongPatchName(const char *name);
lumpnum_t W_GetNumForPatchName(const char *name); // like W_CheckNumForPatchName but I_Error on LUMPERROR
lumpnum_t W_GetNumForLongPatchName(const char *name);
lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend); lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend);
UINT8 W_LumpExists(const char *name); // Lua uses this. UINT8 W_LumpExists(const char *name); // Lua uses this.