]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/q3map2/shaders.c
revert "allocate bigger first"
[xonotic/netradiant.git] / tools / quake3 / q3map2 / shaders.c
index cc58f64b72caad0098638ff53fa0ccd7311f2c5e..75cab6b0d771503ddf24f9d4fa6fe34c40c89085 100644 (file)
@@ -98,21 +98,47 @@ void ColorMod( colorMod_t *cm, int numVerts, bspDrawVert_t *drawVerts ){
                                VectorSet( mult, c, c, c );
                                break;
 
+                       case CM_COLOR_DOT_PRODUCT_SCALE:
+                               c = DotProduct( dv->normal, cm2->data );
+                               c = ( c - cm2->data[3] ) / ( cm2->data[4] - cm2->data[3] );
+                               VectorSet( mult, c, c, c );
+                               break;
+
                        case CM_ALPHA_DOT_PRODUCT:
                                mult[ 3 ] = DotProduct( dv->normal, cm2->data );
                                break;
 
+                       case CM_ALPHA_DOT_PRODUCT_SCALE:
+                               c = DotProduct( dv->normal, cm2->data );
+                               c = ( c - cm2->data[3] ) / ( cm2->data[4] - cm2->data[3] );
+                               mult[ 3 ] = c;
+                               break;
+
                        case CM_COLOR_DOT_PRODUCT_2:
                                c = DotProduct( dv->normal, cm2->data );
                                c *= c;
                                VectorSet( mult, c, c, c );
                                break;
 
+                       case CM_COLOR_DOT_PRODUCT_2_SCALE:
+                               c = DotProduct( dv->normal, cm2->data );
+                               c *= c;
+                               c = ( c - cm2->data[3] ) / ( cm2->data[4] - cm2->data[3] );
+                               VectorSet( mult, c, c, c );
+                               break;
+
                        case CM_ALPHA_DOT_PRODUCT_2:
                                mult[ 3 ] = DotProduct( dv->normal, cm2->data );
                                mult[ 3 ] *= mult[ 3 ];
                                break;
 
+                       case CM_ALPHA_DOT_PRODUCT_2_SCALE:
+                               c = DotProduct( dv->normal, cm2->data );
+                               c *= c;
+                               c = ( c - cm2->data[3] ) / ( cm2->data[4] - cm2->data[3] );
+                               mult[ 3 ] = c;
+                               break;
+
                        default:
                                break;
                        }
