mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-11-10 15:22:20 +00:00
Proper overflow checking, applied to FOFs and midtex's too
This fixes the annoying flickering when you pass by water, FOFs, tall grass, etc.
This commit is contained in:
parent
37575d2219
commit
7c79bbc0b3
4 changed files with 47 additions and 51 deletions
11
src/m_misc.c
11
src/m_misc.c
|
@ -1787,17 +1787,6 @@ UINT8 M_CountBits(UINT32 num, UINT8 size)
|
|||
return sum;
|
||||
}
|
||||
|
||||
|
||||
/** Get the most significant bit in a number.
|
||||
* (integer log2)
|
||||
*/
|
||||
UINT8 M_HighestBit(UINT32 num)
|
||||
{
|
||||
UINT8 i = 0;
|
||||
while (num >>= 1) ++i;
|
||||
return i;
|
||||
}
|
||||
|
||||
const char *GetRevisionString(void)
|
||||
{
|
||||
static char rev[9] = {0};
|
||||
|
|
|
@ -95,7 +95,6 @@ void M_SetupMemcpy(void);
|
|||
|
||||
// counting bits, for weapon ammo code, usually
|
||||
FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);
|
||||
FUNCMATH UINT8 M_HighestBit(UINT32 num);
|
||||
|
||||
// Flags for AA trees.
|
||||
#define AATREE_ZUSER 1 // Treat values as z_zone-allocated blocks and set their user fields
|
||||
|
|
63
src/r_segs.c
63
src/r_segs.c
|
@ -288,6 +288,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
line_t *ldef;
|
||||
sector_t *front, *back;
|
||||
INT32 times, repeats;
|
||||
INT64 overflow_test;
|
||||
#ifdef ESLOPE
|
||||
INT32 range;
|
||||
#endif
|
||||
|
@ -485,7 +486,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
|
||||
}
|
||||
|
||||
|
||||
#ifndef ESLOPE
|
||||
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{
|
||||
|
@ -523,6 +523,16 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
// calculate lighting
|
||||
if (maskedtexturecol[dc_x] != INT16_MAX)
|
||||
{
|
||||
// Check for overflows first
|
||||
overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS);
|
||||
if (overflow_test < 0) overflow_test = -overflow_test;
|
||||
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL)
|
||||
{
|
||||
// Eh, no, go away, don't waste our time
|
||||
spryscale += rw_scalestep;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dc_numlights)
|
||||
{
|
||||
lighttable_t **xwalllights;
|
||||
|
@ -947,16 +957,38 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
// Set heights according to plane, or slope, whichever
|
||||
{
|
||||
fixed_t left_top, right_top, left_bottom, right_bottom;
|
||||
INT64 overflow_test;
|
||||
|
||||
left_top = *pfloor->t_slope ? P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) : *pfloor->topheight;
|
||||
right_top = *pfloor->t_slope ? P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) : *pfloor->topheight;
|
||||
left_bottom = *pfloor->b_slope ? P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) : *pfloor->bottomheight;
|
||||
right_bottom = *pfloor->b_slope ? P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) : *pfloor->bottomheight;
|
||||
if (*pfloor->t_slope)
|
||||
{
|
||||
left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz;
|
||||
right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz;
|
||||
}
|
||||
else
|
||||
left_top = right_top = *pfloor->topheight - viewz;
|
||||
|
||||
left_top -= viewz;
|
||||
right_top -= viewz;
|
||||
left_bottom -= viewz;
|
||||
right_bottom -= viewz;
|
||||
if (*pfloor->b_slope)
|
||||
{
|
||||
left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz;
|
||||
right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz;
|
||||
}
|
||||
else
|
||||
left_bottom = right_bottom = *pfloor->bottomheight - viewz;
|
||||
|
||||
// overflow tests
|
||||
// if any of these fail, abandon. likely we're too high up to see anything anyway
|
||||
overflow_test = (INT64)centeryfrac - (((INT64)left_top*ds->scale1)>>FRACBITS);
|
||||
if (overflow_test < 0) overflow_test = -overflow_test;
|
||||
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return;
|
||||
overflow_test = (INT64)centeryfrac - (((INT64)left_bottom*ds->scale1)>>FRACBITS);
|
||||
if (overflow_test < 0) overflow_test = -overflow_test;
|
||||
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return;
|
||||
overflow_test = (INT64)centeryfrac - (((INT64)right_top*ds->scale2)>>FRACBITS);
|
||||
if (overflow_test < 0) overflow_test = -overflow_test;
|
||||
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return;
|
||||
overflow_test = (INT64)centeryfrac - (((INT64)right_bottom*ds->scale2)>>FRACBITS);
|
||||
if (overflow_test < 0) overflow_test = -overflow_test;
|
||||
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return;
|
||||
|
||||
top_frac = centeryfrac - FixedMul(left_top, ds->scale1);
|
||||
bottom_frac = centeryfrac - FixedMul(left_bottom, ds->scale1);
|
||||
|
@ -1133,19 +1165,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap)
|
||||
dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
|
||||
|
||||
//Handle over/underflows before they happen. This fixes the textures part of the FOF rendering bug.
|
||||
//...for the most part, anyway.
|
||||
if (((signed)dc_texturemid > 0 && (spryscale>>FRACBITS > INT32_MAX / (signed)dc_texturemid))
|
||||
|| ((signed)dc_texturemid < 0 && (spryscale) && (signed)(dc_texturemid)>>FRACBITS < (INT32_MIN / spryscale)))
|
||||
{
|
||||
spryscale += rw_scalestep;
|
||||
#ifdef ESLOPE
|
||||
top_frac += top_step;
|
||||
bottom_frac += bottom_step;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef ESLOPE
|
||||
sprtopscreen = windowtop = top_frac;
|
||||
sprbotscreen = windowbottom = bottom_frac;
|
||||
|
|
|
@ -744,10 +744,16 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
patch_t *patch = W_CacheLumpNum(vis->patch, PU_CACHE);
|
||||
fixed_t this_scale = vis->mobj->scale;
|
||||
INT32 x1, x2;
|
||||
INT64 overflow_test;
|
||||
|
||||
if (!patch)
|
||||
return;
|
||||
|
||||
// Check for overflow
|
||||
overflow_test = (INT64)centeryfrac - (((INT64)vis->texturemid*vis->scale)>>FRACBITS);
|
||||
if (overflow_test < 0) overflow_test = -overflow_test;
|
||||
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // fixed point mult would overflow
|
||||
|
||||
colfunc = basecolfunc; // hack: this isn't resetting properly somewhere.
|
||||
dc_colormap = vis->colormap;
|
||||
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
|
||||
|
@ -1239,15 +1245,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
return;
|
||||
}
|
||||
|
||||
// quick check for possible overflows
|
||||
// if either of these triggers then there's a possibility that drawing is unsafe
|
||||
if (M_HighestBit(abs(gzt - viewz)) + M_HighestBit(abs(yscale)) > 47 // 31 bits + 16 from the division by FRACUNIT
|
||||
|| M_HighestBit(abs(gz - viewz)) + M_HighestBit(abs(yscale)) > 47)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "Suspected overflow in ProjectSprite (sprite %s), ignoring\n", sprnames[thing->sprite]);
|
||||
return;
|
||||
}
|
||||
|
||||
// store information in a vissprite
|
||||
vis = R_NewVisSprite();
|
||||
vis->heightsec = heightsec; //SoM: 3/17/2000
|
||||
|
@ -1458,14 +1455,6 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
return;
|
||||
}
|
||||
|
||||
// quick check for possible overflows
|
||||
// if either of these triggers then there's a possibility that drawing is unsafe
|
||||
if (M_HighestBit(abs(gzt - viewz)) + M_HighestBit(abs(yscale)) > 47) // 31 bits + 16 from the division by FRACUNIT
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "Suspected overflow in ProjectPrecipitationSprite (sprite %s), ignoring\n", sprnames[thing->sprite]);
|
||||
return;
|
||||
}
|
||||
|
||||
// store information in a vissprite
|
||||
vis = R_NewVisSprite();
|
||||
vis->scale = yscale; //<<detailshift;
|
||||
|
|
Loading…
Reference in a new issue