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.

920 lines
28 KiB

  1. //========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "dt_send.h"
  9. #include "mathlib/mathlib.h"
  10. #include "mathlib/vector.h"
  11. #include "tier0/dbg.h"
  12. #include "dt_utlvector_common.h"
  13. #include "networkvar.h"
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include "tier0/memdbgon.h"
  16. #if !defined(_STATIC_LINKED) || defined(GAME_DLL)
  17. static CNonModifiedPointerProxy *s_pNonModifiedPointerProxyHead = NULL;
  18. void SendProxy_UInt8ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID);
  19. void SendProxy_UInt16ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID);
  20. void SendProxy_UInt32ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID);
  21. void SendProxy_UInt64ToInt64( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID);
  22. char *s_ElementNames[MAX_ARRAY_ELEMENTS] =
  23. {
  24. "000", "001", "002", "003", "004", "005", "006", "007", "008", "009",
  25. "010", "011", "012", "013", "014", "015", "016", "017", "018", "019",
  26. "020", "021", "022", "023", "024", "025", "026", "027", "028", "029",
  27. "030", "031", "032", "033", "034", "035", "036", "037", "038", "039",
  28. "040", "041", "042", "043", "044", "045", "046", "047", "048", "049",
  29. "050", "051", "052", "053", "054", "055", "056", "057", "058", "059",
  30. "060", "061", "062", "063", "064", "065", "066", "067", "068", "069",
  31. "070", "071", "072", "073", "074", "075", "076", "077", "078", "079",
  32. "080", "081", "082", "083", "084", "085", "086", "087", "088", "089",
  33. "090", "091", "092", "093", "094", "095", "096", "097", "098", "099",
  34. "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
  35. "110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
  36. "120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
  37. "130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
  38. "140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
  39. "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
  40. "160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
  41. "170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
  42. "180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
  43. "190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
  44. "200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
  45. "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
  46. "220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
  47. "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
  48. "240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
  49. "250", "251", "252", "253", "254", "255", "256", "257", "258", "259",
  50. "260", "261", "262", "263", "264", "265", "266", "267", "268", "269",
  51. "270", "271", "272", "273", "274", "275", "276", "277", "278", "279",
  52. "280", "281", "282", "283", "284", "285", "286", "287", "288", "289",
  53. "290", "291", "292", "293", "294", "295", "296", "297", "298", "299",
  54. "300", "301", "302", "303", "304", "305", "306", "307", "308", "309",
  55. "310", "311", "312", "313", "314", "315", "316", "317", "318", "319",
  56. "320", "321", "322", "323", "324", "325", "326", "327", "328", "329",
  57. "330", "331", "332", "333", "334", "335", "336", "337", "338", "339",
  58. "340", "341", "342", "343", "344", "345", "346", "347", "348", "349",
  59. "350", "351", "352", "353", "354", "355", "356", "357", "358", "359",
  60. "360", "361", "362", "363", "364", "365", "366", "367", "368", "369",
  61. "370", "371", "372", "373", "374", "375", "376", "377", "378", "379",
  62. "380", "381", "382", "383", "384", "385", "386", "387", "388", "389",
  63. "390", "391", "392", "393", "394", "395", "396", "397", "398", "399",
  64. "400", "401", "402", "403", "404", "405", "406", "407", "408", "409",
  65. "410", "411", "412", "413", "414", "415", "416", "417", "418", "419",
  66. "420", "421", "422", "423", "424", "425", "426", "427", "428", "429",
  67. "430", "431", "432", "433", "434", "435", "436", "437", "438", "439",
  68. "440", "441", "442", "443", "444", "445", "446", "447", "448", "449",
  69. "450", "451", "452", "453", "454", "455", "456", "457", "458", "459",
  70. "460", "461", "462", "463", "464", "465", "466", "467", "468", "469",
  71. "470", "471", "472", "473", "474", "475", "476", "477", "478", "479",
  72. "480", "481", "482", "483", "484", "485", "486", "487", "488", "489",
  73. "490", "491", "492", "493", "494", "495", "496", "497", "498", "499",
  74. "500", "501", "502", "503", "504", "505", "506", "507", "508", "509",
  75. "510", "511", "512", "513", "514", "515", "516", "517", "518", "519",
  76. "520", "521", "522", "523", "524", "525", "526", "527", "528", "529",
  77. "530", "531", "532", "533", "534", "535", "536", "537", "538", "539",
  78. "540", "541", "542", "543", "544", "545", "546", "547", "548", "549",
  79. "550", "551", "552", "553", "554", "555", "556", "557", "558", "559",
  80. "560", "561", "562", "563", "564", "565", "566", "567", "568", "569",
  81. "570", "571", "572", "573", "574", "575", "576", "577", "578", "579",
  82. "580", "581", "582", "583", "584", "585", "586", "587", "588", "589",
  83. "590", "591", "592", "593", "594", "595", "596", "597", "598", "599",
  84. "600", "601", "602", "603", "604", "605", "606", "607", "608", "609",
  85. "610", "611", "612", "613", "614", "615", "616", "617", "618", "619",
  86. "620", "621", "622", "623", "624", "625", "626", "627", "628", "629",
  87. "630", "631", "632", "633", "634", "635", "636", "637", "638", "639",
  88. "640", "641", "642", "643", "644", "645", "646", "647", "648", "649",
  89. "650", "651", "652", "653", "654", "655", "656", "657", "658", "659",
  90. "660", "661", "662", "663", "664", "665", "666", "667", "668", "669",
  91. "670", "671", "672", "673", "674", "675", "676", "677", "678", "679",
  92. "680", "681", "682", "683", "684", "685", "686", "687", "688", "689",
  93. "690", "691", "692", "693", "694", "695", "696", "697", "698", "699",
  94. "700", "701", "702", "703", "704", "705", "706", "707", "708", "709",
  95. "710", "711", "712", "713", "714", "715", "716", "717", "718", "719",
  96. "720", "721", "722", "723", "724", "725", "726", "727", "728", "729",
  97. "730", "731", "732", "733", "734", "735", "736", "737", "738", "739",
  98. "740", "741", "742", "743", "744", "745", "746", "747", "748", "749",
  99. "750", "751", "752", "753", "754", "755", "756", "757", "758", "759",
  100. "760", "761", "762", "763", "764", "765", "766", "767", "768", "769",
  101. "770", "771", "772", "773", "774", "775", "776", "777", "778", "779",
  102. "780", "781", "782", "783", "784", "785", "786", "787", "788", "789",
  103. "790", "791", "792", "793", "794", "795", "796", "797", "798", "799",
  104. "800", "801", "802", "803", "804", "805", "806", "807", "808", "809",
  105. "810", "811", "812", "813", "814", "815", "816", "817", "818", "819",
  106. "820", "821", "822", "823", "824", "825", "826", "827", "828", "829",
  107. "830", "831", "832", "833", "834", "835", "836", "837", "838", "839",
  108. "840", "841", "842", "843", "844", "845", "846", "847", "848", "849",
  109. "850", "851", "852", "853", "854", "855", "856", "857", "858", "859",
  110. "860", "861", "862", "863", "864", "865", "866", "867", "868", "869",
  111. "870", "871", "872", "873", "874", "875", "876", "877", "878", "879",
  112. "880", "881", "882", "883", "884", "885", "886", "887", "888", "889",
  113. "890", "891", "892", "893", "894", "895", "896", "897", "898", "899",
  114. "900", "901", "902", "903", "904", "905", "906", "907", "908", "909",
  115. "910", "911", "912", "913", "914", "915", "916", "917", "918", "919",
  116. "920", "921", "922", "923", "924", "925", "926", "927", "928", "929",
  117. "930", "931", "932", "933", "934", "935", "936", "937", "938", "939",
  118. "940", "941", "942", "943", "944", "945", "946", "947", "948", "949",
  119. "950", "951", "952", "953", "954", "955", "956", "957", "958", "959",
  120. "960", "961", "962", "963", "964", "965", "966", "967", "968", "969",
  121. "970", "971", "972", "973", "974", "975", "976", "977", "978", "979",
  122. "980", "981", "982", "983", "984", "985", "986", "987", "988", "989",
  123. "990", "991", "992", "993", "994", "995", "996", "997", "998", "999",
  124. "1000", "1001", "1002", "1003", "1004", "1005", "1006", "1007", "1008", "1009",
  125. "1010", "1011", "1012", "1013", "1014", "1015", "1016", "1017", "1018", "1019",
  126. "1020", "1021", "1022", "1023"
  127. };
  128. CNonModifiedPointerProxy::CNonModifiedPointerProxy( SendTableProxyFn fn )
  129. {
  130. m_pNext = s_pNonModifiedPointerProxyHead;
  131. s_pNonModifiedPointerProxyHead = this;
  132. m_Fn = fn;
  133. }
  134. CStandardSendProxiesV1::CStandardSendProxiesV1()
  135. {
  136. m_Int8ToInt32 = SendProxy_Int8ToInt32;
  137. m_Int16ToInt32 = SendProxy_Int16ToInt32;
  138. m_Int32ToInt32 = SendProxy_Int32ToInt32;
  139. m_Int64ToInt64 = SendProxy_Int64ToInt64;
  140. m_UInt8ToInt32 = SendProxy_UInt8ToInt32;
  141. m_UInt16ToInt32 = SendProxy_UInt16ToInt32;
  142. m_UInt32ToInt32 = SendProxy_UInt32ToInt32;
  143. m_UInt64ToInt64 = SendProxy_UInt64ToInt64;
  144. m_FloatToFloat = SendProxy_FloatToFloat;
  145. m_VectorToVector = SendProxy_VectorToVector;
  146. }
  147. CStandardSendProxies::CStandardSendProxies()
  148. {
  149. m_DataTableToDataTable = SendProxy_DataTableToDataTable;
  150. m_ppNonModifiedPointerProxies = &s_pNonModifiedPointerProxyHead;
  151. }
  152. CStandardSendProxies g_StandardSendProxies;
  153. // ---------------------------------------------------------------------- //
  154. // Proxies.
  155. // ---------------------------------------------------------------------- //
  156. void SendProxy_AngleToFloat( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  157. {
  158. float angle;
  159. angle = *((float*)pData);
  160. pOut->m_Float = anglemod( angle );
  161. Assert( IsFinite( pOut->m_Float ) );
  162. }
  163. void SendProxy_FloatToFloat( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  164. {
  165. pOut->m_Float = *((float*)pData);
  166. Assert( IsFinite( pOut->m_Float ) );
  167. }
  168. void SendProxy_QAngles( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID )
  169. {
  170. QAngle *v = (QAngle*)pData;
  171. pOut->m_Vector[0] = anglemod( v->x );
  172. pOut->m_Vector[1] = anglemod( v->y );
  173. pOut->m_Vector[2] = anglemod( v->z );
  174. }
  175. void SendProxy_VectorToVector( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  176. {
  177. Vector& v = *(Vector*)pData;
  178. Assert( v.IsValid() );
  179. pOut->m_Vector[0] = v[0];
  180. pOut->m_Vector[1] = v[1];
  181. pOut->m_Vector[2] = v[2];
  182. }
  183. void SendProxy_VectorXYToVectorXY( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  184. {
  185. Vector& v = *(Vector*)pData;
  186. Assert( v.IsValid() );
  187. pOut->m_Vector[0] = v[0];
  188. pOut->m_Vector[1] = v[1];
  189. }
  190. #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!!!
  191. void SendProxy_QuaternionToQuaternion( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  192. {
  193. Quaternion& q = *(Quaternion*)pData;
  194. Assert( q.IsValid() );
  195. pOut->m_Vector[0] = q[0];
  196. pOut->m_Vector[1] = q[1];
  197. pOut->m_Vector[2] = q[2];
  198. pOut->m_Vector[3] = q[3];
  199. }
  200. #endif
  201. void SendProxy_Int8ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  202. {
  203. pOut->m_Int = *((char*)pData);
  204. }
  205. void SendProxy_Int16ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  206. {
  207. pOut->m_Int = *((short*)pData);
  208. }
  209. void SendProxy_Int32ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  210. {
  211. pOut->m_Int = *((int*)pData);
  212. }
  213. void SendProxy_Color32ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID )
  214. {
  215. //Always send/receive as little endian to preserve byte order across network byte swaps
  216. pOut->m_Int = LittleDWord( *((uint32 *)pData) );
  217. }
  218. void SendProxy_Int64ToInt64( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  219. {
  220. pOut->m_Int64 = *((int64*)pData);
  221. }
  222. void SendProxy_UInt8ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  223. {
  224. pOut->m_Int = *((unsigned char*)pData);
  225. }
  226. void SendProxy_UInt16ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  227. {
  228. pOut->m_Int = *((unsigned short*)pData);
  229. }
  230. void SendProxy_UInt32ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  231. {
  232. *((unsigned long*)&pOut->m_Int) = *((unsigned long*)pData);
  233. }
  234. void SendProxy_UInt64ToInt64( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  235. {
  236. *((int64*)&pOut->m_Int64) = *((uint64*)pData);
  237. }
  238. void SendProxy_StringToString( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  239. {
  240. pOut->m_pString = (char*)pData;
  241. }
  242. void* SendProxy_DataTableToDataTable( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID )
  243. {
  244. return (void*)pData;
  245. }
  246. void* SendProxy_DataTablePtrToDataTable( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID )
  247. {
  248. return *((void**)pData);
  249. }
  250. static void SendProxy_Empty( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID)
  251. {
  252. }
  253. // ---------------------------------------------------------------------- //
  254. // Prop setup functions (for building tables).
  255. // ---------------------------------------------------------------------- //
  256. float AssignRangeMultiplier( int nBits, double range )
  257. {
  258. unsigned long iHighValue;
  259. if ( nBits == 32 )
  260. iHighValue = 0xFFFFFFFE;
  261. else
  262. iHighValue = ((1 << (unsigned long)nBits) - 1);
  263. float fHighLowMul = iHighValue / range;
  264. if ( CloseEnough( range, 0 ) )
  265. fHighLowMul = iHighValue;
  266. // If the precision is messing us up, then adjust it so it won't.
  267. if ( (unsigned long)(fHighLowMul * range) > iHighValue ||
  268. (fHighLowMul * range) > (double)iHighValue )
  269. {
  270. // Squeeze it down smaller and smaller until it's going to produce an integer
  271. // in the valid range when given the highest value.
  272. float multipliers[] = { 0.9999, 0.99, 0.9, 0.8, 0.7 };
  273. int i;
  274. for ( i=0; i < ARRAYSIZE( multipliers ); i++ )
  275. {
  276. fHighLowMul = (float)( iHighValue / range ) * multipliers[i];
  277. if ( (unsigned long)(fHighLowMul * range) > iHighValue ||
  278. (fHighLowMul * range) > (double)iHighValue )
  279. {
  280. }
  281. else
  282. {
  283. break;
  284. }
  285. }
  286. if ( i == ARRAYSIZE( multipliers ) )
  287. {
  288. // Doh! We seem to be unable to represent this range.
  289. Assert( false );
  290. return 0;
  291. }
  292. }
  293. return fHighLowMul;
  294. }
  295. SendProp SendPropFloat(
  296. char *pVarName,
  297. // Variable name.
  298. int offset, // Offset into container structure.
  299. int sizeofVar,
  300. int nBits, // Number of bits to use when encoding.
  301. int flags,
  302. float fLowValue, // For floating point, low and high values.
  303. float fHighValue, // High value. If HIGH_DEFAULT, it's (1<<nBits).
  304. SendVarProxyFn varProxy,
  305. byte priority
  306. )
  307. {
  308. SendProp ret;
  309. if ( varProxy == SendProxy_FloatToFloat )
  310. {
  311. Assert( sizeofVar == 0 || sizeofVar == 4 );
  312. }
  313. if ( nBits <= 0 || nBits == 32 )
  314. {
  315. flags |= SPROP_NOSCALE;
  316. fLowValue = 0.f;
  317. fHighValue = 0.f;
  318. ret.m_fHighLowMul = 0;
  319. }
  320. else
  321. {
  322. if(fHighValue == HIGH_DEFAULT)
  323. fHighValue = (1 << nBits);
  324. if (flags & SPROP_ROUNDDOWN)
  325. fHighValue = fHighValue - ((fHighValue - fLowValue) / (1 << nBits));
  326. else if (flags & SPROP_ROUNDUP)
  327. fLowValue = fLowValue + ((fHighValue - fLowValue) / (1 << nBits));
  328. ret.m_fHighLowMul = AssignRangeMultiplier( nBits, fHighValue - fLowValue );
  329. }
  330. ret.m_Type = DPT_Float;
  331. ret.m_pVarName = pVarName;
  332. ret.SetOffsetAndNetworkVarFlags( offset );
  333. ret.m_nBits = nBits;
  334. ret.SetFlags( flags );
  335. ret.m_fLowValue = fLowValue;
  336. ret.m_fHighValue = fHighValue;
  337. ret.SetProxyFn( varProxy );
  338. ret.SetPriority( priority );
  339. if( ret.GetFlags() & (SPROP_COORD | SPROP_NOSCALE | SPROP_NORMAL | SPROP_COORD_MP | SPROP_COORD_MP_LOWPRECISION | SPROP_COORD_MP_INTEGRAL ) )
  340. ret.m_nBits = 0;
  341. // If this is pointing at a CNetworkVector, it must be a CNetworkVectorXYZ or else the CNetworkVector won't generate
  342. // changes at the offset of each float inside the vector properly.
  343. bool bIsANetworkVar = ret.AreNetworkVarFlagsSet( NETWORKVAR_IS_A_VECTOR );
  344. bool bIsANetworkVarXYZ = ret.AreNetworkVarFlagsSet( NETWORKVAR_VECTOR_XYZ_FLAG );
  345. bool bIsANetworkVarXY_SeparateZ = ret.AreNetworkVarFlagsSet( NETWORKVAR_VECTOR_XY_SEPARATEZ_FLAG );
  346. if ( bIsANetworkVar && !bIsANetworkVarXYZ && !bIsANetworkVarXY_SeparateZ )
  347. Error( "SendPropFloat( %s ) is referencing a CNetworkVector, but must be referencing a CNetworkVectorXYZ or CNetworkVectorXY_SeparateZ", pVarName );
  348. return ret;
  349. }
  350. SendProp SendPropVector(
  351. char *pVarName,
  352. int offset,
  353. int sizeofVar,
  354. int nBits, // Number of bits to use when encoding.
  355. int flags,
  356. float fLowValue, // For floating point, low and high values.
  357. float fHighValue, // High value. If HIGH_DEFAULT, it's (1<<nBits).
  358. SendVarProxyFn varProxy,
  359. byte priority
  360. )
  361. {
  362. SendProp ret;
  363. if(varProxy == SendProxy_VectorToVector)
  364. {
  365. Assert(sizeofVar == sizeof(Vector));
  366. }
  367. if ( nBits == 32 )
  368. flags |= SPROP_NOSCALE;
  369. ret.m_Type = DPT_Vector;
  370. ret.m_pVarName = pVarName;
  371. ret.SetOffsetAndNetworkVarFlags( offset );
  372. ret.m_nBits = nBits;
  373. ret.SetFlags( flags );
  374. ret.m_fLowValue = fLowValue;
  375. ret.m_fHighValue = fHighValue;
  376. ret.m_fHighLowMul = AssignRangeMultiplier( ret.m_nBits, ret.m_fHighValue - ret.m_fLowValue );
  377. ret.SetProxyFn( varProxy );
  378. ret.SetPriority( priority );
  379. if( ret.GetFlags() & (SPROP_COORD | SPROP_NOSCALE | SPROP_NORMAL | SPROP_COORD_MP | SPROP_COORD_MP_LOWPRECISION | SPROP_COORD_MP_INTEGRAL) )
  380. ret.m_nBits = 0;
  381. return ret;
  382. }
  383. SendProp SendPropVectorXY(
  384. char *pVarName,
  385. int offset,
  386. int sizeofVar,
  387. int nBits, // Number of bits to use when encoding.
  388. int flags,
  389. float fLowValue, // For floating point, low and high values.
  390. float fHighValue, // High value. If HIGH_DEFAULT, it's (1<<nBits).
  391. SendVarProxyFn varProxy,
  392. byte priority
  393. )
  394. {
  395. SendProp ret;
  396. if(varProxy == SendProxy_VectorXYToVectorXY)
  397. {
  398. Assert( sizeofVar == sizeof(Vector) || sizeofVar == sizeof(Vector2D) );
  399. }
  400. if ( nBits == 32 )
  401. flags |= SPROP_NOSCALE;
  402. ret.m_Type = DPT_VectorXY;
  403. ret.m_pVarName = pVarName;
  404. ret.SetOffsetAndNetworkVarFlags( offset );
  405. ret.m_nBits = nBits;
  406. ret.SetFlags( flags );
  407. ret.m_fLowValue = fLowValue;
  408. ret.m_fHighValue = fHighValue;
  409. ret.m_fHighLowMul = AssignRangeMultiplier( ret.m_nBits, ret.m_fHighValue - ret.m_fLowValue );
  410. ret.SetProxyFn( varProxy );
  411. ret.SetPriority( priority );
  412. if( ret.GetFlags() & (SPROP_COORD | SPROP_NOSCALE | SPROP_NORMAL | SPROP_COORD_MP | SPROP_COORD_MP_LOWPRECISION | SPROP_COORD_MP_INTEGRAL) )
  413. ret.m_nBits = 0;
  414. return ret;
  415. }
  416. #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!!!
  417. SendProp SendPropQuaternion(
  418. char *pVarName,
  419. int offset,
  420. int sizeofVar,
  421. int nBits, // Number of bits to use when encoding.
  422. int flags,
  423. float fLowValue, // For floating point, low and high values.
  424. float fHighValue, // High value. If HIGH_DEFAULT, it's (1<<nBits).
  425. SendVarProxyFn varProxy,
  426. byte priority
  427. )
  428. {
  429. SendProp ret;
  430. if(varProxy == SendProxy_QuaternionToQuaternion)
  431. {
  432. Assert(sizeofVar == sizeof(Quaternion));
  433. }
  434. if ( nBits == 32 )
  435. flags |= SPROP_NOSCALE;
  436. ret.m_Type = DPT_Quaternion;
  437. ret.m_pVarName = pVarName;
  438. ret.SetOffset( offset );
  439. ret.m_nBits = nBits;
  440. ret.SetFlags( flags );
  441. ret.m_fLowValue = fLowValue;
  442. ret.m_fHighValue = fHighValue;
  443. ret.m_fHighLowMul = AssignRangeMultiplier( ret.m_nBits, ret.m_fHighValue - ret.m_fLowValue );
  444. ret.SetProxyFn( varProxy );
  445. ret.SetPriority( priority );
  446. if( ret.GetFlags() & (SPROP_COORD | SPROP_NOSCALE | SPROP_NORMAL | SPROP_COORD_MP | SPROP_COORD_MP_LOWPRECISION | SPROP_COORD_MP_INTEGRAL) )
  447. ret.m_nBits = 0;
  448. return ret;
  449. }
  450. #endif
  451. SendProp SendPropAngle(
  452. char *pVarName,
  453. int offset,
  454. int sizeofVar,
  455. int nBits,
  456. int flags,
  457. SendVarProxyFn varProxy,
  458. byte priority
  459. )
  460. {
  461. SendProp ret;
  462. if(varProxy == SendProxy_AngleToFloat)
  463. {
  464. Assert(sizeofVar == 4);
  465. }
  466. if ( nBits == 32 )
  467. flags |= SPROP_NOSCALE;
  468. flags |= SPROP_ROUNDDOWN;
  469. ret.m_Type = DPT_Float;
  470. ret.m_pVarName = pVarName;
  471. ret.SetOffsetAndNetworkVarFlags( offset );
  472. ret.m_nBits = nBits;
  473. ret.SetFlags( flags );
  474. ret.m_fLowValue = 0.0f;
  475. ret.m_fHighValue = 360.0f;
  476. if ( !(flags & SPROP_NOSCALE ) )
  477. {
  478. if (flags & SPROP_ROUNDUP)
  479. {
  480. ret.m_fLowValue = ret.m_fLowValue + ((ret.m_fHighValue - ret.m_fLowValue) / (1 << nBits));
  481. }
  482. else if (flags & SPROP_ROUNDDOWN)
  483. {
  484. ret.m_fHighValue = ret.m_fHighValue - ((ret.m_fHighValue - ret.m_fLowValue) / (1 << nBits));
  485. }
  486. }
  487. ret.m_fHighLowMul = AssignRangeMultiplier( ret.m_nBits, ret.m_fHighValue - ret.m_fLowValue );
  488. ret.SetProxyFn( varProxy );
  489. ret.SetPriority( priority );
  490. return ret;
  491. }
  492. SendProp SendPropQAngles(
  493. char *pVarName,
  494. int offset,
  495. int sizeofVar,
  496. int nBits,
  497. int flags,
  498. SendVarProxyFn varProxy,
  499. byte priority
  500. )
  501. {
  502. SendProp ret;
  503. if(varProxy == SendProxy_AngleToFloat)
  504. {
  505. Assert(sizeofVar == 4);
  506. }
  507. if ( nBits == 32 )
  508. flags |= SPROP_NOSCALE;
  509. flags |= SPROP_ROUNDDOWN;
  510. ret.m_Type = DPT_Vector;
  511. ret.m_pVarName = pVarName;
  512. ret.SetOffsetAndNetworkVarFlags( offset );
  513. ret.m_nBits = nBits;
  514. ret.SetFlags( flags );
  515. ret.m_fLowValue = 0.0f;
  516. ret.m_fHighValue = 360.0f;
  517. if ( !(flags & SPROP_NOSCALE ) )
  518. {
  519. if (flags & SPROP_ROUNDUP)
  520. {
  521. ret.m_fLowValue = ret.m_fLowValue + ((ret.m_fHighValue - ret.m_fLowValue) / (1 << nBits));
  522. }
  523. else if (flags & SPROP_ROUNDDOWN)
  524. {
  525. ret.m_fHighValue = ret.m_fHighValue - ((ret.m_fHighValue - ret.m_fLowValue) / (1 << nBits));
  526. }
  527. }
  528. ret.m_fHighLowMul = AssignRangeMultiplier( ret.m_nBits, ret.m_fHighValue - ret.m_fLowValue );
  529. ret.SetProxyFn( varProxy );
  530. ret.SetPriority( priority );
  531. return ret;
  532. }
  533. SendProp SendPropInt(
  534. char *pVarName,
  535. int offset,
  536. int sizeofVar,
  537. int nBits,
  538. int flags,
  539. SendVarProxyFn varProxy,
  540. byte priority
  541. )
  542. {
  543. SendProp ret;
  544. if ( !varProxy )
  545. {
  546. if ( sizeofVar == 1 )
  547. {
  548. varProxy = SendProxy_Int8ToInt32;
  549. }
  550. else if ( sizeofVar == 2 )
  551. {
  552. varProxy = SendProxy_Int16ToInt32;
  553. }
  554. else if ( sizeofVar == 4 )
  555. {
  556. varProxy = SendProxy_Int32ToInt32;
  557. }
  558. else if ( sizeofVar == 8 )
  559. {
  560. varProxy = SendProxy_Int64ToInt64;
  561. }
  562. else
  563. {
  564. Assert(!"SendPropInt var has invalid size");
  565. varProxy = SendProxy_Int8ToInt32; // safest one...
  566. }
  567. }
  568. // Figure out # of bits if the want us to.
  569. if ( nBits <= 0 )
  570. {
  571. Assert( sizeofVar == 1 || sizeofVar == 2 || sizeofVar == 4 );
  572. nBits = sizeofVar * 8;
  573. }
  574. ret.m_Type = (sizeofVar == 8) ? DPT_Int64 : DPT_Int;
  575. ret.m_pVarName = pVarName;
  576. ret.SetOffset( offset );
  577. ret.m_nBits = nBits;
  578. ret.SetFlags( flags );
  579. // Use UInt proxies if they want unsigned data. This isn't necessary to encode
  580. // the values correctly, but it lets us check the ranges of the data to make sure
  581. // they're valid.
  582. ret.SetProxyFn( varProxy );
  583. ret.SetPriority( priority );
  584. if( ret.GetFlags() & SPROP_UNSIGNED )
  585. {
  586. if( varProxy == SendProxy_Int8ToInt32 )
  587. ret.SetProxyFn( SendProxy_UInt8ToInt32 );
  588. else if( varProxy == SendProxy_Int16ToInt32 )
  589. ret.SetProxyFn( SendProxy_UInt16ToInt32 );
  590. else if( varProxy == SendProxy_Int32ToInt32 )
  591. ret.SetProxyFn( SendProxy_UInt32ToInt32 );
  592. else if( varProxy == SendProxy_Int64ToInt64 )
  593. ret.SetProxyFn( SendProxy_UInt64ToInt64 );
  594. }
  595. return ret;
  596. }
  597. SendProp SendPropString(
  598. char *pVarName,
  599. int offset,
  600. int bufferLen,
  601. int flags,
  602. SendVarProxyFn varProxy,
  603. byte priority
  604. )
  605. {
  606. SendProp ret;
  607. Assert( bufferLen <= DT_MAX_STRING_BUFFERSIZE ); // You can only have strings with 8-bits worth of length.
  608. ret.m_Type = DPT_String;
  609. ret.m_pVarName = pVarName;
  610. ret.SetOffset( offset );
  611. ret.SetFlags( flags );
  612. ret.SetProxyFn( varProxy );
  613. ret.SetPriority( priority );
  614. return ret;
  615. }
  616. SendProp SendPropArray3(
  617. char *pVarName,
  618. int offset,
  619. int sizeofVar,
  620. int elements,
  621. SendProp pArrayProp,
  622. SendTableProxyFn varProxy,
  623. byte priority
  624. )
  625. {
  626. SendProp ret;
  627. Assert( elements <= MAX_ARRAY_ELEMENTS );
  628. ret.m_Type = DPT_DataTable;
  629. ret.m_pVarName = pVarName;
  630. ret.SetOffset( offset );
  631. ret.SetDataTableProxyFn( varProxy );
  632. SendProp *pArrayPropAllocated = new SendProp;
  633. *pArrayPropAllocated = pArrayProp;
  634. ret.SetArrayProp( pArrayPropAllocated );
  635. // Handle special proxy types where they always let all clients get the results.
  636. if ( varProxy == SendProxy_DataTableToDataTable || varProxy == SendProxy_DataTablePtrToDataTable )
  637. {
  638. ret.SetFlags( SPROP_PROXY_ALWAYS_YES );
  639. }
  640. SendProp *pProps = new SendProp[elements]; // TODO free that again
  641. for ( int i = 0; i < elements; i++ )
  642. {
  643. pProps[i] = pArrayProp; // copy array element property setting
  644. pProps[i].SetOffset( i*sizeofVar ); // adjust offset
  645. pProps[i].m_pVarName = s_ElementNames[i]; // give unique name
  646. pProps[i].m_pParentArrayPropName = pVarName; // For debugging...
  647. }
  648. SendTable *pTable = new SendTable( pProps, elements, pVarName ); // TODO free that again
  649. ret.SetDataTable( pTable );
  650. ret.SetPriority( priority );
  651. return ret;
  652. }
  653. SendProp SendPropDataTable(
  654. char *pVarName,
  655. int offset,
  656. SendTable *pTable,
  657. SendTableProxyFn varProxy,
  658. byte priority
  659. )
  660. {
  661. SendProp ret;
  662. ret.m_Type = DPT_DataTable;
  663. ret.m_pVarName = pVarName;
  664. ret.SetOffset( offset );
  665. ret.SetDataTable( pTable );
  666. ret.SetDataTableProxyFn( varProxy );
  667. ret.SetPriority( priority );
  668. // Handle special proxy types where they always let all clients get the results.
  669. if ( varProxy == SendProxy_DataTableToDataTable || varProxy == SendProxy_DataTablePtrToDataTable )
  670. {
  671. ret.SetFlags( SPROP_PROXY_ALWAYS_YES );
  672. }
  673. if ( varProxy == SendProxy_DataTableToDataTable && offset == 0 )
  674. {
  675. ret.SetFlags( SPROP_COLLAPSIBLE );
  676. }
  677. return ret;
  678. }
  679. SendProp InternalSendPropArray(
  680. const int elementCount,
  681. const int elementStride,
  682. char *pName,
  683. ArrayLengthSendProxyFn arrayLengthFn,
  684. byte priority
  685. )
  686. {
  687. SendProp ret;
  688. ret.m_Type = DPT_Array;
  689. ret.m_nElements = elementCount;
  690. ret.m_ElementStride = elementStride;
  691. ret.m_pVarName = pName;
  692. ret.SetProxyFn( SendProxy_Empty );
  693. ret.m_pArrayProp = NULL; // This gets set in SendTable_InitTable. It always points at the property that precedes
  694. // this one in the datatable's list.
  695. ret.SetArrayLengthProxy( arrayLengthFn );
  696. ret.SetPriority( priority );
  697. return ret;
  698. }
  699. SendProp SendPropExclude(
  700. char *pDataTableName, // Data table name (given to BEGIN_SEND_TABLE and BEGIN_RECV_TABLE).
  701. char *pPropName // Name of the property to exclude.
  702. )
  703. {
  704. SendProp ret;
  705. ret.SetFlags( SPROP_EXCLUDE );
  706. ret.m_pExcludeDTName = pDataTableName;
  707. ret.m_pVarName = pPropName;
  708. return ret;
  709. }
  710. // ---------------------------------------------------------------------- //
  711. // SendProp
  712. // ---------------------------------------------------------------------- //
  713. SendProp::SendProp()
  714. {
  715. m_pVarName = NULL;
  716. m_Offset = 0;
  717. m_pDataTable = NULL;
  718. m_ProxyFn = NULL;
  719. m_pExcludeDTName = NULL;
  720. m_pParentArrayPropName = NULL;
  721. m_Type = DPT_Int;
  722. m_Flags = 0;
  723. m_nBits = 0;
  724. m_fLowValue = 0.0f;
  725. m_fHighValue = 0.0f;
  726. m_fHighLowMul = 0.0f;
  727. m_pArrayProp = 0;
  728. m_ArrayLengthProxy = 0;
  729. m_nElements = 1;
  730. m_ElementStride = -1;
  731. m_DataTableProxyFn = NULL;
  732. m_pMatchingRecvProp = NULL;
  733. m_priority = SENDPROP_DEFAULT_PRIORITY;
  734. }
  735. SendProp::~SendProp()
  736. {
  737. }
  738. int SendProp::GetNumArrayLengthBits() const
  739. {
  740. Assert( GetType() == DPT_Array );
  741. #if defined( _X360 )
  742. int elemCount = GetNumElements();
  743. if ( !elemCount )
  744. return 1;
  745. return (32 - _CountLeadingZeros(GetNumElements()));
  746. #else
  747. return Q_log2( GetNumElements() ) + 1;
  748. #endif
  749. }
  750. // ---------------------------------------------------------------------- //
  751. // SendTable
  752. // ---------------------------------------------------------------------- //
  753. SendTable::SendTable()
  754. {
  755. Construct( NULL, 0, NULL );
  756. }
  757. SendTable::SendTable(SendProp *pProps, int nProps, char *pNetTableName)
  758. {
  759. Construct( pProps, nProps, pNetTableName );
  760. }
  761. SendTable::~SendTable()
  762. {
  763. // Assert( !m_pPrecalc );
  764. }
  765. void SendTable::Construct( SendProp *pProps, int nProps, char *pNetTableName )
  766. {
  767. m_pProps = pProps;
  768. m_nProps = nProps;
  769. m_pNetTableName = pNetTableName;
  770. m_pPrecalc = 0;
  771. m_bInitialized = false;
  772. m_bHasBeenWritten = false;
  773. m_bHasPropsEncodedAgainstCurrentTickCount = false;
  774. }
  775. #endif