* support entries with .shader extension in shaderlist.txt

vfsListShaderFiles (empty shaderlist = load all shaders, -pk3, -repack):
	only list pk3 .shaders from scripts/ folder
	support non scripts/ shaderPath (e.g. jka)
unlimit shader files count
case insensitive shaderlist entries, so duplicates aren't loaded twice
This commit is contained in:
Garux 2021-08-12 11:23:59 +03:00
parent aa5de2fee9
commit 4beae3d362
5 changed files with 62 additions and 89 deletions

View File

@ -1583,7 +1583,9 @@ void BuildShaderList( TextInputStream& shaderlist ){
while ( token != 0 ) while ( token != 0 )
{ {
// each token should be a shader filename // each token should be a shader filename
shaderFile << token << "." << g_shadersExtension; shaderFile << token;
if( !string_equal_nocase( path_get_extension( token ), g_shadersExtension ) )
shaderFile << "." << g_shadersExtension;
ShaderList_addShaderFile( shaderFile.c_str() ); ShaderList_addShaderFile( shaderFile.c_str() );

View File

@ -206,33 +206,41 @@ void vfsInitDirectory( const char *path ){
} }
// lists all .shader files // lists all unique .shader files with extension and w/o path
void vfsListShaderFiles( StrList* list, void pushStringCallback( StrList* list, const char* string ) ){ std::vector<CopiedString> vfsListShaderFiles( const char *shaderPath ){
std::vector<CopiedString> list;
const auto insert = [&list]( const char *name ){
for( const CopiedString& str : list )
if( striEqual( str.c_str(), name ) )
return;
list.emplace_back( name );
};
/* search in dirs */ /* search in dirs */
for ( int i = 0; i < g_numDirs; i++ ){ for ( int i = 0; i < g_numDirs; i++ ){
GDir *dir = g_dir_open( StringOutputStream( 256 )( g_strDirs[ i ], "scripts/" ), 0, NULL ); GDir *dir = g_dir_open( StringOutputStream( 256 )( g_strDirs[ i ], shaderPath, "/" ), 0, NULL );
if ( dir != NULL ) { if ( dir != NULL ) {
const char* name; const char* name;
while ( ( name = g_dir_read_name( dir ) ) ) while ( ( name = g_dir_read_name( dir ) ) )
{ {
if ( striEqual( path_get_filename_base_end( name ), ".shader" ) ) { if ( striEqual( path_get_filename_base_end( name ), ".shader" ) ) {
pushStringCallback( list, name ); insert( name );
} }
} }
g_dir_close( dir ); g_dir_close( dir );
} }
} }
/* search in packs */ /* search in packs */
GSList *lst; for ( GSList *lst = g_pakFiles; lst != NULL; lst = g_slist_next( lst ) )
for ( lst = g_pakFiles; lst != NULL; lst = g_slist_next( lst ) )
{ {
VFS_PAKFILE* file = (VFS_PAKFILE*)lst->data; VFS_PAKFILE* file = (VFS_PAKFILE*)lst->data;
if ( striEqual( path_get_filename_base_end( file->name ), ".shader" ) ) { if ( striEqual( path_get_filename_base_end( file->name ), ".shader" )
pushStringCallback( list, path_get_filename_start( file->name ) ); && strniEqual( file->name, shaderPath, path_get_last_separator( file->name ) - file->name ) ) {
insert( path_get_filename_start( file->name ) );
} }
} }
return list;
} }
// frees all memory that we allocated // frees all memory that we allocated

View File

@ -56,8 +56,7 @@ void vfsInitDirectory( const char *path );
void vfsShutdown(); void vfsShutdown();
int vfsGetFileCount( const char *filename ); int vfsGetFileCount( const char *filename );
int vfsLoadFile( const char *filename, void **buffer, int index ); int vfsLoadFile( const char *filename, void **buffer, int index );
struct StrList; std::vector<CopiedString> vfsListShaderFiles( const char *shaderPath );
void vfsListShaderFiles( StrList* list, void pushStringCallback( StrList* list, const char* string ) );
bool vfsPackFile( const char *filename, const char *packname, const int compLevel ); bool vfsPackFile( const char *filename, const char *packname, const int compLevel );
bool vfsPackFile_Absolute_Path( const char *filepath, const char *filename, const char *packname, const int compLevel ); bool vfsPackFile_Absolute_Path( const char *filepath, const char *filename, const char *packname, const int compLevel );

View File

@ -64,11 +64,6 @@ static inline int StrList_find( const StrList* list, const char* string ){
return 0; return 0;
} }
void pushStringCallback( StrList* list, const char* string ){
if( !StrList_find( list, string ) )
StrList_append( list, string );
}
/* /*
Check if newcoming texture is unique and not excluded Check if newcoming texture is unique and not excluded
@ -256,7 +251,7 @@ int pk3BSPMain( int argc, char **argv ){
StrList* pk3Shaders = StrList_allocate( 1024 ); StrList* pk3Shaders = StrList_allocate( 1024 );
StrList* pk3Sounds = StrList_allocate( 1024 ); StrList* pk3Sounds = StrList_allocate( 1024 );
StrList* pk3Shaderfiles = StrList_allocate( 1024 ); std::vector<CopiedString> pk3Shaderfiles;
StrList* pk3Textures = StrList_allocate( 1024 ); StrList* pk3Textures = StrList_allocate( 1024 );
StrList* pk3Videos = StrList_allocate( 1024 ); StrList* pk3Videos = StrList_allocate( 1024 );
@ -325,12 +320,12 @@ int pk3BSPMain( int argc, char **argv ){
} }
} }
vfsListShaderFiles( pk3Shaderfiles, pushStringCallback ); pk3Shaderfiles = vfsListShaderFiles( game->shaderPath );
if( dbg ){ if( dbg ){
Sys_Printf( "\n\tSchroider fileses.....%i\n", pk3Shaderfiles->n ); Sys_Printf( "\n\tSchroider fileses.....%zu\n", pk3Shaderfiles.size() );
for ( i = 0; i < pk3Shaderfiles->n; ++i ){ for ( const CopiedString& file : pk3Shaderfiles ){
Sys_Printf( "%s\n", pk3Shaderfiles->s[i] ); Sys_Printf( "%s\n", file.c_str() );
} }
} }
@ -386,7 +381,7 @@ int pk3BSPMain( int argc, char **argv ){
/* hack */ /* hack */
endofscript = true; endofscript = true;
for ( i = 0; i < pk3Shaderfiles->n; ++i ){ for ( CopiedString& file : pk3Shaderfiles ){
bool wantShader = false, wantShaderFile = false, ShaderFileExcluded = false; bool wantShader = false, wantShaderFile = false, ShaderFileExcluded = false;
int shader, found; int shader, found;
char* reasonShader = NULL; char* reasonShader = NULL;
@ -394,13 +389,13 @@ int pk3BSPMain( int argc, char **argv ){
/* load the shader */ /* load the shader */
char scriptFile[128]; char scriptFile[128];
sprintf( scriptFile, "%s/%s", game->shaderPath, pk3Shaderfiles->s[i] ); sprintf( scriptFile, "%s/%s", game->shaderPath, file.c_str() );
SilentLoadScriptFile( scriptFile, 0 ); SilentLoadScriptFile( scriptFile, 0 );
if( dbg ) if( dbg )
Sys_Printf( "\n\tentering %s\n", pk3Shaderfiles->s[i] ); Sys_Printf( "\n\tentering %s\n", file.c_str() );
/* do wanna le shader file? */ /* do wanna le shader file? */
if( ( found = StrList_find( ExShaderfiles, pk3Shaderfiles->s[i] ) ) ){ if( ( found = StrList_find( ExShaderfiles, file.c_str() ) ) ){
ShaderFileExcluded = true; ShaderFileExcluded = true;
reasonShaderFile = ExShaderfiles->s[found - 1]; reasonShaderFile = ExShaderfiles->s[found - 1];
} }
@ -600,7 +595,7 @@ int pk3BSPMain( int argc, char **argv ){
ExReasonShaderFile[ shader ] = reasonShaderFile; ExReasonShaderFile[ shader ] = reasonShaderFile;
} }
else{ else{
ExReasonShaderFile[ shader ] = copystring( pk3Shaderfiles->s[i] ); ExReasonShaderFile[ shader ] = copystring( file.c_str() );
} }
ExReasonShader[ shader ] = reasonShader; ExReasonShader[ shader ] = reasonShader;
} }
@ -612,7 +607,7 @@ int pk3BSPMain( int argc, char **argv ){
} }
} }
if ( !wantShaderFile ){ if ( !wantShaderFile ){
strClear( pk3Shaderfiles->s[i] ); file = "";
} }
} }
@ -685,9 +680,9 @@ int pk3BSPMain( int argc, char **argv ){
Sys_Printf( "\n\tShaizers....\n" ); Sys_Printf( "\n\tShaizers....\n" );
for ( i = 0; i < pk3Shaderfiles->n; ++i ){ for ( CopiedString& file : pk3Shaderfiles ){
if ( !strEmpty( pk3Shaderfiles->s[i] ) ){ if ( !file.empty() ){
stream( game->shaderPath, "/", pk3Shaderfiles->s[i] ); stream( game->shaderPath, "/", file.c_str() );
if ( !packResource( stream, packname, compLevel ) ){ if ( !packResource( stream, packname, compLevel ) ){
Sys_FPrintf( SYS_WRN, " !FAIL! %s\n", pk3Shaders->s[i] ); Sys_FPrintf( SYS_WRN, " !FAIL! %s\n", pk3Shaders->s[i] );
packFAIL = true; packFAIL = true;
@ -893,7 +888,7 @@ int repackBSPMain( int argc, char **argv ){
/* load bsps */ /* load bsps */
StrList* pk3Shaders = StrList_allocate( 65536 ); StrList* pk3Shaders = StrList_allocate( 65536 );
StrList* pk3Sounds = StrList_allocate( 4096 ); StrList* pk3Sounds = StrList_allocate( 4096 );
StrList* pk3Shaderfiles = StrList_allocate( 4096 ); std::vector<CopiedString> pk3Shaderfiles;
StrList* pk3Textures = StrList_allocate( 65536 ); StrList* pk3Textures = StrList_allocate( 65536 );
StrList* pk3Videos = StrList_allocate( 1024 ); StrList* pk3Videos = StrList_allocate( 1024 );
@ -1110,12 +1105,12 @@ int repackBSPMain( int argc, char **argv ){
vfsListShaderFiles( pk3Shaderfiles, pushStringCallback ); pk3Shaderfiles = vfsListShaderFiles( game->shaderPath );
if( dbg ){ if( dbg ){
Sys_Printf( "\n\tSchroider fileses.....%i\n", pk3Shaderfiles->n ); Sys_Printf( "\n\tSchroider fileses.....%zu\n", pk3Shaderfiles.size() );
for ( i = 0; i < pk3Shaderfiles->n; ++i ){ for ( const CopiedString& file : pk3Shaderfiles ){
Sys_Printf( "%s\n", pk3Shaderfiles->s[i] ); Sys_Printf( "%s\n", file.c_str() );
} }
} }
@ -1139,15 +1134,15 @@ int repackBSPMain( int argc, char **argv ){
/* hack */ /* hack */
endofscript = true; endofscript = true;
for ( i = 0; i < pk3Shaderfiles->n; ++i ){ for ( const CopiedString& file : pk3Shaderfiles ){
bool wantShader = false; bool wantShader = false;
int shader, found; int shader, found;
/* load the shader */ /* load the shader */
char scriptFile[128]; char scriptFile[128];
sprintf( scriptFile, "%s/%s", game->shaderPath, pk3Shaderfiles->s[i] ); sprintf( scriptFile, "%s/%s", game->shaderPath, file.c_str() );
if ( dbg ) if ( dbg )
Sys_Printf( "\n\tentering %s\n", pk3Shaderfiles->s[i] ); Sys_Printf( "\n\tentering %s\n", file.c_str() );
SilentLoadScriptFile( scriptFile, 0 ); SilentLoadScriptFile( scriptFile, 0 );
/* tokenize it */ /* tokenize it */
@ -1166,7 +1161,7 @@ int repackBSPMain( int argc, char **argv ){
shaderText << token; shaderText << token;
if ( strchr( token, '\\') != NULL ){ if ( strchr( token, '\\') != NULL ){
Sys_FPrintf( SYS_WRN, "WARNING1: %s : %s : shader name with backslash\n", pk3Shaderfiles->s[i], token ); Sys_FPrintf( SYS_WRN, "WARNING1: %s : %s : shader name with backslash\n", file.c_str(), token );
} }
/* do wanna le shader? */ /* do wanna le shader? */

View File

@ -1979,31 +1979,6 @@ static void ParseCustomInfoParms( void ){
#define MAX_SHADER_FILES 1024
struct StrList
{
int n;
char* s[MAX_SHADER_FILES];
};
void pushShaderCallback( StrList* list, const char* string ){
char* shader = copystring( string );
strClear( shader + strlen( shader ) - strlen( ".shader" ) );
/* check for duplicate entries */
for ( int i = 0; i < list->n; i++ )
if ( striEqual( list->s[ i ], shader ) ){
free( shader );
return;
}
/* test limit */
if ( list->n >= MAX_SHADER_FILES )
Error( "MAX_SHADER_FILES (%d) reached!", (int) MAX_SHADER_FILES );
/* new shader file */
list->s[ list->n++ ] = shader;
}
/* /*
LoadShaderInfo() LoadShaderInfo()
@ -2013,9 +1988,7 @@ void pushShaderCallback( StrList* list, const char* string ){
*/ */
void LoadShaderInfo( void ){ void LoadShaderInfo( void ){
int i, j, count; std::vector<CopiedString> shaderFiles;
char filename[ 1024 ];
StrList shaderFiles = { .n = 0 };
/* rr2do2: parse custom infoparms first */ /* rr2do2: parse custom infoparms first */
@ -2024,48 +1997,44 @@ void LoadShaderInfo( void ){
} }
/* we can pile up several shader files, the one in baseq3 and ones in the mod dir or other spots */ /* we can pile up several shader files, the one in baseq3 and ones in the mod dir or other spots */
sprintf( filename, "%s/shaderlist.txt", game->shaderPath ); const auto filename = StringOutputStream( 64 )( game->shaderPath, "/shaderlist.txt" );
count = vfsGetFileCount( filename ); const int count = vfsGetFileCount( filename );
/* load them all */ /* load them all */
for ( i = 0; i < count; i++ ) for ( int i = 0; i < count; i++ )
{ {
/* load shader list */ /* load shader list */
sprintf( filename, "%s/shaderlist.txt", game->shaderPath );
LoadScriptFile( filename, i ); LoadScriptFile( filename, i );
/* parse it */ /* parse it */
while ( GetToken( true ) ) while ( GetToken( true ) )
{ {
/* check for duplicate entries */ /* check for duplicate entries */
for ( j = 0; j < shaderFiles.n; j++ ) const auto contains = [&shaderFiles]( const char *file ){
if ( strEqual( shaderFiles.s[ j ], token ) ) { for( const CopiedString& str : shaderFiles )
break; if( striEqual( str.c_str(), file ) )
} return true;
return false;
/* test limit */ };
if ( j >= MAX_SHADER_FILES ) {
Error( "MAX_SHADER_FILES (%d) reached, trim your shaderlist.txt!", (int) MAX_SHADER_FILES );
}
if( !striEqual( path_get_extension( token ), "shader" ) )
strcatQ( token, ".shader", sizeof( token ) );
/* new shader file */ /* new shader file */
if ( j == shaderFiles.n ) { if ( !contains( token ) ) {
shaderFiles.s[ shaderFiles.n++ ] = copystring( token ); shaderFiles.emplace_back( token );
} }
} }
} }
if( shaderFiles.n == 0 ){ if( shaderFiles.empty() ){
Sys_Printf( "%s", "No shaderlist.txt found: loading all shaders\n" ); Sys_Printf( "%s", "No shaderlist.txt found: loading all shaders\n" );
vfsListShaderFiles( &shaderFiles, pushShaderCallback ); shaderFiles = vfsListShaderFiles( game->shaderPath );
} }
/* parse the shader files */ /* parse the shader files */
for ( i = 0; i < shaderFiles.n; i++ ) for ( const CopiedString& file : shaderFiles )
{ {
sprintf( filename, "%s/%s.shader", game->shaderPath, shaderFiles.s[ i ] ); ParseShaderFile( StringOutputStream( 64 )( game->shaderPath, '/', file.c_str() ) );
ParseShaderFile( filename );
free( shaderFiles.s[ i ] );
} }
/* emit some statistics */ /* emit some statistics */