//#include "quakedef.h"
//
//#define MAX_ITERATIONS 100
//
//struct iteration
//{
//	//args
////	hull_t *hull;
//	int num;
//	float p1f;
//	float p2f;
//	vec3_t p1;
//	vec3_t p2;
////	trace_t *trace;
//	
//	//temps
//	float t1, t2;
//	float frac;
//	vec3_t mid;
//	float midf;
//	int side;
//	
//	//loop control
//	int lr;
//	bool return_val;
//};
//
//#define	DIST_EPSILON	(0.03125)
//
//int SV_HullPointContents (hull_t *hull, int num, vec3_t p);
//
//struct iteration stack[MAX_ITERATIONS];
//
//qboolean SV_NonRecursiveHullCheck(hull_t *hull, int start_num, float start_p1f, float start_p2f, vec3_t start_p1, vec3_t start_p2, trace_t *trace)
//{
//	struct iteration *sp = stack;
//
//	sp->num = start_num;
//	sp->p1f = start_p1f;
//	sp->p2f = start_p2f;
//	VectorCopy(start_p1, sp->p1);
//	VectorCopy(start_p2, sp->p2);
//	
//	sp->lr = 0;		//start from the top
//	
//	while (sp >= &stack[0])
//	{
//		if (sp > &stack[MAX_ITERATIONS - 1])
//		{
//			Sys_Error("we\'re out of fake stack!\nif this happens PLEASE get in contact with me!\n");
//		}
//		
//		//arguments
//		int *num = &sp->num;
//		float *p1f = &sp->p1f;
//		float *p2f = &sp->p2f;
//		
//		//temporaries
//		float *t1 = &sp->t1;
//		float *t2 = &sp->t2;
//		float *frac = &sp->frac;
//		float *midf = &sp->midf;
//		int *side = &sp->side;
//		
//		switch (sp->lr)
//		{
//			case 0:
//			{
//				// check for empty
//				if (*num < 0)
//				{
//					if (*num != CONTENTS_SOLID)
//					{
//						trace->allsolid = false;
//						if (*num == CONTENTS_EMPTY)
//							trace->inopen = true;
//						else
//							trace->inwater = true;
//					}
//					else
//						trace->startsolid = true;
//						
////					return true;		// empty
//					sp->return_val = true;
//
//					sp--;
//					
//					continue;
//				}
//			}
//			case 1:
//			{
//				if (*num < hull->firstclipnode || *num > hull->lastclipnode)
//				{
//					Sys_Error ("SV_RecursiveHullCheck: bad node number");
//				}
//					
//				dclipnode_t *node = hull->clipnodes + *num;
//				mplane_t *plane = hull->planes + node->planenum;
//				
//				if (plane->type < 3)
//				{
//					*t1 = sp->p1[plane->type] - plane->dist;
//					*t2 = sp->p2[plane->type] - plane->dist;
//				}
//				else
//				{
//					*t1 = DotProduct (plane->normal, sp->p1) - plane->dist;
//					*t2 = DotProduct (plane->normal, sp->p2) - plane->dist;
//				}
//				
//				if (*t1 >= 0 && *t2 >= 0)
//				{
////					return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace);
//
//					//restart from the next section
//					sp->lr = 2;
//
//					//call it again
//					sp++;
//					
//					sp->num = node->children[0];
//					sp->p1f = *p1f;
//					sp->p2f = *p2f;
//					VectorCopy((sp - 1)->p1, sp->p1);
//					VectorCopy((sp - 1)->p2, sp->p2);
//					sp->lr = 0;
//					
//					continue;
//				}
//				
//				goto skip_2;
//			}
//			case 2:		//the 'return' for the previous line
//			{
//				sp->return_val = (sp + 1)->return_val;
//				
//				sp--;
//				continue;
//			}
//			case 3:
//			{
//skip_2:
//				dclipnode_t *node = hull->clipnodes + *num;
//				mplane_t *plane = hull->planes + node->planenum;
//				
//				if (*t1 < 0 && *t2 < 0)
//				{
////					return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace);
//
//					//restart from the next section
//					sp->lr = 4;
//
//					//call it again
//					sp++;
//					
//					sp->num = node->children[1];
//					sp->p1f = *p1f;
//					sp->p2f = *p2f;
//					VectorCopy((sp - 1)->p1, sp->p1);
//					VectorCopy((sp - 1)->p2, sp->p2);
//					sp->lr = 0;
//					
//					continue;
//				}
//				
//				goto skip_4;
//			}
//			case 4:		//the 'return' for the previous line
//			{
//				sp->return_val = (sp + 1)->return_val;
//				
//				sp--;
//				continue;
//			}
//			case 5:
//			{
//skip_4:
//				dclipnode_t *node = hull->clipnodes + *num;
//				mplane_t *plane = hull->planes + node->planenum;
//				
//				// put the crosspoint DIST_EPSILON pixels on the near side
//				if (*t1 < 0)
//					*frac = (*t1 + DIST_EPSILON) / (*t1 - *t2);
//				else
//					*frac = (*t1 - DIST_EPSILON)/(*t1 - *t2);
//				if (*frac < 0)
//					*frac = 0;
//				if (*frac > 1)
//					*frac = 1;
//					
//				*midf = *p1f + (*p2f - *p1f) * *frac;
//				for (int i = 0 ; i < 3; i++)
//					sp->mid[i] = sp->p1[i] + *frac * (sp->p2[i] - sp->p1[i]);
//			
//				*side = (*t1 < 0);
//				
//				// move up to the node
////				if (!SV_RecursiveHullCheck (hull, node->children[side], p1f, midf, p1, mid, trace) )
////					return false;
//
//				//restart from the next section
//				sp->lr = 6;
//				
//				//call it again
//				sp++;
//					
//				sp->num = node->children[*side];
//				sp->p1f = *p1f;
//				sp->p2f = *midf;
//				VectorCopy((sp - 1)->p1, sp->p1);
//				VectorCopy((sp - 1)->mid, sp->p2);
//				sp->lr = 0;
//				
//				continue;
//			}
//			case 6:
//			{
//				dclipnode_t *node = hull->clipnodes + *num;
//				
//				if ((sp + 1)->return_val == false)
//				{
//					sp->return_val = false;
//					
//					sp--;
//					continue;
//				}
//				
//				if (SV_HullPointContents (hull, node->children[(*side) ^ 1], sp->mid)
//					!= CONTENTS_SOLID)
//				// go past the node
//				{
////					return SV_RecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace);
//
//					//restart from the next section ONLY
//					sp->lr = 7;
//					
//					//call it again
//					sp++;
//						
//					sp->num = node->children[(*side) ^ 1];
//					sp->p1f = *midf;
//					sp->p2f = *p2f;
//					VectorCopy((sp - 1)->mid, sp->p1);
//					VectorCopy((sp - 1)->p2, sp->p2);
//					sp->lr = 0;
//					
//					continue;
//				}
//				
//				goto skip_7;
//			}
//			case 7:		//do the return for the previous bit
//			{
//				sp->return_val = (sp + 1)->return_val;
//				
//				sp--;
//				continue;
//			}
//			case 8:
//			{
//skip_7:
//				dclipnode_t *node = hull->clipnodes + *num;
//				mplane_t *plane = hull->planes + node->planenum;
//				
//				if (trace->allsolid)
//				{
//					sp->return_val = false;
//					
//					sp--;
//					continue;
//				}
//				
//				if ((*side) == 0)
//				{
//					VectorCopy (plane->normal, trace->plane.normal);
//					trace->plane.dist = plane->dist;
//				}
//				else
//				{
//					VectorSubtract (vec3_origin, plane->normal, trace->plane.normal);
//					trace->plane.dist = -plane->dist;
//				}
//				
//				while (SV_HullPointContents (hull, hull->firstclipnode, sp->mid)
//					== CONTENTS_SOLID)
//				{ // shouldn't really happen, but does occasionally
//					*frac -= 0.1;
//					if (frac < 0)
//					{
//						trace->fraction = *midf;
//						VectorCopy (sp->mid, trace->endpos);
//						Con_DPrintf ("backup past 0\n");
////						return false
//						sp->return_val = false;
//						
//						sp--;
//						continue;
//					}
//					*midf = *p1f + (*p2f - *p1f) * *frac;
//					for (int i = 0; i < 3; i++)
//						sp->mid[i] = sp->p1[i] + *frac * (sp->p2[i] - sp->p1[i]);
//				}
//			
//				trace->fraction = *midf;
//				VectorCopy (sp->mid, trace->endpos);
//				
//				sp->return_val = false;
//				
//				sp--;
//				continue;
//			}
//		}
//	}
//
//	return (sp + 1)->return_val;	
//}

