mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
r_bsp.cpp: merge R_ClipSolidWallSegment and R_ClipPassWallSegment into one templated function
Prep for creating a third variant. Control flow is largely the same between these two leveraging if constexpr seems appropriate. Also splits the crunch goto label away into a new function called R_CrunchWallSegment.
This commit is contained in:
parent
ccd5f3bfc4
commit
d55b1b194a
1 changed files with 74 additions and 86 deletions
160
src/r_bsp.cpp
160
src/r_bsp.cpp
|
|
@ -90,13 +90,40 @@ void R_ClearDrawSegs(void)
|
||||||
static cliprange_t *newend;
|
static cliprange_t *newend;
|
||||||
static cliprange_t solidsegs[MAXSEGS];
|
static cliprange_t solidsegs[MAXSEGS];
|
||||||
|
|
||||||
//
|
namespace
|
||||||
// R_ClipSolidWallSegment
|
{
|
||||||
// Does handle solid walls,
|
|
||||||
// e.g. single sided LineDefs (middle texture)
|
enum class ClipType
|
||||||
// that entirely block the view.
|
{
|
||||||
//
|
// Does handle solid walls,
|
||||||
static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
// e.g. single sided LineDefs (middle texture)
|
||||||
|
// that entirely block the view.
|
||||||
|
kSolid,
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
kPass,
|
||||||
|
};
|
||||||
|
|
||||||
|
void R_CrunchWallSegment(cliprange_t *start, cliprange_t *next)
|
||||||
|
{
|
||||||
|
// Remove start+1 to next from the clip list, because start now covers their area.
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <ClipType Type>
|
||||||
|
void R_ClipWallSegment(INT32 first, INT32 last)
|
||||||
{
|
{
|
||||||
cliprange_t *next;
|
cliprange_t *next;
|
||||||
cliprange_t *start;
|
cliprange_t *start;
|
||||||
|
|
@ -112,26 +139,35 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
||||||
{
|
{
|
||||||
// Post is entirely visible (above start), so insert a new clippost.
|
// Post is entirely visible (above start), so insert a new clippost.
|
||||||
R_StoreWallRange(first, last);
|
R_StoreWallRange(first, last);
|
||||||
next = newend;
|
|
||||||
newend++;
|
|
||||||
// NO MORE CRASHING!
|
|
||||||
if (newend - solidsegs > MAXSEGS)
|
|
||||||
I_Error("R_ClipSolidWallSegment: Solid Segs overflow!\n");
|
|
||||||
|
|
||||||
while (next != start)
|
if constexpr (Type != ClipType::kPass)
|
||||||
{
|
{
|
||||||
*next = *(next-1);
|
next = newend;
|
||||||
next--;
|
newend++;
|
||||||
|
// NO MORE CRASHING!
|
||||||
|
if (newend - solidsegs > MAXSEGS)
|
||||||
|
I_Error("R_ClipSolidWallSegment: Solid Segs overflow!\n");
|
||||||
|
|
||||||
|
while (next != start)
|
||||||
|
{
|
||||||
|
*next = *(next-1);
|
||||||
|
next--;
|
||||||
|
}
|
||||||
|
next->first = first;
|
||||||
|
next->last = last;
|
||||||
}
|
}
|
||||||
next->first = first;
|
|
||||||
next->last = last;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is a fragment above *start.
|
// There is a fragment above *start.
|
||||||
R_StoreWallRange(first, start->first - 1);
|
R_StoreWallRange(first, start->first - 1);
|
||||||
// Now adjust the clip size.
|
|
||||||
start->first = first;
|
if constexpr (Type != ClipType::kPass)
|
||||||
|
{
|
||||||
|
// Now adjust the clip size.
|
||||||
|
start->first = first;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bottom contained in start?
|
// Bottom contained in start?
|
||||||
|
|
@ -142,84 +178,36 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
||||||
while (last >= (next+1)->first - 1)
|
while (last >= (next+1)->first - 1)
|
||||||
{
|
{
|
||||||
// There is a fragment between two posts.
|
// There is a fragment between two posts.
|
||||||
R_StoreWallRange(next->last + 1, (next+1)->first - 1);
|
R_StoreWallRange(start->last + 1, (start+1)->first - 1);
|
||||||
next++;
|
next++;
|
||||||
|
|
||||||
if (last <= next->last)
|
if (last <= next->last)
|
||||||
{
|
{
|
||||||
// Bottom is contained in next.
|
if constexpr (Type != ClipType::kPass)
|
||||||
// Adjust the clip size.
|
{
|
||||||
start->last = next->last;
|
// Bottom is contained in next.
|
||||||
goto crunch;
|
// Adjust the clip size.
|
||||||
}
|
start->last = next->last;
|
||||||
}
|
R_CrunchWallSegment(start, next);
|
||||||
|
}
|
||||||
|
|
||||||
// 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;
|
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.
|
// There is a fragment after *next.
|
||||||
R_StoreWallRange(start->last + 1, last);
|
R_StoreWallRange(start->last + 1, last);
|
||||||
|
|
||||||
|
if constexpr (Type != ClipType::kPass)
|
||||||
|
{
|
||||||
|
// Adjust the clip size.
|
||||||
|
start->last = last;
|
||||||
|
R_CrunchWallSegment(start, next);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}; // namespace
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_ClearClipSegs
|
// R_ClearClipSegs
|
||||||
//
|
//
|
||||||
|
|
@ -641,11 +629,11 @@ static void R_AddLine(seg_t *line)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clippass:
|
clippass:
|
||||||
R_ClipPassWallSegment(x1, x2 - 1);
|
R_ClipWallSegment<ClipType::kPass>(x1, x2 - 1);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clipsolid:
|
clipsolid:
|
||||||
R_ClipSolidWallSegment(x1, x2 - 1);
|
R_ClipWallSegment<ClipType::kSolid>(x1, x2 - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue