mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-24 18:21:34 +00:00
Refactor Picture_PatchConvert, so that it no longer makes Doom patches
This commit is contained in:
parent
821460d208
commit
0088326ff0
4 changed files with 151 additions and 325 deletions
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
113
src/r_textures.c
113
src/r_textures.c
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue