From 8ae319a1d251b7fb6c20114a4ecd6e2bd50610f5 Mon Sep 17 00:00:00 2001 From: RaphaelIT7 <64648134+RaphaelIT7@users.noreply.github.com> Date: Sun, 1 Feb 2026 10:51:07 +0100 Subject: [PATCH] engine: rework how channel states & subchannels are handled --- engine/net_chan.cpp | 44 +++++++++++++++++--------------------------- engine/net_chan.h | 8 +++++--- public/bitvec.h | 21 ++++++++++++++++++++- public/const.h | 10 ++++++++++ 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/engine/net_chan.cpp b/engine/net_chan.cpp index c17f852e9..4405c0ad0 100644 --- a/engine/net_chan.cpp +++ b/engine/net_chan.cpp @@ -59,8 +59,6 @@ extern int NET_ReceiveStream( socket_handle nSock, char * buf, int len, int fla #define BYTES2FRAGMENTS(i) (((i)+FRAGMENT_SIZE-1)/FRAGMENT_SIZE) -#define FLIPBIT(v,b) if (v&b) v &= ~b; else v |= b; - // We only need to checksum packets on the PC and only when we're actually sending them over the network. static bool ShouldChecksumPackets() { @@ -105,9 +103,7 @@ void CNetChan::Clear() { if ( m_SubChannels[i].state == SUBCHANNEL_TOSEND ) { - int bit = 1<index; - - FLIPBIT(m_nOutReliableState, bit); + m_nOutReliableState.Flip(freeSubChan->index); freeSubChan->state = SUBCHANNEL_TOSEND; freeSubChan->sendSeqNr = 0; @@ -1631,7 +1625,7 @@ int CNetChan::SendDatagram(bf_write *datagram) // Note, this only matters on the PC int nCheckSumStart = send.GetNumBytesWritten(); - send.WriteByte ( m_nInReliableState ); + send.WriteBits( m_nInReliableState.Base(), MAX_SUBCHANNELS ); // RaphaelIT7: Originally used WriteByte- was changed to support easy changing of MAX_SUBCHANNELS if ( m_nChokedPackets > 0 ) { @@ -2240,7 +2234,8 @@ int CNetChan::ProcessPacketHeader( netpacket_t * packet ) } } - int relState = packet->message.ReadByte(); // reliable state of 8 subchannels + CBitVec relState; // RaphaelIT7: Added to allow easy changing of MAX_SUBCHANNELS + packet->message.ReadBits( relState.Base(), MAX_SUBCHANNELS ); // reliable state of all subchannels (RaphaelIT7: Previously ued ReadByte though was changed) int nChoked = 0; // read later if choked flag is set int i,j; @@ -2309,14 +2304,12 @@ int CNetChan::ProcessPacketHeader( netpacket_t * packet ) for ( i = 0; iindex == i); + Assert( subchan->index == i ); - if ( (m_nOutReliableState & bitmask) == (relState & bitmask) ) + if ( m_nOutReliableState.CompareBit(relState, i) ) { if ( subchan->state == SUBCHANNEL_DIRTY ) { @@ -2366,9 +2359,7 @@ int CNetChan::ProcessPacketHeader( netpacket_t * packet ) else if ( subchan->state == SUBCHANNEL_DIRTY ) { // remote host lost dirty channel data, flip bit back - int bit = 1<index; // flip bit back since data was send yet - - FLIPBIT(m_nOutReliableState, bit); + m_nOutReliableState.Flip(subchan->index); subchan->Free(); } @@ -2447,9 +2438,8 @@ void CNetChan::ProcessPacket( netpacket_t * packet, bool bHasHeader ) if ( flags & PACKET_FLAG_RELIABLE ) { - int i, bit = 1< m_nOutReliableState; // RaphaelIT7: Changed to use a CBitVec to allow easy changing of MAX_SUBCHANNELS // state of incoming reliable data - int m_nInReliableState; + CBitVec m_nInReliableState; // RaphaelIT7: Changed to use a CBitVec to allow easy changing of MAX_SUBCHANNELS int m_nChokedPackets; //number of choked packets diff --git a/public/bitvec.h b/public/bitvec.h index 40a2ca2d8..c0474dcdc 100644 --- a/public/bitvec.h +++ b/public/bitvec.h @@ -246,6 +246,7 @@ class CBitVecT : public BASE_OPS void CopyTo(CBitVecT *out) const; void Copy( const CBitVecT &other, int nBits=-1 ); bool Compare( const CBitVecT &other, int nBits=-1 ) const; + bool CompareBit( const CBitVecT &other, int nBit ) const; bool IsAllClear(void) const; // Are all bits zero? bool IsAllSet(void) const; // Are all bits one? @@ -254,7 +255,8 @@ class CBitVecT : public BASE_OPS bool IsBitSet( int bitNum ) const; void Set( int bitNum ); void Set( int bitNum, bool bNewVal ); - void Clear(int bitNum); + void Clear( int bitNum ); + void Flip( int bitNum ); bool TestAndSet(int bitNum); @@ -664,6 +666,14 @@ inline void CBitVecT::Clear(int bitNum) *pInt &= ~BitVec_Bit( bitNum ); } +template +inline void CBitVecT::Flip(int bitNum) +{ + Assert( bitNum >= 0 && bitNum < this->GetNumBits() ); + uint32 *pInt = this->Base() + BitVec_Int( bitNum ); + *pInt ^= BitVec_Bit(bitNum); +} + //----------------------------------------------------------------------------- template @@ -917,6 +927,15 @@ inline bool CBitVecT::Compare( const CBitVecT &other, int nB return ( memcmp( this->Base(), other.Base(), nBytes ) == 0 ); } +template +inline bool CBitVecT::CompareBit(const CBitVecT &other, int bitNum) const +{ + Assert(bitNum >= 0 && bitNum < this->GetNumBits()); + + return (this->Base()[BitVec_Int(bitNum)] & BitVec_Bit(bitNum)) == + (other.Base()[BitVec_Int(bitNum)] & BitVec_Bit(bitNum)); +} + //----------------------------------------------------------------------------- template inline uint32 CBitVecT::GetDWord(int i) const diff --git a/public/const.h b/public/const.h index 6a8d452f3..dcdc5305a 100644 --- a/public/const.h +++ b/public/const.h @@ -12,6 +12,16 @@ #pragma once #endif +// RaphaelIT7: log function for constexpr numbers - mainly used to figure out how many bits for networking are needed for a limit +constexpr int RequiredBits(int v) +{ + int bits = 0; + while ((1 << bits) < v) + ++bits; + + return bits; +} + // the command line param that tells the engine to use steam #define STEAM_PARM "-steam" // the command line param to tell dedicated server to restart