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,
fixed_t yfracstep, fixed_t scale_y,
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;
UINT8 *dest;
const UINT8 *source;
INT32 topdelta, prevdelta = -1;
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 topdelta;
INT32 originy = 0;
// 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
originy = originPatch->originy;
while (patchcol->topdelta != 0xff)
for (size_t i = 0; i < patchcol->num_posts; i++)
{
topdelta = patchcol->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
topdelta = patchheight-patchcol->length-topdelta;
source = (const UINT8 *)patchcol + 3;
count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS;
post_t *post = &patchcol->posts[i];
source = patchcol->pixels + post->data_offset;
topdelta = patchheight-post->length-post->topdelta;
count = ((post->length * scale_y) + (FRACUNIT/2)) >> FRACBITS;
position = originy + topdelta;
yfrac = (patchcol->length-1) << FRACBITS;
yfrac = (post->length-1) << FRACBITS;
if (position < 0)
{
@ -361,7 +249,6 @@ static void HWR_DrawFlippedPostsInCache(const doompost_t *patchcol, UINT8 *block
dest += blockmodulo;
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,
INT32 pblockwidth, INT32 pblockheight,
texture_t *texture, texpatch_t *patch,
const softwarepatch_t *realpatch)
const patch_t *realpatch)
{
INT32 x, x1, x2;
INT32 col, ncols;
fixed_t xfrac, xfracstep;
fixed_t yfracstep, scale_y;
const doompost_t *patchcol;
const column_t *patchcol;
UINT8 *block = mipmap->data;
INT32 bpp;
INT32 blockmodulo;
INT32 width, height;
// 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,
fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight,
@ -440,11 +327,11 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
if (texture->width <= 0 || texture->height <= 0)
return;
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedPostsInCache : HWR_DrawPostsInCache;
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache;
x1 = patch->originx;
width = SHORT(realpatch->width);
height = SHORT(realpatch->height);
width = realpatch->width;
height = realpatch->height;
x2 = x1 + width;
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)
{
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
patchcol = (const doompost_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS]));
patchcol = &realpatch->columns[xfrac>>FRACBITS];
ColumnDrawerPointer(patchcol, block, mipmap,
pblockheight, blockmodulo,
@ -537,8 +424,6 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
UINT8 *block;
texture_t *texture;
texpatch_t *patch;
softwarepatch_t *realpatch;
UINT8 *pdata;
INT32 blockwidth, blockheight, blocksize;
INT32 i;
@ -590,30 +475,25 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
// Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
{
boolean dealloc = true;
size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump);
pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
realpatch = (softwarepatch_t *)pdata;
UINT8 *pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
patch_t *realpatch = NULL;
#ifndef NO_PNG_LUMPS
if (Picture_IsLumpPNG((UINT8 *)realpatch, lumplength))
realpatch = (softwarepatch_t *)Picture_PNGConvert(pdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, lumplength, NULL, 0);
size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump);
if (Picture_IsLumpPNG(pdata, lumplength))
realpatch = (patch_t *)Picture_PNGConvert(pdata, PICFMT_PATCH, NULL, NULL, NULL, NULL, lumplength, NULL, 0);
else
#endif
#ifdef WALLFLATS
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
#endif
{
(void)lumplength;
dealloc = false;
}
realpatch = (patch_t *)Picture_Convert(PICFMT_DOOMPATCH, pdata, PICFMT_PATCH, 0, NULL, 0, 0, 0, 0, 0);
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch);
if (dealloc)
Z_Unlock(realpatch);
Patch_Free(realpatch);
}
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
if (format2bpp(grtex->mipmap.format)==4)

View file

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

View file

