Merge branch 'fix-1207' into 'next'

Fix 3D floor sides not rendering properly if a light list was involved

Closes #1207 and #1204

See merge request STJr/SRB2!2373
This commit is contained in:
sphere 2024-02-25 23:41:29 +00:00
commit 8ccc4d60ab

View file

@ -186,7 +186,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
if (frontsector->numlights) if (frontsector->numlights)
{ {
dc_numlights = frontsector->numlights; dc_numlights = frontsector->numlights;
if (dc_numlights >= dc_maxlights) if (dc_numlights > dc_maxlights)
{ {
dc_maxlights = dc_numlights; dc_maxlights = dc_numlights;
dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL);
@ -342,7 +342,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
{ {
lighttable_t **xwalllights; lighttable_t **xwalllights;
sprbotscreen = INT32_MAX;
sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale));
realbot = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; realbot = FixedMul(textureheight[texnum], spryscale) + sprtopscreen;
@ -449,10 +448,13 @@ static void R_DrawRepeatMaskedColumn(column_t *col, unsigned lengthcol)
static void R_DrawRepeatFlippedMaskedColumn(column_t *col, unsigned lengthcol) static void R_DrawRepeatFlippedMaskedColumn(column_t *col, unsigned lengthcol)
{ {
do { while (sprtopscreen < sprbotscreen) {
R_DrawFlippedMaskedColumn(col, lengthcol); R_DrawFlippedMaskedColumn(col, lengthcol);
sprtopscreen += dc_texheight*spryscale; if ((INT64)sprtopscreen + (INT64)dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow
} while (sprtopscreen < sprbotscreen); sprtopscreen = INT32_MAX;
else
sprtopscreen += dc_texheight*spryscale;
}
} }
// Returns true if a fake floor is translucent. // Returns true if a fake floor is translucent.
@ -742,7 +744,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (textures[texnum]->flip & 2) // vertically flipped? if (textures[texnum]->flip & 2) // vertically flipped?
colfunc_2s = R_DrawRepeatFlippedMaskedColumn; colfunc_2s = R_DrawRepeatFlippedMaskedColumn;
else else
colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture colfunc_2s = R_DrawRepeatMaskedColumn;
lengthcol = textures[texnum]->height; lengthcol = textures[texnum]->height;
@ -787,6 +789,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac; else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac;
else sprbotscreen = windowbottom = CLAMPMIN; else sprbotscreen = windowbottom = CLAMPMIN;
fixed_t bottomclip = sprbotscreen;
top_frac += top_step; top_frac += top_step;
bottom_frac += bottom_step; bottom_frac += bottom_step;
@ -819,14 +823,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
lighttable_t **xwalllights; lighttable_t **xwalllights;
fixed_t height; fixed_t height;
fixed_t bheight = 0; fixed_t bheight = 0;
INT32 solid = 0; boolean lighteffect = false;
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
rlight = &dc_lightlist[i]; rlight = &dc_lightlist[i];
lighteffect = !(dc_lightlist[i].flags & FOF_NOSHADE); lighteffect = !(rlight->flags & FOF_NOSHADE);
if (lighteffect) if (lighteffect)
{ {
lightnum = rlight->lightnum; lightnum = rlight->lightnum;
@ -859,11 +862,11 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
} }
} }
solid = 0; // don't carry over solid-cutting flag from the previous light
// Check if the current light can cut the current 3D floor. // Check if the current light can cut the current 3D floor.
boolean solid = false;
if (rlight->flags & FOF_CUTSOLIDS && !(pfloor->fofflags & FOF_EXTRA)) if (rlight->flags & FOF_CUTSOLIDS && !(pfloor->fofflags & FOF_EXTRA))
solid = 1; solid = true;
else if (rlight->flags & FOF_CUTEXTRA && pfloor->fofflags & FOF_EXTRA) else if (rlight->flags & FOF_CUTEXTRA && pfloor->fofflags & FOF_EXTRA)
{ {
if (rlight->flags & FOF_EXTRA) if (rlight->flags & FOF_EXTRA)
@ -871,13 +874,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// The light is from an extra 3D floor... Check the flags so // The light is from an extra 3D floor... Check the flags so
// there are no undesired cuts. // there are no undesired cuts.
if ((rlight->flags & (FOF_FOG|FOF_SWIMMABLE)) == (pfloor->fofflags & (FOF_FOG|FOF_SWIMMABLE))) if ((rlight->flags & (FOF_FOG|FOF_SWIMMABLE)) == (pfloor->fofflags & (FOF_FOG|FOF_SWIMMABLE)))
solid = 1; solid = true;
} }
else else
solid = 1; solid = true;
} }
else else
solid = 0; solid = false;
height = rlight->height; height = rlight->height;
rlight->height += rlight->heightstep; rlight->height += rlight->heightstep;
@ -893,14 +896,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (lighteffect) if (lighteffect)
dc_colormap = rlight->rcolormap; dc_colormap = rlight->rcolormap;
if (solid && windowtop < bheight) if (solid && windowtop < bheight)
windowtop = bheight; sprtopscreen = windowtop = bheight;
continue; continue;
} }
windowbottom = height; sprbotscreen = windowbottom = height;
if (windowbottom >= sprbotscreen) if (windowbottom >= bottomclip)
{ {
windowbottom = sprbotscreen; sprbotscreen = windowbottom = bottomclip;
// draw the texture // draw the texture
colfunc_2s (col, lengthcol); colfunc_2s (col, lengthcol);
for (i++; i < dc_numlights; i++) for (i++; i < dc_numlights; i++)
@ -918,10 +921,11 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
windowtop = bheight; windowtop = bheight;
else else
windowtop = windowbottom + 1; windowtop = windowbottom + 1;
sprtopscreen = windowtop;
if (lighteffect) if (lighteffect)
dc_colormap = rlight->rcolormap; dc_colormap = rlight->rcolormap;
} }
windowbottom = sprbotscreen; sprbotscreen = windowbottom = bottomclip;
// draw the texture, if there is any space left // draw the texture, if there is any space left
if (windowtop < windowbottom) if (windowtop < windowbottom)
colfunc_2s (col, lengthcol); colfunc_2s (col, lengthcol);
@ -1022,6 +1026,9 @@ static void R_RenderSegLoop (void)
if (bottomtexture) if (bottomtexture)
R_CheckTextureCache(bottomtexture); R_CheckTextureCache(bottomtexture);
if (dc_numlights)
colfunc = colfuncs[COLDRAWFUNC_SHADOWED];
for (; rw_x < rw_stopx; rw_x++) for (; rw_x < rw_stopx; rw_x++)
{ {
// mark floor / ceiling areas // mark floor / ceiling areas
@ -1234,8 +1241,6 @@ static void R_RenderSegLoop (void)
dc_lightlist[i].rcolormap = dc_lightlist[i].extra_colormap->colormap + (xwalllights[pindex] - colormaps); dc_lightlist[i].rcolormap = dc_lightlist[i].extra_colormap->colormap + (xwalllights[pindex] - colormaps);
else else
dc_lightlist[i].rcolormap = xwalllights[pindex]; dc_lightlist[i].rcolormap = xwalllights[pindex];
colfunc = colfuncs[COLDRAWFUNC_SHADOWED];
} }
} }
@ -2449,7 +2454,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (frontsector->numlights) if (frontsector->numlights)
{ {
dc_numlights = frontsector->numlights; dc_numlights = frontsector->numlights;
if (dc_numlights >= dc_maxlights) if (dc_numlights > dc_maxlights)
{ {
dc_maxlights = dc_numlights; dc_maxlights = dc_numlights;
dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL);