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.

673 lines
19 KiB

  1. //====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "importkeyvaluebase.h"
  7. #include "dmserializers.h"
  8. #include "datamodel/idatamodel.h"
  9. #include "datamodel/dmelement.h"
  10. #include "datamodel/dmattributevar.h"
  11. #include "tier1/KeyValues.h"
  12. #include "tier1/UtlBuffer.h"
  13. #include "datamodel/dmattribute.h"
  14. #include "filesystem.h"
  15. #include "tier2/tier2.h"
  16. #include "materialobjects/amalgtexturevars.h"
  17. //-----------------------------------------------------------------------------
  18. // Serialization class for make sheet files
  19. //-----------------------------------------------------------------------------
  20. class CImportMKS : public IDmSerializer
  21. {
  22. public:
  23. virtual const char *GetName() const { return "mks"; }
  24. virtual const char *GetDescription() const { return "Valve Make Sheet File"; }
  25. virtual bool IsBinaryFormat() const { return false; }
  26. virtual bool StoresVersionInFile() const { return false; }
  27. virtual int GetCurrentVersion() const { return 0; } // doesn't store a version
  28. virtual const char *GetImportedFormat() const { return "mks"; }
  29. virtual int GetImportedVersion() const { return 1; }
  30. bool Serialize( CUtlBuffer &outBuf, CDmElement *pRoot );
  31. // Read from the UtlBuffer, return true if successful, and return the read-in root in ppRoot.
  32. bool Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion, const char *pSourceFormatName,
  33. int nSourceFormatVersion, DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot );
  34. private:
  35. CDmElement *CreateDmeAmalgamatedTexture( const char *pName );
  36. CDmElement *CreateDmeSequence( const char *pName );
  37. CDmElement *CreateDmeSequenceFrame( const char *pName );
  38. CDmElement *CreateDmeSheetImage( const char *pImageName );
  39. void SetCurrentSequenceClamp( bool bState );
  40. int ParsePackingMode( char *word );
  41. bool SetPackingMode( int eMode );
  42. int ParseSequenceType( char *word );
  43. bool ValidateSequenceType( int eMode, char *word );
  44. bool CreateNewSequence( int mode );
  45. void ParseFrameImages( CUtlVector<char *> &words, CUtlVector<char *> &outImageNames );
  46. bool CreateNewFrame( CUtlVector<char *> &imageNames, float ftime );
  47. bool ValidateImagePacking( CDmElement *pBitmap, char *pImageName );
  48. CDmElement *FindSequence( CDmrElementArray< CDmElement > &mapsequences, int index );
  49. CDmElement *FindImage( const char *pFrameName );
  50. void AddImage( CDmElement *newSequenceEntry, char *pImageName );
  51. CDmElement *m_pRoot;
  52. int m_NumActualLinesRead;
  53. CDmElement *m_pCurrentSequence;
  54. DmFileId_t m_Fileid;
  55. int m_SequenceCount;
  56. };
  57. //-----------------------------------------------------------------------------
  58. // Singleton instance
  59. //-----------------------------------------------------------------------------
  60. static CImportMKS s_ImportMKS;
  61. void InstallMKSImporter( IDataModel *pFactory )
  62. {
  63. pFactory->AddSerializer( &s_ImportMKS );
  64. }
  65. //-----------------------------------------------------------------------------
  66. // Writes out a new vmt file
  67. //-----------------------------------------------------------------------------
  68. bool CImportMKS::Serialize( CUtlBuffer &buf, CDmElement *pRoot )
  69. {
  70. //PrintStringAttribute( pRoot, buf, "shader", false, true );
  71. buf.Printf( "{\n" );
  72. buf.PushTab();
  73. //if ( !SerializeShaderParameter( buf, pRoot ) )
  74. // return false;
  75. buf.PopTab();
  76. buf.Printf( "}\n" );
  77. return true;
  78. }
  79. //--------------------------------------------------
  80. // Helper functions
  81. //--------------------------------------------------
  82. static void ApplyMacros( char * in_buf )
  83. {
  84. CUtlVector<char *> Words;
  85. V_SplitString( in_buf, " ", Words);
  86. if ( ( Words.Count() == 4 ) && (! stricmp( Words[0],"ga_frame") ) )
  87. {
  88. // ga_frame frm1 frm2 n -> frame frm1{r=a},frm1{g=a},frm1{b=a},frm2{a=a} n
  89. sprintf( in_buf, "frame %s{r=0},%s{g=a},%s{b=0},%s{a=a} %s",
  90. Words[1], Words[1], Words[1], Words[2], Words[3] );
  91. }
  92. Words.PurgeAndDeleteElements();
  93. }
  94. static char *MoveToStart( char *pLineBuffer )
  95. {
  96. // Kill newline '\n'
  97. char *pChop = strchr( pLineBuffer, '\n' );
  98. if ( pChop )
  99. *pChop = 0;
  100. // Kill '//' remove comment lines.
  101. char *comment = Q_strstr( pLineBuffer, "//" );
  102. if ( comment )
  103. *comment = 0;
  104. // Move to start of non-whitespace
  105. char *in_str = pLineBuffer;
  106. while( ( in_str[0]==' ' ) || ( in_str[0]=='\t') )
  107. in_str++;
  108. return in_str;
  109. }
  110. //--------------------------------------------------
  111. // Parse out the packing mode
  112. //--------------------------------------------------
  113. int CImportMKS::ParsePackingMode( char *word )
  114. {
  115. // Read in the packing mode requested.
  116. int eRequestedMode = PCKM_INVALID;
  117. if ( !stricmp( word, "flat" ) || !stricmp( word, "rgba" ) )
  118. {
  119. eRequestedMode = PCKM_FLAT;
  120. }
  121. else if ( !stricmp( word, "rgb+a" ) )
  122. {
  123. eRequestedMode = PCKM_RGB_A;
  124. }
  125. if ( eRequestedMode == PCKM_INVALID )
  126. {
  127. Warning( "*** line %d: invalid packmode specified, allowed values are 'rgba' or 'rgb+a'!\n", m_NumActualLinesRead );
  128. }
  129. return eRequestedMode;
  130. }
  131. //--------------------------------------------------
  132. // Parse out the sequence type
  133. //--------------------------------------------------
  134. int CImportMKS::ParseSequenceType( char *word )
  135. {
  136. int eMode = SQM_ALPHA_INVALID;
  137. char const *szSeqType = StringAfterPrefix( word, "sequence" );
  138. if ( !stricmp( szSeqType, "" ) || !stricmp( szSeqType, "-rgba" ) )
  139. {
  140. eMode = SQM_RGBA;
  141. }
  142. else if ( !stricmp( szSeqType, "-rgb" ) )
  143. {
  144. eMode = SQM_RGB;
  145. }
  146. else if ( !stricmp( szSeqType, "-a" ) )
  147. {
  148. eMode = SQM_ALPHA;
  149. }
  150. else
  151. {
  152. Warning( "*** line %d: invalid sequence type '%s', allowed 'sequence-rgba' or 'sequence-rgb' or 'sequence-a'!\n", m_NumActualLinesRead, word );
  153. }
  154. return eMode;
  155. }
  156. //--------------------------------------------------
  157. // Functions to set attribute values
  158. //--------------------------------------------------
  159. void CImportMKS::SetCurrentSequenceClamp( bool bState )
  160. {
  161. Warning( "Attempting to set clamp when there is no current sequence!\n" );
  162. if ( m_pCurrentSequence )
  163. {
  164. CDmAttribute *pClamp= m_pCurrentSequence->GetAttribute( "clamp" );
  165. Assert( pClamp );
  166. pClamp->SetValue< bool >( bState );
  167. }
  168. }
  169. bool CImportMKS::SetPackingMode( int eMode )
  170. {
  171. CDmAttribute *pCurrentPackingModeAttr = m_pRoot->GetAttribute( "packmode" );
  172. Assert( pCurrentPackingModeAttr );
  173. int currentPackingMode = pCurrentPackingModeAttr->GetValue< int >();
  174. CDmrElementArray< CDmElement > sequences( m_pRoot, "sequences", true );
  175. // Assign the packing mode read in to member var.
  176. if ( !sequences.Count() )
  177. {
  178. pCurrentPackingModeAttr->SetValue< int >( eMode );
  179. }
  180. else if ( currentPackingMode != eMode )
  181. {
  182. // Allow special changes:
  183. // flat -> rgb+a
  184. if ( currentPackingMode == PCKM_FLAT && eMode == PCKM_RGB_A )
  185. {
  186. Msg( "Warning changing packing mode when %d sequences already defined. This may not be serialized correctly.\n", sequences.Count() );
  187. pCurrentPackingModeAttr->SetValue< int >( eMode );
  188. }
  189. // everything else
  190. else
  191. {
  192. Msg( "*** line error: incompatible packmode change when %d sequences already defined!\n", sequences.Count() );
  193. return false;
  194. }
  195. }
  196. return true;
  197. }
  198. //--------------------------------------------------
  199. // Validation
  200. //--------------------------------------------------
  201. bool CImportMKS::ValidateSequenceType( int eMode, char *word )
  202. {
  203. CDmAttribute *pCurrentPackingModeAttr = m_pRoot->GetAttribute( "packmode" );
  204. Assert( pCurrentPackingModeAttr );
  205. int currentPackingMode = pCurrentPackingModeAttr->GetValue< int >();
  206. switch ( currentPackingMode )
  207. {
  208. case PCKM_FLAT:
  209. switch ( eMode )
  210. {
  211. case SQM_RGBA:
  212. break;
  213. default:
  214. Msg( "*** line error: invalid sequence type '%s', packing 'flat' allows only 'sequence-rgba'!\n", word );
  215. return false;
  216. }
  217. break;
  218. case PCKM_RGB_A:
  219. switch ( eMode )
  220. {
  221. case SQM_RGB:
  222. case SQM_ALPHA:
  223. break;
  224. default:
  225. return false;
  226. }
  227. break;
  228. default:
  229. Warning( "Invalid packing mode!" );
  230. return false;
  231. }
  232. return true;
  233. }
  234. //--------------------------------------------------
  235. // Validate that image packing is correct
  236. //--------------------------------------------------
  237. bool CImportMKS::ValidateImagePacking( CDmElement *pBitmap, char *pImageName )
  238. {
  239. CDmAttribute *pCurrentPackingModeAttr = m_pRoot->GetAttribute( "packmode" );
  240. Assert( pCurrentPackingModeAttr );
  241. int currentPackingMode = pCurrentPackingModeAttr->GetValue< int >();
  242. if ( currentPackingMode == PCKM_RGB_A )
  243. {
  244. CDmrElementArray< CDmElement > mapsequences( pBitmap, "mapsequences", true );
  245. for ( uint16 idx = 0; idx < mapsequences.Count(); ++idx )
  246. {
  247. CDmElement *pSeq = FindSequence( mapsequences, idx );
  248. Assert( pSeq );
  249. CDmAttribute *pSequenceNumberAttr = pSeq->GetAttribute( "sequencenumber" );
  250. Assert( pSequenceNumberAttr );
  251. int sequenceNumber = pSequenceNumberAttr->GetValue<int>();
  252. CDmAttribute *pModeAttr = pSeq->GetAttribute( "mode" );
  253. Assert( pModeAttr );
  254. int mode = pModeAttr->GetValue<int>();
  255. CDmAttribute *pCurrentSequenceNumberAttr = m_pCurrentSequence->GetAttribute( "sequencenumber" );
  256. Assert( pCurrentSequenceNumberAttr );
  257. int currentSequenceNumber = pCurrentSequenceNumberAttr->GetValue<int>();
  258. CDmAttribute *pCurrentModeAttr = m_pCurrentSequence->GetAttribute( "mode" );
  259. Assert( pCurrentModeAttr );
  260. int currentMode = pCurrentModeAttr->GetValue<int>();
  261. if ( ( mode != SQM_RGBA ) && ( mode != currentMode ) )
  262. {
  263. Msg( "*** line error: 'rgb+a' packing cannot pack image '%s' belonging to sequences %d and %d!\n",
  264. pImageName,
  265. sequenceNumber,
  266. currentSequenceNumber );
  267. return false;
  268. }
  269. }
  270. }
  271. return true;
  272. }
  273. //--------------------------------------------------
  274. // Functions to create dme elements
  275. //--------------------------------------------------
  276. CDmElement *CImportMKS::CreateDmeAmalgamatedTexture( const char *pName )
  277. {
  278. DmElementHandle_t hElement = g_pDataModel->CreateElement( "DmeAmalgamatedTexture", "CDmeAmalgamatedTexture", m_Fileid );
  279. if ( hElement == DMELEMENT_HANDLE_INVALID )
  280. {
  281. Warning( "Element uses unknown element type %s\n", "CDmeAmalgamatedTexture" );
  282. return NULL;
  283. }
  284. CDmElement *pElement = g_pDataModel->GetElement( hElement );
  285. if ( !pElement )
  286. return NULL;
  287. // Base members
  288. if ( !pElement->AddAttribute( "images", AT_ELEMENT_ARRAY ) )
  289. return NULL;
  290. if ( !pElement->AddAttribute( "packmode", AT_INT ) )
  291. return NULL;
  292. if ( !pElement->AddAttribute( "width", AT_INT ) )
  293. return NULL;
  294. if ( !pElement->AddAttribute( "height", AT_INT ) )
  295. return NULL;
  296. return pElement;
  297. }
  298. CDmElement *CImportMKS::CreateDmeSequence( const char *pName )
  299. {
  300. DmElementHandle_t hElement = g_pDataModel->CreateElement( "DmeSheetSequence", pName, m_Fileid );
  301. if ( hElement == DMELEMENT_HANDLE_INVALID )
  302. {
  303. Warning( "Element uses unknown element type %s\n", "CDmeSheetSequence" );
  304. return false;
  305. }
  306. CDmElement *pElement = g_pDataModel->GetElement( hElement );
  307. if ( !pElement )
  308. return NULL;
  309. if ( !pElement->AddAttribute( "sequencenumber", AT_INT ) )
  310. return false;
  311. if ( !pElement->AddAttribute( "clamp", AT_BOOL ) )
  312. return false;
  313. if ( !pElement->AddAttribute( "mode", AT_INT ) )
  314. return false;
  315. if ( !pElement->AddAttribute( "frames", AT_ELEMENT_ARRAY ) )
  316. return false;
  317. CDmAttribute *pClapAttr = pElement->GetAttribute( "clamp" );
  318. Assert( pClapAttr );
  319. pClapAttr->SetValue< bool >( true );
  320. CDmAttribute *pModeAttr = pElement->GetAttribute( "mode" );
  321. Assert( pModeAttr );
  322. pModeAttr->SetValue< int >( SQM_RGBA );
  323. return pElement;
  324. }
  325. CDmElement *CImportMKS::CreateDmeSequenceFrame( const char *pName )
  326. {
  327. DmElementHandle_t hElement = g_pDataModel->CreateElement( "DmeSheetSequenceFrame", pName, m_Fileid );
  328. if ( hElement == DMELEMENT_HANDLE_INVALID )
  329. {
  330. Warning( "Element uses unknown element type %s\n", "CDmeSheetSequenceFrame" );
  331. return false;
  332. }
  333. CDmElement *pElement = g_pDataModel->GetElement( hElement );
  334. if ( !pElement )
  335. return NULL;
  336. if ( !pElement->AddAttribute( "sheetimages", AT_ELEMENT_ARRAY ) )
  337. return false;
  338. if ( !pElement->AddAttribute( "displaytime", AT_FLOAT ) )
  339. return false;
  340. return pElement;
  341. }
  342. CDmElement *CImportMKS::CreateDmeSheetImage( const char *pImageName )
  343. {
  344. DmElementHandle_t hElement = g_pDataModel->CreateElement( "DmeSheetImage", pImageName, m_Fileid );
  345. if ( hElement == DMELEMENT_HANDLE_INVALID )
  346. {
  347. Warning("Element uses unknown element type %s\n", "CDmeSheetImage" );
  348. return false;
  349. }
  350. CDmElement *pElement = g_pDataModel->GetElement( hElement );
  351. if ( !pElement )
  352. return NULL;
  353. if ( !pElement->AddAttribute( "xcoord", AT_INT ) )
  354. return NULL;
  355. if ( !pElement->AddAttribute( "ycoord", AT_INT ) )
  356. return NULL;
  357. return pElement;
  358. }
  359. //---------------------------------------------------------------
  360. // Functions to put this all together
  361. //---------------------------------------------------------------
  362. bool CImportMKS::CreateNewSequence( int mode )
  363. {
  364. m_pCurrentSequence = CreateDmeSequence( "CDmeSheetSequence" );
  365. if ( !m_pCurrentSequence )
  366. return false;
  367. CDmAttribute *pSeqNoAttr = m_pCurrentSequence->GetAttribute( "sequencenumber" );
  368. Assert( pSeqNoAttr );
  369. pSeqNoAttr->SetValue< int >( m_SequenceCount );
  370. m_SequenceCount++;
  371. CDmAttribute *pSeqType = m_pCurrentSequence->GetAttribute( "mode" );
  372. Assert( pSeqType );
  373. pSeqType->SetValue< int >( mode );
  374. CDmrElementArray< CDmElement > sequences( m_pRoot, "sequences", true );
  375. sequences.AddToTail( m_pCurrentSequence );
  376. return true;
  377. }
  378. bool CImportMKS::CreateNewFrame( CUtlVector<char *> &imageNames, float ftime )
  379. {
  380. CDmElement *pNewFrame = CreateDmeSequenceFrame( "CDmeSheetSequenceFrame" );
  381. if ( !pNewFrame )
  382. return false;
  383. CDmAttribute *pDisplayTimeAttr = pNewFrame->GetAttribute( "displaytime" );
  384. Assert( pDisplayTimeAttr );
  385. pDisplayTimeAttr->SetValue< float >( ftime );
  386. for ( int i = 0; i < imageNames.Count(); ++i )
  387. {
  388. Assert( imageNames.Count() <= MAX_IMAGES_PER_FRAME );
  389. AddImage( pNewFrame, imageNames[i] );
  390. }
  391. CDmrElementArray< CDmElement > currentFrames( m_pCurrentSequence->GetAttribute( "frames" ) );
  392. currentFrames.AddToTail( pNewFrame );
  393. return true;
  394. }
  395. CDmElement *CImportMKS::FindImage( const char *pFrameName )
  396. {
  397. CDmrElementArray< CDmElement > images = m_pRoot->GetAttribute( "images" );
  398. int nCount = images.Count();
  399. for ( int i = 0; i < nCount; ++i )
  400. {
  401. if ( !Q_stricmp( pFrameName, images[i]->GetName() ) )
  402. return images[i];
  403. }
  404. return NULL;
  405. }
  406. CDmElement *CImportMKS::FindSequence( CDmrElementArray< CDmElement > &mapsequences, int index )
  407. {
  408. if ( index < mapsequences.Count() )
  409. {
  410. return mapsequences[index];
  411. }
  412. return NULL;
  413. }
  414. void CImportMKS::AddImage( CDmElement *pSequenceEntry, char *pImageName )
  415. {
  416. // Store the image in the image list, this is a string - bitmap mapping.
  417. CDmElement *pBitmap = FindImage( pImageName );
  418. if ( !pBitmap )
  419. {
  420. CDmElement *pBitmap = CreateDmeSheetImage( pImageName );
  421. if ( !pBitmap )
  422. return;
  423. CDmrElementArray< CDmElement > images = m_pRoot->GetAttribute( "images" );
  424. images.AddToTail( pBitmap );
  425. }
  426. pBitmap = FindImage( pImageName );
  427. Assert( pBitmap );
  428. CDmrElementArray< CDmElement > sheetImages = pSequenceEntry->GetAttribute( "sheetimages" );
  429. sheetImages.AddToTail( pBitmap );
  430. if ( !ValidateImagePacking( pBitmap, pImageName ) )
  431. {
  432. Warning( "Image packing validation failed!" );
  433. }
  434. CDmrElementArray< CDmElement > mapSequences( pBitmap, "mapsequences", true );
  435. mapSequences.AddToTail( m_pCurrentSequence );
  436. }
  437. void CImportMKS::ParseFrameImages( CUtlVector<char *> &words, CUtlVector<char *> &outImageNames )
  438. {
  439. for ( int i = 0; i < words.Count() - 2; i++ )
  440. {
  441. char *fnamebuf = words[i+1];
  442. outImageNames.AddToTail( fnamebuf );
  443. }
  444. }
  445. //-----------------------------------------------------------------------------
  446. // Main entry point for the unserialization
  447. //-----------------------------------------------------------------------------
  448. bool CImportMKS::Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion, const char *pSourceFormatName,
  449. int nSourceFormatVersion, DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot )
  450. {
  451. *ppRoot = NULL;
  452. m_Fileid = fileid;
  453. // Create the main element
  454. m_pRoot = CreateDmeAmalgamatedTexture( "CDmeAmalgamatedTexture" );
  455. if ( !m_pRoot )
  456. return false;
  457. *ppRoot = m_pRoot;
  458. // Initial value for this param
  459. m_SequenceCount = 0;
  460. bool bSuccess = SetPackingMode( PCKM_FLAT );
  461. if ( !bSuccess )
  462. return false;
  463. char linebuffer[4096];
  464. m_NumActualLinesRead = 0;
  465. while ( buf.IsValid() )
  466. {
  467. buf.GetLine( linebuffer, sizeof(linebuffer) );
  468. ++m_NumActualLinesRead;
  469. char *in_str = MoveToStart( linebuffer );
  470. if ( in_str[0] == NULL )
  471. continue;
  472. strlwr( in_str ); // send string to lowercase.
  473. ApplyMacros( in_str );
  474. CUtlVector<char *> words;
  475. V_SplitString( in_str, " ", words);
  476. if ( ( words.Count() == 1) && ( !stricmp( words[0], "loop" ) ) )
  477. {
  478. SetCurrentSequenceClamp( false );
  479. }
  480. else if ( ( words.Count() == 2 ) && ( !stricmp( words[0], "packmode" ) ) )
  481. {
  482. // Read in the packing mode requested.
  483. int eRequestedMode = ParsePackingMode( words[1] );
  484. if ( ( eRequestedMode == PCKM_INVALID ) || !SetPackingMode( eRequestedMode ) )
  485. {
  486. Warning( "Unable to set packing mode." );
  487. return NULL;
  488. }
  489. }
  490. else if ( ( words.Count() == 2) && StringHasPrefix( words[0], "sequence" ) )
  491. {
  492. int seq_no = atoi( words[1] );
  493. if ( seq_no != m_SequenceCount )
  494. {
  495. Warning( "Sequence number mismatch.\n" );
  496. }
  497. // Figure out the sequence type
  498. int mode = ParseSequenceType( words[0] );
  499. if ( ( mode == SQM_ALPHA_INVALID ) || !ValidateSequenceType( mode, words[0] ) )
  500. {
  501. Warning( "Invalid sequence type.\n" );
  502. return NULL;
  503. }
  504. bool bSuccess = CreateNewSequence( mode );
  505. if ( !bSuccess )
  506. {
  507. Warning( "Unable to create new sequence.\n" );
  508. return NULL;
  509. }
  510. }
  511. else if ( ( words.Count() >= 3) && (! stricmp( words[0], "frame" ) ) )
  512. {
  513. if ( m_pCurrentSequence )
  514. {
  515. float ftime = atof( words[ words.Count() - 1 ] );
  516. // Warning( "ftime is %f\n", ftime );
  517. CUtlVector<char *> imageNames;
  518. ParseFrameImages( words, imageNames );
  519. bool bSuccess = CreateNewFrame( imageNames, ftime );
  520. if ( !bSuccess )
  521. {
  522. Warning( "Unable to create new frame.\n" );
  523. return NULL;
  524. }
  525. }
  526. else
  527. {
  528. Warning( "Trying to add a frame when there is no current sequence.\n" );
  529. }
  530. }
  531. else
  532. {
  533. Warning( "*** line %d: Bad command \"%s\"!\n", m_NumActualLinesRead, in_str );
  534. return NULL;
  535. }
  536. words.PurgeAndDeleteElements();
  537. }
  538. // Import compiler settings
  539. char pTexFile[MAX_PATH];
  540. const char *pFileName = g_pDataModel->GetFileName( fileid );
  541. Q_strncpy( pTexFile, pFileName, sizeof(pTexFile) );
  542. Q_SetExtension( pTexFile, "txt", sizeof(pTexFile) );
  543. if ( g_pFullFileSystem->FileExists( pTexFile ) )
  544. {
  545. CDmElement *pTextureCompileSettings = NULL;
  546. if ( !g_pDataModel->RestoreFromFile( pTexFile, NULL, "tex_source1", &pTextureCompileSettings, CR_COPY_NEW ) )
  547. {
  548. Warning( "Error reading texture compile settings file \"%s\"!\n", pTexFile );
  549. return NULL;
  550. }
  551. pTextureCompileSettings->SetFileId( m_pRoot->GetFileId(), TD_DEEP, true );
  552. m_pRoot->SetValue( "textureCompileSettings", pTextureCompileSettings );
  553. }
  554. return g_pDataModel->UpdateUnserializedElements( pSourceFormatName, nSourceFormatVersion, fileid, idConflictResolution, ppRoot );
  555. }