]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_brush.c
no more warping meshs of any kind
[xonotic/darkplaces.git] / model_brush.c
index c4fae28348345e60facc470962d6df5924a5e516..5b7e7dd5979a918c5470921634123cdbf2fda7cf 100644 (file)
@@ -20,14 +20,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "quakedef.h"
 
+// note: model_shared.c sets up r_notexture, and r_surf_notexture
+
 qbyte mod_novis[(MAX_MAP_LEAFS + 7)/ 8];
 
-cvar_t r_subdivide_size = {CVAR_SAVE, "r_subdivide_size", "128"};
+//cvar_t r_subdivide_size = {CVAR_SAVE, "r_subdivide_size", "128"};
 cvar_t halflifebsp = {0, "halflifebsp", "0"};
 cvar_t r_novis = {0, "r_novis", "0"};
 cvar_t r_miplightmaps = {CVAR_SAVE, "r_miplightmaps", "0"};
 cvar_t r_lightmaprgba = {0, "r_lightmaprgba", "1"};
 cvar_t r_vertexsurfacesthreshold = {CVAR_SAVE, "r_vertexsurfacesthreshold", "0"};
+cvar_t r_nosurftextures = {0, "r_nosurftextures", "0"};
+cvar_t r_sortsurfaces = {0, "r_sortsurfaces", "0"};
 
 /*
 ===============
@@ -36,20 +40,17 @@ Mod_BrushInit
 */
 void Mod_BrushInit (void)
 {
-       Cvar_RegisterVariable(&r_subdivide_size);
+//     Cvar_RegisterVariable(&r_subdivide_size);
        Cvar_RegisterVariable(&halflifebsp);
        Cvar_RegisterVariable(&r_novis);
        Cvar_RegisterVariable(&r_miplightmaps);
        Cvar_RegisterVariable(&r_lightmaprgba);
        Cvar_RegisterVariable(&r_vertexsurfacesthreshold);
+       Cvar_RegisterVariable(&r_nosurftextures);
+       Cvar_RegisterVariable(&r_sortsurfaces);
        memset(mod_novis, 0xff, sizeof(mod_novis));
 }
 
