diff --git a/src/r_things.c b/src/r_things.c index b1790933d6acfda65f81169f3ca086f204fc2eca..f8456fa11885c8ed0dc427b3fdf9c2c29dc4298b 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -888,7 +888,7 @@ static void R_DrawVisSprite(vissprite_t *vis) frac = vis->startfrac; windowtop = windowbottom = sprbotscreen = INT32_MAX; - if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES) + if (vis->cut & SC_SHADOW && vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES) this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->skin)->highresscale); if (this_scale <= 0) this_scale = 1; @@ -898,10 +898,10 @@ static void R_DrawVisSprite(vissprite_t *vis) { vis->scale = FixedMul(vis->scale, this_scale); vis->scalestep = FixedMul(vis->scalestep, this_scale); - vis->xiscale = FixedDiv(vis->xiscale,this_scale); + vis->xiscale = FixedDiv(vis->xiscale, this_scale); vis->cut |= SC_ISSCALED; } - dc_texturemid = FixedDiv(dc_texturemid,this_scale); + dc_texturemid = FixedDiv(dc_texturemid, this_scale); } spryscale = vis->scale; @@ -1759,9 +1759,6 @@ static void R_ProjectSprite(mobj_t *thing) I_Assert(lump < max_spritelumps); - if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) - this_scale = FixedMul(this_scale, ((skin_t *)thing->skin)->highresscale); - spr_width = spritecachedinfo[lump].width; spr_height = spritecachedinfo[lump].height; spr_offset = spritecachedinfo[lump].offset; @@ -1811,6 +1808,14 @@ static void R_ProjectSprite(mobj_t *thing) // calculate edges of the shape spritexscale = interp.spritexscale; spriteyscale = interp.spriteyscale; + + if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) + { + fixed_t highresscale = ((skin_t *)thing->skin)->highresscale; + spritexscale = FixedMul(spritexscale, highresscale); + spriteyscale = FixedMul(spriteyscale, highresscale); + } + if (spritexscale < 1 || spriteyscale < 1) return; @@ -3183,6 +3188,40 @@ static void R_HeightSecClip(vissprite_t *spr, INT32 x1, INT32 x2) } } +static boolean R_CheckSpriteVisible(vissprite_t *spr, INT32 x1, INT32 x2) +{ + INT16 sz = spr->sz; + INT16 szt = spr->szt; + + fixed_t texturemid, yscale, scalestep = spr->scalestep; + + if (scalestep) + { + yscale = spr->scale; + scalestep = FixedMul(scalestep, spr->spriteyscale); + + if (spr->thingscale != FRACUNIT) + texturemid = FixedDiv(spr->texturemid, max(spr->thingscale, 1)); + else + texturemid = spr->texturemid; + } + + for (INT32 x = x1; x <= x2; x++) + { + if (scalestep) + { + szt = (INT16)((centeryfrac - FixedMul(texturemid, yscale))>>FRACBITS); + sz = (INT16)((centeryfrac - FixedMul(texturemid, yscale))>>FRACBITS); + yscale += scalestep; + } + + if (spr->cliptop[x] < spr->clipbot[x] && sz > spr->cliptop[x] && szt < spr->clipbot[x]) + return true; + } + + return false; +} + // R_ClipVisSprite // Clips vissprites without drawing, so that portals can work. -Red static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* portal) @@ -3356,17 +3395,8 @@ static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* port // Not done for floorsprites. if (cv_spriteclip.value && (spr->cut & SC_SPLAT) == 0) { - for (x = x1; x <= x2; x++) - { - if (spr->cliptop[x] < spr->clipbot[x] - && spr->sz > spr->cliptop[x] - && spr->szt < spr->clipbot[x]) - { - return; - } - } - - spr->cut |= SC_NOTVISIBLE; + if (!R_CheckSpriteVisible(spr, x1, x2)) + spr->cut |= SC_NOTVISIBLE; } } @@ -3436,7 +3466,9 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) { vissprite_t *spr = R_GetVisSprite(clippedvissprites); - if (spr->szt > vid.height || spr->sz < 0) + if (cv_spriteclip.value + && (spr->szt > vid.height || spr->sz < 0) + && !((spr->cut & SC_SPLAT) || spr->scalestep)) { spr->cut |= SC_NOTVISIBLE; continue;