diff --git a/src/r_draw.h b/src/r_draw.h index 7b44d6185..741ddcc2a 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -180,6 +180,7 @@ void R_DrawViewBorder(void); void R_DrawColumn_8(void); void R_DrawShadeColumn_8(void); void R_DrawTranslucentColumn_8(void); +void R_DrawDropShadowColumn_8(void); void R_DrawTranslatedColumn_8(void); void R_DrawTranslatedTranslucentColumn_8(void); void R_Draw2sMultiPatchColumn_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index 0dd8463f6..61b22bc66 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -566,6 +566,39 @@ void R_DrawTranslucentColumn_8(void) } } +// Hack: A cut-down copy of R_DrawTranslucentColumn_8 that does not read texture +// data since something about calculating the texture reading address for drop shadows is broken. +// dc_texturemid and dc_iscale get wrong values for drop shadows, however those are not strictly +// needed for the current design of the shadows, so this function bypasses the issue +// by not using those variables at all. +void R_DrawDropShadowColumn_8(void) +{ + register INT32 count; + register UINT8 *dest; + + count = dc_yh - dc_yl + 1; + + if (count <= 0) // Zero length, column does not exceed a pixel. + return; + + dest = &topleft[dc_yl*vid.width + dc_x]; + + { +#define DSCOLOR 15 // palette index for the color of the shadow + register const UINT8 *transmap_offset = dc_transmap + (dc_colormap[DSCOLOR] << 8); +#undef DSCOLOR + while ((count -= 2) >= 0) + { + *dest = *(transmap_offset + (*dest)); + dest += vid.width; + *dest = *(transmap_offset + (*dest)); + dest += vid.width; + } + if (count & 1) + *dest = *(transmap_offset + (*dest)); + } +} + /** \brief The R_DrawTranslatedTranslucentColumn_8 function Spiffy function. Not only does it colormap a sprite, but does translucency as well. Uber-kudos to Cyan Helkaraxe diff --git a/src/r_things.c b/src/r_things.c index 97d45d62d..4779e4df8 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -836,7 +836,15 @@ static void R_DrawVisSprite(vissprite_t *vis) dc_fullbright = colormaps; dc_translation = R_GetSpriteTranslation(vis); - if (R_SpriteIsFlashing(vis)) // Bosses "flash" + // Hack: Use a special column function for drop shadows that bypasses + // invalid memory access crashes caused by R_ProjectDropShadow putting wrong values + // in dc_texturemid and dc_iscale when the shadow is sloped. + if (vis->cut & SC_SHADOW) + { + R_SetColumnFunc(COLDRAWFUNC_DROPSHADOW, false); + dc_transmap = vis->transmap; + } + else if (R_SpriteIsFlashing(vis)) // Bosses "flash" R_SetColumnFunc(COLDRAWFUNC_TRANS, false); // translate certain pixels to white else if (vis->mobj->color && vis->transmap) // Color mapping { diff --git a/src/screen.c b/src/screen.c index 25dcbb1f7..5ca870cfe 100644 --- a/src/screen.c +++ b/src/screen.c @@ -133,6 +133,7 @@ void SCR_SetDrawFuncs(void) colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8; colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS] = R_Draw2sMultiPatchTranslucentColumn_8; colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn_8; + colfuncs[COLDRAWFUNC_DROPSHADOW] = R_DrawDropShadowColumn_8; spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8; spanfuncs[SPANDRAWFUNC_TILTED] = R_DrawTiltedSpan_8; diff --git a/src/screen.h b/src/screen.h index 66c52dd67..f279e8444 100644 --- a/src/screen.h +++ b/src/screen.h @@ -131,6 +131,7 @@ enum COLDRAWFUNC_TWOSMULTIPATCH, COLDRAWFUNC_TWOSMULTIPATCHTRANS, COLDRAWFUNC_FOG, + COLDRAWFUNC_DROPSHADOW, COLDRAWFUNC_MAX };