@ -78,24 +78,20 @@ static INT32 tidcachelen = 0;
// R_DrawColumnInCache
// 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;
UINT8 *source;
INT32 topdelta, prevdelta = -1;
INT32 originy = originPatch->originy;
(void)patchheight; // This parameter is unused
while (patch->topdelta != 0xff)
for (size_t i = 0; i < column->num_posts; i++)
{
topdelta = patch->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
source = (UINT8 *)patch + 3;
count = patch->length;
position = originy + topdelta;
post_t *post = &column->posts[i];
source = column->pixels + post->data_offset;
count = post->length;
position = originy + post->topdelta;
if (position < 0)
{
@ -109,8 +105,6 @@ static inline void R_DrawColumnInCache(doompost_t *patch, UINT8 *cache, texpatch
if (count > 0)
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
// 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;
UINT8 *source, *dest;
INT32 topdelta, prevdelta = -1;
INT32 originy = originPatch->originy;
INT32 topdelta;
while (patch->topdelta != 0xff)
for (size_t i = 0; i < column->num_posts; i++)
{
topdelta = patch->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
topdelta = patchheight-patch->length-topdelta;
source = (UINT8 *)patch + 2 + patch->length; // patch + 3 + (patch->length-1)
count = patch->length;
post_t *post = &column->posts[i];
topdelta = patchheight - post->length - post->topdelta;
source = column->pixels + post->data_offset + post->length;
count = post->length;
position = originy + topdelta;
if (position < 0)
@ -152,33 +143,27 @@ static inline void R_DrawFlippedColumnInCache(doompost_t *patch, UINT8 *cache, t
for (; dest < cache + position + count; --source)
*dest++ = *source;
}
patch = (doompost_t *)((UINT8 *)patch + patch->length + 4);
}
}
//
// 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;
UINT8 *source, *dest;
INT32 topdelta, prevdelta = -1;
INT32 originy = originPatch->originy;
(void)patchheight; // This parameter is unused
while (patch->topdelta != 0xff)
for (size_t i = 0; i < column->num_posts; i++)
{
topdelta = patch->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
source = (UINT8 *)patch + 3;
count = patch->length;
position = originy + topdelta;
post_t *post = &column->posts[i];
source = column->pixels + post->data_offset;
count = post->length;
position = originy + post->topdelta;
if (position < 0)
{
@ -197,8 +182,6 @@ static inline void R_DrawBlendColumnInCache(doompost_t *patch, UINT8 *cache, tex
if (*source != 0xFF)
*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
// 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;
UINT8 *source, *dest;
INT32 topdelta, prevdelta = -1;
INT32 originy = originPatch->originy;
INT32 topdelta;
while (patch->topdelta != 0xff)
for (size_t i = 0; i < column->num_posts; i++)
{
topdelta = patch->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
topdelta = patchheight-patch->length-topdelta;
source = (UINT8 *)patch + 2 + patch->length; // patch + 3 + (patch->length-1)
count = patch->length;
post_t *post = &column->posts[i];
topdelta = patchheight - post->length - post->topdelta;
source = column->pixels + post->data_offset + post->length;
count = post->length;
position = originy + topdelta;
if (position < 0)
@ -241,8 +221,6 @@ static inline void R_DrawBlendFlippedColumnInCache(doompost_t *patch, UINT8 *cac
if (*source != 0xFF)
*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.
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)
columnDrawer = (patch->flip & 2) ? R_DrawBlendFlippedColumnInCache : R_DrawBlendColumnInCache;
else
@ -388,42 +366,36 @@ UINT8 *R_GenerateTexture(size_t texnum)
UINT16 wadnum = patch->wad;
lumpnum_t lumpnum = patch->lump;
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
UINT8 *pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
softwarepatch_t *realpatch = (softwarepatch_t *)pdata;
boolean dealloc = true;
patch_t *realpatch = NULL;
#ifndef NO_PNG_LUMPS
if (Picture_IsLumpPNG((UINT8 *)realpatch, lumplength))
realpatch = (softwarepatch_t *)Picture_PNGConvert((UINT8 *)realpatch, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, lumplength, NULL, 0);
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
if (Picture_IsLumpPNG(pdata, lumplength))
realpatch = (patch_t *)Picture_PNGConvert(pdata, PICFMT_PATCH, NULL, NULL, NULL, NULL, lumplength, NULL, 0);
else
#endif
#ifdef WALLFLATS
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
#endif
{
(void)lumplength;
dealloc = false;
}
realpatch = (patch_t *)Picture_Convert(PICFMT_DOOMPATCH, pdata, PICFMT_PATCH, 0, NULL, 0, 0, 0, 0, 0);
x1 = patch->originx;
width = SHORT(realpatch->width);
height = SHORT(realpatch->height);
width = realpatch->width;
height = realpatch->height;
x2 = x1 + width;
if (x1 > texture->width || x2 < 0)
{
if (dealloc)
Z_Free(realpatch);
Patch_Free(realpatch);
continue; // patch not located within texture's x bounds, ignore
}
if (patch->originy > texture->height || (patch->originy + height) < 0)
{
if (dealloc)
Z_Free(realpatch);
Patch_Free(realpatch);
continue; // patch not located within texture's y bounds, ignore
}
@ -442,17 +414,16 @@ UINT8 *R_GenerateTexture(size_t texnum)
for (; x < x2; x++)
{
doompost_t *patchcol;
column_t *patchcol;
if (patch->flip & 1)
patchcol = (doompost_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[(x1+width-1)-x]));
patchcol = &realpatch->columns[(x1+width-1)-x];
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);
}
if (dealloc)
Z_Free(realpatch);
Patch_Free(realpatch);
}
done:

View file

@ -2056,12 +2056,16 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
#ifndef NO_PNG_LUMPS
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
dest = Z_Calloc(sizeof(patch_t), tag, &lumpcache[lump]);
Patch_Create(ptr, len, dest);
Z_Free(ptr);
}
else