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.

220 lines
7.4 KiB

  1. //====== Copyright � 1996-2006, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "dmserializers.h"
  7. #include "dmebaseimporter.h"
  8. #include "datamodel/idatamodel.h"
  9. #include "datamodel/dmattribute.h"
  10. #include "datamodel/dmelement.h"
  11. #include "datamodel/dmattributevar.h"
  12. #include <math.h>
  13. //-----------------------------------------------------------------------------
  14. // Format converter
  15. //-----------------------------------------------------------------------------
  16. class CImportSFMV1 : public CSFMBaseImporter
  17. {
  18. typedef CSFMBaseImporter BaseClass;
  19. public:
  20. CImportSFMV1( char const *formatName, char const *nextFormatName );
  21. private:
  22. virtual bool DoFixup( CDmElement *pSourceRoot );
  23. // Fixes up a single time attribute - converting from float seconds to int tenths-of-a-millisecond
  24. void ConvertTimeAttribute( CDmElement *pElementInternal, const char *pOldName, const char *pNewName );
  25. // Fixes up a single timeframe
  26. void FixupTimeframe( CDmElement *pElementInternal );
  27. // Fixes up a single log - converting from int milliseconds to int tenths-of-a-millisecond
  28. void FixupLog( CDmElement *pElementInternal );
  29. CUtlRBTree< CDmElement*, int > m_fixedElements;
  30. };
  31. //-----------------------------------------------------------------------------
  32. // Singleton instance
  33. //-----------------------------------------------------------------------------
  34. static CImportSFMV1 s_ImportDmxV1( "sfm_v1", "sfm_v2" );
  35. void InstallSFMV1Importer( IDataModel *pFactory )
  36. {
  37. pFactory->AddLegacyUpdater( &s_ImportDmxV1 );
  38. }
  39. //-----------------------------------------------------------------------------
  40. // Constructor
  41. //-----------------------------------------------------------------------------
  42. CImportSFMV1::CImportSFMV1( char const *formatName, char const *nextFormatName ) :
  43. BaseClass( formatName, nextFormatName )
  44. {
  45. m_fixedElements.SetLessFunc( DefLessFunc( CDmElement * ) );
  46. }
  47. //-----------------------------------------------------------------------------
  48. // Fixes up all elements
  49. //-----------------------------------------------------------------------------
  50. bool CImportSFMV1::DoFixup( CDmElement *pElementInternal )
  51. {
  52. if ( !pElementInternal )
  53. return true;
  54. if ( m_fixedElements.Find( pElementInternal ) != m_fixedElements.InvalidIndex() )
  55. return true;
  56. m_fixedElements.Insert( pElementInternal );
  57. const char *pType = pElementInternal->GetTypeString();
  58. if ( !Q_strcmp( pType, "DmeTimeFrame" ) )
  59. {
  60. FixupTimeframe( pElementInternal );
  61. }
  62. else if ( !Q_strcmp( pType, "DmeLog" ) ||
  63. !Q_strcmp( pType, "DmeIntLog" ) ||
  64. !Q_strcmp( pType, "DmeFloatLog" ) ||
  65. !Q_strcmp( pType, "DmeBoolLog" ) ||
  66. !Q_strcmp( pType, "DmeColorLog" ) ||
  67. !Q_strcmp( pType, "DmeVector2Log" ) ||
  68. !Q_strcmp( pType, "DmeVector3Log" ) ||
  69. !Q_strcmp( pType, "DmeVector4Log" ) ||
  70. !Q_strcmp( pType, "DmeQAngleLog" ) ||
  71. !Q_strcmp( pType, "DmeQuaternionLog" ) ||
  72. !Q_strcmp( pType, "DmeVMatrixLog" ) )
  73. {
  74. FixupLog( pElementInternal );
  75. }
  76. for ( CDmAttribute *pAttribute = pElementInternal->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
  77. {
  78. if ( pAttribute->GetType() == AT_ELEMENT )
  79. {
  80. CDmElement *pElement = pAttribute->GetValueElement<CDmElement>( );
  81. DoFixup( pElement );
  82. continue;
  83. }
  84. if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
  85. {
  86. CDmrElementArray<> array( pAttribute );
  87. int nCount = array.Count();
  88. for ( int i = 0; i < nCount; ++i )
  89. {
  90. CDmElement *pChild = array[ i ];
  91. DoFixup( pChild );
  92. }
  93. continue;
  94. }
  95. }
  96. return true;
  97. }
  98. //-----------------------------------------------------------------------------
  99. // Fixes up a single time attribute - converting from float seconds to int tenths-of-a-millisecond
  100. //-----------------------------------------------------------------------------
  101. void CImportSFMV1::ConvertTimeAttribute( CDmElement *pElementInternal, const char *pOldName, const char *pNewName )
  102. {
  103. float time = 0.0f;
  104. CDmAttribute *pOldAttr = pElementInternal->GetAttribute( pOldName );
  105. if ( !pOldAttr )
  106. {
  107. Warning( "*** Problem in file encountered!\n" );
  108. Warning( "*** TimeFrame \"%s\" is missing attribute \"%s\"!\n", pElementInternal->GetName(), pOldName );
  109. Warning( "*** Setting new attribute \"%s\" to 0\n", pNewName );
  110. }
  111. else if ( pOldAttr->GetType() != AT_FLOAT )
  112. {
  113. Warning( "*** Problem in file encountered!\n" );
  114. Warning( "*** TimeFrame \"%s\" has attribute \"%s\" with an unexpected type (expected float)!\n", pElementInternal->GetName(), pOldName );
  115. }
  116. else
  117. {
  118. time = pOldAttr->GetValue< float >();
  119. pElementInternal->RemoveAttribute( pOldName );
  120. }
  121. CDmAttribute *pNewAttr = NULL;
  122. // this is disabled because even dmxconvert installs *some* movieobjects factories, when it probably shouldn't
  123. // the method of installing movieobjects factories will change at some point in the future, and we can turn on this safety check then
  124. #if 0
  125. int i = g_pDataModel->GetFirstFactory();
  126. if ( g_pDataModel->IsValidFactory( i ) )
  127. {
  128. // factories installed - most likely from within movieobjects.lib
  129. // ie there may be different ways of allocating attributes, so it's not safe to add them here
  130. pNewAttr = pElementInternal->GetAttribute( pNewName );
  131. if ( !pNewAttr || pNewAttr->GetType() != AT_INT )
  132. {
  133. Assert( 0 );
  134. Warning( "*** Converter error - expected element \"%s\" to contain int attribute \"%s\"!\n", pElementInternal->GetName(), pNewName );
  135. Warning( "*** - if you get this error, the converter is out of sync with the element library!\n" );
  136. return;
  137. }
  138. }
  139. else
  140. {
  141. #endif
  142. // no factories installed - most likely from within dmxconvert.exe
  143. // ie we're just working with CDmElement subclasses, so it's safe to add attributes
  144. pNewAttr = pElementInternal->AddAttribute( pNewName, AT_INT );
  145. if ( !pNewAttr )
  146. {
  147. Assert( 0 );
  148. Warning( "*** Converter error - element \"%s\" already has a non-int attribute \"%s\"!\n", pElementInternal->GetName(), pNewName );
  149. return;
  150. }
  151. #if 0
  152. }
  153. #endif
  154. pNewAttr->SetValue< int >( floor( time * 10000 + 0.5f ) );
  155. }
  156. //-----------------------------------------------------------------------------
  157. // Fixes up a single timeframe
  158. //-----------------------------------------------------------------------------
  159. void CImportSFMV1::FixupTimeframe( CDmElement *pElementInternal )
  160. {
  161. ConvertTimeAttribute( pElementInternal, "start", "startTime" );
  162. ConvertTimeAttribute( pElementInternal, "duration", "durationTime" );
  163. ConvertTimeAttribute( pElementInternal, "offset", "offsetTime" );
  164. }
  165. //-----------------------------------------------------------------------------
  166. // Fixes up a single log - converting from int milliseconds to int tenths-of-a-millisecond
  167. //-----------------------------------------------------------------------------
  168. void CImportSFMV1::FixupLog( CDmElement *pElementInternal )
  169. {
  170. CDmAttribute *pAttr = pElementInternal->GetAttribute( "times" );
  171. if ( !pAttr )
  172. {
  173. Warning( "*** Problem in file encountered!\n" );
  174. Warning( "*** Log \"%s\" is missing attribute \"%s\"!\n", pElementInternal->GetName(), "times" );
  175. return;
  176. }
  177. if ( pAttr->GetType() != AT_INT_ARRAY )
  178. {
  179. Warning( "*** Problem in file encountered!\n" );
  180. Warning( "*** Log \"%s\" has attribute \"%s\" with an unexpected type (expected int array)!\n", pElementInternal->GetName(), "times" );
  181. return;
  182. }
  183. CDmrArray<int> array( pAttr );
  184. int c = array.Count();
  185. for ( int i = 0; i < c; ++i )
  186. {
  187. // convert all log times from int milliseconds to int tenths-of-a-millisecond
  188. array.Set( i, 10 * array[i] );
  189. }
  190. }