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.

241 lines
7.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "cbase.h"
  9. #include "isaverestore.h"
  10. #include "saverestoretypes.h"
  11. // memdbgon must be the last include file in a .cpp file!!!
  12. #include "tier0/memdbgon.h"
  13. //-----------------------------------------------------------------------------
  14. // Purpose: iterates through a typedescript data block, so it can insert key/value data into the block
  15. // Input : *pObject - pointer to the struct or class the data is to be insterted into
  16. // *pFields - description of the data
  17. // iNumFields - number of fields contained in pFields
  18. // char *szKeyName - name of the variable to look for
  19. // char *szValue - value to set the variable to
  20. // Output : Returns true if the variable is found and set, false if the key is not found.
  21. //-----------------------------------------------------------------------------
  22. bool ParseKeyvalue( void *pObject, typedescription_t *pFields, int iNumFields, const char *szKeyName, const char *szValue )
  23. {
  24. int i;
  25. typedescription_t *pField;
  26. for ( i = 0; i < iNumFields; i++ )
  27. {
  28. pField = &pFields[i];
  29. int fieldOffset = pField->fieldOffset[ TD_OFFSET_NORMAL ];
  30. // Check the nested classes, but only if they aren't in array form.
  31. if ((pField->fieldType == FIELD_EMBEDDED) && (pField->fieldSize == 1))
  32. {
  33. for ( datamap_t *dmap = pField->td; dmap != NULL; dmap = dmap->baseMap )
  34. {
  35. void *pEmbeddedObject = (void*)((char*)pObject + fieldOffset);
  36. if ( ParseKeyvalue( pEmbeddedObject, dmap->dataDesc, dmap->dataNumFields, szKeyName, szValue) )
  37. return true;
  38. }
  39. }
  40. if ( (pField->flags & FTYPEDESC_KEY) && !stricmp(pField->externalName, szKeyName) )
  41. {
  42. switch( pField->fieldType )
  43. {
  44. case FIELD_MODELNAME:
  45. case FIELD_SOUNDNAME:
  46. case FIELD_STRING:
  47. (*(string_t *)((char *)pObject + fieldOffset)) = AllocPooledString( szValue );
  48. return true;
  49. case FIELD_TIME:
  50. case FIELD_FLOAT:
  51. (*(float *)((char *)pObject + fieldOffset)) = atof( szValue );
  52. return true;
  53. case FIELD_BOOLEAN:
  54. (*(bool *)((char *)pObject + fieldOffset)) = (bool)(atoi( szValue ) != 0);
  55. return true;
  56. case FIELD_CHARACTER:
  57. (*(char *)((char *)pObject + fieldOffset)) = (char)atoi( szValue );
  58. return true;
  59. case FIELD_SHORT:
  60. (*(short *)((char *)pObject + fieldOffset)) = (short)atoi( szValue );
  61. return true;
  62. case FIELD_INTEGER:
  63. case FIELD_TICK:
  64. (*(int *)((char *)pObject + fieldOffset)) = atoi( szValue );
  65. return true;
  66. case FIELD_POSITION_VECTOR:
  67. case FIELD_VECTOR:
  68. UTIL_StringToVector( (float *)((char *)pObject + fieldOffset), szValue );
  69. return true;
  70. case FIELD_VMATRIX:
  71. case FIELD_VMATRIX_WORLDSPACE:
  72. UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 16, szValue );
  73. return true;
  74. case FIELD_MATRIX3X4_WORLDSPACE:
  75. UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 12, szValue );
  76. return true;
  77. case FIELD_COLOR32:
  78. UTIL_StringToColor32( (color32 *) ((char *)pObject + fieldOffset), szValue );
  79. return true;
  80. case FIELD_CUSTOM:
  81. {
  82. SaveRestoreFieldInfo_t fieldInfo =
  83. {
  84. (char *)pObject + fieldOffset,
  85. pObject,
  86. pField
  87. };
  88. pField->pSaveRestoreOps->Parse( fieldInfo, szValue );
  89. return true;
  90. }
  91. default:
  92. case FIELD_INTERVAL: // Fixme, could write this if needed
  93. case FIELD_CLASSPTR:
  94. case FIELD_MODELINDEX:
  95. case FIELD_MATERIALINDEX:
  96. case FIELD_EDICT:
  97. Warning( "Bad field in entity!!\n" );
  98. Assert(0);
  99. break;
  100. }
  101. }
  102. }
  103. return false;
  104. }
  105. //-----------------------------------------------------------------------------
  106. // Purpose: iterates through a typedescript data block, so it can insert key/value data into the block
  107. // Input : *pObject - pointer to the struct or class the data is to be insterted into
  108. // *pFields - description of the data
  109. // iNumFields - number of fields contained in pFields
  110. // char *szKeyName - name of the variable to look for
  111. // char *szValue - value to set the variable to
  112. // Output : Returns true if the variable is found and set, false if the key is not found.
  113. //-----------------------------------------------------------------------------
  114. bool ExtractKeyvalue( void *pObject, typedescription_t *pFields, int iNumFields, const char *szKeyName, char *szValue, int iMaxLen )
  115. {
  116. int i;
  117. typedescription_t *pField;
  118. for ( i = 0; i < iNumFields; i++ )
  119. {
  120. pField = &pFields[i];
  121. int fieldOffset = pField->fieldOffset[ TD_OFFSET_NORMAL ];
  122. // Check the nested classes, but only if they aren't in array form.
  123. if ((pField->fieldType == FIELD_EMBEDDED) && (pField->fieldSize == 1))
  124. {
  125. for ( datamap_t *dmap = pField->td; dmap != NULL; dmap = dmap->baseMap )
  126. {
  127. void *pEmbeddedObject = (void*)((char*)pObject + fieldOffset);
  128. if ( ExtractKeyvalue( pEmbeddedObject, dmap->dataDesc, dmap->dataNumFields, szKeyName, szValue, iMaxLen ) )
  129. return true;
  130. }
  131. }
  132. if ( (pField->flags & FTYPEDESC_KEY) && !stricmp(pField->externalName, szKeyName) )
  133. {
  134. switch( pField->fieldType )
  135. {
  136. case FIELD_MODELNAME:
  137. case FIELD_SOUNDNAME:
  138. case FIELD_STRING:
  139. Q_strncpy( szValue, ((char *)pObject + fieldOffset), iMaxLen );
  140. return true;
  141. case FIELD_TIME:
  142. case FIELD_FLOAT:
  143. Q_snprintf( szValue, iMaxLen, "%f", (*(float *)((char *)pObject + fieldOffset)) );
  144. return true;
  145. case FIELD_BOOLEAN:
  146. Q_snprintf( szValue, iMaxLen, "%d", (*(bool *)((char *)pObject + fieldOffset)) != 0);
  147. return true;
  148. case FIELD_CHARACTER:
  149. Q_snprintf( szValue, iMaxLen, "%d", (*(char *)((char *)pObject + fieldOffset)) );
  150. return true;
  151. case FIELD_SHORT:
  152. Q_snprintf( szValue, iMaxLen, "%d", (*(short *)((char *)pObject + fieldOffset)) );
  153. return true;
  154. case FIELD_INTEGER:
  155. case FIELD_TICK:
  156. Q_snprintf( szValue, iMaxLen, "%d", (*(int *)((char *)pObject + fieldOffset)) );
  157. return true;
  158. case FIELD_POSITION_VECTOR:
  159. case FIELD_VECTOR:
  160. Q_snprintf( szValue, iMaxLen, "%f %f %f",
  161. ((float *)((char *)pObject + fieldOffset))[0],
  162. ((float *)((char *)pObject + fieldOffset))[1],
  163. ((float *)((char *)pObject + fieldOffset))[2] );
  164. return true;
  165. case FIELD_VMATRIX:
  166. case FIELD_VMATRIX_WORLDSPACE:
  167. //UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 16, szValue );
  168. return false;
  169. case FIELD_MATRIX3X4_WORLDSPACE:
  170. //UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 12, szValue );
  171. return false;
  172. case FIELD_COLOR32:
  173. Q_snprintf( szValue, iMaxLen, "%d %d %d %d",
  174. ((int *)((char *)pObject + fieldOffset))[0],
  175. ((int *)((char *)pObject + fieldOffset))[1],
  176. ((int *)((char *)pObject + fieldOffset))[2],
  177. ((int *)((char *)pObject + fieldOffset))[3] );
  178. return true;
  179. case FIELD_CUSTOM:
  180. {
  181. /*
  182. SaveRestoreFieldInfo_t fieldInfo =
  183. {
  184. (char *)pObject + fieldOffset,
  185. pObject,
  186. pField
  187. };
  188. pField->pSaveRestoreOps->Parse( fieldInfo, szValue );
  189. */
  190. return false;
  191. }
  192. default:
  193. case FIELD_INTERVAL: // Fixme, could write this if needed
  194. case FIELD_CLASSPTR:
  195. case FIELD_MODELINDEX:
  196. case FIELD_MATERIALINDEX:
  197. case FIELD_EDICT:
  198. Warning( "Bad field in entity!!\n" );
  199. Assert(0);
  200. break;
  201. }
  202. }
  203. }
  204. return false;
  205. }