//////////////////////////////////////////////////////////////// // // CRenderWareSA::ModelInfoTXDLoadTextures // // Load textures from a TXD file // //////////////////////////////////////////////////////////////// bool CRenderWareSA::ModelInfoTXDLoadTextures ( SReplacementTextures* pReplacementTextures, const SString& strFilename, bool bFilteringEnabled ) { // Are we already loaded? if ( !pReplacementTextures->textures.empty () ) return false; if ( !g_pCore->GetNetwork ()->CheckFile ( "txd", strFilename ) ) return false; // Try to load it RwTexDictionary* pTxd = ReadTXD ( strFilename ); if ( pTxd ) { // Get the list of textures into our own list GetTxdTextures ( pReplacementTextures->textures, pTxd ); for ( uint i = 0 ; i < pReplacementTextures->textures.size () ; i++ ) { pReplacementTextures->textures[i]->txd = NULL; if ( bFilteringEnabled ) pReplacementTextures->textures[i]->flags = 0x1102; // Enable filtering (otherwise textures are pixely) } // Make the txd forget it has any textures and destroy it pTxd->textures.root.next = &pTxd->textures.root; pTxd->textures.root.prev = &pTxd->textures.root; RwTexDictionaryDestroy ( pTxd ); pTxd = NULL; // We succeeded if we got any textures return pReplacementTextures->textures.size () > 0; } return false; }
///////////////////////////////////////////////////////////////////////////// // // CRenderWareSA::RightSizeTxd // // Check textures in a txd and shrink if required. // Returns true if shrunk file was written // ///////////////////////////////////////////////////////////////////////////// bool CRenderWareSA::RightSizeTxd( const SString& strInTxdFilename, const SString& strOutTxdFilename, uint uiSizeLimit ) { // // Read txd from memory // RwStream* pStream = RwStreamOpen( STREAM_TYPE_FILENAME, STREAM_MODE_READ, *strInTxdFilename ); if ( pStream == NULL ) return false; // Find our txd chunk if ( RwStreamFindChunk( pStream, 0x16, NULL, NULL ) == false ) { RwStreamClose( pStream, NULL ); return false; } // read the txd RwTexDictionary* pTxd = RwTexDictionaryGtaStreamRead( pStream ); RwStreamClose( pStream, NULL ); if ( !pTxd ) return false; // // Process each texture in the txd // std::vector < RwTexture* > textureList; pGame->GetRenderWareSA()->GetTxdTextures( textureList, pTxd ); bool bChanged = false; for ( std::vector < RwTexture* > ::iterator iter = textureList.begin() ; iter != textureList.end() ; iter++ ) { RwTexture* pTexture = *iter; RwTexture* pNewRwTexture = RightSizeTexture( pTexture, uiSizeLimit ); if ( pNewRwTexture && pNewRwTexture != pTexture ) { // Replace texture in txd if changed RwTextureDestroy( pTexture ); RwTexDictionaryAddTexture( pTxd, pNewRwTexture ); bChanged = true; } else { // Keep texture (Reinsert to preserve order for easier debugging) RwTexDictionaryRemoveTexture( pTxd, pTexture ); RwTexDictionaryAddTexture( pTxd, pTexture ); } } // // Save shrunked txd if changed // if ( bChanged ) { pStream = RwStreamOpen( STREAM_TYPE_FILENAME, STREAM_MODE_WRITE, *strOutTxdFilename ); if ( pStream ) { RwTexDictionaryStreamWrite( pTxd, pStream ); RwStreamClose( pStream, NULL ); RwTexDictionaryDestroy( pTxd ); return true; } } RwTexDictionaryDestroy( pTxd ); return false; }