You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
552 lines
16 KiB
552 lines
16 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include <stdio.h> |
|
#include "bsplib.h" |
|
#include "cmdlib.h" |
|
#include "tier0/icommandline.h" |
|
#include "utlbuffer.h" |
|
|
|
int CopyVariableLump( int lump, void **dest, int size ); |
|
|
|
void StripPath( const char* pPath, char* pBuf, int nBufLen ) |
|
{ |
|
const char *pSrc; |
|
|
|
// want filename only |
|
pSrc = pPath + Q_strlen( pPath ) - 1; |
|
while ((pSrc != pPath) && (*(pSrc-1) != '\\') && (*(pSrc-1) != '/') && (*(pSrc-1) != ':')) |
|
pSrc--; |
|
|
|
Q_strncpy( pBuf, pSrc, nBufLen ); |
|
} |
|
|
|
bool RepackBSP( const char *pszMapFile, bool bCompress ) |
|
{ |
|
Msg( "Repacking %s\n", pszMapFile ); |
|
|
|
if ( !g_pFullFileSystem->FileExists( pszMapFile ) ) |
|
{ |
|
Warning( "Couldn't open input file %s - BSP recompress failed\n", pszMapFile ); |
|
return false; |
|
} |
|
|
|
CUtlBuffer inputBuffer; |
|
if ( !g_pFullFileSystem->ReadFile( pszMapFile, NULL, inputBuffer ) ) |
|
{ |
|
Warning( "Couldn't read file %s - BSP compression failed\n", pszMapFile ); |
|
return false; |
|
} |
|
|
|
CUtlBuffer outputBuffer; |
|
|
|
if ( !RepackBSP( inputBuffer, outputBuffer, |
|
bCompress ? RepackBSPCallback_LZMA : NULL, |
|
bCompress ? IZip::eCompressionType_LZMA : IZip::eCompressionType_None ) ) |
|
{ |
|
Warning( "Internal error compressing BSP\n" ); |
|
return false; |
|
} |
|
|
|
g_pFullFileSystem->WriteFile( pszMapFile, NULL, outputBuffer ); |
|
|
|
Msg( "Successfully repacked %s -- %u -> %u bytes\n", |
|
pszMapFile, inputBuffer.TellPut(), outputBuffer.TellPut() ); |
|
|
|
return true; |
|
} |
|
|
|
void Usage( void ) |
|
{ |
|
fprintf( stderr, "usage: \n" ); |
|
fprintf( stderr, "bspzip -extract <bspfile> <blah.zip>\n"); |
|
fprintf( stderr, "bspzip -extractfiles <bspfile> <targetpath>\n"); |
|
fprintf( stderr, "bspzip -dir <bspfile>\n"); |
|
fprintf( stderr, "bspzip -addfile <bspfile> <relativepathname> <fullpathname> <newbspfile>\n"); |
|
fprintf( stderr, "bspzip -addlist <bspfile> <listfile> <newbspfile>\n"); |
|
fprintf( stderr, "bspzip -addorupdatelist <bspfile> <listfile> <newbspfile>\n"); |
|
fprintf( stderr, "bspzip -extractcubemaps <bspfile> <targetPath>\n"); |
|
fprintf( stderr, " Extracts the cubemaps to <targetPath>.\n"); |
|
fprintf( stderr, "bspzip -deletecubemaps <bspfile>\n"); |
|
fprintf( stderr, " Deletes the cubemaps from <bspFile>.\n"); |
|
fprintf( stderr, "bspzip -addfiles <bspfile> <relativePathPrefix> <listfile> <newbspfile>\n"); |
|
fprintf( stderr, " Adds files to <newbspfile>.\n"); |
|
fprintf( stderr, "bspzip -repack [ -compress ] <bspfile>\n"); |
|
fprintf( stderr, " Optimally repacks a BSP file, optionally using compressed BSP format.\n"); |
|
fprintf( stderr, " Using on a compressed BSP without -compress will effectively decompress\n"); |
|
fprintf( stderr, " a compressed BSP.\n"); |
|
|
|
exit( -1 ); |
|
} |
|
|
|
char* xzpFilename = NULL; |
|
|
|
int main( int argc, char **argv ) |
|
{ |
|
::SetHDRMode( false ); |
|
|
|
Msg( "\nValve Software - bspzip.exe (%s)\n", __DATE__ ); |
|
|
|
int curArg = 1; |
|
|
|
// Options parsing assumes |
|
// [ -game foo ] -<action> <action specific args> |
|
|
|
// Skip -game foo |
|
if ( argc >= curArg + 2 && stricmp( argv[curArg], "-game" ) == 0 ) |
|
{ |
|
// Handled by filesystem code |
|
curArg += 2; |
|
} |
|
|
|
// Should have at least action |
|
if ( curArg >= argc ) |
|
{ |
|
// End of args |
|
Usage(); |
|
return 0; |
|
} |
|
|
|
// Pointers to the action, the file, and any action args so I can remove all the messy argc pointer math this was |
|
// using. |
|
char *pAction = argv[curArg]; |
|
curArg++; |
|
char **pActionArgs = &argv[curArg]; |
|
int nActionArgs = argc - curArg; |
|
|
|
CommandLine()->CreateCmdLine( argc, argv ); |
|
|
|
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f ); |
|
if( ( stricmp( pAction, "-extract" ) == 0 ) && nActionArgs == 2 ) |
|
{ |
|
// bspzip -extract <bspfile> <blah.zip> |
|
CmdLib_InitFileSystem( pActionArgs[0] ); |
|
|
|
char bspName[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); |
|
Q_DefaultExtension( bspName, ".bsp", sizeof( bspName ) ); |
|
|
|
char zipName[MAX_PATH] = { 0 }; |
|
V_strncpy( zipName, pActionArgs[1], sizeof( zipName ) ); |
|
Q_DefaultExtension(zipName, ".zip", sizeof( zipName ) ); |
|
|
|
ExtractZipFileFromBSP( bspName, zipName ); |
|
} |
|
else if( ( stricmp( pAction, "-extractfiles" ) == 0 ) && nActionArgs == 2 ) |
|
{ |
|
// bsipzip -extractfiles <bspfile> <targetpath> |
|
CmdLib_InitFileSystem( pActionArgs[0] ); |
|
|
|
// necessary for xbox process |
|
// only the .vtf are extracted as necessary for streaming and not the .vmt |
|
// the .vmt are non-streamed and therefore remain, referenced normally as part of the bsp search path |
|
char bspName[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); |
|
Q_DefaultExtension( bspName, ".bsp", sizeof( bspName ) ); |
|
|
|
char targetPathName[MAX_PATH] = { 0 }; |
|
V_strncpy( targetPathName, pActionArgs[1], sizeof( targetPathName ) ); |
|
Q_AppendSlash( targetPathName, sizeof( targetPathName ) ); |
|
|
|
printf( "\n" ); |
|
printf( "Opening bsp file: %s\n", bspName ); |
|
LoadBSPFile( bspName ); |
|
|
|
CUtlBuffer buf; |
|
char relativeName[MAX_PATH] = { 0 }; |
|
char targetName[MAX_PATH] = { 0 }; |
|
int fileSize = 0; |
|
int id = -1; |
|
int numFilesExtracted = 0; |
|
while(true) |
|
{ |
|
id = GetNextFilename( GetPakFile(), id, relativeName, sizeof(relativeName), fileSize ); |
|
if ( id == -1) |
|
break; |
|
|
|
{ |
|
buf.EnsureCapacity( fileSize ); |
|
buf.SeekPut( CUtlBuffer::SEEK_HEAD, 0 ); |
|
ReadFileFromPak( GetPakFile(), relativeName, false, buf ); |
|
|
|
V_strncpy( targetName, targetPathName, sizeof(targetName) ); |
|
V_strncat( targetName, relativeName, sizeof(targetName) ); |
|
Q_FixSlashes( targetName, '\\' ); |
|
|
|
SafeCreatePath( targetName ); |
|
|
|
printf( "Writing file: %s\n", targetName ); |
|
FILE *fp = fopen( targetName, "wb" ); |
|
if ( !fp ) |
|
{ |
|
printf( "Error: Could not write %s\n", targetName); |
|
exit( -1 ); |
|
} |
|
|
|
fwrite( buf.Base(), fileSize, 1, fp ); |
|
fclose( fp ); |
|
|
|
numFilesExtracted++; |
|
} |
|
} |
|
printf( "%d files extracted.\n", numFilesExtracted ); |
|
} |
|
else if( ( stricmp( pAction, "-extractcubemaps" ) == 0 ) && nActionArgs == 2 ) |
|
{ |
|
// bspzip -extractcubemaps <bspfile> <targetPath> |
|
CmdLib_InitFileSystem( pActionArgs[0] ); |
|
// necessary for xbox process |
|
// only the .vtf are extracted as necessary for streaming and not the .vmt |
|
// the .vmt are non-streamed and therefore remain, referenced normally as part of the bsp search path |
|
char bspName[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); |
|
Q_DefaultExtension( bspName, ".bsp", sizeof( bspName ) ); |
|
|
|
char targetPathName[MAX_PATH] = { 0 }; |
|
V_strncpy( targetPathName, pActionArgs[1], sizeof(targetPathName) ); |
|
Q_AppendSlash( targetPathName, sizeof( targetPathName ) ); |
|
|
|
printf( "\n" ); |
|
printf( "Opening bsp file: %s\n", bspName ); |
|
LoadBSPFile( bspName ); |
|
|
|
CUtlBuffer buf; |
|
char relativeName[MAX_PATH] = { 0 }; |
|
char targetName[MAX_PATH] = { 0 }; |
|
int fileSize = 0; |
|
int id = -1; |
|
int numFilesExtracted = 0; |
|
while (1) |
|
{ |
|
id = GetNextFilename( GetPakFile(), id, relativeName, sizeof(relativeName), fileSize ); |
|
if ( id == -1) |
|
break; |
|
|
|
if ( Q_stristr( relativeName, ".vtf" ) ) |
|
{ |
|
buf.EnsureCapacity( fileSize ); |
|
buf.SeekPut( CUtlBuffer::SEEK_HEAD, 0 ); |
|
ReadFileFromPak( GetPakFile(), relativeName, false, buf ); |
|
|
|
V_strncpy( targetName, targetPathName, sizeof( targetName ) ); |
|
V_strncat( targetName, relativeName, sizeof( targetName ) ); |
|
Q_FixSlashes( targetName, '\\' ); |
|
|
|
SafeCreatePath( targetName ); |
|
|
|
printf( "Writing vtf file: %s\n", targetName ); |
|
FILE *fp = fopen( targetName, "wb" ); |
|
if ( !fp ) |
|
{ |
|
printf( "Error: Could not write %s\n", targetName); |
|
exit( -1 ); |
|
} |
|
|
|
fwrite( buf.Base(), fileSize, 1, fp ); |
|
fclose( fp ); |
|
|
|
numFilesExtracted++; |
|
} |
|
} |
|
printf( "%d cubemaps extracted.\n", numFilesExtracted ); |
|
} |
|
else if( ( stricmp( pAction, "-deletecubemaps" ) == 0 ) && nActionArgs == 1 ) |
|
{ |
|
// bspzip -deletecubemaps <bspfile> |
|
CmdLib_InitFileSystem( pActionArgs[0] ); |
|
// necessary for xbox process |
|
// the cubemaps are deleted as they cannot yet be streamed out of the bsp |
|
char bspName[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); |
|
Q_DefaultExtension( bspName, ".bsp", sizeof( bspName ) ); |
|
|
|
printf( "\n" ); |
|
printf( "Opening bsp file: %s\n", bspName ); |
|
LoadBSPFile( bspName ); |
|
|
|
CUtlBuffer buf; |
|
char relativeName[MAX_PATH] = { 0 }; |
|
int fileSize = 0; |
|
int id = -1; |
|
int numFilesDeleted = 0; |
|
while (1) |
|
{ |
|
id = GetNextFilename( GetPakFile(), id, relativeName, sizeof(relativeName), fileSize ); |
|
if ( id == -1) |
|
break; |
|
|
|
if ( Q_stristr( relativeName, ".vtf" ) ) |
|
{ |
|
RemoveFileFromPak( GetPakFile(), relativeName ); |
|
|
|
numFilesDeleted++; |
|
|
|
// start over |
|
id = -1; |
|
} |
|
} |
|
|
|
printf( "%d cubemaps deleted.\n", numFilesDeleted ); |
|
if ( numFilesDeleted ) |
|
{ |
|
// save out bsp file |
|
printf( "Updating bsp file: %s\n", bspName ); |
|
WriteBSPFile( bspName ); |
|
} |
|
} |
|
else if( ( stricmp( pAction, "-addfiles" ) == 0 ) && nActionArgs == 4 ) |
|
{ |
|
// bspzip -addfiles <bspfile> <relativePathPrefix> <listfile> <newbspfile> |
|
CmdLib_InitFileSystem( pActionArgs[0] ); |
|
char bspName[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); |
|
Q_DefaultExtension( bspName, ".bsp", sizeof( bspName ) ); |
|
|
|
char relativePrefixName[MAX_PATH] = { 0 }; |
|
V_strncpy( relativePrefixName, pActionArgs[1], sizeof( relativePrefixName ) ); |
|
|
|
char filelistName[MAX_PATH] = { 0 }; |
|
V_strncpy( filelistName, pActionArgs[2], sizeof( filelistName ) ); |
|
|
|
char newbspName[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( newbspName, sizeof( newbspName ), pActionArgs[3] ); |
|
Q_DefaultExtension( newbspName, ".bsp", sizeof( newbspName) ); |
|
|
|
char fullpathName[MAX_PATH] = { 0 }; |
|
FILE *fp = fopen(filelistName, "r"); |
|
if ( fp ) |
|
{ |
|
printf("Opening bsp file: %s\n", bspName); |
|
LoadBSPFile(bspName); |
|
|
|
while ( !feof(fp) ) |
|
{ |
|
if ( ( fgets( fullpathName, sizeof( fullpathName ), fp ) != NULL ) ) |
|
{ |
|
if ( *fullpathName && fullpathName[strlen(fullpathName) - 1] == '\n' ) |
|
{ |
|
fullpathName[strlen(fullpathName) - 1] = '\0'; |
|
} |
|
|
|
// strip the path and add relative prefix |
|
char fileName[MAX_PATH] = { 0 }; |
|
char relativeName[MAX_PATH] = { 0 }; |
|
StripPath( fullpathName, fileName, sizeof( fileName ) ); |
|
V_strncpy( relativeName, relativePrefixName, sizeof( relativeName ) ); |
|
V_strncat( relativeName, fileName, sizeof( relativeName ) ); |
|
|
|
printf( "Adding file: %s as %s\n", fullpathName, relativeName ); |
|
|
|
AddFileToPak( GetPakFile(), relativeName, fullpathName ); |
|
} |
|
else if ( !feof( fp ) ) |
|
{ |
|
printf( "Error: Missing full path names\n"); |
|
fclose( fp ); |
|
return( -1 ); |
|
} |
|
} |
|
printf("Writing new bsp file: %s\n", newbspName); |
|
WriteBSPFile(newbspName); |
|
fclose( fp ); |
|
} |
|
} |
|
else if( ( stricmp( pAction, "-dir" ) == 0 ) && nActionArgs == 1 ) |
|
{ |
|
// bspzip -dir <bspfile> |
|
CmdLib_InitFileSystem( pActionArgs[0] ); |
|
char bspName[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); |
|
Q_DefaultExtension (bspName, ".bsp", sizeof( bspName ) ); |
|
LoadBSPFile (bspName); |
|
PrintBSPPackDirectory(); |
|
} |
|
else if( ( stricmp( pAction, "-addfile" ) == 0 ) && nActionArgs == 4 ) |
|
{ |
|
// bspzip -addfile <bspfile> <relativepathname> <fullpathname> <newbspfile> |
|
CmdLib_InitFileSystem( pActionArgs[0] ); |
|
|
|
char bspName[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); |
|
Q_DefaultExtension (bspName, ".bsp", sizeof( bspName ) ); |
|
|
|
char relativeName[MAX_PATH] = { 0 }; |
|
V_strncpy( relativeName, pActionArgs[1], sizeof( relativeName ) ); |
|
|
|
char fullpathName[MAX_PATH] = { 0 }; |
|
V_strncpy( fullpathName, pActionArgs[2], sizeof( fullpathName ) ); |
|
|
|
char newbspName[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( newbspName, sizeof( newbspName ), pActionArgs[3] ); |
|
Q_DefaultExtension (newbspName, ".bsp", sizeof( newbspName ) ); |
|
|
|
// read it in, add pack file, write it back out |
|
LoadBSPFile (bspName); |
|
AddFileToPak( GetPakFile(), relativeName, fullpathName ); |
|
WriteBSPFile(newbspName); |
|
} |
|
else if( ( stricmp( pAction, "-addlist" ) == 0 ) && nActionArgs == 3 ) |
|
{ |
|
// bspzip -addlist <bspfile> <listfile> <newbspfile> |
|
CmdLib_InitFileSystem( pActionArgs[0] ); |
|
|
|
char bspName[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); |
|
Q_DefaultExtension (bspName, ".bsp", sizeof( bspName ) ); |
|
|
|
char filelistName[MAX_PATH] = { 0 }; |
|
V_strncpy( filelistName, pActionArgs[1], sizeof( filelistName ) ); |
|
|
|
char newbspName[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( newbspName, sizeof( newbspName ), pActionArgs[2] ); |
|
Q_DefaultExtension (newbspName, ".bsp", sizeof( newbspName) ); |
|
|
|
// read it in, add pack file, write it back out |
|
|
|
char relativeName[MAX_PATH] = { 0 }; |
|
char fullpathName[MAX_PATH] = { 0 }; |
|
FILE *fp = fopen(filelistName, "r"); |
|
if ( fp ) |
|
{ |
|
printf("Opening bsp file: %s\n", bspName); |
|
LoadBSPFile (bspName); |
|
|
|
while ( !feof(fp) ) |
|
{ |
|
relativeName[ 0 ] = 0; |
|
fullpathName[ 0 ] = 0; |
|
if ( ( fgets( relativeName, sizeof( relativeName ), fp ) != NULL ) && |
|
( fgets( fullpathName, sizeof( fullpathName ), fp ) != NULL ) ) |
|
{ |
|
int l1 = strlen(relativeName); |
|
int l2 = strlen(fullpathName); |
|
if ( l1 > 0 ) |
|
{ |
|
if ( relativeName[ l1 - 1 ] == '\n' ) |
|
{ |
|
relativeName[ l1 - 1 ] = 0; |
|
} |
|
} |
|
if ( l2 > 0 ) |
|
{ |
|
if ( fullpathName[ l2 - 1 ] == '\n' ) |
|
{ |
|
fullpathName[ l2 - 1 ] = 0; |
|
} |
|
} |
|
printf("Adding file: %s\n", fullpathName); |
|
AddFileToPak( GetPakFile(), relativeName, fullpathName ); |
|
} |
|
else if ( !feof( fp ) || ( relativeName[0] && !fullpathName[0] ) ) |
|
{ |
|
printf( "Error: Missing paired relative/full path names\n"); |
|
fclose( fp ); |
|
return( -1 ); |
|
} |
|
} |
|
printf("Writing new bsp file: %s\n", newbspName); |
|
WriteBSPFile(newbspName); |
|
fclose( fp ); |
|
} |
|
} |
|
else if( ( stricmp( pAction, "-addorupdatelist" ) == 0 ) && nActionArgs == 3 ) |
|
{ |
|
// bspzip -addorupdatelist <bspfile> <listfile> <newbspfile> |
|
CmdLib_InitFileSystem( pActionArgs[0] ); |
|
char bspName[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); |
|
Q_DefaultExtension (bspName, ".bsp", sizeof( bspName ) ); |
|
|
|
char filelistName[MAX_PATH] = { 0 }; |
|
V_strncpy( filelistName, pActionArgs[1], sizeof( filelistName ) ); |
|
|
|
char newbspName[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( newbspName, sizeof( newbspName ), pActionArgs[2] ); |
|
Q_DefaultExtension (newbspName, ".bsp", sizeof( newbspName) ); |
|
|
|
// read it in, add pack file, write it back out |
|
|
|
char relativeName[MAX_PATH] = { 0 }; |
|
char fullpathName[MAX_PATH] = { 0 }; |
|
FILE *fp = fopen(filelistName, "r"); |
|
if ( fp ) |
|
{ |
|
printf("Opening bsp file: %s\n", bspName); |
|
LoadBSPFile (bspName); |
|
|
|
while ( !feof(fp) ) |
|
{ |
|
relativeName[ 0 ] = 0; |
|
fullpathName[ 0 ] = 0; |
|
if ( ( fgets( relativeName, sizeof( relativeName ), fp ) != NULL ) && |
|
( fgets( fullpathName, sizeof( fullpathName ), fp ) != NULL ) ) |
|
{ |
|
int l1 = strlen(relativeName); |
|
int l2 = strlen(fullpathName); |
|
if ( l1 > 0 ) |
|
{ |
|
if ( relativeName[ l1 - 1 ] == '\n' ) |
|
{ |
|
relativeName[ l1 - 1 ] = 0; |
|
} |
|
} |
|
if ( l2 > 0 ) |
|
{ |
|
if ( fullpathName[ l2 - 1 ] == '\n' ) |
|
{ |
|
fullpathName[ l2 - 1 ] = 0; |
|
} |
|
} |
|
|
|
bool bUpdating = FileExistsInPak( GetPakFile(), relativeName ); |
|
printf("%s file: %s\n", bUpdating ? "Updating" : "Adding", fullpathName); |
|
if ( bUpdating ) |
|
{ |
|
RemoveFileFromPak( GetPakFile(), relativeName ); |
|
} |
|
AddFileToPak( GetPakFile(), relativeName, fullpathName ); |
|
} |
|
else if ( !feof( fp ) || ( relativeName[0] && !fullpathName[0] ) ) |
|
{ |
|
printf( "Error: Missing paired relative/full path names\n"); |
|
fclose( fp ); |
|
return( -1 ); |
|
} |
|
} |
|
printf("Writing new bsp file: %s\n", newbspName); |
|
WriteBSPFile(newbspName); |
|
fclose( fp ); |
|
} |
|
} |
|
else if( ( stricmp( pAction, "-repack" ) == 0 ) && ( nActionArgs == 1 || nActionArgs == 2 ) ) |
|
{ |
|
// bspzip -repack [ -compress ] <bspfile> |
|
bool bCompress = false; |
|
const char *pFile = pActionArgs[0]; |
|
if ( nActionArgs == 2 && stricmp( pActionArgs[0], "-compress" ) == 0 ) |
|
{ |
|
pFile = pActionArgs[1]; |
|
bCompress = true; |
|
} |
|
else if ( nActionArgs == 2 ) |
|
{ |
|
Usage(); |
|
return 0; |
|
} |
|
|
|
CmdLib_InitFileSystem( pFile ); |
|
char szAbsBSPPath[MAX_PATH] = { 0 }; |
|
Q_MakeAbsolutePath( szAbsBSPPath, sizeof( szAbsBSPPath ), pFile ); |
|
Q_DefaultExtension( szAbsBSPPath, ".bsp", sizeof( szAbsBSPPath ) ); |
|
return RepackBSP( szAbsBSPPath, bCompress ) ? 0 : -1; |
|
} |
|
else |
|
{ |
|
Usage(); |
|
} |
|
return 0; |
|
}
|
|
|