]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/q3map2/map.c
Using Sys_FPrintf with SYS_WRN and SYS_ERR
[xonotic/netradiant.git] / tools / quake3 / q3map2 / map.c
index 9c3041c9b0454965975b3e34653f30f6ceadc566..22fc166fc3773b8a45bfaf444552982fe9bf45f9 100644 (file)
@@ -44,7 +44,7 @@
 #define USE_HASHING
 #define PLANE_HASHES    8192
 
-plane_t                 *planehash[ PLANE_HASHES ];
+int planehash[ PLANE_HASHES ];
 
 int c_boxbevels;
 int c_edgebevels;
@@ -96,7 +96,7 @@ void AddPlaneToHash( plane_t *p ){
        hash = ( PLANE_HASHES - 1 ) & (int) fabs( p->dist );
 
        p->hash_chain = planehash[hash];
-       planehash[hash] = p;
+       planehash[hash] = p - mapplanes + 1;
 }
 
 /*
@@ -113,9 +113,7 @@ int CreateNewFloatPlane( vec3_t normal, vec_t dist ){
        }
 
        // create a new plane
-       if ( nummapplanes + 2 > MAX_MAP_PLANES ) {
-               Error( "MAX_MAP_PLANES" );
-       }
+       AUTOEXPAND_BY_REALLOC( mapplanes, nummapplanes + 1, allocatedmapplanes, 1024 );
 
        p = &mapplanes[nummapplanes];
        VectorCopy( normal, p->normal );
@@ -239,7 +237,7 @@ qboolean SnapNormal( vec3_t normal ){
    snaps a plane to normal/distance epsilons
  */
 
