diff --git a/src/r_defs.h b/src/r_defs.h index 036e980b7e..4015103966 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -60,7 +60,6 @@ enum SIL_BOTH }; -namespace swrenderer { extern size_t MaxDrawSegs; } struct FDisplacement; // diff --git a/src/swrenderer/r_main.cpp b/src/swrenderer/r_main.cpp index 72cefcefa4..eefb4af83f 100644 --- a/src/swrenderer/r_main.cpp +++ b/src/swrenderer/r_main.cpp @@ -406,12 +406,7 @@ static void R_ShutdownRenderer() openings = NULL; } - // Free drawsegs - if (drawsegs != NULL) - { - M_Free (drawsegs); - drawsegs = NULL; - } + R_FreeDrawSegs(); } //========================================================================== diff --git a/src/swrenderer/scene/r_draw_segment.cpp b/src/swrenderer/scene/r_draw_segment.cpp index b6e29b3967..6181911f2a 100644 --- a/src/swrenderer/scene/r_draw_segment.cpp +++ b/src/swrenderer/scene/r_draw_segment.cpp @@ -26,17 +26,30 @@ namespace swrenderer { - size_t MaxDrawSegs; - drawseg_t *drawsegs; drawseg_t *firstdrawseg; drawseg_t *ds_p; + drawseg_t *drawsegs; size_t FirstInterestingDrawseg; TArray InterestingDrawsegs; + namespace + { + size_t MaxDrawSegs; + } + + void R_FreeDrawSegs() + { + if (drawsegs != nullptr) + { + M_Free(drawsegs); + drawsegs = nullptr; + } + } + void R_ClearDrawSegs() { - if (drawsegs == NULL) + if (drawsegs == nullptr) { MaxDrawSegs = 256; // [RH] Default. Increased as needed. firstdrawseg = drawsegs = (drawseg_t *)M_Malloc (MaxDrawSegs * sizeof(drawseg_t)); @@ -46,6 +59,22 @@ namespace swrenderer ds_p = drawsegs; } + drawseg_t *R_AddDrawSegment() + { + if (ds_p == &drawsegs[MaxDrawSegs]) + { // [RH] Grab some more drawsegs + size_t newdrawsegs = MaxDrawSegs ? MaxDrawSegs * 2 : 32; + ptrdiff_t firstofs = firstdrawseg - drawsegs; + drawsegs = (drawseg_t *)M_Realloc(drawsegs, newdrawsegs * sizeof(drawseg_t)); + firstdrawseg = drawsegs + firstofs; + ds_p = drawsegs + MaxDrawSegs; + MaxDrawSegs = newdrawsegs; + DPrintf(DMSG_NOTIFY, "MaxDrawSegs increased to %zu\n", MaxDrawSegs); + } + + return ds_p++; + } + ptrdiff_t R_NewOpening(ptrdiff_t len) { ptrdiff_t res = lastopening; @@ -61,18 +90,4 @@ namespace swrenderer } return res; } - - void R_CheckDrawSegs() - { - if (ds_p == &drawsegs[MaxDrawSegs]) - { // [RH] Grab some more drawsegs - size_t newdrawsegs = MaxDrawSegs ? MaxDrawSegs * 2 : 32; - ptrdiff_t firstofs = firstdrawseg - drawsegs; - drawsegs = (drawseg_t *)M_Realloc(drawsegs, newdrawsegs * sizeof(drawseg_t)); - firstdrawseg = drawsegs + firstofs; - ds_p = drawsegs + MaxDrawSegs; - MaxDrawSegs = newdrawsegs; - DPrintf(DMSG_NOTIFY, "MaxDrawSegs increased to %zu\n", MaxDrawSegs); - } - } } diff --git a/src/swrenderer/scene/r_draw_segment.h b/src/swrenderer/scene/r_draw_segment.h index d22e754e00..05d6c3846f 100644 --- a/src/swrenderer/scene/r_draw_segment.h +++ b/src/swrenderer/scene/r_draw_segment.h @@ -32,14 +32,16 @@ namespace swrenderer int CurrentPortalUniq; // [ZZ] to identify the portal that this drawseg is in. used for sprite clipping. }; - extern drawseg_t *drawsegs; extern drawseg_t *firstdrawseg; extern drawseg_t *ds_p; + extern drawseg_t *drawsegs; extern TArray InterestingDrawsegs; // drawsegs that have something drawn on them extern size_t FirstInterestingDrawseg; void R_ClearDrawSegs(); - void R_CheckDrawSegs(); + void R_FreeDrawSegs(); + + drawseg_t *R_AddDrawSegment(); ptrdiff_t R_NewOpening(ptrdiff_t len); } diff --git a/src/swrenderer/scene/r_plane.cpp b/src/swrenderer/scene/r_plane.cpp index 746205e707..2b698e2728 100644 --- a/src/swrenderer/scene/r_plane.cpp +++ b/src/swrenderer/scene/r_plane.cpp @@ -1446,26 +1446,26 @@ void R_DrawPortals () } // Create a drawseg to clip sprites to the sky plane - R_CheckDrawSegs (); - ds_p->CurrentPortalUniq = CurrentPortalUniq; - ds_p->siz1 = INT_MAX; - ds_p->siz2 = INT_MAX; - ds_p->sz1 = 0; - ds_p->sz2 = 0; - ds_p->x1 = pl->left; - ds_p->x2 = pl->right; - ds_p->silhouette = SIL_BOTH; - ds_p->sprbottomclip = R_NewOpening (pl->right - pl->left); - ds_p->sprtopclip = R_NewOpening (pl->right - pl->left); - ds_p->maskedtexturecol = ds_p->swall = -1; - ds_p->bFogBoundary = false; - ds_p->curline = NULL; - ds_p->fake = 0; - memcpy (openings + ds_p->sprbottomclip, floorclip + pl->left, (pl->right - pl->left)*sizeof(short)); - memcpy (openings + ds_p->sprtopclip, ceilingclip + pl->left, (pl->right - pl->left)*sizeof(short)); + drawseg_t *draw_segment = R_AddDrawSegment(); + draw_segment->CurrentPortalUniq = CurrentPortalUniq; + draw_segment->siz1 = INT_MAX; + draw_segment->siz2 = INT_MAX; + draw_segment->sz1 = 0; + draw_segment->sz2 = 0; + draw_segment->x1 = pl->left; + draw_segment->x2 = pl->right; + draw_segment->silhouette = SIL_BOTH; + draw_segment->sprbottomclip = R_NewOpening (pl->right - pl->left); + draw_segment->sprtopclip = R_NewOpening (pl->right - pl->left); + draw_segment->maskedtexturecol = ds_p->swall = -1; + draw_segment->bFogBoundary = false; + draw_segment->curline = NULL; + draw_segment->fake = 0; + memcpy (openings + draw_segment->sprbottomclip, floorclip + pl->left, (pl->right - pl->left)*sizeof(short)); + memcpy (openings + draw_segment->sprtopclip, ceilingclip + pl->left, (pl->right - pl->left)*sizeof(short)); firstvissprite = vissprite_p; - firstdrawseg = ds_p++; + firstdrawseg = draw_segment; FirstInterestingDrawseg = InterestingDrawsegs.Size(); interestingStack.Push (FirstInterestingDrawseg); diff --git a/src/swrenderer/scene/r_segs.cpp b/src/swrenderer/scene/r_segs.cpp index 833755fe1a..e8439ab140 100644 --- a/src/swrenderer/scene/r_segs.cpp +++ b/src/swrenderer/scene/r_segs.cpp @@ -1557,9 +1557,8 @@ bool R_StoreWallRange (int start, int stop) I_FatalError ("Bad R_StoreWallRange: %i to %i", start , stop); #endif - // don't overflow and crash - R_CheckDrawSegs (); - + drawseg_t *draw_segment = R_AddDrawSegment(); + if (!rw_prepped) { rw_prepped = true; @@ -1569,57 +1568,56 @@ bool R_StoreWallRange (int start, int stop) rw_offset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid)); rw_light = rw_lightleft + rw_lightstep * (start - WallC.sx1); - ds_p->CurrentPortalUniq = CurrentPortalUniq; - ds_p->sx1 = WallC.sx1; - ds_p->sx2 = WallC.sx2; - ds_p->sz1 = WallC.sz1; - ds_p->sz2 = WallC.sz2; - ds_p->cx = WallC.tleft.X;; - ds_p->cy = WallC.tleft.Y; - ds_p->cdx = WallC.tright.X - WallC.tleft.X; - ds_p->cdy = WallC.tright.Y - WallC.tleft.Y; - ds_p->tmapvals = WallT; - ds_p->siz1 = 1 / WallC.sz1; - ds_p->siz2 = 1 / WallC.sz2; - ds_p->x1 = rw_x = start; - ds_p->x2 = stop; - ds_p->curline = curline; + draw_segment->CurrentPortalUniq = CurrentPortalUniq; + draw_segment->sx1 = WallC.sx1; + draw_segment->sx2 = WallC.sx2; + draw_segment->sz1 = WallC.sz1; + draw_segment->sz2 = WallC.sz2; + draw_segment->cx = WallC.tleft.X;; + draw_segment->cy = WallC.tleft.Y; + draw_segment->cdx = WallC.tright.X - WallC.tleft.X; + draw_segment->cdy = WallC.tright.Y - WallC.tleft.Y; + draw_segment->tmapvals = WallT; + draw_segment->siz1 = 1 / WallC.sz1; + draw_segment->siz2 = 1 / WallC.sz2; + draw_segment->x1 = rw_x = start; + draw_segment->x2 = stop; + draw_segment->curline = curline; rw_stopx = stop; - ds_p->bFogBoundary = false; - ds_p->bFakeBoundary = false; - if(fake3D & 7) ds_p->fake = 1; - else ds_p->fake = 0; + draw_segment->bFogBoundary = false; + draw_segment->bFakeBoundary = false; + if(fake3D & 7) draw_segment->fake = 1; + else draw_segment->fake = 0; - // killough 1/6/98, 2/1/98: remove limit on openings - ds_p->sprtopclip = ds_p->sprbottomclip = ds_p->maskedtexturecol = ds_p->bkup = ds_p->swall = -1; + draw_segment->sprtopclip = draw_segment->sprbottomclip = draw_segment->maskedtexturecol = draw_segment->bkup = draw_segment->swall = -1; if (rw_markportal) { - ds_p->silhouette = SIL_BOTH; + draw_segment->silhouette = SIL_BOTH; } else if (backsector == NULL) { - ds_p->sprtopclip = R_NewOpening (stop - start); - ds_p->sprbottomclip = R_NewOpening (stop - start); - fillshort (openings + ds_p->sprtopclip, stop-start, viewheight); - memset (openings + ds_p->sprbottomclip, -1, (stop-start)*sizeof(short)); - ds_p->silhouette = SIL_BOTH; + draw_segment->sprtopclip = R_NewOpening (stop - start); + draw_segment->sprbottomclip = R_NewOpening (stop - start); + fillshort (openings + draw_segment->sprtopclip, stop-start, viewheight); + memset (openings + draw_segment->sprbottomclip, -1, (stop-start)*sizeof(short)); + draw_segment->silhouette = SIL_BOTH; } else { // two sided line - ds_p->silhouette = 0; + draw_segment->silhouette = 0; if (rw_frontfz1 > rw_backfz1 || rw_frontfz2 > rw_backfz2 || backsector->floorplane.PointOnSide(ViewPos) < 0) { - ds_p->silhouette = SIL_BOTTOM; + draw_segment->silhouette = SIL_BOTTOM; } if (rw_frontcz1 < rw_backcz1 || rw_frontcz2 < rw_backcz2 || backsector->ceilingplane.PointOnSide(ViewPos) < 0) { - ds_p->silhouette |= SIL_TOP; + draw_segment->silhouette |= SIL_TOP; } // killough 1/17/98: this test is required if the fix @@ -1634,41 +1632,41 @@ bool R_StoreWallRange (int start, int stop) extern int doorclosed; // killough 1/17/98, 2/8/98, 4/7/98 if (doorclosed || (rw_backcz1 <= rw_frontfz1 && rw_backcz2 <= rw_frontfz2)) { - ds_p->sprbottomclip = R_NewOpening (stop - start); - memset (openings + ds_p->sprbottomclip, -1, (stop-start)*sizeof(short)); - ds_p->silhouette |= SIL_BOTTOM; + draw_segment->sprbottomclip = R_NewOpening (stop - start); + memset (openings + draw_segment->sprbottomclip, -1, (stop-start)*sizeof(short)); + draw_segment->silhouette |= SIL_BOTTOM; } if (doorclosed || (rw_backfz1 >= rw_frontcz1 && rw_backfz2 >= rw_frontcz2)) { // killough 1/17/98, 2/8/98 - ds_p->sprtopclip = R_NewOpening (stop - start); - fillshort (openings + ds_p->sprtopclip, stop - start, viewheight); - ds_p->silhouette |= SIL_TOP; + draw_segment->sprtopclip = R_NewOpening (stop - start); + fillshort (openings + draw_segment->sprtopclip, stop - start, viewheight); + draw_segment->silhouette |= SIL_TOP; } } - if(!ds_p->fake && r_3dfloors && backsector->e && backsector->e->XFloor.ffloors.Size()) { + if(!draw_segment->fake && r_3dfloors && backsector->e && backsector->e->XFloor.ffloors.Size()) { for(i = 0; i < (int)backsector->e->XFloor.ffloors.Size(); i++) { F3DFloor *rover = backsector->e->XFloor.ffloors[i]; if(rover->flags & FF_RENDERSIDES && (!(rover->flags & FF_INVERTSIDES) || rover->flags & FF_ALLSIDES)) { - ds_p->bFakeBoundary |= 1; + draw_segment->bFakeBoundary |= 1; break; } } } - if(!ds_p->fake && r_3dfloors && frontsector->e && frontsector->e->XFloor.ffloors.Size()) { + if(!draw_segment->fake && r_3dfloors && frontsector->e && frontsector->e->XFloor.ffloors.Size()) { for(i = 0; i < (int)frontsector->e->XFloor.ffloors.Size(); i++) { F3DFloor *rover = frontsector->e->XFloor.ffloors[i]; if(rover->flags & FF_RENDERSIDES && (rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES)) { - ds_p->bFakeBoundary |= 2; + draw_segment->bFakeBoundary |= 2; break; } } } // kg3D - no for fakes - if(!ds_p->fake) + if(!draw_segment->fake) // allocate space for masked texture tables, if needed // [RH] Don't just allocate the space; fill it in too. - if ((TexMan(sidedef->GetTexture(side_t::mid), true)->UseType != FTexture::TEX_Null || ds_p->bFakeBoundary || IsFogBoundary (frontsector, backsector)) && + if ((TexMan(sidedef->GetTexture(side_t::mid), true)->UseType != FTexture::TEX_Null || draw_segment->bFakeBoundary || IsFogBoundary (frontsector, backsector)) && (rw_ceilstat != 12 || !sidedef->GetTexture(side_t::top).isValid()) && (rw_floorstat != 3 || !sidedef->GetTexture(side_t::bottom).isValid()) && (WallC.sz1 >= TOO_CLOSE_Z && WallC.sz2 >= TOO_CLOSE_Z)) @@ -1680,21 +1678,21 @@ bool R_StoreWallRange (int start, int stop) maskedtexture = true; // kg3D - backup for mid and fake walls - ds_p->bkup = R_NewOpening(stop - start); - memcpy(openings + ds_p->bkup, &ceilingclip[start], sizeof(short)*(stop - start)); + draw_segment->bkup = R_NewOpening(stop - start); + memcpy(openings + draw_segment->bkup, &ceilingclip[start], sizeof(short)*(stop - start)); - ds_p->bFogBoundary = IsFogBoundary (frontsector, backsector); - if (sidedef->GetTexture(side_t::mid).isValid() || ds_p->bFakeBoundary) + draw_segment->bFogBoundary = IsFogBoundary (frontsector, backsector); + if (sidedef->GetTexture(side_t::mid).isValid() || draw_segment->bFakeBoundary) { if(sidedef->GetTexture(side_t::mid).isValid()) - ds_p->bFakeBoundary |= 4; // it is also mid texture + draw_segment->bFakeBoundary |= 4; // it is also mid texture // note: This should never have used the openings array to store its data! - ds_p->maskedtexturecol = R_NewOpening ((stop - start) * 2); - ds_p->swall = R_NewOpening ((stop - start) * 2); + draw_segment->maskedtexturecol = R_NewOpening ((stop - start) * 2); + draw_segment->swall = R_NewOpening ((stop - start) * 2); - lwal = (fixed_t *)(openings + ds_p->maskedtexturecol); - swal = (float *)(openings + ds_p->swall); + lwal = (fixed_t *)(openings + draw_segment->maskedtexturecol); + swal = (float *)(openings + draw_segment->swall); FTexture *pic = TexMan(sidedef->GetTexture(side_t::mid), true); double yscale = pic->Scale.Y * sidedef->GetTextureYScale(side_t::mid); fixed_t xoffset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid)); @@ -1710,7 +1708,7 @@ bool R_StoreWallRange (int start, int stop) *swal++ = swall[i]; } - double istart = *((float *)(openings + ds_p->swall)) * yscale; + double istart = *((float *)(openings + draw_segment->swall)) * yscale; double iend = *(swal - 1) * yscale; #if 0 ///This was for avoiding overflow when using fixed point. It might not be needed anymore. @@ -1722,19 +1720,19 @@ bool R_StoreWallRange (int start, int stop) #endif istart = 1 / istart; iend = 1 / iend; - ds_p->yscale = (float)yscale; - ds_p->iscale = (float)istart; + draw_segment->yscale = (float)yscale; + draw_segment->iscale = (float)istart; if (stop - start > 0) { - ds_p->iscalestep = float((iend - istart) / (stop - start)); + draw_segment->iscalestep = float((iend - istart) / (stop - start)); } else { - ds_p->iscalestep = 0; + draw_segment->iscalestep = 0; } } - ds_p->light = rw_light; - ds_p->lightstep = rw_lightstep; + draw_segment->light = rw_light; + draw_segment->lightstep = rw_lightstep; // Masked midtextures should get the light level from the sector they reference, // not from the current subsector, which is what the current wallshade value @@ -1742,17 +1740,17 @@ bool R_StoreWallRange (int start, int stop) // sector should be whichever one they move into. if (curline->sidedef->Flags & WALLF_POLYOBJ) { - ds_p->shade = wallshade; + draw_segment->shade = wallshade; } else { - ds_p->shade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, curline->frontsector->lightlevel) + draw_segment->shade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, curline->frontsector->lightlevel) + r_actualextralight); } - if (ds_p->bFogBoundary || ds_p->maskedtexturecol != -1) + if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != -1) { - size_t drawsegnum = ds_p - drawsegs; + size_t drawsegnum = draw_segment - drawsegs; InterestingDrawsegs.Push (drawsegnum); } } @@ -1786,27 +1784,25 @@ bool R_StoreWallRange (int start, int stop) R_RenderSegLoop (); if(fake3D & 7) { - ds_p++; - return !(fake3D & FAKE3D_FAKEMASK); } // save sprite clipping info - if ( ((ds_p->silhouette & SIL_TOP) || maskedtexture) && ds_p->sprtopclip == -1) + if ( ((draw_segment->silhouette & SIL_TOP) || maskedtexture) && draw_segment->sprtopclip == -1) { - ds_p->sprtopclip = R_NewOpening (stop - start); - memcpy (openings + ds_p->sprtopclip, &ceilingclip[start], sizeof(short)*(stop-start)); + draw_segment->sprtopclip = R_NewOpening (stop - start); + memcpy (openings + draw_segment->sprtopclip, &ceilingclip[start], sizeof(short)*(stop-start)); } - if ( ((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && ds_p->sprbottomclip == -1) + if ( ((draw_segment->silhouette & SIL_BOTTOM) || maskedtexture) && draw_segment->sprbottomclip == -1) { - ds_p->sprbottomclip = R_NewOpening (stop - start); - memcpy (openings + ds_p->sprbottomclip, &floorclip[start], sizeof(short)*(stop-start)); + draw_segment->sprbottomclip = R_NewOpening (stop - start); + memcpy (openings + draw_segment->sprbottomclip, &floorclip[start], sizeof(short)*(stop-start)); } if (maskedtexture && curline->sidedef->GetTexture(side_t::mid).isValid()) { - ds_p->silhouette |= SIL_TOP | SIL_BOTTOM; + draw_segment->silhouette |= SIL_TOP | SIL_BOTTOM; } // [RH] Draw any decals bound to the seg @@ -1815,7 +1811,7 @@ bool R_StoreWallRange (int start, int stop) { for (DBaseDecal *decal = curline->sidedef->AttachedDecals; decal != NULL; decal = decal->WallNext) { - R_RenderDecal (curline->sidedef, decal, ds_p, 0); + R_RenderDecal (curline->sidedef, decal, draw_segment, 0); } } @@ -1824,13 +1820,13 @@ bool R_StoreWallRange (int start, int stop) PortalDrawseg pds; pds.src = curline->linedef; pds.dst = curline->linedef->special == Line_Mirror? curline->linedef : curline->linedef->getPortalDestination(); - pds.x1 = ds_p->x1; - pds.x2 = ds_p->x2; + pds.x1 = draw_segment->x1; + pds.x2 = draw_segment->x2; pds.len = pds.x2 - pds.x1; pds.ceilingclip.Resize(pds.len); - memcpy(&pds.ceilingclip[0], openings + ds_p->sprtopclip, pds.len*sizeof(*openings)); + memcpy(&pds.ceilingclip[0], openings + draw_segment->sprtopclip, pds.len*sizeof(*openings)); pds.floorclip.Resize(pds.len); - memcpy(&pds.floorclip[0], openings + ds_p->sprbottomclip, pds.len*sizeof(*openings)); + memcpy(&pds.floorclip[0], openings + draw_segment->sprbottomclip, pds.len*sizeof(*openings)); for (int i = 0; i < pds.x2-pds.x1; i++) { @@ -1848,8 +1844,6 @@ bool R_StoreWallRange (int start, int stop) WallPortals.Push(pds); } - ds_p++; - return !(fake3D & FAKE3D_FAKEMASK); }