mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-24 05:11:08 +00:00
Undo clipsegs optimization
This commit is contained in:
parent
e22ea1f2e9
commit
5f5fff7e58
4 changed files with 162 additions and 99 deletions
217
src/r_bsp.c
217
src/r_bsp.c
|
@ -52,66 +52,164 @@ void R_ClearDrawSegs(void)
|
|||
ds_p = drawsegs;
|
||||
}
|
||||
|
||||
// CPhipps -
|
||||
// Instead of clipsegs, let's try using an array with one entry for each column,
|
||||
// indicating whether it's blocked by a solid wall yet or not.
|
||||
UINT8 solidcol[MAXVIDWIDTH];
|
||||
// Fix from boom.
|
||||
#define MAXSEGS (MAXVIDWIDTH/2+1)
|
||||
|
||||
// newend is one past the last valid seg
|
||||
static cliprange_t *newend;
|
||||
static cliprange_t solidsegs[MAXSEGS];
|
||||
|
||||
// CPhipps -
|
||||
// R_ClipWallSegment
|
||||
//
|
||||
// Replaces the old R_Clip*WallSegment functions. It draws bits of walls in those
|
||||
// columns which aren't solid, and updates the solidcol[] array appropriately
|
||||
static void R_ClipWallSegment(INT32 first, INT32 last, boolean solid)
|
||||
// R_ClipSolidWallSegment
|
||||
// Does handle solid walls,
|
||||
// e.g. single sided LineDefs (middle texture)
|
||||
// that entirely block the view.
|
||||
//
|
||||
static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
||||
{
|
||||
while (first < last)
|
||||
cliprange_t *next;
|
||||
cliprange_t *start;
|
||||
|
||||
// Find the first range that touches the range (adjacent pixels are touching).
|
||||
start = solidsegs;
|
||||
while (start->last < first - 1)
|
||||
start++;
|
||||
|
||||
if (first < start->first)
|
||||
{
|
||||
UINT8 *p;
|
||||
|
||||
if (solidcol[first])
|
||||
if (last < start->first - 1)
|
||||
{
|
||||
p = memchr(solidcol+first, 0, last-first);
|
||||
if (!p)
|
||||
return; // All solid
|
||||
// Post is entirely visible (above start), so insert a new clippost.
|
||||
R_StoreWallRange(first, last);
|
||||
next = newend;
|
||||
newend++;
|
||||
// NO MORE CRASHING!
|
||||
if (newend - solidsegs > MAXSEGS)
|
||||
I_Error("R_ClipSolidWallSegment: Solid Segs overflow!\n");
|
||||
|
||||
first = p - solidcol;
|
||||
while (next != start)
|
||||
{
|
||||
*next = *(next-1);
|
||||
next--;
|
||||
}
|
||||
next->first = first;
|
||||
next->last = last;
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
// There is a fragment above *start.
|
||||
R_StoreWallRange(first, start->first - 1);
|
||||
// Now adjust the clip size.
|
||||
start->first = first;
|
||||
}
|
||||
|
||||
// Bottom contained in start?
|
||||
if (last <= start->last)
|
||||
return;
|
||||
|
||||
next = start;
|
||||
while (last >= (next+1)->first - 1)
|
||||
{
|
||||
// There is a fragment between two posts.
|
||||
R_StoreWallRange(next->last + 1, (next+1)->first - 1);
|
||||
next++;
|
||||
|
||||
if (last <= next->last)
|
||||
{
|
||||
p = memchr(solidcol+first, 1, last-first);
|
||||
|
||||
int to;
|
||||
if (!p)
|
||||
to = last;
|
||||
else
|
||||
to = p - solidcol;
|
||||
|
||||
R_StoreWallRange(first, to-1);
|
||||
|
||||
if (solid)
|
||||
memset(solidcol+first, 1, to-first);
|
||||
|
||||
first = to;
|
||||
// Bottom is contained in next.
|
||||
// Adjust the clip size.
|
||||
start->last = next->last;
|
||||
goto crunch;
|
||||
}
|
||||
}
|
||||
|
||||
// There is a fragment after *next.
|
||||
R_StoreWallRange(next->last + 1, last);
|
||||
// Adjust the clip size.
|
||||
start->last = last;
|
||||
|
||||
// Remove start+1 to next from the clip list, because start now covers their area.
|
||||
crunch:
|
||||
if (next == start)
|
||||
return; // Post just extended past the bottom of one post.
|
||||
|
||||
while (next++ != newend)
|
||||
*++start = *next; // Remove a post.
|
||||
|
||||
newend = start + 1;
|
||||
|
||||
// NO MORE CRASHING!
|
||||
if (newend - solidsegs > MAXSEGS)
|
||||
I_Error("R_ClipSolidWallSegment: Solid Segs overflow!\n");
|
||||
}
|
||||
|
||||
//
|
||||
// R_ClipPassWallSegment
|
||||
// Clips the given range of columns, but does not include it in the clip list.
|
||||
// Does handle windows, e.g. LineDefs with upper and lower texture.
|
||||
//
|
||||
static inline void R_ClipPassWallSegment(INT32 first, INT32 last)
|
||||
{
|
||||
cliprange_t *start;
|
||||
|
||||
// Find the first range that touches the range
|
||||
// (adjacent pixels are touching).
|
||||
start = solidsegs;
|
||||
while (start->last < first - 1)
|
||||
start++;
|
||||
|
||||
if (first < start->first)
|
||||
{
|
||||
if (last < start->first - 1)
|
||||
{
|
||||
// Post is entirely visible (above start).
|
||||
R_StoreWallRange(first, last);
|
||||
return;
|
||||
}
|
||||
|
||||
// There is a fragment above *start.
|
||||
R_StoreWallRange(first, start->first - 1);
|
||||
}
|
||||
|
||||
// Bottom contained in start?
|
||||
if (last <= start->last)
|
||||
return;
|
||||
|
||||
while (last >= (start+1)->first - 1)
|
||||
{
|
||||
// There is a fragment between two posts.
|
||||
R_StoreWallRange(start->last + 1, (start+1)->first - 1);
|
||||
start++;
|
||||
|
||||
if (last <= start->last)
|
||||
return;
|
||||
}
|
||||
|
||||
// There is a fragment after *next.
|
||||
R_StoreWallRange(start->last + 1, last);
|
||||
}
|
||||
|
||||
//
|
||||
// R_ClearClipSegs
|
||||
//
|
||||
void R_ClearClipSegs(void)
|
||||
{
|
||||
memset(solidcol, 0, viewwidth);
|
||||
solidsegs[0].first = -0x7fffffff;
|
||||
solidsegs[0].last = -1;
|
||||
solidsegs[1].first = viewwidth;
|
||||
solidsegs[1].last = 0x7fffffff;
|
||||
newend = solidsegs + 2;
|
||||
}
|
||||
|
||||
void R_PortalClearClipSegs(INT32 start, INT32 end)
|
||||
{
|
||||
R_ClearClipSegs();
|
||||
|
||||
for (INT32 x = 0; x < start; x++)
|
||||
solidcol[x] = 1;
|
||||
|
||||
for (INT32 x = end; x < viewwidth; x++)
|
||||
solidcol[x] = 1;
|
||||
solidsegs[0].first = -0x7fffffff;
|
||||
solidsegs[0].last = start-1;
|
||||
solidsegs[1].first = end;
|
||||
solidsegs[1].last = 0x7fffffff;
|
||||
newend = solidsegs + 2;
|
||||
}
|
||||
|
||||
|
||||
// R_DoorClosed
|
||||
//
|
||||
// This function is used to fix the automap bug which
|
||||
|
@ -517,11 +615,11 @@ static void R_AddLine(seg_t *line)
|
|||
return;
|
||||
|
||||
clippass:
|
||||
R_ClipWallSegment(x1, x2, false);
|
||||
R_ClipPassWallSegment(x1, x2 - 1);
|
||||
return;
|
||||
|
||||
clipsolid:
|
||||
R_ClipWallSegment(x1, x2, true);
|
||||
R_ClipSolidWallSegment(x1, x2 - 1);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -554,23 +652,10 @@ static boolean R_CheckBBox(const fixed_t *bspcoord)
|
|||
angle_t angle1, angle2;
|
||||
INT32 sx1, sx2, boxpos;
|
||||
const INT32* check;
|
||||
cliprange_t *start;
|
||||
|
||||
// Find the corners of the box that define the edges from current viewpoint.
|
||||
if (viewx <= bspcoord[BOXLEFT])
|
||||
boxpos = 0;
|
||||
else if (viewx < bspcoord[BOXRIGHT])
|
||||
boxpos = 1;
|
||||
else
|
||||
boxpos = 2;
|
||||
|
||||
if (viewy >= bspcoord[BOXTOP])
|
||||
boxpos |= 0;
|
||||
else if (viewy > bspcoord[BOXBOTTOM])
|
||||
boxpos |= 1<<2;
|
||||
else
|
||||
boxpos |= 2<<2;
|
||||
|
||||
if (boxpos == 5)
|
||||
if ((boxpos = (viewx <= bspcoord[BOXLEFT] ? 0 : viewx < bspcoord[BOXRIGHT] ? 1 : 2) + (viewy >= bspcoord[BOXTOP] ? 0 : viewy > bspcoord[BOXBOTTOM] ? 4 : 8)) == 5)
|
||||
return true;
|
||||
|
||||
check = checkcoord[boxpos];
|
||||
|
@ -599,14 +684,14 @@ static boolean R_CheckBBox(const fixed_t *bspcoord)
|
|||
sx2 = viewangletox[angle2];
|
||||
|
||||
// Does not cross a pixel.
|
||||
if (sx1 >= sx2)
|
||||
return false;
|
||||
if (sx1 >= sx2) return false;
|
||||
|
||||
if (!memchr(solidcol+sx1, 0, sx2-sx1))
|
||||
{
|
||||
// All columns it covers are already solidly covered
|
||||
return false;
|
||||
}
|
||||
start = solidsegs;
|
||||
while (start->last < sx2)
|
||||
start++;
|
||||
|
||||
if (sx1 >= start->first && sx2 <= start->last)
|
||||
return false; // The clippost contains the new span.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1313,7 +1398,7 @@ void R_RenderPortalHorizonLine(sector_t *sector)
|
|||
firstseg = NULL;
|
||||
curline = &segs[0];
|
||||
|
||||
R_ClipWallSegment(portalclipstart, portalclipend, true);
|
||||
R_ClipSolidWallSegment(portalclipstart, portalclipend);
|
||||
|
||||
curline = NULL;
|
||||
}
|
||||
|
|
|
@ -38,8 +38,6 @@ extern boolean horizonline;
|
|||
|
||||
extern INT32 doorclosed;
|
||||
|
||||
extern UINT8 solidcol[MAXVIDWIDTH];
|
||||
|
||||
// BSP?
|
||||
void R_ClearClipSegs(void);
|
||||
void R_PortalClearClipSegs(INT32 start, INT32 end);
|
||||
|
|
11
src/r_defs.h
11
src/r_defs.h
|
@ -31,6 +31,17 @@
|
|||
|
||||
#include "taglist.h"
|
||||
|
||||
//
|
||||
// ClipWallSegment
|
||||
// Clips the given range of columns
|
||||
// and includes it in the new clip list.
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
INT32 first;
|
||||
INT32 last;
|
||||
} cliprange_t;
|
||||
|
||||
// Silhouette, needed for clipping segs (mainly) and sprites representing things.
|
||||
#define SIL_NONE 0
|
||||
#define SIL_BOTTOM 1
|
||||
|
|
31
src/r_segs.c
31
src/r_segs.c
|
@ -994,8 +994,6 @@ static boolean R_FFloorCanClip(visffloor_t *pfloor)
|
|||
return (cv_ffloorclip.value && !R_IsFFloorTranslucent(pfloor) && !pfloor->polyobj);
|
||||
}
|
||||
|
||||
static boolean didsolidcol; // True if at least one column was marked solid
|
||||
|
||||
//
|
||||
// R_RenderSegLoop
|
||||
// Draws zero, one, or two textures (and possibly a masked
|
||||
|
@ -1437,12 +1435,6 @@ static void R_RenderSegLoop (void)
|
|||
floorclip[rw_x] = bottomclip;
|
||||
}
|
||||
|
||||
if ((markceiling || markfloor) && (floorclip[rw_x] <= ceilingclip[rw_x] + 1))
|
||||
{
|
||||
solidcol[rw_x] = 1;
|
||||
didsolidcol = true;
|
||||
}
|
||||
|
||||
if (maskedtexturecol)
|
||||
maskedtexturecol[rw_x] = texturecolumn + rw_offsetx;
|
||||
|
||||
|
@ -1565,12 +1557,6 @@ static void R_MarkSegBounds(void)
|
|||
if (markfloor) // no bottom wall
|
||||
floorclip[rw_x] = bottomclip;
|
||||
|
||||
if (floorclip[rw_x] <= ceilingclip[rw_x] + 1)
|
||||
{
|
||||
solidcol[rw_x] = 1;
|
||||
didsolidcol = true;
|
||||
}
|
||||
|
||||
rw_scale += rw_scalestep;
|
||||
topfrac += topstep;
|
||||
bottomfrac += bottomstep;
|
||||
|
@ -2954,8 +2940,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
}
|
||||
}
|
||||
|
||||
didsolidcol = false;
|
||||
|
||||
if (!segtextured && !numffloors && !numbackffloors)
|
||||
{
|
||||
if (markfloor || markceiling)
|
||||
|
@ -2985,21 +2969,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
else
|
||||
ds_p->portalpass = 0;
|
||||
|
||||
// cph - if a column was made solid by this wall, we _must_ save full clipping info
|
||||
if (backsector && didsolidcol)
|
||||
{
|
||||
if (!(ds_p->silhouette & SIL_BOTTOM))
|
||||
{
|
||||
ds_p->silhouette |= SIL_BOTTOM;
|
||||
ds_p->bsilheight = backsector->f_slope ? INT32_MAX : backsector->floorheight;
|
||||
}
|
||||
if (!(ds_p->silhouette & SIL_TOP))
|
||||
{
|
||||
ds_p->silhouette |= SIL_TOP;
|
||||
ds_p->tsilheight = backsector->c_slope ? INT32_MIN : backsector->ceilingheight;
|
||||
}
|
||||
}
|
||||
|
||||
// save sprite clipping info
|
||||
if (maskedtexture || (ds_p->silhouette & (SIL_TOP | SIL_BOTTOM)))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue