mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-19 12:06:07 +08:00
Sync with upstream (Issue #30).
Recompiled tier1 and mathlib for all platforms will come in next commit.
This commit is contained in:
@ -26,11 +26,13 @@
|
||||
#include "tier0/dbg.h"
|
||||
#include "lumpfiles.h"
|
||||
#include "vtf/vtf.h"
|
||||
#include "lzma/lzma.h"
|
||||
#include "tier1/lzmaDecoder.h"
|
||||
|
||||
//=============================================================================
|
||||
|
||||
// Boundary each lump should be aligned to
|
||||
#define LUMP_ALIGNMENT 4
|
||||
#define LUMP_ALIGNMENT 4
|
||||
|
||||
// Data descriptions for byte swapping - only needed
|
||||
// for structures that are written to file for use by the game.
|
||||
@ -45,7 +47,7 @@ BEGIN_BYTESWAP_DATADESC( lump_t )
|
||||
DEFINE_FIELD( fileofs, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( filelen, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( version, FIELD_INTEGER ),
|
||||
DEFINE_ARRAY( fourCC, FIELD_CHARACTER, 4 ),
|
||||
DEFINE_FIELD( uncompressedSize, FIELD_INTEGER ),
|
||||
END_BYTESWAP_DATADESC()
|
||||
|
||||
BEGIN_BYTESWAP_DATADESC( dflagslump_t )
|
||||
@ -815,9 +817,10 @@ void ClearPakFile( IZip *pak )
|
||||
// Input : *relativename -
|
||||
// *fullpath -
|
||||
//-----------------------------------------------------------------------------
|
||||
void AddFileToPak( IZip *pak, const char *relativename, const char *fullpath )
|
||||
void AddFileToPak( IZip *pak, const char *relativename, const char *fullpath, IZip::eCompressionType compressionType )
|
||||
{
|
||||
pak->AddFileToZip( relativename, fullpath );
|
||||
DevMsg( "Adding file to pakfile [ %s ]\n", fullpath );
|
||||
pak->AddFileToZip( relativename, fullpath, compressionType );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -826,9 +829,65 @@ void AddFileToPak( IZip *pak, const char *relativename, const char *fullpath )
|
||||
// *data -
|
||||
// length -
|
||||
//-----------------------------------------------------------------------------
|
||||
void AddBufferToPak( IZip *pak, const char *pRelativeName, void *data, int length, bool bTextMode )
|
||||
void AddBufferToPak( IZip *pak, const char *pRelativeName, void *data, int length, bool bTextMode, IZip::eCompressionType compressionType )
|
||||
{
|
||||
pak->AddBufferToZip( pRelativeName, data, length, bTextMode );
|
||||
pak->AddBufferToZip( pRelativeName, data, length, bTextMode, compressionType );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Add entire directory to .bsp PAK lump as named file
|
||||
// Input : *relativename -
|
||||
// *data -
|
||||
// length -
|
||||
//-----------------------------------------------------------------------------
|
||||
void AddDirToPak( IZip *pak, const char *pDirPath, const char *pPakPrefix )
|
||||
{
|
||||
if ( !g_pFullFileSystem->IsDirectory( pDirPath ) )
|
||||
{
|
||||
Warning( "Passed non-directory to AddDirToPak [ %s ]\n", pDirPath );
|
||||
return;
|
||||
}
|
||||
|
||||
DevMsg( "Adding directory to pakfile [ %s ]\n", pDirPath );
|
||||
|
||||
// Enumerate dir
|
||||
char szEnumerateDir[MAX_PATH] = { 0 };
|
||||
V_snprintf( szEnumerateDir, sizeof( szEnumerateDir ), "%s/*.*", pDirPath );
|
||||
V_FixSlashes( szEnumerateDir );
|
||||
|
||||
FileFindHandle_t handle;
|
||||
const char *szFindResult = g_pFullFileSystem->FindFirst( szEnumerateDir, &handle );
|
||||
do
|
||||
{
|
||||
if ( szFindResult[0] != '.' )
|
||||
{
|
||||
char szPakName[MAX_PATH] = { 0 };
|
||||
char szFullPath[MAX_PATH] = { 0 };
|
||||
if ( pPakPrefix )
|
||||
{
|
||||
V_snprintf( szPakName, sizeof( szPakName ), "%s/%s", pPakPrefix, szFindResult );
|
||||
}
|
||||
else
|
||||
{
|
||||
V_strncpy( szPakName, szFindResult, sizeof( szPakName ) );
|
||||
}
|
||||
V_snprintf( szFullPath, sizeof( szFullPath ), "%s/%s", pDirPath, szFindResult );
|
||||
V_FixDoubleSlashes( szFullPath );
|
||||
V_FixDoubleSlashes( szPakName );
|
||||
|
||||
if ( g_pFullFileSystem->FindIsDirectory( handle ) )
|
||||
{
|
||||
// Recurse
|
||||
AddDirToPak( pak, szFullPath, szPakName );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just add this file
|
||||
AddFileToPak( pak, szPakName, szFullPath );
|
||||
}
|
||||
}
|
||||
szFindResult = g_pFullFileSystem->FindNext( handle );
|
||||
} while ( szFindResult);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1290,14 +1349,11 @@ static void AddOcclusionLump( )
|
||||
3 * sizeof(int);
|
||||
|
||||
lump_t *lump = &g_pBSPHeader->lumps[LUMP_OCCLUSION];
|
||||
|
||||
|
||||
lump->fileofs = g_pFileSystem->Tell( g_hBSPFile );
|
||||
lump->filelen = nLumpLength;
|
||||
lump->version = LUMP_OCCLUSION_VERSION;
|
||||
lump->fourCC[0] = ( char )0;
|
||||
lump->fourCC[1] = ( char )0;
|
||||
lump->fourCC[2] = ( char )0;
|
||||
lump->fourCC[3] = ( char )0;
|
||||
lump->uncompressedSize = 0;
|
||||
|
||||
// Data is swapped in place, so the 'Count' variables aren't safe to use after they're written
|
||||
WriteData( FIELD_INTEGER, &nOccluderCount );
|
||||
@ -2484,14 +2540,11 @@ static void AddLumpInternal( int lumpnum, void *data, int len, int version )
|
||||
g_Lumps.size[lumpnum] = 0; // mark it written
|
||||
|
||||
lump = &g_pBSPHeader->lumps[lumpnum];
|
||||
|
||||
|
||||
lump->fileofs = g_pFileSystem->Tell( g_hBSPFile );
|
||||
lump->filelen = len;
|
||||
lump->version = version;
|
||||
lump->fourCC[0] = ( char )0;
|
||||
lump->fourCC[1] = ( char )0;
|
||||
lump->fourCC[2] = ( char )0;
|
||||
lump->fourCC[3] = ( char )0;
|
||||
lump->uncompressedSize = 0;
|
||||
|
||||
SafeWrite( g_hBSPFile, data, len );
|
||||
|
||||
@ -3705,19 +3758,6 @@ void BuildClusterTable( void )
|
||||
}
|
||||
}
|
||||
|
||||
// There's a version of this in host.cpp!!! Make sure that they match.
|
||||
void GetPlatformMapPath( const char *pMapPath, char *pPlatformMapPath, int dxlevel, int maxLength )
|
||||
{
|
||||
Q_StripExtension( pMapPath, pPlatformMapPath, maxLength );
|
||||
|
||||
// if( dxlevel <= 60 )
|
||||
// {
|
||||
// Q_strncat( pPlatformMapPath, "_dx60", maxLength, COPY_ALL_CHARACTERS );
|
||||
// }
|
||||
|
||||
Q_strncat( pPlatformMapPath, ".bsp", maxLength, COPY_ALL_CHARACTERS );
|
||||
}
|
||||
|
||||
// There's a version of this in checksum_engine.cpp!!! Make sure that they match.
|
||||
static bool CRC_MapFile(CRC32_t *crcvalue, const char *pszFileName)
|
||||
{
|
||||
@ -3979,7 +4019,7 @@ void ConvertPakFileContents( const char *pInFilename )
|
||||
if ( !bConverted )
|
||||
{
|
||||
// straight copy
|
||||
AddBufferToPak( newPakFile, relativeName, sourceBuf.Base(), sourceBuf.TellMaxPut(), false );
|
||||
AddBufferToPak( newPakFile, relativeName, sourceBuf.Base(), sourceBuf.TellMaxPut(), false, IZip::eCompressionType_None );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3987,7 +4027,7 @@ void ConvertPakFileContents( const char *pInFilename )
|
||||
V_StripExtension( relativeName, relativeName, sizeof( relativeName ) );
|
||||
V_strcat( relativeName, ".360", sizeof( relativeName ) );
|
||||
V_strcat( relativeName, pExt, sizeof( relativeName ) );
|
||||
AddBufferToPak( newPakFile, relativeName, targetBuf.Base(), targetBuf.TellMaxPut(), false );
|
||||
AddBufferToPak( newPakFile, relativeName, targetBuf.Base(), targetBuf.TellMaxPut(), false, IZip::eCompressionType_None );
|
||||
}
|
||||
|
||||
if ( V_stristr( relativeName, ".hdr" ) || V_stristr( relativeName, "_hdr" ) )
|
||||
@ -4407,21 +4447,28 @@ bool CompressGameLump( dheader_t *pInBSPHeader, dheader_t *pOutBSPHeader, CUtlBu
|
||||
dgamelumpheader_t* pInGameLumpHeader = (dgamelumpheader_t*)(((byte *)pInBSPHeader) + pInBSPHeader->lumps[LUMP_GAME_LUMP].fileofs);
|
||||
dgamelump_t* pInGameLump = (dgamelump_t*)(pInGameLumpHeader + 1);
|
||||
|
||||
byteSwap.ActivateByteSwapping( true );
|
||||
byteSwap.SwapFieldsToTargetEndian( pInGameLumpHeader );
|
||||
byteSwap.SwapFieldsToTargetEndian( pInGameLump, pInGameLumpHeader->lumpCount );
|
||||
if ( IsX360() )
|
||||
{
|
||||
byteSwap.ActivateByteSwapping( true );
|
||||
byteSwap.SwapFieldsToTargetEndian( pInGameLumpHeader );
|
||||
byteSwap.SwapFieldsToTargetEndian( pInGameLump, pInGameLumpHeader->lumpCount );
|
||||
}
|
||||
|
||||
unsigned int newOffset = outputBuffer.TellPut();
|
||||
outputBuffer.Put( pInGameLumpHeader, sizeof( dgamelumpheader_t ) );
|
||||
outputBuffer.Put( pInGameLump, pInGameLumpHeader->lumpCount * sizeof( dgamelump_t ) );
|
||||
// Make room for gamelump header and gamelump structs, which we'll write at the end
|
||||
outputBuffer.SeekPut( CUtlBuffer::SEEK_CURRENT, sizeof( dgamelumpheader_t ) );
|
||||
outputBuffer.SeekPut( CUtlBuffer::SEEK_CURRENT, pInGameLumpHeader->lumpCount * sizeof( dgamelump_t ) );
|
||||
|
||||
dgamelumpheader_t* pOutGameLumpHeader = (dgamelumpheader_t*)((byte *)outputBuffer.Base() + newOffset);
|
||||
dgamelump_t* pOutGameLump = (dgamelump_t*)(pOutGameLumpHeader + 1);
|
||||
// Start with input lumps, and fixup
|
||||
dgamelumpheader_t sOutGameLumpHeader = *pInGameLumpHeader;
|
||||
CUtlBuffer sOutGameLumpBuf;
|
||||
sOutGameLumpBuf.Put( pInGameLump, pInGameLumpHeader->lumpCount * sizeof( dgamelump_t ) );
|
||||
dgamelump_t *sOutGameLump = (dgamelump_t *)sOutGameLumpBuf.Base();
|
||||
|
||||
// add a dummy terminal gamelump
|
||||
// purposely NOT updating the .filelen to reflect the compressed size, but leaving as original size
|
||||
// callers use the next entry offset to determine compressed size
|
||||
pOutGameLumpHeader->lumpCount++;
|
||||
sOutGameLumpHeader.lumpCount++;
|
||||
dgamelump_t dummyLump = { 0 };
|
||||
outputBuffer.Put( &dummyLump, sizeof( dgamelump_t ) );
|
||||
|
||||
@ -4430,62 +4477,130 @@ bool CompressGameLump( dheader_t *pInBSPHeader, dheader_t *pOutBSPHeader, CUtlBu
|
||||
CUtlBuffer inputBuffer;
|
||||
CUtlBuffer compressedBuffer;
|
||||
|
||||
pOutGameLump[i].fileofs = AlignBuffer( outputBuffer, 4 );
|
||||
sOutGameLump[i].fileofs = AlignBuffer( outputBuffer, 4 );
|
||||
|
||||
if ( pInGameLump[i].filelen )
|
||||
{
|
||||
inputBuffer.SetExternalBuffer( ((byte *)pInBSPHeader) + pInGameLump[i].fileofs, pInGameLump[i].filelen, pInGameLump[i].filelen );
|
||||
if ( pInGameLump[i].flags & GAMELUMPFLAG_COMPRESSED )
|
||||
{
|
||||
byte *pCompressedLump = ((byte *)pInBSPHeader) + pInGameLump[i].fileofs;
|
||||
if ( CLZMA::IsCompressed( pCompressedLump ) )
|
||||
{
|
||||
inputBuffer.EnsureCapacity( CLZMA::GetActualSize( pCompressedLump ) );
|
||||
unsigned int outSize = CLZMA::Uncompress( pCompressedLump, (unsigned char *)inputBuffer.Base() );
|
||||
inputBuffer.SeekPut( CUtlBuffer::SEEK_CURRENT, outSize );
|
||||
if ( outSize != CLZMA::GetActualSize( pCompressedLump ) )
|
||||
{
|
||||
Warning( "Decompressed size differs from header, BSP may be corrupt\n" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( CLZMA::IsCompressed( pCompressedLump ) );
|
||||
Warning( "Unsupported BSP: Unrecognized compressed game lump\n" );
|
||||
}
|
||||
|
||||
bool bCompressed = pCompressFunc( inputBuffer, compressedBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
inputBuffer.SetExternalBuffer( ((byte *)pInBSPHeader) + pInGameLump[i].fileofs,
|
||||
pInGameLump[i].filelen, pInGameLump[i].filelen );
|
||||
}
|
||||
|
||||
bool bCompressed = pCompressFunc ? pCompressFunc( inputBuffer, compressedBuffer ) : false;
|
||||
if ( bCompressed )
|
||||
{
|
||||
pOutGameLump[i].flags |= GAMELUMPFLAG_COMPRESSED;
|
||||
sOutGameLump[i].flags |= GAMELUMPFLAG_COMPRESSED;
|
||||
|
||||
outputBuffer.Put( compressedBuffer.Base(), compressedBuffer.TellPut() );
|
||||
compressedBuffer.Purge();
|
||||
}
|
||||
else
|
||||
{
|
||||
// as is
|
||||
// as is, clear compression flag from input lump
|
||||
sOutGameLump[i].flags &= ~GAMELUMPFLAG_COMPRESSED;
|
||||
outputBuffer.Put( inputBuffer.Base(), inputBuffer.TellPut() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fix the dummy terminal lump
|
||||
int lastLump = pOutGameLumpHeader->lumpCount-1;
|
||||
pOutGameLump[lastLump].fileofs = outputBuffer.TellPut();
|
||||
int lastLump = sOutGameLumpHeader.lumpCount-1;
|
||||
sOutGameLump[lastLump].fileofs = outputBuffer.TellPut();
|
||||
|
||||
// fix the output for 360, swapping it back
|
||||
byteSwap.SwapFieldsToTargetEndian( pOutGameLump, pOutGameLumpHeader->lumpCount );
|
||||
byteSwap.SwapFieldsToTargetEndian( pOutGameLumpHeader );
|
||||
if ( IsX360() )
|
||||
{
|
||||
// fix the output for 360, swapping it back
|
||||
byteSwap.SwapFieldsToTargetEndian( sOutGameLump, sOutGameLumpHeader.lumpCount );
|
||||
byteSwap.SwapFieldsToTargetEndian( &sOutGameLumpHeader );
|
||||
}
|
||||
|
||||
pOutBSPHeader->lumps[LUMP_GAME_LUMP].fileofs = newOffset;
|
||||
pOutBSPHeader->lumps[LUMP_GAME_LUMP].filelen = outputBuffer.TellPut() - newOffset;
|
||||
// We set GAMELUMPFLAG_COMPRESSED and handle compression at the sub-lump level, this whole lump is not
|
||||
// decompressable as a block.
|
||||
pOutBSPHeader->lumps[LUMP_GAME_LUMP].uncompressedSize = 0;
|
||||
|
||||
// Rewind to start and write lump headers
|
||||
unsigned int endOffset = outputBuffer.TellPut();
|
||||
outputBuffer.SeekPut( CUtlBuffer::SEEK_HEAD, newOffset );
|
||||
outputBuffer.Put( &sOutGameLumpHeader, sizeof( dgamelumpheader_t ) );
|
||||
outputBuffer.Put( sOutGameLumpBuf.Base(), sOutGameLumpBuf.TellPut() );
|
||||
outputBuffer.SeekPut( CUtlBuffer::SEEK_HEAD, endOffset );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CompressBSP( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer, CompressFunc_t pCompressFunc )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compress callback for RepackBSP
|
||||
//-----------------------------------------------------------------------------
|
||||
bool RepackBSPCallback_LZMA( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer )
|
||||
{
|
||||
CByteswap byteSwap;
|
||||
|
||||
dheader_t *pInBSPHeader = (dheader_t *)inputBuffer.Base();
|
||||
if ( pInBSPHeader->ident != BigLong( IDBSPHEADER ) || !pCompressFunc )
|
||||
if ( !inputBuffer.TellPut() )
|
||||
{
|
||||
// only compress 360 bsp's
|
||||
// nothing to do
|
||||
return false;
|
||||
}
|
||||
|
||||
// bsp is 360, swap the header back
|
||||
byteSwap.ActivateByteSwapping( true );
|
||||
byteSwap.SwapFieldsToTargetEndian( pInBSPHeader );
|
||||
unsigned int originalSize = inputBuffer.TellPut() - inputBuffer.TellGet();
|
||||
unsigned int compressedSize = 0;
|
||||
unsigned char *pCompressedOutput = LZMA_Compress( (unsigned char *)inputBuffer.Base() + inputBuffer.TellGet(),
|
||||
originalSize, &compressedSize );
|
||||
if ( pCompressedOutput )
|
||||
{
|
||||
outputBuffer.Put( pCompressedOutput, compressedSize );
|
||||
DevMsg( "Compressed bsp lump %u -> %u bytes\n", originalSize, compressedSize );
|
||||
free( pCompressedOutput );
|
||||
return true;
|
||||
}
|
||||
|
||||
// output will be smaller, use input size as upper bound
|
||||
outputBuffer.EnsureCapacity( inputBuffer.TellMaxPut() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool RepackBSP( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer, CompressFunc_t pCompressFunc, IZip::eCompressionType packfileCompression )
|
||||
{
|
||||
dheader_t *pInBSPHeader = (dheader_t *)inputBuffer.Base();
|
||||
// The 360 swaps this header to disk. For some reason.
|
||||
if ( pInBSPHeader->ident != ( IsX360() ? BigLong( IDBSPHEADER ) : IDBSPHEADER ) )
|
||||
{
|
||||
Warning( "RepackBSP given invalid input data\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
CByteswap byteSwap;
|
||||
if ( IsX360() )
|
||||
{
|
||||
// bsp is 360, swap the header back
|
||||
byteSwap.ActivateByteSwapping( true );
|
||||
byteSwap.SwapFieldsToTargetEndian( pInBSPHeader );
|
||||
}
|
||||
|
||||
unsigned int headerOffset = outputBuffer.TellPut();
|
||||
outputBuffer.Put( pInBSPHeader, sizeof( dheader_t ) );
|
||||
|
||||
dheader_t *pOutBSPHeader = (dheader_t *)outputBuffer.Base();
|
||||
// This buffer grows dynamically, don't keep pointers to it around. Write out header at end.
|
||||
dheader_t sOutBSPHeader = *pInBSPHeader;
|
||||
|
||||
// must adhere to input lump's offset order and process according to that, NOT lump num
|
||||
// sort by offset order
|
||||
@ -4504,12 +4619,13 @@ bool CompressBSP( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer, CompressFun
|
||||
SortedLump_t *pSortedLump = &sortedLumps[i];
|
||||
int lumpNum = pSortedLump->lumpNum;
|
||||
|
||||
if ( !pSortedLump->pLump->filelen )
|
||||
{
|
||||
// degenerate
|
||||
pOutBSPHeader->lumps[lumpNum].fileofs = 0;
|
||||
}
|
||||
else
|
||||
// Should be set below, don't copy over old data
|
||||
sOutBSPHeader.lumps[lumpNum].fileofs = 0;
|
||||
sOutBSPHeader.lumps[lumpNum].filelen = 0;
|
||||
// Only set by compressed lumps
|
||||
sOutBSPHeader.lumps[lumpNum].uncompressedSize = 0;
|
||||
|
||||
if ( pSortedLump->pLump->filelen ) // Otherwise its degenerate
|
||||
{
|
||||
int alignment = 4;
|
||||
if ( lumpNum == LUMP_PAKFILE )
|
||||
@ -4518,49 +4634,114 @@ bool CompressBSP( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer, CompressFun
|
||||
}
|
||||
unsigned int newOffset = AlignBuffer( outputBuffer, alignment );
|
||||
|
||||
// only set by compressed lumps, hides the uncompressed size
|
||||
*((unsigned int *)pOutBSPHeader->lumps[lumpNum].fourCC) = 0;
|
||||
|
||||
CUtlBuffer inputBuffer;
|
||||
inputBuffer.SetExternalBuffer( ((byte *)pInBSPHeader) + pSortedLump->pLump->fileofs, pSortedLump->pLump->filelen, pSortedLump->pLump->filelen );
|
||||
if ( pSortedLump->pLump->uncompressedSize )
|
||||
{
|
||||
byte *pCompressedLump = ((byte *)pInBSPHeader) + pSortedLump->pLump->fileofs;
|
||||
if ( CLZMA::IsCompressed( pCompressedLump ) && pSortedLump->pLump->uncompressedSize == CLZMA::GetActualSize( pCompressedLump ) )
|
||||
{
|
||||
inputBuffer.EnsureCapacity( CLZMA::GetActualSize( pCompressedLump ) );
|
||||
unsigned int outSize = CLZMA::Uncompress( pCompressedLump, (unsigned char *)inputBuffer.Base() );
|
||||
inputBuffer.SeekPut( CUtlBuffer::SEEK_CURRENT, outSize );
|
||||
if ( outSize != pSortedLump->pLump->uncompressedSize )
|
||||
{
|
||||
Warning( "Decompressed size differs from header, BSP may be corrupt\n" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( CLZMA::IsCompressed( pCompressedLump ) &&
|
||||
pSortedLump->pLump->uncompressedSize == CLZMA::GetActualSize( pCompressedLump ) );
|
||||
Warning( "Unsupported BSP: Unrecognized compressed lump\n" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just use input
|
||||
inputBuffer.SetExternalBuffer( ((byte *)pInBSPHeader) + pSortedLump->pLump->fileofs,
|
||||
pSortedLump->pLump->filelen, pSortedLump->pLump->filelen );
|
||||
}
|
||||
|
||||
if ( lumpNum == LUMP_GAME_LUMP )
|
||||
{
|
||||
// the game lump has to have each of its components individually compressed
|
||||
CompressGameLump( pInBSPHeader, pOutBSPHeader, outputBuffer, pCompressFunc );
|
||||
CompressGameLump( pInBSPHeader, &sOutBSPHeader, outputBuffer, pCompressFunc );
|
||||
}
|
||||
else if ( lumpNum == LUMP_PAKFILE )
|
||||
{
|
||||
// add as is
|
||||
pOutBSPHeader->lumps[lumpNum].fileofs = newOffset;
|
||||
outputBuffer.Put( inputBuffer.Base(), inputBuffer.TellPut() );
|
||||
IZip *newPakFile = IZip::CreateZip( NULL );
|
||||
IZip *oldPakFile = IZip::CreateZip( NULL );
|
||||
oldPakFile->ParseFromBuffer( inputBuffer.Base(), inputBuffer.Size() );
|
||||
|
||||
int id = -1;
|
||||
int fileSize;
|
||||
while ( 1 )
|
||||
{
|
||||
char relativeName[MAX_PATH];
|
||||
id = GetNextFilename( oldPakFile, id, relativeName, sizeof( relativeName ), fileSize );
|
||||
if ( id == -1 )
|
||||
break;
|
||||
|
||||
CUtlBuffer sourceBuf;
|
||||
CUtlBuffer targetBuf;
|
||||
|
||||
bool bOK = ReadFileFromPak( oldPakFile, relativeName, false, sourceBuf );
|
||||
if ( !bOK )
|
||||
{
|
||||
Error( "Failed to load '%s' from lump pak for repacking.\n", relativeName );
|
||||
continue;
|
||||
}
|
||||
|
||||
AddBufferToPak( newPakFile, relativeName, sourceBuf.Base(), sourceBuf.TellMaxPut(), false, packfileCompression );
|
||||
|
||||
DevMsg( "Repacking BSP: Created '%s' in lump pak\n", relativeName );
|
||||
}
|
||||
|
||||
// save new pack to buffer
|
||||
newPakFile->SaveToBuffer( outputBuffer );
|
||||
sOutBSPHeader.lumps[lumpNum].fileofs = newOffset;
|
||||
sOutBSPHeader.lumps[lumpNum].filelen = outputBuffer.TellPut() - newOffset;
|
||||
// Note that this *lump* is uncompressed, it just contains a packfile that uses compression, so we're
|
||||
// not setting lumps[lumpNum].uncompressedSize
|
||||
|
||||
IZip::ReleaseZip( oldPakFile );
|
||||
IZip::ReleaseZip( newPakFile );
|
||||
}
|
||||
else
|
||||
{
|
||||
CUtlBuffer compressedBuffer;
|
||||
bool bCompressed = pCompressFunc( inputBuffer, compressedBuffer );
|
||||
bool bCompressed = pCompressFunc ? pCompressFunc( inputBuffer, compressedBuffer ) : false;
|
||||
if ( bCompressed )
|
||||
{
|
||||
// placing the uncompressed size in the unused fourCC, will decode at runtime
|
||||
*((unsigned int *)pOutBSPHeader->lumps[lumpNum].fourCC) = BigLong( inputBuffer.TellPut() );
|
||||
pOutBSPHeader->lumps[lumpNum].filelen = compressedBuffer.TellPut();
|
||||
pOutBSPHeader->lumps[lumpNum].fileofs = newOffset;
|
||||
sOutBSPHeader.lumps[lumpNum].uncompressedSize = inputBuffer.TellPut();
|
||||
sOutBSPHeader.lumps[lumpNum].filelen = compressedBuffer.TellPut();
|
||||
sOutBSPHeader.lumps[lumpNum].fileofs = newOffset;
|
||||
outputBuffer.Put( compressedBuffer.Base(), compressedBuffer.TellPut() );
|
||||
compressedBuffer.Purge();
|
||||
}
|
||||
else
|
||||
{
|
||||
// add as is
|
||||
pOutBSPHeader->lumps[lumpNum].fileofs = newOffset;
|
||||
sOutBSPHeader.lumps[lumpNum].fileofs = newOffset;
|
||||
sOutBSPHeader.lumps[lumpNum].filelen = inputBuffer.TellPut();
|
||||
outputBuffer.Put( inputBuffer.Base(), inputBuffer.TellPut() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fix the output for 360, swapping it back
|
||||
byteSwap.SetTargetBigEndian( true );
|
||||
byteSwap.SwapFieldsToTargetEndian( pOutBSPHeader );
|
||||
if ( IsX360() )
|
||||
{
|
||||
// fix the output for 360, swapping it back
|
||||
byteSwap.SetTargetBigEndian( true );
|
||||
byteSwap.SwapFieldsToTargetEndian( &sOutBSPHeader );
|
||||
}
|
||||
|
||||
// Write out header
|
||||
unsigned int endOffset = outputBuffer.TellPut();
|
||||
outputBuffer.SeekPut( CUtlBuffer::SEEK_HEAD, headerOffset );
|
||||
outputBuffer.Put( &sOutBSPHeader, sizeof( sOutBSPHeader ) );
|
||||
outputBuffer.SeekPut( CUtlBuffer::SEEK_HEAD, endOffset );
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -4768,12 +4949,12 @@ bool SwapBSPFile( const char *pInFilename, const char *pOutFilename, bool bSwapO
|
||||
}
|
||||
|
||||
CUtlBuffer outputBuffer;
|
||||
if ( !CompressBSP( inputBuffer, outputBuffer, pCompressFunc ) )
|
||||
if ( !RepackBSP( inputBuffer, outputBuffer, pCompressFunc, IZip::eCompressionType_None ) )
|
||||
{
|
||||
Warning( "Error! Failed to compress BSP '%s'!\n", pOutFilename );
|
||||
Warning( "Error! Failed to compress BSP '%s'!\n", pOutFilename );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
g_hBSPFile = SafeOpenWrite( pOutFilename );
|
||||
if ( !g_hBSPFile )
|
||||
{
|
||||
|
Reference in New Issue
Block a user