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;
|
||||
|
||||
|
||||
|
||||
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.
|
||||
//
|
||||
|
@ -703,7 +561,7 @@ void R_AddLine (seg_t *line)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (R_ClipWallSegment (WallC.sx1, WallC.sx2, solid))
|
||||
if (R_ClipWallSegment(WallC.sx1, WallC.sx2, solid, R_StoreWallRange))
|
||||
{
|
||||
InSubsector->flags |= SSECF_DRAWN;
|
||||
}
|
||||
|
@ -836,8 +694,6 @@ static bool R_CheckBBox (float *bspcoord) // killough 1/28/98: static
|
|||
double rx1, ry1, rx2, ry2;
|
||||
int sx1, sx2;
|
||||
|
||||
cliprange_t* start;
|
||||
|
||||
// Find the corners of the box
|
||||
// that define the edges from current viewpoint.
|
||||
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
|
||||
// (adjacent pixels are touching).
|
||||
|
||||
// Does not cross a pixel.
|
||||
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;
|
||||
return R_IsWallSegmentVisible(sx1, sx2);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -26,8 +26,16 @@
|
|||
|
||||
namespace swrenderer
|
||||
{
|
||||
cliprange_t *newend;
|
||||
cliprange_t solidsegs[MAXWIDTH/2+2];
|
||||
namespace
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -37,4 +45,145 @@ namespace swrenderer
|
|||
solidsegs[1].last = 0x7fff;
|
||||
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
|
||||
{
|
||||
struct cliprange_t
|
||||
{
|
||||
short first, last;
|
||||
};
|
||||
|
||||
// newend is one past the last valid seg
|
||||
extern cliprange_t *newend;
|
||||
extern cliprange_t solidsegs[MAXWIDTH/2+2];
|
||||
typedef bool(*VisibleSegmentCallback)(int x1, int x2);
|
||||
|
||||
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).
|
||||
//
|
||||
|
||||
void R_StoreWallRange (int start, int stop)
|
||||
bool R_StoreWallRange (int start, int stop)
|
||||
{
|
||||
int i;
|
||||
bool maskedtexture = false;
|
||||
|
@ -1827,7 +1827,8 @@ void R_StoreWallRange (int start, int stop)
|
|||
|
||||
if(fake3D & 7) {
|
||||
ds_p++;
|
||||
return;
|
||||
|
||||
return !(fake3D & FAKE3D_FAKEMASK);
|
||||
}
|
||||
|
||||
// save sprite clipping info
|
||||
|
@ -1888,6 +1889,8 @@ void R_StoreWallRange (int start, int stop)
|
|||
}
|
||||
|
||||
ds_p++;
|
||||
|
||||
return !(fake3D & FAKE3D_FAKEMASK);
|
||||
}
|
||||
|
||||
int R_CreateWallSegmentY(short *outbuf, double z1, double z2, const FWallCoords *wallc)
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace swrenderer
|
|||
|
||||
struct drawseg_t;
|
||||
|
||||
bool R_StoreWallRange(int start, int stop);
|
||||
void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2);
|
||||
|
||||
extern short *openings;
|
||||
|
|
Loading…
Reference in a new issue