//#include "quakedef.h"
//
//#define MAX_ITERATIONS 100
//
//struct iteration
//{
//	//args
//	int num;
//	fixed_point p1f;
//	fixed_point p2f;
//	fixed_point p1[3];
//	fixed_point p2[3];
//	
//	//temps
//	fixed_point t1, t2;
//	fixed_point frac;
//	fixed_point mid[3];
//	fixed_point midf;
//	int side;
//	
//	//loop control
//	int lr;
//	bool return_val;
//};
//
//#define	DIST_EPSILON	(0.03125)
//
//int SV_HullPointContents (hull_t *hull, int num, vec3_t p);
//int SV_HullPointContentsFP (hull_t *hull, int num, fixed_point *f_p);
//
//struct iteration stack[MAX_ITERATIONS];
//
//qboolean SV_NonRecursiveHullCheck(hull_t *hull, int start_num, float start_p1f, float start_p2f, vec3_t start_p1, vec3_t start_p2, trace_t *trace)
//{
//	struct iteration *sp = stack;
//
//	sp->num = start_num;
//	sp->p1f = start_p1f;
//	sp->p2f = start_p2f;
//	VectorCopy(start_p1, sp->p1);
//	VectorCopy(start_p2, sp->p2);
//	
//	sp->lr = 0;		//start from the top
//	
//	while (sp >= &stack[0])
//	{
//		if (sp > &stack[MAX_ITERATIONS - 1])
//		{
//			Sys_Error("we\'re out of fake stack!\nif this happens PLEASE get in contact with me!\n");
//		}
//		
//		//arguments
//		int *num = &sp->num;
//		fixed_point *p1f = &sp->p1f;
//		fixed_point *p2f = &sp->p2f;
//		
//		//temporaries
//		fixed_point *t1 = &sp->t1;
//		fixed_point *t2 = &sp->t2;
//		fixed_point *frac = &sp->frac;
//		fixed_point *midf = &sp->midf;
//		int *side = &sp->side;
//		
//		switch (sp->lr)
//		{
//			case 0:
//			{
//				// check for empty
//				if (*num < 0)
//				{
//					if (*num != CONTENTS_SOLID)
//					{
//						trace->allsolid = false;
//						if (*num == CONTENTS_EMPTY)
//							trace->inopen = true;
//						else
//							trace->inwater = true;
//					}
//					else
//						trace->startsolid = true;
//						
////					return true;		// empty
//					sp->return_val = true;
//
//					sp--;
//					
//					continue;
//				}
//			}
//			case 1:
//			{
//				if (*num < hull->firstclipnode || *num > hull->lastclipnode)
//				{
//					Sys_Error ("SV_RecursiveHullCheck: bad node number");
//				}
//					
//				dclipnode_t *node = hull->clipnodes + *num;
//				mplane_t *plane = hull->planes + node->planenum;
//				
//				if (plane->type < 3)
//				{
//					*t1 = sp->p1[plane->type] - plane->dist;
//					*t2 = sp->p2[plane->type] - plane->dist;
//				}
//				else
//				{
//					*t1 = DotProduct (plane->normal, sp->p1) - plane->dist;
//					*t2 = DotProduct (plane->normal, sp->p2) - plane->dist;
//				}
//				
//				if (*t1 >= 0 && *t2 >= 0)
//				{
////					return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace);
//
//					//restart from the next section
//					sp->lr = 2;
//
//					//call it again
//					sp++;
//					
//					sp->num = node->children[0];
//					sp->p1f = *p1f;
//					sp->p2f = *p2f;
//					VectorCopy((sp - 1)->p1, sp->p1);
//					VectorCopy((sp - 1)->p2, sp->p2);
//					sp->lr = 0;
//					
//					continue;
//				}
//				
//				goto skip_2;
//			}
//			case 2:		//the 'return' for the previous line
//			{
//				sp->return_val = (sp + 1)->return_val;
//				
//				sp--;
//				continue;
//			}
//			case 3:
//			{
//skip_2:
//				dclipnode_t *node = hull->clipnodes + *num;
//				mplane_t *plane = hull->planes + node->planenum;
//				
//				if (*t1 < 0 && *t2 < 0)
//				{
////					return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace);
//
//					//restart from the next section
//					sp->lr = 4;
//
//					//call it again
//					sp++;
//					
//					sp->num = node->children[1];
//					sp->p1f = *p1f;
//					sp->p2f = *p2f;
//					VectorCopy((sp - 1)->p1, sp->p1);
//					VectorCopy((sp - 1)->p2, sp->p2);
//					sp->lr = 0;
//					
//					continue;
//				}
//				
//				goto skip_4;
//			}
//			case 4:		//the 'return' for the previous line
//			{
//				sp->return_val = (sp + 1)->return_val;
//				
//				sp--;
//				continue;
//			}
//			case 5:
//			{
//skip_4:
//				dclipnode_t *node = hull->clipnodes + *num;
//				mplane_t *plane = hull->planes + node->planenum;
//				
//				// put the crosspoint DIST_EPSILON pixels on the near side
//				if (*t1 < 0)
//					*frac = (*t1 + DIST_EPSILON) / (*t1 - *t2);
//				else
//					*frac = (*t1 - DIST_EPSILON)/(*t1 - *t2);
//				if (*frac < 0)
//					*frac = 0;
//				if (*frac > 1)
//					*frac = 1;
//					
//				*midf = *p1f + (*p2f - *p1f) * *frac;
//				for (int i = 0 ; i < 3; i++)
//					sp->mid[i] = sp->p1[i] + *frac * (sp->p2[i] - sp->p1[i]);
//			
//				*side = (*t1 < 0);
//				
//				// move up to the node
////				if (!SV_RecursiveHullCheck (hull, node->children[side], p1f, midf, p1, mid, trace) )
////					return false;
//
//				//restart from the next section
//				sp->lr = 6;
//				
//				//call it again
//				sp++;
//					
//				sp->num = node->children[*side];
//				sp->p1f = *p1f;
//				sp->p2f = *midf;
//				VectorCopy((sp - 1)->p1, sp->p1);
//				VectorCopy((sp - 1)->mid, sp->p2);
//				sp->lr = 0;
//				
//				continue;
//			}
//			case 6:
//			{
//				dclipnode_t *node = hull->clipnodes + *num;
//				
//				if ((sp + 1)->return_val == false)
//				{
//					sp->return_val = false;
//					
//					sp--;
//					continue;
//				}
//				
//				if (SV_HullPointContentsFP (hull, node->children[(*side) ^ 1], sp->mid)
//					!= CONTENTS_SOLID)
//				// go past the node
//				{
////					return SV_RecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace);
//
//					//restart from the next section ONLY
//					sp->lr = 7;
//					
//					//call it again
//					sp++;
//						
//					sp->num = node->children[(*side) ^ 1];
//					sp->p1f = *midf;
//					sp->p2f = *p2f;
//					VectorCopy((sp - 1)->mid, sp->p1);
//					VectorCopy((sp - 1)->p2, sp->p2);
//					sp->lr = 0;
//					
//					continue;
//				}
//				
//				goto skip_7;
//			}
//			case 7:		//do the return for the previous bit
//			{
//				sp->return_val = (sp + 1)->return_val;
//				
//				sp--;
//				continue;
//			}
//			case 8:
//			{
//skip_7:
//				dclipnode_t *node = hull->clipnodes + *num;
//				mplane_t *plane = hull->planes + node->planenum;
//				
//				if (trace->allsolid)
//				{
//					sp->return_val = false;
//					
//					sp--;
//					continue;
//				}
//				
//				if ((*side) == 0)
//				{
//					VectorCopy (plane->normal, trace->plane.normal);
//					trace->plane.dist = plane->dist;
//				}
//				else
//				{
//					VectorSubtract (vec3_origin, plane->normal, trace->plane.normal);
//					trace->plane.dist = -plane->dist;
//				}
//				
//				while (SV_HullPointContentsFP (hull, hull->firstclipnode, sp->mid)
//					== CONTENTS_SOLID)
//				{ // shouldn't really happen, but does occasionally
//					*frac = *frac - 0.1f;
//					if (frac < 0)
//					{
//						trace->fraction = *midf;
//						VectorCopy (sp->mid, trace->endpos);
//						Con_DPrintf ("backup past 0\n");
////						return false
//						sp->return_val = false;
//						
//						sp--;
//						continue;
//					}
//					*midf = *p1f + (*p2f - *p1f) * *frac;
//					for (int i = 0; i < 3; i++)
//						sp->mid[i] = sp->p1[i] + *frac * (sp->p2[i] - sp->p1[i]);
//				}
//			
//				trace->fraction = *midf;
//				VectorCopy (sp->mid, trace->endpos);
//				
//				sp->return_val = false;
//				
//				sp--;
//				continue;
//			}
//		}
//	}
//
//	return (sp + 1)->return_val;	
//}
//

