diff --git a/src/r_segs.c b/src/r_segs.c index 683844439a2a294f105a8460b37b51e510912fd4..56a62f10cf5eed0a12fbdc3b709205d7de3f3440 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -186,7 +186,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (frontsector->numlights) { dc_numlights = frontsector->numlights; - if (dc_numlights >= dc_maxlights) + if (dc_numlights > dc_maxlights) { dc_maxlights = dc_numlights; 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; - sprbotscreen = INT32_MAX; sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); 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) { - do { + while (sprtopscreen < sprbotscreen) { R_DrawFlippedMaskedColumn(col, lengthcol); - sprtopscreen += dc_texheight*spryscale; - } while (sprtopscreen < sprbotscreen); + if ((INT64)sprtopscreen + (INT64)dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow + sprtopscreen = INT32_MAX; + else + sprtopscreen += dc_texheight*spryscale; + } } // 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? colfunc_2s = R_DrawRepeatFlippedMaskedColumn; else - colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture + colfunc_2s = R_DrawRepeatMaskedColumn; 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 sprbotscreen = windowbottom = CLAMPMIN; + fixed_t bottomclip = sprbotscreen; + top_frac += top_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; fixed_t height; fixed_t bheight = 0; - INT32 solid = 0; - INT32 lighteffect = 0; + boolean lighteffect = false; for (i = 0; i < dc_numlights; i++) { // Check if the current light effects the colormap/lightlevel rlight = &dc_lightlist[i]; - lighteffect = !(dc_lightlist[i].flags & FOF_NOSHADE); + lighteffect = !(rlight->flags & FOF_NOSHADE); if (lighteffect) { 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. + boolean solid = false; + if (rlight->flags & FOF_CUTSOLIDS && !(pfloor->fofflags & FOF_EXTRA)) - solid = 1; + solid = true; else if (rlight->flags & FOF_CUTEXTRA && pfloor->fofflags & 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 // there are no undesired cuts. if ((rlight->flags & (FOF_FOG|FOF_SWIMMABLE)) == (pfloor->fofflags & (FOF_FOG|FOF_SWIMMABLE))) - solid = 1; + solid = true; } else - solid = 1; + solid = true; } else - solid = 0; + solid = false; height = rlight->height; rlight->height += rlight->heightstep; @@ -893,14 +896,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (lighteffect) dc_colormap = rlight->rcolormap; if (solid && windowtop < bheight) - windowtop = bheight; + sprtopscreen = windowtop = bheight; continue; } - windowbottom = height; - if (windowbottom >= sprbotscreen) + sprbotscreen = windowbottom = height; + if (windowbottom >= bottomclip) { - windowbottom = sprbotscreen; + sprbotscreen = windowbottom = bottomclip; // draw the texture colfunc_2s (col, lengthcol); 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; else windowtop = windowbottom + 1; + sprtopscreen = windowtop; if (lighteffect) dc_colormap = rlight->rcolormap; } - windowbottom = sprbotscreen; + sprbotscreen = windowbottom = bottomclip; // draw the texture, if there is any space left if (windowtop < windowbottom) colfunc_2s (col, lengthcol); @@ -1022,6 +1026,9 @@ static void R_RenderSegLoop (void) if (bottomtexture) R_CheckTextureCache(bottomtexture); + if (dc_numlights) + colfunc = colfuncs[COLDRAWFUNC_SHADOWED]; + for (; rw_x < rw_stopx; rw_x++) { // 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); else dc_lightlist[i].rcolormap = xwalllights[pindex]; - - colfunc = colfuncs[COLDRAWFUNC_SHADOWED]; } } @@ -2449,7 +2454,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (frontsector->numlights) { dc_numlights = frontsector->numlights; - if (dc_numlights >= dc_maxlights) + if (dc_numlights > dc_maxlights) { dc_maxlights = dc_numlights; dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL);