From 97311dc5b00ab232a6e898c085c20d2f6bdbfa3b Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Thu, 27 Jul 2023 19:15:35 -0300 Subject: [PATCH] Use separate table for maskedtexturecol --- src/r_defs.h | 4 +- src/r_main.c | 1 + src/r_plane.c | 6 - src/r_plane.h | 3 - src/r_segs.c | 729 +++++++++++++++++++++++++------------------------- src/r_segs.h | 1 + 6 files changed, 365 insertions(+), 379 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index a9b9a4a08..dfd2d6d70 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -757,12 +757,12 @@ typedef struct drawseg_s // Pointers to lists for sprite clipping, all three adjusted so [x1] is first value. INT16 *sprtopclip; INT16 *sprbottomclip; - INT16 *maskedtexturecol; + fixed_t *maskedtexturecol; struct visplane_s *ffloorplanes[MAXFFLOORS]; INT32 numffloorplanes; struct ffloor_s *thicksides[MAXFFLOORS]; - INT16 *thicksidecol; + fixed_t *thicksidecol; INT32 numthicksides; fixed_t frontscale[MAXVIDWIDTH]; diff --git a/src/r_main.c b/src/r_main.c index 55bb9c4ff..952171405 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1479,6 +1479,7 @@ void R_RenderPlayerView(player_t *player) R_ClearClipSegs(); } R_ClearDrawSegs(); + R_ClearSegTables(); R_ClearSprites(); Portal_InitList(); diff --git a/src/r_plane.c b/src/r_plane.c index c568484b6..29ce26b29 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -53,10 +53,6 @@ INT32 numffloors; #define visplane_hash(picnum,lightlevel,height) \ ((unsigned)((picnum)*3+(lightlevel)+(height)*7) & VISPLANEHASHMASK) -//SoM: 3/23/2000: Use boom opening limit removal -size_t maxopenings; -INT16 *openings, *lastopening; /// \todo free leak - // // Clip values are the solid pixel bounding the range. // floorclip starts out SCREENHEIGHT @@ -366,8 +362,6 @@ void R_ClearPlanes(void) freehead = &(*freehead)->next; } - lastopening = openings; - // texture calculation memset(cachedheight, 0, sizeof (cachedheight)); } diff --git a/src/r_plane.h b/src/r_plane.h index 9870a43e2..917e8b041 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -60,9 +60,6 @@ extern visplane_t *floorplane; extern visplane_t *ceilingplane; // Visplane related. -extern INT16 *lastopening, *openings; -extern size_t maxopenings; - extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH]; extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16]; extern fixed_t cachedheight[MAXVIDHEIGHT]; diff --git a/src/r_segs.c b/src/r_segs.c index facab62ab..9ee3bcfec 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -71,9 +71,22 @@ static fixed_t topfrac, topstep; static fixed_t bottomfrac, bottomstep; static lighttable_t **walllights; -static INT16 *maskedtexturecol; +static fixed_t *maskedtexturecol; static fixed_t *maskedtextureheight = NULL; +//SoM: 3/23/2000: Use boom opening limit removal +static size_t numopenings; +static INT16 *openings, *lastopening; + +static size_t texturecolumntablesize; +static fixed_t *texturecolumntable, *curtexturecolumntable; + +void R_ClearSegTables(void) +{ + lastopening = openings; + curtexturecolumntable = texturecolumntable; +} + // ========================================================================== // R_RenderMaskedSegRange // ========================================================================== @@ -350,170 +363,115 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; else dc_texturemid -= (textureheight[texnum])*times; - // 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) { - // 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 + if (dc_numlights) { - // Eh, no, go away, don't waste our time - if (dc_numlights) + for (i = 0; i < dc_numlights; i++) { - for (i = 0; i < dc_numlights; i++) + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + } + } + spryscale += rw_scalestep; + continue; + } + + // calculate lighting + if (dc_numlights) + { + lighttable_t **xwalllights; + + sprbotscreen = INT32_MAX; + sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); + + realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); + + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + + if ((rlight->flags & FOF_NOSHADE)) + continue; + + if (rlight->lightnum < 0) + xwalllights = scalelight[0]; + else if (rlight->lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[rlight->lightnum]; + + pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (height <= windowtop) + { + dc_colormap = rlight->rcolormap; + continue; + } + + windowbottom = height; + if (windowbottom >= realbot) + { + windowbottom = realbot; + colfunc_2s(col); + for (i++; i < dc_numlights; i++) { rlight = &dc_lightlist[i]; rlight->height += rlight->heightstep; } + + continue; } - spryscale += rw_scalestep; - continue; - } - - if (dc_numlights) - { - lighttable_t **xwalllights; - - sprbotscreen = INT32_MAX; - sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - - realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); - - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - - if ((rlight->flags & FOF_NOSHADE)) - continue; - - if (rlight->lightnum < 0) - xwalllights = scalelight[0]; - else if (rlight->lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[rlight->lightnum]; - - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (height <= windowtop) - { - dc_colormap = rlight->rcolormap; - continue; - } - - windowbottom = height; - if (windowbottom >= realbot) - { - windowbottom = realbot; - colfunc_2s(col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } - - continue; - } - colfunc_2s(col); - windowtop = windowbottom + 1; - dc_colormap = rlight->rcolormap; - } - windowbottom = realbot; - if (windowtop < windowbottom) - colfunc_2s(col); - - spryscale += rw_scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); - -#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red - if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) - { - fixed_t my_topscreen; - fixed_t my_bottomscreen; - fixed_t my_yl, my_yh; - - my_topscreen = sprtopscreen + spryscale*col->topdelta; - my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length - : sprbotscreen + spryscale*col->length; - - my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; - my_yh = (my_bottomscreen-1)>>FRACBITS; - // CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); - - if (numffloors) - { - INT32 top = my_yl; - INT32 bottom = my_yh; - - for (i = 0; i < numffloors; i++) - { - if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) - continue; - - if (ffloor[i].height < viewz) - { - INT32 top_w = ffloor[i].plane->top[dc_x]; - - // CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); - // CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); - if (top_w < top) - { - ffloor[i].plane->top[dc_x] = (INT16)top; - ffloor[i].plane->picnum = 0; - } - // CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); - } - else if (ffloor[i].height > viewz) - { - INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; - - if (bottom_w > bottom) - { - ffloor[i].plane->bottom[dc_x] = (INT16)bottom; - ffloor[i].plane->picnum = 0; - } - } - } - } - } - else -#endif colfunc_2s(col); + windowtop = windowbottom + 1; + dc_colormap = rlight->rcolormap; + } + windowbottom = realbot; + if (windowtop < windowbottom) + colfunc_2s(col); + + spryscale += rw_scalestep; + continue; } + + // calculate lighting + pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); + colfunc_2s(col); + spryscale += rw_scalestep; } } @@ -857,183 +815,182 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // draw the columns for (dc_x = x1; dc_x <= x2; dc_x++) { - if (maskedtexturecol[dc_x] != INT16_MAX) + // skew FOF walls + if (ffloortextureslide) { - if (ffloortextureslide) { // skew FOF walls - if (oldx != -1) - dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])< (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; + // Calculate bounds + // clamp the values if necessary to avoid overflows and rendering glitches caused by them + 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; + top_frac += top_step; + bottom_frac += bottom_step; - // SoM: If column is out of range, why bother with it?? - if (windowbottom < topbounds || windowtop > bottombounds) + // SoM: If column is out of range, why bother with it?? + if (windowbottom < topbounds || windowtop > bottombounds) + { + if (dc_numlights) { - if (dc_numlights) + for (i = 0; i < dc_numlights; i++) { - for (i = 0; i < dc_numlights; i++) + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FOF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; + } + } + spryscale += rw_scalestep; + continue; + } + + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // Get data for the column + col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 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++) + { + // Check if the current light effects the colormap/lightlevel + rlight = &dc_lightlist[i]; + lighteffect = !(dc_lightlist[i].flags & FOF_NOSHADE); + if (lighteffect) + { + lightnum = 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]; + } + } + + solid = 0; // don't carry over solid-cutting flag from the previous light + + // Check if the current light can cut the current 3D floor. + if (rlight->flags & FOF_CUTSOLIDS && !(pfloor->fofflags & FOF_EXTRA)) + solid = 1; + else if (rlight->flags & FOF_CUTEXTRA && pfloor->fofflags & FOF_EXTRA) + { + if (rlight->flags & FOF_EXTRA) + { + // 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; + } + else + solid = 1; + } + else + solid = 0; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (solid) + { + bheight = rlight->botheight - (FRACUNIT >> 1); + rlight->botheight += rlight->botheightstep; + } + + if (height <= windowtop) + { + if (lighteffect) + dc_colormap = rlight->rcolormap; + if (solid && windowtop < bheight) + windowtop = bheight; + continue; + } + + windowbottom = height; + if (windowbottom >= sprbotscreen) + { + windowbottom = sprbotscreen; + // draw the texture + colfunc_2s (col); + for (i++; i < dc_numlights; i++) { rlight = &dc_lightlist[i]; rlight->height += rlight->heightstep; if (rlight->flags & FOF_CUTLEVEL) rlight->botheight += rlight->botheightstep; } + continue; } - spryscale += rw_scalestep; - continue; + // draw the texture + colfunc_2s (col); + if (solid) + windowtop = bheight; + else + windowtop = windowbottom + 1; + if (lighteffect) + dc_colormap = rlight->rcolormap; } + windowbottom = sprbotscreen; + // draw the texture, if there is any space left + if (windowtop < windowbottom) + colfunc_2s (col); - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // Get data for the column - 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++) - { - // Check if the current light effects the colormap/lightlevel - rlight = &dc_lightlist[i]; - lighteffect = !(dc_lightlist[i].flags & FOF_NOSHADE); - if (lighteffect) - { - lightnum = 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]; - } - } - - solid = 0; // don't carry over solid-cutting flag from the previous light - - // Check if the current light can cut the current 3D floor. - if (rlight->flags & FOF_CUTSOLIDS && !(pfloor->fofflags & FOF_EXTRA)) - solid = 1; - else if (rlight->flags & FOF_CUTEXTRA && pfloor->fofflags & FOF_EXTRA) - { - if (rlight->flags & FOF_EXTRA) - { - // 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; - } - else - solid = 1; - } - else - solid = 0; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (solid) - { - bheight = rlight->botheight - (FRACUNIT >> 1); - rlight->botheight += rlight->botheightstep; - } - - if (height <= windowtop) - { - if (lighteffect) - dc_colormap = rlight->rcolormap; - if (solid && windowtop < bheight) - windowtop = bheight; - continue; - } - - windowbottom = height; - if (windowbottom >= sprbotscreen) - { - windowbottom = sprbotscreen; - // draw the texture - colfunc_2s (col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FOF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } - continue; - } - // draw the texture - colfunc_2s (col); - if (solid) - windowtop = bheight; - else - windowtop = windowbottom + 1; - if (lighteffect) - dc_colormap = rlight->rcolormap; - } - windowbottom = sprbotscreen; - // draw the texture, if there is any space left - if (windowtop < windowbottom) - colfunc_2s (col); - - spryscale += rw_scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (pfloor->fofflags & FOF_FOG && pfloor->master->frontsector->extra_colormap) - dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - else if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - // draw the texture - colfunc_2s (col); spryscale += rw_scalestep; + continue; } + + // calculate lighting + pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (pfloor->fofflags & FOF_FOG && pfloor->master->frontsector->extra_colormap) + dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + else if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + // draw the texture + colfunc_2s (col); + spryscale += rw_scalestep; } colfunc = colfuncs[BASEDRAWFUNC]; @@ -1270,7 +1227,7 @@ static void R_RenderSegLoop (void) } oldtexturecolumn = texturecolumn; - texturecolumn >>= FRACBITS; + INT32 itexturecolumn = texturecolumn >> FRACBITS; // texturecolumn and lighting are independent of wall tiers if (segtextured) @@ -1336,7 +1293,7 @@ static void R_RenderSegLoop (void) dc_yl = yl; dc_yh = yh; dc_texturemid = rw_midtexturemid; - dc_source = R_GetColumn(midtexture,texturecolumn + (rw_offset_mid>>FRACBITS)); + dc_source = R_GetColumn(midtexture, itexturecolumn + (rw_offset_mid>>FRACBITS)); dc_texheight = textureheight[midtexture]>>FRACBITS; //profile stuff --------------------------------------------------------- @@ -1397,7 +1354,7 @@ static void R_RenderSegLoop (void) dc_yl = yl; dc_yh = mid; dc_texturemid = rw_toptexturemid; - dc_source = R_GetColumn(toptexture,texturecolumn + (rw_offset_top>>FRACBITS)); + dc_source = R_GetColumn(toptexture, itexturecolumn + (rw_offset_top>>FRACBITS)); dc_texheight = textureheight[toptexture]>>FRACBITS; colfunc(); ceilingclip[rw_x] = (INT16)mid; @@ -1433,8 +1390,7 @@ static void R_RenderSegLoop (void) dc_yl = mid; dc_yh = yh; dc_texturemid = rw_bottomtexturemid; - dc_source = R_GetColumn(bottomtexture, - texturecolumn + (rw_offset_bot>>FRACBITS)); + dc_source = R_GetColumn(bottomtexture, itexturecolumn + (rw_offset_bot>>FRACBITS)); dc_texheight = textureheight[bottomtexture]>>FRACBITS; colfunc(); floorclip[rw_x] = (INT16)mid; @@ -1453,7 +1409,7 @@ static void R_RenderSegLoop (void) { // save texturecol // for backdrawing of masked mid texture - maskedtexturecol[rw_x] = (INT16)(texturecolumn + (rw_offset_mid>>FRACBITS)); + maskedtexturecol[rw_x] = texturecolumn + rw_offset_mid; if (maskedtextureheight != NULL) { maskedtextureheight[rw_x] = (curline->linedef->flags & ML_MIDPEG) ? @@ -1512,6 +1468,67 @@ static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2) } } +//SoM: Code to remove limits on openings. +static void R_AllocClippingTables(size_t range) +{ + size_t pos = lastopening - openings; + size_t need = range * 2; // for both sprtopclip and sprbottomclip + + if (pos + need < numopenings) + return; + + INT16 *oldopenings = openings; + INT16 *oldlast = lastopening; + + if (numopenings == 0) + numopenings = 16384; + + numopenings += need; + openings = Z_Realloc(openings, numopenings * sizeof (*openings), PU_STATIC, NULL); + lastopening = openings + pos; + + // borrowed fix from *cough* zdoom *cough* + // [RH] We also need to adjust the openings pointers that + // were already stored in drawsegs. + for (drawseg_t *ds = drawsegs; ds < ds_p; ds++) + { + // Check if it's in range of the openings + if (ds->sprtopclip + ds->x1 >= oldopenings && ds->sprtopclip + ds->x1 <= oldlast) + ds->sprtopclip = (ds->sprtopclip - oldopenings) + openings; + if (ds->sprbottomclip + ds->x1 >= oldopenings && ds->sprbottomclip + ds->x1 <= oldlast) + ds->sprbottomclip = (ds->sprbottomclip - oldopenings) + openings; + } +} + +static void R_AllocTextureColumnTables(size_t range) +{ + size_t pos = curtexturecolumntable - texturecolumntable; + + // For both tables, we reserve exactly an amount of memory that's equivalent to + // how many columns the seg will take on the entire screen (think about it) + if (pos + range < texturecolumntablesize) + return; + + fixed_t *oldtable = texturecolumntable; + fixed_t *oldlast = curtexturecolumntable; + + if (texturecolumntablesize == 0) + texturecolumntablesize = 16384; + + texturecolumntablesize += range; + texturecolumntable = Z_Realloc(texturecolumntable, texturecolumntablesize * sizeof (*texturecolumntable), PU_STATIC, NULL); + curtexturecolumntable = texturecolumntable + pos; + + for (drawseg_t *ds = drawsegs; ds < ds_p; ds++) + { + // Check if it's in range of the tables + if (ds->maskedtexturecol + ds->x1 >= oldtable && ds->maskedtexturecol + ds->x1 <= oldlast) + ds->maskedtexturecol = (ds->maskedtexturecol - oldtable) + texturecolumntable; + if (ds->thicksidecol + ds->x1 >= oldtable && ds->thicksidecol + ds->x1 <= oldlast) + ds->thicksidecol = (ds->thicksidecol - oldtable) + texturecolumntable; + } +} + // // R_StoreWallRange // A wall segment will be drawn @@ -1580,37 +1597,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->curline = curline; rw_stopx = stop+1; - //SoM: Code to remove limits on openings. - { - size_t pos = lastopening - openings; - size_t need = (rw_stopx - start)*4 + pos; - if (need > maxopenings) - { - drawseg_t *ds; //needed for fix from *cough* zdoom *cough* - INT16 *oldopenings = openings; - INT16 *oldlast = lastopening; - - do - maxopenings = maxopenings ? maxopenings*2 : 16384; - while (need > maxopenings); - openings = Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL); - lastopening = openings + pos; - - // borrowed fix from *cough* zdoom *cough* - // [RH] We also need to adjust the openings pointers that - // were already stored in drawsegs. - for (ds = drawsegs; ds < ds_p; ds++) - { -#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings; - ADJUST(maskedtexturecol); - ADJUST(sprtopclip); - ADJUST(sprbottomclip); - ADJUST(thicksidecol); -#undef ADJUST - } - } - } // end of code to remove limits on openings - // calculate scale at both ends and step ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); @@ -2026,6 +2012,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_toptexturemid += sidedef->rowoffset + sidedef->offsety_top; rw_bottomtexturemid += sidedef->rowoffset + sidedef->offsety_bot; + R_AllocTextureColumnTables(rw_stopx - start); + // allocate space for masked texture tables if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors)) { @@ -2040,8 +2028,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) //markceiling = markfloor = true; maskedtexture = true; - ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; + ds_p->thicksidecol = maskedtexturecol = curtexturecolumntable - rw_x; + curtexturecolumntable += rw_stopx - rw_x; lowcut = max(worldbottom, worldlow) + viewz; highcut = min(worldtop, worldhigh) + viewz; @@ -2224,8 +2212,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) // masked midtexture if (!ds_p->thicksidecol) { - ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; + ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x; + curtexturecolumntable += rw_stopx - rw_x; } else ds_p->maskedtexturecol = ds_p->thicksidecol; @@ -2737,29 +2725,34 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->portalpass = 0; // save sprite clipping info - if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip) + if (maskedtexture || (ds_p->silhouette & (SIL_TOP | SIL_BOTTOM))) { - M_Memcpy(lastopening, ceilingclip+start, 2*(rw_stopx - start)); - ds_p->sprtopclip = lastopening - start; - lastopening += rw_stopx - start; - } + R_AllocClippingTables(rw_stopx - start); - if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip) - { - M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx-start)); - ds_p->sprbottomclip = lastopening - start; - lastopening += rw_stopx - start; + if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip) + { + M_Memcpy(lastopening, ceilingclip + start, 2*(rw_stopx - start)); + ds_p->sprtopclip = lastopening - start; + lastopening += rw_stopx - start; + } + + if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip) + { + M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx - start)); + ds_p->sprbottomclip = lastopening - start; + lastopening += rw_stopx - start; + } } if (maskedtexture && !(ds_p->silhouette & SIL_TOP)) { ds_p->silhouette |= SIL_TOP; - ds_p->tsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MIN: INT32_MAX; + ds_p->tsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MIN : INT32_MAX; } if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM)) { ds_p->silhouette |= SIL_BOTTOM; - ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN; + ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX : INT32_MIN; } ds_p++; } diff --git a/src/r_segs.h b/src/r_segs.h index 09c68b27e..cad014674 100644 --- a/src/r_segs.h +++ b/src/r_segs.h @@ -22,5 +22,6 @@ transnum_t R_GetLinedefTransTable(fixed_t alpha); void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2); void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor); void R_StoreWallRange(INT32 start, INT32 stop); +void R_ClearSegTables(void); #endif