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
128
src/r_bsp.cpp
128
src/r_bsp.cpp
|
|
@ -90,13 +90,40 @@ void R_ClearDrawSegs(void)
|
|||
static cliprange_t *newend;
|
||||
static cliprange_t solidsegs[MAXSEGS];
|
||||
|
||||
//
|
||||
// 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)
|
||||
namespace
|
||||
{
|
||||
|
||||
enum class ClipType
|
||||
{
|
||||
// Does handle solid walls,
|
||||
// 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 *start;
|
||||
|
|
@ -112,6 +139,9 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
|||
{
|
||||
// Post is entirely visible (above start), so insert a new clippost.
|
||||
R_StoreWallRange(first, last);
|
||||
|
||||
if constexpr (Type != ClipType::kPass)
|
||||
{
|
||||
next = newend;
|
||||
newend++;
|
||||
// NO MORE CRASHING!
|
||||
|
|
@ -125,14 +155,20 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
|||
}
|
||||
next->first = first;
|
||||
next->last = last;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// There is a fragment above *start.
|
||||
R_StoreWallRange(first, start->first - 1);
|
||||
|
||||
if constexpr (Type != ClipType::kPass)
|
||||
{
|
||||
// Now adjust the clip size.
|
||||
start->first = first;
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom contained in start?
|
||||
if (last <= start->last)
|
||||
|
|
@ -142,84 +178,36 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
|||
while (last >= (next+1)->first - 1)
|
||||
{
|
||||
// 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++;
|
||||
|
||||
if (last <= next->last)
|
||||
{
|
||||
if constexpr (Type != ClipType::kPass)
|
||||
{
|
||||
// Bottom is contained in next.
|
||||
// Adjust the clip size.
|
||||
start->last = next->last;
|
||||
goto crunch;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
if constexpr (Type != ClipType::kPass)
|
||||
{
|
||||
// Adjust the clip size.
|
||||
start->last = last;
|
||||
R_CrunchWallSegment(start, next);
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace
|
||||
|
||||
//
|
||||
// R_ClearClipSegs
|
||||
//
|
||||
|
|
@ -641,11 +629,11 @@ static void R_AddLine(seg_t *line)
|
|||
return;
|
||||
|
||||
clippass:
|
||||
R_ClipPassWallSegment(x1, x2 - 1);
|
||||
R_ClipWallSegment<ClipType::kPass>(x1, x2 - 1);
|
||||
return;
|
||||
|
||||
clipsolid:
|
||||
R_ClipSolidWallSegment(x1, x2 - 1);
|
||||
R_ClipWallSegment<ClipType::kSolid>(x1, x2 - 1);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue