diff --git a/src/r_draw.h b/src/r_draw.h index 60c3c9db6..4a105b5b0 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -162,6 +162,7 @@ void R_DrawSplat_8(void); void R_DrawTranslucentSplat_8(void); void R_DrawTranslucentSpan_8(void); void R_Draw2sMultiPatchColumn_8(void); +void R_Draw2sMultiPatchTranslucentColumn_8(void); void R_DrawFogSpan_8(void); void R_DrawFogColumn_8(void); void R_DrawColumnShadowed_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index c1b7da11b..9340b61c6 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -203,6 +203,103 @@ void R_Draw2sMultiPatchColumn_8(void) } } +void R_Draw2sMultiPatchTranslucentColumn_8(void) +{ + INT32 count; + register UINT8 *dest; + register fixed_t frac; + fixed_t fracstep; + + count = dc_yh - dc_yl; + + if (count < 0) // Zero length, column does not exceed a pixel. + return; + +#ifdef RANGECHECK + if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) + return; +#endif + + // Framebuffer destination address. + // Use ylookup LUT to avoid multiply with ScreenWidth. + // Use columnofs LUT for subwindows? + + //dest = ylookup[dc_yl] + columnofs[dc_x]; + dest = &topleft[dc_yl*vid.width + dc_x]; + + count++; + + // Determine scaling, which is the only mapping to be done. + fracstep = dc_iscale; + //frac = dc_texturemid + (dc_yl - centery)*fracstep; + frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + + // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. + // This is as fast as it gets. + { + register const UINT8 *source = dc_source; + register const UINT8 *transmap = dc_transmap; + register const lighttable_t *colormap = dc_colormap; + register INT32 heightmask = dc_texheight-1; + register UINT8 val; + if (dc_texheight & heightmask) // not a power of 2 -- killough + { + heightmask++; + heightmask <<= FRACBITS; + + if (frac < 0) + while ((frac += heightmask) < 0); + else + while (frac >= heightmask) + frac -= heightmask; + + do + { + // Re-map color indices from wall texture column + // using a lighting/special effects LUT. + // heightmask is the Tutti-Frutti fix + val = source[frac>>FRACBITS]; + + if (val != TRANSPARENTPIXEL) + *dest = colormap[*(transmap + (val<<8) + (*dest))]; + + dest += vid.width; + + // Avoid overflow. + if (fracstep > 0x7FFFFFFF - frac) + frac += fracstep - heightmask; + else + frac += fracstep; + + while (frac >= heightmask) + frac -= heightmask; + } while (--count); + } + else + { + while ((count -= 2) >= 0) // texture height is a power of 2 + { + val = source[(frac>>FRACBITS) & heightmask]; + if (val != TRANSPARENTPIXEL) + *dest = colormap[*(transmap + (val<<8) + (*dest))]; + dest += vid.width; + frac += fracstep; + val = source[(frac>>FRACBITS) & heightmask]; + if (val != TRANSPARENTPIXEL) + *dest = colormap[*(transmap + (val<<8) + (*dest))]; + dest += vid.width; + frac += fracstep; + } + if (count & 1) + { + val = source[(frac>>FRACBITS) & heightmask]; + if (val != TRANSPARENTPIXEL) + *dest = colormap[*(transmap + (val<<8) + (*dest))]; + } + } + } +} + /** \brief The R_DrawShadeColumn_8 function Experiment to make software go faster. Taken from the Boom source */ diff --git a/src/r_segs.c b/src/r_segs.c index 257be2989..3bd8b94c1 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -271,6 +271,8 @@ static void R_Render2sidedMultiPatchColumn(column_t *column) if (colfunc == wallcolfunc) twosmultipatchfunc(); + else if (colfunc == fuzzcolfunc) + twosmultipatchtransfunc(); else colfunc(); } diff --git a/src/screen.c b/src/screen.c index d00155785..97c865a97 100644 --- a/src/screen.c +++ b/src/screen.c @@ -49,6 +49,7 @@ void (*splatfunc)(void); // span drawer w/ transparency void (*basespanfunc)(void); // default span func for color mode void (*transtransfunc)(void); // translucent translated column drawer void (*twosmultipatchfunc)(void); // for cols with transparent pixels +void (*twosmultipatchtransfunc)(void); // for cols with transparent pixels AND translucency // ------------------ // global video state @@ -127,6 +128,7 @@ void SCR_SetMode(void) fuzzcolfunc = R_DrawTranslucentColumn_8; walldrawerfunc = R_DrawWallColumn_8; twosmultipatchfunc = R_Draw2sMultiPatchColumn_8; + twosmultipatchtransfunc = R_Draw2sMultiPatchTranslucentColumn_8; #ifdef RUSEASM if (R_ASM) { diff --git a/src/screen.h b/src/screen.h index 2dff4590e..a61de7f92 100644 --- a/src/screen.h +++ b/src/screen.h @@ -136,6 +136,7 @@ extern void (*basespanfunc)(void); extern void (*splatfunc)(void); extern void (*transtransfunc)(void); extern void (*twosmultipatchfunc)(void); +extern void (*twosmultipatchtransfunc)(void); // ----- // CPUID