]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/q3map2/light.c
q3map2: do not leak user temporary paths
[xonotic/netradiant.git] / tools / quake3 / q3map2 / light.c
index a09659795a527a326e7628697a36d20c8881d1fc..bedc3f1770bf603d766d5126a84d5e575fe85418 100644 (file)
@@ -107,8 +107,7 @@ static void CreateSunLight( sun_t *sun ){
 
                /* create a light */
                numSunLights++;
-               light = safe_malloc( sizeof( *light ) );
-               memset( light, 0, sizeof( *light ) );
+               light = safe_malloc0( sizeof( *light ) );
                light->next = lights;
                lights = light;
 
@@ -254,8 +253,7 @@ void CreateEntityLights( void ){
 
                /* create a light */
                numPointLights++;
-               light = safe_malloc( sizeof( *light ) );
-               memset( light, 0, sizeof( *light ) );
+               light = safe_malloc0( sizeof( *light ) );
                light->next = lights;
                lights = light;
 
@@ -442,7 +440,7 @@ void CreateEntityLights( void ){
                        /* get target */
                        e2 = FindTargetEntity( target );
                        if ( e2 == NULL ) {
-                               Sys_Printf( "WARNING: light at (%i %i %i) has missing target\n",
+                               Sys_FPrintf( SYS_WRN, "WARNING: light at (%i %i %i) has missing target\n",
                                                        (int) light->origin[ 0 ], (int) light->origin[ 1 ], (int) light->origin[ 2 ] );
                                light->photons *= pointScale;
                        }
@@ -592,8 +590,7 @@ void CreateSurfaceLights( void ){
                        VectorScale( origin, 0.5f, origin );
 
                        /* create a light */
-                       light = safe_malloc( sizeof( *light ) );
-                       memset( light, 0, sizeof( *light ) );
+                       light = safe_malloc0( sizeof( *light ) );
                        light->next = lights;
                        lights = light;
 
@@ -1159,7 +1156,7 @@ int LightContributionToSample( trace_t *trace ){
                /* return to sender */
                return 1;
        }
-       else{
+       else {
                Error( "Light of undefined type!" );
        }
 
@@ -1774,7 +1771,17 @@ void TraceGrid( int num ){
                        }
 
                /* vortex: apply gridscale and gridambientscale here */
-               ColorToBytes( color, bgp->ambient[ i ], gridScale * gridAmbientScale );
+               if (gp->directed[i][0] || gp->directed[i][1] || gp->directed[i][2]) {
+                       /*
+                        * HACK: if there's a non-zero directed component, this
+                        * lightgrid cell is useful. However, ioq3 skips grid
+                        * cells with zero ambient. So let's force ambient to be
+                        * nonzero unless directed is zero too.
+                        */
+                       ColorToBytesNonZero(color, bgp->ambient[i], gridScale * gridAmbientScale);
+               } else {
+                       ColorToBytes(color, bgp->ambient[i], gridScale * gridAmbientScale);
+               }
                ColorToBytes( gp->directed[ i ], bgp->directed[ i ], gridScale );
        }
 
@@ -1857,14 +1864,12 @@ void SetupGrid( void ){
        numBSPGridPoints = numRawGridPoints;
 
        /* allocate lightgrid */
-       rawGridPoints = safe_malloc( numRawGridPoints * sizeof( *rawGridPoints ) );
-       memset( rawGridPoints, 0, numRawGridPoints * sizeof( *rawGridPoints ) );
+       rawGridPoints = safe_malloc0( numRawGridPoints * sizeof( *rawGridPoints ) );
 
        if ( bspGridPoints != NULL ) {
                free( bspGridPoints );
        }
-       bspGridPoints = safe_malloc( numBSPGridPoints * sizeof( *bspGridPoints ) );
-       memset( bspGridPoints, 0, numBSPGridPoints * sizeof( *bspGridPoints ) );
+       bspGridPoints = safe_malloc0( numBSPGridPoints * sizeof( *bspGridPoints ) );
 
        /* clear lightgrid */
        for ( i = 0; i < numRawGridPoints; i++ )
@@ -1890,14 +1895,13 @@ void SetupGrid( void ){
    does what it says...
  */
 
-void LightWorld( void ){
+void LightWorld( const char *BSPFilePath, qboolean fastLightmapSearch, qboolean noBounceStore ){
        vec3_t color;
        float f;
        int b, bt;
        qboolean minVertex, minGrid;
        const char  *value;
 
-
        /* ydnar: smooth normals */
        if ( shade ) {
                Sys_Printf( "--- SmoothNormals ---\n" );
@@ -1910,14 +1914,15 @@ void LightWorld( void ){
 
        /* find the optional minimum lighting values */
        GetVectorForKey( &entities[ 0 ], "_color", color );
+       if ( VectorLength( color ) == 0.0f ) {
+               VectorSet( color, 1.0, 1.0, 1.0 );
+       }
+
        if ( colorsRGB ) {
                color[0] = Image_LinearFloatFromsRGBFloat( color[0] );
                color[1] = Image_LinearFloatFromsRGBFloat( color[1] );
                color[2] = Image_LinearFloatFromsRGBFloat( color[2] );
        }
-       if ( VectorLength( color ) == 0.0f ) {
-               VectorSet( color, 1.0, 1.0, 1.0 );
-       }
 
        /* ambient */
        f = FloatForKey( &entities[ 0 ], "_ambient" );
@@ -2030,13 +2035,19 @@ void LightWorld( void ){
        /* radiosity */
        b = 1;
        bt = bounce;
+
        while ( bounce > 0 )
        {
+               qboolean storeForReal = !noBounceStore;
+
                /* store off the bsp between bounces */
-               StoreSurfaceLightmaps();
+               StoreSurfaceLightmaps( fastLightmapSearch, storeForReal );
                UnparseEntities();
-               Sys_Printf( "Writing %s\n", source );
-               WriteBSPFile( source );
+
+               if ( storeForReal ) {
+                       Sys_Printf( "Writing %s\n", BSPFilePath );
+                       WriteBSPFile( BSPFilePath );
+               }
 
                /* note it */
                Sys_Printf( "\n--- Radiosity (bounce %d of %d) ---\n", b, bt );
@@ -2054,7 +2065,10 @@ void LightWorld( void ){
                SetupEnvelopes( qfalse, fastbounce );
                if ( numLights == 0 ) {
                        Sys_Printf( "No diffuse light to calculate, ending radiosity.\n" );
-                       break;
+                       if ( noBounceStore ) {
+                               break;
+                       }
+                       return;
                }
 
                /* add to lightgrid */
@@ -2097,6 +2111,29 @@ void LightWorld( void ){
                bounce--;
                b++;
        }
+
+       /* ydnar: store off lightmaps */
+       StoreSurfaceLightmaps( fastLightmapSearch, qtrue );
+}
+
+
+
+/*
+   LoadSurfaceFlags()
+   added by spoon to get back the changed surfaceflags
+   from tex file
+*/
+
+void LoadSurfaceFlags( char *filename ) {
+       int i;
+
+       for( i = 0; i < numBSPShaders; i++ ) {
+               shaderInfo_t *si;
+
+               si = ShaderInfoForShader( bspShaders[i].shader );
+
+               bspShaders[ i ].surfaceFlags = si->surfaceFlags;
+       }
 }
 
 
@@ -2109,11 +2146,15 @@ void LightWorld( void ){
 int LightMain( int argc, char **argv ){
        int i;
        float f;
-       char mapSource[ 1024 ];
+       char BSPFilePath[ 1024 ];
+       char surfaceFilePath[ 1024 ];
+       BSPFilePath[0] = 0;
+       surfaceFilePath[0] = 0;
        const char  *value;
        int lightmapMergeSize = 0;
        qboolean lightSamplesInsist = qfalse;
-
+       qboolean fastLightmapSearch = qfalse;
+       qboolean noBounceStore = qfalse;
 
        /* note it */
        Sys_Printf( "--- Light ---\n" );
@@ -2480,6 +2521,7 @@ int LightMain( int argc, char **argv ){
                        }
                        i++;
                }
+
                else if ( !strcmp( argv[ i ], "-deluxe" ) || !strcmp( argv[ i ], "-deluxemap" ) ) {
                        deluxemap = qtrue;
                        Sys_Printf( "Generating deluxemaps for average light direction\n" );
@@ -2509,7 +2551,7 @@ int LightMain( int argc, char **argv ){
 
                        /* must be a power of 2 and greater than 2 */
                        if ( ( ( lmCustomSize - 1 ) & lmCustomSize ) || lmCustomSize < 2 ) {
-                               Sys_Printf( "WARNING: Lightmap size must be a power of 2, greater or equal to 2 pixels.\n" );
+                               Sys_FPrintf( SYS_WRN, "WARNING: Lightmap size must be a power of 2, greater or equal to 2 pixels.\n" );
                                lmCustomSize = game->lightmapSize;
                        }
                        i++;
@@ -2531,7 +2573,9 @@ int LightMain( int argc, char **argv ){
 
                else if ( !strcmp( argv[ i ], "-lightmapdir" ) ) {
                        lmCustomDir = argv[i + 1];
+                       argv[ i ] = NULL;
                        i++;
+                       argv[ i ] = NULL;
                        Sys_Printf( "Lightmap directory set to %s\n", lmCustomDir );
                        externalLightmaps = qtrue;
                        Sys_Printf( "Storing all lightmaps externally\n" );
@@ -2574,6 +2618,11 @@ int LightMain( int argc, char **argv ){
                        Sys_Printf( "Storing bounced light (radiosity) only\n" );
                }
 
+               else if ( !strcmp( argv[ i ], "-nobouncestore" ) ) {
+                       noBounceStore = qtrue;
+                       Sys_Printf( "Do not store BSP, lightmap and shader files between bounces\n" );
+               }
+
                else if ( !strcmp( argv[ i ], "-nocollapse" ) ) {
                        noCollapse = qtrue;
                        Sys_Printf( "Identical lightmap collapsing disabled\n" );
@@ -2633,6 +2682,17 @@ int LightMain( int argc, char **argv ){
                        Sys_Printf( "Faster mode enabled\n" );
                }
 
+               else if ( !strcmp( argv[ i ], "-fastlightmapsearch" ) || !strcmp( argv[ i ], "-fastallocate") ) {
+                       fastLightmapSearch = qtrue;
+
+                       if ( !strcmp( argv[ i ], "-fastallocate" ) ) {
+                               Sys_Printf( "The -fastallocate argument is deprecated, use \"-fastlightmapsearch\" instead\n" );
+                       }
+                       else {
+                               Sys_Printf( "Fast lightmap search enabled\n" );
+                       }
+               }
+
                else if ( !strcmp( argv[ i ], "-fastgrid" ) ) {
                        fastgrid = qtrue;
                        Sys_Printf( "Fast grid lighting enabled\n" );
@@ -2767,6 +2827,14 @@ int LightMain( int argc, char **argv ){
                        loMem = qtrue;
                        Sys_Printf( "Enabling low-memory (potentially slower) lighting mode\n" );
                }
+               else if ( !strcmp( argv[ i ], "-lightsubdiv" ) ) {
+                       defaultLightSubdivide = atoi( argv[ i + 1 ] );
+                       if ( defaultLightSubdivide < 1 ) {
+                               defaultLightSubdivide = 1;
+                       }
+                       i++;
+                       Sys_Printf( "Default light subdivision set to %d\n", defaultLightSubdivide );
+               }
                else if ( !strcmp( argv[ i ], "-lightanglehl" ) ) {
                        if ( ( atoi( argv[ i + 1 ] ) != 0 ) != lightAngleHL ) {
                                lightAngleHL = ( atoi( argv[ i + 1 ] ) != 0 );
@@ -2777,6 +2845,7 @@ int LightMain( int argc, char **argv ){
                                        Sys_Printf( "Disabling half lambert light angle attenuation\n" );
                                }
                        }
+                       i++;
                }
                else if ( !strcmp( argv[ i ], "-nostyle" ) || !strcmp( argv[ i ], "-nostyles" ) ) {
                        noStyles = qtrue;
@@ -2859,10 +2928,26 @@ int LightMain( int argc, char **argv ){
                        lightmapFill = qtrue;
                        Sys_Printf( "Filling lightmap colors from surrounding pixels to improve JPEG compression\n" );
                }
+               else if ( !strcmp( argv[ i ], "-bspfile" ) )
+               {
+                       strcpy( BSPFilePath, argv[i + 1] );
+                       argv[ i ] = NULL;
+                       i++;
+                       argv[ i ] = NULL;
+                       Sys_Printf( "Use %s as bsp file\n", BSPFilePath );
+               }
+               else if ( !strcmp( argv[ i ], "-srffile" ) )
+               {
+                       strcpy( surfaceFilePath, argv[i + 1] );
+                       argv[ i ] = NULL;
+                       i++;
+                       argv[ i ] = NULL;
+                       Sys_Printf( "Use %s as surface file\n", surfaceFilePath );
+               }
                /* unhandled args */
                else
                {
-                       Sys_Printf( "WARNING: Unknown argument \"%s\"\n", argv[ i ] );
+                       Sys_FPrintf( SYS_WRN, "WARNING: Unknown argument \"%s\"\n", argv[ i ] );
                }
 
        }
@@ -2912,29 +2997,42 @@ int LightMain( int argc, char **argv ){
                Sys_Printf( "Restricted lightmap searching enabled - block size adjusted to %d\n", lightmapSearchBlockSize );
        }
 
-       /* clean up map name */
+       /* arg checking */
+       if ( i != ( argc - 1 ) ) {
+               Error( "usage: q3map -light [options] <bspfile>" );
+       }
+
        strcpy( source, ExpandArg( argv[ i ] ) );
        StripExtension( source );
-       DefaultExtension( source, ".bsp" );
-       strcpy( mapSource, ExpandArg( argv[ i ] ) );
-       StripExtension( mapSource );
-       DefaultExtension( mapSource, ".map" );
+       DefaultExtension( source, ".map" );
+
+       if (!BSPFilePath[0]) {
+               strcpy( BSPFilePath, ExpandArg( argv[ i ] ) );
+               StripExtension( BSPFilePath );
+               DefaultExtension( BSPFilePath, ".bsp" );
+       }
+
+       if (!surfaceFilePath[0]) {
+               strcpy( surfaceFilePath, ExpandArg( argv[ i ] ) );
+               StripExtension( surfaceFilePath );
+               DefaultExtension( surfaceFilePath, ".srf" );
+       }
 
        /* ydnar: set default sample size */
        SetDefaultSampleSize( sampleSize );
 
        /* ydnar: handle shaders */
-       BeginMapShaderFile( source );
+       BeginMapShaderFile( BSPFilePath );
        LoadShaderInfo();
 
        /* note loading */
        Sys_Printf( "Loading %s\n", source );
 
        /* ydnar: load surface file */
-       LoadSurfaceExtraFile( source );
+       LoadSurfaceExtraFile( surfaceFilePath );
 
        /* load bsp file */
-       LoadBSPFile( source );
+       LoadBSPFile( BSPFilePath );
 
        /* parse bsp entities */
        ParseEntities();
@@ -2945,7 +3043,7 @@ int LightMain( int argc, char **argv ){
        /* load map file */
        value = ValueForKey( &entities[ 0 ], "_keepLights" );
        if ( value[ 0 ] != '1' ) {
-               LoadMapFile( mapSource, qtrue, qfalse );
+               LoadMapFile( source, qtrue, qfalse );
        }
 
        /* set the entity/model origins and init yDrawVerts */
@@ -2961,15 +3059,12 @@ int LightMain( int argc, char **argv ){
        SetupTraceNodes();
 
        /* light the world */
-       LightWorld();
-
-       /* ydnar: store off lightmaps */
-       StoreSurfaceLightmaps();
+       LightWorld( BSPFilePath, fastLightmapSearch, noBounceStore );
 
        /* write out the bsp */
        UnparseEntities();
-       Sys_Printf( "Writing %s\n", source );
-       WriteBSPFile( source );
+       Sys_Printf( "Writing %s\n", BSPFilePath );
+       WriteBSPFile( BSPFilePath );
 
        /* ydnar: export lightmaps */
        if ( exportLightmaps && !externalLightmaps ) {