void CGameGibManager::AddGibToLRU( CBaseAnimating *pEntity )
{
	int i, next;

	if ( pEntity == NULL )
		return;

	//Find stale gibs.
	for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next )
	{
		next = m_LRU.Next(i);

		if ( m_LRU[i].Get() == NULL )
		{
			m_LRU.Remove(i);
		}
	}

	// We're not tracking gibs at the moment
	if ( m_iCurrentMaxPieces <= 0 )
		return;

	while ( m_LRU.Count() >= m_iCurrentMaxPieces )
	{
		i = m_LRU.Head();

		//TODO: Make this fade out instead of pop.
		UTIL_Remove( m_LRU[i] );
		m_LRU.Remove(i);
	}
	
	m_LRU.AddToTail( pEntity );
	m_iLastFrame = gpGlobals->framecount;
}
Example #2
0
// ----------------------------------------------------------------------------- //
// Add/remove decals
// ----------------------------------------------------------------------------- //
DispDecalHandle_t CDispInfo::NotifyAddDecal( decal_t *pDecal )
{
    // FIXME: Add decal retirement...
//	if( m_Decals.Size() < MAX_DISP_DECALS )
//		return;

    // Create a new decal, link it in
    DispDecalHandle_t h = s_DispDecals.Alloc( true );

    // When linking, insert it in sorted order based on material enumeration ID
    // This will help us when rendering later
    int last = DISP_DECAL_HANDLE_INVALID;
    int i = m_FirstDecal;
    int enumerationId = pDecal->material->GetEnumerationID();
    while( i != s_DispDecals.InvalidIndex() )
    {
        int testId = s_DispDecals[i].m_pDecal->material->GetEnumerationID();
        if (enumerationId <= testId)
            break;

        last = i;
        i = s_DispDecals.Next(i);
    }

    // NOTE: when the list is used in multimode, we can't use LinkBefore( i, INVALID_INDEX ),
    // since the Head and Tail of the linked list are meaningless...

    if ( last != DISP_DECAL_HANDLE_INVALID )
        s_DispDecals.LinkAfter( last, h );
    else
    {
        s_DispDecals.LinkBefore( m_FirstDecal, h );
        m_FirstDecal = h;
    }

    CDispDecal *pDispDecal = &s_DispDecals[h];
    pDispDecal->m_pDecal = pDecal;
    pDispDecal->m_FirstFragment = DISP_DECAL_FRAGMENT_HANDLE_INVALID;
    pDispDecal->m_nVerts = 0;
    pDispDecal->m_nTris = 0;

    // Setup a basis for it.
    CDecalVert *pOutVerts = NULL;
    R_SetupDecalClip(
        pOutVerts,
        pDispDecal->m_pDecal,
        MSurf_Plane( m_ParentSurfID ).normal,
        pDispDecal->m_pDecal->material,
        pDispDecal->m_TextureSpaceBasis,
        pDispDecal->m_DecalWorldScale );

    // Recurse and precalculate which nodes this thing can touch.
    SetupDecalNodeIntersect(
        m_pPowerInfo->m_RootNode,
        0,			// node bit index into CDispDecal::m_NodeIntersects
        pDispDecal,
        0 );

    return h;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *focus - 
//-----------------------------------------------------------------------------
void CInputWin32::PanelDeleted(VPANEL focus)
{
	HInputContext i;
	for (i = m_Contexts.Head(); i != m_Contexts.InvalidIndex(); i = m_Contexts.Next(i) )
	{
		PanelDeleted( focus, m_Contexts[i] );
	}
	PanelDeleted( focus, m_DefaultInputContext );
}
void CGroundLine::DrawAllGroundLines()
{
	VPROF("CGroundLine::DrawAllGroundLines()");
	unsigned short i;
	for( i = s_GroundLines.Head(); i != s_GroundLines.InvalidIndex(); i = s_GroundLines.Next(i) )
	{
		s_GroundLines[i]->Draw();
	}
}
Example #5
0
void CDispInfo::ClearAllShadowDecalFragments()
{
    // Iterate over all shadow decals on the displacement
    DispShadowHandle_t h = m_FirstShadowDecal;
    while( h != DISP_SHADOW_HANDLE_INVALID )
    {
        ClearShadowDecalFragments( h );
        h = s_DispShadowDecals.Next(h);
    }
}
Example #6
0
void CVGui::DestroyAllContexts( )
{
	HContext next;
	HContext i = m_Contexts.Head();
	while (i != m_Contexts.InvalidIndex())
	{
		next = m_Contexts.Next(i);
		DestroyContext( i );
		i = next;
	}
}
Example #7
0
//-----------------------------------------------------------------------------
// Enumerate elements in a particular leaf
//-----------------------------------------------------------------------------
int CBSPTreeData::CountElementsInLeaf( int leaf )
{
	int i;
	int nCount = 0;
	for( i = m_Leaf[leaf].m_FirstElement; i != m_LeafElements.InvalidIndex(); i = m_LeafElements.Next(i) )
	{
		++nCount;
	}

	return nCount;
}
Example #8
0
void CDispInfo::RemoveShadowDecal( DispShadowHandle_t h )
{
    // Any fragments we got we don't need
    ClearShadowDecalFragments(h);

    // Reset the head of the list
    if (m_FirstShadowDecal == h)
        m_FirstShadowDecal = s_DispShadowDecals.Next(h);

    // Blow away the decal
    s_DispShadowDecals.Free( h );
}
Example #9
0
void CBSPTreeData::RemoveFromTree( BSPTreeDataHandle_t handle )
{
	// Iterate over the list of all leaves the handle is in
	unsigned short i = m_Handles[handle].m_LeafList;
	while (i != m_HandleLeafList.InvalidIndex())
	{
		int leaf = m_HandleLeafList[i].m_Leaf;
		unsigned short leafElement = m_HandleLeafList[i].m_LeafElementIndex; 

		// Unhook the handle from the leaf handle list
		if (leafElement == m_Leaf[leaf].m_FirstElement)
			m_Leaf[leaf].m_FirstElement = m_LeafElements.Next(leafElement);
		m_LeafElements.Free(leafElement);

		unsigned short prevNode = i;
		i = m_HandleLeafList.Next(i);
		m_HandleLeafList.Free(prevNode);
	}

	m_Handles[handle].m_LeafList = m_HandleLeafList.InvalidIndex();
}
void TimeoutJobIDs()
{
	double flCurTime = Plat_FloatTime();
	
	int iNext;
	for ( int i=g_JobMemories.Head(); i != g_JobMemories.InvalidIndex(); i=iNext )
	{
		iNext = g_JobMemories.Next( i );
		
		if ( (flCurTime - g_JobMemories[i].m_Time) > JOB_MEMORY_DURATION )
			g_JobMemories.Remove( i );
	}
}
bool FindJobMemory( int id[4] )
{
	int iNext;
	for ( int i=g_JobMemories.Head(); i != g_JobMemories.InvalidIndex(); i=iNext )
	{
		iNext = g_JobMemories.Next( i );
		
		CJobMemory *pJob = &g_JobMemories[i];
		if ( memcmp( pJob->m_ID, id, sizeof( pJob->m_ID ) ) == 0 )
			return true;
	}
	return false;
}
static bool EventCollidesWithRows( CUtlLinkedList< CChoreoEvent*, int >& list, CChoreoEvent *event, char *trackName, size_t trackNameLength )
{
    float st = event->GetStartTime();
    float ed = event->GetEndTime();

    for ( int i = list.Head(); i != list.InvalidIndex(); i = list.Next( i ) )
    {
        CChoreoEvent *test = list[ i ];

        float teststart = test->GetStartTime();
        float testend = test->GetEndTime();

        // See if spans overlap
        if ( teststart >= ed )
            continue;
        if ( testend <= st )
            continue;

        // Now see if they deal with the same flex controller
        int tc = event->GetNumFlexAnimationTracks();
        for ( int track = 0; track < tc; ++track )
        {
            CFlexAnimationTrack *t = event->GetFlexAnimationTrack( track );
            if ( !t->IsTrackActive() )
            {
                continue;
            }

            int sampleCountNormal = t->GetNumSamples( 0 );
            int sampleCountBalance = 0;
            if ( t->IsComboType() )
            {
                sampleCountBalance = t->GetNumSamples( 1 );
            }

            if ( !sampleCountNormal && !sampleCountBalance )
                continue;

            // Otherwise, see if the test track has this as an active track
            if ( IsFlexTrackBeingUsed( test, t->GetFlexControllerName() ) )
            {
                Q_strncpy( trackName, t->GetFlexControllerName(), trackNameLength );
                return true;
            }
        }
        return false;
    }

    return false;
}
Example #13
0
//-----------------------------------------------------------------------------
// Clears shadow decal fragment lists
//-----------------------------------------------------------------------------
void CDispInfo::ClearShadowDecalFragments( DispShadowHandle_t h )
{
    // Iterate over all fragments associated with each shadow decal
    CDispShadowDecal& decal = s_DispShadowDecals[h];
    DispShadowFragmentHandle_t f = decal.m_FirstFragment;
    DispShadowFragmentHandle_t next;
    while( f != DISP_SHADOW_FRAGMENT_HANDLE_INVALID )
    {
        next = s_DispShadowFragments.Next(f);
        s_DispShadowFragments.Free(f);
        f = next;
    }

    // Blat out the list
    decal.m_FirstFragment = DISP_SHADOW_FRAGMENT_HANDLE_INVALID;

    // Mark is as not computed
    decal.m_Flags &= ~CDispDecalBase::FRAGMENTS_COMPUTED;

    // Update the number of triangles in the decal
    decal.m_nTris = 0;
    decal.m_nVerts = 0;
}
Example #14
0
//-----------------------------------------------------------------------------
// Enumerate elements in a particular leaf
//-----------------------------------------------------------------------------
bool CBSPTreeData::EnumerateElementsInLeaf( int leaf, IBSPTreeDataEnumerator* pEnum, int context )
{
#ifdef DBGFLAG_ASSERT
	// The enumeration method better damn well not change this list...
	int nCount = CountElementsInLeaf(leaf);
#endif

	unsigned short idx = m_Leaf[leaf].m_FirstElement;
	while (idx != m_LeafElements.InvalidIndex())
	{
		BSPTreeDataHandle_t handle = m_LeafElements[idx];
		if (!pEnum->EnumerateElement( m_Handles[handle].m_UserId, context ))
		{
			Assert( CountElementsInLeaf(leaf) == nCount );
			return false;
		}
		idx = m_LeafElements.Next(idx);
	}

	Assert( CountElementsInLeaf(leaf) == nCount );

	return true;
}
Example #15
0
// ----------------------------------------------------------------------------- //
// Adds shadow rendering data to a particular mesh builder
// ----------------------------------------------------------------------------- //
int DispInfo_AddShadowsToMeshBuilder( CMeshBuilder& meshBuilder,
                                      DispShadowHandle_t h, int baseIndex )
{
#ifndef SWDS
    if ( !r_DrawDisp.GetBool() )
    {
        return baseIndex;
    }

    CDispShadowDecal* pShadowDecal = &s_DispShadowDecals[h];
    int shadow = pShadowDecal->m_Shadow;
    ShadowInfo_t const& info = g_pShadowMgr->GetInfo( shadow );

    // It had better be computed by now...
    Assert( pShadowDecal->m_Flags & CDispDecalBase::FRAGMENTS_COMPUTED );

#ifdef _DEBUG
    int triCount = 0;
    int vertCount = 0;
#endif

    DispShadowFragmentHandle_t f = pShadowDecal->m_FirstFragment;
    while ( f != DISP_SHADOW_FRAGMENT_HANDLE_INVALID )
    {
        CDispShadowFragment& fragment = s_DispShadowFragments[f];

        // Add in the vertices + indices, use two loops to minimize tests...
        int i;
        for ( i = 0; i < fragment.m_nVerts - 2; ++i )
        {
            meshBuilder.Position3fv( fragment.m_Verts[i].Base() );

            // Transform + offset the texture coords
            Vector2D texCoord;
            Vector2DMultiply( fragment.m_TCoords[i].AsVector2D(), info.m_TexSize, texCoord );
            texCoord += info.m_TexOrigin;
            meshBuilder.TexCoord2fv( 0, texCoord.Base() );

            unsigned char c = g_pShadowMgr->ComputeDarkness( fragment.m_TCoords[i].z, info );
            meshBuilder.Color4ub( c, c, c, c );

            meshBuilder.AdvanceVertex();

            meshBuilder.Index( baseIndex );
            meshBuilder.AdvanceIndex();
            meshBuilder.Index( i + baseIndex + 1 );
            meshBuilder.AdvanceIndex();
            meshBuilder.Index( i + baseIndex + 2 );
            meshBuilder.AdvanceIndex();

#ifdef _DEBUG
            ++triCount;
            ++vertCount;
#endif
        }

        for ( ; i < fragment.m_nVerts; ++i )
        {
            meshBuilder.Position3fv( fragment.m_Verts[i].Base() );

            // Transform + offset the texture coords
            Vector2D texCoord;
            Vector2DMultiply( fragment.m_TCoords[i].AsVector2D(), info.m_TexSize, texCoord );
            texCoord += info.m_TexOrigin;
            meshBuilder.TexCoord2fv( 0, texCoord.Base() );

            unsigned char c = g_pShadowMgr->ComputeDarkness( fragment.m_TCoords[i].z, info );
            meshBuilder.Color4ub( c, c, c, c );

            meshBuilder.AdvanceVertex();

#ifdef _DEBUG
            ++vertCount;
#endif
        }

        baseIndex += fragment.m_nVerts;

        f = s_DispShadowFragments.Next(f);
    }

#ifdef _DEBUG
    Assert( triCount == pShadowDecal->m_nTris );
    Assert( vertCount == pShadowDecal->m_nVerts );
#endif

    return baseIndex;
#else
    return 0;
#endif
}
Example #16
0
void DispInfo_DrawDecals( CDispInfo *visibleDisps[MAX_MAP_DISPINFO], int nVisibleDisps )
{
#ifndef SWDS
    VPROF("DispInfo_DrawDecals");
    if( !nVisibleDisps )
        return;

    int nTrisDrawn = 0;

    // FIXME: We should bucket all decals (displacement + otherwise)
    // and sort them by material enum id + lightmap
    // To do this, we need to associate a sort index from 0-n for all
    // decals we've seen this level. Then we add those decals to the
    // appropriate search list, (sorted by lightmap id)?

    for( int i=0; i < nVisibleDisps; i++ )
    {
        CDispInfo *pDisp = visibleDisps[i];

        // Don't bother if there's no decals
        if( pDisp->m_FirstDecal == DISP_DECAL_HANDLE_INVALID )
            continue;

        materialSystemInterface->BindLightmapPage( pDisp->m_pMesh->m_pGroup->m_LightmapPageID );

        // At the moment, all decals in a single displacement are sorted by material
        // so we get a little batching at least
        DispDecalHandle_t d = pDisp->m_FirstDecal;
        while( d != DISP_DECAL_HANDLE_INVALID )
        {
            CDispDecal& decal = s_DispDecals[d];

            // Compute decal fragments if we haven't already....
            if ((decal.m_Flags & CDispDecalBase::FRAGMENTS_COMPUTED) == 0)
            {
                pDisp->GenerateDecalFragments( pDisp->m_pPowerInfo->m_RootNode, 0, d, &decal );
            }

            // Don't draw if there's no triangles
            if (decal.m_nTris == 0)
            {
                d = s_DispDecals.Next(d);
                continue;
            }

            // Now draw all the fragments with this material.
            IMaterial* pMaterial = decal.m_pDecal->material;

            IMesh *pMesh = materialSystemInterface->GetDynamicMesh( true, NULL, NULL, pMaterial );

            CMeshBuilder meshBuilder;
            meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, decal.m_nVerts, decal.m_nTris * 3 );

            int baseIndex = 0;
            DispDecalFragmentHandle_t f = decal.m_FirstFragment;
            while (f != DISP_DECAL_FRAGMENT_HANDLE_INVALID)
            {
                CDispDecalFragment& fragment = s_DispDecalFragments[f];
                int v;
                for ( v = 0; v < fragment.m_nVerts - 2; ++v)
                {
                    meshBuilder.Position3fv( fragment.m_pVerts[v].m_vPos.Base() );
                    meshBuilder.TexCoord2fv( 0, fragment.m_pVerts[v].m_tCoords.Base() );
                    meshBuilder.TexCoord2fv( 1, fragment.m_pVerts[v].m_LMCoords.Base() );
                    meshBuilder.AdvanceVertex();

                    meshBuilder.Index( baseIndex );
                    meshBuilder.AdvanceIndex();
                    meshBuilder.Index( v + baseIndex + 1 );
                    meshBuilder.AdvanceIndex();
                    meshBuilder.Index( v + baseIndex + 2 );
                    meshBuilder.AdvanceIndex();
                }

                meshBuilder.Position3fv( fragment.m_pVerts[v].m_vPos.Base() );
                meshBuilder.TexCoord2fv( 0, fragment.m_pVerts[v].m_tCoords.Base() );
                meshBuilder.TexCoord2fv( 1, fragment.m_pVerts[v].m_LMCoords.Base() );
                meshBuilder.AdvanceVertex();

                ++v;
                meshBuilder.Position3fv( fragment.m_pVerts[v].m_vPos.Base() );
                meshBuilder.TexCoord2fv( 0, fragment.m_pVerts[v].m_tCoords.Base() );
                meshBuilder.TexCoord2fv( 1, fragment.m_pVerts[v].m_LMCoords.Base() );
                meshBuilder.AdvanceVertex();

                baseIndex += fragment.m_nVerts;

                f = s_DispDecalFragments.Next(f);
            }
            meshBuilder.End( false, true );

            nTrisDrawn += decal.m_nTris * pMaterial->GetNumPasses();

            d = s_DispDecals.Next(d);
        }
    }
    g_EngineStats.IncrementCountedStat( ENGINE_STATS_DECAL_TRIANGLES, nTrisDrawn );
#endif
}