#include "quakedef.h"
#include "ds.h"

#ifdef USE_EXTRA_RAM
#define MAX_ITERATIONS 200
#else
#define MAX_ITERATIONS 100
#endif

struct iteration
{
	//args
	int num;
	fixed_point p1f;
	fixed_point p2f;
	fixed_point p1[3];
	fixed_point p2[3];
	
	//temps
	fixed_point t1, t2;
	fixed_point frac;
	fixed_point mid[3];
	fixed_point midf;
	int side;
	
	//loop control
	int lr;
	int return_val;
};

#define	DIST_EPSILON	(0.03125)
const int DIST_EPSILON_FP = (int)(0.03125 * FP_SCALE);

int SV_HullPointContents (hull_t *hull, int num, vec3_t p);
int SV_HullPointContentsFP (hull_t *hull, int num, fixed_point *f_p);

struct iteration stack[MAX_ITERATIONS];
//struct iteration *stack;

const int point_one = (int)(FP_SCALE * 0.1f);

qboolean SV_NonRecursiveHullCheck(hull_t *hull, int start_num, float start_p1f, float start_p2f, vec3_t start_p1, vec3_t start_p2, trace_t *trace) __attribute__((section(".itcm"), long_call));
qboolean SV_NonRecursiveHullCheck(hull_t *hull, int start_num, float start_p1f, float start_p2f, vec3_t start_p1, vec3_t start_p2, trace_t *trace)
{
	struct iteration *sp = stack;
	
	fixed_point origin_fp[3];
	VectorCopy(vec3_origin, origin_fp);

	sp->num = start_num;
	sp->p1f = start_p1f;
	sp->p2f = start_p2f;
	VectorCopy(start_p1, sp->p1);
	VectorCopy(start_p2, sp->p2);
	
	sp->lr = 0;		//start from the top
	
	while (sp >= &stack[0])
	{
		if (sp > &stack[MAX_ITERATIONS - 1])
		{
			Sys_Error("we\'re out of fake stack!\nif this happens PLEASE get in contact with me!\n");
		}
		
		//arguments
		int *num = &sp->num;
		fixed_point *p1f = &sp->p1f;
		fixed_point *p2f = &sp->p2f;
		
		//temporaries
		fixed_point *t1 = &sp->t1;
		fixed_point *t2 = &sp->t2;
		fixed_point *frac = &sp->frac;
		fixed_point *midf = &sp->midf;
		int *side = &sp->side;
		
		switch (sp->lr)
		{
			//looks ok
			case 0:
			{
				// check for empty
				if (*num < 0)
				{
					if (*num != CONTENTS_SOLID)
					{
#ifdef USE_EXTRA_RAM
						byte_write(&trace->allsolid, false);
						
						if (*num == CONTENTS_EMPTY)
							byte_write(&trace->inopen, true);
						else
							byte_write(&trace->inwater, true);
#else
						trace->allsolid = false;
						
						if (*num == CONTENTS_EMPTY)
							trace->inopen = true;
						else
							trace->inwater = true;
#endif
					}
					else
#ifdef USE_EXTRA_RAM
						byte_write(&trace->startsolid, true);
#else
						trace->startsolid = true;
#endif
						
//					return true;		// empty
					sp->return_val = true;

					sp--;
					
					continue;
				}
			}
			//ok
			case 1:
			{
				if (*num < hull->firstclipnode || *num > hull->lastclipnode)
				{
					Sys_Error ("SV_RecursiveHullCheck: bad node number");
				}
					
				dclipnode_t *node = hull->clipnodes + *num;
				mplane_t *plane = hull->planes + node->planenum;
				
				if (plane->type < 3)
				{
					t1->value = sp->p1[plane->type].value - plane->dist.value;
					t2->value = sp->p2[plane->type].value - plane->dist.value;
				}
				else
				{
					t1->value = ((long long)plane->normal[0].value * (long long)sp->p1[0].value
									+ (long long)plane->normal[1].value * (long long)sp->p1[1].value
									+ (long long)plane->normal[2].value * (long long)sp->p1[2].value) / FP_SCALE;
					t1->value = t1->value - plane->dist.value;
					
					
					t2->value = ((long long)plane->normal[0].value * (long long)sp->p2[0].value
									+ (long long)plane->normal[1].value * (long long)sp->p2[1].value
									+ (long long)plane->normal[2].value * (long long)sp->p2[2].value) / FP_SCALE;
					t2->value = t2->value - plane->dist.value;
				}
				
				if (t1->value >= 0 && t2->value >= 0)
				{
//					return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace);

					//restart from the next section
					sp->lr = 2;

					//call it again
					sp++;
					
					sp->num = node->children[0];
					sp->p1f = *p1f;
					sp->p2f = *p2f;
					VectorFPCopy((sp - 1)->p1, sp->p1);
					VectorFPCopy((sp - 1)->p2, sp->p2);
					sp->lr = 0;
					
					continue;
				}
				
				goto skip_2;
			}
			case 2:		//the 'return' for the previous line
			{
				sp->return_val = (sp + 1)->return_val;
				
				sp--;
				continue;
			}
			//ok
			case 3:
			{
skip_2:
				dclipnode_t *node = hull->clipnodes + *num;
				mplane_t *plane = hull->planes + node->planenum;
				
				if (t1->value < 0 && t2->value < 0)
				{
//					return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace);

					//restart from the next section
					sp->lr = 4;

					//call it again
					sp++;
					
					sp->num = node->children[1];
					sp->p1f = *p1f;
					sp->p2f = *p2f;
					VectorFPCopy((sp - 1)->p1, sp->p1);
					VectorFPCopy((sp - 1)->p2, sp->p2);
					sp->lr = 0;
					
					continue;
				}
				
				goto skip_4;
			}
			case 4:		//the 'return' for the previous line
			{
				sp->return_val = (sp + 1)->return_val;
				
				sp--;
				continue;
			}
			case 5:
			{
skip_4:
				dclipnode_t *node = hull->clipnodes + *num;
				mplane_t *plane = hull->planes + node->planenum;
				
				// put the crosspoint DIST_EPSILON pixels on the near side
				if (t1->value < 0)
					frac->value = (((long long)t1->value + (long long)DIST_EPSILON_FP) * (long long)FP_SCALE)
						/ (t1->value - t2->value);
				else
					frac->value = (((long long)t1->value - (long long)DIST_EPSILON_FP) * (long long)FP_SCALE)
						/ (t1->value - t2->value);
				if (frac->value < 0)
					frac->value = 0;
				if (frac->value > FP_SCALE)
					frac->value = FP_SCALE;
					
				midf->value = p1f->value + (((long long)(p2f->value - p1f->value) * (long long)frac->value) >> FP_SCALE_SHIFT);

				for (int i = 0 ; i < 3; i++)
					sp->mid[i].value = sp->p1[i].value
						+ (((long long)frac->value * (long long)(sp->p2[i].value - sp->p1[i].value)) >> FP_SCALE_SHIFT);
			
				*side = (t1->value < 0);
				
				// move up to the node
//				if (!SV_RecursiveHullCheck (hull, node->children[side], p1f, midf, p1, mid, trace) )
//					return false;

				//restart from the next section
				sp->lr = 6;
				
				//call it again
				sp++;
					
				sp->num = node->children[*side];
				sp->p1f = *p1f;
				sp->p2f = *midf;
				VectorFPCopy((sp - 1)->p1, sp->p1);
				VectorFPCopy((sp - 1)->mid, sp->p2);
				sp->lr = 0;
				
				continue;
			}
			case 6:
			{
				dclipnode_t *node = hull->clipnodes + *num;
				
				if ((sp + 1)->return_val == false)
				{
					sp->return_val = false;
					
					sp--;
					continue;
				}
				
				if (SV_HullPointContentsFP (hull, node->children[(*side) ^ 1], sp->mid)
					!= CONTENTS_SOLID)
				// go past the node
				{
//					return SV_RecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace);

					//restart from the next section ONLY
					sp->lr = 7;
					
					//call it again
					sp++;
						
					sp->num = node->children[(*side) ^ 1];
					sp->p1f = *midf;
					sp->p2f = *p2f;
					VectorFPCopy((sp - 1)->mid, sp->p1);
					VectorFPCopy((sp - 1)->p2, sp->p2);
					sp->lr = 0;
					
					continue;
				}
				
				goto skip_7;
			}
			case 7:		//do the return for the previous bit
			{
				sp->return_val = (sp + 1)->return_val;
				
				sp--;
				continue;
			}
			case 8:
			{
skip_7:
				dclipnode_t *node = hull->clipnodes + *num;
				mplane_t *plane = hull->planes + node->planenum;
				
				if (trace->allsolid)
				{
					sp->return_val = false;
					
					sp--;
					continue;
				}
				
				if ((*side) == 0)
				{
					VectorCopy (plane->normal, trace->plane.normal);
					trace->plane.dist = plane->dist;
				}
				else
				{
					trace->plane.normal[0].value = origin_fp[0].value - plane->normal[0].value;
					trace->plane.normal[1].value = origin_fp[1].value - plane->normal[1].value;
					trace->plane.normal[2].value = origin_fp[2].value - plane->normal[2].value;
					
					trace->plane.dist.value = -plane->dist.value;
				}
				
				while (SV_HullPointContentsFP (hull, hull->firstclipnode, sp->mid)
					== CONTENTS_SOLID)
				{ // shouldn't really happen, but does occasionally
					frac->value = frac->value - point_one;
					if (frac->value < 0)
					{
						trace->fraction = *midf;
						VectorCopy (sp->mid, trace->endpos);
						Con_DPrintf ("backup past 0\n");
//						return false
						sp->return_val = false;
						
						sp--;
						continue;
					}

					midf->value = p1f->value + (((long long)(p2f->value - p1f->value) * (long long)frac->value) >> FP_SCALE_SHIFT);

					for (int i = 0 ; i < 3; i++)
						sp->mid[i].value = sp->p1[i].value
							+ (((long long)frac->value * (long long)(sp->p2[i].value - sp->p1[i].value)) >> FP_SCALE_SHIFT);
				}
			
				trace->fraction = *midf;
				VectorCopy (sp->mid, trace->endpos);
				
				sp->return_val = false;
				
				sp--;
				continue;
			}
		}
	}

	return (sp + 1)->return_val;	
}
