]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/q3map2/bsp.c
another experimental change: better handle leaky maps
[xonotic/netradiant.git] / tools / quake3 / q3map2 / bsp.c
index 2b29ff5ec6a34f5ecebb482faf371fd26b8e2253..a0ddafa47f1b10b03ca43a836085d4bc6d92c8f0 100644 (file)
@@ -44,7 +44,6 @@ functions
 
 ------------------------------------------------------------------------------- */
 
-
 /*
 ProcessAdvertisements()
 copies advertisement info into the BSP structures
@@ -138,7 +137,11 @@ static void SetCloneModelNumbers( void )
                        continue;
                
                /* is this a clone? */
-               value = ValueForKey( &entities[ i ], "_clone" );
+               value = ValueForKey( &entities[ i ], "_ins" );
+               if( value[ 0 ] == '\0' )
+                       value = ValueForKey( &entities[ i ], "_instance" );
+               if( value[ 0 ] == '\0' )
+                       value = ValueForKey( &entities[ i ], "_clone" );
                if( value[ 0 ] != '\0' )
                        continue;
                
@@ -263,7 +266,7 @@ void ProcessWorldModel( void )
        xmlNodePtr      polyline, leaknode;
        char            level[ 2 ], shader[ 1024 ];
        const char      *value;
-       
+       int             leakStatus;
        
        /* sets integer blockSize from worldspawn "_blocksize" key if it exists */
        value = ValueForKey( &entities[ 0 ], "_blocksize" );
@@ -312,48 +315,55 @@ void ProcessWorldModel( void )
        FilterStructuralBrushesIntoTree( e, tree );
        
        /* see if the bsp is completely enclosed */
-       if( FloodEntities( tree ) || ignoreLeaks )
-       {
-               /* rebuild a better bsp tree using only the sides that are visible from the inside */
-               FillOutside( tree->headnode );
+       leakStatus = FloodEntities(tree);
+       if (ignoreLeaks)
+               if(leakStatus == FLOODENTITIES_LEAKED)
+                       leakStatus = FLOODENTITIES_GOOD;
 
-               /* chop the sides to the convex hull of their visible fragments, giving us the smallest polygons */
-               ClipSidesIntoTree( e, tree );
-               
-               /* build a visible face tree */
-               faces = MakeVisibleBSPFaceList( entities[ 0 ].brushes );
-               FreeTree( tree );
-               tree = FaceBSP( faces );
-               MakeTreePortals( tree );
-               FilterStructuralBrushesIntoTree( e, tree );
+       if ( leakStatus == FLOODENTITIES_GOOD )
+       {
                leaked = qfalse;
-               
-               /* ydnar: flood again for skybox */
-               if( skyboxPresent )
-                       FloodEntities( tree );
        }
        else
        {
+               leaked = qtrue;
+
                Sys_FPrintf( SYS_NOXML, "**********************\n" );
                Sys_FPrintf( SYS_NOXML, "******* leaked *******\n" );
                Sys_FPrintf( SYS_NOXML, "**********************\n" );
                polyline = LeakFile( tree );
-               leaknode = xmlNewNode( NULL, "message" );
-               xmlNodeSetContent( leaknode, "MAP LEAKED\n" );
+               leaknode = xmlNewNode( NULL, (xmlChar*)"message" );
+               xmlNodeSetContent( leaknode, (xmlChar*)"MAP LEAKED\n" );
                xmlAddChild( leaknode, polyline );
                level[0] = (int) '0' + SYS_ERR;
                level[1] = 0;
-               xmlSetProp( leaknode, "level", (char*) &level );
+               xmlSetProp( leaknode, (xmlChar*)"level", (xmlChar*) &level );
                xml_SendNode( leaknode );
                if( leaktest )
                {
                        Sys_Printf ("--- MAP LEAKED, ABORTING LEAKTEST ---\n");
                        exit( 0 );
                }
-               leaked = qtrue;
-               
+       }
+
+       if(leakStatus != FLOODENTITIES_EMPTY) /* if no entities exist, this would accidentally the whole map, and that IS bad */
+       {
+               /* rebuild a better bsp tree using only the sides that are visible from the inside */
+               FillOutside( tree->headnode );
+
                /* chop the sides to the convex hull of their visible fragments, giving us the smallest polygons */
                ClipSidesIntoTree( e, tree );
+               
+               /* build a visible face tree (same thing as the initial bsp tree but after reducing the faces) */
+               faces = MakeVisibleBSPFaceList( entities[ 0 ].brushes );
+               FreeTree( tree );
+               tree = FaceBSP( faces );
+               MakeTreePortals( tree );
+               FilterStructuralBrushesIntoTree( e, tree );
+       
+               /* ydnar: flood again for skybox */
+               if( skyboxPresent )
+                       FloodEntities( tree );
        }
        
        /* save out information for visibility processing */
@@ -454,9 +464,16 @@ void ProcessWorldModel( void )
                                else
                                        //%     VectorClear( normal );
                                        VectorSet( normal, 0, 0, -1 );
+
+                               if(colorsRGB)
+                               {
+                                       color[0] = Image_LinearFloatFromsRGBFloat(color[0]);
+                                       color[1] = Image_LinearFloatFromsRGBFloat(color[1]);
+                                       color[2] = Image_LinearFloatFromsRGBFloat(color[2]);
+                               }
                                
                                /* create the flare surface (note shader defaults automatically) */
-                               DrawSurfaceForFlare( mapEntityNum, origin, normal, color, (char*) flareShader, lightStyle );
+                               DrawSurfaceForFlare( mapEntityNum, origin, normal, color, flareShader, lightStyle );
                        }
                }
        }