-void Mod_Brush_SERAddEntity(void)
-{
-       R_Clip_AddBox(currentrenderentity->mins, currentrenderentity->maxs, R_Entity_Callback, currentrenderentity, NULL);
-}
-
 /*
 ===============
 Mod_PointInLeaf
@@ -127,40 +128,6 @@ qbyte *Mod_LeafPVS (mleaf_t *leaf, model_t *model)
        return Mod_DecompressVis (leaf->compressed_vis, model);
 }
 
-void Mod_SetupNoTexture(void)
-{
-       int x, y;
-       qbyte pix[16][16][4];
-
-       for (y = 0;y < 16;y++)
-       {
-               for (x = 0;x < 16;x++)
-               {
-                       if ((y < 8) ^ (x < 8))
-                       {
-                               pix[y][x][0] = 128;
-                               pix[y][x][1] = 128;
-                               pix[y][x][2] = 128;
-                               pix[y][x][3] = 255;
-                       }
-                       else
-                       {
-                               pix[y][x][0] = 64;
-                               pix[y][x][1] = 64;
-                               pix[y][x][2] = 64;
-                               pix[y][x][3] = 255;
-                       }
-               }
-       }
-
-       memset(&loadmodel->notexture, 0, sizeof(texture_t));
-       strcpy(loadmodel->notexture.name, "notexture");
-       loadmodel->notexture.width = 16;
-       loadmodel->notexture.height = 16;
-       loadmodel->notexture.flags = 0;
-       loadmodel->notexture.texture = R_LoadTexture(loadmodel->texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP);
-}
-
 /*
 =================
 Mod_LoadTextures
@@ -168,36 +135,52 @@ Mod_LoadTextures
 */
 static void Mod_LoadTextures (lump_t *l)
 {
-       int                             i, j, k, num, max, altmax, mtwidth, mtheight, *dofs;
-       miptex_t                *dmiptex;
-       texture_t               *tx, *tx2, *anims[10], *altanims[10];
-       dmiptexlump_t   *m;
-       qbyte                   *data, *mtdata, *data2;
-       char                    name[256];
+       int i, j, k, num, max, altmax, mtwidth, mtheight, *dofs, incomplete;
+       miptex_t *dmiptex;
+       texture_t *tx, *tx2, *anims[10], *altanims[10];
+       dmiptexlump_t *m;
+       qbyte *data, *mtdata, *data2;
+       char name[256];
 
-       Mod_SetupNoTexture();
+       loadmodel->textures = NULL;
 
        if (!l->filelen)
-       {
-               loadmodel->textures = NULL;
                return;
-       }
 
        m = (dmiptexlump_t *)(mod_base + l->fileofs);
 
        m->nummiptex = LittleLong (m->nummiptex);
 
-       loadmodel->numtextures = m->nummiptex;
-       loadmodel->textures = Mem_Alloc(loadmodel->mempool, m->nummiptex * sizeof(*loadmodel->textures));
+       // add two slots for notexture walls and notexture liquids
+       loadmodel->numtextures = m->nummiptex + 2;
+       loadmodel->textures = Mem_Alloc(loadmodel->mempool, loadmodel->numtextures * sizeof(*loadmodel->textures));
+
+       // fill out all slots with notexture
+       for (i = 0;i < loadmodel->numtextures;i++)
+       {
+               loadmodel->textures[i] = tx = Mem_Alloc(loadmodel->mempool, sizeof(texture_t));
+               tx->width = 16;
+               tx->height = 16;
+               tx->texture = r_notexture;
+               if (i == loadmodel->numtextures - 1)
+                       tx->flags = SURF_DRAWTURB | SURF_DRAWFULLBRIGHT | SURF_DRAWNOALPHA | SURF_CLIPSOLID;
+       }
 
        // just to work around bounds checking when debugging with it (array index out of bounds error thing)
        dofs = m->dataofs;
+       // LordHavoc: mostly rewritten map texture loader
        for (i = 0;i < m->nummiptex;i++)
        {
                dofs[i] = LittleLong(dofs[i]);
-               if (dofs[i] == -1)
+               if (dofs[i] == -1 || r_nosurftextures.integer)
                        continue;
                dmiptex = (miptex_t *)((qbyte *)m + dofs[i]);
+
+               // make sure name is no more than 15 characters
+               for (j = 0;dmiptex->name[j] && j < 15;j++)
+                       name[j] = dmiptex->name[j];
+               name[j] = 0;
+
                mtwidth = LittleLong (dmiptex->width);
                mtheight = LittleLong (dmiptex->height);
                mtdata = NULL;
@@ -206,61 +189,59 @@ static void Mod_LoadTextures (lump_t *l)
                {
                        // texture included
                        if (j < 40 || j + mtwidth * mtheight > l->filelen)
-                               Host_Error ("Texture %s is corrupt or incomplete\n", dmiptex->name);
+                       {
+                               Con_Printf ("Texture \"%s\" in \"%s\"is corrupt or incomplete\n", dmiptex->name, loadmodel->name);
+                               continue;
+                       }
                        mtdata = (qbyte *)dmiptex + j;
                }
 
                if ((mtwidth & 15) || (mtheight & 15))
-                       Host_Error ("Texture %s is not 16 aligned", dmiptex->name);
-               // LordHavoc: rewriting the map texture loader for GLQuake
-               tx = Mem_Alloc(loadmodel->mempool, sizeof(texture_t));
-               memset(tx, 0, sizeof(texture_t));
-               tx->anim_total = 0;
-               tx->alternate_anims = NULL;
-               loadmodel->textures[i] = tx;
-
-               // LordHavoc: force all names to lowercase and make sure they are terminated while copying
-               for (j = 0;dmiptex->name[j] && j < 15;j++)
-               {
-                       if (dmiptex->name[j] >= 'A' && dmiptex->name[j] <= 'Z')
-                               tx->name[j] = dmiptex->name[j] + ('a' - 'A');
-                       else
-                               tx->name[j] = dmiptex->name[j];
-               }
-               for (;j < 16;j++)
-                       tx->name[j] = 0;
+                       Con_Printf ("warning: texture \"%s\" in \"%s\" is not 16 aligned", dmiptex->name, loadmodel->name);
 
-               if (!tx->name[0])
-               {
-                       Con_Printf("warning: unnamed texture in %s\n", loadmodel->name);
-                       sprintf(tx->name, "unnamed%i", i);
-               }
+               // LordHavoc: force all names to lowercase
+               for (j = 0;name[j];j++)
+                       if (name[j] >= 'A' && name[j] <= 'Z')
+                               name[j] += 'a' - 'A';
 
+               tx = loadmodel->textures[i];
+               strcpy(tx->name, name);
                tx->width = mtwidth;
                tx->height = mtheight;
                tx->texture = NULL;
                tx->glowtexture = NULL;
                tx->fogtexture = NULL;
 
-               if (!loadmodel->ishlbsp && !strncmp(tx->name,"sky",3) && mtwidth == 256 && mtheight == 128) // LordHavoc: HL sky textures are entirely unrelated
+               if (!tx->name[0])
                {
-                       data = loadimagepixels(tx->name, false, 0, 0);
-                       if (data)
+                       sprintf(tx->name, "unnamed%i", i);
+                       Con_Printf("warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, tx->name);
+               }
+
+               // LordHavoc: HL sky textures are entirely different than quake
+               if (!loadmodel->ishlbsp && !strncmp(tx->name, "sky", 3) && mtwidth == 256 && mtheight == 128)
+               {
+                       if (loadmodel->isworldmodel)
                        {
-                               if (image_width == 256 && image_height == 128)
-                               {
-                                       if (loadmodel->isworldmodel)
-                                               R_InitSky (data, 4);
-                                       Mem_Free(data);
-                               }
-                               else
+                               data = loadimagepixels(tx->name, false, 0, 0);
+                               if (data)
                                {
-                                       Mem_Free(data);
-                                       Host_Error("Mod_LoadTextures: replacement sky image must be 256x128 pixels\n");
+                                       if (image_width == 256 && image_height == 128)
+                                       {
+                                               R_InitSky (data, 4);
+                                               Mem_Free(data);
+                                       }
+                                       else
+                                       {
+                                               Mem_Free(data);
+                                               Con_Printf ("Invalid replacement texture for sky \"%s\" in %\"%s\", must be 256x128 pixels\n", tx->name, loadmodel->name);
+                                               if (mtdata != NULL)
+                                                       R_InitSky (mtdata, 1);
+                                       }
                                }
+                               else if (mtdata != NULL)
+                                       R_InitSky (mtdata, 1);
                        }
-                       else if (loadmodel->isworldmodel)
-                               R_InitSky (mtdata, 1);
                }
                else if ((tx->texture = loadtextureimagewithmask(loadmodel->texturepool, tx->name, 0, 0, false, true, true)))
                {
@@ -309,7 +290,7 @@ static void Mod_LoadTextures (lump_t *l)
                                {
                                        tx->width = 16;
                                        tx->height = 16;
-                                       tx->texture = loadmodel->notexture.texture;
+                                       tx->texture = r_notexture;
                                }
                        }
                        else
@@ -350,7 +331,7 @@ static void Mod_LoadTextures (lump_t *l)
                                {
                                        tx->width = 16;
                                        tx->height = 16;
-                                       tx->texture = loadmodel->notexture.texture;
+                                       tx->texture = r_notexture;
                                }
                        }
                }
@@ -374,21 +355,18 @@ static void Mod_LoadTextures (lump_t *l)
                }
        }
 
