Refactor Picture_PatchConvert, so that it no longer makes Doom patches

This commit is contained in:
Lactozilla 2023-08-01 12:58:01 -03:00
parent 821460d208
commit 0088326ff0
4 changed files with 151 additions and 325 deletions

View file

@ -148,7 +148,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
} }
} }
static void HWR_DrawPostsInCache(const doompost_t *patchcol, UINT8 *block, GLMipmap_t *mipmap, static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap,
INT32 pblockheight, INT32 blockmodulo, INT32 pblockheight, INT32 blockmodulo,
fixed_t yfracstep, fixed_t scale_y, fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight, texpatch_t *originPatch, INT32 patchheight,
@ -157,116 +157,7 @@ static void HWR_DrawPostsInCache(const doompost_t *patchcol, UINT8 *block, GLMip
fixed_t yfrac, position, count; fixed_t yfrac, position, count;
UINT8 *dest; UINT8 *dest;
const UINT8 *source; const UINT8 *source;
INT32 topdelta, prevdelta = -1; INT32 topdelta;
INT32 originy = 0;
// for writing a pixel to dest
RGBA_t colortemp;
UINT8 alpha;
UINT8 texel;
UINT16 texelu16;
(void)patchheight; // This parameter is unused
if (originPatch) // originPatch can be NULL here, unlike in the software version
originy = originPatch->originy;
while (patchcol->topdelta != 0xff)
{
topdelta = patchcol->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
source = (const UINT8 *)patchcol + 3;
count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS;
position = originy + topdelta;
yfrac = 0;
//yfracstep = (patchcol->length << FRACBITS) / count;
if (position < 0)
{
yfrac = -position<<FRACBITS;
count += (((position * scale_y) + (FRACUNIT/2)) >> FRACBITS);
position = 0;
}
position = ((position * scale_y) + (FRACUNIT/2)) >> FRACBITS;
if (position < 0)
position = 0;
if (position + count >= pblockheight)
count = pblockheight - position;
dest = block + (position*blockmodulo);
while (count > 0)
{
count--;
texel = source[yfrac>>FRACBITS];
alpha = 0xFF;
// Make pixel transparent if chroma keyed
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
alpha = 0x00;
if (mipmap->colormap)
texel = mipmap->colormap->data[texel];
switch (bpp)
{
case 2:
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16));
break;
case 3:
colortemp = V_GetColor(texel);
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break;
case 4:
colortemp = V_GetColor(texel);
colortemp.s.alpha = alpha;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t));
break;
// default is 1
default:
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
*dest = ASTBlendPaletteIndexes(*dest, texel, originPatch->style, originPatch->alpha);
else
*dest = texel;
break;
}
dest += blockmodulo;
yfrac += yfracstep;
}
patchcol = (const doompost_t *)((const UINT8 *)patchcol + patchcol->length + 4);
}
}
static void HWR_DrawFlippedPostsInCache(const doompost_t *patchcol, UINT8 *block, GLMipmap_t *mipmap,
INT32 pblockheight, INT32 blockmodulo,
fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight,
INT32 bpp)
{
fixed_t yfrac, position, count;
UINT8 *dest;
const UINT8 *source;
INT32 topdelta, prevdelta = -1;
INT32 originy = 0; INT32 originy = 0;
// for writing a pixel to dest // for writing a pixel to dest
@ -278,18 +169,15 @@ static void HWR_DrawFlippedPostsInCache(const doompost_t *patchcol, UINT8 *block
if (originPatch) // originPatch can be NULL here, unlike in the software version if (originPatch) // originPatch can be NULL here, unlike in the software version
originy = originPatch->originy; originy = originPatch->originy;
while (patchcol->topdelta != 0xff) for (size_t i = 0; i < patchcol->num_posts; i++)
{ {
topdelta = patchcol->topdelta; post_t *post = &patchcol->posts[i];
if (topdelta <= prevdelta) source = patchcol->pixels + post->data_offset;
topdelta += prevdelta; topdelta = patchheight-post->length-post->topdelta;
prevdelta = topdelta; count = ((post->length * scale_y) + (FRACUNIT/2)) >> FRACBITS;
topdelta = patchheight-patchcol->length-topdelta;
source = (const UINT8 *)patchcol + 3;
count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS;
position = originy + topdelta; position = originy + topdelta;
yfrac = (patchcol->length-1) << FRACBITS; yfrac = (post->length-1) << FRACBITS;
if (position < 0) if (position < 0)
{ {
@ -361,7 +249,6 @@ static void HWR_DrawFlippedPostsInCache(const doompost_t *patchcol, UINT8 *block
dest += blockmodulo; dest += blockmodulo;
yfrac -= yfracstep; yfrac -= yfracstep;
} }
patchcol = (const doompost_t *)((const UINT8 *)patchcol + patchcol->length + 4);
} }
} }
@ -419,19 +306,19 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
INT32 pblockwidth, INT32 pblockheight, INT32 pblockwidth, INT32 pblockheight,
texture_t *texture, texpatch_t *patch, texture_t *texture, texpatch_t *patch,
const softwarepatch_t *realpatch) const patch_t *realpatch)
{ {
INT32 x, x1, x2; INT32 x, x1, x2;
INT32 col, ncols; INT32 col, ncols;
fixed_t xfrac, xfracstep; fixed_t xfrac, xfracstep;
fixed_t yfracstep, scale_y; fixed_t yfracstep, scale_y;
const doompost_t *patchcol; const column_t *patchcol;
UINT8 *block = mipmap->data; UINT8 *block = mipmap->data;
INT32 bpp; INT32 bpp;
INT32 blockmodulo; INT32 blockmodulo;
INT32 width, height; INT32 width, height;
// Column drawing function pointer. // Column drawing function pointer.
static void (*ColumnDrawerPointer)(const doompost_t *patchcol, UINT8 *block, GLMipmap_t *mipmap, static void (*ColumnDrawerPointer)(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap,
INT32 pblockheight, INT32 blockmodulo, INT32 pblockheight, INT32 blockmodulo,
fixed_t yfracstep, fixed_t scale_y, fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight, texpatch_t *originPatch, INT32 patchheight,
@ -440,11 +327,11 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
if (texture->width <= 0 || texture->height <= 0) if (texture->width <= 0 || texture->height <= 0)
return; return;
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedPostsInCache : HWR_DrawPostsInCache; ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache;
x1 = patch->originx; x1 = patch->originx;
width = SHORT(realpatch->width); width = realpatch->width;
height = SHORT(realpatch->height); height = realpatch->height;
x2 = x1 + width; x2 = x1 + width;
if (x1 > texture->width || x2 < 0) if (x1 > texture->width || x2 < 0)
@ -491,9 +378,9 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
for (block += col*bpp; ncols--; block += bpp, xfrac += xfracstep) for (block += col*bpp; ncols--; block += bpp, xfrac += xfracstep)
{ {
if (patch->flip & 1) if (patch->flip & 1)
patchcol = (const doompost_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[(width-1)-(xfrac>>FRACBITS)])); patchcol = &realpatch->columns[(width-1)-(xfrac>>FRACBITS)];
else else
patchcol = (const doompost_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS])); patchcol = &realpatch->columns[xfrac>>FRACBITS];
ColumnDrawerPointer(patchcol, block, mipmap, ColumnDrawerPointer(patchcol, block, mipmap,
pblockheight, blockmodulo, pblockheight, blockmodulo,
@ -537,8 +424,6 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
UINT8 *block; UINT8 *block;
texture_t *texture; texture_t *texture;
texpatch_t *patch; texpatch_t *patch;
softwarepatch_t *realpatch;
UINT8 *pdata;
INT32 blockwidth, blockheight, blocksize; INT32 blockwidth, blockheight, blocksize;
INT32 i; INT32 i;
@ -590,30 +475,25 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
// Composite the columns together. // Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
{ {
boolean dealloc = true; UINT8 *pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump); patch_t *realpatch = NULL;
pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
realpatch = (softwarepatch_t *)pdata;
#ifndef NO_PNG_LUMPS #ifndef NO_PNG_LUMPS
if (Picture_IsLumpPNG((UINT8 *)realpatch, lumplength)) size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump);
realpatch = (softwarepatch_t *)Picture_PNGConvert(pdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, lumplength, NULL, 0); if (Picture_IsLumpPNG(pdata, lumplength))
realpatch = (patch_t *)Picture_PNGConvert(pdata, PICFMT_PATCH, NULL, NULL, NULL, NULL, lumplength, NULL, 0);
else else
#endif #endif
#ifdef WALLFLATS #ifdef WALLFLATS
if (texture->type == TEXTURETYPE_FLAT) if (texture->type == TEXTURETYPE_FLAT)
realpatch = (softwarepatch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_DOOMPATCH, 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
#endif #endif
{ realpatch = (patch_t *)Picture_Convert(PICFMT_DOOMPATCH, pdata, PICFMT_PATCH, 0, NULL, 0, 0, 0, 0, 0);
(void)lumplength;
dealloc = false;
}
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch); HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch);
if (dealloc) Patch_Free(realpatch);
Z_Unlock(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 :(
if (format2bpp(grtex->mipmap.format)==4) if (format2bpp(grtex->mipmap.format)==4)

View file

@ -51,8 +51,6 @@
#endif #endif
#endif #endif
static unsigned char imgbuf[1<<26];
#ifdef PICTURE_PNG_USELOOKUP #ifdef PICTURE_PNG_USELOOKUP
static colorlookup_t png_colorlookup; static colorlookup_t png_colorlookup;
#endif #endif
@ -116,13 +114,9 @@ void *Picture_PatchConvert(
INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset, INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset,
pictureflags_t flags) pictureflags_t flags)
{ {
INT16 x, y; INT32 outbpp = Picture_FormatBPP(outformat);
UINT8 *img;
UINT8 *imgptr = imgbuf;
UINT8 *colpointers, *startofspan;
size_t size = 0;
patch_t *inpatch = NULL;
INT32 inbpp = Picture_FormatBPP(informat); INT32 inbpp = Picture_FormatBPP(informat);
patch_t *inpatch = NULL;
(void)insize; // ignore (void)insize; // ignore
@ -130,16 +124,17 @@ void *Picture_PatchConvert(
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)
I_Error("Picture_PatchConvert: output format was PICFMT_NONE!"); I_Error("Picture_PatchConvert: output format was PICFMT_NONE!");
else if (Picture_IsDoomPatchFormat(outformat))
I_Error("Picture_PatchConvert: cannot convert to Doom patch!");
else if (informat == outformat) else if (informat == outformat)
I_Error("Picture_PatchConvert: input and output formats were the same!"); I_Error("Picture_PatchConvert: input and output formats were the same!");
if (inbpp == PICDEPTH_NONE) if (inbpp == PICDEPTH_NONE)
I_Error("Picture_PatchConvert: unknown input bits per pixel?!"); I_Error("Picture_PatchConvert: unknown input bits per pixel!");
if (Picture_FormatBPP(outformat) == PICDEPTH_NONE) if (outbpp == PICDEPTH_NONE)
I_Error("Picture_PatchConvert: unknown output bits per pixel?!"); I_Error("Picture_PatchConvert: unknown output bits per pixel!");
// If it's a patch, you can just figure out // If it's a patch, we can just figure out the dimensions from the header.
// the dimensions from the header.
if (Picture_IsPatchFormat(informat)) if (Picture_IsPatchFormat(informat))
{ {
inpatch = (patch_t *)picture; inpatch = (patch_t *)picture;
@ -160,28 +155,40 @@ void *Picture_PatchConvert(
} }
} }
// Write image size and offset patch_t *out = Z_Calloc(sizeof(patch_t), PU_PATCH, NULL);
WRITEINT16(imgptr, inwidth);
WRITEINT16(imgptr, inheight);
WRITEINT16(imgptr, inleftoffset);
WRITEINT16(imgptr, intopoffset);
// Leave placeholder to column pointers out->width = inwidth;
colpointers = imgptr; out->height = inheight;
imgptr += inwidth*4; out->leftoffset = inleftoffset;
out->topoffset = intopoffset;
size_t max_pixels = out->width * out->height;
size_t num_posts = 0;
out->columns = Z_Calloc(sizeof(column_t) * out->width, PU_PATCH_DATA, NULL);
out->pixels = Z_Calloc(max_pixels * (outbpp / 8), PU_PATCH_DATA, NULL);
out->posts = NULL;
UINT8 *imgptr = out->pixels;
size_t *column_posts = Z_Calloc(sizeof(size_t) * inwidth, PU_STATIC, NULL);
// Write columns // Write columns
for (x = 0; x < inwidth; x++) for (INT16 x = 0; x < inwidth; x++)
{ {
int lastStartY = 0; post_t *post;
int spanSize = 0; size_t post_data_offset = 0;
startofspan = NULL; boolean was_opaque = false;
// Write column pointer column_t *column = &out->columns[x];
WRITEINT32(colpointers, imgptr - imgbuf); column->pixels = imgptr;
column->posts = NULL;
column->num_posts = 0;
column_posts[x] = (size_t)-1;
// Write pixels // Write pixels
for (y = 0; y < inheight; y++) for (INT16 y = 0; y < inheight; y++)
{ {
void *input = NULL; void *input = NULL;
boolean opaque = false; boolean opaque = false;
@ -231,57 +238,32 @@ void *Picture_PatchConvert(
if (px == TRANSPARENTPIXEL) if (px == TRANSPARENTPIXEL)
alpha = 0; alpha = 0;
} }
opaque = (alpha > 1);
opaque = alpha > 1;
} }
// End span if we have a transparent pixel // End span if we have a transparent pixel
if (!opaque) if (!opaque)
{ {
if (startofspan) was_opaque = false;
WRITEUINT8(imgptr, 0);
startofspan = NULL;
continue; continue;
} }
// Start new column if we need to if (!was_opaque)
if (!startofspan || spanSize == 255)
{ {
int writeY = y; num_posts++;
// If we reached the span size limit, finish the previous span out->posts = Z_Realloc(out->posts, sizeof(post_t) * num_posts, PU_PATCH_DATA, NULL);
if (startofspan) post = &out->posts[num_posts - 1];
WRITEUINT8(imgptr, 0); post->topdelta = (size_t)y;
post->length = 0;
if (y > 254) post->data_offset = post_data_offset;
{ if (column_posts[x] == (size_t)-1)
// Make sure we're aligned to 254 column_posts[x] = num_posts - 1;
if (lastStartY < 254) column->num_posts++;
{
WRITEUINT8(imgptr, 254);
WRITEUINT8(imgptr, 0);
imgptr += 2;
lastStartY = 254;
} }
// Write stopgap empty spans if needed was_opaque = true;
writeY = y - lastStartY;
while (writeY > 254)
{
WRITEUINT8(imgptr, 254);
WRITEUINT8(imgptr, 0);
imgptr += 2;
writeY -= 254;
}
}
startofspan = imgptr;
WRITEUINT8(imgptr, writeY);
imgptr += 2;
spanSize = 0;
lastStartY = y;
}
// Write the pixel // Write the pixel
switch (outformat) switch (outformat)
@ -291,18 +273,18 @@ void *Picture_PatchConvert(
{ {
if (inbpp == PICDEPTH_32BPP) if (inbpp == PICDEPTH_32BPP)
{ {
RGBA_t out = *(RGBA_t *)input; RGBA_t px = *(RGBA_t *)input;
WRITEUINT32(imgptr, out.rgba); WRITEUINT32(imgptr, px.rgba);
} }
else if (inbpp == PICDEPTH_16BPP) else if (inbpp == PICDEPTH_16BPP)
{ {
RGBA_t out = pMasterPalette[*((UINT16 *)input) & 0xFF]; RGBA_t px = pMasterPalette[*((UINT16 *)input) & 0xFF];
WRITEUINT32(imgptr, out.rgba); WRITEUINT32(imgptr, px.rgba);
} }
else // PICFMT_PATCH else // PICFMT_PATCH
{ {
RGBA_t out = pMasterPalette[*((UINT8 *)input) & 0xFF]; RGBA_t px = pMasterPalette[*((UINT8 *)input) & 0xFF];
WRITEUINT32(imgptr, out.rgba); WRITEUINT32(imgptr, px.rgba);
} }
break; break;
} }
@ -311,8 +293,8 @@ void *Picture_PatchConvert(
if (inbpp == PICDEPTH_32BPP) if (inbpp == PICDEPTH_32BPP)
{ {
RGBA_t in = *(RGBA_t *)input; RGBA_t in = *(RGBA_t *)input;
UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue); UINT8 px = NearestColor(in.s.red, in.s.green, in.s.blue);
WRITEUINT16(imgptr, (0xFF00 | out)); WRITEUINT16(imgptr, (0xFF00 | px));
} }
else if (inbpp == PICDEPTH_16BPP) else if (inbpp == PICDEPTH_16BPP)
WRITEUINT16(imgptr, *(UINT16 *)input); WRITEUINT16(imgptr, *(UINT16 *)input);
@ -324,13 +306,13 @@ void *Picture_PatchConvert(
if (inbpp == PICDEPTH_32BPP) if (inbpp == PICDEPTH_32BPP)
{ {
RGBA_t in = *(RGBA_t *)input; RGBA_t in = *(RGBA_t *)input;
UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue); UINT8 px = NearestColor(in.s.red, in.s.green, in.s.blue);
WRITEUINT8(imgptr, out); WRITEUINT8(imgptr, px);
} }
else if (inbpp == PICDEPTH_16BPP) else if (inbpp == PICDEPTH_16BPP)
{ {
UINT16 out = *(UINT16 *)input; UINT16 px = *(UINT16 *)input;
WRITEUINT8(imgptr, (out & 0xFF)); WRITEUINT8(imgptr, (px & 0xFF));
} }
else // PICFMT_PATCH else // PICFMT_PATCH
WRITEUINT8(imgptr, *(UINT8 *)input); WRITEUINT8(imgptr, *(UINT8 *)input);
@ -338,40 +320,29 @@ void *Picture_PatchConvert(
} }
} }
spanSize++; post->length++;
startofspan[1] = spanSize; post_data_offset += imgptr - column->pixels;
}
} }
if (startofspan) UINT8 *old_pixels = out->pixels;
WRITEUINT8(imgptr, 0); size_t total_pixels = imgptr - out->pixels;
if (total_pixels != max_pixels)
out->pixels = Z_Realloc(out->pixels, total_pixels, PU_PATCH_DATA, NULL);
WRITEUINT8(imgptr, 0xFF); for (INT16 x = 0; x < inwidth; x++)
}
size = imgptr-imgbuf;
img = Z_Malloc(size, PU_STATIC, NULL);
memcpy(img, imgbuf, size);
if (Picture_IsInternalPatchFormat(outformat))
{ {
patch_t *converted = Patch_Create((softwarepatch_t *)img, size, NULL); column_t *column = &out->columns[x];
column->posts = &out->posts[column_posts[x]];
column->pixels = out->pixels + (column->pixels - old_pixels);
}
#ifdef HWRENDER Z_Free(column_posts);
Patch_CreateGL(converted);
#endif
Z_Free(img);
if (outsize != NULL) if (outsize != NULL)
*outsize = sizeof(patch_t); *outsize = sizeof(patch_t);
return converted;
} return (void *)out;
else
{
if (outsize != NULL)
*outsize = size;
return img;
}
} }
/** Converts a picture to a flat. /** Converts a picture to a flat.

View file

@ -78,24 +78,20 @@ static INT32 tidcachelen = 0;
// R_DrawColumnInCache // R_DrawColumnInCache
// Clip and draw a column from a patch into a cached post. // Clip and draw a column from a patch into a cached post.
// //
static inline void R_DrawColumnInCache(doompost_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) static inline void R_DrawColumnInCache(column_t *column, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
{ {
INT32 count, position; INT32 count, position;
UINT8 *source; UINT8 *source;
INT32 topdelta, prevdelta = -1;
INT32 originy = originPatch->originy; INT32 originy = originPatch->originy;
(void)patchheight; // This parameter is unused (void)patchheight; // This parameter is unused
while (patch->topdelta != 0xff) for (size_t i = 0; i < column->num_posts; i++)
{ {
topdelta = patch->topdelta; post_t *post = &column->posts[i];
if (topdelta <= prevdelta) source = column->pixels + post->data_offset;
topdelta += prevdelta; count = post->length;
prevdelta = topdelta; position = originy + post->topdelta;
source = (UINT8 *)patch + 3;
count = patch->length;
position = originy + topdelta;
if (position < 0) if (position < 0)
{ {
@ -109,8 +105,6 @@ static inline void R_DrawColumnInCache(doompost_t *patch, UINT8 *cache, texpatch
if (count > 0) if (count > 0)
M_Memcpy(cache + position, source, count); M_Memcpy(cache + position, source, count);
patch = (doompost_t *)((UINT8 *)patch + patch->length + 4);
} }
} }
@ -118,22 +112,19 @@ static inline void R_DrawColumnInCache(doompost_t *patch, UINT8 *cache, texpatch
// R_DrawFlippedColumnInCache // R_DrawFlippedColumnInCache
// Similar to R_DrawColumnInCache; it draws the column inverted, however. // Similar to R_DrawColumnInCache; it draws the column inverted, however.
// //
static inline void R_DrawFlippedColumnInCache(doompost_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) static inline void R_DrawFlippedColumnInCache(column_t *column, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
{ {
INT32 count, position; INT32 count, position;
UINT8 *source, *dest; UINT8 *source, *dest;
INT32 topdelta, prevdelta = -1;
INT32 originy = originPatch->originy; INT32 originy = originPatch->originy;
INT32 topdelta;
while (patch->topdelta != 0xff) for (size_t i = 0; i < column->num_posts; i++)
{ {
topdelta = patch->topdelta; post_t *post = &column->posts[i];
if (topdelta <= prevdelta) topdelta = patchheight - post->length - post->topdelta;
topdelta += prevdelta; source = column->pixels + post->data_offset + post->length;
prevdelta = topdelta; count = post->length;
topdelta = patchheight-patch->length-topdelta;
source = (UINT8 *)patch + 2 + patch->length; // patch + 3 + (patch->length-1)
count = patch->length;
position = originy + topdelta; position = originy + topdelta;
if (position < 0) if (position < 0)
@ -152,33 +143,27 @@ static inline void R_DrawFlippedColumnInCache(doompost_t *patch, UINT8 *cache, t
for (; dest < cache + position + count; --source) for (; dest < cache + position + count; --source)
*dest++ = *source; *dest++ = *source;
} }
patch = (doompost_t *)((UINT8 *)patch + patch->length + 4);
} }
} }
// //
// R_DrawBlendColumnInCache // R_DrawBlendColumnInCache
// Draws a translucent column into the cache, applying a half-cooked equation to get a proper translucency value (Needs code in R_GenerateTexture()). // Draws a translucent column into the cache.
// //
static inline void R_DrawBlendColumnInCache(doompost_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) static inline void R_DrawBlendColumnInCache(column_t *column, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
{ {
INT32 count, position; INT32 count, position;
UINT8 *source, *dest; UINT8 *source, *dest;
INT32 topdelta, prevdelta = -1;
INT32 originy = originPatch->originy; INT32 originy = originPatch->originy;
(void)patchheight; // This parameter is unused (void)patchheight; // This parameter is unused
while (patch->topdelta != 0xff) for (size_t i = 0; i < column->num_posts; i++)
{ {
topdelta = patch->topdelta; post_t *post = &column->posts[i];
if (topdelta <= prevdelta) source = column->pixels + post->data_offset;
topdelta += prevdelta; count = post->length;
prevdelta = topdelta; position = originy + post->topdelta;
source = (UINT8 *)patch + 3;
count = patch->length;
position = originy + topdelta;
if (position < 0) if (position < 0)
{ {
@ -197,8 +182,6 @@ static inline void R_DrawBlendColumnInCache(doompost_t *patch, UINT8 *cache, tex
if (*source != 0xFF) if (*source != 0xFF)
*dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha); *dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
} }
patch = (doompost_t *)((UINT8 *)patch + patch->length + 4);
} }
} }
@ -206,22 +189,19 @@ static inline void R_DrawBlendColumnInCache(doompost_t *patch, UINT8 *cache, tex
// R_DrawBlendFlippedColumnInCache // R_DrawBlendFlippedColumnInCache
// Similar to the one above except that the column is inverted. // Similar to the one above except that the column is inverted.
// //
static inline void R_DrawBlendFlippedColumnInCache(doompost_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) static inline void R_DrawBlendFlippedColumnInCache(column_t *column, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
{ {
INT32 count, position; INT32 count, position;
UINT8 *source, *dest; UINT8 *source, *dest;
INT32 topdelta, prevdelta = -1;
INT32 originy = originPatch->originy; INT32 originy = originPatch->originy;
INT32 topdelta;
while (patch->topdelta != 0xff) for (size_t i = 0; i < column->num_posts; i++)
{ {
topdelta = patch->topdelta; post_t *post = &column->posts[i];
if (topdelta <= prevdelta) topdelta = patchheight - post->length - post->topdelta;
topdelta += prevdelta; source = column->pixels + post->data_offset + post->length;
prevdelta = topdelta; count = post->length;
topdelta = patchheight-patch->length-topdelta;
source = (UINT8 *)patch + 2 + patch->length; // patch + 3 + (patch->length-1)
count = patch->length;
position = originy + topdelta; position = originy + topdelta;
if (position < 0) if (position < 0)
@ -241,8 +221,6 @@ static inline void R_DrawBlendFlippedColumnInCache(doompost_t *patch, UINT8 *cac
if (*source != 0xFF) if (*source != 0xFF)
*dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha); *dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
} }
patch = (doompost_t *)((UINT8 *)patch + patch->length + 4);
} }
} }
@ -380,7 +358,7 @@ UINT8 *R_GenerateTexture(size_t texnum)
// Composite the columns together. // Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
{ {
static void (*columnDrawer)(doompost_t *, UINT8 *, texpatch_t *, INT32, INT32); // Column drawing function pointer. static void (*columnDrawer)(column_t *, UINT8 *, texpatch_t *, INT32, INT32); // Column drawing function pointer.
if (patch->style != AST_COPY) if (patch->style != AST_COPY)
columnDrawer = (patch->flip & 2) ? R_DrawBlendFlippedColumnInCache : R_DrawBlendColumnInCache; columnDrawer = (patch->flip & 2) ? R_DrawBlendFlippedColumnInCache : R_DrawBlendColumnInCache;
else else
@ -388,42 +366,36 @@ UINT8 *R_GenerateTexture(size_t texnum)
UINT16 wadnum = patch->wad; UINT16 wadnum = patch->wad;
lumpnum_t lumpnum = patch->lump; lumpnum_t lumpnum = patch->lump;
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
UINT8 *pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); UINT8 *pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
softwarepatch_t *realpatch = (softwarepatch_t *)pdata; patch_t *realpatch = NULL;
boolean dealloc = true;
#ifndef NO_PNG_LUMPS #ifndef NO_PNG_LUMPS
if (Picture_IsLumpPNG((UINT8 *)realpatch, lumplength)) size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
realpatch = (softwarepatch_t *)Picture_PNGConvert((UINT8 *)realpatch, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, lumplength, NULL, 0); if (Picture_IsLumpPNG(pdata, lumplength))
realpatch = (patch_t *)Picture_PNGConvert(pdata, PICFMT_PATCH, NULL, NULL, NULL, NULL, lumplength, NULL, 0);
else else
#endif #endif
#ifdef WALLFLATS #ifdef WALLFLATS
if (texture->type == TEXTURETYPE_FLAT) if (texture->type == TEXTURETYPE_FLAT)
realpatch = (softwarepatch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_DOOMPATCH, 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
#endif #endif
{ realpatch = (patch_t *)Picture_Convert(PICFMT_DOOMPATCH, pdata, PICFMT_PATCH, 0, NULL, 0, 0, 0, 0, 0);
(void)lumplength;
dealloc = false;
}
x1 = patch->originx; x1 = patch->originx;
width = SHORT(realpatch->width); width = realpatch->width;
height = SHORT(realpatch->height); height = realpatch->height;
x2 = x1 + width; x2 = x1 + width;
if (x1 > texture->width || x2 < 0) if (x1 > texture->width || x2 < 0)
{ {
if (dealloc) Patch_Free(realpatch);
Z_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 (dealloc) Patch_Free(realpatch);
Z_Free(realpatch);
continue; // patch not located within texture's y bounds, ignore continue; // patch not located within texture's y bounds, ignore
} }
@ -442,17 +414,16 @@ UINT8 *R_GenerateTexture(size_t texnum)
for (; x < x2; x++) for (; x < x2; x++)
{ {
doompost_t *patchcol; column_t *patchcol;
if (patch->flip & 1) if (patch->flip & 1)
patchcol = (doompost_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[(x1+width-1)-x])); patchcol = &realpatch->columns[(x1+width-1)-x];
else else
patchcol = (doompost_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1])); patchcol = &realpatch->columns[x-x1];
columnDrawer(patchcol, columns[x].pixels, patch, texture->height, height); columnDrawer(patchcol, columns[x].pixels, patch, texture->height, height);
} }
if (dealloc) Patch_Free(realpatch);
Z_Free(realpatch);
} }
done: done:

View file

@ -2056,12 +2056,16 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
#ifndef NO_PNG_LUMPS #ifndef NO_PNG_LUMPS
if (Picture_IsLumpPNG((UINT8 *)lumpdata, len)) if (Picture_IsLumpPNG((UINT8 *)lumpdata, len))
ptr = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, len, &len, 0); {
ptr = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_PATCH, NULL, NULL, NULL, NULL, len, &len, 0);
Z_ChangeTag(ptr, tag);
Z_SetUser(ptr, &lumpcache[lump]);
return lumpcache[lump];
}
#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, len, dest);
Z_Free(ptr); Z_Free(ptr);
} }
else else