@@ -601,6 +618,9 @@ void ProcessModels( void )
        
        /* write fogs */
        EmitFogs();
+
+       /* vortex: emit meta stats */
+       EmitMetaStats();
 }
 
 
@@ -614,18 +634,39 @@ void OnlyEnts( void )
 {
        char out[ 1024 ];
 
+       char save_cmdline[1024], save_version[1024], save_gridsize[1024];
+       const char *p;
        
        /* note it */
        Sys_Printf( "--- OnlyEnts ---\n" );
        
        sprintf( out, "%s.bsp", source );
        LoadBSPFile( out );
+
+       ParseEntities();
+       p = ValueForKey(&entities[0], "_q3map2_cmdline");
+       strncpy(save_cmdline, p, sizeof(save_cmdline));
+       save_cmdline[sizeof(save_cmdline)-1] = 0;
+       p = ValueForKey(&entities[0], "_q3map2_version");
+       strncpy(save_version, p, sizeof(save_version));
+       save_version[sizeof(save_version)-1] = 0;
+       p = ValueForKey(&entities[0], "gridsize");
+       strncpy(save_gridsize, p, sizeof(save_gridsize));
+       save_gridsize[sizeof(save_gridsize)-1] = 0;
+
        numEntities = 0;
 
        LoadShaderInfo();
-       LoadMapFile( name, qfalse );
+       LoadMapFile( name, qfalse, qfalse );
        SetModelNumbers();
        SetLightStyles();
+
+       if(*save_cmdline)
+               SetKeyValue(&entities[0], "_q3map2_cmdline", save_cmdline);
+       if(*save_version)
+               SetKeyValue(&entities[0], "_q3map2_version", save_version);
+       if(*save_gridsize)
+               SetKeyValue(&entities[0], "gridsize", save_gridsize);
        
        numBSPEntities = numEntities;
        UnparseEntities();
@@ -656,11 +697,14 @@ int BSPMain( int argc, char **argv )
        numMapDrawSurfs = 0;
        
        tempSource[ 0 ] = '\0';
+       globalCelShader[0] = 0;
        
        /* set standard game flags */
        maxSurfaceVerts = game->maxSurfaceVerts;
        maxSurfaceIndexes = game->maxSurfaceIndexes;
        emitFlares = game->emitFlares;
+       texturesRGB = game->texturesRGB;
+       colorsRGB = game->colorsRGB;
        
        /* process arguments */
        for( i = 1; i < (argc - 1); i++ )
@@ -679,6 +723,11 @@ int BSPMain( int argc, char **argv )
                        Sys_Printf( "Disabling water\n" );
                        nowater = qtrue;
                }
