mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-21 11:21:11 +00:00
Load textures and flats from PK3 files more reliably
This commit is contained in:
parent
dcf5c4d3bf
commit
feffdb373b
3 changed files with 210 additions and 152 deletions
291
src/r_textures.c
291
src/r_textures.c
|
@ -545,17 +545,21 @@ UINT8 *R_GetFlatForTexture(size_t texnum)
|
|||
UINT16 wadnum = patch->wad;
|
||||
lumpnum_t lumpnum = patch->lump;
|
||||
UINT8 *pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
if (Picture_IsLumpPNG(pdata, lumplength))
|
||||
{
|
||||
texture->flat = Picture_PNGConvert(pdata, PICFMT_FLAT, NULL, NULL, NULL, NULL, lumplength, NULL, 0);
|
||||
Z_Free(pdata);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
texture->flat = pdata;
|
||||
{
|
||||
texture->flat = Z_Malloc(lumplength, PU_STATIC, NULL);
|
||||
memcpy(texture->flat, pdata, lumplength);
|
||||
}
|
||||
|
||||
Z_SetUser(texture->flat, &texture->flat);
|
||||
|
||||
Z_Free(pdata);
|
||||
}
|
||||
else
|
||||
texture->flat = (UINT8 *)Picture_TextureToFlat(texnum);
|
||||
|
@ -718,7 +722,10 @@ void R_FlushTextureCache(void)
|
|||
|
||||
if (numtextures)
|
||||
for (i = 0; i < numtextures; i++)
|
||||
{
|
||||
Z_Free(textures[i]->flat);
|
||||
Z_Free(texturecache[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Need these prototypes for later; defining them here instead of r_textures.h so they're "private"
|
||||
|
@ -728,83 +735,81 @@ void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *index);
|
|||
static INT32
|
||||
Rloadflats (INT32 i, INT32 w)
|
||||
{
|
||||
UINT16 j;
|
||||
UINT16 texstart, texend;
|
||||
texture_t *texture;
|
||||
texpatch_t *patch;
|
||||
UINT16 j, numlumps = 0;
|
||||
UINT16 texstart = 0, texend = 0;
|
||||
UINT32 *list = NULL;
|
||||
#ifndef NO_PNG_LUMPS
|
||||
UINT8 header[PNG_HEADER_SIZE];
|
||||
#endif
|
||||
|
||||
// Get every lump inside the Flats/ folder
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart);
|
||||
W_GetFolderLumpsPwad("Flats/", (UINT16)w, &list, NULL, &numlumps);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Else, get the lumps between F_START/F_END markers
|
||||
texstart = W_CheckNumForMarkerStartPwad("F_START", (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart);
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
return i;
|
||||
|
||||
numlumps = texend - texstart;
|
||||
}
|
||||
|
||||
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
|
||||
// Now add every entry as a texture
|
||||
for (j = 0; j < numlumps; 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;
|
||||
UINT16 wadnum = list ? WADFILENUM(list[j]) : (UINT16)w;
|
||||
lumpnum_t lumpnum = list ? LUMPNUM(list[j]) : (texstart + j);
|
||||
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
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_GetFlatSize(lumplength);
|
||||
|
||||
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
size_t flatsize = R_GetFlatSize(lumplength);
|
||||
//CONS_Printf("\n\"%s\" is a flat, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),flatsize,flatsize);
|
||||
texture_t *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->flip = 0;
|
||||
|
||||
// Allocate information for the texture's patches.
|
||||
patch = &texture->patches[0];
|
||||
|
||||
patch->originx = patch->originy = 0;
|
||||
patch->wad = (UINT16)w;
|
||||
patch->lump = texstart + j;
|
||||
patch->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->flip = 0;
|
||||
|
||||
// Allocate information for the texture's patches.
|
||||
texpatch_t *patch = &texture->patches[0];
|
||||
|
||||
patch->originx = patch->originy = 0;
|
||||
patch->wad = wadnum;
|
||||
patch->lump = lumpnum;
|
||||
patch->flip = 0;
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (list)
|
||||
Z_Free(list);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -814,17 +819,16 @@ Rloadflats (INT32 i, INT32 w)
|
|||
static INT32
|
||||
Rloadtextures (INT32 i, INT32 w)
|
||||
{
|
||||
UINT16 j;
|
||||
UINT16 texstart, texend, texturesLumpPos;
|
||||
texture_t *texture;
|
||||
texpatch_t *patch;
|
||||
softwarepatch_t patchlump;
|
||||
UINT16 j, numlumps = 0;
|
||||
UINT16 texstart = 0, texend = 0;
|
||||
UINT16 texturesLumpPos;
|
||||
UINT32 *list = NULL;
|
||||
|
||||
// Get the lump numbers for the markers in the WAD, if they exist.
|
||||
// Get every lump inside the Textures/ folder
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||
W_GetFolderLumpsPwad("Textures/", (UINT16)w, &list, NULL, &numlumps);
|
||||
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
|
@ -832,79 +836,82 @@ Rloadtextures (INT32 i, INT32 w)
|
|||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||
}
|
||||
}
|
||||
// Else, get the lumps between TX_START/TX_END markers
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
if (texturesLumpPos != INT16_MAX)
|
||||
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||
|
||||
texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, texstart);
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
return i;
|
||||
|
||||
numlumps = texend - texstart;
|
||||
}
|
||||
|
||||
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
|
||||
// Now add every entry as a texture
|
||||
for (j = 0; j < numlumps; j++)
|
||||
{
|
||||
// Work through each lump between the markers in the WAD.
|
||||
for (j = 0; j < (texend - texstart); j++)
|
||||
UINT16 wadnum = list ? WADFILENUM(list[j]) : (UINT16)w;
|
||||
lumpnum_t lumpnum = list ? LUMPNUM(list[j]) : (texstart + j);
|
||||
|
||||
softwarepatch_t patchlump;
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
size_t lumplength;
|
||||
#endif
|
||||
|
||||
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_t *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))
|
||||
{
|
||||
UINT16 wadnum = (UINT16)w;
|
||||
lumpnum_t lumpnum = texstart + j;
|
||||
#ifndef NO_PNG_LUMPS
|
||||
size_t lumplength;
|
||||
#endif
|
||||
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
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->flip = 0;
|
||||
|
||||
// Allocate information for the texture's patches.
|
||||
patch = &texture->patches[0];
|
||||
|
||||
patch->originx = patch->originy = 0;
|
||||
patch->wad = (UINT16)w;
|
||||
patch->lump = texstart + j;
|
||||
patch->flip = 0;
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
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->flip = 0;
|
||||
|
||||
// Allocate information for the texture's patches.
|
||||
texpatch_t *patch = &texture->patches[0];
|
||||
|
||||
patch->originx = patch->originy = 0;
|
||||
patch->wad = wadnum;
|
||||
patch->lump = lumpnum;
|
||||
patch->flip = 0;
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (list)
|
||||
Z_Free(list);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -915,37 +922,17 @@ count_range
|
|||
const char * folder,
|
||||
UINT16 wadnum)
|
||||
{
|
||||
UINT16 j;
|
||||
UINT16 texstart, texend;
|
||||
INT32 count = 0;
|
||||
|
||||
// Count flats
|
||||
if (W_FileHasFolders(wadfiles[wadnum]))
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3(folder, wadnum, 0);
|
||||
texend = W_CheckNumForFolderEndPK3(folder, wadnum, texstart);
|
||||
}
|
||||
count += W_CountFolderLumpsPwad(folder, wadnum);
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForMarkerStartPwad(marker_start, wadnum, 0);
|
||||
texend = W_CheckNumForNamePwad(marker_end, wadnum, texstart);
|
||||
}
|
||||
UINT16 texstart = W_CheckNumForMarkerStartPwad(marker_start, wadnum, 0);
|
||||
UINT16 texend = W_CheckNumForNamePwad(marker_end, wadnum, texstart);
|
||||
|
||||
if (texstart != INT16_MAX && texend != INT16_MAX)
|
||||
{
|
||||
// PK3s have subfolders, so we can't just make a simple sum
|
||||
if (W_FileHasFolders(wadfiles[wadnum]))
|
||||
{
|
||||
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
|
||||
{
|
||||
if (texstart != INT16_MAX && texend != INT16_MAX)
|
||||
count += (texend - texstart);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
|
|
66
src/w_wad.c
66
src/w_wad.c
|
@ -1335,6 +1335,72 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump)
|
|||
return i;
|
||||
}
|
||||
|
||||
void W_GetFolderLumpsPwad(const char *name, UINT16 wad, UINT32 **list, UINT16 *list_capacity, UINT16 *numlumps)
|
||||
{
|
||||
size_t name_length = strlen(name);
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo;
|
||||
|
||||
UINT16 capacity = list_capacity ? *list_capacity : 0;
|
||||
UINT16 count = *numlumps;
|
||||
|
||||
for (UINT16 i = 0; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
{
|
||||
if (strnicmp(name, lump_p->fullname, name_length) == 0)
|
||||
{
|
||||
if (strlen(lump_p->fullname) > name_length)
|
||||
{
|
||||
if (!capacity || count >= capacity)
|
||||
{
|
||||
capacity = capacity ? (capacity * 2) : 16;
|
||||
*list = Z_Realloc(*list, capacity * sizeof(UINT32), PU_STATIC, NULL);
|
||||
}
|
||||
|
||||
(*list)[count] = (wad << 16) + i;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (list_capacity)
|
||||
(*list_capacity) = capacity;
|
||||
(*numlumps) = count;
|
||||
}
|
||||
|
||||
void W_GetFolderLumps(const char *name, UINT32 **list, UINT16 *list_capacity, UINT16 *numlumps)
|
||||
{
|
||||
for (UINT16 i = 0; i < numwadfiles; i++)
|
||||
W_GetFolderLumpsPwad(name, i, list, list_capacity, numlumps);
|
||||
}
|
||||
|
||||
UINT32 W_CountFolderLumpsPwad(const char *name, UINT16 wad)
|
||||
{
|
||||
size_t name_length = strlen(name);
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo;
|
||||
|
||||
UINT32 count = 0;
|
||||
|
||||
for (UINT16 i = 0; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
{
|
||||
if (strnicmp(name, lump_p->fullname, name_length) == 0)
|
||||
{
|
||||
if (strlen(lump_p->fullname) > name_length)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
UINT32 W_CountFolderLumps(const char *name)
|
||||
{
|
||||
UINT32 count = 0;
|
||||
|
||||
for (UINT16 i = 0; i < numwadfiles; i++)
|
||||
count += W_CountFolderLumpsPwad(name, i);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// In a PK3 type of resource file, it looks for an entry with the specified full name.
|
||||
// Returns lump position in PK3's lumpinfo, or INT16_MAX if not found.
|
||||
UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump)
|
||||
|
|
|
@ -181,6 +181,11 @@ 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);
|
||||
|
||||
void W_GetFolderLumpsPwad(const char *name, UINT16 wad, UINT32 **list, UINT16 *list_capacity, UINT16 *numlumps);
|
||||
void W_GetFolderLumps(const char *name, UINT32 **list, UINT16 *list_capacity, UINT16 *numlumps);
|
||||
UINT32 W_CountFolderLumpsPwad(const char *name, UINT16 wad);
|
||||
UINT32 W_CountFolderLumps(const char *name);
|
||||
|
||||
lumpnum_t W_CheckNumForMap(const char *name);
|
||||
lumpnum_t W_CheckNumForName(const char *name);
|
||||
lumpnum_t W_CheckNumForLongName(const char *name);
|
||||
|
|
Loading…
Reference in a new issue