07 Aug 2010

This commit is contained in:
g-cont 2010-08-07 00:00:00 +04:00 committed by Alibek Omarov
parent dbcf0695fe
commit 78a36858fb
36 changed files with 663 additions and 1120 deletions

View File

@ -1229,7 +1229,7 @@ addEntity:
state->mins = pEntity->pev->mins;
state->maxs = pEntity->pev->maxs;
state->flags = pEntity->pev->flags;
state->oldorigin = pEntity->pev->oldorigin;
state->vuser1 = pEntity->pev->oldorigin; // used for portals and skyportals
state->colormap = pEntity->pev->colormap; // attachments
state->rendercolor.r = (byte)pEntity->pev->rendercolor.x;
@ -1238,7 +1238,7 @@ addEntity:
if( pEntity->pev->groundentity )
state->onground = ENTINDEX( pEntity->pev->groundentity );
else state->onground = 0;
else state->onground = -1;
// translate attached entity
if( pEntity->pev->aiment )
@ -1269,8 +1269,6 @@ addEntity:
state->aiment = ENTINDEX( pEntity->pev->aiment );
else state->aiment = 0;
state->viewangles = pEntity->pev->v_angle;
state->idealpitch = pEntity->pev->idealpitch;
state->velocity = pEntity->pev->velocity;
state->basevelocity = pEntity->pev->clbasevelocity;
state->iStepLeft = pEntity->pev->iStepLeft;
@ -1282,7 +1280,6 @@ addEntity:
if( pEntity->pev->weaponmodel != iStringNull )
state->weaponmodel = MODEL_INDEX( STRING( pEntity->pev->weaponmodel ));
else state->weaponmodel = 0;
state->maxspeed = pEntity->pev->maxspeed;
}
else if( state->ed_type == ED_AMBIENT )
{

View File

@ -233,7 +233,6 @@ TYPEDESCRIPTION gEntvarsDescription[] =
DEFINE_ENTITY_FIELD( movedir, FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( angles, FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( oldangles, FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( avelocity, FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( punchangle, FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( v_angle, FIELD_VECTOR ),
@ -273,8 +272,8 @@ TYPEDESCRIPTION gEntvarsDescription[] =
DEFINE_ENTITY_FIELD( sequence, FIELD_INTEGER ),
DEFINE_ENTITY_FIELD( animtime, FIELD_TIME ),
DEFINE_ENTITY_FIELD( framerate, FIELD_FLOAT ),
DEFINE_ENTITY_FIELD_ARRAY( controller, FIELD_CHARACTER, 16 ),
DEFINE_ENTITY_FIELD_ARRAY( blending, FIELD_CHARACTER, 16 ),
DEFINE_ENTITY_FIELD( controller, FIELD_INTEGER ),
DEFINE_ENTITY_FIELD( blending, FIELD_INTEGER ),
DEFINE_ENTITY_FIELD( rendermode, FIELD_INTEGER ),
DEFINE_ENTITY_FIELD( renderamt, FIELD_FLOAT ),

View File

@ -210,8 +210,6 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
ent->v.gravity = state->gravity;
ent->v.solid = state->solid;
ent->v.movetype = state->movetype;
ent->v.flags = state->flags;
ent->v.idealpitch = state->idealpitch;
ent->v.animtime = state->animtime;
if( ent != GetLocalPlayer())
@ -219,43 +217,29 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
ent->v.health = state->health;
}
if( state->onground )
ent->v.groundentity = GetEntityByIndex( state->onground );
else ent->v.groundentity = NULL;
if( state->aiment )
ent->v.aiment = GetEntityByIndex( state->aiment );
else ent->v.aiment = NULL;
if( ent->v.flags & FL_MONSTER )
{
switch( ent->v.movetype )
{
case MOVETYPE_NONE:
case MOVETYPE_STEP:
case MOVETYPE_FLY:
// monster's steps will be interpolated on render-side
ent->v.origin = state->origin;
ent->v.angles = state->angles;
ent->v.oldorigin = prev->origin; // used for lerp 'monster view'
ent->v.oldangles = prev->angles; // used for lerp 'monster view'
break;
default:
ent->v.angles = LerpAngle( prev->angles, state->angles, m_fLerp );
ent->v.origin = LerpPoint( prev->origin, state->origin, m_fLerp );
ent->v.basevelocity = LerpPoint( prev->basevelocity, state->basevelocity, m_fLerp );
break;
}
}
else
switch( ent->v.movetype )
{
case MOVETYPE_NONE:
case MOVETYPE_STEP:
case MOVETYPE_FLY:
// monster's steps will be interpolated on render-side
ent->v.origin = state->origin;
ent->v.angles = state->angles;
ent->v.oldorigin = prev->origin; // used for lerp 'monster view'
ent->v.vuser1 = prev->angles; // used for lerp 'monster view'
break;
default:
ent->v.angles = LerpAngle( prev->angles, state->angles, m_fLerp );
ent->v.basevelocity = LerpPoint( prev->basevelocity, state->basevelocity, m_fLerp );
if( ent != GetLocalPlayer( ))
{
ent->v.origin = LerpPoint( prev->origin, state->origin, m_fLerp );
}
break;
}
// interpolate scale, renderamount etc
@ -280,7 +264,9 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
switch( state->ed_type )
{
case ED_CLIENT:
ent->v.v_angle = LerpAngle( prev->viewangles, state->viewangles, m_fLerp );
// restore viewangles from angles
ent->v.v_angle[PITCH] = -ent->v.angles[PITCH] * 3;
ent->v.v_angle[YAW] = ent->v.angles[YAW];
if( ent != GetLocalPlayer( ))
{
@ -291,7 +277,9 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
else ent->v.fov = LerpPoint( prev->fov, state->fov, m_fLerp );
}
ent->v.maxspeed = state->maxspeed;
if( state->onground != -1 )
ent->v.groundentity = GetEntityByIndex( state->onground );
else ent->v.groundentity = NULL;
ent->v.iStepLeft = state->iStepLeft;
ent->v.flFallVelocity = state->flFallVelocity;
@ -300,7 +288,7 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
case ED_MOVER:
case ED_BSPBRUSH:
ent->v.movedir = BitsToDir( state->body );
ent->v.oldorigin = state->oldorigin;
ent->v.oldorigin = state->vuser1; // used for portals and skyportals
break;
case ED_SKYPORTAL:
{
@ -371,7 +359,6 @@ void HUD_UpdateClientVars( edict_t *ent, const clientdata_t *state, const client
ent->v.velocity = state->velocity;
ent->v.flags = state->flags;
ent->v.health = state->health;
ent->v.flags = state->flags;
ent->v.punchangle = LerpAngle( prev->punchangle, state->punchangle, m_fLerp );
ent->v.view_ofs = LerpPoint( prev->view_ofs, state->view_ofs, m_fLerp );
@ -383,7 +370,7 @@ void HUD_UpdateClientVars( edict_t *ent, const clientdata_t *state, const client
// Water state
ent->v.watertype = state->watertype;
ent->v.waterlevel = state->waterlevel;
// suit and weapon bits
ent->v.weapons = state->weapons;

View File

@ -7,6 +7,9 @@
#include "utils.h"
#include "ev_hldm.h"
#include "r_tempents.h"
#include "ref_params.h"
extern ref_params_t *gpViewParams;
extern "C"
{
@ -181,8 +184,17 @@ void EV_UpadteFlashlight( edict_t *pEnt )
float rgba[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
TraceResult tr;
AngleVectors( pEnt->v.v_angle, forward, NULL, NULL );
vecSrc = pEnt->v.origin +pEnt->v.view_ofs;
if ( EV_IsLocal( pEnt->serialnumber ) )
{
// get the predicted angles
AngleVectors( gpViewParams->cl_viewangles, forward, NULL, NULL );
}
else
{
AngleVectors( pEnt->v.v_angle, forward, NULL, NULL );
}
vecSrc = pEnt->v.origin + pEnt->v.view_ofs;
vecEnd = vecSrc + forward * 512;
UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, pEnt, &tr );

View File

@ -555,7 +555,7 @@ void V_CalcCameraRefdef( ref_params_t *pparams )
v_origin += viewmonster->eyeposition;
if( viewentity->v.movetype == MOVETYPE_STEP )
v_angles = LerpAngle( viewentity->v.oldangles, viewentity->v.angles, m_fLerp );
v_angles = LerpAngle( viewentity->v.vuser1, viewentity->v.angles, m_fLerp );
else v_angles = viewentity->v.angles; // already interpolated
if( gHUD.viewFlags & INVERSE_X ) // inverse X coordinate
@ -580,16 +580,13 @@ void V_CalcCameraRefdef( ref_params_t *pparams )
v_origin = LerpPoint( viewentity->v.oldorigin, viewentity->v.origin, m_fLerp );
else v_origin = viewentity->v.origin; // already interpolated
// calc monster view if supposed
if( viewentity->v.flags & FL_MONSTER && viewmonster )
v_origin += viewmonster->eyeposition;
// add view offset
if( viewmonster ) v_origin += viewmonster->eyeposition;
if( viewentity->v.movetype == MOVETYPE_STEP )
v_angles = LerpAngle( viewentity->v.oldangles, viewentity->v.angles, m_fLerp );
v_angles = LerpAngle( viewentity->v.vuser1, viewentity->v.angles, m_fLerp );
else v_angles = viewentity->v.angles; // already interpolated
if( viewentity->v.flags & FL_PROJECTILE ) // inverse X coordinate
v_angles[0] = -v_angles[0];
pparams->crosshairangle[ROLL] = 1; // crosshair is hided
// refresh position

89
common/cl_entity.h Normal file
View File

@ -0,0 +1,89 @@
//=======================================================================
// Copyright XashXT Group 2008 ©
// cl_entity.h - cient entity
//=======================================================================
#ifndef CL_ENTITY_H
#define CL_ENTITY_H
#define HISTORY_MAX 64 // Must be power of 2
#define HISTORY_MASK ( HISTORY_MAX - 1 )
typedef struct efrag_s
{
struct mleaf_s *leaf;
struct efrag_s *leafnext;
struct cl_entity_s *entity;
struct efrag_s *entnext;
} efrag_t;
typedef struct
{
byte mouthopen; // 0 = mouth closed, 255 = mouth agape
byte sndcount; // counter for running average
int sndavg; // running average
} mouth_t;
typedef struct
{
float prevanimtime;
float sequencetime;
float gaitsequencetime;
byte prevseqblending[16];//MAXSTUDIOBLENDINGS
vec3_t prevorigin;
vec3_t prevangles;
int prevsequence;
int prevgaitsequence;
float prevframe;
float prevgaitframe;
byte prevcontroller[16];
byte prevblending[16];
} latchedvars_t;
typedef struct
{
float animtime; // Time stamp for this movement
vec3_t origin;
vec3_t angles;
} position_history_t;
typedef struct cl_entity_s
{
int index; // Index into cl_entities ( always match actual slot )
int player; // True if this entity is a "player"
entity_state_t baseline; // The original state from which to delta during an uncompressed message
entity_state_t prevstate; // The state information from the penultimate message received from the server
entity_state_t curstate; // The state information from the last message received from server
int current_position; // Last received history update index
position_history_t ph[HISTORY_MAX]; // History of position and angle updates for this player
mouth_t mouth; // For synchronizing mouth movements.
latchedvars_t latched; // Variables used by studio model rendering routines
// Information based on interplocation, extrapolation, prediction, or just copied from last msg received.
float lastmove;
// Actual render position and angles
vec3_t origin;
vec3_t angles;
// Attachment points
vec3_t attachment_origin[16];
vec3_t attachment_angles[16];
// Other entity local information
int trivial_accept;
struct model_s *model; // all visible entities have a model
struct efrag_s *efrag; // linked list of efrags
struct mnode_s *topnode; // for bmodels, first world node that splits bmodel,
// or NULL if not split
int visframe; // last frame this entity was found in an active leaf
} cl_entity_t;
#endif//CL_ENTITY_H

View File

@ -20,11 +20,16 @@ typedef struct entvars_s
vec3_t movedir;
vec3_t angles;
vec3_t oldangles;
vec3_t avelocity; // angular velocity (degrees per second)
vec3_t punchangle; // auto-decaying view angle adjustment
vec3_t v_angle; // Viewing angle (player only)
// For parametric entities
vec3_t endpos;
vec3_t startpos;
float impacttime;
float starttime;
int fixangle; // 0 - nothing, 1 - force view angles, 2 - add avelocity
float idealpitch;
float pitch_speed;
@ -62,8 +67,8 @@ typedef struct entvars_s
float frame; // % playback position in animation sequences (0..255)
float animtime; // world time when frame was set
float framerate; // animation playback rate (-8x to 8x)
byte controller[16]; // bone controller setting (0..255)
byte blending[16]; // blending amount between sub-sequences (0..255)
byte controller[4]; // bone controller setting (0..255)
byte blending[2]; // blending amount between sub-sequences (0..255)
float scale; // sprites and models rendering scale (0..255)
int rendermode;

View File

@ -115,10 +115,6 @@ typedef struct entity_state_s
// FIXME: old xash variables needs to be removed
int flags;
float maxspeed;
float idealpitch;
vec3_t oldorigin; // FIXME: needs to be removed
vec3_t viewangles; // already calculated view angles on server-side
} entity_state_t;
typedef struct clientdata_s

View File

@ -16,7 +16,7 @@ CL_WriteDemoMessage
Dumps the current net message, prefixed by the length
====================
*/
void CL_WriteDemoMessage( bitbuf_t *msg, int head_size )
void CL_WriteDemoMessage( sizebuf_t *msg, int head_size )
{
int len, swlen;
@ -38,7 +38,7 @@ void CL_WriteDemoHeader( const char *name )
char buf_data[MAX_MSGLEN];
entity_state_t *state, nullstate;
movevars_t nullmovevars;
bitbuf_t buf;
sizebuf_t buf;
int i, len;
MsgDev( D_INFO, "recording to %s.\n", name );
@ -156,7 +156,7 @@ void CL_WriteDemoHeader( const char *name )
else BF_WriteByte( &buf, false );
}
BF_WriteDeltaMovevars( &buf, &nullmovevars, &clgame.movevars );
MSG_WriteDeltaMovevars( &buf, &nullmovevars, &clgame.movevars );
// write it to the demo file
len = LittleLong( BF_GetNumBytesWritten( &buf ));
@ -254,7 +254,7 @@ reads demo data and write it to client
*/
void CL_ReadDemoMessage( void )
{
bitbuf_t buf;
sizebuf_t buf;
char buf_data[MAX_MSGLEN];
int r, curSize;
@ -359,7 +359,7 @@ bool CL_GetComment( const char *demoname, char *comment )
char buf_data[MAX_MSGLEN];
int r, maxClients, curSize;
string maptitle;
bitbuf_t buf;
sizebuf_t buf;
if( !comment ) return false;

View File

@ -42,7 +42,7 @@ Parses deltas from the given base and adds the resulting entity
to the current frame
==================
*/
void CL_DeltaEntity( bitbuf_t *msg, frame_t *frame, int newnum, entity_state_t *old, bool unchanged )
void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t *old, bool unchanged )
{
edict_t *ent;
entity_state_t *state;
@ -94,7 +94,7 @@ An svc_packetentities has just been parsed, deal with the
rest of the data stream.
==================
*/
void CL_ParsePacketEntities( bitbuf_t *msg, frame_t *oldframe, frame_t *newframe )
void CL_ParsePacketEntities( sizebuf_t *msg, frame_t *oldframe, frame_t *newframe )
{
int newnum;
entity_state_t *oldstate;
@ -200,7 +200,7 @@ void CL_ParsePacketEntities( bitbuf_t *msg, frame_t *oldframe, frame_t *newframe
CL_ParseClientData
===================
*/
void CL_ParseClientData( frame_t *from, frame_t *to, bitbuf_t *msg )
void CL_ParseClientData( frame_t *from, frame_t *to, sizebuf_t *msg )
{
clientdata_t *cd, *ocd;
clientdata_t dummy;
@ -223,7 +223,7 @@ void CL_ParseClientData( frame_t *from, frame_t *to, bitbuf_t *msg )
CL_ParseFrame
================
*/
void CL_ParseFrame( bitbuf_t *msg )
void CL_ParseFrame( sizebuf_t *msg )
{
int cmd;
edict_t *clent;

View File

@ -17,6 +17,7 @@ cvar_t *cl_predict;
cvar_t *cl_showfps;
cvar_t *cl_nodelta;
cvar_t *cl_crosshair;
cvar_t *cl_idealpitchscale;
cvar_t *cl_shownet;
cvar_t *cl_showmiss;
cvar_t *userinfo;
@ -375,7 +376,7 @@ Sends a disconnect message to the server
*/
void CL_SendDisconnectMessage( void )
{
bitbuf_t buf;
sizebuf_t buf;
byte data[32];
BF_Init( &buf, "LastMessage", data, sizeof( data ));
@ -573,7 +574,7 @@ CL_ParseStatusMessage
Handle a reply from a info
=================
*/
void CL_ParseStatusMessage( netadr_t from, bitbuf_t *msg )
void CL_ParseStatusMessage( netadr_t from, sizebuf_t *msg )
{
char *s;
@ -701,7 +702,7 @@ CL_ConnectionlessPacket
Responses to broadcasts, etc
=================
*/
void CL_ConnectionlessPacket( netadr_t from, bitbuf_t *msg )
void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
{
char *s, *c;
@ -1080,7 +1081,8 @@ void CL_InitLocal( void )
cl_predict = Cvar_Get( "cl_predict", "1", CVAR_ARCHIVE, "disables client movement prediction" );
cl_crosshair = Cvar_Get( "crosshair", "1", CVAR_ARCHIVE|CVAR_USERINFO, "show weapon chrosshair" );
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0, "disable delta-compression for usercommnds" );
cl_idealpitchscale = Cvar_Get( "cl_idealpitchscale", "0.8", 0, "how much to look up/down slopes and stairs when not using freelook" );
cl_shownet = Cvar_Get( "cl_shownet", "0", 0, "client show network packets" );
cl_showmiss = Cvar_Get( "cl_showmiss", "0", CVAR_ARCHIVE, "client show prediction errors" );
cl_timeout = Cvar_Get( "cl_timeout", "120", 0, "connect timeout (in-seconds)" );

View File

@ -12,6 +12,7 @@
#include "net_encode.h"
#define CONNECTION_PROBLEM_TIME 15.0 * 1000 // 15 seconds
#define MAX_FORWARD 6
bool CL_IsPredicted( void )
{
@ -103,7 +104,7 @@ During normal gameplay, a client packet will contain something like:
*/
void CL_WritePacket( void )
{
bitbuf_t buf;
sizebuf_t buf;
bool noDelta = false;
byte data[MAX_MSGLEN];
usercmd_t *cmd, *oldcmd;
@ -558,6 +559,71 @@ void CL_CheckPredictionError( void )
}
}
/*
===============
CL_SetIdealPitch
===============
*/
void CL_SetIdealPitch( edict_t *ent )
{
float angleval, sinval, cosval;
trace_t tr;
vec3_t top, bottom;
float z[MAX_FORWARD];
int i, j;
int step, dir, steps;
if( !( ent->v.groundentity ))
return;
angleval = ent->v.angles[YAW] * M_PI * 2 / 360;
com.sincos( angleval, &sinval, &cosval );
for( i = 0; i < MAX_FORWARD; i++ )
{
top[0] = ent->v.origin[0] + cosval * (i + 3) * 12;
top[1] = ent->v.origin[1] + sinval * (i + 3) * 12;
top[2] = ent->v.origin[2] + ent->v.view_ofs[2];
bottom[0] = top[0];
bottom[1] = top[1];
bottom[2] = top[2] - 160;
tr = CL_Move( top, vec3_origin, vec3_origin, bottom, MOVE_NOMONSTERS, ent );
if( tr.fAllSolid )
return; // looking at a wall, leave ideal the way is was
if( tr.flFraction == 1.0f )
return; // near a dropoff
z[i] = top[2] + tr.flFraction * (bottom[2] - top[2]);
}
dir = 0;
steps = 0;
for( j = 1; j < i; j++ )
{
step = z[j] - z[j-1];
if( step > -ON_EPSILON && step < ON_EPSILON )
continue;
if( dir && ( step-dir > ON_EPSILON || step-dir < -ON_EPSILON ))
return; // mixed changes
steps++;
dir = step;
}
if( !dir )
{
cl.refdef.idealpitch = 0;
return;
}
if( steps < 2 ) return;
cl.refdef.idealpitch = -dir * cl_idealpitchscale->value;
}
/*
=================
CL_PredictMovement
@ -580,6 +646,8 @@ void CL_PredictMovement( void )
viewent = CL_GetEdictByIndex( cl.refdef.viewentity );
cd = &cl.frame.cd;
CL_SetIdealPitch( player );
if( cls.demoplayback && CL_IsValidEdict( viewent ))
{
// use interpolated server values

View File

@ -113,7 +113,7 @@ CL_WriteErrorMessage
write net_message into buffer.dat for debugging
=====================
*/
void CL_WriteErrorMessage( int current_count, bitbuf_t *msg )
void CL_WriteErrorMessage( int current_count, sizebuf_t *msg )
{
file_t *fp;
const char *buffer_file = "buffer.dat";
@ -140,7 +140,7 @@ void CL_WriteMessageHistory( void )
{
int i, thecmd;
oldcmd_t *old, *failcommand;
bitbuf_t *msg = &net_message;
sizebuf_t *msg = &net_message;
if( !cls.initialized || cls.state == ca_disconnected )
return;
@ -233,7 +233,7 @@ CL_ParseDownload
A download message has been received from the server
=====================
*/
void CL_ParseDownload( bitbuf_t *msg )
void CL_ParseDownload( sizebuf_t *msg )
{
int size, percent;
char buffer[MAX_MSGLEN];
@ -332,7 +332,7 @@ CL_ParseSoundPacket
==================
*/
void CL_ParseSoundPacket( bitbuf_t *msg, bool is_ambient )
void CL_ParseSoundPacket( sizebuf_t *msg, bool is_ambient )
{
vec3_t pos_;
float *pos = NULL;
@ -392,9 +392,9 @@ CL_ParseMovevars
==================
*/
void CL_ParseMovevars( bitbuf_t *msg )
void CL_ParseMovevars( sizebuf_t *msg )
{
BF_ReadDeltaMovevars( msg, &clgame.oldmovevars, &clgame.movevars );
MSG_ReadDeltaMovevars( msg, &clgame.oldmovevars, &clgame.movevars );
Mem_Copy( &clgame.oldmovevars, &clgame.movevars, sizeof( movevars_t ));
}
@ -404,7 +404,7 @@ CL_ParseParticles
==================
*/
void CL_ParseParticles( bitbuf_t *msg )
void CL_ParseParticles( sizebuf_t *msg )
{
vec3_t org, dir;
int i, count, color;
@ -427,7 +427,7 @@ CL_ParseStaticDecal
==================
*/
void CL_ParseStaticDecal( bitbuf_t *msg )
void CL_ParseStaticDecal( sizebuf_t *msg )
{
vec3_t origin;
int decalIndex, entityIndex, modelIndex;
@ -445,7 +445,7 @@ void CL_ParseStaticDecal( bitbuf_t *msg )
CL_DecalShoot( cl.decal_shaders[decalIndex], entityIndex, modelIndex, origin, flags );
}
void CL_ParseSoundFade( bitbuf_t *msg )
void CL_ParseSoundFade( sizebuf_t *msg )
{
float fadePercent, fadeOutSeconds;
float holdTime, fadeInSeconds;
@ -458,7 +458,7 @@ void CL_ParseSoundFade( bitbuf_t *msg )
S_FadeClientVolume( fadePercent, fadeOutSeconds, holdTime, fadeInSeconds );
}
void CL_ParseReliableEvent( bitbuf_t *msg, int flags )
void CL_ParseReliableEvent( sizebuf_t *msg, int flags )
{
int event_index;
event_args_t nullargs, args;
@ -472,7 +472,7 @@ void CL_ParseReliableEvent( bitbuf_t *msg, int flags )
CL_QueueEvent( flags, event_index, delay, &args );
}
void CL_ParseEvent( bitbuf_t *msg )
void CL_ParseEvent( sizebuf_t *msg )
{
int i, num_events;
@ -495,7 +495,7 @@ void CL_ParseEvent( bitbuf_t *msg )
CL_ParseServerData
==================
*/
void CL_ParseServerData( bitbuf_t *msg )
void CL_ParseServerData( sizebuf_t *msg )
{
string str;
int i;
@ -557,7 +557,7 @@ void CL_ParseServerData( bitbuf_t *msg )
CL_ParseBaseline
==================
*/
void CL_ParseBaseline( bitbuf_t *msg )
void CL_ParseBaseline( sizebuf_t *msg )
{
int newnum, timebase;
entity_state_t nullstate;
@ -591,7 +591,7 @@ void CL_ParseBaseline( bitbuf_t *msg )
CL_ParseConfigString
================
*/
void CL_ParseConfigString( bitbuf_t *msg )
void CL_ParseConfigString( sizebuf_t *msg )
{
int i;
@ -669,7 +669,7 @@ CL_ParseSetAngle
set the view angle to this absolute value
================
*/
void CL_ParseSetAngle( bitbuf_t *msg )
void CL_ParseSetAngle( sizebuf_t *msg )
{
cl.refdef.cl_viewangles[0] = BF_ReadBitAngle( msg, 16 );
cl.refdef.cl_viewangles[1] = BF_ReadBitAngle( msg, 16 );
@ -682,7 +682,7 @@ CL_ParseAddAngle
add the view angle yaw
================
*/
void CL_ParseAddAngle( bitbuf_t *msg )
void CL_ParseAddAngle( sizebuf_t *msg )
{
float add_angle;
@ -696,7 +696,7 @@ CL_ParseCrosshairAngle
offset crosshair angles
================
*/
void CL_ParseCrosshairAngle( bitbuf_t *msg )
void CL_ParseCrosshairAngle( sizebuf_t *msg )
{
cl.refdef.crosshairangle[0] = BF_ReadBitAngle( msg, 8 );
cl.refdef.crosshairangle[1] = BF_ReadBitAngle( msg, 8 );
@ -710,7 +710,7 @@ CL_RegisterUserMessage
register new user message or update existing
================
*/
void CL_RegisterUserMessage( bitbuf_t *msg )
void CL_RegisterUserMessage( sizebuf_t *msg )
{
char *pszName;
int svc_num, size;
@ -732,7 +732,7 @@ CL_UpdateUserinfo
collect userinfo from all players
================
*/
void CL_UpdateUserinfo( bitbuf_t *msg )
void CL_UpdateUserinfo( sizebuf_t *msg )
{
int slot;
bool active;
@ -762,7 +762,7 @@ CL_ServerInfo
change serverinfo
==============
*/
void CL_ServerInfo( bitbuf_t *msg )
void CL_ServerInfo( sizebuf_t *msg )
{
char key[MAX_MSGLEN];
char value[MAX_MSGLEN];
@ -779,7 +779,7 @@ CL_ParseUserMessage
handles all user messages
==============
*/
void CL_ParseUserMessage( bitbuf_t *msg, int svc_num )
void CL_ParseUserMessage( sizebuf_t *msg, int svc_num )
{
int i, iSize;
byte *pbuf;
@ -837,7 +837,7 @@ ACTION MESSAGES
CL_ParseServerMessage
=====================
*/
void CL_ParseServerMessage( bitbuf_t *msg )
void CL_ParseServerMessage( sizebuf_t *msg )
{
char *s;
int i, cmd;

View File

@ -40,7 +40,6 @@ void V_SetupRefDef( void )
cl.refdef.onground = clent->v.groundentity;
cl.refdef.health = clent->v.health;
cl.refdef.movetype = clent->v.movetype;
cl.refdef.idealpitch = clent->v.idealpitch;
cl.refdef.num_entities = clgame.globals->numEntities;
cl.refdef.max_entities = clgame.globals->maxEntities;
cl.refdef.maxclients = clgame.globals->maxClients;

View File

@ -353,6 +353,7 @@ extern cvar_t *cl_nodelta;
extern cvar_t *cl_crosshair;
extern cvar_t *cl_showmiss;
extern cvar_t *cl_testlights;
extern cvar_t *cl_idealpitchscale;
extern cvar_t *cl_allow_levelshots;
extern cvar_t *cl_levelshot_name;
extern cvar_t *scr_centertime;
@ -363,7 +364,7 @@ extern cvar_t *userinfo;
//=============================================================================
bool CL_CheckOrDownloadFile( const char *filename );
void CL_ParseConfigString( bitbuf_t *msg );
void CL_ParseConfigString( sizebuf_t *msg );
void CL_SetLightstyle( int i );
void CL_RunLightStyles( void );
@ -411,7 +412,7 @@ void CL_SendCmd( void );
// cl_demo.c
//
void CL_DrawDemoRecording( void );
void CL_WriteDemoMessage( bitbuf_t *msg, int head_size );
void CL_WriteDemoMessage( sizebuf_t *msg, int head_size );
void CL_ReadDemoMessage( void );
void CL_StopPlayback( void );
void CL_StopRecord( void );
@ -427,7 +428,7 @@ void CL_Stop_f( void );
//
void CL_UnloadProgs( void );
bool CL_LoadProgs( const char *name );
void CL_ParseUserMessage( bitbuf_t *msg, int svc_num );
void CL_ParseUserMessage( sizebuf_t *msg, int svc_num );
void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize );
void CL_DrawHUD( int state );
void CL_InitEdicts( void );
@ -459,7 +460,7 @@ _inline edict_t *CL_EDICT_NUM( int n, const char *file, const int line )
//
// cl_parse.c
//
void CL_ParseServerMessage( bitbuf_t *msg );
void CL_ParseServerMessage( sizebuf_t *msg );
void CL_RunBackgroundTrack( void );
void CL_Download_f( void );
@ -502,7 +503,7 @@ void CL_UpdateBaseVelocity( edict_t *ent );
//
// cl_frame.c
//
void CL_ParseFrame( bitbuf_t *msg );
void CL_ParseFrame( sizebuf_t *msg );
void CL_GetEntitySpatialization( int ent, vec3_t origin, vec3_t velocity );
//

View File

@ -33,21 +33,20 @@ void BF_InitMasks( void )
ExtraMasks[maskBit] = BIT( maskBit ) - 1;
}
void BF_InitExt( bitbuf_t *bf, const char *pDebugName, void *pData, int nBytes, int nMaxBits )
void BF_InitExt( sizebuf_t *bf, const char *pDebugName, void *pData, int nBytes, int nMaxBits )
{
bf->pDebugName = pDebugName;
BF_StartWriting( bf, pData, nBytes, 0, nMaxBits );
}
void BF_StartWriting( bitbuf_t *bf, void *pData, int nBytes, int iStartBit, int nBits )
void BF_StartWriting( sizebuf_t *bf, void *pData, int nBytes, int iStartBit, int nBits )
{
// make sure it's dword aligned and padded.
// Assert(( nBytes % 4 ) == 0 );
Assert(((dword)pData & 3 ) == 0 );
bf->pData = (byte *)pData;
bf->nDataBytes = nBytes;
if( nBits == -1 )
{
@ -70,40 +69,37 @@ MSG_Clear
for clearing overflowed buffer
=======================
*/
void BF_Clear( bitbuf_t *bf )
void BF_Clear( sizebuf_t *bf )
{
bf->iCurBit = 0;
bf->bOverflow = false;
}
static bool BF_Overflow( bitbuf_t *bf, int nBits )
static bool BF_Overflow( sizebuf_t *bf, int nBits )
{
if( bf->iCurBit + nBits > bf->nDataBits )
{
bf->bOverflow = true;
Host_Error( "Msg %s: overflow! %i + %i > %i\n", bf->pDebugName, bf->iCurBit, nBits, bf->nDataBits );
}
return bf->bOverflow;
}
bool BF_CheckOverflow( bitbuf_t *bf )
bool BF_CheckOverflow( sizebuf_t *bf )
{
ASSERT( bf );
return BF_Overflow( bf, 0 );
}
void BF_SeekToBit( bitbuf_t *bf, int bitPos )
void BF_SeekToBit( sizebuf_t *bf, int bitPos )
{
bf->iCurBit = bitPos;
}
void BF_SeekToByte( bitbuf_t *bf, int bytePos )
void BF_SeekToByte( sizebuf_t *bf, int bytePos )
{
bf->iCurBit = bytePos << 3;
}
void BF_WriteOneBit( bitbuf_t *bf, int nValue )
void BF_WriteOneBit( sizebuf_t *bf, int nValue )
{
if( !BF_Overflow( bf, 1 ))
{
@ -114,24 +110,23 @@ void BF_WriteOneBit( bitbuf_t *bf, int nValue )
}
}
void BF_WriteUBitLongExt( bitbuf_t *bf, uint curData, int numbits, bool bCheckRange )
void BF_WriteUBitLongExt( sizebuf_t *bf, uint curData, int numbits, bool bCheckRange )
{
#ifdef _DEBUG
// make sure it doesn't overflow.
if( bCheckRange && numbits < 32 )
{
if( curData >= (unsigned long)BIT( numbits ))
MsgDev( D_ERROR, "Msg %s: out of range value!\n", bf->pDebugName );
if( curData >= (dword)BIT( numbits ))
MsgDev( D_ERROR, "Write%s: out of range value!\n", bf->pDebugName );
}
Assert( numbits >= 0 && numbits <= 32 );
#endif
Assert( numbits >= 0 && numbits <= 32 );
// bounds checking..
if(( bf->iCurBit + numbits ) > bf->nDataBits )
{
bf->bOverflow = true;
bf->iCurBit = bf->nDataBits;
MsgDev( D_ERROR, "WriteError: %s: overflow!\n", bf->pDebugName );
}
else
{
@ -141,7 +136,7 @@ void BF_WriteUBitLongExt( bitbuf_t *bf, uint curData, int numbits, bool bCheckRa
dword iCurBitMasked;
int nBitsWritten;
Assert(( iDWord * 4 + sizeof( long )) <= (uint)bf->nDataBytes );
Assert(( iDWord * 4 + sizeof( long )) <= (uint)BF_GetMaxBytes( bf ));
iCurBitMasked = iCurBit & 31;
((dword *)bf->pData)[iDWord] &= BitWriteMasks[iCurBitMasked][nBitsLeft];
@ -171,7 +166,7 @@ BF_WriteSBitLong
sign bit comes first
=======================
*/
void BF_WriteSBitLong( bitbuf_t *bf, int data, int numbits )
void BF_WriteSBitLong( sizebuf_t *bf, int data, int numbits )
{
// do we have a valid # of bits to encode with?
Assert( numbits >= 1 );
@ -205,14 +200,14 @@ void BF_WriteSBitLong( bitbuf_t *bf, int data, int numbits )
}
}
void BF_WriteBitLong( bitbuf_t *bf, uint data, int numbits, bool bSigned )
void BF_WriteBitLong( sizebuf_t *bf, uint data, int numbits, bool bSigned )
{
if( bSigned )
BF_WriteSBitLong( bf, (int)data, numbits );
else BF_WriteUBitLong( bf, data, numbits );
}
bool BF_WriteBits( bitbuf_t *bf, const void *pData, int nBits )
bool BF_WriteBits( sizebuf_t *bf, const void *pData, int nBits )
{
byte *pOut = (byte *)pData;
int nBitsLeft = nBits;
@ -254,7 +249,7 @@ bool BF_WriteBits( bitbuf_t *bf, const void *pData, int nBits )
}
void BF_WriteBitAngle( bitbuf_t *bf, float fAngle, int numbits )
void BF_WriteBitAngle( sizebuf_t *bf, float fAngle, int numbits )
{
uint mask, shift;
int d;
@ -272,7 +267,7 @@ void BF_WriteBitAngle( bitbuf_t *bf, float fAngle, int numbits )
BF_WriteUBitLong( bf, (uint)d, numbits );
}
void BF_WriteBitCoord( bitbuf_t *bf, const float f )
void BF_WriteBitCoord( sizebuf_t *bf, const float f )
{
int signbit = ( f <= -COORD_RESOLUTION );
int fractval = abs(( int )( f * COORD_DENOMINATOR )) & ( COORD_DENOMINATOR - 1 );
@ -303,7 +298,7 @@ void BF_WriteBitCoord( bitbuf_t *bf, const float f )
}
}
void BF_WriteBitFloat( bitbuf_t *bf, float val )
void BF_WriteBitFloat( sizebuf_t *bf, float val )
{
long intVal;
@ -314,7 +309,7 @@ void BF_WriteBitFloat( bitbuf_t *bf, float val )
BF_WriteUBitLong( bf, intVal, 32 );
}
void BF_WriteBitVec3Coord( bitbuf_t *bf, const float *fa )
void BF_WriteBitVec3Coord( sizebuf_t *bf, const float *fa )
{
int xflag, yflag, zflag;
@ -331,7 +326,7 @@ void BF_WriteBitVec3Coord( bitbuf_t *bf, const float *fa )
if( zflag ) BF_WriteBitCoord( bf, fa[2] );
}
void BF_WriteBitNormal( bitbuf_t *bf, float f )
void BF_WriteBitNormal( sizebuf_t *bf, float f )
{
int signbit = ( f <= -NORMAL_RESOLUTION );
uint fractval = abs(( int )(f * NORMAL_DENOMINATOR ));
@ -346,7 +341,7 @@ void BF_WriteBitNormal( bitbuf_t *bf, float f )
BF_WriteUBitLong( bf, fractval, NORMAL_FRACTIONAL_BITS );
}
void BF_WriteBitVec3Normal( bitbuf_t *bf, const float *fa )
void BF_WriteBitVec3Normal( sizebuf_t *bf, const float *fa )
{
int xflag, yflag;
int signbit;
@ -365,48 +360,48 @@ void BF_WriteBitVec3Normal( bitbuf_t *bf, const float *fa )
BF_WriteOneBit( bf, signbit );
}
void BF_WriteBitAngles( bitbuf_t *bf, const float *fa )
void BF_WriteBitAngles( sizebuf_t *bf, const float *fa )
{
// FIXME: uses WriteBitAngle instead ?
BF_WriteBitVec3Coord( bf, fa );
}
void BF_WriteChar( bitbuf_t *bf, int val )
void BF_WriteChar( sizebuf_t *bf, int val )
{
BF_WriteSBitLong( bf, val, sizeof( char ) << 3 );
}
void BF_WriteByte( bitbuf_t *bf, int val )
void BF_WriteByte( sizebuf_t *bf, int val )
{
BF_WriteUBitLong( bf, val, sizeof( byte ) << 3 );
}
void BF_WriteShort( bitbuf_t *bf, int val )
void BF_WriteShort( sizebuf_t *bf, int val )
{
BF_WriteSBitLong( bf, val, sizeof(short ) << 3 );
}
void BF_WriteWord( bitbuf_t *bf, int val )
void BF_WriteWord( sizebuf_t *bf, int val )
{
BF_WriteUBitLong( bf, val, sizeof( word ) << 3 );
}
void BF_WriteLong( bitbuf_t *bf, long val )
void BF_WriteLong( sizebuf_t *bf, long val )
{
BF_WriteSBitLong( bf, val, sizeof( long ) << 3 );
}
void BF_WriteFloat( bitbuf_t *bf, float val )
void BF_WriteFloat( sizebuf_t *bf, float val )
{
BF_WriteBits( bf, &val, sizeof( val ) << 3 );
}
bool BF_WriteBytes( bitbuf_t *bf, const void *pBuf, int nBytes )
bool BF_WriteBytes( sizebuf_t *bf, const void *pBuf, int nBytes )
{
return BF_WriteBits( bf, pBuf, nBytes << 3 );
}
bool BF_WriteString( bitbuf_t *bf, const char *pStr )
bool BF_WriteString( sizebuf_t *bf, const char *pStr )
{
if( pStr )
{
@ -421,7 +416,7 @@ bool BF_WriteString( bitbuf_t *bf, const char *pStr )
return !bf->bOverflow;
}
int BF_ReadOneBit( bitbuf_t *bf )
int BF_ReadOneBit( sizebuf_t *bf )
{
if( !BF_Overflow( bf, 1 ))
{
@ -432,7 +427,7 @@ int BF_ReadOneBit( bitbuf_t *bf )
return 0;
}
uint BF_ReadUBitLong( bitbuf_t *bf, int numbits )
uint BF_ReadUBitLong( sizebuf_t *bf, int numbits )
{
int idword1;
uint dword1, ret;
@ -448,7 +443,6 @@ uint BF_ReadUBitLong( bitbuf_t *bf, int numbits )
if(( bf->iCurBit + numbits ) > bf->nDataBits )
{
bf->bOverflow = true;
MsgDev( D_ERROR, "ReadError: %s: overflow! cur %i num %i, total %i\n", bf->pDebugName, bf->iCurBit, numbits, bf->nDataBits );
bf->iCurBit = bf->nDataBits;
return 0;
}
@ -481,7 +475,7 @@ uint BF_ReadUBitLong( bitbuf_t *bf, int numbits )
return ret;
}
float BF_ReadBitFloat( bitbuf_t *bf )
float BF_ReadBitFloat( sizebuf_t *bf )
{
long val;
int bit, byte;
@ -507,7 +501,7 @@ float BF_ReadBitFloat( bitbuf_t *bf )
return *((float *)&val);
}
bool BF_ReadBits( bitbuf_t *bf, void *pOutData, int nBits )
bool BF_ReadBits( sizebuf_t *bf, void *pOutData, int nBits )
{
byte *pOut = (byte *)pOutData;
int nBitsLeft = nBits;
@ -546,7 +540,7 @@ bool BF_ReadBits( bitbuf_t *bf, void *pOutData, int nBits )
return !bf->bOverflow;
}
float BF_ReadBitAngle( bitbuf_t *bf, int numbits )
float BF_ReadBitAngle( sizebuf_t *bf, int numbits )
{
float fReturn, shift;
int i;
@ -564,7 +558,7 @@ float BF_ReadBitAngle( bitbuf_t *bf, int numbits )
}
// Append numbits least significant bits from data to the current bit stream
int BF_ReadSBitLong( bitbuf_t *bf, int numbits )
int BF_ReadSBitLong( sizebuf_t *bf, int numbits )
{
int r, sign;
@ -578,7 +572,7 @@ int BF_ReadSBitLong( bitbuf_t *bf, int numbits )
return r;
}
uint BF_ReadBitLong( bitbuf_t *bf, int numbits, bool bSigned )
uint BF_ReadBitLong( sizebuf_t *bf, int numbits, bool bSigned )
{
if( bSigned )
return (uint)BF_ReadSBitLong( bf, numbits );
@ -587,7 +581,7 @@ uint BF_ReadBitLong( bitbuf_t *bf, int numbits, bool bSigned )
// Basic Coordinate Routines (these contain bit-field size AND fixed point scaling constants)
float BF_ReadBitCoord( bitbuf_t *bf )
float BF_ReadBitCoord( sizebuf_t *bf )
{
int intval = 0, fractval = 0, signbit = 0;
float value = 0.0;
@ -624,7 +618,7 @@ float BF_ReadBitCoord( bitbuf_t *bf )
return value;
}
void BF_ReadBitVec3Coord( bitbuf_t *bf, vec3_t fa )
void BF_ReadBitVec3Coord( sizebuf_t *bf, vec3_t fa )
{
int xflag, yflag, zflag;
@ -641,7 +635,7 @@ void BF_ReadBitVec3Coord( bitbuf_t *bf, vec3_t fa )
if( zflag ) fa[2] = BF_ReadBitCoord( bf );
}
float BF_ReadBitNormal( bitbuf_t *bf )
float BF_ReadBitNormal( sizebuf_t *bf )
{
// read the sign bit
int signbit = BF_ReadOneBit( bf );
@ -658,7 +652,7 @@ float BF_ReadBitNormal( bitbuf_t *bf )
return value;
}
void BF_ReadBitVec3Normal( bitbuf_t *bf, vec3_t fa )
void BF_ReadBitVec3Normal( sizebuf_t *bf, vec3_t fa )
{
int xflag = BF_ReadOneBit( bf );
int yflag = BF_ReadOneBit( bf );
@ -682,32 +676,32 @@ void BF_ReadBitVec3Normal( bitbuf_t *bf, vec3_t fa )
if( znegative ) fa[2] = -fa[2];
}
int BF_ReadChar( bitbuf_t *bf )
int BF_ReadChar( sizebuf_t *bf )
{
return BF_ReadSBitLong( bf, sizeof( char ) << 3 );
}
int BF_ReadByte( bitbuf_t *bf )
int BF_ReadByte( sizebuf_t *bf )
{
return BF_ReadUBitLong( bf, sizeof( byte ) << 3 );
}
int BF_ReadShort( bitbuf_t *bf )
int BF_ReadShort( sizebuf_t *bf )
{
return BF_ReadSBitLong( bf, sizeof( short ) << 3 );
}
int BF_ReadWord( bitbuf_t *bf )
int BF_ReadWord( sizebuf_t *bf )
{
return BF_ReadUBitLong( bf, sizeof( word ) << 3 );
}
long BF_ReadLong( bitbuf_t *bf )
long BF_ReadLong( sizebuf_t *bf )
{
return BF_ReadSBitLong( bf, sizeof( long ) << 3 );
}
float BF_ReadFloat( bitbuf_t *bf )
float BF_ReadFloat( sizebuf_t *bf )
{
float ret;
ASSERT( sizeof( ret ) == 4 );
@ -717,12 +711,12 @@ float BF_ReadFloat( bitbuf_t *bf )
return ret;
}
bool BF_ReadBytes( bitbuf_t *bf, void *pOut, int nBytes )
bool BF_ReadBytes( sizebuf_t *bf, void *pOut, int nBytes )
{
return BF_ReadBits( bf, pOut, nBytes << 3 );
}
char *BF_ReadStringExt( bitbuf_t *bf, bool bLine )
char *BF_ReadStringExt( sizebuf_t *bf, bool bLine )
{
static char string[MAX_SYSPATH];
int l = 0, c;

View File

@ -5,6 +5,14 @@
#ifndef NET_BUFFER_H
#define NET_BUFFER_H
/*
==============================================================================
MESSAGE IO FUNCTIONS
Handles byte ordering and avoids alignment errors
==============================================================================
*/
// Pad a number so it lies on an N byte boundary.
// So PAD_NUMBER(0,4) is 0 and PAD_NUMBER(1,4) is 4
#define PAD_NUMBER( num, boundary ) ((( num ) + (( boundary ) - 1 )) / ( boundary )) * ( boundary )
@ -14,17 +22,15 @@ _inline int BitByte( int bits )
return PAD_NUMBER( bits, 8 ) >> 3;
}
typedef struct bitbuf_s
typedef struct
{
bool bOverflow; // overflow reading or writing
const char *pDebugName; // buffer name (pointer to const name)
byte *pData;
int iCurBit;
int nDataBytes;
int nDataBits;
size_t nMaxSize; // buffer maxsize
} bitbuf_t;
} sizebuf_t;
#define BF_WriteUBitLong( bf, data, bits ) BF_WriteUBitLongExt( bf, data, bits, true );
#define BF_StartReading BF_StartWriting
@ -35,76 +41,76 @@ typedef struct bitbuf_s
#define BF_Init( bf, name, data, bytes ) BF_InitExt( bf, name, data, bytes, -1 )
// common functions
void BF_InitExt( bitbuf_t *bf, const char *pDebugName, void *pData, int nBytes, int nMaxBits );
void BF_InitExt( sizebuf_t *bf, const char *pDebugName, void *pData, int nBytes, int nMaxBits );
void BF_InitMasks( void ); // called once at startup engine
void BF_SeekToBit( bitbuf_t *bf, int bitPos );
void BF_SeekToByte( bitbuf_t *bf, int bytePos );
bool BF_CheckOverflow( bitbuf_t *bf );
void BF_SeekToBit( sizebuf_t *bf, int bitPos );
void BF_SeekToByte( sizebuf_t *bf, int bytePos );
bool BF_CheckOverflow( sizebuf_t *bf );
// init writing
void BF_StartWriting( bitbuf_t *bf, void *pData, int nBytes, int iStartBit, int nBits );
void BF_Clear( bitbuf_t *bf );
void BF_StartWriting( sizebuf_t *bf, void *pData, int nBytes, int iStartBit, int nBits );
void BF_Clear( sizebuf_t *bf );
// Bit-write functions
void BF_WriteOneBit( bitbuf_t *bf, int nValue );
void BF_WriteUBitLongExt( bitbuf_t *bf, uint curData, int numbits, bool bCheckRange );
void BF_WriteSBitLong( bitbuf_t *bf, int data, int numbits );
void BF_WriteBitLong( bitbuf_t *bf, uint data, int numbits, bool bSigned );
bool BF_WriteBits( bitbuf_t *bf, const void *pData, int nBits );
void BF_WriteBitAngle( bitbuf_t *bf, float fAngle, int numbits );
void BF_WriteBitCoord( bitbuf_t *bf, const float f );
void BF_WriteBitFloat( bitbuf_t *bf, float val );
void BF_WriteBitVec3Coord( bitbuf_t *bf, const float *fa );
void BF_WriteBitNormal( bitbuf_t *bf, float f );
void BF_WriteBitVec3Normal( bitbuf_t *bf, const float *fa );
void BF_WriteBitAngles( bitbuf_t *bf, const float *fa );
void BF_WriteOneBit( sizebuf_t *bf, int nValue );
void BF_WriteUBitLongExt( sizebuf_t *bf, uint curData, int numbits, bool bCheckRange );
void BF_WriteSBitLong( sizebuf_t *bf, int data, int numbits );
void BF_WriteBitLong( sizebuf_t *bf, uint data, int numbits, bool bSigned );
bool BF_WriteBits( sizebuf_t *bf, const void *pData, int nBits );
void BF_WriteBitAngle( sizebuf_t *bf, float fAngle, int numbits );
void BF_WriteBitCoord( sizebuf_t *bf, const float f );
void BF_WriteBitFloat( sizebuf_t *bf, float val );
void BF_WriteBitVec3Coord( sizebuf_t *bf, const float *fa );
void BF_WriteBitNormal( sizebuf_t *bf, float f );
void BF_WriteBitVec3Normal( sizebuf_t *bf, const float *fa );
void BF_WriteBitAngles( sizebuf_t *bf, const float *fa );
// Byte-write functions
void BF_WriteChar( bitbuf_t *bf, int val );
void BF_WriteByte( bitbuf_t *bf, int val );
void BF_WriteShort( bitbuf_t *bf, int val );
void BF_WriteWord( bitbuf_t *bf, int val );
void BF_WriteLong( bitbuf_t *bf, long val );
void BF_WriteFloat( bitbuf_t *bf, float val );
bool BF_WriteBytes( bitbuf_t *bf, const void *pBuf, int nBytes ); // same as MSG_WriteData
bool BF_WriteString( bitbuf_t *bf, const char *pStr ); // returns false if it overflows the buffer.
void BF_WriteChar( sizebuf_t *bf, int val );
void BF_WriteByte( sizebuf_t *bf, int val );
void BF_WriteShort( sizebuf_t *bf, int val );
void BF_WriteWord( sizebuf_t *bf, int val );
void BF_WriteLong( sizebuf_t *bf, long val );
void BF_WriteFloat( sizebuf_t *bf, float val );
bool BF_WriteBytes( sizebuf_t *bf, const void *pBuf, int nBytes ); // same as MSG_WriteData
bool BF_WriteString( sizebuf_t *bf, const char *pStr ); // returns false if it overflows the buffer.
// delta-write functions
bool BF_WriteDeltaMovevars( bitbuf_t *sb, movevars_t *from, movevars_t *cmd );
bool BF_WriteDeltaMovevars( sizebuf_t *sb, movevars_t *from, movevars_t *cmd );
// helper functions
_inline int BF_GetNumBytesWritten( bitbuf_t *bf ) { return BitByte( bf->iCurBit ); }
_inline int BF_GetNumBitsWritten( bitbuf_t *bf ) { return bf->iCurBit; }
_inline int BF_GetMaxBits( bitbuf_t *bf ) { return bf->nDataBits; }
_inline int BF_GetMaxBytes( bitbuf_t *bf ) { return bf->nDataBytes; }
_inline int BF_GetNumBitsLeft( bitbuf_t *bf ) { return bf->nDataBits - bf->iCurBit; }
_inline int BF_GetNumBytesLeft( bitbuf_t *bf ) { return BF_GetNumBitsLeft( bf ) >> 3; }
_inline byte *BF_GetData( bitbuf_t *bf ) { return bf->pData; }
_inline int BF_GetNumBytesWritten( sizebuf_t *bf ) { return BitByte( bf->iCurBit ); }
_inline int BF_GetNumBitsWritten( sizebuf_t *bf ) { return bf->iCurBit; }
_inline int BF_GetMaxBits( sizebuf_t *bf ) { return bf->nDataBits; }
_inline int BF_GetMaxBytes( sizebuf_t *bf ) { return bf->nDataBits >> 3; }
_inline int BF_GetNumBitsLeft( sizebuf_t *bf ) { return bf->nDataBits - bf->iCurBit; }
_inline int BF_GetNumBytesLeft( sizebuf_t *bf ) { return BF_GetNumBitsLeft( bf ) >> 3; }
_inline byte *BF_GetData( sizebuf_t *bf ) { return bf->pData; }
// Bit-read functions
int BF_ReadOneBit( bitbuf_t *bf );
float BF_ReadBitFloat( bitbuf_t *bf );
bool BF_ReadBits( bitbuf_t *bf, void *pOutData, int nBits );
float BF_ReadBitAngle( bitbuf_t *bf, int numbits );
int BF_ReadSBitLong( bitbuf_t *bf, int numbits );
uint BF_ReadUBitLong( bitbuf_t *bf, int numbits );
uint BF_ReadBitLong( bitbuf_t *bf, int numbits, bool bSigned );
float BF_ReadBitCoord( bitbuf_t *bf );
void BF_ReadBitVec3Coord( bitbuf_t *bf, vec3_t fa );
float BF_ReadBitNormal( bitbuf_t *bf );
void BF_ReadBitVec3Normal( bitbuf_t *bf, vec3_t fa );
int BF_ReadOneBit( sizebuf_t *bf );
float BF_ReadBitFloat( sizebuf_t *bf );
bool BF_ReadBits( sizebuf_t *bf, void *pOutData, int nBits );
float BF_ReadBitAngle( sizebuf_t *bf, int numbits );
int BF_ReadSBitLong( sizebuf_t *bf, int numbits );
uint BF_ReadUBitLong( sizebuf_t *bf, int numbits );
uint BF_ReadBitLong( sizebuf_t *bf, int numbits, bool bSigned );
float BF_ReadBitCoord( sizebuf_t *bf );
void BF_ReadBitVec3Coord( sizebuf_t *bf, vec3_t fa );
float BF_ReadBitNormal( sizebuf_t *bf );
void BF_ReadBitVec3Normal( sizebuf_t *bf, vec3_t fa );
// Byte-read functions
int BF_ReadChar( bitbuf_t *bf );
int BF_ReadByte( bitbuf_t *bf );
int BF_ReadShort( bitbuf_t *bf );
int BF_ReadWord( bitbuf_t *bf );
long BF_ReadLong( bitbuf_t *bf );
float BF_ReadFloat( bitbuf_t *bf );
bool BF_ReadBytes( bitbuf_t *bf, void *pOut, int nBytes );
char *BF_ReadStringExt( bitbuf_t *bf, bool bLine );
int BF_ReadChar( sizebuf_t *bf );
int BF_ReadByte( sizebuf_t *bf );
int BF_ReadShort( sizebuf_t *bf );
int BF_ReadWord( sizebuf_t *bf );
long BF_ReadLong( sizebuf_t *bf );
float BF_ReadFloat( sizebuf_t *bf );
bool BF_ReadBytes( sizebuf_t *bf, void *pOut, int nBytes );
char *BF_ReadStringExt( sizebuf_t *bf, bool bLine );
// delta-read functions
void BF_ReadDeltaMovevars( bitbuf_t *sb, movevars_t *from, movevars_t *cmd );
void BF_ReadDeltaMovevars( sizebuf_t *sb, movevars_t *from, movevars_t *cmd );
#endif//NET_BUFFER_H

View File

@ -66,7 +66,7 @@ cvar_t *net_speeds;
cvar_t *net_qport;
netadr_t net_from;
bitbuf_t net_message;
sizebuf_t net_message;
byte net_message_buffer[MAX_MSGLEN];
/*
@ -121,7 +121,7 @@ Sends an out-of-band datagram
*/
void Netchan_OutOfBand( int net_socket, netadr_t adr, int length, byte *data )
{
bitbuf_t send;
sizebuf_t send;
byte send_buf[MAX_MSGLEN];
// write the packet header
@ -195,7 +195,7 @@ void Netchan_Transmit( netchan_t *chan, int lengthInBytes, byte *data )
void Netchan_TransmitBits( netchan_t *chan, int lengthInBits, byte *data )
{
bitbuf_t send;
sizebuf_t send;
static bool overflow = false;
byte send_buf[MAX_MSGLEN];
bool send_reliable;
@ -279,7 +279,7 @@ called when the current net message is from remote_address
modifies net message so that it points to the packet payload
=================
*/
bool Netchan_Process( netchan_t *chan, bitbuf_t *msg )
bool Netchan_Process( netchan_t *chan, sizebuf_t *msg )
{
uint sequence, sequence_ack;
uint reliable_ack, recv_reliable;

View File

@ -264,15 +264,7 @@ static const delta_field_t ent_fields[] =
{ ENTS_DEF( vuser4[2] ) },
// Xash3D legacy (needs to be removed)
{ ENTS_DEF( oldorigin[0] ) },
{ ENTS_DEF( oldorigin[1] ) },
{ ENTS_DEF( oldorigin[2] ) },
{ ENTS_DEF( flags ) },
{ ENTS_DEF( viewangles[0] ) },
{ ENTS_DEF( viewangles[1] ) },
{ ENTS_DEF( viewangles[2] ) },
{ ENTS_DEF( idealpitch ) },
{ ENTS_DEF( maxspeed ) },
{ NULL },
};
@ -448,7 +440,7 @@ bool Delta_AddField( const char *pStructName, const char *pName, int flags, int
return true;
}
void Delta_WriteTableField( bitbuf_t *msg, int tableIndex, const delta_t *pField )
void Delta_WriteTableField( sizebuf_t *msg, int tableIndex, const delta_t *pField )
{
int nameIndex;
delta_info_t *dt;
@ -486,7 +478,7 @@ void Delta_WriteTableField( bitbuf_t *msg, int tableIndex, const delta_t *pField
else BF_WriteOneBit( msg, 0 );
}
void Delta_ParseTableField( bitbuf_t *msg )
void Delta_ParseTableField( sizebuf_t *msg )
{
int tableIndex, nameIndex;
float mul = 1.0f, post_mul = 1.0f;
@ -713,9 +705,6 @@ void Delta_InitFields( void )
delta_info_t *dt;
string encodeDll, encodeFunc;
token_t token;
// already initialized
if( delta_init ) return;
delta_script = Com_OpenScript( DELTA_PATH, NULL, 0 );
if( !delta_script ) com.error( "DELTA_Load: couldn't load file %s\n", DELTA_PATH );
@ -741,27 +730,68 @@ void Delta_InitFields( void )
// adding some requrid fields fields that use may forget or don't know how to specified
Delta_AddField( "event_t", "flags", DT_INTEGER, 8, 1.0f, 1.0f );
delta_init = true;
}
void Delta_Init( void )
{
delta_info_t *dt;
// already initialized
if( delta_init ) return;
Delta_InitFields (); // initialize fields
delta_init = true;
dt = Delta_FindStruct( "movevars_t" );
ASSERT( dt != NULL );
if( dt->bInitialized ) return; // specified by user
// create movevars_t delta
Delta_AddField( "movevars_t", "gravity", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "stopspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "maxspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "spectatormaxspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "accelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "airaccelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "wateraccelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "friction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "edgefriction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "waterfriction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "bounce", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "stepsize", DT_FLOAT|DT_SIGNED, 16, 16.0f, 1.0f );
Delta_AddField( "movevars_t", "maxvelocity", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "footsteps", DT_INTEGER, 1, 1.0f, 1.0f );
Delta_AddField( "movevars_t", "rollangle", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
Delta_AddField( "movevars_t", "rollspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
// now done
dt->bInitialized = true;
}
void Delta_Shutdown( void )
{
int i;
if( !delta_init ) return;
for( i = 0; i < NUM_FIELDS( dt_info ); i++ )
{
dt_info[i].numFields = 0;
dt_info[i].customEncode = CUSTOM_NONE;
dt_info[i].userCallback = NULL;
dt_info[i].funcName[0] = '\0';
if( dt_info[i].pFields )
{
Z_Free( dt_info[i].pFields );
dt_info[i].pFields = NULL;
}
dt_info[i].bInitialized = false;
}
delta_init = false;
}
/*
@ -851,7 +881,7 @@ write fields by offsets
assume from and to is valid
=====================
*/
bool Delta_WriteField( bitbuf_t *msg, delta_t *pField, void *from, void *to, float timebase )
bool Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, void *to, float timebase )
{
bool bSigned = ( pField->flags & DT_SIGNED ) ? true : false;
float flValue, flAngle, flTime;
@ -922,7 +952,7 @@ read fields by offsets
assume from and to is valid
=====================
*/
bool Delta_ReadField( bitbuf_t *msg, delta_t *pField, void *from, void *to, float timebase )
bool Delta_ReadField( sizebuf_t *msg, delta_t *pField, void *from, void *to, float timebase )
{
bool bSigned = ( pField->flags & DT_SIGNED ) ? true : false;
float flValue, flAngle, flTime;
@ -1043,7 +1073,7 @@ usercmd_t communication
MSG_WriteDeltaUsercmd
=====================
*/
void MSG_WriteDeltaUsercmd( bitbuf_t *msg, usercmd_t *from, usercmd_t *to )
void MSG_WriteDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to )
{
delta_t *pField;
delta_info_t *dt;
@ -1070,7 +1100,7 @@ void MSG_WriteDeltaUsercmd( bitbuf_t *msg, usercmd_t *from, usercmd_t *to )
MSG_ReadDeltaUsercmd
=====================
*/
void MSG_ReadDeltaUsercmd( bitbuf_t *msg, usercmd_t *from, usercmd_t *to )
void MSG_ReadDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to )
{
delta_t *pField;
delta_info_t *dt;
@ -1103,7 +1133,7 @@ event_args_t communication
MSG_WriteDeltaEvent
=====================
*/
void MSG_WriteDeltaEvent( bitbuf_t *msg, event_args_t *from, event_args_t *to )
void MSG_WriteDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to )
{
delta_t *pField;
delta_info_t *dt;
@ -1130,7 +1160,7 @@ void MSG_WriteDeltaEvent( bitbuf_t *msg, event_args_t *from, event_args_t *to )
MSG_ReadDeltaEvent
=====================
*/
void MSG_ReadDeltaEvent( bitbuf_t *msg, event_args_t *from, event_args_t *to )
void MSG_ReadDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to )
{
delta_t *pField;
delta_info_t *dt;
@ -1154,6 +1184,70 @@ void MSG_ReadDeltaEvent( bitbuf_t *msg, event_args_t *from, event_args_t *to )
/*
=============================================================================
movevars_t communication
=============================================================================
*/
bool MSG_WriteDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to )
{
delta_t *pField;
delta_info_t *dt;
int i, startBit;
int numChanges = 0;
dt = Delta_FindStruct( "movevars_t" );
ASSERT( dt && dt->bInitialized );
pField = dt->pFields;
ASSERT( pField );
startBit = msg->iCurBit;
// activate fields and call custom encode func
Delta_CustomEncode( dt, from, to );
BF_WriteByte( msg, svc_movevars );
// process fields
for( i = 0; i < dt->numFields; i++, pField++ )
{
if( Delta_WriteField( msg, pField, from, to, 0.0f ))
numChanges++;
}
// if we have no changes - kill the message
if( !numChanges )
{
BF_SeekToBit( msg, startBit );
return false;
}
return true;
}
void MSG_ReadDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to )
{
delta_t *pField;
delta_info_t *dt;
int i;
dt = Delta_FindStruct( "movevars_t" );
ASSERT( dt && dt->bInitialized );
pField = dt->pFields;
ASSERT( pField );
*to = *from;
// process fields
for( i = 0; i < dt->numFields; i++, pField++ )
{
Delta_ReadField( msg, pField, from, to, 0.0f );
}
}
/*
=============================================================================
clientdata_t communication
=============================================================================
@ -1166,7 +1260,7 @@ Writes current client data only for local client
Other clients can grab the client state from entity_state_t
==================
*/
void MSG_WriteClientData( bitbuf_t *msg, clientdata_t *from, clientdata_t *to, int timebase )
void MSG_WriteClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, int timebase )
{
delta_t *pField;
delta_info_t *dt;
@ -1196,7 +1290,7 @@ MSG_ReadClientData
Read the clientdata
==================
*/
void MSG_ReadClientData( bitbuf_t *msg, clientdata_t *from, clientdata_t *to, int timebase )
void MSG_ReadClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, int timebase )
{
delta_t *pField;
delta_info_t *dt;
@ -1236,7 +1330,7 @@ If force is not set, then nothing at all will be generated if the entity is
identical, under the assumption that the in-order delta code will catch it.
==================
*/
void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, bitbuf_t *msg, bool force, int timebase )
void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *msg, bool force, int timebase )
{
delta_info_t *dt;
delta_t *pField;
@ -1312,7 +1406,7 @@ If the delta removes the entity, entity_state_t->number will be set to MAX_EDICT
Can go from either a baseline or a previous packet_entity
==================
*/
void MSG_ReadDeltaEntity( bitbuf_t *msg, entity_state_t *from, entity_state_t *to, int number, int timebase )
void MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state_t *to, int number, int timebase )
{
delta_info_t *dt;
delta_t *pField;
@ -1361,7 +1455,7 @@ void MSG_ReadDeltaEntity( bitbuf_t *msg, entity_state_t *from, entity_state_t *t
}
}
void MSG_DeltaAddEncoder( char *name, pfnDeltaEncode encodeFunc )
void Delta_AddEncoder( char *name, pfnDeltaEncode encodeFunc )
{
delta_info_t *dt;
@ -1383,7 +1477,7 @@ void MSG_DeltaAddEncoder( char *name, pfnDeltaEncode encodeFunc )
dt->userCallback = encodeFunc;
}
int MSG_DeltaFindField( delta_t *pFields, const char *fieldname )
int Delta_FindField( delta_t *pFields, const char *fieldname )
{
delta_info_t *dt;
delta_t *pField;
@ -1401,7 +1495,7 @@ int MSG_DeltaFindField( delta_t *pFields, const char *fieldname )
return -1;
}
void MSG_DeltaSetField( delta_t *pFields, const char *fieldname )
void Delta_SetField( delta_t *pFields, const char *fieldname )
{
delta_info_t *dt;
delta_t *pField;
@ -1421,7 +1515,7 @@ void MSG_DeltaSetField( delta_t *pFields, const char *fieldname )
}
}
void MSG_DeltaUnsetField( delta_t *pFields, const char *fieldname )
void Delta_UnsetField( delta_t *pFields, const char *fieldname )
{
delta_info_t *dt;
delta_t *pField;
@ -1441,7 +1535,7 @@ void MSG_DeltaUnsetField( delta_t *pFields, const char *fieldname )
}
}
void MSG_DeltaSetFieldByIndex( delta_t *pFields, int fieldNumber )
void Delta_SetFieldByIndex( delta_t *pFields, int fieldNumber )
{
delta_info_t *dt;
@ -1452,7 +1546,7 @@ void MSG_DeltaSetFieldByIndex( delta_t *pFields, int fieldNumber )
dt->pFields[fieldNumber].bInactive = false;
}
void MSG_DeltaUnsetFieldByIndex( delta_t *pFields, int fieldNumber )
void Delta_UnsetFieldByIndex( delta_t *pFields, int fieldNumber )
{
delta_info_t *dt;

View File

@ -78,26 +78,28 @@ void Delta_Shutdown( void );
void Delta_InitFields( void );
int Delta_NumTables( void );
delta_info_t *Delta_FindStructByIndex( int index );
void MSG_DeltaAddEncoder( char *name, pfnDeltaEncode encodeFunc );
int MSG_DeltaFindField( delta_t *pFields, const char *fieldname );
void MSG_DeltaSetField( delta_t *pFields, const char *fieldname );
void MSG_DeltaUnsetField( delta_t *pFields, const char *fieldname );
void MSG_DeltaSetFieldByIndex( struct delta_s *pFields, int fieldNumber );
void MSG_DeltaUnsetFieldByIndex( struct delta_s *pFields, int fieldNumber );
void Delta_AddEncoder( char *name, pfnDeltaEncode encodeFunc );
int Delta_FindField( delta_t *pFields, const char *fieldname );
void Delta_SetField( delta_t *pFields, const char *fieldname );
void Delta_UnsetField( delta_t *pFields, const char *fieldname );
void Delta_SetFieldByIndex( struct delta_s *pFields, int fieldNumber );
void Delta_UnsetFieldByIndex( struct delta_s *pFields, int fieldNumber );
// send table over network
void Delta_WriteTableField( bitbuf_t *msg, int tableIndex, const delta_t *pField );
void Delta_ParseTableField( bitbuf_t *msg );
void Delta_WriteTableField( sizebuf_t *msg, int tableIndex, const delta_t *pField );
void Delta_ParseTableField( sizebuf_t *msg );
// encode routines
void MSG_WriteDeltaUsercmd( bitbuf_t *msg, usercmd_t *from, usercmd_t *to );
void MSG_ReadDeltaUsercmd( bitbuf_t *msg, usercmd_t *from, usercmd_t *to );
void MSG_WriteDeltaEvent( bitbuf_t *msg, event_args_t *from, event_args_t *to );
void MSG_ReadDeltaEvent( bitbuf_t *msg, event_args_t *from, event_args_t *to );
void MSG_WriteClientData( bitbuf_t *msg, clientdata_t *from, clientdata_t *to, int timebase );
void MSG_ReadClientData( bitbuf_t *msg, clientdata_t *from, clientdata_t *to, int timebase );
void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, bitbuf_t *msg, bool force, int timebase );
void MSG_ReadDeltaEntity( bitbuf_t *msg, entity_state_t *from, entity_state_t *to, int number, int timebase );
void MSG_WriteDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to );
void MSG_ReadDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to );
void MSG_WriteDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to );
void MSG_ReadDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to );
bool MSG_WriteDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to );
void MSG_ReadDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to );
void MSG_WriteClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, int timebase );
void MSG_ReadClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, int timebase );
void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *msg, bool force, int timebase );
void MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state_t *to, int number, int timebase );
#endif//NET_ENCODE_H

View File

@ -499,7 +499,7 @@ Compress message using dynamic Huffman tree,
beginning from specified offset
============
*/
void Huff_CompressPacket( bitbuf_t *msg, int offset )
void Huff_CompressPacket( sizebuf_t *msg, int offset )
{
tree_t tree;
byte buffer[MAX_MSGLEN];
@ -537,7 +537,7 @@ Decompress message using dynamic Huffman tree,
beginning from specified offset
============
*/
void Huff_DecompressPacket( bitbuf_t *msg, int offset )
void Huff_DecompressPacket( sizebuf_t *msg, int offset )
{
tree_t tree;
byte buffer[MAX_MSGLEN];
@ -581,8 +581,7 @@ void Huff_DecompressPacket( bitbuf_t *msg, int offset )
Huff_AddReference( tree, ch );
}
msg->nDataBytes = offset + outLen;
msg->nDataBits = ( msg->nDataBytes ) << 3;
msg->nDataBits = ( offset + outLen ) << 3;
Mem_Copy( data, buffer, outLen );
}

View File

@ -1,487 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// net_msg.c - network messages
//=======================================================================
#include "common.h"
#include "protocol.h"
#include "byteorder.h"
#include "mathlib.h"
// angles pack methods
#define ANGLE2CHAR(x) ((int)((x)*256 / 360) & 255)
#define CHAR2ANGLE(x) ((x)*(360.0f / 256))
#define ANGLE2SHORT(x) ((int)((x)*65536 / 360) & 65535)
#define SHORT2ANGLE(x) ((x)*(360.0f / 65536))
// probably movevars_t never reached 32 field integer limit (in theory of course)
static net_field_t move_fields[] =
{
{ PM_FIELD(gravity), NET_FLOAT, false },
{ PM_FIELD(stopspeed), NET_FLOAT, false },
{ PM_FIELD(maxspeed), NET_FLOAT, false },
{ PM_FIELD(spectatormaxspeed),NET_FLOAT, false },
{ PM_FIELD(accelerate), NET_FLOAT, false },
{ PM_FIELD(airaccelerate), NET_FLOAT, false },
{ PM_FIELD(wateraccelerate), NET_FLOAT, false },
{ PM_FIELD(friction), NET_FLOAT, false },
{ PM_FIELD(edgefriction), NET_FLOAT, false },
{ PM_FIELD(waterfriction), NET_FLOAT, false },
{ PM_FIELD(bounce), NET_FLOAT, false },
{ PM_FIELD(stepsize), NET_FLOAT, false },
{ PM_FIELD(maxvelocity), NET_FLOAT, false },
{ PM_FIELD(footsteps), NET_FLOAT, false },
{ PM_FIELD(rollangle), NET_FLOAT, false },
{ PM_FIELD(rollspeed), NET_FLOAT, false },
{ NULL },
};
/*
=============================================================================
SZ BUFFER (io functions)
=============================================================================
*/
/*
=======================
MSG_Init
init new buffer
=======================
*/
void MSG_Init( sizebuf_t *buf, byte *data, size_t length )
{
Mem_Set( buf, 0, sizeof(*buf));
buf->data = data;
buf->maxsize = length;
}
/*
=======================
MSG_GetSpace
get some space for write
=======================
*/
void *MSG_GetSpace( sizebuf_t *msg, size_t length )
{
void *data;
if( msg->cursize + length > msg->maxsize )
{
if( length > msg->maxsize )
Host_Error("MSG_GetSpace: length[%i] > buffer maxsize [%i]\n", length, msg->maxsize );
MsgDev( D_WARN, "MSG_GetSpace: overflow\n", msg->cursize + length, msg->maxsize );
MSG_Clear( msg );
msg->overflowed = true;
}
data = msg->data + msg->cursize;
msg->cursize += length;
return data;
}
/*
=======================
MSG_Print
used for write sv.forward cmds
=======================
*/
void MSG_Print( sizebuf_t *msg, const char *data )
{
size_t length = com.strlen(data) + 1;
if( msg->cursize )
{
if(msg->data[msg->cursize - 1]) Mem_Copy((byte *)MSG_GetSpace( msg, length ), data, length );
else Mem_Copy((byte *)MSG_GetSpace( msg, length - 1) - 1, data, length ); // write over trailing 0
}
else Mem_Copy((byte *)MSG_GetSpace( msg, length ), data, length );
}
/*
=======================
MSG_WriteData
used for swap buffers
=======================
*/
void _MSG_WriteData( sizebuf_t *buf, const void *data, size_t length, const char *filename, int fileline )
{
Mem_Copy( MSG_GetSpace( buf, length ), data, length );
}
void MSG_Clear( sizebuf_t *buf )
{
buf->cursize = 0;
buf->overflowed = false;
}
void MSG_BeginReading( sizebuf_t *msg )
{
msg->readcount = 0;
}
/*
=======================
MSG_WriteBits
write # of bytes
=======================
*/
void _MSG_WriteBits( sizebuf_t *msg, long value, const char *name, int net_type, const char *filename, const int fileline )
{
ftol_t dat;
byte *buf;
// this isn't an exact overflow check, but close enough
if( msg->maxsize - msg->cursize < 4 )
{
MsgDev( D_ERROR, "MSG_WriteBits: overflowed %i > %i (called at %s:%i)\n", msg->cursize, msg->maxsize, filename, fileline );
msg->overflowed = true;
return;
}
dat.l = value;
/*
switch( net_type )
{
case NET_SCALE:
value = dat.f * 4;
buf = MSG_GetSpace( msg, 1 );
buf[0] = value;
break;
case NET_COLOR:
value = bound( 0, dat.f, 255 );
buf = MSG_GetSpace( msg, 1 );
buf[0] = value;
break;
case NET_CHAR:
case NET_BYTE:
buf = MSG_GetSpace( msg, 1 );
buf[0] = value;
break;
case NET_SHORT:
case NET_WORD:
buf = MSG_GetSpace( msg, 2 );
buf[0] = value & 0xff;
buf[1] = value>>8;
break;
case NET_LONG:
case NET_FLOAT:
buf = MSG_GetSpace( msg, 4 );
buf[0] = (value>>0 ) & 0xff;
buf[1] = (value>>8 ) & 0xff;
buf[2] = (value>>16) & 0xff;
buf[3] = (value>>24);
break;
case NET_ANGLE8:
if( dat.f > 360 ) dat.f -= 360;
else if( dat.f < 0 ) dat.f += 360;
value = ANGLE2CHAR( dat.f );
buf = MSG_GetSpace( msg, 1 );
buf[0] = value;
break;
case NET_ANGLE:
if( dat.f > 360 ) dat.f -= 360;
else if( dat.f < 0 ) dat.f += 360;
value = ANGLE2SHORT( dat.f );
buf = MSG_GetSpace( msg, 2 );
buf[0] = value & 0xff;
buf[1] = value>>8;
break;
case NET_COORD:
value = dat.f * 8;
buf = MSG_GetSpace( msg, 2 );
buf[0] = value & 0xff;
buf[1] = value>>8;
break;
default:
Host_Error( "MSG_WriteBits: bad net.type %i (called at %s:%i)\n", net_type, filename, fileline );
break;
}
*/
if((NWDesc[net_type].min_range + NWDesc[net_type].max_range) != 0 )
{
// check range
if( value < NWDesc[net_type].min_range || value > NWDesc[net_type].max_range )
{
MsgDev( D_INFO, "MSG_Write%s: ", NWDesc[net_type].name );
if( name ) MsgDev( D_INFO, "'%s' ", name );
MsgDev( D_INFO, "range error %i should be in range (%i", value, NWDesc[net_type].min_range );
MsgDev( D_INFO, " %i)(called at %s:%i)\n", NWDesc[net_type].max_range, filename, fileline );
}
}
}
/*
=======================
MSG_ReadBits
read # of bytes
=======================
*/
long _MSG_ReadBits( sizebuf_t *msg, const char *name, int net_type, const char *filename, const int fileline )
{
ftol_t dat;
long value = 0;
/*
switch( net_type )
{
case NET_SCALE:
value = (signed char)(msg->data[msg->readcount]);
dat.f = value * 0.25f;
msg->readcount += 1;
break;
case NET_COLOR:
value = (byte)(msg->data[msg->readcount]);
dat.f = value;
msg->readcount += 1;
break;
case NET_CHAR:
dat.l = (signed char)msg->data[msg->readcount];
msg->readcount += 1;
break;
case NET_BYTE:
dat.l = (byte)msg->data[msg->readcount];
msg->readcount += 1;
break;
case NET_WORD:
case NET_SHORT:
dat.l = (short)BuffLittleShort( msg->data + msg->readcount );
msg->readcount += 2;
break;
case NET_LONG:
case NET_FLOAT:
dat.l = (long)BuffLittleLong( msg->data + msg->readcount );
msg->readcount += 4;
break;
case NET_ANGLE8:
value = (unsigned char)msg->data[msg->readcount];
dat.f = CHAR2ANGLE( value );
if( dat.f < -180 ) dat.f += 360;
else if( dat.f > 180 ) dat.f -= 360;
msg->readcount += 1;
break;
case NET_ANGLE:
value = (unsigned short)BuffLittleShort( msg->data + msg->readcount );
dat.f = SHORT2ANGLE( value );
if( dat.f < -180 ) dat.f += 360;
else if( dat.f > 180 ) dat.f -= 360;
msg->readcount += 2;
break;
case NET_COORD:
value = (short)BuffLittleShort( msg->data + msg->readcount );
dat.f = value * 0.125f;
msg->readcount += 2;
break;
default:
Host_Error( "MSG_ReadBits: bad net.type %i, (called at %s:%i)\n", net_type, filename, fileline );
break;
}
*/
value = dat.l;
// end of message or error reading
if( msg->readcount > msg->cursize )
{
if(( msg->readcount - msg->cursize ) > 1 )
{
MsgDev( D_ERROR, "MSG_Read%s: ", NWDesc[net_type].name );
MsgDev( D_ERROR, "msg total size %i, reading %i\n", msg->cursize, msg->readcount );
msg->error = true;
}
return -1;
}
return value;
}
/*
==============================================================================
MESSAGE IO FUNCTIONS
Handles byte ordering and avoids alignment errors
==============================================================================
*/
void _MSG_WriteString( sizebuf_t *sb, const char *src, const char *filename, int fileline )
{
if( !src )
{
_MSG_WriteData( sb, "", 1, filename, fileline );
}
else
{
char string[MAX_SYSPATH];
int l = com.strlen( src ) + 1;
if( l >= MAX_SYSPATH )
{
MsgDev( D_ERROR, "MSG_WriteString: exceeds %i symbols (called at %s:%i\n", MAX_SYSPATH, filename, fileline );
_MSG_WriteData( sb, "", 1, filename, fileline );
return;
}
com.strncpy( string, src, sizeof( string ));
_MSG_WriteData( sb, string, l, filename, fileline );
}
}
void _MSG_WriteStringLine( sizebuf_t *sb, const char *src, const char *filename, int fileline )
{
if( !src )
{
_MSG_WriteData( sb, "", 1, filename, fileline );
}
else
{
int l;
char *dst, string[MAX_SYSPATH];
l = com.strlen( src ) + 1;
if( l >= MAX_SYSPATH )
{
MsgDev( D_ERROR, "MSG_WriteString: exceeds %i symbols (called at %s:%i\n", MAX_SYSPATH, filename, fileline );
_MSG_WriteData( sb, "", 1, filename, fileline );
return;
}
dst = string;
while( 1 )
{
// some escaped chars parsed as two symbols - merge it here
if( src[0] == '\\' && src[1] == 'n' )
{
*dst++ = '\n';
src += 2;
l -= 1;
}
if( src[0] == '\\' && src[1] == 'r' )
{
*dst++ = '\r';
src += 2;
l -= 1;
}
if( src[0] == '\\' && src[1] == 't' )
{
*dst++ = '\t';
src += 2;
l -= 1;
}
else if(( *dst++ = *src++ ) == 0 )
break;
}
*dst = '\0'; // string end
_MSG_WriteData( sb, string, l, filename, fileline );
}
}
char *MSG_ReadString( sizebuf_t *msg )
{
static char string[MAX_SYSPATH];
int l = 0, c;
do
{
// use MSG_ReadByte so -1 is out of bounds
c = MSG_ReadByte( msg );
if( c == -1 || c == '\0' )
break;
// translate all fmt spec to avoid crash bugs
if( c == '%' ) c = '.';
string[l] = c;
l++;
} while( l < sizeof(string) - 1 );
string[l] = 0; // terminator
return string;
}
char *MSG_ReadStringLine( sizebuf_t *msg )
{
static char string[MAX_SYSPATH];
int l = 0, c;
do
{
// use MSG_ReadByte so -1 is out of bounds
c = MSG_ReadByte( msg );
if( c == -1 || c == '\0' || c == '\n' )
break;
// translate all fmt spec to avoid crash bugs
if( c == '%' ) c = '.';
string[l] = c;
l++;
} while( l < sizeof(string) - 1 );
string[l] = 0; // terminator
return string;
}
/*
=============================================================================
movevars_t communication
=============================================================================
*/
bool BF_WriteDeltaMovevars( bitbuf_t *msg, movevars_t *from, movevars_t *to )
{
int num_fields;
net_field_t *field;
int *fromF, *toF;
int i, flags = 0;
num_fields = (sizeof( move_fields ) / sizeof( move_fields[0] )) - 1;
if( num_fields > MASK_FLAGS ) return false; // this should never happen
// compare fields
for( i = 0, field = move_fields; i < num_fields; i++, field++ )
{
fromF = (int *)((byte *)from + field->offset );
toF = (int *)((byte *)to + field->offset );
if(*fromF != *toF || field->force) flags |= 1<<i;
}
// nothing at all changed
if( flags == 0 ) return false;
BF_WriteByte( msg, svc_movevars );
BF_WriteLong( msg, flags ); // send flags who indicates changes
for( i = 0, field = move_fields; i < num_fields; i++, field++ )
{
toF = (int *)((byte *)to + field->offset );
if( flags & 1<<i ) BF_WriteBits( msg, toF, field->bits );
}
return true;
}
void BF_ReadDeltaMovevars( bitbuf_t *msg, movevars_t *from, movevars_t *to )
{
net_field_t *field;
int i, flags;
int *fromF, *toF;
*to = *from;
for( i = 0, field = move_fields; field->name; i++, field++ )
{
// get flags of next packet if LONG out of range
if(( i & MASK_FLAGS ) == 0) flags = BF_ReadLong( msg );
fromF = (int *)((byte *)from + field->offset );
toF = (int *)((byte *)to + field->offset );
if( flags & ( 1<<( i & MASK_FLAGS )))
BF_ReadBits( msg, toF, field->bits );
else *toF = *fromF; // no change
}
}

View File

@ -5,73 +5,6 @@
#ifndef NET_MSG_H
#define NET_MSG_H
enum net_types_e
{
NET_BAD = 0,
NET_CHAR = 8,
NET_BYTE = 8,
NET_SHORT = 16,
NET_WORD = 16,
NET_LONG = 32,
NET_FLOAT = 32,
NET_ANGLE8 = 8, // angle 2 char
NET_ANGLE = 16, // angle 2 short
NET_SCALE = 8,
NET_COORD = 32,
NET_COLOR = 8,
NET_TYPES,
};
typedef union
{
float f;
long l;
} ftol_t;
typedef struct
{
bool overflowed; // set to true if the buffer size failed
bool error;
byte *data;
int maxsize;
int cursize; // size in bytes
int readcount;
} sizebuf_t;
typedef struct net_desc_s
{
int type; // pixelformat
char name[8]; // used for debug
int min_range;
int max_range;
} net_desc_t;
// communication state description
typedef struct net_field_s
{
char *name;
int offset;
int bits;
bool force; // will be send for newentity
} net_field_t;
static const net_desc_t NWDesc[] =
{
{ NET_BAD, "none", 0, 0 }, // full range
{ NET_CHAR, "Char", -128, 127 },
{ NET_BYTE, "Byte", 0, 255 },
{ NET_SHORT, "Short", -32767, 32767 },
{ NET_WORD, "Word", 0, 65535 },
{ NET_LONG, "Long", 0, 0 }, // can't overflow
{ NET_FLOAT, "Float", 0, 0 }, // can't overflow
{ NET_ANGLE8, "Angle", -360, 360 },
{ NET_ANGLE, "Angle", -360, 360 },
{ NET_SCALE, "Scale", -128, 127 },
{ NET_COORD, "Coord", -262140, 262140 },
{ NET_COLOR, "Color", 0, 255 },
};
/*
==========================================================
@ -86,11 +19,6 @@ static const net_desc_t NWDesc[] =
#include "entity_state.h"
#include "net_buffer.h"
#define ES_FIELD( x ) #x,(int)&((entity_state_t*)0)->x
#define EV_FIELD( x ) #x,(int)&((event_args_t*)0)->x
#define PM_FIELD( x ) #x,(int)&((movevars_t*)0)->x
#define CM_FIELD( x ) #x,(int)&((usercmd_t*)0)->x
// config strings are a general means of communication from
// the server to all connected clients.
// each config string can be at most CS_SIZE characters.
@ -117,57 +45,10 @@ static const net_desc_t NWDesc[] =
#define CS_LIGHTSTYLES (CS_CLASSNAMES+MAX_CLASSNAMES) // lightstyle patterns
#define MAX_CONFIGSTRINGS (CS_LIGHTSTYLES+MAX_LIGHTSTYLES) // total count
/*
==============================================================================
MESSAGE IO FUNCTIONS
Handles byte ordering and avoids alignment errors
==============================================================================
*/
void MSG_Init( sizebuf_t *buf, byte *data, size_t length );
void MSG_Clear( sizebuf_t *buf );
void MSG_Print( sizebuf_t *msg, const char *data );
void _MSG_WriteBits( sizebuf_t *msg, long value, const char *name, int bits, const char *filename, const int fileline );
long _MSG_ReadBits( sizebuf_t *msg, const char *name, int bits, const char *filename, const int fileline );
void _MSG_Begin( int dest, const char *filename, int fileline );
void _MSG_WriteString( sizebuf_t *sb, const char *s, const char *filename, int fileline );
void _MSG_WriteStringLine( sizebuf_t *sb, const char *src, const char *filename, int fileline );
void _MSG_WriteData( sizebuf_t *sb, const void *data, size_t length, const char *filename, int fileline );
bool _MSG_WriteDeltaMovevars( sizebuf_t *sb, movevars_t *from, movevars_t *cmd, const char *filename, const int fileline );
bool _MSG_Send( int dest, const vec3_t origin, const edict_t *ent, bool direct, const char *filename, int fileline );
#define MSG_Begin( x ) _MSG_Begin( x, __FILE__, __LINE__)
#define MSG_WriteChar(x,y) _MSG_WriteBits (x, y, NWDesc[NET_CHAR].name, NET_CHAR, __FILE__, __LINE__)
#define MSG_WriteByte(x,y) _MSG_WriteBits (x, y, NWDesc[NET_BYTE].name, NET_BYTE, __FILE__, __LINE__)
#define MSG_WriteShort(x,y) _MSG_WriteBits(x, y, NWDesc[NET_SHORT].name, NET_SHORT,__FILE__, __LINE__)
#define MSG_WriteWord(x,y) _MSG_WriteBits (x, y, NWDesc[NET_WORD].name, NET_WORD, __FILE__, __LINE__)
#define MSG_WriteLong(x,y) _MSG_WriteBits (x, y, NWDesc[NET_LONG].name, NET_LONG, __FILE__, __LINE__)
#define MSG_WriteFloat(x,y) _MSG_WriteFloat(x, y, __FILE__, __LINE__)
#define MSG_WriteDouble(x,y) _MSG_WriteDouble(x, y, __FILE__, __LINE__)
#define MSG_WriteString(x,y) _MSG_WriteString (x, y, __FILE__, __LINE__)
#define MSG_WriteStringLine(x,y) _MSG_WriteStringLine (x, y, __FILE__, __LINE__)
#define MSG_WriteData(x,y,z) _MSG_WriteData( x, y, z, __FILE__, __LINE__)
#define MSG_WriteDeltaMovevars(x, y, z) _MSG_WriteDeltaMovevars(x, y, z, __FILE__, __LINE__)
#define MSG_WriteBits( buf, value, name, bits ) _MSG_WriteBits( buf, value, name, bits, __FILE__, __LINE__ )
#define MSG_ReadBits( buf, name, bits ) _MSG_ReadBits( buf, name, bits, __FILE__, __LINE__ )
#define MSG_Send(x, y, z) _MSG_Send(x, y, z, false, __FILE__, __LINE__)
#define MSG_DirectSend(x, y, z) _MSG_Send(x, y, z, true, __FILE__, __LINE__)
void MSG_BeginReading (sizebuf_t *sb);
#define MSG_ReadChar( x ) _MSG_ReadBits( x, NWDesc[NET_CHAR].name, NET_CHAR, __FILE__, __LINE__ )
#define MSG_ReadByte( x ) _MSG_ReadBits( x, NWDesc[NET_BYTE].name, NET_BYTE, __FILE__, __LINE__ )
#define MSG_ReadShort( x) _MSG_ReadBits( x, NWDesc[NET_SHORT].name, NET_SHORT, __FILE__, __LINE__ )
#define MSG_ReadWord( x ) _MSG_ReadBits( x, NWDesc[NET_WORD].name, NET_WORD, __FILE__, __LINE__ )
#define MSG_ReadLong( x ) _MSG_ReadBits( x, NWDesc[NET_LONG].name, NET_LONG, __FILE__, __LINE__ )
char *MSG_ReadString( sizebuf_t *sb );
char *MSG_ReadStringLine( sizebuf_t *sb );
void MSG_ReadData( sizebuf_t *sb, void *buffer, size_t size );
void MSG_ReadDeltaMovevars( sizebuf_t *sb, movevars_t *from, movevars_t *cmd );
// huffman compression
void Huff_Init( void );
void Huff_CompressPacket( bitbuf_t *msg, int offset );
void Huff_DecompressPacket( bitbuf_t *msg, int offset );
void Huff_CompressPacket( sizebuf_t *msg, int offset );
void Huff_DecompressPacket( sizebuf_t *msg, int offset );
/*
==============================================================
@ -206,7 +87,7 @@ typedef struct netchan_s
int last_reliable_sequence; // sequence number of last send
// reliable staging and holding areas
bitbuf_t message; // writing buffer to send to server
sizebuf_t message; // writing buffer to send to server
byte message_buf[MAX_MSGLEN-16]; // leave space for header
// message is copied to this buffer when it is first transfered
@ -222,7 +103,7 @@ typedef struct netchan_s
} netchan_t;
extern netadr_t net_from;
extern bitbuf_t net_message;
extern sizebuf_t net_message;
extern byte net_message_buffer[MAX_MSGLEN];
extern cvar_t *net_speeds;
@ -231,8 +112,6 @@ extern cvar_t *net_speeds;
#define PORT_SERVER 27910
#define MULTIPLAYER_BACKUP 64 // how many data slots to use when in multiplayer (must be power of 2)
#define SINGLEPLAYER_BACKUP 16 // same for single player
#define MAX_FLAGS 32 // 32 bits == 32 flags
#define MASK_FLAGS (MAX_FLAGS - 1)
void Netchan_Init( void );
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport );
@ -241,6 +120,6 @@ void Netchan_Transmit( netchan_t *chan, int lengthInBytes, byte *data );
void Netchan_TransmitBits( netchan_t *chan, int lengthInBits, byte *data );
void Netchan_OutOfBand( int net_socket, netadr_t adr, int length, byte *data );
void Netchan_OutOfBandPrint( int net_socket, netadr_t adr, char *format, ... );
bool Netchan_Process( netchan_t *chan, bitbuf_t *msg );
bool Netchan_Process( netchan_t *chan, sizebuf_t *msg );
#endif//NET_MSG_H

View File

@ -226,10 +226,6 @@ SOURCE=.\common\net_huff.c
# End Source File
# Begin Source File
SOURCE=.\common\net_msg.c
# End Source File
# Begin Source File
SOURCE=.\server\sv_client.c
# End Source File
# Begin Source File

View File

@ -27,6 +27,8 @@ extern int SV_UPDATE_BACKUP;
#define MAP_HAS_SPAWNPOINT BIT( 1 )
#define MAP_HAS_LANDMARK BIT( 2 )
#define SV_Send(x,y,z) SV_Multicast(x, y, z, false )
#define SV_DirectSend(x,y,z) SV_Multicast( x, y, z, true )
#define NUM_FOR_EDICT(e) ((int)((edict_t *)(e) - svgame.edicts))
#define EDICT_NUM( num ) SV_EDICT_NUM( num, __FILE__, __LINE__ )
#define STRING( offset ) SV_GetString( offset )
@ -74,10 +76,10 @@ typedef struct server_s
// the multicast buffer is used to send a message to a set of clients
// it is only used to marshall data until SV_Message is called
bitbuf_t multicast;
sizebuf_t multicast;
byte multicast_buf[MAX_MSGLEN];
bitbuf_t signon;
sizebuf_t signon;
byte signon_buf[MAX_MSGLEN];
bool write_bad_message; // just for debug
@ -128,12 +130,12 @@ typedef struct sv_client_s
// The reliable buf contain reliable user messages that must be followed
// after pvs frame
bitbuf_t reliable;
sizebuf_t reliable;
byte reliable_buf[MAX_MSGLEN];
// the datagram is written to by sound calls, prints, temp ents, etc.
// it can be harmlessly overflowed.
bitbuf_t datagram;
sizebuf_t datagram;
byte datagram_buf[MAX_MSGLEN];
client_frame_t *frames; // updates can be delta'd from here
@ -275,7 +277,6 @@ extern cvar_t *sv_airaccelerate;
extern cvar_t *sv_accelerate;
extern cvar_t *sv_friction;
extern cvar_t *sv_edgefriction;
extern cvar_t *sv_idealpitchscale;
extern cvar_t *sv_maxvelocity;
extern cvar_t *sv_gravity;
extern cvar_t *sv_stopspeed;
@ -362,17 +363,17 @@ void SV_GetChallenge( netadr_t from );
void SV_DirectConnect( netadr_t from );
void SV_TogglePause( const char *msg );
void SV_PutClientInServer( edict_t *ent );
void SV_FullClientUpdate( sv_client_t *cl, bitbuf_t *msg );
void SV_UpdatePhysinfo( sv_client_t *cl, bitbuf_t *msg );
void SV_FullClientUpdate( sv_client_t *cl, sizebuf_t *msg );
void SV_UpdatePhysinfo( sv_client_t *cl, sizebuf_t *msg );
bool SV_ClientConnect( edict_t *ent, char *userinfo );
void SV_ClientThink( sv_client_t *cl, usercmd_t *cmd );
void SV_ExecuteClientMessage( sv_client_t *cl, bitbuf_t *msg );
void SV_ConnectionlessPacket( netadr_t from, bitbuf_t *msg );
void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg );
void SV_ConnectionlessPacket( netadr_t from, sizebuf_t *msg );
int SV_Multicast( int dest, const vec3_t origin, const edict_t *ent, bool direct );
edict_t *SV_FakeConnect( const char *netname );
void SV_PreRunCmd( sv_client_t *cl, usercmd_t *ucmd );
void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd );
void SV_PostRunCmd( sv_client_t *cl );
void SV_SetIdealPitch( sv_client_t *cl );
void SV_InitClientMove( void );
void SV_UpdateServerInfo( void );
@ -385,7 +386,7 @@ void SV_Newgame_f( void );
//
// sv_frame.c
//
void SV_WriteFrameToClient( sv_client_t *client, bitbuf_t *msg );
void SV_WriteFrameToClient( sv_client_t *client, sizebuf_t *msg );
void SV_BuildClientFrame( sv_client_t *client );
void SV_InactivateClients( void );
void SV_SendMessagesToAll( void );
@ -405,7 +406,7 @@ void SV_SetModel( edict_t *ent, const char *name );
void SV_CopyTraceToGlobal( trace_t *trace );
void SV_SetMinMaxSize( edict_t *e, const float *min, const float *max );
void SV_CreateDecal( const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags );
void SV_PlaybackEvent( bitbuf_t *msg, event_info_t *info );
void SV_PlaybackEvent( sizebuf_t *msg, event_info_t *info );
void SV_BaselineForEntity( edict_t *pEdict );
void SV_WriteEntityPatch( const char *filename );
script_t *SV_GetEntityScript( const char *filename );

View File

@ -9,8 +9,6 @@
#include "protocol.h"
#include "net_encode.h"
#define MAX_FORWARD 6
typedef struct ucmd_s
{
const char *name;
@ -556,7 +554,7 @@ Shift down the remaining args
Redirect all printfs
===============
*/
void SV_RemoteCommand( netadr_t from, bitbuf_t *msg )
void SV_RemoteCommand( netadr_t from, sizebuf_t *msg )
{
char remaining[1024];
static char outputbuf[MAX_MSGLEN - 16];
@ -590,7 +588,7 @@ SV_FullClientUpdate
Writes all update values to a bitbuf
===================
*/
void SV_FullClientUpdate( sv_client_t *cl, bitbuf_t *msg )
void SV_FullClientUpdate( sv_client_t *cl, sizebuf_t *msg )
{
int i;
char info[MAX_INFO_STRING];
@ -612,7 +610,7 @@ void SV_FullClientUpdate( sv_client_t *cl, bitbuf_t *msg )
}
else BF_WriteByte( msg, false );
MSG_DirectSend( MSG_ALL, vec3_origin, NULL );
SV_DirectSend( MSG_ALL, vec3_origin, NULL );
BF_Clear( msg );
}
@ -623,7 +621,7 @@ void SV_RefreshUserinfo( void )
for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
if( cl->state >= cs_connected && !(cl->edict && cl->edict->v.flags & FL_FAKECLIENT ))
cl->sendinfo = cl->sendmovevars = true;
cl->sendinfo = true;
}
/*
@ -634,13 +632,13 @@ this is send all movevars values when client connected
otherwise see code SV_UpdateMovevars()
===================
*/
void SV_UpdatePhysinfo( sv_client_t *cl, bitbuf_t *msg )
void SV_UpdatePhysinfo( sv_client_t *cl, sizebuf_t *msg )
{
movevars_t nullmovevars;
Mem_Set( &nullmovevars, 0, sizeof( nullmovevars ));
BF_WriteDeltaMovevars( msg, &nullmovevars, &svgame.movevars );
MSG_DirectSend( MSG_ONE, NULL, cl->edict );
MSG_WriteDeltaMovevars( msg, &nullmovevars, &svgame.movevars );
SV_DirectSend( MSG_ONE, NULL, cl->edict );
BF_Clear( msg );
}
@ -692,7 +690,7 @@ void SV_PutClientInServer( edict_t *ent )
BF_WriteByte( &sv.multicast, svc_setangle );
BF_WriteBitAngle( &sv.multicast, ent->v.angles[0], 16 );
BF_WriteBitAngle( &sv.multicast, ent->v.angles[1], 16 );
MSG_DirectSend( MSG_ONE, vec3_origin, client->edict );
SV_DirectSend( MSG_ONE, vec3_origin, client->edict );
ent->v.fixangle = 0;
}
ent->pvServerData->s.ed_flags |= (ESF_NODELTA|ESF_NO_PREDICTION);
@ -707,7 +705,7 @@ void SV_PutClientInServer( edict_t *ent )
BF_WriteByte( &client->netchan.message, svc_setview );
BF_WriteWord( &client->netchan.message, NUM_FOR_EDICT( client->edict ));
MSG_Send( MSG_ONE, NULL, client->edict );
SV_Send( MSG_ONE, NULL, client->edict );
}
// clear any temp states
@ -732,7 +730,7 @@ void SV_TogglePause( const char *msg )
// send notification to all clients
BF_WriteByte( &sv.multicast, svc_setpause );
BF_WriteByte( &sv.multicast, sv.paused );
MSG_Send( MSG_ALL, vec3_origin, NULL );
SV_Send( MSG_ALL, vec3_origin, NULL );
}
/*
@ -1009,6 +1007,8 @@ void SV_Begin_f( sv_client_t *cl )
return;
}
// don't send movevars before svc_deltatable
cl->sendmovevars = true;
cl->state = cs_spawned;
SV_PutClientInServer( cl->edict );
@ -1017,7 +1017,7 @@ void SV_Begin_f( sv_client_t *cl )
{
BF_WriteByte( &sv.multicast, svc_setpause );
BF_WriteByte( &sv.multicast, sv.paused );
MSG_Send( MSG_ONE, vec3_origin, cl->edict );
SV_Send( MSG_ONE, vec3_origin, cl->edict );
SV_ClientPrintf( cl, PRINT_HIGH, "Server is paused.\n" );
}
}
@ -1255,13 +1255,13 @@ SV_Send
Sends the contents of sv.multicast to a subset of the clients,
then clears sv.multicast.
MULTICAST_ONE send to one client (ent can't be NULL)
MULTICAST_ALL same as broadcast (origin can be NULL)
MULTICAST_PVS send to clients potentially visible from org
MULTICAST_PHS send to clients potentially hearable from org
MSG_ONE send to one client (ent can't be NULL)
MSG_ALL same as broadcast (origin can be NULL)
MSG_PVS send to clients potentially visible from org
MSG_PHS send to clients potentially hearable from org
=================
*/
bool _MSG_Send( int dest, const vec3_t origin, const edict_t *ent, bool direct, const char *filename, int fileline )
bool SV_Multicast( int dest, const vec3_t origin, const edict_t *ent, bool direct )
{
byte *mask = NULL;
int leafnum = 0, numsends = 0;
@ -1317,7 +1317,7 @@ bool _MSG_Send( int dest, const vec3_t origin, const edict_t *ent, bool direct,
specproxy = reliable = true;
break;
default:
Host_Error( "MSG_Send: bad dest: %i (called at %s:%i)\n", dest, filename, fileline );
Host_Error( "SV_Send: bad dest: %i\n", dest );
return false;
}
@ -1359,7 +1359,7 @@ bool _MSG_Send( int dest, const vec3_t origin, const edict_t *ent, bool direct,
BF_WriteByte( &sv.multicast, svc_bad );
BF_WriteLong( &sv.multicast, rand( )); // send some random data
BF_WriteString( &sv.multicast, host.finalmsg ); // send final message
MSG_Send( MSG_ALL, vec3_origin, NULL );
SV_Send( MSG_ALL, vec3_origin, NULL );
sv.write_bad_message = false;
}
return numsends; // debug
@ -1375,7 +1375,7 @@ Clients that are in the game can still send
connectionless packets.
=================
*/
void SV_ConnectionlessPacket( netadr_t from, bitbuf_t *msg )
void SV_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
{
char *s;
char *c;
@ -1399,72 +1399,6 @@ void SV_ConnectionlessPacket( netadr_t from, bitbuf_t *msg )
else MsgDev( D_ERROR, "bad connectionless packet from %s:\n%s\n", NET_AdrToString( from ), s );
}
/*
===============
SV_SetIdealPitch
===============
*/
void SV_SetIdealPitch( sv_client_t *cl )
{
float angleval, sinval, cosval;
trace_t tr;
vec3_t top, bottom;
float z[MAX_FORWARD];
int i, j;
int step, dir, steps;
edict_t *ent = cl->edict;
if( !( ent->v.flags & FL_ONGROUND ))
return;
angleval = ent->v.angles[YAW] * M_PI * 2 / 360;
com.sincos( angleval, &sinval, &cosval );
for( i = 0; i < MAX_FORWARD; i++ )
{
top[0] = ent->v.origin[0] + cosval * (i + 3) * 12;
top[1] = ent->v.origin[1] + sinval * (i + 3) * 12;
top[2] = ent->v.origin[2] + ent->v.view_ofs[2];
bottom[0] = top[0];
bottom[1] = top[1];
bottom[2] = top[2] - 160;
tr = SV_Move( top, vec3_origin, vec3_origin, bottom, MOVE_NOMONSTERS, ent );
if( tr.fAllSolid )
return; // looking at a wall, leave ideal the way is was
if( tr.flFraction == 1.0f )
return; // near a dropoff
z[i] = top[2] + tr.flFraction * (bottom[2] - top[2]);
}
dir = 0;
steps = 0;
for( j = 1; j < i; j++ )
{
step = z[j] - z[j-1];
if( step > -ON_EPSILON && step < ON_EPSILON )
continue;
if( dir && ( step-dir > ON_EPSILON || step-dir < -ON_EPSILON ))
return; // mixed changes
steps++;
dir = step;
}
if( !dir )
{
ent->v.idealpitch = 0;
return;
}
if( steps < 2 ) return;
ent->v.idealpitch = -dir * sv_idealpitchscale->value;
}
/*
==================
SV_ReadClientMove
@ -1477,7 +1411,7 @@ On very fast clients, there may be multiple usercmd packed into
each of the backup packets.
==================
*/
static void SV_ReadClientMove( sv_client_t *cl, bitbuf_t *msg )
static void SV_ReadClientMove( sv_client_t *cl, sizebuf_t *msg )
{
int checksum1, checksum2;
int key, lastframe, net_drop, size;
@ -1553,7 +1487,7 @@ SV_ExecuteClientMessage
Parse a client packet
===================
*/
void SV_ExecuteClientMessage( sv_client_t *cl, bitbuf_t *msg )
void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg )
{
int c, stringCmdCount = 0;
bool move_issued = false;

View File

@ -88,7 +88,7 @@ void SV_BroadcastCommand( char *fmt, ... )
BF_WriteByte( &sv.multicast, svc_stufftext );
BF_WriteString( &sv.multicast, string );
MSG_Send( MSG_ALL, NULL, NULL );
SV_Send( MSG_ALL, NULL, NULL );
}
/*

View File

@ -53,7 +53,7 @@ SV_EmitPacketEntities
Writes a delta update of an entity_state_t list to the message->
=============
*/
void SV_EmitPacketEntities( client_frame_t *from, client_frame_t *to, bitbuf_t *msg )
void SV_EmitPacketEntities( client_frame_t *from, client_frame_t *to, sizebuf_t *msg )
{
entity_state_t *oldent, *newent;
int oldindex, newindex;
@ -209,7 +209,7 @@ static void SV_AddEntitiesToPacket( edict_t *pViewEnt, edict_t *pClient, client_
}
}
static void SV_EmitEvents( sv_client_t *cl, client_frame_t *frame, bitbuf_t *msg )
static void SV_EmitEvents( sv_client_t *cl, client_frame_t *frame, sizebuf_t *msg )
{
int i, ev;
event_state_t *es;
@ -259,7 +259,7 @@ SV_WriteClientData
=============
*/
void SV_WriteClientData( client_frame_t *from, client_frame_t *to, bitbuf_t *msg )
void SV_WriteClientData( client_frame_t *from, client_frame_t *to, sizebuf_t *msg )
{
clientdata_t *cd, *ocd;
clientdata_t dummy;
@ -282,7 +282,7 @@ void SV_WriteClientData( client_frame_t *from, client_frame_t *to, bitbuf_t *msg
SV_WriteFrameToClient
==================
*/
void SV_WriteFrameToClient( sv_client_t *cl, bitbuf_t *msg )
void SV_WriteFrameToClient( sv_client_t *cl, sizebuf_t *msg )
{
client_frame_t *frame, *oldframe;
int lastframe;
@ -366,8 +366,6 @@ void SV_BuildClientFrame( sv_client_t *cl )
if( !sv.paused )
{
SV_SetIdealPitch( cl );
// update client fixangle
switch( clent->v.fixangle )
{
@ -375,13 +373,13 @@ void SV_BuildClientFrame( sv_client_t *cl )
BF_WriteByte( &sv.multicast, svc_setangle );
BF_WriteBitAngle( &sv.multicast, clent->v.angles[0], 16 );
BF_WriteBitAngle( &sv.multicast, clent->v.angles[1], 16 );
MSG_DirectSend( MSG_ONE, vec3_origin, clent );
SV_DirectSend( MSG_ONE, vec3_origin, clent );
clent->pvServerData->s.ed_flags |= ESF_NO_PREDICTION;
break;
case 2:
BF_WriteByte( &sv.multicast, svc_addangle );
BF_WriteBitAngle( &sv.multicast, cl->addangle, 16 );
MSG_DirectSend( MSG_ONE, vec3_origin, clent );
SV_DirectSend( MSG_ONE, vec3_origin, clent );
cl->addangle = 0;
break;
}
@ -444,7 +442,7 @@ SV_SendClientDatagram
bool SV_SendClientDatagram( sv_client_t *cl )
{
byte msg_buf[MAX_MSGLEN];
bitbuf_t msg;
sizebuf_t msg;
SV_BuildClientFrame( cl );

View File

@ -159,7 +159,7 @@ void SV_ConfigString( int index, const char *val )
BF_WriteByte( &sv.multicast, svc_configstring );
BF_WriteShort( &sv.multicast, index );
BF_WriteString( &sv.multicast, val );
MSG_Send( MSG_ALL, vec3_origin, NULL );
SV_Send( MSG_ALL, vec3_origin, NULL );
}
}
@ -175,7 +175,7 @@ void SV_CreateDecal( const float *origin, int decalIndex, int entityIndex, int m
if( entityIndex > 0 )
BF_WriteWord( &sv.multicast, modelIndex );
BF_WriteByte( &sv.multicast, flags );
MSG_Send( MSG_INIT, NULL, NULL );
SV_Send( MSG_INIT, NULL, NULL );
}
static bool SV_OriginIn( int mode, const vec3_t v1, const vec3_t v2 )
@ -507,7 +507,7 @@ void SV_FreeEdicts( void )
}
}
void SV_PlaybackEvent( bitbuf_t *msg, event_info_t *info )
void SV_PlaybackEvent( sizebuf_t *msg, event_info_t *info )
{
event_args_t nullargs;
@ -620,7 +620,7 @@ void SV_BaselineForEntity( edict_t *pEdict )
Mem_Set( &nullstate, 0, sizeof( nullstate ));
BF_WriteByte( &sv.multicast, svc_spawnbaseline );
MSG_WriteDeltaEntity( &nullstate, &sv_ent->s, &sv.multicast, true, sv.time );
MSG_DirectSend( MSG_ALL, vec3_origin, NULL );
SV_DirectSend( MSG_ALL, vec3_origin, NULL );
}
}
}
@ -1450,7 +1450,7 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float
BF_WriteWord( &sv.multicast, entityIndex );
if( flags & SND_FIXED_ORIGIN ) BF_WriteBitVec3Coord( &sv.multicast, origin );
MSG_Send( msg_dest, origin, NULL );
SV_Send( msg_dest, origin, NULL );
}
/*
@ -1534,7 +1534,7 @@ void pfnEmitAmbientSound( edict_t *ent, float *pos, const char *sample, float vo
BF_WriteWord( &sv.multicast, number );
BF_WriteBitVec3Coord( &sv.multicast, pos );
MSG_Send( msg_dest, origin, NULL );
SV_Send( msg_dest, origin, NULL );
}
/*
@ -1830,7 +1830,7 @@ void pfnClientCommand( edict_t* pEdict, char* szFmt, ... )
{
BF_WriteByte( &sv.multicast, svc_stufftext );
BF_WriteString( &sv.multicast, buffer );
MSG_Send( MSG_ONE, NULL, client->edict );
SV_Send( MSG_ONE, NULL, client->edict );
}
else MsgDev( D_ERROR, "Tried to stuff bad command %s\n", buffer );
}
@ -1863,7 +1863,7 @@ void pfnParticleEffect( const float *org, const float *dir, float color, float c
}
BF_WriteByte( &sv.multicast, count );
BF_WriteByte( &sv.multicast, color );
MSG_Send( MSG_ALL, org, NULL );
SV_Send( MSG_ALL, org, NULL );
}
/*
@ -1999,7 +1999,7 @@ void pfnMessageEnd( void )
if( !VectorIsNull( svgame.msg_org )) org = svgame.msg_org;
svgame.msg_dest = bound( MSG_BROADCAST, svgame.msg_dest, MSG_SPEC );
MSG_Send( svgame.msg_dest, org, svgame.msg_ent );
SV_Send( svgame.msg_dest, org, svgame.msg_ent );
}
/*
@ -2081,17 +2081,52 @@ pfnWriteString
=============
*/
void pfnWriteString( const char *sz )
void pfnWriteString( const char *src )
{
int cur_size = BF_GetNumBytesWritten( &sv.multicast );
int total_size;
char *dst, string[MAX_SYSPATH];
int len = com.strlen( src ) + 1;
// FIXME: replace with BF_WriteStringLine
BF_WriteString( &sv.multicast, sz ); // allow \n, \r, \t
total_size = BF_GetNumBytesWritten( &sv.multicast ) - cur_size;
if( len >= MAX_SYSPATH )
{
MsgDev( D_ERROR, "pfnWriteString: exceeds %i symbols\n", MAX_SYSPATH );
BF_WriteChar( &sv.multicast, 0 );
svgame.msg_realsize += 1;
return;
}
// prepare string to sending
dst = string;
while( 1 )
{
// some escaped chars parsed as two symbols - merge it here
if( src[0] == '\\' && src[1] == 'n' )
{
*dst++ = '\n';
src += 2;
len -= 1;
}
else if( src[0] == '\\' && src[1] == 'r' )
{
*dst++ = '\r';
src += 2;
len -= 1;
}
else if( src[0] == '\\' && src[1] == 't' )
{
*dst++ = '\t';
src += 2;
len -= 1;
}
else if(( *dst++ = *src++ ) == 0 )
break;
}
*dst = '\0'; // string end (not included in count)
BF_WriteString( &sv.multicast, string );
// NOTE: some messages with constant string length can be marked as known sized
svgame.msg_realsize += total_size;
svgame.msg_realsize += len;
}
/*
@ -2342,7 +2377,7 @@ int pfnRegUserMsg( const char *pszName, int iSize )
BF_WriteString( &sv.multicast, pszName );
BF_WriteByte( &sv.multicast, i );
BF_WriteByte( &sv.multicast, (byte)iSize );
MSG_Send( MSG_ALL, vec3_origin, NULL );
SV_Send( MSG_ALL, vec3_origin, NULL );
}
return i;
}
@ -2439,7 +2474,7 @@ void pfnClientPrintf( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg )
if( fake ) return;
BF_WriteByte( &sv.multicast, svc_centerprint );
BF_WriteString( &sv.multicast, szMsg );
MSG_Send( MSG_ONE, NULL, client->edict );
SV_Send( MSG_ONE, NULL, client->edict );
break;
}
}
@ -2542,7 +2577,7 @@ void pfnCrosshairAngle( const edict_t *pClient, float pitch, float yaw )
BF_WriteByte( &sv.multicast, svc_crosshairangle );
BF_WriteBitAngle( &sv.multicast, pitch, 8 );
BF_WriteBitAngle( &sv.multicast, yaw, 8 );
MSG_Send( MSG_ONE, vec3_origin, pClient );
SV_Send( MSG_ONE, vec3_origin, pClient );
}
/*
@ -2582,7 +2617,7 @@ void pfnSetView( const edict_t *pClient, const edict_t *pViewent )
BF_WriteByte( &client->netchan.message, svc_setview );
BF_WriteWord( &client->netchan.message, NUM_FOR_EDICT( pViewent ));
MSG_Send( MSG_ONE, NULL, client->edict );
SV_Send( MSG_ONE, NULL, client->edict );
}
/*
@ -2715,7 +2750,7 @@ void pfnFadeClientVolume( const edict_t *pEdict, float fadePercent, float fadeOu
BF_WriteFloat( &sv.multicast, fadeOutSeconds );
BF_WriteFloat( &sv.multicast, holdTime );
BF_WriteFloat( &sv.multicast, fadeInSeconds );
MSG_Send( MSG_ONE, NULL, cl->edict );
SV_Send( MSG_ONE, NULL, cl->edict );
}
/*
@ -3499,14 +3534,14 @@ static enginefuncs_t gEngfuncs =
pfnSetFatPVS,
pfnSetFatPAS,
pfnCheckVisibility,
MSG_DeltaSetField,
MSG_DeltaUnsetField,
MSG_DeltaAddEncoder,
Delta_SetField,
Delta_UnsetField,
Delta_AddEncoder,
pfnGetCurrentPlayer,
pfnCanSkipPlayer,
MSG_DeltaFindField,
MSG_DeltaSetFieldByIndex,
MSG_DeltaUnsetFieldByIndex,
Delta_FindField,
Delta_SetFieldByIndex,
Delta_UnsetFieldByIndex,
pfnSetGroupMask,
pfnDropClient,
Host_Error,

View File

@ -45,7 +45,7 @@ int SV_FindIndex( const char *name, int start, int end, bool create )
BF_WriteByte( &sv.multicast, svc_configstring );
BF_WriteShort( &sv.multicast, start + i );
BF_WriteString( &sv.multicast, name );
MSG_Send( MSG_ALL, vec3_origin, NULL );
SV_Send( MSG_ALL, vec3_origin, NULL );
}
return i;
}

View File

@ -6,6 +6,7 @@
#include "common.h"
#include "server.h"
#include "protocol.h"
#include "net_encode.h"
#define HEARTBEAT_SECONDS (300 * 1000) // 300 seconds
@ -23,7 +24,6 @@ cvar_t *allow_download;
cvar_t *sv_enforcetime;
cvar_t *sv_airaccelerate;
cvar_t *sv_wateraccelerate;
cvar_t *sv_idealpitchscale;
cvar_t *sv_maxvelocity;
cvar_t *sv_gravity;
cvar_t *sv_stepheight;
@ -160,6 +160,28 @@ void SV_GiveMsec( void )
}
}
/*
================
SV_HasActivePlayers
returns true if server have spawned players
================
*/
bool SV_HasActivePlayers( void )
{
int i;
// server inactive
if( !svs.clients ) return false;
for( i = 0; i < sv_maxclients->integer; i++ )
{
if( svs.clients[i].state == cs_spawned )
return true;
}
return false;
}
/*
===================
SV_UpdateMovevars
@ -233,9 +255,9 @@ void SV_UpdateMovevars( void )
BF_Clear( &sv.multicast );
if( BF_WriteDeltaMovevars( &sv.multicast, &svgame.oldmovevars, &svgame.movevars ))
if( MSG_WriteDeltaMovevars( &sv.multicast, &svgame.oldmovevars, &svgame.movevars ))
{
MSG_Send( MSG_ALL, vec3_origin, NULL );
SV_Send( MSG_ALL, vec3_origin, NULL );
Mem_Copy( &svgame.oldmovevars, &svgame.movevars, sizeof( movevars_t )); // oldstate changed
}
physinfo->modified = false;
@ -250,7 +272,7 @@ void pfnUpdateServerInfo( const char *szKey, const char *szValue, const char *un
BF_WriteByte( &sv.multicast, svc_serverinfo );
BF_WriteString( &sv.multicast, szKey );
BF_WriteString( &sv.multicast, szValue );
MSG_Send( MSG_ALL, vec3_origin, NULL );
SV_Send( MSG_ALL, vec3_origin, NULL );
cv->modified = false; // reset state
}
@ -435,28 +457,6 @@ void SV_PrepWorldFrame( void )
}
}
/*
================
SV_HasActivePlayers
returns true if server have spawned players
================
*/
bool SV_HasActivePlayers( void )
{
int i;
// server inactive
if( !svs.clients ) return false;
for( i = 0; i < sv_maxclients->integer; i++ )
{
if( svs.clients[i].state == cs_spawned )
return true;
}
return false;
}
/*
=================
SV_RunGameFrame
@ -665,7 +665,6 @@ void SV_Init( void )
sv_rollangle = Cvar_Get( "sv_rollangle", "2", CVAR_PHYSICINFO, "how much to tilt the view when strafing" );
sv_rollspeed = Cvar_Get( "sv_rollspeed", "200", CVAR_PHYSICINFO, "how much strafing is necessary to tilt the view" );
sv_airaccelerate = Cvar_Get("sv_airaccelerate", "1", CVAR_PHYSICINFO, "player accellerate in air" );
sv_idealpitchscale = Cvar_Get( "sv_idealpitchscale", "0.8", 0, "how much to look up/down slopes and stairs when not using freelook" );
sv_maxvelocity = Cvar_Get( "sv_maxvelocity", "2000", CVAR_PHYSICINFO, "max world velocity" );
sv_gravity = Cvar_Get( "sv_gravity", "800", CVAR_PHYSICINFO, "world gravity" );
sv_maxspeed = Cvar_Get( "sv_maxspeed", "320", CVAR_PHYSICINFO, "maximum speed a player can accelerate to when on ground");
@ -699,7 +698,7 @@ void SV_FinalMessage( char *message, bool reconnect )
{
sv_client_t *cl;
byte msg_buf[MAX_MSGLEN];
bitbuf_t msg;
sizebuf_t msg;
int i;
BF_Init( &msg, "FinalMessage", msg_buf, sizeof( msg_buf ));

View File

@ -1247,59 +1247,6 @@ void SV_Physics_Pusher( edict_t *ent )
}
//============================================================================
/*
=============
SV_Physics_Compound
Entities that are "stuck" to another entity
assume oldorigin as originoffset and oldangles as angle difference
=============
*/
void SV_Physics_Compound( edict_t *ent )
{
vec3_t vf, vr, vu, angles;
edict_t *parent;
// regular thinking
if( !SV_RunThink( ent )) return;
parent = ent->v.aiment;
if( !SV_IsValidEdict( parent )) return;
// force to hold current values as offsets
if( ent->v.effects & EF_NOINTERP )
{
VectorSubtract( ent->v.origin, parent->v.origin, ent->v.oldorigin );
VectorSubtract( ent->v.angles, parent->v.angles, ent->v.oldangles );
ent->v.effects &= ~EF_NOINTERP; // done
}
if( VectorCompare( parent->v.angles, ent->v.oldangles ))
{
// quick case for no rotation
VectorAdd( parent->v.origin, ent->v.oldorigin, ent->v.origin );
}
else
{
vec3_t org, org2, move;
VectorAdd( parent->v.origin, ent->v.oldorigin, ent->v.origin );
VectorSubtract( ent->v.origin, parent->v.origin, org );
VectorNegate( parent->v.angles, angles );
AngleVectors( angles, vf, vr, vu );
org2[0] = DotProduct( ent->v.oldorigin, vf );
org2[1] = -DotProduct( ent->v.oldorigin, vr );
org2[2] = DotProduct( ent->v.oldorigin, vu );
VectorSubtract( org2, ent->v.oldorigin, move );
VectorAdd( ent->v.origin, move, ent->v.origin );
}
VectorAdd( parent->v.angles, ent->v.oldangles, ent->v.angles );
SV_LinkEdict( ent, false );
}
/*
=============
SV_Physics_Follow
@ -1758,9 +1705,6 @@ static void SV_Physics_Entity( edict_t *ent )
case MOVETYPE_FOLLOW:
SV_Physics_Follow( ent );
break;
case MOVETYPE_COMPOUND:
SV_Physics_Compound( ent );
break;
case MOVETYPE_STEP:
case MOVETYPE_PUSHSTEP:
SV_Physics_Step( ent );

View File

@ -1750,7 +1750,7 @@ void SV_SaveGame( const char *pName )
BF_WriteByte( &sv.multicast, svgame.gmsgHudText );
BF_WriteByte( &sv.multicast, com.strlen( pMsg ) + 1 );
BF_WriteString( &sv.multicast, pMsg );
MSG_Send( MSG_ONE, NULL, EDICT_NUM( 1 ));
SV_Send( MSG_ONE, NULL, EDICT_NUM( 1 ));
}
}

View File

@ -1336,7 +1336,7 @@ addEntity:
state->mins = pEntity->pev->mins;
state->maxs = pEntity->pev->maxs;
state->flags = pEntity->pev->flags;
state->oldorigin = pEntity->pev->oldorigin;
state->vuser1 = pEntity->pev->oldorigin; // used for portals and skyportals
state->colormap = pEntity->pev->colormap; // attachments
state->rendercolor.r = (byte)pEntity->pev->rendercolor.x;
@ -1376,8 +1376,6 @@ addEntity:
state->aiment = ENTINDEX( pEntity->pev->aiment );
else state->aiment = 0;
state->viewangles = pEntity->pev->v_angle;
state->idealpitch = pEntity->pev->idealpitch;
state->velocity = pEntity->pev->velocity;
state->basevelocity = pEntity->pev->clbasevelocity;
state->iStepLeft = pEntity->pev->iStepLeft;
@ -1389,7 +1387,6 @@ addEntity:
if( pEntity->pev->weaponmodel != iStringNull )
state->weaponmodel = MODEL_INDEX( STRING( pEntity->pev->weaponmodel ));
else state->weaponmodel = 0;
state->maxspeed = pEntity->pev->maxspeed;
// clamp fov
if( pEntity->pev->fov < 0.0 ) pEntity->pev->fov = 0.0;

View File

@ -437,7 +437,6 @@ TYPEDESCRIPTION gEntvarsDescription[] =
DEFINE_ENTITY_FIELD( movedir, FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( angles, FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( oldangles, FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( avelocity, FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( punchangle, FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( v_angle, FIELD_VECTOR ),
@ -477,8 +476,8 @@ TYPEDESCRIPTION gEntvarsDescription[] =
DEFINE_ENTITY_FIELD( sequence, FIELD_INTEGER ),
DEFINE_ENTITY_FIELD( animtime, FIELD_TIME ),
DEFINE_ENTITY_FIELD( framerate, FIELD_FLOAT ),
DEFINE_ENTITY_FIELD_ARRAY( controller, FIELD_CHARACTER, 16 ),
DEFINE_ENTITY_FIELD_ARRAY( blending, FIELD_CHARACTER, 16 ),
DEFINE_ENTITY_FIELD( controller, FIELD_INTEGER ),
DEFINE_ENTITY_FIELD( blending, FIELD_INTEGER ),
DEFINE_ENTITY_FIELD( rendermode, FIELD_INTEGER ),
DEFINE_ENTITY_FIELD( renderamt, FIELD_FLOAT ),

View File

@ -1314,10 +1314,8 @@ void R_StudioSetUpTransform( ref_entity_t *e, bool trivial_accept )
VectorCopy( e->origin, origin );
VectorCopy( e->angles, angles );
m_pEntity = ri.GetClientEdict( e->index );
// interoplate monsters position
if( m_pEntity && !m_pEntity->free && m_pEntity->v.flags & FL_MONSTER && ( e->movetype == MOVETYPE_STEP || e->movetype == MOVETYPE_FLY ))
if( e->movetype == MOVETYPE_STEP || e->movetype == MOVETYPE_FLY )
{
float d, f = 0.0f;
edict_t *m_pGroundEntity;
@ -1339,7 +1337,10 @@ void R_StudioSetUpTransform( ref_entity_t *e, bool trivial_accept )
f = f - 1.0f;
}
if( m_pEntity && !m_pEntity->free ) m_pGroundEntity = m_pEntity->v.groundentity;
m_pEntity = ri.GetClientEdict( e->index );
if( m_pEntity && !m_pEntity->free )
m_pGroundEntity = m_pEntity->v.groundentity;
if( m_pGroundEntity && m_pGroundEntity->v.movetype == MOVETYPE_PUSH && !VectorIsNull( m_pGroundEntity->v.velocity ))
{