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); UINT8 *pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
patch_t *realpatch = NULL; patch_t *realpatch = NULL;
boolean free_patch = true;
#ifndef NO_PNG_LUMPS #ifndef NO_PNG_LUMPS
size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump); size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump);
@ -487,10 +488,20 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
if (texture->type == TEXTURETYPE_FLAT) if (texture->type == TEXTURETYPE_FLAT)
realpatch = (patch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_PATCH, 0, NULL, texture->width, texture->height, 0, 0, 0); realpatch = (patch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_PATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
else 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); HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch);
if (free_patch)
Patch_Free(realpatch); Patch_Free(realpatch);
} }
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :( //Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
@ -1096,7 +1107,7 @@ patch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum)
if (!lumpcache[lumpnum]) if (!lumpcache[lumpnum])
{ {
void *ptr = Z_Calloc(sizeof(patch_t), PU_PATCH, &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); Patch_AllocateHardwarePatch(ptr);
} }
return (patch_t *)(lumpcache[lumpnum]); return (patch_t *)(lumpcache[lumpnum]);

View file

@ -377,7 +377,7 @@ static void md2_loadTexture(md2_t *model)
Z_Free(grPatch->mipmap->data); Z_Free(grPatch->mipmap->data);
} }
else else
model->grpatch = patch = Patch_Create(NULL, 0, NULL); model->grpatch = patch = Patch_Create(NULL, NULL);
if (!patch->hardware) if (!patch->hardware)
Patch_AllocateHardwarePatch(patch); Patch_AllocateHardwarePatch(patch);
@ -442,7 +442,7 @@ static void md2_loadBlendTexture(md2_t *model)
Z_Free(grPatch->mipmap->data); Z_Free(grPatch->mipmap->data);
} }
else else
model->blendgrpatch = patch = Patch_Create(NULL, 0, NULL); model->blendgrpatch = patch = Patch_Create(NULL, NULL);
if (!patch->hardware) if (!patch->hardware)
Patch_AllocateHardwarePatch(patch); 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 // 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); patch_t *patch = (dest == NULL) ? Z_Calloc(sizeof(patch_t), PU_PATCH, NULL) : (patch_t *)(dest);
if (!source) if (!source)
return patch; return patch;
(void)srcsize;
patch->width = SHORT(source->width); patch->width = SHORT(source->width);
patch->height = SHORT(source->height); patch->height = SHORT(source->height);
patch->leftoffset = SHORT(source->leftoffset); patch->leftoffset = SHORT(source->leftoffset);

View file

@ -18,7 +18,7 @@
#include "doomdef.h" #include "doomdef.h"
// Patch functions // 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_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_MakeColumns(softwarepatch_t *source, size_t num_columns, UINT8 *pixels, column_t *columns, post_t *posts, boolean flip);
void Patch_Free(patch_t *patch); void Patch_Free(patch_t *patch);

View file

