07 Sep 2007

This commit is contained in:
g-cont 2007-09-07 00:00:00 +04:00 committed by Alibek Omarov
parent d6ccf91e53
commit 539c0a6ebb
74 changed files with 5664 additions and 12195 deletions

View File

@ -6,10 +6,12 @@ SV_Move SV_Trace
SV_ClipMoveToEntity CM_BoxTrace
SV_ClipToLinks SV_ClipMoveToEntities
//==================================================
// FIXME
//==================================================
1. Пофиксить движение игрока (сл. большая скорость)
1. Перенести основные части gamed.dll в движок OK
2. Попытка полностью отказаться от gamed.dll OK
3. Перенести физику в движок OK
4. Восстановить изменения кода до 06.09.07 (кроме PRVM)
//==================================================
// òî, ÷òî óæå ãîòîâî

View File

@ -55,5 +55,5 @@ if exist progs\server.dat copy progs\server.dat D:\Xash3D\xash\server.dat
echo Build succeeded!
echo Please wait. Xash is now loading
cd D:\Xash3D\
xash.exe +map qctest -debug
xash.exe +map qctest -log
:done

View File

@ -402,17 +402,17 @@ void SCR_RunCinematic (void)
if (cls.key_dest != key_game)
{ // pause if menu or console is up
cl.cinematictime = cls.realtime - cl.cinematicframe/14;
cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14;
return;
}
frame = (cls.realtime - cl.cinematictime)*14.0;
frame = (cls.realtime - cl.cinematictime)*14.0/1000;
if (frame <= cl.cinematicframe)
return;
if (frame > cl.cinematicframe+1)
{
Msg ("Dropped frame: %i > %i\n", frame, cl.cinematicframe+1);
cl.cinematictime = cls.realtime - cl.cinematicframe/14;
cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14;
}
if (cin.pic)
Z_Free (cin.pic);
@ -546,5 +546,5 @@ void SCR_PlayCinematic (char *arg)
cl.cinematicframe = 0;
cin.pic = SCR_ReadNextFrame ();
cl.cinematictime = cls.realtime;
cl.cinematictime = Sys_Milliseconds ();
}

View File

@ -323,8 +323,7 @@ void CL_DeltaEntity (frame_t *frame, int newnum, entity_state_t *old, int bits)
}
if (ent->serverframe != cl.frame.serverframe - 1)
{
// wasn't in last update, so initialize some things
{ // wasn't in last update, so initialize some things
ent->trailcount = 1024; // for diminishing rocket / grenade trails
// duplicate the current state so lerping doesn't hurt anything
ent->prev = *state;
@ -657,7 +656,7 @@ void CL_ParseFrame (void)
cl.frame.serverframe = MSG_ReadLong (&net_message);
cl.frame.deltaframe = MSG_ReadLong (&net_message);
cl.frame.servertime = cl.frame.serverframe * 0.1;
cl.frame.servertime = cl.frame.serverframe*100;
// BIG HACK to let old demos continue to work
if (cls.serverProtocol != 26)
@ -700,8 +699,8 @@ void CL_ParseFrame (void)
// clamp time
if (cl.time > cl.frame.servertime)
cl.time = cl.frame.servertime;
else if (cl.time < cl.frame.servertime - 0.1)
cl.time = cl.frame.servertime - 0.1;
else if (cl.time < cl.frame.servertime - 100)
cl.time = cl.frame.servertime - 100;
// read areabits
len = MSG_ReadByte (&net_message);
@ -739,8 +738,9 @@ void CL_ParseFrame (void)
cl.predicted_origin[1] = cl.frame.playerstate.pmove.origin[1]*0.125;
cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2]*0.125;
VectorCopy (cl.frame.playerstate.viewangles, cl.predicted_angles);
if (cls.disable_servercount != cl.servercount && cl.refresh_prepped)
SCR_EndLoadingPlaque (); // get rid of loading plaque
if (cls.disable_servercount != cl.servercount
&& cl.refresh_prepped)
SCR_EndLoadingPlaque (); // get rid of loading plaque
}
cl.sound_prepped = true; // can start mixing ambient sounds
@ -829,7 +829,7 @@ void CL_AddPacketEntities (frame_t *frame)
autorotate = anglemod(cl.time/10);
// brush models can auto animate their frames
autoanim = 2 * cl.time;
autoanim = 2*cl.time/1000;
memset (&ent, 0, sizeof(ent));
@ -850,7 +850,7 @@ void CL_AddPacketEntities (frame_t *frame)
else if (effects & EF_ANIM_ALL)
ent.frame = autoanim;
else if (effects & EF_ANIM_ALLFAST)
ent.frame = cl.time * 0.1;
ent.frame = cl.time / 100;
else
ent.frame = s1->frame;
@ -974,7 +974,7 @@ void CL_AddPacketEntities (frame_t *frame)
vec3_t forward;
vec3_t start;
AngleVectorsRight(ent.angles, forward, NULL, NULL);
AngleVectors (ent.angles, forward, NULL, NULL);
VectorMA (ent.origin, 64, forward, start);
V_AddLight (start, 100, 1, 0, 0);
}
@ -1231,7 +1231,8 @@ void CL_CalcViewValues (void)
// smooth out stair climbing
delta = cls.realtime - cl.predicted_step_time;
if (delta < 0.1) cl.refdef.vieworg[2] -= cl.predicted_step * (0.1 - delta) * 100;
if (delta < 100)
cl.refdef.vieworg[2] -= cl.predicted_step * (100 - delta) * 0.01;
}
else
{ // just use interpolated values
@ -1256,7 +1257,7 @@ void CL_CalcViewValues (void)
for (i=0 ; i<3 ; i++)
cl.refdef.viewangles[i] += LerpAngle (ops->kick_angles[i], ps->kick_angles[i], lerp);
AngleVectorsRight(cl.refdef.viewangles, cl.v_forward, cl.v_right, cl.v_up);
AngleVectors (cl.refdef.viewangles, cl.v_forward, cl.v_right, cl.v_up);
// interpolate field of view
cl.refdef.fov_x = ops->fov + lerp * (ps->fov - ops->fov);
@ -1288,14 +1289,15 @@ void CL_AddEntities (void)
cl.time = cl.frame.servertime;
cl.lerpfrac = 1.0;
}
else if (cl.time < cl.frame.servertime - 0.1)
else if (cl.time < cl.frame.servertime - 100)
{
if (cl_showclamp->value)
Msg ("low clamp %i\n", cl.frame.servertime - 0.1 - cl.time);
cl.time = cl.frame.servertime - 0.1;
Msg ("low clamp %i\n", cl.frame.servertime-100 - cl.time);
cl.time = cl.frame.servertime - 100;
cl.lerpfrac = 0;
}
else cl.lerpfrac = 1.0 - (cl.frame.servertime - cl.time) * 100;
else
cl.lerpfrac = 1.0 - (cl.frame.servertime - cl.time) * 0.01;
if (cl_timedemo->value)
cl.lerpfrac = 1.0;

View File

