Useful math references
http://iq.orst.edu/mathsg/vcalc/dotprod/dotprod.html
http://hack.box.sk/mirrors/dsl/

Pseudo-code tree trace:

** Main (qbsp.c):
Setup argv stuff, then calls Processfile

** ProcessFile (qbsp.c):
Initial arg setup stuff
LoadMapFile - reads in ents and brushes
UpdateEntLump if onlyents if set, then done
BeginBSPFile - initialize a few vars
CreateHulls
ReadClipHull 1,2
WriteEntitiesToString
FinishBSPFile - write miptextures, and throw BSP to disk

** LoadMapFile (map.c):
Reads a .MAP file into:
mbrush_t	mapbrushes[MAX_MAP_BRUSHES];
entity_t	entities[MAX_MAP_ENTITIES];
char		miptex[MAX_MAP_TEXINFO][16];

** UpdateEntLump (qbsp.c):
Updates the entities lump in the BSP file only

** BeginBSPFile (writebsp.c)
** FinishBSPFile (writebsp.c)

** CreateHulls (qbsp.c):
Normally creates three hulls, setting hullnum = 1,2,0 and calling
CreateSingleHull

** CreateSingleHull (qbsp.c):
for each entity, calls ProcessEntity
when finished, if hullnum == 1,2 calls WriteClipHull

** ProcessEntity (qbsp.c):
Set worldmodel t/f based on whether entity is #0
If entity contains no brushes return
Call Brush_LoadEntity to create a perfect skin of the brush
Error if no brushes are found on the entity
Call CSGFaces with the brushset that Brush_loadEntity returned
	in order to get a list of surfaces that covers all brush faces
...

** WriteClipHull (qbsp.c):
** ReadClipHull (qbsp.c):
Save hull computations to disk and read them in later

** Brush_LoadEntity (brush.c):
For each brush in the entity:
	Calls LoadBrush to convert map brush to BSP brush
	Update numbrushes
	Prepends brush to water or other linked list
	Updates bounds of bset (AddToBounds)
Prepend all water brushes to front of other linked list
Set bset->brushes to point to start of other list
Set brushset = bset
Brush_DrawAll the bset

** LoadBrush (brush.c):
If texture name is "clip" and we're on hull 0, return
If texture starts with *, set contents to lava, slime, water
If texture name is "sky" and hull is 0 on the worldmodel, set contents
Else, contents are solid
Return if hullnum != 0 and the brush isn't sky or solid (no water in clip hulls)
Copy all faces of brush (mb) into elements of array (faces), set
	texinfo to 0 for clip hulls (hullnum != 0)
Call CreateBrushFaces
If this is a clipping hull (hullnum != 0)
	ExpandBrush, then CreateBrushFaces again
Allocate a new brush (AllocBrush), copy info over into new brush
Return the brush

** CreateBrushFaces (brush.c):
For each face:
	Create a winding using BaseWindingForPlane
	For each other face, flip the plane (VectorSubtract origin, change dest),
		and then use ClipWinding to truncate the original winding
		to this particular plane
	If the resultant winding is non-existant, move to next face
	Allocate a new face (AllocFace)
	Set numpoints on f = numpoints of the winding
	For each point on the winding:
		Round each number closer than 0.001 to an integer, and store
			all numbers in the face (f)
		Update brush_mins and brush_maxs
	Free the winding
	Set face planenum to FindPlane(mapface plane, face planeside)
	Prepend face (f) to the brush_faces linked list
	CheckFace

** BaseWindingForPlane (qbsp.c):
Find the largest component of the plane normal vector
Set vup to the "up" vector relative to major axis found in step 1
Create vup to be 90 deg to plane normal, pointing "up"
Mult normal * dist and store in org (org is vector from origin to plane)
Crossproduct vup and normal to get vright
Scale vup and vright by 8192 to make them really long
Set w to be a new winding with 4 points (NewWinding)
Create 4 points at the corners of vup and vright box

