Do fixes and optimizations

This commit is contained in:
Lactozilla 2023-08-16 14:22:19 -03:00
parent 9d7a734acc
commit 393e5f7d8d
9 changed files with 278 additions and 146 deletions

View file

@ -477,6 +477,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
{
UINT8 *pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
patch_t *realpatch = NULL;
boolean free_patch = true;
#ifndef NO_PNG_LUMPS
size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump);
@ -487,11 +488,21 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
if (texture->type == TEXTURETYPE_FLAT)
realpatch = (patch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_PATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
else
realpatch = (patch_t *)Picture_Convert(PICFMT_DOOMPATCH, pdata, PICFMT_PATCH, 0, NULL, 0, 0, 0, 0, 0);
{
// If this patch has already been loaded, we just use it from the cache.
realpatch = W_GetCachedPatchNumPwad(patch->wad, patch->lump);
// Otherwise, we convert it here.
if (realpatch == NULL)
realpatch = Patch_Create((softwarepatch_t *)pdata, NULL);
else
free_patch = false;
}
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch);
Patch_Free(realpatch);
if (free_patch)
Patch_Free(realpatch);
}
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
if (format2bpp(grtex->mipmap.format)==4)
@ -1096,7 +1107,7 @@ patch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum)
if (!lumpcache[lumpnum])
{
void *ptr = Z_Calloc(sizeof(patch_t), PU_PATCH, &lumpcache[lumpnum]);
Patch_Create(NULL, 0, ptr);
Patch_Create(NULL, ptr);
Patch_AllocateHardwarePatch(ptr);
}
return (patch_t *)(lumpcache[lumpnum]);

View file

@ -377,7 +377,7 @@ static void md2_loadTexture(md2_t *model)
Z_Free(grPatch->mipmap->data);
}
else
model->grpatch = patch = Patch_Create(NULL, 0, NULL);
model->grpatch = patch = Patch_Create(NULL, NULL);
if (!patch->hardware)
Patch_AllocateHardwarePatch(patch);
@ -442,7 +442,7 @@ static void md2_loadBlendTexture(md2_t *model)
Z_Free(grPatch->mipmap->data);
}
else
model->blendgrpatch = patch = Patch_Create(NULL, 0, NULL);
model->blendgrpatch = patch = Patch_Create(NULL, NULL);
if (!patch->hardware)
Patch_AllocateHardwarePatch(patch);

View file

@ -24,14 +24,12 @@
// Assumes a PU_PATCH zone memory tag and no user, but can always be set later
//
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest)
patch_t *Patch_Create(softwarepatch_t *source, void *dest)
{
patch_t *patch = (dest == NULL) ? Z_Calloc(sizeof(patch_t), PU_PATCH, NULL) : (patch_t *)(dest);
if (!source)
return patch;
(void)srcsize;
patch->width = SHORT(source->width);
patch->height = SHORT(source->height);
patch->leftoffset = SHORT(source->leftoffset);

View file

@ -18,7 +18,7 @@
#include "doomdef.h"
// Patch functions
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest);
patch_t *Patch_Create(softwarepatch_t *source, void *dest);
void Patch_CalcDataSizes(softwarepatch_t *source, size_t *total_pixels, size_t *total_posts);
void Patch_MakeColumns(softwarepatch_t *source, size_t num_columns, UINT8 *pixels, column_t *columns, post_t *posts, boolean flip);
void Patch_Free(patch_t *patch);

View file

