//----------------------------------------------------------------------------- // Serialization //----------------------------------------------------------------------------- bool CVTFTexture::Serialize( CUtlBuffer &buf ) { if (!m_pImageData) { Warning("*** Unable to serialize... have no image data!\n"); return false; } VTFFileHeader_t header; Q_strncpy( header.fileTypeString, "VTF", 4 ); header.version[0] = VTF_MAJOR_VERSION; header.version[1] = VTF_MINOR_VERSION; header.headerSize = sizeof(VTFFileHeader_t); header.width = m_nWidth; header.height = m_nHeight; header.flags = m_nFlags; header.numFrames = m_nFrameCount; header.numMipLevels = m_nMipCount; header.imageFormat = m_Format; VectorCopy( m_vecReflectivity, header.reflectivity ); header.bumpScale = m_flBumpScale; // FIXME: Why is this needed? header.startFrame = m_iStartFrame; header.lowResImageWidth = m_nLowResImageWidth; header.lowResImageHeight = m_nLowResImageHeight; header.lowResImageFormat = m_LowResImageFormat; buf.Put( &header, sizeof(VTFFileHeader_t) ); if (!buf.IsValid()) return false; // Write the low-res image if (m_pLowResImageData) { int iLowResImageSize = ImageLoader::GetMemRequired( m_nLowResImageWidth, m_nLowResImageHeight, m_LowResImageFormat, false ); buf.Put( m_pLowResImageData, iLowResImageSize ); if (!buf.IsValid()) return false; } else { // If we have a non-zero image size, we better have bits! Assert((m_nLowResImageWidth == 0) || (m_nLowResImageHeight == 0)); } // Write out the image WriteImageData( buf ); return buf.IsValid(); }
/** * Save a navigation area to the opened binary stream */ void CNavArea::Save( CUtlBuffer &fileBuffer, unsigned int version ) const { // save ID fileBuffer.PutUnsignedInt( m_id ); // save attribute flags fileBuffer.PutInt( m_attributeFlags ); // save extent of area fileBuffer.Put( &m_nwCorner, 3*sizeof(float) ); fileBuffer.Put( &m_seCorner, 3*sizeof(float) ); // save heights of implicit corners fileBuffer.PutFloat( m_neZ ); fileBuffer.PutFloat( m_swZ ); // save connections to adjacent areas // in the enum order NORTH, EAST, SOUTH, WEST for( int d=0; d<NUM_DIRECTIONS; d++ ) { // save number of connections for this direction unsigned int count = m_connect[d].Count(); fileBuffer.PutUnsignedInt( count ); FOR_EACH_VEC( m_connect[d], it ) { NavConnect connect = m_connect[d][ it ]; fileBuffer.PutUnsignedInt( connect.area->m_id ); } }
// build the final pool void GetTableAndPool( CUtlVector< unsigned int > &offsets, CUtlBuffer &buffer ) { offsets.Purge(); buffer.Purge(); offsets.EnsureCapacity( m_StringMap.GetNumStrings() ); buffer.EnsureCapacity( m_nOffset ); unsigned int currentOffset = 0; for ( int i = 0; i < m_StringMap.GetNumStrings(); i++ ) { offsets.AddToTail( currentOffset ); const char *pString = m_StringMap.String( i ); buffer.Put( pString, strlen( pString ) + 1 ); currentOffset += strlen( pString ) + 1; } Assert( currentOffset == m_nOffset ); // align string pool to end on dword boundary while ( buffer.TellMaxPut() & 0x03 ) { buffer.PutChar( '\0' ); m_nOffset++; } }
//----------------------------------------------------------------------------- // Binary buffer attribute //----------------------------------------------------------------------------- bool Serialize( CUtlBuffer &buf, const CUtlBinaryBlock &src ) { int nLength = src.Length(); if ( !buf.IsText() ) { buf.PutInt( nLength ); if ( nLength != 0 ) { buf.Put( src.Get(), nLength ); } return buf.IsValid(); } // Writes out uuencoded binaries for ( int i = 0; i < nLength; ++i ) { if ( (i % 40) == 0 ) { buf.PutChar( '\n' ); } char b1 = src[i] & 0xF; char b2 = src[i] >> 4; char c1 = ( b1 <= 9 ) ? b1 + '0' : b1 - 10 + 'A'; char c2 = ( b2 <= 9 ) ? b2 + '0' : b2 - 10 + 'A'; buf.PutChar( c2 ); buf.PutChar( c1 ); } buf.PutChar( '\n' ); return buf.IsValid(); }
//----------------------------------------------------------------------------- // Get the preload data for a vvd file //----------------------------------------------------------------------------- bool GetPreloadData_VVD( const char *pFilename, CUtlBuffer &fileBufferIn, CUtlBuffer &preloadBufferOut ) { vertexFileHeader_t *pHeader = (vertexFileHeader_t *)fileBufferIn.Base(); unsigned int id = BigLong( pHeader->id ); unsigned int version = BigLong( pHeader->version ); // ensure caller's buffer is clean // caller determines preload size, via TellMaxPut() preloadBufferOut.Purge(); if ( id != MODEL_VERTEX_FILE_ID ) { // bad version Msg( "Can't preload: '%s', expecting id %d got id %d\n", pFilename, MODEL_VERTEX_FILE_ID, id ); return false; } if ( version != MODEL_VERTEX_FILE_VERSION ) { // bad version Msg( "Can't preload: '%s', expecting version %d got version %d\n", pFilename, MODEL_VERTEX_FILE_VERSION, version ); return false; } unsigned int nPreloadSize = sizeof( vertexFileHeader_t ); preloadBufferOut.Put( fileBufferIn.Base(), nPreloadSize ); return true; }
bool CBaseGameStats::SaveToFileNOW( bool bForceSyncWrite /* = false */ ) { if ( !StatsTrackingIsFullyEnabled() ) return false; // this code path is only for old format stats. Products that use new format take a different path. if ( !gamestats->UseOldFormat() ) return false; CUtlBuffer buf; buf.PutShort( GAMESTATS_FILE_VERSION ); buf.Put( s_szPseudoUniqueID, 16 ); if( ShouldTrackStandardStats() ) m_BasicStats.SaveToBuffer( buf ); else buf.PutInt( GAMESTATS_STANDARD_NOT_SAVED ); gamestats->AppendCustomDataToSaveBuffer( buf ); char fullpath[ 512 ] = { 0 }; if ( filesystem->FileExists( GetStatSaveFileName(), GAMESTATS_PATHID ) ) { filesystem->RelativePathToFullPath( GetStatSaveFileName(), GAMESTATS_PATHID, fullpath, sizeof( fullpath ) ); } else { // filename is local to game dir for Steam, so we need to prepend game dir for regular file save char gamePath[256]; engine->GetGameDir( gamePath, 256 ); Q_StripTrailingSlash( gamePath ); Q_snprintf( fullpath, sizeof( fullpath ), "%s/%s", gamePath, GetStatSaveFileName() ); Q_strlower( fullpath ); Q_FixSlashes( fullpath ); } // StatsLog( "SaveToFileNOW '%s'\n", fullpath ); if( CBGSDriver.m_bShuttingDown || bForceSyncWrite ) //write synchronously { filesystem->WriteFile( fullpath, GAMESTATS_PATHID, buf ); StatsLog( "Shut down wrote to '%s'\n", fullpath ); } else { // Allocate memory for async system to use (and free afterward!!!) size_t nBufferSize = buf.TellPut(); void *pMem = malloc(nBufferSize); CUtlBuffer statsBuffer( pMem, nBufferSize ); statsBuffer.Put( buf.Base(), nBufferSize ); // Write data async filesystem->AsyncWrite( fullpath, statsBuffer.Base(), statsBuffer.TellPut(), true, false ); } return true; }
//----------------------------------------------------------------------------- // Purpose: Empty the output buffer --- called whenever buffer fills up. // Input : boolean - //----------------------------------------------------------------------------- METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo) { JPEGDestinationManager_t *dest = (JPEGDestinationManager_t *)cinfo->dest; CUtlBuffer *buf = dest->pBuffer; buf->Put(dest->buffer, OUTPUT_BUF_SIZE); dest->pub.next_output_byte = dest->buffer; dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; return TRUE; }
//----------------------------------------------------------------------------- // Purpose: Terminate destination --- called by jpeg_finish_compress // after all data has been written. Usually needs to flush buffer. // // NB: *not* called by jpeg_abort or jpeg_destroy; surrounding // application must deal with any cleanup that should happen even // for error exit. //----------------------------------------------------------------------------- void term_destination( j_compress_ptr cinfo ) { JPEGDestinationManager_t *dest = (JPEGDestinationManager_t *) cinfo->dest; size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; CUtlBuffer *buf = dest->pBuffer; /* Write any data remaining in the buffer */ if (datacount > 0) { buf->Put( dest->buffer, datacount ); } }
void CCompiledKeyValuesWriter::WriteStringTable( CUtlBuffer& buf ) { int i; CUtlVector< int > offsets; CUtlBuffer stringBuffer; offsets.AddToTail( stringBuffer.TellPut() ); stringBuffer.PutString( "" ); // save all the rest int c = m_StringTable.GetNumStrings(); for ( i = 1; i < c; i++) { offsets.AddToTail( stringBuffer.TellPut() ); stringBuffer.PutString( m_StringTable.String( i ) ); } buf.Put( offsets.Base(), offsets.Count() * sizeof( int ) ); buf.PutInt( stringBuffer.TellPut() ); buf.Put( stringBuffer.Base(), stringBuffer.TellPut() ); }
void CCompiledKeyValuesWriter::WriteFile( char const *outfile ) { CUtlBuffer buf; // Write the data file out KVHeader_t header; header.fileid = COMPILED_KEYVALUES_ID; header.version = COMPILED_KEYVALUES_VERSION; header.numStrings = m_StringTable.GetNumStrings(); buf.Put( &header, sizeof( header ) ); WriteStringTable( buf ); WriteData( buf ); WriteFiles( buf ); g_pFullFileSystem->WriteFile( outfile, NULL, buf ); }
/// store the directory void PlaceDirectory::Save( CUtlBuffer &fileBuffer ) { // store number of entries in directory IndexType count = (IndexType)m_directory.Count(); fileBuffer.PutUnsignedShort( count ); // store entries for( int i=0; i<m_directory.Count(); ++i ) { const char *placeName = TheNavMesh->PlaceToName( m_directory[i] ); // store string length followed by string itself unsigned short len = (unsigned short)(strlen( placeName ) + 1); fileBuffer.PutUnsignedShort( len ); fileBuffer.Put( placeName, len ); } fileBuffer.PutUnsignedChar( m_hasUnnamedAreas ); }
bool Serialize( CUtlBuffer &buf, const VMatrix &src ) { if ( buf.IsText() ) { buf.Printf( "\n" ); SerializeFloats( buf, 4, src[0] ); buf.Printf( "\n" ); SerializeFloats( buf, 4, src[1] ); buf.Printf( "\n" ); SerializeFloats( buf, 4, src[2] ); buf.Printf( "\n" ); SerializeFloats( buf, 4, src[3] ); buf.Printf( "\n" ); } else { buf.Put( &src, sizeof(VMatrix) ); } return buf.IsValid(); }
void CNetworkStringTable::WriteStringTable( CUtlBuffer& buf ) { int numstrings = GetNumStrings(); buf.PutInt( numstrings ); for ( int i = 0 ; i < numstrings; i++ ) { buf.PutString( GetString( i ) ); int userDataSize; const void *pUserData = GetStringUserData( i, &userDataSize ); if ( userDataSize > 0 ) { buf.PutChar( 1 ); buf.PutShort( (short)userDataSize ); buf.Put( pUserData, userDataSize ); } else { buf.PutChar( 0 ); } } }
//----------------------------------------------------------------------------- // Serialization of image data //----------------------------------------------------------------------------- bool CVTFTexture::WriteImageData( CUtlBuffer &buf ) { // NOTE: We load the bits this way because we store the bits in memory // differently that the way they are stored on disk; we store on disk // differently so we can only load up // NOTE: The smallest mip levels are stored first!! for (int iMip = m_nMipCount; --iMip >= 0; ) { int iMipSize = ComputeMipSize( iMip ); for (int iFrame = 0; iFrame < m_nFrameCount; ++iFrame) { for (int iFace = 0; iFace < m_nFaceCount; ++iFace) { unsigned char *pMipBits = ImageData( iFrame, iFace, iMip ); buf.Put( pMipBits, iMipSize ); } } } return buf.IsValid(); }
CMacroTextureData* LoadMacroTextureFile( const char *pFilename ) { FileHandle_t hFile = g_pFileSystem->Open( pFilename, "rb" ); if ( hFile == FILESYSTEM_INVALID_HANDLE ) return NULL; // Read the file in. CUtlVector<char> tempData; tempData.SetSize( g_pFileSystem->Size( hFile ) ); g_pFileSystem->Read( tempData.Base(), tempData.Count(), hFile ); g_pFileSystem->Close( hFile ); // Now feed the data into a CUtlBuffer (great...) CUtlBuffer buf; buf.Put( tempData.Base(), tempData.Count() ); // Now make a texture out of it. IVTFTexture *pTex = CreateVTFTexture(); if ( !pTex->Unserialize( buf ) ) Error( "IVTFTexture::Unserialize( %s ) failed.", pFilename ); pTex->ConvertImageFormat( IMAGE_FORMAT_RGBA8888, false ); // Get it in a format we like. // Now convert to a CMacroTextureData. CMacroTextureData *pData = new CMacroTextureData; pData->m_Width = pTex->Width(); pData->m_Height = pTex->Height(); pData->m_ImageData.EnsureCapacity( pData->m_Width * pData->m_Height * 4 ); memcpy( pData->m_ImageData.Base(), pTex->ImageData(), pData->m_Width * pData->m_Height * 4 ); DestroyVTFTexture( pTex ); Msg( "-- LoadMacroTextureFile: %s\n", pFilename ); return pData; }
//----------------------------------------------------------------------------- // Get the preload data for a vtx file //----------------------------------------------------------------------------- bool GetPreloadData_VTX( const char *pFilename, CUtlBuffer &fileBufferIn, CUtlBuffer &preloadBufferOut ) { OptimizedModel::FileHeader_t *pHeader = (OptimizedModel::FileHeader_t *)fileBufferIn.Base(); unsigned int version = BigLong( pHeader->version ); // ensure caller's buffer is clean // caller determines preload size, via TellMaxPut() preloadBufferOut.Purge(); if ( version != OPTIMIZED_MODEL_FILE_VERSION ) { // bad version Msg( "Can't preload: '%s', expecting version %d got version %d\n", pFilename, OPTIMIZED_MODEL_FILE_VERSION, version ); return false; } unsigned int nPreloadSize = sizeof( OptimizedModel::FileHeader_t ); preloadBufferOut.Put( fileBufferIn.Base(), nPreloadSize ); return true; }
//----------------------------------------------------------------------------- // Get the preload data for a vhv file //----------------------------------------------------------------------------- bool GetPreloadData_VHV( const char *pFilename, CUtlBuffer &fileBufferIn, CUtlBuffer &preloadBufferOut ) { HardwareVerts::FileHeader_t *pHeader = (HardwareVerts::FileHeader_t *)fileBufferIn.Base(); unsigned int version = BigLong( pHeader->m_nVersion ); // ensure caller's buffer is clean // caller determines preload size, via TellMaxPut() preloadBufferOut.Purge(); if ( version != VHV_VERSION ) { // bad version Msg( "Can't preload: '%s', expecting version %d got version %d\n", pFilename, VHV_VERSION, version ); return false; } unsigned int nPreloadSize = sizeof( HardwareVerts::FileHeader_t ); preloadBufferOut.Put( fileBufferIn.Base(), nPreloadSize ); return true; }
//----------------------------------------------------------------------------- // A Scene image file contains all the compiled .XCD //----------------------------------------------------------------------------- bool CSceneImage::CreateSceneImageFile( CUtlBuffer &targetBuffer, char const *pchModPath, bool bLittleEndian, bool bQuiet, ISceneCompileStatus *pStatus ) { CUtlVector<fileList_t> vcdFileList; CUtlSymbolTable vcdSymbolTable( 0, 32, true ); Msg( "\n" ); // get all the VCD files according to the seacrh paths char searchPaths[512]; g_pFullFileSystem->GetSearchPath( "GAME", false, searchPaths, sizeof( searchPaths ) ); char *pPath = strtok( searchPaths, ";" ); while ( pPath ) { int currentCount = vcdFileList.Count(); char szPath[MAX_PATH]; V_ComposeFileName( pPath, "scenes/*.vcd", szPath, sizeof( szPath ) ); scriptlib->FindFiles( szPath, true, vcdFileList ); Msg( "Scenes: Searching '%s' - Found %d scenes.\n", szPath, vcdFileList.Count() - currentCount ); pPath = strtok( NULL, ";" ); } if ( !vcdFileList.Count() ) { Msg( "Scenes: No Scene Files found!\n" ); return false; } // iterate and convert all the VCD files bool bGameIsTF = V_stristr( pchModPath, "\\tf" ) != NULL; for ( int i=0; i<vcdFileList.Count(); i++ ) { const char *pFilename = vcdFileList[i].fileName.String(); const char *pSceneName = V_stristr( pFilename, "scenes\\" ); if ( !pSceneName ) { continue; } if ( !bLittleEndian && bGameIsTF && V_stristr( pSceneName, "high\\" ) ) { continue; } // process files in order they would be found in search paths // i.e. skipping later processed files that match an earlier conversion UtlSymId_t symbol = vcdSymbolTable.Find( pSceneName ); if ( symbol == UTL_INVAL_SYMBOL ) { vcdSymbolTable.AddString( pSceneName ); pStatus->UpdateStatus( pFilename, bQuiet, i, vcdFileList.Count() ); if ( !CreateTargetFile_VCD( pFilename, "", false, bLittleEndian ) ) { Error( "CreateSceneImageFile: Failed on '%s' conversion!\n", pFilename ); } } } if ( !g_SceneFiles.Count() ) { // nothing to do return true; } Msg( "Scenes: Finalizing %d unique scenes.\n", g_SceneFiles.Count() ); // get the string pool CUtlVector< unsigned int > stringOffsets; CUtlBuffer stringPool; g_ChoreoStringPool.GetTableAndPool( stringOffsets, stringPool ); if ( !bQuiet ) { Msg( "Scenes: String Table: %d bytes\n", stringOffsets.Count() * sizeof( int ) ); Msg( "Scenes: String Pool: %d bytes\n", stringPool.TellMaxPut() ); } // first header, then lookup table, then string pool blob int stringPoolStart = sizeof( SceneImageHeader_t ) + stringOffsets.Count() * sizeof( int ); // then directory int sceneEntryStart = stringPoolStart + stringPool.TellMaxPut(); // then variable sized summaries int sceneSummaryStart = sceneEntryStart + g_SceneFiles.Count() * sizeof( SceneImageEntry_t ); // then variable sized compiled binary scene data int sceneDataStart = 0; // construct header SceneImageHeader_t imageHeader = { 0 }; imageHeader.nId = SCENE_IMAGE_ID; imageHeader.nVersion = SCENE_IMAGE_VERSION; imageHeader.nNumScenes = g_SceneFiles.Count(); imageHeader.nNumStrings = stringOffsets.Count(); imageHeader.nSceneEntryOffset = sceneEntryStart; if ( !bLittleEndian ) { imageHeader.nId = BigLong( imageHeader.nId ); imageHeader.nVersion = BigLong( imageHeader.nVersion ); imageHeader.nNumScenes = BigLong( imageHeader.nNumScenes ); imageHeader.nNumStrings = BigLong( imageHeader.nNumStrings ); imageHeader.nSceneEntryOffset = BigLong( imageHeader.nSceneEntryOffset ); } targetBuffer.Put( &imageHeader, sizeof( imageHeader ) ); // header is immediately followed by string table and pool for ( int i = 0; i < stringOffsets.Count(); i++ ) { unsigned int offset = stringPoolStart + stringOffsets[i]; if ( !bLittleEndian ) { offset = BigLong( offset ); } targetBuffer.PutInt( offset ); } Assert( stringPoolStart == targetBuffer.TellMaxPut() ); targetBuffer.Put( stringPool.Base(), stringPool.TellMaxPut() ); // construct directory CUtlSortVector< SceneImageEntry_t, CSceneImageEntryLessFunc > imageDirectory; imageDirectory.EnsureCapacity( g_SceneFiles.Count() ); // build directory // directory is linear sorted by filename checksum for later binary search for ( int i = 0; i < g_SceneFiles.Count(); i++ ) { SceneImageEntry_t imageEntry = { 0 }; // name needs to be normalized for determinstic later CRC name calc // calc crc based on scenes\anydir\anyscene.vcd char szCleanName[MAX_PATH]; V_strncpy( szCleanName, g_SceneFiles[i].fileName.String(), sizeof( szCleanName ) ); V_strlower( szCleanName ); V_FixSlashes( szCleanName ); char *pName = V_stristr( szCleanName, "scenes\\" ); if ( !pName ) { // must have scenes\ in filename Error( "CreateSceneImageFile: Unexpected lack of scenes prefix on %s\n", g_SceneFiles[i].fileName.String() ); } CRC32_t crcFilename = CRC32_ProcessSingleBuffer( pName, strlen( pName ) ); imageEntry.crcFilename = crcFilename; // temp store an index to its file, fixup later, necessary to access post sort imageEntry.nDataOffset = i; if ( imageDirectory.Find( imageEntry ) != imageDirectory.InvalidIndex() ) { // filename checksums must be unique or runtime binary search would be bogus Error( "CreateSceneImageFile: Unexpected filename checksum collision!\n" ); } imageDirectory.Insert( imageEntry ); } // determine sort order and start of data after dynamic summaries CUtlVector< int > writeOrder; writeOrder.EnsureCapacity( g_SceneFiles.Count() ); sceneDataStart = sceneSummaryStart; for ( int i = 0; i < imageDirectory.Count(); i++ ) { // reclaim offset, indicates write order of scene file int iScene = imageDirectory[i].nDataOffset; writeOrder.AddToTail( iScene ); // march past each variable sized summary to determine start of scene data int numSounds = g_SceneFiles[iScene].soundList.Count(); sceneDataStart += sizeof( SceneImageSummary_t ) + ( numSounds - 1 ) * sizeof( int ); } // finalize and write directory Assert( sceneEntryStart == targetBuffer.TellMaxPut() ); int nSummaryOffset = sceneSummaryStart; int nDataOffset = sceneDataStart; for ( int i = 0; i < imageDirectory.Count(); i++ ) { int iScene = writeOrder[i]; imageDirectory[i].nDataOffset = nDataOffset; imageDirectory[i].nDataLength = g_SceneFiles[iScene].compiledBuffer.TellMaxPut(); imageDirectory[i].nSceneSummaryOffset = nSummaryOffset; if ( !bLittleEndian ) { imageDirectory[i].crcFilename = BigLong( imageDirectory[i].crcFilename ); imageDirectory[i].nDataOffset = BigLong( imageDirectory[i].nDataOffset ); imageDirectory[i].nDataLength = BigLong( imageDirectory[i].nDataLength ); imageDirectory[i].nSceneSummaryOffset = BigLong( imageDirectory[i].nSceneSummaryOffset ); } targetBuffer.Put( &imageDirectory[i], sizeof( SceneImageEntry_t ) ); int numSounds = g_SceneFiles[iScene].soundList.Count(); nSummaryOffset += sizeof( SceneImageSummary_t ) + (numSounds - 1) * sizeof( int ); nDataOffset += g_SceneFiles[iScene].compiledBuffer.TellMaxPut(); } // finalize and write summaries Assert( sceneSummaryStart == targetBuffer.TellMaxPut() ); for ( int i = 0; i < imageDirectory.Count(); i++ ) { int iScene = writeOrder[i]; int msecs = g_SceneFiles[iScene].msecs; int soundCount = g_SceneFiles[iScene].soundList.Count(); if ( !bLittleEndian ) { msecs = BigLong( msecs ); soundCount = BigLong( soundCount ); } targetBuffer.PutInt( msecs ); targetBuffer.PutInt( soundCount ); for ( int j = 0; j < g_SceneFiles[iScene].soundList.Count(); j++ ) { int soundId = g_SceneFiles[iScene].soundList[j]; if ( !bLittleEndian ) { soundId = BigLong( soundId ); } targetBuffer.PutInt( soundId ); } } // finalize and write data Assert( sceneDataStart == targetBuffer.TellMaxPut() ); for ( int i = 0; i < imageDirectory.Count(); i++ ) { int iScene = writeOrder[i]; targetBuffer.Put( g_SceneFiles[iScene].compiledBuffer.Base(), g_SceneFiles[iScene].compiledBuffer.TellMaxPut() ); } if ( !bQuiet ) { Msg( "Scenes: Final size: %.2f MB\n", targetBuffer.TellMaxPut() / (1024.0f * 1024.0f ) ); } // cleanup g_SceneFiles.Purge(); return true; }
//================================= // Add the current snapshot to the db //================================= void AddSnapshotToDatabase( void ) { char szSnapshot[1024]; //Only update the prices and close. if ( g_bWeeklyUpdate == true ) { weeklyprice_t prices; CUtlBuffer buf; prices.iVersion = PRICE_BLOB_VERSION; for ( int i = 1; i < WEAPON_MAX; i ++ ) { Q_snprintf( szSnapshot, sizeof( szSnapshot ), "update weapon_info set current_price=%d, purchases_thisweek=0 where WeaponID=%d", g_iNewWeaponPrices[i], i ); int retcode = mysql->Execute( szSnapshot ); if ( retcode != 0 ) { Msg( "Query:\n %s\n failed - Retcode: %d\n", szSnapshot, retcode ); } prices.iPreviousPrice[i] = g_Weapons[i].iCurrentPrice; prices.iCurrentPrice[i] = g_iNewWeaponPrices[i]; } buf.Put( &prices, sizeof( weeklyprice_t ) ); if ( g_pFullFileSystem ) { g_pFullFileSystem->WriteFile( PRICE_BLOB_NAME, NULL, buf ); } Q_snprintf( szSnapshot, sizeof( szSnapshot ), "update reset_counter set counter=counter+1" ); int retcode = mysql->Execute( szSnapshot ); if ( retcode != 0 ) { Msg( "Query:\n %s\n failed - Retcode: %d\n", szSnapshot, retcode ); } return; } g_iCounter++; for ( int i = 1; i < WEAPON_MAX; i ++ ) { Q_snprintf( szSnapshot, sizeof( szSnapshot ), "Insert into purchases_pricing ( snapshot, dt2, weapon_id, purchases, current_price, projected_price, reset_counter ) values ( \"%d_%d\", NOW(), %d, %d, %d, %d, %d );", g_iCounter, i, i, g_iPurchaseDelta[i], g_Weapons[i].iCurrentPrice, g_iNewWeaponPrices[i], g_iResetCounter ); int retcode = mysql->Execute( szSnapshot ); if ( retcode != 0 ) { Msg( "Query:\n %s\n failed - Retcode: %d\n", szSnapshot, retcode ); } } Q_snprintf( szSnapshot, sizeof( szSnapshot ), "update snapshot_counter set counter=%d", g_iCounter ); int retcode = mysql->Execute( szSnapshot ); if ( retcode != 0 ) { Msg( "Query:\n %s\n failed - Retcode: %d\n", szSnapshot, retcode ); } for ( int i = 1; i < WEAPON_MAX; i ++ ) { Q_snprintf( szSnapshot, sizeof( szSnapshot ), "update weapon_info set purchases=%d, purchases_thisweek=purchases_thisweek+%d where WeaponID=%d", g_iCurrentWeaponPurchases[i], g_iPurchaseDelta[i], i ); int retcode = mysql->Execute( szSnapshot ); if ( retcode != 0 ) { Msg( "Query:\n %s\n failed - Retcode: %d\n", szSnapshot, retcode ); } } Msg( "Added new snapshot to database\n", szSnapshot, retcode ); }
//----------------------------------------------------------------------------- // Rebuilds all of a MDL's components. //----------------------------------------------------------------------------- static bool GenerateModelFiles( const char *pMdlFilename ) { CUtlBuffer tempBuffer; int fileSize; int paddedSize; int swappedSize; // .mdl CUtlBuffer mdlBuffer; if ( !scriptlib->ReadFileToBuffer( pMdlFilename, mdlBuffer ) ) { return false; } if ( !Studio_ConvertStudioHdrToNewVersion( (studiohdr_t *)mdlBuffer.Base() )) { Msg("%s needs to be recompiled\n", pMdlFilename ); } // .vtx char szVtxFilename[MAX_PATH]; V_StripExtension( pMdlFilename, szVtxFilename, sizeof( szVtxFilename ) ); V_strncat( szVtxFilename, ".dx90.vtx", sizeof( szVtxFilename ) ); CUtlBuffer vtxBuffer; bool bHasVtx = ReadFileToBuffer( szVtxFilename, vtxBuffer, false, true ); // .vvd char szVvdFilename[MAX_PATH]; V_StripExtension( pMdlFilename, szVvdFilename, sizeof( szVvdFilename ) ); V_strncat( szVvdFilename, ".vvd", sizeof( szVvdFilename ) ); CUtlBuffer vvdBuffer; bool bHasVvd = ReadFileToBuffer( szVvdFilename, vvdBuffer, false, true ); if ( bHasVtx != bHasVvd ) { // paired resources, either mandates the other return false; } // a .mdl file that has .vtx/.vvd gets re-processed to cull lod data if ( bHasVtx && bHasVvd ) { // cull lod if needed IMdlStripInfo *pStripInfo = NULL; bool bResult = mdllib->StripModelBuffers( mdlBuffer, vvdBuffer, vtxBuffer, &pStripInfo ); if ( !bResult ) { return false; } if ( pStripInfo ) { // .vsi CUtlBuffer vsiBuffer; pStripInfo->Serialize( vsiBuffer ); pStripInfo->DeleteThis(); // save strip info for later processing char szVsiFilename[MAX_PATH]; V_StripExtension( pMdlFilename, szVsiFilename, sizeof( szVsiFilename ) ); V_strncat( szVsiFilename, ".vsi", sizeof( szVsiFilename ) ); WriteBufferToFile( szVsiFilename, vsiBuffer, false, WRITE_TO_DISK_ALWAYS ); } } // .ani processing may further update .mdl buffer char szAniFilename[MAX_PATH]; V_StripExtension( pMdlFilename, szAniFilename, sizeof( szAniFilename ) ); V_strncat( szAniFilename, ".ani", sizeof( szAniFilename ) ); CUtlBuffer aniBuffer; bool bHasAni = ReadFileToBuffer( szAniFilename, aniBuffer, false, true ); if ( bHasAni ) { // Some vestigal .ani files exist in the tree, only process valid .ani if ( ((studiohdr_t*)mdlBuffer.Base())->numanimblocks != 0 ) { // .ani processing modifies .mdl buffer fileSize = aniBuffer.TellPut(); paddedSize = fileSize + BYTESWAP_ALIGNMENT_PADDING; aniBuffer.EnsureCapacity( paddedSize ); tempBuffer.EnsureCapacity( paddedSize ); V_StripExtension( pMdlFilename, szAniFilename, sizeof( szAniFilename ) ); V_strncat( szAniFilename, ".360.ani", sizeof( szAniFilename ) ); swappedSize = StudioByteSwap::ByteswapStudioFile( szAniFilename, tempBuffer.Base(), aniBuffer.PeekGet(), fileSize, (studiohdr_t*)mdlBuffer.Base(), CompressFunc ); if ( swappedSize > 0 ) { // .ani buffer is replaced with swapped data aniBuffer.Purge(); aniBuffer.Put( tempBuffer.Base(), swappedSize ); WriteBufferToFile( szAniFilename, aniBuffer, false, WRITE_TO_DISK_ALWAYS ); } else { return false; } } } // .phy char szPhyFilename[MAX_PATH]; V_StripExtension( pMdlFilename, szPhyFilename, sizeof( szPhyFilename ) ); V_strncat( szPhyFilename, ".phy", sizeof( szPhyFilename ) ); CUtlBuffer phyBuffer; bool bHasPhy = ReadFileToBuffer( szPhyFilename, phyBuffer, false, true ); if ( bHasPhy ) { fileSize = phyBuffer.TellPut(); paddedSize = fileSize + BYTESWAP_ALIGNMENT_PADDING; phyBuffer.EnsureCapacity( paddedSize ); tempBuffer.EnsureCapacity( paddedSize ); V_StripExtension( pMdlFilename, szPhyFilename, sizeof( szPhyFilename ) ); V_strncat( szPhyFilename, ".360.phy", sizeof( szPhyFilename ) ); swappedSize = StudioByteSwap::ByteswapStudioFile( szPhyFilename, tempBuffer.Base(), phyBuffer.PeekGet(), fileSize, (studiohdr_t*)mdlBuffer.Base(), CompressFunc ); if ( swappedSize > 0 ) { // .phy buffer is replaced with swapped data phyBuffer.Purge(); phyBuffer.Put( tempBuffer.Base(), swappedSize ); WriteBufferToFile( szPhyFilename, phyBuffer, false, WRITE_TO_DISK_ALWAYS ); } else { return false; } } if ( bHasVtx ) { fileSize = vtxBuffer.TellPut(); paddedSize = fileSize + BYTESWAP_ALIGNMENT_PADDING; vtxBuffer.EnsureCapacity( paddedSize ); tempBuffer.EnsureCapacity( paddedSize ); V_StripExtension( pMdlFilename, szVtxFilename, sizeof( szVtxFilename ) ); V_strncat( szVtxFilename, ".dx90.360.vtx", sizeof( szVtxFilename ) ); swappedSize = StudioByteSwap::ByteswapStudioFile( szVtxFilename, tempBuffer.Base(), vtxBuffer.PeekGet(), fileSize, (studiohdr_t*)mdlBuffer.Base(), CompressFunc ); if ( swappedSize > 0 ) { // .vtx buffer is replaced with swapped data vtxBuffer.Purge(); vtxBuffer.Put( tempBuffer.Base(), swappedSize ); WriteBufferToFile( szVtxFilename, vtxBuffer, false, WRITE_TO_DISK_ALWAYS ); } else { return false; } } if ( bHasVvd ) { fileSize = vvdBuffer.TellPut(); paddedSize = fileSize + BYTESWAP_ALIGNMENT_PADDING; vvdBuffer.EnsureCapacity( paddedSize ); tempBuffer.EnsureCapacity( paddedSize ); V_StripExtension( pMdlFilename, szVvdFilename, sizeof( szVvdFilename ) ); V_strncat( szVvdFilename, ".360.vvd", sizeof( szVvdFilename ) ); swappedSize = StudioByteSwap::ByteswapStudioFile( szVvdFilename, tempBuffer.Base(), vvdBuffer.PeekGet(), fileSize, (studiohdr_t*)mdlBuffer.Base(), CompressFunc ); if ( swappedSize > 0 ) { // .vvd buffer is replaced with swapped data vvdBuffer.Purge(); vvdBuffer.Put( tempBuffer.Base(), swappedSize ); WriteBufferToFile( szVvdFilename, vvdBuffer, false, WRITE_TO_DISK_ALWAYS ); } else { return false; } } // swap and write final .mdl fileSize = mdlBuffer.TellPut(); paddedSize = fileSize + BYTESWAP_ALIGNMENT_PADDING; mdlBuffer.EnsureCapacity( paddedSize ); tempBuffer.EnsureCapacity( paddedSize ); char szMdlFilename[MAX_PATH]; V_StripExtension( pMdlFilename, szMdlFilename, sizeof( szMdlFilename ) ); V_strncat( szMdlFilename, ".360.mdl", sizeof( szMdlFilename ) ); swappedSize = StudioByteSwap::ByteswapStudioFile( szMdlFilename, tempBuffer.Base(), mdlBuffer.PeekGet(), fileSize, NULL, CompressFunc ); if ( swappedSize > 0 ) { // .mdl buffer is replaced with swapped data mdlBuffer.Purge(); mdlBuffer.Put( tempBuffer.Base(), swappedSize ); WriteBufferToFile( szMdlFilename, mdlBuffer, false, WRITE_TO_DISK_ALWAYS ); } else { return false; } return true; }
void CSentence::SaveToBuffer( CUtlBuffer& buf ) { int i, j; buf.Printf( "VERSION 1.0\n" ); buf.Printf( "PLAINTEXT\n" ); buf.Printf( "{\n" ); buf.Printf( "%s\n", GetText() ); buf.Printf( "}\n" ); buf.Printf( "WORDS\n" ); buf.Printf( "{\n" ); for ( i = 0; i < m_Words.Size(); i++ ) { CWordTag *word = m_Words[ i ]; Assert( word ); buf.Printf( "WORD %s %.3f %.3f\n", word->m_pszWord[ 0 ] ? word->m_pszWord : "???", word->m_flStartTime, word->m_flEndTime ); buf.Printf( "{\n" ); for ( j = 0; j < word->m_Phonemes.Size(); j++ ) { CPhonemeTag *phoneme = word->m_Phonemes[ j ]; Assert( phoneme ); buf.Printf( "%i %s %.3f %.3f %.3f\n", phoneme->m_nPhonemeCode, phoneme->m_szPhoneme[ 0 ] ? phoneme->m_szPhoneme : "???", phoneme->m_flStartTime, phoneme->m_flEndTime, phoneme->m_flVolume ); } buf.Printf( "}\n" ); } buf.Printf( "}\n" ); buf.Printf( "EMPHASIS\n" ); buf.Printf( "{\n" ); int c = m_EmphasisSamples.Count(); for ( i = 0; i < c; i++ ) { CEmphasisSample *sample = &m_EmphasisSamples[ i ]; Assert( sample ); buf.Printf( "%f %f\n", sample->time, sample->value ); } buf.Printf( "}\n" ); buf.Printf( "CLOSECAPTION\n" ); buf.Printf( "{\n" ); for ( int l = 0; l < CC_NUM_LANGUAGES; l++ ) { int count = GetCloseCaptionPhraseCount( l ); if ( count == 0 && l == CC_ENGLISH ) { SetCloseCaptionFromText( l ); count = GetCloseCaptionPhraseCount( l ); } if ( count <= 0 ) continue; buf.Printf( "%s\n", CCloseCaptionPhrase::NameForLanguage( l ) ); buf.Printf( "{\n" ); for ( int j = 0 ; j < count; j++ ) { CCloseCaptionPhrase *phrase = GetCloseCaptionPhrase( l, j ); Assert( phrase ); int len = wcslen( phrase->GetStream() ); len <<= 1; // double because it's a wchar_t buf.Printf( "PHRASE unicode %i ", len ); buf.Put( phrase->GetStream(), len ); buf.Printf( " %.3f %.3f\n", phrase->GetStartTime(), phrase->GetEndTime() ); } buf.Printf( "}\n" ); } buf.Printf( "}\n" ); buf.Printf( "OPTIONS\n" ); buf.Printf( "{\n" ); buf.Printf( "voice_duck %d\n", GetVoiceDuck() ? 1 : 0 ); buf.Printf( "}\n" ); }
void CCompileCaptionsApp::CompileCaptionFile( char const *infile, char const *outfile ) { StringIndex_t maxindex = (StringIndex_t)-1; int maxunicodesize = 0; int totalsize = 0; int c = 0; int curblock = 0; int usedBytes = 0; int blockSize = MAX_BLOCK_SIZE; int freeSpace = 0; CUtlVector< CaptionLookup_t > directory; CUtlBuffer data; CUtlRBTree< unsigned int > hashcollision( 0, 0, DefLessFunc( unsigned int ) ); for ( StringIndex_t i = g_pVGuiLocalize->GetFirstStringIndex(); i != INVALID_LOCALIZE_STRING_INDEX; i = g_pVGuiLocalize->GetNextStringIndex( i ), ++c ) { char const *entryName = g_pVGuiLocalize->GetNameByIndex( i ); CaptionLookup_t entry; entry.SetHash( entryName ); // vprint( 0, "%d / %d: %s == %u\n", c, i, g_pVGuiLocalize->GetNameByIndex( i ), entry.hash ); if ( hashcollision.Find( entry.hash ) != hashcollision.InvalidIndex() ) { Error( "Hash name collision on %s!!!\n", g_pVGuiLocalize->GetNameByIndex( i ) ); } hashcollision.Insert( entry.hash ); const wchar_t *text = g_pVGuiLocalize->GetValueByIndex( i ); if ( verbose ) { vprint( 0, "Processing: '%30.30s' = '%S'\n", entryName, text ); } int len = text ? ( wcslen( text ) + 1 ) * sizeof( short ) : 0; if ( len > maxunicodesize ) { maxindex = i; maxunicodesize = len; } if ( len > blockSize ) { Error( "Caption text file '%s' contains a single caption '%s' of %d bytes (%d is max), change MAX_BLOCK_SIZE in captioncompiler.h to fix!!!\n", g_pVGuiLocalize->GetNameByIndex( i ), entryName, len, blockSize ); } totalsize += len; if ( usedBytes + len >= blockSize ) { ++curblock; int leftover = ( blockSize - usedBytes ); totalsize += leftover; freeSpace += leftover; while ( --leftover >= 0 ) { data.PutChar( 0 ); } usedBytes = len; entry.offset = 0; data.Put( (const void *)text, len ); } else { entry.offset = usedBytes; usedBytes += len; data.Put( (const void *)text, len ); } entry.length = len; entry.blockNum = curblock; directory.AddToTail( entry ); } int leftover = ( blockSize - usedBytes ); totalsize += leftover; freeSpace += leftover; while ( --leftover >= 0 ) { data.PutChar( 0 ); } vprint( 0, "Found %i strings in '%s'\n", c, infile ); if ( maxindex != INVALID_LOCALIZE_STRING_INDEX ) { vprint( 0, "Longest string '%s' = (%i) bytes average(%.3f)\n%", g_pVGuiLocalize->GetNameByIndex( maxindex ), maxunicodesize, (float)totalsize/(float)c ); } vprint( 0, "%d blocks (%d bytes each), %d bytes wasted (%.3f per block average), total bytes %d\n", curblock + 1, blockSize, freeSpace, (float)freeSpace/(float)( curblock + 1 ), totalsize ); vprint( 0, "directory size %d entries, %d bytes, data size %d bytes\n", directory.Count(), directory.Count() * sizeof( CaptionLookup_t ), data.TellPut() ); CompiledCaptionHeader_t header; header.magic = COMPILED_CAPTION_FILEID; header.version = COMPILED_CAPTION_VERSION; header.numblocks = curblock + 1; header.blocksize = blockSize; header.directorysize = directory.Count(); header.dataoffset = 0; // Now write the outfile CUtlBuffer out; out.Put( &header, sizeof( header ) ); out.Put( directory.Base(), directory.Count() * sizeof( CaptionLookup_t ) ); int curOffset = out.TellPut(); // Round it up to the next 512 byte boundary int nBytesDestBuffer = AlignValue( curOffset, 512 ); // align to HD sector int nPadding = nBytesDestBuffer - curOffset; while ( --nPadding >= 0 ) { out.PutChar( 0 ); } out.Put( data.Base(), data.TellPut() ); // Write out a corrected header header.dataoffset = nBytesDestBuffer; int savePos = out.TellPut(); out.SeekPut( CUtlBuffer::SEEK_HEAD, 0 ); out.Put( &header, sizeof( header ) ); out.SeekPut( CUtlBuffer::SEEK_HEAD, savePos ); g_pFullFileSystem->WriteFile( outfile, NULL, out ); // Jeep: this function no longer exisits /*if ( bX360 ) { UpdateOrCreateCaptionFile_X360( g_pFullFileSystem, outfile, NULL, true ); }*/ }
//----------------------------------------------------------------------------- // Converts a buffer from a CRLF buffer to a CR buffer (and back) // Returns false if no conversion was necessary (and outBuf is left untouched) // If the conversion occurs, outBuf will be cleared. //----------------------------------------------------------------------------- bool CUtlBuffer::ConvertCRLF( CUtlBuffer &outBuf ) { if ( !IsText() || !outBuf.IsText() ) return false; if ( ContainsCRLF() == outBuf.ContainsCRLF() ) return false; int nInCount = TellMaxPut(); outBuf.Purge(); outBuf.EnsureCapacity( nInCount ); bool bFromCRLF = ContainsCRLF(); // Start reading from the beginning int nGet = TellGet(); int nPut = TellPut(); int nGetDelta = 0; int nPutDelta = 0; const char *pBase = (const char*)Base(); int nCurrGet = 0; while ( nCurrGet < nInCount ) { const char *pCurr = &pBase[nCurrGet]; if ( bFromCRLF ) { const char *pNext = Q_strnistr( pCurr, "\r\n", nInCount - nCurrGet ); if ( !pNext ) { outBuf.Put( pCurr, nInCount - nCurrGet ); break; } int nBytes = (size_t)pNext - (size_t)pCurr; outBuf.Put( pCurr, nBytes ); outBuf.PutChar( '\n' ); nCurrGet += nBytes + 2; if ( nGet >= nCurrGet - 1 ) { --nGetDelta; } if ( nPut >= nCurrGet - 1 ) { --nPutDelta; } } else { const char *pNext = Q_strnchr( pCurr, '\n', nInCount - nCurrGet ); if ( !pNext ) { outBuf.Put( pCurr, nInCount - nCurrGet ); break; } int nBytes = (size_t)pNext - (size_t)pCurr; outBuf.Put( pCurr, nBytes ); outBuf.PutChar( '\r' ); outBuf.PutChar( '\n' ); nCurrGet += nBytes + 1; if ( nGet >= nCurrGet ) { ++nGetDelta; } if ( nPut >= nCurrGet ) { ++nPutDelta; } } } Assert( nPut + nPutDelta <= outBuf.TellMaxPut() ); outBuf.SeekGet( SEEK_HEAD, nGet + nGetDelta ); outBuf.SeekPut( SEEK_HEAD, nPut + nPutDelta ); return true; }
void Disp_BuildVirtualMesh( int contentsMask ) { CUtlVector<CPhysCollide *> virtualMeshes; virtualMeshes.EnsureCount( g_CoreDispInfos.Count() ); for ( int i = 0; i < g_CoreDispInfos.Count(); i++ ) { CCoreDispInfo *pDispInfo = g_CoreDispInfos[ i ]; mapdispinfo_t *pMapDisp = &mapdispinfo[ i ]; virtualMeshes[i] = NULL; // not solid for this pass if ( !(pMapDisp->contents & contentsMask) ) continue; // Build a triangle list. This shares the tesselation code with the engine. CUtlVector<unsigned short> indices; CVBSPTesselateHelper helper; helper.m_pIndices = &indices; helper.m_pActiveVerts = pDispInfo->GetAllowedVerts().Base(); helper.m_pPowerInfo = pDispInfo->GetPowerInfo(); ::TesselateDisplacement( &helper ); // validate the collision data if ( 1 ) { int triCount = indices.Count() / 3; for ( int j = 0; j < triCount; j++ ) { int index = j * 3; Vector v0 = pDispInfo->GetVert( indices[index+0] ); Vector v1 = pDispInfo->GetVert( indices[index+1] ); Vector v2 = pDispInfo->GetVert( indices[index+2] ); if ( v0 == v1 || v1 == v2 || v2 == v0 ) { Warning( "Displacement %d has bad geometry near %.2f %.2f %.2f\n", i, v0.x, v0.y, v0.z ); texinfo_t *pTexInfo = &texinfo[pMapDisp->face.texinfo]; dtexdata_t *pTexData = GetTexData( pTexInfo->texdata ); const char *pMatName = TexDataStringTable_GetString( pTexData->nameStringTableID ); Error( "Can't compile displacement physics, exiting. Texture is %s\n", pMatName ); } } } CDispMeshEvent meshHandler( indices.Base(), indices.Count(), pDispInfo ); virtualmeshparams_t params; params.buildOuterHull = true; params.pMeshEventHandler = &meshHandler; params.userData = &meshHandler; virtualMeshes[i] = physcollision->CreateVirtualMesh( params ); } unsigned int totalSize = 0; CUtlBuffer buf; dphysdisp_t header; header.numDisplacements = g_CoreDispInfos.Count(); buf.PutObjects( &header ); CUtlVector<char> dispBuf; for ( int i = 0; i < header.numDisplacements; i++ ) { if ( virtualMeshes[i] ) { unsigned int testSize = physcollision->CollideSize( virtualMeshes[i] ); totalSize += testSize; buf.PutShort( testSize ); } else { buf.PutShort( -1 ); } } for ( int i = 0; i < header.numDisplacements; i++ ) { if ( virtualMeshes[i] ) { unsigned int testSize = physcollision->CollideSize( virtualMeshes[i] ); dispBuf.RemoveAll(); dispBuf.EnsureCount(testSize); unsigned int outSize = physcollision->CollideWrite( dispBuf.Base(), virtualMeshes[i], false ); Assert( outSize == testSize ); buf.Put( dispBuf.Base(), outSize ); } } g_PhysDispSize = totalSize + sizeof(dphysdisp_t) + (sizeof(unsigned short) * header.numDisplacements); Assert( buf.TellMaxPut() == g_PhysDispSize ); g_PhysDispSize = buf.TellMaxPut(); g_pPhysDisp = new byte[g_PhysDispSize]; Q_memcpy( g_pPhysDisp, buf.Base(), g_PhysDispSize ); }
void WritePHXFile( const char *pName, const phyfile_t &file ) { if ( file.header.size != sizeof(file.header) || file.collide.solidCount <= 0 ) return; CUtlBuffer out; char outName[1024]; Q_snprintf( outName, sizeof(outName), "%s", pName ); Q_SetExtension( outName, ".phx", sizeof(outName) ); simplifyparams_t params; params.Defaults(); params.tolerance = (file.collide.solidCount > 1) ? 4.0f : 2.0f; // single solids constraint to AABB for placement help params.addAABBToSimplifiedHull = (file.collide.solidCount == 1) ? true : false; params.mergeConvexElements = true; params.mergeConvexTolerance = 0.025f; Q_FixSlashes(outName); Q_strlower(outName); char *pSearch = Q_strstr( outName,"models\\" ); if ( pSearch ) { char keyname[1024]; pSearch += strlen("models\\"); Q_StripExtension( pSearch, keyname, sizeof(keyname) ); OverrideDefaultsForModel( keyname, params ); } out.Put( &file.header, sizeof(file.header) ); int outSize = 0; bool bStoreSolidNames = file.collide.solidCount > 1 ? true : false; bStoreSolidNames = bStoreSolidNames || HasMultipleBones(outName); vcollide_t *pNewCollide = ConvertVCollideToPHX( &file.collide, params, &outSize, false, bStoreSolidNames); g_TotalOut += file.fileSize; for ( int i = 0; i < pNewCollide->solidCount; i++ ) { int collideSize = physcollision->CollideSize( pNewCollide->solids[i] ); out.PutInt( collideSize ); char *pMem = new char[collideSize]; physcollision->CollideWrite( pMem, pNewCollide->solids[i] ); out.Put( pMem, collideSize ); delete[] pMem; } if (!g_bQuiet) { Msg("%s Compressed %d (%d text) to %d (%d text)\n", outName, file.fileSize, file.collide.descSize, out.TellPut(), pNewCollide->descSize ); } out.Put( pNewCollide->pKeyValues, pNewCollide->descSize ); g_TotalCompress += out.TellPut(); #if 0 //Msg("OLD:\n-----------------------------------\n%s\n", file.collide.pKeyValues ); CPackedPhysicsDescription *pPacked = physcollision->CreatePackedDesc( pNewCollide->pKeyValues, pNewCollide->descSize ); Msg("NEW:\n-----------------------------------\n" ); for ( int i = 0; i < pPacked->m_solidCount; i++ ) { solid_t solid; pPacked->GetSolid( &solid, i ); Msg("index %d\n", solid.index ); Msg("name %s\n", solid.name ); Msg("mass %.2f\n", solid.params.mass ); Msg("surfaceprop %s\n", solid.surfaceprop); Msg("damping %.2f\n", solid.params.damping ); Msg("rotdamping %.2f\n", solid.params.rotdamping ); Msg("drag %.2f\n", solid.params.dragCoefficient ); Msg("inertia %.2f\n", solid.params.inertia ); Msg("volume %.2f\n", solid.params.volume ); } #endif DestroyPHX( pNewCollide ); if ( !g_pFullFileSystem->WriteFile( outName, NULL, out ) ) Warning("Can't write file: %s\n", outName ); }
void CUtlBufferEditor::WriteToBuffer( CUtlBuffer &buf ) { int size = TellPut(); buf.Put( Base(), size ); }