/* ================== SV_WriteClientdataToMessage ================== */ void SV_WriteClientdataToMessage( sv_client_t *cl, sizebuf_t *msg ) { clientdata_t nullcd; clientdata_t *from_cd, *to_cd; weapon_data_t nullwd; weapon_data_t *from_wd, *to_wd; client_frame_t *frame; edict_t *clent; int i; Q_memset( &nullcd, 0, sizeof( nullcd )); clent = cl->edict; frame = &cl->frames[cl->netchan.outgoing_sequence & SV_UPDATE_MASK]; frame->senttime = host.realtime; frame->raw_ping = -1.0f; frame->latency = -1.0f; if( cl->chokecount != 0 ) { BF_WriteByte( msg, svc_chokecount ); BF_WriteByte( msg, cl->chokecount ); cl->chokecount = 0; } // update client fixangle switch( clent->v.fixangle ) { case 1: BF_WriteByte( msg, svc_setangle ); BF_WriteBitAngle( msg, clent->v.angles[0], 16 ); BF_WriteBitAngle( msg, clent->v.angles[1], 16 ); BF_WriteBitAngle( msg, clent->v.angles[2], 16 ); clent->v.effects |= EF_NOINTERP; break; case 2: BF_WriteByte( msg, svc_addangle ); BF_WriteBitAngle( msg, clent->v.avelocity[1], 16 ); clent->v.avelocity[1] = 0.0f; break; } clent->v.fixangle = 0; // reset fixangle clent->v.pushmsec = 0; // reset net framenum Q_memset( &frame->clientdata, 0, sizeof( frame->clientdata )); // update clientdata_t svgame.dllFuncs.pfnUpdateClientData( clent, cl->local_weapons, &frame->clientdata ); BF_WriteByte( msg, svc_clientdata ); if( cl->hltv_proxy ) return; // don't send more nothing if( cl->delta_sequence == -1 ) from_cd = &nullcd; else from_cd = &cl->frames[cl->delta_sequence & SV_UPDATE_MASK].clientdata; to_cd = &frame->clientdata; if( cl->delta_sequence == -1 ) { BF_WriteOneBit( msg, 0 ); // no delta-compression } else { BF_WriteOneBit( msg, 1 ); // we are delta-ing from BF_WriteByte( msg, cl->delta_sequence ); } // write clientdata_t MSG_WriteClientData( msg, from_cd, to_cd, sv.time ); if( cl->local_weapons && svgame.dllFuncs.pfnGetWeaponData( clent, frame->weapondata )) { Q_memset( &nullwd, 0, sizeof( nullwd )); for( i = 0; i < 64; i++ ) { if( cl->delta_sequence == -1 ) from_wd = &nullwd; else from_wd = &cl->frames[cl->delta_sequence & SV_UPDATE_MASK].weapondata[i]; to_wd = &frame->weapondata[i]; MSG_WriteWeaponData( msg, from_wd, to_wd, sv.time, i ); } } // end marker BF_WriteOneBit( msg, 0 ); }
/* ===================== Delta_WriteField write fields by offsets assume from and to is valid ===================== */ qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, void *to, float timebase ) { qboolean bSigned = ( pField->flags & DT_SIGNED ) ? true : false; float flValue, flAngle, flTime; uint iValue; const char *pStr; if( Delta_CompareField( pField, from, to, timebase )) { BF_WriteOneBit( msg, 0 ); // unchanged return false; } BF_WriteOneBit( msg, 1 ); // changed if( pField->flags & DT_BYTE ) { iValue = *(byte *)((byte *)to + pField->offset ); iValue = Delta_ClampIntegerField( iValue, bSigned, pField->bits ); if ( pField->multiplier != 1.0f ) iValue *= pField->multiplier; BF_WriteBitLong( msg, iValue, pField->bits, bSigned ); } else if( pField->flags & DT_SHORT ) { iValue = *(word *)((byte *)to + pField->offset ); iValue = Delta_ClampIntegerField( iValue, bSigned, pField->bits ); if ( pField->multiplier != 1.0f ) iValue *= pField->multiplier; BF_WriteBitLong( msg, iValue, pField->bits, bSigned ); } else if( pField->flags & DT_INTEGER ) { iValue = *(uint *)((byte *)to + pField->offset ); iValue = Delta_ClampIntegerField( iValue, bSigned, pField->bits ); if ( pField->multiplier != 1.0f ) iValue *= pField->multiplier; BF_WriteBitLong( msg, iValue, pField->bits, bSigned ); } else if( pField->flags & DT_FLOAT ) { #ifdef __arm__ memcpy(&flValue,(byte *)to + pField->offset, sizeof(float) ); #else flValue = *(float *)((byte *)to + pField->offset ); #endif iValue = (int)(flValue * pField->multiplier); BF_WriteBitLong( msg, iValue, pField->bits, bSigned ); } else if( pField->flags & DT_ANGLE ) { #ifdef __arm__ memcpy(&flAngle,(byte *)to + pField->offset, sizeof(float) ); #else flAngle = *(float *)((byte *)to + pField->offset ); #endif // NOTE: never applies multipliers to angle because // result may be wrong on client-side BF_WriteBitAngle( msg, flAngle, pField->bits ); } else if( pField->flags & DT_TIMEWINDOW_8 ) { #ifdef __arm__ memcpy(&flValue,(byte *)to + pField->offset, sizeof(float) ); #else flValue = *(float *)((byte *)to + pField->offset ); #endif flTime = (timebase * 100.0f) - (flValue * 100.0f); #if 1 iValue = (uint)fabs( flTime ); #else iValue = (uint)fabs( flTime ); if (flTime<0.0f) { iValue |= 0x80000000; } #endif BF_WriteBitLong( msg, iValue, pField->bits, bSigned ); } else if( pField->flags & DT_TIMEWINDOW_BIG ) { #ifdef __arm__ memcpy(&flValue,(byte *)to + pField->offset, sizeof(float) ); #else flValue = *(float *)((byte *)to + pField->offset ); #endif flTime = (timebase * pField->multiplier) - (flValue * pField->multiplier); #if 1 iValue = (uint)fabs( flTime ); #else iValue = (uint)fabs( flTime ); if (flTime<0.0f) { iValue |= 0x80000000; } #endif BF_WriteBitLong( msg, iValue, pField->bits, bSigned ); } else if( pField->flags & DT_STRING ) { pStr = (char *)((byte *)to + pField->offset ); BF_WriteString( msg, pStr ); } return true; }