From 78a36858fbb84dd47c48d45c0dfe5031104ff5af Mon Sep 17 00:00:00 2001 From: g-cont Date: Sat, 7 Aug 2010 00:00:00 +0400 Subject: [PATCH] 07 Aug 2010 --- bshift/client.cpp | 7 +- bshift/util.cpp | 5 +- client/global/dll_int.cpp | 53 ++-- client/global/ev_common.cpp | 16 +- client/global/view.cpp | 11 +- common/cl_entity.h | 89 +++++++ common/entity_def.h | 11 +- common/entity_state.h | 4 - engine/client/cl_demo.c | 10 +- engine/client/cl_frame.c | 8 +- engine/client/cl_main.c | 10 +- engine/client/cl_move.c | 70 +++++- engine/client/cl_parse.c | 44 ++-- engine/client/cl_view.c | 1 - engine/client/client.h | 11 +- engine/common/net_buffer.c | 106 ++++---- engine/common/net_buffer.h | 122 ++++----- engine/common/net_chan.c | 8 +- engine/common/net_encode.c | 156 +++++++++--- engine/common/net_encode.h | 34 +-- engine/common/net_huff.c | 7 +- engine/common/net_msg.c | 487 ------------------------------------ engine/common/net_msg.h | 131 +--------- engine/engine.dsp | 4 - engine/server/server.h | 25 +- engine/server/sv_client.c | 112 ++------- engine/server/sv_cmds.c | 2 +- engine/server/sv_frame.c | 16 +- engine/server/sv_game.c | 89 +++++-- engine/server/sv_init.c | 2 +- engine/server/sv_main.c | 55 ++-- engine/server/sv_phys.c | 56 ----- engine/server/sv_save.c | 2 +- spirit/client.cpp | 5 +- spirit/util.cpp | 5 +- vid_gl/r_studio.c | 9 +- 36 files changed, 663 insertions(+), 1120 deletions(-) create mode 100644 common/cl_entity.h delete mode 100644 engine/common/net_msg.c diff --git a/bshift/client.cpp b/bshift/client.cpp index 81613cc9..05d7b081 100644 --- a/bshift/client.cpp +++ b/bshift/client.cpp @@ -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 ) { diff --git a/bshift/util.cpp b/bshift/util.cpp index ea47b6d6..d91a0f4a 100644 --- a/bshift/util.cpp +++ b/bshift/util.cpp @@ -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 ), diff --git a/client/global/dll_int.cpp b/client/global/dll_int.cpp index df2f26a2..d781368b 100644 --- a/client/global/dll_int.cpp +++ b/client/global/dll_int.cpp @@ -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; diff --git a/client/global/ev_common.cpp b/client/global/ev_common.cpp index 9540b5f7..eb6230f0 100644 --- a/client/global/ev_common.cpp +++ b/client/global/ev_common.cpp @@ -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 ); diff --git a/client/global/view.cpp b/client/global/view.cpp index 8010aeae..11b00cfd 100644 --- a/client/global/view.cpp +++ b/client/global/view.cpp @@ -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 diff --git a/common/cl_entity.h b/common/cl_entity.h new file mode 100644 index 00000000..a5d462ec --- /dev/null +++ b/common/cl_entity.h @@ -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 \ No newline at end of file diff --git a/common/entity_def.h b/common/entity_def.h index 369d3368..2d30b74f 100644 --- a/common/entity_def.h +++ b/common/entity_def.h @@ -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; diff --git a/common/entity_state.h b/common/entity_state.h index 2d5420c5..c56eddde 100644 --- a/common/entity_state.h +++ b/common/entity_state.h @@ -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 diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 392f1bb6..c1a67f52 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -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; diff --git a/engine/client/cl_frame.c b/engine/client/cl_frame.c index 3295e358..8ec0e781 100644 --- a/engine/client/cl_frame.c +++ b/engine/client/cl_frame.c @@ -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; diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index a5013cb0..277d32ed 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -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)" ); diff --git a/engine/client/cl_move.c b/engine/client/cl_move.c index e568a996..a3659e1e 100644 --- a/engine/client/cl_move.c +++ b/engine/client/cl_move.c @@ -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 diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 55082d69..f7acb875 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -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; diff --git a/engine/client/cl_view.c b/engine/client/cl_view.c index 53d047fb..54fc1472 100644 --- a/engine/client/cl_view.c +++ b/engine/client/cl_view.c @@ -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; diff --git a/engine/client/client.h b/engine/client/client.h index 123ea7d1..be321431 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -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 ); // diff --git a/engine/common/net_buffer.c b/engine/common/net_buffer.c index da3df530..e6cab979 100644 --- a/engine/common/net_buffer.c +++ b/engine/common/net_buffer.c @@ -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; diff --git a/engine/common/net_buffer.h b/engine/common/net_buffer.h index 76e247ae..d1d04052 100644 --- a/engine/common/net_buffer.h +++ b/engine/common/net_buffer.h @@ -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 \ No newline at end of file diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index ec5abf8a..1f4bee8c 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -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; diff --git a/engine/common/net_encode.c b/engine/common/net_encode.c index dfd025f9..10aafa15 100644 --- a/engine/common/net_encode.c +++ b/engine/common/net_encode.c @@ -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; diff --git a/engine/common/net_encode.h b/engine/common/net_encode.h index 74f47e26..a354ede3 100644 --- a/engine/common/net_encode.h +++ b/engine/common/net_encode.h @@ -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 \ No newline at end of file diff --git a/engine/common/net_huff.c b/engine/common/net_huff.c index c5dc16c7..af221ce1 100644 --- a/engine/common/net_huff.c +++ b/engine/common/net_huff.c @@ -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 ); } diff --git a/engine/common/net_msg.c b/engine/common/net_msg.c deleted file mode 100644 index 8908b430..00000000 --- a/engine/common/net_msg.c +++ /dev/null @@ -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<offset ); - if( flags & 1<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 - } -} \ No newline at end of file diff --git a/engine/common/net_msg.h b/engine/common/net_msg.h index 3d8e676f..7a7354d0 100644 --- a/engine/common/net_msg.h +++ b/engine/common/net_msg.h @@ -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 \ No newline at end of file diff --git a/engine/engine.dsp b/engine/engine.dsp index 8cbf033a..205c1abd 100644 --- a/engine/engine.dsp +++ b/engine/engine.dsp @@ -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 diff --git a/engine/server/server.h b/engine/server/server.h index 1422ce0c..20fdc24d 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -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 ); diff --git a/engine/server/sv_client.c b/engine/server/sv_client.c index 4e2619c0..de7345a5 100644 --- a/engine/server/sv_client.c +++ b/engine/server/sv_client.c @@ -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; diff --git a/engine/server/sv_cmds.c b/engine/server/sv_cmds.c index a89fa5e2..099e54a4 100644 --- a/engine/server/sv_cmds.c +++ b/engine/server/sv_cmds.c @@ -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 ); } /* diff --git a/engine/server/sv_frame.c b/engine/server/sv_frame.c index f4fc2b23..40ef1f3a 100644 --- a/engine/server/sv_frame.c +++ b/engine/server/sv_frame.c @@ -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 ); diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 465a3841..d48b69f4 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -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, diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index f00bced8..0b765a66 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -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; } diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index df83edad..8e33ecd1 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -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 )); diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index 203411d2..5574a688 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -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 ); diff --git a/engine/server/sv_save.c b/engine/server/sv_save.c index 058a7c88..7cb3e07e 100644 --- a/engine/server/sv_save.c +++ b/engine/server/sv_save.c @@ -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 )); } } diff --git a/spirit/client.cpp b/spirit/client.cpp index 915e66bd..e7d967ae 100644 --- a/spirit/client.cpp +++ b/spirit/client.cpp @@ -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; diff --git a/spirit/util.cpp b/spirit/util.cpp index 076e1d23..14d8f96a 100644 --- a/spirit/util.cpp +++ b/spirit/util.cpp @@ -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 ), diff --git a/vid_gl/r_studio.c b/vid_gl/r_studio.c index 8ca94444..1f8dd585 100644 --- a/vid_gl/r_studio.c +++ b/vid_gl/r_studio.c @@ -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 )) {