-//
-// sequence the animations
-//
+       // sequence the animations
        for (i = 0;i < m->nummiptex;i++)
        {
                tx = loadmodel->textures[i];
-               if (!tx || tx->name[0] != '+')
+               if (!tx || tx->name[0] != '+' || tx->name[1] == 0 || tx->name[2] == 0)
                        continue;
-               if (tx->anim_total)
+               if (tx->anim_total[0] || tx->anim_total[1])
                        continue;       // already sequenced
 
                // find the number of frames in the animation
                memset (anims, 0, sizeof(anims));
                memset (altanims, 0, sizeof(altanims));
-               max = altmax = 0;
 
                for (j = i;j < m->nummiptex;j++)
                {
@@ -402,38 +380,79 @@ static void Mod_LoadTextures (lump_t *l)
                        else if (num >= 'a' && num <= 'j')
                                altanims[num - 'a'] = tx2;
                        else
-                               Host_Error ("Bad animating texture %s", tx->name);
+                               Con_Printf ("Bad animating texture %s\n", tx->name);
                }
 
+               max = altmax = 0;
                for (j = 0;j < 10;j++)
                {
-                       if (anims[j] != NULL)
+                       if (anims[j])
                                max = j + 1;
-                       if (altanims[j] != NULL)
+                       if (altanims[j])
                                altmax = j + 1;
                }
+               //Con_Printf("linking animation %s (%i:%i frames)\n\n", tx->name, max, altmax);
 
-               // link them all together
+               incomplete = false;
                for (j = 0;j < max;j++)
                {
-                       tx2 = anims[j];
-                       if (!tx2)
-                               Host_Error ("Missing frame %i of %s", j, tx->name);
-                       tx2->anim_total = max;
-                       tx2->alternate_anims = altanims[0]; // NULL if there is no alternate
+                       if (!anims[j])
+                       {
+                               Con_Printf ("Missing frame %i of %s\n", j, tx->name);
+                               incomplete = true;
+                       }
+               }
+               for (j = 0;j < altmax;j++)
+               {
+                       if (!altanims[j])
+                       {
+                               Con_Printf ("Missing altframe %i of %s\n", j, tx->name);
+                               incomplete = true;
+                       }
+               }
+               if (incomplete)
+                       continue;
+
+               if (altmax < 1)
+               {
+                       // if there is no alternate animation, duplicate the primary
+                       // animation into the alternate
+                       altmax = max;
                        for (k = 0;k < 10;k++)
-                               tx2->anim_frames[k] = anims[k];
+                               altanims[k] = anims[k];
                }
 
-               for (j = 0;j < altmax;j++)
+               // link together the primary animation
+               for (j = 0;j < max;j++)
                {
-                       tx2 = altanims[j];
-                       if (!tx2)
-                               Host_Error ("Missing frame %i of %s", j, tx->name);
-                       tx2->anim_total = altmax;
-                       tx2->alternate_anims = anims[0]; // NULL if there is no alternate
+                       tx2 = anims[j];
+                       tx2->animated = true;
+                       tx2->anim_total[0] = max;
+                       tx2->anim_total[1] = altmax;
                        for (k = 0;k < 10;k++)
-                               tx2->anim_frames[k] = altanims[k];
+                       {
+                               tx2->anim_frames[0][k] = anims[k];
+                               tx2->anim_frames[1][k] = altanims[k];
+                       }
+               }
+
+               // if there really is an alternate anim...
+               if (anims[0] != altanims[0])
+               {
+                       // link together the alternate animation
+                       for (j = 0;j < altmax;j++)
+                       {
+                               tx2 = altanims[j];
+                               tx2->animated = true;
+                               // the primary/alternate are reversed here
+                               tx2->anim_total[0] = altmax;
+                               tx2->anim_total[1] = max;
+                               for (k = 0;k < 10;k++)
+                               {
+                                       tx2->anim_frames[0][k] = altanims[k];
+                                       tx2->anim_frames[1][k] = anims[k];
+                               }
+                       }
                }
        }
 }
