From 30a00c812cbefb6292eadf8ef8eceb16001f2880 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 13 Feb 2019 16:39:37 +0000 Subject: [PATCH 1/7] Split the column caching code of HWR_DrawPatchInCache into a new function, HWR_DrawColumnInCache. This should make modifying the OpenGL caching code look a little less daunting, hopefully. I also removed some "const"s for now, since I wasn't sure if they were needed or even correct to use or not here... if they're fine I could add them back later though. (Note: I have not tested if this compiles yet) --- src/hardware/hw_cache.c | 194 ++++++++++++++++++++++------------------ 1 file changed, 108 insertions(+), 86 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 395fc2e4b..f42441133 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -41,26 +41,114 @@ static INT32 blocksize, blockwidth, blockheight; INT32 patchformat = GR_TEXFMT_AP_88; // use alpha for holes INT32 textureformat = GR_TEXFMT_P_8; // use chromakey for hole + +// This code was originally placed directly in HWR_DrawPatchInCache. +// It is now split from it for my sanity! (and the sanity of others) +// -- Monster Iestyn (13/02/19) +static void HWR_DrawColumnInCache(column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap, + INT32 pblockwidth, INT32 pblockheight, INT32 blockmodulo, + fixed_t yfracstep, fixed_t scale_y, + INT32 originy, + INT32 bpp + ) +{ + fixed_t yfrac, position, count; + UINT8 *dest; + UINT8 *source; + INT32 topdelta, prevdelta = -1; + + // for writing a pixel to dest + RGBA_t colortemp; + UINT8 alpha; + UINT8 texel; + UINT16 texelu16; + + while (patchcol->topdelta != 0xff) + { + topdelta = patchcol->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + source = (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]; + + if (firetranslucent && (transtables[(texel<<8)+0x40000]!=texel)) + alpha = 0x80; + else + alpha = 0xff; + + //Hurdler: not perfect, but better than holes + if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED)) + texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX; + //Hurdler: 25/04/2000: now support colormap in hardware mode + else if (mipmap->colormap) + texel = mipmap->colormap[texel]; + + // hope compiler will get this switch out of the loops (dreams...) + // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) + // Alam: SRB2 uses Mingw, HUGS + switch (bpp) + { + case 2 : texelu16 = (UINT16)((alpha<<8) | texel); + memcpy(dest, &texelu16, sizeof(UINT16)); + break; + case 3 : colortemp = V_GetColor(texel); + memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); + break; + case 4 : colortemp = V_GetColor(texel); + colortemp.s.alpha = alpha; + memcpy(dest, &colortemp, sizeof(RGBA_t)); + break; + // default is 1 + default: *dest = texel; + break; + } + + dest += blockmodulo; + yfrac += yfracstep; + } + patchcol = (column_t *)((UINT8 *)patchcol + patchcol->length + 4); + } +} + + // sprite, use alpha and chroma key for hole static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32 pblockheight, INT32 blockmodulo, INT32 ptexturewidth, INT32 ptextureheight, INT32 originx, INT32 originy, // where to draw patch in surface block - const patch_t *realpatch, INT32 bpp) + patch_t *realpatch, INT32 bpp) { INT32 x, x1, x2; INT32 col, ncols; fixed_t xfrac, xfracstep; - fixed_t yfrac, yfracstep, position, count; - fixed_t scale_y; - RGBA_t colortemp; - UINT8 *dest; - const UINT8 *source; - const column_t *patchcol; - UINT8 alpha; + column_t *patchcol; UINT8 *block = mipmap->grInfo.data; - UINT8 texel; - UINT16 texelu16; if (!ptexturewidth) return; @@ -107,88 +195,22 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, xfracstep = (ptexturewidth << FRACBITS) / pblockwidth; yfracstep = (ptextureheight<< FRACBITS) / pblockheight; + scale_y = (pblockheight << FRACBITS) / ptextureheight; + if (bpp < 1 || bpp > 4) I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp); + // Draw each column to the block cache for (block += col*bpp; ncols--; block += bpp, xfrac += xfracstep) { - INT32 topdelta, prevdelta = -1; - patchcol = (const column_t *)((const UINT8 *)realpatch - + LONG(realpatch->columnofs[xfrac>>FRACBITS])); + patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS])); - scale_y = (pblockheight << FRACBITS) / ptextureheight; - - 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]; - - if (firetranslucent && (transtables[(texel<<8)+0x40000]!=texel)) - alpha = 0x80; - else - alpha = 0xff; - - //Hurdler: not perfect, but better than holes - if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED)) - texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX; - //Hurdler: 25/04/2000: now support colormap in hardware mode - else if (mipmap->colormap) - texel = mipmap->colormap[texel]; - - // hope compiler will get this switch out of the loops (dreams...) - // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) - // Alam: SRB2 uses Mingw, HUGS - switch (bpp) - { - case 2 : texelu16 = (UINT16)((alpha<<8) | texel); - memcpy(dest, &texelu16, sizeof(UINT16)); - break; - case 3 : colortemp = V_GetColor(texel); - memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); - break; - case 4 : colortemp = V_GetColor(texel); - colortemp.s.alpha = alpha; - memcpy(dest, &colortemp, sizeof(RGBA_t)); - break; - // default is 1 - default: *dest = texel; - break; - } - - dest += blockmodulo; - yfrac += yfracstep; - } - patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4); - } + HWR_DrawColumnInCache(patchcol, block, mipmap, + pblockwidth, ptextureheight, blockmodulo, + yfracstep, scale_y, + originy, + bpp + ); } } From efa042a995d4c54115a55c15785b4bb32eb4bc7d Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 13 Feb 2019 16:52:51 +0000 Subject: [PATCH 2/7] whoops, removed some variables I shouldn't have, so I've added them back --- src/hardware/hw_cache.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index f42441133..5dc250879 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -147,6 +147,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, INT32 x, x1, x2; INT32 col, ncols; fixed_t xfrac, xfracstep; + fixed_t yfracstep, scale_y; column_t *patchcol; UINT8 *block = mipmap->grInfo.data; From ff2ebf20fb22d18deb6d16c5e6af4b24ad775004 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 13 Feb 2019 17:27:20 +0000 Subject: [PATCH 3/7] blockmodulo and bpp do not need to be args of HWR_DrawPatchInCache --- src/hardware/hw_cache.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 5dc250879..ef95dbbf0 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -139,10 +139,10 @@ static void HWR_DrawColumnInCache(column_t *patchcol, UINT8 *block, GLMipmap_t * // sprite, use alpha and chroma key for hole static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, - INT32 pblockwidth, INT32 pblockheight, INT32 blockmodulo, + INT32 pblockwidth, INT32 pblockheight, INT32 ptexturewidth, INT32 ptextureheight, INT32 originx, INT32 originy, // where to draw patch in surface block - patch_t *realpatch, INT32 bpp) + patch_t *realpatch) { INT32 x, x1, x2; INT32 col, ncols; @@ -150,6 +150,8 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, fixed_t yfracstep, scale_y; column_t *patchcol; UINT8 *block = mipmap->grInfo.data; + INT32 bpp; + INT32 blockmodulo; if (!ptexturewidth) return; @@ -198,9 +200,13 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, yfracstep = (ptextureheight<< FRACBITS) / pblockheight; scale_y = (pblockheight << FRACBITS) / ptextureheight; + bpp = format2bpp[mipmap->grInfo.format]; + if (bpp < 1 || bpp > 4) I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp); + blockmodulo = blockwidth*bpp; + // Draw each column to the block cache for (block += col*bpp; ncols--; block += bpp, xfrac += xfracstep) { @@ -477,11 +483,9 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); HWR_DrawPatchInCache(&grtex->mipmap, blockwidth, blockheight, - blockwidth*format2bpp[grtex->mipmap.grInfo.format], texture->width, texture->height, patch->originx, patch->originy, - realpatch, - format2bpp[grtex->mipmap.grInfo.format]); + realpatch); Z_Unlock(realpatch); } //Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :( @@ -568,11 +572,9 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm HWR_DrawPatchInCache(grMipmap, newwidth, newheight, - blockwidth*format2bpp[grMipmap->grInfo.format], grPatch->width, grPatch->height, 0, 0, - patch, - format2bpp[grMipmap->grInfo.format]); + patch); } grPatch->max_s = (float)newwidth / (float)blockwidth; From 497e79d1defc10210d713d78fc87827b661e9005 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 13 Feb 2019 18:20:26 +0000 Subject: [PATCH 4/7] Turns out the consts ARE needed after all, also fix some other errors the compiler reported --- src/hardware/hw_cache.c | 57 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index ef95dbbf0..de4d6582b 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -41,12 +41,31 @@ static INT32 blocksize, blockwidth, blockheight; INT32 patchformat = GR_TEXFMT_AP_88; // use alpha for holes INT32 textureformat = GR_TEXFMT_P_8; // use chromakey for hole +static const INT32 format2bpp[16] = +{ + 0, //0 + 0, //1 + 1, //2 GR_TEXFMT_ALPHA_8 + 1, //3 GR_TEXFMT_INTENSITY_8 + 1, //4 GR_TEXFMT_ALPHA_INTENSITY_44 + 1, //5 GR_TEXFMT_P_8 + 4, //6 GR_RGBA + 0, //7 + 0, //8 + 0, //9 + 2, //10 GR_TEXFMT_RGB_565 + 2, //11 GR_TEXFMT_ARGB_1555 + 2, //12 GR_TEXFMT_ARGB_4444 + 2, //13 GR_TEXFMT_ALPHA_INTENSITY_88 + 2, //14 GR_TEXFMT_AP_88 +}; + // This code was originally placed directly in HWR_DrawPatchInCache. // It is now split from it for my sanity! (and the sanity of others) // -- Monster Iestyn (13/02/19) -static void HWR_DrawColumnInCache(column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap, - INT32 pblockwidth, INT32 pblockheight, INT32 blockmodulo, +static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap, + INT32 pblockheight, INT32 blockmodulo, fixed_t yfracstep, fixed_t scale_y, INT32 originy, INT32 bpp @@ -54,7 +73,7 @@ static void HWR_DrawColumnInCache(column_t *patchcol, UINT8 *block, GLMipmap_t * { fixed_t yfrac, position, count; UINT8 *dest; - UINT8 *source; + const UINT8 *source; INT32 topdelta, prevdelta = -1; // for writing a pixel to dest @@ -69,7 +88,7 @@ static void HWR_DrawColumnInCache(column_t *patchcol, UINT8 *block, GLMipmap_t * if (topdelta <= prevdelta) topdelta += prevdelta; prevdelta = topdelta; - source = (UINT8 *)patchcol + 3; + source = (const UINT8 *)patchcol + 3; count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS; position = originy + topdelta; @@ -132,7 +151,7 @@ static void HWR_DrawColumnInCache(column_t *patchcol, UINT8 *block, GLMipmap_t * dest += blockmodulo; yfrac += yfracstep; } - patchcol = (column_t *)((UINT8 *)patchcol + patchcol->length + 4); + patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4); } } @@ -142,13 +161,13 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32 pblockheight, INT32 ptexturewidth, INT32 ptextureheight, INT32 originx, INT32 originy, // where to draw patch in surface block - patch_t *realpatch) + const patch_t *realpatch) { INT32 x, x1, x2; INT32 col, ncols; fixed_t xfrac, xfracstep; fixed_t yfracstep, scale_y; - column_t *patchcol; + const column_t *patchcol; UINT8 *block = mipmap->grInfo.data; INT32 bpp; INT32 blockmodulo; @@ -210,10 +229,10 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, // Draw each column to the block cache for (block += col*bpp; ncols--; block += bpp, xfrac += xfracstep) { - patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS])); + patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS])); HWR_DrawColumnInCache(patchcol, block, mipmap, - pblockwidth, ptextureheight, blockmodulo, + ptextureheight, blockmodulo, yfracstep, scale_y, originy, bpp @@ -378,26 +397,6 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, //CONS_Debug(DBG_RENDER, "Width is %d, Height is %d\n", blockwidth, blockheight); } - -static const INT32 format2bpp[16] = -{ - 0, //0 - 0, //1 - 1, //2 GR_TEXFMT_ALPHA_8 - 1, //3 GR_TEXFMT_INTENSITY_8 - 1, //4 GR_TEXFMT_ALPHA_INTENSITY_44 - 1, //5 GR_TEXFMT_P_8 - 4, //6 GR_RGBA - 0, //7 - 0, //8 - 0, //9 - 2, //10 GR_TEXFMT_RGB_565 - 2, //11 GR_TEXFMT_ARGB_1555 - 2, //12 GR_TEXFMT_ARGB_4444 - 2, //13 GR_TEXFMT_ALPHA_INTENSITY_88 - 2, //14 GR_TEXFMT_AP_88 -}; - static UINT8 *MakeBlock(GLMipmap_t *grMipmap) { UINT8 *block; From d2c6b995d31dba7584f56ecb666aacaf545343eb Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 13 Feb 2019 20:12:10 +0000 Subject: [PATCH 5/7] split HWR_DrawPatchInCache into two functions: one for texture patches and one for everything else --- src/hardware/hw_cache.c | 59 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index de4d6582b..1e095af7c 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -156,8 +156,59 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm } -// sprite, use alpha and chroma key for hole +// Simplified patch caching function +// for use by sprites and other patches that are not part of a wall texture +// no alpha or flipping should be present since we do not want non-texture graphics to have them +// no offsets are used either +// -- Monster Iestyn (13/02/19) static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, + INT32 pblockwidth, INT32 pblockheight, + INT32 pwidth, INT32 pheight, + const patch_t *realpatch) +{ + INT32 ncols; + fixed_t xfrac, xfracstep; + fixed_t yfracstep, scale_y; + const column_t *patchcol; + UINT8 *block = mipmap->grInfo.data; + INT32 bpp; + INT32 blockmodulo; + + if (pwidth <= 0 || pheight <= 0) + return; + + ncols = (pwidth * pblockwidth) / pwidth; + + // source advance + xfrac = 0; + xfracstep = (pwidth << FRACBITS) / pblockwidth; + yfracstep = (pheight << FRACBITS) / pblockheight; + scale_y = (pblockheight << FRACBITS) / pheight; + + bpp = format2bpp[mipmap->grInfo.format]; + + if (bpp < 1 || bpp > 4) + I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp); + + // NOTE: should this actually be pblockwidth*bpp? + blockmodulo = blockwidth*bpp; + + // Draw each column to the block cache + for (; ncols--; block += bpp, xfrac += xfracstep) + { + patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS])); + + HWR_DrawColumnInCache(patchcol, block, mipmap, + pheight, blockmodulo, + yfracstep, scale_y, + 0, + bpp + ); + } +} + +// This function we use for caching patches that belong to textures +static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32 pblockheight, INT32 ptexturewidth, INT32 ptextureheight, INT32 originx, INT32 originy, // where to draw patch in surface block @@ -172,7 +223,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, INT32 bpp; INT32 blockmodulo; - if (!ptexturewidth) + if (ptexturewidth <= 0 || ptextureheight <= 0) return; x1 = originx; @@ -224,6 +275,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, if (bpp < 1 || bpp > 4) I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp); + // NOTE: should this actually be pblockwidth*bpp? blockmodulo = blockwidth*bpp; // Draw each column to the block cache @@ -480,7 +532,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); - HWR_DrawPatchInCache(&grtex->mipmap, + HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture->width, texture->height, patch->originx, patch->originy, @@ -572,7 +624,6 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm HWR_DrawPatchInCache(grMipmap, newwidth, newheight, grPatch->width, grPatch->height, - 0, 0, patch); } From 7321df801576b46f05c30695bbdbe72ad9f5438b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 13 Feb 2019 20:56:59 +0000 Subject: [PATCH 6/7] some more mucking about with function arguments (preparing for alpha/flip support adding particularly), also fixed a slipup I made when I first made HWR_DrawColumnInCache --- src/hardware/hw_cache.c | 67 +++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 1e095af7c..e90ee944d 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -67,14 +67,14 @@ static const INT32 format2bpp[16] = static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap, INT32 pblockheight, INT32 blockmodulo, fixed_t yfracstep, fixed_t scale_y, - INT32 originy, - INT32 bpp - ) + texpatch_t *originPatch, INT32 patchheight, + INT32 bpp) { 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; @@ -82,6 +82,11 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm 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; @@ -199,19 +204,17 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS])); HWR_DrawColumnInCache(patchcol, block, mipmap, - pheight, blockmodulo, + pblockheight, blockmodulo, yfracstep, scale_y, - 0, - bpp - ); + NULL, pheight, // not that pheight is going to get used anyway... + bpp); } } // This function we use for caching patches that belong to textures static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32 pblockheight, - INT32 ptexturewidth, INT32 ptextureheight, - INT32 originx, INT32 originy, // where to draw patch in surface block + texture_t *texture, texpatch_t *patch, const patch_t *realpatch) { INT32 x, x1, x2; @@ -222,17 +225,20 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, UINT8 *block = mipmap->grInfo.data; INT32 bpp; INT32 blockmodulo; + INT32 width, height; - if (ptexturewidth <= 0 || ptextureheight <= 0) + if (texture->width <= 0 || texture->height <= 0) return; - x1 = originx; - x2 = x1 + SHORT(realpatch->width); + x1 = patch->originx; + width = SHORT(realpatch->width); + height = SHORT(realpatch->height); + x2 = x1 + width; - if (x1 > ptexturewidth || x2 < 0) + if (x1 > texture->width || x2 < 0) return; // patch not located within texture's x bounds, ignore - if (originy > ptextureheight || (originy + SHORT(realpatch->height)) < 0) + if (patch->originy > texture->height || (patch->originy + height) < 0) return; // patch not located within texture's y bounds, ignore // patch is actually inside the texture! @@ -245,19 +251,18 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, x = x1; // right edge - if (x2 > ptexturewidth) - x2 = ptexturewidth; + if (x2 > texture->width) + x2 = texture->width; - col = x * pblockwidth / ptexturewidth; - ncols = ((x2 - x) * pblockwidth) / ptexturewidth; + col = x * pblockwidth / texture->width; + ncols = ((x2 - x) * pblockwidth) / texture->width; /* - CONS_Debug(DBG_RENDER, "patch %dx%d texture %dx%d block %dx%d\n", SHORT(realpatch->width), - SHORT(realpatch->height), - ptexturewidth, - textureheight, - pblockwidth,pblockheight); + CONS_Debug(DBG_RENDER, "patch %dx%d texture %dx%d block %dx%d\n", + width, height, + texture->width, texture->height, + pblockwidth, pblockheight); CONS_Debug(DBG_RENDER, " col %d ncols %d x %d\n", col, ncols, x); */ @@ -266,9 +271,9 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, if (x1 < 0) xfrac = -x1<width << FRACBITS) / pblockwidth; + yfracstep = (texture->height<< FRACBITS) / pblockheight; + scale_y = (pblockheight << FRACBITS) / texture->height; bpp = format2bpp[mipmap->grInfo.format]; @@ -284,11 +289,10 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS])); HWR_DrawColumnInCache(patchcol, block, mipmap, - ptextureheight, blockmodulo, + pblockheight, blockmodulo, yfracstep, scale_y, - originy, - bpp - ); + patch, height, + bpp); } } @@ -534,8 +538,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, - texture->width, texture->height, - patch->originx, patch->originy, + texture, patch, realpatch); Z_Unlock(realpatch); } From cb986bf1c068705d05a82c536f9fbc17d1f3ae07 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 13 Feb 2019 22:40:48 +0000 Subject: [PATCH 7/7] added support for both horizontal and vertical flipping (not sure if complete or not atm, but I've done enough for tonight I think) --- src/hardware/hw_cache.c | 119 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index e90ee944d..6bc2c712e 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -160,6 +160,101 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm } } +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, + INT32 bpp) +{ + 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; + + 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; + topdelta = patchheight-patchcol->length-topdelta; + source = (const UINT8 *)patchcol + 3; + count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS; + position = originy + topdelta; + + yfrac = (patchcol->length-1) << FRACBITS; + + 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]; + + if (firetranslucent && (transtables[(texel<<8)+0x40000]!=texel)) + alpha = 0x80; + else + alpha = 0xff; + + //Hurdler: not perfect, but better than holes + if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED)) + texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX; + //Hurdler: 25/04/2000: now support colormap in hardware mode + else if (mipmap->colormap) + texel = mipmap->colormap[texel]; + + // hope compiler will get this switch out of the loops (dreams...) + // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) + // Alam: SRB2 uses Mingw, HUGS + switch (bpp) + { + case 2 : texelu16 = (UINT16)((alpha<<8) | texel); + memcpy(dest, &texelu16, sizeof(UINT16)); + break; + case 3 : colortemp = V_GetColor(texel); + memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); + break; + case 4 : colortemp = V_GetColor(texel); + colortemp.s.alpha = alpha; + memcpy(dest, &colortemp, sizeof(RGBA_t)); + break; + // default is 1 + default: *dest = texel; + break; + } + + dest += blockmodulo; + yfrac -= yfracstep; + } + patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4); + } +} + // Simplified patch caching function // for use by sprites and other patches that are not part of a wall texture @@ -226,10 +321,27 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, INT32 bpp; INT32 blockmodulo; INT32 width, height; + // Column drawing function pointer. + 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, + INT32 bpp); if (texture->width <= 0 || texture->height <= 0) return; + /*if ((patch->style == AST_TRANSLUCENT) && (patch->alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency? + { + if (patch->alpha < 255/11) // Is the patch way too translucent? Don't render then. + continue; + ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawTransFlippedColumnInCache : HWR_DrawTransColumnInCache; + } + else*/ + { + ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache; + } + x1 = patch->originx; width = SHORT(realpatch->width); height = SHORT(realpatch->height); @@ -286,9 +398,12 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, // Draw each column to the block cache for (block += col*bpp; ncols--; block += bpp, xfrac += xfracstep) { - patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS])); + if (patch->flip & 1) + patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[(width-1)-(xfrac>>FRACBITS)])); + else + patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS])); - HWR_DrawColumnInCache(patchcol, block, mipmap, + ColumnDrawerPointer(patchcol, block, mipmap, pblockheight, blockmodulo, yfracstep, scale_y, patch, height,