Replace snappy with trained zstd dictionary
This commit is contained in:
parent
5036c0b09d
commit
1a3e348316
17 changed files with 270 additions and 64 deletions
BIN
css_zstd_training_set.dictionary
Normal file
BIN
css_zstd_training_set.dictionary
Normal file
Binary file not shown.
BIN
css_zstd_training_set.tar.gz
Normal file
BIN
css_zstd_training_set.tar.gz
Normal file
Binary file not shown.
|
@ -9,12 +9,16 @@
|
||||||
#include "host.h"
|
#include "host.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
|
#include "strtools.h"
|
||||||
|
#include "sysexternal.h"
|
||||||
|
#include "utlbuffer.h"
|
||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include <edict.h>
|
#include <edict.h>
|
||||||
#include <coordsize.h>
|
#include <coordsize.h>
|
||||||
#include <characterset.h>
|
#include <characterset.h>
|
||||||
#include <bitbuf.h>
|
#include <bitbuf.h>
|
||||||
|
#include <mutex>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#ifdef OSX
|
#ifdef OSX
|
||||||
#include <malloc/malloc.h>
|
#include <malloc/malloc.h>
|
||||||
|
@ -44,6 +48,8 @@
|
||||||
#include <vgui/ILocalize.h>
|
#include <vgui/ILocalize.h>
|
||||||
#include "tier1/lzss.h"
|
#include "tier1/lzss.h"
|
||||||
#include "tier1/snappy.h"
|
#include "tier1/snappy.h"
|
||||||
|
#include "zstd.h"
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
// memdbgon must be the last include file in a .cpp file!!!
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
#include "tier0/memdbgon.h"
|
#include "tier0/memdbgon.h"
|
||||||
|
@ -1292,6 +1298,160 @@ bool COM_BufferToBufferCompress_Snappy( void *dest, unsigned int *destLen, const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int COM_GetIdealDestinationCompressionBufferSize_ZSTD(
|
||||||
|
unsigned int uncompressedSize)
|
||||||
|
{
|
||||||
|
return 4 + ZSTD_compressBound(uncompressedSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr int ZSTD_COMPRESSION_LEVEL = 999;
|
||||||
|
static auto g_pZSTDCCtx = ZSTD_createCCtx();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static T* GetZSTD_CDictionary()
|
||||||
|
{
|
||||||
|
static T* dict = nullptr;
|
||||||
|
static constexpr auto dictionaryFilePath = "bin/zstd.dictionary";
|
||||||
|
|
||||||
|
static std::once_flag flag;
|
||||||
|
std::call_once(flag,
|
||||||
|
[&]
|
||||||
|
{
|
||||||
|
CUtlBuffer buffer;
|
||||||
|
if (!g_pFileSystem->ReadFile(dictionaryFilePath,
|
||||||
|
"DEFAULT_WRITE_PATH",
|
||||||
|
buffer))
|
||||||
|
{
|
||||||
|
Sys_Error("g_pZSTDInfo: could not find "
|
||||||
|
"dictionary at %s!\n",
|
||||||
|
dictionaryFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (std::is_same<T, ZSTD_CDict>::value)
|
||||||
|
{
|
||||||
|
dict = ZSTD_createCDict(buffer.Base(),
|
||||||
|
buffer.Size(),
|
||||||
|
ZSTD_COMPRESSION_LEVEL);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same<T, ZSTD_DDict>::value)
|
||||||
|
{
|
||||||
|
dict = ZSTD_createDDict(buffer.Base(),
|
||||||
|
buffer.Size());
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorIfNot(dict != NULL, ("GetZSTD_Dictionary() failed!\n"));
|
||||||
|
});
|
||||||
|
|
||||||
|
return dict;
|
||||||
|
};
|
||||||
|
|
||||||
|
void* COM_CompressBuffer_ZSTD(const void* source,
|
||||||
|
unsigned int sourceLen,
|
||||||
|
unsigned int* compressedLen,
|
||||||
|
unsigned int maxCompressedLen)
|
||||||
|
{
|
||||||
|
Assert( source );
|
||||||
|
Assert( compressedLen );
|
||||||
|
|
||||||
|
// Allocate a buffer big enough to hold the worst case.
|
||||||
|
unsigned nMaxCompressedSize = COM_GetIdealDestinationCompressionBufferSize_ZSTD( sourceLen );
|
||||||
|
char *pCompressed = (char*)malloc( nMaxCompressedSize );
|
||||||
|
if ( pCompressed == NULL )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Do the compression
|
||||||
|
*(uint32 *)pCompressed = ZSTD_ID;
|
||||||
|
size_t compressed_length = ZSTD_compress_usingCDict(
|
||||||
|
g_pZSTDCCtx,
|
||||||
|
pCompressed + sizeof(uint32),
|
||||||
|
nMaxCompressedSize,
|
||||||
|
(const char*)source,
|
||||||
|
sourceLen,
|
||||||
|
GetZSTD_CDictionary<ZSTD_CDict>());
|
||||||
|
compressed_length += 4;
|
||||||
|
Assert( compressed_length <= nMaxCompressedSize );
|
||||||
|
|
||||||
|
// Check if this result is OK
|
||||||
|
if ( (maxCompressedLen != 0 && compressed_length > maxCompressedLen) || ZSTD_isError(compressed_length) )
|
||||||
|
{
|
||||||
|
free( pCompressed );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*compressedLen = compressed_length;
|
||||||
|
return pCompressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool COM_BufferToBufferCompress_ZSTD(void* dest,
|
||||||
|
unsigned int* destLen,
|
||||||
|
const void* source,
|
||||||
|
unsigned int sourceLen)
|
||||||
|
{
|
||||||
|
Assert( dest );
|
||||||
|
Assert( destLen );
|
||||||
|
Assert( source );
|
||||||
|
|
||||||
|
//#define ZSTD_GENERATE_TRAINING_SET
|
||||||
|
|
||||||
|
#ifdef ZSTD_GENERATE_TRAINING_SET
|
||||||
|
static int zstdTrainingSetCount = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ZSTD_GENERATE_TRAINING_SET
|
||||||
|
char fileName[64];
|
||||||
|
#ifdef SWDS
|
||||||
|
const auto strContext = "dedicated";
|
||||||
|
#else
|
||||||
|
const auto strContext = "client";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
V_sprintf_safe(fileName, "css_zstd_training_set/%s_%i.bin", strContext, zstdTrainingSetCount++);
|
||||||
|
CUtlBuffer buffer;
|
||||||
|
buffer.CopyBuffer(source, sourceLen);
|
||||||
|
static std::once_flag flag;
|
||||||
|
std::call_once(flag, [&]{g_pFileSystem->CreateDirHierarchy("css_zstd_training_set", "DEFAULT_WRITE_PATH");});
|
||||||
|
g_pFileSystem->WriteFile(fileName, NULL, buffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Check if we need to use a temporary buffer
|
||||||
|
unsigned nMaxCompressedSize = COM_GetIdealDestinationCompressionBufferSize_ZSTD( sourceLen );
|
||||||
|
unsigned compressedLen = *destLen;
|
||||||
|
if ( compressedLen < nMaxCompressedSize )
|
||||||
|
{
|
||||||
|
|
||||||
|
// Yep. Use the other function to allocate the buffer of the right size and comrpess into it
|
||||||
|
void *temp = COM_CompressBuffer_ZSTD( source, sourceLen, &compressedLen, compressedLen );
|
||||||
|
if ( temp == NULL )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Copy over the data
|
||||||
|
V_memcpy( dest, temp, compressedLen );
|
||||||
|
*destLen = compressedLen;
|
||||||
|
free( temp );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have room and should be able to compress directly
|
||||||
|
*(uint32 *)dest = ZSTD_ID;
|
||||||
|
size_t compressed_length = ZSTD_compress_usingCDict(
|
||||||
|
g_pZSTDCCtx,
|
||||||
|
(char*)dest + sizeof(uint32),
|
||||||
|
nMaxCompressedSize,
|
||||||
|
(const char*)source,
|
||||||
|
sourceLen,
|
||||||
|
GetZSTD_CDictionary<ZSTD_CDict>());
|
||||||
|
if (ZSTD_isError(compressed_length))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
compressed_length += 4;
|
||||||
|
Assert( compressed_length <= nMaxCompressedSize );
|
||||||
|
*destLen = compressed_length;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
unsigned COM_GetIdealDestinationCompressionBufferSize_LZSS( unsigned int uncompressedSize )
|
unsigned COM_GetIdealDestinationCompressionBufferSize_LZSS( unsigned int uncompressedSize )
|
||||||
{
|
{
|
||||||
|
@ -1354,6 +1514,19 @@ int COM_GetUncompressedSize( const void *compressed, unsigned int compressedLen
|
||||||
size_t snappySize;
|
size_t snappySize;
|
||||||
if ( snappy::GetUncompressedLength( (const char *)compressed + sizeof(pHeader->id), compressedLen-sizeof(pHeader->id), &snappySize ) )
|
if ( snappy::GetUncompressedLength( (const char *)compressed + sizeof(pHeader->id), compressedLen-sizeof(pHeader->id), &snappySize ) )
|
||||||
return (int)snappySize;
|
return (int)snappySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pHeader->id == ZSTD_ID)
|
||||||
|
{
|
||||||
|
auto srcSize = ZSTD_getFrameContentSize((const char*)compressed + sizeof(pHeader->id),
|
||||||
|
compressedLen);
|
||||||
|
if (srcSize > std::numeric_limits<int>::max() || ZSTD_isError(srcSize))
|
||||||
|
{
|
||||||
|
Warning("COM_GetUncompressedSize: ZSTD Failed on getting uncompressed size\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<int>(srcSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1400,6 +1573,25 @@ bool COM_BufferToBufferDecompress( void *dest, unsigned int *destLen, const void
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( pHeader->id == ZSTD_ID )
|
||||||
|
{
|
||||||
|
static auto g_pZSTDDCtx = ZSTD_createDCtx();
|
||||||
|
|
||||||
|
if (ZSTD_isError(ZSTD_decompress_usingDDict(
|
||||||
|
g_pZSTDDCtx,
|
||||||
|
(char*)dest,
|
||||||
|
*destLen,
|
||||||
|
(const char*)source + 4,
|
||||||
|
sourceLen - 4,
|
||||||
|
GetZSTD_CDictionary<ZSTD_DDict>())))
|
||||||
|
{
|
||||||
|
Warning( "NET_BufferToBufferDecompress: ZSTD decompression failed\n" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*destLen = nDecompressedSize;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Mismatch between this routine and COM_GetUncompressedSize
|
// Mismatch between this routine and COM_GetUncompressedSize
|
||||||
AssertMsg( false, "Unknown compression type?" );
|
AssertMsg( false, "Unknown compression type?" );
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -114,6 +114,10 @@ void *COM_CompressBuffer_Snappy( const void *source, unsigned int sourceLen, uns
|
||||||
bool COM_BufferToBufferCompress_Snappy( void *dest, unsigned int *destLen, const void *source, unsigned int sourceLen );
|
bool COM_BufferToBufferCompress_Snappy( void *dest, unsigned int *destLen, const void *source, unsigned int sourceLen );
|
||||||
unsigned int COM_GetIdealDestinationCompressionBufferSize_Snappy( unsigned int uncompressedSize );
|
unsigned int COM_GetIdealDestinationCompressionBufferSize_Snappy( unsigned int uncompressedSize );
|
||||||
|
|
||||||
|
void *COM_CompressBuffer_ZSTD( const void *source, unsigned int sourceLen, unsigned int *compressedLen, unsigned int maxCompressedLen = 0 );
|
||||||
|
bool COM_BufferToBufferCompress_ZSTD( void *dest, unsigned int *destLen, const void *source, unsigned int sourceLen );
|
||||||
|
unsigned int COM_GetIdealDestinationCompressionBufferSize_ZSTD( unsigned int uncompressedSize );
|
||||||
|
|
||||||
/// Fetch ideal working buffer size. You should allocate the buffer you wish to compress into
|
/// Fetch ideal working buffer size. You should allocate the buffer you wish to compress into
|
||||||
/// at least this big, in order to get the best performance when using COM_BufferToBufferCompress
|
/// at least this big, in order to get the best performance when using COM_BufferToBufferCompress
|
||||||
inline unsigned int COM_GetIdealDestinationCompressionBufferSize( unsigned int uncompressedSize )
|
inline unsigned int COM_GetIdealDestinationCompressionBufferSize( unsigned int uncompressedSize )
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "../utils/bzip2/bzlib.h"
|
#include "../utils/bzip2/bzlib.h"
|
||||||
#include "net_chan.h"
|
#include "net_chan.h"
|
||||||
|
#include "common.h"
|
||||||
#include "tier1/strtools.h"
|
#include "tier1/strtools.h"
|
||||||
#include "filesystem_engine.h"
|
#include "filesystem_engine.h"
|
||||||
#include "demo.h"
|
#include "demo.h"
|
||||||
|
@ -167,10 +168,10 @@ void CNetChan::CompressFragments()
|
||||||
compressTimer.Start();
|
compressTimer.Start();
|
||||||
|
|
||||||
// fragments data is in memory
|
// fragments data is in memory
|
||||||
unsigned int compressedSize = COM_GetIdealDestinationCompressionBufferSize_Snappy( data->bytes );
|
unsigned int compressedSize = COM_GetIdealDestinationCompressionBufferSize_ZSTD( data->bytes );
|
||||||
char * compressedData = new char[ compressedSize ];
|
char * compressedData = new char[ compressedSize ];
|
||||||
|
|
||||||
if ( COM_BufferToBufferCompress_Snappy( compressedData, &compressedSize, data->buffer, data->bytes ) &&
|
if ( COM_BufferToBufferCompress_ZSTD( compressedData, &compressedSize, data->buffer, data->bytes ) &&
|
||||||
( compressedSize < data->bytes ) )
|
( compressedSize < data->bytes ) )
|
||||||
{
|
{
|
||||||
compressTimer.End();
|
compressTimer.End();
|
||||||
|
@ -218,7 +219,7 @@ void CNetChan::CompressFragments()
|
||||||
{
|
{
|
||||||
// create compressed version of source file
|
// create compressed version of source file
|
||||||
unsigned int uncompressedSize = data->bytes;
|
unsigned int uncompressedSize = data->bytes;
|
||||||
unsigned int compressedSize = COM_GetIdealDestinationCompressionBufferSize_Snappy( uncompressedSize );
|
unsigned int compressedSize = COM_GetIdealDestinationCompressionBufferSize_ZSTD( uncompressedSize );
|
||||||
char *uncompressed = new char[uncompressedSize];
|
char *uncompressed = new char[uncompressedSize];
|
||||||
char *compressed = new char[compressedSize];
|
char *compressed = new char[compressedSize];
|
||||||
|
|
||||||
|
@ -226,7 +227,7 @@ void CNetChan::CompressFragments()
|
||||||
g_pFileSystem->Read( uncompressed, data->bytes, data->file );
|
g_pFileSystem->Read( uncompressed, data->bytes, data->file );
|
||||||
|
|
||||||
// compress into buffer
|
// compress into buffer
|
||||||
if ( COM_BufferToBufferCompress_Snappy( compressed, &compressedSize, uncompressed, uncompressedSize ) )
|
if ( COM_BufferToBufferCompress_ZSTD( compressed, &compressedSize, uncompressed, uncompressedSize ) )
|
||||||
{
|
{
|
||||||
// write out to disk compressed version
|
// write out to disk compressed version
|
||||||
hZipFile = g_pFileSystem->Open( compressedfilename, "wb", NULL );
|
hZipFile = g_pFileSystem->Open( compressedfilename, "wb", NULL );
|
||||||
|
|
|
@ -2346,6 +2346,8 @@ int NET_SendPacket ( INetChannel *chan, int sock, const netadr_t &to, const uns
|
||||||
struct sockaddr addr;
|
struct sockaddr addr;
|
||||||
int net_socket;
|
int net_socket;
|
||||||
|
|
||||||
|
bUseCompression = true;
|
||||||
|
|
||||||
if ( net_showudp.GetInt() && (*(unsigned int*)data == CONNECTIONLESS_HEADER) )
|
if ( net_showudp.GetInt() && (*(unsigned int*)data == CONNECTIONLESS_HEADER) )
|
||||||
{
|
{
|
||||||
Assert( !bUseCompression );
|
Assert( !bUseCompression );
|
||||||
|
@ -2405,7 +2407,7 @@ int NET_SendPacket ( INetChannel *chan, int sock, const netadr_t &to, const uns
|
||||||
if ( pVoicePayload )
|
if ( pVoicePayload )
|
||||||
{
|
{
|
||||||
VPROF_BUDGET( "NET_SendPacket_CompressVoice", VPROF_BUDGETGROUP_OTHER_NETWORKING );
|
VPROF_BUDGET( "NET_SendPacket_CompressVoice", VPROF_BUDGETGROUP_OTHER_NETWORKING );
|
||||||
unsigned int nCompressedLength = COM_GetIdealDestinationCompressionBufferSize_Snappy( pVoicePayload->GetNumBytesWritten() );
|
unsigned int nCompressedLength = COM_GetIdealDestinationCompressionBufferSize_ZSTD( pVoicePayload->GetNumBytesWritten() );
|
||||||
memCompressedVoice.EnsureCapacity( nCompressedLength + sizeof( unsigned short ) );
|
memCompressedVoice.EnsureCapacity( nCompressedLength + sizeof( unsigned short ) );
|
||||||
|
|
||||||
byte *pVoice = (byte *)memCompressedVoice.Base();
|
byte *pVoice = (byte *)memCompressedVoice.Base();
|
||||||
|
@ -2417,7 +2419,7 @@ int NET_SendPacket ( INetChannel *chan, int sock, const netadr_t &to, const uns
|
||||||
byte *pOutput = NULL;
|
byte *pOutput = NULL;
|
||||||
if ( net_compressvoice.GetBool() )
|
if ( net_compressvoice.GetBool() )
|
||||||
{
|
{
|
||||||
if ( COM_BufferToBufferCompress_Snappy( pVoice, &nCompressedLength, pVoicePayload->GetData(), pVoicePayload->GetNumBytesWritten()
|
if ( COM_BufferToBufferCompress_ZSTD( pVoice, &nCompressedLength, pVoicePayload->GetData(), pVoicePayload->GetNumBytesWritten()
|
||||||
&& ( (int)nCompressedLength < pVoicePayload->GetNumBytesWritten() ) ) )
|
&& ( (int)nCompressedLength < pVoicePayload->GetNumBytesWritten() ) ) )
|
||||||
{
|
{
|
||||||
pOutput = pVoice;
|
pOutput = pVoice;
|
||||||
|
@ -2432,17 +2434,17 @@ int NET_SendPacket ( INetChannel *chan, int sock, const netadr_t &to, const uns
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( bUseCompression )
|
if ( bUseCompression )
|
||||||
{
|
{
|
||||||
VPROF_BUDGET( "NET_SendPacket_Compress", VPROF_BUDGETGROUP_OTHER_NETWORKING );
|
VPROF_BUDGET( "NET_SendPacket_Compress", VPROF_BUDGETGROUP_OTHER_NETWORKING );
|
||||||
unsigned int nCompressedLength = COM_GetIdealDestinationCompressionBufferSize_Snappy( length );
|
unsigned int nCompressedLength = COM_GetIdealDestinationCompressionBufferSize_ZSTD( length );
|
||||||
|
|
||||||
memCompressed.EnsureCapacity( nCompressedLength + nVoiceBytes + sizeof( unsigned int ) );
|
memCompressed.EnsureCapacity( nCompressedLength + nVoiceBytes + sizeof( unsigned int ) );
|
||||||
|
|
||||||
*(int *)memCompressed.Base() = LittleLong( NET_HEADER_FLAG_COMPRESSEDPACKET );
|
*(int *)memCompressed.Base() = LittleLong( NET_HEADER_FLAG_COMPRESSEDPACKET );
|
||||||
|
|
||||||
if ( COM_BufferToBufferCompress_Snappy( memCompressed.Base() + sizeof( unsigned int ), &nCompressedLength, data, length )
|
if ( COM_BufferToBufferCompress_ZSTD( memCompressed.Base() + sizeof( unsigned int ), &nCompressedLength, data, length )
|
||||||
&& (int)nCompressedLength < length )
|
&& (int)nCompressedLength < length )
|
||||||
{
|
{
|
||||||
data = memCompressed.Base();
|
data = memCompressed.Base();
|
||||||
length = nCompressedLength + sizeof( unsigned int );
|
length = nCompressedLength + sizeof( unsigned int );
|
||||||
|
|
||||||
|
|
|
@ -1433,7 +1433,7 @@ void CNetworkStringTableContainer::WriteBaselines( bf_write &buf )
|
||||||
unsigned int compressedSize = (unsigned int)numBytes;
|
unsigned int compressedSize = (unsigned int)numBytes;
|
||||||
char *compressedData = new char[numBytes];
|
char *compressedData = new char[numBytes];
|
||||||
|
|
||||||
if ( COM_BufferToBufferCompress_Snappy( compressedData, &compressedSize, (char *)msg.m_DataOut.GetData(), numBytes ) )
|
if ( COM_BufferToBufferCompress_ZSTD( compressedData, &compressedSize, (char *)msg.m_DataOut.GetData(), numBytes ) )
|
||||||
{
|
{
|
||||||
msg.m_bDataCompressed = true;
|
msg.m_bDataCompressed = true;
|
||||||
msg.m_DataOut.Reset();
|
msg.m_DataOut.Reset();
|
||||||
|
|
|
@ -357,7 +357,7 @@ def build(bld):
|
||||||
|
|
||||||
defines = []
|
defines = []
|
||||||
|
|
||||||
libs = ['tier0','vgui_controls','dmxloader','tier1','tier2','tier3','bitmap','vstdlib','appframework','datamodel','vtf','mathlib','steam_api','matsys_controls','BZ2','SDL2','JPEG','ZLIB','OPENAL','CURL' ]
|
libs = ['ZSTD','tier0','vgui_controls','dmxloader','tier1','tier2','tier3','bitmap','vstdlib','appframework','datamodel','vtf','mathlib','steam_api','matsys_controls','BZ2','SDL2','JPEG','ZLIB','OPENAL','CURL' ]
|
||||||
|
|
||||||
if bld.env.DEST_OS == 'android':
|
if bld.env.DEST_OS == 'android':
|
||||||
libs += ['SSL', 'CRYPTO'] # android curl was built with openssl
|
libs += ['SSL', 'CRYPTO'] # android curl was built with openssl
|
||||||
|
|
|
@ -176,7 +176,8 @@ public:
|
||||||
float &flPenetrationDistance,
|
float &flPenetrationDistance,
|
||||||
float &flBulletDiameter );
|
float &flBulletDiameter );
|
||||||
|
|
||||||
void FireBullet(
|
void FireBullet(
|
||||||
|
int iBullet,
|
||||||
Vector vecSrc,
|
Vector vecSrc,
|
||||||
const QAngle &shootAngles,
|
const QAngle &shootAngles,
|
||||||
float flDistance,
|
float flDistance,
|
||||||
|
|
|
@ -304,7 +304,7 @@ LINK_ENTITY_TO_CLASS( player, CCSPlayer );
|
||||||
PRECACHE_REGISTER(player);
|
PRECACHE_REGISTER(player);
|
||||||
|
|
||||||
BEGIN_SEND_TABLE_NOBASE( CCSPlayer, DT_CSLocalPlayerExclusive )
|
BEGIN_SEND_TABLE_NOBASE( CCSPlayer, DT_CSLocalPlayerExclusive )
|
||||||
SendPropFloat( SENDINFO( m_flStamina ), 14, 0, 0, 1400 ),
|
SendPropFloat( SENDINFO( m_flStamina ) ),
|
||||||
SendPropInt( SENDINFO( m_iDirection ), 1, SPROP_UNSIGNED ),
|
SendPropInt( SENDINFO( m_iDirection ), 1, SPROP_UNSIGNED ),
|
||||||
SendPropInt( SENDINFO( m_iShotsFired ), 8, SPROP_UNSIGNED ),
|
SendPropInt( SENDINFO( m_iShotsFired ), 8, SPROP_UNSIGNED ),
|
||||||
SendPropFloat( SENDINFO( m_flVelocityModifier ), 8, 0, 0, 1 ),
|
SendPropFloat( SENDINFO( m_flVelocityModifier ), 8, 0, 0, 1 ),
|
||||||
|
|
|
@ -296,7 +296,8 @@ public:
|
||||||
|
|
||||||
virtual float GetPlayerMaxSpeed();
|
virtual float GetPlayerMaxSpeed();
|
||||||
|
|
||||||
void FireBullet(
|
void FireBullet(
|
||||||
|
int iBullet,
|
||||||
Vector vecSrc,
|
Vector vecSrc,
|
||||||
const QAngle &shootAngles,
|
const QAngle &shootAngles,
|
||||||
float flDistance,
|
float flDistance,
|
||||||
|
|
|
@ -45,9 +45,9 @@ BEGIN_SEND_TABLE_NOBASE( CPlayerLocalData, DT_Local )
|
||||||
SendPropFloat ( SENDINFO_VECTORELEM(m_vecPunchAngleVel, 2), 32, SPROP_NOSCALE|SPROP_CHANGES_OFTEN ),
|
SendPropFloat ( SENDINFO_VECTORELEM(m_vecPunchAngleVel, 2), 32, SPROP_NOSCALE|SPROP_CHANGES_OFTEN ),
|
||||||
|
|
||||||
#else
|
#else
|
||||||
SendPropFloat (SENDINFO(m_flFallVelocity), -1, SPROP_COORD|SPROP_CHANGES_OFTEN ),
|
SendPropFloat (SENDINFO(m_flFallVelocity), -1, SPROP_CHANGES_OFTEN ),
|
||||||
SendPropVector (SENDINFO(m_vecPunchAngle), -1, SPROP_COORD|SPROP_CHANGES_OFTEN),
|
SendPropVector (SENDINFO(m_vecPunchAngle), -1, SPROP_CHANGES_OFTEN),
|
||||||
SendPropVector (SENDINFO(m_vecPunchAngleVel), -1, SPROP_COORD),
|
SendPropVector (SENDINFO(m_vecPunchAngleVel)),
|
||||||
#endif
|
#endif
|
||||||
SendPropInt (SENDINFO(m_bDrawViewmodel), 1, SPROP_UNSIGNED ),
|
SendPropInt (SENDINFO(m_bDrawViewmodel), 1, SPROP_UNSIGNED ),
|
||||||
SendPropInt (SENDINFO(m_bWearingSuit), 1, SPROP_UNSIGNED ),
|
SendPropInt (SENDINFO(m_bWearingSuit), 1, SPROP_UNSIGNED ),
|
||||||
|
|
|
@ -185,19 +185,14 @@ float CCSPlayer::GetPlayerMaxSpeed()
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UTIL_ClipTraceToPlayersHull( float flBulletDiameter, const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, ITraceFilter *filter, trace_t *tr )
|
void UTIL_ClipTraceToPlayersHull(const Vector& vecAbsStart, const Vector& vecAbsEnd, const Vector& mins, const Vector& maxs, unsigned int mask, ITraceFilter *filter, trace_t *tr )
|
||||||
{
|
{
|
||||||
trace_t playerTrace;
|
trace_t playerTrace;
|
||||||
Ray_t ray;
|
Ray_t ray;
|
||||||
float smallestFraction = tr->fraction;
|
float smallestFraction = tr->fraction;
|
||||||
const float maxRange = 60.0f;
|
const float maxRange = 60.0f;
|
||||||
|
|
||||||
Vector vecBulletDiameterMaxs(flBulletDiameter, flBulletDiameter, flBulletDiameter);
|
ray.Init( vecAbsStart, vecAbsEnd , mins, maxs );
|
||||||
vecBulletDiameterMaxs /= 2.0f;
|
|
||||||
Vector vecBulletDiameterMins(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter);
|
|
||||||
vecBulletDiameterMins /= 2.0f;
|
|
||||||
|
|
||||||
ray.Init( vecAbsStart, vecAbsEnd , vecBulletDiameterMins, vecBulletDiameterMaxs );
|
|
||||||
|
|
||||||
for ( int k = 1; k <= gpGlobals->maxClients; ++k )
|
for ( int k = 1; k <= gpGlobals->maxClients; ++k )
|
||||||
{
|
{
|
||||||
|
@ -411,25 +406,21 @@ static bool TraceToExit(Vector &start, Vector &dir, Vector &end, float flStepSiz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void UTIL_TraceLineIgnoreTwoEntities(float flBulletDiameter, const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask,
|
inline void UTIL_TraceLineIgnoreTwoEntities(const Vector& vecAbsStart, const Vector& vecAbsEnd, const Vector& mins, const Vector& maxs, unsigned int mask,
|
||||||
const IHandleEntity *ignore, const IHandleEntity *ignore2, int collisionGroup, trace_t *ptr )
|
const IHandleEntity *ignore, const IHandleEntity *ignore2, int collisionGroup, trace_t *ptr )
|
||||||
{
|
{
|
||||||
Vector vecBulletDiameterMaxs(flBulletDiameter, flBulletDiameter, flBulletDiameter);
|
|
||||||
vecBulletDiameterMaxs /= 2.0f;
|
|
||||||
Vector vecBulletDiameterMins(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter);
|
|
||||||
vecBulletDiameterMins /= 2.0f;
|
|
||||||
|
|
||||||
Ray_t ray;
|
Ray_t ray;
|
||||||
ray.Init( vecAbsStart, vecAbsEnd, vecBulletDiameterMins, vecBulletDiameterMaxs );
|
ray.Init( vecAbsStart, vecAbsEnd, mins, maxs );
|
||||||
CTraceFilterSkipTwoEntities traceFilter( ignore, ignore2, collisionGroup );
|
CTraceFilterSkipTwoEntities traceFilter( ignore, ignore2, collisionGroup );
|
||||||
enginetrace->TraceRay( ray, mask, &traceFilter, ptr );
|
enginetrace->TraceRay( ray, mask, &traceFilter, ptr );
|
||||||
if( r_visualizetraces.GetBool() )
|
if( r_visualizetraces.GetBool() )
|
||||||
{
|
{
|
||||||
NDebugOverlay::SweptBox( ptr->startpos, ptr->endpos, vecBulletDiameterMins, vecBulletDiameterMaxs, QAngle(), 255, 0, 0, true, 100.0f );
|
NDebugOverlay::SweptBox( ptr->startpos, ptr->endpos, mins, maxs, QAngle(), 255, 0, 0, true, 100.0f );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCSPlayer::FireBullet(
|
void CCSPlayer::FireBullet(
|
||||||
|
int iBullet, // bullet number
|
||||||
Vector vecSrc, // shooting postion
|
Vector vecSrc, // shooting postion
|
||||||
const QAngle &shootAngles, //shooting angle
|
const QAngle &shootAngles, //shooting angle
|
||||||
float flDistance, // max distance
|
float flDistance, // max distance
|
||||||
|
@ -457,10 +448,10 @@ void CCSPlayer::FireBullet(
|
||||||
|
|
||||||
GetBulletTypeParameters( iBulletType, flPenetrationPower, flPenetrationDistance, flBulletDiameter );
|
GetBulletTypeParameters( iBulletType, flPenetrationPower, flPenetrationDistance, flBulletDiameter );
|
||||||
|
|
||||||
Vector vecBulletDiameterMaxs(flBulletDiameter, flBulletDiameter, flBulletDiameter);
|
float flBulletRadius = flBulletDiameter / 2.0f;
|
||||||
vecBulletDiameterMaxs /= 2.0f;
|
|
||||||
Vector vecBulletDiameterMins(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter);
|
Vector vecBulletRadiusMaxs(flBulletRadius, flBulletRadius, flBulletRadius);
|
||||||
vecBulletDiameterMins /= 2.0f;
|
Vector vecBulletRadiusMins(-flBulletRadius, -flBulletRadius, -flBulletRadius);
|
||||||
|
|
||||||
if ( !pevAttacker )
|
if ( !pevAttacker )
|
||||||
pevAttacker = this; // the default attacker is ourselves
|
pevAttacker = this; // the default attacker is ourselves
|
||||||
|
@ -534,13 +525,13 @@ void CCSPlayer::FireBullet(
|
||||||
|
|
||||||
trace_t tr; // main enter bullet trace
|
trace_t tr; // main enter bullet trace
|
||||||
|
|
||||||
UTIL_TraceLineIgnoreTwoEntities(flBulletDiameter, vecSrc, vecEnd, CS_MASK_SHOOT|CONTENTS_HITBOX, this, lastPlayerHit, COLLISION_GROUP_NONE, &tr );
|
UTIL_TraceLineIgnoreTwoEntities(vecSrc, vecEnd, vecBulletRadiusMins, vecBulletRadiusMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, this, lastPlayerHit, COLLISION_GROUP_NONE, &tr );
|
||||||
{
|
{
|
||||||
CTraceFilterSkipTwoEntities filter( this, lastPlayerHit, COLLISION_GROUP_NONE );
|
CTraceFilterSkipTwoEntities filter( this, lastPlayerHit, COLLISION_GROUP_NONE );
|
||||||
|
|
||||||
// Check for player hitboxes extending outside their collision bounds
|
// Check for player hitboxes extending outside their collision bounds
|
||||||
const float rayExtension = 40.0f;
|
const float rayExtension = 40.0f;
|
||||||
UTIL_ClipTraceToPlayersHull(flBulletDiameter, vecSrc, vecEnd + vecDir * rayExtension, CS_MASK_SHOOT|CONTENTS_HITBOX, &filter, &tr );
|
UTIL_ClipTraceToPlayersHull(vecSrc, vecEnd + vecDir * rayExtension, vecBulletRadiusMins, vecBulletRadiusMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, &filter, &tr );
|
||||||
}
|
}
|
||||||
|
|
||||||
lastPlayerHit = ToBasePlayer(tr.m_pEnt);
|
lastPlayerHit = ToBasePlayer(tr.m_pEnt);
|
||||||
|
@ -583,8 +574,8 @@ void CCSPlayer::FireBullet(
|
||||||
{
|
{
|
||||||
NDebugOverlay::SweptBox(vecSrc,
|
NDebugOverlay::SweptBox(vecSrc,
|
||||||
tr.endpos,
|
tr.endpos,
|
||||||
vecBulletDiameterMins,
|
vecBulletRadiusMins,
|
||||||
vecBulletDiameterMaxs,
|
vecBulletRadiusMaxs,
|
||||||
QAngle(0, 0, 0),
|
QAngle(0, 0, 0),
|
||||||
255,
|
255,
|
||||||
0,
|
0,
|
||||||
|
@ -609,23 +600,17 @@ void CCSPlayer::FireBullet(
|
||||||
#else
|
#else
|
||||||
if ( m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ON_HIT || m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ALWAYS_ON )
|
if ( m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ON_HIT || m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ALWAYS_ON )
|
||||||
{
|
{
|
||||||
if (m_iBulletServerPositionCount.Get()
|
if (iBullet < MAX_PLAYER_BULLET_SERVER_POSITIONS)
|
||||||
< MAX_PLAYER_BULLET_SERVER_POSITIONS)
|
|
||||||
{
|
{
|
||||||
m_vecBulletServerPositions.Set(
|
m_vecBulletServerPositions.Set(m_iBulletServerPositionCount.Get(), tr.endpos);
|
||||||
m_iBulletServerPositionCount.Get(),
|
m_vecServerShootPosition.Set(m_iBulletServerPositionCount.Get(), vecSrc);
|
||||||
tr.endpos);
|
m_iBulletServerPositionCount.Set(m_iBulletServerPositionCount.Get() + 1);
|
||||||
m_vecServerShootPosition.Set(
|
|
||||||
m_iBulletServerPositionCount.Get(),
|
|
||||||
vecSrc);
|
|
||||||
m_iBulletServerPositionCount.Set(
|
|
||||||
m_iBulletServerPositionCount.Get() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
|
if (tr.m_pEnt && tr.m_pEnt->IsPlayer())
|
||||||
{
|
{
|
||||||
CBasePlayer *player = ToBasePlayer( tr.m_pEnt );
|
CBasePlayer* player = ToBasePlayer(tr.m_pEnt);
|
||||||
player->RecordServerHitboxes( this );
|
player->RecordServerHitboxes(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -651,7 +636,7 @@ void CCSPlayer::FireBullet(
|
||||||
if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) )
|
if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) )
|
||||||
{
|
{
|
||||||
trace_t waterTrace;
|
trace_t waterTrace;
|
||||||
UTIL_TraceHull( vecSrc, tr.endpos, vecBulletDiameterMins, vecBulletDiameterMaxs, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), this, COLLISION_GROUP_NONE, &waterTrace );
|
UTIL_TraceHull( vecSrc, tr.endpos, vecBulletRadiusMins, vecBulletRadiusMaxs, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), this, COLLISION_GROUP_NONE, &waterTrace );
|
||||||
|
|
||||||
if( waterTrace.allsolid != 1 )
|
if( waterTrace.allsolid != 1 )
|
||||||
{
|
{
|
||||||
|
@ -734,12 +719,12 @@ void CCSPlayer::FireBullet(
|
||||||
|
|
||||||
// find exact penetration exit
|
// find exact penetration exit
|
||||||
trace_t exitTr;
|
trace_t exitTr;
|
||||||
UTIL_TraceHull( penetrationEnd, tr.endpos, vecBulletDiameterMins, vecBulletDiameterMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, NULL, &exitTr );
|
UTIL_TraceHull( penetrationEnd, tr.endpos, vecBulletRadiusMins, vecBulletRadiusMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, NULL, &exitTr );
|
||||||
|
|
||||||
if( exitTr.m_pEnt != tr.m_pEnt && exitTr.m_pEnt != NULL )
|
if( exitTr.m_pEnt != tr.m_pEnt && exitTr.m_pEnt != NULL )
|
||||||
{
|
{
|
||||||
// something was blocking, trace again
|
// something was blocking, trace again
|
||||||
UTIL_TraceHull( penetrationEnd, tr.endpos, vecBulletDiameterMins, vecBulletDiameterMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, exitTr.m_pEnt, COLLISION_GROUP_NONE, &exitTr );
|
UTIL_TraceHull( penetrationEnd, tr.endpos, vecBulletRadiusMins, vecBulletRadiusMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, exitTr.m_pEnt, COLLISION_GROUP_NONE, &exitTr );
|
||||||
}
|
}
|
||||||
|
|
||||||
// get material at exit point
|
// get material at exit point
|
||||||
|
|
|
@ -301,7 +301,8 @@ void FX_FireBullets(
|
||||||
if (debug_screenshot_bullet_position.GetBool())
|
if (debug_screenshot_bullet_position.GetBool())
|
||||||
gpGlobals->client_taking_screenshot = true;
|
gpGlobals->client_taking_screenshot = true;
|
||||||
#endif
|
#endif
|
||||||
pPlayer->FireBullet(
|
pPlayer->FireBullet(
|
||||||
|
iBullet,
|
||||||
vOrigin,
|
vOrigin,
|
||||||
vAngles,
|
vAngles,
|
||||||
flRange,
|
flRange,
|
||||||
|
|
|
@ -381,13 +381,17 @@ SendProp SendPropFloat(
|
||||||
Assert( sizeofVar == 0 || sizeofVar == 4 );
|
Assert( sizeofVar == 0 || sizeofVar == 4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO_ENHANCED: These variables will get compressed with zstd
|
||||||
|
flags = SPROP_NOSCALE;
|
||||||
|
nBits = 0;
|
||||||
|
|
||||||
if ( nBits <= 0 || nBits == 32 )
|
if ( nBits <= 0 || nBits == 32 )
|
||||||
{
|
{
|
||||||
flags |= SPROP_NOSCALE;
|
flags |= SPROP_NOSCALE;
|
||||||
fLowValue = 0.f;
|
fLowValue = 0.f;
|
||||||
fHighValue = 0.f;
|
fHighValue = 0.f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (fHighValue == HIGH_DEFAULT)
|
if (fHighValue == HIGH_DEFAULT)
|
||||||
{
|
{
|
||||||
|
@ -428,13 +432,17 @@ SendProp SendPropVector(
|
||||||
Assert(sizeofVar == sizeof(Vector));
|
Assert(sizeofVar == sizeof(Vector));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO_ENHANCED: These variables will get compressed with zstd
|
||||||
|
flags = SPROP_NOSCALE;
|
||||||
|
nBits = 0;
|
||||||
|
|
||||||
if ( nBits <= 0 || nBits == 32 )
|
if ( nBits <= 0 || nBits == 32 )
|
||||||
{
|
{
|
||||||
flags |= SPROP_NOSCALE;
|
flags |= SPROP_NOSCALE;
|
||||||
fLowValue = 0.f;
|
fLowValue = 0.f;
|
||||||
fHighValue = 0.f;
|
fHighValue = 0.f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (fHighValue == HIGH_DEFAULT)
|
if (fHighValue == HIGH_DEFAULT)
|
||||||
{
|
{
|
||||||
|
@ -475,13 +483,17 @@ SendProp SendPropVectorXY(
|
||||||
Assert(sizeofVar == sizeof(Vector));
|
Assert(sizeofVar == sizeof(Vector));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO_ENHANCED: These variables will get compressed with zstd
|
||||||
|
flags = SPROP_NOSCALE;
|
||||||
|
nBits = 0;
|
||||||
|
|
||||||
if ( nBits <= 0 || nBits == 32 )
|
if ( nBits <= 0 || nBits == 32 )
|
||||||
{
|
{
|
||||||
flags |= SPROP_NOSCALE;
|
flags |= SPROP_NOSCALE;
|
||||||
fLowValue = 0.f;
|
fLowValue = 0.f;
|
||||||
fHighValue = 0.f;
|
fHighValue = 0.f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (fHighValue == HIGH_DEFAULT)
|
if (fHighValue == HIGH_DEFAULT)
|
||||||
{
|
{
|
||||||
|
@ -504,7 +516,8 @@ SendProp SendPropVectorXY(
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!!
|
#if 0 // We can't ship this since it changes the size of DTVariant to
|
||||||
|
// be 20 bytes instead of 16 and that breaks MODs!!!
|
||||||
SendProp SendPropQuaternion(
|
SendProp SendPropQuaternion(
|
||||||
const char *pVarName,
|
const char *pVarName,
|
||||||
int offset,
|
int offset,
|
||||||
|
@ -523,13 +536,17 @@ SendProp SendPropQuaternion(
|
||||||
Assert(sizeofVar == sizeof(Quaternion));
|
Assert(sizeofVar == sizeof(Quaternion));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO_ENHANCED: These variables will get compressed with zstd
|
||||||
|
flags = SPROP_NOSCALE;
|
||||||
|
nBits = 0;
|
||||||
|
|
||||||
if ( nBits <= 0 || nBits == 32 )
|
if ( nBits <= 0 || nBits == 32 )
|
||||||
{
|
{
|
||||||
flags |= SPROP_NOSCALE;
|
flags |= SPROP_NOSCALE;
|
||||||
fLowValue = 0.f;
|
fLowValue = 0.f;
|
||||||
fHighValue = 0.f;
|
fHighValue = 0.f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (fHighValue == HIGH_DEFAULT)
|
if (fHighValue == HIGH_DEFAULT)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#define LZSS_ID uint32( BigLong( ('L'<<24)|('Z'<<16)|('S'<<8)|('S') ) )
|
#define LZSS_ID uint32( BigLong( ('L'<<24)|('Z'<<16)|('S'<<8)|('S') ) )
|
||||||
#define SNAPPY_ID uint32( BigLong( ('S'<<24)|('N'<<16)|('A'<<8)|('P') ) )
|
#define SNAPPY_ID uint32( BigLong( ('S'<<24)|('N'<<16)|('A'<<8)|('P') ) )
|
||||||
|
#define ZSTD_ID uint32( BigLong( ('Z'<<24)|('S'<<16)|('T'<<8)|('D') ) )
|
||||||
|
|
||||||
// bind the buffer for correct identification
|
// bind the buffer for correct identification
|
||||||
struct lzss_header_t
|
struct lzss_header_t
|
||||||
|
|
1
wscript
1
wscript
|
@ -327,6 +327,7 @@ def options(opt):
|
||||||
opt.load('reconfigure')
|
opt.load('reconfigure')
|
||||||
|
|
||||||
def check_deps(conf):
|
def check_deps(conf):
|
||||||
|
conf.check_cc(lib='zstd', mandatory=False)
|
||||||
if conf.env.DEST_OS != 'win32':
|
if conf.env.DEST_OS != 'win32':
|
||||||
conf.check_cc(lib='dl', mandatory=False)
|
conf.check_cc(lib='dl', mandatory=False)
|
||||||
conf.check_cc(lib='bz2', mandatory=True)
|
conf.check_cc(lib='bz2', mandatory=True)
|
||||||
|
|
Loading…
Reference in a new issue