Replace snappy with trained zstd dictionary

This commit is contained in:
Kamay Xutax 2024-07-18 08:12:29 +02:00
parent 5036c0b09d
commit 1a3e348316
17 changed files with 270 additions and 64 deletions

Binary file not shown.

Binary file not shown.

View file

@ -9,12 +9,16 @@
#include "host.h"
#include <ctype.h>
#include "draw.h"
#include "strtools.h"
#include "sysexternal.h"
#include "utlbuffer.h"
#include "zone.h"
#include "sys.h"
#include <edict.h>
#include <coordsize.h>
#include <characterset.h>
#include <bitbuf.h>
#include <mutex>
#include "common.h"
#ifdef OSX
#include <malloc/malloc.h>
@ -44,6 +48,8 @@
#include <vgui/ILocalize.h>
#include "tier1/lzss.h"
#include "tier1/snappy.h"
#include "zstd.h"
#include <limits>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@ -1292,6 +1298,160 @@ bool COM_BufferToBufferCompress_Snappy( void *dest, unsigned int *destLen, const
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 )
{
@ -1354,6 +1514,19 @@ int COM_GetUncompressedSize( const void *compressed, unsigned int compressedLen
size_t snappySize;
if ( snappy::GetUncompressedLength( (const char *)compressed + sizeof(pHeader->id), compressedLen-sizeof(pHeader->id), &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;
@ -1400,6 +1573,25 @@ bool COM_BufferToBufferDecompress( void *dest, unsigned int *destLen, const void
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
AssertMsg( false, "Unknown compression type?" );
return false;

View file

@ -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 );
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
/// at least this big, in order to get the best performance when using COM_BufferToBufferCompress
inline unsigned int COM_GetIdealDestinationCompressionBufferSize( unsigned int uncompressedSize )

View file

@ -6,6 +6,7 @@
#include "../utils/bzip2/bzlib.h"
#include "net_chan.h"
#include "common.h"
#include "tier1/strtools.h"
#include "filesystem_engine.h"
#include "demo.h"
@ -167,10 +168,10 @@ void CNetChan::CompressFragments()
compressTimer.Start();
// 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 ];
if ( COM_BufferToBufferCompress_Snappy( compressedData, &compressedSize, data->buffer, data->bytes ) &&
if ( COM_BufferToBufferCompress_ZSTD( compressedData, &compressedSize, data->buffer, data->bytes ) &&
( compressedSize < data->bytes ) )
{
compressTimer.End();
@ -218,7 +219,7 @@ void CNetChan::CompressFragments()
{
// create compressed version of source file
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 *compressed = new char[compressedSize];
@ -226,7 +227,7 @@ void CNetChan::CompressFragments()
g_pFileSystem->Read( uncompressed, data->bytes, data->file );
// 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
hZipFile = g_pFileSystem->Open( compressedfilename, "wb", NULL );

View file

@ -2346,6 +2346,8 @@ int NET_SendPacket ( INetChannel *chan, int sock, const netadr_t &to, const uns
struct sockaddr addr;
int net_socket;
bUseCompression = true;
if ( net_showudp.GetInt() && (*(unsigned int*)data == CONNECTIONLESS_HEADER) )
{
Assert( !bUseCompression );
@ -2405,7 +2407,7 @@ int NET_SendPacket ( INetChannel *chan, int sock, const netadr_t &to, const uns
if ( pVoicePayload )
{
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 ) );
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;
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() ) ) )
{
pOutput = pVoice;
@ -2432,17 +2434,17 @@ int NET_SendPacket ( INetChannel *chan, int sock, const netadr_t &to, const uns
}
if ( bUseCompression )
{
{
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 ) );
*(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 )
{
{
data = memCompressed.Base();
length = nCompressedLength + sizeof( unsigned int );

View file

@ -1433,7 +1433,7 @@ void CNetworkStringTableContainer::WriteBaselines( bf_write &buf )
unsigned int compressedSize = (unsigned int)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_DataOut.Reset();

View file

@ -357,7 +357,7 @@ def build(bld):
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':
libs += ['SSL', 'CRYPTO'] # android curl was built with openssl

View file

@ -176,7 +176,8 @@ public:
float &flPenetrationDistance,
float &flBulletDiameter );
void FireBullet(
void FireBullet(
int iBullet,
Vector vecSrc,
const QAngle &shootAngles,
float flDistance,

View file

@ -304,7 +304,7 @@ LINK_ENTITY_TO_CLASS( player, CCSPlayer );
PRECACHE_REGISTER(player);
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_iShotsFired ), 8, SPROP_UNSIGNED ),
SendPropFloat( SENDINFO( m_flVelocityModifier ), 8, 0, 0, 1 ),

View file

@ -296,7 +296,8 @@ public:
virtual float GetPlayerMaxSpeed();
void FireBullet(
void FireBullet(
int iBullet,
Vector vecSrc,
const QAngle &shootAngles,
float flDistance,

View file

@ -45,9 +45,9 @@ BEGIN_SEND_TABLE_NOBASE( CPlayerLocalData, DT_Local )
SendPropFloat ( SENDINFO_VECTORELEM(m_vecPunchAngleVel, 2), 32, SPROP_NOSCALE|SPROP_CHANGES_OFTEN ),
#else
SendPropFloat (SENDINFO(m_flFallVelocity), -1, SPROP_COORD|SPROP_CHANGES_OFTEN ),
SendPropVector (SENDINFO(m_vecPunchAngle), -1, SPROP_COORD|SPROP_CHANGES_OFTEN),
SendPropVector (SENDINFO(m_vecPunchAngleVel), -1, SPROP_COORD),
SendPropFloat (SENDINFO(m_flFallVelocity), -1, SPROP_CHANGES_OFTEN ),
SendPropVector (SENDINFO(m_vecPunchAngle), -1, SPROP_CHANGES_OFTEN),
SendPropVector (SENDINFO(m_vecPunchAngleVel)),
#endif
SendPropInt (SENDINFO(m_bDrawViewmodel), 1, SPROP_UNSIGNED ),
SendPropInt (SENDINFO(m_bWearingSuit), 1, SPROP_UNSIGNED ),

View file

@ -185,19 +185,14 @@ float CCSPlayer::GetPlayerMaxSpeed()
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;
Ray_t ray;
float smallestFraction = tr->fraction;
const float maxRange = 60.0f;
Vector vecBulletDiameterMaxs(flBulletDiameter, flBulletDiameter, flBulletDiameter);
vecBulletDiameterMaxs /= 2.0f;
Vector vecBulletDiameterMins(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter);
vecBulletDiameterMins /= 2.0f;
ray.Init( vecAbsStart, vecAbsEnd , vecBulletDiameterMins, vecBulletDiameterMaxs );
ray.Init( vecAbsStart, vecAbsEnd , mins, maxs );
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;
}
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 )
{
Vector vecBulletDiameterMaxs(flBulletDiameter, flBulletDiameter, flBulletDiameter);
vecBulletDiameterMaxs /= 2.0f;
Vector vecBulletDiameterMins(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter);
vecBulletDiameterMins /= 2.0f;
Ray_t ray;
ray.Init( vecAbsStart, vecAbsEnd, vecBulletDiameterMins, vecBulletDiameterMaxs );
ray.Init( vecAbsStart, vecAbsEnd, mins, maxs );
CTraceFilterSkipTwoEntities traceFilter( ignore, ignore2, collisionGroup );
enginetrace->TraceRay( ray, mask, &traceFilter, ptr );
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(
int iBullet, // bullet number
Vector vecSrc, // shooting postion
const QAngle &shootAngles, //shooting angle
float flDistance, // max distance
@ -457,10 +448,10 @@ void CCSPlayer::FireBullet(
GetBulletTypeParameters( iBulletType, flPenetrationPower, flPenetrationDistance, flBulletDiameter );
Vector vecBulletDiameterMaxs(flBulletDiameter, flBulletDiameter, flBulletDiameter);
vecBulletDiameterMaxs /= 2.0f;
Vector vecBulletDiameterMins(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter);
vecBulletDiameterMins /= 2.0f;
float flBulletRadius = flBulletDiameter / 2.0f;
Vector vecBulletRadiusMaxs(flBulletRadius, flBulletRadius, flBulletRadius);
Vector vecBulletRadiusMins(-flBulletRadius, -flBulletRadius, -flBulletRadius);
if ( !pevAttacker )
pevAttacker = this; // the default attacker is ourselves
@ -534,13 +525,13 @@ void CCSPlayer::FireBullet(
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 );
// Check for player hitboxes extending outside their collision bounds
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);
@ -583,8 +574,8 @@ void CCSPlayer::FireBullet(
{
NDebugOverlay::SweptBox(vecSrc,
tr.endpos,
vecBulletDiameterMins,
vecBulletDiameterMaxs,
vecBulletRadiusMins,
vecBulletRadiusMaxs,
QAngle(0, 0, 0),
255,
0,
@ -609,23 +600,17 @@ void CCSPlayer::FireBullet(
#else
if ( m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ON_HIT || m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ALWAYS_ON )
{
if (m_iBulletServerPositionCount.Get()
< MAX_PLAYER_BULLET_SERVER_POSITIONS)
if (iBullet < MAX_PLAYER_BULLET_SERVER_POSITIONS)
{
m_vecBulletServerPositions.Set(
m_iBulletServerPositionCount.Get(),
tr.endpos);
m_vecServerShootPosition.Set(
m_iBulletServerPositionCount.Get(),
vecSrc);
m_iBulletServerPositionCount.Set(
m_iBulletServerPositionCount.Get() + 1);
m_vecBulletServerPositions.Set(m_iBulletServerPositionCount.Get(), tr.endpos);
m_vecServerShootPosition.Set(m_iBulletServerPositionCount.Get(), vecSrc);
m_iBulletServerPositionCount.Set(m_iBulletServerPositionCount.Get() + 1);
}
if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
{
CBasePlayer *player = ToBasePlayer( tr.m_pEnt );
player->RecordServerHitboxes( this );
if (tr.m_pEnt && tr.m_pEnt->IsPlayer())
{
CBasePlayer* player = ToBasePlayer(tr.m_pEnt);
player->RecordServerHitboxes(this);
}
}
#endif
@ -651,7 +636,7 @@ void CCSPlayer::FireBullet(
if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) )
{
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 )
{
@ -734,12 +719,12 @@ void CCSPlayer::FireBullet(
// find exact penetration exit
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 )
{
// 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

View file

@ -301,7 +301,8 @@ void FX_FireBullets(
if (debug_screenshot_bullet_position.GetBool())
gpGlobals->client_taking_screenshot = true;
#endif
pPlayer->FireBullet(
pPlayer->FireBullet(
iBullet,
vOrigin,
vAngles,
flRange,

View file

@ -381,13 +381,17 @@ SendProp SendPropFloat(
Assert( sizeofVar == 0 || sizeofVar == 4 );
}
// TODO_ENHANCED: These variables will get compressed with zstd
flags = SPROP_NOSCALE;
nBits = 0;
if ( nBits <= 0 || nBits == 32 )
{
flags |= SPROP_NOSCALE;
fLowValue = 0.f;
fHighValue = 0.f;
}
else
else
{
if (fHighValue == HIGH_DEFAULT)
{
@ -428,13 +432,17 @@ SendProp SendPropVector(
Assert(sizeofVar == sizeof(Vector));
}
// TODO_ENHANCED: These variables will get compressed with zstd
flags = SPROP_NOSCALE;
nBits = 0;
if ( nBits <= 0 || nBits == 32 )
{
flags |= SPROP_NOSCALE;
fLowValue = 0.f;
fHighValue = 0.f;
}
else
else
{
if (fHighValue == HIGH_DEFAULT)
{
@ -475,13 +483,17 @@ SendProp SendPropVectorXY(
Assert(sizeofVar == sizeof(Vector));
}
// TODO_ENHANCED: These variables will get compressed with zstd
flags = SPROP_NOSCALE;
nBits = 0;
if ( nBits <= 0 || nBits == 32 )
{
flags |= SPROP_NOSCALE;
fLowValue = 0.f;
fHighValue = 0.f;
}
else
else
{
if (fHighValue == HIGH_DEFAULT)
{
@ -504,7 +516,8 @@ SendProp SendPropVectorXY(
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(
const char *pVarName,
int offset,
@ -523,13 +536,17 @@ SendProp SendPropQuaternion(
Assert(sizeofVar == sizeof(Quaternion));
}
// TODO_ENHANCED: These variables will get compressed with zstd
flags = SPROP_NOSCALE;
nBits = 0;
if ( nBits <= 0 || nBits == 32 )
{
flags |= SPROP_NOSCALE;
fLowValue = 0.f;
fHighValue = 0.f;
}
else
else
{
if (fHighValue == HIGH_DEFAULT)
{

View file

@ -11,6 +11,7 @@
#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 ZSTD_ID uint32( BigLong( ('Z'<<24)|('S'<<16)|('T'<<8)|('D') ) )
// bind the buffer for correct identification
struct lzss_header_t

View file

@ -327,6 +327,7 @@ def options(opt):
opt.load('reconfigure')
def check_deps(conf):
conf.check_cc(lib='zstd', mandatory=False)
if conf.env.DEST_OS != 'win32':
conf.check_cc(lib='dl', mandatory=False)
conf.check_cc(lib='bz2', mandatory=True)