@@ -49,6 +49,14 @@ static cullType_t implicitCullType;
4949
5050static char whenTokens[ MAX_STRING_CHARS ];
5151
52+ // DarkPlaces material compatibility
53+ static Cvar::Cvar<bool > r_dpMaterial (" r_dpMaterial" , " Enable DarkPlaces material compatibility." , Cvar::NONE, false );
54+
55+ static bool UseDpMaterial ()
56+ {
57+ return *r_dpMaterial;
58+ }
59+
5260/*
5361================
5462return a hash value for the filename
@@ -1479,6 +1487,58 @@ static bool ParseClampType( char *token, wrapType_t *clamp )
14791487 return true ;
14801488}
14811489
1490+ /*
1491+ ===================
1492+ FindMapInStage
1493+ ===================
1494+ */
1495+ static bool FindMapInStage ( const char **text, char *buffer, int bufferlen )
1496+ {
1497+ char *token;
1498+ bool foundMap;
1499+
1500+ while ( true )
1501+ {
1502+ token = COM_ParseExt2 ( text, true );
1503+
1504+ if ( token[ 0 ] == ' \0 ' )
1505+ {
1506+ // the real parser will complain about it
1507+ // no need to print twice the same warning
1508+ return false ;
1509+ }
1510+ if ( token[ 0 ] == ' }' )
1511+ {
1512+ break ;
1513+ }
1514+ else if ( !Q_stricmp ( token, " stage" ) )
1515+ {
1516+ return false ;
1517+ }
1518+ else if ( !Q_stricmp ( token, " map" ) )
1519+ {
1520+ if ( !ParseMap ( text, buffer, bufferlen ) )
1521+ {
1522+ return false ;
1523+ }
1524+ foundMap = true ;
1525+ }
1526+ }
1527+
1528+ if ( foundMap )
1529+ {
1530+ if ( buffer[0 ] == ' *'
1531+ || buffer[0 ] == ' _'
1532+ || buffer[0 ] == ' $' )
1533+ {
1534+ return false ;
1535+ }
1536+ return true ;
1537+ }
1538+
1539+ return false ;
1540+ }
1541+
14821542/*
14831543===================
14841544ParseStage
@@ -3100,6 +3160,22 @@ static void ParseLightFalloffImage( shaderStage_t *stage, const char **text )
31003160 }
31013161}
31023162
3163+ struct extraMapParser_t
3164+ {
3165+ const char *suffix;
3166+ const char *description;
3167+ void ( *parser ) ( shaderStage_t*, const char ** );
3168+ };
3169+
3170+ static const extraMapParser_t extraMapParsers[] =
3171+ {
3172+ { " _norm" , " normal map" , ParseNormalMap },
3173+ { " _gloss" , " specular map" , ParseSpecularMap },
3174+ { " _glow" , " glow map" , ParseGlowMap },
3175+ };
3176+
3177+ static int numExtraMapParsers = ARRAY_LEN( extraMapParsers );
3178+
31033179/*
31043180=================
31053181ParseShader
@@ -3144,6 +3220,55 @@ static bool ParseShader( const char *_text )
31443220 // stage definition
31453221 else if ( token[ 0 ] == ' {' )
31463222 {
3223+ if ( UseDpMaterial () )
3224+ {
3225+ // DarkPlaces material compatibility
3226+ // look if the stage to be parsed has a map keyword without a stage keyword
3227+ // look for extra maps based on their suffixes
3228+ // if they exist, load them
3229+ // and tell the stage to be parsed is a diffuseMap one just before parsing it
3230+ const char **safeTextPointer;
3231+ const char *_safeTextPointer;
3232+ _safeTextPointer = *text;
3233+ safeTextPointer = &_safeTextPointer;
3234+
3235+ char colorMapName[ 1024 ] = " " ;
3236+ bool foundMap = FindMapInStage ( safeTextPointer, colorMapName, sizeof ( colorMapName ) );
3237+ if (foundMap) {
3238+ const char *prefix; // not used but required by R_FindImageLoader
3239+ const char *extraMapName;
3240+ char colorMapBaseName[ MAX_QPATH ];
3241+ bool foundExtraMap = false ;
3242+
3243+ Log::Debug ( " looking for extra maps for color map: '%s'" , colorMapName );
3244+ COM_StripExtension3 ( colorMapName, colorMapBaseName, MAX_QPATH );
3245+
3246+ int i;
3247+ for ( i = 0 ; i < numExtraMapParsers; i++ )
3248+ {
3249+ if ( s >= ( MAX_SHADER_STAGES - 1 ) )
3250+ {
3251+ Log::Warn ( " too many extra stages in shader %s" , shader.name );
3252+ return false ;
3253+ }
3254+
3255+ extraMapName = va ( " %s%s" , colorMapBaseName, extraMapParsers[ i ].suffix );
3256+ if ( R_FindImageLoader ( (char *) extraMapName, &prefix ) >= 0 )
3257+ {
3258+ foundExtraMap = true ;
3259+ Log::Debug ( " found extra %s '%s'" , extraMapParsers[ i ].description , extraMapName );
3260+ extraMapParsers[ i ].parser ( &stages[ s ], &extraMapName );
3261+ s++;
3262+ }
3263+ }
3264+
3265+ if ( foundExtraMap )
3266+ {
3267+ stages[ s ].type = stageType_t::ST_DIFFUSEMAP;
3268+ }
3269+ }
3270+ }
3271+
31473272 if ( s >= ( MAX_SHADER_STAGES - 1 ) )
31483273 {
31493274 Log::Warn (" too many stages in shader %s" , shader.name );
0 commit comments