ref: 61fd6eaba2a5361e5d83000b86010efe11547ba6
parent: 13a3ee197cee081a5ef480c9443f88dbf203ab35
author: Andrew Apted <ajapted@gmail.com>
date: Fri Dec 15 08:35:14 EST 2023
restored original R_RenderBSPNode(), P_CheckSight(), R_PointInSubsector().
--- a/p_sight.c
+++ b/p_sight.c
@@ -122,148 +122,172 @@
//
// P_CrossSubsector
-// Returns true if strace crosses the given subsector successfully.
+// Returns true
+// if strace crosses the given subsector successfully.
//
-boolean P_CrossSubsector (subsector_t * sub)
+boolean P_CrossSubsector (int num)
{+ seg_t* seg;
+ line_t* line;
+ int s1;
+ int s2;
+ int count;
+ subsector_t* sub;
+ sector_t* front;
+ sector_t* back;
+ fixed_t opentop;
+ fixed_t openbottom;
+ divline_t divl;
+ vertex_t* v1;
+ vertex_t* v2;
+ fixed_t frac;
+ fixed_t slope;
+
+//#ifdef RANGECHECK
+ if (num>=numsubsectors)
+ I_Error ("P_CrossSubsector: ss %i with numss = %i",+ num,
+ numsubsectors);
+//#endif
+
+ sub = &subsectors[num];
+
// check lines
- seg_t * seg;
- for (seg = sub->segs ; seg != NULL ; seg = seg->next)
+ count = sub->numlines;
+ seg = &segs[sub->firstline];
+
+ for ( ; count ; seg++, count--)
{- line_t * line = seg->linedef;
+ line = seg->linedef;
- // allready checked other side?
- if (line->validcount == validcount)
- continue;
+ // allready checked other side?
+ if (line->validcount == validcount)
+ continue;
+
+ line->validcount = validcount;
- line->validcount = validcount;
+ v1 = line->v1;
+ v2 = line->v2;
+ s1 = P_DivlineSide (v1->x,v1->y, &strace);
+ s2 = P_DivlineSide (v2->x, v2->y, &strace);
- vertex_t * v1 = line->v1;
- vertex_t * v2 = line->v2;
+ // line isn't crossed?
+ if (s1 == s2)
+ continue;
+
+ divl.x = v1->x;
+ divl.y = v1->y;
+ divl.dx = v2->x - v1->x;
+ divl.dy = v2->y - v1->y;
+ s1 = P_DivlineSide (strace.x, strace.y, &divl);
+ s2 = P_DivlineSide (t2x, t2y, &divl);
- int s1 = P_DivlineSide (v1->x, v1->y, &strace);
- int s2 = P_DivlineSide (v2->x, v2->y, &strace);
+ // line isn't crossed?
+ if (s1 == s2)
+ continue;
- // line isn't crossed?
- if (s1 == s2)
- continue;
-
- divline_t divl;
-
- divl.x = v1->x;
- divl.y = v1->y;
- divl.dx = v2->x - v1->x;
- divl.dy = v2->y - v1->y;
-
- s1 = P_DivlineSide (strace.x, strace.y, &divl);
- s2 = P_DivlineSide (t2x, t2y, &divl);
-
- // line isn't crossed?
- if (s1 == s2)
- continue;
-
// Backsector may be NULL if this is an "impassible
// glass" hack line.
if (line->backsector == NULL)
+ {return false;
+ }
- // stop because it is not two sided anyway
- // might do this after updating validcount?
- if ( !(line->flags & ML_TWOSIDED) )
- return false;
+ // stop because it is not two sided anyway
+ // might do this after updating validcount?
+ if ( !(line->flags & ML_TWOSIDED) )
+ return false;
+
+ // crosses a two sided line
+ front = seg->frontsector;
+ back = seg->backsector;
- // crosses a two sided line
- sector_t * front = seg->frontsector;
- sector_t * back = seg->backsector;
+ // no wall to block sight with?
+ if (front->floorheight == back->floorheight
+ && front->ceilingheight == back->ceilingheight)
+ continue;
- // no wall to block sight with?
- if (front->floorheight == back->floorheight
- && front->ceilingheight == back->ceilingheight)
- continue;
+ // possible occluder
+ // because of ceiling height differences
+ if (front->ceilingheight < back->ceilingheight)
+ opentop = front->ceilingheight;
+ else
+ opentop = back->ceilingheight;
- fixed_t opentop;
- fixed_t openbottom;
-
- // possible occluder
- // because of ceiling height differences
- if (front->ceilingheight < back->ceilingheight)
- opentop = front->ceilingheight;
- else
- opentop = back->ceilingheight;
-
- // because of ceiling height differences
- if (front->floorheight > back->floorheight)
- openbottom = front->floorheight;
- else
- openbottom = back->floorheight;
-
- // quick test for totally closed doors
- if (openbottom >= opentop)
- return false; // stop
-
- fixed_t frac = P_InterceptVector2 (&strace, &divl);
- fixed_t slope;
-
- if (front->floorheight != back->floorheight)
- {- slope = FixedDiv (openbottom - sightzstart , frac);
- if (slope > bottomslope)
- bottomslope = slope;
- }
-
- if (front->ceilingheight != back->ceilingheight)
- {- slope = FixedDiv (opentop - sightzstart , frac);
- if (slope < topslope)
- topslope = slope;
- }
-
- if (topslope <= bottomslope)
- return false; // stop
+ // because of ceiling height differences
+ if (front->floorheight > back->floorheight)
+ openbottom = front->floorheight;
+ else
+ openbottom = back->floorheight;
+
+ // quick test for totally closed doors
+ if (openbottom >= opentop)
+ return false; // stop
+
+ frac = P_InterceptVector2 (&strace, &divl);
+
+ if (front->floorheight != back->floorheight)
+ {+ slope = FixedDiv (openbottom - sightzstart , frac);
+ if (slope > bottomslope)
+ bottomslope = slope;
+ }
+
+ if (front->ceilingheight != back->ceilingheight)
+ {+ slope = FixedDiv (opentop - sightzstart , frac);
+ if (slope < topslope)
+ topslope = slope;
+ }
+
+ if (topslope <= bottomslope)
+ return false; // stop
}
-
// passed the subsector ok
- return true;
+ return true;
}
+
//
// P_CrossBSPNode
// Returns true
// if strace crosses the given node successfully.
//
-boolean P_CrossBSPNode (node_t * bsp)
+boolean P_CrossBSPNode (int bspnum)
{-loop:
- if (bsp->sub != NULL)
- return P_CrossSubsector (bsp->sub);
+ node_t* bsp;
+ int side;
+ if (bspnum & NF_SUBSECTOR)
+ {+ if (bspnum == -1)
+ return P_CrossSubsector (0);
+ else
+ return P_CrossSubsector (bspnum&(~NF_SUBSECTOR));
+ }
+
+ bsp = &nodes[bspnum];
+
// decide which side the start point is on
- divline_t div;
- div.x = bsp->x;
- div.y = bsp->y;
- div.dx = bsp->dx;
- div.dy = bsp->dy;
-
- int side = P_DivlineSide (strace.x, strace.y, &div);
+ side = P_DivlineSide (strace.x, strace.y, (divline_t *)bsp);
if (side == 2)
- side = 0; // an "on" should cross both sides
+ side = 0; // an "on" should cross both sides
// cross the starting side
- if (! P_CrossBSPNode (side ? bsp->left : bsp->right))
- return false;
-
+ if (!P_CrossBSPNode (bsp->children[side]) )
+ return false;
+
// the partition plane is crossed here
- if (side == P_DivlineSide (t2x, t2y, &div))
+ if (side == P_DivlineSide (t2x, t2y,(divline_t *)bsp))
{- // the line doesn't touch the other side
- return true;
+ // the line doesn't touch the other side
+ return true;
}
-
- // cross the ending side
- bsp = side ? bsp->right : bsp->left;
- goto loop;
+
+ // cross the ending side
+ return P_CrossBSPNode (bsp->children[side^1]);
}
@@ -320,7 +344,7 @@
strace.dy = t2->y - t1->y;
// the head node is the last node output
- return P_CrossBSPNode (root_node);
+ return P_CrossBSPNode (numnodes-1);
}
--- a/r_bsp.c
+++ b/r_bsp.c
@@ -492,36 +492,50 @@
// Add sprites of things in sector.
// Draw one or more line segments.
//
-void R_Subsector (subsector_t * sub)
+void R_Subsector (int num)
{+ int count;
+ seg_t* line;
+ subsector_t* sub;
+
+//#ifdef RANGECHECK
+ if (num>=numsubsectors)
+ I_Error ("R_Subsector: ss %i with numss = %i",+ num,
+ numsubsectors);
+//#endif
+
sscount++;
+ sub = &subsectors[num];
frontsector = sub->sector;
+ count = sub->numlines;
+ line = &segs[sub->firstline];
if (frontsector->floorheight < viewz)
{- floorplane = R_FindPlane (frontsector->floorheight,
- frontsector->floorpic,
- frontsector->lightlevel);
+ floorplane = R_FindPlane (frontsector->floorheight,
+ frontsector->floorpic,
+ frontsector->lightlevel);
}
else
- floorplane = NULL;
-
- if (frontsector->ceilingheight > viewz
- || frontsector->ceilingpic == skyflatnum)
+ floorplane = NULL;
+
+ if (frontsector->ceilingheight > viewz
+ || frontsector->ceilingpic == skyflatnum)
{- ceilingplane = R_FindPlane (frontsector->ceilingheight,
- frontsector->ceilingpic,
- frontsector->lightlevel);
+ ceilingplane = R_FindPlane (frontsector->ceilingheight,
+ frontsector->ceilingpic,
+ frontsector->lightlevel);
}
else
- ceilingplane = NULL;
+ ceilingplane = NULL;
+
+ R_AddSprites (frontsector);
- R_AddSprites (frontsector);
-
- seg_t * line;
- for (line = sub->segs ; line != NULL ; line = line->next)
+ while (count--)
{- R_AddLine (line);
+ R_AddLine (line);
+ line++;
}
}
@@ -531,25 +545,32 @@
// Renders all subsectors below a given node,
// traversing subtree recursively.
// Just call with BSP root.
-void R_RenderBSPNode (node_t * bsp)
+void R_RenderBSPNode (int bspnum)
{-loop:
+ node_t* bsp;
+ int side;
+
// Found a subsector?
- if (bsp->sub != NULL)
+ if (bspnum & NF_SUBSECTOR)
{- R_Subsector (bsp->sub);
- return;
+ if (bspnum == -1)
+ R_Subsector (0);
+ else
+ R_Subsector (bspnum&(~NF_SUBSECTOR));
+ return;
}
-
+
+ bsp = &nodes[bspnum];
+
// Decide which side the view point is on.
- int side = R_PointOnSide (viewx, viewy, bsp);
+ side = R_PointOnSide (viewx, viewy, bsp);
// Recursively divide front space.
- R_RenderBSPNode (side ? bsp->left : bsp->right);
+ R_RenderBSPNode (bsp->children[side]);
// Possibly divide back space.
- bsp = side ? bsp->right : bsp->left;
- if (R_CheckBBox (bsp->bbox))
- goto loop;
+ if (R_CheckBBox (bsp->bbox[side^1]))
+ R_RenderBSPNode (bsp->children[side^1]);
}
+
--- a/r_bsp.h
+++ b/r_bsp.h
@@ -55,7 +55,7 @@
void R_ClearDrawSegs (void);
-void R_RenderBSPNode (node_t * bsp);
+void R_RenderBSPNode (int bspnum);
#endif
--- a/r_main.c
+++ b/r_main.c
@@ -702,17 +702,29 @@
//
// R_PointInSubsector
//
-subsector_t * R_PointInSubsector (fixed_t x, fixed_t y)
+subsector_t*
+R_PointInSubsector
+( fixed_t x,
+ fixed_t y )
{- node_t * node = root_node;
+ node_t* node;
+ int side;
+ int nodenum;
- while (node->sub == NULL)
+ // single subsector is a special case
+ if (!numnodes)
+ return subsectors;
+
+ nodenum = numnodes-1;
+
+ while (! (nodenum & NF_SUBSECTOR) )
{- int side = R_PointOnSide (x, y, node);
- node = side ? node->left : node->right;
+ node = &nodes[nodenum];
+ side = R_PointOnSide (x, y, node);
+ nodenum = node->children[side];
}
-
- return node->sub;
+
+ return &subsectors[nodenum & ~NF_SUBSECTOR];
}
@@ -774,7 +786,7 @@
NetUpdate ();
// The head node is the last node output.
- R_RenderBSPNode (root_node);
+ R_RenderBSPNode (numnodes-1);
// Check for new console commands.
NetUpdate ();
--- a/r_state.h
+++ b/r_state.h
@@ -72,10 +72,17 @@
extern int numvertexes;
extern vertex_t* vertexes;
+extern int numsegs;
+extern seg_t* segs;
+
extern int numsectors;
extern sector_t* sectors;
-extern node_t* root_node;
+extern int numsubsectors;
+extern subsector_t* subsectors;
+
+extern int numnodes;
+extern node_t* nodes;
extern int numlines;
extern line_t* lines;
--
⑨