@@ -574,11 +593,9 @@ Mod_LoadVisibility
 */
 static void Mod_LoadVisibility (lump_t *l)
 {
+       loadmodel->visdata = NULL;
        if (!l->filelen)
-       {
-               loadmodel->visdata = NULL;
                return;
-       }
        loadmodel->visdata = Mem_Alloc(loadmodel->mempool, l->filelen);
        memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen);
 }
@@ -653,11 +670,9 @@ Mod_LoadEntities
 */
 static void Mod_LoadEntities (lump_t *l)
 {
+       loadmodel->entities = NULL;
        if (!l->filelen)
-       {
-               loadmodel->entities = NULL;
                return;
-       }
        loadmodel->entities = Mem_Alloc(loadmodel->mempool, l->filelen);
        memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen);
        if (loadmodel->ishlbsp)
@@ -766,8 +781,7 @@ static void Mod_LoadTexinfo (lump_t *l)
 {
        texinfo_t *in;
        mtexinfo_t *out;
-       int     i, j, k, count;
-       int             miptex;
+       int i, j, k, count, miptex;
 
        in = (void *)(mod_base + l->fileofs);
        if (l->filelen % sizeof(*in))
@@ -787,18 +801,22 @@ static void Mod_LoadTexinfo (lump_t *l)
                miptex = LittleLong (in->miptex);
                out->flags = LittleLong (in->flags);
 
-               if (!loadmodel->textures)
-                       out->texture = &loadmodel->notexture;
-               else
+               out->texture = NULL;
+               if (loadmodel->textures)
                {
-                       if (miptex < 0)
-                               Host_Error ("miptex < 0");
-                       if (miptex >= loadmodel->numtextures)
-                               Host_Error ("miptex >= loadmodel->numtextures");
-                       out->texture = loadmodel->textures[miptex];
+                       if ((unsigned int) miptex >= (unsigned int) loadmodel->numtextures)
+                               Con_Printf ("error in model \"%s\": invalid miptex index %i (of %i)\n", loadmodel->name, miptex, loadmodel->numtextures);
+                       else
+                               out->texture = loadmodel->textures[miptex];
+               }
+               if (out->texture == NULL)
+               {
+                       // choose either the liquid notexture, or the normal notexture
+                       if (out->flags & TEX_SPECIAL)
+                               out->texture = loadmodel->textures[loadmodel->numtextures - 1];
+                       else
+                               out->texture = loadmodel->textures[loadmodel->numtextures - 2];
                }
-               if (!out->texture)
-                       out->texture = &loadmodel->notexture;
        }
 }
 
