mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 15:22:16 +00:00
Move all clip segment handling to r_clip_segment and make its working data private
This commit is contained in:
parent
1b284ecf3b
commit
18a551f936
5 changed files with 164 additions and 173 deletions
|
@ -96,148 +96,6 @@ WORD MirrorFlags;
|
||||||
|
|
||||||
subsector_t *InSubsector;
|
subsector_t *InSubsector;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void R_StoreWallRange (int start, int stop);
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// R_ClipWallSegment
|
|
||||||
//
|
|
||||||
// Clips the given range of columns, possibly including it in the clip list.
|
|
||||||
// Handles both windows (e.g. LineDefs with upper and lower textures) and
|
|
||||||
// solid walls (e.g. single sided LineDefs [middle texture]) that entirely
|
|
||||||
// block the view.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
bool R_ClipWallSegment (int first, int last, bool solid)
|
|
||||||
{
|
|
||||||
cliprange_t *next, *start;
|
|
||||||
int i, j;
|
|
||||||
bool res = false;
|
|
||||||
|
|
||||||
// Find the first range that touches the range
|
|
||||||
// (adjacent pixels are touching).
|
|
||||||
start = solidsegs;
|
|
||||||
while (start->last < first)
|
|
||||||
start++;
|
|
||||||
|
|
||||||
if (first < start->first)
|
|
||||||
{
|
|
||||||
res = true;
|
|
||||||
if (last <= start->first)
|
|
||||||
{
|
|
||||||
// Post is entirely visible (above start).
|
|
||||||
R_StoreWallRange (first, last);
|
|
||||||
if (fake3D & FAKE3D_FAKEMASK)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert a new clippost for solid walls.
|
|
||||||
if (solid)
|
|
||||||
{
|
|
||||||
if (last == start->first)
|
|
||||||
{
|
|
||||||
start->first = first;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
next = newend;
|
|
||||||
newend++;
|
|
||||||
while (next != start)
|
|
||||||
{
|
|
||||||
*next = *(next-1);
|
|
||||||
next--;
|
|
||||||
}
|
|
||||||
next->first = first;
|
|
||||||
next->last = last;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is a fragment above *start.
|
|
||||||
R_StoreWallRange (first, start->first);
|
|
||||||
|
|
||||||
// Adjust the clip size for solid walls
|
|
||||||
if (solid && !(fake3D & FAKE3D_FAKEMASK))
|
|
||||||
{
|
|
||||||
start->first = first;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bottom contained in start?
|
|
||||||
if (last <= start->last)
|
|
||||||
return res;
|
|
||||||
|
|
||||||
next = start;
|
|
||||||
while (last >= (next+1)->first)
|
|
||||||
{
|
|
||||||
// There is a fragment between two posts.
|
|
||||||
R_StoreWallRange (next->last, (next+1)->first);
|
|
||||||
next++;
|
|
||||||
|
|
||||||
if (last <= next->last)
|
|
||||||
{
|
|
||||||
// Bottom is contained in next.
|
|
||||||
last = next->last;
|
|
||||||
goto crunch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is a fragment after *next.
|
|
||||||
R_StoreWallRange (next->last, last);
|
|
||||||
|
|
||||||
crunch:
|
|
||||||
if (fake3D & FAKE3D_FAKEMASK)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (solid)
|
|
||||||
{
|
|
||||||
// Adjust the clip size.
|
|
||||||
start->last = last;
|
|
||||||
|
|
||||||
if (next != start)
|
|
||||||
{
|
|
||||||
// Remove start+1 to next from the clip list,
|
|
||||||
// because start now covers their area.
|
|
||||||
for (i = 1, j = (int)(newend - next); j > 0; i++, j--)
|
|
||||||
{
|
|
||||||
start[i] = next[i];
|
|
||||||
}
|
|
||||||
newend = start+i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool R_CheckClipWallSegment (int first, int last)
|
|
||||||
{
|
|
||||||
cliprange_t *start;
|
|
||||||
|
|
||||||
// Find the first range that touches the range
|
|
||||||
// (adjacent pixels are touching).
|
|
||||||
start = solidsegs;
|
|
||||||
while (start->last < first)
|
|
||||||
start++;
|
|
||||||
|
|
||||||
if (first < start->first)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bottom contained in start?
|
|
||||||
if (last > start->last)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// killough 3/7/98: Hack floor/ceiling heights for deep water etc.
|
// killough 3/7/98: Hack floor/ceiling heights for deep water etc.
|
||||||
//
|
//
|
||||||
|
@ -703,7 +561,7 @@ void R_AddLine (seg_t *line)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (R_ClipWallSegment (WallC.sx1, WallC.sx2, solid))
|
if (R_ClipWallSegment(WallC.sx1, WallC.sx2, solid, R_StoreWallRange))
|
||||||
{
|
{
|
||||||
InSubsector->flags |= SSECF_DRAWN;
|
InSubsector->flags |= SSECF_DRAWN;
|
||||||
}
|
}
|
||||||
|
@ -836,8 +694,6 @@ static bool R_CheckBBox (float *bspcoord) // killough 1/28/98: static
|
||||||
double rx1, ry1, rx2, ry2;
|
double rx1, ry1, rx2, ry2;
|
||||||
int sx1, sx2;
|
int sx1, sx2;
|
||||||
|
|
||||||
cliprange_t* start;
|
|
||||||
|
|
||||||
// Find the corners of the box
|
// Find the corners of the box
|
||||||
// that define the edges from current viewpoint.
|
// that define the edges from current viewpoint.
|
||||||
if (ViewPos.X <= bspcoord[BOXLEFT])
|
if (ViewPos.X <= bspcoord[BOXLEFT])
|
||||||
|
@ -911,21 +767,7 @@ static bool R_CheckBBox (float *bspcoord) // killough 1/28/98: static
|
||||||
// Find the first clippost that touches the source post
|
// Find the first clippost that touches the source post
|
||||||
// (adjacent pixels are touching).
|
// (adjacent pixels are touching).
|
||||||
|
|
||||||
// Does not cross a pixel.
|
return R_IsWallSegmentVisible(sx1, sx2);
|
||||||
if (sx2 <= sx1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
start = solidsegs;
|
|
||||||
while (start->last < sx2)
|
|
||||||
start++;
|
|
||||||
|
|
||||||
if (sx1 >= start->first && sx2 <= start->last)
|
|
||||||
{
|
|
||||||
// The clippost contains the new span.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,16 @@
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
cliprange_t *newend;
|
namespace
|
||||||
cliprange_t solidsegs[MAXWIDTH/2+2];
|
{
|
||||||
|
struct cliprange_t
|
||||||
|
{
|
||||||
|
short first, last;
|
||||||
|
};
|
||||||
|
|
||||||
|
cliprange_t *newend; // newend is one past the last valid seg
|
||||||
|
cliprange_t solidsegs[MAXWIDTH / 2 + 2];
|
||||||
|
}
|
||||||
|
|
||||||
void R_ClearClipSegs(short left, short right)
|
void R_ClearClipSegs(short left, short right)
|
||||||
{
|
{
|
||||||
|
@ -37,4 +45,145 @@ namespace swrenderer
|
||||||
solidsegs[1].last = 0x7fff;
|
solidsegs[1].last = 0x7fff;
|
||||||
newend = solidsegs+2;
|
newend = solidsegs+2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool R_CheckClipWallSegment(int first, int last)
|
||||||
|
{
|
||||||
|
cliprange_t *start;
|
||||||
|
|
||||||
|
// Find the first range that touches the range
|
||||||
|
// (adjacent pixels are touching).
|
||||||
|
start = solidsegs;
|
||||||
|
while (start->last < first)
|
||||||
|
start++;
|
||||||
|
|
||||||
|
if (first < start->first)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bottom contained in start?
|
||||||
|
if (last > start->last)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool R_IsWallSegmentVisible(int sx1, int sx2)
|
||||||
|
{
|
||||||
|
// Does not cross a pixel.
|
||||||
|
if (sx2 <= sx1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
cliprange_t *start = solidsegs;
|
||||||
|
while (start->last < sx2)
|
||||||
|
start++;
|
||||||
|
|
||||||
|
if (sx1 >= start->first && sx2 <= start->last)
|
||||||
|
{
|
||||||
|
// The clippost contains the new span.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool R_ClipWallSegment(int first, int last, bool solid, VisibleSegmentCallback callback)
|
||||||
|
{
|
||||||
|
cliprange_t *next, *start;
|
||||||
|
int i, j;
|
||||||
|
bool res = false;
|
||||||
|
|
||||||
|
// Find the first range that touches the range
|
||||||
|
// (adjacent pixels are touching).
|
||||||
|
start = solidsegs;
|
||||||
|
while (start->last < first)
|
||||||
|
start++;
|
||||||
|
|
||||||
|
if (first < start->first)
|
||||||
|
{
|
||||||
|
res = true;
|
||||||
|
if (last <= start->first)
|
||||||
|
{
|
||||||
|
// Post is entirely visible (above start).
|
||||||
|
if (!callback(first, last))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Insert a new clippost for solid walls.
|
||||||
|
if (solid)
|
||||||
|
{
|
||||||
|
if (last == start->first)
|
||||||
|
{
|
||||||
|
start->first = first;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
next = newend;
|
||||||
|
newend++;
|
||||||
|
while (next != start)
|
||||||
|
{
|
||||||
|
*next = *(next - 1);
|
||||||
|
next--;
|
||||||
|
}
|
||||||
|
next->first = first;
|
||||||
|
next->last = last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is a fragment above *start.
|
||||||
|
if (!callback(first, start->first) && solid)
|
||||||
|
{
|
||||||
|
start->first = first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bottom contained in start?
|
||||||
|
if (last <= start->last)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
bool clipsegment;
|
||||||
|
next = start;
|
||||||
|
while (last >= (next + 1)->first)
|
||||||
|
{
|
||||||
|
// There is a fragment between two posts.
|
||||||
|
clipsegment = callback(next->last, (next + 1)->first);
|
||||||
|
next++;
|
||||||
|
|
||||||
|
if (last <= next->last)
|
||||||
|
{
|
||||||
|
// Bottom is contained in next.
|
||||||
|
last = next->last;
|
||||||
|
goto crunch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is a fragment after *next.
|
||||||
|
clipsegment = callback(next->last, last);
|
||||||
|
|
||||||
|
crunch:
|
||||||
|
if (!clipsegment)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (solid)
|
||||||
|
{
|
||||||
|
// Adjust the clip size.
|
||||||
|
start->last = last;
|
||||||
|
|
||||||
|
if (next != start)
|
||||||
|
{
|
||||||
|
// Remove start+1 to next from the clip list,
|
||||||
|
// because start now covers their area.
|
||||||
|
for (i = 1, j = (int)(newend - next); j > 0; i++, j--)
|
||||||
|
{
|
||||||
|
start[i] = next[i];
|
||||||
|
}
|
||||||
|
newend = start + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,10 @@
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
struct cliprange_t
|
typedef bool(*VisibleSegmentCallback)(int x1, int x2);
|
||||||
{
|
|
||||||
short first, last;
|
|
||||||
};
|
|
||||||
|
|
||||||
// newend is one past the last valid seg
|
|
||||||
extern cliprange_t *newend;
|
|
||||||
extern cliprange_t solidsegs[MAXWIDTH/2+2];
|
|
||||||
|
|
||||||
void R_ClearClipSegs(short left, short right);
|
void R_ClearClipSegs(short left, short right);
|
||||||
|
bool R_ClipWallSegment(int x1, int x2, bool solid, VisibleSegmentCallback callback);
|
||||||
|
bool R_CheckClipWallSegment(int first, int last);
|
||||||
|
bool R_IsWallSegmentVisible(int x1, int x2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1587,7 +1587,7 @@ ptrdiff_t R_NewOpening (ptrdiff_t len)
|
||||||
// A wall segment will be drawn between start and stop pixels (inclusive).
|
// A wall segment will be drawn between start and stop pixels (inclusive).
|
||||||
//
|
//
|
||||||
|
|
||||||
void R_StoreWallRange (int start, int stop)
|
bool R_StoreWallRange (int start, int stop)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool maskedtexture = false;
|
bool maskedtexture = false;
|
||||||
|
@ -1827,7 +1827,8 @@ void R_StoreWallRange (int start, int stop)
|
||||||
|
|
||||||
if(fake3D & 7) {
|
if(fake3D & 7) {
|
||||||
ds_p++;
|
ds_p++;
|
||||||
return;
|
|
||||||
|
return !(fake3D & FAKE3D_FAKEMASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// save sprite clipping info
|
// save sprite clipping info
|
||||||
|
@ -1888,6 +1889,8 @@ void R_StoreWallRange (int start, int stop)
|
||||||
}
|
}
|
||||||
|
|
||||||
ds_p++;
|
ds_p++;
|
||||||
|
|
||||||
|
return !(fake3D & FAKE3D_FAKEMASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
int R_CreateWallSegmentY(short *outbuf, double z1, double z2, const FWallCoords *wallc)
|
int R_CreateWallSegmentY(short *outbuf, double z1, double z2, const FWallCoords *wallc)
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace swrenderer
|
||||||
|
|
||||||
struct drawseg_t;
|
struct drawseg_t;
|
||||||
|
|
||||||
|
bool R_StoreWallRange(int start, int stop);
|
||||||
void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2);
|
void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2);
|
||||||
|
|
||||||
extern short *openings;
|
extern short *openings;
|
||||||
|
|
Loading…
Reference in a new issue