@@ -1442,6 +1442,13 @@ static bool LoadMap( shaderStage_t *stage, const char *buffer )
14421442 return false ;
14431443 }
14441444
1445+ // DarkPlaces compatibility
1446+ // a diffuse maps loaded without stage keyword is a color map
1447+ // backup texture name somewhere, its basename will be needed for extra map lookup
1448+ if ( stage->type == stageType_t::ST_COLORMAP ) {
1449+ strcpy ( stage->textureName , buffer );
1450+ }
1451+
14451452 return true ;
14461453}
14471454
@@ -3100,6 +3107,23 @@ static void ParseLightFalloffImage( shaderStage_t *stage, const char **text )
31003107 }
31013108}
31023109
3110+ struct extraMapParser_t
3111+ {
3112+ const char *suffix;
3113+ const char *description;
3114+ void ( *parser ) ( shaderStage_t*, const char ** );
3115+ };
3116+
3117+ static const extraMapParser_t extraMapParsers[] =
3118+ {
3119+ { " _glow" , " glow map" , ParseGlowMap },
3120+ { " _norm" , " normal map" , ParseNormalMap },
3121+ { " _gloss" , " specular map" , ParseSpecularMap },
3122+ { " _reflect" , " reflection map" , ParseReflectionMap },
3123+ };
3124+
3125+ static int numExtraMapParsers = ARRAY_LEN( extraMapParsers );
3126+
31033127/*
31043128=================
31053129ParseShader
@@ -3111,13 +3135,12 @@ will optimize it.
31113135*/
31123136static bool ParseShader ( const char *_text )
31133137{
3138+ int s;
31143139 const char **text;
31153140 char *token;
3116- int s;
31173141
31183142 s = 0 ;
31193143 text = &_text;
3120-
31213144 token = COM_ParseExt2 ( text, true );
31223145
31233146 if ( token[ 0 ] != ' {' )
@@ -3679,6 +3702,46 @@ static bool ParseShader( const char *_text )
36793702 }
36803703 }
36813704
3705+ // DarkPlaces compatibility
3706+ // It looks for extra maps based on their suffixes.
3707+ int c;
3708+ shaderStage_t colorMapStage;
3709+
3710+ for (c = 0 ; c < s; c++) {
3711+ if ( stages[c].type == stageType_t::ST_COLORMAP && stages[c].textureName != nullptr ) {
3712+ colorMapStage = stages[c];
3713+ break ;
3714+ }
3715+ }
3716+
3717+ if ( colorMapStage.textureName [0 ] != ' \0 ' )
3718+ {
3719+ const char *prefix; // not used but required by R_FindAltImage
3720+ const char *mapName;
3721+ char baseName[ MAX_QPATH ];
3722+
3723+ Log::Debug (" looking for extra maps for color map: '%s'" , colorMapStage.textureName );
3724+ COM_StripExtension3 ( colorMapStage.textureName , baseName, MAX_QPATH );
3725+
3726+ int i;
3727+ for ( i = 0 ; i < numExtraMapParsers; i++ )
3728+ {
3729+ if ( s >= ( MAX_SHADER_STAGES - 1 ) )
3730+ {
3731+ Log::Warn (" too many stages in shader %s" , shader.name );
3732+ return false ;
3733+ }
3734+
3735+ mapName = va ( " %s%s" , baseName, extraMapParsers[i].suffix );
3736+ if ( R_FindAltImage ( (char *) mapName, &prefix ) >= 0 ) {
3737+ Log::Debug (" found implicit %s '%s'" , extraMapParsers[i].description , mapName );
3738+ // colorMapStage.type = stageType_t::ST_DIFFUSEMAP;
3739+ extraMapParsers[i].parser ( &stages[ s ], &mapName );
3740+ s++;
3741+ }
3742+ }
3743+ }
3744+
36823745 // ignore shaders that don't have any stages, unless it is a sky or fog
36833746 if ( s == 0 && !shader.forceOpaque && !shader.isSky && !( shader.contentFlags & CONTENTS_FOG ) && implicitMap[ 0 ] == ' \0 ' )
36843747 {
0 commit comments