@@ -407,7 +433,6 @@ shaderInfo_t *CustomShader( shaderInfo_t *si, char *find, char *replace ){
        char shader[ MAX_QPATH ];
        char            *s;
        int loc;
-       md5_state_t mh;
        byte digest[ 16 ];
        char            *srcShaderText, temp[ 8192 ], shaderText[ 8192 ];   /* ydnar: fixme (make this bigger?) */
 
@@ -527,10 +552,8 @@ shaderInfo_t *CustomShader( shaderInfo_t *si, char *find, char *replace ){
                strcat( shaderText, &srcShaderText[ loc + strlen( find ) ] );
        }
 
-       /* make md5 hash of the shader text */
-       md5_init( &mh );
-       md5_append( &mh, shaderText, strlen( shaderText ) );
-       md5_finish( &mh, digest );
+       /* make md4 hash of the shader text */
+       Com_BlockFullChecksum( shaderText, strlen( shaderText ), digest );
 
        /* mangle hash into a shader name */
        sprintf( shader, "%s/%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", mapName,
@@ -566,7 +589,6 @@ shaderInfo_t *CustomShader( shaderInfo_t *si, char *find, char *replace ){
  */
 
 void EmitVertexRemapShader( char *from, char *to ){
-       md5_state_t mh;
        byte digest[ 16 ];
        char key[ 64 ], value[ 256 ];
 
@@ -580,10 +602,8 @@ void EmitVertexRemapShader( char *from, char *to ){
        /* build value */
        sprintf( value, "%s;%s", from, to );
 
-       /* make md5 hash */
-       md5_init( &mh );
-       md5_append( &mh, value, strlen( value ) );
-       md5_finish( &mh, digest );
+       /* make md4 hash */
+       Com_BlockFullChecksum( value, strlen( value ), digest );
 
        /* make key (this is annoying, as vertexremapshader is precisely 17 characters,
           which is one too long, so we leave off the last byte of the md5 digest) */
@@ -664,7 +684,7 @@ static shaderInfo_t *AllocShaderInfo( void ){
 void FinishShader( shaderInfo_t *si ){
        int x, y;
        float st[ 2 ], o[ 2 ], dist, bestDist;
-       vec4_t color, bestColor, delta;
+       vec4_t color, delta;
 
 
        /* don't double-dip */
@@ -702,8 +722,6 @@ void FinishShader( shaderInfo_t *si ){
                        delta[ 3 ] = color[ 3 ] - si->averageColor[ 3 ];
                        dist = delta[ 0 ] * delta[ 0 ] + delta[ 1 ] * delta[ 1 ] + delta[ 2 ] * delta[ 2 ] + delta[ 3 ] * delta[ 3 ];
                        if ( dist < bestDist ) {
-                               VectorCopy( color, bestColor );
-                               bestColor[ 3 ] = color[ 3 ];
                                si->stFlat[ 0 ] = st[ 0 ];
                                si->stFlat[ 1 ] = st[ 1 ];
                        }
@@ -789,8 +807,12 @@ static void LoadShaderImages( shaderInfo_t *si ){
 
        if ( VectorLength( si->color ) <= 0.0f ) {
                ColorNormalize( color, si->color );
+               VectorScale( color, ( 1.0f / count ), si->averageColor );
+       }
+       else
+       {
+               VectorCopy( si->color, si->averageColor );
        }
-       VectorScale( color, ( 1.0f / count ), si->averageColor );
 }
 
 
@@ -800,12 +822,21 @@ static void LoadShaderImages( shaderInfo_t *si ){
    finds a shaderinfo for a named shader
  */
 
+#define MAX_SHADER_DEPRECATION_DEPTH 16
+
+shaderInfo_t *ShaderInfoForShaderNull( const char *shaderName ){
+       if ( !strcmp( shaderName, "noshader" ) ) {
+               return NULL;
+       }
+       return ShaderInfoForShader( shaderName );
+}
+
 shaderInfo_t *ShaderInfoForShader( const char *shaderName ){
        int i;
+       int deprecationDepth;
        shaderInfo_t    *si;
        char shader[ MAX_QPATH ];
 
-
        /* dummy check */
        if ( shaderName == NULL || shaderName[ 0 ] == '\0' ) {
                Sys_Printf( "WARNING: Null or empty shader name\n" );
@@ -817,10 +848,26 @@ shaderInfo_t *ShaderInfoForShader( const char *shaderName ){
        StripExtension( shader );
 
        /* search for it */
+       deprecationDepth = 0;
        for ( i = 0; i < numShaderInfo; i++ )
        {
                si = &shaderInfo[ i ];
                if ( !Q_stricmp( shader, si->shader ) ) {
+                       /* check if shader is deprecated */
+                       if ( deprecationDepth < MAX_SHADER_DEPRECATION_DEPTH && si->deprecateShader && si->deprecateShader[ 0 ] ) {
+                               /* override name */
+                               strcpy( shader, si->deprecateShader );
+                               StripExtension( shader );
+                               /* increase deprecation depth */
+                               deprecationDepth++;
+                               if ( deprecationDepth == MAX_SHADER_DEPRECATION_DEPTH ) {
+                                       Sys_Printf( "WARNING: Max deprecation depth of %i is reached on shader '%s'\n", MAX_SHADER_DEPRECATION_DEPTH, shader );
+                               }
+                               /* search again from beginning */
+                               i = -1;
+                               continue;
+                       }
+
                        /* load image if necessary */
                        if ( si->finished == qfalse ) {
                                LoadShaderImages( si );
@@ -1248,8 +1295,14 @@ static void ParseShaderFile( const char *filename ){
                                GetTokenAppend( shaderText, qfalse );
                                sun->color[ 2 ] = atof( token );
 
+                               if ( colorsRGB ) {
+                                       sun->color[0] = Image_LinearFloatFromsRGBFloat( sun->color[0] );
+                                       sun->color[1] = Image_LinearFloatFromsRGBFloat( sun->color[1] );
+                                       sun->color[2] = Image_LinearFloatFromsRGBFloat( sun->color[2] );
+                               }
+
                                /* normalize it */
-                               VectorNormalize( sun->color, sun->color );
+                               ColorNormalize( sun->color, sun->color );
 
                                /* scale color by brightness */
                                GetTokenAppend( shaderText, qfalse );
@@ -1328,7 +1381,6 @@ static void ParseShaderFile( const char *filename ){
                                else if ( !Q_stricmp( token, "q3map_surfacemodel" ) ) {
                                        surfaceModel_t  *model;
 
-
                                        /* allocate new model and attach it */
                                        model = safe_malloc( sizeof( *model ) );
                                        memset( model, 0, sizeof( *model ) );
@@ -1433,6 +1485,11 @@ static void ParseShaderFile( const char *filename ){
                                        si->color[ 1 ] = atof( token );
                                        GetTokenAppend( shaderText, qfalse );
                                        si->color[ 2 ] = atof( token );
+                                       if ( colorsRGB ) {
+                                               si->color[0] = Image_LinearFloatFromsRGBFloat( si->color[0] );
+                                               si->color[1] = Image_LinearFloatFromsRGBFloat( si->color[1] );
+                                               si->color[2] = Image_LinearFloatFromsRGBFloat( si->color[2] );
+                                       }
                                        ColorNormalize( si->color, si->color );
                                }
 
@@ -1450,13 +1507,41 @@ static void ParseShaderFile( const char *filename ){
                                        si->backsplashDistance = atof( token );
                                }
 
+                               /* q3map_floodLight <r> <g> <b> <diste> <intensity> <light_direction_power> */
+                               else if ( !Q_stricmp( token, "q3map_floodLight" ) ) {
+                                       /* get color */
+                                       GetTokenAppend( shaderText, qfalse );
+                                       si->floodlightRGB[ 0 ] = atof( token );
+                                       GetTokenAppend( shaderText, qfalse );
+                                       si->floodlightRGB[ 1 ] = atof( token );
+                                       GetTokenAppend( shaderText, qfalse );
+                                       si->floodlightRGB[ 2 ] = atof( token );
+                                       GetTokenAppend( shaderText, qfalse );
+                                       si->floodlightDistance = atof( token );
+                                       GetTokenAppend( shaderText, qfalse );
+                                       si->floodlightIntensity = atof( token );
+                                       GetTokenAppend( shaderText, qfalse );
+                                       si->floodlightDirectionScale = atof( token );
+                                       if ( colorsRGB ) {
+                                               si->floodlightRGB[0] = Image_LinearFloatFromsRGBFloat( si->floodlightRGB[0] );
+                                               si->floodlightRGB[1] = Image_LinearFloatFromsRGBFloat( si->floodlightRGB[1] );
+                                               si->floodlightRGB[2] = Image_LinearFloatFromsRGBFloat( si->floodlightRGB[2] );
+                                       }
+                                       ColorNormalize( si->floodlightRGB, si->floodlightRGB );
+                               }
+
+                               /* jal: q3map_nodirty : skip dirty */
+                               else if ( !Q_stricmp( token, "q3map_nodirty" ) ) {
+                                       si->noDirty = qtrue;
+                               }
+
                                /* q3map_lightmapSampleSize <value> */
                                else if ( !Q_stricmp( token, "q3map_lightmapSampleSize" ) ) {
                                        GetTokenAppend( shaderText, qfalse );
                                        si->lightmapSampleSize = atoi( token );
                                }
 
-                               /* q3map_lightmapSampleSffset <value> */
+                               /* q3map_lightmapSampleOffset <value> */
                                else if ( !Q_stricmp( token, "q3map_lightmapSampleOffset" ) ) {
                                        GetTokenAppend( shaderText, qfalse );
                                        si->lightmapSampleOffset = atof( token );
@@ -1562,13 +1647,23 @@ static void ParseShaderFile( const char *filename ){
                                        }
                                }
 
+                               /* q3map_deprecateShader <shader> */
+                               else if ( !Q_stricmp( token, "q3map_deprecateShader" ) ) {
+                                       GetTokenAppend( shaderText, qfalse );
+                                       if ( token[ 0 ] != '\0' ) {
+
+                                               si->deprecateShader = safe_malloc( strlen( token ) + 1 );
+                                               strcpy( si->deprecateShader, token );
+                                       }
+                               }
+
                                /* ydnar: q3map_offset <value> */
                                else if ( !Q_stricmp( token, "q3map_offset" ) ) {
                                        GetTokenAppend( shaderText, qfalse );
                                        si->offset = atof( token );
                                }
 
-                               /* ydnar: q3map_textureSize <width> <height> (substitute for q3map_lightimage derivation for terrain) */
+                               /* ydnar: q3map_fur <numlayers> <offset> <fade> */
                                else if ( !Q_stricmp( token, "q3map_fur" ) ) {
                                        GetTokenAppend( shaderText, qfalse );
                                        si->furNumLayers = atoi( token );
@@ -1684,6 +1779,11 @@ static void ParseShaderFile( const char *filename ){
                                        else if ( !Q_stricmp( token, "set" ) || !Q_stricmp( token, "const" ) ) {
                                                cm->type = CM_COLOR_SET;
                                                Parse1DMatrixAppend( shaderText, 3, cm->data );
+                                               if ( colorsRGB ) {
+                                                       cm->data[0] = Image_LinearFloatFromsRGBFloat( cm->data[0] );
+                                                       cm->data[1] = Image_LinearFloatFromsRGBFloat( cm->data[1] );
+                                                       cm->data[2] = Image_LinearFloatFromsRGBFloat( cm->data[2] );
+                                               }
                                        }
 
                                        /* alpha scale A */
@@ -1705,12 +1805,24 @@ static void ParseShaderFile( const char *filename ){
                                                Parse1DMatrixAppend( shaderText, 3, cm->data );
                                        }
 
+                                       /* dotProductScale ( X Y Z MIN MAX ) */
+                                       else if ( !Q_stricmp( token, "dotProductScale" ) ) {
+                                               cm->type = CM_COLOR_DOT_PRODUCT_SCALE + alpha;
+                                               Parse1DMatrixAppend( shaderText, 5, cm->data );
+                                       }
+
                                        /* dotProduct2 ( X Y Z ) */
                                        else if ( !Q_stricmp( token, "dotProduct2" ) ) {
                                                cm->type = CM_COLOR_DOT_PRODUCT_2 + alpha;
                                                Parse1DMatrixAppend( shaderText, 3, cm->data );
                                        }
 
+                                       /* dotProduct2scale ( X Y Z MIN MAX ) */
+                                       else if ( !Q_stricmp( token, "dotProduct2scale" ) ) {
+                                               cm->type = CM_COLOR_DOT_PRODUCT_2_SCALE + alpha;
+                                               Parse1DMatrixAppend( shaderText, 5, cm->data );
+                                       }
+
                                        /* volume */
                                        else if ( !Q_stricmp( token, "volume" ) ) {
                                                /* special stub mode for flagging volume brushes */
@@ -1865,13 +1977,15 @@ static void ParseShaderFile( const char *filename ){
                                }
 
                                /* ydnar: default to searching for q3map_<surfaceparm> */
+#if 0
                                else
                                {
-                                       //%     Sys_FPrintf( SYS_VRB, "Attempting to match %s with a known surfaceparm\n", token );
+                                       Sys_FPrintf( SYS_VRB, "Attempting to match %s with a known surfaceparm\n", token );
                                        if ( ApplySurfaceParm( &token[ 6 ], &si->contentFlags, &si->surfaceFlags, &si->compileFlags ) == qfalse ) {
-                                               ; //%   Sys_Printf( "WARNING: Unknown q3map_* directive \"%s\"\n", token );
+                                               Sys_Printf( "WARNING: Unknown q3map_* directive \"%s\"\n", token );
                                        }
                                }
+#endif
                        }