@ -84,22 +84,148 @@ void *Picture_Convert(
else if (informat == outformat)
I_Error("Picture_Convert: input and output formats were the same!");
(void)insize;
if (Picture_IsPatchFormat(outformat))
return Picture_PatchConvert(informat, picture, outformat, insize, outsize, inwidth, inheight, inleftoffset, intopoffset, flags);
return Picture_PatchConvert(informat, picture, outformat, outsize, inwidth, inheight, inleftoffset, intopoffset, flags);
else if (Picture_IsFlatFormat(outformat))
return Picture_FlatConvert(informat, picture, outformat, insize, outsize, inwidth, inheight, inleftoffset, intopoffset, flags);
return Picture_FlatConvert(informat, picture, outformat, outsize, inwidth, intopoffset, flags);
else
I_Error("Picture_Convert: unsupported input format!");
return NULL;
}
static void *ReadPixelFunc_Patch(void *picture, pictureformat_t informat, INT32 x, INT32 y, INT32 inwidth, INT32 inheight, pictureflags_t flags)
{
(void)inwidth;
(void)inheight;
return Picture_GetPatchPixel((patch_t*)picture, informat, x, y, flags);
}
static void *ReadPixelFunc_Flat_8bpp(void *picture, pictureformat_t informat, INT32 x, INT32 y, INT32 inwidth, INT32 inheight, pictureflags_t flags)
{
(void)informat;
(void)flags;
(void)inheight;
return (UINT8 *)picture + ((y * inwidth) + x);
}
static void *ReadPixelFunc_Flat_16bpp(void *picture, pictureformat_t informat, INT32 x, INT32 y, INT32 inwidth, INT32 inheight, pictureflags_t flags)
{
(void)informat;
(void)flags;
(void)inheight;
return (UINT16 *)picture + ((y * inwidth) + x);
}
static void *ReadPixelFunc_Flat_32bpp(void *picture, pictureformat_t informat, INT32 x, INT32 y, INT32 inwidth, INT32 inheight, pictureflags_t flags)
{
(void)informat;
(void)flags;
(void)inheight;
return (UINT32 *)picture + ((y * inwidth) + x);
}
static UINT8 GetAlphaFunc_32bpp(void *input, pictureflags_t flags)
{
(void)flags;
RGBA_t px = *(RGBA_t *)input;
return px.s.alpha;
}
static UINT8 GetAlphaFunc_16bpp(void *input, pictureflags_t flags)
{
(void)flags;
UINT16 px = *(UINT16 *)input;
return (px & 0xFF00) >> 8;
}
static UINT8 GetAlphaFunc_8bpp(void *input, pictureflags_t flags)
{
UINT8 px = *(UINT8 *)input;
if (px == TRANSPARENTPIXEL && (flags & PICFLAGS_USE_TRANSPARENTPIXEL))
return 0;
else
return 255;
}
// input 32bpp output 32bpp
static void *WritePatchPixel_i32o32(void *ptr, void *input)
{
RGBA_t px = *(RGBA_t *)input;
WRITEUINT32(ptr, px.rgba);
return ptr;
}
// input 16bpp output 32bpp
static void *WritePatchPixel_i16o32(void *ptr, void *input)
{
RGBA_t px = pMasterPalette[*((UINT16 *)input) & 0xFF];
WRITEUINT32(ptr, px.rgba);
return ptr;
}
// input 8bpp output 32bpp
static void *WritePatchPixel_i8o32(void *ptr, void *input)
{
RGBA_t px = pMasterPalette[*((UINT8 *)input) & 0xFF];
WRITEUINT32(ptr, px.rgba);
return ptr;
}
// input 32bpp output 16bpp
static void *WritePatchPixel_i32o16(void *ptr, void *input)
{
RGBA_t in = *(RGBA_t *)input;
UINT8 px = NearestColor(in.s.red, in.s.green, in.s.blue);
WRITEUINT16(ptr, (0xFF00 | px));
return ptr;
}
// input 16bpp output 16bpp
static void *WritePatchPixel_i16o16(void *ptr, void *input)
{
WRITEUINT16(ptr, *(UINT16 *)input);
return ptr;
}
// input 8bpp output 16bpp
static void *WritePatchPixel_i8o16(void *ptr, void *input)
{
WRITEUINT16(ptr, (0xFF00 | (*(UINT8 *)input)));
return ptr;
}
// input 32bpp output 8bpp
static void *WritePatchPixel_i32o8(void *ptr, void *input)
{
RGBA_t in = *(RGBA_t *)input;
UINT8 px = NearestColor(in.s.red, in.s.green, in.s.blue);
WRITEUINT8(ptr, px);
return ptr;
}
// input 16bpp output 8bpp
static void *WritePatchPixel_i16o8(void *ptr, void *input)
{
UINT16 px = *(UINT16 *)input;
WRITEUINT8(ptr, (px & 0xFF));
return ptr;
}
// input 8bpp output 8bpp
static void *WritePatchPixel_i8o8(void *ptr, void *input)
{
WRITEUINT8(ptr, *(UINT8 *)input);
return ptr;
}
/** Converts a picture to a patch.
*
* \param informat Input picture format.
* \param picture Input picture data.
* \param outformat Output picture format.
* \param insize Input picture size.
* \param outsize Output picture size, as a pointer.
* \param inwidth Input picture width.
* \param inheight Input picture height.
@ -110,16 +236,22 @@ void *Picture_Convert(
*/
void *Picture_PatchConvert(
pictureformat_t informat, void *picture, pictureformat_t outformat,
size_t insize, size_t *outsize,
INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset,
size_t *outsize,
INT32 inwidth, INT32 inheight, INT32 inleftoffset, INT32 intopoffset,
pictureflags_t flags)
{
// Shortcut: If converting a Doom patch into a regular patch, use Patch_Create
if (informat == PICFMT_DOOMPATCH && outformat == PICFMT_PATCH && flags == 0)
{
if (outsize != NULL)
*outsize = sizeof(patch_t);
return Patch_Create(picture, NULL);
}
INT32 outbpp = Picture_FormatBPP(outformat);
INT32 inbpp = Picture_FormatBPP(informat);
patch_t *inpatch = NULL;
(void)insize; // ignore
if (informat == PICFMT_NONE)
I_Error("Picture_PatchConvert: input format was PICFMT_NONE!");
else if (outformat == PICFMT_NONE)
@ -155,6 +287,74 @@ void *Picture_PatchConvert(
}
}
void *(*readPixelFunc)(void *, pictureformat_t, INT32, INT32, INT32, INT32, pictureflags_t) = NULL;
UINT8 (*getAlphaFunc)(void *, pictureflags_t) = NULL;
void *(*writePatchPixel)(void *, void *) = NULL;
if (Picture_IsPatchFormat(informat))
readPixelFunc = ReadPixelFunc_Patch;
else if (Picture_IsFlatFormat(informat))
{
switch (informat)
{
case PICFMT_FLAT32:
readPixelFunc = ReadPixelFunc_Flat_32bpp;
break;
case PICFMT_FLAT16:
readPixelFunc = ReadPixelFunc_Flat_16bpp;
break;
case PICFMT_FLAT:
readPixelFunc = ReadPixelFunc_Flat_8bpp;
break;
default:
I_Error("Picture_PatchConvert: unsupported flat input format!");
break;
}
}
else
I_Error("Picture_PatchConvert: unsupported input format!");
if (inbpp == PICDEPTH_32BPP)
getAlphaFunc = GetAlphaFunc_32bpp;
else if (inbpp == PICDEPTH_16BPP)
getAlphaFunc = GetAlphaFunc_16bpp;
else if (inbpp == PICDEPTH_8BPP)
getAlphaFunc = GetAlphaFunc_8bpp;
switch (outformat)
{
case PICFMT_PATCH32:
case PICFMT_DOOMPATCH32:
{
if (inbpp == PICDEPTH_32BPP)
writePatchPixel = WritePatchPixel_i32o32;
else if (inbpp == PICDEPTH_16BPP)
writePatchPixel = WritePatchPixel_i16o32;
else // PICFMT_PATCH
writePatchPixel = WritePatchPixel_i8o32;
break;
}
case PICFMT_PATCH16:
case PICFMT_DOOMPATCH16:
if (inbpp == PICDEPTH_32BPP)
writePatchPixel = WritePatchPixel_i32o16;
else if (inbpp == PICDEPTH_16BPP)
writePatchPixel = WritePatchPixel_i16o16;
else // PICFMT_PATCH
writePatchPixel = WritePatchPixel_i8o16;
break;
default: // PICFMT_PATCH
{
if (inbpp == PICDEPTH_32BPP)
writePatchPixel = WritePatchPixel_i32o8;
else if (inbpp == PICDEPTH_16BPP)
writePatchPixel = WritePatchPixel_i16o8;
else // PICFMT_PATCH
writePatchPixel = WritePatchPixel_i8o8;
break;
}
}
patch_t *out = Z_Calloc(sizeof(patch_t), PU_PATCH, NULL);
out->width = inwidth;
@ -174,7 +374,7 @@ void *Picture_PatchConvert(
size_t *column_posts = Z_Calloc(sizeof(size_t) * inwidth, PU_STATIC, NULL);
// Write columns
for (INT16 x = 0; x < inwidth; x++)
for (INT32 x = 0; x < inwidth; x++)
{
post_t *post;
size_t post_data_offset = 0;
@ -188,59 +388,16 @@ void *Picture_PatchConvert(
column_posts[x] = (size_t)-1;
// Write pixels
for (INT16 y = 0; y < inheight; y++)
for (INT32 y = 0; y < inheight; y++)
{
void *input = NULL;
boolean opaque = false;
// Read pixel
if (Picture_IsPatchFormat(informat))
input = Picture_GetPatchPixel(inpatch, informat, x, y, flags);
else if (Picture_IsFlatFormat(informat))
{
size_t offs = ((y * inwidth) + x);
switch (informat)
{
case PICFMT_FLAT32:
input = (UINT32 *)picture + offs;
break;
case PICFMT_FLAT16:
input = (UINT16 *)picture + offs;
break;
case PICFMT_FLAT:
input = (UINT8 *)picture + offs;
break;
default:
I_Error("Picture_PatchConvert: unsupported flat input format!");
break;
}
}
else
I_Error("Picture_PatchConvert: unsupported input format!");
void *input = readPixelFunc(picture, informat, x, y, inwidth, inheight, flags);
// Determine opacity
if (input != NULL)
{
UINT8 alpha = 0xFF;
if (inbpp == PICDEPTH_32BPP)
{
RGBA_t px = *(RGBA_t *)input;
alpha = px.s.alpha;
}
else if (inbpp == PICDEPTH_16BPP)
{
UINT16 px = *(UINT16 *)input;
alpha = (px & 0xFF00) >> 8;
}
else if (inbpp == PICDEPTH_8BPP)
{
UINT8 px = *(UINT8 *)input;
if (px == TRANSPARENTPIXEL)
alpha = 0;
}
opaque = alpha > 1;
}
opaque = getAlphaFunc(input, flags) > 0;
// End span if we have a transparent pixel
if (!opaque)
@ -266,62 +423,11 @@ void *Picture_PatchConvert(
was_opaque = true;
// Write the pixel
switch (outformat)
{
case PICFMT_PATCH32:
case PICFMT_DOOMPATCH32:
{
if (inbpp == PICDEPTH_32BPP)
{
RGBA_t px = *(RGBA_t *)input;
WRITEUINT32(imgptr, px.rgba);
}
else if (inbpp == PICDEPTH_16BPP)
{
RGBA_t px = pMasterPalette[*((UINT16 *)input) & 0xFF];
WRITEUINT32(imgptr, px.rgba);
}
else // PICFMT_PATCH
{
RGBA_t px = pMasterPalette[*((UINT8 *)input) & 0xFF];
WRITEUINT32(imgptr, px.rgba);
}
break;
}
case PICFMT_PATCH16:
case PICFMT_DOOMPATCH16:
if (inbpp == PICDEPTH_32BPP)
{
RGBA_t in = *(RGBA_t *)input;
UINT8 px = NearestColor(in.s.red, in.s.green, in.s.blue);
WRITEUINT16(imgptr, (0xFF00 | px));
}
else if (inbpp == PICDEPTH_16BPP)
WRITEUINT16(imgptr, *(UINT16 *)input);
else // PICFMT_PATCH
WRITEUINT16(imgptr, (0xFF00 | (*(UINT8 *)input)));
break;
default: // PICFMT_PATCH
{
if (inbpp == PICDEPTH_32BPP)
{
RGBA_t in = *(RGBA_t *)input;
UINT8 px = NearestColor(in.s.red, in.s.green, in.s.blue);
WRITEUINT8(imgptr, px);
}
else if (inbpp == PICDEPTH_16BPP)
{
UINT16 px = *(UINT16 *)input;
WRITEUINT8(imgptr, (px & 0xFF));
}
else // PICFMT_PATCH
WRITEUINT8(imgptr, *(UINT8 *)input);
break;
}
}
UINT8 *last_ptr = imgptr;
imgptr = writePatchPixel(last_ptr, input);
post->length++;
post_data_offset += imgptr - column->pixels;
post_data_offset += imgptr - last_ptr;
}
}
@ -333,8 +439,10 @@ void *Picture_PatchConvert(
for (INT16 x = 0; x < inwidth; x++)
{
column_t *column = &out->columns[x];
column->posts = &out->posts[column_posts[x]];
column->pixels = out->pixels + (column->pixels - old_pixels);
if (column->num_posts > 0)
column->posts = &out->posts[column_posts[x]];
if (old_pixels != out->pixels)
column->pixels = out->pixels + (column->pixels - old_pixels);
}
Z_Free(column_posts);
@ -350,19 +458,16 @@ void *Picture_PatchConvert(
* \param informat Input picture format.
* \param picture Input picture data.
* \param outformat Output picture format.
* \param insize Input picture size.
* \param outsize Output picture size, as a pointer.
* \param inwidth Input picture width.
* \param inheight Input picture height.
* \param inleftoffset Input picture left offset, for patches.
* \param intopoffset Input picture top offset, for patches.
* \param flags Input picture flags.
* \return A pointer to the converted picture.
*/
void *Picture_FlatConvert(
pictureformat_t informat, void *picture, pictureformat_t outformat,
size_t insize, size_t *outsize,
INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset,
size_t *outsize,
INT32 inwidth, INT32 inheight,
pictureflags_t flags)
{
void *outflat;
@ -372,10 +477,6 @@ void *Picture_FlatConvert(
INT32 x, y;
size_t size;
(void)insize; // ignore
(void)inleftoffset; // ignore
(void)intopoffset; // ignore
if (informat == PICFMT_NONE)
I_Error("Picture_FlatConvert: input format was PICFMT_NONE!");
else if (outformat == PICFMT_NONE)
@ -1280,7 +1381,7 @@ void *Picture_PNGConvert(
}
// Now, convert it!
converted = Picture_PatchConvert(informat, flat, outformat, insize, outsize, (INT16)width, (INT16)height, *leftoffset, *topoffset, flags);
converted = Picture_PatchConvert(informat, flat, outformat, outsize, (INT32)width, (INT32)height, *leftoffset, *topoffset, flags);
Z_Free(flat);
return converted;
}

View file

@ -42,8 +42,9 @@ typedef enum
typedef enum
{
PICFLAGS_XFLIP = 1,
PICFLAGS_YFLIP = 1<<1
PICFLAGS_XFLIP = 1,
PICFLAGS_YFLIP = 1<<1,
PICFLAGS_USE_TRANSPARENTPIXEL = 1<<2
} pictureflags_t;
enum
@ -62,13 +63,13 @@ void *Picture_Convert(
void *Picture_PatchConvert(
pictureformat_t informat, void *picture, pictureformat_t outformat,
size_t insize, size_t *outsize,
INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset,
size_t *outsize,
INT32 inwidth, INT32 inheight, INT32 inleftoffset, INT32 intopoffset,
pictureflags_t flags);
void *Picture_FlatConvert(
pictureformat_t informat, void *picture, pictureformat_t outformat,
size_t insize, size_t *outsize,
INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset,
size_t *outsize,
INT32 inwidth, INT32 inheight,
pictureflags_t flags);
void *Picture_GetPatchPixel(
patch_t *patch, pictureformat_t informat,

View file

@ -367,6 +367,7 @@ UINT8 *R_GenerateTexture(size_t texnum)
lumpnum_t lumpnum = patch->lump;
UINT8 *pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
patch_t *realpatch = NULL;
boolean free_patch = true;
#ifndef NO_PNG_LUMPS
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
@ -377,7 +378,16 @@ UINT8 *R_GenerateTexture(size_t texnum)
if (texture->type == TEXTURETYPE_FLAT)
realpatch = (patch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_PATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
else
realpatch = (patch_t *)Picture_Convert(PICFMT_DOOMPATCH, pdata, PICFMT_PATCH, 0, NULL, 0, 0, 0, 0, 0);
{
// If this patch has already been loaded, we just use it from the cache.
realpatch = W_GetCachedPatchNumPwad(wadnum, lumpnum);
// Otherwise, we convert it here.
if (realpatch == NULL)
realpatch = Patch_Create((softwarepatch_t *)pdata, NULL);
else
free_patch = false;
}
x1 = patch->originx;
width = realpatch->width;
@ -386,13 +396,15 @@ UINT8 *R_GenerateTexture(size_t texnum)
if (x1 > texture->width || x2 < 0)
{
Patch_Free(realpatch);
if (free_patch)
Patch_Free(realpatch);
continue; // patch not located within texture's x bounds, ignore
}
if (patch->originy > texture->height || (patch->originy + height) < 0)
{
Patch_Free(realpatch);
if (free_patch)
Patch_Free(realpatch);
continue; // patch not located within texture's y bounds, ignore
}
@ -417,10 +429,12 @@ UINT8 *R_GenerateTexture(size_t texnum)
else
patchcol = &realpatch->columns[x-x1];
columnDrawer(patchcol, columns[x].pixels, patch, texture->height, height);
if (patchcol->num_posts > 0)
columnDrawer(patchcol, columns[x].pixels, patch, texture->height, height);
}
Patch_Free(realpatch);
if (free_patch)
Patch_Free(realpatch);
}
done:

View file

@ -1987,8 +1987,7 @@ boolean W_IsLumpCached(lumpnum_t lumpnum, void *ptr)
// If a patch is already cached return true, otherwise
// return false.
//
// no outside code uses the PWAD form, for now
static boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
boolean W_IsPatchCachedPwad(UINT16 wad, UINT16 lump, void *ptr)
{
void *lcache;
@ -2010,7 +2009,7 @@ static boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
boolean W_IsPatchCached(lumpnum_t lumpnum, void *ptr)
{
return W_IsPatchCachedPWAD(WADFILENUM(lumpnum),LUMPNUM(lumpnum), ptr);
return W_IsPatchCachedPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum), ptr);
}
// ==========================================================================
@ -2065,7 +2064,7 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
#endif
dest = Z_Calloc(sizeof(patch_t), tag, &lumpcache[lump]);
Patch_Create(ptr, len, dest);
Patch_Create(ptr, dest);
Z_Free(ptr);
}
else
@ -2105,6 +2104,14 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag)
return W_CachePatchNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag);
}
void *W_GetCachedPatchNumPwad(UINT16 wad, UINT16 lump)
{
if (!TestValidLump(wad, lump))
return NULL;
return wadfiles[wad]->patchcache[lump];
}
void W_UnlockCachedPatch(void *patch)
{
if (!patch)

View file

@ -210,15 +210,15 @@ void *W_CacheLumpNumForce(lumpnum_t lumpnum, INT32 tag);
boolean W_IsLumpCached(lumpnum_t lump, void *ptr);
boolean W_IsPatchCached(lumpnum_t lump, void *ptr);
boolean W_IsPatchCachedPwad(UINT16 wad, UINT16 lump, void *ptr);
void *W_CacheLumpName(const char *name, INT32 tag);
void *W_CachePatchName(const char *name, INT32 tag);
void *W_CachePatchLongName(const char *name, INT32 tag);
// Returns either a Software patch, or an OpenGL patch.
// Performs any necessary conversions from PNG images.
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag);
void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag);
void *W_GetCachedPatchNumPwad(UINT16 wad, UINT16 lump);
// Returns a Software patch.
// Performs any necessary conversions from PNG images.