]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_brush.c
removed \n from all Host_Error, Sys_Error, PRVM_ERROR, PF_ERROR calls, since Host_Err...
[xonotic/darkplaces.git] / model_brush.c
index 68554e0dfc69f1d81c96494012fd52bc079a68fb..26e731a5a0d3717e54fc716fb551810e724c5db0 100644 (file)
@@ -83,7 +83,7 @@ static mleaf_t *Mod_Q1BSP_PointInLeaf(model_t *model, const vec3_t p)
        return (mleaf_t *)node;
 }
 
-static void Mod_Q1BSP_AmbientSoundLevelsForPoint(model_t *model, const vec3_t p, qbyte *out, int outsize)
+static void Mod_Q1BSP_AmbientSoundLevelsForPoint(model_t *model, const vec3_t p, unsigned char *out, int outsize)
 {
        int i;
        mleaf_t *leaf;
@@ -104,17 +104,19 @@ static void Mod_Q1BSP_AmbientSoundLevelsForPoint(model_t *model, const vec3_t p,
 
 static int Mod_Q1BSP_FindBoxClusters(model_t *model, const vec3_t mins, const vec3_t maxs, int maxclusters, int *clusterlist)
 {
-       int numclusters = 0, side, nodestackindex = 0;
+       int numclusters = 0;
+       int nodestackindex = 0;
        mnode_t *node, *nodestack[1024];
        if (!model->brush.num_pvsclusters)
                return -1;
        node = model->brush.data_nodes;
        for (;;)
        {
+#if 1
                if (node->plane)
                {
                        // node - recurse down the BSP tree
-                       side = BoxOnPlaneSide(mins, maxs, node->plane) - 1;
+                       int side = BoxOnPlaneSide(mins, maxs, node->plane) - 1;
                        if (side < 2)
                        {
                                // box is on one side of plane, take that path
@@ -127,36 +129,57 @@ static int Mod_Q1BSP_FindBoxClusters(model_t *model, const vec3_t mins, const ve
                                        nodestack[nodestackindex++] = node->children[0];
                                node = node->children[1];
                        }
+                       continue;
                }
                else
                {
-                       // leaf - check cluster bit
+                       // leaf - add clusterindex to list
                        if (numclusters < maxclusters)
                                clusterlist[numclusters] = ((mleaf_t *)node)->clusterindex;
                        numclusters++;
-                       // try another path we didn't take earlier
-                       if (nodestackindex == 0)
-                               break;
-                       node = nodestack[--nodestackindex];
                }
+#else
+               if (BoxesOverlap(mins, maxs, node->mins, node->maxs))
+               {
+                       if (node->plane)
+                       {
+                               if (nodestackindex < 1024)
+                                       nodestack[nodestackindex++] = node->children[0];
+                               node = node->children[1];
+                               continue;
+                       }
+                       else
+                       {
+                               // leaf - add clusterindex to list
+                               if (numclusters < maxclusters)
+                                       clusterlist[numclusters] = ((mleaf_t *)node)->clusterindex;
+                               numclusters++;
+                       }
+               }
+#endif
+               // try another path we didn't take earlier
+               if (nodestackindex == 0)
+                       break;
+               node = nodestack[--nodestackindex];
        }
        // return number of clusters found (even if more than the maxclusters)
        return numclusters;
 }
 
-static int Mod_Q1BSP_BoxTouchingPVS(model_t *model, const qbyte *pvs, const vec3_t mins, const vec3_t maxs)
+static int Mod_Q1BSP_BoxTouchingPVS(model_t *model, const unsigned char *pvs, const vec3_t mins, const vec3_t maxs)
 {
-       int clusterindex, side, nodestackindex = 0;
+       int nodestackindex = 0;
        mnode_t *node, *nodestack[1024];
        if (!model->brush.num_pvsclusters)
                return true;
        node = model->brush.data_nodes;
        for (;;)
        {
+#if 1
                if (node->plane)
                {
                        // node - recurse down the BSP tree
-                       side = BoxOnPlaneSide(mins, maxs, node->plane) - 1;
+                       int side = BoxOnPlaneSide(mins, maxs, node->plane) - 1;
                        if (side < 2)
                        {
                                // box is on one side of plane, take that path
@@ -169,42 +192,63 @@ static int Mod_Q1BSP_BoxTouchingPVS(model_t *model, const qbyte *pvs, const vec3
                                        nodestack[nodestackindex++] = node->children[0];
                                node = node->children[1];
                        }
+                       continue;
                }
                else
                {
                        // leaf - check cluster bit
-                       clusterindex = ((mleaf_t *)node)->clusterindex;
+                       int clusterindex = ((mleaf_t *)node)->clusterindex;
                        if (CHECKPVSBIT(pvs, clusterindex))
                        {
                                // it is visible, return immediately with the news
                                return true;
                        }
+               }
+#else
+               if (BoxesOverlap(mins, maxs, node->mins, node->maxs))
+               {
+                       if (node->plane)
+                       {
+                               if (nodestackindex < 1024)
+                                       nodestack[nodestackindex++] = node->children[0];
+                               node = node->children[1];
+                               continue;
+                       }
                        else
                        {
-                               // nothing to see here, try another path we didn't take earlier
-                               if (nodestackindex == 0)
-                                       break;
-                               node = nodestack[--nodestackindex];
+                               // leaf - check cluster bit
+                               int clusterindex = ((mleaf_t *)node)->clusterindex;
+                               if (CHECKPVSBIT(pvs, clusterindex))
+                               {
+                                       // it is visible, return immediately with the news
+                                       return true;
+                               }
                        }
                }
+#endif
+               // nothing to see here, try another path we didn't take earlier
+               if (nodestackindex == 0)
+                       break;
+               node = nodestack[--nodestackindex];
        }
        // it is not visible
        return false;
 }
 
-static int Mod_Q1BSP_BoxTouchingLeafPVS(model_t *model, const qbyte *pvs, const vec3_t mins, const vec3_t maxs)
+static int Mod_Q1BSP_BoxTouchingLeafPVS(model_t *model, const unsigned char *pvs, const vec3_t mins, const vec3_t maxs)
 {
-       int clusterindex, side, nodestackindex = 0;
+       int nodestackindex = 0;
        mnode_t *node, *nodestack[1024];
        if (!model->brush.num_leafs)
                return true;
        node = model->brush.data_nodes;
        for (;;)
        {
+#if 1
                if (node->plane)
                {
                        // node - recurse down the BSP tree
-                       side = BoxOnPlaneSide(mins, maxs, node->plane) - 1;
+                       int side = BoxOnPlaneSide(mins, maxs, node->plane) - 1;
                        if (side < 2)
                        {
                                // box is on one side of plane, take that path
@@ -217,40 +261,63 @@ static int Mod_Q1BSP_BoxTouchingLeafPVS(model_t *model, const qbyte *pvs, const
                                        nodestack[nodestackindex++] = node->children[0];
                                node = node->children[1];
                        }
+                       continue;
                }
                else
                {
                        // leaf - check cluster bit
-                       clusterindex = ((mleaf_t *)node) - model->brush.data_leafs;
+                       int clusterindex = ((mleaf_t *)node) - model->brush.data_leafs;
                        if (CHECKPVSBIT(pvs, clusterindex))
                        {
                                // it is visible, return immediately with the news
                                return true;
                        }
+               }
+#else
+               if (BoxesOverlap(mins, maxs, node->mins, node->maxs))
+               {
+                       if (node->plane)
+                       {
+                               if (nodestackindex < 1024)
+                                       nodestack[nodestackindex++] = node->children[0];
+                               node = node->children[1];
+                               continue;
+                       }
                        else
                        {
-                               // nothing to see here, try another path we didn't take earlier
-                               if (nodestackindex == 0)
-                                       break;
-                               node = nodestack[--nodestackindex];
+                               // leaf - check cluster bit
+                               int clusterindex = ((mleaf_t *)node) - model->brush.data_leafs;
+                               if (CHECKPVSBIT(pvs, clusterindex))
+                               {
+                                       // it is visible, return immediately with the news
+                                       return true;
+                               }
                        }
                }
+#endif
+               // nothing to see here, try another path we didn't take earlier
+               if (nodestackindex == 0)
+                       break;
+               node = nodestack[--nodestackindex];
        }
        // it is not visible
        return false;
 }
 
-static int Mod_Q1BSP_BoxTouchingVisibleLeafs(model_t *model, const qbyte *visibleleafs, const vec3_t mins, const vec3_t maxs)
+static int Mod_Q1BSP_BoxTouchingVisibleLeafs(model_t *model, const unsigned char *visibleleafs, const vec3_t mins, const vec3_t maxs)
 {
-       int side, nodestackindex = 0;
+       int nodestackindex = 0;
        mnode_t *node, *nodestack[1024];
+       if (!model->brush.num_leafs)
+               return true;
        node = model->brush.data_nodes;
        for (;;)
        {
+#if 1
                if (node->plane)
                {
                        // node - recurse down the BSP tree
-                       side = BoxOnPlaneSide(mins, maxs, node->plane) - 1;
+                       int side = BoxOnPlaneSide(mins, maxs, node->plane) - 1;
                        if (side < 2)
                        {
                                // box is on one side of plane, take that path
@@ -263,6 +330,7 @@ static int Mod_Q1BSP_BoxTouchingVisibleLeafs(model_t *model, const qbyte *visibl
                                        nodestack[nodestackindex++] = node->children[0];
                                node = node->children[1];
                        }
+                       continue;
                }
                else
                {
@@ -272,14 +340,32 @@ static int Mod_Q1BSP_BoxTouchingVisibleLeafs(model_t *model, const qbyte *visibl
                                // it is visible, return immediately with the news
                                return true;
                        }
+               }
+#else
+               if (BoxesOverlap(mins, maxs, node->mins, node->maxs))
+               {
+                       if (node->plane)
+                       {
+                               if (nodestackindex < 1024)
+                                       nodestack[nodestackindex++] = node->children[0];
+                               node = node->children[1];
+                               continue;
+                       }
                        else
                        {
-                               // nothing to see here, try another path we didn't take earlier
-                               if (nodestackindex == 0)
-                                       break;
-                               node = nodestack[--nodestackindex];
+                               // leaf - check if it is visible
+                               if (visibleleafs[(mleaf_t *)node - model->brush.data_leafs])
+                               {
+                                       // it is visible, return immediately with the news
+                                       return true;
+                               }
                        }
                }
+#endif
+               // nothing to see here, try another path we didn't take earlier
+               if (nodestackindex == 0)
+                       break;
+               node = nodestack[--nodestackindex];
        }
        // it is not visible
        return false;
@@ -887,7 +973,7 @@ loc0:
 
                                if (ds >= 0 && ds < surface->lightmapinfo->extents[0] && dt >= 0 && dt < surface->lightmapinfo->extents[1])
                                {
-                                       qbyte *lightmap;
+                                       unsigned char *lightmap;
                                        int lmwidth, lmheight, maps, line3, size3, dsfrac = ds & 15, dtfrac = dt & 15, scale = 0, r00 = 0, g00 = 0, b00 = 0, r01 = 0, g01 = 0, b01 = 0, r10 = 0, g10 = 0, b10 = 0, r11 = 0, g11 = 0, b11 = 0;
                                        lmwidth = ((surface->lightmapinfo->extents[0]>>4)+1);
                                        lmheight = ((surface->lightmapinfo->extents[1]>>4)+1);
@@ -898,7 +984,7 @@ loc0:
 
                                        for (maps = 0;maps < MAXLIGHTMAPS && surface->lightmapinfo->styles[maps] != 255;maps++)
                                        {
-                                               scale = d_lightstylevalue[surface->lightmapinfo->styles[maps]];
+                                               scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[maps]];
                                                r00 += lightmap[      0] * scale;g00 += lightmap[      1] * scale;b00 += lightmap[      2] * scale;
                                                r01 += lightmap[      3] * scale;g01 += lightmap[      4] * scale;b01 += lightmap[      5] * scale;
                                                r10 += lightmap[line3+0] * scale;g10 += lightmap[line3+1] * scale;b10 += lightmap[line3+2] * scale;
@@ -960,10 +1046,10 @@ void Mod_Q1BSP_LightPoint(model_t *model, const vec3_t p, vec3_t ambientcolor, v
        Mod_Q1BSP_LightPoint_RecursiveBSPNode(model, ambientcolor, diffusecolor, diffusenormal, model->brush.data_nodes + model->brushq1.hulls[0].firstclipnode, p[0], p[1], p[2], p[2] - 65536);
 }
 
-static void Mod_Q1BSP_DecompressVis(const qbyte *in, const qbyte *inend, qbyte *out, qbyte *outend)
+static void Mod_Q1BSP_DecompressVis(const unsigned char *in, const unsigned char *inend, unsigned char *out, unsigned char *outend)
 {
        int c;
-       qbyte *outstart = out;
+       unsigned char *outstart = out;
        while (out < outend)
        {
                if (in == inend)
@@ -1001,7 +1087,7 @@ R_Q1BSP_LoadSplitSky
 A sky texture is 256*128, with the right side being a masked overlay
 ==============
 */
-void R_Q1BSP_LoadSplitSky (qbyte *src, int width, int height, int bytesperpixel)
+void R_Q1BSP_LoadSplitSky (unsigned char *src, int width, int height, int bytesperpixel)
 {
        int i, j;
        unsigned solidpixels[128*128], alphapixels[128*128];
@@ -1061,8 +1147,8 @@ void R_Q1BSP_LoadSplitSky (qbyte *src, int width, int height, int bytesperpixel)
                }
        }
 
-       loadmodel->brush.solidskytexture = R_LoadTexture2D(loadmodel->texturepool, "sky_solidtexture", 128, 128, (qbyte *) solidpixels, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
-       loadmodel->brush.alphaskytexture = R_LoadTexture2D(loadmodel->texturepool, "sky_alphatexture", 128, 128, (qbyte *) alphapixels, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL);
+       loadmodel->brush.solidskytexture = R_LoadTexture2D(loadmodel->texturepool, "sky_solidtexture", 128, 128, (unsigned char *) solidpixels, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
+       loadmodel->brush.alphaskytexture = R_LoadTexture2D(loadmodel->texturepool, "sky_alphatexture", 128, 128, (unsigned char *) alphapixels, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL);
 }
 
 static void Mod_Q1BSP_LoadTextures(lump_t *l)
@@ -1071,7 +1157,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
        miptex_t *dmiptex;
        texture_t *tx, *tx2, *anims[10], *altanims[10];
        dmiptexlump_t *m;
-       qbyte *data, *mtdata;
+       unsigned char *data, *mtdata;
        char name[256];
 
        loadmodel->data_textures = NULL;
@@ -1123,7 +1209,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                dofs[i] = LittleLong(dofs[i]);
                if (dofs[i] == -1 || r_nosurftextures.integer)
                        continue;
-               dmiptex = (miptex_t *)((qbyte *)m + dofs[i]);
+               dmiptex = (miptex_t *)((unsigned char *)m + dofs[i]);
 
                // make sure name is no more than 15 characters
                for (j = 0;dmiptex->name[j] && j < 15;j++)
@@ -1142,7 +1228,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                                Con_Printf("Texture \"%s\" in \"%s\"is corrupt or incomplete\n", dmiptex->name, loadmodel->name);
                                continue;
                        }
-                       mtdata = (qbyte *)dmiptex + j;
+                       mtdata = (unsigned char *)dmiptex + j;
                }
 
                if ((mtwidth & 15) || (mtheight & 15))
@@ -1187,7 +1273,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                                if (loadmodel->brush.ishlbsp)
                                {
                                        // internal texture overrides wad
-                                       qbyte *pixels, *freepixels, *fogpixels;
+                                       unsigned char *pixels, *freepixels, *fogpixels;
                                        pixels = freepixels = NULL;
                                        if (mtdata)
                                                pixels = W_ConvertWAD3Texture(dmiptex);
@@ -1200,7 +1286,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                                                tx->skin.base = tx->skin.merged = R_LoadTexture2D(loadmodel->texturepool, tx->name, image_width, image_height, pixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, NULL);
                                                if (Image_CheckAlpha(pixels, image_width * image_height, true))
                                                {
-                                                       fogpixels = (qbyte *)Mem_Alloc(tempmempool, image_width * image_height * 4);
+                                                       fogpixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
                                                        for (j = 0;j < image_width * image_height * 4;j += 4)
                                                        {
                                                                fogpixels[j + 0] = 255;
@@ -1368,18 +1454,19 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
 static void Mod_Q1BSP_LoadLighting(lump_t *l)
 {
        int i;
-       qbyte *in, *out, *data, d;
+       unsigned char *in, *out, *data, d;
        char litfilename[1024];
+       fs_offset_t filesize;
        loadmodel->brushq1.lightdata = NULL;
        if (loadmodel->brush.ishlbsp) // LordHavoc: load the colored lighting data straight
        {
-               loadmodel->brushq1.lightdata = (qbyte *)Mem_Alloc(loadmodel->mempool, l->filelen);
+               loadmodel->brushq1.lightdata = (unsigned char *)Mem_Alloc(loadmodel->mempool, l->filelen);
                for (i=0; i<l->filelen; i++)
                        loadmodel->brushq1.lightdata[i] = mod_base[l->fileofs+i] >>= 1;
        }
        else if (loadmodel->brush.ismcbsp)
        {
-               loadmodel->brushq1.lightdata = (qbyte *)Mem_Alloc(loadmodel->mempool, l->filelen);
+               loadmodel->brushq1.lightdata = (unsigned char *)Mem_Alloc(loadmodel->mempool, l->filelen);
                memcpy(loadmodel->brushq1.lightdata, mod_base + l->fileofs, l->filelen);
        }
        else // LordHavoc: bsp version 29 (normal white lighting)
@@ -1388,17 +1475,17 @@ static void Mod_Q1BSP_LoadLighting(lump_t *l)
                strlcpy (litfilename, loadmodel->name, sizeof (litfilename));
                FS_StripExtension (litfilename, litfilename, sizeof (litfilename));
                strlcat (litfilename, ".lit", sizeof (litfilename));
-               data = (qbyte*) FS_LoadFile(litfilename, tempmempool, false);
+               data = (unsigned char*) FS_LoadFile(litfilename, tempmempool, false, &filesize);
                if (data)
                {
-                       if (fs_filesize == (fs_offset_t)(8 + l->filelen * 3) && data[0] == 'Q' && data[1] == 'L' && data[2] == 'I' && data[3] == 'T')
+                       if (filesize == (fs_offset_t)(8 + l->filelen * 3) && data[0] == 'Q' && data[1] == 'L' && data[2] == 'I' && data[3] == 'T')
                        {
                                i = LittleLong(((int *)data)[1]);
                                if (i == 1)
                                {
                                        Con_DPrintf("loaded %s\n", litfilename);
-                                       loadmodel->brushq1.lightdata = (qbyte *)Mem_Alloc(loadmodel->mempool, fs_filesize - 8);
-                                       memcpy(loadmodel->brushq1.lightdata, data + 8, fs_filesize - 8);
+                                       loadmodel->brushq1.lightdata = (unsigned char *)Mem_Alloc(loadmodel->mempool, filesize - 8);
+                                       memcpy(loadmodel->brushq1.lightdata, data + 8, filesize - 8);
                                        Mem_Free(data);
                                        return;
                                }
@@ -1410,17 +1497,17 @@ static void Mod_Q1BSP_LoadLighting(lump_t *l)
                        }
                        else
                        {
-                               if (fs_filesize == 8)
+                               if (filesize == 8)
                                        Con_Print("Empty .lit file, ignoring\n");
                                else
-                                       Con_Printf("Corrupt .lit file (file size %i bytes, should be %i bytes), ignoring\n", fs_filesize, 8 + l->filelen * 3);
+                                       Con_Printf("Corrupt .lit file (file size %i bytes, should be %i bytes), ignoring\n", filesize, 8 + l->filelen * 3);
                                Mem_Free(data);
                        }
                }
                // LordHavoc: oh well, expand the white lighting data
                if (!l->filelen)
                        return;
-               loadmodel->brushq1.lightdata = (qbyte *)Mem_Alloc(loadmodel->mempool, l->filelen*3);
+               loadmodel->brushq1.lightdata = (unsigned char *)Mem_Alloc(loadmodel->mempool, l->filelen*3);
                in = loadmodel->brushq1.lightdata + l->filelen*2; // place the file at the end, so it will not be overwritten until the very last write
                out = loadmodel->brushq1.lightdata;
                memcpy(in, mod_base + l->fileofs, l->filelen);
@@ -1443,7 +1530,7 @@ static void Mod_Q1BSP_LoadLightList(void)
        strlcpy (lightsfilename, loadmodel->name, sizeof (lightsfilename));
        FS_StripExtension (lightsfilename, lightsfilename, sizeof(lightsfilename));
        strlcat (lightsfilename, ".lights", sizeof (lightsfilename));
-       s = lightsstring = (char *) FS_LoadFile(lightsfilename, tempmempool, false);
+       s = lightsstring = (char *) FS_LoadFile(lightsfilename, tempmempool, false, NULL);
        if (s)
        {
                numlights = 0;
@@ -1503,7 +1590,7 @@ static void Mod_Q1BSP_LoadVisibility(lump_t *l)
        if (!l->filelen)
                return;
        loadmodel->brushq1.num_compressedpvs = l->filelen;
-       loadmodel->brushq1.data_compressedpvs = (qbyte *)Mem_Alloc(loadmodel->mempool, l->filelen);
+       loadmodel->brushq1.data_compressedpvs = (unsigned char *)Mem_Alloc(loadmodel->mempool, l->filelen);
        memcpy(loadmodel->brushq1.data_compressedpvs, mod_base + l->fileofs, l->filelen);
 }
 
@@ -1605,7 +1692,7 @@ static void Mod_Q1BSP_LoadVertexes(lump_t *l)
 // The following two functions should be removed and MSG_* or SZ_* function sets adjusted so they
 // can be used for this
 // REMOVEME
-int SB_ReadInt (qbyte **buffer)
+int SB_ReadInt (unsigned char **buffer)
 {
        int     i;
        i = ((*buffer)[0]) + 256*((*buffer)[1]) + 65536*((*buffer)[2]) + 16777216*((*buffer)[3]);
@@ -1614,7 +1701,7 @@ int SB_ReadInt (qbyte **buffer)
 }
 
 // REMOVEME
-float SB_ReadFloat (qbyte **buffer)
+float SB_ReadFloat (unsigned char **buffer)
 {
        union
        {
@@ -1628,11 +1715,11 @@ float SB_ReadFloat (qbyte **buffer)
 
 static void Mod_Q1BSP_LoadSubmodels(lump_t *l, hullinfo_t *hullinfo)
 {
-       qbyte           *index;
+       unsigned char           *index;
        dmodel_t        *out;
        int                     i, j, count;
 
-       index = (qbyte *)(mod_base + l->fileofs);
+       index = (unsigned char *)(mod_base + l->fileofs);
        if (l->filelen % (48+4*hullinfo->filehulls))
                Host_Error ("Mod_Q1BSP_LoadSubmodels: funny lump size in %s", loadmodel->name);
 
@@ -1862,7 +1949,7 @@ static void Mod_Q1BSP_GenerateWarpMesh(msurface_t *surface)
        subdivpolyverts = 0;
        SubdividePolygon(surface->num_vertices, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex));
        if (subdivpolytriangles < 1)
-               Host_Error("Mod_Q1BSP_GenerateWarpMesh: no triangles?\n");
+               Host_Error("Mod_Q1BSP_GenerateWarpMesh: no triangles?");
 
        surface->mesh = mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + subdivpolytriangles * sizeof(int[3]) + subdivpolyverts * sizeof(surfvertex_t));
        mesh->num_vertices = subdivpolyverts;
@@ -1925,16 +2012,16 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l)
                firstedge = LittleLong(in->firstedge);
                numedges = LittleShort(in->numedges);
                if ((unsigned int) firstedge > (unsigned int) loadmodel->brushq1.numsurfedges || (unsigned int) numedges > (unsigned int) loadmodel->brushq1.numsurfedges || (unsigned int) firstedge + (unsigned int) numedges > (unsigned int) loadmodel->brushq1.numsurfedges)
-                       Host_Error("Mod_Q1BSP_LoadFaces: invalid edge range (firstedge %i, numedges %i, model edges %i)\n", firstedge, numedges, loadmodel->brushq1.numsurfedges);
+                       Host_Error("Mod_Q1BSP_LoadFaces: invalid edge range (firstedge %i, numedges %i, model edges %i)", firstedge, numedges, loadmodel->brushq1.numsurfedges);
                i = LittleShort(in->texinfo);
                if ((unsigned int) i >= (unsigned int) loadmodel->brushq1.numtexinfo)
-                       Host_Error("Mod_Q1BSP_LoadFaces: invalid texinfo index %i(model has %i texinfos)\n", i, loadmodel->brushq1.numtexinfo);
+                       Host_Error("Mod_Q1BSP_LoadFaces: invalid texinfo index %i(model has %i texinfos)", i, loadmodel->brushq1.numtexinfo);
                surface->lightmapinfo->texinfo = loadmodel->brushq1.texinfo + i;
                surface->texture = surface->lightmapinfo->texinfo->texture;
 
                planenum = LittleShort(in->planenum);
                if ((unsigned int) planenum >= (unsigned int) loadmodel->brush.num_planes)
-                       Host_Error("Mod_Q1BSP_LoadFaces: invalid plane index %i (model has %i planes)\n", planenum, loadmodel->brush.num_planes);
+                       Host_Error("Mod_Q1BSP_LoadFaces: invalid plane index %i (model has %i planes)", planenum, loadmodel->brush.num_planes);
 
                //surface->flags = surface->texture->flags;
                //if (LittleShort(in->side))
@@ -2015,7 +2102,7 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l)
                        // give non-lightmapped water a 1x white lightmap
                        if ((surface->texture->basematerialflags & MATERIALFLAG_WATER) && (surface->lightmapinfo->texinfo->flags & TEX_SPECIAL) && ssize <= 256 && tsize <= 256)
                        {
-                               surface->lightmapinfo->samples = (qbyte *)Mem_Alloc(loadmodel->mempool, ssize * tsize * 3);
+                               surface->lightmapinfo->samples = (unsigned char *)Mem_Alloc(loadmodel->mempool, ssize * tsize * 3);
                                surface->lightmapinfo->styles[0] = 0;
                                memset(surface->lightmapinfo->samples, 128, ssize * tsize * 3);
                        }
@@ -2033,7 +2120,7 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l)
                        if (ssize > 256 || tsize > 256)
                                Host_Error("Bad surface extents");
                        // stainmap for permanent marks on walls
-                       surface->lightmapinfo->stainsamples = (qbyte *)Mem_Alloc(loadmodel->mempool, ssize * tsize * 3);
+                       surface->lightmapinfo->stainsamples = (unsigned char *)Mem_Alloc(loadmodel->mempool, ssize * tsize * 3);
                        // clear to white
                        memset(surface->lightmapinfo->stainsamples, 255, ssize * tsize * 3);
 
@@ -2069,7 +2156,7 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l)
 static void Mod_Q1BSP_LoadNodes_RecursiveSetParent(mnode_t *node, mnode_t *parent)
 {
        //if (node->parent)
-       //      Host_Error("Mod_Q1BSP_LoadNodes_RecursiveSetParent: runaway recursion\n");
+       //      Host_Error("Mod_Q1BSP_LoadNodes_RecursiveSetParent: runaway recursion");
        node->parent = parent;
        if (node->plane)
        {
@@ -2219,7 +2306,7 @@ static void Mod_Q1BSP_LoadClipnodes(lump_t *l, hullinfo_t *hullinfo)
                out->children[0] = LittleShort(in->children[0]);
                out->children[1] = LittleShort(in->children[1]);
                if (out->children[0] >= count || out->children[1] >= count)
-                       Host_Error("Corrupt clipping hull(out of range child)\n");
+                       Host_Error("Corrupt clipping hull(out of range child)");
        }
 }
 
@@ -2319,7 +2406,7 @@ static void Mod_Q1BSP_LoadMapBrushes(void)
        char mapfilename[MAX_QPATH];
        FS_StripExtension (loadmodel->name, mapfilename, sizeof (mapfilename));
        strlcat (mapfilename, ".map", sizeof (mapfilename));
-       maptext = (qbyte*) FS_LoadFile(mapfilename, tempmempool, false);
+       maptext = (unsigned char*) FS_LoadFile(mapfilename, tempmempool, false, NULL);
        if (!maptext)
                return;
        text = maptext;
@@ -2466,7 +2553,8 @@ static void Mod_Q1BSP_FinalizePortals(void)
        mvertex_t *point;
        mleaf_t *leaf, *endleaf;
 
-       // recalculate bounding boxes for all leafs(because qbsp is very sloppy)
+       // tally up portal and point counts and recalculate bounding boxes for all
+       // leafs (because qbsp is very sloppy)
        leaf = loadmodel->brush.data_leafs;
        endleaf = leaf + loadmodel->brush.num_leafs;
        for (;leaf < endleaf;leaf++)
@@ -2475,31 +2563,6 @@ static void Mod_Q1BSP_FinalizePortals(void)
                VectorSet(leaf->maxs, -2000000000, -2000000000, -2000000000);
        }
        p = portalchain;
-       while (p)
-       {
-               if (p->numpoints >= 3)
-               {
-                       for (i = 0;i < 2;i++)
-                       {
-                               leaf = (mleaf_t *)p->nodes[i];
-                               for (j = 0;j < p->numpoints;j++)
-                               {
-                                       if (leaf->mins[0] > p->points[j*3+0]) leaf->mins[0] = p->points[j*3+0];
-                                       if (leaf->mins[1] > p->points[j*3+1]) leaf->mins[1] = p->points[j*3+1];
-                                       if (leaf->mins[2] > p->points[j*3+2]) leaf->mins[2] = p->points[j*3+2];
-                                       if (leaf->maxs[0] < p->points[j*3+0]) leaf->maxs[0] = p->points[j*3+0];
-                                       if (leaf->maxs[1] < p->points[j*3+1]) leaf->maxs[1] = p->points[j*3+1];
-                                       if (leaf->maxs[2] < p->points[j*3+2]) leaf->maxs[2] = p->points[j*3+2];
-                               }
-                       }
-               }
-               p = p->chain;
-       }
-
-       Mod_Q1BSP_RecursiveRecalcNodeBBox(loadmodel->brush.data_nodes);
-
-       // tally up portal and point counts
-       p = portalchain;
        numportals = 0;
        numpoints = 0;
        while (p)
@@ -2515,7 +2578,7 @@ static void Mod_Q1BSP_FinalizePortals(void)
        }
        loadmodel->brush.data_portals = (mportal_t *)Mem_Alloc(loadmodel->mempool, numportals * sizeof(mportal_t) + numpoints * sizeof(mvertex_t));
        loadmodel->brush.num_portals = numportals;
-       loadmodel->brush.data_portalpoints = (mvertex_t *)((qbyte *) loadmodel->brush.data_portals + numportals * sizeof(mportal_t));
+       loadmodel->brush.data_portalpoints = (mvertex_t *)((unsigned char *) loadmodel->brush.data_portals + numportals * sizeof(mportal_t));
        loadmodel->brush.num_portalpoints = numpoints;
        // clear all leaf portal chains
        for (i = 0;i < loadmodel->brush.num_leafs;i++)
@@ -2529,59 +2592,78 @@ static void Mod_Q1BSP_FinalizePortals(void)
        {
                pnext = p->chain;
 
-               // note: this check must match the one above or it will usually corrupt memory
-               // the nodes[0] != nodes[1] check is because leaf 0 is the shared solid leaf, it can have many portals inside with leaf 0 on both sides
-               if (p->numpoints >= 3 && p->nodes[0] != p->nodes[1] && ((mleaf_t *)p->nodes[0])->clusterindex >= 0 && ((mleaf_t *)p->nodes[1])->clusterindex >= 0)
+               if (p->numpoints >= 3 && p->nodes[0] != p->nodes[1])
                {
-                       // first make the back to front portal(forward portal)
-                       portal->points = point;
-                       portal->numpoints = p->numpoints;
-                       portal->plane.dist = p->plane.dist;
-                       VectorCopy(p->plane.normal, portal->plane.normal);
-                       portal->here = (mleaf_t *)p->nodes[1];
-                       portal->past = (mleaf_t *)p->nodes[0];
-                       // copy points
-                       for (j = 0;j < portal->numpoints;j++)
+                       // note: this check must match the one above or it will usually corrupt memory
+                       // the nodes[0] != nodes[1] check is because leaf 0 is the shared solid leaf, it can have many portals inside with leaf 0 on both sides
+                       if (((mleaf_t *)p->nodes[0])->clusterindex >= 0 && ((mleaf_t *)p->nodes[1])->clusterindex >= 0)
                        {
-                               VectorCopy(p->points + j*3, point->position);
-                               point++;
+                               // first make the back to front portal(forward portal)
+                               portal->points = point;
+                               portal->numpoints = p->numpoints;
+                               portal->plane.dist = p->plane.dist;
+                               VectorCopy(p->plane.normal, portal->plane.normal);
+                               portal->here = (mleaf_t *)p->nodes[1];
+                               portal->past = (mleaf_t *)p->nodes[0];
+                               // copy points
+                               for (j = 0;j < portal->numpoints;j++)
+                               {
+                                       VectorCopy(p->points + j*3, point->position);
+                                       point++;
+                               }
+                               BoxFromPoints(portal->mins, portal->maxs, portal->numpoints, portal->points->position);
+                               PlaneClassify(&portal->plane);
+
+                               // link into leaf's portal chain
+                               portal->next = portal->here->portals;
+                               portal->here->portals = portal;
+
+                               // advance to next portal
+                               portal++;
+
+                               // then make the front to back portal(backward portal)
+                               portal->points = point;
+                               portal->numpoints = p->numpoints;
+                               portal->plane.dist = -p->plane.dist;
+                               VectorNegate(p->plane.normal, portal->plane.normal);
+                               portal->here = (mleaf_t *)p->nodes[0];
+                               portal->past = (mleaf_t *)p->nodes[1];
+                               // copy points
+                               for (j = portal->numpoints - 1;j >= 0;j--)
+                               {
+                                       VectorCopy(p->points + j*3, point->position);
+                                       point++;
+                               }
+                               BoxFromPoints(portal->mins, portal->maxs, portal->numpoints, portal->points->position);
+                               PlaneClassify(&portal->plane);
+
+                               // link into leaf's portal chain
+                               portal->next = portal->here->portals;
+                               portal->here->portals = portal;
+
+                               // advance to next portal
+                               portal++;
                        }
-                       BoxFromPoints(portal->mins, portal->maxs, portal->numpoints, portal->points->position);
-                       PlaneClassify(&portal->plane);
-
-                       // link into leaf's portal chain
-                       portal->next = portal->here->portals;
-                       portal->here->portals = portal;
-
-                       // advance to next portal
-                       portal++;
-
-                       // then make the front to back portal(backward portal)
-                       portal->points = point;
-                       portal->numpoints = p->numpoints;
-                       portal->plane.dist = -p->plane.dist;
-                       VectorNegate(p->plane.normal, portal->plane.normal);
-                       portal->here = (mleaf_t *)p->nodes[0];
-                       portal->past = (mleaf_t *)p->nodes[1];
-                       // copy points
-                       for (j = portal->numpoints - 1;j >= 0;j--)
+                       // add the portal's polygon points to the leaf bounding boxes
+                       for (i = 0;i < 2;i++)
                        {
-                               VectorCopy(p->points + j*3, point->position);
-                               point++;
+                               leaf = (mleaf_t *)p->nodes[i];
+                               for (j = 0;j < p->numpoints;j++)
+                               {
+                                       if (leaf->mins[0] > p->points[j*3+0]) leaf->mins[0] = p->points[j*3+0];
+                                       if (leaf->mins[1] > p->points[j*3+1]) leaf->mins[1] = p->points[j*3+1];
+                                       if (leaf->mins[2] > p->points[j*3+2]) leaf->mins[2] = p->points[j*3+2];
+                                       if (leaf->maxs[0] < p->points[j*3+0]) leaf->maxs[0] = p->points[j*3+0];
+                                       if (leaf->maxs[1] < p->points[j*3+1]) leaf->maxs[1] = p->points[j*3+1];
+                                       if (leaf->maxs[2] < p->points[j*3+2]) leaf->maxs[2] = p->points[j*3+2];
+                               }
                        }
-                       BoxFromPoints(portal->mins, portal->maxs, portal->numpoints, portal->points->position);
-                       PlaneClassify(&portal->plane);
-
-                       // link into leaf's portal chain
-                       portal->next = portal->here->portals;
-                       portal->here->portals = portal;
-
-                       // advance to next portal
-                       portal++;
                }
                FreePortal(p);
                p = pnext;
        }
+       // now recalculate the node bounding boxes from the leafs
+       Mod_Q1BSP_RecursiveRecalcNodeBBox(loadmodel->brush.data_nodes);
 }
 
 /*
@@ -2818,7 +2900,7 @@ static void Mod_Q1BSP_BuildLightmapUpdateChains(mempool_t *mempool, model_t *mod
        }
        if (!totalcount)
                return;
-       model->brushq1.light_style = (qbyte *)Mem_Alloc(mempool, model->brushq1.light_styles * sizeof(qbyte));
+       model->brushq1.light_style = (unsigned char *)Mem_Alloc(mempool, model->brushq1.light_styles * sizeof(unsigned char));
        model->brushq1.light_stylevalue = (int *)Mem_Alloc(mempool, model->brushq1.light_styles * sizeof(int));
        model->brushq1.light_styleupdatechains = (msurface_t ***)Mem_Alloc(mempool, model->brushq1.light_styles * sizeof(msurface_t **));
        model->brushq1.light_styleupdatechainsbuffer = (msurface_t **)Mem_Alloc(mempool, totalcount * sizeof(msurface_t *));
@@ -2850,7 +2932,7 @@ static void Mod_Q1BSP_BuildLightmapUpdateChains(mempool_t *mempool, model_t *mod
 
 //Returns PVS data for a given point
 //(note: can return NULL)
-static qbyte *Mod_Q1BSP_GetPVS(model_t *model, const vec3_t p)
+static unsigned char *Mod_Q1BSP_GetPVS(model_t *model, const vec3_t p)
 {
        mnode_t *node;
        node = model->brush.data_nodes;
@@ -2862,7 +2944,7 @@ static qbyte *Mod_Q1BSP_GetPVS(model_t *model, const vec3_t p)
                return NULL;
 }
 
-static void Mod_Q1BSP_FatPVS_RecursiveBSPNode(model_t *model, const vec3_t org, vec_t radius, qbyte *pvsbuffer, int pvsbytes, mnode_t *node)
+static void Mod_Q1BSP_FatPVS_RecursiveBSPNode(model_t *model, const vec3_t org, vec_t radius, unsigned char *pvsbuffer, int pvsbytes, mnode_t *node)
 {
        while (node->plane)
        {
@@ -2882,7 +2964,7 @@ static void Mod_Q1BSP_FatPVS_RecursiveBSPNode(model_t *model, const vec3_t org,
        if (((mleaf_t *)node)->clusterindex >= 0)
        {
                int i;
-               qbyte *pvs = model->brush.data_pvsclusters + ((mleaf_t *)node)->clusterindex * model->brush.num_pvsclusterbytes;
+               unsigned char *pvs = model->brush.data_pvsclusters + ((mleaf_t *)node)->clusterindex * model->brush.num_pvsclusterbytes;
                for (i = 0;i < pvsbytes;i++)
                        pvsbuffer[i] |= pvs[i];
        }
@@ -2890,7 +2972,7 @@ static void Mod_Q1BSP_FatPVS_RecursiveBSPNode(model_t *model, const vec3_t org,
 
 //Calculates a PVS that is the inclusive or of all leafs within radius pixels
 //of the given point.
-static int Mod_Q1BSP_FatPVS(model_t *model, const vec3_t org, vec_t radius, qbyte *pvsbuffer, int pvsbufferlength)
+static int Mod_Q1BSP_FatPVS(model_t *model, const vec3_t org, vec_t radius, unsigned char *pvsbuffer, int pvsbufferlength)
 {
        int bytes = model->brush.num_pvsclusterbytes;
        bytes = min(bytes, pvsbufferlength);
@@ -2962,12 +3044,12 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
 
        if (!memcmp (buffer, "MCBSPpad", 8))
        {
-               qbyte   *index;
+               unsigned char   *index;
 
                mod->brush.ismcbsp = true;
                mod->brush.ishlbsp = false;
 
-               mod_base = (qbyte*)buffer;
+               mod_base = (unsigned char*)buffer;
 
                index = mod_base;
                index += 8;
@@ -3035,7 +3117,7 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
                }
 
        // read lumps
-               mod_base = (qbyte*)buffer;
+               mod_base = (unsigned char*)buffer;
                for (i = 0; i < HEADER_LUMPS; i++)
                {
                        header->lumps[i].fileofs = LittleLong(header->lumps[i].fileofs);
@@ -3647,7 +3729,7 @@ void static Mod_Q2BSP_Load(model_t *mod, void *buffer, void *bufferend)
        int i;
        q2dheader_t *header;
 
-       Host_Error("Mod_Q2BSP_Load: not yet implemented\n");
+       Host_Error("Mod_Q2BSP_Load: not yet implemented");
 
        mod->type = mod_brushq2;
 
@@ -3664,7 +3746,7 @@ void static Mod_Q2BSP_Load(model_t *mod, void *buffer, void *bufferend)
                Cvar_SetValue("mcbsp", mod->brush.ismcbsp);
        }
 
-       mod_base = (qbyte *)header;
+       mod_base = (unsigned char *)header;
 
        // swap all the lumps
        for (i = 0;i < (int) sizeof(*header) / 4;i++)
@@ -3774,7 +3856,7 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l)
        {
                for (i = 0;i < search->numfilenames;i++)
                {
-                       if ((f = (char *)FS_LoadFile(search->filenames[i], tempmempool, false)))
+                       if ((f = (char *)FS_LoadFile(search->filenames[i], tempmempool, false, NULL)))
                        {
                                text = f;
                                while (COM_ParseToken(&text, false))
@@ -4079,11 +4161,11 @@ static void Mod_Q3BSP_LoadBrushSides(lump_t *l)
        {
                n = LittleLong(in->planeindex);
                if (n < 0 || n >= loadmodel->brush.num_planes)
-                       Host_Error("Mod_Q3BSP_LoadBrushSides: invalid planeindex %i (%i planes)\n", n, loadmodel->brush.num_planes);
+                       Host_Error("Mod_Q3BSP_LoadBrushSides: invalid planeindex %i (%i planes)", n, loadmodel->brush.num_planes);
                out->plane = loadmodel->brush.data_planes + n;
                n = LittleLong(in->textureindex);
                if (n < 0 || n >= loadmodel->num_textures)
-                       Host_Error("Mod_Q3BSP_LoadBrushSides: invalid textureindex %i (%i textures)\n", n, loadmodel->num_textures);
+                       Host_Error("Mod_Q3BSP_LoadBrushSides: invalid textureindex %i (%i textures)", n, loadmodel->num_textures);
                out->texture = loadmodel->data_textures + n;
        }
 }
@@ -4112,12 +4194,12 @@ static void Mod_Q3BSP_LoadBrushes(lump_t *l)
                n = LittleLong(in->firstbrushside);
                c = LittleLong(in->numbrushsides);
                if (n < 0 || n + c > loadmodel->brush.num_brushsides)
-                       Host_Error("Mod_Q3BSP_LoadBrushes: invalid brushside range %i : %i (%i brushsides)\n", n, n + c, loadmodel->brush.num_brushsides);
+                       Host_Error("Mod_Q3BSP_LoadBrushes: invalid brushside range %i : %i (%i brushsides)", n, n + c, loadmodel->brush.num_brushsides);
                out->firstbrushside = loadmodel->brush.data_brushsides + n;
                out->numbrushsides = c;
                n = LittleLong(in->textureindex);
                if (n < 0 || n >= loadmodel->num_textures)
-                       Host_Error("Mod_Q3BSP_LoadBrushes: invalid textureindex %i (%i textures)\n", n, loadmodel->num_textures);
+                       Host_Error("Mod_Q3BSP_LoadBrushes: invalid textureindex %i (%i textures)", n, loadmodel->num_textures);
                out->texture = loadmodel->data_textures + n;
 
                // make a list of mplane_t structs to construct a colbrush from
@@ -4615,13 +4697,13 @@ static void Mod_Q3BSP_LoadModels(lump_t *l)
                n = LittleLong(in->firstface);
                c = LittleLong(in->numfaces);
                if (n < 0 || n + c > loadmodel->num_surfaces)
-                       Host_Error("Mod_Q3BSP_LoadModels: invalid face range %i : %i (%i faces)\n", n, n + c, loadmodel->num_surfaces);
+                       Host_Error("Mod_Q3BSP_LoadModels: invalid face range %i : %i (%i faces)", n, n + c, loadmodel->num_surfaces);
                out->firstface = n;
                out->numfaces = c;
                n = LittleLong(in->firstbrush);
                c = LittleLong(in->numbrushes);
                if (n < 0 || n + c > loadmodel->brush.num_brushes)
-                       Host_Error("Mod_Q3BSP_LoadModels: invalid brush range %i : %i (%i brushes)\n", n, n + c, loadmodel->brush.num_brushes);
+                       Host_Error("Mod_Q3BSP_LoadModels: invalid brush range %i : %i (%i brushes)", n, n + c, loadmodel->brush.num_brushes);
                out->firstbrush = n;
                out->numbrushes = c;
        }
@@ -4646,7 +4728,7 @@ static void Mod_Q3BSP_LoadLeafBrushes(lump_t *l)
        {
                n = LittleLong(*in);
                if (n < 0 || n >= loadmodel->brush.num_brushes)
-                       Host_Error("Mod_Q3BSP_LoadLeafBrushes: invalid brush index %i (%i brushes)\n", n, loadmodel->brush.num_brushes);
+                       Host_Error("Mod_Q3BSP_LoadLeafBrushes: invalid brush index %i (%i brushes)", n, loadmodel->brush.num_brushes);
                *out = n;
        }
 }
@@ -4670,7 +4752,7 @@ static void Mod_Q3BSP_LoadLeafFaces(lump_t *l)
        {
                n = LittleLong(*in);
                if (n < 0 || n >= loadmodel->num_surfaces)
-                       Host_Error("Mod_Q3BSP_LoadLeafFaces: invalid face index %i (%i faces)\n", n, loadmodel->num_surfaces);
+                       Host_Error("Mod_Q3BSP_LoadLeafFaces: invalid face index %i (%i faces)", n, loadmodel->num_surfaces);
                *out = n;
        }
 }
@@ -4705,13 +4787,13 @@ static void Mod_Q3BSP_LoadLeafs(lump_t *l)
                n = LittleLong(in->firstleafface);
                c = LittleLong(in->numleaffaces);
                if (n < 0 || n + c > loadmodel->brush.num_leafsurfaces)
-                       Host_Error("Mod_Q3BSP_LoadLeafs: invalid leafsurface range %i : %i (%i leafsurfaces)\n", n, n + c, loadmodel->brush.num_leafsurfaces);
+                       Host_Error("Mod_Q3BSP_LoadLeafs: invalid leafsurface range %i : %i (%i leafsurfaces)", n, n + c, loadmodel->brush.num_leafsurfaces);
                out->firstleafsurface = loadmodel->brush.data_leafsurfaces + n;
                out->numleafsurfaces = c;
                n = LittleLong(in->firstleafbrush);
                c = LittleLong(in->numleafbrushes);
                if (n < 0 || n + c > loadmodel->brush.num_leafbrushes)
-                       Host_Error("Mod_Q3BSP_LoadLeafs: invalid leafbrush range %i : %i (%i leafbrushes)\n", n, n + c, loadmodel->brush.num_leafbrushes);
+                       Host_Error("Mod_Q3BSP_LoadLeafs: invalid leafbrush range %i : %i (%i leafbrushes)", n, n + c, loadmodel->brush.num_leafbrushes);
                out->firstleafbrush = loadmodel->brush.data_leafbrushes + n;
                out->numleafbrushes = c;
        }
@@ -4737,7 +4819,7 @@ static void Mod_Q3BSP_LoadNodes(lump_t *l)
                out->parent = NULL;
                n = LittleLong(in->planeindex);
                if (n < 0 || n >= loadmodel->brush.num_planes)
-                       Host_Error("Mod_Q3BSP_LoadNodes: invalid planeindex %i (%i planes)\n", n, loadmodel->brush.num_planes);
+                       Host_Error("Mod_Q3BSP_LoadNodes: invalid planeindex %i (%i planes)", n, loadmodel->brush.num_planes);
                out->plane = loadmodel->brush.data_planes + n;
                for (j = 0;j < 2;j++)
                {
@@ -4745,14 +4827,14 @@ static void Mod_Q3BSP_LoadNodes(lump_t *l)
                        if (n >= 0)
                        {
                                if (n >= loadmodel->brush.num_nodes)
-                                       Host_Error("Mod_Q3BSP_LoadNodes: invalid child node index %i (%i nodes)\n", n, loadmodel->brush.num_nodes);
+                                       Host_Error("Mod_Q3BSP_LoadNodes: invalid child node index %i (%i nodes)", n, loadmodel->brush.num_nodes);
                                out->children[j] = loadmodel->brush.data_nodes + n;
                        }
                        else
                        {
                                n = -1 - n;
                                if (n >= loadmodel->brush.num_leafs)
-                                       Host_Error("Mod_Q3BSP_LoadNodes: invalid child leaf index %i (%i leafs)\n", n, loadmodel->brush.num_leafs);
+                                       Host_Error("Mod_Q3BSP_LoadNodes: invalid child leaf index %i (%i leafs)", n, loadmodel->brush.num_leafs);
                                out->children[j] = (mnode_t *)(loadmodel->brush.data_leafs + n);
                        }
                }
@@ -4797,9 +4879,9 @@ static void Mod_Q3BSP_LoadLightGrid(lump_t *l)
        if (l->filelen)
        {
                if (l->filelen < count * (int)sizeof(*in))
-                       Host_Error("Mod_Q3BSP_LoadLightGrid: invalid lightgrid lump size %i bytes, should be %i bytes (%ix%ix%i)\n", l->filelen, count * sizeof(*in), loadmodel->brushq3.num_lightgrid_dimensions[0], loadmodel->brushq3.num_lightgrid_dimensions[1], loadmodel->brushq3.num_lightgrid_dimensions[2]);
+                       Host_Error("Mod_Q3BSP_LoadLightGrid: invalid lightgrid lump size %i bytes, should be %i bytes (%ix%ix%i)", l->filelen, count * sizeof(*in), loadmodel->brushq3.num_lightgrid_dimensions[0], loadmodel->brushq3.num_lightgrid_dimensions[1], loadmodel->brushq3.num_lightgrid_dimensions[2]);
                if (l->filelen != count * (int)sizeof(*in))
-                       Con_Printf("Mod_Q3BSP_LoadLightGrid: Warning: calculated lightgrid size %i bytes does not match lump size %i\n", count * sizeof(*in), l->filelen);
+                       Con_Printf("Mod_Q3BSP_LoadLightGrid: Warning: calculated lightgrid size %i bytes does not match lump size %i", count * sizeof(*in), l->filelen);
                out = (q3dlightgrid_t *)Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
                loadmodel->brushq3.data_lightgrid = out;
                loadmodel->brushq3.num_lightgrid = count;
@@ -4837,13 +4919,13 @@ static void Mod_Q3BSP_LoadPVS(lump_t *l)
        loadmodel->brush.num_pvsclusters = LittleLong(in->numclusters);
        loadmodel->brush.num_pvsclusterbytes = LittleLong(in->chainlength);
        if (loadmodel->brush.num_pvsclusterbytes < ((loadmodel->brush.num_pvsclusters + 7) / 8))
-               Host_Error("Mod_Q3BSP_LoadPVS: (chainlength = %i) < ((numclusters = %i) + 7) / 8\n", loadmodel->brush.num_pvsclusterbytes, loadmodel->brush.num_pvsclusters);
+               Host_Error("Mod_Q3BSP_LoadPVS: (chainlength = %i) < ((numclusters = %i) + 7) / 8", loadmodel->brush.num_pvsclusterbytes, loadmodel->brush.num_pvsclusters);
        totalchains = loadmodel->brush.num_pvsclusterbytes * loadmodel->brush.num_pvsclusters;
        if (l->filelen < totalchains + (int)sizeof(*in))
-               Host_Error("Mod_Q3BSP_LoadPVS: lump too small ((numclusters = %i) * (chainlength = %i) + sizeof(q3dpvs_t) == %i bytes, lump is %i bytes)\n", loadmodel->brush.num_pvsclusters, loadmodel->brush.num_pvsclusterbytes, totalchains + sizeof(*in), l->filelen);
+               Host_Error("Mod_Q3BSP_LoadPVS: lump too small ((numclusters = %i) * (chainlength = %i) + sizeof(q3dpvs_t) == %i bytes, lump is %i bytes)", loadmodel->brush.num_pvsclusters, loadmodel->brush.num_pvsclusterbytes, totalchains + sizeof(*in), l->filelen);
 
        loadmodel->brush.data_pvsclusters = (unsigned char *)Mem_Alloc(loadmodel->mempool, totalchains);
-       memcpy(loadmodel->brush.data_pvsclusters, (qbyte *)(in + 1), totalchains);
+       memcpy(loadmodel->brush.data_pvsclusters, (unsigned char *)(in + 1), totalchains);
 }
 
 static void Mod_Q3BSP_LightPoint(model_t *model, const vec3_t p, vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal)
@@ -5010,7 +5092,7 @@ static void Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace_t *trace, model_t *model,
 static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, model_t *model, mnode_t *node, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, int markframe, const vec3_t segmentmins, const vec3_t segmentmaxs)
 {
        int i;
-       //int sides;
+       int sides;
        float nodesegmentmins[3], nodesegmentmaxs[3];
        mleaf_t *leaf;
        colbrushf_t *brush;
@@ -5231,6 +5313,57 @@ static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, model_t *model
                }
        */
 #if 1
+       for (;;)
+       {
+               mplane_t *plane = node->plane;
+               if (!plane)
+                       break;
+               // axial planes are much more common than non-axial, so an optimized
+               // axial case pays off here
+               if (plane->type < 3)
+               {
+                       // this is an axial plane, compare bounding box directly to it and
+                       // recurse sides accordingly
+                       // recurse down node sides
+                       // use an inlined axial BoxOnPlaneSide to slightly reduce overhead
+                       //sides = BoxOnPlaneSide(nodesegmentmins, nodesegmentmaxs, plane);
+                       sides = ((segmentmaxs[plane->type] >= plane->dist) | ((segmentmins[plane->type] < plane->dist) << 1));
+                       if (sides == 3)
+                       {
+                               // segment box crosses plane
+                               Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, model, node->children[0], thisbrush_start, thisbrush_end, markframe, segmentmins, segmentmaxs);
+                               sides = 2;
+                       }
+               }
+               else
+               {
+                       // this is a non-axial plane, entire trace bounding box
+                       // comparisons against it are likely to be very sloppy, so in if
+                       // the whole box is split by the plane we then test the start/end
+                       // boxes against it to be sure
+                       sides = BoxOnPlaneSide(segmentmins, segmentmaxs, plane);
+                       if (sides == 3)
+                       {
+                               // segment box crosses plane
+                               // now check start and end brush boxes to handle a lot of 'diagonal' cases more efficiently...
+                               sides = BoxOnPlaneSide(thisbrush_start->mins, thisbrush_start->maxs, plane) | BoxOnPlaneSide(thisbrush_end->mins, thisbrush_end->maxs, plane);
+                               if (sides == 3)
+                               {
+                                       Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, model, node->children[0], thisbrush_start, thisbrush_end, markframe, segmentmins, segmentmaxs);
+                                       sides = 2;
+                               }
+                       }
+               }
+               // take whichever side the segment box is on
+               node = node->children[sides - 1];
+       }
+       nodesegmentmins[0] = max(segmentmins[0], node->mins[0]);
+       nodesegmentmins[1] = max(segmentmins[1], node->mins[1]);
+       nodesegmentmins[2] = max(segmentmins[2], node->mins[2]);
+       nodesegmentmaxs[0] = min(segmentmaxs[0], node->maxs[0]);
+       nodesegmentmaxs[1] = min(segmentmaxs[1], node->maxs[1]);
+       nodesegmentmaxs[2] = min(segmentmaxs[2], node->maxs[2]);
+#elif 1
        for (;;)
        {
                nodesegmentmins[0] = max(segmentmins[0], node->mins[0]);
@@ -5565,7 +5698,7 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer, void *bufferend)
        mod->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        mod->DrawLight = R_Q1BSP_DrawLight;
 
-       mod_base = (qbyte *)header;
+       mod_base = (unsigned char *)header;
 
        // swap all the lumps
        header->ident = LittleLong(header->ident);
@@ -5694,11 +5827,11 @@ void Mod_IBSP_Load(model_t *mod, void *buffer, void *bufferend)
        else if (i == Q2BSPVERSION)
                Mod_Q2BSP_Load(mod,buffer, bufferend);
        else
-               Host_Error("Mod_IBSP_Load: unknown/unsupported version %i\n", i);
+               Host_Error("Mod_IBSP_Load: unknown/unsupported version %i", i);
 }
 
 void Mod_MAP_Load(model_t *mod, void *buffer, void *bufferend)
 {
-       Host_Error("Mod_MAP_Load: not yet implemented\n");
+       Host_Error("Mod_MAP_Load: not yet implemented");
 }