void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName, const char *pNewKey, const char *pNewValue ) { char oldVMTFile[ 512 ]; char newVMTFile[ 512 ]; AddNewTranslation( pOriginalMaterialName, pNewMaterialName ); sprintf( oldVMTFile, "materials/%s.vmt", pOriginalMaterialName ); sprintf( newVMTFile, "materials/%s.vmt", pNewMaterialName ); // printf( "Creating material patch file %s which points at %s\n", newVMTFile, oldVMTFile ); KeyValues *kv = new KeyValues( "patch" ); if ( !kv ) { Error( "Couldn't allocate KeyValues for %s!!!", pNewMaterialName ); } kv->SetString( "include", oldVMTFile ); KeyValues *section = kv->FindKey( "insert", true ); section->SetString( pNewKey, pNewValue ); // Write patched .vmt into a memory buffer CUtlBuffer buf( 0, 0, true ); kv->RecursiveSaveToFile( buf, 0 ); // Add to pak file for this .bsp AddBufferToPack( newVMTFile, (void*)buf.Base(), buf.TellPut(), true ); // Cleanup kv->deleteThis(); }
//----------------------------------------------------------------------------- // A version which allows you to patch multiple key values //----------------------------------------------------------------------------- void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName, int nKeys, const MaterialPatchInfo_t *pInfo, MaterialPatchType_t nPatchType ) { char pOldVMTFile[ 512 ]; char pNewVMTFile[ 512 ]; AddNewTranslation( pOriginalMaterialName, pNewMaterialName ); Q_snprintf( pOldVMTFile, 512, "materials/%s.vmt", pOriginalMaterialName ); Q_snprintf( pNewVMTFile, 512, "materials/%s.vmt", pNewMaterialName ); // printf( "Creating material patch file %s which points at %s\n", newVMTFile, oldVMTFile ); KeyValues *kv = new KeyValues( "patch" ); if ( !kv ) { Error( "Couldn't allocate KeyValues for %s!!!", pNewMaterialName ); } kv->SetString( "include", pOldVMTFile ); const char *pSectionName = (nPatchType == PATCH_INSERT) ? "insert" : "replace"; KeyValues *section = kv->FindKey( pSectionName, true ); if( nPatchType == PATCH_REPLACE ) { char name[512]; Q_snprintf( name, 512, "materials/%s.vmt", GetOriginalMaterialNameForPatchedMaterial( pOriginalMaterialName ) ); KeyValues *origkv = new KeyValues( "blah" ); if ( !origkv->LoadFromFile( g_pFileSystem, name ) ) { origkv->deleteThis(); Assert( 0 ); return; } CreateMaterialPatchRecursive( origkv, section, nKeys, pInfo ); origkv->deleteThis(); } else { for ( int i = 0; i < nKeys; ++i ) { section->SetString( pInfo[i].m_pKey, pInfo[i].m_pValue ); } } // Write patched .vmt into a memory buffer CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); kv->RecursiveSaveToFile( buf, 0 ); // Add to pak file for this .bsp AddBufferToPak( GetPakFile(), pNewVMTFile, (void*)buf.Base(), buf.TellPut(), true ); // Cleanup kv->deleteThis(); }
void UTIL_IncrementMapKey( const char *pszCustomKey ) { if ( !pszCustomKey ) return; char szFilename[ _MAX_PATH ]; if ( !UTIL_GetMapLoadCountFileName( MAP_KEY_FILE, szFilename, _MAX_PATH ) ) return; int iCount = 1; KeyValues *kvMapLoadFile = new KeyValues( MAP_KEY_FILE ); if ( kvMapLoadFile ) { kvMapLoadFile->LoadFromFile( g_pFullFileSystem, szFilename, "MOD" ); char mapname[MAX_MAP_NAME]; Q_FileBase( engine->GetLevelName(), mapname, sizeof( mapname) ); Q_strlower( mapname ); // Increment existing, or add a new one KeyValues *pMapKey = kvMapLoadFile->FindKey( mapname ); if ( pMapKey ) { iCount = pMapKey->GetInt( pszCustomKey, 0 ) + 1; pMapKey->SetInt( pszCustomKey, iCount ); } else { KeyValues *pNewKey = new KeyValues( mapname ); if ( pNewKey ) { pNewKey->SetString( pszCustomKey, "1" ); kvMapLoadFile->AddSubKey( pNewKey ); } } // Write it out // force create this directory incase it doesn't exist filesystem->CreateDirHierarchy( MAP_KEY_FILE_DIR, "MOD"); CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); kvMapLoadFile->RecursiveSaveToFile( buf, 0 ); g_pFullFileSystem->WriteFile( szFilename, "MOD", buf ); kvMapLoadFile->deleteThis(); } if ( IsX360() ) { #ifdef _X360 xboxsystem->FinishContainerWrites(); #endif } }
bool CASW_Location_Grid::SaveLocationGrid() { const char *filename = "resource/mission_grid.txt"; CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); for ( int i = 0; i < m_Groups.Count(); i++ ) { KeyValues *pKey = m_Groups[i]->GetKeyValuesForEditor(); pKey->RecursiveSaveToFile( buf, 0 ); pKey->deleteThis(); } if ( !g_pFullFileSystem->WriteFile( filename, "GAME", buf ) ) { Warning( "Failed to SaveLocationGrid %s\n", filename ); return false; } return true; }
CRC32_t IFaceposerModels::CFacePoserModel::GetBitmapCRC( int sequence ) { CStudioHdr *hdr = m_pModel ? m_pModel->GetStudioHdr() : NULL; if ( !hdr ) return (CRC32_t)-1; if ( sequence < 0 || sequence >= hdr->GetNumSeq() ) return (CRC32_t)-1; mstudioseqdesc_t &seqdesc = hdr->pSeqdesc( sequence ); CRC32_t crc; CRC32_Init( &crc ); // For sequences, we'll checsum a bit of data CRC32_ProcessBuffer( &crc, (void *)seqdesc.pszLabel(), Q_strlen( seqdesc.pszLabel() ) ); CRC32_ProcessBuffer( &crc, (void *)seqdesc.pszActivityName(), Q_strlen( seqdesc.pszActivityName() ) ); CRC32_ProcessBuffer( &crc, (void *)&seqdesc.flags, sizeof( seqdesc.flags ) ); //CRC32_ProcessBuffer( &crc, (void *)&seqdesc.numevents, sizeof( seqdesc.numevents ) ); CRC32_ProcessBuffer( &crc, (void *)&seqdesc.numblends, sizeof( seqdesc.numblends ) ); CRC32_ProcessBuffer( &crc, (void *)seqdesc.groupsize, sizeof( seqdesc.groupsize ) ); KeyValues *seqKeyValues = new KeyValues(""); if ( seqKeyValues->LoadFromBuffer( m_pModel->GetFileName( ), m_pModel->GetKeyValueText( sequence ) ) ) { // Yuck, but I need it in a contiguous block of memory... oh well... CUtlBuffer buf; seqKeyValues->RecursiveSaveToFile( buf, 0 ); CRC32_ProcessBuffer( &crc, ( void * )buf.Base(), buf.TellPut() ); } seqKeyValues->deleteThis(); CRC32_Final( &crc ); return crc; }
bool VMFExporter::ExportVMF( CMapLayout* pLayout, const char *mapname, bool bPopupWarnings ) { m_bPopupWarnings = bPopupWarnings; Init(); m_pMapLayout = pLayout; if ( pLayout->m_PlacedRooms.Count() <= 0 ) { Q_snprintf( m_szLastExporterError, sizeof(m_szLastExporterError), "Failed to export: No rooms placed in the map layout!\n" ); return false; } // see if we have a start room bool bHasStartRoom = false; for ( int i = 0 ; i < pLayout->m_PlacedRooms.Count() ; i++ ) { if ( pLayout->m_PlacedRooms[i]->m_pRoomTemplate->IsStartRoom() ) { int half_map_size = MAP_LAYOUT_TILES_WIDE * 0.5f; // shift back so the middle of our grid is the origin m_vecStartRoomOrigin.x = ( pLayout->m_PlacedRooms[i]->m_iPosX - half_map_size ) * ASW_TILE_SIZE; m_vecStartRoomOrigin.y = ( pLayout->m_PlacedRooms[i]->m_iPosY - half_map_size ) * ASW_TILE_SIZE; bHasStartRoom = true; break; } } LoadUniqueKeyList(); m_iNextNodeID = 0; m_pExportKeys = new KeyValues( "ExportKeys" ); m_pExportKeys->AddSubKey( GetVersionInfo() ); m_pExportKeys->AddSubKey( GetDefaultVisGroups() ); m_pExportKeys->AddSubKey( GetViewSettings() ); m_pExportWorldKeys = GetDefaultWorldChunk(); if ( !m_pExportWorldKeys ) { Q_snprintf( m_szLastExporterError, sizeof(m_szLastExporterError), "Failed to save world chunk start\n"); return false; } m_pExportKeys->AddSubKey( m_pExportWorldKeys ); // save out the big cube the whole level sits in if ( !AddLevelContainer() ) { Q_snprintf( m_szLastExporterError, sizeof(m_szLastExporterError), "Failed to save level container\n"); return false; } if ( tilegen_use_instancing.GetBool() ) { int nLogicalRooms = m_pMapLayout->m_LogicalRooms.Count(); int nPlacedRooms = m_pMapLayout->m_PlacedRooms.Count(); m_pRoom = NULL; for ( int i = 0; i < nLogicalRooms; ++ i ) { AddRoomInstance( m_pMapLayout->m_LogicalRooms[i] ); } for ( int i = 0; i < nPlacedRooms; ++ i ) { m_pRoom = m_pMapLayout->m_PlacedRooms[i]; AddRoomInstance( m_pRoom->m_pRoomTemplate, i ); } } else { // write out logical room solids int iLogicalRooms = m_pMapLayout->m_LogicalRooms.Count(); m_pRoom = NULL; for ( int i = 0 ; i < iLogicalRooms ; i++ ) { // start logical room IDs at 5000 (assumes we'll never place 5000 real rooms) m_iCurrentRoom = 5000 + i; CRoomTemplate *pRoomTemplate = m_pMapLayout->m_LogicalRooms[i]; if ( !pRoomTemplate ) continue; if ( !AddRoomTemplateSolids( pRoomTemplate ) ) return false; } // go through each CRoom and write out its world solids int iRooms = m_pMapLayout->m_PlacedRooms.Count(); for ( m_iCurrentRoom = 0 ; m_iCurrentRoom<iRooms ; m_iCurrentRoom++) { m_pRoom = m_pMapLayout->m_PlacedRooms[m_iCurrentRoom]; if (!m_pRoom) continue; const CRoomTemplate *pRoomTemplate = m_pRoom->m_pRoomTemplate; if (!pRoomTemplate) continue; if ( !AddRoomTemplateSolids( pRoomTemplate ) ) return false; } // write out logical room entities m_pRoom = NULL; for ( int i = 0 ; i < iLogicalRooms ; i++ ) { // start logical room IDs at 5000 (assumes we'll never place 5000 real rooms) m_iCurrentRoom = 5000 + i; CRoomTemplate *pRoomTemplate = m_pMapLayout->m_LogicalRooms[i]; if ( !pRoomTemplate ) continue; if ( !AddRoomTemplateEntities( pRoomTemplate ) ) return false; } // go through each CRoom and add its entities for ( m_iCurrentRoom = 0 ; m_iCurrentRoom<iRooms ; m_iCurrentRoom++) { m_pRoom = m_pMapLayout->m_PlacedRooms[m_iCurrentRoom]; if (!m_pRoom) continue; const CRoomTemplate *pRoomTemplate = m_pRoom->m_pRoomTemplate; if (!pRoomTemplate) continue; if ( !AddRoomTemplateEntities( pRoomTemplate ) ) return false; } } // add some player starts to the map in the tile the user selected if ( !bHasStartRoom ) { m_pExportKeys->AddSubKey( GetPlayerStarts() ); } m_pExportKeys->AddSubKey( GetGameRulesProxy() ); m_pExportKeys->AddSubKey( GetDefaultCamera() ); // save out the export keys char filename[512]; Q_snprintf( filename, sizeof(filename), "maps\\%s", mapname ); Q_SetExtension( filename, "vmf", sizeof( filename ) ); CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); for ( KeyValues *pKey = m_pExportKeys->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey() ) { pKey->RecursiveSaveToFile( buf, 0 ); } if ( !g_pFullFileSystem->WriteFile( filename, "GAME", buf ) ) { Msg( "Failed to SaveToFile %s\n", filename ); return false; } // save the map layout there (so the game can get information about rooms during play) Q_snprintf( filename, sizeof( filename ), "maps\\%s", mapname ); Q_SetExtension( filename, "layout", sizeof( filename ) ); if ( !m_pMapLayout->SaveMapLayout( filename ) ) { Q_snprintf( m_szLastExporterError, sizeof(m_szLastExporterError), "Failed to save .layout file\n"); return false; } return true; }
bool CMapLayout::SaveMapLayout( const char *filename ) { KeyValues *pLayoutKeys = new KeyValues( "Layout" ); if ( m_pGenerationOptions ) { pLayoutKeys->AddSubKey( m_pGenerationOptions->MakeCopy() ); } KeyValues *pMiscKeys = new KeyValues( "mapmisc" ); pMiscKeys->SetInt( "PlayerStartX", m_iPlayerStartTileX ); pMiscKeys->SetInt( "PlayerStartY", m_iPlayerStartTileY ); pLayoutKeys->AddSubKey( pMiscKeys ); // save out each room int iRooms = m_PlacedRooms.Count(); for (int i=0;i<iRooms;i++) { CRoom *pRoom = m_PlacedRooms[i]; if (!pRoom) continue; pLayoutKeys->AddSubKey( pRoom->GetKeyValuesCopy() ); } // save out logical rooms iRooms = m_LogicalRooms.Count(); for (int i=0;i<iRooms;i++) { KeyValues *pRoomKeys = new KeyValues( "logical_room" ); if ( m_LogicalRooms[i]->m_pLevelTheme ) { pRoomKeys->SetString( "theme", m_LogicalRooms[i]->m_pLevelTheme->m_szName ); } pRoomKeys->SetString( "template", m_LogicalRooms[i]->GetFullName() ); pLayoutKeys->AddSubKey( pRoomKeys ); } for ( int i = 0; i < m_InstanceSpawns.Count(); ++ i ) { KeyValues *pNewInstanceSpawn = new KeyValues( "instance_spawn" ); m_InstanceSpawns[i].SaveToKeyValues( pNewInstanceSpawn ); pLayoutKeys->AddSubKey( pNewInstanceSpawn ); } for ( int i = 0; i < m_Encounters.Count(); ++ i ) { KeyValues *pEncounterKeys = new KeyValues( "npc_encounter" ); m_Encounters[i]->SaveToKeyValues( pEncounterKeys ); pLayoutKeys->AddSubKey( pEncounterKeys ); } CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); for ( KeyValues *pKey = pLayoutKeys->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey() ) { pKey->RecursiveSaveToFile( buf, 0 ); } pLayoutKeys->deleteThis(); if ( !g_pFullFileSystem->WriteFile( filename, "GAME", buf ) ) { Log_Warning( LOG_TilegenLayoutSystem, "Failed to SaveToFile %s\n", filename ); return false; } return true; }
//========================================================= //========================================================= bool C_GameInstructor::WriteSaveData() { if ( engine->IsPlayingDemo() ) return false; if ( !m_bDirtySaveData ) return true; #ifdef _X360 float flPlatTime = Plat_FloatTime(); static ConVarRef host_write_last_time( "host_write_last_time" ); if ( host_write_last_time.IsValid() ) { float flTimeSinceLastWrite = flPlatTime - host_write_last_time.GetFloat(); if ( flTimeSinceLastWrite < 3.5f ) { // Prevent writing to the same storage device twice in less than 3 second succession for TCR success! // This happens after leaving a game in splitscreen. //DevMsg( "Waiting to write Game Instructor for splitscreen slot %d... (%.1f seconds remain)\n", m_nSplitScreenSlot, 3.5f - flTimeSinceLastWrite ); return false; } } #endif // Always mark as clean state to avoid re-entry on // subsequent frames when storage device might be // in a yet-unmounted state. m_bDirtySaveData = false; #ifdef _X360 DevMsg( "Write Game Instructor for splitscreen slot %d at time: %.1f\n", m_nSplitScreenSlot, flPlatTime ); if ( m_nSplitScreenSlot < 0 ) return false; if ( m_nSplitScreenSlot >= (int) XBX_GetNumGameUsers() ) return false; int iController = XBX_GetUserId( m_nSplitScreenSlot ); if ( iController < 0 || XBX_GetUserIsGuest( iController ) ) { // Can't save data for guests return false; } DWORD nStorageDevice = XBX_GetStorageDeviceId( iController ); if ( !XBX_DescribeStorageDevice( nStorageDevice ) ) return false; #endif // Build key value data to save KeyValues *data = new KeyValues( "Game Instructor Counts" ); KeyValues::AutoDelete autoDelete(data); for ( int i = 0; i < m_Lessons.Count(); ++i ) { CBaseLesson *pLesson = m_Lessons[i]; int iDisplayCount = pLesson->GetDisplayCount(); int iSuccessCount = pLesson->GetSuccessCount(); if ( iDisplayCount || iSuccessCount ) { // We've got some data worth saving KeyValues *pKVData = new KeyValues( pLesson->GetName() ); if ( iDisplayCount ) pKVData->SetInt( "display", iDisplayCount ); if ( iSuccessCount ) pKVData->SetInt( "success", iSuccessCount ); data->AddSubKey( pKVData ); } } // Save it! CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); data->RecursiveSaveToFile( buf, 0 ); char szFilename[_MAX_PATH]; #ifdef _X360 if ( IsX360() ) { XBX_MakeStorageContainerRoot( iController, XBX_USER_SETTINGS_CONTAINER_DRIVE, szFilename, sizeof( szFilename ) ); int nLen = strlen( szFilename ); Q_snprintf( szFilename + nLen, sizeof( szFilename ) - nLen, ":\\game_instructor_counts.txt" ); } else #endif { Q_snprintf( szFilename, sizeof( szFilename ), "save/game_instructor_counts.txt" ); filesystem->CreateDirHierarchy( "save", "MOD" ); } bool bWriteSuccess = filesystem->WriteFile( szFilename, MOD_DIR, buf ); #ifdef _X360 if ( xboxsystem ) { xboxsystem->FinishContainerWrites( iController ); } #endif return bWriteSuccess; }
bool C_ASW_Medal_Store::SaveMedalStore() { if ( !m_bLoaded ) return false; KeyValues *kv = new KeyValues( "CLIENTDAT" ); // output missions/campaigns/kills kv->SetInt("MC", m_iMissionsCompleted); kv->SetInt("CC", m_iCampaignsCompleted); kv->SetInt("AK", m_iAliensKilled); kv->SetInt("OMC", m_iOfflineMissionsCompleted); kv->SetInt("OCC", m_iOfflineCampaignsCompleted); kv->SetInt("OAK", m_iOfflineAliensKilled); kv->SetInt( "LPL", m_iXP ); kv->SetInt( "LPP", m_iPromotion ); KeyValues *pSubSection = new KeyValues("NEWEQUIP"); char buffer[64]; if (pSubSection) { for (int i=0;i<m_NewEquipment.Count();i++) { pSubSection->SetInt( "EQUIP", m_NewEquipment[i]); } kv->AddSubKey(pSubSection); } // output player medals pSubSection = new KeyValues("LP"); if (pSubSection) { for (int i=0;i<m_PlayerMedals.Count();i++) { Q_snprintf(buffer, sizeof(buffer), "M%d", i); pSubSection->SetInt(buffer, m_PlayerMedals[i]); } kv->AddSubKey(pSubSection); } for (int k=0;k<ASW_NUM_MARINE_PROFILES;k++) { Q_snprintf(buffer, sizeof(buffer), "LA%d", k); pSubSection = new KeyValues(buffer); if (pSubSection) { for (int i=0;i<m_MarineMedals[k].Count();i++) { Q_snprintf(buffer, sizeof(buffer), "M%d", i); pSubSection->SetInt(buffer, m_MarineMedals[k][i]); } kv->AddSubKey(pSubSection); } } // offline medal store pSubSection = new KeyValues("FP"); if (pSubSection) { for (int i=0;i<m_OfflinePlayerMedals.Count();i++) { Q_snprintf(buffer, sizeof(buffer), "M%d", i); pSubSection->SetInt(buffer, m_OfflinePlayerMedals[i]); } kv->AddSubKey(pSubSection); } for (int k=0;k<ASW_NUM_MARINE_PROFILES;k++) { Q_snprintf(buffer, sizeof(buffer), "FA%d", k); pSubSection = new KeyValues(buffer); if (pSubSection) { for (int i=0;i<m_OfflineMarineMedals[k].Count();i++) { Q_snprintf(buffer, sizeof(buffer), "M%d", i); pSubSection->SetInt(buffer, m_OfflineMarineMedals[k][i]); } kv->AddSubKey(pSubSection); } } CUtlBuffer buf; //( 0, 0, CUtlBuffer::TEXT_BUFFER ); kv->RecursiveSaveToFile( buf, 0 ); // pad buffer with zeroes to make a multiple of 8 int nExtra = buf.TellPut() % 8; while ( nExtra != 0 && nExtra < 8 ) { buf.PutChar( 0 ); nExtra++; } UTIL_EncodeICE( (unsigned char*) buf.Base(), buf.TellPut(), g_ucMedalStoreEncryptionKey ); ISteamUser *pSteamUser = steamapicontext ? steamapicontext->SteamUser() : NULL; if ( !pSteamUser ) return false; char szMedalFile[ 256 ]; Q_snprintf( szMedalFile, sizeof( szMedalFile ), "cfg/clientc_%I64u.dat", pSteamUser->GetSteamID().ConvertToUint64() ); int len = Q_strlen( szMedalFile ); for ( int i = 0; i < len; i++ ) { if ( szMedalFile[ i ] == ':' ) szMedalFile[i] = '_'; } bool bResult = filesystem->WriteFile( szMedalFile, "MOD", buf ); if ( bResult ) { #if defined(NO_STEAM) AssertMsg( false, "SteamCloud not available." ); #else ISteamRemoteStorage *pRemoteStorage = SteamClient() ? ( ISteamRemoteStorage * )SteamClient()->GetISteamGenericInterface( SteamAPI_GetHSteamUser(), SteamAPI_GetHSteamPipe(), STEAMREMOTESTORAGE_INTERFACE_VERSION ) : NULL; if ( asw_steam_cloud.GetBool() && pRemoteStorage ) { WriteFileToRemoteStorage( pRemoteStorage, "PersistentMarines.dat", szMedalFile ); } #endif } return bResult; }
void KeyValues::RecursiveSaveToFile(IFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel) { WriteIndents(filesystem, f, pBuf, indentLevel); INTERNALWRITE("\"", 1); WriteConvertedString(filesystem, f, pBuf, GetName()); INTERNALWRITE("\"\n", 2); WriteIndents(filesystem, f, pBuf, indentLevel); INTERNALWRITE("{\n", 2); for (KeyValues *dat = m_pSub; dat != NULL; dat = dat->m_pPeer) { if (dat->m_pSub) { dat->RecursiveSaveToFile(filesystem, f, pBuf, indentLevel + 1); } else { switch (dat->m_iDataType) { case TYPE_STRING: { if (dat->m_sValue && *(dat->m_sValue)) { WriteIndents(filesystem, f, pBuf, indentLevel + 1); INTERNALWRITE("\"", 1); WriteConvertedString(filesystem, f, pBuf, dat->GetName()); INTERNALWRITE("\"\t\t\"", 4); WriteConvertedString(filesystem, f, pBuf, dat->m_sValue); INTERNALWRITE("\"\r\n", 3); } break; } #ifdef _WIN32 case TYPE_WSTRING: { if (dat->m_wsValue) { static char buf[KEYVALUES_TOKEN_SIZE]; assert(::WideCharToMultiByte(CP_UTF8, 0, dat->m_wsValue, -1, NULL, 0, NULL, NULL) < KEYVALUES_TOKEN_SIZE); int result = ::WideCharToMultiByte(CP_UTF8, 0, dat->m_wsValue, -1, buf, KEYVALUES_TOKEN_SIZE, NULL, NULL); if (result) { WriteIndents(filesystem, f, pBuf, indentLevel + 1); INTERNALWRITE("\"", 1); INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName())); INTERNALWRITE("\"\t\t\"", 4); WriteConvertedString(filesystem, f, pBuf, buf); INTERNALWRITE("\"\r\n", 3); } } #endif break; } case TYPE_INT: { WriteIndents(filesystem, f, pBuf, indentLevel + 1); INTERNALWRITE("\"", 1); INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName())); INTERNALWRITE("\"\t\t\"", 4); char buf[32]; Q_snprintf(buf, 32, "%d", dat->m_iValue); INTERNALWRITE(buf, Q_strlen(buf)); INTERNALWRITE("\"\r\n", 3); break; } case TYPE_UINT64: { WriteIndents(filesystem, f, pBuf, indentLevel + 1); INTERNALWRITE("\"", 1); INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName())); INTERNALWRITE("\"\t\t\"", 4); char buf[32]; Q_snprintf(buf, sizeof(buf), "0x%016I64X", *((uint64 *)dat->m_sValue)); INTERNALWRITE(buf, Q_strlen(buf)); INTERNALWRITE("\"\r\n", 3); break; } case TYPE_FLOAT: { WriteIndents(filesystem, f, pBuf, indentLevel + 1); INTERNALWRITE("\"", 1); INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName())); INTERNALWRITE("\"\t\t\"", 4); char buf[48]; Q_snprintf(buf, 48, "%f", dat->m_flValue); INTERNALWRITE(buf, Q_strlen(buf)); INTERNALWRITE("\"\r\n", 3); break; } case TYPE_COLOR: { DevMsg(1, "KeyValues::RecursiveSaveToFile: TODO, missing code for TYPE_COLOR.\n"); break; } default: break; } } } WriteIndents(filesystem, f, pBuf, indentLevel); INTERNALWRITE("}\r\n", 3); }