diff --git a/plugins/shaders/shaders.cpp b/plugins/shaders/shaders.cpp index c358fd48..a140a6ab 100644 --- a/plugins/shaders/shaders.cpp +++ b/plugins/shaders/shaders.cpp @@ -1583,7 +1583,9 @@ void BuildShaderList( TextInputStream& shaderlist ){ while ( token != 0 ) { // 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() ); diff --git a/tools/quake3/common/vfs.cpp b/tools/quake3/common/vfs.cpp index e42af6b9..47732e0f 100644 --- a/tools/quake3/common/vfs.cpp +++ b/tools/quake3/common/vfs.cpp @@ -206,33 +206,41 @@ void vfsInitDirectory( const char *path ){ } -// lists all .shader files -void vfsListShaderFiles( StrList* list, void pushStringCallback( StrList* list, const char* string ) ){ +// lists all unique .shader files with extension and w/o path +std::vector vfsListShaderFiles( const char *shaderPath ){ + std::vector 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 */ 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 ) { const char* name; while ( ( name = g_dir_read_name( dir ) ) ) { if ( striEqual( path_get_filename_base_end( name ), ".shader" ) ) { - pushStringCallback( list, name ); + insert( name ); } } g_dir_close( dir ); } } /* search in packs */ - GSList *lst; - - for ( lst = g_pakFiles; lst != NULL; lst = g_slist_next( lst ) ) + for ( GSList *lst = g_pakFiles; lst != NULL; lst = g_slist_next( lst ) ) { VFS_PAKFILE* file = (VFS_PAKFILE*)lst->data; - if ( striEqual( path_get_filename_base_end( file->name ), ".shader" ) ) { - pushStringCallback( list, path_get_filename_start( file->name ) ); + if ( striEqual( path_get_filename_base_end( file->name ), ".shader" ) + && 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 diff --git a/tools/quake3/common/vfs.h b/tools/quake3/common/vfs.h index 4240a956..3678d453 100644 --- a/tools/quake3/common/vfs.h +++ b/tools/quake3/common/vfs.h @@ -56,8 +56,7 @@ void vfsInitDirectory( const char *path ); void vfsShutdown(); int vfsGetFileCount( const char *filename ); int vfsLoadFile( const char *filename, void **buffer, int index ); -struct StrList; -void vfsListShaderFiles( StrList* list, void pushStringCallback( StrList* list, const char* string ) ); +std::vector vfsListShaderFiles( const char *shaderPath ); 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 ); diff --git a/tools/quake3/q3map2/autopk3.cpp b/tools/quake3/q3map2/autopk3.cpp index 74e610d5..fa08a83e 100644 --- a/tools/quake3/q3map2/autopk3.cpp +++ b/tools/quake3/q3map2/autopk3.cpp @@ -64,11 +64,6 @@ static inline int StrList_find( const StrList* list, const char* string ){ 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 @@ -256,7 +251,7 @@ int pk3BSPMain( int argc, char **argv ){ StrList* pk3Shaders = StrList_allocate( 1024 ); StrList* pk3Sounds = StrList_allocate( 1024 ); - StrList* pk3Shaderfiles = StrList_allocate( 1024 ); + std::vector pk3Shaderfiles; StrList* pk3Textures = 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 ){ - Sys_Printf( "\n\tSchroider fileses.....%i\n", pk3Shaderfiles->n ); - for ( i = 0; i < pk3Shaderfiles->n; ++i ){ - Sys_Printf( "%s\n", pk3Shaderfiles->s[i] ); + Sys_Printf( "\n\tSchroider fileses.....%zu\n", pk3Shaderfiles.size() ); + for ( const CopiedString& file : pk3Shaderfiles ){ + Sys_Printf( "%s\n", file.c_str() ); } } @@ -386,7 +381,7 @@ int pk3BSPMain( int argc, char **argv ){ /* hack */ endofscript = true; - for ( i = 0; i < pk3Shaderfiles->n; ++i ){ + for ( CopiedString& file : pk3Shaderfiles ){ bool wantShader = false, wantShaderFile = false, ShaderFileExcluded = false; int shader, found; char* reasonShader = NULL; @@ -394,13 +389,13 @@ int pk3BSPMain( int argc, char **argv ){ /* load the shader */ char scriptFile[128]; - sprintf( scriptFile, "%s/%s", game->shaderPath, pk3Shaderfiles->s[i] ); + sprintf( scriptFile, "%s/%s", game->shaderPath, file.c_str() ); SilentLoadScriptFile( scriptFile, 0 ); 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? */ - if( ( found = StrList_find( ExShaderfiles, pk3Shaderfiles->s[i] ) ) ){ + if( ( found = StrList_find( ExShaderfiles, file.c_str() ) ) ){ ShaderFileExcluded = true; reasonShaderFile = ExShaderfiles->s[found - 1]; } @@ -600,7 +595,7 @@ int pk3BSPMain( int argc, char **argv ){ ExReasonShaderFile[ shader ] = reasonShaderFile; } else{ - ExReasonShaderFile[ shader ] = copystring( pk3Shaderfiles->s[i] ); + ExReasonShaderFile[ shader ] = copystring( file.c_str() ); } ExReasonShader[ shader ] = reasonShader; } @@ -612,7 +607,7 @@ int pk3BSPMain( int argc, char **argv ){ } } if ( !wantShaderFile ){ - strClear( pk3Shaderfiles->s[i] ); + file = ""; } } @@ -685,9 +680,9 @@ int pk3BSPMain( int argc, char **argv ){ Sys_Printf( "\n\tShaizers....\n" ); - for ( i = 0; i < pk3Shaderfiles->n; ++i ){ - if ( !strEmpty( pk3Shaderfiles->s[i] ) ){ - stream( game->shaderPath, "/", pk3Shaderfiles->s[i] ); + for ( CopiedString& file : pk3Shaderfiles ){ + if ( !file.empty() ){ + stream( game->shaderPath, "/", file.c_str() ); if ( !packResource( stream, packname, compLevel ) ){ Sys_FPrintf( SYS_WRN, " !FAIL! %s\n", pk3Shaders->s[i] ); packFAIL = true; @@ -893,7 +888,7 @@ int repackBSPMain( int argc, char **argv ){ /* load bsps */ StrList* pk3Shaders = StrList_allocate( 65536 ); StrList* pk3Sounds = StrList_allocate( 4096 ); - StrList* pk3Shaderfiles = StrList_allocate( 4096 ); + std::vector pk3Shaderfiles; StrList* pk3Textures = StrList_allocate( 65536 ); StrList* pk3Videos = StrList_allocate( 1024 ); @@ -1110,12 +1105,12 @@ int repackBSPMain( int argc, char **argv ){ - vfsListShaderFiles( pk3Shaderfiles, pushStringCallback ); + pk3Shaderfiles = vfsListShaderFiles( game->shaderPath ); if( dbg ){ - Sys_Printf( "\n\tSchroider fileses.....%i\n", pk3Shaderfiles->n ); - for ( i = 0; i < pk3Shaderfiles->n; ++i ){ - Sys_Printf( "%s\n", pk3Shaderfiles->s[i] ); + Sys_Printf( "\n\tSchroider fileses.....%zu\n", pk3Shaderfiles.size() ); + for ( const CopiedString& file : pk3Shaderfiles ){ + Sys_Printf( "%s\n", file.c_str() ); } } @@ -1139,15 +1134,15 @@ int repackBSPMain( int argc, char **argv ){ /* hack */ endofscript = true; - for ( i = 0; i < pk3Shaderfiles->n; ++i ){ + for ( const CopiedString& file : pk3Shaderfiles ){ bool wantShader = false; int shader, found; /* load the shader */ char scriptFile[128]; - sprintf( scriptFile, "%s/%s", game->shaderPath, pk3Shaderfiles->s[i] ); + sprintf( scriptFile, "%s/%s", game->shaderPath, file.c_str() ); if ( dbg ) - Sys_Printf( "\n\tentering %s\n", pk3Shaderfiles->s[i] ); + Sys_Printf( "\n\tentering %s\n", file.c_str() ); SilentLoadScriptFile( scriptFile, 0 ); /* tokenize it */ @@ -1166,7 +1161,7 @@ int repackBSPMain( int argc, char **argv ){ shaderText << token; 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? */ diff --git a/tools/quake3/q3map2/shaders.cpp b/tools/quake3/q3map2/shaders.cpp index 4c837783..5c97c415 100644 --- a/tools/quake3/q3map2/shaders.cpp +++ b/tools/quake3/q3map2/shaders.cpp @@ -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() @@ -2013,9 +1988,7 @@ void pushShaderCallback( StrList* list, const char* string ){ */ void LoadShaderInfo( void ){ - int i, j, count; - char filename[ 1024 ]; - StrList shaderFiles = { .n = 0 }; + std::vector shaderFiles; /* 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 */ - sprintf( filename, "%s/shaderlist.txt", game->shaderPath ); - count = vfsGetFileCount( filename ); + const auto filename = StringOutputStream( 64 )( game->shaderPath, "/shaderlist.txt" ); + const int count = vfsGetFileCount( filename ); /* load them all */ - for ( i = 0; i < count; i++ ) + for ( int i = 0; i < count; i++ ) { /* load shader list */ - sprintf( filename, "%s/shaderlist.txt", game->shaderPath ); LoadScriptFile( filename, i ); /* parse it */ while ( GetToken( true ) ) { /* check for duplicate entries */ - for ( j = 0; j < shaderFiles.n; j++ ) - if ( strEqual( shaderFiles.s[ j ], token ) ) { - break; - } - - /* test limit */ - if ( j >= MAX_SHADER_FILES ) { - Error( "MAX_SHADER_FILES (%d) reached, trim your shaderlist.txt!", (int) MAX_SHADER_FILES ); - } + const auto contains = [&shaderFiles]( const char *file ){ + for( const CopiedString& str : shaderFiles ) + if( striEqual( str.c_str(), file ) ) + return true; + return false; + }; + if( !striEqual( path_get_extension( token ), "shader" ) ) + strcatQ( token, ".shader", sizeof( token ) ); /* new shader file */ - if ( j == shaderFiles.n ) { - shaderFiles.s[ shaderFiles.n++ ] = copystring( token ); + if ( !contains( token ) ) { + shaderFiles.emplace_back( token ); } } } - if( shaderFiles.n == 0 ){ + if( shaderFiles.empty() ){ Sys_Printf( "%s", "No shaderlist.txt found: loading all shaders\n" ); - vfsListShaderFiles( &shaderFiles, pushShaderCallback ); + shaderFiles = vfsListShaderFiles( game->shaderPath ); } /* 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( filename ); - free( shaderFiles.s[ i ] ); + ParseShaderFile( StringOutputStream( 64 )( game->shaderPath, '/', file.c_str() ) ); } /* emit some statistics */