Add W_CheckNumForMarkers, clean up lump validation
Fixes many cases of invalid startlumps, so validation is now actually done only when PARANOIA is defined The W_CheckNumFor* functions allow startlump == numlumps, to make iteration less frustrating
This commit is contained in:
parent
286dfc7a43
commit
be35926843
6 changed files with 253 additions and 356 deletions
|
|
@ -9027,11 +9027,14 @@ boolean P_RunSOC(const char *socfilename)
|
|||
|
||||
// Auxiliary function for PK3 loading - looks for sound replacements.
|
||||
// NOTE: it does not really add any new sound entry or anything.
|
||||
static void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 end, size_t *sreplaces)
|
||||
static void P_LoadSoundsRange(UINT16 wadnum, size_t *sreplaces)
|
||||
{
|
||||
sfxenum_t j;
|
||||
UINT16 i;
|
||||
for (i = first; i < end; i++)
|
||||
UINT16 i, end;
|
||||
if (!W_CheckNumForMarkers((const char *[]){"Sounds/"}, 1, wadnum, &i, &end))
|
||||
return;
|
||||
|
||||
for (; i < end; i++)
|
||||
{
|
||||
// Let's check whether it's replacing an existing sound or it's a brand new one.
|
||||
const char *name = W_CheckNameForNumPwad(wadnum, i);
|
||||
|
|
@ -9055,10 +9058,13 @@ static void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 end, size_t *s
|
|||
|
||||
// Auxiliary function for PK3 loading - looks for music and music replacements.
|
||||
// NOTE: does nothing but print debug messages. The code is handled somewhere else.
|
||||
static void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 end, size_t *digmreplaces, size_t *mreplaces)
|
||||
static void P_LoadMusicsRange(UINT16 wadnum, size_t *digmreplaces, size_t *mreplaces)
|
||||
{
|
||||
UINT16 i;
|
||||
for (i = first; i < end; i++)
|
||||
UINT16 i, end;
|
||||
if (!W_CheckNumForMarkers((const char *[]){"Music/"}, 1, wadnum, &i, &end))
|
||||
return;
|
||||
|
||||
for (; i < end; i++)
|
||||
{
|
||||
const char *name = W_CheckNameForNumPwad(wadnum, i);
|
||||
if (name[0] == 'O' && name[1] == '_')
|
||||
|
|
@ -9236,12 +9242,6 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, wadcompat_t compat)
|
|||
size_t sreplaces = 0, mreplaces = 0, digmreplaces = 0;
|
||||
UINT16 numlumps, wadnum;
|
||||
|
||||
// Vars to help us with the position start and amount of each resource type.
|
||||
// Useful for PK3s since they use folders.
|
||||
// WADs use markers for some resources, but others such as sounds are checked lump-by-lump anyway.
|
||||
UINT16 sfxPos, sfxEnd;
|
||||
UINT16 musPos, musEnd;
|
||||
|
||||
// Init file.
|
||||
if ((numlumps = W_InitFile(wadfilename, false, false, compat)) == LUMPERROR)
|
||||
{
|
||||
|
|
@ -9261,23 +9261,8 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, wadcompat_t compat)
|
|||
}
|
||||
partadd_stage = 0;
|
||||
|
||||
switch(wadfiles[wadnum]->type)
|
||||
{
|
||||
case RET_PK3:
|
||||
sfxPos = W_CheckNumForFolderStartPK3("Sounds/", wadnum, 0);
|
||||
sfxEnd = W_CheckNumForFolderEndPK3("Sounds/", wadnum, sfxPos);
|
||||
musPos = W_CheckNumForFolderStartPK3("Music/", wadnum, 0);
|
||||
musEnd = W_CheckNumForFolderEndPK3("Music/", wadnum, musPos);
|
||||
break;
|
||||
|
||||
default:
|
||||
sfxPos = musPos = 0;
|
||||
sfxEnd = musEnd = numlumps;
|
||||
break;
|
||||
}
|
||||
|
||||
P_LoadSoundsRange(wadnum, sfxPos, sfxEnd, &sreplaces);
|
||||
P_LoadMusicsRange(wadnum, musPos, musEnd, &digmreplaces, &mreplaces);
|
||||
P_LoadSoundsRange(wadnum, &sreplaces);
|
||||
P_LoadMusicsRange(wadnum, &digmreplaces, &mreplaces);
|
||||
|
||||
if (!devparm && sreplaces)
|
||||
CONS_Printf(M_GetText("%s sounds replaced\n"), sizeu1(sreplaces));
|
||||
|
|
|
|||
|
|
@ -648,7 +648,7 @@ void R_AddSkins(UINT16 wadnum)
|
|||
// search for all skin markers in pwad
|
||||
//
|
||||
|
||||
while ((lump = W_CheckNumForNamePrefixPwad("S_SKIN", 6, wadnum, lastlump)) != LUMPERROR)
|
||||
while (lastlump != LUMPERROR && (lump = W_CheckNumForNamePrefixPwad("S_SKIN", 6, wadnum, lastlump)) != LUMPERROR)
|
||||
{
|
||||
// advance by default
|
||||
lastlump = lump + 1;
|
||||
|
|
@ -820,7 +820,7 @@ void R_PatchSkins(UINT16 wadnum)
|
|||
// search for all skin patch markers in pwad
|
||||
//
|
||||
|
||||
while ((lump = W_CheckNumForNamePrefixPwad("P_SKIN", 6, wadnum, lastlump)) != LUMPERROR)
|
||||
while (lastlump != LUMPERROR && (lump = W_CheckNumForNamePrefixPwad("P_SKIN", 6, wadnum, lastlump)) != LUMPERROR)
|
||||
{
|
||||
INT32 skinnum = 0;
|
||||
|
||||
|
|
|
|||
298
src/r_textures.c
298
src/r_textures.c
|
|
@ -1117,6 +1117,11 @@ void R_FlushTextureCache(void)
|
|||
int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum);
|
||||
void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *index);
|
||||
|
||||
static const char *flatmarkers[] = {
|
||||
"Flats/",
|
||||
"F_START", "F_END",
|
||||
};
|
||||
|
||||
static INT32
|
||||
Rloadflats (INT32 i, INT32 w)
|
||||
{
|
||||
|
|
@ -1126,81 +1131,74 @@ Rloadflats (INT32 i, INT32 w)
|
|||
texpatch_t *patch;
|
||||
UINT8 header[PNG_HEADER_SIZE];
|
||||
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForLongNamePwad("F_START", (UINT16)w, 0);
|
||||
if (texstart != LUMPERROR) texstart++;
|
||||
texend = W_CheckNumForLongNamePwad("F_END", (UINT16)w, texstart);
|
||||
}
|
||||
if (!W_CheckNumForMarkers(flatmarkers, sizeof(flatmarkers)/sizeof(*flatmarkers), (UINT16)w, &texstart, &texend))
|
||||
return i;
|
||||
|
||||
if (!( texstart == LUMPERROR || texend == LUMPERROR ))
|
||||
// Work through each lump between the markers in the WAD.
|
||||
for (j = 0; j < (texend - texstart); j++)
|
||||
{
|
||||
// Work through each lump between the markers in the WAD.
|
||||
for (j = 0; j < (texend - texstart); j++)
|
||||
UINT16 wadnum = (UINT16)w;
|
||||
lumpnum_t lumpnum = texstart + j;
|
||||
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
UINT16 wadnum = (UINT16)w;
|
||||
lumpnum_t lumpnum = texstart + j;
|
||||
if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder
|
||||
continue; // If it is then SKIP IT
|
||||
}
|
||||
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder
|
||||
continue; // If it is then SKIP IT
|
||||
}
|
||||
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
size_t flatsize = R_FlatDimensionsFromLumpSize(lumplength);
|
||||
|
||||
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
size_t flatsize = R_FlatDimensionsFromLumpSize(lumplength);
|
||||
//CONS_Printf("\n\"%s\" is a flat, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),flatsize,flatsize);
|
||||
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
|
||||
|
||||
//CONS_Printf("\n\"%s\" is a flat, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),flatsize,flatsize);
|
||||
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
|
||||
|
||||
// Set texture properties.
|
||||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
texture->hash = quickncasehash(texture->name, 8);
|
||||
// Set texture properties.
|
||||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
texture->hash = quickncasehash(texture->name, 8);
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
W_ReadLumpHeaderPwad(wadnum, lumpnum, header, sizeof header, 0);
|
||||
W_ReadLumpHeaderPwad(wadnum, lumpnum, header, sizeof header, 0);
|
||||
|
||||
if (Picture_IsLumpPNG(header, lumplength))
|
||||
{
|
||||
UINT8 *flatlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
INT32 width, height;
|
||||
Picture_PNGDimensions((UINT8 *)flatlump, &width, &height, NULL, NULL, lumplength);
|
||||
texture->width = (INT16)width;
|
||||
texture->height = (INT16)height;
|
||||
Z_Free(flatlump);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
texture->width = texture->height = flatsize;
|
||||
|
||||
texture->type = TEXTURETYPE_FLAT;
|
||||
texture->patchcount = 1;
|
||||
texture->holes = false;
|
||||
texture->flip = 0;
|
||||
texture->terrainID = K_GetTerrainIDForTextureName(texture->name);
|
||||
|
||||
// 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->flip = 0;
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
if (Picture_IsLumpPNG(header, lumplength))
|
||||
{
|
||||
UINT8 *flatlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
INT32 width, height;
|
||||
Picture_PNGDimensions((UINT8 *)flatlump, &width, &height, NULL, NULL, lumplength);
|
||||
texture->width = (INT16)width;
|
||||
texture->height = (INT16)height;
|
||||
Z_Free(flatlump);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
texture->width = texture->height = flatsize;
|
||||
|
||||
texture->type = TEXTURETYPE_FLAT;
|
||||
texture->patchcount = 1;
|
||||
texture->holes = false;
|
||||
texture->flip = 0;
|
||||
texture->terrainID = K_GetTerrainIDForTextureName(texture->name);
|
||||
|
||||
// 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->flip = 0;
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static const char *texturemarkers[] = {
|
||||
"Textures/",
|
||||
"TX_START", "TX_END",
|
||||
};
|
||||
|
||||
static INT32
|
||||
Rloadtextures (INT32 i, INT32 w)
|
||||
{
|
||||
|
|
@ -1211,136 +1209,108 @@ Rloadtextures (INT32 i, INT32 w)
|
|||
softwarepatch_t patchlump;
|
||||
|
||||
// Get the lump numbers for the markers in the WAD, if they exist.
|
||||
if (!W_CheckNumForMarkers(texturemarkers, sizeof(texturemarkers)/sizeof(*texturemarkers), (UINT16)w, &texstart, &texend))
|
||||
return i;
|
||||
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||
texturesLumpPos = W_CheckNumForLongNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
while (texturesLumpPos != LUMPERROR)
|
||||
{
|
||||
for (texturesLumpPos = 0; (texturesLumpPos = W_CheckNumForLongNamePwad("TEXTURES", (UINT16)w, texturesLumpPos)) != LUMPERROR; texturesLumpPos++)
|
||||
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||
texturesLumpPos = W_CheckNumForLongNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForLongNamePwad("TX_START", (UINT16)w, 0);
|
||||
if (texstart != LUMPERROR) texstart++;
|
||||
texend = W_CheckNumForLongNamePwad("TX_END", (UINT16)w, 0);
|
||||
texturesLumpPos = W_CheckNumForLongNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
if (texturesLumpPos != LUMPERROR)
|
||||
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||
}
|
||||
|
||||
if (!( texstart == LUMPERROR || texend == LUMPERROR ))
|
||||
// Work through each lump between the markers in the WAD.
|
||||
for (j = 0; j < (texend - texstart); j++)
|
||||
{
|
||||
// Work through each lump between the markers in the WAD.
|
||||
for (j = 0; j < (texend - texstart); j++)
|
||||
UINT16 wadnum = (UINT16)w;
|
||||
lumpnum_t lumpnum = texstart + j;
|
||||
#ifndef NO_PNG_LUMPS
|
||||
size_t lumplength;
|
||||
#endif
|
||||
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
UINT16 wadnum = (UINT16)w;
|
||||
lumpnum_t lumpnum = texstart + j;
|
||||
#ifndef NO_PNG_LUMPS
|
||||
size_t lumplength;
|
||||
#endif
|
||||
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder
|
||||
continue; // If it is then SKIP IT
|
||||
}
|
||||
|
||||
W_ReadLumpHeaderPwad(wadnum, lumpnum, &patchlump, PNG_HEADER_SIZE, 0);
|
||||
#ifndef NO_PNG_LUMPS
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
#endif
|
||||
|
||||
//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(wadnum, lumpnum), sizeof(texture->name));
|
||||
texture->hash = quickncasehash(texture->name, 8);
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)&patchlump, lumplength))
|
||||
{
|
||||
UINT8 *png = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
INT32 width, height;
|
||||
Picture_PNGDimensions(png, &width, &height, NULL, NULL, lumplength);
|
||||
texture->width = (INT16)width;
|
||||
texture->height = (INT16)height;
|
||||
Z_Free(png);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
texture->width = SHORT(patchlump.width);
|
||||
texture->height = SHORT(patchlump.height);
|
||||
}
|
||||
|
||||
texture->type = TEXTURETYPE_SINGLEPATCH;
|
||||
texture->patchcount = 1;
|
||||
texture->holes = false;
|
||||
texture->flip = 0;
|
||||
texture->terrainID = K_GetTerrainIDForTextureName(texture->name);
|
||||
|
||||
// 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->flip = 0;
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder
|
||||
continue; // If it is then SKIP IT
|
||||
}
|
||||
|
||||
W_ReadLumpHeaderPwad(wadnum, lumpnum, &patchlump, PNG_HEADER_SIZE, 0);
|
||||
#ifndef NO_PNG_LUMPS
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
#endif
|
||||
|
||||
//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(wadnum, lumpnum), sizeof(texture->name));
|
||||
texture->hash = quickncasehash(texture->name, 8);
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)&patchlump, lumplength))
|
||||
{
|
||||
UINT8 *png = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
INT32 width, height;
|
||||
Picture_PNGDimensions(png, &width, &height, NULL, NULL, lumplength);
|
||||
texture->width = (INT16)width;
|
||||
texture->height = (INT16)height;
|
||||
Z_Free(png);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
texture->width = SHORT(patchlump.width);
|
||||
texture->height = SHORT(patchlump.height);
|
||||
}
|
||||
|
||||
texture->type = TEXTURETYPE_SINGLEPATCH;
|
||||
texture->patchcount = 1;
|
||||
texture->holes = false;
|
||||
texture->flip = 0;
|
||||
texture->terrainID = K_GetTerrainIDForTextureName(texture->name);
|
||||
|
||||
// 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->flip = 0;
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static INT32
|
||||
count_range
|
||||
( const char * marker_start,
|
||||
const char * marker_end,
|
||||
const char * folder,
|
||||
UINT16 wadnum)
|
||||
static INT32 count_range(const char *markers[], size_t nummarkers, UINT16 wadnum)
|
||||
{
|
||||
UINT16 j;
|
||||
UINT16 texstart, texend;
|
||||
INT32 count = 0;
|
||||
|
||||
// Count flats
|
||||
if (!W_CheckNumForMarkers(markers, nummarkers, wadnum, &texstart, &texend))
|
||||
return count;
|
||||
|
||||
// PK3s have subfolders, so we can't just make a simple sum
|
||||
if (wadfiles[wadnum]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3(folder, wadnum, 0);
|
||||
texend = W_CheckNumForFolderEndPK3(folder, wadnum, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForLongNamePwad(marker_start, wadnum, 0);
|
||||
if (texstart != LUMPERROR) texstart++;
|
||||
texend = W_CheckNumForLongNamePwad(marker_end, wadnum, texstart);
|
||||
}
|
||||
|
||||
if (texstart != LUMPERROR && texend != LUMPERROR)
|
||||
{
|
||||
// PK3s have subfolders, so we can't just make a simple sum
|
||||
if (wadfiles[wadnum]->type == RET_PK3)
|
||||
for (j = texstart; j < texend; j++)
|
||||
{
|
||||
for (j = texstart; j < texend; j++)
|
||||
{
|
||||
if (!W_IsLumpFolder(wadnum, j)) // Check if lump is a folder; if not, then count it
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else // Add all the textures between markers
|
||||
{
|
||||
count += (texend - texstart);
|
||||
if (!W_IsLumpFolder(wadnum, j)) // Check if lump is a folder; if not, then count it
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else // Add all the textures between markers
|
||||
{
|
||||
count += (texend - texstart);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
|
@ -1358,14 +1328,14 @@ static INT32 R_CountTextures(UINT16 wadnum)
|
|||
// This system will allocate memory for all duplicate/patched textures even if it never uses them,
|
||||
// but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures.
|
||||
|
||||
count += count_range("F_START", "F_END", "flats/", wadnum);
|
||||
count += count_range(flatmarkers, sizeof(flatmarkers)/sizeof(*flatmarkers), wadnum);
|
||||
|
||||
// Count the textures from TEXTURES lumps
|
||||
for (texturesLumpPos = 0; (texturesLumpPos = W_CheckNumForLongNamePwad("TEXTURES", wadnum, texturesLumpPos)) != LUMPERROR; texturesLumpPos++)
|
||||
count += R_CountTexturesInTEXTURESLump(wadnum, texturesLumpPos);
|
||||
|
||||
// Count single-patch textures
|
||||
count += count_range("TX_START", "TX_END", "textures/", wadnum);
|
||||
count += count_range(texturemarkers, sizeof(texturemarkers)/sizeof(*texturemarkers), wadnum);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -489,6 +489,12 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
|
|||
return true;
|
||||
}
|
||||
|
||||
static const char *spritemarkers[] = {
|
||||
"Sprites/",
|
||||
"S_START", "S_END",
|
||||
"SS_START", "SS_END", // deutex compatib.
|
||||
};
|
||||
|
||||
//
|
||||
// Search for sprites replacements in a wad whose names are in namelist
|
||||
//
|
||||
|
|
@ -498,47 +504,12 @@ void R_AddSpriteDefs(UINT16 wadnum)
|
|||
UINT16 start, end;
|
||||
char wadname[MAX_WADPATH];
|
||||
|
||||
// Find the sprites section in this resource file.
|
||||
switch (wadfiles[wadnum]->type)
|
||||
{
|
||||
case RET_WAD:
|
||||
start = W_CheckNumForLongNamePwad("S_START", wadnum, 0);
|
||||
if (start == LUMPERROR)
|
||||
start = W_CheckNumForLongNamePwad("SS_START", wadnum, 0); //deutex compatib.
|
||||
if (start != LUMPERROR) start++;
|
||||
|
||||
end = W_CheckNumForLongNamePwad("S_END", wadnum, start);
|
||||
if (end == LUMPERROR)
|
||||
end = W_CheckNumForLongNamePwad("SS_END", wadnum, start); //deutex compatib.
|
||||
break;
|
||||
case RET_PK3:
|
||||
start = W_CheckNumForFolderStartPK3("Sprites/", wadnum, 0);
|
||||
end = W_CheckNumForFolderEndPK3("Sprites/", wadnum, start);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (start == LUMPERROR)
|
||||
{
|
||||
// ignore skin wads (we don't want skin sprites interfering with vanilla sprites)
|
||||
// G: DON'T ignore skin wads. this check did nothing because it incorrectly checked for UINT16_MAX instead of INT16_MAX
|
||||
// plus, this didn't exist in kart, so it might break old WADs...
|
||||
/*
|
||||
if (W_CheckNumForLongNamePwad("S_SKIN", wadnum, 0) != LUMPERROR)
|
||||
return;
|
||||
*/
|
||||
|
||||
start = 0; //let say S_START is lump 0
|
||||
}
|
||||
|
||||
if (end == LUMPERROR || start >= end)
|
||||
if (!W_CheckNumForMarkers(spritemarkers, sizeof(spritemarkers)/sizeof(*spritemarkers), wadnum, &start, &end))
|
||||
{
|
||||
CONS_Debug(DBG_SETUP, "no sprites in pwad %d\n", wadnum);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// scan through lumps, for each sprite, find all the sprite frames
|
||||
//
|
||||
|
|
|
|||
217
src/w_wad.c
217
src/w_wad.c
|
|
@ -332,23 +332,15 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile)
|
|||
{
|
||||
LUA_LoadLump(wadnum, posStart, true);
|
||||
}
|
||||
else
|
||||
else if (W_CheckNumForMarkers((const char *[]){"Lua/"}, 1, wadnum, &posStart, &posEnd))
|
||||
{
|
||||
posStart = W_CheckNumForFolderStartPK3("Lua/", wadnum, 0);
|
||||
if (posStart != LUMPERROR)
|
||||
{
|
||||
posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart);
|
||||
for (; posStart < posEnd; posStart++)
|
||||
LUA_LoadLump(wadnum, posStart, true);
|
||||
}
|
||||
for (; posStart < posEnd; posStart++)
|
||||
LUA_LoadLump(wadnum, posStart, true);
|
||||
}
|
||||
|
||||
posStart = W_CheckNumForFolderStartPK3("SOC/", wadnum, 0);
|
||||
if (posStart != LUMPERROR)
|
||||
if (W_CheckNumForMarkers((const char *[]){"SOC/"}, 1, wadnum, &posStart, &posEnd))
|
||||
{
|
||||
posEnd = W_CheckNumForFolderEndPK3("SOC/", wadnum, posStart);
|
||||
|
||||
for(; posStart < posEnd; posStart++)
|
||||
for (; posStart < posEnd; posStart++)
|
||||
{
|
||||
CONS_Printf(M_GetText("Loading SOC from %s|%s\n"), wadfiles[wadnum]->filename, W_CheckFullNameForNumPwad(wadnum, posStart));
|
||||
DEH_LoadDehackedLumpPwad(wadnum, posStart, mainfile);
|
||||
|
|
@ -1099,22 +1091,25 @@ INT32 W_InitMultipleFiles(char **filenames, boolean addons)
|
|||
return overallrc;
|
||||
}
|
||||
|
||||
// check for a valid lump number
|
||||
// lump cannot be asserted because some callers pass LUMPERROR,
|
||||
// and most W_ functions previously always passed 0 for lump...
|
||||
static boolean TestValidLump(UINT16 wad, UINT16 lump)
|
||||
{
|
||||
I_Assert(wad < numwadfiles);
|
||||
return lump < wadfiles[wad]->numlumps;
|
||||
}
|
||||
#ifdef PARANOIA
|
||||
#define TESTVALID(wad, lump) \
|
||||
if (wad >= numwadfiles || lump >= wadfiles[wad]->numlumps) \
|
||||
I_Error("Invalid lump number %04x:%04x", wad, lump);
|
||||
|
||||
// allows one past the end of the lump array to make iteration less hellish
|
||||
#define TESTVALIDEND(wad, lump) \
|
||||
if (wad >= numwadfiles || lump > wadfiles[wad]->numlumps) \
|
||||
I_Error("Invalid lump number %04x:%04x", wad, lump);
|
||||
#else
|
||||
#define TESTVALID(wad, lump)
|
||||
#define TESTVALIDEND(wad, lump)
|
||||
#endif
|
||||
|
||||
// NOTE: this actually returns the longname, but since nothing relies on
|
||||
// the 8-char truncation, i thought i'd save some effort :^)
|
||||
const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump)
|
||||
{
|
||||
if (!TestValidLump(wad, lump))
|
||||
return NULL;
|
||||
|
||||
TESTVALID(wad, lump)
|
||||
return strbuf_get(lumpnamebuf, wadfiles[wad]->lumpinfo[lump].longname);
|
||||
}
|
||||
|
||||
|
|
@ -1125,9 +1120,7 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum)
|
|||
|
||||
const char *W_CheckFullNameForNumPwad(UINT16 wad, UINT16 lump)
|
||||
{
|
||||
if (!TestValidLump(wad, lump))
|
||||
return NULL;
|
||||
|
||||
TESTVALID(wad, lump)
|
||||
return strbuf_get(lumpnamebuf, wadfiles[wad]->lumpinfo[lump].fullname);
|
||||
}
|
||||
|
||||
|
|
@ -1146,21 +1139,17 @@ UINT16 W_FindNextEmptyInPwad(UINT16 wad, UINT16 startlump)
|
|||
{
|
||||
UINT16 i;
|
||||
|
||||
if (!TestValidLump(wad, startlump))
|
||||
return LUMPERROR;
|
||||
TESTVALIDEND(wad, startlump)
|
||||
|
||||
//
|
||||
// scan forward
|
||||
// start at 'startlump', useful parameter when there are multiple
|
||||
// resources with the same name
|
||||
//
|
||||
if (startlump < wadfiles[wad]->numlumps)
|
||||
{
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
if (!lump_p->size)
|
||||
return i;
|
||||
}
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
if (!lump_p->size)
|
||||
return i;
|
||||
|
||||
// not found.
|
||||
return LUMPERROR;
|
||||
|
|
@ -1202,8 +1191,7 @@ UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
|||
UINT32 hash;
|
||||
char *up = uname;
|
||||
|
||||
if (!TestValidLump(wad, startlump))
|
||||
return LUMPERROR;
|
||||
TESTVALIDEND(wad, startlump)
|
||||
|
||||
while (*name)
|
||||
*up++ = toupper(*name++);
|
||||
|
|
@ -1219,8 +1207,7 @@ UINT16 W_CheckNumForNamePrefixPwad(const char *name, size_t namelen, UINT16 wad,
|
|||
UINT16 i;
|
||||
lumpinfo_t *lump_p;
|
||||
|
||||
if (!TestValidLump(wad, startlump))
|
||||
return LUMPERROR;
|
||||
TESTVALIDEND(wad, startlump)
|
||||
|
||||
// scan forward, start at <startlump>
|
||||
lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
|
|
@ -1238,8 +1225,7 @@ UINT16 W_CheckNumForNameMultiPrefixPwad(const lumpprefixes_t *prefixes, size_t n
|
|||
size_t j;
|
||||
lumpinfo_t *lump_p;
|
||||
|
||||
if (!TestValidLump(wad, startlump))
|
||||
return LUMPERROR;
|
||||
TESTVALIDEND(wad, startlump)
|
||||
|
||||
// scan forward, start at <startlump>
|
||||
lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
|
|
@ -1251,39 +1237,50 @@ UINT16 W_CheckNumForNameMultiPrefixPwad(const lumpprefixes_t *prefixes, size_t n
|
|||
return LUMPERROR; // not found
|
||||
}
|
||||
|
||||
// Look for the first lump from a folder.
|
||||
UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump)
|
||||
// finds the range [start:end) of lumps within the given PK3 folder or (optionally) WAD marker names
|
||||
// if wadnum is a WAD but no markers are specified, yields 0 and wad->numlumps
|
||||
// returns true and sets ostart/oend if lumps were found
|
||||
// [0] = PK3 folder [1], [2] = WAD start/end markers [3], [4] = secondary WAD start/end markers etc...
|
||||
boolean W_CheckNumForMarkers(const char *markers[], size_t nummarkers, UINT16 wad, UINT16 *ostart, UINT16 *oend)
|
||||
{
|
||||
size_t name_length;
|
||||
INT32 i;
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
name_length = strlen(name);
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
INT32 start, end;
|
||||
if (wadfiles[wad]->type == RET_PK3)
|
||||
{
|
||||
if (strnicmp(name, strbuf_get(lumpnamebuf, lump_p->fullname), name_length) == 0)
|
||||
size_t name_length = strlen(markers[0]);
|
||||
for (start = 0; start < wadfiles[wad]->numlumps; start++)
|
||||
if (!strncasecmp(markers[0], W_CheckFullNameForNumPwad(wad, start), name_length))
|
||||
break;
|
||||
if (start == wadfiles[wad]->numlumps)
|
||||
return false;
|
||||
for (end = start + 1; end < wadfiles[wad]->numlumps; end++)
|
||||
if (strncasecmp(markers[0], W_CheckFullNameForNumPwad(wad, end), name_length))
|
||||
break;
|
||||
}
|
||||
else if (nummarkers == 1)
|
||||
{
|
||||
start = 0;
|
||||
end = wadfiles[wad]->numlumps;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t i;
|
||||
for (i = 1; i < nummarkers; i += 2)
|
||||
{
|
||||
/* SLADE is special and puts a single directory entry. Skip that. */
|
||||
if (strlen(strbuf_get(lumpnamebuf, lump_p->fullname)) == name_length)
|
||||
i++;
|
||||
start = W_CheckNumForLongNamePwad(markers[i], wad, 0);
|
||||
if (start == LUMPERROR || ++start == wadfiles[wad]->numlumps)
|
||||
continue;
|
||||
end = W_CheckNumForLongNamePwad(markers[i+1], wad, start);
|
||||
if (end == LUMPERROR)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (i == nummarkers)
|
||||
return false;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
// In a PK3 type of resource file, it looks for the next lumpinfo entry that doesn't share the specified pathfile.
|
||||
// Useful for finding folder ends.
|
||||
// Returns the position of the lumpinfo entry.
|
||||
UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump)
|
||||
{
|
||||
INT32 i;
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
{
|
||||
if (strnicmp(name, strbuf_get(lumpnamebuf, lump_p->fullname), strlen(name)))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
*ostart = (UINT16)start;
|
||||
*oend = (UINT16)end;
|
||||
return true;
|
||||
}
|
||||
|
||||
// In a PK3 type of resource file, it looks for an entry with the specified full name.
|
||||
|
|
@ -1292,6 +1289,7 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump)
|
|||
{
|
||||
INT32 i;
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
{
|
||||
if (!strnicmp(name, strbuf_get(lumpnamebuf, lump_p->fullname), strlen(name)))
|
||||
|
|
@ -1315,8 +1313,7 @@ lumpnum_t W_CheckNumForLongName(const char *name)
|
|||
char uname[MAXLUMPNAME+1];
|
||||
char *up = uname;
|
||||
|
||||
if (name == NULL)
|
||||
return LUMPERROR;
|
||||
I_Assert(name != NULL);
|
||||
|
||||
if (!*name) // some doofus gave us an empty string?
|
||||
return LUMPERROR;
|
||||
|
|
@ -1388,19 +1385,7 @@ lumpnum_t W_CheckNumForMap(const char *name)
|
|||
for (i = numwadfiles - 1; i >= 0; i--)
|
||||
{
|
||||
UINT16 start, end;
|
||||
switch (wadfiles[i]->type)
|
||||
{
|
||||
case RET_PK3:
|
||||
start = W_CheckNumForFolderStartPK3("Maps/", i, 0);
|
||||
end = W_CheckNumForFolderEndPK3("Maps/", i, start);
|
||||
break;
|
||||
default:
|
||||
start = 0;
|
||||
end = wadfiles[i]->numlumps;
|
||||
break;
|
||||
}
|
||||
|
||||
if (start == LUMPERROR || end == LUMPERROR)
|
||||
if (!W_CheckNumForMarkers((const char *[]){"Maps/"}, 1, i, &start, &end))
|
||||
continue;
|
||||
|
||||
retry:
|
||||
|
|
@ -1454,31 +1439,22 @@ lumpnum_t W_GetNumForLongName(const char *name)
|
|||
lumpnum_t W_CheckNumForNameInFolder(const char *lump, const char *folder)
|
||||
{
|
||||
INT32 i;
|
||||
lumpnum_t fsid, feid;
|
||||
UINT16 fsid, feid;
|
||||
lumpnum_t check = LUMPERROR;
|
||||
|
||||
// scan wad files backwards so patch lump files take precedence
|
||||
for (i = numwadfiles - 1; i >= 0; i--)
|
||||
{
|
||||
if (wadfiles[i]->type == RET_PK3)
|
||||
if (wadfiles[i]->type != RET_PK3)
|
||||
continue;
|
||||
|
||||
if (!W_CheckNumForMarkers(&folder, 1, i, &fsid, &feid))
|
||||
continue;
|
||||
|
||||
check = W_CheckNumForLongNamePwad(lump, (UINT16)i, fsid);
|
||||
if (check < feid)
|
||||
{
|
||||
fsid = W_CheckNumForFolderStartPK3(folder, (UINT16)i, 0);
|
||||
if (fsid == LUMPERROR)
|
||||
{
|
||||
continue; // Start doesn't exist?
|
||||
}
|
||||
|
||||
feid = W_CheckNumForFolderEndPK3(folder, (UINT16)i, fsid);
|
||||
if (feid == LUMPERROR)
|
||||
{
|
||||
continue; // End doesn't exist?
|
||||
}
|
||||
|
||||
check = W_CheckNumForLongNamePwad(lump, (UINT16)i, fsid);
|
||||
if (check < feid)
|
||||
{
|
||||
return (i<<16) + check; // found it, in our constraints
|
||||
}
|
||||
return (i<<16) + check; // found it, in our constraints
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1502,8 +1478,7 @@ UINT8 W_LumpExists(const char *name)
|
|||
|
||||
size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump)
|
||||
{
|
||||
if (!TestValidLump(wad, lump))
|
||||
return 0;
|
||||
TESTVALID(wad, lump)
|
||||
return wadfiles[wad]->lumpinfo[lump].size;
|
||||
}
|
||||
|
||||
|
|
@ -1617,8 +1592,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
lumpinfo_t *l;
|
||||
FILE *handle;
|
||||
|
||||
if (!TestValidLump(wad,lump))
|
||||
return 0;
|
||||
TESTVALID(wad, lump)
|
||||
|
||||
lumpsize = wadfiles[wad]->lumpinfo[lump].size;
|
||||
// empty resource (usually markers like S_START, F_END ..)
|
||||
|
|
@ -1782,8 +1756,7 @@ void *W_CacheLumpNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
|||
{
|
||||
lumpcache_t *lumpcache;
|
||||
|
||||
if (!TestValidLump(wad,lump))
|
||||
return NULL;
|
||||
TESTVALID(wad, lump)
|
||||
|
||||
lumpcache = wadfiles[wad]->lumpcache;
|
||||
if (!lumpcache[lump])
|
||||
|
|
@ -1815,8 +1788,7 @@ void *W_CacheLumpNumForce(lumpnum_t lumpnum, INT32 tag)
|
|||
wad = WADFILENUM(lumpnum);
|
||||
lump = LUMPNUM(lumpnum);
|
||||
|
||||
if (!TestValidLump(wad,lump))
|
||||
return NULL;
|
||||
TESTVALID(wad, lump)
|
||||
|
||||
ptr = Z_Malloc(W_LumpLengthPwad(wad, lump), tag, NULL);
|
||||
W_ReadLumpHeaderPwad(wad, lump, ptr, 0, 0); // read the lump in full
|
||||
|
|
@ -1835,8 +1807,7 @@ static inline boolean W_IsLumpCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
|
|||
{
|
||||
void *lcache;
|
||||
|
||||
if (!TestValidLump(wad, lump))
|
||||
return false;
|
||||
TESTVALID(wad, lump)
|
||||
|
||||
lcache = wadfiles[wad]->lumpcache[lump];
|
||||
|
||||
|
|
@ -1867,8 +1838,7 @@ static inline boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
|
|||
{
|
||||
void *lcache;
|
||||
|
||||
if (!TestValidLump(wad, lump))
|
||||
return false;
|
||||
TESTVALID(wad, lump)
|
||||
|
||||
lcache = wadfiles[wad]->patchcache[lump];
|
||||
|
||||
|
|
@ -1929,8 +1899,7 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
|||
{
|
||||
lumpcache_t *lumpcache = NULL;
|
||||
|
||||
if (!TestValidLump(wad, lump))
|
||||
return NULL;
|
||||
TESTVALID(wad, lump)
|
||||
|
||||
lumpcache = wadfiles[wad]->patchcache;
|
||||
|
||||
|
|
@ -1960,8 +1929,7 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
|||
{
|
||||
patch_t *patch;
|
||||
|
||||
if (!TestValidLump(wad, lump))
|
||||
return NULL;
|
||||
TESTVALID(wad, lump)
|
||||
|
||||
patch = W_CacheSoftwarePatchNumPwad(wad, lump, tag);
|
||||
|
||||
|
|
@ -2405,17 +2373,20 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
|
|||
{
|
||||
// Count number of lumps until the end of resource OR up until next 0-length lump.
|
||||
lumpnum_t lumppos = lumpnum + 1;
|
||||
lumpnum_t lastlump = wadfiles[WADFILENUM(lumpnum)]->numlumps;
|
||||
UINT16 wad = WADFILENUM(lumpnum);
|
||||
UINT16 lastlump = wadfiles[wad]->numlumps;
|
||||
|
||||
// or the end of directory, for PK3 files
|
||||
if (wadfiles[WADFILENUM(lumpnum)]->type == RET_PK3)
|
||||
{
|
||||
const char *fullname = W_CheckFullNameForNum(lumpnum);
|
||||
const char *dirend = strrchr(fullname, '/');
|
||||
char *dirname = malloc(dirend - fullname + 2);
|
||||
strlcpy(dirname, fullname, dirend - fullname + 2);
|
||||
lastlump = W_CheckNumForFolderEndPK3(dirname, WADFILENUM(lumpnum), lumpnum);
|
||||
free(dirname);
|
||||
size_t dirlen = dirend - fullname + 1;
|
||||
for (lastlump = LUMPNUM(lumppos); lastlump < wadfiles[wad]->numlumps; lastlump++)
|
||||
if (strnicmp(fullname, W_CheckFullNameForNumPwad(wad, lastlump), dirlen))
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = LUMPNUM(lumppos); i < lastlump; i++, lumppos++, numlumps++)
|
||||
{
|
||||
if (W_LumpLength(lumppos) > 0)
|
||||
|
|
|
|||
|
|
@ -127,9 +127,9 @@ UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
|||
UINT16 W_CheckNumForNamePrefixPwad(const char *name, size_t namelen, UINT16 wad, UINT16 startlump);
|
||||
UINT16 W_CheckNumForNameMultiPrefixPwad(const lumpprefixes_t *prefixes, size_t numprefixes, UINT16 wad, UINT16 startlump);
|
||||
|
||||
boolean W_CheckNumForMarkers(const char *markers[], size_t nummarkers, UINT16 wad, UINT16 *ostart, UINT16 *oend);
|
||||
|
||||
UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||
UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||
UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||
|
||||
lumpnum_t W_CheckNumForMap(const char *name);
|
||||
lumpnum_t W_CheckNumForLongName(const char *name);
|
||||
|
|
|
|||
Loading…
Reference in a new issue