@ -84,22 +84,148 @@ void *Picture_Convert(
else if (informat == outformat) else if (informat == outformat)
I_Error("Picture_Convert: input and output formats were the same!"); I_Error("Picture_Convert: input and output formats were the same!");
(void)insize;
if (Picture_IsPatchFormat(outformat)) 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)) 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 else
I_Error("Picture_Convert: unsupported input format!"); I_Error("Picture_Convert: unsupported input format!");
return NULL; 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. /** Converts a picture to a patch.
* *
* \param informat Input picture format. * \param informat Input picture format.
* \param picture Input picture data. * \param picture Input picture data.
* \param outformat Output picture format. * \param outformat Output picture format.
* \param insize Input picture size.
* \param outsize Output picture size, as a pointer. * \param outsize Output picture size, as a pointer.
* \param inwidth Input picture width. * \param inwidth Input picture width.
* \param inheight Input picture height. * \param inheight Input picture height.
@ -110,16 +236,22 @@ void *Picture_Convert(
*/ */
void *Picture_PatchConvert( void *Picture_PatchConvert(
pictureformat_t informat, void *picture, pictureformat_t outformat, pictureformat_t informat, void *picture, pictureformat_t outformat,
size_t insize, size_t *outsize, size_t *outsize,
INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset, INT32 inwidth, INT32 inheight, INT32 inleftoffset, INT32 intopoffset,
pictureflags_t flags) 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 outbpp = Picture_FormatBPP(outformat);
INT32 inbpp = Picture_FormatBPP(informat); INT32 inbpp = Picture_FormatBPP(informat);
patch_t *inpatch = NULL; patch_t *inpatch = NULL;
(void)insize; // ignore
if (informat == PICFMT_NONE) if (informat == PICFMT_NONE)
I_Error("Picture_PatchConvert: input format was PICFMT_NONE!"); I_Error("Picture_PatchConvert: input format was PICFMT_NONE!");
else if (outformat == 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); patch_t *out = Z_Calloc(sizeof(patch_t), PU_PATCH, NULL);
out->width = inwidth; out->width = inwidth;
@ -174,7 +374,7 @@ void *Picture_PatchConvert(
size_t *column_posts = Z_Calloc(sizeof(size_t) * inwidth, PU_STATIC, NULL); size_t *column_posts = Z_Calloc(sizeof(size_t) * inwidth, PU_STATIC, NULL);
// Write columns // Write columns
for (INT16 x = 0; x < inwidth; x++) for (INT32 x = 0; x < inwidth; x++)
{ {
post_t *post; post_t *post;
size_t post_data_offset = 0; size_t post_data_offset = 0;
@ -188,59 +388,16 @@ void *Picture_PatchConvert(
column_posts[x] = (size_t)-1; column_posts[x] = (size_t)-1;
// Write pixels // Write pixels
for (INT16 y = 0; y < inheight; y++) for (INT32 y = 0; y < inheight; y++)
{ {
void *input = NULL;
boolean opaque = false; boolean opaque = false;
// Read pixel // Read pixel
if (Picture_IsPatchFormat(informat)) void *input = readPixelFunc(picture, informat, x, y, inwidth, inheight, flags);
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!");
// Determine opacity // Determine opacity
if (input != NULL) if (input != NULL)
{ opaque = getAlphaFunc(input, flags) > 0;
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;
}
// End span if we have a transparent pixel // End span if we have a transparent pixel
if (!opaque) if (!opaque)
@ -266,62 +423,11 @@ void *Picture_PatchConvert(
was_opaque = true; was_opaque = true;
// Write the pixel // Write the pixel
switch (outformat) UINT8 *last_ptr = imgptr;
{ imgptr = writePatchPixel(last_ptr, input);
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;
}
}
post->length++; post->length++;
post_data_offset += imgptr - column->pixels; post_data_offset += imgptr - last_ptr;
} }
} }
@ -333,7 +439,9 @@ void *Picture_PatchConvert(
for (INT16 x = 0; x < inwidth; x++) for (INT16 x = 0; x < inwidth; x++)
{ {
column_t *column = &out->columns[x]; column_t *column = &out->columns[x];
if (column->num_posts > 0)
column->posts = &out->posts[column_posts[x]]; column->posts = &out->posts[column_posts[x]];
if (old_pixels != out->pixels)
column->pixels = out->pixels + (column->pixels - old_pixels); column->pixels = out->pixels + (column->pixels - old_pixels);
} }
@ -350,19 +458,16 @@ void *Picture_PatchConvert(
* \param informat Input picture format. * \param informat Input picture format.
* \param picture Input picture data. * \param picture Input picture data.
* \param outformat Output picture format. * \param outformat Output picture format.
* \param insize Input picture size.
* \param outsize Output picture size, as a pointer. * \param outsize Output picture size, as a pointer.
* \param inwidth Input picture width. * \param inwidth Input picture width.
* \param inheight Input picture height. * \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. * \param flags Input picture flags.
* \return A pointer to the converted picture. * \return A pointer to the converted picture.
*/ */
void *Picture_FlatConvert( void *Picture_FlatConvert(
pictureformat_t informat, void *picture, pictureformat_t outformat, pictureformat_t informat, void *picture, pictureformat_t outformat,
size_t insize, size_t *outsize, size_t *outsize,
INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset, INT32 inwidth, INT32 inheight,
pictureflags_t flags) pictureflags_t flags)
{ {
void *outflat; void *outflat;
@ -372,10 +477,6 @@ void *Picture_FlatConvert(
INT32 x, y; INT32 x, y;
size_t size; size_t size;
(void)insize; // ignore
(void)inleftoffset; // ignore
(void)intopoffset; // ignore
if (informat == PICFMT_NONE) if (informat == PICFMT_NONE)
I_Error("Picture_FlatConvert: input format was PICFMT_NONE!"); I_Error("Picture_FlatConvert: input format was PICFMT_NONE!");
else if (outformat == PICFMT_NONE) else if (outformat == PICFMT_NONE)
@ -1280,7 +1381,7 @@ void *Picture_PNGConvert(
} }
// Now, convert it! // 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); Z_Free(flat);
return converted; return converted;
} }

View file

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

View file

@ -367,6 +367,7 @@ UINT8 *R_GenerateTexture(size_t texnum)
lumpnum_t lumpnum = patch->lump; lumpnum_t lumpnum = patch->lump;
UINT8 *pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); UINT8 *pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
patch_t *realpatch = NULL; patch_t *realpatch = NULL;
boolean free_patch = true;
#ifndef NO_PNG_LUMPS #ifndef NO_PNG_LUMPS
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum); size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
@ -377,7 +378,16 @@ UINT8 *R_GenerateTexture(size_t texnum)
if (texture->type == TEXTURETYPE_FLAT) if (texture->type == TEXTURETYPE_FLAT)
realpatch = (patch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_PATCH, 0, NULL, texture->width, texture->height, 0, 0, 0); realpatch = (patch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_PATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
else 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; x1 = patch->originx;
width = realpatch->width; width = realpatch->width;
@ -386,12 +396,14 @@ UINT8 *R_GenerateTexture(size_t texnum)
if (x1 > texture->width || x2 < 0) if (x1 > texture->width || x2 < 0)
{ {
if (free_patch)
Patch_Free(realpatch); Patch_Free(realpatch);
continue; // patch not located within texture's x bounds, ignore continue; // patch not located within texture's x bounds, ignore
} }
if (patch->originy > texture->height || (patch->originy + height) < 0) if (patch->originy > texture->height || (patch->originy + height) < 0)
{ {
if (free_patch)
Patch_Free(realpatch); Patch_Free(realpatch);
continue; // patch not located within texture's y bounds, ignore continue; // patch not located within texture's y bounds, ignore
} }
@ -417,9 +429,11 @@ UINT8 *R_GenerateTexture(size_t texnum)
else else
patchcol = &realpatch->columns[x-x1]; patchcol = &realpatch->columns[x-x1];
if (patchcol->num_posts > 0)
columnDrawer(patchcol, columns[x].pixels, patch, texture->height, height); columnDrawer(patchcol, columns[x].pixels, patch, texture->height, height);
} }
if (free_patch)
Patch_Free(realpatch); Patch_Free(realpatch);
} }