** ClipWinding (qbsp.c):
For each point on the winding:
	Dot that point with the split plane normal to get front/back,
		subtract dist.  0 is on plane, + is front, - is back.
	Store dot - dist in dist[] array
	Set sides[i] to SIDE_FRONT, SIDE_BACK, SIDE_ON
	Increment count of appropriate side
Set sides[numpoints] and dist[numpoints] to 0 values for wraparound
If we're keeping windings that are on the plane, and nothing is
	SIDE_FRONT or SIDE_BACK, just return the input winding
If counts[0] is empty (nothing on SIDE_FRONT), free winding and
	return NULL (all of it was clipped)
If counts[1] is empty, return input winding (all if it is saved)
Otherwise we have to do some splitting, allocate a new winding
Estimate new winding to have 4 more points
For each point on the input winding:
	If the point is SIDE_ON, copy it over and go to next one
	If the point is SIDE_FRONT, copy it over
	If the next point is the same SIDE status as the current one,
		or the next one is SIDE_ON, continue, otherwise need a
		split point
	p1 and p2 are on both sides of the split point
	Set dot = the ratio of the location of the plane in the distance
		from p1 to p2
	For each vector coordinate, set the new point (mid) to the
		correct coords
	Add mid to the new winding
Delete the input winding and return mid

** NewWinding (qbsp.c):
Increment c_activewindings, set c_peakwindings if active is higher
Calculate the necessary size, malloc it, memset it to 0
Return it

** AllocFace (qbsp.c):
Increment c_activefaces, set c_peakfaces if active is higher
Malloc it, memset it to 0, set planenum = -1
Return it

** FindPlane (brush.c):
Verify that the plane's normal vector is correctly normalized
Call NormalizePlane on the input plane
Set the side of the plane according to whether the plane was
	flipped or not
Check through all numbrushplanes:
	If the dot is close to 1 and the distance is about the same,
		return the number of the plane we've found
Otherwise, we need to add the plane to the planes array
Increment numbrushplanes, return numbrushplanes-1

** NormalizePlane (brush.c):
If the plane is axis-aligned, flip it to point positively and
	set the plane type to PLANE_X, PLANE_Y, or PLANE_Z as appropriate.
If the plane isn't directly axis aligned, set the type to be
	PLANE_ANYX, PLANE_ANYY, or PLANE_ANYZ for whichever has the
	largest vector component
Reverse the plane to point in the positive direction if necessary

** CheckFace (brush.c):
If face has less than 3 points on it, it's an error
Get the plane normal in facenormal, subtract from origin if necessary
For each point on the face:
	Ensure the point coords are in the range -18000 to 18000
	Ensure distance from current point to next point is > ON_EPSILON
	Dot the point with the face normal to ensure it is on the plane
	Cross and normalize the face normal and point to point normal
		to get the edge normal
	Calculate edge's distance from origin (dot point, edgenormal,
		use that distance)
	Dot every other point on the face with the edgenormal and
		verify that they are on the + side of the edge
		(convex polygon)

** ExpandBrush (brush.c):
For each point in each brush_face:
	Add the current point to the current hull (AddHullPoint)
--- DO OTHER STUFF

** AddHullPoint (brush.c):
Check all hull_points, add this point if it doesn't exist yet
Add each point +- each size (point, player, shambler) to hull_corners

** Brush_DrawAll (brush.c):
For each face on each brush:
	Draw_DrawFace the face, which does nothing

** CSGFaces (csg4.c):
Reset validfaces and csgfaces, brushfaces, csgmergefaces
For each brush:
	Copy each face to outside (CopyFacesToOutside)
	For each other brush:
		If bounding boxes don't intersect, continue
		Set inside = outside linked list, outside to NULL
		For each face on the brush, ClipInside the throwaway faces
		...

** CopyFacesToOutside (csg4.c):
For each brush face:
	Increment brushfaces
	Allocate a new face
	Copy the face over to the allocated space
	Contents of front side are EMPTY, back are same as face
	Prepend the face to the outside linked list

** ClipInside (csg4.c):
