diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index ab9a50dd5..731c6b682 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -126,7 +126,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm { case 2 : // uhhhhhhhh.......... if ((originPatch != NULL) && (originPatch->style != AST_COPY)) - texel = ASTBlendPixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha); + texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha); texelu16 = (UINT16)((alpha<<8) | texel); memcpy(dest, &texelu16, sizeof(UINT16)); break; @@ -135,7 +135,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm { RGBA_t rgbatexel; rgbatexel.rgba = *(UINT32 *)dest; - colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); + colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); } memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); break; @@ -145,14 +145,14 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm { RGBA_t rgbatexel; rgbatexel.rgba = *(UINT32 *)dest; - colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); + 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 = ASTBlendPixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha); + *dest = ASTBlendPaletteIndexes(*dest, texel, originPatch->style, originPatch->alpha); else *dest = texel; break; @@ -238,7 +238,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, { case 2 : // uhhhhhhhh.......... if ((originPatch != NULL) && (originPatch->style != AST_COPY)) - texel = ASTBlendPixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha); + texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha); texelu16 = (UINT16)((alpha<<8) | texel); memcpy(dest, &texelu16, sizeof(UINT16)); break; @@ -247,7 +247,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, { RGBA_t rgbatexel; rgbatexel.rgba = *(UINT32 *)dest; - colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); + colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); } memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); break; @@ -257,14 +257,14 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, { RGBA_t rgbatexel; rgbatexel.rgba = *(UINT32 *)dest; - colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); + 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 = ASTBlendPixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha); + *dest = ASTBlendPaletteIndexes(*dest, texel, originPatch->style, originPatch->alpha); else *dest = texel; break; diff --git a/src/r_data.c b/src/r_data.c index b72214996..d10919d81 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -227,6 +227,8 @@ static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, tex } } +// Blends two pixels together, using the equation +// that matches the specified alpha style. UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha) { RGBA_t output; @@ -245,7 +247,13 @@ UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph // if the background pixel is empty, // match software and don't blend anything if (!background.s.alpha) - output.s.alpha = 0; + { + // ...unless the foreground pixel ISN'T actually translucent. + if (alpha == 0xFF) + output.rgba = foreground.rgba; + else + output.rgba = 0; + } else { UINT8 beta = (0xFF - alpha); @@ -302,18 +310,46 @@ UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph return 0; } -UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha) +INT32 ASTTextureBlendingThreshold[2] = {255/11, (10*255/11)}; + +// Blends a pixel for a texture patch. +UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha) { // Alpha style set to translucent? if (style == AST_TRANSLUCENT) { // Is the alpha small enough for translucency? - if (alpha <= (10*255/11)) + if (alpha <= ASTTextureBlendingThreshold[1]) + { + // Is the patch way too translucent? Don't blend then. + if (alpha < ASTTextureBlendingThreshold[0]) + return background.rgba; + + return ASTBlendPixel(background, foreground, style, alpha); + } + else // just copy the pixel + return foreground.rgba; + } + else + return ASTBlendPixel(background, foreground, style, alpha); +} + +// Blends two palette indexes for a texture patch, then +// finds the nearest palette index from the blended output. +UINT8 ASTBlendPaletteIndexes(UINT8 background, UINT8 foreground, int style, UINT8 alpha) +{ + // Alpha style set to translucent? + if (style == AST_TRANSLUCENT) + { + // Is the alpha small enough for translucency? + if (alpha <= ASTTextureBlendingThreshold[1]) { UINT8 *mytransmap; + // Is the patch way too translucent? Don't blend then. - if (alpha < 255/11) + if (alpha < ASTTextureBlendingThreshold[0]) return background; + // The equation's not exact but it works as intended. I'll call it a day for now. mytransmap = transtables + ((8*(alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT); if (background != 0xFF) @@ -378,7 +414,7 @@ static inline void R_DrawBlendColumnInCache(column_t *patch, UINT8 *cache, texpa { for (; dest < cache + position + count; source++, dest++) if (*source != 0xFF) - *dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha); + *dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha); } patch = (column_t *)((UINT8 *)patch + patch->length + 4); @@ -422,7 +458,7 @@ static inline void R_DrawBlendFlippedColumnInCache(column_t *patch, UINT8 *cache { for (; dest < cache + position + count; --source, dest++) if (*source != 0xFF) - *dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha); + *dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha); } patch = (column_t *)((UINT8 *)patch + patch->length + 4); diff --git a/src/r_data.h b/src/r_data.h index 78ce35a41..8b8d08c52 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -26,7 +26,10 @@ enum patchalphastyle {AST_COPY, AST_TRANSLUCENT, AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY}; UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha); -UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha); +UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha); +UINT8 ASTBlendPaletteIndexes(UINT8 background, UINT8 foreground, int style, UINT8 alpha); + +extern INT32 ASTTextureBlendingThreshold[2]; UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);