//----------------------------------------------------------------------------- // Purpose: Composes a path and filename together, inserting a path separator // if need be // Input: path - path to use // filename - filename to use // dest - buffer to compose result in // destSize - size of destination buffer //----------------------------------------------------------------------------- void V_ComposeFileName( const char *path, const char *filename, char *dest, int destSize ) { V_strncpy( dest, path, destSize ); V_AppendSlash( dest, destSize ); V_strncat( dest, filename, destSize, COPY_ALL_CHARACTERS ); V_FixSlashes( dest ); }
//----------------------------------------------------------------------------- // Purpose: // Input : *path - // *extension - // pathStringLength - //----------------------------------------------------------------------------- void V_DefaultExtension( char *path, const char *extension, int pathStringLength ) { Assert( path ); Assert( pathStringLength >= 1 ); Assert( extension ); Assert( extension[0] == '.' ); char *src; // if path doesn't have a .EXT, append extension // (extension should include the .) src = path + V_strlen(path) - 1; while ( !PATHSEPARATOR( *src ) && ( src > path ) ) { if (*src == '.') { // it has an extension return; } src--; } // Concatenate the desired extension V_strncat( path, extension, pathStringLength, COPY_ALL_CHARACTERS ); }
static char *BuildDecoratedName(Action<CTFBot> *action, char *buf) { V_strncat(buf, action->GetName(), 256); if (action->m_ActionChild != nullptr) { V_strncat(buf, "( ", 256); BuildDecoratedName(action->m_ActionChild, buf); V_strncat(buf, " )", 256); } if (action->m_ActionWeSuspended != nullptr) { V_strncat(buf, "<<", 256); BuildDecoratedName(action->m_ActionWeSuspended, buf); } return buf; }
void V_MakeAbsolutePath( char *pOut, int outLen, const char *pPath, const char *pStartingDir ) { if ( V_IsAbsolutePath( pPath ) ) { // pPath is not relative.. just copy it. V_strncpy( pOut, pPath, outLen ); } else { // Make sure the starting directory is absolute.. if ( pStartingDir && V_IsAbsolutePath( pStartingDir ) ) { V_strncpy( pOut, pStartingDir, outLen ); } else { if ( !_getcwd( pOut, outLen ) ) Error( "V_MakeAbsolutePath: _getcwd failed." ); if ( pStartingDir ) { V_AppendSlash( pOut, outLen ); V_strncat( pOut, pStartingDir, outLen, COPY_ALL_CHARACTERS ); } } // Concatenate the paths. V_AppendSlash( pOut, outLen ); V_strncat( pOut, pPath, outLen, COPY_ALL_CHARACTERS ); } if ( !V_RemoveDotSlashes( pOut ) ) Error( "V_MakeAbsolutePath: tried to \"..\" past the root." ); V_FixSlashes( pOut ); }
//----------------------------------------------------------------------------- // Purpose: // Input : *in - // inputbytes - // *out - // outsize - //----------------------------------------------------------------------------- void V_binarytohex( const byte *in, int inputbytes, char *out, int outsize ) { Assert( outsize >= 1 ); char doublet[10]; int i; out[0]=0; for ( i = 0; i < inputbytes; i++ ) { unsigned char c = in[i]; V_snprintf( doublet, sizeof( doublet ), "%02x", c ); V_strncat( out, doublet, outsize, COPY_ALL_CHARACTERS ); } }
FSReturnCode_t FileSystem_LoadSearchPaths( CFSSearchPathsInit &initInfo ) { if ( !initInfo.m_pFileSystem || !initInfo.m_pDirectoryName ) return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_LoadSearchPaths: Invalid parameters specified." ); KeyValues *pMainFile, *pFileSystemInfo, *pSearchPaths; FSReturnCode_t retVal = LoadGameInfoFile( initInfo.m_pDirectoryName, pMainFile, pFileSystemInfo, pSearchPaths ); if ( retVal != FS_OK ) return retVal; // All paths except those marked with |gameinfo_path| are relative to the base dir. char baseDir[MAX_PATH]; if ( !FileSystem_GetBaseDir( baseDir, sizeof( baseDir ) ) ) return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetBaseDir failed." ); initInfo.m_ModPath[0] = 0; #define GAMEINFOPATH_TOKEN "|gameinfo_path|" #define BASESOURCEPATHS_TOKEN "|all_source_engine_paths|" bool bLowViolence = IsLowViolenceBuild(); bool bFirstGamePath = true; for ( KeyValues *pCur=pSearchPaths->GetFirstValue(); pCur; pCur=pCur->GetNextValue() ) { const char *pPathID = pCur->GetName(); const char *pLocation = pCur->GetString(); if ( Q_stristr( pLocation, GAMEINFOPATH_TOKEN ) == pLocation ) { pLocation += strlen( GAMEINFOPATH_TOKEN ); FileSystem_AddLoadedSearchPath( initInfo, pPathID, &bFirstGamePath, initInfo.m_pDirectoryName, pLocation, bLowViolence ); } else if ( Q_stristr( pLocation, BASESOURCEPATHS_TOKEN ) == pLocation ) { // This is a special identifier that tells it to add the specified path for all source engine versions equal to or prior to this version. // So in Orange Box, if they specified: // |all_source_engine_paths|hl2 // it would add the ep2\hl2 folder and the base (ep1-era) hl2 folder. // // We need a special identifier in the gameinfo.txt here because the base hl2 folder exists in different places. // In the case of a game or a Steam-launched dedicated server, all the necessary prior engine content is mapped in with the Steam depots, // so we can just use the path as-is. // In the case of an hldsupdatetool dedicated server, the base hl2 folder is "..\..\hl2" (since we're up in the 'orangebox' folder). pLocation += strlen( BASESOURCEPATHS_TOKEN ); // Add the Orange-box path (which also will include whatever the depots mapped in as well if we're // running a Steam-launched app). FileSystem_AddLoadedSearchPath( initInfo, pPathID, &bFirstGamePath, baseDir, pLocation, bLowViolence ); if ( FileSystem_IsHldsUpdateToolDedicatedServer() ) { // If we're using the hldsupdatetool dedicated server, then go up a directory to get the ep1-era files too. char ep1EraPath[MAX_PATH]; V_snprintf( ep1EraPath, sizeof( ep1EraPath ), "..%c%s", CORRECT_PATH_SEPARATOR, pLocation ); FileSystem_AddLoadedSearchPath( initInfo, pPathID, &bFirstGamePath, baseDir, ep1EraPath, bLowViolence ); } } else { FileSystem_AddLoadedSearchPath( initInfo, pPathID, &bFirstGamePath, baseDir, pLocation, bLowViolence ); } } pMainFile->deleteThis(); // // Set up search paths for add-ons // if ( IsPC() ) { #ifdef ENGINE_DLL FileSystem_UpdateAddonSearchPaths( initInfo.m_pFileSystem ); #endif } // these specialized tool paths are not used on 360 and cause a costly constant perf tax, so inhibited if ( IsPC() ) { // Create a content search path based on the game search path const char *pGameRoot = getenv( GAMEROOT_TOKEN ); const char *pContentRoot = getenv( CONTENTROOT_TOKEN ); if ( pGameRoot && pContentRoot ) { int nLen = initInfo.m_pFileSystem->GetSearchPath( "GAME", false, NULL, 0 ); char *pSearchPath = (char*)stackalloc( nLen * sizeof(char) ); initInfo.m_pFileSystem->GetSearchPath( "GAME", false, pSearchPath, nLen ); char *pPath = pSearchPath; while( pPath ) { char *pSemiColon = strchr( pPath, ';' ); if ( pSemiColon ) { *pSemiColon = 0; } Q_StripTrailingSlash( pPath ); Q_FixSlashes( pPath ); const char *pCurPath = pPath; pPath = pSemiColon ? pSemiColon + 1 : NULL; char pRelativePath[MAX_PATH]; char pContentPath[MAX_PATH]; if ( !Q_MakeRelativePath( pCurPath, pGameRoot, pRelativePath, sizeof(pRelativePath) ) ) continue; Q_ComposeFileName( pContentRoot, pRelativePath, pContentPath, sizeof(pContentPath) ); initInfo.m_pFileSystem->AddSearchPath( pContentPath, "CONTENT" ); } // Add the "platform" directory as a game searchable path char pPlatformPath[MAX_PATH]; Q_ComposeFileName( pGameRoot, "platform", pPlatformPath, sizeof(pPlatformPath) ); initInfo.m_pFileSystem->AddSearchPath( pPlatformPath, "GAME", PATH_ADD_TO_TAIL ); initInfo.m_pFileSystem->AddSearchPath( pContentRoot, "CONTENTROOT" ); initInfo.m_pFileSystem->AddSearchPath( pGameRoot, "GAMEROOT" ); } else { // Come up with some reasonable default int nLen = initInfo.m_pFileSystem->GetSearchPath( "MOD", false, NULL, 0 ); char *pSearchPath = (char*)stackalloc( nLen * sizeof(char) ); initInfo.m_pFileSystem->GetSearchPath( "MOD", false, pSearchPath, nLen ); char *pSemiColon = strchr( pSearchPath, ';' ); if ( pSemiColon ) { *pSemiColon = 0; } char pGameRootPath[MAX_PATH]; Q_strncpy( pGameRootPath, pSearchPath, sizeof(pGameRootPath) ); Q_StripTrailingSlash( pGameRootPath ); Q_StripFilename( pGameRootPath ); char pContentRootPath[MAX_PATH]; Q_strncpy( pContentRootPath, pGameRootPath, sizeof(pContentRootPath) ); char *pGame = Q_stristr( pContentRootPath, "game" ); if ( pGame ) { Q_strcpy( pGame, "content" ); } initInfo.m_pFileSystem->AddSearchPath( pContentRootPath, "CONTENTROOT" ); initInfo.m_pFileSystem->AddSearchPath( pGameRootPath, "GAMEROOT" ); } // Also, mark specific path IDs as "by request only". That way, we won't waste time searching in them // when people forget to specify a search path. initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "contentroot", true ); initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "gameroot", true ); initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "content", true ); } // Also, mark specific path IDs as "by request only". That way, we won't waste time searching in them // when people forget to specify a search path. initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "executable_path", true ); initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "gamebin", true ); initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "mod", true ); // Add the write path last. if ( initInfo.m_ModPath[0] != 0 ) { initInfo.m_pFileSystem->AddSearchPath( initInfo.m_ModPath, "DEFAULT_WRITE_PATH", PATH_ADD_TO_TAIL ); } #ifdef _DEBUG initInfo.m_pFileSystem->PrintSearchPaths(); #endif #if defined( ENABLE_RUNTIME_STACK_TRANSLATION ) && !defined( _X360 ) //copy search paths to stack tools so it can grab pdb's from all over. But only on P4 or Steam Beta builds if( (CommandLine()->FindParm( "-steam" ) == 0) || //not steam (CommandLine()->FindParm( "-internalbuild" ) != 0) ) //steam beta is ok { char szSearchPaths[4096]; //int CBaseFileSystem::GetSearchPath( const char *pathID, bool bGetPackFiles, char *pPath, int nMaxLen ) int iLength1 = initInfo.m_pFileSystem->GetSearchPath( "EXECUTABLE_PATH", false, szSearchPaths, 4096 ); if( iLength1 == 1 ) iLength1 = 0; int iLength2 = initInfo.m_pFileSystem->GetSearchPath( "GAMEBIN", false, szSearchPaths + iLength1, 4096 - iLength1 ); if( (iLength2 > 1) && (iLength1 > 1) ) { szSearchPaths[iLength1 - 1] = ';'; //replace first null terminator } const char *szAdditionalPath = CommandLine()->ParmValue( "-AdditionalPDBSearchPath" ); if( szAdditionalPath && szAdditionalPath[0] ) { int iLength = iLength1; if( iLength2 > 1 ) iLength += iLength2; if( iLength != 0 ) { szSearchPaths[iLength - 1] = ';'; //replaces null terminator } V_strncpy( &szSearchPaths[iLength], szAdditionalPath, 4096 - iLength ); } //Append the perforce symbol server last. Documentation says that "srv*\\perforce\symbols" should work, but it doesn't. //"symsrv*symsrv.dll*\\perforce\symbols" which the docs say is the same statement, works. { V_strncat( szSearchPaths, ";symsrv*symsrv.dll*\\\\perforce\\symbols", 4096 ); } SetStackTranslationSymbolSearchPath( szSearchPaths ); //MessageBox( NULL, szSearchPaths, "Search Paths", 0 ); } #endif return FS_OK; }
//----------------------------------------------------------------------------- // Models require specialized group handling to generate intermediate lod culled // versions that are then used as the the source for target conversion. //----------------------------------------------------------------------------- bool PreprocessModelFiles( CUtlVector<fileList_t> &fileList ) { if ( !InitStudioByteSwap() ) { return false; } CUtlVector< CUtlString > updateList; CUtlRBTree< CUtlString, int > visitedModels( 0, 0, ModelNamesLessFunc ); char szSourcePath[MAX_PATH]; strcpy( szSourcePath, g_szSourcePath ); V_StripFilename( szSourcePath ); if ( !szSourcePath[0] ) strcpy( szSourcePath, "." ); V_AppendSlash( szSourcePath, sizeof( szSourcePath ) ); char szModelName[MAX_PATH]; for ( int i=0; i<fileList.Count(); i++ ) { V_strncpy( szModelName, fileList[i].fileName.String(), sizeof( szModelName ) ); if ( V_stristr( szModelName, ".360." ) ) { // must ignore any target files continue; } // want only model related files char *pExtension = V_stristr( szModelName, ".mdl" ); if ( !pExtension ) { pExtension = V_stristr( szModelName, ".dx90.vtx" ); if ( !pExtension ) { pExtension = V_stristr( szModelName, ".vvd" ); if ( !pExtension ) { pExtension = V_stristr( szModelName, ".ani" ); if ( !pExtension ) { pExtension = V_stristr( szModelName, ".phy" ); if ( !pExtension ) { pExtension = V_stristr( szModelName, ".vsi" ); if ( !pExtension ) { continue; } } } } } } *pExtension = '\0'; V_strncat( szModelName, ".mdl", sizeof( szModelName ) ); if ( visitedModels.Find( szModelName ) != visitedModels.InvalidIndex() ) { // already processed continue; } visitedModels.Insert( szModelName ); // resolve to full source path const char *ptr = szModelName; if ( !strnicmp( ptr, ".\\", 2 ) ) ptr += 2; else if ( !strnicmp( ptr, szSourcePath, strlen( szSourcePath ) ) ) ptr += strlen( szSourcePath ); char szCleanName[MAX_PATH]; strcpy( szCleanName, szSourcePath ); strcat( szCleanName, ptr ); char szFullSourcePath[MAX_PATH]; _fullpath( szFullSourcePath, szCleanName, sizeof( szFullSourcePath ) ); // any one dirty component generates the set of all expected files if ( ModelNeedsUpdate( szFullSourcePath ) ) { int index = updateList.AddToTail(); updateList[index].Set( szFullSourcePath ); } } Msg( "\n" ); Msg( "Model Pre Pass: Updating %d Models.\n", updateList.Count() ); for ( int i = 0; i < updateList.Count(); i++ ) { if ( !GenerateModelFiles( updateList[i].String() ) ) { int error = g_errorList.AddToTail(); g_errorList[error].result = false; g_errorList[error].fileName.Set( updateList[i].String() ); } } // iterate error list if ( g_errorList.Count() ) { Msg( "\n" ); for ( int i = 0; i < g_errorList.Count(); i++ ) { Msg( "ERROR: could not pre-process model: %s\n", g_errorList[i].fileName.String() ); } } return true; }
//----------------------------------------------------------------------------- // 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; }
//----------------------------------------------------------------------------- // Generate a tree containing files from a reslist. Returns TRUE if successful. //----------------------------------------------------------------------------- bool LoadReslist( const char *pReslistName, CUtlRBTree< CUtlString, int > *pTree ) { CUtlBuffer buffer; if ( !scriptlib->ReadFileToBuffer( pReslistName, buffer, true ) ) { return false; } char szBasename[MAX_PATH]; V_FileBase( pReslistName, szBasename, sizeof( szBasename ) ); characterset_t breakSet; CharacterSetBuild( &breakSet, "" ); // parse reslist char szToken[MAX_PATH]; char szBspName[MAX_PATH]; szBspName[0] = '\0'; for ( ;; ) { int nTokenSize = buffer.ParseToken( &breakSet, szToken, sizeof( szToken ) ); if ( nTokenSize <= 0 ) { break; } // reslists are pc built, filenames can be sloppy V_strlower( szToken ); V_FixSlashes( szToken ); V_RemoveDotSlashes( szToken ); // can safely cull filetypes that are ignored by queued loader at runtime bool bKeep = false; const char *pExt = V_GetFileExtension( szToken ); if ( !pExt ) { // unknown continue; } else if ( !V_stricmp( pExt, "vmt" ) || !V_stricmp( pExt, "vhv" ) || !V_stricmp( pExt, "mdl" ) || !V_stricmp( pExt, "raw" ) || !V_stricmp( pExt, "wav" ) ) { bKeep = true; } else if ( !V_stricmp( pExt, "mp3" ) ) { // change to .wav V_SetExtension( szToken, ".wav", sizeof( szToken ) ); bKeep = true; } else if ( !V_stricmp( pExt, "bsp" ) ) { // reslists erroneously have multiple bsps if ( !V_stristr( szToken, szBasename ) ) { // wrong one, cull it continue; } else { // right one, save it strcpy( szBspName, szToken ); bKeep = true; } } if ( bKeep ) { FindOrAddFileToResourceList( szToken, pTree ); } } if ( !szBspName[0] ) { // reslist is not bsp derived, nothing more to do return true; } CUtlVector< CUtlString > bspList; bool bOK = GetDependants_BSP( szBspName, &bspList ); if ( !bOK ) { return false; } // add all the bsp dependants to the resource list for ( int i=0; i<bspList.Count(); i++ ) { FindOrAddFileToResourceList( bspList[i].String(), pTree ); } // iterate all the models in the resource list, get all their dependents CUtlVector< CUtlString > modelList; for ( int i = pTree->FirstInorder(); i != pTree->InvalidIndex(); i = pTree->NextInorder( i ) ) { const char *pExt = V_GetFileExtension( pTree->Element( i ).String() ); if ( !pExt || V_stricmp( pExt, "mdl" ) ) { continue; } if ( !GetDependants_MDL( pTree->Element( i ).String(), &modelList ) ) { return false; } } // add all the model dependents to the resource list for ( int i=0; i<modelList.Count(); i++ ) { FindOrAddFileToResourceList( modelList[i].String(), pTree ); } // check for optional commentary, include wav dependencies char szCommentaryName[MAX_PATH]; V_ComposeFileName( g_szGamePath, szBspName, szCommentaryName, sizeof( szCommentaryName ) ); V_StripExtension( szCommentaryName, szCommentaryName, sizeof( szCommentaryName ) ); V_strncat( szCommentaryName, "_commentary.txt", sizeof( szCommentaryName ) ); CUtlBuffer commentaryBuffer; if ( ReadFileToBuffer( szCommentaryName, commentaryBuffer, true, true ) ) { // any single token may be quite large to due to text char szCommentaryToken[8192]; for ( ;; ) { int nTokenSize = commentaryBuffer.ParseToken( &breakSet, szCommentaryToken, sizeof( szCommentaryToken ) ); if ( nTokenSize < 0 ) { break; } if ( nTokenSize > 0 && !V_stricmp( szCommentaryToken, "commentaryfile" ) ) { // get the commentary file nTokenSize = commentaryBuffer.ParseToken( &breakSet, szCommentaryToken, sizeof( szCommentaryToken ) ); if ( nTokenSize > 0 ) { // skip past sound chars char *pName = szCommentaryToken; while ( *pName && IsSoundChar( *pName ) ) { pName++; } char szWavFile[MAX_PATH]; V_snprintf( szWavFile, sizeof( szWavFile ), "sound/%s", pName ); FindOrAddFileToResourceList( szWavFile, pTree ); } } } } // check for optional blacklist char szBlacklist[MAX_PATH]; V_ComposeFileName( g_szGamePath, "reslistfixes_xbox.xsc", szBlacklist, sizeof( szBlacklist ) ); CUtlBuffer blacklistBuffer; if ( ReadFileToBuffer( szBlacklist, blacklistBuffer, true, true ) ) { for ( ;; ) { int nTokenSize = blacklistBuffer.ParseToken( &breakSet, szToken, sizeof( szToken ) ); if ( nTokenSize <= 0 ) { break; } bool bAdd; if ( !V_stricmp( szToken, "-" ) ) { bAdd = false; } else if ( !V_stricmp( szToken, "+" ) ) { bAdd = true; } else { // bad syntax, skip line Msg( "Bad Syntax, expecting '+' or '-' as first token in reslist fixup file '%s'.\n", szBlacklist ); continue; } // get entry nTokenSize = blacklistBuffer.ParseToken( &breakSet, szToken, sizeof( szToken ) ); if ( nTokenSize <= 0 ) { break; } if ( bAdd ) { FindOrAddFileToResourceList( szToken, pTree ); } else { RemoveFileFromResourceList( szToken, pTree ); } } } return true; }
void CSun::Activate() { BaseClass::Activate(); // Find our target. if ( m_bUseAngles ) { SetupLightNormalFromProps( GetAbsAngles(), m_flYaw, m_flPitch, m_vDirection.GetForModify() ); m_vDirection = -m_vDirection.Get(); } else { CBaseEntity *pEnt = gEntList.FindEntityByName( 0, m_target ); if( pEnt ) { Vector vDirection = GetAbsOrigin() - pEnt->GetAbsOrigin(); VectorNormalize( vDirection ); m_vDirection = vDirection; } } // Default behavior if ( m_nOverlaySize == -1 ) { m_nOverlaySize = m_nSize; } // Cache off our image indices if ( m_strMaterial == NULL_STRING ) { m_strMaterial = AllocPooledString( "sprites/light_glow02_add_noz.vmt" ); } else { const char *pExtension = V_GetFileExtension( STRING( m_strMaterial ) ); if ( !pExtension ) { char szFixedString[MAX_PATH]; V_strncpy( szFixedString, STRING( m_strMaterial ), sizeof( szFixedString ) ); V_strncat( szFixedString, ".vmt", sizeof( szFixedString ) ); m_strMaterial = AllocPooledString( szFixedString ); } } if ( m_strOverlayMaterial == NULL_STRING ) { m_strOverlayMaterial = AllocPooledString( "sprites/light_glow02_add_noz.vmt" ); } else { const char *pExtension = V_GetFileExtension( STRING( m_strOverlayMaterial ) ); if ( !pExtension ) { char szFixedString[MAX_PATH]; V_strncpy( szFixedString, STRING( m_strOverlayMaterial ), sizeof( szFixedString ) ); V_strncat( szFixedString, ".vmt", sizeof( szFixedString ) ); m_strOverlayMaterial = AllocPooledString( szFixedString ); } } m_nMaterial = PrecacheModel( STRING( m_strMaterial ) ); m_nOverlayMaterial = PrecacheModel( STRING( m_strOverlayMaterial ) ); }
//----------------------------------------------------------------------------- // ExcludePathsDlg_Populate // // Generate a path table. //----------------------------------------------------------------------------- void ExcludePathsDlg_Populate( HWND hWnd, bool bRefresh ) { struct GamePath_t { CUtlString pathName; bool bIsModPath; }; CUtlVector< GamePath_t > gamePaths; // can skip the time consuming directory scan, unless forced if ( bRefresh || !g_PathTable.Count() ) { g_PathTable.Purge(); for ( int i = 0; i < ARRAYSIZE( g_GameNames ); i++ ) { char szTargetPath[MAX_PATH]; V_strncpy( szTargetPath, g_localPath, sizeof( szTargetPath ) ); V_AppendSlash( szTargetPath, sizeof( szTargetPath ) ); V_strncat( szTargetPath, g_GameNames[i].pName, sizeof( szTargetPath ) ); GamePath_t gamePath; gamePath.pathName = szTargetPath; gamePath.bIsModPath = g_GameNames[i].bIsModPath; gamePaths.AddToTail( gamePath ); } // iterate all game paths for ( int i = 0; i < gamePaths.Count(); i++ ) { CUtlVector< CUtlString > dirList; RecurseFileTree_r( g_localPath, gamePaths[i].pathName.String(), 0, dirList, gamePaths[i].bIsModPath ); } } // reset the tree HWND hWndTree = GetDlgItem( hWnd, IDC_PATHS_TREE ); TreeView_DeleteAllItems( hWndTree ); // reset and add root // only the root is at depth 0 AddItemToTree( hWndTree, ROOT_NAME, 0, false ); // build the tree view for ( int iIndex = g_PathTable.FirstInorder(); iIndex != g_PathTable.InvalidIndex(); iIndex = g_PathTable.NextInorder( iIndex ) ) { // due to sorting, number of slashes is depth const char *pString = g_PathTable[iIndex].pathName.String(); int depth = 0; for ( int j = 0; j < (int)strlen( pString ); j++ ) { if ( pString[j] == '\\' ) { depth++; } } if ( !depth ) { depth = 1; } char szPath[MAX_PATH]; V_FileBase( pString, szPath, sizeof( szPath ) ); AddItemToTree( hWndTree, szPath, depth, g_PathTable[iIndex].bIsModPath ); } HTREEITEM hTreeRoot = TreeView_GetRoot( hWndTree ); for ( int i = 0; i < g_ExcludePaths.Count(); i++ ) { HTREEITEM hTree = ExcludePathsDlg_Find_r( hWndTree, hTreeRoot, 0, "", g_ExcludePaths[i].String() ); if ( hTree ) { ExcludePathsDlg_SetCheckState_r( hWndTree, hTree, 0, true ); } } // expand the root node to show state ExcludePathsDlg_ExpandToShowState_r( hWndTree, hTreeRoot, 0 ); }