View file

@ -1987,8 +1987,7 @@ boolean W_IsLumpCached(lumpnum_t lumpnum, void *ptr)
// If a patch is already cached return true, otherwise // If a patch is already cached return true, otherwise
// return false. // return false.
// //
// no outside code uses the PWAD form, for now boolean W_IsPatchCachedPwad(UINT16 wad, UINT16 lump, void *ptr)
static boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
{ {
void *lcache; void *lcache;
@ -2010,7 +2009,7 @@ static boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
boolean W_IsPatchCached(lumpnum_t lumpnum, 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 #endif
dest = Z_Calloc(sizeof(patch_t), tag, &lumpcache[lump]); dest = Z_Calloc(sizeof(patch_t), tag, &lumpcache[lump]);
Patch_Create(ptr, len, dest); Patch_Create(ptr, dest);
Z_Free(ptr); Z_Free(ptr);
} }
else else
@ -2105,6 +2104,14 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag)
return W_CachePatchNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),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) void W_UnlockCachedPatch(void *patch)
{ {
if (!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_IsLumpCached(lumpnum_t lump, void *ptr);
boolean W_IsPatchCached(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_CacheLumpName(const char *name, INT32 tag);
void *W_CachePatchName(const char *name, INT32 tag); void *W_CachePatchName(const char *name, INT32 tag);
void *W_CachePatchLongName(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_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag);
void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag);
void *W_GetCachedPatchNumPwad(UINT16 wad, UINT16 lump);
// Returns a Software patch. // Returns a Software patch.
// Performs any necessary conversions from PNG images. // Performs any necessary conversions from PNG images.