engine: restore delta float decode/encode from 2007 branch

This commit is contained in:
nillerusr 2022-07-31 20:11:48 +03:00
parent ba8fd2952f
commit 000b2db0b7

View File

@ -19,101 +19,140 @@ extern bool ShouldWatchThisProp( const SendTable *pTable, int objectID, const ch
// The engine implements this. // The engine implements this.
extern const char* GetObjectClassName( int objectID ); extern const char* GetObjectClassName( int objectID );
void EncodeFloat( const SendProp *pProp, float fVal, bf_write *pOut, int objectID ) // Check for special flags like SPROP_COORD, SPROP_NOSCALE, and SPROP_NORMAL.
// Returns true if it encoded the float.
static inline bool EncodeSpecialFloat( const SendProp *pProp, float fVal, bf_write *pOut )
{ {
// Check for special flags like SPROP_COORD, SPROP_NOSCALE, and SPROP_NORMAL.
int flags = pProp->GetFlags(); int flags = pProp->GetFlags();
if ( flags & SPROP_COORD ) if ( flags & SPROP_COORD )
{ {
pOut->WriteBitCoord( fVal ); pOut->WriteBitCoord( fVal );
return true;
} }
else if ( flags & ( SPROP_COORD_MP | SPROP_COORD_MP_LOWPRECISION | SPROP_COORD_MP_INTEGRAL ) ) else if ( flags & SPROP_COORD_MP )
{ {
COMPILE_TIME_ASSERT( SPROP_COORD_MP_INTEGRAL == (1<<15) ); pOut->WriteBitCoordMP( fVal, false, false );
COMPILE_TIME_ASSERT( SPROP_COORD_MP_LOWPRECISION == (1<<14) ); return true;
pOut->WriteBitCoordMP( fVal, ((flags >> 15) & 1), ((flags >> 14) & 1) ); }
else if ( flags & SPROP_COORD_MP_LOWPRECISION )
{
pOut->WriteBitCoordMP( fVal, false, true );
return true;
}
else if ( flags & SPROP_COORD_MP_INTEGRAL )
{
pOut->WriteBitCoordMP( fVal, true, false );
return true;
}
else if ( flags & SPROP_NOSCALE )
{
pOut->WriteBitFloat( fVal );
return true;
} }
else if ( flags & SPROP_NORMAL ) else if ( flags & SPROP_NORMAL )
{ {
pOut->WriteBitNormal( fVal ); pOut->WriteBitNormal( fVal );
return true;
} }
else // standard clamped-range float return false;
{ }
unsigned int ulVal;
int nBits = pProp->m_nBits;
if ( flags & SPROP_NOSCALE )
{
union { float f; uint32 u; } convert = { fVal };
ulVal = convert.u;
nBits = 32;
}
else if( fVal < pProp->m_fLowValue )
{
// clamp < 0
ulVal = 0;
if(!(flags & SPROP_ROUNDUP))
{
DataTable_Warning("(class %s): Out-of-range value (%f / %f) in SendPropFloat '%s', clamping.\n",
GetObjectClassName( objectID ), fVal, pProp->m_fLowValue, pProp->m_pVarName );
}
}
else if( fVal > pProp->m_fHighValue )
{
// clamp > 1
ulVal = ((1 << pProp->m_nBits) - 1);
if(!(flags & SPROP_ROUNDDOWN))
{ static inline void EncodeFloat( const SendProp *pProp, float fVal, bf_write *pOut, int objectID )
DataTable_Warning("%s: Out-of-range value (%f/%f) in SendPropFloat '%s', clamping.\n", {
GetObjectClassName( objectID ), fVal, pProp->m_fHighValue, pProp->m_pVarName ); // Check for special flags like SPROP_COORD, SPROP_NOSCALE, and SPROP_NORMAL.
} if( EncodeSpecialFloat( pProp, fVal, pOut ) )
} {
else return;
{
float fRangeVal = (fVal - pProp->m_fLowValue) * pProp->m_fHighLowMul;
if ( pProp->m_nBits <= 22 )
{
// this is the case we always expect to hit
ulVal = FastFloatToSmallInt( fRangeVal );
}
else
{
// retain old logic just in case anyone relies on its behavior
ulVal = RoundFloatToUnsignedLong( fRangeVal );
}
}
pOut->WriteUBitLong(ulVal, nBits);
} }
uint32 ulVal;
if( fVal < pProp->m_fLowValue )
{
// clamp < 0
ulVal = 0;
if(!(pProp->GetFlags() & SPROP_ROUNDUP))
{
DataTable_Warning("(class %s): Out-of-range value (%f) in SendPropFloat '%s', clamping.\n", GetObjectClassName( objectID ), fVal, pProp->m_pVarName );
}
}
else if( fVal > pProp->m_fHighValue )
{
// clamp > 1
ulVal = ((1 << pProp->m_nBits) - 1);
if(!(pProp->GetFlags() & SPROP_ROUNDDOWN))
{
DataTable_Warning("%s: Out-of-range value (%f) in SendPropFloat '%s', clamping.\n", GetObjectClassName( objectID ), fVal, pProp->m_pVarName );
}
}
else
{
float fRangeVal = (fVal - pProp->m_fLowValue) * pProp->m_fHighLowMul;
ulVal = RoundFloatToUnsignedLong( fRangeVal );
}
pOut->WriteUBitLong(ulVal, pProp->m_nBits);
}
// Look for special flags like SPROP_COORD, SPROP_NOSCALE, and SPROP_NORMAL and
// decode if they're there. Fills in fVal and returns true if it decodes anything.
static inline bool DecodeSpecialFloat( SendProp const *pProp, bf_read *pIn, float &fVal )
{
int flags = pProp->GetFlags();
if ( flags & SPROP_COORD )
{
fVal = pIn->ReadBitCoord();
return true;
}
else if ( flags & SPROP_COORD_MP )
{
fVal = pIn->ReadBitCoordMP( false, false );
return true;
}
else if ( flags & SPROP_COORD_MP_LOWPRECISION )
{
fVal = pIn->ReadBitCoordMP( false, true );
return true;
}
else if ( flags & SPROP_COORD_MP_INTEGRAL )
{
fVal = pIn->ReadBitCoordMP( true, false );
return true;
}
else if ( flags & SPROP_NOSCALE )
{
fVal = pIn->ReadBitFloat();
return true;
}
else if ( flags & SPROP_NORMAL )
{
fVal = pIn->ReadBitNormal();
return true;
}
return false;
} }
static float DecodeFloat(SendProp const *pProp, bf_read *pIn) static float DecodeFloat(SendProp const *pProp, bf_read *pIn)
{ {
int flags = pProp->GetFlags(); float fVal;
if ( flags & SPROP_COORD ) uint32 dwInterp;
// Check for special flags..
if( DecodeSpecialFloat( pProp, pIn, fVal ) )
{ {
return pIn->ReadBitCoord();
}
else if ( flags & ( SPROP_COORD_MP | SPROP_COORD_MP_LOWPRECISION | SPROP_COORD_MP_INTEGRAL ) )
{
return pIn->ReadBitCoordMP( (flags >> 15) & 1, (flags >> 14) & 1 );
}
else if ( flags & SPROP_NOSCALE )
{
return pIn->ReadBitFloat();
}
else if ( flags & SPROP_NORMAL )
{
return pIn->ReadBitNormal();
}
else // standard clamped-range float
{
unsigned int dwInterp = pIn->ReadUBitLong(pProp->m_nBits);
float fVal = (float)dwInterp / ((1 << pProp->m_nBits) - 1);
fVal = pProp->m_fLowValue + (pProp->m_fHighValue - pProp->m_fLowValue) * fVal;
return fVal; return fVal;
} }
dwInterp = pIn->ReadUBitLong(pProp->m_nBits);
fVal = (float)dwInterp / ((1 << pProp->m_nBits) - 1);
fVal = pProp->m_fLowValue + (pProp->m_fHighValue - pProp->m_fLowValue) * fVal;
return fVal;
} }
static inline void DecodeVector(SendProp const *pProp, bf_read *pIn, float *v) static inline void DecodeVector(SendProp const *pProp, bf_read *pIn, float *v)
@ -400,26 +439,33 @@ void Float_Decode( DecodeInfo *pInfo )
int Float_CompareDeltas( const SendProp *pProp, bf_read *p1, bf_read *p2 ) int Float_CompareDeltas( const SendProp *pProp, bf_read *p1, bf_read *p2 )
{ {
int flags = pProp->GetFlags(); if ( pProp->GetFlags() & SPROP_COORD )
if ( flags & SPROP_COORD )
{ {
return p1->ReadBitCoordBits() != p2->ReadBitCoordBits(); return p1->ReadBitCoord() != p2->ReadBitCoord();
} }
else if ( flags & ( SPROP_COORD_MP | SPROP_COORD_MP_LOWPRECISION | SPROP_COORD_MP_INTEGRAL ) ) else if ( pProp->GetFlags() & SPROP_COORD_MP )
{ {
return p1->ReadBitCoordMPBits( (flags >> 15) & 1, (flags >> 14) & 1 ) return p1->ReadBitCoordMP( false, false ) != p2->ReadBitCoordMP( false, false );
!= p2->ReadBitCoordMPBits( (flags >> 15) & 1, (flags >> 14) & 1 ); }
else if ( pProp->GetFlags() & SPROP_COORD_MP_LOWPRECISION )
{
return p1->ReadBitCoordMP( false, true ) != p2->ReadBitCoordMP( false, true );
}
else if ( pProp->GetFlags() & SPROP_COORD_MP_INTEGRAL )
{
return p1->ReadBitCoordMP( true, false ) != p2->ReadBitCoordMP( true, false );
}
else if ( pProp->GetFlags() & SPROP_NOSCALE )
{
return p1->ReadUBitLong( 32 ) != p2->ReadUBitLong( 32 );
}
else if ( pProp->GetFlags() & SPROP_NORMAL )
{
return p1->ReadUBitLong( NORMAL_FRACTIONAL_BITS+1 ) != p2->ReadUBitLong( NORMAL_FRACTIONAL_BITS+1 );
} }
else else
{ {
int bits; return p1->ReadUBitLong( pProp->m_nBits ) != p2->ReadUBitLong( pProp->m_nBits );
if ( flags & SPROP_NOSCALE )
bits = 32;
else if ( flags & SPROP_NORMAL )
bits = NORMAL_FRACTIONAL_BITS+1;
else
bits = pProp->m_nBits;
return p1->ReadUBitLong( bits ) != p2->ReadUBitLong( bits );
} }
} }