From 0088326ff028effcca30ded4d45af257d7c2a7d2 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Tue, 1 Aug 2023 12:58:01 -0300 Subject: [PATCH] Refactor Picture_PatchConvert, so that it no longer makes Doom patches --- src/hardware/hw_cache.c | 168 ++++++------------------------------ src/r_picformats.c | 187 +++++++++++++++++----------------------- src/r_textures.c | 113 +++++++++--------------- src/w_wad.c | 8 +- 4 files changed, 151 insertions(+), 325 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 50e4adfac..8ac5b0ec8 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -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); - 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) diff --git a/src/r_picformats.c b/src/r_picformats.c index c7be4ea22..b11eae138 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -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. diff --git a/src/r_textures.c b/src/r_textures.c index 5896ab30d..4021dc916 100644 --- a/src/r_textures.c +++ b/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: diff --git a/src/w_wad.c b/src/w_wad.c index 171eab4f3..099b9381d 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -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