+               else if( !strcmp( argv[ i ], "-keeplights" ))
+               {
+                       keepLights = qtrue;
+                       Sys_Printf( "Leaving light entities on map after compile\n" );
+               }
                else if( !strcmp( argv[ i ],  "-nodetail" ) )
                {
                        Sys_Printf( "Ignoring detail brushes\n") ;
@@ -788,7 +837,7 @@ int BSPMain( int argc, char **argv )
                {
                        npDegrees = atof( argv[ i + 1 ] );
                        if( npDegrees < 0.0f )
-                               shadeAngleDegrees = 0.0f;
+                               npDegrees = 0.0f;
                        else if( npDegrees > 0.0f )
                                Sys_Printf( "Forcing nonplanar surfaces with a breaking angle of %f degrees\n", npDegrees );
                        i++;
@@ -820,11 +869,47 @@ int BSPMain( int argc, char **argv )
                        Sys_Printf( "Flatshading enabled\n" );
                        flat = qtrue;
                }
+               else if( !strcmp( argv[ i ], "-celshader" ) )
+               {
+                       ++i;
+                       if(argv[i][0])
+                               sprintf( globalCelShader, "textures/%s", argv[ i ] );
+                       else
+                               *globalCelShader = 0;
+                       Sys_Printf( "Global cel shader set to \"%s\"\n", globalCelShader );
+               }
                else if( !strcmp( argv[ i ], "-meta" ) )
                {
                        Sys_Printf( "Creating meta surfaces from brush faces\n" );
                        meta = qtrue;
                }
+               else if( !strcmp( argv[ i ], "-metaadequatescore" ) )
+               {
+                       metaAdequateScore = atoi( argv[ i + 1 ]);
+                       if( metaAdequateScore < 0 )
+                               metaAdequateScore = -1;
+                       i++;
+                       if( metaAdequateScore >= 0 )
+                               Sys_Printf( "Setting ADEQUATE meta score to %d (see surface_meta.c)\n", metaAdequateScore );
+               }
+               else if( !strcmp( argv[ i ], "-metagoodscore" ) )
+               {
+                       metaGoodScore = atoi( argv[ i + 1 ]);
+                       if( metaGoodScore < 0 )
+                               metaGoodScore = -1;
+                       i++;
+                       if( metaGoodScore >= 0 )
+                               Sys_Printf( "Setting GOOD meta score to %d (see surface_meta.c)\n", metaGoodScore );
+               }
+               else if( !strcmp( argv[ i ], "-metamaxbboxdistance" ) )
+               {
+                       metaMaxBBoxDistance = atof( argv[ i + 1 ]);
+                       if( metaMaxBBoxDistance < 0 )
+                               metaMaxBBoxDistance = -1;
+                       i++;
+                       if( metaMaxBBoxDistance >= 0 )
+                               Sys_Printf( "Setting meta maximum bounding box distance to %f\n", metaMaxBBoxDistance );
+               }
                else if( !strcmp( argv[ i ], "-patchmeta" ) )
                {
                        Sys_Printf( "Creating meta surfaces from patches\n" );
@@ -860,6 +945,48 @@ int BSPMain( int argc, char **argv )
                        Sys_Printf( "Debug portal surfaces enabled\n" );
                        debugPortals = qtrue;
                }
+               else if( !strcmp( argv[ i ], "-sRGBtex" ) )
+               {
+                       texturesRGB = qtrue;
+                       Sys_Printf( "Textures are in sRGB\n" );
+               }
+               else if( !strcmp( argv[ i ], "-nosRGBtex" ) )
+               {
+                       texturesRGB = qfalse;
+                       Sys_Printf( "Textures are linear\n" );
+               }
+               else if( !strcmp( argv[ i ], "-sRGBcolor" ) )
+               {
+                       colorsRGB = qtrue;
+                       Sys_Printf( "Colors are in sRGB\n" );
+               }
+               else if( !strcmp( argv[ i ], "-nosRGBcolor" ) )
+               {
+                       colorsRGB = qfalse;
+                       Sys_Printf( "Colors are linear\n" );
+               }
+               else if( !strcmp( argv[ i ], "-nosRGB" ) )
+               {
+                       texturesRGB = qfalse;
+                       Sys_Printf( "Textures are linear\n" );
+                       colorsRGB = qfalse;
+                       Sys_Printf( "Colors are linear\n" );
+               }
+               else if( !strcmp( argv[ i ], "-altsplit" ) )
+               {
+                       Sys_Printf( "Alternate BSP splitting (by 27) enabled\n" );
+                       bspAlternateSplitWeights = qtrue;
+               }
+               else if( !strcmp( argv[ i ], "-deep" ) )
+               {
+                       Sys_Printf( "Deep BSP tree generation enabled\n" );
+                       deepBSP = qtrue;
+               }
+               else if( !strcmp( argv[ i ], "-maxarea" ) )
+               {
+                       Sys_Printf( "Max Area face surface generation enabled\n" );
+                       maxAreaFaceSurface = qtrue;
+               }
                else if( !strcmp( argv[ i ], "-bsp" ) )
                        Sys_Printf( "-bsp argument unnecessary\n" );
                else
@@ -909,9 +1036,12 @@ int BSPMain( int argc, char **argv )
        
        /* load original file from temp spot in case it was renamed by the editor on the way in */
        if( strlen( tempSource ) > 0 )
-               LoadMapFile( tempSource, qfalse );
+               LoadMapFile( tempSource, qfalse, qfalse );
        else
-               LoadMapFile( name, qfalse );
+               LoadMapFile( name, qfalse, qfalse );
+       
+       /* div0: inject command line parameters */
+       InjectCommandLine(argv, 1, argc - 1);
        
        /* ydnar: decal setup */
        ProcessDecals();
@@ -929,7 +1059,7 @@ int BSPMain( int argc, char **argv )
        ProcessAdvertisements();
 
        /* finish and write bsp */
-       EndBSPFile();
+       EndBSPFile(qtrue);
        
        /* remove temp map source file if appropriate */
        if( strlen( tempSource ) > 0)