diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /dmserializers/importsfmv1.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'dmserializers/importsfmv1.cpp')
| -rw-r--r-- | dmserializers/importsfmv1.cpp | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/dmserializers/importsfmv1.cpp b/dmserializers/importsfmv1.cpp new file mode 100644 index 0000000..1da3f5e --- /dev/null +++ b/dmserializers/importsfmv1.cpp @@ -0,0 +1,219 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "dmserializers.h" +#include "dmebaseimporter.h" +#include "datamodel/idatamodel.h" +#include "datamodel/dmattribute.h" +#include "datamodel/dmelement.h" + +#include <math.h> + +//----------------------------------------------------------------------------- +// Format converter +//----------------------------------------------------------------------------- +class CImportSFMV1 : public CSFMBaseImporter +{ + typedef CSFMBaseImporter BaseClass; +public: + CImportSFMV1( char const *formatName, char const *nextFormatName ); + +private: + virtual bool DoFixup( CDmElement *pSourceRoot ); + + // Fixes up a single time attribute - converting from float seconds to int tenths-of-a-millisecond + void ConvertTimeAttribute( CDmElement *pElementInternal, const char *pOldName, const char *pNewName ); + + // Fixes up a single timeframe + void FixupTimeframe( CDmElement *pElementInternal ); + + // Fixes up a single log - converting from int milliseconds to int tenths-of-a-millisecond + void FixupLog( CDmElement *pElementInternal ); + + CUtlRBTree< CDmElement*, int > m_fixedElements; +}; + + +//----------------------------------------------------------------------------- +// Singleton instance +//----------------------------------------------------------------------------- +static CImportSFMV1 s_ImportDmxV1( "sfm_v1", "sfm_v2" ); + +void InstallSFMV1Importer( IDataModel *pFactory ) +{ + pFactory->AddLegacyUpdater( &s_ImportDmxV1 ); +} + + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +CImportSFMV1::CImportSFMV1( char const *formatName, char const *nextFormatName ) : + BaseClass( formatName, nextFormatName ) +{ + m_fixedElements.SetLessFunc( DefLessFunc( CDmElement * ) ); +} + + +//----------------------------------------------------------------------------- +// Fixes up all elements +//----------------------------------------------------------------------------- +bool CImportSFMV1::DoFixup( CDmElement *pElementInternal ) +{ + if ( !pElementInternal ) + return true; + + if ( m_fixedElements.Find( pElementInternal ) != m_fixedElements.InvalidIndex() ) + return true; + + m_fixedElements.Insert( pElementInternal ); + + const char *pType = pElementInternal->GetTypeString(); + if ( !Q_strcmp( pType, "DmeTimeFrame" ) ) + { + FixupTimeframe( pElementInternal ); + } + else if ( !Q_strcmp( pType, "DmeLog" ) || + !Q_strcmp( pType, "DmeIntLog" ) || + !Q_strcmp( pType, "DmeFloatLog" ) || + !Q_strcmp( pType, "DmeBoolLog" ) || + !Q_strcmp( pType, "DmeColorLog" ) || + !Q_strcmp( pType, "DmeVector2Log" ) || + !Q_strcmp( pType, "DmeVector3Log" ) || + !Q_strcmp( pType, "DmeVector4Log" ) || + !Q_strcmp( pType, "DmeQAngleLog" ) || + !Q_strcmp( pType, "DmeQuaternionLog" ) || + !Q_strcmp( pType, "DmeVMatrixLog" ) ) + { + FixupLog( pElementInternal ); + } + + + for ( CDmAttribute *pAttribute = pElementInternal->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() ) + { + if ( pAttribute->GetType() == AT_ELEMENT ) + { + CDmElement *pElement = pAttribute->GetValueElement<CDmElement>( ); + DoFixup( pElement ); + continue; + } + + if ( pAttribute->GetType() == AT_ELEMENT_ARRAY ) + { + CDmrElementArray<> array( pAttribute ); + int nCount = array.Count(); + for ( int i = 0; i < nCount; ++i ) + { + CDmElement *pChild = array[ i ]; + DoFixup( pChild ); + } + continue; + } + } + + return true; +} + +//----------------------------------------------------------------------------- +// Fixes up a single time attribute - converting from float seconds to int tenths-of-a-millisecond +//----------------------------------------------------------------------------- +void CImportSFMV1::ConvertTimeAttribute( CDmElement *pElementInternal, const char *pOldName, const char *pNewName ) +{ + float time = 0.0f; + CDmAttribute *pOldAttr = pElementInternal->GetAttribute( pOldName ); + if ( !pOldAttr ) + { + Warning( "*** Problem in file encountered!\n" ); + Warning( "*** TimeFrame \"%s\" is missing attribute \"%s\"!\n", pElementInternal->GetName(), pOldName ); + Warning( "*** Setting new attribute \"%s\" to 0\n", pNewName ); + } + else if ( pOldAttr->GetType() != AT_FLOAT ) + { + Warning( "*** Problem in file encountered!\n" ); + Warning( "*** TimeFrame \"%s\" has attribute \"%s\" with an unexpected type (expected float)!\n", pElementInternal->GetName(), pOldName ); + } + else + { + time = pOldAttr->GetValue< float >(); + pElementInternal->RemoveAttribute( pOldName ); + } + + CDmAttribute *pNewAttr = NULL; + + // this is disabled because even dmxconvert installs *some* movieobjects factories, when it probably shouldn't + // the method of installing movieobjects factories will change at some point in the future, and we can turn on this safety check then +#if 0 + int i = g_pDataModel->GetFirstFactory(); + if ( g_pDataModel->IsValidFactory( i ) ) + { + // factories installed - most likely from within movieobjects.lib + // ie there may be different ways of allocating attributes, so it's not safe to add them here + pNewAttr = pElementInternal->GetAttribute( pNewName ); + if ( !pNewAttr || pNewAttr->GetType() != AT_INT ) + { + Assert( 0 ); + Warning( "*** Converter error - expected element \"%s\" to contain int attribute \"%s\"!\n", pElementInternal->GetName(), pNewName ); + Warning( "*** - if you get this error, the converter is out of sync with the element library!\n" ); + return; + } + } + else + { +#endif + // no factories installed - most likely from within dmxconvert.exe + // ie we're just working with CDmElement subclasses, so it's safe to add attributes + pNewAttr = pElementInternal->AddAttribute( pNewName, AT_INT ); + if ( !pNewAttr ) + { + Assert( 0 ); + Warning( "*** Converter error - element \"%s\" already has a non-int attribute \"%s\"!\n", pElementInternal->GetName(), pNewName ); + return; + } +#if 0 + } +#endif + + pNewAttr->SetValue< int >( floor( time * 10000 + 0.5f ) ); +} + +//----------------------------------------------------------------------------- +// Fixes up a single timeframe +//----------------------------------------------------------------------------- +void CImportSFMV1::FixupTimeframe( CDmElement *pElementInternal ) +{ + ConvertTimeAttribute( pElementInternal, "start", "startTime" ); + ConvertTimeAttribute( pElementInternal, "duration", "durationTime" ); + ConvertTimeAttribute( pElementInternal, "offset", "offsetTime" ); +} + +//----------------------------------------------------------------------------- +// Fixes up a single log - converting from int milliseconds to int tenths-of-a-millisecond +//----------------------------------------------------------------------------- +void CImportSFMV1::FixupLog( CDmElement *pElementInternal ) +{ + CDmAttribute *pAttr = pElementInternal->GetAttribute( "times" ); + if ( !pAttr ) + { + Warning( "*** Problem in file encountered!\n" ); + Warning( "*** Log \"%s\" is missing attribute \"%s\"!\n", pElementInternal->GetName(), "times" ); + return; + } + + if ( pAttr->GetType() != AT_INT_ARRAY ) + { + Warning( "*** Problem in file encountered!\n" ); + Warning( "*** Log \"%s\" has attribute \"%s\" with an unexpected type (expected int array)!\n", pElementInternal->GetName(), "times" ); + return; + } + + CDmrArray<int> array( pAttr ); + int c = array.Count(); + for ( int i = 0; i < c; ++i ) + { + // convert all log times from int milliseconds to int tenths-of-a-millisecond + array.Set( i, 10 * array[i] ); + } +} |