Counter Strike : Global Offensive Source Code
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.

1464 lines
36 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "quakedef.h"
  8. #include "dt.h"
  9. #include "dt_encode.h"
  10. #include "coordsize.h"
  11. // memdbgon must be the last include file in a .cpp file!!!
  12. #include "tier0/memdbgon.h"
  13. extern void DataTable_Warning( const char *pInMessage, ... );
  14. extern bool ShouldWatchThisProp( const SendTable *pTable, int objectID, const char *pPropName );
  15. // The engine implements this.
  16. extern const char* GetObjectClassName( int objectID );
  17. // Check for special flags like SPROP_COORD, SPROP_NOSCALE, and SPROP_NORMAL.
  18. // Returns true if it encoded the float.
  19. static inline bool EncodeSpecialFloat( const SendProp *pProp, float fVal, bf_write *pOut )
  20. {
  21. int flags = pProp->GetFlags();
  22. if ( flags & SPROP_COORD )
  23. {
  24. pOut->WriteBitCoord( fVal );
  25. return true;
  26. }
  27. else if ( flags & SPROP_COORD_MP )
  28. {
  29. pOut->WriteBitCoordMP( fVal, kCW_None );
  30. return true;
  31. }
  32. else if ( flags & SPROP_COORD_MP_LOWPRECISION )
  33. {
  34. pOut->WriteBitCoordMP( fVal, kCW_LowPrecision );
  35. return true;
  36. }
  37. else if ( flags & SPROP_COORD_MP_INTEGRAL )
  38. {
  39. pOut->WriteBitCoordMP( fVal, kCW_Integral );
  40. return true;
  41. }
  42. else if ( flags & SPROP_NOSCALE )
  43. {
  44. pOut->WriteBitFloat( fVal );
  45. return true;
  46. }
  47. else if ( flags & SPROP_NORMAL )
  48. {
  49. pOut->WriteBitNormal( fVal );
  50. return true;
  51. }
  52. else if ( flags & SPROP_CELL_COORD )
  53. {
  54. pOut->WriteBitCellCoord( fVal, pProp->m_nBits, kCW_None );
  55. return true;
  56. }
  57. else if ( flags & SPROP_CELL_COORD_LOWPRECISION )
  58. {
  59. pOut->WriteBitCellCoord( fVal, pProp->m_nBits, kCW_LowPrecision );
  60. return true;
  61. }
  62. else if ( flags & SPROP_CELL_COORD_INTEGRAL )
  63. {
  64. pOut->WriteBitCellCoord( fVal, pProp->m_nBits, kCW_Integral );
  65. return true;
  66. }
  67. return false;
  68. }
  69. static inline void EncodeFloat( const SendProp *pProp, float fVal, bf_write *pOut, int objectID )
  70. {
  71. // Check for special flags like SPROP_COORD, SPROP_NOSCALE, and SPROP_NORMAL.
  72. if( EncodeSpecialFloat( pProp, fVal, pOut ) )
  73. {
  74. return;
  75. }
  76. unsigned long ulVal;
  77. if( fVal < pProp->m_fLowValue )
  78. {
  79. // clamp < 0
  80. ulVal = 0;
  81. if(!(pProp->GetFlags() & SPROP_ROUNDUP))
  82. {
  83. DataTable_Warning("(class %s): Out-of-range value (%f) in SendPropFloat '%s', clamping.\n", GetObjectClassName( objectID ), fVal, pProp->m_pVarName );
  84. }
  85. }
  86. else if( fVal > pProp->m_fHighValue )
  87. {
  88. // clamp > 1
  89. ulVal = ((1 << pProp->m_nBits) - 1);
  90. if(!(pProp->GetFlags() & SPROP_ROUNDDOWN))
  91. {
  92. DataTable_Warning("%s: Out-of-range value (%f) in SendPropFloat '%s', clamping.\n", GetObjectClassName( objectID ), fVal, pProp->m_pVarName );
  93. }
  94. }
  95. else
  96. {
  97. float fRangeVal = (fVal - pProp->m_fLowValue) * pProp->m_fHighLowMul;
  98. ulVal = RoundFloatToUnsignedLong( fRangeVal );
  99. }
  100. pOut->WriteUBitLong(ulVal, pProp->m_nBits);
  101. }
  102. // Look for special flags like SPROP_COORD, SPROP_NOSCALE, and SPROP_NORMAL and
  103. // decode if they're there. Fills in fVal and returns true if it decodes anything.
  104. static inline bool DecodeSpecialFloat( SendProp const *pProp, bf_read *pIn, float &fVal )
  105. {
  106. int flags = pProp->GetFlags();
  107. if ( flags & SPROP_COORD )
  108. {
  109. fVal = pIn->ReadBitCoord();
  110. return true;
  111. }
  112. else if ( flags & SPROP_COORD_MP )
  113. {
  114. fVal = pIn->ReadBitCoordMP( kCW_None );
  115. return true;
  116. }
  117. else if ( flags & SPROP_COORD_MP_LOWPRECISION )
  118. {
  119. fVal = pIn->ReadBitCoordMP( kCW_LowPrecision );
  120. return true;
  121. }
  122. else if ( flags & SPROP_COORD_MP_INTEGRAL )
  123. {
  124. fVal = pIn->ReadBitCoordMP( kCW_Integral );
  125. return true;
  126. }
  127. else if ( flags & SPROP_NOSCALE )
  128. {
  129. fVal = pIn->ReadBitFloat();
  130. return true;
  131. }
  132. else if ( flags & SPROP_NORMAL )
  133. {
  134. fVal = pIn->ReadBitNormal();
  135. return true;
  136. }
  137. else if ( flags & SPROP_CELL_COORD )
  138. {
  139. fVal = pIn->ReadBitCellCoord( pProp->m_nBits, kCW_None );
  140. return true;
  141. }
  142. else if ( flags & SPROP_CELL_COORD_LOWPRECISION )
  143. {
  144. fVal = pIn->ReadBitCellCoord( pProp->m_nBits, kCW_LowPrecision );
  145. return true;
  146. }
  147. else if ( flags & SPROP_CELL_COORD_INTEGRAL )
  148. {
  149. fVal = pIn->ReadBitCellCoord( pProp->m_nBits, kCW_Integral );
  150. return true;
  151. }
  152. return false;
  153. }
  154. static float DecodeFloat(SendProp const *pProp, bf_read *pIn)
  155. {
  156. float fVal = 0;
  157. unsigned long dwInterp;
  158. // Check for special flags..
  159. if( DecodeSpecialFloat( pProp, pIn, fVal ) )
  160. {
  161. return fVal;
  162. }
  163. dwInterp = pIn->ReadUBitLong(pProp->m_nBits);
  164. fVal = (float)dwInterp / ((1 << pProp->m_nBits) - 1);
  165. fVal = pProp->m_fLowValue + (pProp->m_fHighValue - pProp->m_fLowValue) * fVal;
  166. return fVal;
  167. }
  168. static inline void DecodeVector(SendProp const *pProp, bf_read *pIn, float *v)
  169. {
  170. v[0] = DecodeFloat(pProp, pIn);
  171. v[1] = DecodeFloat(pProp, pIn);
  172. // Don't read in the third component for normals
  173. if ((pProp->GetFlags() & SPROP_NORMAL) == 0)
  174. {
  175. v[2] = DecodeFloat(pProp, pIn);
  176. }
  177. else
  178. {
  179. int signbit = pIn->ReadOneBit();
  180. float v0v0v1v1 = v[0] * v[0] +
  181. v[1] * v[1];
  182. if (v0v0v1v1 < 1.0f)
  183. v[2] = sqrtf( 1.0f - v0v0v1v1 );
  184. else
  185. v[2] = 0.0f;
  186. if (signbit)
  187. v[2] *= -1.0f;
  188. }
  189. }
  190. static inline void DecodeQuaternion(SendProp const *pProp, bf_read *pIn, float *v)
  191. {
  192. v[0] = DecodeFloat(pProp, pIn);
  193. v[1] = DecodeFloat(pProp, pIn);
  194. v[2] = DecodeFloat(pProp, pIn);
  195. v[3] = DecodeFloat(pProp, pIn);
  196. }
  197. int DecodeBits( DecodeInfo *pInfo, unsigned char *pOut )
  198. {
  199. bf_read temp;
  200. // Read the property in (note: we don't return the bits from here because Decode returns
  201. // the decoded bits.. we're interested in getting the encoded bits).
  202. temp = *pInfo->m_pIn;
  203. pInfo->m_pRecvProp = NULL;
  204. pInfo->m_pData = NULL;
  205. g_PropTypeFns[pInfo->m_pProp->m_Type].Decode( pInfo );
  206. // Return the encoded bits.
  207. int nBits = pInfo->m_pIn->GetNumBitsRead() - temp.GetNumBitsRead();
  208. temp.ReadBits(pOut, nBits);
  209. return nBits;
  210. }
  211. // ---------------------------------------------------------------------------------------- //
  212. // Most of the prop types can use this generic FastCopy version. Arrays are a bit of a pain.
  213. // ---------------------------------------------------------------------------------------- //
  214. inline void Generic_FastCopy(
  215. const SendProp *pSendProp,
  216. const RecvProp *pRecvProp,
  217. const unsigned char *pSendData,
  218. unsigned char *pRecvData,
  219. int objectID )
  220. {
  221. // Get the data out of the ent.
  222. CRecvProxyData recvProxyData;
  223. pSendProp->GetProxyFn()(
  224. pSendProp,
  225. pSendData,
  226. pSendData + pSendProp->GetOffset(),
  227. &recvProxyData.m_Value,
  228. 0,
  229. objectID
  230. );
  231. // Fill in the data for the recv proxy.
  232. recvProxyData.m_pRecvProp = pRecvProp;
  233. recvProxyData.m_iElement = 0;
  234. recvProxyData.m_ObjectID = objectID;
  235. pRecvProp->GetProxyFn()( &recvProxyData, pRecvData, pRecvData + pRecvProp->GetOffset() );
  236. }
  237. // ---------------------------------------------------------------------------------------- //
  238. // DecodeInfo implementation.
  239. // ---------------------------------------------------------------------------------------- //
  240. void DecodeInfo::CopyVars( const DecodeInfo *pOther )
  241. {
  242. m_pStruct = pOther->m_pStruct;
  243. m_pData = pOther->m_pData;
  244. m_pRecvProp = pOther->m_pRecvProp;
  245. m_pProp = pOther->m_pProp;
  246. m_pIn = pOther->m_pIn;
  247. m_ObjectID = pOther->m_ObjectID;
  248. m_iElement = pOther->m_iElement;
  249. }
  250. // ---------------------------------------------------------------------------------------- //
  251. // Int property type abstraction.
  252. // ---------------------------------------------------------------------------------------- //
  253. void Int_Encode( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp, bf_write *pOut, int objectID )
  254. {
  255. #ifdef DBGFLAG_ASSERT
  256. // Assert that either the property is unsigned and in valid range,
  257. // or signed with a consistant sign extension in the high bits
  258. if ( !(pProp->GetFlags() & SPROP_VARINT) )
  259. {
  260. if ( pProp->m_nBits < 32 )
  261. {
  262. if ( pProp->GetFlags() & SPROP_UNSIGNED )
  263. {
  264. int32 nMaskedValue = pVar->m_Int;
  265. nMaskedValue &= (1u << pProp->m_nBits) - 1;
  266. Assert( nMaskedValue == pVar->m_Int );
  267. }
  268. else
  269. {
  270. int32 nSignExtendedValue = pVar->m_Int;
  271. nSignExtendedValue <<= 32 - pProp->m_nBits;
  272. nSignExtendedValue >>= 32 - pProp->m_nBits;
  273. Assert( nSignExtendedValue == pVar->m_Int );
  274. }
  275. }
  276. }
  277. #endif
  278. if ( pProp->GetFlags() & SPROP_VARINT)
  279. {
  280. if ( pProp->GetFlags() & SPROP_UNSIGNED )
  281. {
  282. pOut->WriteVarInt32( pVar->m_Int );
  283. }
  284. else
  285. {
  286. pOut->WriteSignedVarInt32( pVar->m_Int );
  287. }
  288. }
  289. else
  290. {
  291. if( pProp->IsSigned() )
  292. {
  293. pOut->WriteSBitLong( pVar->m_Int, pProp->m_nBits );
  294. }
  295. else
  296. {
  297. pOut->WriteUBitLong( (unsigned int)pVar->m_Int, pProp->m_nBits );
  298. }
  299. }
  300. }
  301. void Int_Decode( DecodeInfo *pInfo )
  302. {
  303. const SendProp *pProp = pInfo->m_pProp;
  304. int flags = pProp->GetFlags();
  305. if ( flags & SPROP_VARINT )
  306. {
  307. if ( flags & SPROP_UNSIGNED )
  308. {
  309. pInfo->m_Value.m_Int = (long)pInfo->m_pIn->ReadVarInt32();
  310. }
  311. else
  312. {
  313. pInfo->m_Value.m_Int = pInfo->m_pIn->ReadSignedVarInt32();
  314. }
  315. }
  316. else
  317. {
  318. if ( flags & SPROP_UNSIGNED )
  319. {
  320. pInfo->m_Value.m_Int = pInfo->m_pIn->ReadUBitLong(pInfo->m_pProp->m_nBits);
  321. }
  322. else
  323. {
  324. pInfo->m_Value.m_Int = pInfo->m_pIn->ReadSBitLong( pInfo->m_pProp->m_nBits );
  325. }
  326. }
  327. if ( pInfo->m_pRecvProp )
  328. {
  329. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  330. }
  331. }
  332. int Int_CompareDeltas( const SendProp *pProp, bf_read *p1, bf_read *p2 )
  333. {
  334. if ( pProp->GetFlags() & SPROP_VARINT)
  335. {
  336. if ( pProp->GetFlags() & SPROP_UNSIGNED )
  337. {
  338. return p1->ReadVarInt32() != p2->ReadVarInt32();
  339. }
  340. return p1->ReadSignedVarInt32() != p2->ReadSignedVarInt32();
  341. }
  342. return p1->ReadUBitLong( pProp->m_nBits ) != p2->ReadUBitLong( pProp->m_nBits );
  343. }
  344. const char* Int_GetTypeNameString()
  345. {
  346. return "DPT_Int";
  347. }
  348. bool Int_IsZero( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp )
  349. {
  350. return (pVar->m_Int == 0);
  351. }
  352. void Int_DecodeZero( DecodeInfo *pInfo )
  353. {
  354. pInfo->m_Value.m_Int = 0;
  355. if ( pInfo->m_pRecvProp )
  356. {
  357. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  358. }
  359. }
  360. bool Int_IsEncodedZero( const SendProp *pProp, bf_read *pIn )
  361. {
  362. if ( pProp->GetFlags() & SPROP_VARINT)
  363. {
  364. if ( pProp->GetFlags() & SPROP_UNSIGNED )
  365. {
  366. return pIn->ReadVarInt32() == 0;
  367. }
  368. return pIn->ReadSignedVarInt32() == 0;
  369. }
  370. return pIn->ReadUBitLong( pProp->m_nBits ) == 0;
  371. }
  372. void Int_SkipProp( const SendProp *pProp, bf_read *pIn )
  373. {
  374. if ( pProp->GetFlags() & SPROP_VARINT)
  375. {
  376. if ( pProp->GetFlags() & SPROP_UNSIGNED )
  377. {
  378. pIn->ReadVarInt32();
  379. }
  380. else
  381. {
  382. pIn->ReadSignedVarInt32();
  383. }
  384. }
  385. else
  386. {
  387. pIn->SeekRelative( pProp->m_nBits );
  388. }
  389. }
  390. // ---------------------------------------------------------------------------------------- //
  391. // Float type abstraction.
  392. // ---------------------------------------------------------------------------------------- //
  393. void Float_Encode( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp, bf_write *pOut, int objectID )
  394. {
  395. EncodeFloat( pProp, pVar->m_Float, pOut, objectID );
  396. }
  397. void Float_Decode( DecodeInfo *pInfo )
  398. {
  399. pInfo->m_Value.m_Float = DecodeFloat(pInfo->m_pProp, pInfo->m_pIn);
  400. if ( pInfo->m_pRecvProp )
  401. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  402. }
  403. int Float_CompareDeltas( const SendProp *pProp, bf_read *p1, bf_read *p2 )
  404. {
  405. if ( pProp->GetFlags() & SPROP_COORD )
  406. {
  407. return p1->ReadBitCoord() != p2->ReadBitCoord();
  408. }
  409. else if ( pProp->GetFlags() & SPROP_COORD_MP )
  410. {
  411. return p1->ReadBitCoordMP( kCW_None ) != p2->ReadBitCoordMP( kCW_None );
  412. }
  413. else if ( pProp->GetFlags() & SPROP_COORD_MP_LOWPRECISION )
  414. {
  415. return p1->ReadBitCoordMP( kCW_LowPrecision ) != p2->ReadBitCoordMP( kCW_LowPrecision );
  416. }
  417. else if ( pProp->GetFlags() & SPROP_COORD_MP_INTEGRAL )
  418. {
  419. return p1->ReadBitCoordMP( kCW_Integral ) != p2->ReadBitCoordMP( kCW_Integral );
  420. }
  421. else if ( pProp->GetFlags() & SPROP_NOSCALE )
  422. {
  423. return p1->ReadUBitLong( 32 ) != p2->ReadUBitLong( 32 );
  424. }
  425. else if ( pProp->GetFlags() & SPROP_NORMAL )
  426. {
  427. return p1->ReadUBitLong( NORMAL_FRACTIONAL_BITS+1 ) != p2->ReadUBitLong( NORMAL_FRACTIONAL_BITS+1 );
  428. }
  429. else if ( pProp->GetFlags() & SPROP_CELL_COORD )
  430. {
  431. return p1->ReadBitCellCoord( pProp->m_nBits, kCW_None ) != p2->ReadBitCellCoord( pProp->m_nBits, kCW_None );
  432. }
  433. else if ( pProp->GetFlags() & SPROP_CELL_COORD_LOWPRECISION )
  434. {
  435. return p1->ReadBitCellCoord( pProp->m_nBits, kCW_LowPrecision ) != p2->ReadBitCellCoord( pProp->m_nBits, kCW_LowPrecision );
  436. }
  437. else if ( pProp->GetFlags() & SPROP_CELL_COORD_INTEGRAL )
  438. {
  439. return p1->ReadBitCellCoord( pProp->m_nBits, kCW_Integral ) != p2->ReadBitCellCoord( pProp->m_nBits, kCW_Integral );
  440. }
  441. else
  442. {
  443. return p1->ReadUBitLong( pProp->m_nBits ) != p2->ReadUBitLong( pProp->m_nBits );
  444. }
  445. }
  446. const char* Float_GetTypeNameString()
  447. {
  448. return "DPT_Float";
  449. }
  450. bool Float_IsZero( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp )
  451. {
  452. return (pVar->m_Float == 0);
  453. }
  454. void Float_DecodeZero( DecodeInfo *pInfo )
  455. {
  456. pInfo->m_Value.m_Float = 0;
  457. if ( pInfo->m_pRecvProp )
  458. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  459. }
  460. bool Float_IsEncodedZero( const SendProp *pProp, bf_read *pIn )
  461. {
  462. return DecodeFloat( pProp, pIn ) == 0.0f;
  463. }
  464. void Float_SkipProp( const SendProp *pProp, bf_read *pIn )
  465. {
  466. // Check for special flags..
  467. if(pProp->GetFlags() & SPROP_COORD)
  468. {
  469. // Read the required integer and fraction flags
  470. unsigned int val = pIn->ReadUBitLong(2);
  471. // this reads two bits, the first bit (bit0 in this word) indicates integer part
  472. // the second bit (bit1 in this word) indicates the fractional part
  473. // If we got either parse them, otherwise it's a zero.
  474. if ( val )
  475. {
  476. // sign bit
  477. int seekDist = 1;
  478. // If there's an integer, read it in
  479. if ( val & 1 )
  480. seekDist += COORD_INTEGER_BITS;
  481. if ( val & 2 )
  482. seekDist += COORD_FRACTIONAL_BITS;
  483. pIn->SeekRelative( seekDist );
  484. }
  485. }
  486. else if ( pProp->GetFlags() & SPROP_COORD_MP )
  487. {
  488. pIn->ReadBitCoordMP( kCW_None );
  489. }
  490. else if ( pProp->GetFlags() & SPROP_COORD_MP_LOWPRECISION )
  491. {
  492. pIn->ReadBitCoordMP( kCW_LowPrecision );
  493. }
  494. else if ( pProp->GetFlags() & SPROP_COORD_MP_INTEGRAL )
  495. {
  496. pIn->ReadBitCoordMP( kCW_Integral );
  497. }
  498. else if(pProp->GetFlags() & SPROP_NOSCALE)
  499. {
  500. pIn->SeekRelative( 32 );
  501. }
  502. else if(pProp->GetFlags() & SPROP_NORMAL)
  503. {
  504. pIn->SeekRelative( NORMAL_FRACTIONAL_BITS + 1 );
  505. }
  506. else if ( pProp->GetFlags() & SPROP_CELL_COORD )
  507. {
  508. pIn->ReadBitCellCoord( pProp->m_nBits, kCW_None );
  509. }
  510. else if ( pProp->GetFlags() & SPROP_CELL_COORD_LOWPRECISION )
  511. {
  512. pIn->ReadBitCellCoord( pProp->m_nBits, kCW_LowPrecision );
  513. }
  514. else if ( pProp->GetFlags() & SPROP_CELL_COORD_INTEGRAL )
  515. {
  516. pIn->ReadBitCellCoord( pProp->m_nBits, kCW_Integral );
  517. }
  518. else
  519. {
  520. pIn->SeekRelative( pProp->m_nBits );
  521. }
  522. }
  523. // ---------------------------------------------------------------------------------------- //
  524. // Vector type abstraction.
  525. // ---------------------------------------------------------------------------------------- //
  526. void Vector_Encode( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp, bf_write *pOut, int objectID )
  527. {
  528. EncodeFloat(pProp, pVar->m_Vector[0], pOut, objectID);
  529. EncodeFloat(pProp, pVar->m_Vector[1], pOut, objectID);
  530. // Don't write out the third component for normals
  531. if ((pProp->GetFlags() & SPROP_NORMAL) == 0)
  532. {
  533. EncodeFloat(pProp, pVar->m_Vector[2], pOut, objectID);
  534. }
  535. else
  536. {
  537. // Write a sign bit for z instead!
  538. int signbit = (pVar->m_Vector[2] <= -NORMAL_RESOLUTION);
  539. pOut->WriteOneBit( signbit );
  540. }
  541. }
  542. void Vector_Decode(DecodeInfo *pInfo)
  543. {
  544. DecodeVector( pInfo->m_pProp, pInfo->m_pIn, pInfo->m_Value.m_Vector );
  545. if( pInfo->m_pRecvProp )
  546. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  547. }
  548. int Vector_CompareDeltas( const SendProp *pProp, bf_read *p1, bf_read *p2 )
  549. {
  550. int c1 = Float_CompareDeltas( pProp, p1, p2 );
  551. int c2 = Float_CompareDeltas( pProp, p1, p2 );
  552. int c3;
  553. if ( pProp->GetFlags() & SPROP_NORMAL )
  554. {
  555. c3 = p1->ReadOneBit() != p2->ReadOneBit();
  556. }
  557. else
  558. {
  559. c3 = Float_CompareDeltas( pProp, p1, p2 );
  560. }
  561. return c1 | c2 | c3;
  562. }
  563. const char* Vector_GetTypeNameString()
  564. {
  565. return "DPT_Vector";
  566. }
  567. bool Vector_IsZero( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp )
  568. {
  569. return ( pVar->m_Vector[0] == 0 ) && ( pVar->m_Vector[1] == 0 ) && ( pVar->m_Vector[2] == 0 );
  570. }
  571. void Vector_DecodeZero( DecodeInfo *pInfo )
  572. {
  573. pInfo->m_Value.m_Vector[0] = 0;
  574. pInfo->m_Value.m_Vector[1] = 0;
  575. pInfo->m_Value.m_Vector[2] = 0;
  576. if ( pInfo->m_pRecvProp )
  577. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  578. }
  579. bool Vector_IsEncodedZero( const SendProp *pProp, bf_read *pIn )
  580. {
  581. float v[3];
  582. DecodeVector( pProp, pIn, v );
  583. return ( v[0] == 0 ) && ( v[1] == 0 ) && ( v[2] == 0 );
  584. }
  585. void Vector_SkipProp( const SendProp *pProp, bf_read *pIn )
  586. {
  587. Float_SkipProp(pProp, pIn);
  588. Float_SkipProp(pProp, pIn);
  589. // Don't read in the third component for normals
  590. if ( pProp->GetFlags() & SPROP_NORMAL )
  591. {
  592. pIn->SeekRelative( 1 );
  593. }
  594. else
  595. {
  596. Float_SkipProp(pProp, pIn);
  597. }
  598. }
  599. // ---------------------------------------------------------------------------------------- //
  600. // VectorXY type abstraction.
  601. // ---------------------------------------------------------------------------------------- //
  602. void VectorXY_Encode( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp, bf_write *pOut, int objectID )
  603. {
  604. EncodeFloat(pProp, pVar->m_Vector[0], pOut, objectID);
  605. EncodeFloat(pProp, pVar->m_Vector[1], pOut, objectID);
  606. }
  607. void VectorXY_Decode(DecodeInfo *pInfo)
  608. {
  609. pInfo->m_Value.m_Vector[0] = DecodeFloat(pInfo->m_pProp, pInfo->m_pIn);
  610. pInfo->m_Value.m_Vector[1] = DecodeFloat(pInfo->m_pProp, pInfo->m_pIn);
  611. if( pInfo->m_pRecvProp )
  612. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  613. }
  614. int VectorXY_CompareDeltas( const SendProp *pProp, bf_read *p1, bf_read *p2 )
  615. {
  616. int c1 = Float_CompareDeltas( pProp, p1, p2 );
  617. int c2 = Float_CompareDeltas( pProp, p1, p2 );
  618. return c1 | c2;
  619. }
  620. const char* VectorXY_GetTypeNameString()
  621. {
  622. return "DPT_VectorXY";
  623. }
  624. bool VectorXY_IsZero( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp )
  625. {
  626. return ( pVar->m_Vector[0] == 0 ) && ( pVar->m_Vector[1] == 0 );
  627. }
  628. void VectorXY_DecodeZero( DecodeInfo *pInfo )
  629. {
  630. pInfo->m_Value.m_Vector[0] = 0;
  631. pInfo->m_Value.m_Vector[1] = 0;
  632. if ( pInfo->m_pRecvProp )
  633. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  634. }
  635. bool VectorXY_IsEncodedZero( const SendProp *pProp, bf_read *pIn )
  636. {
  637. float v[2];
  638. v[0] = DecodeFloat(pProp, pIn);
  639. v[1] = DecodeFloat(pProp, pIn);
  640. return ( v[0] == 0 ) && ( v[1] == 0 );
  641. }
  642. void VectorXY_SkipProp( const SendProp *pProp, bf_read *pIn )
  643. {
  644. Float_SkipProp(pProp, pIn);
  645. Float_SkipProp(pProp, pIn);
  646. }
  647. #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!!!
  648. // ---------------------------------------------------------------------------------------- //
  649. // Quaternion type abstraction.
  650. // ---------------------------------------------------------------------------------------- //
  651. void Quaternion_Encode( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp, bf_write *pOut, int objectID )
  652. {
  653. EncodeFloat(pProp, pVar->m_Vector[0], pOut, objectID);
  654. EncodeFloat(pProp, pVar->m_Vector[1], pOut, objectID);
  655. EncodeFloat(pProp, pVar->m_Vector[2], pOut, objectID);
  656. EncodeFloat(pProp, pVar->m_Vector[3], pOut, objectID);
  657. }
  658. void Quaternion_Decode(DecodeInfo *pInfo)
  659. {
  660. DecodeQuaternion( pInfo->m_pProp, pInfo->m_pIn, pInfo->m_Value.m_Vector );
  661. if( pInfo->m_pRecvProp )
  662. {
  663. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  664. }
  665. }
  666. int Quaternion_CompareDeltas( const SendProp *pProp, bf_read *p1, bf_read *p2 )
  667. {
  668. int c1 = Float_CompareDeltas( pProp, p1, p2 );
  669. int c2 = Float_CompareDeltas( pProp, p1, p2 );
  670. int c3 = Float_CompareDeltas( pProp, p1, p2 );
  671. int c4 = Float_CompareDeltas( pProp, p1, p2 );
  672. return c1 | c2 | c3 | c4;
  673. }
  674. const char* Quaternion_GetTypeNameString()
  675. {
  676. return "DPT_Quaternion";
  677. }
  678. bool Quaternion_IsZero( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp )
  679. {
  680. return ( pVar->m_Vector[0] == 0 ) && ( pVar->m_Vector[1] == 0 ) && ( pVar->m_Vector[2] == 0 ) && ( pVar->m_Vector[3] == 0 );
  681. }
  682. void Quaternion_DecodeZero( DecodeInfo *pInfo )
  683. {
  684. pInfo->m_Value.m_Vector[0] = 0;
  685. pInfo->m_Value.m_Vector[1] = 0;
  686. pInfo->m_Value.m_Vector[2] = 0;
  687. pInfo->m_Value.m_Vector[3] = 0;
  688. if ( pInfo->m_pRecvProp )
  689. {
  690. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  691. }
  692. }
  693. bool Quaternion_IsEncodedZero( const SendProp *pProp, bf_read *pIn )
  694. {
  695. float v[4];
  696. DecodeQuaternion( pProp, pIn, v );
  697. return ( v[0] == 0 ) && ( v[1] == 0 ) && ( v[2] == 0 ) && ( v[3] == 0 );
  698. }
  699. void Quaternion_SkipProp( const SendProp *pProp, bf_read *pIn )
  700. {
  701. Float_SkipProp(pProp, pIn);
  702. Float_SkipProp(pProp, pIn);
  703. Float_SkipProp(pProp, pIn);
  704. Float_SkipProp(pProp, pIn);
  705. }
  706. #endif
  707. // ---------------------------------------------------------------------------------------- //
  708. // String type abstraction.
  709. // ---------------------------------------------------------------------------------------- //
  710. void String_Encode( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp, bf_write *pOut, int objectID )
  711. {
  712. // First count the string length, then do one WriteBits call.
  713. int len;
  714. for ( len=0; len < DT_MAX_STRING_BUFFERSIZE-1; len++ )
  715. {
  716. if( pVar->m_pString[len] == 0 )
  717. {
  718. break;
  719. }
  720. }
  721. // Optionally write the length here so deltas can be compared faster.
  722. pOut->WriteUBitLong( len, DT_MAX_STRING_BITS );
  723. pOut->WriteBits( pVar->m_pString, len * 8 );
  724. }
  725. void String_Decode(DecodeInfo *pInfo)
  726. {
  727. // Read it in.
  728. int len = pInfo->m_pIn->ReadUBitLong( DT_MAX_STRING_BITS );
  729. char *tempStr = pInfo->m_TempStr;
  730. if ( len >= DT_MAX_STRING_BUFFERSIZE )
  731. {
  732. Warning( "String_Decode( %s ) invalid length (%d)\n", pInfo->m_pRecvProp->GetName(), len );
  733. len = DT_MAX_STRING_BUFFERSIZE - 1;
  734. }
  735. pInfo->m_pIn->ReadBits( tempStr, len*8 );
  736. tempStr[len] = 0;
  737. pInfo->m_Value.m_pString = tempStr;
  738. // Give it to the RecvProxy.
  739. if ( pInfo->m_pRecvProp )
  740. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  741. }
  742. // Compare the bits in pBuf1 and pBuf2 and return 1 if they are different.
  743. // This must always seek both buffers to wherever they start at + nBits.
  744. static inline int AreBitsDifferent( bf_read *pBuf1, bf_read *pBuf2, int nBits )
  745. {
  746. int nDWords = nBits >> 5;
  747. int diff = 0;
  748. for ( int iDWord=0; iDWord < nDWords; iDWord++ )
  749. {
  750. diff |= (pBuf1->ReadUBitLong(32) != pBuf2->ReadUBitLong(32));
  751. }
  752. int nRemainingBits = nBits - (nDWords<<5);
  753. if (nRemainingBits > 0)
  754. diff |= pBuf1->ReadUBitLong( nRemainingBits ) != pBuf2->ReadUBitLong( nRemainingBits );
  755. return diff;
  756. }
  757. int String_CompareDeltas( const SendProp *pProp, bf_read *p1, bf_read *p2 )
  758. {
  759. int len1 = p1->ReadUBitLong( DT_MAX_STRING_BITS );
  760. int len2 = p2->ReadUBitLong( DT_MAX_STRING_BITS );
  761. if ( len1 == len2 )
  762. {
  763. // check if both strings are empty
  764. if (len1 == 0)
  765. return false;
  766. // Ok, they're short and fast.
  767. return AreBitsDifferent( p1, p2, len1*8 );
  768. }
  769. else
  770. {
  771. p1->SeekRelative( len1 * 8 );
  772. p2->SeekRelative( len2 * 8 );
  773. return true;
  774. }
  775. }
  776. const char* String_GetTypeNameString()
  777. {
  778. return "DPT_String";
  779. }
  780. bool String_IsZero( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp )
  781. {
  782. return ( pVar->m_pString[0] == 0 );
  783. }
  784. void String_DecodeZero( DecodeInfo *pInfo )
  785. {
  786. pInfo->m_Value.m_pString = pInfo->m_TempStr;
  787. pInfo->m_TempStr[0] = 0;
  788. if ( pInfo->m_pRecvProp )
  789. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  790. }
  791. bool String_IsEncodedZero( const SendProp *pProp, bf_read *pIn )
  792. {
  793. // Read it in.
  794. int len = pIn->ReadUBitLong( DT_MAX_STRING_BITS );
  795. pIn->SeekRelative( len*8 );
  796. return len == 0;
  797. }
  798. void String_SkipProp( const SendProp *pProp, bf_read *pIn )
  799. {
  800. int len = pIn->ReadUBitLong( DT_MAX_STRING_BITS );
  801. pIn->SeekRelative( len*8 );
  802. }
  803. // ---------------------------------------------------------------------------------------- //
  804. // Array abstraction.
  805. // ---------------------------------------------------------------------------------------- //
  806. int Array_GetLength( const unsigned char *pStruct, const SendProp *pProp, int objectID )
  807. {
  808. // Get the array length from the proxy.
  809. ArrayLengthSendProxyFn proxy = pProp->GetArrayLengthProxy();
  810. if ( proxy )
  811. {
  812. int nElements = proxy( pStruct, objectID );
  813. // Make sure it's not too big.
  814. if ( nElements > pProp->GetNumElements() )
  815. {
  816. Assert( false );
  817. nElements = pProp->GetNumElements();
  818. }
  819. return nElements;
  820. }
  821. else
  822. {
  823. return pProp->GetNumElements();
  824. }
  825. }
  826. void Array_Encode( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp, bf_write *pOut, int objectID )
  827. {
  828. SendProp *pArrayProp = pProp->GetArrayProp();
  829. AssertMsg( pArrayProp, ("Array_Encode: missing m_pArrayProp for SendProp '%s'.", pProp->m_pVarName) );
  830. int nElements = Array_GetLength( pStruct, pProp, objectID );
  831. // Write the number of elements.
  832. pOut->WriteUBitLong( nElements, pProp->GetNumArrayLengthBits() );
  833. unsigned char *pCurStructOffset = (unsigned char*)pStruct + pArrayProp->GetOffset();
  834. for ( int iElement=0; iElement < nElements; iElement++ )
  835. {
  836. DVariant var;
  837. // Call the proxy to get the value, then encode.
  838. pArrayProp->GetProxyFn()( pArrayProp, pStruct, pCurStructOffset, &var, iElement, objectID );
  839. g_PropTypeFns[pArrayProp->GetType()].Encode( pStruct, &var, pArrayProp, pOut, objectID );
  840. pCurStructOffset += pProp->GetElementStride();
  841. }
  842. }
  843. void Array_Decode( DecodeInfo *pInfo )
  844. {
  845. SendProp *pArrayProp = pInfo->m_pProp->GetArrayProp();
  846. AssertMsg( pArrayProp, ("Array_Decode: missing m_pArrayProp for a property.") );
  847. // Setup a DecodeInfo that is used to decode each of the child properties.
  848. DecodeInfo subDecodeInfo;
  849. subDecodeInfo.CopyVars( pInfo );
  850. subDecodeInfo.m_pProp = pArrayProp;
  851. int elementStride = 0;
  852. ArrayLengthRecvProxyFn lengthProxy = 0;
  853. if ( pInfo->m_pRecvProp )
  854. {
  855. RecvProp *pArrayRecvProp = pInfo->m_pRecvProp->GetArrayProp();
  856. subDecodeInfo.m_pRecvProp = pArrayRecvProp;
  857. // Note we get the OFFSET from the array element property and the STRIDE from the array itself.
  858. subDecodeInfo.m_pData = (char*)pInfo->m_pData + pArrayRecvProp->GetOffset();
  859. elementStride = pInfo->m_pRecvProp->GetElementStride();
  860. Assert( elementStride != -1 ); // (Make sure it was set..)
  861. lengthProxy = pInfo->m_pRecvProp->GetArrayLengthProxy();
  862. }
  863. int nElements = pInfo->m_pIn->ReadUBitLong( pInfo->m_pProp->GetNumArrayLengthBits() );
  864. if ( lengthProxy )
  865. lengthProxy( pInfo->m_pStruct, pInfo->m_ObjectID, nElements );
  866. for ( subDecodeInfo.m_iElement=0; subDecodeInfo.m_iElement < nElements; subDecodeInfo.m_iElement++ )
  867. {
  868. g_PropTypeFns[pArrayProp->GetType()].Decode( &subDecodeInfo );
  869. subDecodeInfo.m_pData = (char*)subDecodeInfo.m_pData + elementStride;
  870. }
  871. }
  872. int Array_CompareDeltas( const SendProp *pProp, bf_read *p1, bf_read *p2 )
  873. {
  874. SendProp *pArrayProp = pProp->GetArrayProp();
  875. AssertMsg( pArrayProp, ("Array_CompareDeltas: missing m_pArrayProp for SendProp '%s'.", pProp->m_pVarName) );
  876. int nLengthBits = pProp->GetNumArrayLengthBits();
  877. int length1 = p1->ReadUBitLong( nLengthBits );
  878. int length2 = p2->ReadUBitLong( nLengthBits );
  879. int bDifferent = length1 != length2;
  880. // Compare deltas on the props that are the same.
  881. int nSame = MIN( length1, length2 );
  882. for ( int iElement=0; iElement < nSame; iElement++ )
  883. {
  884. bDifferent |= g_PropTypeFns[pArrayProp->GetType()].CompareDeltas( pArrayProp, p1, p2 );
  885. }
  886. // Now just eat up the remaining properties in whichever buffer was larger.
  887. if ( length1 != length2 )
  888. {
  889. bf_read *buffer = (length1 > length2) ? p1 : p2;
  890. int nExtra = MAX( length1, length2 ) - nSame;
  891. for ( int iEatUp=0; iEatUp < nExtra; iEatUp++ )
  892. {
  893. SkipPropData( buffer, pArrayProp );
  894. }
  895. }
  896. return bDifferent;
  897. }
  898. void Array_FastCopy(
  899. const SendProp *pSendProp,
  900. const RecvProp *pRecvProp,
  901. const unsigned char *pSendData,
  902. unsigned char *pRecvData,
  903. int objectID )
  904. {
  905. const RecvProp *pArrayRecvProp = pRecvProp->GetArrayProp();
  906. const SendProp *pArraySendProp = pSendProp->GetArrayProp();
  907. CRecvProxyData recvProxyData;
  908. recvProxyData.m_pRecvProp = pArrayRecvProp;
  909. recvProxyData.m_ObjectID = objectID;
  910. // Find out the array length and call the RecvProp's array-length proxy.
  911. int nElements = Array_GetLength( pSendData, pSendProp, objectID );
  912. ArrayLengthRecvProxyFn lengthProxy = pRecvProp->GetArrayLengthProxy();
  913. if ( lengthProxy )
  914. lengthProxy( pRecvData, objectID, nElements );
  915. const unsigned char *pCurSendPos = pSendData + pArraySendProp->GetOffset();
  916. unsigned char *pCurRecvPos = pRecvData + pArrayRecvProp->GetOffset();
  917. for ( recvProxyData.m_iElement=0; recvProxyData.m_iElement < nElements; recvProxyData.m_iElement++ )
  918. {
  919. // Get this array element out of the sender's data.
  920. pArraySendProp->GetProxyFn()( pArraySendProp, pSendData, pCurSendPos, &recvProxyData.m_Value, recvProxyData.m_iElement, objectID );
  921. pCurSendPos += pSendProp->GetElementStride();
  922. // Write it into the receiver.
  923. pArrayRecvProp->GetProxyFn()( &recvProxyData, pRecvData, pCurRecvPos );
  924. pCurRecvPos += pRecvProp->GetElementStride();
  925. }
  926. }
  927. const char* Array_GetTypeNameString()
  928. {
  929. return "DPT_Array";
  930. }
  931. bool Array_IsZero( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp )
  932. {
  933. int nElements = Array_GetLength( pStruct, pProp, -1 );
  934. return ( nElements == 0 );
  935. }
  936. void Array_DecodeZero( DecodeInfo *pInfo )
  937. {
  938. ArrayLengthRecvProxyFn lengthProxy = pInfo->m_pRecvProp->GetArrayLengthProxy();
  939. if ( lengthProxy )
  940. lengthProxy( pInfo->m_pStruct, pInfo->m_ObjectID, 0 );
  941. }
  942. bool Array_IsEncodedZero( const SendProp *pProp, bf_read *pIn )
  943. {
  944. SendProp *pArrayProp = pProp->GetArrayProp();
  945. AssertMsg( pArrayProp, ("Array_IsEncodedZero: missing m_pArrayProp for a property.") );
  946. int nElements = pIn->ReadUBitLong( pProp->GetNumArrayLengthBits() );
  947. for ( int i=0; i < nElements; i++ )
  948. {
  949. // skip over data
  950. g_PropTypeFns[pArrayProp->GetType()].IsEncodedZero( pArrayProp, pIn );
  951. }
  952. return nElements == 0;;
  953. }
  954. void Array_SkipProp( const SendProp *pProp, bf_read *pIn )
  955. {
  956. SendProp *pArrayProp = pProp->GetArrayProp();
  957. AssertMsg( pArrayProp, ("Array_SkipProp: missing m_pArrayProp for a property.") );
  958. int nElements = pIn->ReadUBitLong( pProp->GetNumArrayLengthBits() );
  959. for ( int i=0; i < nElements; i++ )
  960. {
  961. // skip over data
  962. g_PropTypeFns[pArrayProp->GetType()].SkipProp( pArrayProp, pIn );
  963. }
  964. }
  965. // ---------------------------------------------------------------------------------------- //
  966. // Datatable type abstraction.
  967. // ---------------------------------------------------------------------------------------- //
  968. const char* DataTable_GetTypeNameString()
  969. {
  970. return "DPT_DataTable";
  971. }
  972. // ---------------------------------------------------------------------------------------- //
  973. // Int 64 property type abstraction.
  974. // ---------------------------------------------------------------------------------------- //
  975. void Int64_Encode( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp, bf_write *pOut, int objectID )
  976. {
  977. if ( pProp->GetFlags() & SPROP_VARINT)
  978. {
  979. if ( pProp->GetFlags() & SPROP_UNSIGNED )
  980. {
  981. pOut->WriteVarInt64( pVar->m_Int64 );
  982. }
  983. else
  984. {
  985. pOut->WriteSignedVarInt64( pVar->m_Int64 );
  986. }
  987. }
  988. else
  989. {
  990. bool bNeg = pVar->m_Int64 < 0;
  991. int64 iCopy = bNeg ? -pVar->m_Int64 : pVar->m_Int64;
  992. uint32 *pInt = (uint32*)&iCopy;
  993. uint32 lowInt = *pInt++;
  994. uint32 highInt = *pInt;
  995. if( pProp->IsSigned() )
  996. {
  997. pOut->WriteOneBit( bNeg );
  998. pOut->WriteUBitLong( (unsigned int)lowInt, 32 );
  999. pOut->WriteUBitLong( (unsigned int)highInt, pProp->m_nBits - 32 - 1 ); // For the sign bit
  1000. }
  1001. else
  1002. {
  1003. pOut->WriteUBitLong( (unsigned int)lowInt, 32 );
  1004. pOut->WriteUBitLong( (unsigned int)highInt, pProp->m_nBits - 32 );
  1005. }
  1006. }
  1007. }
  1008. void Int64_Decode( DecodeInfo *pInfo )
  1009. {
  1010. if ( pInfo->m_pProp->GetFlags() & SPROP_VARINT )
  1011. {
  1012. if ( pInfo->m_pProp->GetFlags() & SPROP_UNSIGNED )
  1013. {
  1014. pInfo->m_Value.m_Int64 = (int64)pInfo->m_pIn->ReadVarInt64();
  1015. }
  1016. else
  1017. {
  1018. pInfo->m_Value.m_Int64 = pInfo->m_pIn->ReadSignedVarInt64();
  1019. }
  1020. }
  1021. else
  1022. {
  1023. uint32 highInt = 0;
  1024. uint32 lowInt = 0;
  1025. bool bNeg = false;
  1026. if(pInfo->m_pProp->IsSigned())
  1027. {
  1028. bNeg = pInfo->m_pIn->ReadOneBit() != 0;
  1029. lowInt = pInfo->m_pIn->ReadUBitLong( 32 );
  1030. highInt = pInfo->m_pIn->ReadUBitLong( pInfo->m_pProp->m_nBits - 32 - 1 );
  1031. }
  1032. else
  1033. {
  1034. lowInt = pInfo->m_pIn->ReadUBitLong( 32 );
  1035. highInt = pInfo->m_pIn->ReadUBitLong( pInfo->m_pProp->m_nBits - 32 );
  1036. }
  1037. uint32 *pInt = (uint32*)&pInfo->m_Value.m_Int64;
  1038. *pInt++ = lowInt;
  1039. *pInt = highInt;
  1040. if ( bNeg )
  1041. {
  1042. pInfo->m_Value.m_Int64 = -pInfo->m_Value.m_Int64;
  1043. }
  1044. }
  1045. if ( pInfo->m_pRecvProp )
  1046. {
  1047. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  1048. }
  1049. }
  1050. int Int64_CompareDeltas( const SendProp *pProp, bf_read *p1, bf_read *p2 )
  1051. {
  1052. if ( pProp->GetFlags() & SPROP_VARINT)
  1053. {
  1054. if ( pProp->GetFlags() & SPROP_UNSIGNED )
  1055. {
  1056. return p1->ReadVarInt64() != p2->ReadVarInt64();
  1057. }
  1058. return p1->ReadSignedVarInt64() != p2->ReadSignedVarInt64();
  1059. }
  1060. uint32 highInt1 = p1->ReadUBitLong( pProp->m_nBits - 32 );
  1061. uint32 lowInt1 = p1->ReadUBitLong( 32 );
  1062. uint32 highInt2 = p2->ReadUBitLong( pProp->m_nBits - 32 );
  1063. uint32 lowInt2 = p2->ReadUBitLong( 32 );
  1064. return highInt1 != highInt2 || lowInt1 != lowInt2;
  1065. }
  1066. const char* Int64_GetTypeNameString()
  1067. {
  1068. return "DPT_Int64";
  1069. }
  1070. bool Int64_IsZero( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp )
  1071. {
  1072. return (pVar->m_Int64 == 0);
  1073. }
  1074. void Int64_DecodeZero( DecodeInfo *pInfo )
  1075. {
  1076. pInfo->m_Value.m_Int64 = 0;
  1077. if ( pInfo->m_pRecvProp )
  1078. {
  1079. pInfo->m_pRecvProp->GetProxyFn()( pInfo, pInfo->m_pStruct, pInfo->m_pData );
  1080. }
  1081. }
  1082. bool Int64_IsEncodedZero( const SendProp *pProp, bf_read *pIn )
  1083. {
  1084. if ( pProp->GetFlags() & SPROP_VARINT)
  1085. {
  1086. if ( pProp->GetFlags() & SPROP_UNSIGNED )
  1087. {
  1088. return pIn->ReadVarInt64() == 0;
  1089. }
  1090. return pIn->ReadSignedVarInt64() == 0;
  1091. }
  1092. uint32 highInt1 = pIn->ReadUBitLong( pProp->m_nBits - 32 );
  1093. uint32 lowInt1 = pIn->ReadUBitLong( 32 );
  1094. return (highInt1 == 0 && lowInt1 == 0);
  1095. }
  1096. void Int64_SkipProp( const SendProp *pProp, bf_read *pIn )
  1097. {
  1098. if ( pProp->GetFlags() & SPROP_VARINT)
  1099. {
  1100. if ( pProp->GetFlags() & SPROP_UNSIGNED )
  1101. {
  1102. pIn->ReadVarInt64();
  1103. }
  1104. else
  1105. {
  1106. pIn->ReadSignedVarInt64();
  1107. }
  1108. }
  1109. else
  1110. {
  1111. pIn->SeekRelative( pProp->m_nBits );
  1112. }
  1113. }
  1114. PropTypeFns g_PropTypeFns[DPT_NUMSendPropTypes] =
  1115. {
  1116. // DPT_Int
  1117. {
  1118. Int_Encode,
  1119. Int_Decode,
  1120. Int_CompareDeltas,
  1121. Generic_FastCopy,
  1122. Int_GetTypeNameString,
  1123. Int_IsZero,
  1124. Int_DecodeZero,
  1125. Int_IsEncodedZero,
  1126. Int_SkipProp,
  1127. },
  1128. // DPT_Float
  1129. {
  1130. Float_Encode,
  1131. Float_Decode,
  1132. Float_CompareDeltas,
  1133. Generic_FastCopy,
  1134. Float_GetTypeNameString,
  1135. Float_IsZero,
  1136. Float_DecodeZero,
  1137. Float_IsEncodedZero,
  1138. Float_SkipProp,
  1139. },
  1140. // DPT_Vector
  1141. {
  1142. Vector_Encode,
  1143. Vector_Decode,
  1144. Vector_CompareDeltas,
  1145. Generic_FastCopy,
  1146. Vector_GetTypeNameString,
  1147. Vector_IsZero,
  1148. Vector_DecodeZero,
  1149. Vector_IsEncodedZero,
  1150. Vector_SkipProp,
  1151. },
  1152. // DPT_VectorXY
  1153. {
  1154. VectorXY_Encode,
  1155. VectorXY_Decode,
  1156. VectorXY_CompareDeltas,
  1157. Generic_FastCopy,
  1158. VectorXY_GetTypeNameString,
  1159. VectorXY_IsZero,
  1160. VectorXY_DecodeZero,
  1161. VectorXY_IsEncodedZero,
  1162. VectorXY_SkipProp,
  1163. },
  1164. // DPT_String
  1165. {
  1166. String_Encode,
  1167. String_Decode,
  1168. String_CompareDeltas,
  1169. Generic_FastCopy,
  1170. String_GetTypeNameString,
  1171. String_IsZero,
  1172. String_DecodeZero,
  1173. String_IsEncodedZero,
  1174. String_SkipProp,
  1175. },
  1176. // DPT_Array
  1177. {
  1178. Array_Encode,
  1179. Array_Decode,
  1180. Array_CompareDeltas,
  1181. Array_FastCopy,
  1182. Array_GetTypeNameString,
  1183. Array_IsZero,
  1184. Array_DecodeZero,
  1185. Array_IsEncodedZero,
  1186. Array_SkipProp,
  1187. },
  1188. // DPT_DataTable
  1189. {
  1190. NULL,
  1191. NULL,
  1192. NULL,
  1193. NULL,
  1194. DataTable_GetTypeNameString,
  1195. NULL,
  1196. NULL,
  1197. NULL,
  1198. NULL,
  1199. },
  1200. #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!!!
  1201. // DPT_Quaternion
  1202. {
  1203. Quaternion_Encode,
  1204. Quaternion_Decode,
  1205. Quaternion_CompareDeltas,
  1206. Generic_FastCopy,
  1207. Quaternion_GetTypeNameString,
  1208. Quaternion_IsZero,
  1209. Quaternion_DecodeZero,
  1210. Quaternion_IsEncodedZero,
  1211. Quaternion_SkipProp,
  1212. },
  1213. #endif
  1214. // DPT_Int64
  1215. {
  1216. Int64_Encode,
  1217. Int64_Decode,
  1218. Int64_CompareDeltas,
  1219. Generic_FastCopy,
  1220. Int64_GetTypeNameString,
  1221. Int64_IsZero,
  1222. Int64_DecodeZero,
  1223. Int64_IsEncodedZero,
  1224. Int64_SkipProp,
  1225. },
  1226. };