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.

181 lines
5.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // The copyright to the contents herein is the property of Valve, L.L.C.
  4. // The contents may be used and/or copied only with the written permission of
  5. // Valve, L.L.C., or in accordance with the terms and conditions stipulated in
  6. // the agreement/contract under which the contents have been supplied.
  7. //
  8. // $Header: $
  9. // $NoKeywords: $
  10. //
  11. // Converts from any one DMX file format to another
  12. // Can also output SMD or a QCI header from DMX input
  13. //
  14. //=============================================================================
  15. #include "tier0/dbg.h"
  16. #include "tier0/icommandline.h"
  17. #include "datamodel/idatamodel.h"
  18. #include "filesystem.h"
  19. #include "appframework/appframework.h"
  20. #include "tier1/utlbuffer.h"
  21. #include "dmserializers/idmserializers.h"
  22. #include "tier1/utlstring.h"
  23. #include "datamodel/dmattribute.h"
  24. #include "datamodel/dmelement.h"
  25. #include "tier2/tier2.h"
  26. class CDmElement;
  27. //-----------------------------------------------------------------------------
  28. // Standard spew functions
  29. //-----------------------------------------------------------------------------
  30. static SpewRetval_t DMXConvertOutputFunc( SpewType_t spewType, char const *pMsg )
  31. {
  32. printf( pMsg );
  33. fflush( stdout );
  34. if (spewType == SPEW_ERROR)
  35. return SPEW_ABORT;
  36. return (spewType == SPEW_ASSERT) ? SPEW_DEBUGGER : SPEW_CONTINUE;
  37. }
  38. //-----------------------------------------------------------------------------
  39. // The application object
  40. //-----------------------------------------------------------------------------
  41. class CDmxConvertApp : public CDefaultAppSystemGroup<CSteamAppSystemGroup>
  42. {
  43. public:
  44. // Methods of IApplication
  45. virtual bool Create();
  46. virtual bool PreInit( );
  47. virtual int Main();
  48. virtual void PostShutdown();
  49. };
  50. DEFINE_CONSOLE_STEAM_APPLICATION_OBJECT( CDmxConvertApp );
  51. //-----------------------------------------------------------------------------
  52. // The application object
  53. //-----------------------------------------------------------------------------
  54. bool CDmxConvertApp::Create()
  55. {
  56. SpewOutputFunc( DMXConvertOutputFunc );
  57. AddSystem( g_pDataModel, VDATAMODEL_INTERFACE_VERSION );
  58. AddSystem( g_pDmSerializers, DMSERIALIZERS_INTERFACE_VERSION );
  59. return true;
  60. }
  61. bool CDmxConvertApp::PreInit( )
  62. {
  63. CreateInterfaceFn factory = GetFactory();
  64. ConnectTier1Libraries( &factory, 1 );
  65. ConnectTier2Libraries( &factory, 1 );
  66. if ( !g_pFullFileSystem || !g_pDataModel )
  67. {
  68. Warning( "DMXConvert is missing a required interface!\n" );
  69. return false;
  70. }
  71. return true;
  72. }
  73. void CDmxConvertApp::PostShutdown()
  74. {
  75. DisconnectTier2Libraries();
  76. DisconnectTier1Libraries();
  77. }
  78. //-----------------------------------------------------------------------------
  79. // The application object
  80. //-----------------------------------------------------------------------------
  81. int CDmxConvertApp::Main()
  82. {
  83. g_pDataModel->OnlyCreateUntypedElements( true );
  84. g_pDataModel->SetDefaultElementFactory( NULL );
  85. // This bit of hackery allows us to access files on the harddrive
  86. g_pFullFileSystem->AddSearchPath( "", "LOCAL", PATH_ADD_TO_HEAD );
  87. const char *pInFileName = CommandLine()->ParmValue("-i" );
  88. const char *pOutFileName = CommandLine()->ParmValue("-o" );
  89. const char *pInFormat = CommandLine()->ParmValue("-if" );
  90. const char *pOutFormat = CommandLine()->ParmValue("-of" );
  91. const char *pOutEncoding = CommandLine()->ParmValue("-oe" );
  92. if ( !pInFileName )
  93. {
  94. Msg( "Usage: dmxconvert -i <in file> [-if <in format_hint>] [-o <out file>] [-oe <out encoding>] [-of <out format>]\n" );
  95. Msg( "If no output file is specified, dmx to dmx conversion will overwrite the input\n" );
  96. Msg( "Supported DMX file encodings:\n" );
  97. for ( int i = 0; i < g_pDataModel->GetEncodingCount(); ++i )
  98. {
  99. Msg( " %s\n", g_pDataModel->GetEncodingName( i ) );
  100. }
  101. Msg( "Supported DMX file formats:\n" );
  102. for ( int i = 0; i < g_pDataModel->GetFormatCount(); ++i )
  103. {
  104. Msg( " %s\n", g_pDataModel->GetFormatName( i ) );
  105. }
  106. return -1;
  107. }
  108. // When reading, keep the CRLF; this will make ReadFile read it in binary format
  109. // and also append a couple 0s to the end of the buffer.
  110. DmxHeader_t header;
  111. CDmElement *pRoot;
  112. if ( g_pDataModel->RestoreFromFile( pInFileName, NULL, pInFormat, &pRoot, CR_DELETE_NEW, &header ) == DMFILEID_INVALID )
  113. {
  114. Error( "Encountered an error reading file \"%s\"!\n", pInFileName );
  115. return -1;
  116. }
  117. if ( !pOutFormat )
  118. {
  119. pOutFormat = header.formatName;
  120. if ( !g_pDataModel->FindFormatUpdater( pOutFormat ) )
  121. {
  122. pOutFormat = "dmx"; // default to generic dmx format for legacy files
  123. }
  124. }
  125. if ( !pOutEncoding )
  126. {
  127. pOutEncoding = g_pDataModel->GetDefaultEncoding( pOutFormat );
  128. if ( !pOutEncoding )
  129. {
  130. // no default encoding was found, try to convert the file to the generic dmx format
  131. pOutFormat = GENERIC_DMX_FORMAT;
  132. pOutEncoding = g_pDataModel->GetDefaultEncoding( pOutFormat );
  133. }
  134. }
  135. if ( !pOutFileName )
  136. {
  137. pOutFileName = pInFileName;
  138. }
  139. // TODO - in theory, at some point, we may have converters from pInFormat to pOutFormat
  140. // until then, treat it as a noop, and hope for the best
  141. if ( !g_pDataModel->SaveToFile( pOutFileName, NULL, pOutEncoding, pOutFormat, pRoot ) )
  142. {
  143. Error( "Encountered an error writing file \"%s\"!\n", pOutFileName );
  144. return -1;
  145. }
  146. g_pDataModel->RemoveFileId( pRoot->GetFileId() );
  147. return 0;
  148. }