shithub: nanobsp

Download patch

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;
--