From 2b85b7c20c20df677e30541c93b80725dc2277c9 Mon Sep 17 00:00:00 2001 From: Garux Date: Tue, 1 Aug 2017 13:54:01 +0300 Subject: [PATCH] Q3map2: * packer: rewrote logic to make sure not to include excluded stuff * packer: preserves file date, if grabbing file from .pk3 too * packer: in case of missing *ingame* resources pk3 gets _FAILEDpack suffix --- tools/quake3/common/miniz.c | 191 +++++++++++++++++++- tools/quake3/common/miniz.h | 1 + tools/quake3/common/scriplib.c | 28 +++ tools/quake3/common/scriplib.h | 1 + tools/quake3/common/vfs.c | 5 +- tools/quake3/q3map2/main.c | 316 ++++++++++++++++++++++----------- 6 files changed, 433 insertions(+), 109 deletions(-) diff --git a/tools/quake3/common/miniz.c b/tools/quake3/common/miniz.c index 0b26cbd1..50148dcd 100644 --- a/tools/quake3/common/miniz.c +++ b/tools/quake3/common/miniz.c @@ -3481,6 +3481,149 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name return MZ_TRUE; } +mz_bool mz_zip_writer_add_mem_ex_with_time(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, mz_uint16 dos_time, mz_uint16 dos_date) +{ + mz_uint16 method = 0; + mz_uint level, ext_attributes = 0, num_alignment_padding_bytes; + mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0; + size_t archive_name_size; + mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; + tdefl_compressor *pComp = NULL; + mz_bool store_data_uncompressed; + mz_zip_internal_state *pState; + + if ((int)level_and_flags < 0) + level_and_flags = MZ_DEFAULT_LEVEL; + level = level_and_flags & 0xF; + store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)); + + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (pZip->m_total_files == 0xFFFF) || (level > MZ_UBER_COMPRESSION)) + return MZ_FALSE; + + pState = pZip->m_pState; + + if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size)) + return MZ_FALSE; + // No zip64 support yet + if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) + return MZ_FALSE; + if (!mz_zip_writer_validate_archive_name(pArchive_name)) + return MZ_FALSE; + + archive_name_size = strlen(pArchive_name); + if (archive_name_size > 0xFFFF) + return MZ_FALSE; + + num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); + + // no zip64 support yet + if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF)) + return MZ_FALSE; + + if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/')) + { + // Set DOS Subdirectory attribute bit. + ext_attributes |= 0x10; + // Subdirectories cannot contain data. + if ((buf_size) || (uncomp_size)) + return MZ_FALSE; + } + + // Try to do any allocations before writing to the archive, so if an allocation fails the file remains unmodified. (A good idea if we're doing an in-place modification.) + if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size)) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1))) + return MZ_FALSE; + + if ((!store_data_uncompressed) && (buf_size)) + { + if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)))) + return MZ_FALSE; + } + + if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header))) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return MZ_FALSE; + } + local_dir_header_ofs += num_alignment_padding_bytes; + if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); } + cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header); + + MZ_CLEAR_OBJ(local_dir_header); + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return MZ_FALSE; + } + cur_archive_file_ofs += archive_name_size; + + if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) + { + uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8*)pBuf, buf_size); + uncomp_size = buf_size; + if (uncomp_size <= 3) + { + level = 0; + store_data_uncompressed = MZ_TRUE; + } + } + + if (store_data_uncompressed) + { + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return MZ_FALSE; + } + + cur_archive_file_ofs += buf_size; + comp_size = buf_size; + + if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) + method = MZ_DEFLATED; + } + else if (buf_size) + { + mz_zip_writer_add_state state; + + state.m_pZip = pZip; + state.m_cur_archive_file_ofs = cur_archive_file_ofs; + state.m_comp_size = 0; + + if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) || + (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE)) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return MZ_FALSE; + } + + comp_size = state.m_comp_size; + cur_archive_file_ofs = state.m_cur_archive_file_ofs; + + method = MZ_DEFLATED; + } + + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + pComp = NULL; + + // no zip64 support yet + if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF)) + return MZ_FALSE; + + if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date)) + return MZ_FALSE; + + if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) + return MZ_FALSE; + + if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes)) + return MZ_FALSE; + + pZip->m_total_files++; + pZip->m_archive_size = cur_archive_file_ofs; + + return MZ_TRUE; +} + #ifndef MINIZ_NO_STDIO mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) { @@ -3514,7 +3657,7 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, if (!mz_zip_get_file_modified_time(pSrc_filename, &dos_time, &dos_date)) return MZ_FALSE; - + pSrc_file = MZ_FOPEN(pSrc_filename, "rb"); if (!pSrc_file) return MZ_FALSE; @@ -3926,6 +4069,52 @@ mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const return status; } +mz_bool mz_zip_add_mem_to_archive_file_in_place_with_time(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint16 dos_time, mz_uint16 dos_date) +{ + mz_bool status, created_new_archive = MZ_FALSE; + mz_zip_archive zip_archive; + struct MZ_FILE_STAT_STRUCT file_stat; + MZ_CLEAR_OBJ(zip_archive); + if ((int)level_and_flags < 0) + level_and_flags = MZ_DEFAULT_LEVEL; + if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION)) + return MZ_FALSE; + if (!mz_zip_writer_validate_archive_name(pArchive_name)) + return MZ_FALSE; + if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0) + { + // Create a new archive. + if (!mz_zip_writer_init_file(&zip_archive, pZip_filename, 0)) + return MZ_FALSE; + created_new_archive = MZ_TRUE; + } + else + { + // Append to an existing archive. + if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) + return MZ_FALSE; + if (!mz_zip_writer_init_from_reader(&zip_archive, pZip_filename)) + { + mz_zip_reader_end(&zip_archive); + return MZ_FALSE; + } + } + status = mz_zip_writer_add_mem_ex_with_time(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0, dos_time, dos_date); + // Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.) + if (!mz_zip_writer_finalize_archive(&zip_archive)) + status = MZ_FALSE; + if (!mz_zip_writer_end(&zip_archive)) + status = MZ_FALSE; + if ((!status) && (created_new_archive)) + { + // It's a new archive and something went wrong, so just delete it. + int ignoredStatus = MZ_DELETE_FILE(pZip_filename); + (void)ignoredStatus; + } + return status; +} + + void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags) { int file_index; diff --git a/tools/quake3/common/miniz.h b/tools/quake3/common/miniz.h index 397da296..7e1e04c3 100644 --- a/tools/quake3/common/miniz.h +++ b/tools/quake3/common/miniz.h @@ -669,6 +669,7 @@ mz_bool mz_zip_writer_end(mz_zip_archive *pZip); // mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive. // level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); +mz_bool mz_zip_add_mem_to_archive_file_in_place_with_time(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint16 dos_time, mz_uint16 dos_date); // Reads a single file from an archive into a heap block. // Returns NULL on failure. diff --git a/tools/quake3/common/scriplib.c b/tools/quake3/common/scriplib.c index a33657c7..c223bca2 100644 --- a/tools/quake3/common/scriplib.c +++ b/tools/quake3/common/scriplib.c @@ -98,7 +98,35 @@ void LoadScriptFile( const char *filename, int index ){ endofscript = qfalse; tokenready = qfalse; } +/* &unload current; for autopacker */ +void SilentLoadScriptFile( const char *filename, int index ){ + int size; + + if ( script->buffer != NULL && !endofscript ) { + free( script->buffer ); + script->buffer = NULL; + } + + script = scriptstack; + + script++; + if ( script == &scriptstack[MAX_INCLUDES] ) { + Error( "script file exceeded MAX_INCLUDES" ); + } + strcpy( script->filename, ExpandPath( filename ) ); + size = vfsLoadFile( script->filename, (void **)&script->buffer, index ); + + if ( size == -1 ) { + Sys_Printf( "Script file %s was not found\n", script->filename ); + } + script->line = 1; + script->script_p = script->buffer; + script->end_p = script->buffer + size; + + endofscript = qfalse; + tokenready = qfalse; +} /* ============== diff --git a/tools/quake3/common/scriplib.h b/tools/quake3/common/scriplib.h index 330e2f65..a1cf4def 100644 --- a/tools/quake3/common/scriplib.h +++ b/tools/quake3/common/scriplib.h @@ -38,6 +38,7 @@ extern qboolean endofscript; void LoadScriptFile( const char *filename, int index ); +void SilentLoadScriptFile( const char *filename, int index ); void ParseFromMemory( char *buffer, int size ); qboolean GetToken( qboolean crossline ); diff --git a/tools/quake3/common/vfs.c b/tools/quake3/common/vfs.c index 2e744588..350bbc09 100644 --- a/tools/quake3/common/vfs.c +++ b/tools/quake3/common/vfs.c @@ -545,6 +545,9 @@ qboolean vfsPackFile( const char *filename, const char *packname ){ // we need to end the buffer with a 0 ( (char*) ( bufferptr ) )[file->size] = 0; + mz_uint16 DOS_time = (mz_uint16)(((file->zipinfo.cur_file_info.tmu_date.tm_hour) << 11) + ((file->zipinfo.cur_file_info.tmu_date.tm_min) << 5) + ((file->zipinfo.cur_file_info.tmu_date.tm_sec) >> 1)); + mz_uint16 DOS_date = (mz_uint16)(((file->zipinfo.cur_file_info.tmu_date.tm_year - 1980) << 9) + ((file->zipinfo.cur_file_info.tmu_date.tm_mon + 1) << 5) + file->zipinfo.cur_file_info.tmu_date.tm_mday); + i = unzReadCurrentFile( file->zipfile, bufferptr, file->size ); unzCloseCurrentFile( file->zipfile ); if ( i < 0 ) { @@ -552,7 +555,7 @@ qboolean vfsPackFile( const char *filename, const char *packname ){ } else{ mz_bool success = MZ_TRUE; - success &= mz_zip_add_mem_to_archive_file_in_place( packname, filename, bufferptr, i, 0, 0, 10 ); + success &= mz_zip_add_mem_to_archive_file_in_place_with_time( packname, filename, bufferptr, i, 0, 0, 10, DOS_time, DOS_date ); if ( !success ){ Error( "Failed creating zip archive \"%s\"!\n", packname ); } diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 0ee9be82..b3fe1cda 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -1723,7 +1723,7 @@ char q3map2path[1024]; int pk3BSPMain( int argc, char **argv ){ int i, j, len; - qboolean dbg = qfalse, png = qfalse; + qboolean dbg = qfalse, png = qfalse, packFAIL = qfalse; /* process arguments */ for ( i = 1; i < ( argc - 1 ); i++ ){ @@ -1746,7 +1746,7 @@ int pk3BSPMain( int argc, char **argv ){ ParseEntities(); - char packname[ 1024 ], base[ 1024 ], nameOFmap[ 1024 ], temp[ 1024 ]; + char packname[ 1024 ], packFailName[ 1024 ], base[ 1024 ], nameOFmap[ 1024 ], temp[ 1024 ]; /* copy map name */ strcpy( base, source ); @@ -1769,20 +1769,15 @@ int pk3BSPMain( int argc, char **argv ){ } int pk3ShadersN = 0; - char* pk3Shaders; - pk3Shaders = (char *)calloc( 1024*65, sizeof( char ) ); + char* pk3Shaders = (char *)calloc( 1024*65, sizeof( char ) ); int pk3SoundsN = 0; - char* pk3Sounds; - pk3Sounds = (char *)calloc( 1024*65, sizeof( char ) ); + char* pk3Sounds = (char *)calloc( 1024*65, sizeof( char ) ); int pk3ShaderfilesN = 0; - char* pk3Shaderfiles; - pk3Shaderfiles = (char *)calloc( 1024*65, sizeof( char ) ); + char* pk3Shaderfiles = (char *)calloc( 1024*65, sizeof( char ) ); int pk3TexturesN = 0; - char* pk3Textures; - pk3Textures = (char *)calloc( 1024*65, sizeof( char ) ); + char* pk3Textures = (char *)calloc( 1024*65, sizeof( char ) ); int pk3VideosN = 0; - char* pk3Videos; - pk3Videos = (char *)calloc( 1024*65, sizeof( char ) ); + char* pk3Videos = (char *)calloc( 1024*65, sizeof( char ) ); @@ -1842,11 +1837,11 @@ int pk3BSPMain( int argc, char **argv ){ if( dbg ){ - Sys_Printf( "\tDrawsurface+ent calls....%i\n", pk3ShadersN ); + Sys_Printf( "\n\tDrawsurface+ent calls....%i\n", pk3ShadersN ); for ( i = 0; i < pk3ShadersN; i++ ){ Sys_Printf( "%s\n", pk3Shaders + i*65 ); } - Sys_Printf( "\tSounds....%i\n", pk3SoundsN ); + Sys_Printf( "\n\tSounds....%i\n", pk3SoundsN ); for ( i = 0; i < pk3SoundsN; i++ ){ Sys_Printf( "%s\n", pk3Sounds + i*65 ); } @@ -1855,7 +1850,7 @@ int pk3BSPMain( int argc, char **argv ){ vfsListShaderFiles( pk3Shaderfiles, &pk3ShaderfilesN ); if( dbg ){ - Sys_Printf( "\tSchroider fileses.....%i\n", pk3ShaderfilesN ); + Sys_Printf( "\n\tSchroider fileses.....%i\n", pk3ShaderfilesN ); for ( i = 0; i < pk3ShaderfilesN; i++ ){ Sys_Printf( "%s\n", pk3Shaderfiles + i*65 ); } @@ -1863,21 +1858,21 @@ int pk3BSPMain( int argc, char **argv ){ /* load exclusions file */ - int EXpk3TexturesN = 0; - char* EXpk3Textures; - EXpk3Textures = (char *)calloc( 4096*65, sizeof( char ) ); - int EXpk3ShadersN = 0; - char* EXpk3Shaders; - EXpk3Shaders = (char *)calloc( 4096*65, sizeof( char ) ); - int EXpk3SoundsN = 0; - char* EXpk3Sounds; - EXpk3Sounds = (char *)calloc( 4096*65, sizeof( char ) ); - int EXpk3ShaderfilesN = 0; - char* EXpk3Shaderfiles; - EXpk3Shaderfiles = (char *)calloc( 4096*65, sizeof( char ) ); - int EXpk3VideosN = 0; - char* EXpk3Videos; - EXpk3Videos = (char *)calloc( 4096*65, sizeof( char ) ); + int ExTexturesN = 0; + char* ExTextures = (char *)calloc( 4096*65, sizeof( char ) ); + int ExShadersN = 0; + char* ExShaders = (char *)calloc( 4096*65, sizeof( char ) ); + int ExSoundsN = 0; + char* ExSounds = (char *)calloc( 4096*65, sizeof( char ) ); + int ExShaderfilesN = 0; + char* ExShaderfiles = (char *)calloc( 4096*65, sizeof( char ) ); + int ExVideosN = 0; + char* ExVideos = (char *)calloc( 4096*65, sizeof( char ) ); + int ExPureTexturesN = 0; + char* ExPureTextures = (char *)calloc( 4096*65, sizeof( char ) ); + + char* ExReasonShader[4096] = { NULL }; + char* ExReasonShaderFile[4096] = { NULL }; char exName[ 1024 ]; byte *buffer; @@ -1915,19 +1910,19 @@ int pk3BSPMain( int argc, char **argv ){ /* blocks */ if ( !stricmp( token, "textures" ) ){ - parseEXblock ( EXpk3Textures, &EXpk3TexturesN, exName ); + parseEXblock ( ExTextures, &ExTexturesN, exName ); } else if ( !stricmp( token, "shaders" ) ){ - parseEXblock ( EXpk3Shaders, &EXpk3ShadersN, exName ); + parseEXblock ( ExShaders, &ExShadersN, exName ); } else if ( !stricmp( token, "shaderfiles" ) ){ - parseEXblock ( EXpk3Shaderfiles, &EXpk3ShaderfilesN, exName ); + parseEXblock ( ExShaderfiles, &ExShaderfilesN, exName ); } else if ( !stricmp( token, "sounds" ) ){ - parseEXblock ( EXpk3Sounds, &EXpk3SoundsN, exName ); + parseEXblock ( ExSounds, &ExSoundsN, exName ); } else if ( !stricmp( token, "videos" ) ){ - parseEXblock ( EXpk3Videos, &EXpk3VideosN, exName ); + parseEXblock ( ExVideos, &ExVideosN, exName ); } else{ Error( "ReadExclusionsFile: %s, line %d: unknown block name!\nValid ones are: textures, shaders, shaderfiles, sounds, videos.", exName, scriptline ); @@ -1937,32 +1932,131 @@ int pk3BSPMain( int argc, char **argv ){ /* free the buffer */ free( buffer ); + for ( i = 0; i < ExTexturesN; i++ ){ + for ( j = 0; j < ExShadersN; j++ ){ + if ( !stricmp( ExTextures + i*65, ExShaders + j*65 ) ){ + break; + } + } + if ( j == ExShadersN ){ + strcpy ( ExPureTextures + ExPureTexturesN*65, ExTextures + i*65 ); + ExPureTexturesN++; + } + } + skipEXfile: if( dbg ){ - Sys_Printf( "\tEXpk3Textures....%i\n", EXpk3TexturesN ); - for ( i = 0; i < EXpk3TexturesN; i++ ) Sys_Printf( "%s\n", EXpk3Textures + i*65 ); - Sys_Printf( "\tEXpk3Shaders....%i\n", EXpk3ShadersN ); - for ( i = 0; i < EXpk3ShadersN; i++ ) Sys_Printf( "%s\n", EXpk3Shaders + i*65 ); - Sys_Printf( "\tEXpk3Shaderfiles....%i\n", EXpk3ShaderfilesN ); - for ( i = 0; i < EXpk3ShaderfilesN; i++ ) Sys_Printf( "%s\n", EXpk3Shaderfiles + i*65 ); - Sys_Printf( "\tEXpk3Sounds....%i\n", EXpk3SoundsN ); - for ( i = 0; i < EXpk3SoundsN; i++ ) Sys_Printf( "%s\n", EXpk3Sounds + i*65 ); - Sys_Printf( "\tEXpk3Videos....%i\n", EXpk3VideosN ); - for ( i = 0; i < EXpk3VideosN; i++ ) Sys_Printf( "%s\n", EXpk3Videos + i*65 ); + Sys_Printf( "\n\tExTextures....%i\n", ExTexturesN ); + for ( i = 0; i < ExTexturesN; i++ ) Sys_Printf( "%s\n", ExTextures + i*65 ); + Sys_Printf( "\n\tExPureTextures....%i\n", ExPureTexturesN ); + for ( i = 0; i < ExPureTexturesN; i++ ) Sys_Printf( "%s\n", ExPureTextures + i*65 ); + Sys_Printf( "\n\tExShaders....%i\n", ExShadersN ); + for ( i = 0; i < ExShadersN; i++ ) Sys_Printf( "%s\n", ExShaders + i*65 ); + Sys_Printf( "\n\tExShaderfiles....%i\n", ExShaderfilesN ); + for ( i = 0; i < ExShaderfilesN; i++ ) Sys_Printf( "%s\n", ExShaderfiles + i*65 ); + Sys_Printf( "\n\tExSounds....%i\n", ExSoundsN ); + for ( i = 0; i < ExSoundsN; i++ ) Sys_Printf( "%s\n", ExSounds + i*65 ); + Sys_Printf( "\n\tExVideos....%i\n", ExVideosN ); + for ( i = 0; i < ExVideosN; i++ ) Sys_Printf( "%s\n", ExVideos + i*65 ); + } + + /* can exclude pure textures right now, shouldn't create shaders for them anyway */ + for ( i = 0; i < pk3ShadersN ; i++ ){ + for ( j = 0; j < ExPureTexturesN ; j++ ){ + if ( !stricmp( pk3Shaders + i*65, ExPureTextures + j*65 ) ){ + *( pk3Shaders + i*65 ) = '\0'; + break; + } + } } - //Parse Shader Files + /* hack */ + endofscript = qtrue; + for ( i = 0; i < pk3ShaderfilesN; i++ ){ - qboolean wantShader = qfalse, wantShaderFile = qfalse; - char shadername[ 1024 ], lastwantedShader[ 1024 ]; + qboolean wantShader = qfalse, wantShaderFile = qfalse, ShaderFileExcluded = qfalse; + int shader; + char* reasonShader = NULL, reasonShaderFile = NULL; /* load the shader */ sprintf( temp, "%s/%s", game->shaderPath, pk3Shaderfiles + i*65 ); - LoadScriptFile( temp, 0 ); - + SilentLoadScriptFile( temp, 0 ); + if( dbg ) Sys_Printf( "\n\tentering %s\n", pk3Shaderfiles + i*65 ); + + /* do wanna le shader file? */ + for ( j = 0; j < ExShaderfilesN; j++ ){ + if ( !stricmp( ExShaderfiles + j*65, pk3Shaderfiles + i*65 ) ){ + ShaderFileExcluded = qtrue; + reasonShaderFile = ExShaderfiles + j*65; + break; + } + } /* tokenize it */ + /* check if shader file has to be excluded */ + while ( !ShaderFileExcluded ) + { + /* test for end of file */ + if ( !GetToken( qtrue ) ) { + break; + } + + /* does it contain restricted shaders/textures? */ + for ( j = 0; j < ExShadersN; j++ ){ + if ( !stricmp( ExShaders + j*65, token ) ){ + ShaderFileExcluded = qtrue; + reasonShader = ExShaders + j*65; + break; + } + } + if ( ShaderFileExcluded ) + break; + for ( j = 0; j < ExPureTexturesN; j++ ){ + if ( !stricmp( ExPureTextures + j*65, token ) ){ + ShaderFileExcluded = qtrue; + reasonShader = ExPureTextures + j*65; + break; + } + } + if ( ShaderFileExcluded ) + break; + + /* handle { } section */ + if ( !GetToken( qtrue ) ) { + break; + } + if ( strcmp( token, "{" ) ) { + Error( "ParseShaderFile: %s, line %d: { not found!\nFound instead: %s", + temp, scriptline, token ); + } + + while ( 1 ) + { + /* get the next token */ + if ( !GetToken( qtrue ) ) { + break; + } + if ( !strcmp( token, "}" ) ) { + break; + } + /* parse stage directives */ + if ( !strcmp( token, "{" ) ) { + while ( 1 ) + { + if ( !GetToken( qtrue ) ) { + break; + } + if ( !strcmp( token, "}" ) ) { + break; + } + } + } + } + } + + /* tokenize it again */ + SilentLoadScriptFile( temp, 0 ); while ( 1 ) { /* test for end of file */ @@ -1976,8 +2070,7 @@ skipEXfile: wantShader = qfalse; for ( j = 0; j < pk3ShadersN; j++ ){ if ( !stricmp( pk3Shaders + j*65, token) ){ - strcpy ( shadername, pk3Shaders + j*65 ); - *(pk3Shaders + j*65) = '\0'; + shader = j; wantShader = qtrue; break; } @@ -2027,7 +2120,7 @@ skipEXfile: /* get an image */ GetToken( qfalse ); if ( token[ 0 ] != '*' && token[ 0 ] != '$' ) { - tex2list( pk3Textures, &pk3TexturesN, EXpk3Textures, &EXpk3TexturesN ); + tex2list( pk3Textures, &pk3TexturesN, ExTextures, &ExTexturesN ); } } else if ( !stricmp( token, "animMap" ) || @@ -2035,7 +2128,7 @@ skipEXfile: GetToken( qfalse );// skip num while ( TokenAvailable() ){ GetToken( qfalse ); - tex2list( pk3Textures, &pk3TexturesN, EXpk3Textures, &EXpk3TexturesN ); + tex2list( pk3Textures, &pk3TexturesN, ExTextures, &ExTexturesN ); } } else if ( !stricmp( token, "videoMap" ) ){ @@ -2050,8 +2143,8 @@ skipEXfile: goto away; } } - for ( j = 0; j < EXpk3VideosN; j++ ){ - if ( !stricmp( EXpk3Videos + j*65, token ) ){ + for ( j = 0; j < ExVideosN; j++ ){ + if ( !stricmp( ExVideos + j*65, token ) ){ goto away; } } @@ -2074,6 +2167,7 @@ skipEXfile: GetToken( qfalse ); if ( !stricmp( token, "nodraw" ) ) { wantShader = qfalse; + *( pk3Shaders + shader*65 ) = '\0'; } } @@ -2086,65 +2180,74 @@ skipEXfile: if ( stricmp( token, "-" ) && stricmp( token, "full" ) ) { strcpy ( temp, token ); sprintf( token, "%s_up", temp ); - tex2list( pk3Textures, &pk3TexturesN, EXpk3Textures, &EXpk3TexturesN ); + tex2list( pk3Textures, &pk3TexturesN, ExTextures, &ExTexturesN ); sprintf( token, "%s_dn", temp ); - tex2list( pk3Textures, &pk3TexturesN, EXpk3Textures, &EXpk3TexturesN ); + tex2list( pk3Textures, &pk3TexturesN, ExTextures, &ExTexturesN ); sprintf( token, "%s_lf", temp ); - tex2list( pk3Textures, &pk3TexturesN, EXpk3Textures, &EXpk3TexturesN ); + tex2list( pk3Textures, &pk3TexturesN, ExTextures, &ExTexturesN ); sprintf( token, "%s_rt", temp ); - tex2list( pk3Textures, &pk3TexturesN, EXpk3Textures, &EXpk3TexturesN ); + tex2list( pk3Textures, &pk3TexturesN, ExTextures, &ExTexturesN ); sprintf( token, "%s_bk", temp ); - tex2list( pk3Textures, &pk3TexturesN, EXpk3Textures, &EXpk3TexturesN ); + tex2list( pk3Textures, &pk3TexturesN, ExTextures, &ExTexturesN ); sprintf( token, "%s_ft", temp ); - tex2list( pk3Textures, &pk3TexturesN, EXpk3Textures, &EXpk3TexturesN ); + tex2list( pk3Textures, &pk3TexturesN, ExTextures, &ExTexturesN ); } /* skip rest of line */ GetToken( qfalse ); GetToken( qfalse ); } } + //exclude shader if ( wantShader ){ - for ( j = 0; j < EXpk3ShadersN; j++ ){ - if ( !stricmp( EXpk3Shaders + j*65, shadername ) ){ + for ( j = 0; j < ExShadersN; j++ ){ + if ( !stricmp( ExShaders + j*65, pk3Shaders + shader*65 ) ){ wantShader = qfalse; + *( pk3Shaders + shader*65 ) = '\0'; break; } } - /* shouldnt make shaders for shipped with the game textures aswell */ if ( wantShader ){ - for ( j = 0; j < EXpk3TexturesN; j++ ){ - if ( !stricmp( EXpk3Textures + j*65, shadername ) ){ - wantShader = qfalse; - break; + if ( ShaderFileExcluded ){ + if ( reasonShaderFile != NULL ){ + ExReasonShaderFile[ shader ] = reasonShaderFile; + } + else{ + ExReasonShaderFile[ shader ] = ( char* ) calloc( 65, sizeof( char ) ); + strcpy( ExReasonShaderFile[ shader ], pk3Shaderfiles + i*65 ); } + ExReasonShader[ shader ] = reasonShader; + } + else{ + wantShaderFile = qtrue; + *( pk3Shaders + shader*65 ) = '\0'; } - } - if ( wantShader ){ - wantShaderFile = qtrue; - strcpy( lastwantedShader, shadername ); - } - } - } - //exclude shader file - if ( wantShaderFile ){ - for ( j = 0; j < EXpk3ShaderfilesN; j++ ){ - if ( !stricmp( EXpk3Shaderfiles + j*65, pk3Shaderfiles + i*65 ) ){ - Sys_Printf( "WARNING: excluded shader %s, since it was located in restricted shader file: %s\n", lastwantedShader, pk3Shaderfiles + i*65 ); - *( pk3Shaderfiles + i*65 ) = '\0'; - break; } } } - else { + if ( !wantShaderFile ){ *( pk3Shaderfiles + i*65 ) = '\0'; } - } /* exclude stuff */ +//wanted shaders from excluded .shaders + Sys_Printf( "\n" ); + for ( i = 0; i < pk3ShadersN; i++ ){ + if ( *( pk3Shaders + i*65 ) != '\0' && ( ExReasonShader[i] != NULL || ExReasonShaderFile[i] != NULL ) ){ + Sys_Printf( " !FAIL! %s\n", pk3Shaders + i*65 ); + packFAIL = qtrue; + if ( ExReasonShader[i] != NULL ){ + Sys_Printf( " reason: is located in %s,\n containing restricted shader %s\n", ExReasonShaderFile[i], ExReasonShader[i] ); + } + else{ + Sys_Printf( " reason: is located in restricted %s\n", ExReasonShaderFile[i] ); + } + *( pk3Shaders + i*65 ) = '\0'; + } + } //pure textures (shader ones are done) for ( i = 0; i < pk3ShadersN; i++ ){ if ( *( pk3Shaders + i*65 ) != '\0' ){ @@ -2156,8 +2259,8 @@ skipEXfile: } } if ( *( pk3Shaders + i*65 ) == '\0' ) continue; - for ( j = 0; j < EXpk3TexturesN; j++ ){ - if ( !stricmp( pk3Shaders + i*65, EXpk3Textures + j*65 ) ){ + for ( j = 0; j < ExTexturesN; j++ ){ + if ( !stricmp( pk3Shaders + i*65, ExTextures + j*65 ) ){ *( pk3Shaders + i*65 ) = '\0'; break; } @@ -2167,34 +2270,21 @@ skipEXfile: //snds for ( i = 0; i < pk3SoundsN; i++ ){ - for ( j = 0; j < EXpk3SoundsN; j++ ){ - if ( !stricmp( pk3Sounds + i*65, EXpk3Sounds + j*65 ) ){ + for ( j = 0; j < ExSoundsN; j++ ){ + if ( !stricmp( pk3Sounds + i*65, ExSounds + j*65 ) ){ *( pk3Sounds + i*65 ) = '\0'; break; } } } - if( dbg ){ - Sys_Printf( "\tShader referenced textures....%i\n", pk3TexturesN ); - for ( i = 0; i < pk3TexturesN; i++ ){ - Sys_Printf( "%s\n", pk3Textures + i*65 ); - } - Sys_Printf( "\tShader files....\n" ); - for ( i = 0; i < pk3ShaderfilesN; i++ ){ - if ( *( pk3Shaderfiles + i*65 ) != '\0' ) Sys_Printf( "%s\n", pk3Shaderfiles + i*65 ); - } - Sys_Printf( "\tPure textures....\n" ); - for ( i = 0; i < pk3ShadersN; i++ ){ - if ( *( pk3Shaders + i*65 ) != '\0' ) Sys_Printf( "%s\n", pk3Shaders + i*65 ); - } - } - - + /* make a pack */ sprintf( packname, "%s/%s_autopacked.pk3", EnginePath, nameOFmap ); remove( packname ); + sprintf( packFailName, "%s/%s_FAILEDpack.pk3", EnginePath, nameOFmap ); + remove( packFailName ); - Sys_Printf( "--- ZipZip ---\n" ); + Sys_Printf( "\n--- ZipZip ---\n" ); Sys_Printf( "\n\tShader referenced textures....\n" ); @@ -2217,6 +2307,7 @@ skipEXfile: continue; } Sys_Printf( " !FAIL! %s\n", pk3Textures + i*65 ); + packFAIL = qtrue; } Sys_Printf( "\n\tPure textures....\n" ); @@ -2241,6 +2332,7 @@ skipEXfile: continue; } Sys_Printf( " !FAIL! %s\n", pk3Shaders + i*65 ); + if ( i != pk3ShadersN - 1 ) packFAIL = qtrue; //levelshot typically } } @@ -2254,6 +2346,7 @@ skipEXfile: continue; } Sys_Printf( " !FAIL! %s\n", pk3Shaders + i*65 ); + packFAIL = qtrue; } } @@ -2266,6 +2359,7 @@ skipEXfile: continue; } Sys_Printf( " !FAIL! %s\n", pk3Sounds + i*65 ); + packFAIL = qtrue; } } @@ -2277,9 +2371,10 @@ skipEXfile: continue; } Sys_Printf( " !FAIL! %s\n", pk3Videos + i*65 ); + packFAIL = qtrue; } - Sys_Printf( "\n\t.\n" ); + Sys_Printf( "\n\t.bsp and stuff\n" ); sprintf( temp, "maps/%s.bsp", nameOFmap ); if ( vfsPackFile( temp, packname ) ){ @@ -2287,6 +2382,7 @@ skipEXfile: } else{ Sys_Printf( " !FAIL! %s\n", temp ); + packFAIL = qtrue; } sprintf( temp, "maps/%s.aas", nameOFmap ); @@ -2313,7 +2409,13 @@ skipEXfile: Sys_Printf( " !FAIL! %s\n", temp ); } + if ( !packFAIL ){ Sys_Printf( "\nSaved to %s\n", packname ); + } + else{ + rename( packname, packFailName ); + Sys_Printf( "\nSaved to %s\n", packFailName ); + } /* return to sender */ return 0; } -- 2.39.2