@ -69,7 +69,7 @@ void CL_RunLightStyles (void)
int i;
clightstyle_t *ls;
ofs = cl.time * 0.1;
ofs = cl.time / 100;
if (ofs == lastofs)
return;
lastofs = ofs;
@ -257,7 +257,7 @@ void CL_ParseMuzzleFlash (void)
dl = CL_AllocDlight (i);
VectorCopy (pl->current.origin, dl->origin);
AngleVectorsRight(pl->current.angles, fv, rv, NULL);
AngleVectors (pl->current.angles, fv, rv, NULL);
VectorMA (dl->origin, 18, fv, dl->origin);
VectorMA (dl->origin, 16, rv, dl->origin);
if (silenced)
@ -398,7 +398,7 @@ void CL_ParseMuzzleFlash2 (void)
flash_number = MSG_ReadByte (&net_message);
// locate the origin
AngleVectorsRight(cl_entities[ent].current.angles, forward, right, NULL);
AngleVectors (cl_entities[ent].current.angles, forward, right, NULL);
origin[0] = cl_entities[ent].current.origin[0] + forward[0] + right[0];
origin[1] = cl_entities[ent].current.origin[1] + forward[1] + right[1];
origin[2] = cl_entities[ent].current.origin[2] + forward[2] + right[2];
@ -1607,7 +1607,7 @@ void CL_FlyParticles (vec3_t origin, int count)
}
ltime = cl.time;
ltime = (float)cl.time / 1000.0;
for (i=0 ; i<count ; i+=2)
{
angle = ltime * avelocities[i][0];
@ -1706,7 +1706,7 @@ void CL_BfgParticles (entity_t *ent)
}
ltime = cl.time;
ltime = (float)cl.time / 1000.0;
for (i=0 ; i<NUMVERTEXNORMALS ; i++)
{
angle = ltime * avelocities[i][0];

View File

@ -1,20 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// cl_game.c - client.dll link system
//=======================================================================
#include <windows.h>
#include "client.h"
HINSTANCE cl_library;
void CL_InitGameProgs (void)
{
void *cl;
//find client.dll
cl = Sys_LoadGame("ClientAPI", cl_library, NULL);
if(cl) Msg("client.dll found and loaded\n");
else Msg("client.dll not loaded\n");
}

View File

@ -23,8 +23,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
cvar_t *cl_nodelta;
uint frame_msec;
uint old_sys_frame_time;
extern unsigned sys_frame_time;
unsigned frame_msec;
unsigned old_sys_frame_time;
/*
===============================================================================
@ -93,7 +94,7 @@ void KeyDown (kbutton_t *b)
c = Cmd_Argv(2);
b->downtime = atoi(c);
if (!b->downtime)
b->downtime = host.cl_timer - 100;
b->downtime = sys_frame_time - 100;
b->state |= 1 + 2; // down + impulse down
}
@ -193,8 +194,8 @@ float CL_KeyState (kbutton_t *key)
if (key->state)
{ // still down
msec += host.cl_timer - key->downtime;
key->downtime = host.cl_timer;
msec += sys_frame_time - key->downtime;
key->downtime = sys_frame_time;
}
#if 0
@ -205,8 +206,10 @@ float CL_KeyState (kbutton_t *key)
#endif
val = (float)msec / frame_msec;
if (val < 0) val = 0;
if (val > 1) val = 1;
if (val < 0)
val = 0;
if (val > 1)
val = 1;
return val;
}
@ -295,7 +298,9 @@ void CL_BaseMove (usercmd_t *cmd)
cmd->forwardmove -= cl_forwardspeed->value * CL_KeyState (&in_back);
}
// adjust for speed key / running
//
// adjust for speed key / running
//
if ( (in_speed.state & 1) ^ (int)(cl_run->value) )
{
cmd->forwardmove *= 2;
@ -333,27 +338,34 @@ void CL_FinishMove (usercmd_t *cmd)
int ms;
int i;
// figure button bits
if ( in_attack.state & 3 ) cmd->buttons |= BUTTON_ATTACK;
//
// figure button bits
//
if ( in_attack.state & 3 )
cmd->buttons |= BUTTON_ATTACK;
in_attack.state &= ~2;
if (in_use.state & 3) cmd->buttons |= BUTTON_USE;
if (in_use.state & 3)
cmd->buttons |= BUTTON_USE;
in_use.state &= ~2;
if (anykeydown && cls.key_dest == key_game) cmd->buttons |= BUTTON_ANY;
if (anykeydown && cls.key_dest == key_game)
cmd->buttons |= BUTTON_ANY;
// send milliseconds of time to apply the move
ms = cls.frametime * 1000;
if (ms > 250) ms = 100; // time was unreasonable
if (ms > 250)
ms = 100; // time was unreasonable
cmd->msec = ms;
CL_ClampPitch ();
for (i = 0; i < 3; i++) cmd->angles[i] = ANGLE2SHORT(cl.viewangles[i]);
for (i=0 ; i<3 ; i++)
cmd->angles[i] = ANGLE2SHORT(cl.viewangles[i]);
cmd->impulse = in_impulse;
in_impulse = 0;
// send the ambient light level at the player's current position
// send the ambient light level at the player's current position
cmd->lightlevel = (byte)cl_lightlevel->value;
}
@ -366,8 +378,11 @@ usercmd_t CL_CreateCmd (void)
{
usercmd_t cmd;
frame_msec = host.cl_timer - old_sys_frame_time;
frame_msec = bound(1, frame_msec, 200);
frame_msec = sys_frame_time - old_sys_frame_time;
if (frame_msec < 1)
frame_msec = 1;
if (frame_msec > 200)
frame_msec = 200;
// get basic movement from keyboard
CL_BaseMove (&cmd);
@ -377,9 +392,9 @@ usercmd_t CL_CreateCmd (void)
CL_FinishMove (&cmd);
old_sys_frame_time = host.cl_timer;
old_sys_frame_time = sys_frame_time;
//cmd.impulse = cls.framecount;
//cmd.impulse = cls.framecount;
return cmd;
}
@ -468,7 +483,7 @@ void CL_SendCmd (void)
if ( cls.state == ca_connected)
{
if (cls.netchan.message.cursize || host.realtime - cls.netchan.last_sent > 1.0f )
if (cls.netchan.message.cursize || curtime - cls.netchan.last_sent > 1000 )
Netchan_Transmit (&cls.netchan, 0, buf.data);
return;
}
@ -483,7 +498,7 @@ void CL_SendCmd (void)
}
if (cmd->buttons && cl.cinematictime > 0 && !cl.attractloop
&& cls.realtime - cl.cinematictime > 1.0f)
&& cls.realtime - cl.cinematictime > 1000)
{ // skip the rest of the cinematic
SCR_FinishCinematic ();
}

View File

@ -364,7 +364,7 @@ CL_Pause_f
void CL_Pause_f (void)
{
// never pause in multiplayer
if (host.maxclients > 1 || !Com_ServerState ())
if (Cvar_VariableValue ("maxclients") > 1 || !Com_ServerState ())
{
Cvar_SetValue ("paused", 0);
return;
@ -462,7 +462,7 @@ void CL_CheckForResend (void)
if (cls.state != ca_connecting)
return;
if (cls.realtime - cls.connect_time < 3.0f)
if (cls.realtime - cls.connect_time < 3000)
return;
if (!NET_StringToAdr (cls.servername, &adr))
@ -616,6 +616,16 @@ void CL_Disconnect (void)
if (cls.state == ca_disconnected)
return;
if (cl_timedemo && cl_timedemo->value)
{
int time;
time = Sys_Milliseconds () - cl.timedemo_start;
if (time > 0)
Msg ("%i frames, %3.1f seconds: %3.1f fps\n", cl.timedemo_frames,
time/1000.0, cl.timedemo_frames*1000.0 / time);
}
VectorClear (cl.refdef.blend);
re->CinematicSetPalette(NULL);
@ -717,7 +727,8 @@ void CL_Changing_f (void)
{
//ZOID
//if we are downloading, we don't change! This so we don't suddenly stop downloading a map
if (cls.download) return;
if (cls.download)
return;
SCR_BeginLoadingPlaque ();
cls.state = ca_connected; // not active anymore, but not disconnected
@ -751,7 +762,7 @@ void CL_Reconnect_f (void)
if (*cls.servername) {
if (cls.state >= ca_connected) {
CL_Disconnect();
cls.connect_time = cls.realtime - 1.5f;
cls.connect_time = cls.realtime - 1500;
} else
cls.connect_time = -99999; // fire immediately
@ -1010,7 +1021,8 @@ void CL_ReadPackets (void)
//
// check timeout
//
if (cls.state >= ca_connected && cls.realtime - cls.netchan.last_received > cl_timeout->value)
if (cls.state >= ca_connected
&& cls.realtime - cls.netchan.last_received > cl_timeout->value*1000)
{
if (++cl.timeoutcount > 5) // timeoutcount saves debugger
{
@ -1401,8 +1413,7 @@ CL_InitLocal
void CL_InitLocal (void)
{
cls.state = ca_disconnected;
cls.realtime = Sys_DoubleTime();
cls.realtime = Sys_Milliseconds ();
CL_InitInput ();
adr0 = Cvar_Get( "adr0", "", CVAR_ARCHIVE );
@ -1415,9 +1426,9 @@ void CL_InitLocal (void)
adr7 = Cvar_Get( "adr7", "", CVAR_ARCHIVE );
adr8 = Cvar_Get( "adr8", "", CVAR_ARCHIVE );
//
// register our variables
//
//
// register our variables
//
cl_stereo_separation = Cvar_Get( "cl_stereo_separation", "0.4", CVAR_ARCHIVE );
cl_stereo = Cvar_Get( "cl_stereo", "0", 0 );
@ -1606,8 +1617,9 @@ void CL_FixCvarCheats (void)
int i;
cheatvar_t *var;
if(!strcmp(cl.configstrings[CS_MAXCLIENTS], "1") || !cl.configstrings[CS_MAXCLIENTS][0] )
return; // single player can cheat
if ( !strcmp(cl.configstrings[CS_MAXCLIENTS], "1")
|| !cl.configstrings[CS_MAXCLIENTS][0] )
return; // single player can cheat
// find all the cvars if we haven't done it yet
if (!numcheatvars)
@ -1666,36 +1678,44 @@ CL_Frame
==================
*/
void CL_Frame (float time)
void CL_Frame (int msec)
{
static float extratime;
static float lasttimecalled;
static int extratime;
static int lasttimecalled;
if (host.type == HOST_DEDICATED) return;
if (dedicated->value)
return;
extratime += time;
extratime += msec;
if (!cl_timedemo->value)
{
if (cls.state == ca_connected && extratime < 0.1f)
return; // don't flood packets out while connecting
if (extratime < 1.0f / cl_maxfps->value)
return; // framerate is too high
if (cls.state == ca_connected && extratime < 100)
return; // don't flood packets out while connecting
if (extratime < 1000/cl_maxfps->value)
return; // framerate is too high
}
// let the mouse activate or deactivate
IN_Frame ();
// decide the simulation time
cls.frametime = extratime;
cls.frametime = extratime/1000.0;
cl.time += extratime;
cls.realtime = Sys_DoubleTime();
cls.realtime = curtime;
extratime = 0;
if (cls.frametime > (1.0 / 5)) cls.frametime = (1.0 / 5);
#if 0
if (cls.frametime > (1.0 / cl_minfps->value))
cls.frametime = (1.0 / cl_minfps->value);
#else
if (cls.frametime > (1.0 / 5))
cls.frametime = (1.0 / 5);
#endif
// if in the debugger last frame, don't timeout
if (time > 1.0f) cls.netchan.last_received = Sys_DoubleTime();
if (msec > 5000)
cls.netchan.last_received = Sys_Milliseconds ();
// fetch results from server
CL_ReadPackets ();
@ -1712,7 +1732,11 @@ void CL_Frame (float time)
CL_PrepRefresh ();
// update the screen
if (host_speeds->value)
time_before_ref = Sys_Milliseconds ();
SCR_UpdateScreen ();
if (host_speeds->value)
time_after_ref = Sys_Milliseconds ();
// update audio
S_Update (cl.refdef.vieworg, cl.v_forward, cl.v_right, cl.v_up);
@ -1724,6 +1748,27 @@ void CL_Frame (float time)
SCR_RunConsole ();
cls.framecount++;
if ( log_stats->value )
{
if ( cls.state == ca_active )
{
if ( !lasttimecalled )
{
lasttimecalled = Sys_Milliseconds();
if ( log_stats_file )
FS_Printf( log_stats_file, "0\n" );
}
else
{
int now = Sys_Milliseconds();
if ( log_stats_file )
FS_Printf( log_stats_file, "%d\n", now - lasttimecalled );
lasttimecalled = now;
}
}
}
}
@ -1736,8 +1781,8 @@ CL_Init
*/
void CL_Init (void)
{
// nothing running on the client
if (host.type == HOST_DEDICATED) return;
if (dedicated->value)
return; // nothing running on the client
// all archived variables will now be loaded
@ -1754,7 +1799,6 @@ void CL_Init (void)
SCR_Init ();
cls.disable_screen = true; // don't draw yet
CL_InitGameProgs();
CL_InitLocal ();
IN_Init ();

View File

@ -81,7 +81,7 @@ void CL_Flashlight (int ent, vec3_t pos)
VectorCopy (pos, dl->origin);
dl->radius = 400;
dl->minlight = 250;
dl->die = cl.time + 0.1;
dl->die = cl.time + 100;
dl->color[0] = 1;
dl->color[1] = 1;
dl->color[2] = 1;
@ -100,7 +100,7 @@ void CL_ColorFlash (vec3_t pos, int ent, int intensity, float r, float g, float
VectorCopy (pos, dl->origin);
dl->radius = intensity;
dl->minlight = 250;
dl->die = cl.time + 0.1;
dl->die = cl.time + 100;
dl->color[0] = r;
dl->color[1] = g;
dl->color[2] = b;
@ -453,7 +453,7 @@ void CL_Heatbeam (vec3_t start, vec3_t end)
VectorMA (move, -1, up, move);
VectorScale (vec, step, vec);
ltime = cl.time;
ltime = (float) cl.time/1000.0;
// for (i=0 ; i<len ; i++)
for (i=0 ; i<len ; i+=step)
@ -544,7 +544,7 @@ void CL_Heatbeam (vec3_t start, vec3_t forward)
VectorMA (move, -0.5, up, move);
// otherwise assume SOFT
ltime = cl.time;
ltime = (float) cl.time/1000.0;
start_pt = fmod(ltime*96.0,step);
VectorMA (move, start_pt, vec, move);
@ -664,7 +664,7 @@ void CL_Heatbeam (vec3_t start, vec3_t end)
}
/*
ltime = cl.time;
ltime = (float) cl.time/1000.0;
start_pt = fmod(ltime*16.0,step);
VectorMA (move, start_pt, vec, move);
@ -740,7 +740,7 @@ void CL_ParticleSteamEffect (vec3_t org, vec3_t dir, int color, int count, int m
vec3_t r, u;
// vectoangles2 (dir, angle_dir);
// AngleVectorsRight (angle_dir, f, r, u);
// AngleVectors (angle_dir, f, r, u);
MakeNormalVectors (dir, r, u);
@ -797,7 +797,7 @@ void CL_TrackerTrail (vec3_t start, vec3_t end, int particleColor)
VectorCopy(vec, forward);
vectoangles2 (forward, angle_dir);
AngleVectorsRight (angle_dir, forward, right, up);
AngleVectors (angle_dir, forward, right, up);
dec = 3;
VectorScale (vec, 3, vec);

View File

@ -297,12 +297,13 @@ void CL_ParseServerData (void)
int i;
MsgDev (D_INFO, "Serverdata packet received.\n");
// wipe the client_state_t struct
//
// wipe the client_state_t struct
//
CL_ClearState ();
cls.state = ca_connected;
// parse protocol version number
// parse protocol version number
i = MSG_ReadLong (&net_message);
cls.serverProtocol = i;

View File

@ -125,7 +125,7 @@ void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
if (trace.allsolid || trace.startsolid ||
trace.fraction < tr->fraction)
{
trace.ent = (prvm_edict_t *)ent;
trace.ent = (struct edict_s *)ent;
if (tr->startsolid)
{
*tr = trace;
@ -145,14 +145,14 @@ void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
CL_PMTrace
================
*/
trace_t CL_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
trace_t CL_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
{
trace_t t;
// check against world
t = CM_BoxTrace (start, end, mins, maxs, 0, MASK_PLAYERSOLID);
if (t.fraction < 1.0)
t.ent = (prvm_edict_t *)1;
t.ent = (struct edict_s *)1;
// check all other solid models
CL_ClipMoveToEntities (start, mins, maxs, end, &t);
@ -214,9 +214,8 @@ void CL_PredictMovement (void)
return;
if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
{
// just set angles
for (i = 0; i < 3; i++)
{ // just set angles
for (i=0 ; i<3 ; i++)
{
cl.predicted_angles[i] = cl.viewangles[i] + SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[i]);
}

View File

@ -439,7 +439,8 @@ SCR_DrawNet
*/
void SCR_DrawNet (void)
{
if (cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged < CMD_BACKUP-1)
if (cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged
< CMD_BACKUP-1)
return;
re->DrawPic (scr_vrect.x+64, scr_vrect.y, "net");
@ -504,7 +505,7 @@ Scroll it up or down
*/
void SCR_RunConsole (void)
{
// decide on the height of the console
// decide on the height of the console
if (cls.key_dest == key_console)
scr_conlines = 0.5; // half screen
else
@ -512,14 +513,14 @@ void SCR_RunConsole (void)
if (scr_conlines < scr_con_current)
{
scr_con_current -= scr_conspeed->value * cls.frametime * 1000;
scr_con_current -= scr_conspeed->value*cls.frametime;
if (scr_conlines > scr_con_current)
scr_con_current = scr_conlines;
}
else if (scr_conlines > scr_con_current)
{
scr_con_current += scr_conspeed->value * cls.frametime * 1000;
scr_con_current += scr_conspeed->value*cls.frametime;
if (scr_conlines < scr_con_current)
scr_con_current = scr_conlines;
}
@ -569,19 +570,20 @@ SCR_BeginLoadingPlaque
void SCR_BeginLoadingPlaque (void)
{
S_StopAllSounds ();
cl.sound_prepped = false; // don't play ambients
cl.sound_prepped = false; // don't play ambients
if (cls.disable_screen) return;
if (host.developer) return;
if (cls.state == ca_disconnected) return; // if at console, don't bring up the plaque
if (developer->value)
return;
if (cls.state == ca_disconnected)
return; // if at console, don't bring up the plaque
if (cls.key_dest == key_console)
return;
if (cl.cinematictime > 0)
scr_draw_loading = 2; // clear to black first
else scr_draw_loading = 1;
SCR_UpdateScreen();
cls.disable_screen = cls.realtime;
scr_draw_loading = 2; // clear to black first
else
scr_draw_loading = 1;
SCR_UpdateScreen ();
cls.disable_screen = Sys_Milliseconds ();
cls.disable_servercount = cl.servercount;
}
@ -629,19 +631,18 @@ int entitycmpfnc( const entity_t *a, const entity_t *b )
void SCR_TimeRefresh_f (void)
{
int i;
float start, stop;
float time;
int start, stop;
float time;
if ( cls.state != ca_active )
return;
start = Sys_DoubleTime();
start = Sys_Milliseconds ();
if (Cmd_Argc() == 2)
{
// run without page flipping
{ // run without page flipping
re->BeginFrame( 0 );
for (i = 0; i < 128; i++)
for (i=0 ; i<128 ; i++)
{
cl.refdef.viewangles[1] = i/128.0*360.0;
re->RenderFrame (&cl.refdef);
@ -660,8 +661,8 @@ void SCR_TimeRefresh_f (void)
}
}
stop = Sys_DoubleTime();
time = (stop-start);
stop = Sys_Milliseconds ();
time = (stop-start)/1000.0;
Msg ("%f seconds (%f fps)\n", time, 128/time);
}
@ -1267,7 +1268,7 @@ void SCR_UpdateScreen (void)
// do nothing at all
if (cls.disable_screen)
{
if (cls.realtime - cls.disable_screen > 120.0f)
if (Sys_Milliseconds() - cls.disable_screen > 120000)
{
cls.disable_screen = 0;
Msg ("Loading plaque timed out.\n");

View File

@ -360,10 +360,16 @@ float CalcFov (float fov_x, float width, float height)
float a;
float x;
fov_x = bound(1, fov_x, 180);
x = width / tan(fov_x / 360 * M_PI);
a = atan (height / x);
a = a * 360/M_PI;
if (fov_x < 1 || fov_x > 179)
{
Com_Error (ERR_DROP, "Bad fov: %f", fov_x);
}
x = width/tan(fov_x/360*M_PI);
a = atan (height/x);
a = a*360/M_PI;
return a;
}
@ -439,6 +445,13 @@ void V_RenderView( float stereo_separation )
if (!cl.refresh_prepped)
return; // still loading
if (cl_timedemo->value)
{
if (!cl.timedemo_start)
cl.timedemo_start = Sys_DoubleTime();
cl.timedemo_frames++;
}
// an invalid frame will just use the exact previous refdef
// we can't use the old frame if the video mode has changed, though...
if ( cl.frame.valid && (cl.force_refdef || !cl_paused->value) )
@ -487,7 +500,7 @@ void V_RenderView( float stereo_separation )
cl.refdef.width = scr_vrect.width;
cl.refdef.height = scr_vrect.height;
cl.refdef.fov_y = CalcFov (cl.refdef.fov_x, cl.refdef.width, cl.refdef.height);
cl.refdef.time = cl.time;
cl.refdef.time = (cl.time * 0.001); // render use realtime now
cl.refdef.areabits = cl.frame.areabits;
@ -520,6 +533,9 @@ void V_RenderView( float stereo_separation )
re->RenderFrame (&cl.refdef);
if (cl_stats->value)
Msg ("ent:%i lt:%i part:%i\n", r_numentities, r_numdlights, r_numparticles);
if ( log_stats->value && ( log_stats_file != 0 ) )
FS_Printf( log_stats_file, "%i,%i,%i,",r_numentities, r_numdlights, r_numparticles);
SCR_AddDirtyPoint (scr_vrect.x, scr_vrect.y);
SCR_AddDirtyPoint (scr_vrect.x+scr_vrect.width-1,

View File

@ -34,27 +34,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
typedef struct
{
bool valid; // cleared if delta parsing was invalid
int serverframe;
float servertime; // server time the message is valid for (in msec)
int deltaframe;
byte areabits[MAX_MAP_AREAS/8]; // portalarea visibility bits
int serverframe;
int servertime; // server time the message is valid for (in msec)
int deltaframe;
byte areabits[MAX_MAP_AREAS/8]; // portalarea visibility bits
player_state_t playerstate;
int num_entities;
int parse_entities; // non-masked index into cl_parse_entities array
int num_entities;
int parse_entities; // non-masked index into cl_parse_entities array
} frame_t;
typedef struct
{
entity_state_t baseline; // delta from this if not from a previous frame
entity_state_t baseline; // delta from this if not from a previous frame
entity_state_t current;
entity_state_t prev; // will always be valid, but might just be a copy of current
int serverframe; // if not current, this ent isn't in the frame
int trailcount; // for diminishing grenade trails
int trailcount; // for diminishing grenade trails
vec3_t lerp_origin; // for trails (variable hz)
float fly_stoptime;
int fly_stoptime;
} centity_t;
#define MAX_CLIENTWEAPONMODELS 20 // PGM -- upped from 16 to fit the chainfist vwep
@ -81,24 +81,24 @@ extern int num_cl_weaponmodels;
//
typedef struct
{
int timeoutcount;
int timeoutcount;
int timedemo_frames;
float timedemo_start;
int timedemo_frames;
int timedemo_start;
bool refresh_prepped; // false if on new level or new ref dll
bool sound_prepped; // ambient sounds can start
bool force_refdef; // vid has changed, so we can't use a paused refdef
bool refresh_prepped; // false if on new level or new ref dll
bool sound_prepped; // ambient sounds can start
bool force_refdef; // vid has changed, so we can't use a paused refdef
int parse_entities; // index (not anded off) into cl_parse_entities[]
int parse_entities; // index (not anded off) into cl_parse_entities[]
usercmd_t cmd;
usercmd_t cmds[CMD_BACKUP]; // each mesage will send several old cmds
int cmd_time[CMD_BACKUP]; // time sent, for calculating pings
usercmd_t cmd;
usercmd_t cmds[CMD_BACKUP]; // each mesage will send several old cmds
int cmd_time[CMD_BACKUP]; // time sent, for calculating pings
short predicted_origins[CMD_BACKUP][3]; // for debug comparing against server
float predicted_step; // for stair up smoothing
float predicted_step_time;
unsigned predicted_step_time;
vec3_t predicted_origin; // generated by CL_PredictMovement
vec3_t predicted_angles;
@ -115,11 +115,11 @@ typedef struct
// and teleport direction changes
vec3_t viewangles;
float time; // this is the time value that the client
// is rendering at. always <= cls.realtime
int time; // this is the time value that the client
// is rendering at. always <= cls.realtime
float lerpfrac; // between oldframe and frame
refdef_t refdef;
refdef_t refdef;
vec3_t v_forward, v_right, v_up; // set when refdef.angles is set
@ -133,10 +133,10 @@ typedef struct
// non-gameserver infornamtion
// FIXME: move this cinematic stuff into the cin_t structure
file_t *cinematic_file;
float cinematictime; // cls.realtime for first cinematic frame
int cinematicframe;
int cinematictime; // cls.realtime for first cinematic frame
int cinematicframe;
char cinematicpalette[768];
bool cinematicpalette_active;
bool cinematicpalette_active;
//
// server state information
@ -196,11 +196,11 @@ typedef struct
keydest_t key_dest;
int framecount;
double realtime; // always increasing, no clamping, etc
float frametime; // seconds since last frame
int realtime; // always increasing, no clamping, etc
float frametime; // seconds since last frame
// screen rendering information
float disable_screen; // showing loading plaque between levels
float disable_screen; // showing loading plaque between levels
// or changing rendering dlls
// if time gets > 30 seconds ahead, break it
int disable_servercount; // when we receive a frame and cl.servercount
@ -433,11 +433,6 @@ void CL_PingServers_f (void);
void CL_Snd_Restart_f (void);
void CL_RequestNextDownload (void);
//
// cl_game
//
void CL_InitGameProgs (void);
//
// cl_input
//

View File

@ -59,17 +59,12 @@ typedef struct sizebuf_s
int errorcount; // cause by errors
} sizebuf_t;
void _SZ_Init (sizebuf_t *buf, byte *data, int length, const char *filename, int fileline);
void _SZ_Write (sizebuf_t *buf, void *data, int length, const char *filename, int fileline);
void *_SZ_GetSpace (sizebuf_t *buf, int length, const char *filename, int fileline);
void _SZ_Print (sizebuf_t *buf, char *data, const char *filename, int fileline);
void _SZ_Clear (sizebuf_t *buf, const char *filename, int fileline);
void SZ_Init (sizebuf_t *buf, byte *data, int length);
void SZ_Clear (sizebuf_t *buf);
void *SZ_GetSpace (sizebuf_t *buf, int length);
void SZ_Write (sizebuf_t *buf, void *data, int length);
void SZ_Print (sizebuf_t *buf, char *data); // strcats onto the sizebuf
#define SZ_Init(buf, data, length) _SZ_Init( buf, data, length, __FILE__, __LINE__)
#define SZ_Write(buf, data, length) _SZ_Write( buf, data, length, __FILE__, __LINE__)
#define SZ_Print(buf, data ) _SZ_Print( buf, data, __FILE__, __LINE__)
#define SZ_GetSpace(buf, length) _SZ_GetSpace( buf, length, __FILE__, __LINE__)
#define SZ_Clear(buf) _SZ_Clear( buf, __FILE__, __LINE__)
//============================================================================
struct usercmd_s;
@ -92,26 +87,26 @@ void _MSG_WriteDeltaUsercmd (sizebuf_t *sb, struct usercmd_s *from, struct userc
void _MSG_WriteDeltaEntity (struct entity_state_s *from, struct entity_state_s *to, sizebuf_t *msg, bool force, bool newentity, const char *filename, int fileline);
void _MSG_WriteDir (sizebuf_t *sb, vec3_t vector, const char *filename, int fileline);
void _MSG_WriteVector (sizebuf_t *sb, float *v, const char *filename, int fileline);
void _MSG_Send (msgtype_t to, vec3_t origin, prvm_edict_t *ent, const char *filename, int fileline);
void _MSG_Send (msgtype_t to, vec3_t origin, edict_t *ent, const char *filename, int fileline);
#define MSG_Begin( x ) _MSG_Begin( x, __FILE__, __LINE__)
#define MSG_WriteChar(x,y) _MSG_WriteChar (x, y, __FILE__, __LINE__)
#define MSG_WriteByte(x,y) _MSG_WriteByte (x, y, __FILE__, __LINE__)
#define MSG_WriteShort(x,y) _MSG_WriteShort (x, y, __FILE__, __LINE__)
#define MSG_WriteWord(x,y) _MSG_WriteWord (x, y, __FILE__, __LINE__)
#define MSG_WriteLong(x,y) _MSG_WriteLong (x, y, __FILE__, __LINE__)
#define MSG_WriteFloat(x, y) _MSG_WriteFloat (x, y, __FILE__, __LINE__)
#define MSG_WriteString(x,y) _MSG_WriteString (x, y, __FILE__, __LINE__)
#define MSG_WriteCoord(x, y) _MSG_WriteCoord (x, y, __FILE__, __LINE__)
#define MSG_WritePos(x, y) _MSG_WritePos (x, y, __FILE__, __LINE__)
#define MSG_WriteAngle(x, y) _MSG_WriteAngle (x, y, __FILE__, __LINE__)
#define MSG_WriteAngle16(x, y) _MSG_WriteAngle16 (x, y, __FILE__, __LINE__)
#define MSG_WriteUnterminatedString(x, y) _MSG_WriteUnterminatedString (x, y, __FILE__, __LINE__)
#define MSG_WriteDeltaUsercmd(x, y, z) _MSG_WriteDeltaUsercmd (x, y, z, __FILE__, __LINE__)
#define MSG_WriteDeltaEntity(x, y, z, t, m) _MSG_WriteDeltaEntity (x, y, z, t, m, __FILE__, __LINE__)
#define MSG_WriteDir(x, y) _MSG_WriteDir (x, y, __FILE__, __LINE__)
#define MSG_WriteVector(x, y) _MSG_WriteVector (x, y, __FILE__, __LINE__)
#define MSG_Send(x, y, z) _MSG_Send(x, y, z, __FILE__, __LINE__)
#define MSG_Begin( x ) _MSG_Begin( x, __FILE__, __LINE__);
#define MSG_WriteChar(x,y) _MSG_WriteChar (x, y, __FILE__, __LINE__);
#define MSG_WriteByte(x,y) _MSG_WriteByte (x, y, __FILE__, __LINE__);
#define MSG_WriteShort(x,y) _MSG_WriteShort (x, y, __FILE__, __LINE__);
#define MSG_WriteWord(x,y) _MSG_WriteWord (x, y, __FILE__, __LINE__);
#define MSG_WriteLong(x,y) _MSG_WriteLong (x, y, __FILE__, __LINE__);
#define MSG_WriteFloat(x, y) _MSG_WriteFloat (x, y, __FILE__, __LINE__);
#define MSG_WriteString(x,y) _MSG_WriteString (x, y, __FILE__, __LINE__);
#define MSG_WriteCoord(x, y) _MSG_WriteCoord (x, y, __FILE__, __LINE__);
#define MSG_WritePos(x, y) _MSG_WritePos (x, y, __FILE__, __LINE__);
#define MSG_WriteAngle(x, y) _MSG_WriteAngle (x, y, __FILE__, __LINE__);
#define MSG_WriteAngle16(x, y) _MSG_WriteAngle16 (x, y, __FILE__, __LINE__);
#define MSG_WriteUnterminatedString(x, y) _MSG_WriteUnterminatedString (x, y, __FILE__, __LINE__);
#define MSG_WriteDeltaUsercmd(x, y, z) _MSG_WriteDeltaUsercmd (x, y, z, __FILE__, __LINE__);
#define MSG_WriteDeltaEntity(x, y, z, t, m) _MSG_WriteDeltaEntity (x, y, z, t, m, __FILE__, __LINE__);
#define MSG_WriteDir(x, y) _MSG_WriteDir (x, y, __FILE__, __LINE__);
#define MSG_WriteVector(x, y) _MSG_WriteVector (x, y, __FILE__, __LINE__);
#define MSG_Send(x, y, z) _MSG_Send(x, y, z, __FILE__, __LINE__);
void MSG_BeginReading (sizebuf_t *sb);
@ -136,14 +131,15 @@ void MSG_ReadData (sizebuf_t *sb, void *buffer, int size);
//============================================================================
int COM_Argc (void);
int COM_Argc (void);
char *COM_Argv (int arg); // range and null checked
void COM_ClearArgv (int arg);
int COM_CheckParm (char *parm);
void COM_Init (void);
void COM_InitArgv (int argc, char **argv);
char *CopyString (const char *in);
char *CopyString (char *in);
//============================================================================
@ -418,7 +414,7 @@ void Cmd_AddCommand (char *cmd_name, xcommand_t function);
// as a clc_stringcmd instead of executed locally
void Cmd_RemoveCommand (char *cmd_name);
bool Cmd_Exists (const char *cmd_name);
bool Cmd_Exists (char *cmd_name);
// used by the cvar code to check for cvar / command name overlap
char *Cmd_CompleteCommand (char *partial);
@ -432,11 +428,11 @@ char *Cmd_Args (void);
// functions. Cmd_Argv () will return an empty string, not a NULL
// if arg > argc, so string operations are always safe.
void Cmd_TokenizeString (const char *text, bool macroExpand);
void Cmd_TokenizeString (char *text, bool macroExpand);
// Takes a null terminated string. Does not need to be /n terminated.
// breaks the string up into arg tokens.
void Cmd_ExecuteString (const char *text);
void Cmd_ExecuteString (char *text);
// Parses a single line of text into arguments and tries to execute it
// as if it was typed at the console
@ -461,32 +457,33 @@ NET
#define PACKET_HEADER 10 // two ints and a short
typedef enum {NA_LOOPBACK, NA_BROADCAST, NA_IP, NA_IPX, NA_BROADCAST_IPX} netadrtype_t;
typedef enum {NS_CLIENT, NS_SERVER} netsrc_t;
typedef struct
{
netadrtype_t type;
byte ip[4];
byte ipx[10];
byte ip[4];
byte ipx[10];
word port;
unsigned short port;
} netadr_t;
void NET_Init (void);
void NET_Shutdown (void);
void NET_Init (void);
void NET_Shutdown (void);
void NET_Config (bool multiplayer);
void NET_Config (bool multiplayer);
bool NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message);
void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to);
void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to);
bool NET_CompareAdr (netadr_t a, netadr_t b);
bool NET_CompareBaseAdr (netadr_t a, netadr_t b);
bool NET_IsLocalAddress (netadr_t adr);
char *NET_AdrToString (netadr_t a);
char *NET_AdrToString (netadr_t a);
bool NET_StringToAdr (char *s, netadr_t *a);
void NET_Sleep(int msec);
void NET_Sleep(int msec);
//============================================================================
@ -503,12 +500,12 @@ typedef struct
int dropped; // between last packet and previous
int last_received; // for timeouts
int last_sent; // for retransmits
int last_sent; // for retransmits
netadr_t remote_address;
int qport; // qport value to write when transmitting
// sequencing variables
// sequencing variables
int incoming_sequence;
int incoming_acknowledged;
int incoming_reliable_acknowledged; // single bit
@ -520,16 +517,16 @@ typedef struct
int last_reliable_sequence; // sequence number of last send
// reliable staging and holding areas
sizebuf_t message; // writing buffer to send to server
byte message_buf[MAX_MSGLEN - 16]; // leave space for header
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
int reliable_length;
byte reliable_buf[MAX_MSGLEN - 16]; // unacked reliable message
byte reliable_buf[MAX_MSGLEN-16]; // unacked reliable message
} netchan_t;
extern netadr_t net_from;
extern sizebuf_t net_message;
extern netadr_t net_from;
extern sizebuf_t net_message;
extern byte net_message_buffer[MAX_MSGLEN];
@ -627,25 +624,39 @@ MISC
#define EXEC_INSERT 1 // insert at current position, but don't run yet
#define EXEC_APPEND 2 // add to end of the command buffer
void Com_BeginRedirect (int target, char *buffer, int buffersize, void (*flush));
void Com_EndRedirect (void);
void Com_Printf (char *fmt, ...);
void Com_DPrintf (int level, char *fmt, ...);
void Com_DWarnf (char *fmt, ...);
void Com_Error (int code, char *fmt, ...);
void Com_Error_f ( void );
void Com_Quit (void);
#define PRINT_ALL 0
#define PRINT_DEVELOPER 1 // only print when "developer 1"
int Com_ServerState (void); // this should have just been a cvar...
void Com_SetServerState (int state);
void Com_BeginRedirect (int target, char *buffer, int buffersize, void (*flush));
void Com_EndRedirect (void);
void Com_Printf (char *fmt, ...);
void Com_DPrintf (int level, char *fmt, ...);
void Com_DWarnf (char *fmt, ...);
void Com_Error (int code, char *fmt, ...);
void Com_Error_f ( void );
void Com_Quit (void);
int Com_ServerState (void); // this should have just been a cvar...
void Com_SetServerState (int state);
unsigned Com_BlockChecksum (void *buffer, int length);
byte COM_BlockSequenceCRCByte (byte *base, int length, int sequence);
byte COM_BlockSequenceCRCByte (byte *base, int length, int sequence);
float frand(void); // 0 to 1
float crand(void); // -1 to 1
extern cvar_t *developer;
extern cvar_t *dedicated;
extern cvar_t *host_speeds;
extern cvar_t *log_stats;
extern file_t *log_stats_file;
// host_speeds times
extern int time_before_game;
extern int time_after_game;
extern int time_before_ref;
extern int time_after_ref;
#define NUMVERTEXNORMALS 162
extern vec3_t bytedirs[NUMVERTEXNORMALS];
@ -686,12 +697,12 @@ CLIENT / SERVER SYSTEMS
void CL_Init (void);
void CL_Drop (void);
void CL_Shutdown (void);
void CL_Frame (float time);
void CL_Frame (int msec);
void Con_Print (char *text);
void SCR_BeginLoadingPlaque (void);
void SV_Init (void);
void SV_Shutdown (char *finalmsg, bool reconnect);
void SV_Frame (float time);
void SV_Frame (int msec);
#endif//COMMON_H

View File

@ -234,7 +234,7 @@ void Cbuf_Execute (void)
memmove (text, text+i, cmd_text.cursize);
}
// execute the command line
// execute the command line
Cmd_ExecuteString (line);
if (cmd_wait)
@ -301,7 +301,7 @@ bool Cbuf_AddLateCommands (void)
int argc;
bool ret;
// build the combined string to parse from
// build the combined string to parse from
s = 0;
argc = COM_Argc();
for (i=1 ; i<argc ; i++)
@ -320,7 +320,7 @@ bool Cbuf_AddLateCommands (void)
strcat (text, " ");
}
// pull out the commands
// pull out the commands
build = Z_Malloc (s+1);
build[0] = 0;
@ -344,7 +344,8 @@ bool Cbuf_AddLateCommands (void)
}
ret = (build[0] != 0);
if (ret) Cbuf_AddText (build);
if (ret)
Cbuf_AddText (build);
Z_Free (text);
Z_Free (build);
@ -537,7 +538,7 @@ char *Cmd_Args (void)
Cmd_MacroExpandString
======================
*/
char *Cmd_MacroExpandString (const char *text)
char *Cmd_MacroExpandString (char *text)
{
int i, j, count, len;
bool inquote;
@ -547,7 +548,7 @@ char *Cmd_MacroExpandString (const char *text)
char *token, *start;
inquote = false;
scan = (char *)text;
scan = text;
len = strlen (scan);
if (len >= MAX_STRING_CHARS)
@ -612,10 +613,10 @@ Parses the given string into command line tokens.
$Cvars will be expanded unless they are in a quoted token
============
*/
void Cmd_TokenizeString (const char *text, bool macroExpand)
void Cmd_TokenizeString (char *text, bool macroExpand)
{
int i;
char *token;
char *token;
// clear the args from the last string
for (i = 0; i < cmd_argc; i++) Z_Free (cmd_argv[i]);
@ -740,15 +741,16 @@ void Cmd_RemoveCommand (char *cmd_name)
Cmd_Exists
============
*/
bool Cmd_Exists (const char *cmd_name)
bool Cmd_Exists (char *cmd_name)
{
cmd_function_t *cmd;
for (cmd = cmd_functions; cmd; cmd = cmd->next)
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
{
if (!strcmp (cmd_name,cmd->name))
return true;
}
return false;
}
@ -798,7 +800,7 @@ A complete command line has been parsed, so try to execute it
FIXME: lookupnoadd the token to speed search?
============
*/
void Cmd_ExecuteString (const char *text)
void Cmd_ExecuteString (char *text)
{
cmd_function_t *cmd;
cmdalias_t *a;

View File

@ -36,19 +36,19 @@ typedef struct
typedef struct
{
int contents;
int cluster;
int area;
word firstleafbrush;
word numleafbrushes;
int contents;
int cluster;
int area;
unsigned short firstleafbrush;
unsigned short numleafbrushes;
} cleaf_t;
typedef struct
{
int contents;
int numsides;
int firstbrushside;
int checkcount; // to avoid repeated testings
int contents;
int numsides;
int firstbrushside;
int checkcount; // to avoid repeated testings
} cbrush_t;
typedef struct
@ -926,7 +926,7 @@ Handles offseting and rotation of the end points for moving and
rotating entities
==================
*/
int CM_TransformedPointContents (vec3_t p, int headnode, vec3_t origin, vec3_t angles)
int CM_TransformedPointContents (vec3_t p, int headnode, vec3_t origin, vec3_t angles)
{
vec3_t p_l;
vec3_t temp;
@ -940,7 +940,7 @@ int CM_TransformedPointContents (vec3_t p, int headnode, vec3_t origin, vec3_t a
if (headnode != box_headnode &&
(angles[0] || angles[1] || angles[2]) )
{
AngleVectorsRight (angles, forward, right, up);
AngleVectors (angles, forward, right, up);
VectorCopy (p_l, temp);
p_l[0] = DotProduct (temp, forward);
@ -978,15 +978,16 @@ bool trace_ispoint; // optimized case
CM_ClipBoxToBrush
================
*/
void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace_t *trace, cbrush_t *brush)
void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
trace_t *trace, cbrush_t *brush)
{
int i, j;
cplane_t *plane, *clipplane;
int i, j;
cplane_t *plane, *clipplane;
float dist;
float enterfrac, leavefrac;
vec3_t ofs;
float d1, d2;
bool getout, startout;
bool getout, startout;
float f;
cbrushside_t *side, *leadside;
@ -994,7 +995,8 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace_t
leavefrac = 1;
clipplane = NULL;
if (!brush->numsides) return;
if (!brush->numsides)
return;
c_brush_traces++;
@ -1002,7 +1004,7 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace_t
startout = false;
leadside = NULL;
for (i = 0; i < brush->numsides; i++)
for (i=0 ; i<brush->numsides ; i++)
{
side = &map_brushsides[brush->firstbrushside+i];
plane = side->plane;
@ -1010,17 +1012,17 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace_t
// FIXME: special case for axial
if (!trace_ispoint)
{
// general box case
{ // general box case
// push the plane out apropriately for mins/maxs
// FIXME: use signbits into 8 way lookup for each mins/maxs
for (j = 0; j < 3; j++)
for (j=0 ; j<3 ; j++)
{
if (plane->normal[j] < 0)
ofs[j] = maxs[j];
else ofs[j] = mins[j];
else
ofs[j] = mins[j];
}
dist = DotProduct (ofs, plane->normal);
dist = plane->dist - dist;
@ -1033,13 +1035,17 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace_t
d1 = DotProduct (p1, plane->normal) - dist;
d2 = DotProduct (p2, plane->normal) - dist;
if (d2 > 0) getout = true; // endpoint is not in solid
if (d1 > 0) startout = true;
if (d2 > 0)
getout = true; // endpoint is not in solid
if (d1 > 0)
startout = true;
// if completely in front of face, no intersection
if (d1 > 0 && d2 >= d1) return;
if (d1 > 0 && d2 >= d1)
return;
if (d1 <= 0 && d2 <= 0) continue;
if (d1 <= 0 && d2 <= 0)
continue;
// crosses face
if (d1 > d2)
@ -1054,23 +1060,25 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace_t
}
else
{ // leave
f = (d1 + DIST_EPSILON) / (d1-d2);
if (f < leavefrac) leavefrac = f;
f = (d1+DIST_EPSILON) / (d1-d2);
if (f < leavefrac)
leavefrac = f;
}
}
if (!startout)
{
// original point was inside brush
{ // original point was inside brush
trace->startsolid = true;
if (!getout) trace->allsolid = true;
if (!getout)
trace->allsolid = true;
return;
}
if (enterfrac < leavefrac)
{
if (enterfrac > -1 && enterfrac < trace->fraction)
{
if (enterfrac < 0) enterfrac = 0;
if (enterfrac < 0)
enterfrac = 0;
trace->fraction = enterfrac;
trace->plane = *clipplane;
trace->surface = &(leadside->surface->c);
@ -1184,7 +1192,7 @@ void CM_TestInLeaf (int leafnum)
if ( !(leaf->contents & trace_contents))
return;
// trace line against all brushes in the leaf
for (k = 0; k < leaf->numleafbrushes; k++)
for (k=0 ; k<leaf->numleafbrushes ; k++)
{
brushnum = map_leafbrushes[leaf->firstleafbrush+k];
b = &map_brushes[brushnum];
@ -1192,7 +1200,7 @@ void CM_TestInLeaf (int leafnum)
continue; // already checked this brush in another leaf
b->checkcount = checkcount;
if (!(b->contents & trace_contents))
if ( !(b->contents & trace_contents))
continue;
CM_TestBoxInBrush (trace_mins, trace_maxs, trace_start, &trace_trace, b);
if (!trace_trace.fraction)
@ -1331,12 +1339,15 @@ return;
CM_BoxTrace
==================
*/
trace_t CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask)
trace_t CM_BoxTrace (vec3_t start, vec3_t end,
vec3_t mins, vec3_t maxs,
int headnode, int brushmask)
{
int i;
checkcount++; // for multi-check avoidance
c_traces++; // for statistics, may be zeroed
checkcount++; // for multi-check avoidance
c_traces++; // for statistics, may be zeroed
// fill in a default trace
memset (&trace_trace, 0, sizeof(trace_trace));
@ -1352,24 +1363,26 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int hea
VectorCopy (mins, trace_mins);
VectorCopy (maxs, trace_maxs);
//
// check for position test special case
//
if (start[0] == end[0] && start[1] == end[1] && start[2] == end[2])
{
int leafs[1024];
int i, numleafs;
vec3_t c1, c2;
vec3_t c1, c2;
int topnode;
VectorAdd (start, mins, c1);
VectorAdd (start, maxs, c2);
for (i = 0; i < 3; i++)
for (i=0 ; i<3 ; i++)
{
c1[i] -= 1;
c2[i] += 1;
}
numleafs = CM_BoxLeafnums_headnode (c1, c2, leafs, 1024, headnode, &topnode);
for (i = 0; i < numleafs; i++)
for (i=0 ; i<numleafs ; i++)
{
CM_TestInLeaf (leafs[i]);
if (trace_trace.allsolid)
@ -1379,7 +1392,9 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int hea
return trace_trace;
}
//
// check for point special case
//
if (mins[0] == 0 && mins[1] == 0 && mins[2] == 0
&& maxs[0] == 0 && maxs[1] == 0 && maxs[2] == 0)
{
@ -1394,7 +1409,9 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int hea
trace_extents[2] = -mins[2] > maxs[2] ? -mins[2] : maxs[2];
}
//
// general sweeping through world
//
CM_RecursiveHullCheck (headnode, 0, 1, start, end);
if (trace_trace.fraction == 1)
@ -1403,7 +1420,7 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int hea
}
else
{
for (i = 0; i < 3; i++)
for (i=0 ; i<3 ; i++)
trace_trace.endpos[i] = start[i] + trace_trace.fraction * (end[i] - start[i]);
}
return trace_trace;
@ -1423,7 +1440,10 @@ rotating entities
#endif
trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask, vec3_t origin, vec3_t angles)
trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end,
vec3_t mins, vec3_t maxs,
int headnode, int brushmask,
vec3_t origin, vec3_t angles)
{
trace_t trace;
vec3_t start_l, end_l;
@ -1437,14 +1457,15 @@ trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t ma
VectorSubtract (end, origin, end_l);
// rotate start and end into the models frame of reference
if (headnode != box_headnode && !VectorIsNull(angles))
if (headnode != box_headnode &&
(angles[0] || angles[1] || angles[2]) )
rotated = true;
else
rotated = false;
if (rotated)
{
AngleVectorsRight (angles, forward, right, up);
AngleVectors (angles, forward, right, up);
VectorCopy (start_l, temp);
start_l[0] = DotProduct (temp, forward);
@ -1465,7 +1486,7 @@ trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t ma
// FIXME: figure out how to do this with existing angles
VectorCopy( angles, a );
VectorNegate ( a, a );
AngleVectorsRight (a, forward, right, up);
AngleVectors (a, forward, right, up);
VectorCopy (trace.plane.normal, temp);
trace.plane.normal[0] = DotProduct (temp, forward);
@ -1720,15 +1741,15 @@ STUDIO SHARED CMODELS
===============================================================================
*/
#define HULL_PRECISION 4 // precision factor
#define NUM_HULL_ROUNDS 22
#define HULL_PRECISION 4
word hull_table[] = { 0, 4, 8, 16, 18, 24, 28, 30, 32, 40, 48, 54, 56, 60, 64, 72, 80, 112, 120, 128, 140, 176 };
#define NUM_HULL_ROUNDS (sizeof(hull_table) / sizeof(word))
word hull_table[NUM_HULL_ROUNDS] = { 0, 4, 8, 16, 18, 24, 28, 30, 32, 40, 48, 54, 56, 60, 64, 72, 80, 112, 120, 128, 140, 176 };
void CM_LookUpHullSize(vec3_t size, bool down)
{
int i, j;
for(i = 0; i < 3; i++)
{
bool negative = false;
@ -1748,14 +1769,7 @@ void CM_LookUpHullSize(vec3_t size, bool down)
break;
}
}
if(j == NUM_HULL_ROUNDS)
{
//catch an error
MsgWarn("CM_LookUpHullSize: hull size[%d] is too big, reset value to default\n", i );
size[i] = 16; //default value
}
else size[i] = result;//copy new value
size[i] = result;//copy new value
}
}
@ -1805,7 +1819,7 @@ cmodel_t *CM_StudioModel (char *name, byte *buffer)
VectorSet(out->mins, -32, -32, -32 );
VectorSet(out->maxs, 32, 32, 32 );
}
numsmodels++;
return out;
}

View File

@ -28,11 +28,24 @@ jmp_buf abortframe;
int com_argc;
char *com_argv[MAX_NUM_ARGVS+1];
double realtime;
int realtime;
file_t *log_stats_file;
cvar_t *host_speeds;
cvar_t *log_stats;
cvar_t *developer;
cvar_t *dedicated;
int server_state;
// host_speeds times
int time_before_game;
int time_after_game;
int time_before_ref;
int time_after_ref;
/*
============================================================================
@ -101,9 +114,7 @@ void Com_Error (int code, char *fmt, ...)
va_start (argptr,fmt);
vsprintf (msg,fmt,argptr);
va_end (argptr);
host.state = HOST_ERROR;
if (code == ERR_DISCONNECT)
{
CL_Drop ();
@ -163,7 +174,7 @@ void Com_Printf (char *fmt, ...)
================
Com_DPrintf
A Msg that only shows up in developer mode > 0
A Msg that only shows up in debug mode
================
*/
void Com_DPrintf (int level, char *fmt, ...)
@ -301,7 +312,7 @@ COM_InitArgv
*/
void COM_InitArgv (int argc, char **argv)
{
int i;
int i;
char dev_level[4];
if (argc > MAX_NUM_ARGVS)
@ -325,9 +336,9 @@ void COM_InitArgv (int argc, char **argv)
host.developer = atoi(dev_level);
}
char *CopyString (const char *in)
char *CopyString (char *in)
{
char *out;
char *out;
out = Z_Malloc (strlen(in)+1);
strcpy (out, in);

View File

@ -93,7 +93,7 @@ void Con_ToggleConsole_f (void)
M_ForceMenuOff ();
cls.key_dest = key_console;
if (host.maxclients == 1 && Com_ServerState())
if (Cvar_VariableValue ("maxclients") == 1 && Com_ServerState ())
Cvar_Set ("paused", "1");
}
}
@ -206,7 +206,7 @@ void Con_ClearNotify (void)
{
int i;
for (i = 0; i < NUM_CON_TIMES; i++)
for (i=0 ; i<NUM_CON_TIMES ; i++)
con.times[i] = 0;
}
@ -389,8 +389,9 @@ void Con_Print (char *txt)
if (!con.x)
{
Con_Linefeed ();
// mark time for transparent overlay
if (con.current >= 0) con.times[con.current % NUM_CON_TIMES] = cls.realtime;
// mark time for transparent overlay
if (con.current >= 0)
con.times[con.current % NUM_CON_TIMES] = cls.realtime;
}
switch (c)
@ -466,24 +467,24 @@ void Con_DrawInput (void)
text = key_lines[edit_line];
// add the cursor frame
text[key_linepos] = 10 + ((int)(cls.realtime * 4.0f) & 1);
// add the cursor frame
text[key_linepos] = 10+((int)(cls.realtime>>8)&1);
// fill out remainder with spaces
for (i = key_linepos + 1; i < con.linewidth; i++)
// fill out remainder with spaces
for (i=key_linepos+1 ; i< con.linewidth ; i++)
text[i] = ' ';
// prestep if horizontally scrolling
// prestep if horizontally scrolling
if (key_linepos >= con.linewidth)
text += 1 + key_linepos - con.linewidth;
// draw it
// draw it
y = con.vislines-16;
for (i=0 ; i<con.linewidth ; i++)
re->DrawChar ( (i+1)<<3, con.vislines - 22, text[i]);
// remove cursor
// remove cursor
key_lines[edit_line][key_linepos] = 0;
}
@ -500,19 +501,22 @@ void Con_DrawNotify (void)
int x, v;
char *text;
int i;
float time;
int time;
char *s;
int skip;
v = 0;
for (i= con.current-NUM_CON_TIMES+1 ; i<=con.current ; i++)
{
if (i < 0) continue;
if (i < 0)
continue;
time = con.times[i % NUM_CON_TIMES];
if (time == 0) continue;
if (time == 0)
continue;
time = cls.realtime - time;
if (time > con_notifytime->value) continue;
text = con.text + (i % con.totallines) * con.linewidth;
if (time > con_notifytime->value*1000)
continue;
text = con.text + (i % con.totallines)*con.linewidth;
for (x = 0 ; x < con.linewidth ; x++)
re->DrawChar ( (x+1)<<3, v, text[x]);
@ -543,7 +547,7 @@ void Con_DrawNotify (void)
re->DrawChar ( (x+skip)<<3, v, s[x]);
x++;
}
re->DrawChar ((x+skip)<<3, v, 10 + ((int)(cls.realtime * 4.0f) & 1));
re->DrawChar ( (x+skip)<<3, v, 10+((cls.realtime>>8)&1));
v += 8;
}

View File

@ -28,7 +28,7 @@ cvar_t *cvar_vars;
Cvar_InfoValidate
============
*/
static bool Cvar_InfoValidate (const char *s)
static bool Cvar_InfoValidate (char *s)
{
if (strstr (s, "\\"))
return false;
@ -44,11 +44,11 @@ static bool Cvar_InfoValidate (const char *s)
Cvar_FindVar
============
*/
cvar_t *Cvar_FindVar (const char *var_name)
cvar_t *Cvar_FindVar (char *var_name)
{
cvar_t *var;
for (var = cvar_vars; var; var = var->next)
for (var=cvar_vars ; var ; var=var->next)
if (!strcmp (var_name, var->name))
return var;
@ -60,12 +60,13 @@ cvar_t *Cvar_FindVar (const char *var_name)
Cvar_VariableValue
============
*/
float Cvar_VariableValue (const char *var_name)
float Cvar_VariableValue (char *var_name)
{
cvar_t *var;
var = Cvar_FindVar (var_name);
if (!var) return 0;
if (!var)
return 0;
return atof (var->string);
}
@ -75,12 +76,13 @@ float Cvar_VariableValue (const char *var_name)
Cvar_VariableString
============
*/
char *Cvar_VariableString (const char *var_name)
char *Cvar_VariableString (char *var_name)
{
cvar_t *var;
var = Cvar_FindVar (var_name);
if (!var) return "";
if (!var)
return "";
return var->string;
}
@ -93,15 +95,16 @@ Cvar_CompleteVariable
char *Cvar_CompleteVariable (char *partial)
{
cvar_t *cvar;
int len;
int len;
len = strlen(partial);
if (!len) return NULL;
if (!len)
return NULL;
// check exact match
for (cvar=cvar_vars ; cvar ; cvar=cvar->next)
if (!strcmp (partial, cvar->name))
if (!strcmp (partial,cvar->name))
return cvar->name;
// check partial match
@ -121,7 +124,7 @@ If the variable already exists, the value will not be set
The flags will be or'ed in if the variable exists.
============
*/
cvar_t *Cvar_Get (const char *var_name, const char *var_value, int flags)
cvar_t *Cvar_Get (char *var_name, char *var_value, int flags)
{
cvar_t *var;
@ -173,12 +176,15 @@ cvar_t *Cvar_Get (const char *var_name, const char *var_value, int flags)
Cvar_Set2
============
*/
cvar_t *Cvar_Set2 (const char *var_name, const char *value, bool force)
cvar_t *Cvar_Set2 (char *var_name, char *value, bool force)
{
cvar_t *var;
var = Cvar_FindVar (var_name);
if (!var) return Cvar_Get (var_name, value, 0); // create it
if (!var)
{ // create it
return Cvar_Get (var_name, value, 0);
}
if (var->flags & (CVAR_USERINFO | CVAR_SERVERINFO))
{
@ -238,13 +244,13 @@ cvar_t *Cvar_Set2 (const char *var_name, const char *value, bool force)
var->modified = true;
// transmit at next oportunity
if (var->flags & CVAR_USERINFO) userinfo_modified = true;
if (var->flags & CVAR_USERINFO)
userinfo_modified = true; // transmit at next oportunity
Z_Free (var->string); // free the old value string
Z_Free (var->string); // free the old value string
var->string = CopyString(value);
var->value = atof(var->string);
var->value = atof (var->string);
return var;
}
@ -254,7 +260,7 @@ cvar_t *Cvar_Set2 (const char *var_name, const char *value, bool force)
Cvar_ForceSet
============
*/
cvar_t *Cvar_ForceSet (const char *var_name, const char *value)
cvar_t *Cvar_ForceSet (char *var_name, char *value)
{
return Cvar_Set2 (var_name, value, true);
}
@ -264,7 +270,7 @@ cvar_t *Cvar_ForceSet (const char *var_name, const char *value)
Cvar_Set
============
*/
cvar_t *_Cvar_Set (const char *var_name, const char *value, const char *filename, int fileline)
cvar_t *Cvar_Set (char *var_name, char *value)
{
return Cvar_Set2 (var_name, value, false);
}
@ -346,13 +352,14 @@ Handles variable inspection and changing from the console
*/
bool Cvar_Command (void)
{
cvar_t *v;
// check variables
cvar_t *v;
// check variables
v = Cvar_FindVar (Cmd_Argv(0));
if (!v) return false;
if (!v)
return false;
// perform a variable print or set
// perform a variable print or set
if (Cmd_Argc() == 1)
{
Msg ("\"%s\" is \"%s\"\n", v->name, v->string);
@ -385,8 +392,10 @@ void Cvar_Set_f (void)
if (c == 4)
{
if (!strcmp(Cmd_Argv(3), "u")) flags = CVAR_USERINFO;
else if (!strcmp(Cmd_Argv(3), "s")) flags = CVAR_SERVERINFO;
if (!strcmp(Cmd_Argv(3), "u"))
flags = CVAR_USERINFO;
else if (!strcmp(Cmd_Argv(3), "s"))
flags = CVAR_SERVERINFO;
else
{
Msg ("flags can only be 'u' or 's'\n");
@ -394,7 +403,8 @@ void Cvar_Set_f (void)
}
Cvar_FullSet (Cmd_Argv(1), Cmd_Argv(2), flags);
}
else Cvar_Set (Cmd_Argv(1), Cmd_Argv(2));
else
Cvar_Set (Cmd_Argv(1), Cmd_Argv(2));
}
@ -465,7 +475,7 @@ void Cvar_List_f (void)
bool userinfo_modified;
char *Cvar_BitInfo (int bit)
char *Cvar_BitInfo (int bit)
{
static char info[MAX_INFO_STRING];
cvar_t *var;
@ -481,13 +491,13 @@ char *Cvar_BitInfo (int bit)
}
// returns an info string containing all the CVAR_USERINFO cvars
char *Cvar_Userinfo (void)
char *Cvar_Userinfo (void)
{
return Cvar_BitInfo (CVAR_USERINFO);
}
// returns an info string containing all the CVAR_SERVERINFO cvars
char *Cvar_Serverinfo (void)
char *Cvar_Serverinfo (void)
{
return Cvar_BitInfo (CVAR_SERVERINFO);
}

View File

@ -6,18 +6,17 @@
#define CVAR_H
extern cvar_t *cvar_vars;
cvar_t *Cvar_FindVar (const char *var_name);
cvar_t *Cvar_FindVar (char *var_name);
cvar_t *Cvar_Get (const char *var_name, const char *value, int flags);
cvar_t *Cvar_Get (char *var_name, char *value, int flags);
// creates the variable if it doesn't exist, or returns the existing one
// if it exists, the value will not be changed, but flags will be ORed in
// that allows variables to be unarchived without needing bitflags
#define Cvar_Set(name, val) _Cvar_Set (name, val, __FILE__, __LINE__)
cvar_t *_Cvar_Set (const char *var_name, const char *value, const char *filename, int fileline);
cvar_t *Cvar_Set (char *var_name, char *value);
// will create the variable if it doesn't exist
cvar_t *Cvar_ForceSet (const char *var_name, const char *value);
cvar_t *Cvar_ForceSet (char *var_name, char *value);
// will set the variable even if NOSET or LATCH
cvar_t *Cvar_FullSet (char *var_name, char *value, int flags);
@ -25,10 +24,10 @@ cvar_t *Cvar_FullSet (char *var_name, char *value, int flags);
void Cvar_SetValue (char *var_name, float value);
// expands value to a string and calls Cvar_Set
float Cvar_VariableValue (const char *var_name);
float Cvar_VariableValue (char *var_name);
// returns 0 if not defined or non numeric
char *Cvar_VariableString (const char *var_name);
char *Cvar_VariableString (char *var_name);
// returns an empty string if not defined
char *Cvar_CompleteVariable (char *partial);

View File

@ -737,7 +737,7 @@ Called by the system between frames for both key up and key down events
Should NOT be called during an interrupt!
===================
*/
void Key_Event (int key, bool down, uint msec)
void Key_Event (int key, bool down, unsigned time)
{
char *kb;
char cmd[1024];
@ -835,7 +835,7 @@ void Key_Event (int key, bool down, uint msec)
kb = keybindings[key];
if (kb && kb[0] == '+')
{
sprintf (cmd, "-%s %i %i\n", kb+1, key, msec);
sprintf (cmd, "-%s %i %i\n", kb+1, key, time);
Cbuf_AddText (cmd);
}
if (keyshift[key] != key)
@ -843,7 +843,7 @@ void Key_Event (int key, bool down, uint msec)
kb = keybindings[keyshift[key]];
if (kb && kb[0] == '+')
{
sprintf (cmd, "-%s %i %i\n", kb+1, key, msec);
sprintf (cmd, "-%s %i %i\n", kb+1, key, time);
Cbuf_AddText (cmd);
}
}
@ -859,7 +859,7 @@ void Key_Event (int key, bool down, uint msec)
if (kb[0] == '+')
{
// button commands add keynum and time as a parm
sprintf (cmd, "%s %i %i\n", kb, key, msec);
sprintf (cmd, "%s %i %i\n", kb, key, time);
Cbuf_AddText (cmd);
}
else

View File

@ -137,12 +137,10 @@ extern char chat_buffer[];
extern int chat_bufferlen;
extern bool chat_team;
void Key_Event (int key, bool down, uint msec);
void Key_Event (int key, bool down, unsigned time);
void Key_Init (void);
void Key_WriteBindings (file_t *f);
void Key_SetBinding (int keynum, char *binding);
void Key_ClearStates (void);
char *Key_KeynumToString (int keynum);
int Key_StringToKeynum (char *str);
int Key_GetKey (void);

View File

@ -84,7 +84,7 @@ void M_PushMenu ( void (*draw) (void), const char *(*key) (int k) )
{
int i;
if (host.maxclients == 1 && Com_ServerState ())
if (Cvar_VariableValue ("maxclients") == 1 && Com_ServerState ())
Cvar_Set ("paused", "1");
// if this menu is already present, drop back to that level
@ -321,6 +321,7 @@ void M_DrawCursor( int x, int y, int f )
for ( i = 0; i < NUM_CURSOR_FRAMES; i++ )
{
sprintf( cursorname, "m_cursor%d", i );
re->RegisterPic( cursorname );
}
cached = true;
@ -424,7 +425,7 @@ void M_Main_Draw (void)
strlcat( litname, "_sel", 80 );
re->DrawPic( xoffset, ystart + m_main_cursor * 40 + 13, litname );
M_DrawCursor( xoffset - 25, ystart + m_main_cursor * 40 + 11, (int)(cls.realtime * 8.0f) % NUM_CURSOR_FRAMES );
M_DrawCursor( xoffset - 25, ystart + m_main_cursor * 40 + 11, (int)(cls.realtime / 100)%NUM_CURSOR_FRAMES );
re->DrawGetPicSize( &w, &h, "m_main_plaque" );
re->DrawPic( xoffset - 30 - w, ystart, "m_main_plaque" );
@ -685,8 +686,10 @@ static void M_FindKeysForCommand (char *command, int *twokeys)
static void KeyCursorDrawFunc( menuframework_s *menu )
{
if ( bind_grab ) re->DrawChar( menu->x, menu->y + menu->cursor * 9, '=' );
else re->DrawChar( menu->x, menu->y + menu->cursor * 9, 12 + ((int)(cls.realtime * 5.0f) & 1 ));
if ( bind_grab )
re->DrawChar( menu->x, menu->y + menu->cursor * 9, '=' );
else
re->DrawChar( menu->x, menu->y + menu->cursor * 9, 12 + ( ( int ) ( Sys_Milliseconds() / 250 ) & 1 ) );
}
static void DrawKeyBindingFunc( void *self )
@ -1360,7 +1363,7 @@ END GAME MENU
=============================================================================
*/
static float credits_start_time;
static int credits_start_time;
static const char **credits;
static char *creditsIndex[256];
static char *creditsBuffer;
@ -1452,20 +1455,161 @@ static const char *idcredits[] =
0
};
static const char *xatcredits[] =
{
"+QUAKE II MISSION PACK: THE RECKONING",
"+BY",
"+XATRIX ENTERTAINMENT, INC.",
"",
"+DESIGN AND DIRECTION",
"Drew Markham",
"",
"+PRODUCED BY",
"Greg Goodrich",
"",
"+PROGRAMMING",
"Rafael Paiz",
"",
"+LEVEL DESIGN / ADDITIONAL GAME DESIGN",
"Alex Mayberry",
"",
"+LEVEL DESIGN",
"Mal Blackwell",
"Dan Koppel",
"",
"+ART DIRECTION",
"Michael \"Maxx\" Kaufman",
"",
"+COMPUTER GRAPHICS SUPERVISOR AND",
"+CHARACTER ANIMATION DIRECTION",
"Barry Dempsey",
"",
"+SENIOR ANIMATOR AND MODELER",
"Jason Hoover",
"",
"+CHARACTER ANIMATION AND",
"+MOTION CAPTURE SPECIALIST",
"Amit Doron",
"",
"+ART",
"Claire Praderie-Markham",
"Viktor Antonov",
"Corky Lehmkuhl",
"",
"+INTRODUCTION ANIMATION",
"Dominique Drozdz",
"",
"+ADDITIONAL LEVEL DESIGN",
"Aaron Barber",
"Rhett Baldwin",
"",
"+3D CHARACTER ANIMATION TOOLS",
"Gerry Tyra, SA Technology",
"",
"+ADDITIONAL EDITOR TOOL PROGRAMMING",
"Robert Duffy",
"",
"+ADDITIONAL PROGRAMMING",
"Ryan Feltrin",
"",
"+PRODUCTION COORDINATOR",
"Victoria Sylvester",
"",
"+SOUND DESIGN",
"Gary Bradfield",
"",
"+MUSIC BY",
"Sonic Mayhem",
"",
"",
"",
"+SPECIAL THANKS",
"+TO",
"+OUR FRIENDS AT ID SOFTWARE",
"",
"John Carmack",
"John Cash",
"Brian Hook",
"Adrian Carmack",
"Kevin Cloud",
"Paul Steed",
"Tim Willits",
"Christian Antkow",
"Paul Jaquays",
"Brandon James",
"Todd Hollenshead",
"Barrett (Bear) Alexander",
"Dave \"Zoid\" Kirsch",
"Donna Jackson",
"",
"",
"",
"+THANKS TO ACTIVISION",
"+IN PARTICULAR:",
"",
"Marty Stratton",
"Henk \"The Original Ripper\" Hartong",
"Kevin Kraff",
"Jamey Gottlieb",
"Chris Hepburn",
"",
"+AND THE GAME TESTERS",
"",
"Tim Vanlaw",
"Doug Jacobs",
"Steven Rosenthal",
"David Baker",
"Chris Campbell",
"Aaron Casillas",
"Steve Elwell",
"Derek Johnstone",
"Igor Krinitskiy",
"Samantha Lee",
"Michael Spann",
"Chris Toft",
"Juan Valdes",
"",
"+THANKS TO INTERGRAPH COMPUTER SYTEMS",
"+IN PARTICULAR:",
"",
"Michael T. Nicolaou",
"",
"",
"Quake II Mission Pack: The Reckoning",
"(tm) (C)1998 Id Software, Inc. All",
"Rights Reserved. Developed by Xatrix",
"Entertainment, Inc. for Id Software,",
"Inc. Distributed by Activision Inc.",
"under license. Quake(R) is a",
"registered trademark of Id Software,",
"Inc. Quake II Mission Pack: The",
"Reckoning(tm), Quake II(tm), the Id",
"Software name, the \"Q II\"(tm) logo",
"and id(tm) logo are trademarks of Id",
"Software, Inc. Activision(R) is a",
"registered trademark of Activision,",
"Inc. Xatrix(R) is a registered",
"trademark of Xatrix Entertainment,",
"Inc. All other trademarks and trade",
"names are properties of their",
"respective owners.",
0
};
void M_Credits_MenuDraw( void )
{
int i;
float y;
int i, y;
/*
** draw the credits
*/
for ( i = 0, y = viddef.height - (( cls.realtime - credits_start_time ) * 40.0f ); credits[i] && y < viddef.height; y += 10, i++ )
for ( i = 0, y = viddef.height - ( ( cls.realtime - credits_start_time ) / 40.0F ); credits[i] && y < viddef.height; y += 10, i++ )
{
int j, stringoffset = 0;
int bold = false;
if ( y <= -8 ) continue;
if ( y <= -8 )
continue;
if ( credits[i][0] == '+' )
{
@ -1484,13 +1628,15 @@ void M_Credits_MenuDraw( void )
x = ( viddef.width - strlen( credits[i] ) * 8 - stringoffset * 8 ) / 2 + ( j + stringoffset ) * 8;
if ( bold ) re->DrawChar( x, y, credits[i][j+stringoffset] + 128 );
else re->DrawChar( x, y, credits[i][j+stringoffset] );
if ( bold )
re->DrawChar( x, y, credits[i][j+stringoffset] + 128 );
else
re->DrawChar( x, y, credits[i][j+stringoffset] );
}
}
// loop demonstration
if ( y < 0 ) credits_start_time = cls.realtime;
if ( y < 0 )
credits_start_time = cls.realtime;
}
const char *M_Credits_Key( int key )
@ -1510,12 +1656,12 @@ void M_Menu_Credits_f( void )
{
int n;
int count;
char *p;
char *p;
int isdeveloper = 0;
creditsBuffer = NULL;
creditsBuffer = FS_LoadFile ("scripts/credits.txt", &count );
if (count)
creditsBuffer = FS_LoadFile ("credits", &count );
if (count != -1)
{
p = creditsBuffer;
for (n = 0; n < 255; n++)
@ -1524,15 +1670,18 @@ void M_Menu_Credits_f( void )
while (*p != '\r' && *p != '\n')
{
p++;
if (--count == 0) break;
if (--count == 0)
break;
}
if (*p == '\r')
{
*p++ = 0;
if (--count == 0) break;
if (--count == 0)
break;
}
*p++ = 0;
if (--count == 0) break;
if (--count == 0)
break;
}
creditsIndex[++n] = 0;
credits = creditsIndex;
@ -2086,8 +2235,7 @@ void StartServerActionFunc( void *self )
timelimit = atoi( s_timelimit_field.buffer );
fraglimit = atoi( s_fraglimit_field.buffer );
host.maxclients = maxclients;
Cvar_SetValue( "maxclients", ClampCvar( 0, maxclients, maxclients ) );
Cvar_SetValue ("timelimit", ClampCvar( 0, timelimit, timelimit ) );
Cvar_SetValue ("fraglimit", ClampCvar( 0, fraglimit, fraglimit ) );
Cvar_Set("hostname", s_hostname_field.buffer );
@ -2347,8 +2495,10 @@ void StartServer_MenuInit( void )
s_maxclients_field.generic.statusbar = NULL;
s_maxclients_field.length = 3;
s_maxclients_field.visible_length = 3;
if ( host.maxclients == 1 ) strcpy( s_maxclients_field.buffer, "8" );
else strcpy( s_maxclients_field.buffer, "32" ); // just for test
if ( Cvar_VariableValue( "maxclients" ) == 1 )
strcpy( s_maxclients_field.buffer, "8" );
else
strcpy( s_maxclients_field.buffer, Cvar_VariableString("maxclients") );
s_hostname_field.generic.type = MTYPE_FIELD;
s_hostname_field.generic.name = "hostname";
@ -3338,7 +3488,7 @@ void PlayerConfig_MenuDraw( void )
refdef.height = 168;
refdef.fov_x = 40;
refdef.fov_y = CalcFov( refdef.fov_x, refdef.width, refdef.height );
refdef.time = cls.realtime;
refdef.time = cls.realtime*0.001;
if ( s_pmi[s_player_model_box.curvalue].skindisplaynames )
{
@ -3527,7 +3677,8 @@ void M_Draw (void)
SCR_DirtyScreen ();
// dim everything behind it down
if (cl.cinematictime > 0) re->DrawFill (0, 0, viddef.width, viddef.height, 0);
if (cl.cinematictime > 0)
re->DrawFill (0, 0, viddef.width, viddef.height, 0);
else re->DrawFadeScreen ();
m_drawfunc ();

View File

@ -93,7 +93,7 @@ void Netchan_Init (void)
int port;
// pick a port value that should be nice and random
port = RANDOM_LONG(1, 65535);
port = Sys_Milliseconds() & 0xffff;
Msg("netchan port %d\n", port );
@ -158,7 +158,7 @@ void Netchan_Setup (netsrc_t sock, netchan_t *chan, netadr_t adr, int qport)
chan->sock = sock;
chan->remote_address = adr;
chan->qport = qport;
chan->last_received = host.realtime * 1000;
chan->last_received = curtime;
chan->incoming_sequence = 0;
chan->outgoing_sequence = 1;
@ -218,11 +218,12 @@ void Netchan_Transmit (netchan_t *chan, int length, byte *data)
bool send_reliable;
unsigned w1, w2;
// check for message overflow
// check for message overflow
if (chan->message.overflowed)
{
chan->fatal_error = true;
Msg ("%s:Outgoing message overflow\n", NET_AdrToString (chan->remote_address));
Msg ("%s:Outgoing message overflow\n"
, NET_AdrToString (chan->remote_address));
return;
}
@ -230,21 +231,21 @@ void Netchan_Transmit (netchan_t *chan, int length, byte *data)
if (!chan->reliable_length && chan->message.cursize)
{
Mem_Copy (chan->reliable_buf, chan->message_buf, chan->message.cursize);
memcpy (chan->reliable_buf, chan->message_buf, chan->message.cursize);
chan->reliable_length = chan->message.cursize;
chan->message.cursize = 0;
chan->reliable_sequence ^= 1;
}
// write the packet header
// write the packet header
SZ_Init (&send, send_buf, sizeof(send_buf));
w1 = ( chan->outgoing_sequence & ~(1<<31) ) | (send_reliable<<31);
w2 = ( chan->incoming_sequence & ~(1<<31) ) | (chan->incoming_reliable_sequence<<31);
chan->outgoing_sequence++;
chan->last_sent = host.realtime * 1000;
chan->last_sent = curtime;
MSG_WriteLong (&send, w1);
MSG_WriteLong (&send, w2);
@ -297,9 +298,9 @@ bool Netchan_Process (netchan_t *chan, sizebuf_t *msg)
{
unsigned sequence, sequence_ack;
unsigned reliable_ack, reliable_message;
int qport;
int qport;
// get sequence numbers
// get sequence numbers
MSG_BeginReading (msg);
sequence = MSG_ReadLong (msg);
sequence_ack = MSG_ReadLong (msg);
@ -351,22 +352,22 @@ bool Netchan_Process (netchan_t *chan, sizebuf_t *msg)
if (chan->dropped > 0)
{
if (showdrop->value)
Msg ("%s:Dropped %i packets at %i\n",
NET_AdrToString (chan->remote_address),
chan->dropped,
sequence);
Msg ("%s:Dropped %i packets at %i\n"
, NET_AdrToString (chan->remote_address)
, chan->dropped
, sequence);
}
//
// if the current outgoing reliable message has been acknowledged
// clear the buffer to make way for the next
//
//
// if the current outgoing reliable message has been acknowledged
// clear the buffer to make way for the next
//
if (reliable_ack == chan->reliable_sequence)
chan->reliable_length = 0; // it has been received
//
// if this message contains a reliable message, bump incoming_reliable_sequence
//
//
// if this message contains a reliable message, bump incoming_reliable_sequence
//
chan->incoming_sequence = sequence;
chan->incoming_acknowledged = sequence_ack;
chan->incoming_reliable_acknowledged = reliable_ack;
@ -375,10 +376,10 @@ bool Netchan_Process (netchan_t *chan, sizebuf_t *msg)
chan->incoming_reliable_sequence ^= 1;
}
//
// the message can now be read from the current message pointer
//
chan->last_received = host.realtime * 1000;
//
// the message can now be read from the current message pointer
//
chan->last_received = curtime;
return true;
}

View File

@ -536,37 +536,29 @@ void MSG_ReadData (sizebuf_t *msg_read, void *data, int len)
=======================
*/
void _SZ_Init (sizebuf_t *buf, byte *data, int length, const char *filename, int fileline)
void SZ_Init (sizebuf_t *buf, byte *data, int length)
{
memset (buf, 0, sizeof(*buf));
if(buf == NULL) Sys_Error("SZ_Clear: sizebuf == NULL (called at %s:%i)\n", filename, fileline );
if(data == NULL) Sys_Error("SZ_Init: data == NULL (called at %s:%i)\n", filename, fileline );
if(length <= 0) Sys_Error("SZ_Init: length <= 0 (called at %s:%i)\n", filename, fileline );
buf->data = data;
buf->maxsize = length;
}
void _SZ_Clear (sizebuf_t *buf, const char *filename, int fileline)
void SZ_Clear (sizebuf_t *buf)
{
if(buf == NULL) Sys_Error("SZ_Clear: sizebuf == NULL (called at %s:%i)\n", filename, fileline );
if(buf->overflowed) MsgWarn("SZ_Clear: clearing buffer was overflowed\n");
buf->cursize = 0;
buf->overflowed = false;
}
void *_SZ_GetSpace (sizebuf_t *buf, int length, const char *filename, int fileline)
void *SZ_GetSpace (sizebuf_t *buf, int length)
{
void *data;
if (buf->cursize + length > buf->maxsize)
{
if (length > buf->maxsize)
Sys_Error("SZ_GetSpace: buf->cursize[%d] + length[%d] > buf->maxsize[%d](called at %s:%i)\n", buf->cursize, length, buf->maxsize, filename, fileline );
Com_Error (ERR_DROP, "SZ_GetSpace: %i is > full buffer size", length);
Msg ("SZ_GetSpace: overflow [cursize %d maxsize %d](called at %s:%i)\n", buf->cursize + length, buf->maxsize, filename, fileline );
Msg ("SZ_GetSpace: overflow [cursize %d maxsize %d]\n", buf->cursize + length, buf->maxsize );
SZ_Clear (buf);
buf->overflowed = true;
}
@ -576,20 +568,20 @@ void *_SZ_GetSpace (sizebuf_t *buf, int length, const char *filename, int fileli
return data;
}
void _SZ_Write (sizebuf_t *buf, void *data, int length, const char *filename, int fileline)
void SZ_Write (sizebuf_t *buf, void *data, int length)
{
pi->Mem.Copy(_SZ_GetSpace(buf, length, filename, fileline), data, length, filename, fileline);
Mem_Copy(SZ_GetSpace(buf, length), data, length);
}
void _SZ_Print (sizebuf_t *buf, char *data, const char *filename, int fileline)
void SZ_Print (sizebuf_t *buf, char *data)
{
int len;
len = strlen(data) + 1;
if (buf->cursize)
{
if (buf->data[buf->cursize - 1]) pi->Mem.Copy((byte *)_SZ_GetSpace(buf, len, filename, fileline), data, len, filename, fileline); // no trailing 0
else pi->Mem.Copy((byte *)_SZ_GetSpace(buf, len - 1, filename, fileline) - 1, data, len, filename, fileline); // write over trailing 0
if (buf->data[buf->cursize - 1]) Mem_Copy ((byte *)SZ_GetSpace(buf, len),data,len); //no trailing 0
else Mem_Copy ((byte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0
}
else pi->Mem.Copy((byte *)_SZ_GetSpace(buf, len, filename, fileline), data, len, filename, fileline);
else Mem_Copy ((byte *)SZ_GetSpace(buf, len),data,len);
}

View File

@ -367,9 +367,12 @@ bool NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message)
continue;
}
if (host.type == HOST_DEDICATED) // let dedicated servers continue after errors
Msg ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(*net_from));
else Com_Error (ERR_DROP, "NET_GetPacket: %s from %s", NET_ErrorString(), NET_AdrToString(*net_from));
if (dedicated->value) // let dedicated servers continue after errors
Msg ("NET_GetPacket: %s from %s\n", NET_ErrorString(),
NET_AdrToString(*net_from));
else
Com_Error (ERR_DROP, "NET_GetPacket: %s from %s",
NET_ErrorString(), NET_AdrToString(*net_from));
continue;
}
@ -441,9 +444,10 @@ void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to)
if ((err == WSAEADDRNOTAVAIL) && ((to.type == NA_BROADCAST) || (to.type == NA_BROADCAST_IPX)))
return;
if (host.type == HOST_DEDICATED) // let dedicated servers continue after errors
if (dedicated->value) // let dedicated servers continue after errors
{
Msg ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(), NET_AdrToString (to));
Msg ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(),
NET_AdrToString (to));
}
else
{
@ -529,10 +533,13 @@ NET_OpenIP
void NET_OpenIP (void)
{
cvar_t *ip;
int port;
int port;
int dedicated;
ip = Cvar_Get ("ip", "localhost", CVAR_NOSET);
dedicated = Cvar_VariableValue ("dedicated");
if (!ip_sockets[NS_SERVER])
{
port = Cvar_Get("ip_hostport", "0", CVAR_NOSET)->value;
@ -545,13 +552,12 @@ void NET_OpenIP (void)
}
}
ip_sockets[NS_SERVER] = NET_IPSocket (ip->string, port);
if (!ip_sockets[NS_SERVER] && host.type == HOST_DEDICATED)
Sys_Error("Couldn't allocate dedicated server IP port");
if (!ip_sockets[NS_SERVER] && dedicated) Sys_Error("Couldn't allocate dedicated server IP port");
}
// dedicated servers don't need client ports
if (host.type == HOST_DEDICATED) return;
if (dedicated) return;
if (!ip_sockets[NS_CLIENT])
{
@ -630,6 +636,9 @@ NET_OpenIPX
void NET_OpenIPX (void)
{
int port;
int dedicated;
dedicated = Cvar_VariableValue ("dedicated");
if (!ipx_sockets[NS_SERVER])
{
@ -646,7 +655,8 @@ void NET_OpenIPX (void)
}
// dedicated servers don't need client ports
if (host.type == HOST_DEDICATED) return;
if (dedicated)
return;
if (!ipx_sockets[NS_CLIENT])
{
@ -671,7 +681,7 @@ NET_Config
A single player game will only use the loopback code
====================
*/
void NET_Config (bool multiplayer)
void NET_Config (bool multiplayer)
{
int i;
static bool old_config;
@ -709,26 +719,27 @@ void NET_Config (bool multiplayer)
// sleeps msec or until net socket is ready
void NET_Sleep(int msec)
{
struct timeval timeout;
fd_set fdset;
int i = 0;
struct timeval timeout;
fd_set fdset;
extern cvar_t *dedicated;
int i;
if (!dedicated || !dedicated->value)
return; // we're not a server, just run full speed
// we're not a server, just run full speed
if (host.type == HOST_NORMAL) return;
FD_ZERO(&fdset);
if (ip_sockets[NS_SERVER])
{
i = 0;
if (ip_sockets[NS_SERVER]) {
FD_SET(ip_sockets[NS_SERVER], &fdset); // network socket
i = ip_sockets[NS_SERVER];
}
if (ipx_sockets[NS_SERVER])
{
if (ipx_sockets[NS_SERVER]) {
FD_SET(ipx_sockets[NS_SERVER], &fdset); // network socket
if (ipx_sockets[NS_SERVER] > i) i = ipx_sockets[NS_SERVER];
if (ipx_sockets[NS_SERVER] > i)
i = ipx_sockets[NS_SERVER];
}
timeout.tv_sec = msec/1000;
timeout.tv_usec = (msec%1000) * 1000;
timeout.tv_usec = (msec%1000)*1000;
select(i+1, &fdset, NULL, NULL, &timeout);
}

View File

@ -312,7 +312,7 @@ void PM_Friction (void)
{
friction = pm_friction;
control = speed < pm_stopspeed ? pm_stopspeed : speed;
drop += control*friction * pml.frametime;
drop += control*friction*pml.frametime;
}
// apply water friction
@ -1083,7 +1083,7 @@ void PM_ClampAngles (void)
else if (pm->viewangles[PITCH] < 271 && pm->viewangles[PITCH] >= 180)
pm->viewangles[PITCH] = 271;
}
AngleVectorsRight (pm->viewangles, pml.forward, pml.right, pml.up);
AngleVectors (pm->viewangles, pml.forward, pml.right, pml.up);
}
/*
@ -1173,8 +1173,7 @@ void Pmove (pmove_t *pmove)
// teleport pause stays exactly in place
}
else if (pm->s.pm_flags & PMF_TIME_WATERJUMP)
{
// waterjump has no control, but falls
{ // waterjump has no control, but falls
pml.velocity[2] -= pm->s.gravity * pml.frametime;
if (pml.velocity[2] < 0)
{ // cancel as soon as we are falling down again
@ -1199,7 +1198,7 @@ void Pmove (pmove_t *pmove)
angles[PITCH] = angles[PITCH] - 360;
angles[PITCH] /= 3;
AngleVectorsRight (angles, pml.forward, pml.right, pml.up);
AngleVectors (angles, pml.forward, pml.right, pml.up);
PM_AirMove ();
}
}

View File

@ -116,13 +116,17 @@ void Field_Draw( menufield_s *f )
else
offset = f->cursor;
if ((( int )( cls.realtime * 4.0f)) & 1 )
if ( ( ( int ) ( Sys_Milliseconds() / 250 ) ) & 1 )
{
Draw_Char( f->generic.x + f->generic.parent->x + ( offset + 2 ) * 8 + 8, f->generic.y + f->generic.parent->y, 11 );
Draw_Char( f->generic.x + f->generic.parent->x + ( offset + 2 ) * 8 + 8,
f->generic.y + f->generic.parent->y,
11 );
}
else
{
Draw_Char( f->generic.x + f->generic.parent->x + ( offset + 2 ) * 8 + 8, f->generic.y + f->generic.parent->y, ' ' );
Draw_Char( f->generic.x + f->generic.parent->x + ( offset + 2 ) * 8 + 8,
f->generic.y + f->generic.parent->y,
' ' );
}
}
}
@ -385,11 +389,11 @@ void Menu_Draw( menuframework_s *menu )
{
if ( item->flags & QMF_LEFT_JUSTIFY )
{
Draw_Char( menu->x + item->x - 24 + item->cursor_offset, menu->y + item->y, 12 + ((int)(cls.realtime * 5.0f) & 1 ));
Draw_Char( menu->x + item->x - 24 + item->cursor_offset, menu->y + item->y, 12 + ( ( int ) ( Sys_Milliseconds()/250 ) & 1 ) );
}
else
{
Draw_Char( menu->x + item->cursor_offset, menu->y + item->y, 12 + ((int)(cls.realtime * 5.0f) & 1 ));
Draw_Char( menu->x + item->cursor_offset, menu->y + item->y, 12 + ( ( int ) ( Sys_Milliseconds()/250 ) & 1 ) );
}
}

View File

@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MT /W3 /GX /O2 /Ob0 /I "./" /I "prvm" /I "common" /I "server" /I "client" /I "../public" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /Ob0 /I "./" /I "prvm" /I "common" /I "server" /I "client" /I "../public" /I "../platform/formats" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
@ -80,7 +80,7 @@ SOURCE="$(InputPath)"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MTd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "prvm" /I "common" /I "server" /I "client" /I "../public" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /FD /c
# ADD CPP /nologo /MTd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "prvm" /I "common" /I "server" /I "client" /I "../public" /I "../platform/formats" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
@ -91,7 +91,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 gdi32.lib winmm.lib kernel32.lib user32.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 winmm.lib wsock32.lib kernel32.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# SUBTRACT LINK32 /incremental:no /map /nodefaultlib
# Begin Custom Build
TargetDir=\XASH3D\src_main\!source\temp\engine\!debug
@ -126,10 +126,6 @@ SOURCE=.\client\cl_fx.c
# End Source File
# Begin Source File
SOURCE=.\client\cl_game.c
# End Source File
# Begin Source File
SOURCE=.\client\cl_input.c
# End Source File
# Begin Source File
@ -278,6 +274,10 @@ SOURCE=.\server\sv_send.c
# End Source File
# Begin Source File
SOURCE=.\server\sv_spawn.c
# End Source File
# Begin Source File
SOURCE=.\server\sv_studio.c
# End Source File
# Begin Source File
@ -300,18 +300,6 @@ SOURCE=.\vid_dll.c
SOURCE=.\vid_menu.c
# End Source File
# Begin Source File
SOURCE=.\prvm\vm_cmds.c
# End Source File
# Begin Source File
SOURCE=.\prvm\vm_edict.c
# End Source File
# Begin Source File
SOURCE=.\prvm\vm_exec.c
# End Source File
# End Group
# Begin Group "Header Files"
@ -350,10 +338,6 @@ SOURCE=.\common\cvar.h
# End Source File
# Begin Source File
SOURCE=.\prvm\edict.h
# End Source File
# Begin Source File
SOURCE=.\engine.h
# End Source File
# Begin Source File
@ -370,14 +354,6 @@ SOURCE=..\public\platform.h
# End Source File
# Begin Source File
SOURCE=.\prvm\progdefs.h
# End Source File
# Begin Source File
SOURCE=.\prvm\progsvm.h
# End Source File
# Begin Source File
SOURCE=..\public\qfiles.h
# End Source File
# Begin Source File
@ -404,10 +380,6 @@ SOURCE=.\sound.h
SOURCE=.\common\vid.h
# End Source File
# Begin Source File
SOURCE=.\prvm\vm_cmds.h
# End Source File
# End Group
# End Target
# End Project

View File

@ -21,7 +21,6 @@
#include "basemath.h"
#include "qfiles.h"
#include <ref_system.h>
#include "vprogs.h"
#include "bspmodel.h"
#include "const.h"
#include "common.h"
@ -32,8 +31,6 @@ extern platform_exp_t *pi;
extern byte *zonepool;
extern jmp_buf abortframe;
extern int host_debug;
typedef enum
{
HOST_INIT, // initalize operations
@ -74,6 +71,8 @@ typedef struct host_parm_s
extern host_parm_t host;
int Sys_Milliseconds (void);
bool _GetParmFromCmdLine( char *parm, char *out, size_t size );
#define GetParmFromCmdLine( parm, out ) _GetParmFromCmdLine( parm, out, sizeof(out))
@ -117,7 +116,6 @@ filesystem manager
#define FS_FileBase( x, y ) pi->Fs.FileBase( x, y )
#define FS_Find( x ) pi->Fs.Search( x, false )
#define FS_Printf pi->Fs.Printf
#define FS_Print pi->Fs.Print
#define FS_Seek pi->Fs.Seek
#define FS_Tell pi->Fs.Tell
#define FS_Gets pi->Fs.Gets
@ -170,10 +168,4 @@ void Host_Init ( char *funcname, int argc, char **argv );
void Host_Main ( void );
void Host_Free ( void );
//
// in_win.c
//
extern int mouse_x, mouse_y, old_mouse_x, old_mouse_y, mx_accum, my_accum;
#endif//ENGINE_H

View File

@ -1,89 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: engine - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\Temp\RSP89.tmp" with contents
[
/nologo /MTd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "prvm" /I "common" /I "server" /I "client" /I "../public" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\engine\!debug/" /Fo"..\temp\engine\!debug/" /Fd"..\temp\engine\!debug/" /FD /c
"D:\XASH3D\src_main\!source\engine\server\sv_user.c"
]
Creating command line "cl.exe @C:\Temp\RSP89.tmp"
Creating temporary file "C:\Temp\RSP8A.tmp" with contents
[
gdi32.lib winmm.lib kernel32.lib user32.lib wsock32.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..\temp\engine\!debug/engine.pdb" /debug /machine:I386 /out:"..\temp\engine\!debug/engine.dll" /implib:"..\temp\engine\!debug/engine.lib" /pdbtype:sept
"\XASH3D\src_main\!source\temp\engine\!debug\cl_cin.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cl_ents.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cl_fx.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cl_game.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cl_input.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cl_inv.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cl_main.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cl_newfx.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cl_parse.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cl_pred.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cl_scrn.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cl_tent.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cl_view.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cmd.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cmodel.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\common.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\console.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\crc.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\cvar.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\host.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\in_win.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\keys.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\md4.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\menu.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\net_chan.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\net_msg.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\net_wins.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\pmove.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\qmenu.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\snd_dma.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\snd_mem.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\snd_mix.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\snd_win.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\sv_ccmds.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\sv_ents.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\sv_game.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\sv_init.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\sv_main.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\sv_phys.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\sv_save.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\sv_send.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\sv_studio.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\sv_user.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\sv_world.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\system.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\vid_dll.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\vid_menu.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\vm_cmds.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\vm_edict.obj"
"\XASH3D\src_main\!source\temp\engine\!debug\vm_exec.obj"
]
Creating command line "link.exe @C:\Temp\RSP8A.tmp"
Creating temporary file "C:\Temp\RSP8B.bat" with contents
[
@echo off
copy \XASH3D\src_main\!source\temp\engine\!debug\engine.dll "D:\Xash3D\bin\engine.dll"
]
Creating command line "C:\Temp\RSP8B.bat"
Compiling...
sv_user.c
Linking...
<h3>Output Window</h3>
Performing Custom Build Step on \XASH3D\src_main\!source\temp\engine\!debug\engine.dll
‘ª®¯¨à®¢ ­® ä ©«®¢: 1.
<h3>Results</h3>
engine.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -7,15 +7,14 @@
#include <windows.h>
#include <dsound.h>
#include "engine.h"
#include "progsvm.h"
platform_exp_t *pi; // fundamental callbacks
platform_exp_t *pi; // fundamental callbacks
host_parm_t host; // host parms
byte *zonepool;
int ActiveApp;
// host params
bool Minimized;
extern uint sys_msg_time;
void Key_Init (void);
void SCR_EndLoadingPlaque (void);
@ -91,11 +90,10 @@ void Host_Init (char *funcname, int argc, char **argv)
MsgDev(D_INFO, "------- Loading bin/engine.dll [%g] -------\n", ENGINE_VERSION );
Cbuf_Init();
Cmd_Init();
Cvar_Init();
Key_Init();
PRVM_Init();
Cbuf_Init ();
Cmd_Init ();
Cvar_Init ();
Key_Init ();
// we need to add the early commands twice, because
// a basedir or cddir needs to be set before execing
@ -113,17 +111,18 @@ void Host_Init (char *funcname, int argc, char **argv)
Cmd_AddCommand ("error", Com_Error_f);
host_speeds = Cvar_Get ("host_speeds", "0", 0);
log_stats = Cvar_Get ("log_stats", "0", 0);
developer = Cvar_Get ("developer", "0", 0);
timescale = Cvar_Get ("timescale", "1", 0);
fixedtime = Cvar_Get ("fixedtime", "0", 0);
showtrace = Cvar_Get ("showtrace", "0", 0);
if(host.type == HOST_DEDICATED) dedicated = Cvar_Get ("dedicated", "1", CVAR_NOSET);
else dedicated = Cvar_Get ("dedicated", "0", CVAR_NOSET);
s = va("%4.2f %s %s %s", VERSION, "x86", __DATE__, BUILDSTRING);
Cvar_Get ("version", s, CVAR_SERVERINFO|CVAR_NOSET);
if (host.type == HOST_DEDICATED)
{
Cmd_AddCommand ("quit", Com_Quit);
}
if (dedicated->value) Cmd_AddCommand ("quit", Com_Quit);
Sys_Init();
@ -134,10 +133,10 @@ void Host_Init (char *funcname, int argc, char **argv)
CL_Init();
// add + commands from command line
if (!Cbuf_AddLateCommands())
if (!Cbuf_AddLateCommands ())
{
// if the user didn't give any commands, run default action
if(host.type == HOST_NORMAL) Cbuf_AddText ("d1\n");
if (!dedicated->value) Cbuf_AddText ("d1\n");
else Cbuf_AddText ("dedicated_start\n");
Cbuf_Execute ();
}
@ -156,9 +155,34 @@ Host_Frame
void Host_Frame (double time)
{
char *s;
static double time_before, time_between, time_after;
if (setjmp (abortframe) ) return; // an ERR_DROP was thrown
if ( log_stats->modified )
{
log_stats->modified = false;
if ( log_stats->value )
{
if ( log_stats_file )
{
FS_Close( log_stats_file );
log_stats_file = 0;
}
log_stats_file = FS_Open( "stats.log", "w" );
if ( log_stats_file )
FS_Printf( log_stats_file, "entities,dlights,parts,frame time\n" );
}
else
{
if ( log_stats_file )
{
FS_Close( log_stats_file );
log_stats_file = 0;
}
}
}
if (showtrace->value)
{
extern int c_traces, c_brush_traces;
@ -173,14 +197,32 @@ void Host_Frame (double time)
do
{
s = Sys_ConsoleInput ();
if(s) Cbuf_AddText (va("%s\n",s));
if (s) Cbuf_AddText (va("%s\n",s));
} while (s);
Cbuf_Execute ();
if (host_speeds->value) time_before = Sys_DoubleTime();
SV_Frame (time);
if (host_speeds->value) time_between = Sys_DoubleTime();
CL_Frame (time);
host.framecount++;
if (host_speeds->value) time_after = Sys_DoubleTime();
if (host_speeds->value)
{
double all, sv, gm, cl, rf;
all = time_after - time_before;
sv = time_between - time_before;
cl = time_after - time_between;
gm = time_after_game - time_before_game;
rf = time_after_ref - time_before_ref;
sv -= gm;
cl -= rf;
Msg ("all:%.3f sv:%.3f gm:%.3f cl:%.3f rf:%.3f\n", all, sv, gm, cl, rf);
}
}
/*
@ -190,38 +232,36 @@ Host_Main
*/
void Host_Main( void )
{
MSG msg;
static double oldtime, newtime;
MSG msg;
int time, oldtime, newtime;
host.state = HOST_FRAME;
oldtime = Sys_DoubleTime(); //first call
oldtime = Sys_Milliseconds ();
// main window message loop
while (host.type != HOST_OFFLINE)
while (1)
{
// if at a full screen console, don't update unless needed
if (host.type == HOST_DEDICATED )
if (Minimized || (dedicated && dedicated->value) )
{
Sleep( 1 );
Sleep (1);
}
else if(host.state == HOST_SLEEP) Sleep( 100 );
while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!GetMessage (&msg, NULL, 0, 0)) Com_Quit ();
host.sv_timer = msg.time;
sys_msg_time = msg.time;
TranslateMessage (&msg);
DispatchMessage (&msg);
}
do
{
newtime = Sys_DoubleTime();
host.realtime = newtime - oldtime;
newtime = Sys_Milliseconds ();
time = newtime - oldtime;
} while (time < 1);
} while (host.realtime < 0.001);
_controlfp( _PC_24, _MCW_PC );
Host_Frame (time);
Host_Frame (host.realtime);
oldtime = newtime;
}
}
@ -234,9 +274,6 @@ Host_Shutdown
*/
void Host_Free (void)
{
host.state = HOST_SHUTDOWN;
SV_Shutdown ("Server shutdown\n", false);
CL_Shutdown ();
Host_FreePlatform();
}

View File

@ -24,7 +24,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "engine.h"
#include "./client/client.h"
extern unsigned sys_msg_time;
extern HWND cl_hwnd;
extern bool ActiveApp, Minimized;
// joystick defines and variables
// where should defines be moved?
@ -249,13 +251,13 @@ void IN_MouseEvent (int mstate)
if ( (mstate & (1<<i)) &&
!(mouse_oldbuttonstate & (1<<i)) )
{
Key_Event (K_MOUSE1 + i, true, host.sv_timer);
Key_Event (K_MOUSE1 + i, true, sys_msg_time);
}
if ( !(mstate & (1<<i)) &&
(mouse_oldbuttonstate & (1<<i)) )
{
Key_Event (K_MOUSE1 + i, false, host.sv_timer);
Key_Event (K_MOUSE1 + i, false, sys_msg_time);
}
}
@ -449,7 +451,7 @@ void IN_Move (usercmd_t *cmd)
{
IN_MouseMove (cmd);
if (host.state == HOST_FRAME)
if (ActiveApp)
IN_JoyMove (cmd);
}

View File

@ -1,70 +0,0 @@
/*
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef PROGS_H
#define PROGS_H
#define MAX_ENT_CLUSTERS 16
#define SVF_NOCLIENT 0x00000001 // don't send entity to clients, even if it has effects
#define SVF_DEADMONSTER 0x00000002 // treat as CONTENTS_DEADMONSTER for collision
#define SVF_MONSTER 0x00000004 // treat as CONTENTS_MONSTER for collision
typedef struct link_s
{
struct link_s *prev, *next;
int entnum; // get edict by number
} link_t;
typedef struct server_edict_s
{
// these fields must match with edict_state_t pos. don't move it!
bool free;
float freetime;
bool move;
int linkcount;
link_t area; // linked to a division node or leaf
int num_clusters; // if -1, use headnode instead
int clusternums[MAX_ENT_CLUSTERS];
int headnode; // unused if num_clusters != -1
int areanum, areanum2;
int flags; // SVF_NOCLIENT, SVF_DEADMONSTER, SVF_MONSTER, etc
vec3_t mins, maxs;
vec3_t absmin, absmax, size;
vec3_t moved_from; // used to keep track of where objects were before they were
vec3_t moved_fromangles; // moved, in case they need to be moved back
// trace info
solid_t solid;
int clipmask;
struct server_edict_s *owner;
entity_state_t state;
player_state_t *client;
} server_edict_t;
#endif

View File

@ -1,139 +0,0 @@
#ifndef PROGDEFS_H
#define PROGDEFS_H
typedef struct globalvars_s
{
int pad[28];
int self;
int other;
int world;
float time;
float frametime;
float force_retouch;
string_t mapname;
float deathmatch;
float coop;
float teamplay;
float serverflags;
float total_secrets;
float total_monsters;
float found_secrets;
float killed_monsters;
float parm[16];
vec3_t v_forward;
vec3_t v_up;
vec3_t v_right;
float trace_allsolid;
float trace_startsolid;
float trace_fraction;
vec3_t trace_endpos;
vec3_t trace_plane_normal;
float trace_plane_dist;
int trace_ent;
float trace_inopen;
float trace_inwater;
int msg_entity;
// game_export_s
func_t main; // Init
func_t StartFrame; // RunFrame
func_t EndFrame; // EndFrame
func_t PlayerPreThink; // ClientThink
func_t PlayerPostThink; // ClientThink
func_t ClientKill; // ???
func_t ClientConnect; // ClientConnect
func_t PutClientInServer; // ClientBegin
func_t ClientDisconnect; // ClientDisconnect
func_t SetNewParms; // ???
func_t SetChangeParms; // ???
} globalvars_t;
typedef struct entvars_s
{
float modelindex;
vec3_t absmin;
vec3_t absmax;
float ltime;
float movetype;
float solid;
vec3_t origin;
vec3_t oldorigin;
vec3_t velocity;
vec3_t angles;
vec3_t avelocity;
vec3_t punchangle;
string_t classname;
string_t model;
float frame;
float skin;
float body;
float effects;
float sequence;
float renderfx;
vec3_t mins;
vec3_t maxs;
vec3_t size;
func_t touch;
func_t use;
func_t think;
func_t blocked;
float nextthink;
int groundentity;
float health;
float frags;
float weapon;
string_t weaponmodel;
float weaponframe;
float currentammo;
float ammo_shells;
float ammo_nails;
float ammo_rockets;
float ammo_cells;
float items;
float takedamage;
int chain;
float deadflag;
vec3_t view_ofs;
float button0;
float button1;
float button2;
float impulse;
float fixangle;
vec3_t v_angle;
float idealpitch;
string_t netname;
int enemy;
float flags;
float colormap;
float team;
float max_health;
float teleport_time;
float armortype;
float armorvalue;
float waterlevel;
float watertype;
float ideal_yaw;
float yaw_speed;
int aiment;
int goalentity;
float spawnflags;
string_t target;
string_t targetname;
float dmg_take;
float dmg_save;
int dmg_inflictor;
int owner;
vec3_t movedir;
string_t message;
float sounds;
string_t noise;
string_t noise1;
string_t noise2;
string_t noise3;
} entvars_t;
#define PROG_CRC_SERVER 21645
#endif//PROGDEFS_H

View File

@ -1,385 +0,0 @@
/*
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
This is a try to make the vm more generic, it is mainly based on the progs.h file.
For the license refer to progs.h.
Generic means, less as possible hard-coded links with the other parts of the engine.
This means no edict_engineprivate struct usage, etc.
The code uses void pointers instead.
*/
#ifndef PROGSVM_H
#define PROGSVM_H
#include "vprogs.h" // defs shared with qcc
#include "progdefs.h" // generated by program cdefs
#include "edict.h"
typedef struct prvm_stack_s
{
int s;
mfunction_t *f;
} prvm_stack_t;
typedef union prvm_eval_s
{
string_t string;
float _float;
float vector[3];
func_t function;
int ivector[3];
int _int;
int edict;
} prvm_eval_t;
//with this the crc isn't needed for fields.
typedef struct prvm_fieldvars_s
{
int ofs;
int type;
const char *name;
} prvm_fieldvars_t;
// AK: I dont call it engine private cause it doesnt really belongs to the engine
// it belongs to prvm.
typedef struct edict_state_s
{
bool free;
float freetime;
} edict_state_t;
struct prvm_edict_s
{
// engine-private fields (stored in dynamically resized array)
union
{
edict_state_t *ed; // vm edict state
void *vp; // generic edict
server_edict_t *sv; // server edict
} priv;
// QuakeC fields (stored in dynamically resized array)
union
{
void *vp; // generic entvars
entvars_t *sv; // server entvars
} fields;
};
#define PRVM_GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (prvm_eval_t *)((unsigned char *)ed->fields.vp + fieldoffset) : NULL)
#define PRVM_GETGLOBALFIELDVALUE(fieldoffset) (fieldoffset ? (prvm_eval_t *)((unsigned char *)prog->globals.generic + fieldoffset) : NULL)
#define PRVM_FE_CLASSNAME 8
#define PRVM_FE_CHAIN 4
#define PRVM_OP_STATE 1
#define PRVM_MAX_STACK_DEPTH 1024
#define PRVM_LOCALSTACK_SIZE 16384
#define PRVM_MAX_OPENFILES 256
#define PRVM_MAX_OPENSEARCHES 128
typedef void (*prvm_builtin_t) (void);
// [INIT] variables flagged with this token can be initialized by 'you'
// NOTE: external code has to create and free the mempools but everything else is done by prvm !
typedef struct prvm_prog_s
{
dprograms_t *progs;
mfunction_t *functions;
char *strings;
int stringssize;
ddef_t *fielddefs;
ddef_t *globaldefs;
dstatement_t *statements;
int edict_size; // in bytes
int edictareasize; // in bytes (for bound checking)
int *statement_linenums;// NULL if not available
double *statement_profile; // only incremented if prvm_statementprofiling is on
union
{
float *generic;
globalvars_t *server;
} globals;
int maxknownstrings;
int numknownstrings;
// this is updated whenever a string is removed or added
// (simple optimization of the free string search)
int firstfreeknownstring;
const char **knownstrings;
byte *knownstrings_freeable;
const char ***stringshash;
// all memory allocations related to this vm_prog (code, edicts, strings)
byte *progs_mempool; // [INIT]
prvm_builtin_t *builtins; // [INIT]
int numbuiltins; // [INIT]
int argc;
int trace;
mfunction_t *xfunction;
int xstatement;
// stacktrace writes into stack[MAX_STACK_DEPTH]
// thus increase the array, so depth wont be overwritten
prvm_stack_t stack[PRVM_MAX_STACK_DEPTH + 1];
int depth;
int localstack[PRVM_LOCALSTACK_SIZE];
int localstack_used;
word filecrc;
//============================================================================
// until this point everything also exists (with the pr_ prefix) in the old vm
file_t *openfiles[PRVM_MAX_OPENFILES];
search_t *opensearches[PRVM_MAX_OPENSEARCHES];
// copies of some vars that were former read from sv
int num_edicts;
// number of edicts for which space has been (should be) allocated
int max_edicts; // [INIT]
// used instead of the constant MAX_EDICTS
int limit_edicts; // [INIT]
// number of reserved edicts (allocated from 1)
int reserved_edicts; // [INIT]
prvm_edict_t *edicts;
void *edictsfields;
void *edictprivate;
// size of the engine private struct
int edictprivate_size; // [INIT]
// has to be updated every frame - so the vm time is up-to-date
// AK changed so time will point to the time field (if there is one) else it points to _time
// actually should be double, but qc doesnt support it
float *time;
float _time;
// allow writing to world entity fields, this is set by server init and
// cleared before first server frame
bool protect_world;
// name of the prog, e.g. "Server", "Client" or "Menu" (used for text output)
char *name; // [INIT]
// flag - used to store general flags like PRVM_GE_SELF, etc.
int flag;
char *extensionstring; // [INIT]
bool loadintoworld; // [INIT]
// used to indicate whether a prog is loaded
bool loaded;
//============================================================================
ddef_t *self; // if self != 0 then there is a global self
//============================================================================
// function pointers
void (*begin_increase_edicts)(void); // [INIT] used by PRVM_MEM_Increase_Edicts
void (*end_increase_edicts)(void); // [INIT]
void (*init_edict)(prvm_edict_t *edict); // [INIT] used by PRVM_ED_ClearEdict
void (*free_edict)(prvm_edict_t *ed); // [INIT] used by PRVM_ED_Free
void (*count_edicts)(void); // [INIT] used by PRVM_ED_Count_f
bool (*load_edict)(prvm_edict_t *ent); // [INIT] used by PRVM_ED_LoadFromFile
void (*init_cmd)(void); // [INIT] used by PRVM_InitProg
void (*reset_cmd)(void); // [INIT] used by PRVM_ResetProg
void (*error_cmd)(const char *format, ...); // [INIT]
} prvm_prog_t;
extern prvm_prog_t *prog;
enum
{
PRVM_SERVERPROG = 0,
PRVM_CLIENTPROG,
PRVM_MENUPROG,
PRVM_MAXPROGS, // must be last
};
extern prvm_prog_t prvm_prog_list[PRVM_MAXPROGS];
//============================================================================
// prvm_cmds part
extern prvm_builtin_t vm_sv_builtins[];
extern prvm_builtin_t vm_cl_builtins[];
extern prvm_builtin_t vm_m_builtins[];
extern const int vm_sv_numbuiltins;
extern const int vm_cl_numbuiltins;
extern const int vm_m_numbuiltins;
extern char * vm_sv_extensions;
extern char * vm_cl_extensions;
extern char * vm_m_extensions;
void VM_SV_Cmd_Init(void);
void VM_SV_Cmd_Reset(void);
void VM_CL_Cmd_Init(void);
void VM_CL_Cmd_Reset(void);
void VM_M_Cmd_Init(void);
void VM_M_Cmd_Reset(void);
void VM_Cmd_Init(void);
void VM_Cmd_Reset(void);
//============================================================================
void PRVM_Init (void);
void PRVM_ExecuteProgram (func_t fnum, const char *errormessage);
#define PRVM_Alloc(buffersize) _PRVM_Alloc(buffersize, __FILE__, __LINE__)
#define PRVM_Free(buffer) _PRVM_Free(buffer, __FILE__, __LINE__)
#define PRVM_FreeAll() _PRVM_FreeAll(__FILE__, __LINE__)
void *_PRVM_Alloc (size_t buffersize, const char *filename, int fileline);
void _PRVM_Free (void *buffer, const char *filename, int fileline);
void _PRVM_FreeAll (const char *filename, int fileline);
void PRVM_Profile (int maxfunctions, int mininstructions);
void PRVM_Profile_f (void);
void PRVM_PrintFunction_f (void);
void PRVM_PrintState(void);
void PRVM_CrashAll (void);
void PRVM_Crash (void);
int PRVM_ED_FindFieldOffset(const char *field);
int PRVM_ED_FindGlobalOffset(const char *global);
ddef_t *PRVM_ED_FindField (const char *name);
ddef_t *PRVM_ED_FindGlobal (const char *name);
mfunction_t *PRVM_ED_FindFunction (const char *name);
func_t PRVM_ED_FindFunctionOffset(const char *function);
void PRVM_MEM_IncreaseEdicts(void);
prvm_edict_t *PRVM_ED_Alloc (void);
void PRVM_ED_Free (prvm_edict_t *ed);
void PRVM_ED_ClearEdict (prvm_edict_t *e);
void PRVM_PrintFunctionStatements (const char *name);
void PRVM_ED_Print(prvm_edict_t *ed);
void PRVM_ED_Write (file_t *f, prvm_edict_t *ed);
const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent);
void PRVM_ED_WriteGlobals (file_t *f);
void PRVM_ED_ParseGlobals (const char *data);
void PRVM_ED_LoadFromFile (const char *data);
prvm_edict_t *PRVM_EDICT_NUM_ERROR(int n, char *filename, int fileline);
#define PRVM_EDICT_NUM(n) (((n) >= 0 && (n) < prog->max_edicts) ? prog->edicts + (n) : PRVM_EDICT_NUM_ERROR(n, __FILE__, __LINE__))
#define PRVM_EDICT_NUM_UNSIGNED(n) (((n) < prog->max_edicts) ? prog->edicts + (n) : PRVM_EDICT_NUM_ERROR(n, __FILE__, __LINE__))
#define PRVM_NUM_FOR_EDICT(e) ((int)((prvm_edict_t *)(e) - prog->edicts))
#define PRVM_NEXT_EDICT(e) ((e) + 1)
#define PRVM_EDICT_TO_PROG(e) (PRVM_NUM_FOR_EDICT(e))
#define PRVM_PROG_TO_EDICT(n) (PRVM_EDICT_NUM(n))
//============================================================================
#define PRVM_G_FLOAT(o) (prog->globals.generic[o])
#define PRVM_G_INT(o) (*(int *)&prog->globals.generic[o])
#define PRVM_G_EDICT(o) (PRVM_PROG_TO_EDICT(*(int *)&prog->globals.generic[o]))
#define PRVM_G_EDICTNUM(o) PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(o))
#define PRVM_G_VECTOR(o) (&prog->globals.generic[o])
#define PRVM_G_STRING(o) (PRVM_GetString(*(string_t *)&prog->globals.generic[o]))
//#define PRVM_G_FUNCTION(o) (*(func_t *)&prog->globals.generic[o])
// FIXME: make these go away?
#define PRVM_E_FLOAT(e,o) (((float*)e->fields.vp)[o])
#define PRVM_E_INT(e,o) (((int*)e->fields.vp)[o])
//#define PRVM_E_VECTOR(e,o) (&((float*)e->fields.vp)[o])
#define PRVM_E_STRING(e,o) (PRVM_GetString(*(string_t *)&((float*)e->fields.vp)[o]))
extern int prvm_type_size[8]; // for consistency : I think a goal of this sub-project is to
// make the new vm mostly independent from the old one, thus if it's necessary, I copy everything
void PRVM_Init_Exec(void);
void PRVM_ED_PrintEdicts_f (void);
void PRVM_ED_PrintNum (int ent);
const char *PRVM_GetString(int num);
int PRVM_SetEngineString(const char *s);
int PRVM_AllocString(size_t bufferlength, char **pointer);
void PRVM_FreeString(int num);
//============================================================================
#define PRVM_Begin
#define PRVM_End prog = 0
#define PRVM_NAME (prog->name ? prog->name : "unnamed.dat")
// helper macro to make function pointer calls easier
#define PRVM_GCALL(func) if(prog->func) prog->func
#define PRVM_ERROR prog->error_cmd
// other prog handling functions
bool PRVM_SetProgFromString(const char *str);
void PRVM_SetProg(int prognr);
/*
Initializing a vm:
Call InitProg with the num
Set up the fields marked with [INIT] in the prog struct
Load a program with LoadProgs
*/
void PRVM_InitProg(int prognr);
// LoadProgs expects to be called right after InitProg
void PRVM_LoadProgs (const char *filename, int numrequiredfunc, char **required_func, int numrequiredfields, prvm_fieldvars_t *required_field);
void PRVM_ResetProg(void);
bool PRVM_ProgLoaded(int prognr);
int PRVM_GetProgNr(void);
void VM_Warning(const char *fmt, ...);
void VM_Error(const char *fmt, ...);
// TODO: fill in the params
//void PRVM_Create();
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,343 +0,0 @@
// AK
// Basically every vm builtin cmd should be in here.
// All 3 builtin and extension lists can be found here
// cause large (I think they will) parts are from pr_cmds the same copyright like in pr_cmds
// also applies here
/*
============================================================================
common cmd list:
=================
checkextension(string)
error(...[string])
objerror(...[string)
print(...[strings])
bprint(...[string])
sprint(float clientnum,...[string])
centerprint(...[string])
vector normalize(vector)
float vlen(vector)
float vectoyaw(vector)
vector vectoangles(vector)
float random()
cmd(string)
float cvar (string)
cvar_set (string,string)
dprint(...[string])
string ftos(float)
float fabs(float)
string vtos(vector)
string etos(entity)
float stof(...[string])
entity spawn()
remove(entity e)
entity find(entity start, .string field, string match)
entity findfloat(entity start, .float field, float match)
entity findentity(entity start, .entity field, entity match)
entity findchain(.string field, string match)
entity findchainfloat(.string field, float match)
entity findchainentity(.string field, entity match)
string precache_file(string)
string precache_sound (string sample)
coredump()
traceon()
traceoff()
eprint(entity e)
float rint(float)
float floor(float)
float ceil(float)
entity nextent(entity)
float sin(float)
float cos(float)
float sqrt(float)
vector randomvec()
float registercvar (string name, string value, float flags)
float min(float a, float b, ...[float])
float max(float a, float b, ...[float])
float bound(float min, float value, float max)
float pow(float a, float b)
copyentity(entity src, entity dst)
float fopen(string filename, float mode)
fclose(float fhandle)
string fgets(float fhandle)
fputs(float fhandle, string s)
float strlen(string s)
string strcat(string,string,...[string])
string substring(string s, float start, float length)
vector stov(string s)
string strzone(string s)
strunzone(string s)
float tokenize(string s)
string argv(float n)
float isserver()
float clientcount()
float clientstate()
clientcommand(float client, string s) (for client and menu)
changelevel(string map)
localsound(string sample)
vector getmousepos()
float gettime()
loadfromdata(string data)
loadfromfile(string file)
parseentitydata(entity ent, string data)
float mod(float val, float m)
const string cvar_string (string)
crash()
stackdump()
float search_begin(string pattern, float caseinsensitive, float quiet)
void search_end(float handle)
float search_getsize(float handle)
string search_getfilename(float handle, float num)
string chr(float ascii)
float itof(intt ent)
entity ftoe(float num)
-------will be removed soon----------
float altstr_count(string)
string altstr_prepare(string)
string altstr_get(string,float)
string altstr_set(string altstr, float num, string set)
string altstr_ins(string altstr, float num, string set)
--------------------------------------
entity findflags(entity start, .float field, float match)
entity findchainflags(.float field, float match)
perhaps only : Menu : WriteMsg
===============================
WriteByte(float data, float dest, float desto)
WriteChar(float data, float dest, float desto)
WriteShort(float data, float dest, float desto)
WriteLong(float data, float dest, float desto)
WriteAngle(float data, float dest, float desto)
WriteCoord(float data, float dest, float desto)
WriteString(string data, float dest, float desto)
WriteEntity(entity data, float dest, float desto)
Client & Menu : draw functions & video functions
===================================================
float iscachedpic(string pic)
string precache_pic(string pic)
freepic(string s)
float drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag)
float drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag)
float drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag)
float drawfill(vector position, vector size, vector rgb, float alpha, float flag)
==============================================================================
menu cmd list:
===============
setkeydest(float dest)
float getkeydest()
setmousetarget(float target)
float getmousetarget()
callfunction(...,string function_name)
writetofile(float fhandle, entity ent)
float isfunction(string function_name)
vector getresolution(float number)
string keynumtostring(float keynum)
string findkeysforcommand(string command)
float getserverliststat(float type)
string getserverliststring(float fld, float hostnr)
float stringtokeynum(string key)
resetserverlistmasks()
setserverlistmaskstring(float mask, float fld, string str)
setserverlistmasknumber(float mask, float fld, float num, float op)
resortserverlist()
setserverlistsort(float field, float descending)
refreshserverlist()
float getserverlistnumber(float fld, float hostnr)
float getserverlistindexforkey(string key)
addwantedserverlistkey(string key)
*/
#include "engine.h"
#include "server.h"
#include "progdefs.h"
#include "progsvm.h"
//============================================================================
// nice helper macros
#ifndef VM_NOPARMCHECK
#define VM_SAFEPARMCOUNT(p,f) if(prog->argc != p) PRVM_ERROR(#f " wrong parameter count (" #p " expected ) !")
#else
#define VM_SAFEPARMCOUNT(p,f)
#endif
#define VM_RETURN_EDICT(e) (((int *)prog->globals.generic)[OFS_RETURN] = PRVM_EDICT_TO_PROG(e))
#define e10 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
#define e100 e10,e10,e10,e10,e10,e10,e10,e10,e10,e10
#define e1000 e100,e100,e100,e100,e100,e100,e100,e100,e100,e100
#define VM_STRINGTEMP_BUFFERS 16
#define VM_STRINGTEMP_LENGTH MAX_INPUTLINE
// builtins and other general functions
char *VM_GetTempString(void);
void VM_CheckEmptyString (const char *s);
void VM_VarString(int first, char *out, int outlength);
void VM_checkextension (void);
void VM_error (void);
void VM_objerror (void);
void VM_print (void);
void VM_bprint (void);
void VM_sprint (void);
void VM_centerprint (void);
void VM_normalize (void);
void VM_vlen (void);
void VM_vectoyaw (void);
void VM_vectoangles (void);
void VM_random (void);
void VM_localsound(void);
void VM_break (void);
void VM_localcmd (void);
void VM_cvar (void);
void VM_cvar_string(void);
void VM_cvar_set (void);
void VM_dprint (void);
void VM_ftos (void);
void VM_fabs (void);
void VM_vtos (void);
void VM_etos (void);
void VM_stof(void);
void VM_itof(void);
void VM_ftoe(void);
void VM_spawn (void);
void VM_remove (void);
void VM_find (void);
void VM_findfloat (void);
void VM_findchain (void);
void VM_findchainfloat (void);
void VM_findflags (void);
void VM_findchainflags (void);
void VM_precache_file (void);
void VM_precache_error (void);
void VM_precache_sound (void);
void VM_coredump (void);
void VM_stackdump (void);
void VM_crash(void); // REMOVE IT
void VM_traceon (void);
void VM_traceoff (void);
void VM_eprint (void);
void VM_rint (void);
void VM_floor (void);
void VM_ceil (void);
void VM_nextent (void);
void VM_changelevel (void);
void VM_sin (void);
void VM_cos (void);
void VM_sqrt (void);
void VM_randomvec (void);
void VM_registercvar (void);
void VM_min (void);
void VM_max (void);
void VM_bound (void);
void VM_pow (void);
void VM_copyentity (void);
void VM_Files_Init(void);
void VM_Files_CloseAll(void);
void VM_fopen(void);
void VM_fclose(void);
void VM_fgets(void);
void VM_fputs(void);
// used by M_WriteToFile
// should be only called from a builtin
file_t *VM_GetFileHandle( int index );
void VM_strlen(void);
void VM_strcat(void);
void VM_substring(void);
void VM_stov(void);
void VM_strzone(void);
void VM_strunzone(void);
void VM_clcommand (void);
void VM_tokenize (void);
void VM_argv (void);
void VM_isserver(void);
void VM_clientcount(void);
void VM_getmousepos(void);
void VM_gettime(void);
void VM_loadfromdata(void);
void VM_parseentitydata(void);
void VM_loadfromfile(void);
void VM_modulo(void);
void VM_search_begin(void);
void VM_search_end(void);
void VM_search_getsize(void);
void VM_search_getfilename(void);
void VM_chr(void);
void VM_iscachedpic(void);
void VM_precache_pic(void);
void VM_freepic(void);
void VM_drawcharacter(void);
void VM_drawstring(void);
void VM_drawpic(void);
void VM_drawfill(void);
void VM_drawsetcliparea(void);
void VM_drawresetcliparea(void);
void VM_getimagesize(void);
void VM_vectorvectors (void);
void VM_keynumtostring (void);
void VM_stringtokeynum (void);
void VM_cin_open( void );
void VM_cin_close( void );
void VM_cin_setstate( void );
void VM_cin_getstate( void );
void VM_cin_restart( void );
void VM_drawline (void);
void VM_R_PolygonBegin (void);
void VM_R_PolygonVertex (void);
void VM_R_PolygonEnd (void);
void VM_bitshift (void);
void VM_altstr_count( void );
void VM_altstr_prepare( void );
void VM_altstr_get( void );
void VM_altstr_set( void );
void VM_altstr_ins(void);
void VM_buf_create(void);
void VM_buf_del (void);
void VM_buf_getsize (void);
void VM_buf_copy (void);
void VM_buf_sort (void);
void VM_buf_implode (void);
void VM_bufstr_get (void);
void VM_bufstr_set (void);
void VM_bufstr_add (void);
void VM_bufstr_free (void);
void VM_Cmd_Init(void);
void VM_Cmd_Reset(void);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

191
engine/server/ref_server.h Normal file
View File

@ -0,0 +1,191 @@
// game.h -- game dll information visible to server
#include "savefile.h"
#define GAME_API_VERSION 3
#define FL_TRACKTRAIN 0x00008000
// edict->svflags
#define SVF_NOCLIENT 0x00000001 // don't send entity to clients, even if it has effects
#define SVF_DEADMONSTER 0x00000002 // treat as CONTENTS_DEADMONSTER for collision
#define SVF_MONSTER 0x00000004 // treat as CONTENTS_MONSTER for collision
#define AI_NOSTEP 0x00000400
#define AI_DUCKED 0x00000800
#define AI_ACTOR 0x00040000
// edict->solid values
typedef enum
{
SOLID_NOT, // no interaction with other objects
SOLID_TRIGGER, // only touch when inside, after moving
SOLID_BBOX, // touch on edge
SOLID_BSP // bsp clip, touch on edge
} solid_t;
typedef enum {
F_INT,
F_FLOAT,
F_LSTRING, // string on disk, pointer in memory, TAG_LEVEL
F_GSTRING, // string on disk, pointer in memory, TAG_GAME
F_VECTOR,
F_ANGLEHACK,
F_EDICT, // index on disk, pointer in memory
F_ITEM, // index on disk, pointer in memory
F_CLIENT, // index on disk, pointer in memory
F_FUNCTION,
F_MMOVE,
F_IGNORE
} fieldtype_t;
typedef struct
{
char *name;
int ofs;
fieldtype_t type;
int flags;
} field_t;
typedef struct
{
char *name;
void (*spawn)(edict_t *ent);
} spawn_t;
//===============================================================
// link_t is only used for entity area links now
typedef struct link_s
{
struct link_s *prev, *next;
} link_t;
#define MAX_ENT_CLUSTERS 16
struct gclient_s
{
player_state_t ps; // communicated by server to clients
int ping;
pmove_state_t old_pmove; // for detecting out-of-pmove changes
vec3_t v_angle; // aiming direction
vec3_t oldviewangles;
vec3_t oldvelocity;
float bobtime; // so off-ground doesn't change it
// the game dll can add anything it wants after
// this point in the structure
};
typedef struct monsterinfo_s
{
int aiflags;
float jumpup;
float jumpdn;
void (*jump)(edict_t *self);
} monsterinfo_t;
struct edict_s
{
entity_state_t s;
struct gclient_s *client;
bool inuse;
int linkcount;
// FIXME: move these fields to a server private sv_entity_t
link_t area; // linked to a division node or leaf
int num_clusters; // if -1, use headnode instead
int clusternums[MAX_ENT_CLUSTERS];
int headnode; // unused if num_clusters != -1
int areanum, areanum2;
//================================
int svflags; // SVF_NOCLIENT, SVF_DEADMONSTER, SVF_MONSTER, etc
vec3_t mins, maxs;
vec3_t absmin, absmax, size;
solid_t solid;
int clipmask;
edict_t *owner;
// added for engine
char *classname;
int spawnflags;
int movetype;
int flags;
char *model;
float freetime; // sv.time when the object was freed
vec3_t velocity;
vec3_t avelocity;
vec3_t origin_offset;
int health;
float nextthink;
void (*prethink) (edict_t *ent);
void (*think)(edict_t *self);
void (*blocked)(edict_t *self, edict_t *other); //move to moveinfo?
void (*touch)(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf);
void (*use)(edict_t *self, edict_t *other, edict_t *activator);
edict_t *enemy;
edict_t *goalentity;
edict_t *movetarget;
float teleport_time;
int watertype;
int waterlevel;
int viewheight;
monsterinfo_t monsterinfo;
vec3_t movedir;
edict_t *groundentity;
int groundentity_linkcount;
int mass;
float gravity_debounce_time;
float gravity;
int takedamage;
int dmg;
vec3_t move_origin;
vec3_t move_angles;
vec3_t oldvelocity;
float speed;
float density;
float volume; // precalculated size scale
float bob; // bobbing in water amplitude
float duration;
int bobframe;
int bouncetype;
};
typedef struct game_export_s
{
edict_t *edicts;
int edict_size;
int client_size;
int num_edicts; // current number, <= max_edicts
int max_edicts;
} game_export_t;
//dll handle

View File

@ -18,16 +18,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// server.h
#ifndef SERVER_H
#define SERVER_H
//define PARANOID // speed sapping error checking
#include "progsvm.h"
#include "vm_cmds.h"
#include "ref_server.h"
//=============================================================================
typedef struct
{
gclient_t *clients; // [maxclients]
int maxclients;
int maxentities;
bool autosaved;
} game_locals_t;
#define MAX_MASTERS 8 // max recipients for heartbeat packets
typedef enum {
@ -45,18 +53,14 @@ typedef struct
{
server_state_t state; // precache commands are only valid during load
bool attractloop; // running cinematics and demos for the local system only
bool loadgame; // client begins should reuse existing entity
bool attractloop; // running cinematics and demos for the local system only
bool loadgame; // client begins should reuse existing entity
unsigned time; // always sv.framenum * 100 msec
int framenum;
float time; // always sv.framenum * 0.1 sec
float frametime;
float lastchecktime;
int framenum;
int lastcheck;
char name[MAX_QPATH]; // map name, or cinematic name
cmodel_t *models[MAX_MODELS];
struct cmodel_s *models[MAX_MODELS];
char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH];
entity_state_t baselines[MAX_EDICTS];
@ -66,20 +70,23 @@ typedef struct
sizebuf_t multicast;
byte multicast_buf[MAX_MSGLEN];
prvm_edict_t **moved_edicts;
// demo server information
file_t *demofile;
bool timedemo; // don't time sync
bool timedemo; // don't time sync
byte *mempool;
} server_t;
#define EDICT_NUM(n) ((edict_t *)((byte *)ge->edicts + ge->edict_size * (n) ))
#define NUM_FOR_EDICT(e) ( ((byte *)(e) - (byte *)ge->edicts ) / ge->edict_size)
typedef enum
{
cs_free, // can be reused for a new connection
cs_zombie, // client has been disconnected, but don't reuse
// connection for a couple seconds
cs_zombie, // client has been disconnected, but don't reuse
// connection for a couple seconds
cs_connected, // has been assigned to a client_t, but not in game yet
cs_spawned // client is fully in game
cs_spawned // client is fully in game
} client_state_t;
typedef struct
@ -92,52 +99,49 @@ typedef struct
int senttime; // for ping calculations
} client_frame_t;
#define NUM_SPAWN_PARMS 16
#define LATENCY_COUNTS 16
#define RATE_MESSAGES 10
typedef struct client_s
{
client_state_t state;
client_state_t state;
char userinfo[MAX_INFO_STRING]; // name, etc
int lastframe; // for delta compression
usercmd_t lastcmd; // for filling in big drops
int lastframe; // for delta compression
usercmd_t lastcmd; // for filling in big drops
int commandMsec; // every seconds this is reset, if user
// commands exhaust it, assume time cheating
int commandMsec; // every seconds this is reset, if user
// commands exhaust it, assume time cheating
int frame_latency[LATENCY_COUNTS];
int ping;
int frame_latency[LATENCY_COUNTS];
int ping;
int message_size[RATE_MESSAGES]; // used to rate drop packets
int rate;
int surpressCount; // number of messages rate supressed
int message_size[RATE_MESSAGES]; // used to rate drop packets
int rate;
int surpressCount; // number of messages rate supressed
float spawn_parms[NUM_SPAWN_PARMS]; // quake 1 legacy
prvm_edict_t *edict; // EDICT_NUM(clientnum+1)
edict_t *edict; // EDICT_NUM(clientnum+1)
char name[32]; // extracted from userinfo, high bits masked
int messagelevel; // for filtering printed messages
int messagelevel; // for filtering printed messages
// The datagram is written to by sound calls, prints, temp ents, etc.
// It can be harmlessly overflowed.
sizebuf_t datagram;
sizebuf_t datagram;
byte datagram_buf[MAX_MSGLEN];
client_frame_t frames[UPDATE_BACKUP]; // updates can be delta'd from here
client_frame_t frames[UPDATE_BACKUP]; // updates can be delta'd from here
byte *download; // file being downloaded
int downloadsize; // total bytes (can't use EOF because of paks)
int downloadcount; // bytes sent
int downloadsize; // total bytes (can't use EOF because of paks)
int downloadcount; // bytes sent
float lastmessage; // sv.framenum when packet was last received
float lastconnect;
int lastmessage; // sv.framenum when packet was last received
int lastconnect;
int challenge; // challenge of this user, randomly generated
int challenge; // challenge of this user, randomly generated
netchan_t netchan;
netchan_t netchan;
} client_t;
// a client can leave the server in one of four ways:
@ -164,9 +168,7 @@ typedef struct
typedef struct
{
bool initialized; // sv_init has completed
double realtime; // always increasing, no clamping, etc
int serverflags;
int realtime; // always increasing, no clamping, etc
char mapcmd[MAX_TOKEN_CHARS]; // ie: *intro.cin+base
char comment[MAX_TOKEN_CHARS]; // map name, e.t.c.
@ -174,12 +176,12 @@ typedef struct
int spawncount; // incremented each server start
// used to check late spawns
client_t *clients; // [host.maxclients];
int num_client_entities; // host.maxclients * UPDATE_BACKUP * MAX_PACKET_ENTITIES
client_t *clients; // [maxclients->value];
int num_client_entities; // maxclients->value*UPDATE_BACKUP*MAX_PACKET_ENTITIES
int next_client_entities; // next client_entity to use
entity_state_t *client_entities; // [num_client_entities]
float last_heartbeat;
int last_heartbeat;
challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting
@ -189,17 +191,6 @@ typedef struct
byte demo_multicast_buf[MAX_MSGLEN];
} server_static_t;
typedef struct
{
vec3_t boxmins, boxmaxs; // enclose the test object along entire move
float *mins, *maxs; // size of the moving object
vec3_t mins2, maxs2; // size when clipping against mosnters
float *start, *end;
trace_t trace;
prvm_edict_t *passedict;
int contentmask;
} moveclip_t;
//=============================================================================
extern netadr_t net_from;
@ -211,13 +202,17 @@ extern server_static_t svs; // persistant server info
extern server_t sv; // local server
extern cvar_t *sv_paused;
extern cvar_t *maxclients;
extern cvar_t *sv_noreload; // don't reload level state when reentering
extern cvar_t *sv_airaccelerate; // don't reload level state when reentering
extern cvar_t *sv_maxvelocity;
extern cvar_t *sv_gravity;
// development tool
extern cvar_t *sv_enforcetime;
extern client_t *sv_client;
extern prvm_edict_t *sv_player;
extern client_t *sv_client;
extern edict_t *sv_player;
extern game_locals_t game;
//===========================================================
@ -227,9 +222,9 @@ extern prvm_edict_t *sv_player;
void SV_FinalMessage (char *message, bool reconnect);
void SV_DropClient (client_t *drop);
int SV_ModelIndex (const char *name);
int SV_SoundIndex (const char *name);
int SV_ImageIndex (const char *name);
int SV_ModelIndex (char *name);
int SV_SoundIndex (char *name);
int SV_ImageIndex (char *name);
void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg);
@ -248,16 +243,15 @@ void Master_Packet (void);
//
void SV_InitGame (void);
void SV_Map (bool attractloop, char *levelstring, char *savename, bool loadgame);
void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_state_t serverstate, bool attractloop, bool loadgame);
void SV_VM_Setup(void);
void SV_VM_Begin(void);
void SV_VM_End(void);
//
// sv_phys.c
//
void SV_PrepWorldFrame (void);
void SV_Physics (void);
void SV_Physics (edict_t *ent);
void SV_DropToFloor (edict_t *ent);
void SV_CheckGround (edict_t *ent);
//
// sv_send.c
@ -271,7 +265,7 @@ void SV_FlushRedirect (int sv_redirected, char *outputbuf);
void SV_DemoCompleted (void);
void SV_SendClientMessages (void);
void SV_StartSound (vec3_t origin, prvm_edict_t *entity, int channel,
void SV_StartSound (vec3_t origin, edict_t *entity, int channel,
int soundindex, float volume,
float attenuation, float timeofs);
void SV_ClientPrintf (client_t *cl, int level, char *fmt, ...);
@ -283,8 +277,6 @@ void SV_BroadcastCommand (char *fmt, ...);
//
void SV_Nextserver (void);
void SV_ExecuteClientMessage (client_t *cl);
void SV_ApplyClientMove (void);
void SV_ClientThink (void);
//
// sv_ccmds.c
@ -297,19 +289,50 @@ void SV_Status_f (void);
void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg);
void SV_RecordDemoMessage (void);
void SV_BuildClientFrame (client_t *client);
void SV_FatPVS (vec3_t org);
void SV_Error (char *error, ...);
void SV_InitEdict (prvm_edict_t *e);
//
// sv_game.c
//
extern game_export_t *ge;
void SV_InitGameProgs (void);
void SV_ShutdownGameProgs (void);
void SV_InitEdict (edict_t *e);
// misc game funcs
void PF_error (char *fmt, ...);
void PF_Configstring (int index, char *val);
void PF_setmodel (edict_t *ent, char *name);
void PF_cprintf (edict_t *ent, int level, char *fmt, ...);
bool PF_inPVS (vec3_t p1, vec3_t p2);
void PF_StartSound (edict_t *entity, int channel, int sound_num, float volume, float attenuation, float timeofs);
//
// sv_studio.c
//
byte *SV_GetModelPtr(prvm_edict_t *ent);
byte *SV_GetModelPtr(edict_t *ent);
int SV_StudioExtractBbox( studiohdr_t *phdr, int sequence, float *mins, float *maxs );
//
// sv_spawn.c
//
void SV_SpawnEntities (char *mapname, char *entities, char *spawnpoint);
void SV_FreeEdict (edict_t *ed);
void SV_InitEdict (edict_t *e);
edict_t *SV_Spawn (void);
void SV_RunFrame (void);
void SV_ClientUserinfoChanged (edict_t *ent, char *userinfo);
bool SV_ClientConnect (edict_t *ent, char *userinfo);
void SV_ClientBegin (edict_t *ent);
void ClientThink (edict_t *ent, usercmd_t *ucmd);
void SV_ClientDisconnect (edict_t *ent);
void SV_ClientCommand (edict_t *ent);
void SV_TouchTriggers (edict_t *ent);
//
// sv_save.c
@ -327,18 +350,18 @@ void SV_ReadLevelFile( char *name );
void SV_ClearWorld (void);
// called after the world model has been loaded, before linking any entities
void SV_UnlinkEdict (prvm_edict_t *ent);
void SV_UnlinkEdict (edict_t *ent);
// call before removing an entity, and before trying to move one,
// so it doesn't clip against itself
void SV_LinkEdict (prvm_edict_t *ent);
void SV_LinkEdict (edict_t *ent);
// Needs to be called any time an entity changes origin, mins, maxs,
// or solid. Automatically unlinks if needed.
// sets ent->v.absmin and ent->v.absmax
// sets ent->leafnums[] for pvs determination even if the entity
// is not solid
int SV_AreaEdicts (vec3_t mins, vec3_t maxs, prvm_edict_t **list, int maxcount, int areatype);
int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype);
// fills in a table of edict pointers with edicts that have bounding boxes
// that intersect the given area. It is possible for a non-axial bmodel
// to be returned that doesn't actually intersect the area on an exact
@ -356,10 +379,7 @@ int SV_PointContents (vec3_t p);
// Quake 2 extends this to also check entities, to allow moving liquids
trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, prvm_edict_t *passedict, int contentmask);
trace_t SV_TraceToss (prvm_edict_t *tossent, prvm_edict_t *ignore);
trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int contentsmask);
trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask);
// mins and maxs are relative
// if the entire move stays in a solid volume, trace.allsolid will be set,
@ -368,6 +388,4 @@ trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, vec3_t start, vec3_t mins, vec3_t
// if the starting point is in a solid, it will be allowed to move out
// to an open area
// passedict is explicitly excluded from clipping checks (normally NULL)
#endif//SERVER_H
// passedict is explicitly excluded from clipping checks (normally NULL)

View File

@ -43,7 +43,7 @@ void SV_SetMaster_f (void)
int i, slot;
// only dedicated servers send heartbeats
if (host.type == HOST_NORMAL)
if (!dedicated->value)
{
Msg ("Only dedicated servers use masters.\n");
return;
@ -52,11 +52,11 @@ void SV_SetMaster_f (void)
// make sure the server is listed public
Cvar_Set ("public", "1");
for (i = 1; i < MAX_MASTERS; i++) memset (&master_adr[i], 0, sizeof(master_adr[i]));
for (i=1 ; i<MAX_MASTERS ; i++)
memset (&master_adr[i], 0, sizeof(master_adr[i]));
slot = 1; // slot 0 will always contain the id master
for (i = 1; i < Cmd_Argc(); i++)
slot = 1; // slot 0 will always contain the id master
for (i=1 ; i<Cmd_Argc() ; i++)
{
if (slot == MAX_MASTERS)
break;
@ -106,7 +106,7 @@ bool SV_SetPlayer (void)
if (s[0] >= '0' && s[0] <= '9')
{
idnum = atoi(Cmd_Argv(1));
if (idnum < 0 || idnum >= host.maxclients)
if (idnum < 0 || idnum >= maxclients->value)
{
Msg ("Bad client slot: %i\n", idnum);
return false;
@ -123,7 +123,7 @@ bool SV_SetPlayer (void)
}
// check for a name match
for (i=0,cl=svs.clients ; i < host.maxclients; i++,cl++)
for (i=0,cl=svs.clients ; i<maxclients->value; i++,cl++)
{
if (!cl->state)
continue;
@ -192,18 +192,18 @@ void SV_GameMap_f (void)
// clear all the client inuse flags before saving so that
// when the level is re-entered, the clients will spawn
// at spawn points instead of occupying body shells
savedInuse = Z_Malloc(host.maxclients * sizeof(bool));
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
savedInuse = Z_Malloc(maxclients->value * sizeof(bool));
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
{
savedInuse[i] = cl->edict->priv.sv->free;
cl->edict->priv.sv->free = true;
savedInuse[i] = cl->edict->inuse;
cl->edict->inuse = false;
}
SV_WriteSaveFile( "save0" ); //autosave
// we must restore these for clients to transfer over correctly
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
cl->edict->priv.sv->free = savedInuse[i];
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
cl->edict->inuse = savedInuse[i];
Z_Free (savedInuse);
}
}
@ -225,28 +225,23 @@ For development work
*/
void SV_Map_f (void)
{
char level_path[MAX_QPATH];
char *map;
char expanded[MAX_QPATH];
sprintf(level_path, "maps/%s", Cmd_Argv(1));
FS_DefaultExtension(level_path, ".bsp" );
if (FS_FileExists(level_path))
// if not a pcx, demo, or cinematic, check to make sure the level exists
map = Cmd_Argv(1);
if (!strstr (map, "."))
{
sv.state = ss_dead; // don't save current level when changing
SV_InitGame ();
Cvar_Set ("nextserver", ""); //reset demoloop
SCR_BeginLoadingPlaque (); // for local system
SV_BroadcastCommand ("changing\n");
SV_SendClientMessages ();
SV_SpawnServer (level_path, NULL, NULL, ss_game, false, false);
Cbuf_CopyToDefer ();
//FIXME//SV_BroadcastCommand ("reconnect\n");
strncpy (svs.mapcmd, Cmd_Argv(1), sizeof(svs.mapcmd) - 1); // archive server state
sprintf (expanded, "maps/%s.bsp", map);
if (!FS_LoadFile (expanded, NULL))
{
Msg ("Can't find %s\n", expanded);
return;
}
}
else Msg ("Can't loading %s\n", level_path);
sv.state = ss_dead; // don't save current level when changing
SV_GameMap_f ();
}
/*
@ -314,7 +309,7 @@ void SV_Savegame_f (void)
return;
}
if (host.maxclients == 1 && svs.clients[0].edict->priv.sv->client->stats[STAT_HEALTH] <= 0)
if (maxclients->value == 1 && svs.clients[0].edict->client->ps.stats[STAT_HEALTH] <= 0)
{
Msg ("\nCan't savegame while dead!\n");
return;
@ -382,11 +377,11 @@ void SV_Status_f (void)
Msg ("num score ping name lastmsg address qport \n");
Msg ("--- ----- ---- --------------- ------- --------------------- ------\n");
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
{
if (!cl->state) continue;
Msg ("%3i ", i);
Msg ("%5i ", cl->edict->priv.sv->client->stats[STAT_FRAGS]);
Msg ("%5i ", cl->edict->client->ps.stats[STAT_FRAGS]);
if (cl->state == cs_connected)
Msg ("CNCT ");
@ -403,7 +398,7 @@ void SV_Status_f (void)
for (j=0 ; j<l ; j++)
Msg (" ");
Msg ("%g ", svs.realtime - cl->lastmessage );
Msg ("%7i ", svs.realtime - cl->lastmessage );
s = NET_AdrToString ( cl->netchan.remote_address);
Msg ("%s", s);
@ -444,7 +439,7 @@ void SV_ConSay_f(void)
strcat(text, p);
for (j = 0, client = svs.clients; j < host.maxclients; j++, client++)
for (j = 0, client = svs.clients; j < maxclients->value; j++, client++)
{
if (client->state != cs_spawned)
continue;
@ -622,6 +617,22 @@ void SV_KillServer_f (void)
NET_Config ( false ); // close network sockets
}
/*
===============
SV_ServerCommand_f
Let the game dll handle a command
===============
*/
void SV_ServerCommand_f (void)
{
if (!ge)
{
Msg ("No game loaded.\n");
return;
}
}
//===========================================================
/*
@ -642,15 +653,13 @@ void SV_InitOperatorCommands (void)
Cmd_AddCommand ("gamemap", SV_GameMap_f);
Cmd_AddCommand ("setmaster", SV_SetMaster_f);
if (host.type == HOST_DEDICATED)
{
Cmd_AddCommand ("say", SV_ConSay_f);
}
if ( dedicated->value ) Cmd_AddCommand ("say", SV_ConSay_f);
Cmd_AddCommand ("serverrecord", SV_ServerRecord_f);
Cmd_AddCommand ("serverstop", SV_ServerStop_f);
Cmd_AddCommand ("save", SV_Savegame_f);
Cmd_AddCommand ("load", SV_Loadgame_f);
Cmd_AddCommand ("killserver", SV_KillServer_f);
Cmd_AddCommand ("sv", SV_ServerCommand_f);
}

View File

@ -34,11 +34,11 @@ Encode a client frame onto the network channel
// because there can be a lot of projectiles, there is a special
// network protocol for them
#define MAX_PROJECTILES 64
prvm_edict_t *projectiles[MAX_PROJECTILES];
edict_t *projectiles[MAX_PROJECTILES];
int numprojs;
cvar_t *sv_projectiles;
bool SV_AddProjectileUpdate (prvm_edict_t *ent)
bool SV_AddProjectileUpdate (edict_t *ent)
{
if (!sv_projectiles)
sv_projectiles = Cvar_Get("sv_projectiles", "1", 0);
@ -59,7 +59,7 @@ void SV_EmitProjectileUpdate (sizebuf_t *msg)
{
byte bits[16]; // [modelindex] [48 bits] xyz p y 12 12 12 8 8 [entitynum] [e2]
int n, i;
prvm_edict_t *ent;
edict_t *ent;
int x, y, z, p, yaw;
int len;
@ -157,31 +157,29 @@ void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t
}
if (newnum == oldnum)
{
// delta update from old position
{ // delta update from old position
// because the force parm is false, this will not result
// in any bytes being emited if the entity has not changed at all
// note that players are always 'newentities', this updates their oldorigin always
// and prevents warping
MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= host.maxclients);
MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= maxclients->value);
oldindex++;
newindex++;
continue;
}
if (newnum < oldnum)
{
// this is a new entity, send it from the baseline
{ // this is a new entity, send it from the baseline
MSG_WriteDeltaEntity (&sv.baselines[newnum], newent, msg, true, true);
newindex++;
continue;
}
if (newnum > oldnum)
{
// the old entity isn't present in the new message
{ // the old entity isn't present in the new message
bits = U_REMOVE;
if (oldnum >= 256) bits |= U_NUMBER16 | U_MOREBITS1;
if (oldnum >= 256)
bits |= U_NUMBER16 | U_MOREBITS1;
MSG_WriteByte (msg, bits&255 );
if (bits & 0x0000ff00)
@ -201,6 +199,11 @@ void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t
}
MSG_WriteShort (msg, 0); // end of packetentities
#if 0
if (numprojs)
SV_EmitProjectileUpdate(msg);
#endif
}
@ -228,32 +231,86 @@ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, size
else ops = &from->ps;
// determine what needs to be sent
if (ps->pmove.pm_type != ops->pmove.pm_type) pflags |= PS_M_TYPE;
if (!VectorICompare(ps->pmove.origin, ops->pmove.origin)) pflags |= PS_M_ORIGIN;
if (!VectorICompare(ps->pmove.velocity, ops->pmove.velocity)) pflags |= PS_M_VELOCITY;
if (ps->pmove.pm_time != ops->pmove.pm_time) pflags |= PS_M_TIME;
if (ps->pmove.pm_flags != ops->pmove.pm_flags) pflags |= PS_M_FLAGS;
if (ps->pmove.gravity != ops->pmove.gravity) pflags |= PS_M_GRAVITY;
if (!VectorICompare(ps->pmove.delta_angles, ops->pmove.delta_angles)) pflags |= PS_M_DELTA_ANGLES;
if (!VectorCompare(ps->viewoffset, ops->viewoffset)) pflags |= PS_VIEWOFFSET;
if (!VectorCompare(ps->viewangles, ops->viewangles)) pflags |= PS_VIEWANGLES;
if (!VectorCompare(ps->kick_angles, ops->kick_angles)) pflags |= PS_KICKANGLES;
if (!VectorCompare(ps->blend, ops->blend)) pflags |= PS_BLEND;
if (ps->fov != ops->fov) pflags |= PS_FOV;
if (ps->rdflags != ops->rdflags) pflags |= PS_RDFLAGS;
if (ps->gunframe != ops->gunframe) pflags |= PS_WEAPONFRAME;
if (ps->sequence != ops->sequence) pflags |= PS_WEAPONSEQUENCE;
if (ps->gunbody != ops->gunbody) pflags |= PS_WEAPONBODY;
if (ps->gunskin != ops->gunskin) pflags |= PS_WEAPONSKIN;
if (ps->pmove.pm_type != ops->pmove.pm_type)
pflags |= PS_M_TYPE;
if (ps->pmove.origin[0] != ops->pmove.origin[0]
|| ps->pmove.origin[1] != ops->pmove.origin[1]
|| ps->pmove.origin[2] != ops->pmove.origin[2] )
pflags |= PS_M_ORIGIN;
if (ps->pmove.velocity[0] != ops->pmove.velocity[0]
|| ps->pmove.velocity[1] != ops->pmove.velocity[1]
|| ps->pmove.velocity[2] != ops->pmove.velocity[2] )
pflags |= PS_M_VELOCITY;
if (ps->pmove.pm_time != ops->pmove.pm_time)
pflags |= PS_M_TIME;
if (ps->pmove.pm_flags != ops->pmove.pm_flags)
pflags |= PS_M_FLAGS;
if (ps->pmove.gravity != ops->pmove.gravity)
pflags |= PS_M_GRAVITY;
if (ps->pmove.delta_angles[0] != ops->pmove.delta_angles[0]
|| ps->pmove.delta_angles[1] != ops->pmove.delta_angles[1]
|| ps->pmove.delta_angles[2] != ops->pmove.delta_angles[2] )
pflags |= PS_M_DELTA_ANGLES;
if (ps->viewoffset[0] != ops->viewoffset[0]
|| ps->viewoffset[1] != ops->viewoffset[1]
|| ps->viewoffset[2] != ops->viewoffset[2] )
pflags |= PS_VIEWOFFSET;
if (ps->viewangles[0] != ops->viewangles[0]
|| ps->viewangles[1] != ops->viewangles[1]
|| ps->viewangles[2] != ops->viewangles[2] )
pflags |= PS_VIEWANGLES;
if (ps->kick_angles[0] != ops->kick_angles[0]
|| ps->kick_angles[1] != ops->kick_angles[1]
|| ps->kick_angles[2] != ops->kick_angles[2] )
pflags |= PS_KICKANGLES;
if (ps->blend[0] != ops->blend[0]
|| ps->blend[1] != ops->blend[1]
|| ps->blend[2] != ops->blend[2]
|| ps->blend[3] != ops->blend[3] )
pflags |= PS_BLEND;
if (ps->fov != ops->fov)
pflags |= PS_FOV;
if (ps->rdflags != ops->rdflags)
pflags |= PS_RDFLAGS;
if (ps->gunframe != ops->gunframe)
pflags |= PS_WEAPONFRAME;
if (ps->sequence != ops->sequence)
pflags |= PS_WEAPONSEQUENCE;
if (ps->gunbody != ops->gunbody)
pflags |= PS_WEAPONBODY;
if (ps->gunskin != ops->gunskin)
pflags |= PS_WEAPONSKIN;
pflags |= PS_WEAPONINDEX;
//
// write it
//
MSG_WriteByte (msg, svc_playerinfo);
MSG_WriteLong (msg, pflags);
//
// write the pmove_state_t
if (pflags & PS_M_TYPE) MSG_WriteByte (msg, ps->pmove.pm_type);
//
if (pflags & PS_M_TYPE)
MSG_WriteByte (msg, ps->pmove.pm_type);
if (pflags & PS_M_ORIGIN)
{
@ -269,9 +326,14 @@ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, size
MSG_WriteShort (msg, ps->pmove.velocity[2]);
}
if (pflags & PS_M_TIME) MSG_WriteByte (msg, ps->pmove.pm_time);
if (pflags & PS_M_FLAGS) MSG_WriteByte (msg, ps->pmove.pm_flags);
if (pflags & PS_M_GRAVITY) MSG_WriteShort (msg, ps->pmove.gravity);
if (pflags & PS_M_TIME)
MSG_WriteByte (msg, ps->pmove.pm_time);
if (pflags & PS_M_FLAGS)
MSG_WriteByte (msg, ps->pmove.pm_flags);
if (pflags & PS_M_GRAVITY)
MSG_WriteShort (msg, ps->pmove.gravity);
if (pflags & PS_M_DELTA_ANGLES)
{
@ -280,7 +342,9 @@ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, size
MSG_WriteShort (msg, ps->pmove.delta_angles[2]);
}
//
// write the rest of the player_state_t
//
if (pflags & PS_VIEWOFFSET)
{
MSG_WriteChar (msg, ps->viewoffset[0] * 4);
@ -302,7 +366,11 @@ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, size
MSG_WriteChar (msg, ps->kick_angles[2] * 4);
}
if (pflags & PS_WEAPONINDEX) MSG_WriteByte (msg, ps->gunindex);
if (pflags & PS_WEAPONINDEX)
{
MSG_WriteByte (msg, ps->gunindex);
}
if (pflags & PS_WEAPONFRAME)
{
MSG_WriteByte (msg, ps->gunframe);
@ -314,35 +382,42 @@ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, size
MSG_WriteChar (msg, ps->gunangles[2]*4);
}
if (pflags & PS_WEAPONSEQUENCE) MSG_WriteByte (msg, ps->sequence);
if (pflags & PS_WEAPONBODY) MSG_WriteByte (msg, ps->gunbody);
if (pflags & PS_WEAPONSKIN) MSG_WriteByte (msg, ps->gunskin);
if (pflags & PS_WEAPONSEQUENCE)
{
MSG_WriteByte (msg, ps->sequence);
}
if (pflags & PS_WEAPONBODY)
{
MSG_WriteByte (msg, ps->gunbody);
}
if (pflags & PS_WEAPONSKIN)
{
MSG_WriteByte (msg, ps->gunskin);
}
if (pflags & PS_BLEND)
{
MSG_WriteByte (msg, ps->blend[0] * 255);
MSG_WriteByte (msg, ps->blend[1] * 255);
MSG_WriteByte (msg, ps->blend[2] * 255);
MSG_WriteByte (msg, ps->blend[3] * 255);
MSG_WriteByte (msg, ps->blend[0]*255);
MSG_WriteByte (msg, ps->blend[1]*255);
MSG_WriteByte (msg, ps->blend[2]*255);
MSG_WriteByte (msg, ps->blend[3]*255);
}
if (pflags & PS_FOV) MSG_WriteByte (msg, ps->fov);
if (pflags & PS_RDFLAGS) MSG_WriteByte (msg, ps->rdflags);
if (pflags & PS_FOV)
MSG_WriteByte (msg, ps->fov);
if (pflags & PS_RDFLAGS)
MSG_WriteByte (msg, ps->rdflags);
// send stats
statbits = 0;
for (i = 0; i < MAX_STATS; i++)
{
for (i=0 ; i<MAX_STATS ; i++)
if (ps->stats[i] != ops->stats[i])
statbits |= 1<<i;
}
MSG_WriteLong (msg, statbits);
for (i = 0; i < MAX_STATS; i++)
{
if(statbits & (1<<i) )
for (i=0 ; i<MAX_STATS ; i++)
if (statbits & (1<<i) )
MSG_WriteShort (msg, ps->stats[i]);
}
}
@ -361,21 +436,18 @@ void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg)
frame = &client->frames[sv.framenum & UPDATE_MASK];
if (client->lastframe <= 0)
{
// client is asking for a retransmit
{ // client is asking for a retransmit
oldframe = NULL;
lastframe = -1;
}
else if (sv.framenum - client->lastframe >= (UPDATE_BACKUP - 3) )
{
// client hasn't gotten a good message through in a long time
{ // client hasn't gotten a good message through in a long time
// Msg ("%s: Delta request from out-of-date packet.\n", client->name);
oldframe = NULL;
lastframe = -1;
}
else
{
// we have a valid message to delta from
{ // we have a valid message to delta from
oldframe = &client->frames[client->lastframe & UPDATE_MASK];
lastframe = client->lastframe;
}
@ -465,27 +537,29 @@ copies off the playerstat and areabits.
void SV_BuildClientFrame (client_t *client)
{
int e, i;
vec3_t org;
prvm_edict_t *ent;
prvm_edict_t *clent;
vec3_t org;
edict_t *ent;
edict_t *clent;
client_frame_t *frame;
entity_state_t *state;
int l;
int clientarea, clientcluster;
int leafnum;
int c_fullsend;
byte *clientphs;
byte *bitvector;
byte *clientphs;
byte *bitvector;
clent = client->edict;
if (!clent->priv.sv->client) return;// not in game yet
if (!clent->client) return;// not in game yet
// this is the frame we are creating
frame = &client->frames[sv.framenum & UPDATE_MASK];
frame->senttime = svs.realtime; // save it for ping calc later
// find the client's PVS
for (i = 0; i < 3; i++) org[i] = clent->priv.sv->client->pmove.origin[i]*0.125 + clent->priv.sv->client->viewoffset[i];
for (i=0 ; i<3 ; i++)
org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i];
leafnum = CM_PointLeafnum (org);
clientarea = CM_LeafArea (leafnum);
@ -495,7 +569,8 @@ void SV_BuildClientFrame (client_t *client)
frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea);
// grab the current player_state_t
frame->ps = *clent->priv.sv->client;
frame->ps = clent->client->ps;
SV_FatPVS (org);
clientphs = CM_ClusterPHS (clientcluster);
@ -506,33 +581,34 @@ void SV_BuildClientFrame (client_t *client)
c_fullsend = 0;
ent = PRVM_NEXT_EDICT(prog->edicts);
for (e = 1; e < prog->num_edicts; e++, ent = PRVM_NEXT_EDICT(ent))
for (e = 1; e < ge->num_edicts ; e++)
{
ent = EDICT_NUM(e);
// ignore ents without visible models
if ((int)ent->fields.sv->flags & SVF_NOCLIENT)
if (ent->svflags & SVF_NOCLIENT)
continue;
// ignore ents without visible models unless they have an effect
if (!(int)ent->fields.sv->modelindex && !(int)ent->fields.sv->effects)
if (!ent->s.modelindex && !ent->s.effects && !ent->s.sound && !ent->s.event)
continue;
// ignore if not touching a PV leaf
if (ent != clent)
{
// check area
if (!CM_AreasConnected (clientarea, ent->priv.sv->areanum))
{
// doors can legally straddle two areas, so
if (!CM_AreasConnected (clientarea, ent->areanum))
{ // doors can legally straddle two areas, so
// we may need to check another one
if (!ent->priv.sv->areanum2 || !CM_AreasConnected (clientarea, ent->priv.sv->areanum2))
continue; // blocked by a door
if (!ent->areanum2
|| !CM_AreasConnected (clientarea, ent->areanum2))
continue; // blocked by a door
}
// beams just check one point for PHS
if ((int)ent->fields.sv->renderfx & RF_BEAM)
if (ent->s.renderfx & RF_BEAM)
{
l = ent->priv.sv->clusternums[0];
l = ent->clusternums[0];
if ( !(clientphs[l >> 3] & (1 << (l&7) )) )
continue;
}
@ -540,67 +616,55 @@ void SV_BuildClientFrame (client_t *client)
{
// FIXME: if an ent has a model and a sound, but isn't
// in the PVS, only the PHS, clear the model
if (ent->priv.sv->state.sound)
if (ent->s.sound)
{
bitvector = fatpvs; //clientphs;
}
else bitvector = fatpvs;
else
bitvector = fatpvs;
if (ent->priv.sv->num_clusters == -1)
{
// too many leafs for individual check, go by headnode
if (!CM_HeadnodeVisible (ent->priv.sv->headnode, bitvector))
if (ent->num_clusters == -1)
{ // too many leafs for individual check, go by headnode
if (!CM_HeadnodeVisible (ent->headnode, bitvector))
continue;
c_fullsend++;
}
else
{ // check individual leafs
for (i=0 ; i < ent->priv.sv->num_clusters ; i++)
for (i=0 ; i < ent->num_clusters ; i++)
{
l = ent->priv.sv->clusternums[i];
l = ent->clusternums[i];
if (bitvector[l >> 3] & (1 << (l&7) ))
break;
}
if (i == ent->priv.sv->num_clusters)
continue; // not visible
if (i == ent->num_clusters)
continue; // not visible
}
if (!(int)ent->fields.sv->modelindex)
{
// don't send sounds if they will be attenuated away
if (!ent->s.modelindex)
{ // don't send sounds if they will be attenuated away
vec3_t delta;
float len;
VectorSubtract (org, ent->fields.sv->origin, delta);
VectorSubtract (org, ent->s.origin, delta);
len = VectorLength (delta);
if (len > 400) continue;
if (len > 400)
continue;
}
}
}
// add it to the circular client_entities array
state = &svs.client_entities[svs.next_client_entities % svs.num_client_entities];
if (ent->priv.sv->state.number != e)
if (ent->s.number != e)
{
MsgWarn ("SV_BuildClientFrame: invalid ent->priv.sv->state.number %d (must be %d)\n", ent->priv.sv->state.number, e );
ent->priv.sv->state.number = e; // ptr to current entity such as entnumber
MsgWarn ("SV_BuildClientFrame: invalid ent->s.number %d\n", ent->s.number );
ent->s.number = e; // ptr to current entity such as entnumber
}
// copy state from fields
VectorCopy (ent->fields.sv->origin, ent->priv.sv->state.origin);
VectorCopy (ent->fields.sv->angles, ent->priv.sv->state.angles);
ent->priv.sv->state.frame = (int)ent->fields.sv->frame;
ent->priv.sv->state.skin = (int)ent->fields.sv->skin;
ent->priv.sv->state.body = (int)ent->fields.sv->body;
ent->priv.sv->state.sequence = (int)ent->fields.sv->sequence;
ent->priv.sv->state.effects = (int)ent->fields.sv->effects;
ent->priv.sv->state.renderfx = (int)ent->fields.sv->renderfx;
ent->priv.sv->state.solid = (int)ent->fields.sv->solid;
*state = ent->priv.sv->state;
*state = ent->s;
// don't mark players missiles as solid
if(PRVM_PROG_TO_EDICT(ent->fields.sv->owner) == client->edict) state->solid = 0;
if (ent->owner == client->edict) state->solid = 0;
svs.next_client_entities++;
frame->num_entities++;
@ -619,7 +683,7 @@ Used for recording footage for merged or assembled demos
void SV_RecordDemoMessage (void)
{
int e;
prvm_edict_t *ent;
edict_t *ent;
entity_state_t nostate;
sizebuf_t buf;
byte buf_data[32768];
@ -638,14 +702,18 @@ void SV_RecordDemoMessage (void)
MSG_WriteByte (&buf, svc_packetentities);
e = 1;
ent = PRVM_EDICT_NUM(e);
while (e < prog->num_edicts)
ent = EDICT_NUM(e);
while (e < ge->num_edicts)
{
// ignore ents without visible models unless they have an effect
if (!ent->priv.sv->free && ent->priv.sv->state.number && ((int)ent->fields.sv->modelindex || ent->fields.sv->effects || ent->priv.sv->state.sound || ent->priv.sv->state.event) && !((int)ent->fields.sv->flags & SVF_NOCLIENT))
MSG_WriteDeltaEntity (&nostate, &ent->priv.sv->state, &buf, false, true);
if (ent->inuse &&
ent->s.number &&
(ent->s.modelindex || ent->s.effects || ent->s.sound || ent->s.event) &&
!(ent->svflags & SVF_NOCLIENT))
MSG_WriteDeltaEntity (&nostate, &ent->s, &buf, false, true);
e++;
ent = PRVM_EDICT_NUM(e);
ent = EDICT_NUM(e);
}
MSG_WriteShort (&buf, 0); // end of packetentities
@ -660,4 +728,3 @@ void SV_RecordDemoMessage (void)
FS_Write (svs.demofile, buf.data, buf.cursize);
}

File diff suppressed because it is too large Load Diff

View File

@ -24,120 +24,30 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
server_static_t svs; // persistant server info
server_t sv; // local server
#define REQFIELDS (sizeof(reqfields) / sizeof(prvm_fieldvars_t))
prvm_fieldvars_t reqfields[] =
{
{0, 2, "modelindex"},
{1, 3, "absmin"},
{1, 2, "absmin_x"},
{2, 2, "absmin_y"},
{3, 2, "absmin_z"},
{4, 3, "absmax"},
{7, 2, "ltime"},
{8, 2, "movetype"},
{9, 2, "solid"},
{10, 3, "origin"},
{13, 3, "oldorigin"},
{16, 3, "velocity"},
{19, 3, "angles"},
{22, 3, "avelocity"},
{25, 3, "punchangle"},
{28, 1, "classname"},
{29, 1, "model"},
{30, 2, "frame"},
{31, 2, "skin"},
{32, 2, "body"},
{33, 2, "effects"},
{34, 2, "sequence"},
{35, 2, "renderfx"},
{36, 3, "mins"},
{39, 3, "maxs"},
{42, 3, "size"},
{45, 6, "touch"},
{46, 6, "use"},
{47, 6, "think"},
{48, 6, "blocked"},
{49, 2, "nextthink"},
{50, 4, "groundentity"},
{51, 2, "health"},
{52, 2, "frags"},
{53, 2, "weapon"},
{54, 1, "weaponmodel"},
{55, 2, "weaponframe"},
{56, 2, "currentammo"},
{57, 2, "ammo_shells"},
{58, 2, "ammo_nails"},
{59, 2, "ammo_rockets"},
{60, 2, "ammo_cells"},
{61, 2, "items"},
{62, 2, "takedamage"},
{63, 4, "chain"},
{64, 2, "deadflag"},
{65, 3, "view_ofs"},
{68, 2, "button0"},
{69, 2, "button1"},
{70, 2, "button2"},
{71, 2, "impulse"},
{72, 2, "fixangle"},
{73, 3, "v_angle"},
{76, 2, "idealpitch"},
{77, 1, "netname"},
{78, 4, "enemy"},
{79, 2, "flags"},
{80, 2, "colormap"},
{81, 2, "team"},
{82, 2, "max_health"},
{83, 2, "teleport_time"},
{84, 2, "armortype"},
{85, 2, "armorvalue"},
{86, 2, "waterlevel"},
{87, 2, "watertype"},
{88, 2, "ideal_yaw"},
{89, 2, "yaw_speed"},
{90, 4, "aiment"},
{91, 4, "goalentity"},
{92, 2, "spawnflags"},
{93, 1, "target"},
{94, 1, "targetname"},
{95, 2, "dmg_take"},
{96, 2, "dmg_save"},
{97, 4, "dmg_inflictor"},
{98, 4, "owner"},
{99, 3, "movedir"},
{102, 1, "message"},
{103, 2, "sounds"},
{104, 1, "noise"},
{105, 1, "noise1"},
{106, 1, "noise2"},
{107, 1, "noise3"}
};
/*
================
SV_FindIndex
================
*/
int SV_FindIndex (const char *name, int start, int end, bool create)
int SV_FindIndex (char *name, int start, int max, bool create)
{
int i;
if (!name || !name[0]) return 0;
for (i = 1; i < end && sv.configstrings[start + i][0]; i++)
if(!strcmp(sv.configstrings[start + i], name))
return i;
if (!create) return 0;
if (i == end)
{
MsgWarn ("SV_FindIndex: %d out range [%d - %d]\n", start, end );
if (!name || !name[0])
return 0;
}
// register new resource
strncpy (sv.configstrings[start + i], name, sizeof(sv.configstrings[i]));
for (i=1 ; i<max && sv.configstrings[start+i][0] ; i++)
if (!strcmp(sv.configstrings[start+i], name))
return i;
if (!create)
return 0;
if (i == max)
Com_Error (ERR_DROP, "*Index: overflow");
strncpy (sv.configstrings[start+i], name, sizeof(sv.configstrings[i]));
if (sv.state != ss_loading)
{
@ -145,24 +55,25 @@ int SV_FindIndex (const char *name, int start, int end, bool create)
SZ_Clear (&sv.multicast);
MSG_Begin(svc_configstring);
MSG_WriteShort (&sv.multicast, start+i);
MSG_WriteString (&sv.multicast, (char *)name);
MSG_WriteString (&sv.multicast, name);
MSG_Send(MSG_ALL_R, vec3_origin, NULL );
}
return i;
}
int SV_ModelIndex (const char *name)
int SV_ModelIndex (char *name)
{
return SV_FindIndex (name, CS_MODELS, MAX_MODELS, true);
}
int SV_SoundIndex (const char *name)
int SV_SoundIndex (char *name)
{
return SV_FindIndex (name, CS_SOUNDS, MAX_SOUNDS, true);
}
int SV_ImageIndex (const char *name)
int SV_ImageIndex (char *name)
{
return SV_FindIndex (name, CS_IMAGES, MAX_IMAGES, true);
}
@ -179,78 +90,26 @@ baseline will be transmitted
*/
void SV_CreateBaseline (void)
{
prvm_edict_t *svent;
edict_t *svent;
int entnum;
for (entnum = 1; entnum < prog->num_edicts; entnum++)
for (entnum = 1; entnum < ge->num_edicts ; entnum++)
{
svent = PRVM_EDICT_NUM(entnum);
if (svent->priv.sv->free)
{
Msg("Can't create baseline for entity [%d]\n", entnum );
svent = EDICT_NUM(entnum);
if (!svent->inuse)
continue;
}
if (!(int)svent->fields.sv->modelindex && !(int)svent->priv.sv->state.sound && !(int)svent->fields.sv->effects)
if (!svent->s.modelindex && !svent->s.sound && !svent->s.effects)
continue;
svent->s.number = entnum;
svent->priv.sv->state.number = entnum;
if (entnum > host.maxclients && !(int)svent->fields.sv->modelindex)
continue;
// create entity baseline
VectorCopy (svent->fields.sv->origin, svent->priv.sv->state.origin);
VectorCopy (svent->priv.sv->state.origin, svent->priv.sv->state.old_origin);
VectorCopy (svent->fields.sv->angles, svent->priv.sv->state.angles);
svent->priv.sv->state.frame = (int)svent->fields.sv->frame;
svent->priv.sv->state.skin = (int)svent->fields.sv->skin;
svent->priv.sv->state.body = (int)svent->fields.sv->body;
svent->priv.sv->state.sequence = (int)svent->fields.sv->sequence;
svent->priv.sv->state.effects = (int)svent->fields.sv->effects;
svent->priv.sv->state.renderfx = (int)svent->fields.sv->renderfx;
svent->priv.sv->state.solid = (int)svent->fields.sv->solid;
if (entnum > 0 && entnum <= host.maxclients)
{
svent->priv.sv->state.modelindex = SV_ModelIndex("progs/player.mdl");
}
else
{
svent->priv.sv->state.modelindex = (int)svent->fields.sv->modelindex;
}
//
// take current state as baseline
sv.baselines[entnum] = svent->priv.sv->state;
//
VectorCopy (svent->s.origin, svent->s.old_origin);
sv.baselines[entnum] = svent->s;
}
}
/*
================
SV_SaveSpawnparms
Grabs the current state of each client for saving across the
transition to another level
================
*/
void SV_SaveSpawnparms (void)
{
int i, j;
svs.serverflags = (int)prog->globals.server->serverflags;
for (i = 0, sv_client = svs.clients; i < host.maxclients; i++, sv_client++)
{
if (sv_client->state != cs_spawned)
continue;
// call the progs to get default spawn parms for the new client
prog->globals.server->self = PRVM_EDICT_TO_PROG(sv_client->edict);
PRVM_ExecuteProgram (prog->globals.server->SetChangeParms, "QC function SetChangeParms is missing");
for (j = 0; j < NUM_SPAWN_PARMS; j++)
sv_client->spawn_parms[j] = prog->globals.server->parm[j];
}
}
/*
=================
@ -259,6 +118,7 @@ SV_CheckForSavegame
*/
void SV_CheckForSavegame (char *savename )
{
int i;
char name[MAX_SYSPATH];
if (sv_noreload->value) return;
@ -275,6 +135,22 @@ void SV_CheckForSavegame (char *savename )
// get configstrings and areaportals
SV_ReadLevelFile ( savename );
if (!sv.loadgame)
{ // coming back to a level after being in a different
// level, so run it for ten seconds
// rlava2 was sending too many lightstyles, and overflowing the
// reliable data. temporarily changing the server state to loading
// prevents these from being passed down.
server_state_t previousState; // PGM
previousState = sv.state; // PGM
sv.state = ss_loading; // PGM
for (i = 0; i < 100; i++) SV_RunFrame ();
sv.state = previousState; // PGM
}
}
@ -289,8 +165,7 @@ clients along with it.
*/
void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_state_t serverstate, bool attractloop, bool loadgame)
{
uint i, checksum;
prvm_edict_t *ent;
uint i, checksum;
if (attractloop) Cvar_Set ("paused", "0");
@ -321,17 +196,11 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
pm_airaccelerate = 0;
}
SV_VM_Setup();
SZ_Init (&sv.multicast, sv.multicast_buf, sizeof(sv.multicast_buf));
strcpy (sv.name, server);
strcpy (sv.configstrings[CS_NAME], server);
SV_VM_Begin();
// leave slots at start for clients only
for (i = 0; i < host.maxclients; i++)
for (i=0 ; i<maxclients->value ; i++)
{
// needs to reconnect
if (svs.clients[i].state > cs_connected)
@ -339,8 +208,10 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
svs.clients[i].lastframe = -1;
}
sv.state = ss_loading;
prog->protect_world = false;
sv.time = 1000;
strcpy (sv.name, server);
strcpy (sv.configstrings[CS_NAME], server);
if (serverstate != ss_game)
{
@ -348,7 +219,7 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
}
else
{
strcpy (sv.configstrings[CS_MODELS+1], server);
sprintf (sv.configstrings[CS_MODELS+1], "maps/%s.bsp", server);
sv.models[1] = CM_LoadMap (sv.configstrings[CS_MODELS+1], false, &checksum);
}
sprintf (sv.configstrings[CS_MAPCHECKSUM],"%i", checksum);
@ -362,61 +233,36 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
sv.models[i+1] = CM_InlineModel (sv.configstrings[CS_MODELS+1+i]);
}
ent = PRVM_EDICT_NUM(0);
memset (ent->fields.sv, 0, prog->progs->entityfields * 4);
ent->priv.sv->free = false;
ent->fields.sv->model = PRVM_SetEngineString(sv.configstrings[CS_MODELS]);
ent->fields.sv->modelindex = 1; // world model
ent->fields.sv->solid = SOLID_BSP;
ent->fields.sv->movetype = MOVETYPE_PUSH;
prog->globals.server->mapname = PRVM_SetEngineString(sv.name);
//
// spawn the rest of the entities on the map
//
// precache and static commands can be issued during
// map initialization
sv.state = ss_loading;
Com_SetServerState (sv.state);
// spawn the rest of the entities on the map
sv.moved_edicts = (prvm_edict_t **)PRVM_Alloc(prog->max_edicts * sizeof(prvm_edict_t *));
*prog->time = sv.time = 1.0;
// load and spawn all other entities
SV_SpawnEntities ( sv.name, CM_EntityString(), spawnpoint );
// serverflags are for cross level information (sigils)
prog->globals.server->serverflags = svs.serverflags;
// we need to reset the spawned flag on all connected clients here so that
// their thinks don't run during startup (before PutClientInServer)
// we also need to set up the client entities now
// and we need to set the ->edict pointers to point into the progs edicts
for (i = 0, sv_client = svs.clients; i < host.maxclients; i++, sv_client++)
{
sv_client->state = cs_connected;
sv_client->edict = PRVM_EDICT_NUM(i + 1);
sv_client->edict->priv.sv->client = Z_Malloc(sizeof(player_state_t));
ent->priv.sv->state.number = i + 1;
memset (&sv_client->lastcmd, 0, sizeof(sv_client->lastcmd));
PRVM_ED_ClearEdict(sv_client->edict);
}
PRVM_ED_LoadFromFile (CM_EntityString());
// run two frames to allow everything to settle
SV_RunFrame ();
SV_RunFrame ();
// all precaches are complete
sv.state = serverstate;
Com_SetServerState (sv.state);
prog->protect_world = true;
// run two frames to allow everything to settle
for (i = 0; i < 2; i++)
{
sv.frametime = 0.1f;
SV_Physics();
}
// create a baseline for more efficient communications
SV_CreateBaseline ();
// check for a savegame
SV_CheckForSavegame ( savename );
// set serverinfo variable
Cvar_FullSet ("mapname", sv.name, CVAR_SERVERINFO | CVAR_NOSET);
Msg ("-------------------------------------\n");
SV_VM_End();
}
/*
@ -428,8 +274,8 @@ A brand new game has been started
*/
void SV_InitGame (void)
{
//int i;
//prvm_edict_t *ent;
int i;
edict_t *ent;
char idmaster[32];
if (svs.initialized)
@ -457,38 +303,53 @@ void SV_InitGame (void)
// dedicated servers are can't be single player and are usually DM
// so unless they explicity set coop, force it to deathmatch
if (host.type == HOST_DEDICATED)
if (dedicated->value)
{
if (!Cvar_VariableValue ("coop")) Cvar_FullSet ("deathmatch", "1", CVAR_SERVERINFO | CVAR_LATCH);
if (!Cvar_VariableValue ("coop"))
Cvar_FullSet ("deathmatch", "1", CVAR_SERVERINFO | CVAR_LATCH);
}
// init clients
if (Cvar_VariableValue ("deathmatch"))
{
if (host.maxclients <= 1) host.maxclients = 8;
else if (host.maxclients > MAX_CLIENTS) host.maxclients = MAX_CLIENTS;
if (maxclients->value <= 1)
Cvar_FullSet ("maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH);
else if (maxclients->value > MAX_CLIENTS)
Cvar_FullSet ("maxclients", va("%i", MAX_CLIENTS), CVAR_SERVERINFO | CVAR_LATCH);
}
else if (Cvar_VariableValue ("coop"))
{
if (host.maxclients <= 1 || host.maxclients > 4) host.maxclients = 4;
if (maxclients->value <= 1 || maxclients->value > 4)
Cvar_FullSet ("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH);
}
else // non-deathmatch, non-coop is one player
{
host.maxclients = 1;
Cvar_FullSet ("maxclients", "1", CVAR_SERVERINFO | CVAR_LATCH);
}
svs.spawncount = rand();
svs.clients = Z_Malloc (sizeof(client_t) * host.maxclients);
svs.num_client_entities = host.maxclients * UPDATE_BACKUP * 64;
svs.client_entities = Z_Malloc(sizeof(entity_state_t) * svs.num_client_entities);
svs.clients = Z_Malloc (sizeof(client_t)*maxclients->value);
svs.num_client_entities = maxclients->value*UPDATE_BACKUP*64;
svs.client_entities = Z_Malloc (sizeof(entity_state_t)*svs.num_client_entities);
// init network stuff
NET_Config ( (host.maxclients > 1) );
NET_Config ( (maxclients->value > 1) );
// heartbeats will always be sent to the id master
svs.last_heartbeat = -99999; // send immediately
sprintf(idmaster, "192.246.40.37:%i", PORT_MASTER);
NET_StringToAdr (idmaster, &master_adr[0]);
// init game
SV_InitGameProgs ();
for (i = 0; i < maxclients->value; i++)
{
ent = EDICT_NUM(i + 1);
ent->s.number = i + 1;
svs.clients[i].edict = ent;
memset (&svs.clients[i].lastcmd, 0, sizeof(svs.clients[i].lastcmd));
}
}
@ -577,145 +438,3 @@ void SV_Map (bool attractloop, char *levelstring, char *savename, bool loadgame)
SV_BroadcastCommand ("reconnect\n");
}
void SV_VM_BeginIncreaseEdicts(void)
{
int i;
prvm_edict_t *ent;
PRVM_Free( sv.moved_edicts );
sv.moved_edicts = (prvm_edict_t **)PRVM_Alloc(prog->max_edicts * sizeof(prvm_edict_t *));
// links don't survive the transition, so unlink everything
for (i = 0, ent = prog->edicts;i < prog->max_edicts;i++, ent++)
{
if (!ent->priv.sv->free) SV_UnlinkEdict(prog->edicts + i); //free old entity
memset(&ent->priv.sv->clusternums, 0, sizeof(ent->priv.sv->clusternums));
}
SV_ClearWorld();
}
void SV_VM_EndIncreaseEdicts(void)
{
int i;
prvm_edict_t *ent;
for (i = 0, ent = prog->edicts;i < prog->max_edicts;i++, ent++)
{
// link every entity except world
if (!ent->priv.sv->free) SV_LinkEdict(ent);
}
}
void SV_VM_InitEdict(prvm_edict_t *e)
{
int num = PRVM_NUM_FOR_EDICT(e) - 1;
e->priv.sv->move = false; // don't move on first frame
// set here additional player effects: model, skin, etc...
}
void SV_VM_FreeEdict(prvm_edict_t *ed)
{
SV_UnlinkEdict (ed); // unlink from world bsp
ed->fields.sv->model = 0;
ed->fields.sv->takedamage = 0;
ed->fields.sv->modelindex = 0;
ed->fields.sv->colormap = 0;
ed->fields.sv->skin = 0;
ed->fields.sv->frame = 0;
VectorClear(ed->fields.sv->origin);
VectorClear(ed->fields.sv->angles);
ed->fields.sv->nextthink = -1;
ed->fields.sv->solid = 0;
}
void SV_VM_CountEdicts( void )
{
int i;
prvm_edict_t *ent;
int active = 0, models = 0, solid = 0, step = 0;
for (i = 0; i < prog->num_edicts; i++)
{
ent = PRVM_EDICT_NUM(i);
if (ent->priv.sv->free)
continue;
active++;
if (ent->fields.sv->solid) solid++;
if (ent->fields.sv->model) models++;
if (ent->fields.sv->movetype == MOVETYPE_STEP) step++;
}
Msg("num_edicts:%3i\n", prog->num_edicts);
Msg("active :%3i\n", active);
Msg("view :%3i\n", models);
Msg("touch :%3i\n", solid);
Msg("step :%3i\n", step);
}
bool SV_VM_LoadEdict(prvm_edict_t *ent)
{
int current_skill = (int)Cvar_VariableValue ("skill");
// remove things from different skill levels or deathmatch
if(Cvar_VariableValue ("deathmatch"))
{
if (((int)ent->fields.sv->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
{
return false;
}
}
else if ((current_skill <= 0 && ((int)ent->fields.sv->spawnflags & SPAWNFLAG_NOT_EASY )) || (current_skill == 1 && ((int)ent->fields.sv->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || (current_skill >= 2 && ((int)ent->fields.sv->spawnflags & SPAWNFLAG_NOT_HARD )))
{
return false;
}
return true;
}
void SV_VM_Setup( void )
{
PRVM_Begin;
PRVM_InitProg( PRVM_SERVERPROG );
// allocate the mempools
// TODO: move the magic numbers/constants into #defines [9/13/2006 Black]
prog->progs_mempool = Mem_AllocPool("Server Progs" );
prog->builtins = vm_sv_builtins;
prog->numbuiltins = vm_sv_numbuiltins;
prog->max_edicts = 512;
prog->limit_edicts = MAX_EDICTS;
prog->reserved_edicts = host.maxclients;
prog->edictprivate_size = sizeof(server_edict_t);
prog->name = "server";
prog->extensionstring = "";
prog->loadintoworld = true;
prog->begin_increase_edicts = SV_VM_BeginIncreaseEdicts;
prog->end_increase_edicts = SV_VM_EndIncreaseEdicts;
prog->init_edict = SV_VM_InitEdict;
prog->free_edict = SV_VM_FreeEdict;
prog->count_edicts = SV_VM_CountEdicts;
prog->load_edict = SV_VM_LoadEdict;
prog->init_cmd = VM_Cmd_Init;
prog->reset_cmd = VM_Cmd_Reset;
prog->error_cmd = VM_Error;
// TODO: add a requiredfuncs list (ask LH if this is necessary at all)
PRVM_LoadProgs( "server.dat", 0, NULL, REQFIELDS, reqfields );
PRVM_End;
}
void SV_VM_Begin(void)
{
PRVM_Begin;
PRVM_SetProg( PRVM_SERVERPROG );
*prog->time = sv.time;
}
void SV_VM_End(void)
{
PRVM_End;
}

View File

@ -42,18 +42,11 @@ cvar_t *allow_download_sounds;
cvar_t *allow_download_maps;
cvar_t *sv_airaccelerate;
cvar_t *sv_wateraccelerate;
cvar_t *sv_accelerate;
cvar_t *sv_maxvelocity;
cvar_t *sv_maxspeed;
cvar_t *sv_friction;
cvar_t *sv_gravity;
cvar_t *sv_rollangle;
cvar_t *sv_rollspeed;
cvar_t *sv_noreload; // don't reload level state when reentering
cvar_t *maxclients; // FIXME: rename sv_maxclients
cvar_t *sv_showclamp;
@ -86,7 +79,7 @@ void SV_DropClient (client_t *drop)
{
// call the prog function for removing a client
// this will remove the body, among other things
//ge->ClientDisconnect (drop->edict);
SV_ClientDisconnect(drop->edict);
}
if (drop->download)
@ -128,12 +121,12 @@ char *SV_StatusString (void)
strcat (status, "\n");
statusLength = strlen(status);
for (i=0 ; i<host.maxclients ; i++)
for (i=0 ; i<maxclients->value ; i++)
{
cl = &svs.clients[i];
if (cl->state == cs_connected || cl->state == cs_spawned )
{
sprintf (player, "%i %i \"%s\"\n", cl->edict->priv.sv->client->stats[STAT_FRAGS], cl->ping, cl->name);
sprintf (player, "%i %i \"%s\"\n", cl->edict->client->ps.stats[STAT_FRAGS], cl->ping, cl->name);
playerLength = strlen(player);
if (statusLength + playerLength >= sizeof(status) )
break; // can't hold any more
@ -182,7 +175,7 @@ void SVC_Info (void)
int i, count;
int version;
if (host.maxclients == 1)
if (maxclients->value == 1)
return; // ignore in single player
version = atoi (Cmd_Argv(1));
@ -192,11 +185,11 @@ void SVC_Info (void)
else
{
count = 0;
for (i=0 ; i<host.maxclients ; i++)
for (i=0 ; i<maxclients->value ; i++)
if (svs.clients[i].state >= cs_connected)
count++;
sprintf (string, "%16s %8s %2i/%2i\n", hostname->string, sv.name, count, (int)host.maxclients);
sprintf (string, "%16s %8s %2i/%2i\n", hostname->string, sv.name, count, (int)maxclients->value);
}
Netchan_OutOfBandPrint (NS_SERVER, net_from, "info\n%s", string);
@ -252,7 +245,7 @@ void SVC_GetChallenge (void)
// overwrite the oldest
svs.challenges[oldest].challenge = rand() & 0x7fff;
svs.challenges[oldest].adr = net_from;
svs.challenges[oldest].time = host.realtime;
svs.challenges[oldest].time = curtime;
i = oldest;
}
@ -274,7 +267,7 @@ void SVC_DirectConnect (void)
int i;
client_t *cl, *newcl;
client_t temp;
prvm_edict_t *ent;
edict_t *ent;
int edictnum;
int version;
int qport;
@ -336,7 +329,7 @@ void SVC_DirectConnect (void)
memset (newcl, 0, sizeof(client_t));
// if there is already a slot for this ip, reuse it
for (i=0,cl=svs.clients ; i<host.maxclients ; i++,cl++)
for (i=0,cl=svs.clients ; i<maxclients->value ; i++,cl++)
{
if (cl->state == cs_free)
continue;
@ -344,7 +337,7 @@ void SVC_DirectConnect (void)
&& ( cl->netchan.qport == qport
|| adr.port == cl->netchan.remote_address.port ) )
{
if (!NET_IsLocalAddress (adr) && (svs.realtime - cl->lastconnect) < ((int)sv_reconnect_limit->value))
if (!NET_IsLocalAddress (adr) && (svs.realtime - cl->lastconnect) < ((int)sv_reconnect_limit->value * 1000))
{
MsgWarn("SVC_DirectConnect: %s:reconnect rejected : too soon\n", NET_AdrToString (adr));
return;
@ -357,7 +350,7 @@ void SVC_DirectConnect (void)
// find a client slot
newcl = NULL;
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
{
if (cl->state == cs_free)
{
@ -380,22 +373,19 @@ gotnewcl:
sv_client = newcl;
edictnum = (newcl - svs.clients) + 1;
ent = PRVM_EDICT_NUM(edictnum);
ent = EDICT_NUM(edictnum);
newcl->edict = ent;
newcl->challenge = challenge; // save challenge for checksumming
prog->globals.server->time = sv.time;
prog->globals.server->self = PRVM_EDICT_TO_PROG(sv_client->edict);
PRVM_ExecuteProgram (prog->globals.server->ClientConnect, "QC function ClientConnect is missing");
//if (!(ge->ClientConnect (ent, userinfo)))
/*{
// get the game a chance to reject this connection or modify the userinfo
if (!(SV_ClientConnect(ent, userinfo)))
{
if (*Info_ValueForKey (userinfo, "rejmsg"))
Netchan_OutOfBandPrint (NS_SERVER, adr, "print\n%s\nConnection refused.\n", Info_ValueForKey (userinfo, "rejmsg"));
else Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nConnection refused.\n" );
MsgWarn("SVC_DirectConnect: Game rejected a connection.\n");
return;
}*/
}
// parse some info from the info strings
strncpy (newcl->userinfo, userinfo, sizeof(newcl->userinfo)-1);
@ -514,7 +504,7 @@ void SV_CalcPings (void)
client_t *cl;
int total, count;
for (i=0 ; i<host.maxclients ; i++)
for (i=0 ; i<maxclients->value ; i++)
{
cl = &svs.clients[i];
if (cl->state != cs_spawned )
@ -547,7 +537,7 @@ void SV_CalcPings (void)
#endif
// let the game dll know about the ping
//cl->edict->client->ping = cl->ping;
cl->edict->client->ping = cl->ping;
}
}
@ -565,16 +555,16 @@ void SV_GiveMsec (void)
int i;
client_t *cl;
if (sv.framenum & 15) return;
if (sv.framenum & 15)
return;
for (i = 0; i < host.maxclients; i++)
for (i=0 ; i<maxclients->value ; i++)
{
cl = &svs.clients[i];
if (cl->state == cs_free )
continue;
cl->commandMsec = 1800; // 1600 + some slop
cl->commandMsec = 1800; // 1600 + some slop
}
}
@ -607,7 +597,7 @@ void SV_ReadPackets (void)
qport = MSG_ReadShort (&net_message) & 0xffff;
// check for packets from connected clients
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
for (i=0, cl=svs.clients ; i<maxclients->value ; i++,cl++)
{
if (cl->state == cs_free)
continue;
@ -622,8 +612,7 @@ void SV_ReadPackets (void)
}
if (Netchan_Process(&cl->netchan, &net_message))
{
// this is a valid, sequenced packet, so process it
{ // this is a valid, sequenced packet, so process it
if (cl->state != cs_zombie)
{
cl->lastmessage = svs.realtime; // don't timeout
@ -633,7 +622,7 @@ void SV_ReadPackets (void)
break;
}
if (i != host.maxclients)
if (i != maxclients->value)
continue;
}
}
@ -658,15 +647,17 @@ void SV_CheckTimeouts (void)
int droppoint;
int zombiepoint;
droppoint = svs.realtime - timeout->value;
zombiepoint = svs.realtime - zombietime->value;
droppoint = svs.realtime - 1000*timeout->value;
zombiepoint = svs.realtime - 1000*zombietime->value;
for (i=0,cl=svs.clients ; i<host.maxclients ; i++,cl++)
for (i=0,cl=svs.clients ; i<maxclients->value ; i++,cl++)
{
// message times may be wrong across a changelevel
if (cl->lastmessage > svs.realtime) cl->lastmessage = svs.realtime;
if (cl->lastmessage > svs.realtime)
cl->lastmessage = svs.realtime;
if (cl->state == cs_zombie && cl->lastmessage < zombiepoint)
if (cl->state == cs_zombie
&& cl->lastmessage < zombiepoint)
{
cl->state = cs_free; // can now be reused
continue;
@ -691,15 +682,53 @@ player processing happens outside RunWorldFrame
*/
void SV_PrepWorldFrame (void)
{
prvm_edict_t *ent;
edict_t *ent;
int i;
for (i = 0; i < prog->num_edicts ; i++, ent++)
for (i=0 ; i<ge->num_edicts ; i++, ent++)
{
ent = PRVM_EDICT_NUM(i);
ent = EDICT_NUM(i);
// events only last for a single message
ent->priv.sv->state.event = 0;
ent->s.event = 0;
}
}
/*
=================
SV_RunGameFrame
=================
*/
void SV_RunGameFrame (void)
{
if (host_speeds->value)
time_before_game = Sys_Milliseconds ();
// we always need to bump framenum, even if we
// don't run the world, otherwise the delta
// compression can get confused when a client
// has the "current" frame
sv.framenum++;
sv.time = sv.framenum*100;
// don't run if paused
if (!sv_paused->value || maxclients->value > 1)
{
SV_RunFrame ();
// never get more than one tic behind
if (sv.time < svs.realtime)
{
if (sv_showclamp->value)
Msg ("sv highclamp\n");
svs.realtime = sv.time;
}
}
if (host_speeds->value)
time_after_game = Sys_Milliseconds ();
}
/*
@ -708,22 +737,22 @@ SV_Frame
==================
*/
void SV_Frame (float time)
void SV_Frame (int msec)
{
// if server is not active, do nothing
if (!svs.initialized) return;
time_before_game = time_after_game = 0;
svs.realtime += host.realtime;
// if server is not active, do nothing
if (!svs.initialized)
return;
svs.realtime += msec;
// keep the random time dependent
rand ();
// setup the VM frame
SV_VM_Begin();
// check timeouts
SV_CheckTimeouts ();
// get packets from clients
SV_ReadPackets ();
@ -731,12 +760,13 @@ void SV_Frame (float time)
if (!sv_timedemo->value && svs.realtime < sv.time)
{
// never let the time get too far off
if (sv.time - svs.realtime > 0.1)
if (sv.time - svs.realtime > 100)
{
if (sv_showclamp->value) Msg ("sv lowclamp\n");
svs.realtime = sv.time - 0.1;
if (sv_showclamp->value)
Msg ("sv lowclamp\n");
svs.realtime = sv.time - 100;
}
NET_Sleep((sv.time - svs.realtime) * 0.001);
NET_Sleep(sv.time - svs.realtime);
return;
}
@ -747,7 +777,7 @@ void SV_Frame (float time)
SV_GiveMsec ();
// let everything in the world think and move
SV_Physics();
SV_RunGameFrame ();
// send messages back to the clients that had packets read this frame
SV_SendClientMessages ();
@ -761,8 +791,6 @@ void SV_Frame (float time)
// clear teleport flags, etc for next frame
SV_PrepWorldFrame ();
// end the server VM frame
SV_VM_End();
}
//============================================================================
@ -781,8 +809,9 @@ void Master_Heartbeat (void)
char *string;
int i;
// only dedicated servers send heartbeats
if (host.type == HOST_NORMAL) return;
// pgm post3.19 change, cvar pointer not validated before dereferencing
if (!dedicated || !dedicated->value)
return; // only dedicated servers send heartbeats
// pgm post3.19 change, cvar pointer not validated before dereferencing
if (!public_server || !public_server->value)
@ -792,7 +821,7 @@ void Master_Heartbeat (void)
if (svs.last_heartbeat > svs.realtime)
svs.last_heartbeat = svs.realtime;
if (svs.realtime - svs.last_heartbeat < HEARTBEAT_SECONDS)
if (svs.realtime - svs.last_heartbeat < HEARTBEAT_SECONDS*1000)
return; // not time to send yet
svs.last_heartbeat = svs.realtime;
@ -801,14 +830,12 @@ void Master_Heartbeat (void)
string = SV_StatusString();
// send to group master
for (i = 0; i < MAX_MASTERS; i++)
{
for (i=0 ; i<MAX_MASTERS ; i++)
if (master_adr[i].port)
{
Msg ("Sending heartbeat to %s\n", NET_AdrToString (master_adr[i]));
Netchan_OutOfBandPrint (NS_SERVER, master_adr[i], "heartbeat\n%s", string);
}
}
}
/*
@ -822,21 +849,22 @@ void Master_Shutdown (void)
{
int i;
if (host.type == HOST_NORMAL) return; // only dedicated servers send heartbeats
// pgm post3.19 change, cvar pointer not validated before dereferencing
if (!dedicated || !dedicated->value)
return; // only dedicated servers send heartbeats
// pgm post3.19 change, cvar pointer not validated before dereferencing
if (!public_server || !public_server->value)
return; // a private dedicated game
// send to group master
for ( i = 0; i < MAX_MASTERS; i++)
{
for (i=0 ; i<MAX_MASTERS ; i++)
if (master_adr[i].port)
{
if (i > 0) Msg ("Sending heartbeat to %s\n", NET_AdrToString (master_adr[i]));
if (i > 0)
Msg ("Sending heartbeat to %s\n", NET_AdrToString (master_adr[i]));
Netchan_OutOfBandPrint (NS_SERVER, master_adr[i], "shutdown");
}
}
}
//============================================================================
@ -856,7 +884,7 @@ void SV_UserinfoChanged (client_t *cl)
int i;
// call prog code to allow overrides
//ge->ClientUserinfoChanged (cl->edict, cl->userinfo);
SV_ClientUserinfoChanged(cl->edict, cl->userinfo);
// name for C code
strncpy (cl->name, Info_ValueForKey (cl->userinfo, "name"), sizeof(cl->name)-1);
@ -910,7 +938,8 @@ void SV_Init (void)
Cvar_Get ("timelimit", "0", CVAR_SERVERINFO);
Cvar_Get ("cheats", "0", CVAR_SERVERINFO|CVAR_LATCH);
Cvar_Get ("protocol", va("%i", PROTOCOL_VERSION), CVAR_SERVERINFO|CVAR_NOSET);;
hostname = Cvar_Get ("hostname", "unnamed", CVAR_SERVERINFO | CVAR_ARCHIVE);
maxclients = Cvar_Get ("maxclients", "1", CVAR_SERVERINFO | CVAR_LATCH);
hostname = Cvar_Get ("hostname", "noname", CVAR_SERVERINFO | CVAR_ARCHIVE);
timeout = Cvar_Get ("timeout", "125", 0);
zombietime = Cvar_Get ("zombietime", "2", 0);
sv_showclamp = Cvar_Get ("showclamp", "0", 0);
@ -925,17 +954,10 @@ void SV_Init (void)
sv_noreload = Cvar_Get ("sv_noreload", "0", 0);
sv_wateraccelerate = Cvar_Get("sv_wateraccelerate", "-1", CVAR_ARCHIVE);
sv_airaccelerate = Cvar_Get("sv_airaccelerate", "-1", CVAR_ARCHIVE);
sv_accelerate = Cvar_Get("sv_accelerate", "10", CVAR_ARCHIVE);
sv_maxvelocity = Cvar_Get("sv_maxvelocity", "2000", CVAR_ARCHIVE );
sv_maxspeed = Cvar_Get("sv_maxspeed", "320", CVAR_ARCHIVE);
sv_friction = Cvar_Get("sv_friction", "4", CVAR_ARCHIVE);
sv_gravity = Cvar_Get("sv_gravity", "800", CVAR_ARCHIVE);
sv_rollangle = Cvar_Get("sv_rollangle", "2", CVAR_ARCHIVE);
sv_rollspeed = Cvar_Get("sv_rollspeed", "200", CVAR_ARCHIVE);
sv_airaccelerate = Cvar_Get("sv_airaccelerate", "0", CVAR_LATCH);
sv_maxvelocity = Cvar_Get("sv_maxvelocity", "2000", 0 );
sv_gravity = Cvar_Get("sv_gravity", "800", 0 );
public_server = Cvar_Get ("public", "0", 0);
sv_reconnect_limit = Cvar_Get ("sv_reconnect_limit", "3", CVAR_ARCHIVE);
@ -974,12 +996,12 @@ void SV_FinalMessage (char *message, bool reconnect)
// send it twice
// stagger the packets to crutch operating system limited buffers
for (i=0, cl = svs.clients ; i<host.maxclients ; i++, cl++)
for (i=0, cl = svs.clients ; i<maxclients->value ; i++, cl++)
if (cl->state >= cs_connected)
Netchan_Transmit (&cl->netchan, net_message.cursize
, net_message.data);
for (i=0, cl = svs.clients ; i<host.maxclients ; i++, cl++)
for (i=0, cl = svs.clients ; i<maxclients->value ; i++, cl++)
if (cl->state >= cs_connected)
Netchan_Transmit (&cl->netchan, net_message.cursize
, net_message.data);
@ -1000,7 +1022,7 @@ void SV_Shutdown (char *finalmsg, bool reconnect)
if (svs.clients) SV_FinalMessage (finalmsg, reconnect);
Master_Shutdown ();
//SV_ShutdownGameProgs ();
SV_ShutdownGameProgs ();
// free current level
if (sv.demofile) FS_Close (sv.demofile);

File diff suppressed because it is too large Load Diff

View File

@ -65,7 +65,7 @@ size_t COM_UnpackString( byte *buffer, int pos, char *string )
if(!buffer || !string) return 0;
in = buffer + pos;
do { in++, strsize++; } while(in && *in != '\0');
do { in++, strsize++; } while(*in != '\0' && in != NULL );
strlcpy( string, in - (strsize - 1), strsize );
return pos + strsize;

View File

@ -99,20 +99,19 @@ void SV_BroadcastPrintf (int level, char *fmt, ...)
va_end (argptr);
// echo to console
if (host.type == HOST_DEDICATED)
if (dedicated->value)
{
char copy[1024];
int i;
// mask off high bits
for (i = 0; i < 1023 && string[i]; i++)
copy[i] = string[i] & 127;
copy[i] = 0; //write null terminator
for (i=0 ; i<1023 && string[i] ; i++)
copy[i] = string[i]&127;
copy[i] = 0;
Msg ("%s", copy);
}
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
for (i=0, cl = svs.clients ; i<maxclients->value; i++, cl++)
{
if (level < cl->messagelevel)
continue;
@ -160,12 +159,12 @@ MULTICAST_PVS send to clients potentially visible from org
MULTICAST_PHS send to clients potentially hearable from org
=================
*/
void _MSG_Send (msgtype_t to, vec3_t origin, prvm_edict_t *ent, const char *filename, int fileline)
void _MSG_Send (msgtype_t to, vec3_t origin, edict_t *ent, const char *filename, int fileline)
{
byte *mask = NULL;
int leafnum = 0, cluster = 0;
int area1 = 0, area2 = 0;
int j, numclients = host.maxclients;
int j, numclients = maxclients->value;
client_t *client, *current = svs.clients;
bool reliable = false;
@ -209,7 +208,7 @@ void _MSG_Send (msgtype_t to, vec3_t origin, prvm_edict_t *ent, const char *file
reliable = true; // intentional fallthrough
case MSG_ONE:
if(ent == NULL) return;
j = PRVM_NUM_FOR_EDICT(ent);
j = NUM_FOR_EDICT(ent);
if (j < 1 || j > numclients) return;
current = svs.clients + (j - 1);
numclients = 1; // send to one
@ -229,9 +228,9 @@ void _MSG_Send (msgtype_t to, vec3_t origin, prvm_edict_t *ent, const char *file
{
area2 = CM_LeafArea (leafnum);
cluster = CM_LeafCluster (leafnum);
leafnum = CM_PointLeafnum (client->edict->fields.sv->origin);
leafnum = CM_PointLeafnum (client->edict->s.origin);
if (!CM_AreasConnected (area1, area2)) continue;
if ( mask && (!(mask[cluster>>3] & (1<<(cluster & 7))))) continue;
if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7))))) continue;
}
if (reliable) SZ_Write (&client->netchan.message, sv.multicast.data, sv.multicast.cursize);
@ -279,7 +278,7 @@ If origin is NULL, the origin is determined from the entity origin
or the midpoint of the entity box for bmodels.
==================
*/
void SV_StartSound (vec3_t origin, prvm_edict_t *entity, int channel, int soundindex, float volume, float attenuation, float timeofs)
void SV_StartSound (vec3_t origin, edict_t *entity, int channel, int soundindex, float volume, float attenuation, float timeofs)
{
int i, ent, flags, sendchan;
vec3_t origin_v;
@ -300,7 +299,7 @@ void SV_StartSound (vec3_t origin, prvm_edict_t *entity, int channel, int soundi
MsgWarn("SV_StartSound: timeofs = %f\n", timeofs);
timeofs = bound(0, timeofs, 0.255 );
}
ent = PRVM_NUM_FOR_EDICT(entity);
ent = NUM_FOR_EDICT(entity);
if (channel & 8) // no PHS flag
{
@ -316,7 +315,7 @@ void SV_StartSound (vec3_t origin, prvm_edict_t *entity, int channel, int soundi
// the client doesn't know that bmodels have weird origins
// the origin can also be explicitly set
if (((int)entity->fields.sv->flags & SVF_NOCLIENT) || (entity->fields.sv->solid == SOLID_BSP) || origin )
if ( (entity->svflags & SVF_NOCLIENT) || (entity->solid == SOLID_BSP) || origin )
flags |= SND_POS;
// always send the entity number for channel overrides
@ -328,16 +327,16 @@ void SV_StartSound (vec3_t origin, prvm_edict_t *entity, int channel, int soundi
if (!origin)
{
origin = origin_v;
if (entity->fields.sv->solid == SOLID_BSP)
if (entity->solid == SOLID_BSP)
{
for (i = 0; i < 3; i++)
{
origin_v[i] = entity->fields.sv->origin[i]+0.5*(entity->fields.sv->mins[i]+entity->fields.sv->maxs[i]);
origin_v[i] = entity->s.origin[i]+0.5*(entity->mins[i]+entity->maxs[i]);
}
}
else
{
VectorCopy (entity->fields.sv->origin, origin_v);
VectorCopy (entity->s.origin, origin_v);
}
}
@ -419,8 +418,7 @@ bool SV_SendClientDatagram (client_t *client)
SZ_Clear (&client->datagram);
if (msg.overflowed)
{
// must have room left for the packet header
{ // must have room left for the packet header
Msg ("WARNING: msg overflowed for %s\n", client->name);
SZ_Clear (&msg);
}
@ -492,8 +490,9 @@ SV_SendClientMessages
*/
void SV_SendClientMessages (void)
{
int i;
int msglen;
int i;
client_t *c;
int msglen;
byte msgbuf[MAX_MSGLEN];
msglen = 0;
@ -501,7 +500,8 @@ void SV_SendClientMessages (void)
// read the next demo message if needed
if (sv.state == ss_demo && sv.demofile)
{
if (sv_paused->value) msglen = 0;
if (sv_paused->value)
msglen = 0;
else
{
// get the next message
@ -527,37 +527,39 @@ void SV_SendClientMessages (void)
}
// send a message to each connected client
for (i = 0, sv_client = svs.clients; i < host.maxclients; i++, sv_client++)
for (i=0, c = svs.clients ; i<maxclients->value; i++, c++)
{
if (sv_client->state == cs_free) continue;
// if the reliable message overflowed, drop the client
if (sv_client->netchan.message.overflowed)
if (!c->state)
continue;
// if the reliable message overflowed,
// drop the client
if (c->netchan.message.overflowed)
{
SZ_Clear (&sv_client->netchan.message);
SZ_Clear (&sv_client->datagram);
SV_BroadcastPrintf (PRINT_HIGH, "%s overflowed\n", sv_client->name);
SV_DropClient (sv_client);
SZ_Clear (&c->netchan.message);
SZ_Clear (&c->datagram);
SV_BroadcastPrintf (PRINT_HIGH, "%s overflowed\n", c->name);
SV_DropClient (c);
}
if (sv.state == ss_cinematic || sv.state == ss_demo || sv.state == ss_pic)
{
Netchan_Transmit (&sv_client->netchan, msglen, msgbuf);
}
else if (sv_client->state == cs_spawned)
if (sv.state == ss_cinematic
|| sv.state == ss_demo
|| sv.state == ss_pic
)
Netchan_Transmit (&c->netchan, msglen, msgbuf);
else if (c->state == cs_spawned)
{
// don't overrun bandwidth
if (SV_RateDrop (sv_client)) continue;
SV_SendClientDatagram (sv_client);
if (SV_RateDrop (c))
continue;
SV_SendClientDatagram (c);
}
else
{
// just update reliable if needed
if (sv_client->netchan.message.cursize || host.realtime - sv_client->netchan.last_sent > 1.0f)
Netchan_Transmit (&sv_client->netchan, 0, NULL);
// just update reliable if needed
if (c->netchan.message.cursize || curtime - c->netchan.last_sent > 1000 )
Netchan_Transmit (&c->netchan, 0, NULL);
}
}
}

1190
engine/server/sv_spawn.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,8 @@ int SV_StudioExtractBbox( studiohdr_t *phdr, int sequence, float *mins, float *m
return 1;
}
byte *SV_GetModelPtr(prvm_edict_t *ent)
byte *SV_GetModelPtr(edict_t *ent)
{
if(!ent) return NULL;
return NULL;
}

View File

@ -22,17 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "engine.h"
#include "server.h"
extern cvar_t *sv_maxspeed;
extern cvar_t *sv_accelerate;
extern cvar_t *sv_wateraccelerate;
extern cvar_t *sv_friction;
extern cvar_t *sv_rollangle;
extern cvar_t *sv_rollspeed;
prvm_edict_t *sv_player;
static bool onground;
static vec3_t wishdir, forward, right, up;
static float wishspeed;
edict_t *sv_player;
/*
============================================================
@ -70,7 +60,7 @@ void SV_New_f (void)
{
char *gamedir;
int playernum;
prvm_edict_t *ent;
edict_t *ent;
if (sv_client->state != cs_connected)
{
@ -108,8 +98,8 @@ void SV_New_f (void)
if (sv.state == ss_game)
{
// set up the entity for the client
ent = PRVM_EDICT_NUM(playernum+1);
ent->priv.sv->state.number = playernum+1;
ent = EDICT_NUM(playernum+1);
ent->s.number = playernum+1;
sv_client->edict = ent;
memset (&sv_client->lastcmd, 0, sizeof(sv_client->lastcmd));
@ -204,8 +194,7 @@ void SV_Baselines_f (void)
// write a packet full of data
while ( sv_client->netchan.message.cursize < MAX_MSGLEN/2
&& start < MAX_EDICTS)
while ( sv_client->netchan.message.cursize < MAX_MSGLEN/2 && start < MAX_EDICTS)
{
base = &sv.baselines[start];
if (base->modelindex || base->sound || base->effects)
@ -237,8 +226,6 @@ SV_Begin_f
*/
void SV_Begin_f (void)
{
int i;
// handle the case of a level changing while a client was connecting
if ( atoi(Cmd_Argv(1)) != svs.spawncount )
{
@ -248,22 +235,9 @@ void SV_Begin_f (void)
}
sv_client->state = cs_spawned;
if(!sv_player->priv.sv->free)
{
// call the game begin function
prog->globals.server->time = sv.time;
prog->globals.server->self = PRVM_EDICT_TO_PROG(sv_client->edict);
PRVM_ExecuteProgram (prog->globals.server->PutClientInServer, "QC function PutClientInServer is missing");
}
for (i = 0; i < 3; i++)
{
sv_player->priv.sv->client->pmove.origin[i] = sv_player->priv.sv->state.origin[i] = sv_player->fields.sv->origin[i]*8.0;
sv_player->priv.sv->client->pmove.velocity[i] = sv_player->fields.sv->velocity[i]*8.0;
}
sv_player->priv.sv->client->gunindex = SV_ModelIndex("models/weapons/v_glock.mdl" );
sv_player->priv.sv->client->fov = 90;
// call the game begin function
SV_ClientBegin(sv_player);
Cbuf_InsertFromDefer ();
}
@ -370,7 +344,7 @@ void SV_BeginDownload_f(void)
}
SV_NextDownload_f ();
MsgDev(D_INFO, "Downloading %s to %s\n", name, sv_client->name);
MsgDev (D_INFO, "Downloading %s to %s\n", name, sv_client->name);
}
@ -485,8 +459,8 @@ void SV_ExecuteUserCommand (char *s)
}
}
//if (!u->name && sv.state == ss_game)
//ge->ClientCommand (sv_player);
if (!u->name && sv.state == ss_game)
SV_ClientCommand(sv_player);
}
/*
@ -497,18 +471,8 @@ USER CMD EXECUTION
===========================================================================
*/
trace_t PM_trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
void SV_ClientThink (client_t *cl, usercmd_t *cmd)
{
return SV_Trace (start, mins, maxs, end, sv_client->edict, MASK_SOLID);
}
void SV_ClientRun (client_t *cl, usercmd_t *cmd)
{
pmove_t pm;
int i;
sv_client = cl;
cl->commandMsec -= cmd->msec;
if (cl->commandMsec < 0 && sv_enforcetime->value )
@ -516,359 +480,7 @@ void SV_ClientRun (client_t *cl, usercmd_t *cmd)
MsgWarn("SV_ClientThink: commandMsec underflow from %s\n", cl->name);
return;
}
// set up for pmove
memset (&pm, 0, sizeof(pm));
cl->edict->priv.sv->client->pmove.pm_flags |= PMF_NO_PREDICTION;
if (cl->edict->fields.sv->movetype == MOVETYPE_NOCLIP)
cl->edict->priv.sv->client->pmove.pm_type = PM_SPECTATOR;
else if (cl->edict->fields.sv->movetype == MOVETYPE_WALK)
cl->edict->priv.sv->client->pmove.pm_type = PM_NORMAL;
else if (cl->edict->fields.sv->movetype == MOVETYPE_NONE)
cl->edict->priv.sv->client->pmove.pm_type = PM_FREEZE;
cl->edict->priv.sv->client->pmove.gravity = 0;
pm.s = cl->edict->priv.sv->client->pmove;
for (i = 0; i < 3; i++)
{
pm.s.origin[i] = cl->edict->fields.sv->origin[i] * 8;
pm.s.velocity[i] = cl->edict->fields.sv->velocity[i] * 8;
}
pm.cmd = *cmd;
pm.trace = PM_trace; // adds default parms
pm.pointcontents = SV_PointContents;
Msg("org before pmove [%i %i %i]\n", pm.s.origin[0], pm.s.origin[1], pm.s.origin[2] );
Pmove (&pm); //run pmove
// save results of pmove
cl->edict->priv.sv->client->pmove = pm.s;
Msg("org after pmove [%i %i %i]\n", pm.s.origin[0], pm.s.origin[1], pm.s.origin[2] );
for (i = 0; i < 3; i++)
{
cl->edict->priv.sv->state.old_origin[i] = pm.s.origin[i]*0.125;
cl->edict->fields.sv->origin[i] = pm.s.origin[i]*0.125;
cl->edict->fields.sv->velocity[i] = pm.s.velocity[i]*0.125;
}
VectorCopy (pm.mins, cl->edict->fields.sv->mins);
VectorCopy (pm.maxs, cl->edict->fields.sv->maxs);
VectorCopy (pm.viewangles, cl->edict->fields.sv->v_angle);
VectorCopy (pm.viewangles, cl->edict->priv.sv->client->viewangles);
VectorCopy(cl->edict->fields.sv->view_ofs, cl->edict->priv.sv->client->viewoffset );
SV_LinkEdict( cl->edict );
//SV_ClientThink();
}
/*
===============
SV_CalcRoll
===============
*/
float SV_CalcRoll (vec3_t angles, vec3_t velocity)
{
float sign;
float side;
float value;
side = DotProduct (velocity, right);
sign = side < 0 ? -1 : 1;
side = fabs(side);
value = sv_rollangle->value;
if (side < sv_rollspeed->value)
side = side * value / sv_rollspeed->value;
else side = value;
return side*sign;
}
/*
==================
SV_UserFriction
==================
*/
void SV_UserFriction (void)
{
float speed, newspeed, control, friction;
vec3_t start, stop;
trace_t trace;
speed = sqrt(sv_client->edict->fields.sv->velocity[0]*sv_client->edict->fields.sv->velocity[0]+sv_client->edict->fields.sv->velocity[1]*sv_client->edict->fields.sv->velocity[1]);
if (!speed) return;
// if the leading edge is over a dropoff, increase friction
start[0] = stop[0] = sv_client->edict->fields.sv->origin[0] + sv_client->edict->fields.sv->velocity[0]/speed*16;
start[1] = stop[1] = sv_client->edict->fields.sv->origin[1] + sv_client->edict->fields.sv->velocity[1]/speed*16;
start[2] = sv_client->edict->fields.sv->origin[2] + sv_client->edict->fields.sv->mins[2];
stop[2] = start[2] - 34;
trace = SV_Trace (start, vec3_origin, vec3_origin, stop, sv_client->edict, MASK_SOLID );
if (trace.fraction == 1.0) friction = sv_friction->value * 2;
else friction = sv_friction->value;
// apply friction
control = max(speed, 100);
newspeed = speed - sv.frametime * control * friction;
if (newspeed < 0) newspeed = 0;
else newspeed /= speed;
VectorScale(sv_client->edict->fields.sv->velocity, newspeed, sv_client->edict->fields.sv->velocity);
}
/*
==============
SV_Accelerate
==============
*/
void SV_Accelerate (void)
{
int i;
float addspeed, accelspeed, currentspeed;
currentspeed = DotProduct (sv_client->edict->fields.sv->velocity, wishdir);
addspeed = wishspeed - currentspeed;
if (addspeed <= 0) return;
accelspeed = sv_accelerate->value * sv.frametime * wishspeed;
if (accelspeed > addspeed) accelspeed = addspeed;
for (i = 0; i < 3; i++) sv_client->edict->fields.sv->velocity[i] += accelspeed * wishdir[i];
}
void SV_AirAccelerate (vec3_t wishveloc)
{
int i;
float addspeed, wishspd, accelspeed, currentspeed;
wishspd = VectorNormalize (wishveloc);
if (wishspd > sv_maxspeed->value / 10) wishspd = sv_maxspeed->value / 10;
currentspeed = DotProduct (sv_client->edict->fields.sv->velocity, wishveloc);
addspeed = wishspd - currentspeed;
if (addspeed <= 0) return;
accelspeed = (sv_airaccelerate->value < 0 ? sv_accelerate->value : sv_airaccelerate->value) * wishspeed * sv.frametime;
if (accelspeed > addspeed) accelspeed = addspeed;
for (i = 0; i < 3; i++) sv_client->edict->fields.sv->velocity[i] += accelspeed*wishveloc[i];
}
void DropPunchAngle (void)
{
float len;
len = VectorNormalize(sv_client->edict->fields.sv->punchangle);
len -= 10 * sv.frametime;
if (len < 0) len = 0;
VectorScale (sv_client->edict->fields.sv->punchangle, len, sv_client->edict->fields.sv->punchangle);
}
/*
===================
SV_AirMove
===================
*/
void SV_AirMove (void)
{
int i;
vec3_t wishvel;
float fmove, smove, temp;
wishvel[0] = wishvel[2] = 0;
wishvel[1] = sv_client->edict->fields.sv->angles[1];
AngleVectorsRight (wishvel, forward, right, up);
fmove = 0;//cmd.forwardmove;
smove = 0;//cmd.sidemove;
// hack to not let you back into teleporter
if (sv.time < sv_client->edict->fields.sv->teleport_time && fmove < 0)
fmove = 0;
for (i=0 ; i<3 ; i++)
wishvel[i] = forward[i]*fmove + right[i]*smove;
if ((int)sv_client->edict->fields.sv->movetype != MOVETYPE_WALK)
wishvel[2] += fmove;
VectorCopy (wishvel, wishdir);
wishspeed = VectorNormalize(wishdir);
if (wishspeed > sv_maxspeed->value)
{
temp = sv_maxspeed->value/wishspeed;
VectorScale (wishvel, temp, wishvel);
wishspeed = sv_maxspeed->value;
}
if (sv_client->edict->fields.sv->movetype == MOVETYPE_NOCLIP)
{
// noclip
VectorCopy (wishvel, sv_client->edict->fields.sv->velocity);
}
else if (onground && (!(sv_client->edict->fields.sv->button2)))
{
SV_UserFriction ();
SV_Accelerate ();
}
else
{
// not on ground, so little effect on velocity
SV_AirAccelerate (wishvel);
}
}
/*
===================
SV_WaterMove
===================
*/
void SV_WaterMove (void)
{
int i;
vec3_t wishvel;
float speed, newspeed, wishspeed, addspeed, accelspeed, temp;
// user intentions
AngleVectorsRight (sv_client->edict->fields.sv->v_angle, forward, right, up);
/*for (i = 0; i < 3; i++)
wishvel[i] = forward[i]*cmd.forwardmove + right[i]*cmd.sidemove;
if (!cmd.forwardmove && !cmd.sidemove && !cmd.upmove)
wishvel[2] -= 60; // drift towards bottom
else
wishvel[2] += cmd.upmove;
*/
wishspeed = VectorLength(wishvel);
if (wishspeed > sv_maxspeed->value)
{
temp = sv_maxspeed->value/wishspeed;
VectorScale (wishvel, temp, wishvel);
wishspeed = sv_maxspeed->value;
}
wishspeed *= 0.7;
// water friction
speed = VectorLength(sv_client->edict->fields.sv->velocity);
if (speed)
{
newspeed = speed - sv.frametime * speed * -1;
if (newspeed < 0)
newspeed = 0;
temp = newspeed/speed;
VectorScale(sv_client->edict->fields.sv->velocity, temp, sv_client->edict->fields.sv->velocity);
}
else
newspeed = 0;
// water acceleration
if (!wishspeed)
return;
addspeed = wishspeed - newspeed;
if (addspeed <= 0)
return;
VectorNormalize (wishvel);
accelspeed = (sv_wateraccelerate->value < 0 ? sv_accelerate->value : sv_wateraccelerate->value) * wishspeed * sv.frametime;
if (accelspeed > addspeed) accelspeed = addspeed;
for (i = 0; i < 3; i++) sv_client->edict->fields.sv->velocity[i] += accelspeed * wishvel[i];
}
void SV_WaterJump (void)
{
if (sv.time > sv_client->edict->fields.sv->teleport_time || !sv_client->edict->fields.sv->waterlevel)
{
sv_client->edict->fields.sv->flags = (int)sv_client->edict->fields.sv->flags & ~FL_WATERJUMP;
sv_client->edict->fields.sv->teleport_time = 0;
}
sv_client->edict->fields.sv->velocity[0] = sv_client->edict->fields.sv->movedir[0];
sv_client->edict->fields.sv->velocity[1] = sv_client->edict->fields.sv->movedir[1];
}
/*
===================
SV_ClientThink
the move fields specify an intended velocity in pix/sec
the angle fields specify an exact angular motion in degrees
===================
*/
void SV_ClientThink (void)
{
vec3_t v_angle;
if (sv_client->edict->fields.sv->movetype == MOVETYPE_NONE)
return;
onground = (int)sv_client->edict->fields.sv->flags & FL_ONGROUND;
DropPunchAngle ();
// if dead, behave differently
if (sv_client->edict->fields.sv->health <= 0) return;
// angles
// show 1/3 the pitch angle and all the roll angle
VectorAdd (sv_client->edict->fields.sv->v_angle, sv_client->edict->fields.sv->punchangle, v_angle);
sv_client->edict->fields.sv->angles[ROLL] = SV_CalcRoll (sv_client->edict->fields.sv->angles, sv_client->edict->fields.sv->velocity)*4;
if (!sv_client->edict->fields.sv->fixangle)
{
sv_client->edict->fields.sv->angles[PITCH] = -v_angle[PITCH]/3;
sv_client->edict->fields.sv->angles[YAW] = v_angle[YAW];
}
if ( (int)sv_client->edict->fields.sv->flags & FL_WATERJUMP )
{
SV_WaterJump ();
return;
}
// walk
if ((sv_client->edict->fields.sv->waterlevel >= 2) && (sv_client->edict->fields.sv->movetype != MOVETYPE_NOCLIP))
{
SV_WaterMove();
return;
}
SV_AirMove();
}
void SV_ApplyClientMove (void)
{
usercmd_t *move = &sv_client->lastcmd;
if (!move->msec) return;
// set the edict fields
sv_client->edict->fields.sv->button0 = move->buttons & 1;
sv_client->edict->fields.sv->button2 = (move->buttons & 2)>>1;
if (move->impulse) sv_client->edict->fields.sv->impulse = move->impulse;
// only send the impulse to qc once
move->impulse = 0;
VectorCopy(sv_client->edict->priv.sv->client->viewangles, sv_client->edict->fields.sv->v_angle);
ClientThink (cl->edict, cmd);
}
/*
@ -885,13 +497,13 @@ void SV_ExecuteClientMessage (client_t *cl)
int c;
char *s;
usercmd_t nullcmd;
usercmd_t oldest, oldcmd, newcmd;
usercmd_t nullcmd;
usercmd_t oldest, oldcmd, newcmd;
int net_drop;
int stringCmdCount;
int checksum, calculatedChecksum;
int checksumIndex;
bool move_issued;
bool move_issued;
int lastframe;
sv_client = cl;
@ -963,9 +575,7 @@ void SV_ExecuteClientMessage (client_t *cl)
MsgWarn("SV_ExecuteClientMessage: failed command checksum for %s (%d != %d)/%d\n", cl->name, calculatedChecksum, checksum, cl->netchan.incoming_sequence);
return;
}
//Msg("sv_paused->value %g\n", sv_paused->value );
if (!sv_paused->value)
{
net_drop = cl->netchan.dropped;
@ -973,13 +583,13 @@ void SV_ExecuteClientMessage (client_t *cl)
{
while (net_drop > 2)
{
SV_ClientRun (cl, &cl->lastcmd);
SV_ClientThink (cl, &cl->lastcmd);
net_drop--;
}
if (net_drop > 1) SV_ClientRun (cl, &oldest);
if (net_drop > 0) SV_ClientRun (cl, &oldcmd);
if (net_drop > 1) SV_ClientThink (cl, &oldest);
if (net_drop > 0) SV_ClientThink (cl, &oldcmd);
}
SV_ClientRun (cl, &newcmd);
SV_ClientThink (cl, &newcmd);
}
cl->lastcmd = newcmd;
break;

View File

@ -30,6 +30,14 @@ ENTITY AREA CHECKING
FIXME: this use of "area" is different from the bsp file use
===============================================================================
*/
// (type *)STRUCT_FROM_LINK(link_t *link, type, member)
// ent = STRUCT_FROM_LINK(link,entity_t,order)
// FIXME: remove this mess!
#define STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (int)&(((t *)0)->m)))
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
typedef struct areanode_s
{
int axis; // -1 = leaf node
@ -45,12 +53,12 @@ typedef struct areanode_s
areanode_t sv_areanodes[AREA_NODES];
int sv_numareanodes;
float *area_mins, *area_maxs;
prvm_edict_t **area_list;
float *area_mins, *area_maxs;
edict_t **area_list;
int area_count, area_maxcount;
int area_type;
int SV_HullForEntity (prvm_edict_t *ent);
int SV_HullForEntity (edict_t *ent);
// ClearLink is used for new headnodes
@ -65,9 +73,8 @@ void RemoveLink (link_t *l)
l->prev->next = l->next;
}
void InsertLinkBefore (link_t *l, link_t *before, int entnum)
void InsertLinkBefore (link_t *l, link_t *before)
{
l->entnum = entnum;
l->next = before;
l->prev = before->prev;
l->prev->next = l;
@ -140,11 +147,12 @@ SV_UnlinkEdict
===============
*/
void SV_UnlinkEdict (prvm_edict_t *ent)
void SV_UnlinkEdict (edict_t *ent)
{
if (!ent->priv.sv->area.prev) return; // not linked in anywhere
RemoveLink (&ent->priv.sv->area);
ent->priv.sv->area.prev = ent->priv.sv->area.next = NULL;
if (!ent->area.prev)
return; // not linked in anywhere
RemoveLink (&ent->area);
ent->area.prev = ent->area.next = NULL;
}
@ -155,95 +163,90 @@ SV_LinkEdict
===============
*/
#define MAX_TOTAL_ENT_LEAFS 128
void SV_LinkEdict (prvm_edict_t *ent)
void SV_LinkEdict (edict_t *ent)
{
areanode_t *node;
int leafs[MAX_TOTAL_ENT_LEAFS];
int clusters[MAX_TOTAL_ENT_LEAFS];
int num_leafs;
int i, j, k;
int area;
int topnode;
int leafs[MAX_TOTAL_ENT_LEAFS];
int clusters[MAX_TOTAL_ENT_LEAFS];
int num_leafs;
int i, j, k;
int area;
int topnode;
if (ent->priv.sv->area.prev) SV_UnlinkEdict (ent); // unlink from old position
if (ent == prog->edicts) return; // don't add the world
if (ent->priv.sv->free)
{
Msg("Can't link entity [%d]\n", ent->priv.sv->state.number );
return;
}
if (ent->area.prev) SV_UnlinkEdict (ent); // unlink from old position
if (ent == ge->edicts) return; // don't add the world
if (!ent->inuse) return;
// set the size
VectorSubtract (ent->fields.sv->maxs, ent->fields.sv->mins, ent->fields.sv->size);
VectorSubtract (ent->maxs, ent->mins, ent->size);
// encode the size into the entity_state for client prediction
if (ent->fields.sv->solid == SOLID_BBOX && !((int)ent->fields.sv->flags & SVF_DEADMONSTER))
if (ent->solid == SOLID_BBOX && !(ent->svflags & SVF_DEADMONSTER))
{
// assume that x/y are equal and symetric
i = ent->fields.sv->maxs[0]/8;
if(i < 1) i = 1;
if(i > 31) i = 31;
i = ent->maxs[0]/8;
if (i<1) i = 1;
if (i>31) i = 31;
// z is not symetric
j = (-ent->fields.sv->mins[2])/8;
j = (-ent->mins[2])/8;
if (j < 1) j = 1;
if (j > 31) j = 31;
// and z maxs can be negative...
k = (ent->fields.sv->maxs[2]+32)/8;
if (k < 1) k = 1;
if (k > 63) k = 63;
ent->fields.sv->solid = (k<<10) | (j<<5) | i;
k = (ent->maxs[2]+32)/8;
if (k<1) k = 1;
if (k>63) k = 63;
ent->s.solid = (k<<10) | (j<<5) | i;
}
else if (ent->fields.sv->solid == SOLID_BSP)
else if (ent->solid == SOLID_BSP)
{
ent->fields.sv->solid = 31; // a solid_bbox will never create this value
ent->s.solid = 31; // a solid_bbox will never create this value
}
else ent->fields.sv->solid = 0;
else ent->s.solid = 0;
// set the abs box
if (ent->fields.sv->solid == SOLID_BSP && (!VectorIsNull(ent->fields.sv->angles)))
if (ent->solid == SOLID_BSP && (ent->s.angles[0] || ent->s.angles[1] || ent->s.angles[2]) )
{
// expand for rotation
float max = 0, v;
int i;
for (i = 0; i < 3; i++)
for (i=0 ; i<3 ; i++)
{
v =fabs( ent->fields.sv->mins[i]);
v =fabs( ent->mins[i]);
if (v > max) max = v;
v =fabs( ent->fields.sv->maxs[i]);
v =fabs( ent->maxs[i]);
if (v > max) max = v;
}
for (i = 0; i < 3; i++)
for (i=0 ; i<3 ; i++)
{
ent->fields.sv->absmin[i] = ent->fields.sv->origin[i] - max;
ent->fields.sv->absmax[i] = ent->fields.sv->origin[i] + max;
ent->absmin[i] = ent->s.origin[i] - max;
ent->absmax[i] = ent->s.origin[i] + max;
}
}
else
{
// normal
VectorAdd (ent->fields.sv->origin, ent->fields.sv->mins, ent->fields.sv->absmin);
VectorAdd (ent->fields.sv->origin, ent->fields.sv->maxs, ent->fields.sv->absmax);
{ // normal
VectorAdd (ent->s.origin, ent->mins, ent->absmin);
VectorAdd (ent->s.origin, ent->maxs, ent->absmax);
}
// because movement is clipped an epsilon away from an actual edge,
// we must fully check even when bounding boxes don't quite touch
ent->fields.sv->absmin[0] -= 1;
ent->fields.sv->absmin[1] -= 1;
ent->fields.sv->absmin[2] -= 1;
ent->fields.sv->absmax[0] += 1;
ent->fields.sv->absmax[1] += 1;
ent->fields.sv->absmax[2] += 1;
ent->absmin[0] -= 1;
ent->absmin[1] -= 1;
ent->absmin[2] -= 1;
ent->absmax[0] += 1;
ent->absmax[1] += 1;
ent->absmax[2] += 1;
// link to PVS leafs
ent->priv.sv->num_clusters = 0;
ent->priv.sv->areanum = 0;
ent->priv.sv->areanum2 = 0;
ent->num_clusters = 0;
ent->areanum = 0;
ent->areanum2 = 0;
//get all leafs, including solids
num_leafs = CM_BoxLeafnums (ent->fields.sv->absmin, ent->fields.sv->absmax, leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
num_leafs = CM_BoxLeafnums (ent->absmin, ent->absmax, leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
// set areas
for (i = 0; i < num_leafs; i++)
@ -253,25 +256,25 @@ void SV_LinkEdict (prvm_edict_t *ent)
if (area)
{ // doors may legally straggle two areas,
// but nothing should evern need more than that
if (ent->priv.sv->areanum && ent->priv.sv->areanum != area)
if (ent->areanum && ent->areanum != area)
{
if (ent->priv.sv->areanum2 && ent->priv.sv->areanum2 != area && sv.state == ss_loading)
MsgWarn("SV_LinkEdict: object touching 3 areas at %f %f %f\n", ent->fields.sv->absmin[0], ent->fields.sv->absmin[1], ent->fields.sv->absmin[2]);
ent->priv.sv->areanum2 = area;
if (ent->areanum2 && ent->areanum2 != area && sv.state == ss_loading)
MsgWarn("SV_LinkEdict: object touching 3 areas at %f %f %f\n", ent->absmin[0], ent->absmin[1], ent->absmin[2]);
ent->areanum2 = area;
}
else ent->priv.sv->areanum = area;
else ent->areanum = area;
}
}
if (num_leafs >= MAX_TOTAL_ENT_LEAFS)
{
// assume we missed some leafs, and mark by headnode
ent->priv.sv->num_clusters = -1;
ent->priv.sv->headnode = topnode;
ent->num_clusters = -1;
ent->headnode = topnode;
}
else
{
ent->priv.sv->num_clusters = 0;
ent->num_clusters = 0;
for (i = 0; i < num_leafs; i++)
{
if (clusters[i] == -1) continue; // not a visible leaf
@ -281,43 +284,42 @@ void SV_LinkEdict (prvm_edict_t *ent)
}
if (j == i)
{
if (ent->priv.sv->num_clusters == MAX_ENT_CLUSTERS)
if (ent->num_clusters == MAX_ENT_CLUSTERS)
{
// assume we missed some leafs, and mark by headnode
ent->priv.sv->num_clusters = -1;
ent->priv.sv->headnode = topnode;
ent->num_clusters = -1;
ent->headnode = topnode;
break;
}
ent->priv.sv->clusternums[ent->priv.sv->num_clusters++] = clusters[i];
ent->clusternums[ent->num_clusters++] = clusters[i];
}
}
}
// if first time, make sure old_origin is valid
if (!ent->priv.sv->linkcount)
if (!ent->linkcount)
{
VectorCopy (ent->fields.sv->origin, ent->fields.sv->oldorigin);
VectorCopy (ent->s.origin, ent->s.old_origin);
}
ent->priv.sv->linkcount++;
ent->linkcount++;
if (ent->fields.sv->solid == SOLID_NOT) return;
if (ent->solid == SOLID_NOT) return;
// find the first node that the ent's box crosses
node = sv_areanodes;
while (1)
{
if (node->axis == -1) break;
if (ent->fields.sv->absmin[node->axis] > node->dist)
if (ent->absmin[node->axis] > node->dist)
node = node->children[0];
else if (ent->fields.sv->absmax[node->axis] < node->dist)
else if (ent->absmax[node->axis] < node->dist)
node = node->children[1];
else break; // crosses the node
}
// link it in
if (ent->fields.sv->solid == SOLID_TRIGGER)
InsertLinkBefore (&ent->priv.sv->area, &node->trigger_edicts, PRVM_NUM_FOR_EDICT(ent));
else InsertLinkBefore (&ent->priv.sv->area, &node->solid_edicts, PRVM_NUM_FOR_EDICT(ent));
if (ent->solid == SOLID_TRIGGER) InsertLinkBefore (&ent->area, &node->trigger_edicts);
else InsertLinkBefore (&ent->area, &node->solid_edicts);
}
@ -331,7 +333,7 @@ SV_AreaEdicts_r
void SV_AreaEdicts_r (areanode_t *node)
{
link_t *l, *next, *start;
prvm_edict_t *check;
edict_t *check;
int count = 0;
// touch linked edicts
@ -342,11 +344,11 @@ void SV_AreaEdicts_r (areanode_t *node)
for (l = start->next; l != start; l = next)
{
next = l->next;
check = PRVM_EDICT_NUM_UNSIGNED(l->entnum);
check = EDICT_FROM_AREA(l);
if (check->fields.sv->solid == SOLID_NOT) continue; // deactivated
if (check->fields.sv->absmin[0] > area_maxs[0] || check->fields.sv->absmin[1] > area_maxs[1] || check->fields.sv->absmin[2] > area_maxs[2]
|| check->fields.sv->absmax[0] < area_mins[0] || check->fields.sv->absmax[1] < area_mins[1] || check->fields.sv->absmax[2] < area_mins[2])
if (check->solid == SOLID_NOT) continue; // deactivated
if (check->absmin[0] > area_maxs[0] || check->absmin[1] > area_maxs[1] || check->absmin[2] > area_maxs[2]
|| check->absmax[0] < area_mins[0] || check->absmax[1] < area_mins[1] || check->absmax[2] < area_mins[2])
continue; // not touching
if (area_count == area_maxcount)
@ -362,8 +364,10 @@ void SV_AreaEdicts_r (areanode_t *node)
if (node->axis == -1) return; // terminal node
// recurse down both sides
if ( area_maxs[node->axis] > node->dist ) SV_AreaEdicts_r ( node->children[0] );
if ( area_mins[node->axis] < node->dist ) SV_AreaEdicts_r ( node->children[1] );
if ( area_maxs[node->axis] > node->dist )
SV_AreaEdicts_r ( node->children[0] );
if ( area_mins[node->axis] < node->dist )
SV_AreaEdicts_r ( node->children[1] );
}
/*
@ -371,7 +375,7 @@ void SV_AreaEdicts_r (areanode_t *node)
SV_AreaEdicts
================
*/
int SV_AreaEdicts (vec3_t mins, vec3_t maxs, prvm_edict_t **list, int maxcount, int areatype)
int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype)
{
area_mins = mins;
area_maxs = maxs;
@ -395,7 +399,7 @@ SV_PointContents
*/
int SV_PointContents (vec3_t p)
{
prvm_edict_t *touch[MAX_EDICTS], *hit;
edict_t *touch[MAX_EDICTS], *hit;
int i, num;
int contents, c2;
int headnode;
@ -413,14 +417,30 @@ int SV_PointContents (vec3_t p)
// might intersect, so do an exact clip
headnode = SV_HullForEntity (hit);
angles = hit->fields.sv->angles;
if (hit->fields.sv->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
c2 = CM_TransformedPointContents (p, headnode, hit->fields.sv->origin, hit->fields.sv->angles);
angles = hit->s.angles;
if (hit->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
c2 = CM_TransformedPointContents (p, headnode, hit->s.origin, hit->s.angles);
contents |= c2;
}
return contents;
}
typedef struct
{
vec3_t boxmins, boxmaxs;// enclose the test object along entire move
float *mins, *maxs; // size of the moving object
vec3_t mins2, maxs2; // size when clipping against mosnters
float *start, *end;
trace_t trace;
edict_t *passedict;
int contentmask;
} moveclip_t;
/*
================
SV_HullForEntity
@ -431,15 +451,15 @@ Offset is filled in to contain the adjustment that must be added to the
testing object's origin to get a point to use with the returned hull.
================
*/
int SV_HullForEntity (prvm_edict_t *ent)
int SV_HullForEntity (edict_t *ent)
{
cmodel_t *model;
// decide which clipping hull to use, based on the size
if (ent->fields.sv->solid == SOLID_BSP)
if (ent->solid == SOLID_BSP)
{
// explicit hulls in the BSP model
model = sv.models[ (int)ent->fields.sv->modelindex ];
model = sv.models[ ent->s.modelindex ];
if (!model)
{
@ -450,7 +470,7 @@ int SV_HullForEntity (prvm_edict_t *ent)
}
// create a temp hull from bounding box sizes
return CM_HeadnodeForBox (ent->fields.sv->mins, ent->fields.sv->maxs);
return CM_HeadnodeForBox (ent->mins, ent->maxs);
}
/*
@ -462,7 +482,7 @@ SV_ClipMoveToEntities
void SV_ClipMoveToEntities ( moveclip_t *clip )
{
int i, num;
prvm_edict_t *touchlist[MAX_EDICTS], *touch;
edict_t *touchlist[MAX_EDICTS], *touch;
trace_t trace;
int headnode;
float *angles;
@ -474,32 +494,30 @@ void SV_ClipMoveToEntities ( moveclip_t *clip )
for (i = 0; i < num; i++)
{
touch = touchlist[i];
if (touch->fields.sv->solid == SOLID_NOT) continue;
if (touch->solid == SOLID_NOT) continue;
if (touch == clip->passedict) continue;
if (clip->trace.allsolid) return;
if (clip->passedict)
{
if (PRVM_PROG_TO_EDICT(touch->fields.sv->owner) == clip->passedict)
continue; // don't clip against own missiles
if (PRVM_PROG_TO_EDICT(clip->passedict->fields.sv->owner) == touch)
continue; // don't clip against owner
if (touch->owner == clip->passedict) continue; // don't clip against own missiles
if (clip->passedict->owner == touch) continue; // don't clip against owner
}
if ( !(clip->contentmask & CONTENTS_DEADMONSTER) && ((int)touch->fields.sv->flags & SVF_DEADMONSTER) )
if ( !(clip->contentmask & CONTENTS_DEADMONSTER) && (touch->svflags & SVF_DEADMONSTER) )
continue;
// might intersect, so do an exact clip
headnode = SV_HullForEntity (touch);
angles = touch->fields.sv->angles;
if (touch->fields.sv->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
angles = touch->s.angles;
if (touch->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
if ((int)touch->fields.sv->flags & SVF_MONSTER)
if (touch->svflags & SVF_MONSTER)
{
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins2, clip->maxs2, headnode, clip->contentmask, touch->fields.sv->origin, angles);
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins2, clip->maxs2, headnode, clip->contentmask, touch->s.origin, angles);
}
else
{
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins, clip->maxs, headnode, clip->contentmask, touch->fields.sv->origin, angles);
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins, clip->maxs, headnode, clip->contentmask, touch->s.origin, angles);
}
if (trace.allsolid || trace.startsolid || trace.fraction < clip->trace.fraction)
{
@ -511,11 +529,7 @@ void SV_ClipMoveToEntities ( moveclip_t *clip )
}
else clip->trace = trace;
}
else if (trace.startsolid)
{
clip->trace.startsolid = true;
//clip->trace.startstuck = true;
}
else if (trace.startsolid) clip->trace.startsolid = true;
}
}
@ -554,7 +568,7 @@ Passedict and edicts owned by passedict are explicitly not checked.
==================
*/
trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, prvm_edict_t *passedict, int contentmask)
trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask)
{
moveclip_t clip;
@ -565,7 +579,7 @@ trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, prvm_edict
// clip to world
clip.trace = CM_BoxTrace (start, end, mins, maxs, 0, contentmask);
clip.trace.ent = prog->edicts;
clip.trace.ent = ge->edicts;
if (clip.trace.fraction == 0) return clip.trace; // blocked by the world
clip.contentmask = contentmask;
@ -587,8 +601,3 @@ trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, prvm_edict
return clip.trace;
}
trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int contentsmask)
{
// correct ??
return CM_BoxTrace(start, end, mins, maxs, ent->priv.sv->headnode, contentsmask);
}

View File

@ -53,8 +53,8 @@ vec3_t listener_up;
bool s_registering;
float soundtime; // sample PAIRS
float paintedtime; // sample PAIRS
int soundtime; // sample PAIRS
int paintedtime; // sample PAIRS
// during registration it is possible to have more sounds
// than could actually be referenced during gameplay,
@ -80,7 +80,7 @@ cvar_t *s_mixahead;
cvar_t *s_primary;
float s_rawend;
int s_rawend;
portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
@ -120,7 +120,8 @@ void S_Init (void)
Msg("\n------- sound initialization -------\n");
cv = Cvar_Get ("s_initsound", "1", 0);
if (!cv->value) Msg ("not initializing.\n");
if (!cv->value)
Msg ("not initializing.\n");
else
{
s_volume = Cvar_Get ("s_volume", "0.7", CVAR_ARCHIVE);
@ -136,7 +137,8 @@ void S_Init (void)
Cmd_AddCommand("soundlist", S_SoundList);
Cmd_AddCommand("soundinfo", S_SoundInfo_f);
if (!SNDDMA_Init()) return;
if (!SNDDMA_Init())
return;
S_InitScaletable ();
@ -147,6 +149,7 @@ void S_Init (void)
paintedtime = 0;
Msg ("sound sampling rate: %i\n", dma.speed);
S_StopAllSounds ();
}
@ -163,7 +166,8 @@ void S_Shutdown(void)
int i;
sfx_t *sfx;
if (!sound_started) return;
if (!sound_started)
return;
SNDDMA_Shutdown();
@ -177,10 +181,13 @@ void S_Shutdown(void)
// free all sounds
for (i=0, sfx=known_sfx ; i < num_sfx ; i++,sfx++)
{
if (!sfx->name[0]) continue;
if (sfx->cache) Z_Free (sfx->cache);
if (!sfx->name[0])
continue;
if (sfx->cache)
Z_Free (sfx->cache);
memset (sfx, 0, sizeof(*sfx));
}
num_sfx = 0;
}
@ -195,7 +202,7 @@ S_FindName
==================
*/
sfx_t *S_FindName (const char *name, bool create)
sfx_t *S_FindName (char *name, bool create)
{
int i;
sfx_t *sfx;
@ -295,7 +302,7 @@ S_RegisterSound
==================
*/
sfx_t *S_RegisterSound (const char *name)
sfx_t *S_RegisterSound (char *name)
{
sfx_t *sfx;
@ -364,19 +371,18 @@ S_PickChannel
*/
channel_t *S_PickChannel(int entnum, int entchannel)
{
int ch_idx;
int first_to_die;
float life_left;
int ch_idx;
int first_to_die;
int life_left;
channel_t *ch;
if (entchannel<0)
Com_Error (ERR_DROP, "S_PickChannel: entchannel<0");
// Check for replacement sound, or find the best one to replace
first_to_die = -1;
life_left = 32768.0;
for (ch_idx = 0; ch_idx < MAX_CHANNELS; ch_idx++)
// Check for replacement sound, or find the best one to replace
first_to_die = -1;
life_left = 0x7fffffff;
for (ch_idx=0 ; ch_idx < MAX_CHANNELS ; ch_idx++)
{
if (entchannel != 0 // channel 0 never overrides
&& channels[ch_idx].entnum == entnum
@ -686,16 +692,16 @@ void S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float f
ps->sfx = sfx;
// drift s_beginofs
start = cl.frame.servertime * dma.speed + s_beginofs;
start = cl.frame.servertime * 0.001 * dma.speed + s_beginofs;
if (start < paintedtime)
{
start = paintedtime;
s_beginofs = start - (cl.frame.servertime * dma.speed);
s_beginofs = start - (cl.frame.servertime * 0.001 * dma.speed);
}
else if (start > paintedtime + 0.3 * dma.speed)
{
start = paintedtime + 0.1 * dma.speed;
s_beginofs = start - (cl.frame.servertime * dma.speed);
s_beginofs = start - (cl.frame.servertime * 0.001 * dma.speed);
}
else
{
@ -726,7 +732,7 @@ void S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float f
S_StartLocalSound
==================
*/
int S_StartLocalSound (const char *sound)
int S_StartLocalSound (char *sound)
{
sfx_t *sfx;
@ -886,7 +892,7 @@ void S_AddLoopSounds (void)
ch->rightvol = right_total;
ch->autosound = true; // remove next frame
ch->sfx = sfx;
ch->pos = fmod(paintedtime, sc->length);
ch->pos = paintedtime % sc->length;
ch->end = paintedtime + sc->length - ch->pos;
}
}
@ -920,7 +926,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
{ // optimized case
for (i=0 ; i<samples ; i++)
{
dst = (int)s_rawend & (MAX_RAW_SAMPLES - 1);
dst = s_rawend&(MAX_RAW_SAMPLES-1);
s_rawend++;
s_rawsamples[dst].left =
LittleShort(((short *)data)[i*2]) << 8;
@ -935,7 +941,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
src = i*scale;
if (src >= samples)
break;
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
dst = s_rawend&(MAX_RAW_SAMPLES-1);
s_rawend++;
s_rawsamples[dst].left =
LittleShort(((short *)data)[src*2]) << 8;
@ -951,7 +957,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
src = i*scale;
if (src >= samples)
break;
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
dst = s_rawend&(MAX_RAW_SAMPLES-1);
s_rawend++;
s_rawsamples[dst].left =
LittleShort(((short *)data)[src]) << 8;
@ -966,7 +972,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
src = i*scale;
if (src >= samples)
break;
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
dst = s_rawend&(MAX_RAW_SAMPLES-1);
s_rawend++;
s_rawsamples[dst].left =
((char *)data)[src*2] << 16;
@ -981,7 +987,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
src = i*scale;
if (src >= samples)
break;
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
dst = s_rawend&(MAX_RAW_SAMPLES-1);
s_rawend++;
s_rawsamples[dst].left =
(((byte *)data)[src]-128) << 16;
@ -1104,8 +1110,8 @@ void GetSoundtime(void)
void S_Update_(void)
{
uint endtime;
int samps;
unsigned endtime;
int samps;
if (!sound_started)
return;
@ -1121,7 +1127,7 @@ void S_Update_(void)
// check to make sure that we haven't overshot
if (paintedtime < soundtime)
{
MsgWarn("S_Update_: overflow [%g]\n", soundtime - paintedtime);
MsgWarn("S_Update_: overflow\n");
paintedtime = soundtime;
}

View File

@ -28,7 +28,7 @@ typedef struct
typedef struct
{
float length;
int length;
int loopstart;
int speed; // not needed, because converted on load?
int width;
@ -39,7 +39,7 @@ typedef struct
typedef struct sfx_s
{
char name[MAX_QPATH];
int registration_sequence;
int registration_sequence;
sfxcache_t *cache;
char *truename;
} sfx_t;
@ -53,21 +53,21 @@ typedef struct playsound_s
sfx_t *sfx;
float volume;
float attenuation;
int entnum;
int entchannel;
bool fixed_origin; // use origin field instead of entnum's origin
int entnum;
int entchannel;
bool fixed_origin; // use origin field instead of entnum's origin
vec3_t origin;
float begin; // begin on this sample
unsigned begin; // begin on this sample
} playsound_t;
typedef struct
{
int channels;
int samples; // mono samples in buffer
int submission_chunk; // don't mix less than this #
int samplepos; // in mono samples
int samplebits;
int speed;
int channels;
int samples; // mono samples in buffer
int submission_chunk; // don't mix less than this #
int samplepos; // in mono samples
int samplebits;
int speed;
byte *buffer;
} dma_t;
@ -75,18 +75,18 @@ typedef struct
typedef struct
{
sfx_t *sfx; // sfx number
int leftvol; // 0-255 volume
int rightvol; // 0-255 volume
float end; // end time in global paintsamples
int leftvol; // 0-255 volume
int rightvol; // 0-255 volume
int end; // end time in global paintsamples
int pos; // sample position in sfx
int looping; // where to loop, -1 = no looping OBSOLETE?
int entnum; // to allow overriding a specific sound
int entchannel; //
int looping; // where to loop, -1 = no looping OBSOLETE?
int entnum; // to allow overriding a specific sound
int entchannel; //
vec3_t origin; // only use if fixed_origin is set
vec_t dist_mult; // distance multiplier (attenuation/clipK)
int master_vol; // 0-255 master volume
bool fixed_origin; // use origin instead of fetching entnum's origin
bool autosound; // from an entity->sound, cleared each frame
int master_vol; // 0-255 master volume
bool fixed_origin; // use origin instead of fetching entnum's origin
bool autosound; // from an entity->sound, cleared each frame
} channel_t;
typedef struct
@ -126,8 +126,8 @@ void SNDDMA_Submit(void);
#define MAX_CHANNELS 32
extern channel_t channels[MAX_CHANNELS];
extern float paintedtime;
extern float s_rawend;
extern int paintedtime;
extern int s_rawend;
extern vec3_t listener_origin;
extern vec3_t listener_forward;
extern vec3_t listener_right;
@ -155,7 +155,7 @@ sfxcache_t *S_LoadSound (sfx_t *s);
void S_IssuePlaysound (playsound_t *ps);
void S_PaintChannels(float endtime);
void S_PaintChannels(int endtime);
// picks a channel based on priorities, empty slots, number of channels
channel_t *S_PickChannel(int entnum, int entchannel);

View File

@ -109,17 +109,17 @@ S_TransferPaintBuffer
===================
*/
void S_TransferPaintBuffer(float endtime)
void S_TransferPaintBuffer(int endtime)
{
int out_idx;
float count;
int count;
int out_mask;
int *p;
int step;
int val;
dword *pbuf;
int val;
unsigned long *pbuf;
pbuf = (dword*)dma.buffer;
pbuf = (unsigned long *)dma.buffer;
if (s_testsound->value)
{
@ -129,7 +129,7 @@ void S_TransferPaintBuffer(float endtime)
// write a fixed sine wave
count = (endtime - paintedtime);
for (i=0 ; i<count ; i++)
paintbuffer[i].left = paintbuffer[i].right = sin((paintedtime+i)*0.1)*20*256;
paintbuffer[i].left = paintbuffer[i].right = sin((paintedtime+i)*0.1)*20000*256;
}
@ -142,7 +142,7 @@ void S_TransferPaintBuffer(float endtime)
p = (int *) paintbuffer;
count = (endtime - paintedtime) * dma.channels;
out_mask = dma.samples - 1;
out_idx = (int)(paintedtime * dma.channels) & out_mask;
out_idx = paintedtime * dma.channels & out_mask;
step = 3 - dma.channels;
if (dma.samplebits == 16)
@ -190,18 +190,18 @@ CHANNEL MIXING
void S_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int endtime, int offset);
void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime, int offset);
void S_PaintChannels(float endtime)
void S_PaintChannels(int endtime)
{
int i;
float end;
channel_t *ch;
int i;
int end;
channel_t *ch;
sfxcache_t *sc;
float ltime, count;
int ltime, count;
playsound_t *ps;
snd_vol = s_volume->value*256;
//Msg ("%i to %i\n", paintedtime, endtime);
//Msg ("%i to %i\n", paintedtime, endtime);
while (paintedtime < endtime)
{
// if paintbuffer is smaller than DMA buffer
@ -221,11 +221,12 @@ void S_PaintChannels(float endtime)
continue;
}
if (ps->begin < end) end = ps->begin;// stop here
if (ps->begin < end)
end = ps->begin; // stop here
break;
}
// clear the paint buffer
// clear the paint buffer
if (s_rawend < paintedtime)
{
// Msg ("clear\n");
@ -241,7 +242,7 @@ void S_PaintChannels(float endtime)
for (i=paintedtime ; i<stop ; i++)
{
s = i&(MAX_RAW_SAMPLES-1);
paintbuffer[(int)(i - paintedtime)] = s_rawsamples[s];
paintbuffer[i-paintedtime] = s_rawsamples[s];
}
// if (i != end)
// Msg ("partial stream\n");
@ -249,8 +250,8 @@ void S_PaintChannels(float endtime)
// Msg ("full stream\n");
for ( ; i<end ; i++)
{
paintbuffer[(int)(i - paintedtime)].left =
paintbuffer[(int)(i - paintedtime)].right = 0;
paintbuffer[i-paintedtime].left =
paintbuffer[i-paintedtime].right = 0;
}
}

View File

@ -25,7 +25,7 @@ void S_Shutdown (void);
// if origin is NULL, the sound will be dynamically sourced from the entity
void S_StartSound (vec3_t origin, int entnum, int entchannel, struct sfx_s *sfx, float fvol, float attenuation, float timeofs);
int S_StartLocalSound (const char *s);
int S_StartLocalSound (char *s);
void S_RawSamples (int samples, int rate, int width, int channels, byte *data);
@ -35,10 +35,10 @@ void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up);
void S_Activate (bool active);
void S_BeginRegistration (void);
struct sfx_s *S_RegisterSound (const char *sample);
struct sfx_s *S_RegisterSound (char *sample);
void S_EndRegistration (void);
struct sfx_s *S_FindName (const char *name, bool create);
struct sfx_s *S_FindName (char *name, bool create);
// the sound code makes callbacks to the client for entitiy position
// information, so entities can be dynamically re-spatialized

View File

@ -27,6 +27,10 @@ extern HWND cl_hwnd;
//engine builddate
char *buildstring = __TIME__ " " __DATE__;
stdinout_api_t std;
uint sys_msg_time;
uint sys_frame_time;
int starttime;
/*
===============================================================================
@ -79,34 +83,12 @@ void Sys_Init (void)
{
OSVERSIONINFO vinfo;
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
timeBeginPeriod( 1 );
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
if (!GetVersionEx (&vinfo)) Sys_Error ("Couldn't get OS info");
if (vinfo.dwMajorVersion < 4) Sys_Error ("%s requires windows version 4 or greater", GI.title);
srand(time(NULL));
}
/*
================
Sys_Milliseconds
================
*/
int Sys_Milliseconds ( void )
{
int sys_curtime;
static int sys_timeBase;
static bool init = false;
if (!init)
{
sys_timeBase = timeGetTime();
init = true;
}
sys_curtime = timeGetTime() - sys_timeBase;
return sys_curtime;
}
/*
@ -118,20 +100,18 @@ Send Key_Event calls
*/
void Sys_SendKeyEvents (void)
{
MSG msg;
rand();
MSG msg;
while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!GetMessage (&msg, NULL, 0, 0)) Sys_Quit ();
host.sv_timer = msg.time;
sys_msg_time = msg.time;
TranslateMessage (&msg);
DispatchMessage (&msg);
}
// grab frame time
host.cl_timer = timeGetTime(); // FIXME: should this be at start?
sys_frame_time = timeGetTime(); // FIXME: should this be at start?
}
@ -165,6 +145,28 @@ char *Sys_GetClipboardData( void )
return data;
}
/*
================
Sys_Milliseconds
================
*/
int curtime;
int Sys_Milliseconds (void)
{
static int sys_timeBase;
static bool init = false;
if (!init)
{
sys_timeBase = timeGetTime();
init = true;
}
curtime = timeGetTime() - sys_timeBase;
return curtime;
}
/*
==============================================================================
@ -184,80 +186,6 @@ void Sys_AppActivate (void)
SetForegroundWindow ( cl_hwnd );
}
/*
========================================================================
GAME DLL
========================================================================
*/
/*
=================
Sys_UnloadGame
=================
*/
void Sys_UnloadGame( void *hinstance )
{
if(!hinstance) return;
FreeLibrary(hinstance);
hinstance = NULL;
}
/*
=================
Sys_LoadGame
Loads the game dll
=================
*/
void *Sys_LoadGame (const char* procname, void *hinstance, void *parms)
{
void *(*GetGameAPI) (void *);
char basepath[MAX_SYSPATH];
search_t *gamedll;
int i;
Sys_UnloadGame( hinstance );
//find server.dll
gamedll = FS_Search( "bin/*.dll" );
if(!gamedll)
{
Com_Error (ERR_DROP, "Can't find game.dll\n");
return NULL;
}
// now run through the search paths
for( i = 0; i < gamedll->numfilenames; i++ )
{
sprintf(basepath, "%s/%s", GI.gamedir, gamedll->filenames[i]);
hinstance = LoadLibrary ( basepath );
if (!hinstance)
{
sprintf(basepath, "%s/%s", GI.basedir, gamedll->filenames[i]);
hinstance = LoadLibrary ( basepath );
}
if (hinstance)
{
if (( GetGameAPI = (void *)GetProcAddress( hinstance, procname )) == 0 )
Sys_UnloadGame( hinstance );
else break;
}
else MsgWarn("Can't loading %s\n", gamedll->filenames[i] );
}
GetGameAPI = (void *)GetProcAddress (hinstance, procname );
if (!GetGameAPI)
{
Sys_UnloadGame( hinstance );
return NULL;
}
return GetGameAPI (parms);
}
//=======================================================================
/*

View File

@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
renderer_exp_t *re;
extern HWND cl_hwnd;
extern bool ActiveApp, Minimized;
extern HINSTANCE global_hInstance;
#ifndef WM_MOUSEWHEEL
@ -54,6 +55,9 @@ HWND cl_hwnd; // Main window handle for life of program
LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
extern unsigned sys_msg_time;
/*
==========================================================================
@ -179,25 +183,29 @@ int MapKey (int key)
}
}
void AppActivate(bool fActive, bool fMinimize)
void AppActivate(BOOL fActive, BOOL minimize)
{
if(fActive && !fMinimize) host.state = HOST_FRAME;
else if(fMinimize) host.state = HOST_SLEEP;
else host.state = HOST_NOFOCUS;
Minimized = minimize;
Key_ClearStates();
// minimize/restore mouse-capture on demand
if(host.state == HOST_FRAME)
{
IN_Activate (true);
S_Activate (true);
}
// we don't want to act like we're active if we're minimized
if (fActive && !Minimized)
ActiveApp = true;
else
ActiveApp = false;
// minimize/restore mouse-capture on demand
if (!ActiveApp)
{
IN_Activate (false);
S_Activate (false);
}
else
{
IN_Activate (true);
S_Activate (true);
}
}
/*
@ -215,13 +223,13 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if ( ( ( int ) wParam ) > 0 )
{
Key_Event( K_MWHEELUP, true, host.sv_timer );
Key_Event( K_MWHEELUP, false, host.sv_timer );
Key_Event( K_MWHEELUP, true, sys_msg_time );
Key_Event( K_MWHEELUP, false, sys_msg_time );
}
else
{
Key_Event( K_MWHEELDOWN, true, host.sv_timer );
Key_Event( K_MWHEELDOWN, false, host.sv_timer );
Key_Event( K_MWHEELDOWN, true, sys_msg_time );
Key_Event( K_MWHEELDOWN, false, sys_msg_time );
}
return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
@ -235,13 +243,13 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
*/
if ( ( short ) HIWORD( wParam ) > 0 )
{
Key_Event( K_MWHEELUP, true, host.sv_timer );
Key_Event( K_MWHEELUP, false, host.sv_timer );
Key_Event( K_MWHEELUP, true, sys_msg_time );
Key_Event( K_MWHEELUP, false, sys_msg_time );
}
else
{
Key_Event( K_MWHEELDOWN, true, host.sv_timer );
Key_Event( K_MWHEELDOWN, false, host.sv_timer );
Key_Event( K_MWHEELDOWN, true, sys_msg_time );
Key_Event( K_MWHEELDOWN, false, sys_msg_time );
}
break;
@ -297,7 +305,7 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Cvar_SetValue( "vid_ypos", yPos + r.top);
vid_xpos->modified = false;
vid_ypos->modified = false;
if (host.state == HOST_FRAME)
if (ActiveApp)
IN_Activate (true);
}
}
@ -343,11 +351,11 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
// fall through
case WM_KEYDOWN:
Key_Event( MapKey( lParam ), true, host.sv_timer);
Key_Event( MapKey( lParam ), true, sys_msg_time);
break;
case WM_SYSKEYUP:
case WM_KEYUP:
Key_Event( MapKey( lParam ), false, host.sv_timer);
Key_Event( MapKey( lParam ), false, sys_msg_time);
break;
default: // pass all unhandled messages to DefWindowProc
return DefWindowProc (hWnd, uMsg, wParam, lParam);
@ -462,12 +470,6 @@ char *FS_Title( void )
return GI.title;
}
cvar_t *VID_Cvar_Set (const char *var_name, const char *value)
{
return Cvar_Set( var_name, value );
}
/*
==============
VID_InitRenderer
@ -496,7 +498,7 @@ void VID_InitRenderer( void )
ri.gamedir = FS_Gamedir;
ri.title = FS_Title;
ri.Cvar_Get = Cvar_Get;
ri.Cvar_Set = VID_Cvar_Set;
ri.Cvar_Set = Cvar_Set;
ri.Cvar_SetValue = Cvar_SetValue;
ri.Vid_GetModeInfo = VID_GetModeInfo;
ri.Vid_MenuInit = VID_MenuInit;

View File

@ -33,13 +33,12 @@ _inline void VectorScale(const vec3_t a, const float b, vec3_t c){c[0]=b*a[0];c[
#define VectorSet(v, x, y, z) {v[0] = x; v[1] = y; v[2] = z;}
#define VectorClear(x) {x[0] = x[1] = x[2] = 0;}
#define VectorNegate(x, y) {y[0] =-x[0]; y[1]=-x[1]; y[2]=-x[2];}
_inline float anglemod(const float a){return(360.0/65536) * ((int)(a*(65536/360.0)) & 65535);}
#define VectorM(scale1, b1, c) ((c)[0] = (scale1) * (b1)[0],(c)[1] = (scale1) * (b1)[1],(c)[2] = (scale1) * (b1)[2])
#define VectorMA(a, scale, b, c) ((c)[0] = (a)[0] + (scale) * (b)[0],(c)[1] = (a)[1] + (scale) * (b)[1],(c)[2] = (a)[2] + (scale) * (b)[2])
#define VectorMAM(scale1, b1, scale2, b2, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2])
#define VectorMAMAM(scale1, b1, scale2, b2, scale3, b3, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0] + (scale3) * (b3)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1] + (scale3) * (b3)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2] + (scale3) * (b3)[2])
#define VectorMAMAMAM(scale1, b1, scale2, b2, scale3, b3, scale4, b4, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0] + (scale3) * (b3)[0] + (scale4) * (b4)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1] + (scale3) * (b3)[1] + (scale4) * (b4)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2] + (scale3) * (b3)[2] + (scale4) * (b4)[2])
_inline float anglemod(const float a){return(360.0/65536) * ((int)(a*(65536/360.0)) & 65535);}
_inline void VectorBound(const float min, vec3_t v, const float max)
{
@ -130,13 +129,6 @@ _inline void VectorIRotate (const vec3_t in1, const matrix3x4 in2, vec3_t out)
out[2] = in1[0] * in2[0][2] + in1[1] * in2[1][2] + in1[2] * in2[2][2];
}
_inline void VectorMA (vec3_t va, double scale, vec3_t vb, vec3_t vc)
{
vc[0] = va[0] + scale * vb[0];
vc[1] = va[1] + scale * vb[1];
vc[2] = va[2] + scale * vb[2];
}
_inline void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross)
{
cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
@ -177,7 +169,7 @@ _inline void VectorVectors(vec3_t forward, vec3_t right, vec3_t up)
CrossProduct(right, forward, up);
}
_inline void AngleVectorsRight(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
_inline void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
{
float angle;
static float sr, sp, sy, cr, cp, cy;
@ -199,45 +191,21 @@ _inline void AngleVectorsRight(vec3_t angles, vec3_t forward, vec3_t right, vec3
forward[1] = cp*sy;
forward[2] = -sp;
}
if (right || up)
if (right)
{
if (angles[ROLL])
{
angle = angles[ROLL] * (M_PI*2 / 360);
sr = sin(angle);
cr = cos(angle);
if (right)
{
right[0] = -1*(sr*sp*cy+cr*-sy);
right[1] = -1*(sr*sp*sy+cr*cy);
right[2] = -1*(sr*cp);
}
if (up)
{
up[0] = (cr*sp*cy+-sr*-sy);
up[1] = (cr*sp*sy+-sr*cy);
up[2] = cr*cp;
}
}
else
{
if (right)
{
right[0] = sy;
right[1] = -cy;
right[2] = 0;
}
if (up)
{
up[0] = (sp*cy);
up[1] = (sp*sy);
up[2] = cp;
}
}
right[0] = (-1*sr*sp*cy+-1*cr*-sy);
right[1] = (-1*sr*sp*sy+-1*cr*cy);
right[2] = -1*sr*cp;
}
if (up)
{
up[0] = (cr*sp*cy+-sr*-sy);
up[1] = (cr*sp*sy+-sr*cy);
up[2] = cr*cp;
}
}
_inline void AngleVectorsLeft(const vec3_t angles, vec3_t forward, vec3_t left, vec3_t up)
_inline void AngleVectorsFLU(const vec3_t angles, vec3_t forward, vec3_t left, vec3_t up)
{
float angle;
static float sr, sp, sy, cr, cp, cy;

View File

@ -44,6 +44,8 @@ typedef struct vfile_s vfile_t;
typedef struct image_s image_t;
typedef struct model_s model_t;
typedef int func_t;
typedef struct edict_s edict_t;
typedef struct gclient_s gclient_t;
typedef int string_t;
typedef int progsnum_t;
typedef struct progfuncs_s progfuncs_t;

View File

@ -207,15 +207,6 @@ typedef struct cmodel_s
vec3_t mins, maxs; // boundbox
vec3_t origin; // for sounds or lights
int headnode; // bsp info
vec3_t normalmins; // bounding box at angles '0 0 0'
vec3_t normalmaxs;
vec3_t yawmins; // bounding box if yaw angle is not 0, but pitch and roll are used
vec3_t yawmaxs;
vec3_t rotatedmins; // bounding box if pitch or roll are used
vec3_t rotatedmaxs;
int numframes; //sprite framecount
void *extradata; //for studio models

View File

@ -79,10 +79,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PRINT_HIGH 2 // critical messages
#define PRINT_CHAT 3 // chat messages
#define SPAWNFLAG_NOT_EASY 256
#define SPAWNFLAG_NOT_MEDIUM 512
#define SPAWNFLAG_NOT_HARD 1024
#define SPAWNFLAG_NOT_DEATHMATCH 2048
#define SPAWNFLAG_NOT_EASY 0x00000100
#define SPAWNFLAG_NOT_MEDIUM 0x00000200
#define SPAWNFLAG_NOT_HARD 0x00000400
#define SPAWNFLAG_NOT_DEATHMATCH 0x00000800
// entity_state_t->renderfx flags
#define RF_MINLIGHT 1 // allways have some light (viewmodel)
@ -148,29 +148,23 @@ typedef enum
WEAPON_FIRING
} weaponstate_t;
typedef enum
{
SOLID_NOT, // no interaction with other objects
SOLID_TRIGGER, // only touch when inside, after moving
SOLID_BBOX, // touch on edge
SOLID_BSP // bsp clip, touch on edge
} solid_t;
typedef enum
{
MOVETYPE_NONE = 0, // never moves, but can collide
MOVETYPE_NOCLIP, // origin and angles change with no interaction
MOVETYPE_PUSH, // no clip to world, push on box contact
MOVETYPE_WALK, // player case
MOVETYPE_STEP, // monster case (get rid of this)
MOVETYPE_FLY, // ignore gravity
MOVETYPE_TOSS, // gravity
MOVETYPE_BOUNCE,
MOVETYPE_FOLLOW, // attached models
MOVETYPE_COMPLEX, // complex moving ents (parent system)
MOVETYPE_RAGDOLL, // npc ragdoll (not implemented yet)
} movetype_t;
#define MOVETYPE_NONE 0 // never moves
#define MOVETYPE_NOCLIP 1 // origin and angles change with no interaction
#define MOVETYPE_PUSH 2 // no clip to world, push on box contact
#define MOVETYPE_STOP 3 // no clip to world, stops on box contact
#define MOVETYPE_WALK 4 // gravity
#define MOVETYPE_STEP 5 // gravity, special edge handling
#define MOVETYPE_FLY 6
#define MOVETYPE_TOSS 7 // gravity
#define MOVETYPE_FLYMISSILE 8 // extra size to monsters
#define MOVETYPE_BOUNCE 9
#define MOVETYPE_FOLLOW 10 // attached models
#define MOVETYPE_VEHICLE 11
#define MOVETYPE_PUSHABLE 12
#define MOVETYPE_DEBRIS 13 // non-solid debris that can still hurt you
#define MOVETYPE_RAIN 14 // identical to MOVETYPE_FLYMISSILE, but doesn't cause splash noises when touching water.
#define MOVETYPE_PENDULUM 15 // same as MOVETYPE_PUSH, but used only for pendulums to grab special-case problems
#define MOVETYPE_CONVEYOR 16
/*
==============================================================
@ -217,8 +211,30 @@ void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal );
void PerpendicularVector( vec3_t dst, const vec3_t src );
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );
void Com_PageInMemory (byte *buffer, int size);
//=============================================
//
// key / value info strings
//
char *Info_ValueForKey (char *s, char *key);
void Info_RemoveKey (char *s, char *key);
void Info_SetValueForKey (char *s, char *key, char *value);
bool Info_Validate (char *s);
/*
==============================================================
SYSTEM SPECIFIC
==============================================================
*/
extern int curtime; // time returned by last Sys_Milliseconds
/*
==============================================================
@ -247,16 +263,14 @@ COLLISION DETECTION
// a trace is returned when a box is swept through the world
typedef struct
{
bool allsolid; // if true, plane is not valid
bool startsolid; // if true, the initial point was in a solid area
bool startstuck; // if true, the initial point was stuck into SOLID_BSP model
float fraction; // time completed, 1.0 = didn't hit anything
bool allsolid; // if true, plane is not valid
bool startsolid; // if true, the initial point was in a solid area
float fraction; // time completed, 1.0 = didn't hit anything
vec3_t endpos; // final position
cplane_t plane; // surface normal at impact
csurface_t *surface; // surface hit
int contents; // contents on other side of surface hit
prvm_edict_t *ent; // not set by CM_*() functions
cplane_t plane; // surface normal at impact
csurface_t *surface; // surface hit
int contents; // contents on other side of surface hit
struct edict_s *ent; // not set by CM_*() functions
} trace_t;
@ -298,7 +312,7 @@ typedef struct
byte pm_time; // each unit = 8 ms
short gravity;
short delta_angles[3]; // add to command angles to get view direction
// changed by spawns, rotating objects, and teleporters
// changed by spawns, rotating objects, and teleporters
} pmove_state_t;
@ -324,7 +338,6 @@ typedef struct usercmd_s
short forwardmove, sidemove, upmove;
byte impulse; // remove?
byte lightlevel; // light level the player is standing on
} usercmd_t;
@ -340,14 +353,14 @@ typedef struct
// results (out)
int numtouch;
prvm_edict_t *touchents[MAXTOUCH];
struct edict_s *touchents[MAXTOUCH];
vec3_t viewangles; // clamped
float viewheight;
vec3_t mins, maxs; // bounding box size
prvm_edict_t *groundentity;
struct edict_s *groundentity;
int watertype;
int waterlevel;
@ -790,16 +803,16 @@ typedef struct
// these fields do not need to be communicated bit-precise
vec3_t viewangles; // for fixed views
vec3_t viewoffset; // add to pmovestate->origin
vec3_t viewangles; // for fixed views
vec3_t viewoffset; // add to pmovestate->origin
vec3_t kick_angles; // add to view direction to get render angles
// set by weapon kicks, pain effects, etc
// set by weapon kicks, pain effects, etc
vec3_t gunangles;
vec3_t gunoffset;
int gunindex;
int gunframe; // studio frame
int sequence; // studio animation sequence
int sequence; // stuido animation sequence
int gunbody;
int gunskin;

View File

@ -1,11 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// ref_client.h - client user interface
//=======================================================================
#ifndef REF_CLIENT_H
#define REF_CLIENT_H
//dll handle
typedef void *(*client_api_t)(void);
#endif//REF_CLIENT_H

View File

@ -1,201 +0,0 @@
// game.h -- game dll information visible to server
#include "savefile.h"
#define GAME_API_VERSION 3
// edict->svflags
#define SVF_NOCLIENT 0x00000001 // don't send entity to clients, even if it has effects
#define SVF_DEADMONSTER 0x00000002 // treat as CONTENTS_DEADMONSTER for collision
#define SVF_MONSTER 0x00000004 // treat as CONTENTS_MONSTER for collision
// edict->solid values
typedef enum
{
SOLID_NOT, // no interaction with other objects
SOLID_TRIGGER, // only touch when inside, after moving
SOLID_BBOX, // touch on edge
SOLID_BSP // bsp clip, touch on edge
} solid_t;
//===============================================================
// link_t is only used for entity area links now
typedef struct link_s
{
struct link_s *prev, *next;
} link_t;
#define MAX_ENT_CLUSTERS 16
#ifndef GAME_INCLUDE
struct gclient_s
{
player_state_t ps; // communicated by server to clients
int ping;
// the game dll can add anything it wants after
// this point in the structure
};
struct edict_s
{
entity_state_t s;
struct gclient_s *client;
bool inuse;
int linkcount;
// FIXME: move these fields to a server private sv_entity_t
link_t area; // linked to a division node or leaf
int num_clusters; // if -1, use headnode instead
int clusternums[MAX_ENT_CLUSTERS];
int headnode; // unused if num_clusters != -1
int areanum, areanum2;
//================================
int svflags; // SVF_NOCLIENT, SVF_DEADMONSTER, SVF_MONSTER, etc
vec3_t mins, maxs;
vec3_t absmin, absmax, size;
solid_t solid;
int clipmask;
edict_t *owner;
// the game dll can add anything it wants after
// this point in the structure
};
#endif // GAME_INCLUDE
//===============================================================
//
// functions provided by the main engine
//
typedef struct game_import_s
{
//shared xash systems
filesystem_api_t Fs;
vfilesystem_api_t VFs;
memsystem_api_t Mem;
scriptsystem_api_t Script; // basic script-machine
compilers_api_t Compile; // compilers callback
infostring_api_t Info;
message_write_t Msg; // network messaging
// special messages
void (*bprintf) (int printlevel, char *fmt, ...);
void (*dprintf) (char *fmt, ...);
void (*cprintf) (edict_t *ent, int printlevel, char *fmt, ...);
void (*centerprintf) (edict_t *ent, char *fmt, ...);
void (*sound) (edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs);
void (*positioned_sound) (vec3_t origin, edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs);
// get game info
gameinfo_t (*GameInfo)( void );
// config strings hold all the index strings, the lightstyles,
// and misc data like the sky definition and cdtrack.
// All of the current configstrings are sent to clients when
// they connect, and changes are sent to all connected clients.
void (*configstring) (int num, char *string);
void (*error) (char *fmt, ...);
// the *index functions create configstrings and some internal server state
int (*modelindex) (char *name);
int (*soundindex) (char *name);
int (*imageindex) (char *name);
void (*setmodel) (edict_t *ent, char *name);
// collision detection
trace_t (*trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passent, int contentmask);
int (*pointcontents) (vec3_t point);
bool (*inPVS) (vec3_t p1, vec3_t p2);
bool (*inPHS) (vec3_t p1, vec3_t p2);
void (*SetAreaPortalState) (int portalnum, bool open);
bool (*AreasConnected) (int area1, int area2);
// an entity will never be sent to a client or used for collision
// if it is not passed to linkentity. If the size, position, or
// solidity changes, it must be relinked.
void (*linkentity) (edict_t *ent);
void (*unlinkentity) (edict_t *ent); // call before removing an interactive edict
int (*BoxEdicts) (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype);
void (*Pmove) (pmove_t *pmove); // player movement code common with client prediction
// common studio utils
byte *(*getmodelhdr) (edict_t *ent);//returned a pointer on a studiohdr_t for current entity
// console variable interaction
cvar_t *(*cvar) (char *var_name, char *value, int flags);
cvar_t *(*cvar_set) (char *var_name, char *value);
cvar_t *(*cvar_forceset) (char *var_name, char *value);
// ClientCommand and ServerCommand parameter access
int (*argc) (void);
char *(*argv) (int n);
char *(*args) (void); // concatenation of all argv >= 1
// add commands to the server console as if they were typed in
// for map changing, etc
void (*AddCommandString) (char *text);
void (*DebugGraph) (float value, int color);
} game_import_t;
//
// functions exported by the game subsystem
//
typedef struct game_export_s
{
int apiversion;
// the init function will only be called when a game starts,
// not each time a level is loaded. Persistant data for clients
// and the server can be allocated in init
void (*Init) (void);
void (*Shutdown) (void);
// each new level entered will cause a call to SpawnEntities
void (*SpawnEntities) (char *mapname, char *entstring, char *spawnpoint);
void (*WriteLump) (dsavehdr_t *hdr, file_t *f, int lumpnum, bool autosave);
void (*ReadLump) (byte *base, lump_t *l, int lumpnum);
bool (*ClientConnect) (edict_t *ent, char *userinfo);
void (*ClientBegin) (edict_t *ent);
void (*ClientUserinfoChanged) (edict_t *ent, char *userinfo);
void (*ClientDisconnect) (edict_t *ent);
void (*ClientCommand) (edict_t *ent);
void (*ClientThink) (edict_t *ent, usercmd_t *cmd);
void (*RunFrame) (void);
// ServerCommand will be called when an "sv <command>" command is issued on the
// server console.
// The game can issue gi.argc() / gi.argv() commands to get the rest
// of the parameters
void (*ServerCommand) (void);
//
// global variables shared between game and server
//
// The edict array is allocated in the game dll so it
// can vary in size from one game to another.
//
// The size will be fixed when ge->Init() is called
edict_t *edicts;
int edict_size;
int num_edicts; // current number, <= max_edicts
int max_edicts;
} game_export_t;
//dll handle
typedef game_export_t (*server_api_t)(game_import_t);

View File

@ -293,7 +293,7 @@ typedef struct
float vieworg[3];
float viewangles[3];
float blend[4]; // rgba 0-1 full screen blend
double time; // time is used to auto animate
float time; // time is used to auto animate
int rdflags; // RDF_UNDERWATER, etc
byte *areabits; // if not NULL, only areas with set bits will be drawn

View File

@ -24,7 +24,7 @@ if errorlevel 1 set BUILD_ERROR=1
%MSDEV% renderer/renderer.dsp %CONFIG%"renderer - Win32 Release" %build_target%
if errorlevel 1 set BUILD_ERROR=1
progs\qcclib.exe -O3
progs\qcclib.exe
if errorlevel 1 set BUILD_ERROR=1
if "%BUILD_ERROR%"=="" goto build_ok
@ -56,5 +56,5 @@ if exist progs\server.dat copy progs\server.dat D:\Xash3D\xash\server.dat
echo Build succeeded!
echo Please wait. Xash is now loading
cd D:\Xash3D\
xash.exe +map qctest
xash.exe -game valve +map skytest -debug
:done

View File

@ -125,7 +125,7 @@ void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
// move should be the delta back to the previous frame * backlerp
VectorSubtract (currententity->oldorigin, currententity->origin, delta);
AngleVectorsRight(currententity->angles, vectors[0], vectors[1], vectors[2]);
AngleVectors(currententity->angles, vectors[0], vectors[1], vectors[2]);
move[0] = DotProduct (delta, vectors[0]); // forward
move[1] = -DotProduct (delta, vectors[1]); // left
@ -454,7 +454,7 @@ static bool R_CullAliasModel( vec3_t bbox[8], entity_t *e )
*/
VectorCopy( e->angles, angles );
angles[YAW] = -angles[YAW];
AngleVectorsRight( angles, vectors[0], vectors[1], vectors[2] );
AngleVectors( angles, vectors[0], vectors[1], vectors[2] );
for ( i = 0; i < 8; i++ )
{

View File

@ -499,7 +499,7 @@ void R_SetupFrame (void)
// build the transformation matrix for the given view angles
VectorCopy (r_newrefdef.vieworg, r_origin);
AngleVectorsRight(r_newrefdef.viewangles, vforward, vright, vup);
AngleVectors(r_newrefdef.viewangles, vforward, vright, vup);
// current viewcluster
if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )

View File

@ -976,7 +976,7 @@ void R_DrawBrushModel ( int passnum )
vec3_t forward, right, up;
VectorCopy (modelorg, temp);
AngleVectorsRight(e->angles, forward, right, up);
AngleVectors(e->angles, forward, right, up);
modelorg[0] = DotProduct (temp, forward);
modelorg[1] = -DotProduct (temp, right);
modelorg[2] = DotProduct (temp, up);

View File

@ -281,7 +281,7 @@ void R_DrawSpriteModel( int passnum )
switch( psprite->type )
{
case SPR_ORIENTED:
AngleVectorsRight(e->angles, forward, right, up);
AngleVectors(e->angles, forward, right, up);
VectorScale(forward, 0.01, forward );//offset for decals
VectorSubtract(e->origin, forward, e->origin );
break;

View File

@ -1012,7 +1012,7 @@ static bool R_StudioComputeBBox( vec3_t *bbox )
//rotate the bounding box
VectorCopy( e->angles, angles );
angles[PITCH] = -angles[PITCH];
AngleVectorsRight( angles, vectors[0], vectors[1], vectors[2] );
AngleVectors( angles, vectors[0], vectors[1], vectors[2] );
for ( i = 0; i < 8; i++ )
{