-void SnapPlane( vec3_t normal, vec_t *dist ){
+void SnapPlane( vec3_t normal, vec_t *dist, vec3_t center ){
 // SnapPlane disabled by LordHavoc because it often messes up collision
 // brushes made from triangles of embedded models, and it has little effect
 // on anything else (axial planes are usually derived from snapped points)
@@ -308,22 +306,25 @@ void SnapPlaneImproved( vec3_t normal, vec_t *dist, int numPoints, const vec3_t
 }
 
 
+
 /*
    FindFloatPlane()
    ydnar: changed to allow a number of test points to be supplied that
    must be within an epsilon distance of the plane
  */
 
-int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points )
+int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points ) // NOTE: this has a side effect on the normal. Good or bad?
 
 #ifdef USE_HASHING
 
 {
        int i, j, hash, h;
+       int pidx;
        plane_t *p;
        vec_t d;
+       vec3_t normal;
 
-
+       VectorCopy( innormal, normal );
 #if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX
        SnapPlaneImproved( normal, &dist, numPoints, (const vec3_t *) points );
 #else
@@ -336,8 +337,10 @@ int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points )
        for ( i = -1; i <= 1; i++ )
        {
                h = ( hash + i ) & ( PLANE_HASHES - 1 );
-               for ( p = planehash[ h ]; p != NULL; p = p->hash_chain )
+               for ( pidx = planehash[ h ] - 1; pidx != -1; pidx = mapplanes[pidx].hash_chain - 1 )
                {
+                       p = &mapplanes[pidx];
+
                        /* do standard plane compare */
                        if ( !PlaneEqual( p, normal, dist ) ) {
                                continue;
@@ -354,7 +357,7 @@ int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points )
                                // very small when world coordinates extend to 2^16.  Making the
                                // dot product here in 64 bit land will not really help the situation
                                // because the error will already be carried in dist.
-                               d = DotProduct( points[ j ], normal ) - dist;
+                               d = DotProduct( points[ j ], p->normal ) - p->dist;
                                d = fabs( d );
                                if ( d != 0.0 && d >= distanceEpsilon ) {
                                        break; // Point is too far from plane.
@@ -377,7 +380,9 @@ int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points )
 {
        int i;
        plane_t *p;
+       vec3_t normal;
 
+       VectorCopy( innormal, normal );
 #if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX
        SnapPlaneImproved( normal, &dist, numPoints, (const vec3_t *) points );
 #else
@@ -385,7 +390,24 @@ int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points )
 #endif
        for ( i = 0, p = mapplanes; i < nummapplanes; i++, p++ )
        {
-               if ( PlaneEqual( p, normal, dist ) ) {
+               if ( !PlaneEqual( p, normal, dist ) ) {
+                       continue;
+               }
+
+               /* ydnar: uncomment the following line for old-style plane finding */
+               //%     return i;
+
+               /* ydnar: test supplied points against this plane */
+               for ( j = 0; j < numPoints; j++ )
+               {
+                       d = DotProduct( points[ j ], p->normal ) - p->dist;
+                       if ( fabs( d ) > distanceEpsilon ) {
+                               break;
+                       }
+               }
+
+               /* found a matching plane */
+               if ( j >= numPoints ) {
                        return i;
                }
                // TODO: Note that the non-USE_HASHING code does not compute epsilons
@@ -457,7 +479,7 @@ void SetBrushContents( brush_t *b ){
        int contentFlags, compileFlags;
        side_t      *s;
        int i;
-       qboolean mixed;
+       //%     qboolean        mixed;
 
 
        /* get initial compile flags from first side */
@@ -465,7 +487,7 @@ void SetBrushContents( brush_t *b ){
        contentFlags = s->contentFlags;
        compileFlags = s->compileFlags;
        b->contentShader = s->shaderInfo;
-       mixed = qfalse;
+       //%     mixed = qfalse;
 
        /* get the content/compile flags for every side in the brush */
        for ( i = 1; i < b->numsides; i++, s++ )
@@ -474,9 +496,11 @@ void SetBrushContents( brush_t *b ){
                if ( s->shaderInfo == NULL ) {
                        continue;
                }
-               if ( s->contentFlags != contentFlags || s->compileFlags != compileFlags ) {
-                       mixed = qtrue;
-               }
+               //%     if( s->contentFlags != contentFlags || s->compileFlags != compileFlags )
+               //%             mixed = qtrue;
+
+               contentFlags |= s->contentFlags;
+               compileFlags |= s->compileFlags;
        }
 
        /* ydnar: getting rid of this stupid warning */
@@ -735,7 +759,22 @@ void AddBrushBevels( void ){
    and links it to the current entity
  */
 
-brush_t *FinishBrush( void ){
+static void MergeOrigin( entity_t *ent, vec3_t origin ){
+       vec3_t adjustment;
+       char string[128];
+
+       /* we have not parsed the brush completely yet... */
+       GetVectorForKey( ent, "origin", ent->origin );
+
+       VectorMA( origin, -1, ent->originbrush_origin, adjustment );
+       VectorAdd( adjustment, ent->origin, ent->origin );
+       VectorCopy( origin, ent->originbrush_origin );
+
+       sprintf( string, "%f %f %f", ent->origin[0], ent->origin[1], ent->origin[2] );
+       SetKeyValue( ent, "origin", string );
+}
+
+brush_t *FinishBrush( qboolean noCollapseGroups ){
        brush_t     *b;
 
 
@@ -747,9 +786,11 @@ brush_t *FinishBrush( void ){
        /* origin brushes are removed, but they set the rotation origin for the rest of the brushes in the entity.
           after the entire entity is parsed, the planenums and texinfos will be adjusted for the origin brush */
        if ( buildBrush->compileFlags & C_ORIGIN ) {
-               char string[ 32 ];
                vec3_t origin;
 
+               Sys_Printf( "Entity %i, Brush %i: origin brush detected\n",
+                                       mapEnt->mapEntityNum, entitySourceBrushes );
+
                if ( numEntities == 1 ) {
                        Sys_Printf( "Entity %i, Brush %i: origin brushes not allowed in world\n",
                                                mapEnt->mapEntityNum, entitySourceBrushes );
@@ -759,10 +800,7 @@ brush_t *FinishBrush( void ){
                VectorAdd( buildBrush->mins, buildBrush->maxs, origin );
                VectorScale( origin, 0.5, origin );
 
-               sprintf( string, "%i %i %i", (int) origin[ 0 ], (int) origin[ 1 ], (int) origin[ 2 ] );
-               SetKeyValue( &entities[ numEntities - 1 ], "origin", string );
-
-               VectorCopy( origin, entities[ numEntities - 1 ].origin );
+               MergeOrigin( &entities[ numEntities - 1 ], origin );
 
                /* don't keep this brush */
                return NULL;
@@ -777,7 +815,9 @@ brush_t *FinishBrush( void ){
        }
 
        /* add bevel planes */
-       AddBrushBevels();
+       if ( !noCollapseGroups ) {
+               AddBrushBevels();
+       }
 
        /* keep it */
        b = CopyBrush( buildBrush );
@@ -956,7 +996,7 @@ static void ParseRawBrush( qboolean onlyLights ){
        int planenum;
        shaderInfo_t    *si;
        vec_t shift[ 2 ];
-       vec_t rotate;
+       vec_t rotate = 0;
        vec_t scale[ 2 ];
        char name[ MAX_QPATH ];
        char shader[ MAX_QPATH ];
@@ -1158,10 +1198,7 @@ qboolean RemoveDuplicateBrushPlanes( brush_t *b ){
    parses a brush out of a map file and sets it up
  */
 
-static void ParseBrush( qboolean onlyLights ){
-       brush_t *b;
-
-
+static void ParseBrush( qboolean onlyLights, qboolean noCollapseGroups ){
        /* parse the brush out of the map */
        ParseRawBrush( onlyLights );
 
@@ -1203,7 +1240,7 @@ static void ParseBrush( qboolean onlyLights ){
        }
 
        /* finish the brush */
-       b = FinishBrush();
+       FinishBrush( noCollapseGroups );
 }
 
 
@@ -1215,10 +1252,15 @@ static void ParseBrush( qboolean onlyLights ){
    (used by func_group)
  */
 
+void AdjustBrushesForOrigin( entity_t *ent );
 void MoveBrushesToWorld( entity_t *ent ){
        brush_t     *b, *next;
        parseMesh_t *pm;
 
+       /* we need to undo the common/origin adjustment, and instead shift them by the entity key origin */
+       VectorScale( ent->origin, -1, ent->originbrush_origin );
+       AdjustBrushesForOrigin( ent );
+       VectorClear( ent->originbrush_origin );
 
        /* move brushes */
        for ( b = ent->brushes; b != NULL; b = next )
@@ -1278,7 +1320,6 @@ void AdjustBrushesForOrigin( entity_t *ent ){
        brush_t     *b;
        parseMesh_t *p;
 
-
        /* walk brush list */
        for ( b = ent->brushes; b != NULL; b = b->next )
        {
@@ -1289,7 +1330,7 @@ void AdjustBrushesForOrigin( entity_t *ent ){
                        s = &b->sides[ i ];
 
                        /* offset side plane */
-                       newdist = mapplanes[ s->planenum ].dist - DotProduct( mapplanes[ s->planenum ].normal, ent->origin );
+                       newdist = mapplanes[ s->planenum ].dist - DotProduct( mapplanes[ s->planenum ].normal, ent->originbrush_origin );
 
                        /* find a new plane */
                        s->planenum = FindFloatPlane( mapplanes[ s->planenum ].normal, newdist, 0, NULL );
@@ -1303,7 +1344,7 @@ void AdjustBrushesForOrigin( entity_t *ent ){
        for ( p = ent->patches; p != NULL; p = p->next )
        {
                for ( i = 0; i < ( p->mesh.width * p->mesh.height ); i++ )
-                       VectorSubtract( p->mesh.verts[ i ].xyz, ent->origin, p->mesh.verts[ i ].xyz );
+                       VectorSubtract( p->mesh.verts[ i ].xyz, ent->originbrush_origin, p->mesh.verts[ i ].xyz );
        }
 }
 
@@ -1399,13 +1440,13 @@ void LoadEntityIndexMap( entity_t *e ){
                value = ValueForKey( e, "layers" );
        }
        if ( value[ 0 ] == '\0' ) {
-               Sys_Printf( "WARNING: Entity with index/alpha map \"%s\" has missing \"_layers\" or \"layers\" key\n", indexMapFilename );
+               Sys_FPrintf( SYS_WRN, "WARNING: Entity with index/alpha map \"%s\" has missing \"_layers\" or \"layers\" key\n", indexMapFilename );
                Sys_Printf( "Entity will not be textured properly. Check your keys/values.\n" );
                return;
        }
        numLayers = atoi( value );
        if ( numLayers < 1 ) {
-               Sys_Printf( "WARNING: Entity with index/alpha map \"%s\" has < 1 layer (%d)\n", indexMapFilename, numLayers );
+               Sys_FPrintf( SYS_WRN, "WARNING: Entity with index/alpha map \"%s\" has < 1 layer (%d)\n", indexMapFilename, numLayers );
                Sys_Printf( "Entity will not be textured properly. Check your keys/values.\n" );
                return;
        }
@@ -1416,7 +1457,7 @@ void LoadEntityIndexMap( entity_t *e ){
                value = ValueForKey( e, "shader" );
        }
        if ( value[ 0 ] == '\0' ) {
-               Sys_Printf( "WARNING: Entity with index/alpha map \"%s\" has missing \"_shader\" or \"shader\" key\n", indexMapFilename );
+               Sys_FPrintf( SYS_WRN, "WARNING: Entity with index/alpha map \"%s\" has missing \"_shader\" or \"shader\" key\n", indexMapFilename );
                Sys_Printf( "Entity will not be textured properly. Check your keys/values.\n" );
                return;
        }
@@ -1475,7 +1516,7 @@ void LoadEntityIndexMap( entity_t *e ){
 
        /* the index map must be at least 2x2 pixels */
        if ( w < 2 || h < 2 ) {
-               Sys_Printf( "WARNING: Entity with index/alpha map \"%s\" is smaller than 2x2 pixels\n", indexMapFilename );
+               Sys_FPrintf( SYS_WRN, "WARNING: Entity with index/alpha map \"%s\" is smaller than 2x2 pixels\n", indexMapFilename );
                Sys_Printf( "Entity will not be textured properly. Check your keys/values.\n" );
                free( pixels );
                return;
@@ -1536,10 +1577,11 @@ void LoadEntityIndexMap( entity_t *e ){
    parses a single entity out of a map file
  */
 
-static qboolean ParseMapEntity( qboolean onlyLights ){
+static qboolean ParseMapEntity( qboolean onlyLights, qboolean noCollapseGroups ){
        epair_t         *ep;
        const char      *classname, *value;
-       float lightmapScale;
+       float lightmapScale, shadeAngle;
+       int lightmapSampleSize;
        char shader[ MAX_QPATH ];
        shaderInfo_t    *celShader = NULL;
        brush_t         *brush;
@@ -1555,16 +1597,14 @@ static qboolean ParseMapEntity( qboolean onlyLights ){
 
        /* conformance check */
        if ( strcmp( token, "{" ) ) {
-               Sys_Printf( "WARNING: ParseEntity: { not found, found %s on line %d - last entity was at: <%4.2f, %4.2f, %4.2f>...\n"
+               Sys_FPrintf( SYS_WRN, "WARNING: ParseEntity: { not found, found %s on line %d - last entity was at: <%4.2f, %4.2f, %4.2f>...\n"
                                        "Continuing to process map, but resulting BSP may be invalid.\n",
                                        token, scriptline, entities[ numEntities ].origin[ 0 ], entities[ numEntities ].origin[ 1 ], entities[ numEntities ].origin[ 2 ] );
                return qfalse;
        }
 
        /* range check */
-       if ( numEntities >= MAX_MAP_ENTITIES ) {
-               Error( "numEntities == MAX_MAP_ENTITIES" );
-       }
+       AUTOEXPAND_BY_REALLOC( entities, numEntities, allocatedEntities, 32 );
 
        /* setup */
        entitySourceBrushes = 0;
@@ -1581,7 +1621,7 @@ static qboolean ParseMapEntity( qboolean onlyLights ){
        {
                /* get initial token */
                if ( !GetToken( qtrue ) ) {
-                       Sys_Printf( "WARNING: ParseEntity: EOF without closing brace\n"
+                       Sys_FPrintf( SYS_WRN, "WARNING: ParseEntity: EOF without closing brace\n"
                                                "Continuing to process map, but resulting BSP may be invalid.\n" );
                        return qfalse;
                }
@@ -1603,7 +1643,7 @@ static qboolean ParseMapEntity( qboolean onlyLights ){
                        }
                        else if ( !strcmp( token, "terrainDef" ) ) {
                                //% ParseTerrain();
-                               Sys_Printf( "WARNING: Terrain entity parsing not supported in this build.\n" ); /* ydnar */
+                               Sys_FPrintf( SYS_WRN, "WARNING: Terrain entity parsing not supported in this build.\n" ); /* ydnar */
                        }
                        else if ( !strcmp( token, "brushDef" ) ) {
                                if ( g_bBrushPrimit == BPRIMIT_OLDBRUSHES ) {
@@ -1612,7 +1652,7 @@ static qboolean ParseMapEntity( qboolean onlyLights ){
                                g_bBrushPrimit = BPRIMIT_NEWBRUSHES;
 
                                /* parse brush primitive */
-                               ParseBrush( onlyLights );
+                               ParseBrush( onlyLights, noCollapseGroups );
                        }
                        else
                        {
@@ -1623,7 +1663,7 @@ static qboolean ParseMapEntity( qboolean onlyLights ){
 
                                /* parse old brush format */
                                UnGetToken();
-                               ParseBrush( onlyLights );
+                               ParseBrush( onlyLights, noCollapseGroups );
                        }
                        entitySourceBrushes++;
                }
@@ -1675,21 +1715,27 @@ static qboolean ParseMapEntity( qboolean onlyLights ){
        /* get explicit shadow flags */
        GetEntityShadowFlags( mapEnt, NULL, &castShadows, &recvShadows );
 
+       /* vortex: added _ls key (short name of lightmapscale) */
        /* ydnar: get lightmap scaling value for this entity */
+       lightmapScale = 0.0f;
        if ( strcmp( "", ValueForKey( mapEnt, "lightmapscale" ) ) ||
-                strcmp( "", ValueForKey( mapEnt, "_lightmapscale" ) ) ) {
+                strcmp( "", ValueForKey( mapEnt, "_lightmapscale" ) ) ||
+                strcmp( "", ValueForKey( mapEnt, "_ls" ) ) ) {
                /* get lightmap scale from entity */
                lightmapScale = FloatForKey( mapEnt, "lightmapscale" );
                if ( lightmapScale <= 0.0f ) {
                        lightmapScale = FloatForKey( mapEnt, "_lightmapscale" );
                }
+               if ( lightmapScale <= 0.0f ) {
+                       lightmapScale = FloatForKey( mapEnt, "_ls" );
+               }
+               if ( lightmapScale < 0.0f ) {
+                       lightmapScale = 0.0f;
+               }
                if ( lightmapScale > 0.0f ) {
                        Sys_Printf( "Entity %d (%s) has lightmap scale of %.4f\n", mapEnt->mapEntityNum, classname, lightmapScale );
                }
        }
-       else{
-               lightmapScale = 0.0f;
-       }
 
        /* ydnar: get cel shader :) for this entity */
        value = ValueForKey( mapEnt, "_celshader" );
@@ -1697,12 +1743,59 @@ static qboolean ParseMapEntity( qboolean onlyLights ){
                value = ValueForKey( &entities[ 0 ], "_celshader" );
        }
        if ( value[ 0 ] != '\0' ) {
-               sprintf( shader, "textures/%s", value );
-               celShader = ShaderInfoForShader( shader );
-               Sys_Printf( "Entity %d (%s) has cel shader %s\n", mapEnt->mapEntityNum, classname, celShader->shader );
+               if ( strcmp( value, "none" ) ) {
+                       sprintf( shader, "textures/%s", value );
+                       celShader = ShaderInfoForShader( shader );
+                       Sys_Printf( "Entity %d (%s) has cel shader %s\n", mapEnt->mapEntityNum, classname, celShader->shader );
+               }
+               else
+               {
+                       celShader = NULL;
+               }
        }
        else{
-               celShader = NULL;
+               celShader = ( *globalCelShader ? ShaderInfoForShader( globalCelShader ) : NULL );
+       }
+
+       /* jal : entity based _shadeangle */
+       shadeAngle = 0.0f;
+       if ( strcmp( "", ValueForKey( mapEnt, "_shadeangle" ) ) ) {
+               shadeAngle = FloatForKey( mapEnt, "_shadeangle" );
+       }
+       /* vortex' aliases */
+       else if ( strcmp( "", ValueForKey( mapEnt, "_smoothnormals" ) ) ) {
+               shadeAngle = FloatForKey( mapEnt, "_smoothnormals" );
+       }
+       else if ( strcmp( "", ValueForKey( mapEnt, "_sn" ) ) ) {
+               shadeAngle = FloatForKey( mapEnt, "_sn" );
+       }
+       else if ( strcmp( "", ValueForKey( mapEnt, "_smooth" ) ) ) {
+               shadeAngle = FloatForKey( mapEnt, "_smooth" );
+       }
+
+       if ( shadeAngle < 0.0f ) {
+               shadeAngle = 0.0f;
+       }
+
+       if ( shadeAngle > 0.0f ) {
+               Sys_Printf( "Entity %d (%s) has shading angle of %.4f\n", mapEnt->mapEntityNum, classname, shadeAngle );
+       }
+
+       /* jal : entity based _samplesize */
+       lightmapSampleSize = 0;
+       if ( strcmp( "", ValueForKey( mapEnt, "_lightmapsamplesize" ) ) ) {
+               lightmapSampleSize = IntForKey( mapEnt, "_lightmapsamplesize" );
+       }
+       else if ( strcmp( "", ValueForKey( mapEnt, "_samplesize" ) ) ) {
+               lightmapSampleSize = IntForKey( mapEnt, "_samplesize" );
+       }
+
+       if ( lightmapSampleSize < 0 ) {
+               lightmapSampleSize = 0;
+       }
+
+       if ( lightmapSampleSize > 0 ) {
+               Sys_Printf( "Entity %d (%s) has lightmap sample size of %d\n", mapEnt->mapEntityNum, classname, lightmapSampleSize );
        }
 
        /* attach stuff to everything in the entity */
@@ -1711,8 +1804,10 @@ static qboolean ParseMapEntity( qboolean onlyLights ){
                brush->entityNum = mapEnt->mapEntityNum;
                brush->castShadows = castShadows;
                brush->recvShadows = recvShadows;
+               brush->lightmapSampleSize = lightmapSampleSize;
                brush->lightmapScale = lightmapScale;
                brush->celShader = celShader;
+               brush->shadeAngleDegrees = shadeAngle;
        }
 
        for ( patch = mapEnt->patches; patch != NULL; patch = patch->next )
@@ -1720,6 +1815,7 @@ static qboolean ParseMapEntity( qboolean onlyLights ){
                patch->entityNum = mapEnt->mapEntityNum;
                patch->castShadows = castShadows;
                patch->recvShadows = recvShadows;
+               patch->lightmapSampleSize = lightmapSampleSize;
                patch->lightmapScale = lightmapScale;
                patch->celShader = celShader;
        }
@@ -1732,18 +1828,18 @@ static qboolean ParseMapEntity( qboolean onlyLights ){
 
        /* get entity origin and adjust brushes */
        GetVectorForKey( mapEnt, "origin", mapEnt->origin );
-       if ( mapEnt->origin[ 0 ] || mapEnt->origin[ 1 ] || mapEnt->origin[ 2 ] ) {
+       if ( mapEnt->originbrush_origin[ 0 ] || mapEnt->originbrush_origin[ 1 ] || mapEnt->originbrush_origin[ 2 ] ) {
                AdjustBrushesForOrigin( mapEnt );
        }
 
        /* group_info entities are just for editor grouping (fixme: leak!) */
-       if ( !Q_stricmp( "group_info", classname ) ) {
+       if ( !noCollapseGroups && !Q_stricmp( "group_info", classname ) ) {
                numEntities--;
                return qtrue;
        }
 
        /* group entities are just for editor convenience, toss all brushes into worldspawn */
-       if ( funcGroup ) {
+       if ( !noCollapseGroups && funcGroup ) {
                MoveBrushesToWorld( mapEnt );
                numEntities--;
                return qtrue;
@@ -1760,10 +1856,10 @@ static qboolean ParseMapEntity( qboolean onlyLights ){
    loads a map file into a list of entities
  */
 
-void LoadMapFile( char *filename, qboolean onlyLights ){
+void LoadMapFile( char *filename, qboolean onlyLights, qboolean noCollapseGroups ){
        FILE        *file;
        brush_t     *b;
-       int oldNumEntities, numMapBrushes;
+       int oldNumEntities = 0, numMapBrushes;
 
 
        /* note it */
@@ -1794,7 +1890,7 @@ void LoadMapFile( char *filename, qboolean onlyLights ){
        buildBrush = AllocBrush( MAX_BUILD_SIDES );
 
        /* parse the map file */
-       while ( ParseMapEntity( onlyLights ) ) ;
+       while ( ParseMapEntity( onlyLights, noCollapseGroups ) ) ;
 
        /* light loading */
        if ( onlyLights ) {
@@ -1814,7 +1910,7 @@ void LoadMapFile( char *filename, qboolean onlyLights ){
                /* get brush counts */
                numMapBrushes = CountBrushList( entities[ 0 ].brushes );
                if ( (float) c_detail / (float) numMapBrushes < 0.10f && numMapBrushes > 500 ) {
-                       Sys_Printf( "WARNING: Over 90 percent structural map detected. Compile time may be adversely affected.\n" );
+                       Sys_FPrintf( SYS_WRN, "WARNING: Over 90 percent structural map detected. Compile time may be adversely affected.\n" );
                }
 
                /* emit some statistics */