// ----------------------------------------------------------------------------- // // 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: Updates the current sequence info with the new packet // scans the message window to see if future packets can be used //----------------------------------------------------------------------------- void CTrackerNET::UpdateSequence(NetworkTarget_t *target, int targetIndex, int seqNum) { // update sequence target->incomingSequence = seqNum; // check to see when we should send acknowledgement if (!target->needAck) { target->ackTime = m_pThreads->GetTime() + ACK_DELAY; target->needAck = true; // move the target to the end of the ack list m_TargetList.Unlink(targetIndex); if (m_TargetList.IsValidIndex(m_iHighestAckTarget) && m_TargetList.IsInList(m_iHighestAckTarget)) { m_TargetList.LinkAfter(m_iHighestAckTarget, targetIndex); } else { m_TargetList.LinkToHead(targetIndex); } // set the need high mark for the packets that need ack m_iHighestAckTarget = targetIndex; } // check to see if packets in the window are now valid while (target->m_MessageWindow.Count()) { int index = target->m_MessageWindow.Head(); if (target->m_MessageWindow[index].sequenceNumber == target->incomingSequence + 1) { // this is the next message // update sequence numbers target->incomingSequence = target->m_MessageWindow[index].sequenceNumber; // add message to received list int receivedIndex = m_ReceivedMsgs.AddToTail(); m_ReceivedMsgs[receivedIndex].message = target->m_MessageWindow[index].message; WriteToLog("-> Recv match in window (is: %d)\n", target->m_MessageWindow[index].sequenceNumber); // remove message from window target->m_MessageWindow.Remove(index); } else { // no more break; } } }