Merge branch 'fof-wall-rendering-fixes-and-cleanup' into 'master'

FOF wall rendering fixes and cleanup

See merge request STJr/SRB2!317
This commit is contained in:
Monster Iestyn 2018-11-20 08:54:09 -05:00
commit 948466658f

View file

@ -592,8 +592,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
else else
rlight->rcolormap = xwalllights[pindex]; rlight->rcolormap = xwalllights[pindex];
rlight->height += rlight->heightstep;
height = rlight->height; height = rlight->height;
rlight->height += rlight->heightstep;
if (height <= windowtop) if (height <= windowtop)
{ {
@ -829,26 +829,21 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
light = &frontsector->lightlist[i]; light = &frontsector->lightlist[i];
rlight = &dc_lightlist[p]; rlight = &dc_lightlist[p];
#ifdef ESLOPE #ifdef ESLOPE
if (light->slope) {
leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y);
rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y);
} else
leftheight = rightheight = light->height;
if (*pfloor->b_slope) { #define SLOPEPARAMS(slope, end1, end2, normalheight) \
pfloorleft = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y); if (slope) { \
pfloorright = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y); end1 = P_GetZAt(slope, ds->leftpos.x, ds->leftpos.y); \
} else end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y); \
pfloorleft = pfloorright = *pfloor->bottomheight; } else \
end1 = end2 = normalheight;
SLOPEPARAMS(light->slope, leftheight, rightheight, light->height)
SLOPEPARAMS(*pfloor->b_slope, pfloorleft, pfloorright, *pfloor->bottomheight)
if (leftheight < pfloorleft && rightheight < pfloorright) if (leftheight < pfloorleft && rightheight < pfloorright)
continue; continue;
if (*pfloor->t_slope) { SLOPEPARAMS(*pfloor->t_slope, pfloorleft, pfloorright, *pfloor->topheight)
pfloorleft = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y);
pfloorright = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y);
} else
pfloorleft = pfloorright = *pfloor->topheight;
if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights) if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights)
{ {
@ -861,17 +856,17 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
leftheight -= viewz; leftheight -= viewz;
rightheight -= viewz; rightheight -= viewz;
overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); #define OVERFLOWTEST(height, scale) \
if (overflow_test < 0) overflow_test = -overflow_test; overflow_test = (INT64)centeryfrac - (((INT64)height*scale)>>FRACBITS); \
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue; if (overflow_test < 0) overflow_test = -overflow_test; \
overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS);
if (overflow_test < 0) overflow_test = -overflow_test;
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue; if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue;
OVERFLOWTEST(leftheight, ds->scale1)
OVERFLOWTEST(rightheight, ds->scale2)
rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1);
rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
rlight->heightstep = (rlight->heightstep-rlight->height)/(range); rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
rlight->height -= rlight->heightstep;
#else #else
if (light->height < *pfloor->bottomheight) if (light->height < *pfloor->bottomheight)
continue; continue;
@ -881,36 +876,28 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height; lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height;
rlight->heightstep = -FixedMul (rw_scalestep, (lheight - viewz)); rlight->heightstep = -FixedMul (rw_scalestep, (lheight - viewz));
rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale) - rlight->heightstep; rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale);
#endif #endif
rlight->flags = light->flags; rlight->flags = light->flags;
if (light->flags & FF_CUTLEVEL) if (light->flags & FF_CUTLEVEL)
{ {
#ifdef ESLOPE #ifdef ESLOPE
if (*light->caster->b_slope) { SLOPEPARAMS(*light->caster->b_slope, leftheight, rightheight, *light->caster->bottomheight)
leftheight = P_GetZAt(*light->caster->b_slope, ds->leftpos.x, ds->leftpos.y);
rightheight = P_GetZAt(*light->caster->b_slope, ds->rightpos.x, ds->rightpos.y);
} else
leftheight = rightheight = *light->caster->bottomheight;
leftheight -= viewz; leftheight -= viewz;
rightheight -= viewz; rightheight -= viewz;
overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); OVERFLOWTEST(leftheight, ds->scale1)
if (overflow_test < 0) overflow_test = -overflow_test; OVERFLOWTEST(rightheight, ds->scale2)
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue; #undef OVERFLOWTEST
overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS);
if (overflow_test < 0) overflow_test = -overflow_test;
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue;
rlight->botheight = (centeryfrac) - FixedMul(leftheight, ds->scale1); rlight->botheight = (centeryfrac) - FixedMul(leftheight, ds->scale1);
rlight->botheightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); rlight->botheightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range);
rlight->botheight -= rlight->botheightstep;
#else #else
lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight; lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight;
rlight->botheightstep = -FixedMul (rw_scalestep, (lheight - viewz)); rlight->botheightstep = -FixedMul (rw_scalestep, (lheight - viewz));
rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale) - rlight->botheightstep; rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale);
#endif #endif
} }
@ -1003,21 +990,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
{ {
fixed_t left_top, right_top, left_bottom, right_bottom; fixed_t left_top, right_top, left_bottom, right_bottom;
if (*pfloor->t_slope) SLOPEPARAMS(*pfloor->t_slope, left_top, right_top, *pfloor->topheight)
{ SLOPEPARAMS(*pfloor->b_slope, left_bottom, right_bottom, *pfloor->bottomheight)
left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; #undef SLOPEPARAMS
right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; left_top -= viewz;
} right_top -= viewz;
else left_bottom -= viewz;
left_top = right_top = *pfloor->topheight - 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;
// using INT64 to avoid 32bit overflow // using INT64 to avoid 32bit overflow
top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS);
@ -1041,16 +1020,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
{ {
if (maskedtexturecol[dc_x] != INT16_MAX) if (maskedtexturecol[dc_x] != INT16_MAX)
{ {
// SoM: New code does not rely on R_DrawColumnShadowed_8 which // Calculate bounds
// will (hopefully) put less strain on the stack. // clamp the values if necessary to avoid overflows and rendering glitches caused by them
if (dc_numlights)
{
lighttable_t **xwalllights;
fixed_t height;
fixed_t bheight = 0;
INT32 solid = 0;
INT32 lighteffect = 0;
#ifdef ESLOPE #ifdef ESLOPE
if (top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; if (top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX;
else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac;
@ -1068,6 +1039,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// SoM: If column is out of range, why bother with it?? // SoM: If column is out of range, why bother with it??
if (windowbottom < topbounds || windowtop > bottombounds) if (windowbottom < topbounds || windowtop > bottombounds)
{
if (dc_numlights)
{ {
for (i = 0; i < dc_numlights; i++) for (i = 0; i < dc_numlights; i++)
{ {
@ -1076,15 +1049,26 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (rlight->flags & FF_CUTLEVEL) if (rlight->flags & FF_CUTLEVEL)
rlight->botheight += rlight->botheightstep; rlight->botheight += rlight->botheightstep;
} }
}
spryscale += rw_scalestep; spryscale += rw_scalestep;
continue; continue;
} }
dc_iscale = 0xffffffffu / (unsigned)spryscale; dc_iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture // Get data for the column
col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
// SoM: New code does not rely on R_DrawColumnShadowed_8 which
// will (hopefully) put less strain on the stack.
if (dc_numlights)
{
lighttable_t **xwalllights;
fixed_t height;
fixed_t bheight = 0;
INT32 solid = 0;
INT32 lighteffect = 0;
for (i = 0; i < dc_numlights; i++) for (i = 0; i < dc_numlights; i++)
{ {
// Check if the current light effects the colormap/lightlevel // Check if the current light effects the colormap/lightlevel
@ -1142,13 +1126,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
else else
solid = 0; solid = 0;
rlight->height += rlight->heightstep;
height = rlight->height; height = rlight->height;
rlight->height += rlight->heightstep;
if (solid) if (solid)
{ {
rlight->botheight += rlight->botheightstep;
bheight = rlight->botheight - (FRACUNIT >> 1); bheight = rlight->botheight - (FRACUNIT >> 1);
rlight->botheight += rlight->botheightstep;
} }
if (height <= windowtop) if (height <= windowtop)
@ -1164,6 +1148,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (windowbottom >= sprbotscreen) if (windowbottom >= sprbotscreen)
{ {
windowbottom = sprbotscreen; windowbottom = sprbotscreen;
// draw the texture
colfunc_2s (col); colfunc_2s (col);
for (i++; i < dc_numlights; i++) for (i++; i < dc_numlights; i++)
{ {
@ -1174,6 +1159,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
} }
continue; continue;
} }
// draw the texture
colfunc_2s (col); colfunc_2s (col);
if (solid) if (solid)
windowtop = bheight; windowtop = bheight;
@ -1183,6 +1169,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
dc_colormap = rlight->rcolormap; dc_colormap = rlight->rcolormap;
} }
windowbottom = sprbotscreen; windowbottom = sprbotscreen;
// draw the texture, if there is any space left
if (windowtop < windowbottom) if (windowtop < windowbottom)
colfunc_2s (col); colfunc_2s (col);
@ -1197,31 +1184,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
pindex = MAXLIGHTSCALE - 1; pindex = MAXLIGHTSCALE - 1;
dc_colormap = walllights[pindex]; dc_colormap = walllights[pindex];
if (frontsector->extra_colormap)
dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap)
dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
else if (frontsector->extra_colormap)
#ifdef ESLOPE dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
if (top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX;
else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac;
else sprtopscreen = windowtop = CLAMPMIN;
if (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX;
else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac;
else sprbotscreen = windowbottom = CLAMPMIN;
top_frac += top_step;
bottom_frac += bottom_step;
#else
sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale));
sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen;
#endif
dc_iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture // draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
colfunc_2s (col); colfunc_2s (col);
spryscale += rw_scalestep; spryscale += rw_scalestep;
} }