int CCombatCharVisCache::LookupVisibility( const CBaseCombatCharacter *pChar1, CBaseCombatCharacter *pChar2 ) { VisCacheEntry_t cacheEntry; if ( pChar1 < pChar2 ) { cacheEntry.m_hEntity1 = pChar1; cacheEntry.m_hEntity2 = pChar2; } else { cacheEntry.m_hEntity1 = pChar2; cacheEntry.m_hEntity2 = pChar1; } int iCache = m_VisCache.Find( cacheEntry ); if ( iCache == m_VisCache.InvalidIndex() ) { if ( m_VisCache.Count() == m_VisCache.InvalidIndex() ) return VIS_CACHE_INVALID; iCache = m_VisCache.Insert( cacheEntry ); m_VisCache[iCache].m_flTime = gpGlobals->curtime - 2.0f * VIS_CACHE_ENTRY_LIFE; } return ( pChar1 < pChar2 ) ? iCache : - iCache - 1; }
void CPhysicsListenerCollision::event_friction_pair_created( IVP_Friction_Core_Pair *pair ) { corepair_t test(pair); unsigned short index = m_pairList.Find( test ); if ( m_pairList.IsValidIndex( index ) ) { corepair_t &save = m_pairList.Element(index); // found this one already, update the time if ( save.lastImpactTime.get_seconds() > pair->last_impact_time_pair.get_seconds() ) { pair->last_impact_time_pair = save.lastImpactTime; } else { save.lastImpactTime = pair->last_impact_time_pair; } } else { if ( m_pairList.Count() < 16 ) { m_pairList.Insert( test ); } } }
bool CChoreoChannel::GetSortedCombinedEventList( char const *cctoken, CUtlRBTree< CChoreoEvent * >& events ) { events.RemoveAll(); int i; // Sort items int c = GetNumEvents(); for ( i = 0; i < c; i++ ) { CChoreoEvent *e = GetEvent( i ); Assert( e ); if ( e->GetType() != CChoreoEvent::SPEAK ) continue; if ( e->GetCloseCaptionType() == CChoreoEvent::CC_DISABLED ) continue; // A master with no slaves is not a combined event if ( e->GetCloseCaptionType() == CChoreoEvent::CC_MASTER && e->GetNumSlaves() == 0 ) continue; char const *token = e->GetCloseCaptionToken(); if ( Q_stricmp( token, cctoken ) ) continue; events.Insert( e ); } return ( events.Count() > 0 ) ? true : false; }
void CCombatCharVisCache::FrameUpdatePreEntityThink() { // Msg( "test: %d/%d\n", m_nHitCount, m_nTestCount ); // Lazy retirement of vis cache // NOTE: 256 was chosen heuristically based on a playthrough where 200 // was the max # in the viscache where nothing could be retired. if ( m_VisCache.Count() < 256 ) return; int nMaxIndex = m_VisCache.MaxElement() - 1; for ( int i = 0; i < 8; ++i ) { int n = RandomInt( 0, nMaxIndex ); if ( !m_VisCache.IsValidIndex( n ) ) continue; const VisCacheEntry_t &entry = m_VisCache[n]; if ( !entry.m_hEntity1.IsValid() || !entry.m_hEntity2.IsValid() || ( gpGlobals->curtime - entry.m_flTime > 10.0f ) ) { m_VisCache.RemoveAt( n ); } } }
void BuildWhiteList() { // Search for unusedcontent.cfg file if ( !g_pFileSystem->FileExists( WHITELIST_FILE ) ) { vprint( 1, "Running with no whitelist.cfg file!!!\n" ); return; } vprint( 1, "\nBuilding whitelist\n" ); KeyValues *kv = new KeyValues( WHITELIST_FILE ); if ( kv ) { if ( kv->LoadFromFile( g_pFileSystem, WHITELIST_FILE, NULL ) ) { for ( KeyValues *sub = kv->GetFirstSubKey(); sub; sub = sub->GetNextKey() ) { if ( !Q_stricmp( sub->GetName(), "add" ) ) { AddToWhiteList( sub->GetString() ); } else if ( !Q_stricmp( sub->GetName(), "remove" ) ) { RemoveFromWhiteList( sub->GetString() ); } else { vprint( 1, "Unknown subkey '%s' in %s\n", sub->GetName(), WHITELIST_FILE ); } } } kv->deleteThis(); } if ( verbose || printwhitelist ) { vprint( 1, "Whitelist:\n\n" ); for ( int i = g_WhiteList.FirstInorder(); i != g_WhiteList.InvalidIndex(); i = g_WhiteList.NextInorder( i ) ) { UnusedContent::CUtlSymbol& sym = g_WhiteList[ i ]; char const *resolved = g_Analysis.symbols.String( sym ); vprint( 2, " %s\n", resolved ); } } // dump the whitelist file list anyway { filesystem->RemoveFile( "whitelist_files.txt", "GAME" ); for ( int i = g_WhiteList.FirstInorder(); i != g_WhiteList.InvalidIndex(); i = g_WhiteList.NextInorder( i ) ) { UnusedContent::CUtlSymbol& sym = g_WhiteList[ i ]; char const *resolved = g_Analysis.symbols.String( sym ); logprint( "whitelist_files.txt", "\"%s\"\n", resolved ); } } vprint( 1, "Whitelist resolves to %d files (added %i/removed %i)\n\n", g_WhiteList.Count(), wl_added, wl_removed ); }
void Correlate( CUtlRBTree< ReferencedFile, int >& referencedfiles, CUtlVector< FileEntry >& contentfiles, const char *modname ) { int i; int c = contentfiles.Count(); double totalDiskSize = 0; double totalReferencedDiskSize = 0; double totalWhiteListDiskSize = 0; for ( i = 0; i < c; ++i ) { totalDiskSize += contentfiles [ i ].size; } vprint( 0, "Content tree size on disk %s\n", Q_pretifymem( totalDiskSize, 3 ) ); // Analysis is to walk tree and see which files on disk are referenced in the .lst files // Need a fast lookup from file symbol to referenced list CUtlRBTree< ReferencedFile, int > tree( 0, 0, ReferencedFileLessFunc ); c = referencedfiles.Count(); for ( i = 0 ; i < c; ++i ) { tree.Insert( referencedfiles[ i ] ); } // Now walk the on disk file and see check off resources which are in referenced c = contentfiles.Count(); int invalidindex = tree.InvalidIndex(); unsigned int refcounted = 0; unsigned int whitelisted = 0; filesystem->RemoveFile( CFmtStr( "%swhitelist.lst", g_szReslistDir ), "GAME" ); for ( i = 0; i < c; ++i ) { FileEntry & entry = contentfiles[ i ]; ReferencedFile foo; foo.sym = entry.sym; bool gameref = tree.Find( foo ) != invalidindex; char const *fn = g_Analysis.symbols.String( entry.sym ); bool whitelist = g_WhiteList.Find( entry.sym ) != g_WhiteList.InvalidIndex(); if ( gameref || whitelist ) { entry.referenced = gameref ? REFERENCED_GAME : REFERENCED_WHITELIST; totalReferencedDiskSize += entry.size; if ( entry.referenced == REFERENCED_WHITELIST ) { logprint( CFmtStr( "%swhitelist.lst", g_szReslistDir ), "\"%s\\%s\"\n", modname, fn ); totalWhiteListDiskSize += entry.size; ++whitelisted; } ++refcounted; } } vprint( 0, "Found %i referenced (%i whitelist) files in tree, %s\n", refcounted, whitelisted, Q_pretifymem( totalReferencedDiskSize, 2 ) ); vprint( 0, "%s appear unused\n", Q_pretifymem( totalDiskSize - totalReferencedDiskSize, 2 ) ); // Now sort and dump the unreferenced ones.. vprint( 0, "Sorting unreferenced files list...\n" ); CUtlRBTree< FileEntry, int > unreftree( 0, 0, FileEntryLessFunc ); for ( i = 0; i < c; ++i ) { FileEntry & entry = contentfiles[ i ]; if ( entry.referenced != REFERENCED_NO ) continue; unreftree.Insert( entry ); } // Now walk the unref tree in order i = unreftree.FirstInorder(); invalidindex = unreftree.InvalidIndex(); int index = 0; while ( i != invalidindex ) { FileEntry & entry = unreftree[ i ]; if ( showreferencedfiles ) { vprint( 1, "%6i %12s: %s\n", ++index, Q_pretifymem( entry.size, 2 ), g_Analysis.symbols.String( entry.sym ) ); } i = unreftree.NextInorder( i ); } if ( showmapfileusage ) { vprint( 0, "Writing referenced.csv...\n" ); // Now walk the list of referenced files and print out how many and which maps reference them i = tree.FirstInorder(); invalidindex = tree.InvalidIndex(); index = 0; while ( i != invalidindex ) { ReferencedFile & entry = tree[ i ]; char ext[ 32 ]; Q_ExtractFileExtension( g_Analysis.symbols.String( entry.sym ), ext, sizeof( ext ) ); logprint( "referenced.csv", "\"%s\",\"%s\",%d", g_Analysis.symbols.String( entry.sym ), ext, entry.maplist.Count() ); int mapcount = entry.maplist.Count(); for ( int j = 0 ; j < mapcount; ++j ) { char basemap[ 128 ]; Q_FileBase( g_Analysis.symbols.String( entry.maplist[ j ] ), basemap, sizeof( basemap ) ); logprint( "referenced.csv", ",\"%s\"", basemap ); } logprint( "referenced.csv", "\n" ); i = tree.NextInorder( i ); } } vprint( 0, "\nBuilding directory summary list...\n" ); // Now build summaries by root branch off of gamedir (e.g., for sound, materials, models, etc.) CUtlDict< DirEntry, int > directories; invalidindex = directories.InvalidIndex(); for ( i = 0; i < c; ++i ) { FileEntry & entry = contentfiles[ i ]; // Get the dir name char const *dirname = g_Analysis.symbols.String( entry.sym ); const char *backslash = strstr( dirname, "\\" ); char dir[ 256 ]; if ( !backslash ) { dir[0] = 0; } else { Q_strncpy( dir, dirname, backslash - dirname + 1); } int idx = directories.Find( dir ); if ( idx == invalidindex ) { DirEntry foo; idx = directories.Insert( dir, foo ); } DirEntry & de = directories[ idx ]; de.total += entry.size; if ( entry.referenced == REFERENCED_NO ) { de.unreferenced += entry.size; } if ( entry.referenced == REFERENCED_WHITELIST ) { de.whitelist += entry.size; } } if ( spewdeletions ) { // Spew deletion commands to console if ( immediatedelete ) { vprint( 0, "\n\nDeleting files...\n" ); } else { vprint( 0, "\n\nGenerating deletions.bat\n" ); } i = unreftree.FirstInorder(); invalidindex = unreftree.InvalidIndex(); float deletionSize = 0.0f; int deletionCount = 0; while ( i != invalidindex ) { FileEntry & entry = unreftree[ i ]; i = unreftree.NextInorder( i ); // Don't delete stuff that's in the white list if ( g_WhiteList.Find( entry.sym ) != g_WhiteList.InvalidIndex() ) { if ( verbose ) { vprint( 0, "whitelist blocked deletion of %s\n", g_Analysis.symbols.String( entry.sym ) ); } continue; } ++deletionCount; deletionSize += entry.size; if ( immediatedelete ) { if ( _chmod( g_Analysis.symbols.String( entry.sym ), _S_IWRITE ) == -1 ) { vprint( 0, "Could not find file %s\n", g_Analysis.symbols.String( entry.sym ) ); } if ( _unlink( g_Analysis.symbols.String( entry.sym ) ) == -1 ) { vprint( 0, "Could not delete file %s\n", g_Analysis.symbols.String( entry.sym ) ); } if ( deletionCount % 1000 == 0 ) { vprint( 0, "...deleted %i files\n", deletionCount ); } } else { logprint( "deletions.bat", "del \"%s\" /f\n", g_Analysis.symbols.String( entry.sym ) ); } } vprint( 0, "\nFile deletion (%d files, %s)\n\n", deletionCount, Q_pretifymem(deletionSize, 2) ); } double grand_total = 0; double grand_total_unref = 0; double grand_total_white = 0; char totalstring[ 20 ]; char unrefstring[ 20 ]; char refstring[ 20 ]; char whiteliststring[ 20 ]; vprint( 0, "---------------------------------------- Summary ----------------------------------------\n" ); vprint( 0, "% 15s % 15s % 15s % 15s %12s\n", "Referenced", "WhiteListed", "Unreferenced", "Total", "Directory" ); // Now walk the dictionary in order i = directories.First(); while ( i != invalidindex ) { DirEntry & de = directories[ i ]; double remainder = de.total - de.unreferenced; float percent_unref = 0.0f; float percent_white = 0.0f; if ( de.total > 0 ) { percent_unref = 100.0f * (float)de.unreferenced / (float)de.total; percent_white = 100.0f * (float)de.whitelist / (float)de.total; } Q_strncpy( totalstring, Q_pretifymem( de.total, 2 ), sizeof( totalstring ) ); Q_strncpy( unrefstring, Q_pretifymem( de.unreferenced, 2 ), sizeof( unrefstring ) ); Q_strncpy( refstring, Q_pretifymem( remainder, 2 ), sizeof( refstring ) ); Q_strncpy( whiteliststring, Q_pretifymem( de.whitelist, 2 ), sizeof( whiteliststring ) ); vprint( 0, "%15s (%8.3f%%) %15s (%8.3f%%) %15s (%8.3f%%) %15s => dir: %s\n", refstring, 100.0f - percent_unref, whiteliststring, percent_white, unrefstring, percent_unref, totalstring, directories.GetElementName( i ) ); grand_total += de.total; grand_total_unref += de.unreferenced; grand_total_white += de.whitelist; i = directories.Next( i ); } Q_strncpy( totalstring, Q_pretifymem( grand_total, 2 ), sizeof( totalstring ) ); Q_strncpy( unrefstring, Q_pretifymem( grand_total_unref, 2 ), sizeof( unrefstring ) ); Q_strncpy( refstring, Q_pretifymem( grand_total - grand_total_unref, 2 ), sizeof( refstring ) ); Q_strncpy( whiteliststring, Q_pretifymem( grand_total_white, 2 ), sizeof( whiteliststring ) ); double percent_unref = 100.0 * grand_total_unref / grand_total; double percent_white = 100.0 * grand_total_white / grand_total; vprint( 0, "-----------------------------------------------------------------------------------------\n" ); vprint( 0, "%15s (%8.3f%%) %15s (%8.3f%%) %15s (%8.3f%%) %15s\n", refstring, 100.0f - percent_unref, whiteliststring, percent_white, unrefstring, percent_unref, totalstring ); }
//----------------------------------------------------------------------------- // 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 ); }
float GetSubdivSizeForFogVolume( int fogVolumeID ) { Assert( fogVolumeID >= 0 && fogVolumeID < g_WaterTexInfos.Count() ); return g_WaterTexInfos[fogVolumeID].m_SubdivSize; }