@@ -874,6 +892,7 @@ void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs)
        }
 }
 
+#if 0
 #define MAX_SUBDIVPOLYTRIANGLES 4096
 #define MAX_SUBDIVPOLYVERTS (MAX_SUBDIVPOLYTRIANGLES * 3)
 
@@ -981,9 +1000,9 @@ can be done reasonably.
 */
 void Mod_GenerateWarpMesh (msurface_t *surf)
 {
-       int                             i, j;
-       surfvertex_t    *v;
-       surfmesh_t              *mesh;
+       int i, j;
+       surfvertex_t *v;
+       surfmesh_t *mesh;
 
        subdivpolytriangles = 0;
        subdivpolyverts = 0;
@@ -1009,6 +1028,7 @@ void Mod_GenerateWarpMesh (msurface_t *surf)
                v->st[1] = DotProduct (v->v, surf->texinfo->vecs[1]);
        }
 }
+#endif
 
 void Mod_GenerateVertexLitMesh (msurface_t *surf)
 {
@@ -1076,12 +1096,12 @@ void Mod_GenerateLightmappedMesh (msurface_t *surf)
        if (r_miplightmaps.integer)
        {
                surf->lightmaptexturestride = (surf->extents[0]>>4)+1;
-               surf->lightmaptexture = R_ProceduralTexture(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_MIPMAP | TEXF_PRECACHE, NULL, NULL, 0);
+               surf->lightmaptexture = R_LoadTexture(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_MIPMAP | TEXF_PRECACHE);
        }
        else
        {
                surf->lightmaptexturestride = R_CompatibleFragmentWidth((surf->extents[0]>>4)+1, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, 0);
-               surf->lightmaptexture = R_ProceduralTexture(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_FRAGMENT | TEXF_PRECACHE, NULL, NULL, 0);
+               surf->lightmaptexture = R_LoadTexture(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_FRAGMENT | TEXF_PRECACHE);
        }
        R_FragmentLocation(surf->lightmaptexture, NULL, NULL, &xbase, &ybase, &xscale, &yscale);
        xscale = (xscale - xbase) * 16.0 / ((surf->extents[0] & ~15) + 16);
@@ -1239,9 +1259,9 @@ Mod_LoadFaces
 */
 static void Mod_LoadFaces (lump_t *l)
 {
-       dface_t         *in;
+       dface_t *in;
        msurface_t      *out;
-       int                     i, count, surfnum, planenum, side, ssize, tsize;
+       int i, count, surfnum, planenum, ssize, tsize;
 
        in = (void *)(mod_base + l->fileofs);
        if (l->filelen % sizeof(*in))
@@ -1257,13 +1277,20 @@ static void Mod_LoadFaces (lump_t *l)
                // FIXME: validate edges, texinfo, etc?
                out->firstedge = LittleLong(in->firstedge);
                out->numedges = LittleShort(in->numedges);
+               if ((unsigned int) out->firstedge + (unsigned int) out->numedges > (unsigned int) loadmodel->numsurfedges)
+                       Host_Error("Mod_LoadFaces: invalid edge range (firstedge %i, numedges %i, model edges %i)\n", out->firstedge, out->numedges, loadmodel->numsurfedges);
 
-               out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo);
+               i = LittleShort (in->texinfo);
+               if ((unsigned int) i >= (unsigned int) loadmodel->numtexinfo)
+                       Host_Error("Mod_LoadFaces: invalid texinfo index %i (model has %i texinfos)\n", i, loadmodel->numtexinfo);
+               out->texinfo = loadmodel->texinfo + i;
                out->flags = out->texinfo->texture->flags;
 
                planenum = LittleShort(in->planenum);
-               side = LittleShort(in->side);
-               if (side)
+               if ((unsigned int) planenum >= (unsigned int) loadmodel->numplanes)
+                       Host_Error("Mod_LoadFaces: invalid plane index %i (model has %i planes)\n", planenum, loadmodel->numplanes);
+
+               if (LittleShort(in->side))
                        out->flags |= SURF_PLANEBACK;
 
                out->plane = loadmodel->planes + planenum;
@@ -1298,13 +1325,13 @@ static void Mod_LoadFaces (lump_t *l)
                {
                        out->shader = &Cshader_sky;
                        out->samples = NULL;
-                       Mod_GenerateWarpMesh (out);
+                       Mod_GenerateVertexMesh (out);
                }
                else if (out->texinfo->texture->flags & SURF_DRAWTURB)
                {
                        out->shader = &Cshader_water;
                        out->samples = NULL;
-                       Mod_GenerateWarpMesh (out);
+                       Mod_GenerateVertexMesh (out);
                }
                else
                {
@@ -1316,9 +1343,9 @@ static void Mod_LoadFaces (lump_t *l)
                                out->shader = &Cshader_water;
                                out->shader = &Cshader_water;
                                out->samples = NULL;
-                               Mod_GenerateWarpMesh (out);
+                               Mod_GenerateVertexMesh (out);
                        }
-                       else if ((out->extents[0]+1) > (256*16) || (out->extents[1]+1) > (256*16))
+                       else if ((out->extents[0] >> 4) + 1 > (256) || (out->extents[1] >> 4) + 1 > (256))
                        {
                                Con_Printf ("Bad surface extents, converting to fullbright polygon");
                                out->shader = &Cshader_wall_fullbright;
@@ -1369,7 +1396,8 @@ static void Mod_BrushSortedSurfaces(model_t *model, mempool_t *pool)
        for (surfnum = 0;surfnum < sortmodel->nummodelsurfaces;surfnum++)
                sortmodel->modelsortedsurfaces[surfnum] = &sortmodel->surfaces[surfnum + sortmodel->firstmodelsurface];
 
-       qsort(sortmodel->modelsortedsurfaces, sortmodel->nummodelsurfaces, sizeof(msurface_t *), Mod_SurfaceQSortCompare);
+       if (r_sortsurfaces.integer)
+               qsort(sortmodel->modelsortedsurfaces, sortmodel->nummodelsurfaces, sizeof(msurface_t *), Mod_SurfaceQSortCompare);
 }
 
 
@@ -2377,7 +2405,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
 
        i = LittleLong (header->version);
        if (i != BSPVERSION && i != 30)
-               Host_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i or 30 (HalfLife))", mod->name, i, BSPVERSION);
+               Host_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i (Quake) or 30 (HalfLife))", mod->name, i, BSPVERSION);
        mod->ishlbsp = i == 30;
        if (loadmodel->isworldmodel)
                Cvar_SetValue("halflifebsp", mod->ishlbsp);
@@ -2494,7 +2522,6 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
 
                mod->numleafs = bm->visleafs;
 
-               mod->SERAddEntity = Mod_Brush_SERAddEntity;
                mod->Draw = R_DrawBrushModelNormal;
                mod->DrawShadow = NULL;