R_RenderMaskedSegLoop, R_RenderThickSideRange: set dc.colormap above first FOF

How lightlists work:

- Each FOF casts a shadow beneath it.
- Draw the column above each FOF with colormap set from
  the previous FOF.
- Then set colormap from the current FOF, so the next FOF
  is bathed in the current FOF's shadow.

What broke:

- Colormap was not set when drawing the column above the
  first FOF.

This commit:

- Before iterating lightlists, set colormap to base sector
  lighting.
- De-duplicate some code by using lambdas.
This commit is contained in:
James R 2024-02-04 01:28:21 -08:00
parent d2a22a6960
commit f9b66ad969

View file

@ -396,13 +396,10 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
bmCol = (column_t *)((UINT8 *)R_GetBrightmapColumn(texnum, maskedtexturecol[dc->x]) - 3);
}
for (i = 0; i < dc->numlights; i++)
auto set_light_vars = [&](INT32 i)
{
rlight = &dc->lightlist[i];
if ((rlight->flags & FOF_NOSHADE))
continue;
lightnum = R_AdjustLightLevel(rlight->lightnum);
if (lightnum < 0)
@ -421,20 +418,38 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
else
rlight->rcolormap = xwalllights[pindex];
};
auto set_colormap_below_light = [&]
{
dc->colormap = rlight->rcolormap;
dc->lightmap = xwalllights[pindex];
dc->fullbright = colormaps;
if (remap && !(ldef->flags & ML_TFERLINE))
{
dc->colormap += COLORMAP_REMAPOFFSET;
dc->fullbright += COLORMAP_REMAPOFFSET;
}
};
// Use the base sector's light level above the first FOF.
// You can imagine it as the sky casting its light on top of the highest FOF.
set_light_vars(0);
set_colormap_below_light();
for (i = 0; i < dc->numlights; i++)
{
if ((dc->lightlist[i].flags & FOF_NOSHADE))
continue;
set_light_vars(i);
height = rlight->height;
rlight->height += rlight->heightstep;
if (height <= windowtop)
{
dc->colormap = rlight->rcolormap;
dc->lightmap = xwalllights[pindex];
dc->fullbright = colormaps;
if (remap && !(ldef->flags & ML_TFERLINE))
{
dc->colormap += COLORMAP_REMAPOFFSET;
dc->fullbright += COLORMAP_REMAPOFFSET;
}
set_colormap_below_light();
continue;
}
@ -453,14 +468,7 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
}
colfunc_2s(dc, col, bmCol, -1);
windowtop = windowbottom + 1;
dc->colormap = rlight->rcolormap;
dc->lightmap = xwalllights[pindex];
dc->fullbright = colormaps;
if (remap && !(ldef->flags & ML_TFERLINE))
{
dc->colormap += COLORMAP_REMAPOFFSET;
dc->fullbright += COLORMAP_REMAPOFFSET;
}
set_colormap_below_light();
}
windowbottom = realbot;
if (windowtop < windowbottom)
@ -1158,42 +1166,64 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
fixed_t bheight = 0;
INT32 solid = 0;
auto set_light_vars = [&](INT32 i)
{
rlight = &dc->lightlist[i];
lightnum = R_AdjustLightLevel(rlight->lightnum);
if (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE-1;
if (pfloor->fofflags & FOF_FOG)
{
if (pfloor->master->frontsector->extra_colormap)
rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
else
rlight->rcolormap = xwalllights[pindex];
}
else
{
if (rlight->extra_colormap)
rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
else
rlight->rcolormap = xwalllights[pindex];
}
};
auto set_colormap_below_light = [&]
{
dc->colormap = rlight->rcolormap;
dc->lightmap = xwalllights[pindex];
dc->fullbright = colormaps;
if (remap && !(curline->linedef->flags & ML_TFERLINE))
{
dc->colormap += COLORMAP_REMAPOFFSET;
dc->fullbright += COLORMAP_REMAPOFFSET;
}
};
// Use the base sector's light level above the first FOF.
// You can imagine it as the sky casting its light on top of the highest FOF.
set_light_vars(0);
set_colormap_below_light();
for (i = 0; i < dc->numlights; i++)
{
// Check if the current light effects the colormap/lightlevel
rlight = &dc->lightlist[i];
xwalllights = NULL;
if (!(dc->lightlist[i].flags & FOF_NOSHADE))
{
lightnum = R_AdjustLightLevel(rlight->lightnum);
if (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE-1;
if (pfloor->fofflags & FOF_FOG)
{
if (pfloor->master->frontsector->extra_colormap)
rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
else
rlight->rcolormap = xwalllights[pindex];
}
else
{
if (rlight->extra_colormap)
rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
else
rlight->rcolormap = xwalllights[pindex];
}
}
set_light_vars(i);
solid = 0; // don't carry over solid-cutting flag from the previous light
@ -1227,16 +1257,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (height <= windowtop)
{
if (xwalllights)
{
dc->colormap = rlight->rcolormap;
dc->lightmap = xwalllights[pindex];
dc->fullbright = colormaps;
if (remap && !(curline->linedef->flags & ML_TFERLINE))
{
dc->colormap += COLORMAP_REMAPOFFSET;
dc->fullbright += COLORMAP_REMAPOFFSET;
}
}
set_colormap_below_light();
if (solid && windowtop < bheight)
windowtop = bheight;
continue;
@ -1264,16 +1285,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
else
windowtop = windowbottom + 1;
if (xwalllights)
{
dc->colormap = rlight->rcolormap;
dc->lightmap = xwalllights[pindex];
dc->fullbright = colormaps;
if (remap && !(curline->linedef->flags & ML_TFERLINE))
{
dc->colormap += COLORMAP_REMAPOFFSET;
dc->fullbright += COLORMAP_REMAPOFFSET;
}
}
set_colormap_below_light();
}
windowbottom = sprbotscreen;
// draw the texture, if there is any space left