Team Fortress 2 Source Code as on 22/4/2020
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.

218 lines
7.0 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #ifndef DATATABLE_COMMON_H
  9. #define DATATABLE_COMMON_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include "basetypes.h"
  14. #include "tier0/dbg.h"
  15. #include "tier1/strtools.h"
  16. #include <stddef.h>
  17. // Max number of properties in a datatable and its children.
  18. #define MAX_DATATABLES 1024 // must be a power of 2.
  19. #define MAX_DATATABLE_PROPS 4096
  20. #define MAX_ARRAY_ELEMENTS 2048 // a network array should have more that 1024 elements
  21. #define HIGH_DEFAULT -121121.121121f
  22. #define BITS_FULLRES -1 // Use the full resolution of the type being encoded.
  23. #define BITS_WORLDCOORD -2 // Encode as a world coordinate.
  24. #define DT_MAX_STRING_BITS 9
  25. #define DT_MAX_STRING_BUFFERSIZE (1<<DT_MAX_STRING_BITS) // Maximum length of a string that can be sent.
  26. #define STRINGBUFSIZE(className, varName) sizeof( ((className*)0)->varName )
  27. // Gets the size of a variable in a class.
  28. #define PROPSIZEOF(className, varName) sizeof(((className*)0)->varName)
  29. // SendProp::m_Flags.
  30. #define SPROP_UNSIGNED (1<<0) // Unsigned integer data.
  31. #define SPROP_COORD (1<<1) // If this is set, the float/vector is treated like a world coordinate.
  32. // Note that the bit count is ignored in this case.
  33. #define SPROP_NOSCALE (1<<2) // For floating point, don't scale into range, just take value as is.
  34. #define SPROP_ROUNDDOWN (1<<3) // For floating point, limit high value to range minus one bit unit
  35. #define SPROP_ROUNDUP (1<<4) // For floating point, limit low value to range minus one bit unit
  36. #define SPROP_NORMAL (1<<5) // If this is set, the vector is treated like a normal (only valid for vectors)
  37. #define SPROP_EXCLUDE (1<<6) // This is an exclude prop (not excludED, but it points at another prop to be excluded).
  38. #define SPROP_XYZE (1<<7) // Use XYZ/Exponent encoding for vectors.
  39. #define SPROP_INSIDEARRAY (1<<8) // This tells us that the property is inside an array, so it shouldn't be put into the
  40. // flattened property list. Its array will point at it when it needs to.
  41. #define SPROP_PROXY_ALWAYS_YES (1<<9) // Set for datatable props using one of the default datatable proxies like
  42. // SendProxy_DataTableToDataTable that always send the data to all clients.
  43. #define SPROP_CHANGES_OFTEN (1<<10) // this is an often changed field, moved to head of sendtable so it gets a small index
  44. #define SPROP_IS_A_VECTOR_ELEM (1<<11) // Set automatically if SPROP_VECTORELEM is used.
  45. #define SPROP_COLLAPSIBLE (1<<12) // Set automatically if it's a datatable with an offset of 0 that doesn't change the pointer
  46. // (ie: for all automatically-chained base classes).
  47. // In this case, it can get rid of this SendPropDataTable altogether and spare the
  48. // trouble of walking the hierarchy more than necessary.
  49. #define SPROP_COORD_MP (1<<13) // Like SPROP_COORD, but special handling for multiplayer games
  50. #define SPROP_COORD_MP_LOWPRECISION (1<<14) // Like SPROP_COORD, but special handling for multiplayer games where the fractional component only gets a 3 bits instead of 5
  51. #define SPROP_COORD_MP_INTEGRAL (1<<15) // SPROP_COORD_MP, but coordinates are rounded to integral boundaries
  52. #define SPROP_VARINT SPROP_NORMAL // reuse existing flag so we don't break demo. note you want to include SPROP_UNSIGNED if needed, its more efficient
  53. #define SPROP_NUMFLAGBITS_NETWORKED 16
  54. // This is server side only, it's used to mark properties whose SendProxy_* functions encode against gpGlobals->tickcount (the only ones that currently do this are
  55. // m_flAnimTime and m_flSimulationTime. MODs shouldn't need to mess with this probably
  56. #define SPROP_ENCODED_AGAINST_TICKCOUNT (1<<16)
  57. // See SPROP_NUMFLAGBITS_NETWORKED for the ones which are networked
  58. #define SPROP_NUMFLAGBITS 17
  59. // Used by the SendProp and RecvProp functions to disable debug checks on type sizes.
  60. #define SIZEOF_IGNORE -1
  61. // Use this to extern send and receive datatables, and reference them.
  62. #define EXTERN_SEND_TABLE(tableName) namespace tableName {extern SendTable g_SendTable;}
  63. #define EXTERN_RECV_TABLE(tableName) namespace tableName {extern RecvTable g_RecvTable;}
  64. #define REFERENCE_SEND_TABLE(tableName) tableName::g_SendTable
  65. #define REFERENCE_RECV_TABLE(tableName) tableName::g_RecvTable
  66. class SendProp;
  67. // The day we do this, we break all mods until they recompile.
  68. //#define SUPPORTS_INT64
  69. typedef enum
  70. {
  71. DPT_Int=0,
  72. DPT_Float,
  73. DPT_Vector,
  74. DPT_VectorXY, // Only encodes the XY of a vector, ignores Z
  75. DPT_String,
  76. DPT_Array, // An array of the base types (can't be of datatables).
  77. DPT_DataTable,
  78. #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!!!
  79. DPT_Quaternion,
  80. #endif
  81. #ifdef SUPPORTS_INT64
  82. DPT_Int64,
  83. #endif
  84. DPT_NUMSendPropTypes
  85. } SendPropType;
  86. class DVariant
  87. {
  88. public:
  89. DVariant() {m_Type = DPT_Float;}
  90. DVariant(float val) {m_Type = DPT_Float; m_Float = val;}
  91. const char *ToString()
  92. {
  93. static char text[128];
  94. switch ( m_Type )
  95. {
  96. case DPT_Int :
  97. Q_snprintf( text, sizeof(text), "%i", m_Int );
  98. break;
  99. case DPT_Float :
  100. Q_snprintf( text, sizeof(text), "%.3f", m_Float );
  101. break;
  102. case DPT_Vector :
  103. Q_snprintf( text, sizeof(text), "(%.3f,%.3f,%.3f)",
  104. m_Vector[0], m_Vector[1], m_Vector[2] );
  105. break;
  106. case DPT_VectorXY :
  107. Q_snprintf( text, sizeof(text), "(%.3f,%.3f)",
  108. m_Vector[0], m_Vector[1] );
  109. break;
  110. #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!!!
  111. case DPT_Quaternion :
  112. Q_snprintf( text, sizeof(text), "(%.3f,%.3f,%.3f %.3f)",
  113. m_Vector[0], m_Vector[1], m_Vector[2], m_Vector[3] );
  114. break;
  115. #endif
  116. case DPT_String :
  117. if ( m_pString )
  118. return m_pString;
  119. else
  120. return "NULL";
  121. break;
  122. case DPT_Array :
  123. Q_snprintf( text, sizeof(text), "Array" );
  124. break;
  125. case DPT_DataTable :
  126. Q_snprintf( text, sizeof(text), "DataTable" );
  127. break;
  128. #ifdef SUPPORTS_INT64
  129. case DPT_Int64:
  130. Q_snprintf( text, sizeof(text), "%I64d", m_Int64 );
  131. break;
  132. #endif
  133. default :
  134. Q_snprintf( text, sizeof(text), "DVariant type %i unknown", m_Type );
  135. break;
  136. }
  137. return text;
  138. }
  139. union
  140. {
  141. float m_Float;
  142. int m_Int;
  143. const char *m_pString;
  144. void *m_pData; // For DataTables.
  145. #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!!!
  146. float m_Vector[4];
  147. #else
  148. float m_Vector[3];
  149. #endif
  150. #ifdef SUPPORTS_INT64
  151. int64 m_Int64;
  152. #endif
  153. };
  154. SendPropType m_Type;
  155. };
  156. // This can be used to set the # of bits used to transmit a number between 0 and nMaxElements-1.
  157. inline int NumBitsForCount( int nMaxElements )
  158. {
  159. int nBits = 0;
  160. while ( nMaxElements > 0 )
  161. {
  162. ++nBits;
  163. nMaxElements >>= 1;
  164. }
  165. return nBits;
  166. }
  167. #endif // DATATABLE_COMMON_H