07 Sep 2007
This commit is contained in:
parent
d6ccf91e53
commit
539c0a6ebb
|
@ -6,10 +6,12 @@ SV_Move SV_Trace
|
||||||
SV_ClipMoveToEntity CM_BoxTrace
|
SV_ClipMoveToEntity CM_BoxTrace
|
||||||
SV_ClipToLinks SV_ClipMoveToEntities
|
SV_ClipToLinks SV_ClipMoveToEntities
|
||||||
|
|
||||||
//==================================================
|
1. Перенести основные части gamed.dll в движок OK
|
||||||
// FIXME
|
2. Попытка полностью отказаться от gamed.dll OK
|
||||||
//==================================================
|
3. Перенести физику в движок OK
|
||||||
1. Пофиксить движение игрока (сл. большая скорость)
|
4. Восстановить изменения кода до 06.09.07 (кроме PRVM)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==================================================
|
//==================================================
|
||||||
// òî, ÷òî óæå ãîòîâî
|
// òî, ÷òî óæå ãîòîâî
|
||||||
|
|
|
@ -55,5 +55,5 @@ if exist progs\server.dat copy progs\server.dat D:\Xash3D\xash\server.dat
|
||||||
echo Build succeeded!
|
echo Build succeeded!
|
||||||
echo Please wait. Xash is now loading
|
echo Please wait. Xash is now loading
|
||||||
cd D:\Xash3D\
|
cd D:\Xash3D\
|
||||||
xash.exe +map qctest -debug
|
xash.exe +map qctest -log
|
||||||
:done
|
:done
|
|
@ -402,17 +402,17 @@ void SCR_RunCinematic (void)
|
||||||
|
|
||||||
if (cls.key_dest != key_game)
|
if (cls.key_dest != key_game)
|
||||||
{ // pause if menu or console is up
|
{ // pause if menu or console is up
|
||||||
cl.cinematictime = cls.realtime - cl.cinematicframe/14;
|
cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = (cls.realtime - cl.cinematictime)*14.0;
|
frame = (cls.realtime - cl.cinematictime)*14.0/1000;
|
||||||
if (frame <= cl.cinematicframe)
|
if (frame <= cl.cinematicframe)
|
||||||
return;
|
return;
|
||||||
if (frame > cl.cinematicframe+1)
|
if (frame > cl.cinematicframe+1)
|
||||||
{
|
{
|
||||||
Msg ("Dropped frame: %i > %i\n", 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)
|
if (cin.pic)
|
||||||
Z_Free (cin.pic);
|
Z_Free (cin.pic);
|
||||||
|
@ -546,5 +546,5 @@ void SCR_PlayCinematic (char *arg)
|
||||||
|
|
||||||
cl.cinematicframe = 0;
|
cl.cinematicframe = 0;
|
||||||
cin.pic = SCR_ReadNextFrame ();
|
cin.pic = SCR_ReadNextFrame ();
|
||||||
cl.cinematictime = cls.realtime;
|
cl.cinematictime = Sys_Milliseconds ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
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
|
ent->trailcount = 1024; // for diminishing rocket / grenade trails
|
||||||
// duplicate the current state so lerping doesn't hurt anything
|
// duplicate the current state so lerping doesn't hurt anything
|
||||||
ent->prev = *state;
|
ent->prev = *state;
|
||||||
|
@ -657,7 +656,7 @@ void CL_ParseFrame (void)
|
||||||
|
|
||||||
cl.frame.serverframe = MSG_ReadLong (&net_message);
|
cl.frame.serverframe = MSG_ReadLong (&net_message);
|
||||||
cl.frame.deltaframe = 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
|
// BIG HACK to let old demos continue to work
|
||||||
if (cls.serverProtocol != 26)
|
if (cls.serverProtocol != 26)
|
||||||
|
@ -700,8 +699,8 @@ void CL_ParseFrame (void)
|
||||||
// clamp time
|
// clamp time
|
||||||
if (cl.time > cl.frame.servertime)
|
if (cl.time > cl.frame.servertime)
|
||||||
cl.time = cl.frame.servertime;
|
cl.time = cl.frame.servertime;
|
||||||
else if (cl.time < cl.frame.servertime - 0.1)
|
else if (cl.time < cl.frame.servertime - 100)
|
||||||
cl.time = cl.frame.servertime - 0.1;
|
cl.time = cl.frame.servertime - 100;
|
||||||
|
|
||||||
// read areabits
|
// read areabits
|
||||||
len = MSG_ReadByte (&net_message);
|
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[1] = cl.frame.playerstate.pmove.origin[1]*0.125;
|
||||||
cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2]*0.125;
|
cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2]*0.125;
|
||||||
VectorCopy (cl.frame.playerstate.viewangles, cl.predicted_angles);
|
VectorCopy (cl.frame.playerstate.viewangles, cl.predicted_angles);
|
||||||
if (cls.disable_servercount != cl.servercount && cl.refresh_prepped)
|
if (cls.disable_servercount != cl.servercount
|
||||||
SCR_EndLoadingPlaque (); // get rid of loading plaque
|
&& cl.refresh_prepped)
|
||||||
|
SCR_EndLoadingPlaque (); // get rid of loading plaque
|
||||||
}
|
}
|
||||||
cl.sound_prepped = true; // can start mixing ambient sounds
|
cl.sound_prepped = true; // can start mixing ambient sounds
|
||||||
|
|
||||||
|
@ -829,7 +829,7 @@ void CL_AddPacketEntities (frame_t *frame)
|
||||||
autorotate = anglemod(cl.time/10);
|
autorotate = anglemod(cl.time/10);
|
||||||
|
|
||||||
// brush models can auto animate their frames
|
// brush models can auto animate their frames
|
||||||
autoanim = 2 * cl.time;
|
autoanim = 2*cl.time/1000;
|
||||||
|
|
||||||
memset (&ent, 0, sizeof(ent));
|
memset (&ent, 0, sizeof(ent));
|
||||||
|
|
||||||
|
@ -850,7 +850,7 @@ void CL_AddPacketEntities (frame_t *frame)
|
||||||
else if (effects & EF_ANIM_ALL)
|
else if (effects & EF_ANIM_ALL)
|
||||||
ent.frame = autoanim;
|
ent.frame = autoanim;
|
||||||
else if (effects & EF_ANIM_ALLFAST)
|
else if (effects & EF_ANIM_ALLFAST)
|
||||||
ent.frame = cl.time * 0.1;
|
ent.frame = cl.time / 100;
|
||||||
else
|
else
|
||||||
ent.frame = s1->frame;
|
ent.frame = s1->frame;
|
||||||
|
|
||||||
|
@ -974,7 +974,7 @@ void CL_AddPacketEntities (frame_t *frame)
|
||||||
vec3_t forward;
|
vec3_t forward;
|
||||||
vec3_t start;
|
vec3_t start;
|
||||||
|
|
||||||
AngleVectorsRight(ent.angles, forward, NULL, NULL);
|
AngleVectors (ent.angles, forward, NULL, NULL);
|
||||||
VectorMA (ent.origin, 64, forward, start);
|
VectorMA (ent.origin, 64, forward, start);
|
||||||
V_AddLight (start, 100, 1, 0, 0);
|
V_AddLight (start, 100, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -1231,7 +1231,8 @@ void CL_CalcViewValues (void)
|
||||||
|
|
||||||
// smooth out stair climbing
|
// smooth out stair climbing
|
||||||
delta = cls.realtime - cl.predicted_step_time;
|
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
|
else
|
||||||
{ // just use interpolated values
|
{ // just use interpolated values
|
||||||
|
@ -1256,7 +1257,7 @@ void CL_CalcViewValues (void)
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i=0 ; i<3 ; i++)
|
||||||
cl.refdef.viewangles[i] += LerpAngle (ops->kick_angles[i], ps->kick_angles[i], lerp);
|
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
|
// interpolate field of view
|
||||||
cl.refdef.fov_x = ops->fov + lerp * (ps->fov - ops->fov);
|
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.time = cl.frame.servertime;
|
||||||
cl.lerpfrac = 1.0;
|
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)
|
if (cl_showclamp->value)
|
||||||
Msg ("low clamp %i\n", cl.frame.servertime - 0.1 - cl.time);
|
Msg ("low clamp %i\n", cl.frame.servertime-100 - cl.time);
|
||||||
cl.time = cl.frame.servertime - 0.1;
|
cl.time = cl.frame.servertime - 100;
|
||||||
cl.lerpfrac = 0;
|
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)
|
if (cl_timedemo->value)
|
||||||
cl.lerpfrac = 1.0;
|
cl.lerpfrac = 1.0;
|
||||||
|
|
|
@ -69,7 +69,7 @@ void CL_RunLightStyles (void)
|
||||||
int i;
|
int i;
|
||||||
clightstyle_t *ls;
|
clightstyle_t *ls;
|
||||||
|
|
||||||
ofs = cl.time * 0.1;
|
ofs = cl.time / 100;
|
||||||
if (ofs == lastofs)
|
if (ofs == lastofs)
|
||||||
return;
|
return;
|
||||||
lastofs = ofs;
|
lastofs = ofs;
|
||||||
|
@ -257,7 +257,7 @@ void CL_ParseMuzzleFlash (void)
|
||||||
|
|
||||||
dl = CL_AllocDlight (i);
|
dl = CL_AllocDlight (i);
|
||||||
VectorCopy (pl->current.origin, dl->origin);
|
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, 18, fv, dl->origin);
|
||||||
VectorMA (dl->origin, 16, rv, dl->origin);
|
VectorMA (dl->origin, 16, rv, dl->origin);
|
||||||
if (silenced)
|
if (silenced)
|
||||||
|
@ -398,7 +398,7 @@ void CL_ParseMuzzleFlash2 (void)
|
||||||
flash_number = MSG_ReadByte (&net_message);
|
flash_number = MSG_ReadByte (&net_message);
|
||||||
|
|
||||||
// locate the origin
|
// 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[0] = cl_entities[ent].current.origin[0] + forward[0] + right[0];
|
||||||
origin[1] = cl_entities[ent].current.origin[1] + forward[1] + right[1];
|
origin[1] = cl_entities[ent].current.origin[1] + forward[1] + right[1];
|
||||||
origin[2] = cl_entities[ent].current.origin[2] + forward[2] + right[2];
|
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)
|
for (i=0 ; i<count ; i+=2)
|
||||||
{
|
{
|
||||||
angle = ltime * avelocities[i][0];
|
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++)
|
for (i=0 ; i<NUMVERTEXNORMALS ; i++)
|
||||||
{
|
{
|
||||||
angle = ltime * avelocities[i][0];
|
angle = ltime * avelocities[i][0];
|
||||||
|
|
|
@ -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");
|
|
||||||
}
|
|
|
@ -23,8 +23,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
cvar_t *cl_nodelta;
|
cvar_t *cl_nodelta;
|
||||||
|
|
||||||
uint frame_msec;
|
extern unsigned sys_frame_time;
|
||||||
uint old_sys_frame_time;
|
unsigned frame_msec;
|
||||||
|
unsigned old_sys_frame_time;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
@ -93,7 +94,7 @@ void KeyDown (kbutton_t *b)
|
||||||
c = Cmd_Argv(2);
|
c = Cmd_Argv(2);
|
||||||
b->downtime = atoi(c);
|
b->downtime = atoi(c);
|
||||||
if (!b->downtime)
|
if (!b->downtime)
|
||||||
b->downtime = host.cl_timer - 100;
|
b->downtime = sys_frame_time - 100;
|
||||||
|
|
||||||
b->state |= 1 + 2; // down + impulse down
|
b->state |= 1 + 2; // down + impulse down
|
||||||
}
|
}
|
||||||
|
@ -193,8 +194,8 @@ float CL_KeyState (kbutton_t *key)
|
||||||
|
|
||||||
if (key->state)
|
if (key->state)
|
||||||
{ // still down
|
{ // still down
|
||||||
msec += host.cl_timer - key->downtime;
|
msec += sys_frame_time - key->downtime;
|
||||||
key->downtime = host.cl_timer;
|
key->downtime = sys_frame_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -205,8 +206,10 @@ float CL_KeyState (kbutton_t *key)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
val = (float)msec / frame_msec;
|
val = (float)msec / frame_msec;
|
||||||
if (val < 0) val = 0;
|
if (val < 0)
|
||||||
if (val > 1) val = 1;
|
val = 0;
|
||||||
|
if (val > 1)
|
||||||
|
val = 1;
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
@ -295,7 +298,9 @@ void CL_BaseMove (usercmd_t *cmd)
|
||||||
cmd->forwardmove -= cl_forwardspeed->value * CL_KeyState (&in_back);
|
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) )
|
if ( (in_speed.state & 1) ^ (int)(cl_run->value) )
|
||||||
{
|
{
|
||||||
cmd->forwardmove *= 2;
|
cmd->forwardmove *= 2;
|
||||||
|
@ -333,27 +338,34 @@ void CL_FinishMove (usercmd_t *cmd)
|
||||||
int ms;
|
int ms;
|
||||||
int i;
|
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;
|
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;
|
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
|
// send milliseconds of time to apply the move
|
||||||
ms = cls.frametime * 1000;
|
ms = cls.frametime * 1000;
|
||||||
if (ms > 250) ms = 100; // time was unreasonable
|
if (ms > 250)
|
||||||
|
ms = 100; // time was unreasonable
|
||||||
cmd->msec = ms;
|
cmd->msec = ms;
|
||||||
|
|
||||||
CL_ClampPitch ();
|
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;
|
cmd->impulse = in_impulse;
|
||||||
in_impulse = 0;
|
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;
|
cmd->lightlevel = (byte)cl_lightlevel->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,8 +378,11 @@ usercmd_t CL_CreateCmd (void)
|
||||||
{
|
{
|
||||||
usercmd_t cmd;
|
usercmd_t cmd;
|
||||||
|
|
||||||
frame_msec = host.cl_timer - old_sys_frame_time;
|
frame_msec = sys_frame_time - old_sys_frame_time;
|
||||||
frame_msec = bound(1, frame_msec, 200);
|
if (frame_msec < 1)
|
||||||
|
frame_msec = 1;
|
||||||
|
if (frame_msec > 200)
|
||||||
|
frame_msec = 200;
|
||||||
|
|
||||||
// get basic movement from keyboard
|
// get basic movement from keyboard
|
||||||
CL_BaseMove (&cmd);
|
CL_BaseMove (&cmd);
|
||||||
|
@ -377,9 +392,9 @@ usercmd_t CL_CreateCmd (void)
|
||||||
|
|
||||||
CL_FinishMove (&cmd);
|
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;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
@ -468,7 +483,7 @@ void CL_SendCmd (void)
|
||||||
|
|
||||||
if ( cls.state == ca_connected)
|
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);
|
Netchan_Transmit (&cls.netchan, 0, buf.data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -483,7 +498,7 @@ void CL_SendCmd (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd->buttons && cl.cinematictime > 0 && !cl.attractloop
|
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
|
{ // skip the rest of the cinematic
|
||||||
SCR_FinishCinematic ();
|
SCR_FinishCinematic ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,7 +364,7 @@ CL_Pause_f
|
||||||
void CL_Pause_f (void)
|
void CL_Pause_f (void)
|
||||||
{
|
{
|
||||||
// never pause in multiplayer
|
// never pause in multiplayer
|
||||||
if (host.maxclients > 1 || !Com_ServerState ())
|
if (Cvar_VariableValue ("maxclients") > 1 || !Com_ServerState ())
|
||||||
{
|
{
|
||||||
Cvar_SetValue ("paused", 0);
|
Cvar_SetValue ("paused", 0);
|
||||||
return;
|
return;
|
||||||
|
@ -462,7 +462,7 @@ void CL_CheckForResend (void)
|
||||||
if (cls.state != ca_connecting)
|
if (cls.state != ca_connecting)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cls.realtime - cls.connect_time < 3.0f)
|
if (cls.realtime - cls.connect_time < 3000)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!NET_StringToAdr (cls.servername, &adr))
|
if (!NET_StringToAdr (cls.servername, &adr))
|
||||||
|
@ -616,6 +616,16 @@ void CL_Disconnect (void)
|
||||||
if (cls.state == ca_disconnected)
|
if (cls.state == ca_disconnected)
|
||||||
return;
|
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);
|
VectorClear (cl.refdef.blend);
|
||||||
re->CinematicSetPalette(NULL);
|
re->CinematicSetPalette(NULL);
|
||||||
|
|
||||||
|
@ -717,7 +727,8 @@ void CL_Changing_f (void)
|
||||||
{
|
{
|
||||||
//ZOID
|
//ZOID
|
||||||
//if we are downloading, we don't change! This so we don't suddenly stop downloading a map
|
//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 ();
|
SCR_BeginLoadingPlaque ();
|
||||||
cls.state = ca_connected; // not active anymore, but not disconnected
|
cls.state = ca_connected; // not active anymore, but not disconnected
|
||||||
|
@ -751,7 +762,7 @@ void CL_Reconnect_f (void)
|
||||||
if (*cls.servername) {
|
if (*cls.servername) {
|
||||||
if (cls.state >= ca_connected) {
|
if (cls.state >= ca_connected) {
|
||||||
CL_Disconnect();
|
CL_Disconnect();
|
||||||
cls.connect_time = cls.realtime - 1.5f;
|
cls.connect_time = cls.realtime - 1500;
|
||||||
} else
|
} else
|
||||||
cls.connect_time = -99999; // fire immediately
|
cls.connect_time = -99999; // fire immediately
|
||||||
|
|
||||||
|
@ -1010,7 +1021,8 @@ void CL_ReadPackets (void)
|
||||||
//
|
//
|
||||||
// check timeout
|
// 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
|
if (++cl.timeoutcount > 5) // timeoutcount saves debugger
|
||||||
{
|
{
|
||||||
|
@ -1401,8 +1413,7 @@ CL_InitLocal
|
||||||
void CL_InitLocal (void)
|
void CL_InitLocal (void)
|
||||||
{
|
{
|
||||||
cls.state = ca_disconnected;
|
cls.state = ca_disconnected;
|
||||||
cls.realtime = Sys_DoubleTime();
|
cls.realtime = Sys_Milliseconds ();
|
||||||
|
|
||||||
CL_InitInput ();
|
CL_InitInput ();
|
||||||
|
|
||||||
adr0 = Cvar_Get( "adr0", "", CVAR_ARCHIVE );
|
adr0 = Cvar_Get( "adr0", "", CVAR_ARCHIVE );
|
||||||
|
@ -1415,9 +1426,9 @@ void CL_InitLocal (void)
|
||||||
adr7 = Cvar_Get( "adr7", "", CVAR_ARCHIVE );
|
adr7 = Cvar_Get( "adr7", "", CVAR_ARCHIVE );
|
||||||
adr8 = Cvar_Get( "adr8", "", 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_separation = Cvar_Get( "cl_stereo_separation", "0.4", CVAR_ARCHIVE );
|
||||||
cl_stereo = Cvar_Get( "cl_stereo", "0", 0 );
|
cl_stereo = Cvar_Get( "cl_stereo", "0", 0 );
|
||||||
|
|
||||||
|
@ -1606,8 +1617,9 @@ void CL_FixCvarCheats (void)
|
||||||
int i;
|
int i;
|
||||||
cheatvar_t *var;
|
cheatvar_t *var;
|
||||||
|
|
||||||
if(!strcmp(cl.configstrings[CS_MAXCLIENTS], "1") || !cl.configstrings[CS_MAXCLIENTS][0] )
|
if ( !strcmp(cl.configstrings[CS_MAXCLIENTS], "1")
|
||||||
return; // single player can cheat
|
|| !cl.configstrings[CS_MAXCLIENTS][0] )
|
||||||
|
return; // single player can cheat
|
||||||
|
|
||||||
// find all the cvars if we haven't done it yet
|
// find all the cvars if we haven't done it yet
|
||||||
if (!numcheatvars)
|
if (!numcheatvars)
|
||||||
|
@ -1666,36 +1678,44 @@ CL_Frame
|
||||||
|
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void CL_Frame (float time)
|
void CL_Frame (int msec)
|
||||||
{
|
{
|
||||||
static float extratime;
|
static int extratime;
|
||||||
static float lasttimecalled;
|
static int lasttimecalled;
|
||||||
|
|
||||||
if (host.type == HOST_DEDICATED) return;
|
if (dedicated->value)
|
||||||
|
return;
|
||||||
|
|
||||||
extratime += time;
|
extratime += msec;
|
||||||
|
|
||||||
if (!cl_timedemo->value)
|
if (!cl_timedemo->value)
|
||||||
{
|
{
|
||||||
if (cls.state == ca_connected && extratime < 0.1f)
|
if (cls.state == ca_connected && extratime < 100)
|
||||||
return; // don't flood packets out while connecting
|
return; // don't flood packets out while connecting
|
||||||
if (extratime < 1.0f / cl_maxfps->value)
|
if (extratime < 1000/cl_maxfps->value)
|
||||||
return; // framerate is too high
|
return; // framerate is too high
|
||||||
}
|
}
|
||||||
|
|
||||||
// let the mouse activate or deactivate
|
// let the mouse activate or deactivate
|
||||||
IN_Frame ();
|
IN_Frame ();
|
||||||
|
|
||||||
// decide the simulation time
|
// decide the simulation time
|
||||||
cls.frametime = extratime;
|
cls.frametime = extratime/1000.0;
|
||||||
cl.time += extratime;
|
cl.time += extratime;
|
||||||
cls.realtime = Sys_DoubleTime();
|
cls.realtime = curtime;
|
||||||
|
|
||||||
extratime = 0;
|
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 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
|
// fetch results from server
|
||||||
CL_ReadPackets ();
|
CL_ReadPackets ();
|
||||||
|
@ -1712,7 +1732,11 @@ void CL_Frame (float time)
|
||||||
CL_PrepRefresh ();
|
CL_PrepRefresh ();
|
||||||
|
|
||||||
// update the screen
|
// update the screen
|
||||||
|
if (host_speeds->value)
|
||||||
|
time_before_ref = Sys_Milliseconds ();
|
||||||
SCR_UpdateScreen ();
|
SCR_UpdateScreen ();
|
||||||
|
if (host_speeds->value)
|
||||||
|
time_after_ref = Sys_Milliseconds ();
|
||||||
|
|
||||||
// update audio
|
// update audio
|
||||||
S_Update (cl.refdef.vieworg, cl.v_forward, cl.v_right, cl.v_up);
|
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 ();
|
SCR_RunConsole ();
|
||||||
|
|
||||||
cls.framecount++;
|
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)
|
void CL_Init (void)
|
||||||
{
|
{
|
||||||
// nothing running on the client
|
if (dedicated->value)
|
||||||
if (host.type == HOST_DEDICATED) return;
|
return; // nothing running on the client
|
||||||
|
|
||||||
// all archived variables will now be loaded
|
// all archived variables will now be loaded
|
||||||
|
|
||||||
|
@ -1754,7 +1799,6 @@ void CL_Init (void)
|
||||||
SCR_Init ();
|
SCR_Init ();
|
||||||
cls.disable_screen = true; // don't draw yet
|
cls.disable_screen = true; // don't draw yet
|
||||||
|
|
||||||
CL_InitGameProgs();
|
|
||||||
CL_InitLocal ();
|
CL_InitLocal ();
|
||||||
IN_Init ();
|
IN_Init ();
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ void CL_Flashlight (int ent, vec3_t pos)
|
||||||
VectorCopy (pos, dl->origin);
|
VectorCopy (pos, dl->origin);
|
||||||
dl->radius = 400;
|
dl->radius = 400;
|
||||||
dl->minlight = 250;
|
dl->minlight = 250;
|
||||||
dl->die = cl.time + 0.1;
|
dl->die = cl.time + 100;
|
||||||
dl->color[0] = 1;
|
dl->color[0] = 1;
|
||||||
dl->color[1] = 1;
|
dl->color[1] = 1;
|
||||||
dl->color[2] = 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);
|
VectorCopy (pos, dl->origin);
|
||||||
dl->radius = intensity;
|
dl->radius = intensity;
|
||||||
dl->minlight = 250;
|
dl->minlight = 250;
|
||||||
dl->die = cl.time + 0.1;
|
dl->die = cl.time + 100;
|
||||||
dl->color[0] = r;
|
dl->color[0] = r;
|
||||||
dl->color[1] = g;
|
dl->color[1] = g;
|
||||||
dl->color[2] = b;
|
dl->color[2] = b;
|
||||||
|
@ -453,7 +453,7 @@ void CL_Heatbeam (vec3_t start, vec3_t end)
|
||||||
VectorMA (move, -1, up, move);
|
VectorMA (move, -1, up, move);
|
||||||
|
|
||||||
VectorScale (vec, step, vec);
|
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++)
|
||||||
for (i=0 ; i<len ; i+=step)
|
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);
|
VectorMA (move, -0.5, up, move);
|
||||||
|
|
||||||
// otherwise assume SOFT
|
// otherwise assume SOFT
|
||||||
ltime = cl.time;
|
ltime = (float) cl.time/1000.0;
|
||||||
start_pt = fmod(ltime*96.0,step);
|
start_pt = fmod(ltime*96.0,step);
|
||||||
VectorMA (move, start_pt, vec, move);
|
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);
|
start_pt = fmod(ltime*16.0,step);
|
||||||
VectorMA (move, start_pt, vec, move);
|
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;
|
vec3_t r, u;
|
||||||
|
|
||||||
// vectoangles2 (dir, angle_dir);
|
// vectoangles2 (dir, angle_dir);
|
||||||
// AngleVectorsRight (angle_dir, f, r, u);
|
// AngleVectors (angle_dir, f, r, u);
|
||||||
|
|
||||||
MakeNormalVectors (dir, r, u);
|
MakeNormalVectors (dir, r, u);
|
||||||
|
|
||||||
|
@ -797,7 +797,7 @@ void CL_TrackerTrail (vec3_t start, vec3_t end, int particleColor)
|
||||||
|
|
||||||
VectorCopy(vec, forward);
|
VectorCopy(vec, forward);
|
||||||
vectoangles2 (forward, angle_dir);
|
vectoangles2 (forward, angle_dir);
|
||||||
AngleVectorsRight (angle_dir, forward, right, up);
|
AngleVectors (angle_dir, forward, right, up);
|
||||||
|
|
||||||
dec = 3;
|
dec = 3;
|
||||||
VectorScale (vec, 3, vec);
|
VectorScale (vec, 3, vec);
|
||||||
|
|
|
@ -297,12 +297,13 @@ void CL_ParseServerData (void)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
MsgDev (D_INFO, "Serverdata packet received.\n");
|
MsgDev (D_INFO, "Serverdata packet received.\n");
|
||||||
|
//
|
||||||
// wipe the client_state_t struct
|
// wipe the client_state_t struct
|
||||||
|
//
|
||||||
CL_ClearState ();
|
CL_ClearState ();
|
||||||
cls.state = ca_connected;
|
cls.state = ca_connected;
|
||||||
|
|
||||||
// parse protocol version number
|
// parse protocol version number
|
||||||
i = MSG_ReadLong (&net_message);
|
i = MSG_ReadLong (&net_message);
|
||||||
cls.serverProtocol = i;
|
cls.serverProtocol = i;
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
|
||||||
if (trace.allsolid || trace.startsolid ||
|
if (trace.allsolid || trace.startsolid ||
|
||||||
trace.fraction < tr->fraction)
|
trace.fraction < tr->fraction)
|
||||||
{
|
{
|
||||||
trace.ent = (prvm_edict_t *)ent;
|
trace.ent = (struct edict_s *)ent;
|
||||||
if (tr->startsolid)
|
if (tr->startsolid)
|
||||||
{
|
{
|
||||||
*tr = trace;
|
*tr = trace;
|
||||||
|
@ -145,14 +145,14 @@ void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
|
||||||
CL_PMTrace
|
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;
|
trace_t t;
|
||||||
|
|
||||||
// check against world
|
// check against world
|
||||||
t = CM_BoxTrace (start, end, mins, maxs, 0, MASK_PLAYERSOLID);
|
t = CM_BoxTrace (start, end, mins, maxs, 0, MASK_PLAYERSOLID);
|
||||||
if (t.fraction < 1.0)
|
if (t.fraction < 1.0)
|
||||||
t.ent = (prvm_edict_t *)1;
|
t.ent = (struct edict_s *)1;
|
||||||
|
|
||||||
// check all other solid models
|
// check all other solid models
|
||||||
CL_ClipMoveToEntities (start, mins, maxs, end, &t);
|
CL_ClipMoveToEntities (start, mins, maxs, end, &t);
|
||||||
|
@ -214,9 +214,8 @@ void CL_PredictMovement (void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
|
if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
|
||||||
{
|
{ // just set angles
|
||||||
// just set angles
|
for (i=0 ; i<3 ; i++)
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
{
|
{
|
||||||
cl.predicted_angles[i] = cl.viewangles[i] + SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[i]);
|
cl.predicted_angles[i] = cl.viewangles[i] + SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -439,7 +439,8 @@ SCR_DrawNet
|
||||||
*/
|
*/
|
||||||
void SCR_DrawNet (void)
|
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;
|
return;
|
||||||
|
|
||||||
re->DrawPic (scr_vrect.x+64, scr_vrect.y, "net");
|
re->DrawPic (scr_vrect.x+64, scr_vrect.y, "net");
|
||||||
|
@ -504,7 +505,7 @@ Scroll it up or down
|
||||||
*/
|
*/
|
||||||
void SCR_RunConsole (void)
|
void SCR_RunConsole (void)
|
||||||
{
|
{
|
||||||
// decide on the height of the console
|
// decide on the height of the console
|
||||||
if (cls.key_dest == key_console)
|
if (cls.key_dest == key_console)
|
||||||
scr_conlines = 0.5; // half screen
|
scr_conlines = 0.5; // half screen
|
||||||
else
|
else
|
||||||
|
@ -512,14 +513,14 @@ void SCR_RunConsole (void)
|
||||||
|
|
||||||
if (scr_conlines < scr_con_current)
|
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)
|
if (scr_conlines > scr_con_current)
|
||||||
scr_con_current = scr_conlines;
|
scr_con_current = scr_conlines;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (scr_conlines > scr_con_current)
|
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)
|
if (scr_conlines < scr_con_current)
|
||||||
scr_con_current = scr_conlines;
|
scr_con_current = scr_conlines;
|
||||||
}
|
}
|
||||||
|
@ -569,19 +570,20 @@ SCR_BeginLoadingPlaque
|
||||||
void SCR_BeginLoadingPlaque (void)
|
void SCR_BeginLoadingPlaque (void)
|
||||||
{
|
{
|
||||||
S_StopAllSounds ();
|
S_StopAllSounds ();
|
||||||
cl.sound_prepped = false; // don't play ambients
|
cl.sound_prepped = false; // don't play ambients
|
||||||
if (cls.disable_screen) return;
|
if (cls.disable_screen) return;
|
||||||
if (host.developer) return;
|
if (developer->value)
|
||||||
|
return;
|
||||||
if (cls.state == ca_disconnected) return; // if at console, don't bring up the plaque
|
if (cls.state == ca_disconnected)
|
||||||
|
return; // if at console, don't bring up the plaque
|
||||||
if (cls.key_dest == key_console)
|
if (cls.key_dest == key_console)
|
||||||
return;
|
return;
|
||||||
if (cl.cinematictime > 0)
|
if (cl.cinematictime > 0)
|
||||||
scr_draw_loading = 2; // clear to black first
|
scr_draw_loading = 2; // clear to black first
|
||||||
else scr_draw_loading = 1;
|
else
|
||||||
SCR_UpdateScreen();
|
scr_draw_loading = 1;
|
||||||
|
SCR_UpdateScreen ();
|
||||||
cls.disable_screen = cls.realtime;
|
cls.disable_screen = Sys_Milliseconds ();
|
||||||
cls.disable_servercount = cl.servercount;
|
cls.disable_servercount = cl.servercount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,19 +631,18 @@ int entitycmpfnc( const entity_t *a, const entity_t *b )
|
||||||
void SCR_TimeRefresh_f (void)
|
void SCR_TimeRefresh_f (void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
float start, stop;
|
int start, stop;
|
||||||
float time;
|
float time;
|
||||||
|
|
||||||
if ( cls.state != ca_active )
|
if ( cls.state != ca_active )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
start = Sys_DoubleTime();
|
start = Sys_Milliseconds ();
|
||||||
|
|
||||||
if (Cmd_Argc() == 2)
|
if (Cmd_Argc() == 2)
|
||||||
{
|
{ // run without page flipping
|
||||||
// run without page flipping
|
|
||||||
re->BeginFrame( 0 );
|
re->BeginFrame( 0 );
|
||||||
for (i = 0; i < 128; i++)
|
for (i=0 ; i<128 ; i++)
|
||||||
{
|
{
|
||||||
cl.refdef.viewangles[1] = i/128.0*360.0;
|
cl.refdef.viewangles[1] = i/128.0*360.0;
|
||||||
re->RenderFrame (&cl.refdef);
|
re->RenderFrame (&cl.refdef);
|
||||||
|
@ -660,8 +661,8 @@ void SCR_TimeRefresh_f (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stop = Sys_DoubleTime();
|
stop = Sys_Milliseconds ();
|
||||||
time = (stop-start);
|
time = (stop-start)/1000.0;
|
||||||
Msg ("%f seconds (%f fps)\n", time, 128/time);
|
Msg ("%f seconds (%f fps)\n", time, 128/time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1267,7 +1268,7 @@ void SCR_UpdateScreen (void)
|
||||||
// do nothing at all
|
// do nothing at all
|
||||||
if (cls.disable_screen)
|
if (cls.disable_screen)
|
||||||
{
|
{
|
||||||
if (cls.realtime - cls.disable_screen > 120.0f)
|
if (Sys_Milliseconds() - cls.disable_screen > 120000)
|
||||||
{
|
{
|
||||||
cls.disable_screen = 0;
|
cls.disable_screen = 0;
|
||||||
Msg ("Loading plaque timed out.\n");
|
Msg ("Loading plaque timed out.\n");
|
||||||
|
|
|
@ -360,10 +360,16 @@ float CalcFov (float fov_x, float width, float height)
|
||||||
float a;
|
float a;
|
||||||
float x;
|
float x;
|
||||||
|
|
||||||
fov_x = bound(1, fov_x, 180);
|
if (fov_x < 1 || fov_x > 179)
|
||||||
x = width / tan(fov_x / 360 * M_PI);
|
{
|
||||||
a = atan (height / x);
|
Com_Error (ERR_DROP, "Bad fov: %f", fov_x);
|
||||||
a = a * 360/M_PI;
|
}
|
||||||
|
|
||||||
|
x = width/tan(fov_x/360*M_PI);
|
||||||
|
|
||||||
|
a = atan (height/x);
|
||||||
|
|
||||||
|
a = a*360/M_PI;
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
@ -439,6 +445,13 @@ void V_RenderView( float stereo_separation )
|
||||||
if (!cl.refresh_prepped)
|
if (!cl.refresh_prepped)
|
||||||
return; // still loading
|
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
|
// an invalid frame will just use the exact previous refdef
|
||||||
// we can't use the old frame if the video mode has changed, though...
|
// we can't use the old frame if the video mode has changed, though...
|
||||||
if ( cl.frame.valid && (cl.force_refdef || !cl_paused->value) )
|
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.width = scr_vrect.width;
|
||||||
cl.refdef.height = scr_vrect.height;
|
cl.refdef.height = scr_vrect.height;
|
||||||
cl.refdef.fov_y = CalcFov (cl.refdef.fov_x, cl.refdef.width, cl.refdef.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;
|
cl.refdef.areabits = cl.frame.areabits;
|
||||||
|
|
||||||
|
@ -520,6 +533,9 @@ void V_RenderView( float stereo_separation )
|
||||||
re->RenderFrame (&cl.refdef);
|
re->RenderFrame (&cl.refdef);
|
||||||
if (cl_stats->value)
|
if (cl_stats->value)
|
||||||
Msg ("ent:%i lt:%i part:%i\n", r_numentities, r_numdlights, r_numparticles);
|
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.y);
|
||||||
SCR_AddDirtyPoint (scr_vrect.x+scr_vrect.width-1,
|
SCR_AddDirtyPoint (scr_vrect.x+scr_vrect.width-1,
|
||||||
|
|
|
@ -34,27 +34,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
bool valid; // cleared if delta parsing was invalid
|
bool valid; // cleared if delta parsing was invalid
|
||||||
int serverframe;
|
int serverframe;
|
||||||
float servertime; // server time the message is valid for (in msec)
|
int servertime; // server time the message is valid for (in msec)
|
||||||
int deltaframe;
|
int deltaframe;
|
||||||
byte areabits[MAX_MAP_AREAS/8]; // portalarea visibility bits
|
byte areabits[MAX_MAP_AREAS/8]; // portalarea visibility bits
|
||||||
player_state_t playerstate;
|
player_state_t playerstate;
|
||||||
int num_entities;
|
int num_entities;
|
||||||
int parse_entities; // non-masked index into cl_parse_entities array
|
int parse_entities; // non-masked index into cl_parse_entities array
|
||||||
} frame_t;
|
} frame_t;
|
||||||
|
|
||||||
typedef struct
|
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 current;
|
||||||
entity_state_t prev; // will always be valid, but might just be a copy of 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 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)
|
vec3_t lerp_origin; // for trails (variable hz)
|
||||||
|
|
||||||
float fly_stoptime;
|
int fly_stoptime;
|
||||||
} centity_t;
|
} centity_t;
|
||||||
|
|
||||||
#define MAX_CLIENTWEAPONMODELS 20 // PGM -- upped from 16 to fit the chainfist vwep
|
#define MAX_CLIENTWEAPONMODELS 20 // PGM -- upped from 16 to fit the chainfist vwep
|
||||||
|
@ -81,24 +81,24 @@ extern int num_cl_weaponmodels;
|
||||||
//
|
//
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int timeoutcount;
|
int timeoutcount;
|
||||||
|
|
||||||
int timedemo_frames;
|
int timedemo_frames;
|
||||||
float timedemo_start;
|
int timedemo_start;
|
||||||
|
|
||||||
bool refresh_prepped; // false if on new level or new ref dll
|
bool refresh_prepped; // false if on new level or new ref dll
|
||||||
bool sound_prepped; // ambient sounds can start
|
bool sound_prepped; // ambient sounds can start
|
||||||
bool force_refdef; // vid has changed, so we can't use a paused refdef
|
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 cmd;
|
||||||
usercmd_t cmds[CMD_BACKUP]; // each mesage will send several old cmds
|
usercmd_t cmds[CMD_BACKUP]; // each mesage will send several old cmds
|
||||||
int cmd_time[CMD_BACKUP]; // time sent, for calculating pings
|
int cmd_time[CMD_BACKUP]; // time sent, for calculating pings
|
||||||
short predicted_origins[CMD_BACKUP][3]; // for debug comparing against server
|
short predicted_origins[CMD_BACKUP][3]; // for debug comparing against server
|
||||||
|
|
||||||
float predicted_step; // for stair up smoothing
|
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_origin; // generated by CL_PredictMovement
|
||||||
vec3_t predicted_angles;
|
vec3_t predicted_angles;
|
||||||
|
@ -115,11 +115,11 @@ typedef struct
|
||||||
// and teleport direction changes
|
// and teleport direction changes
|
||||||
vec3_t viewangles;
|
vec3_t viewangles;
|
||||||
|
|
||||||
float time; // this is the time value that the client
|
int time; // this is the time value that the client
|
||||||
// is rendering at. always <= cls.realtime
|
// is rendering at. always <= cls.realtime
|
||||||
float lerpfrac; // between oldframe and frame
|
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
|
vec3_t v_forward, v_right, v_up; // set when refdef.angles is set
|
||||||
|
|
||||||
|
@ -133,10 +133,10 @@ typedef struct
|
||||||
// non-gameserver infornamtion
|
// non-gameserver infornamtion
|
||||||
// FIXME: move this cinematic stuff into the cin_t structure
|
// FIXME: move this cinematic stuff into the cin_t structure
|
||||||
file_t *cinematic_file;
|
file_t *cinematic_file;
|
||||||
float cinematictime; // cls.realtime for first cinematic frame
|
int cinematictime; // cls.realtime for first cinematic frame
|
||||||
int cinematicframe;
|
int cinematicframe;
|
||||||
char cinematicpalette[768];
|
char cinematicpalette[768];
|
||||||
bool cinematicpalette_active;
|
bool cinematicpalette_active;
|
||||||
|
|
||||||
//
|
//
|
||||||
// server state information
|
// server state information
|
||||||
|
@ -196,11 +196,11 @@ typedef struct
|
||||||
keydest_t key_dest;
|
keydest_t key_dest;
|
||||||
|
|
||||||
int framecount;
|
int framecount;
|
||||||
double realtime; // always increasing, no clamping, etc
|
int realtime; // always increasing, no clamping, etc
|
||||||
float frametime; // seconds since last frame
|
float frametime; // seconds since last frame
|
||||||
|
|
||||||
// screen rendering information
|
// screen rendering information
|
||||||
float disable_screen; // showing loading plaque between levels
|
float disable_screen; // showing loading plaque between levels
|
||||||
// or changing rendering dlls
|
// or changing rendering dlls
|
||||||
// if time gets > 30 seconds ahead, break it
|
// if time gets > 30 seconds ahead, break it
|
||||||
int disable_servercount; // when we receive a frame and cl.servercount
|
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_Snd_Restart_f (void);
|
||||||
void CL_RequestNextDownload (void);
|
void CL_RequestNextDownload (void);
|
||||||
|
|
||||||
//
|
|
||||||
// cl_game
|
|
||||||
//
|
|
||||||
void CL_InitGameProgs (void);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// cl_input
|
// cl_input
|
||||||
//
|
//
|
||||||
|
|
137
engine/common.h
137
engine/common.h
|
@ -59,17 +59,12 @@ typedef struct sizebuf_s
|
||||||
int errorcount; // cause by errors
|
int errorcount; // cause by errors
|
||||||
} sizebuf_t;
|
} sizebuf_t;
|
||||||
|
|
||||||
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);
|
||||||
void _SZ_Write (sizebuf_t *buf, void *data, int length, const char *filename, int fileline);
|
void SZ_Clear (sizebuf_t *buf);
|
||||||
void *_SZ_GetSpace (sizebuf_t *buf, int length, const char *filename, int fileline);
|
void *SZ_GetSpace (sizebuf_t *buf, int length);
|
||||||
void _SZ_Print (sizebuf_t *buf, char *data, const char *filename, int fileline);
|
void SZ_Write (sizebuf_t *buf, void *data, int length);
|
||||||
void _SZ_Clear (sizebuf_t *buf, const char *filename, int fileline);
|
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;
|
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_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_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_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_Begin( x ) _MSG_Begin( x, __FILE__, __LINE__);
|
||||||
#define MSG_WriteChar(x,y) _MSG_WriteChar (x, y, __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_WriteByte(x,y) _MSG_WriteByte (x, y, __FILE__, __LINE__);
|
||||||
#define MSG_WriteShort(x,y) _MSG_WriteShort (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_WriteWord(x,y) _MSG_WriteWord (x, y, __FILE__, __LINE__);
|
||||||
#define MSG_WriteLong(x,y) _MSG_WriteLong (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_WriteFloat(x, y) _MSG_WriteFloat (x, y, __FILE__, __LINE__);
|
||||||
#define MSG_WriteString(x,y) _MSG_WriteString (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_WriteCoord(x, y) _MSG_WriteCoord (x, y, __FILE__, __LINE__);
|
||||||
#define MSG_WritePos(x, y) _MSG_WritePos (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_WriteAngle(x, y) _MSG_WriteAngle (x, y, __FILE__, __LINE__);
|
||||||
#define MSG_WriteAngle16(x, y) _MSG_WriteAngle16 (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_WriteUnterminatedString(x, y) _MSG_WriteUnterminatedString (x, y, __FILE__, __LINE__);
|
||||||
#define MSG_WriteDeltaUsercmd(x, y, z) _MSG_WriteDeltaUsercmd (x, y, z, __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_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_WriteDir(x, y) _MSG_WriteDir (x, y, __FILE__, __LINE__);
|
||||||
#define MSG_WriteVector(x, y) _MSG_WriteVector (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_Send(x, y, z) _MSG_Send(x, y, z, __FILE__, __LINE__);
|
||||||
|
|
||||||
void MSG_BeginReading (sizebuf_t *sb);
|
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
|
char *COM_Argv (int arg); // range and null checked
|
||||||
void COM_ClearArgv (int arg);
|
void COM_ClearArgv (int arg);
|
||||||
|
int COM_CheckParm (char *parm);
|
||||||
|
|
||||||
void COM_Init (void);
|
void COM_Init (void);
|
||||||
void COM_InitArgv (int argc, char **argv);
|
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
|
// as a clc_stringcmd instead of executed locally
|
||||||
void Cmd_RemoveCommand (char *cmd_name);
|
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
|
// used by the cvar code to check for cvar / command name overlap
|
||||||
|
|
||||||
char *Cmd_CompleteCommand (char *partial);
|
char *Cmd_CompleteCommand (char *partial);
|
||||||
|
@ -432,11 +428,11 @@ char *Cmd_Args (void);
|
||||||
// functions. Cmd_Argv () will return an empty string, not a NULL
|
// functions. Cmd_Argv () will return an empty string, not a NULL
|
||||||
// if arg > argc, so string operations are always safe.
|
// 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.
|
// Takes a null terminated string. Does not need to be /n terminated.
|
||||||
// breaks the string up into arg tokens.
|
// 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
|
// Parses a single line of text into arguments and tries to execute it
|
||||||
// as if it was typed at the console
|
// as if it was typed at the console
|
||||||
|
|
||||||
|
@ -461,32 +457,33 @@ NET
|
||||||
#define PACKET_HEADER 10 // two ints and a short
|
#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 {NA_LOOPBACK, NA_BROADCAST, NA_IP, NA_IPX, NA_BROADCAST_IPX} netadrtype_t;
|
||||||
|
|
||||||
typedef enum {NS_CLIENT, NS_SERVER} netsrc_t;
|
typedef enum {NS_CLIENT, NS_SERVER} netsrc_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
netadrtype_t type;
|
netadrtype_t type;
|
||||||
|
|
||||||
byte ip[4];
|
byte ip[4];
|
||||||
byte ipx[10];
|
byte ipx[10];
|
||||||
|
|
||||||
word port;
|
unsigned short port;
|
||||||
} netadr_t;
|
} netadr_t;
|
||||||
|
|
||||||
void NET_Init (void);
|
void NET_Init (void);
|
||||||
void NET_Shutdown (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);
|
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_CompareAdr (netadr_t a, netadr_t b);
|
||||||
bool NET_CompareBaseAdr (netadr_t a, netadr_t b);
|
bool NET_CompareBaseAdr (netadr_t a, netadr_t b);
|
||||||
bool NET_IsLocalAddress (netadr_t adr);
|
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);
|
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 dropped; // between last packet and previous
|
||||||
|
|
||||||
int last_received; // for timeouts
|
int last_received; // for timeouts
|
||||||
int last_sent; // for retransmits
|
int last_sent; // for retransmits
|
||||||
|
|
||||||
netadr_t remote_address;
|
netadr_t remote_address;
|
||||||
int qport; // qport value to write when transmitting
|
int qport; // qport value to write when transmitting
|
||||||
|
|
||||||
// sequencing variables
|
// sequencing variables
|
||||||
int incoming_sequence;
|
int incoming_sequence;
|
||||||
int incoming_acknowledged;
|
int incoming_acknowledged;
|
||||||
int incoming_reliable_acknowledged; // single bit
|
int incoming_reliable_acknowledged; // single bit
|
||||||
|
@ -520,16 +517,16 @@ typedef struct
|
||||||
int last_reliable_sequence; // sequence number of last send
|
int last_reliable_sequence; // sequence number of last send
|
||||||
|
|
||||||
// reliable staging and holding areas
|
// reliable staging and holding areas
|
||||||
sizebuf_t message; // writing buffer to send to server
|
sizebuf_t message; // writing buffer to send to server
|
||||||
byte message_buf[MAX_MSGLEN - 16]; // leave space for header
|
byte message_buf[MAX_MSGLEN-16]; // leave space for header
|
||||||
|
|
||||||
// message is copied to this buffer when it is first transfered
|
// message is copied to this buffer when it is first transfered
|
||||||
int reliable_length;
|
int reliable_length;
|
||||||
byte reliable_buf[MAX_MSGLEN - 16]; // unacked reliable message
|
byte reliable_buf[MAX_MSGLEN-16]; // unacked reliable message
|
||||||
} netchan_t;
|
} netchan_t;
|
||||||
|
|
||||||
extern netadr_t net_from;
|
extern netadr_t net_from;
|
||||||
extern sizebuf_t net_message;
|
extern sizebuf_t net_message;
|
||||||
extern byte net_message_buffer[MAX_MSGLEN];
|
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_INSERT 1 // insert at current position, but don't run yet
|
||||||
#define EXEC_APPEND 2 // add to end of the command buffer
|
#define EXEC_APPEND 2 // add to end of the command buffer
|
||||||
|
|
||||||
void Com_BeginRedirect (int target, char *buffer, int buffersize, void (*flush));
|
#define PRINT_ALL 0
|
||||||
void Com_EndRedirect (void);
|
#define PRINT_DEVELOPER 1 // only print when "developer 1"
|
||||||
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_BeginRedirect (int target, char *buffer, int buffersize, void (*flush));
|
||||||
void Com_SetServerState (int state);
|
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);
|
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 frand(void); // 0 to 1
|
||||||
float crand(void); // -1 to 1
|
float crand(void); // -1 to 1
|
||||||
|
|
||||||
|
extern cvar_t *developer;
|
||||||
|
extern cvar_t *dedicated;
|
||||||
extern cvar_t *host_speeds;
|
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
|
#define NUMVERTEXNORMALS 162
|
||||||
extern vec3_t bytedirs[NUMVERTEXNORMALS];
|
extern vec3_t bytedirs[NUMVERTEXNORMALS];
|
||||||
|
@ -686,12 +697,12 @@ CLIENT / SERVER SYSTEMS
|
||||||
void CL_Init (void);
|
void CL_Init (void);
|
||||||
void CL_Drop (void);
|
void CL_Drop (void);
|
||||||
void CL_Shutdown (void);
|
void CL_Shutdown (void);
|
||||||
void CL_Frame (float time);
|
void CL_Frame (int msec);
|
||||||
void Con_Print (char *text);
|
void Con_Print (char *text);
|
||||||
void SCR_BeginLoadingPlaque (void);
|
void SCR_BeginLoadingPlaque (void);
|
||||||
|
|
||||||
void SV_Init (void);
|
void SV_Init (void);
|
||||||
void SV_Shutdown (char *finalmsg, bool reconnect);
|
void SV_Shutdown (char *finalmsg, bool reconnect);
|
||||||
void SV_Frame (float time);
|
void SV_Frame (int msec);
|
||||||
|
|
||||||
#endif//COMMON_H
|
#endif//COMMON_H
|
|
@ -234,7 +234,7 @@ void Cbuf_Execute (void)
|
||||||
memmove (text, text+i, cmd_text.cursize);
|
memmove (text, text+i, cmd_text.cursize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute the command line
|
// execute the command line
|
||||||
Cmd_ExecuteString (line);
|
Cmd_ExecuteString (line);
|
||||||
|
|
||||||
if (cmd_wait)
|
if (cmd_wait)
|
||||||
|
@ -301,7 +301,7 @@ bool Cbuf_AddLateCommands (void)
|
||||||
int argc;
|
int argc;
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
// build the combined string to parse from
|
// build the combined string to parse from
|
||||||
s = 0;
|
s = 0;
|
||||||
argc = COM_Argc();
|
argc = COM_Argc();
|
||||||
for (i=1 ; i<argc ; i++)
|
for (i=1 ; i<argc ; i++)
|
||||||
|
@ -320,7 +320,7 @@ bool Cbuf_AddLateCommands (void)
|
||||||
strcat (text, " ");
|
strcat (text, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// pull out the commands
|
// pull out the commands
|
||||||
build = Z_Malloc (s+1);
|
build = Z_Malloc (s+1);
|
||||||
build[0] = 0;
|
build[0] = 0;
|
||||||
|
|
||||||
|
@ -344,7 +344,8 @@ bool Cbuf_AddLateCommands (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = (build[0] != 0);
|
ret = (build[0] != 0);
|
||||||
if (ret) Cbuf_AddText (build);
|
if (ret)
|
||||||
|
Cbuf_AddText (build);
|
||||||
|
|
||||||
Z_Free (text);
|
Z_Free (text);
|
||||||
Z_Free (build);
|
Z_Free (build);
|
||||||
|
@ -537,7 +538,7 @@ char *Cmd_Args (void)
|
||||||
Cmd_MacroExpandString
|
Cmd_MacroExpandString
|
||||||
======================
|
======================
|
||||||
*/
|
*/
|
||||||
char *Cmd_MacroExpandString (const char *text)
|
char *Cmd_MacroExpandString (char *text)
|
||||||
{
|
{
|
||||||
int i, j, count, len;
|
int i, j, count, len;
|
||||||
bool inquote;
|
bool inquote;
|
||||||
|
@ -547,7 +548,7 @@ char *Cmd_MacroExpandString (const char *text)
|
||||||
char *token, *start;
|
char *token, *start;
|
||||||
|
|
||||||
inquote = false;
|
inquote = false;
|
||||||
scan = (char *)text;
|
scan = text;
|
||||||
|
|
||||||
len = strlen (scan);
|
len = strlen (scan);
|
||||||
if (len >= MAX_STRING_CHARS)
|
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
|
$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;
|
int i;
|
||||||
char *token;
|
char *token;
|
||||||
|
|
||||||
// clear the args from the last string
|
// clear the args from the last string
|
||||||
for (i = 0; i < cmd_argc; i++) Z_Free (cmd_argv[i]);
|
for (i = 0; i < cmd_argc; i++) Z_Free (cmd_argv[i]);
|
||||||
|
@ -740,15 +741,16 @@ void Cmd_RemoveCommand (char *cmd_name)
|
||||||
Cmd_Exists
|
Cmd_Exists
|
||||||
============
|
============
|
||||||
*/
|
*/
|
||||||
bool Cmd_Exists (const char *cmd_name)
|
bool Cmd_Exists (char *cmd_name)
|
||||||
{
|
{
|
||||||
cmd_function_t *cmd;
|
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))
|
if (!strcmp (cmd_name,cmd->name))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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?
|
FIXME: lookupnoadd the token to speed search?
|
||||||
============
|
============
|
||||||
*/
|
*/
|
||||||
void Cmd_ExecuteString (const char *text)
|
void Cmd_ExecuteString (char *text)
|
||||||
{
|
{
|
||||||
cmd_function_t *cmd;
|
cmd_function_t *cmd;
|
||||||
cmdalias_t *a;
|
cmdalias_t *a;
|
||||||
|
|
|
@ -36,19 +36,19 @@ typedef struct
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int contents;
|
int contents;
|
||||||
int cluster;
|
int cluster;
|
||||||
int area;
|
int area;
|
||||||
word firstleafbrush;
|
unsigned short firstleafbrush;
|
||||||
word numleafbrushes;
|
unsigned short numleafbrushes;
|
||||||
} cleaf_t;
|
} cleaf_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int contents;
|
int contents;
|
||||||
int numsides;
|
int numsides;
|
||||||
int firstbrushside;
|
int firstbrushside;
|
||||||
int checkcount; // to avoid repeated testings
|
int checkcount; // to avoid repeated testings
|
||||||
} cbrush_t;
|
} cbrush_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -926,7 +926,7 @@ Handles offseting and rotation of the end points for moving and
|
||||||
rotating entities
|
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 p_l;
|
||||||
vec3_t temp;
|
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 &&
|
if (headnode != box_headnode &&
|
||||||
(angles[0] || angles[1] || angles[2]) )
|
(angles[0] || angles[1] || angles[2]) )
|
||||||
{
|
{
|
||||||
AngleVectorsRight (angles, forward, right, up);
|
AngleVectors (angles, forward, right, up);
|
||||||
|
|
||||||
VectorCopy (p_l, temp);
|
VectorCopy (p_l, temp);
|
||||||
p_l[0] = DotProduct (temp, forward);
|
p_l[0] = DotProduct (temp, forward);
|
||||||
|
@ -978,15 +978,16 @@ bool trace_ispoint; // optimized case
|
||||||
CM_ClipBoxToBrush
|
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;
|
int i, j;
|
||||||
cplane_t *plane, *clipplane;
|
cplane_t *plane, *clipplane;
|
||||||
float dist;
|
float dist;
|
||||||
float enterfrac, leavefrac;
|
float enterfrac, leavefrac;
|
||||||
vec3_t ofs;
|
vec3_t ofs;
|
||||||
float d1, d2;
|
float d1, d2;
|
||||||
bool getout, startout;
|
bool getout, startout;
|
||||||
float f;
|
float f;
|
||||||
cbrushside_t *side, *leadside;
|
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;
|
leavefrac = 1;
|
||||||
clipplane = NULL;
|
clipplane = NULL;
|
||||||
|
|
||||||
if (!brush->numsides) return;
|
if (!brush->numsides)
|
||||||
|
return;
|
||||||
|
|
||||||
c_brush_traces++;
|
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;
|
startout = false;
|
||||||
leadside = NULL;
|
leadside = NULL;
|
||||||
|
|
||||||
for (i = 0; i < brush->numsides; i++)
|
for (i=0 ; i<brush->numsides ; i++)
|
||||||
{
|
{
|
||||||
side = &map_brushsides[brush->firstbrushside+i];
|
side = &map_brushsides[brush->firstbrushside+i];
|
||||||
plane = side->plane;
|
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
|
// FIXME: special case for axial
|
||||||
|
|
||||||
if (!trace_ispoint)
|
if (!trace_ispoint)
|
||||||
{
|
{ // general box case
|
||||||
// general box case
|
|
||||||
|
|
||||||
// push the plane out apropriately for mins/maxs
|
// push the plane out apropriately for mins/maxs
|
||||||
|
|
||||||
// FIXME: use signbits into 8 way lookup for each 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)
|
if (plane->normal[j] < 0)
|
||||||
ofs[j] = maxs[j];
|
ofs[j] = maxs[j];
|
||||||
else ofs[j] = mins[j];
|
else
|
||||||
|
ofs[j] = mins[j];
|
||||||
}
|
}
|
||||||
dist = DotProduct (ofs, plane->normal);
|
dist = DotProduct (ofs, plane->normal);
|
||||||
dist = plane->dist - dist;
|
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;
|
d1 = DotProduct (p1, plane->normal) - dist;
|
||||||
d2 = DotProduct (p2, plane->normal) - dist;
|
d2 = DotProduct (p2, plane->normal) - dist;
|
||||||
|
|
||||||
if (d2 > 0) getout = true; // endpoint is not in solid
|
if (d2 > 0)
|
||||||
if (d1 > 0) startout = true;
|
getout = true; // endpoint is not in solid
|
||||||
|
if (d1 > 0)
|
||||||
|
startout = true;
|
||||||
|
|
||||||
// if completely in front of face, no intersection
|
// 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
|
// crosses face
|
||||||
if (d1 > d2)
|
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
|
else
|
||||||
{ // leave
|
{ // leave
|
||||||
f = (d1 + DIST_EPSILON) / (d1-d2);
|
f = (d1+DIST_EPSILON) / (d1-d2);
|
||||||
if (f < leavefrac) leavefrac = f;
|
if (f < leavefrac)
|
||||||
|
leavefrac = f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!startout)
|
if (!startout)
|
||||||
{
|
{ // original point was inside brush
|
||||||
// original point was inside brush
|
|
||||||
trace->startsolid = true;
|
trace->startsolid = true;
|
||||||
if (!getout) trace->allsolid = true;
|
if (!getout)
|
||||||
|
trace->allsolid = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (enterfrac < leavefrac)
|
if (enterfrac < leavefrac)
|
||||||
{
|
{
|
||||||
if (enterfrac > -1 && enterfrac < trace->fraction)
|
if (enterfrac > -1 && enterfrac < trace->fraction)
|
||||||
{
|
{
|
||||||
if (enterfrac < 0) enterfrac = 0;
|
if (enterfrac < 0)
|
||||||
|
enterfrac = 0;
|
||||||
trace->fraction = enterfrac;
|
trace->fraction = enterfrac;
|
||||||
trace->plane = *clipplane;
|
trace->plane = *clipplane;
|
||||||
trace->surface = &(leadside->surface->c);
|
trace->surface = &(leadside->surface->c);
|
||||||
|
@ -1184,7 +1192,7 @@ void CM_TestInLeaf (int leafnum)
|
||||||
if ( !(leaf->contents & trace_contents))
|
if ( !(leaf->contents & trace_contents))
|
||||||
return;
|
return;
|
||||||
// trace line against all brushes in the leaf
|
// 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];
|
brushnum = map_leafbrushes[leaf->firstleafbrush+k];
|
||||||
b = &map_brushes[brushnum];
|
b = &map_brushes[brushnum];
|
||||||
|
@ -1192,7 +1200,7 @@ void CM_TestInLeaf (int leafnum)
|
||||||
continue; // already checked this brush in another leaf
|
continue; // already checked this brush in another leaf
|
||||||
b->checkcount = checkcount;
|
b->checkcount = checkcount;
|
||||||
|
|
||||||
if (!(b->contents & trace_contents))
|
if ( !(b->contents & trace_contents))
|
||||||
continue;
|
continue;
|
||||||
CM_TestBoxInBrush (trace_mins, trace_maxs, trace_start, &trace_trace, b);
|
CM_TestBoxInBrush (trace_mins, trace_maxs, trace_start, &trace_trace, b);
|
||||||
if (!trace_trace.fraction)
|
if (!trace_trace.fraction)
|
||||||
|
@ -1331,12 +1339,15 @@ return;
|
||||||
CM_BoxTrace
|
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;
|
int i;
|
||||||
|
|
||||||
checkcount++; // for multi-check avoidance
|
checkcount++; // for multi-check avoidance
|
||||||
c_traces++; // for statistics, may be zeroed
|
|
||||||
|
c_traces++; // for statistics, may be zeroed
|
||||||
|
|
||||||
// fill in a default trace
|
// fill in a default trace
|
||||||
memset (&trace_trace, 0, sizeof(trace_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 (mins, trace_mins);
|
||||||
VectorCopy (maxs, trace_maxs);
|
VectorCopy (maxs, trace_maxs);
|
||||||
|
|
||||||
|
//
|
||||||
// check for position test special case
|
// check for position test special case
|
||||||
|
//
|
||||||
if (start[0] == end[0] && start[1] == end[1] && start[2] == end[2])
|
if (start[0] == end[0] && start[1] == end[1] && start[2] == end[2])
|
||||||
{
|
{
|
||||||
int leafs[1024];
|
int leafs[1024];
|
||||||
int i, numleafs;
|
int i, numleafs;
|
||||||
vec3_t c1, c2;
|
vec3_t c1, c2;
|
||||||
int topnode;
|
int topnode;
|
||||||
|
|
||||||
VectorAdd (start, mins, c1);
|
VectorAdd (start, mins, c1);
|
||||||
VectorAdd (start, maxs, c2);
|
VectorAdd (start, maxs, c2);
|
||||||
for (i = 0; i < 3; i++)
|
for (i=0 ; i<3 ; i++)
|
||||||
{
|
{
|
||||||
c1[i] -= 1;
|
c1[i] -= 1;
|
||||||
c2[i] += 1;
|
c2[i] += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
numleafs = CM_BoxLeafnums_headnode (c1, c2, leafs, 1024, headnode, &topnode);
|
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]);
|
CM_TestInLeaf (leafs[i]);
|
||||||
if (trace_trace.allsolid)
|
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;
|
return trace_trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
// check for point special case
|
// check for point special case
|
||||||
|
//
|
||||||
if (mins[0] == 0 && mins[1] == 0 && mins[2] == 0
|
if (mins[0] == 0 && mins[1] == 0 && mins[2] == 0
|
||||||
&& maxs[0] == 0 && maxs[1] == 0 && maxs[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];
|
trace_extents[2] = -mins[2] > maxs[2] ? -mins[2] : maxs[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
// general sweeping through world
|
// general sweeping through world
|
||||||
|
//
|
||||||
CM_RecursiveHullCheck (headnode, 0, 1, start, end);
|
CM_RecursiveHullCheck (headnode, 0, 1, start, end);
|
||||||
|
|
||||||
if (trace_trace.fraction == 1)
|
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
|
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]);
|
trace_trace.endpos[i] = start[i] + trace_trace.fraction * (end[i] - start[i]);
|
||||||
}
|
}
|
||||||
return trace_trace;
|
return trace_trace;
|
||||||
|
@ -1423,7 +1440,10 @@ rotating entities
|
||||||
#endif
|
#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;
|
trace_t trace;
|
||||||
vec3_t start_l, end_l;
|
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);
|
VectorSubtract (end, origin, end_l);
|
||||||
|
|
||||||
// rotate start and end into the models frame of reference
|
// 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;
|
rotated = true;
|
||||||
else
|
else
|
||||||
rotated = false;
|
rotated = false;
|
||||||
|
|
||||||
if (rotated)
|
if (rotated)
|
||||||
{
|
{
|
||||||
AngleVectorsRight (angles, forward, right, up);
|
AngleVectors (angles, forward, right, up);
|
||||||
|
|
||||||
VectorCopy (start_l, temp);
|
VectorCopy (start_l, temp);
|
||||||
start_l[0] = DotProduct (temp, forward);
|
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
|
// FIXME: figure out how to do this with existing angles
|
||||||
VectorCopy( angles, a );
|
VectorCopy( angles, a );
|
||||||
VectorNegate ( a, a );
|
VectorNegate ( a, a );
|
||||||
AngleVectorsRight (a, forward, right, up);
|
AngleVectors (a, forward, right, up);
|
||||||
|
|
||||||
VectorCopy (trace.plane.normal, temp);
|
VectorCopy (trace.plane.normal, temp);
|
||||||
trace.plane.normal[0] = DotProduct (temp, forward);
|
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 };
|
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 };
|
||||||
#define NUM_HULL_ROUNDS (sizeof(hull_table) / sizeof(word))
|
|
||||||
|
|
||||||
void CM_LookUpHullSize(vec3_t size, bool down)
|
void CM_LookUpHullSize(vec3_t size, bool down)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
for(i = 0; i < 3; i++)
|
for(i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
bool negative = false;
|
bool negative = false;
|
||||||
|
@ -1748,14 +1769,7 @@ void CM_LookUpHullSize(vec3_t size, bool down)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
size[i] = result;//copy new value
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1805,7 +1819,7 @@ cmodel_t *CM_StudioModel (char *name, byte *buffer)
|
||||||
VectorSet(out->mins, -32, -32, -32 );
|
VectorSet(out->mins, -32, -32, -32 );
|
||||||
VectorSet(out->maxs, 32, 32, 32 );
|
VectorSet(out->maxs, 32, 32, 32 );
|
||||||
}
|
}
|
||||||
|
|
||||||
numsmodels++;
|
numsmodels++;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,24 @@ jmp_buf abortframe;
|
||||||
|
|
||||||
int com_argc;
|
int com_argc;
|
||||||
char *com_argv[MAX_NUM_ARGVS+1];
|
char *com_argv[MAX_NUM_ARGVS+1];
|
||||||
double realtime;
|
int realtime;
|
||||||
|
|
||||||
|
file_t *log_stats_file;
|
||||||
|
|
||||||
cvar_t *host_speeds;
|
cvar_t *host_speeds;
|
||||||
|
cvar_t *log_stats;
|
||||||
|
cvar_t *developer;
|
||||||
|
cvar_t *dedicated;
|
||||||
|
|
||||||
int server_state;
|
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);
|
va_start (argptr,fmt);
|
||||||
vsprintf (msg,fmt,argptr);
|
vsprintf (msg,fmt,argptr);
|
||||||
va_end (argptr);
|
va_end (argptr);
|
||||||
|
|
||||||
host.state = HOST_ERROR;
|
|
||||||
|
|
||||||
if (code == ERR_DISCONNECT)
|
if (code == ERR_DISCONNECT)
|
||||||
{
|
{
|
||||||
CL_Drop ();
|
CL_Drop ();
|
||||||
|
@ -163,7 +174,7 @@ void Com_Printf (char *fmt, ...)
|
||||||
================
|
================
|
||||||
Com_DPrintf
|
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, ...)
|
void Com_DPrintf (int level, char *fmt, ...)
|
||||||
|
@ -301,7 +312,7 @@ COM_InitArgv
|
||||||
*/
|
*/
|
||||||
void COM_InitArgv (int argc, char **argv)
|
void COM_InitArgv (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char dev_level[4];
|
char dev_level[4];
|
||||||
|
|
||||||
if (argc > MAX_NUM_ARGVS)
|
if (argc > MAX_NUM_ARGVS)
|
||||||
|
@ -325,9 +336,9 @@ void COM_InitArgv (int argc, char **argv)
|
||||||
host.developer = atoi(dev_level);
|
host.developer = atoi(dev_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *CopyString (const char *in)
|
char *CopyString (char *in)
|
||||||
{
|
{
|
||||||
char *out;
|
char *out;
|
||||||
|
|
||||||
out = Z_Malloc (strlen(in)+1);
|
out = Z_Malloc (strlen(in)+1);
|
||||||
strcpy (out, in);
|
strcpy (out, in);
|
||||||
|
|
|
@ -93,7 +93,7 @@ void Con_ToggleConsole_f (void)
|
||||||
M_ForceMenuOff ();
|
M_ForceMenuOff ();
|
||||||
cls.key_dest = key_console;
|
cls.key_dest = key_console;
|
||||||
|
|
||||||
if (host.maxclients == 1 && Com_ServerState())
|
if (Cvar_VariableValue ("maxclients") == 1 && Com_ServerState ())
|
||||||
Cvar_Set ("paused", "1");
|
Cvar_Set ("paused", "1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ void Con_ClearNotify (void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NUM_CON_TIMES; i++)
|
for (i=0 ; i<NUM_CON_TIMES ; i++)
|
||||||
con.times[i] = 0;
|
con.times[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,8 +389,9 @@ void Con_Print (char *txt)
|
||||||
if (!con.x)
|
if (!con.x)
|
||||||
{
|
{
|
||||||
Con_Linefeed ();
|
Con_Linefeed ();
|
||||||
// mark time for transparent overlay
|
// mark time for transparent overlay
|
||||||
if (con.current >= 0) con.times[con.current % NUM_CON_TIMES] = cls.realtime;
|
if (con.current >= 0)
|
||||||
|
con.times[con.current % NUM_CON_TIMES] = cls.realtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
|
@ -466,24 +467,24 @@ void Con_DrawInput (void)
|
||||||
|
|
||||||
text = key_lines[edit_line];
|
text = key_lines[edit_line];
|
||||||
|
|
||||||
// add the cursor frame
|
// add the cursor frame
|
||||||
text[key_linepos] = 10 + ((int)(cls.realtime * 4.0f) & 1);
|
text[key_linepos] = 10+((int)(cls.realtime>>8)&1);
|
||||||
|
|
||||||
// fill out remainder with spaces
|
// fill out remainder with spaces
|
||||||
for (i = key_linepos + 1; i < con.linewidth; i++)
|
for (i=key_linepos+1 ; i< con.linewidth ; i++)
|
||||||
text[i] = ' ';
|
text[i] = ' ';
|
||||||
|
|
||||||
// prestep if horizontally scrolling
|
// prestep if horizontally scrolling
|
||||||
if (key_linepos >= con.linewidth)
|
if (key_linepos >= con.linewidth)
|
||||||
text += 1 + key_linepos - con.linewidth;
|
text += 1 + key_linepos - con.linewidth;
|
||||||
|
|
||||||
// draw it
|
// draw it
|
||||||
y = con.vislines-16;
|
y = con.vislines-16;
|
||||||
|
|
||||||
for (i=0 ; i<con.linewidth ; i++)
|
for (i=0 ; i<con.linewidth ; i++)
|
||||||
re->DrawChar ( (i+1)<<3, con.vislines - 22, text[i]);
|
re->DrawChar ( (i+1)<<3, con.vislines - 22, text[i]);
|
||||||
|
|
||||||
// remove cursor
|
// remove cursor
|
||||||
key_lines[edit_line][key_linepos] = 0;
|
key_lines[edit_line][key_linepos] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,19 +501,22 @@ void Con_DrawNotify (void)
|
||||||
int x, v;
|
int x, v;
|
||||||
char *text;
|
char *text;
|
||||||
int i;
|
int i;
|
||||||
float time;
|
int time;
|
||||||
char *s;
|
char *s;
|
||||||
int skip;
|
int skip;
|
||||||
|
|
||||||
v = 0;
|
v = 0;
|
||||||
for (i= con.current-NUM_CON_TIMES+1 ; i<=con.current ; i++)
|
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];
|
time = con.times[i % NUM_CON_TIMES];
|
||||||
if (time == 0) continue;
|
if (time == 0)
|
||||||
|
continue;
|
||||||
time = cls.realtime - time;
|
time = cls.realtime - time;
|
||||||
if (time > con_notifytime->value) continue;
|
if (time > con_notifytime->value*1000)
|
||||||
text = con.text + (i % con.totallines) * con.linewidth;
|
continue;
|
||||||
|
text = con.text + (i % con.totallines)*con.linewidth;
|
||||||
|
|
||||||
for (x = 0 ; x < con.linewidth ; x++)
|
for (x = 0 ; x < con.linewidth ; x++)
|
||||||
re->DrawChar ( (x+1)<<3, v, text[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]);
|
re->DrawChar ( (x+skip)<<3, v, s[x]);
|
||||||
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;
|
v += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ cvar_t *cvar_vars;
|
||||||
Cvar_InfoValidate
|
Cvar_InfoValidate
|
||||||
============
|
============
|
||||||
*/
|
*/
|
||||||
static bool Cvar_InfoValidate (const char *s)
|
static bool Cvar_InfoValidate (char *s)
|
||||||
{
|
{
|
||||||
if (strstr (s, "\\"))
|
if (strstr (s, "\\"))
|
||||||
return false;
|
return false;
|
||||||
|
@ -44,11 +44,11 @@ static bool Cvar_InfoValidate (const char *s)
|
||||||
Cvar_FindVar
|
Cvar_FindVar
|
||||||
============
|
============
|
||||||
*/
|
*/
|
||||||
cvar_t *Cvar_FindVar (const char *var_name)
|
cvar_t *Cvar_FindVar (char *var_name)
|
||||||
{
|
{
|
||||||
cvar_t *var;
|
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))
|
if (!strcmp (var_name, var->name))
|
||||||
return var;
|
return var;
|
||||||
|
|
||||||
|
@ -60,12 +60,13 @@ cvar_t *Cvar_FindVar (const char *var_name)
|
||||||
Cvar_VariableValue
|
Cvar_VariableValue
|
||||||
============
|
============
|
||||||
*/
|
*/
|
||||||
float Cvar_VariableValue (const char *var_name)
|
float Cvar_VariableValue (char *var_name)
|
||||||
{
|
{
|
||||||
cvar_t *var;
|
cvar_t *var;
|
||||||
|
|
||||||
var = Cvar_FindVar (var_name);
|
var = Cvar_FindVar (var_name);
|
||||||
if (!var) return 0;
|
if (!var)
|
||||||
|
return 0;
|
||||||
return atof (var->string);
|
return atof (var->string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,12 +76,13 @@ float Cvar_VariableValue (const char *var_name)
|
||||||
Cvar_VariableString
|
Cvar_VariableString
|
||||||
============
|
============
|
||||||
*/
|
*/
|
||||||
char *Cvar_VariableString (const char *var_name)
|
char *Cvar_VariableString (char *var_name)
|
||||||
{
|
{
|
||||||
cvar_t *var;
|
cvar_t *var;
|
||||||
|
|
||||||
var = Cvar_FindVar (var_name);
|
var = Cvar_FindVar (var_name);
|
||||||
if (!var) return "";
|
if (!var)
|
||||||
|
return "";
|
||||||
return var->string;
|
return var->string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,15 +95,16 @@ Cvar_CompleteVariable
|
||||||
char *Cvar_CompleteVariable (char *partial)
|
char *Cvar_CompleteVariable (char *partial)
|
||||||
{
|
{
|
||||||
cvar_t *cvar;
|
cvar_t *cvar;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
len = strlen(partial);
|
len = strlen(partial);
|
||||||
|
|
||||||
if (!len) return NULL;
|
if (!len)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
// check exact match
|
// check exact match
|
||||||
for (cvar=cvar_vars ; cvar ; cvar=cvar->next)
|
for (cvar=cvar_vars ; cvar ; cvar=cvar->next)
|
||||||
if (!strcmp (partial, cvar->name))
|
if (!strcmp (partial,cvar->name))
|
||||||
return cvar->name;
|
return cvar->name;
|
||||||
|
|
||||||
// check partial match
|
// 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.
|
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;
|
cvar_t *var;
|
||||||
|
|
||||||
|
@ -173,12 +176,15 @@ cvar_t *Cvar_Get (const char *var_name, const char *var_value, int flags)
|
||||||
Cvar_Set2
|
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;
|
cvar_t *var;
|
||||||
|
|
||||||
var = Cvar_FindVar (var_name);
|
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))
|
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;
|
var->modified = true;
|
||||||
|
|
||||||
// transmit at next oportunity
|
if (var->flags & CVAR_USERINFO)
|
||||||
if (var->flags & CVAR_USERINFO) userinfo_modified = true;
|
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->string = CopyString(value);
|
||||||
var->value = atof(var->string);
|
var->value = atof (var->string);
|
||||||
|
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
@ -254,7 +260,7 @@ cvar_t *Cvar_Set2 (const char *var_name, const char *value, bool force)
|
||||||
Cvar_ForceSet
|
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);
|
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_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);
|
return Cvar_Set2 (var_name, value, false);
|
||||||
}
|
}
|
||||||
|
@ -346,13 +352,14 @@ Handles variable inspection and changing from the console
|
||||||
*/
|
*/
|
||||||
bool Cvar_Command (void)
|
bool Cvar_Command (void)
|
||||||
{
|
{
|
||||||
cvar_t *v;
|
cvar_t *v;
|
||||||
|
|
||||||
// check variables
|
// check variables
|
||||||
v = Cvar_FindVar (Cmd_Argv(0));
|
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)
|
if (Cmd_Argc() == 1)
|
||||||
{
|
{
|
||||||
Msg ("\"%s\" is \"%s\"\n", v->name, v->string);
|
Msg ("\"%s\" is \"%s\"\n", v->name, v->string);
|
||||||
|
@ -385,8 +392,10 @@ void Cvar_Set_f (void)
|
||||||
|
|
||||||
if (c == 4)
|
if (c == 4)
|
||||||
{
|
{
|
||||||
if (!strcmp(Cmd_Argv(3), "u")) flags = CVAR_USERINFO;
|
if (!strcmp(Cmd_Argv(3), "u"))
|
||||||
else if (!strcmp(Cmd_Argv(3), "s")) flags = CVAR_SERVERINFO;
|
flags = CVAR_USERINFO;
|
||||||
|
else if (!strcmp(Cmd_Argv(3), "s"))
|
||||||
|
flags = CVAR_SERVERINFO;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Msg ("flags can only be 'u' or 's'\n");
|
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);
|
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;
|
bool userinfo_modified;
|
||||||
|
|
||||||
|
|
||||||
char *Cvar_BitInfo (int bit)
|
char *Cvar_BitInfo (int bit)
|
||||||
{
|
{
|
||||||
static char info[MAX_INFO_STRING];
|
static char info[MAX_INFO_STRING];
|
||||||
cvar_t *var;
|
cvar_t *var;
|
||||||
|
@ -481,13 +491,13 @@ char *Cvar_BitInfo (int bit)
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns an info string containing all the CVAR_USERINFO cvars
|
// returns an info string containing all the CVAR_USERINFO cvars
|
||||||
char *Cvar_Userinfo (void)
|
char *Cvar_Userinfo (void)
|
||||||
{
|
{
|
||||||
return Cvar_BitInfo (CVAR_USERINFO);
|
return Cvar_BitInfo (CVAR_USERINFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns an info string containing all the CVAR_SERVERINFO cvars
|
// returns an info string containing all the CVAR_SERVERINFO cvars
|
||||||
char *Cvar_Serverinfo (void)
|
char *Cvar_Serverinfo (void)
|
||||||
{
|
{
|
||||||
return Cvar_BitInfo (CVAR_SERVERINFO);
|
return Cvar_BitInfo (CVAR_SERVERINFO);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,18 +6,17 @@
|
||||||
#define CVAR_H
|
#define CVAR_H
|
||||||
|
|
||||||
extern cvar_t *cvar_vars;
|
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
|
// 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
|
// if it exists, the value will not be changed, but flags will be ORed in
|
||||||
// that allows variables to be unarchived without needing bitflags
|
// that allows variables to be unarchived without needing bitflags
|
||||||
|
|
||||||
#define Cvar_Set(name, val) _Cvar_Set (name, val, __FILE__, __LINE__)
|
cvar_t *Cvar_Set (char *var_name, char *value);
|
||||||
cvar_t *_Cvar_Set (const char *var_name, const char *value, const char *filename, int fileline);
|
|
||||||
// will create the variable if it doesn't exist
|
// 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
|
// will set the variable even if NOSET or LATCH
|
||||||
|
|
||||||
cvar_t *Cvar_FullSet (char *var_name, char *value, int flags);
|
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);
|
void Cvar_SetValue (char *var_name, float value);
|
||||||
// expands value to a string and calls Cvar_Set
|
// 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
|
// 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
|
// returns an empty string if not defined
|
||||||
|
|
||||||
char *Cvar_CompleteVariable (char *partial);
|
char *Cvar_CompleteVariable (char *partial);
|
||||||
|
|
|
@ -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!
|
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 *kb;
|
||||||
char cmd[1024];
|
char cmd[1024];
|
||||||
|
@ -835,7 +835,7 @@ void Key_Event (int key, bool down, uint msec)
|
||||||
kb = keybindings[key];
|
kb = keybindings[key];
|
||||||
if (kb && kb[0] == '+')
|
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);
|
Cbuf_AddText (cmd);
|
||||||
}
|
}
|
||||||
if (keyshift[key] != key)
|
if (keyshift[key] != key)
|
||||||
|
@ -843,7 +843,7 @@ void Key_Event (int key, bool down, uint msec)
|
||||||
kb = keybindings[keyshift[key]];
|
kb = keybindings[keyshift[key]];
|
||||||
if (kb && kb[0] == '+')
|
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);
|
Cbuf_AddText (cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -859,7 +859,7 @@ void Key_Event (int key, bool down, uint msec)
|
||||||
if (kb[0] == '+')
|
if (kb[0] == '+')
|
||||||
{
|
{
|
||||||
// button commands add keynum and time as a parm
|
// 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);
|
Cbuf_AddText (cmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -137,12 +137,10 @@ extern char chat_buffer[];
|
||||||
extern int chat_bufferlen;
|
extern int chat_bufferlen;
|
||||||
extern bool chat_team;
|
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_Init (void);
|
||||||
void Key_WriteBindings (file_t *f);
|
void Key_WriteBindings (file_t *f);
|
||||||
void Key_SetBinding (int keynum, char *binding);
|
void Key_SetBinding (int keynum, char *binding);
|
||||||
void Key_ClearStates (void);
|
void Key_ClearStates (void);
|
||||||
char *Key_KeynumToString (int keynum);
|
|
||||||
int Key_StringToKeynum (char *str);
|
|
||||||
int Key_GetKey (void);
|
int Key_GetKey (void);
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ void M_PushMenu ( void (*draw) (void), const char *(*key) (int k) )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (host.maxclients == 1 && Com_ServerState ())
|
if (Cvar_VariableValue ("maxclients") == 1 && Com_ServerState ())
|
||||||
Cvar_Set ("paused", "1");
|
Cvar_Set ("paused", "1");
|
||||||
|
|
||||||
// if this menu is already present, drop back to that level
|
// 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++ )
|
for ( i = 0; i < NUM_CURSOR_FRAMES; i++ )
|
||||||
{
|
{
|
||||||
sprintf( cursorname, "m_cursor%d", i );
|
sprintf( cursorname, "m_cursor%d", i );
|
||||||
|
|
||||||
re->RegisterPic( cursorname );
|
re->RegisterPic( cursorname );
|
||||||
}
|
}
|
||||||
cached = true;
|
cached = true;
|
||||||
|
@ -424,7 +425,7 @@ void M_Main_Draw (void)
|
||||||
strlcat( litname, "_sel", 80 );
|
strlcat( litname, "_sel", 80 );
|
||||||
re->DrawPic( xoffset, ystart + m_main_cursor * 40 + 13, litname );
|
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->DrawGetPicSize( &w, &h, "m_main_plaque" );
|
||||||
re->DrawPic( xoffset - 30 - w, ystart, "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 )
|
static void KeyCursorDrawFunc( menuframework_s *menu )
|
||||||
{
|
{
|
||||||
if ( bind_grab ) re->DrawChar( menu->x, menu->y + menu->cursor * 9, '=' );
|
if ( bind_grab )
|
||||||
else re->DrawChar( menu->x, menu->y + menu->cursor * 9, 12 + ((int)(cls.realtime * 5.0f) & 1 ));
|
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 )
|
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 const char **credits;
|
||||||
static char *creditsIndex[256];
|
static char *creditsIndex[256];
|
||||||
static char *creditsBuffer;
|
static char *creditsBuffer;
|
||||||
|
@ -1452,20 +1455,161 @@ static const char *idcredits[] =
|
||||||
0
|
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 )
|
void M_Credits_MenuDraw( void )
|
||||||
{
|
{
|
||||||
int i;
|
int i, y;
|
||||||
float y;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** draw the credits
|
** 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 j, stringoffset = 0;
|
||||||
int bold = false;
|
int bold = false;
|
||||||
|
|
||||||
if ( y <= -8 ) continue;
|
if ( y <= -8 )
|
||||||
|
continue;
|
||||||
|
|
||||||
if ( credits[i][0] == '+' )
|
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;
|
x = ( viddef.width - strlen( credits[i] ) * 8 - stringoffset * 8 ) / 2 + ( j + stringoffset ) * 8;
|
||||||
|
|
||||||
if ( bold ) re->DrawChar( x, y, credits[i][j+stringoffset] + 128 );
|
if ( bold )
|
||||||
else re->DrawChar( x, y, credits[i][j+stringoffset] );
|
re->DrawChar( x, y, credits[i][j+stringoffset] + 128 );
|
||||||
|
else
|
||||||
|
re->DrawChar( x, y, credits[i][j+stringoffset] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop demonstration
|
if ( y < 0 )
|
||||||
if ( y < 0 ) credits_start_time = cls.realtime;
|
credits_start_time = cls.realtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *M_Credits_Key( int key )
|
const char *M_Credits_Key( int key )
|
||||||
|
@ -1510,12 +1656,12 @@ void M_Menu_Credits_f( void )
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
int count;
|
int count;
|
||||||
char *p;
|
char *p;
|
||||||
int isdeveloper = 0;
|
int isdeveloper = 0;
|
||||||
|
|
||||||
creditsBuffer = NULL;
|
creditsBuffer = NULL;
|
||||||
creditsBuffer = FS_LoadFile ("scripts/credits.txt", &count );
|
creditsBuffer = FS_LoadFile ("credits", &count );
|
||||||
if (count)
|
if (count != -1)
|
||||||
{
|
{
|
||||||
p = creditsBuffer;
|
p = creditsBuffer;
|
||||||
for (n = 0; n < 255; n++)
|
for (n = 0; n < 255; n++)
|
||||||
|
@ -1524,15 +1670,18 @@ void M_Menu_Credits_f( void )
|
||||||
while (*p != '\r' && *p != '\n')
|
while (*p != '\r' && *p != '\n')
|
||||||
{
|
{
|
||||||
p++;
|
p++;
|
||||||
if (--count == 0) break;
|
if (--count == 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (*p == '\r')
|
if (*p == '\r')
|
||||||
{
|
{
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
if (--count == 0) break;
|
if (--count == 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
if (--count == 0) break;
|
if (--count == 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
creditsIndex[++n] = 0;
|
creditsIndex[++n] = 0;
|
||||||
credits = creditsIndex;
|
credits = creditsIndex;
|
||||||
|
@ -2086,8 +2235,7 @@ void StartServerActionFunc( void *self )
|
||||||
timelimit = atoi( s_timelimit_field.buffer );
|
timelimit = atoi( s_timelimit_field.buffer );
|
||||||
fraglimit = atoi( s_fraglimit_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 ("timelimit", ClampCvar( 0, timelimit, timelimit ) );
|
||||||
Cvar_SetValue ("fraglimit", ClampCvar( 0, fraglimit, fraglimit ) );
|
Cvar_SetValue ("fraglimit", ClampCvar( 0, fraglimit, fraglimit ) );
|
||||||
Cvar_Set("hostname", s_hostname_field.buffer );
|
Cvar_Set("hostname", s_hostname_field.buffer );
|
||||||
|
@ -2347,8 +2495,10 @@ void StartServer_MenuInit( void )
|
||||||
s_maxclients_field.generic.statusbar = NULL;
|
s_maxclients_field.generic.statusbar = NULL;
|
||||||
s_maxclients_field.length = 3;
|
s_maxclients_field.length = 3;
|
||||||
s_maxclients_field.visible_length = 3;
|
s_maxclients_field.visible_length = 3;
|
||||||
if ( host.maxclients == 1 ) strcpy( s_maxclients_field.buffer, "8" );
|
if ( Cvar_VariableValue( "maxclients" ) == 1 )
|
||||||
else strcpy( s_maxclients_field.buffer, "32" ); // just for test
|
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.type = MTYPE_FIELD;
|
||||||
s_hostname_field.generic.name = "hostname";
|
s_hostname_field.generic.name = "hostname";
|
||||||
|
@ -3338,7 +3488,7 @@ void PlayerConfig_MenuDraw( void )
|
||||||
refdef.height = 168;
|
refdef.height = 168;
|
||||||
refdef.fov_x = 40;
|
refdef.fov_x = 40;
|
||||||
refdef.fov_y = CalcFov( refdef.fov_x, refdef.width, refdef.height );
|
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 )
|
if ( s_pmi[s_player_model_box.curvalue].skindisplaynames )
|
||||||
{
|
{
|
||||||
|
@ -3527,7 +3677,8 @@ void M_Draw (void)
|
||||||
SCR_DirtyScreen ();
|
SCR_DirtyScreen ();
|
||||||
|
|
||||||
// dim everything behind it down
|
// 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 ();
|
else re->DrawFadeScreen ();
|
||||||
|
|
||||||
m_drawfunc ();
|
m_drawfunc ();
|
||||||
|
|
|
@ -93,7 +93,7 @@ void Netchan_Init (void)
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
// pick a port value that should be nice and random
|
// 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 );
|
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->sock = sock;
|
||||||
chan->remote_address = adr;
|
chan->remote_address = adr;
|
||||||
chan->qport = qport;
|
chan->qport = qport;
|
||||||
chan->last_received = host.realtime * 1000;
|
chan->last_received = curtime;
|
||||||
chan->incoming_sequence = 0;
|
chan->incoming_sequence = 0;
|
||||||
chan->outgoing_sequence = 1;
|
chan->outgoing_sequence = 1;
|
||||||
|
|
||||||
|
@ -218,11 +218,12 @@ void Netchan_Transmit (netchan_t *chan, int length, byte *data)
|
||||||
bool send_reliable;
|
bool send_reliable;
|
||||||
unsigned w1, w2;
|
unsigned w1, w2;
|
||||||
|
|
||||||
// check for message overflow
|
// check for message overflow
|
||||||
if (chan->message.overflowed)
|
if (chan->message.overflowed)
|
||||||
{
|
{
|
||||||
chan->fatal_error = true;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,21 +231,21 @@ void Netchan_Transmit (netchan_t *chan, int length, byte *data)
|
||||||
|
|
||||||
if (!chan->reliable_length && chan->message.cursize)
|
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->reliable_length = chan->message.cursize;
|
||||||
chan->message.cursize = 0;
|
chan->message.cursize = 0;
|
||||||
chan->reliable_sequence ^= 1;
|
chan->reliable_sequence ^= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// write the packet header
|
// write the packet header
|
||||||
SZ_Init (&send, send_buf, sizeof(send_buf));
|
SZ_Init (&send, send_buf, sizeof(send_buf));
|
||||||
|
|
||||||
w1 = ( chan->outgoing_sequence & ~(1<<31) ) | (send_reliable<<31);
|
w1 = ( chan->outgoing_sequence & ~(1<<31) ) | (send_reliable<<31);
|
||||||
w2 = ( chan->incoming_sequence & ~(1<<31) ) | (chan->incoming_reliable_sequence<<31);
|
w2 = ( chan->incoming_sequence & ~(1<<31) ) | (chan->incoming_reliable_sequence<<31);
|
||||||
|
|
||||||
chan->outgoing_sequence++;
|
chan->outgoing_sequence++;
|
||||||
chan->last_sent = host.realtime * 1000;
|
chan->last_sent = curtime;
|
||||||
|
|
||||||
MSG_WriteLong (&send, w1);
|
MSG_WriteLong (&send, w1);
|
||||||
MSG_WriteLong (&send, w2);
|
MSG_WriteLong (&send, w2);
|
||||||
|
@ -297,9 +298,9 @@ bool Netchan_Process (netchan_t *chan, sizebuf_t *msg)
|
||||||
{
|
{
|
||||||
unsigned sequence, sequence_ack;
|
unsigned sequence, sequence_ack;
|
||||||
unsigned reliable_ack, reliable_message;
|
unsigned reliable_ack, reliable_message;
|
||||||
int qport;
|
int qport;
|
||||||
|
|
||||||
// get sequence numbers
|
// get sequence numbers
|
||||||
MSG_BeginReading (msg);
|
MSG_BeginReading (msg);
|
||||||
sequence = MSG_ReadLong (msg);
|
sequence = MSG_ReadLong (msg);
|
||||||
sequence_ack = 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 (chan->dropped > 0)
|
||||||
{
|
{
|
||||||
if (showdrop->value)
|
if (showdrop->value)
|
||||||
Msg ("%s:Dropped %i packets at %i\n",
|
Msg ("%s:Dropped %i packets at %i\n"
|
||||||
NET_AdrToString (chan->remote_address),
|
, NET_AdrToString (chan->remote_address)
|
||||||
chan->dropped,
|
, chan->dropped
|
||||||
sequence);
|
, sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// if the current outgoing reliable message has been acknowledged
|
// if the current outgoing reliable message has been acknowledged
|
||||||
// clear the buffer to make way for the next
|
// clear the buffer to make way for the next
|
||||||
//
|
//
|
||||||
if (reliable_ack == chan->reliable_sequence)
|
if (reliable_ack == chan->reliable_sequence)
|
||||||
chan->reliable_length = 0; // it has been received
|
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_sequence = sequence;
|
||||||
chan->incoming_acknowledged = sequence_ack;
|
chan->incoming_acknowledged = sequence_ack;
|
||||||
chan->incoming_reliable_acknowledged = reliable_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;
|
chan->incoming_reliable_sequence ^= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// the message can now be read from the current message pointer
|
// the message can now be read from the current message pointer
|
||||||
//
|
//
|
||||||
chan->last_received = host.realtime * 1000;
|
chan->last_received = curtime;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
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->data = data;
|
||||||
buf->maxsize = length;
|
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->cursize = 0;
|
||||||
buf->overflowed = false;
|
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;
|
void *data;
|
||||||
|
|
||||||
if (buf->cursize + length > buf->maxsize)
|
if (buf->cursize + length > buf->maxsize)
|
||||||
{
|
{
|
||||||
if (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);
|
SZ_Clear (buf);
|
||||||
buf->overflowed = true;
|
buf->overflowed = true;
|
||||||
}
|
}
|
||||||
|
@ -576,20 +568,20 @@ void *_SZ_GetSpace (sizebuf_t *buf, int length, const char *filename, int fileli
|
||||||
return data;
|
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;
|
int len;
|
||||||
|
|
||||||
len = strlen(data) + 1;
|
len = strlen(data) + 1;
|
||||||
if (buf->cursize)
|
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
|
if (buf->data[buf->cursize - 1]) Mem_Copy ((byte *)SZ_GetSpace(buf, len),data,len); //no trailing 0
|
||||||
else pi->Mem.Copy((byte *)_SZ_GetSpace(buf, len - 1, filename, fileline) - 1, data, len, filename, fileline); // write over 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);
|
||||||
}
|
}
|
|
@ -367,9 +367,12 @@ bool NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (host.type == HOST_DEDICATED) // let dedicated servers continue after errors
|
if (dedicated->value) // let dedicated servers continue after errors
|
||||||
Msg ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(*net_from));
|
Msg ("NET_GetPacket: %s from %s\n", NET_ErrorString(),
|
||||||
else Com_Error (ERR_DROP, "NET_GetPacket: %s from %s", NET_ErrorString(), NET_AdrToString(*net_from));
|
NET_AdrToString(*net_from));
|
||||||
|
else
|
||||||
|
Com_Error (ERR_DROP, "NET_GetPacket: %s from %s",
|
||||||
|
NET_ErrorString(), NET_AdrToString(*net_from));
|
||||||
continue;
|
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)))
|
if ((err == WSAEADDRNOTAVAIL) && ((to.type == NA_BROADCAST) || (to.type == NA_BROADCAST_IPX)))
|
||||||
return;
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -529,10 +533,13 @@ NET_OpenIP
|
||||||
void NET_OpenIP (void)
|
void NET_OpenIP (void)
|
||||||
{
|
{
|
||||||
cvar_t *ip;
|
cvar_t *ip;
|
||||||
int port;
|
int port;
|
||||||
|
int dedicated;
|
||||||
|
|
||||||
ip = Cvar_Get ("ip", "localhost", CVAR_NOSET);
|
ip = Cvar_Get ("ip", "localhost", CVAR_NOSET);
|
||||||
|
|
||||||
|
dedicated = Cvar_VariableValue ("dedicated");
|
||||||
|
|
||||||
if (!ip_sockets[NS_SERVER])
|
if (!ip_sockets[NS_SERVER])
|
||||||
{
|
{
|
||||||
port = Cvar_Get("ip_hostport", "0", CVAR_NOSET)->value;
|
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);
|
ip_sockets[NS_SERVER] = NET_IPSocket (ip->string, port);
|
||||||
if (!ip_sockets[NS_SERVER] && host.type == HOST_DEDICATED)
|
if (!ip_sockets[NS_SERVER] && dedicated) Sys_Error("Couldn't allocate dedicated server IP port");
|
||||||
Sys_Error("Couldn't allocate dedicated server IP port");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// dedicated servers don't need client ports
|
// dedicated servers don't need client ports
|
||||||
if (host.type == HOST_DEDICATED) return;
|
if (dedicated) return;
|
||||||
|
|
||||||
if (!ip_sockets[NS_CLIENT])
|
if (!ip_sockets[NS_CLIENT])
|
||||||
{
|
{
|
||||||
|
@ -630,6 +636,9 @@ NET_OpenIPX
|
||||||
void NET_OpenIPX (void)
|
void NET_OpenIPX (void)
|
||||||
{
|
{
|
||||||
int port;
|
int port;
|
||||||
|
int dedicated;
|
||||||
|
|
||||||
|
dedicated = Cvar_VariableValue ("dedicated");
|
||||||
|
|
||||||
if (!ipx_sockets[NS_SERVER])
|
if (!ipx_sockets[NS_SERVER])
|
||||||
{
|
{
|
||||||
|
@ -646,7 +655,8 @@ void NET_OpenIPX (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// dedicated servers don't need client ports
|
// dedicated servers don't need client ports
|
||||||
if (host.type == HOST_DEDICATED) return;
|
if (dedicated)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!ipx_sockets[NS_CLIENT])
|
if (!ipx_sockets[NS_CLIENT])
|
||||||
{
|
{
|
||||||
|
@ -671,7 +681,7 @@ NET_Config
|
||||||
A single player game will only use the loopback code
|
A single player game will only use the loopback code
|
||||||
====================
|
====================
|
||||||
*/
|
*/
|
||||||
void NET_Config (bool multiplayer)
|
void NET_Config (bool multiplayer)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
static bool old_config;
|
static bool old_config;
|
||||||
|
@ -709,26 +719,27 @@ void NET_Config (bool multiplayer)
|
||||||
// sleeps msec or until net socket is ready
|
// sleeps msec or until net socket is ready
|
||||||
void NET_Sleep(int msec)
|
void NET_Sleep(int msec)
|
||||||
{
|
{
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
fd_set fdset;
|
fd_set fdset;
|
||||||
int i = 0;
|
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);
|
FD_ZERO(&fdset);
|
||||||
|
i = 0;
|
||||||
if (ip_sockets[NS_SERVER])
|
if (ip_sockets[NS_SERVER]) {
|
||||||
{
|
|
||||||
FD_SET(ip_sockets[NS_SERVER], &fdset); // network socket
|
FD_SET(ip_sockets[NS_SERVER], &fdset); // network socket
|
||||||
i = ip_sockets[NS_SERVER];
|
i = ip_sockets[NS_SERVER];
|
||||||
}
|
}
|
||||||
if (ipx_sockets[NS_SERVER])
|
if (ipx_sockets[NS_SERVER]) {
|
||||||
{
|
|
||||||
FD_SET(ipx_sockets[NS_SERVER], &fdset); // network socket
|
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_sec = msec/1000;
|
||||||
timeout.tv_usec = (msec%1000) * 1000;
|
timeout.tv_usec = (msec%1000)*1000;
|
||||||
select(i+1, &fdset, NULL, NULL, &timeout);
|
select(i+1, &fdset, NULL, NULL, &timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -312,7 +312,7 @@ void PM_Friction (void)
|
||||||
{
|
{
|
||||||
friction = pm_friction;
|
friction = pm_friction;
|
||||||
control = speed < pm_stopspeed ? pm_stopspeed : speed;
|
control = speed < pm_stopspeed ? pm_stopspeed : speed;
|
||||||
drop += control*friction * pml.frametime;
|
drop += control*friction*pml.frametime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply water friction
|
// apply water friction
|
||||||
|
@ -1083,7 +1083,7 @@ void PM_ClampAngles (void)
|
||||||
else if (pm->viewangles[PITCH] < 271 && pm->viewangles[PITCH] >= 180)
|
else if (pm->viewangles[PITCH] < 271 && pm->viewangles[PITCH] >= 180)
|
||||||
pm->viewangles[PITCH] = 271;
|
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
|
// teleport pause stays exactly in place
|
||||||
}
|
}
|
||||||
else if (pm->s.pm_flags & PMF_TIME_WATERJUMP)
|
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;
|
pml.velocity[2] -= pm->s.gravity * pml.frametime;
|
||||||
if (pml.velocity[2] < 0)
|
if (pml.velocity[2] < 0)
|
||||||
{ // cancel as soon as we are falling down again
|
{ // 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] = angles[PITCH] - 360;
|
||||||
angles[PITCH] /= 3;
|
angles[PITCH] /= 3;
|
||||||
|
|
||||||
AngleVectorsRight (angles, pml.forward, pml.right, pml.up);
|
AngleVectors (angles, pml.forward, pml.right, pml.up);
|
||||||
PM_AirMove ();
|
PM_AirMove ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,13 +116,17 @@ void Field_Draw( menufield_s *f )
|
||||||
else
|
else
|
||||||
offset = f->cursor;
|
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
|
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 )
|
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
|
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 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ RSC=rc.exe
|
||||||
# PROP Ignore_Export_Lib 1
|
# PROP Ignore_Export_Lib 1
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
|
# 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
|
# SUBTRACT CPP /YX
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /win32
|
# ADD BASE MTL /nologo /D "NDEBUG" /win32
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
@ -80,7 +80,7 @@ SOURCE="$(InputPath)"
|
||||||
# PROP Ignore_Export_Lib 1
|
# PROP Ignore_Export_Lib 1
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
|
# 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
|
# SUBTRACT CPP /YX
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /win32
|
# ADD BASE MTL /nologo /D "_DEBUG" /win32
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
@ -91,7 +91,7 @@ BSC32=bscmake.exe
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
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 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
|
# SUBTRACT LINK32 /incremental:no /map /nodefaultlib
|
||||||
# Begin Custom Build
|
# Begin Custom Build
|
||||||
TargetDir=\XASH3D\src_main\!source\temp\engine\!debug
|
TargetDir=\XASH3D\src_main\!source\temp\engine\!debug
|
||||||
|
@ -126,10 +126,6 @@ SOURCE=.\client\cl_fx.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\client\cl_game.c
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\client\cl_input.c
|
SOURCE=.\client\cl_input.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
@ -278,6 +274,10 @@ SOURCE=.\server\sv_send.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\server\sv_spawn.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\server\sv_studio.c
|
SOURCE=.\server\sv_studio.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
@ -300,18 +300,6 @@ SOURCE=.\vid_dll.c
|
||||||
|
|
||||||
SOURCE=.\vid_menu.c
|
SOURCE=.\vid_menu.c
|
||||||
# End Source File
|
# 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
|
# End Group
|
||||||
# Begin Group "Header Files"
|
# Begin Group "Header Files"
|
||||||
|
|
||||||
|
@ -350,10 +338,6 @@ SOURCE=.\common\cvar.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\prvm\edict.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\engine.h
|
SOURCE=.\engine.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
@ -370,14 +354,6 @@ SOURCE=..\public\platform.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin 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
|
SOURCE=..\public\qfiles.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
@ -404,10 +380,6 @@ SOURCE=.\sound.h
|
||||||
|
|
||||||
SOURCE=.\common\vid.h
|
SOURCE=.\common\vid.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\prvm\vm_cmds.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
# End Group
|
||||||
# End Target
|
# End Target
|
||||||
# End Project
|
# End Project
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "basemath.h"
|
#include "basemath.h"
|
||||||
#include "qfiles.h"
|
#include "qfiles.h"
|
||||||
#include <ref_system.h>
|
#include <ref_system.h>
|
||||||
#include "vprogs.h"
|
|
||||||
#include "bspmodel.h"
|
#include "bspmodel.h"
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
@ -32,8 +31,6 @@ extern platform_exp_t *pi;
|
||||||
extern byte *zonepool;
|
extern byte *zonepool;
|
||||||
extern jmp_buf abortframe;
|
extern jmp_buf abortframe;
|
||||||
|
|
||||||
extern int host_debug;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
HOST_INIT, // initalize operations
|
HOST_INIT, // initalize operations
|
||||||
|
@ -74,6 +71,8 @@ typedef struct host_parm_s
|
||||||
|
|
||||||
extern host_parm_t host;
|
extern host_parm_t host;
|
||||||
|
|
||||||
|
int Sys_Milliseconds (void);
|
||||||
|
|
||||||
bool _GetParmFromCmdLine( char *parm, char *out, size_t size );
|
bool _GetParmFromCmdLine( char *parm, char *out, size_t size );
|
||||||
#define GetParmFromCmdLine( parm, out ) _GetParmFromCmdLine( parm, out, sizeof(out))
|
#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_FileBase( x, y ) pi->Fs.FileBase( x, y )
|
||||||
#define FS_Find( x ) pi->Fs.Search( x, false )
|
#define FS_Find( x ) pi->Fs.Search( x, false )
|
||||||
#define FS_Printf pi->Fs.Printf
|
#define FS_Printf pi->Fs.Printf
|
||||||
#define FS_Print pi->Fs.Print
|
|
||||||
#define FS_Seek pi->Fs.Seek
|
#define FS_Seek pi->Fs.Seek
|
||||||
#define FS_Tell pi->Fs.Tell
|
#define FS_Tell pi->Fs.Tell
|
||||||
#define FS_Gets pi->Fs.Gets
|
#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_Main ( void );
|
||||||
void Host_Free ( 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
|
#endif//ENGINE_H
|
|
@ -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>
|
|
109
engine/host.c
109
engine/host.c
|
@ -7,15 +7,14 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <dsound.h>
|
#include <dsound.h>
|
||||||
#include "engine.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
|
host_parm_t host; // host parms
|
||||||
|
|
||||||
byte *zonepool;
|
byte *zonepool;
|
||||||
int ActiveApp;
|
int ActiveApp;
|
||||||
|
bool Minimized;
|
||||||
// host params
|
extern uint sys_msg_time;
|
||||||
|
|
||||||
void Key_Init (void);
|
void Key_Init (void);
|
||||||
void SCR_EndLoadingPlaque (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 );
|
MsgDev(D_INFO, "------- Loading bin/engine.dll [%g] -------\n", ENGINE_VERSION );
|
||||||
|
|
||||||
Cbuf_Init();
|
Cbuf_Init ();
|
||||||
Cmd_Init();
|
Cmd_Init ();
|
||||||
Cvar_Init();
|
Cvar_Init ();
|
||||||
Key_Init();
|
Key_Init ();
|
||||||
PRVM_Init();
|
|
||||||
|
|
||||||
// we need to add the early commands twice, because
|
// we need to add the early commands twice, because
|
||||||
// a basedir or cddir needs to be set before execing
|
// 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);
|
Cmd_AddCommand ("error", Com_Error_f);
|
||||||
|
|
||||||
host_speeds = Cvar_Get ("host_speeds", "0", 0);
|
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);
|
timescale = Cvar_Get ("timescale", "1", 0);
|
||||||
fixedtime = Cvar_Get ("fixedtime", "0", 0);
|
fixedtime = Cvar_Get ("fixedtime", "0", 0);
|
||||||
showtrace = Cvar_Get ("showtrace", "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);
|
s = va("%4.2f %s %s %s", VERSION, "x86", __DATE__, BUILDSTRING);
|
||||||
Cvar_Get ("version", s, CVAR_SERVERINFO|CVAR_NOSET);
|
Cvar_Get ("version", s, CVAR_SERVERINFO|CVAR_NOSET);
|
||||||
|
|
||||||
if (host.type == HOST_DEDICATED)
|
if (dedicated->value) Cmd_AddCommand ("quit", Com_Quit);
|
||||||
{
|
|
||||||
Cmd_AddCommand ("quit", Com_Quit);
|
|
||||||
}
|
|
||||||
|
|
||||||
Sys_Init();
|
Sys_Init();
|
||||||
|
|
||||||
|
@ -134,10 +133,10 @@ void Host_Init (char *funcname, int argc, char **argv)
|
||||||
CL_Init();
|
CL_Init();
|
||||||
|
|
||||||
// add + commands from command line
|
// add + commands from command line
|
||||||
if (!Cbuf_AddLateCommands())
|
if (!Cbuf_AddLateCommands ())
|
||||||
{
|
{
|
||||||
// if the user didn't give any commands, run default action
|
// 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");
|
else Cbuf_AddText ("dedicated_start\n");
|
||||||
Cbuf_Execute ();
|
Cbuf_Execute ();
|
||||||
}
|
}
|
||||||
|
@ -156,9 +155,34 @@ Host_Frame
|
||||||
void Host_Frame (double time)
|
void Host_Frame (double time)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
|
static double time_before, time_between, time_after;
|
||||||
|
|
||||||
if (setjmp (abortframe) ) return; // an ERR_DROP was thrown
|
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)
|
if (showtrace->value)
|
||||||
{
|
{
|
||||||
extern int c_traces, c_brush_traces;
|
extern int c_traces, c_brush_traces;
|
||||||
|
@ -173,14 +197,32 @@ void Host_Frame (double time)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
s = Sys_ConsoleInput ();
|
s = Sys_ConsoleInput ();
|
||||||
if(s) Cbuf_AddText (va("%s\n",s));
|
if (s) Cbuf_AddText (va("%s\n",s));
|
||||||
} while (s);
|
} while (s);
|
||||||
Cbuf_Execute ();
|
Cbuf_Execute ();
|
||||||
|
|
||||||
|
if (host_speeds->value) time_before = Sys_DoubleTime();
|
||||||
|
|
||||||
SV_Frame (time);
|
SV_Frame (time);
|
||||||
|
|
||||||
|
if (host_speeds->value) time_between = Sys_DoubleTime();
|
||||||
|
|
||||||
CL_Frame (time);
|
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 )
|
void Host_Main( void )
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg;
|
||||||
static double oldtime, newtime;
|
int time, oldtime, newtime;
|
||||||
|
|
||||||
host.state = HOST_FRAME;
|
oldtime = Sys_Milliseconds ();
|
||||||
oldtime = Sys_DoubleTime(); //first call
|
|
||||||
|
|
||||||
// main window message loop
|
// main window message loop
|
||||||
while (host.type != HOST_OFFLINE)
|
while (1)
|
||||||
{
|
{
|
||||||
// if at a full screen console, don't update unless needed
|
// 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))
|
while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
|
||||||
{
|
{
|
||||||
if (!GetMessage (&msg, NULL, 0, 0)) Com_Quit ();
|
if (!GetMessage (&msg, NULL, 0, 0)) Com_Quit ();
|
||||||
host.sv_timer = msg.time;
|
sys_msg_time = msg.time;
|
||||||
TranslateMessage (&msg);
|
TranslateMessage (&msg);
|
||||||
DispatchMessage (&msg);
|
DispatchMessage (&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
newtime = Sys_DoubleTime();
|
newtime = Sys_Milliseconds ();
|
||||||
host.realtime = newtime - oldtime;
|
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;
|
oldtime = newtime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,9 +274,6 @@ Host_Shutdown
|
||||||
*/
|
*/
|
||||||
void Host_Free (void)
|
void Host_Free (void)
|
||||||
{
|
{
|
||||||
host.state = HOST_SHUTDOWN;
|
|
||||||
|
|
||||||
SV_Shutdown ("Server shutdown\n", false);
|
|
||||||
CL_Shutdown ();
|
CL_Shutdown ();
|
||||||
Host_FreePlatform();
|
Host_FreePlatform();
|
||||||
}
|
}
|
|
@ -24,7 +24,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "./client/client.h"
|
#include "./client/client.h"
|
||||||
|
|
||||||
|
extern unsigned sys_msg_time;
|
||||||
extern HWND cl_hwnd;
|
extern HWND cl_hwnd;
|
||||||
|
extern bool ActiveApp, Minimized;
|
||||||
|
|
||||||
// joystick defines and variables
|
// joystick defines and variables
|
||||||
// where should defines be moved?
|
// where should defines be moved?
|
||||||
|
@ -249,13 +251,13 @@ void IN_MouseEvent (int mstate)
|
||||||
if ( (mstate & (1<<i)) &&
|
if ( (mstate & (1<<i)) &&
|
||||||
!(mouse_oldbuttonstate & (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)) &&
|
if ( !(mstate & (1<<i)) &&
|
||||||
(mouse_oldbuttonstate & (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);
|
IN_MouseMove (cmd);
|
||||||
|
|
||||||
if (host.state == HOST_FRAME)
|
if (ActiveApp)
|
||||||
IN_JoyMove (cmd);
|
IN_JoyMove (cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
@ -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
|
@ -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
|
|
@ -18,16 +18,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
// server.h
|
// server.h
|
||||||
#ifndef SERVER_H
|
|
||||||
#define SERVER_H
|
|
||||||
|
|
||||||
//define PARANOID // speed sapping error checking
|
//define PARANOID // speed sapping error checking
|
||||||
|
|
||||||
#include "progsvm.h"
|
#include "ref_server.h"
|
||||||
#include "vm_cmds.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
|
#define MAX_MASTERS 8 // max recipients for heartbeat packets
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -45,18 +53,14 @@ typedef struct
|
||||||
{
|
{
|
||||||
server_state_t state; // precache commands are only valid during load
|
server_state_t state; // precache commands are only valid during load
|
||||||
|
|
||||||
bool attractloop; // running cinematics and demos for the local system only
|
bool attractloop; // running cinematics and demos for the local system only
|
||||||
bool loadgame; // client begins should reuse existing entity
|
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
|
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];
|
char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH];
|
||||||
entity_state_t baselines[MAX_EDICTS];
|
entity_state_t baselines[MAX_EDICTS];
|
||||||
|
@ -66,20 +70,23 @@ typedef struct
|
||||||
sizebuf_t multicast;
|
sizebuf_t multicast;
|
||||||
byte multicast_buf[MAX_MSGLEN];
|
byte multicast_buf[MAX_MSGLEN];
|
||||||
|
|
||||||
prvm_edict_t **moved_edicts;
|
|
||||||
|
|
||||||
// demo server information
|
// demo server information
|
||||||
file_t *demofile;
|
file_t *demofile;
|
||||||
bool timedemo; // don't time sync
|
bool timedemo; // don't time sync
|
||||||
|
|
||||||
|
byte *mempool;
|
||||||
} server_t;
|
} 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
|
typedef enum
|
||||||
{
|
{
|
||||||
cs_free, // can be reused for a new connection
|
cs_free, // can be reused for a new connection
|
||||||
cs_zombie, // client has been disconnected, but don't reuse
|
cs_zombie, // client has been disconnected, but don't reuse
|
||||||
// connection for a couple seconds
|
// connection for a couple seconds
|
||||||
cs_connected, // has been assigned to a client_t, but not in game yet
|
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;
|
} client_state_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -92,52 +99,49 @@ typedef struct
|
||||||
int senttime; // for ping calculations
|
int senttime; // for ping calculations
|
||||||
} client_frame_t;
|
} client_frame_t;
|
||||||
|
|
||||||
#define NUM_SPAWN_PARMS 16
|
|
||||||
#define LATENCY_COUNTS 16
|
#define LATENCY_COUNTS 16
|
||||||
#define RATE_MESSAGES 10
|
#define RATE_MESSAGES 10
|
||||||
|
|
||||||
typedef struct client_s
|
typedef struct client_s
|
||||||
{
|
{
|
||||||
client_state_t state;
|
client_state_t state;
|
||||||
|
|
||||||
char userinfo[MAX_INFO_STRING]; // name, etc
|
char userinfo[MAX_INFO_STRING]; // name, etc
|
||||||
|
|
||||||
int lastframe; // for delta compression
|
int lastframe; // for delta compression
|
||||||
usercmd_t lastcmd; // for filling in big drops
|
usercmd_t lastcmd; // for filling in big drops
|
||||||
|
|
||||||
int commandMsec; // every seconds this is reset, if user
|
int commandMsec; // every seconds this is reset, if user
|
||||||
// commands exhaust it, assume time cheating
|
// commands exhaust it, assume time cheating
|
||||||
|
|
||||||
int frame_latency[LATENCY_COUNTS];
|
int frame_latency[LATENCY_COUNTS];
|
||||||
int ping;
|
int ping;
|
||||||
|
|
||||||
int message_size[RATE_MESSAGES]; // used to rate drop packets
|
int message_size[RATE_MESSAGES]; // used to rate drop packets
|
||||||
int rate;
|
int rate;
|
||||||
int surpressCount; // number of messages rate supressed
|
int surpressCount; // number of messages rate supressed
|
||||||
|
|
||||||
float spawn_parms[NUM_SPAWN_PARMS]; // quake 1 legacy
|
edict_t *edict; // EDICT_NUM(clientnum+1)
|
||||||
|
|
||||||
prvm_edict_t *edict; // EDICT_NUM(clientnum+1)
|
|
||||||
char name[32]; // extracted from userinfo, high bits masked
|
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.
|
// The datagram is written to by sound calls, prints, temp ents, etc.
|
||||||
// It can be harmlessly overflowed.
|
// It can be harmlessly overflowed.
|
||||||
sizebuf_t datagram;
|
sizebuf_t datagram;
|
||||||
byte datagram_buf[MAX_MSGLEN];
|
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
|
byte *download; // file being downloaded
|
||||||
int downloadsize; // total bytes (can't use EOF because of paks)
|
int downloadsize; // total bytes (can't use EOF because of paks)
|
||||||
int downloadcount; // bytes sent
|
int downloadcount; // bytes sent
|
||||||
|
|
||||||
float lastmessage; // sv.framenum when packet was last received
|
int lastmessage; // sv.framenum when packet was last received
|
||||||
float lastconnect;
|
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;
|
} client_t;
|
||||||
|
|
||||||
// a client can leave the server in one of four ways:
|
// a client can leave the server in one of four ways:
|
||||||
|
@ -164,9 +168,7 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
bool initialized; // sv_init has completed
|
bool initialized; // sv_init has completed
|
||||||
double realtime; // always increasing, no clamping, etc
|
int realtime; // always increasing, no clamping, etc
|
||||||
|
|
||||||
int serverflags;
|
|
||||||
|
|
||||||
char mapcmd[MAX_TOKEN_CHARS]; // ie: *intro.cin+base
|
char mapcmd[MAX_TOKEN_CHARS]; // ie: *intro.cin+base
|
||||||
char comment[MAX_TOKEN_CHARS]; // map name, e.t.c.
|
char comment[MAX_TOKEN_CHARS]; // map name, e.t.c.
|
||||||
|
@ -174,12 +176,12 @@ typedef struct
|
||||||
int spawncount; // incremented each server start
|
int spawncount; // incremented each server start
|
||||||
// used to check late spawns
|
// used to check late spawns
|
||||||
|
|
||||||
client_t *clients; // [host.maxclients];
|
client_t *clients; // [maxclients->value];
|
||||||
int num_client_entities; // host.maxclients * UPDATE_BACKUP * MAX_PACKET_ENTITIES
|
int num_client_entities; // maxclients->value*UPDATE_BACKUP*MAX_PACKET_ENTITIES
|
||||||
int next_client_entities; // next client_entity to use
|
int next_client_entities; // next client_entity to use
|
||||||
entity_state_t *client_entities; // [num_client_entities]
|
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
|
challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting
|
||||||
|
|
||||||
|
@ -189,17 +191,6 @@ typedef struct
|
||||||
byte demo_multicast_buf[MAX_MSGLEN];
|
byte demo_multicast_buf[MAX_MSGLEN];
|
||||||
} server_static_t;
|
} 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;
|
extern netadr_t net_from;
|
||||||
|
@ -211,13 +202,17 @@ extern server_static_t svs; // persistant server info
|
||||||
extern server_t sv; // local server
|
extern server_t sv; // local server
|
||||||
|
|
||||||
extern cvar_t *sv_paused;
|
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_noreload; // don't reload level state when reentering
|
||||||
extern cvar_t *sv_airaccelerate; // 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
|
// development tool
|
||||||
extern cvar_t *sv_enforcetime;
|
extern cvar_t *sv_enforcetime;
|
||||||
|
|
||||||
extern client_t *sv_client;
|
extern client_t *sv_client;
|
||||||
extern prvm_edict_t *sv_player;
|
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_FinalMessage (char *message, bool reconnect);
|
||||||
void SV_DropClient (client_t *drop);
|
void SV_DropClient (client_t *drop);
|
||||||
|
|
||||||
int SV_ModelIndex (const char *name);
|
int SV_ModelIndex (char *name);
|
||||||
int SV_SoundIndex (const char *name);
|
int SV_SoundIndex (char *name);
|
||||||
int SV_ImageIndex (const char *name);
|
int SV_ImageIndex (char *name);
|
||||||
|
|
||||||
void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg);
|
void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg);
|
||||||
|
|
||||||
|
@ -248,16 +243,15 @@ void Master_Packet (void);
|
||||||
//
|
//
|
||||||
void SV_InitGame (void);
|
void SV_InitGame (void);
|
||||||
void SV_Map (bool attractloop, char *levelstring, char *savename, bool loadgame);
|
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
|
// sv_phys.c
|
||||||
//
|
//
|
||||||
void SV_PrepWorldFrame (void);
|
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
|
// sv_send.c
|
||||||
|
@ -271,7 +265,7 @@ void SV_FlushRedirect (int sv_redirected, char *outputbuf);
|
||||||
|
|
||||||
void SV_DemoCompleted (void);
|
void SV_DemoCompleted (void);
|
||||||
void SV_SendClientMessages (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,
|
int soundindex, float volume,
|
||||||
float attenuation, float timeofs);
|
float attenuation, float timeofs);
|
||||||
void SV_ClientPrintf (client_t *cl, int level, char *fmt, ...);
|
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_Nextserver (void);
|
||||||
void SV_ExecuteClientMessage (client_t *cl);
|
void SV_ExecuteClientMessage (client_t *cl);
|
||||||
void SV_ApplyClientMove (void);
|
|
||||||
void SV_ClientThink (void);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// sv_ccmds.c
|
// sv_ccmds.c
|
||||||
|
@ -297,19 +289,50 @@ void SV_Status_f (void);
|
||||||
void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg);
|
void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg);
|
||||||
void SV_RecordDemoMessage (void);
|
void SV_RecordDemoMessage (void);
|
||||||
void SV_BuildClientFrame (client_t *client);
|
void SV_BuildClientFrame (client_t *client);
|
||||||
void SV_FatPVS (vec3_t org);
|
|
||||||
|
|
||||||
|
|
||||||
void SV_Error (char *error, ...);
|
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
|
// 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 );
|
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
|
// sv_save.c
|
||||||
|
@ -327,18 +350,18 @@ void SV_ReadLevelFile( char *name );
|
||||||
void SV_ClearWorld (void);
|
void SV_ClearWorld (void);
|
||||||
// called after the world model has been loaded, before linking any entities
|
// 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,
|
// call before removing an entity, and before trying to move one,
|
||||||
// so it doesn't clip against itself
|
// 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,
|
// Needs to be called any time an entity changes origin, mins, maxs,
|
||||||
// or solid. Automatically unlinks if needed.
|
// or solid. Automatically unlinks if needed.
|
||||||
// sets ent->v.absmin and ent->v.absmax
|
// sets ent->v.absmin and ent->v.absmax
|
||||||
// sets ent->leafnums[] for pvs determination even if the entity
|
// sets ent->leafnums[] for pvs determination even if the entity
|
||||||
// is not solid
|
// 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
|
// 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
|
// 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
|
// 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
|
// 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_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, 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);
|
|
||||||
|
|
||||||
// mins and maxs are relative
|
// mins and maxs are relative
|
||||||
|
|
||||||
// if the entire move stays in a solid volume, trace.allsolid will be set,
|
// 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
|
// if the starting point is in a solid, it will be allowed to move out
|
||||||
// to an open area
|
// to an open area
|
||||||
|
|
||||||
// passedict is explicitly excluded from clipping checks (normally NULL)
|
// passedict is explicitly excluded from clipping checks (normally NULL)
|
||||||
|
|
||||||
#endif//SERVER_H
|
|
|
@ -43,7 +43,7 @@ void SV_SetMaster_f (void)
|
||||||
int i, slot;
|
int i, slot;
|
||||||
|
|
||||||
// only dedicated servers send heartbeats
|
// only dedicated servers send heartbeats
|
||||||
if (host.type == HOST_NORMAL)
|
if (!dedicated->value)
|
||||||
{
|
{
|
||||||
Msg ("Only dedicated servers use masters.\n");
|
Msg ("Only dedicated servers use masters.\n");
|
||||||
return;
|
return;
|
||||||
|
@ -52,11 +52,11 @@ void SV_SetMaster_f (void)
|
||||||
// make sure the server is listed public
|
// make sure the server is listed public
|
||||||
Cvar_Set ("public", "1");
|
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
|
slot = 1; // slot 0 will always contain the id master
|
||||||
|
for (i=1 ; i<Cmd_Argc() ; i++)
|
||||||
for (i = 1; i < Cmd_Argc(); i++)
|
|
||||||
{
|
{
|
||||||
if (slot == MAX_MASTERS)
|
if (slot == MAX_MASTERS)
|
||||||
break;
|
break;
|
||||||
|
@ -106,7 +106,7 @@ bool SV_SetPlayer (void)
|
||||||
if (s[0] >= '0' && s[0] <= '9')
|
if (s[0] >= '0' && s[0] <= '9')
|
||||||
{
|
{
|
||||||
idnum = atoi(Cmd_Argv(1));
|
idnum = atoi(Cmd_Argv(1));
|
||||||
if (idnum < 0 || idnum >= host.maxclients)
|
if (idnum < 0 || idnum >= maxclients->value)
|
||||||
{
|
{
|
||||||
Msg ("Bad client slot: %i\n", idnum);
|
Msg ("Bad client slot: %i\n", idnum);
|
||||||
return false;
|
return false;
|
||||||
|
@ -123,7 +123,7 @@ bool SV_SetPlayer (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for a name match
|
// 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)
|
if (!cl->state)
|
||||||
continue;
|
continue;
|
||||||
|
@ -192,18 +192,18 @@ void SV_GameMap_f (void)
|
||||||
// clear all the client inuse flags before saving so that
|
// clear all the client inuse flags before saving so that
|
||||||
// when the level is re-entered, the clients will spawn
|
// when the level is re-entered, the clients will spawn
|
||||||
// at spawn points instead of occupying body shells
|
// at spawn points instead of occupying body shells
|
||||||
savedInuse = Z_Malloc(host.maxclients * sizeof(bool));
|
savedInuse = Z_Malloc(maxclients->value * sizeof(bool));
|
||||||
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
|
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
|
||||||
{
|
{
|
||||||
savedInuse[i] = cl->edict->priv.sv->free;
|
savedInuse[i] = cl->edict->inuse;
|
||||||
cl->edict->priv.sv->free = true;
|
cl->edict->inuse = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SV_WriteSaveFile( "save0" ); //autosave
|
SV_WriteSaveFile( "save0" ); //autosave
|
||||||
|
|
||||||
// we must restore these for clients to transfer over correctly
|
// we must restore these for clients to transfer over correctly
|
||||||
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
|
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
|
||||||
cl->edict->priv.sv->free = savedInuse[i];
|
cl->edict->inuse = savedInuse[i];
|
||||||
Z_Free (savedInuse);
|
Z_Free (savedInuse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,28 +225,23 @@ For development work
|
||||||
*/
|
*/
|
||||||
void SV_Map_f (void)
|
void SV_Map_f (void)
|
||||||
{
|
{
|
||||||
char level_path[MAX_QPATH];
|
char *map;
|
||||||
|
char expanded[MAX_QPATH];
|
||||||
|
|
||||||
sprintf(level_path, "maps/%s", Cmd_Argv(1));
|
// if not a pcx, demo, or cinematic, check to make sure the level exists
|
||||||
FS_DefaultExtension(level_path, ".bsp" );
|
map = Cmd_Argv(1);
|
||||||
|
if (!strstr (map, "."))
|
||||||
if (FS_FileExists(level_path))
|
|
||||||
{
|
{
|
||||||
sv.state = ss_dead; // don't save current level when changing
|
sprintf (expanded, "maps/%s.bsp", map);
|
||||||
|
if (!FS_LoadFile (expanded, NULL))
|
||||||
SV_InitGame ();
|
{
|
||||||
Cvar_Set ("nextserver", ""); //reset demoloop
|
Msg ("Can't find %s\n", expanded);
|
||||||
|
return;
|
||||||
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
|
|
||||||
}
|
}
|
||||||
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;
|
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");
|
Msg ("\nCan't savegame while dead!\n");
|
||||||
return;
|
return;
|
||||||
|
@ -382,11 +377,11 @@ void SV_Status_f (void)
|
||||||
|
|
||||||
Msg ("num score ping name lastmsg address qport \n");
|
Msg ("num score ping name lastmsg address qport \n");
|
||||||
Msg ("--- ----- ---- --------------- ------- --------------------- ------\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;
|
if (!cl->state) continue;
|
||||||
Msg ("%3i ", i);
|
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)
|
if (cl->state == cs_connected)
|
||||||
Msg ("CNCT ");
|
Msg ("CNCT ");
|
||||||
|
@ -403,7 +398,7 @@ void SV_Status_f (void)
|
||||||
for (j=0 ; j<l ; j++)
|
for (j=0 ; j<l ; j++)
|
||||||
Msg (" ");
|
Msg (" ");
|
||||||
|
|
||||||
Msg ("%g ", svs.realtime - cl->lastmessage );
|
Msg ("%7i ", svs.realtime - cl->lastmessage );
|
||||||
|
|
||||||
s = NET_AdrToString ( cl->netchan.remote_address);
|
s = NET_AdrToString ( cl->netchan.remote_address);
|
||||||
Msg ("%s", s);
|
Msg ("%s", s);
|
||||||
|
@ -444,7 +439,7 @@ void SV_ConSay_f(void)
|
||||||
|
|
||||||
strcat(text, p);
|
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)
|
if (client->state != cs_spawned)
|
||||||
continue;
|
continue;
|
||||||
|
@ -622,6 +617,22 @@ void SV_KillServer_f (void)
|
||||||
NET_Config ( false ); // close network sockets
|
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 ("gamemap", SV_GameMap_f);
|
||||||
Cmd_AddCommand ("setmaster", SV_SetMaster_f);
|
Cmd_AddCommand ("setmaster", SV_SetMaster_f);
|
||||||
|
|
||||||
if (host.type == HOST_DEDICATED)
|
if ( dedicated->value ) Cmd_AddCommand ("say", SV_ConSay_f);
|
||||||
{
|
|
||||||
Cmd_AddCommand ("say", SV_ConSay_f);
|
|
||||||
}
|
|
||||||
|
|
||||||
Cmd_AddCommand ("serverrecord", SV_ServerRecord_f);
|
Cmd_AddCommand ("serverrecord", SV_ServerRecord_f);
|
||||||
Cmd_AddCommand ("serverstop", SV_ServerStop_f);
|
Cmd_AddCommand ("serverstop", SV_ServerStop_f);
|
||||||
Cmd_AddCommand ("save", SV_Savegame_f);
|
Cmd_AddCommand ("save", SV_Savegame_f);
|
||||||
Cmd_AddCommand ("load", SV_Loadgame_f);
|
Cmd_AddCommand ("load", SV_Loadgame_f);
|
||||||
Cmd_AddCommand ("killserver", SV_KillServer_f);
|
Cmd_AddCommand ("killserver", SV_KillServer_f);
|
||||||
|
Cmd_AddCommand ("sv", SV_ServerCommand_f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,11 +34,11 @@ Encode a client frame onto the network channel
|
||||||
// because there can be a lot of projectiles, there is a special
|
// because there can be a lot of projectiles, there is a special
|
||||||
// network protocol for them
|
// network protocol for them
|
||||||
#define MAX_PROJECTILES 64
|
#define MAX_PROJECTILES 64
|
||||||
prvm_edict_t *projectiles[MAX_PROJECTILES];
|
edict_t *projectiles[MAX_PROJECTILES];
|
||||||
int numprojs;
|
int numprojs;
|
||||||
cvar_t *sv_projectiles;
|
cvar_t *sv_projectiles;
|
||||||
|
|
||||||
bool SV_AddProjectileUpdate (prvm_edict_t *ent)
|
bool SV_AddProjectileUpdate (edict_t *ent)
|
||||||
{
|
{
|
||||||
if (!sv_projectiles)
|
if (!sv_projectiles)
|
||||||
sv_projectiles = Cvar_Get("sv_projectiles", "1", 0);
|
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]
|
byte bits[16]; // [modelindex] [48 bits] xyz p y 12 12 12 8 8 [entitynum] [e2]
|
||||||
int n, i;
|
int n, i;
|
||||||
prvm_edict_t *ent;
|
edict_t *ent;
|
||||||
int x, y, z, p, yaw;
|
int x, y, z, p, yaw;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
@ -157,31 +157,29 @@ void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newnum == oldnum)
|
if (newnum == oldnum)
|
||||||
{
|
{ // delta update from old position
|
||||||
// delta update from old position
|
|
||||||
// because the force parm is false, this will not result
|
// because the force parm is false, this will not result
|
||||||
// in any bytes being emited if the entity has not changed at all
|
// in any bytes being emited if the entity has not changed at all
|
||||||
// note that players are always 'newentities', this updates their oldorigin always
|
// note that players are always 'newentities', this updates their oldorigin always
|
||||||
// and prevents warping
|
// and prevents warping
|
||||||
MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= host.maxclients);
|
MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= maxclients->value);
|
||||||
oldindex++;
|
oldindex++;
|
||||||
newindex++;
|
newindex++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newnum < oldnum)
|
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);
|
MSG_WriteDeltaEntity (&sv.baselines[newnum], newent, msg, true, true);
|
||||||
newindex++;
|
newindex++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newnum > oldnum)
|
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;
|
bits = U_REMOVE;
|
||||||
if (oldnum >= 256) bits |= U_NUMBER16 | U_MOREBITS1;
|
if (oldnum >= 256)
|
||||||
|
bits |= U_NUMBER16 | U_MOREBITS1;
|
||||||
|
|
||||||
MSG_WriteByte (msg, bits&255 );
|
MSG_WriteByte (msg, bits&255 );
|
||||||
if (bits & 0x0000ff00)
|
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
|
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;
|
else ops = &from->ps;
|
||||||
|
|
||||||
// determine what needs to be sent
|
// determine what needs to be sent
|
||||||
if (ps->pmove.pm_type != ops->pmove.pm_type) pflags |= PS_M_TYPE;
|
if (ps->pmove.pm_type != ops->pmove.pm_type)
|
||||||
if (!VectorICompare(ps->pmove.origin, ops->pmove.origin)) pflags |= PS_M_ORIGIN;
|
pflags |= PS_M_TYPE;
|
||||||
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.origin[0] != ops->pmove.origin[0]
|
||||||
if (ps->pmove.pm_flags != ops->pmove.pm_flags) pflags |= PS_M_FLAGS;
|
|| ps->pmove.origin[1] != ops->pmove.origin[1]
|
||||||
if (ps->pmove.gravity != ops->pmove.gravity) pflags |= PS_M_GRAVITY;
|
|| ps->pmove.origin[2] != ops->pmove.origin[2] )
|
||||||
if (!VectorICompare(ps->pmove.delta_angles, ops->pmove.delta_angles)) pflags |= PS_M_DELTA_ANGLES;
|
pflags |= PS_M_ORIGIN;
|
||||||
if (!VectorCompare(ps->viewoffset, ops->viewoffset)) pflags |= PS_VIEWOFFSET;
|
|
||||||
if (!VectorCompare(ps->viewangles, ops->viewangles)) pflags |= PS_VIEWANGLES;
|
if (ps->pmove.velocity[0] != ops->pmove.velocity[0]
|
||||||
if (!VectorCompare(ps->kick_angles, ops->kick_angles)) pflags |= PS_KICKANGLES;
|
|| ps->pmove.velocity[1] != ops->pmove.velocity[1]
|
||||||
if (!VectorCompare(ps->blend, ops->blend)) pflags |= PS_BLEND;
|
|| ps->pmove.velocity[2] != ops->pmove.velocity[2] )
|
||||||
if (ps->fov != ops->fov) pflags |= PS_FOV;
|
pflags |= PS_M_VELOCITY;
|
||||||
if (ps->rdflags != ops->rdflags) pflags |= PS_RDFLAGS;
|
|
||||||
if (ps->gunframe != ops->gunframe) pflags |= PS_WEAPONFRAME;
|
if (ps->pmove.pm_time != ops->pmove.pm_time)
|
||||||
if (ps->sequence != ops->sequence) pflags |= PS_WEAPONSEQUENCE;
|
pflags |= PS_M_TIME;
|
||||||
if (ps->gunbody != ops->gunbody) pflags |= PS_WEAPONBODY;
|
|
||||||
if (ps->gunskin != ops->gunskin) pflags |= PS_WEAPONSKIN;
|
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;
|
pflags |= PS_WEAPONINDEX;
|
||||||
|
|
||||||
|
//
|
||||||
// write it
|
// write it
|
||||||
|
//
|
||||||
MSG_WriteByte (msg, svc_playerinfo);
|
MSG_WriteByte (msg, svc_playerinfo);
|
||||||
MSG_WriteLong (msg, pflags);
|
MSG_WriteLong (msg, pflags);
|
||||||
|
|
||||||
|
//
|
||||||
// write the pmove_state_t
|
// 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)
|
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]);
|
MSG_WriteShort (msg, ps->pmove.velocity[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pflags & PS_M_TIME) MSG_WriteByte (msg, ps->pmove.pm_time);
|
if (pflags & PS_M_TIME)
|
||||||
if (pflags & PS_M_FLAGS) MSG_WriteByte (msg, ps->pmove.pm_flags);
|
MSG_WriteByte (msg, ps->pmove.pm_time);
|
||||||
if (pflags & PS_M_GRAVITY) MSG_WriteShort (msg, ps->pmove.gravity);
|
|
||||||
|
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)
|
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]);
|
MSG_WriteShort (msg, ps->pmove.delta_angles[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
// write the rest of the player_state_t
|
// write the rest of the player_state_t
|
||||||
|
//
|
||||||
if (pflags & PS_VIEWOFFSET)
|
if (pflags & PS_VIEWOFFSET)
|
||||||
{
|
{
|
||||||
MSG_WriteChar (msg, ps->viewoffset[0] * 4);
|
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);
|
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)
|
if (pflags & PS_WEAPONFRAME)
|
||||||
{
|
{
|
||||||
MSG_WriteByte (msg, ps->gunframe);
|
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);
|
MSG_WriteChar (msg, ps->gunangles[2]*4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pflags & PS_WEAPONSEQUENCE) MSG_WriteByte (msg, ps->sequence);
|
if (pflags & PS_WEAPONSEQUENCE)
|
||||||
if (pflags & PS_WEAPONBODY) MSG_WriteByte (msg, ps->gunbody);
|
{
|
||||||
if (pflags & PS_WEAPONSKIN) MSG_WriteByte (msg, ps->gunskin);
|
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)
|
if (pflags & PS_BLEND)
|
||||||
{
|
{
|
||||||
MSG_WriteByte (msg, ps->blend[0] * 255);
|
MSG_WriteByte (msg, ps->blend[0]*255);
|
||||||
MSG_WriteByte (msg, ps->blend[1] * 255);
|
MSG_WriteByte (msg, ps->blend[1]*255);
|
||||||
MSG_WriteByte (msg, ps->blend[2] * 255);
|
MSG_WriteByte (msg, ps->blend[2]*255);
|
||||||
MSG_WriteByte (msg, ps->blend[3] * 255);
|
MSG_WriteByte (msg, ps->blend[3]*255);
|
||||||
}
|
}
|
||||||
if (pflags & PS_FOV) MSG_WriteByte (msg, ps->fov);
|
if (pflags & PS_FOV)
|
||||||
if (pflags & PS_RDFLAGS) MSG_WriteByte (msg, ps->rdflags);
|
MSG_WriteByte (msg, ps->fov);
|
||||||
|
if (pflags & PS_RDFLAGS)
|
||||||
|
MSG_WriteByte (msg, ps->rdflags);
|
||||||
|
|
||||||
// send stats
|
// send stats
|
||||||
statbits = 0;
|
statbits = 0;
|
||||||
for (i = 0; i < MAX_STATS; i++)
|
for (i=0 ; i<MAX_STATS ; i++)
|
||||||
{
|
|
||||||
if (ps->stats[i] != ops->stats[i])
|
if (ps->stats[i] != ops->stats[i])
|
||||||
statbits |= 1<<i;
|
statbits |= 1<<i;
|
||||||
}
|
|
||||||
|
|
||||||
MSG_WriteLong (msg, statbits);
|
MSG_WriteLong (msg, statbits);
|
||||||
|
for (i=0 ; i<MAX_STATS ; i++)
|
||||||
for (i = 0; i < MAX_STATS; i++)
|
if (statbits & (1<<i) )
|
||||||
{
|
|
||||||
if(statbits & (1<<i) )
|
|
||||||
MSG_WriteShort (msg, ps->stats[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];
|
frame = &client->frames[sv.framenum & UPDATE_MASK];
|
||||||
|
|
||||||
if (client->lastframe <= 0)
|
if (client->lastframe <= 0)
|
||||||
{
|
{ // client is asking for a retransmit
|
||||||
// client is asking for a retransmit
|
|
||||||
oldframe = NULL;
|
oldframe = NULL;
|
||||||
lastframe = -1;
|
lastframe = -1;
|
||||||
}
|
}
|
||||||
else if (sv.framenum - client->lastframe >= (UPDATE_BACKUP - 3) )
|
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);
|
// Msg ("%s: Delta request from out-of-date packet.\n", client->name);
|
||||||
oldframe = NULL;
|
oldframe = NULL;
|
||||||
lastframe = -1;
|
lastframe = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{ // we have a valid message to delta from
|
||||||
// we have a valid message to delta from
|
|
||||||
oldframe = &client->frames[client->lastframe & UPDATE_MASK];
|
oldframe = &client->frames[client->lastframe & UPDATE_MASK];
|
||||||
lastframe = client->lastframe;
|
lastframe = client->lastframe;
|
||||||
}
|
}
|
||||||
|
@ -465,27 +537,29 @@ copies off the playerstat and areabits.
|
||||||
void SV_BuildClientFrame (client_t *client)
|
void SV_BuildClientFrame (client_t *client)
|
||||||
{
|
{
|
||||||
int e, i;
|
int e, i;
|
||||||
vec3_t org;
|
vec3_t org;
|
||||||
prvm_edict_t *ent;
|
edict_t *ent;
|
||||||
prvm_edict_t *clent;
|
edict_t *clent;
|
||||||
client_frame_t *frame;
|
client_frame_t *frame;
|
||||||
entity_state_t *state;
|
entity_state_t *state;
|
||||||
int l;
|
int l;
|
||||||
int clientarea, clientcluster;
|
int clientarea, clientcluster;
|
||||||
int leafnum;
|
int leafnum;
|
||||||
int c_fullsend;
|
int c_fullsend;
|
||||||
byte *clientphs;
|
byte *clientphs;
|
||||||
byte *bitvector;
|
byte *bitvector;
|
||||||
|
|
||||||
clent = client->edict;
|
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
|
// this is the frame we are creating
|
||||||
frame = &client->frames[sv.framenum & UPDATE_MASK];
|
frame = &client->frames[sv.framenum & UPDATE_MASK];
|
||||||
|
|
||||||
frame->senttime = svs.realtime; // save it for ping calc later
|
frame->senttime = svs.realtime; // save it for ping calc later
|
||||||
|
|
||||||
// find the client's PVS
|
// 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);
|
leafnum = CM_PointLeafnum (org);
|
||||||
clientarea = CM_LeafArea (leafnum);
|
clientarea = CM_LeafArea (leafnum);
|
||||||
|
@ -495,7 +569,8 @@ void SV_BuildClientFrame (client_t *client)
|
||||||
frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea);
|
frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea);
|
||||||
|
|
||||||
// grab the current player_state_t
|
// grab the current player_state_t
|
||||||
frame->ps = *clent->priv.sv->client;
|
frame->ps = clent->client->ps;
|
||||||
|
|
||||||
|
|
||||||
SV_FatPVS (org);
|
SV_FatPVS (org);
|
||||||
clientphs = CM_ClusterPHS (clientcluster);
|
clientphs = CM_ClusterPHS (clientcluster);
|
||||||
|
@ -506,33 +581,34 @@ void SV_BuildClientFrame (client_t *client)
|
||||||
|
|
||||||
c_fullsend = 0;
|
c_fullsend = 0;
|
||||||
|
|
||||||
ent = PRVM_NEXT_EDICT(prog->edicts);
|
for (e = 1; e < ge->num_edicts ; e++)
|
||||||
for (e = 1; e < prog->num_edicts; e++, ent = PRVM_NEXT_EDICT(ent))
|
|
||||||
{
|
{
|
||||||
|
ent = EDICT_NUM(e);
|
||||||
|
|
||||||
// ignore ents without visible models
|
// ignore ents without visible models
|
||||||
if ((int)ent->fields.sv->flags & SVF_NOCLIENT)
|
if (ent->svflags & SVF_NOCLIENT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// ignore ents without visible models unless they have an effect
|
// 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;
|
continue;
|
||||||
|
|
||||||
// ignore if not touching a PV leaf
|
// ignore if not touching a PV leaf
|
||||||
if (ent != clent)
|
if (ent != clent)
|
||||||
{
|
{
|
||||||
// check area
|
// check area
|
||||||
if (!CM_AreasConnected (clientarea, ent->priv.sv->areanum))
|
if (!CM_AreasConnected (clientarea, ent->areanum))
|
||||||
{
|
{ // doors can legally straddle two areas, so
|
||||||
// doors can legally straddle two areas, so
|
|
||||||
// we may need to check another one
|
// we may need to check another one
|
||||||
if (!ent->priv.sv->areanum2 || !CM_AreasConnected (clientarea, ent->priv.sv->areanum2))
|
if (!ent->areanum2
|
||||||
continue; // blocked by a door
|
|| !CM_AreasConnected (clientarea, ent->areanum2))
|
||||||
|
continue; // blocked by a door
|
||||||
}
|
}
|
||||||
|
|
||||||
// beams just check one point for PHS
|
// 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) )) )
|
if ( !(clientphs[l >> 3] & (1 << (l&7) )) )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -540,67 +616,55 @@ void SV_BuildClientFrame (client_t *client)
|
||||||
{
|
{
|
||||||
// FIXME: if an ent has a model and a sound, but isn't
|
// FIXME: if an ent has a model and a sound, but isn't
|
||||||
// in the PVS, only the PHS, clear the model
|
// in the PVS, only the PHS, clear the model
|
||||||
if (ent->priv.sv->state.sound)
|
if (ent->s.sound)
|
||||||
{
|
{
|
||||||
bitvector = fatpvs; //clientphs;
|
bitvector = fatpvs; //clientphs;
|
||||||
}
|
}
|
||||||
else bitvector = fatpvs;
|
else
|
||||||
|
bitvector = fatpvs;
|
||||||
|
|
||||||
if (ent->priv.sv->num_clusters == -1)
|
if (ent->num_clusters == -1)
|
||||||
{
|
{ // too many leafs for individual check, go by headnode
|
||||||
// too many leafs for individual check, go by headnode
|
if (!CM_HeadnodeVisible (ent->headnode, bitvector))
|
||||||
if (!CM_HeadnodeVisible (ent->priv.sv->headnode, bitvector))
|
|
||||||
continue;
|
continue;
|
||||||
c_fullsend++;
|
c_fullsend++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // check individual leafs
|
{ // 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) ))
|
if (bitvector[l >> 3] & (1 << (l&7) ))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == ent->priv.sv->num_clusters)
|
if (i == ent->num_clusters)
|
||||||
continue; // not visible
|
continue; // not visible
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(int)ent->fields.sv->modelindex)
|
if (!ent->s.modelindex)
|
||||||
{
|
{ // don't send sounds if they will be attenuated away
|
||||||
// don't send sounds if they will be attenuated away
|
|
||||||
vec3_t delta;
|
vec3_t delta;
|
||||||
float len;
|
float len;
|
||||||
|
|
||||||
VectorSubtract (org, ent->fields.sv->origin, delta);
|
VectorSubtract (org, ent->s.origin, delta);
|
||||||
len = VectorLength (delta);
|
len = VectorLength (delta);
|
||||||
if (len > 400) continue;
|
if (len > 400)
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add it to the circular client_entities array
|
// add it to the circular client_entities array
|
||||||
state = &svs.client_entities[svs.next_client_entities % svs.num_client_entities];
|
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 );
|
MsgWarn ("SV_BuildClientFrame: invalid ent->s.number %d\n", ent->s.number );
|
||||||
ent->priv.sv->state.number = e; // ptr to current entity such as entnumber
|
ent->s.number = e; // ptr to current entity such as entnumber
|
||||||
}
|
}
|
||||||
|
*state = ent->s;
|
||||||
// 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;
|
|
||||||
|
|
||||||
// don't mark players missiles as solid
|
// 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++;
|
svs.next_client_entities++;
|
||||||
frame->num_entities++;
|
frame->num_entities++;
|
||||||
|
@ -619,7 +683,7 @@ Used for recording footage for merged or assembled demos
|
||||||
void SV_RecordDemoMessage (void)
|
void SV_RecordDemoMessage (void)
|
||||||
{
|
{
|
||||||
int e;
|
int e;
|
||||||
prvm_edict_t *ent;
|
edict_t *ent;
|
||||||
entity_state_t nostate;
|
entity_state_t nostate;
|
||||||
sizebuf_t buf;
|
sizebuf_t buf;
|
||||||
byte buf_data[32768];
|
byte buf_data[32768];
|
||||||
|
@ -638,14 +702,18 @@ void SV_RecordDemoMessage (void)
|
||||||
MSG_WriteByte (&buf, svc_packetentities);
|
MSG_WriteByte (&buf, svc_packetentities);
|
||||||
|
|
||||||
e = 1;
|
e = 1;
|
||||||
ent = PRVM_EDICT_NUM(e);
|
ent = EDICT_NUM(e);
|
||||||
while (e < prog->num_edicts)
|
while (e < ge->num_edicts)
|
||||||
{
|
{
|
||||||
// ignore ents without visible models unless they have an effect
|
// 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))
|
if (ent->inuse &&
|
||||||
MSG_WriteDeltaEntity (&nostate, &ent->priv.sv->state, &buf, false, true);
|
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++;
|
e++;
|
||||||
ent = PRVM_EDICT_NUM(e);
|
ent = EDICT_NUM(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
MSG_WriteShort (&buf, 0); // end of packetentities
|
MSG_WriteShort (&buf, 0); // end of packetentities
|
||||||
|
@ -660,4 +728,3 @@ void SV_RecordDemoMessage (void)
|
||||||
FS_Write (svs.demofile, buf.data, buf.cursize);
|
FS_Write (svs.demofile, buf.data, buf.cursize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -24,120 +24,30 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
server_static_t svs; // persistant server info
|
server_static_t svs; // persistant server info
|
||||||
server_t sv; // local server
|
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
|
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;
|
int i;
|
||||||
|
|
||||||
if (!name || !name[0]) return 0;
|
if (!name || !name[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 );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
// register new resource
|
for (i=1 ; i<max && sv.configstrings[start+i][0] ; i++)
|
||||||
strncpy (sv.configstrings[start + i], name, sizeof(sv.configstrings[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)
|
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);
|
SZ_Clear (&sv.multicast);
|
||||||
MSG_Begin(svc_configstring);
|
MSG_Begin(svc_configstring);
|
||||||
MSG_WriteShort (&sv.multicast, start+i);
|
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 );
|
MSG_Send(MSG_ALL_R, vec3_origin, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int SV_ModelIndex (const char *name)
|
int SV_ModelIndex (char *name)
|
||||||
{
|
{
|
||||||
return SV_FindIndex (name, CS_MODELS, MAX_MODELS, true);
|
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);
|
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);
|
return SV_FindIndex (name, CS_IMAGES, MAX_IMAGES, true);
|
||||||
}
|
}
|
||||||
|
@ -179,78 +90,26 @@ baseline will be transmitted
|
||||||
*/
|
*/
|
||||||
void SV_CreateBaseline (void)
|
void SV_CreateBaseline (void)
|
||||||
{
|
{
|
||||||
prvm_edict_t *svent;
|
edict_t *svent;
|
||||||
int entnum;
|
int entnum;
|
||||||
|
|
||||||
for (entnum = 1; entnum < prog->num_edicts; entnum++)
|
for (entnum = 1; entnum < ge->num_edicts ; entnum++)
|
||||||
{
|
{
|
||||||
svent = PRVM_EDICT_NUM(entnum);
|
svent = EDICT_NUM(entnum);
|
||||||
|
if (!svent->inuse)
|
||||||
if (svent->priv.sv->free)
|
|
||||||
{
|
|
||||||
Msg("Can't create baseline for entity [%d]\n", entnum );
|
|
||||||
continue;
|
continue;
|
||||||
}
|
if (!svent->s.modelindex && !svent->s.sound && !svent->s.effects)
|
||||||
if (!(int)svent->fields.sv->modelindex && !(int)svent->priv.sv->state.sound && !(int)svent->fields.sv->effects)
|
|
||||||
continue;
|
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
|
// 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 )
|
void SV_CheckForSavegame (char *savename )
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
char name[MAX_SYSPATH];
|
char name[MAX_SYSPATH];
|
||||||
|
|
||||||
if (sv_noreload->value) return;
|
if (sv_noreload->value) return;
|
||||||
|
@ -275,6 +135,22 @@ void SV_CheckForSavegame (char *savename )
|
||||||
|
|
||||||
// get configstrings and areaportals
|
// get configstrings and areaportals
|
||||||
SV_ReadLevelFile ( savename );
|
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)
|
void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_state_t serverstate, bool attractloop, bool loadgame)
|
||||||
{
|
{
|
||||||
uint i, checksum;
|
uint i, checksum;
|
||||||
prvm_edict_t *ent;
|
|
||||||
|
|
||||||
if (attractloop) Cvar_Set ("paused", "0");
|
if (attractloop) Cvar_Set ("paused", "0");
|
||||||
|
|
||||||
|
@ -321,17 +196,11 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
|
||||||
pm_airaccelerate = 0;
|
pm_airaccelerate = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SV_VM_Setup();
|
|
||||||
|
|
||||||
SZ_Init (&sv.multicast, sv.multicast_buf, sizeof(sv.multicast_buf));
|
SZ_Init (&sv.multicast, sv.multicast_buf, sizeof(sv.multicast_buf));
|
||||||
|
|
||||||
strcpy (sv.name, server);
|
strcpy (sv.name, server);
|
||||||
strcpy (sv.configstrings[CS_NAME], server);
|
|
||||||
|
|
||||||
SV_VM_Begin();
|
|
||||||
|
|
||||||
// leave slots at start for clients only
|
// leave slots at start for clients only
|
||||||
for (i = 0; i < host.maxclients; i++)
|
for (i=0 ; i<maxclients->value ; i++)
|
||||||
{
|
{
|
||||||
// needs to reconnect
|
// needs to reconnect
|
||||||
if (svs.clients[i].state > cs_connected)
|
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;
|
svs.clients[i].lastframe = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sv.state = ss_loading;
|
sv.time = 1000;
|
||||||
prog->protect_world = false;
|
|
||||||
|
strcpy (sv.name, server);
|
||||||
|
strcpy (sv.configstrings[CS_NAME], server);
|
||||||
|
|
||||||
if (serverstate != ss_game)
|
if (serverstate != ss_game)
|
||||||
{
|
{
|
||||||
|
@ -348,7 +219,7 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
|
||||||
}
|
}
|
||||||
else
|
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);
|
sv.models[1] = CM_LoadMap (sv.configstrings[CS_MODELS+1], false, &checksum);
|
||||||
}
|
}
|
||||||
sprintf (sv.configstrings[CS_MAPCHECKSUM],"%i", 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]);
|
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);
|
// spawn the rest of the entities on the map
|
||||||
ent->priv.sv->free = false;
|
//
|
||||||
ent->fields.sv->model = PRVM_SetEngineString(sv.configstrings[CS_MODELS]);
|
|
||||||
ent->fields.sv->modelindex = 1; // world model
|
// precache and static commands can be issued during
|
||||||
ent->fields.sv->solid = SOLID_BSP;
|
// map initialization
|
||||||
ent->fields.sv->movetype = MOVETYPE_PUSH;
|
sv.state = ss_loading;
|
||||||
|
|
||||||
prog->globals.server->mapname = PRVM_SetEngineString(sv.name);
|
|
||||||
Com_SetServerState (sv.state);
|
Com_SetServerState (sv.state);
|
||||||
|
|
||||||
// spawn the rest of the entities on the map
|
// load and spawn all other entities
|
||||||
sv.moved_edicts = (prvm_edict_t **)PRVM_Alloc(prog->max_edicts * sizeof(prvm_edict_t *));
|
SV_SpawnEntities ( sv.name, CM_EntityString(), spawnpoint );
|
||||||
*prog->time = sv.time = 1.0;
|
|
||||||
|
|
||||||
// serverflags are for cross level information (sigils)
|
// run two frames to allow everything to settle
|
||||||
prog->globals.server->serverflags = svs.serverflags;
|
SV_RunFrame ();
|
||||||
|
SV_RunFrame ();
|
||||||
// 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());
|
|
||||||
|
|
||||||
// all precaches are complete
|
// all precaches are complete
|
||||||
sv.state = serverstate;
|
sv.state = serverstate;
|
||||||
Com_SetServerState (sv.state);
|
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
|
// create a baseline for more efficient communications
|
||||||
SV_CreateBaseline ();
|
SV_CreateBaseline ();
|
||||||
|
|
||||||
|
// check for a savegame
|
||||||
|
SV_CheckForSavegame ( savename );
|
||||||
|
|
||||||
// set serverinfo variable
|
// set serverinfo variable
|
||||||
Cvar_FullSet ("mapname", sv.name, CVAR_SERVERINFO | CVAR_NOSET);
|
Cvar_FullSet ("mapname", sv.name, CVAR_SERVERINFO | CVAR_NOSET);
|
||||||
|
|
||||||
Msg ("-------------------------------------\n");
|
Msg ("-------------------------------------\n");
|
||||||
|
|
||||||
SV_VM_End();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -428,8 +274,8 @@ A brand new game has been started
|
||||||
*/
|
*/
|
||||||
void SV_InitGame (void)
|
void SV_InitGame (void)
|
||||||
{
|
{
|
||||||
//int i;
|
int i;
|
||||||
//prvm_edict_t *ent;
|
edict_t *ent;
|
||||||
char idmaster[32];
|
char idmaster[32];
|
||||||
|
|
||||||
if (svs.initialized)
|
if (svs.initialized)
|
||||||
|
@ -457,38 +303,53 @@ void SV_InitGame (void)
|
||||||
|
|
||||||
// dedicated servers are can't be single player and are usually DM
|
// dedicated servers are can't be single player and are usually DM
|
||||||
// so unless they explicity set coop, force it to deathmatch
|
// 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
|
// init clients
|
||||||
if (Cvar_VariableValue ("deathmatch"))
|
if (Cvar_VariableValue ("deathmatch"))
|
||||||
{
|
{
|
||||||
if (host.maxclients <= 1) host.maxclients = 8;
|
if (maxclients->value <= 1)
|
||||||
else if (host.maxclients > MAX_CLIENTS) host.maxclients = MAX_CLIENTS;
|
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"))
|
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
|
else // non-deathmatch, non-coop is one player
|
||||||
{
|
{
|
||||||
host.maxclients = 1;
|
Cvar_FullSet ("maxclients", "1", CVAR_SERVERINFO | CVAR_LATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
svs.spawncount = rand();
|
svs.spawncount = rand();
|
||||||
svs.clients = Z_Malloc (sizeof(client_t) * host.maxclients);
|
svs.clients = Z_Malloc (sizeof(client_t)*maxclients->value);
|
||||||
svs.num_client_entities = host.maxclients * UPDATE_BACKUP * 64;
|
svs.num_client_entities = maxclients->value*UPDATE_BACKUP*64;
|
||||||
svs.client_entities = Z_Malloc(sizeof(entity_state_t) * svs.num_client_entities);
|
svs.client_entities = Z_Malloc (sizeof(entity_state_t)*svs.num_client_entities);
|
||||||
|
|
||||||
// init network stuff
|
// init network stuff
|
||||||
NET_Config ( (host.maxclients > 1) );
|
NET_Config ( (maxclients->value > 1) );
|
||||||
|
|
||||||
// heartbeats will always be sent to the id master
|
// heartbeats will always be sent to the id master
|
||||||
svs.last_heartbeat = -99999; // send immediately
|
svs.last_heartbeat = -99999; // send immediately
|
||||||
sprintf(idmaster, "192.246.40.37:%i", PORT_MASTER);
|
sprintf(idmaster, "192.246.40.37:%i", PORT_MASTER);
|
||||||
NET_StringToAdr (idmaster, &master_adr[0]);
|
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");
|
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;
|
|
||||||
}
|
|
|
@ -42,18 +42,11 @@ cvar_t *allow_download_sounds;
|
||||||
cvar_t *allow_download_maps;
|
cvar_t *allow_download_maps;
|
||||||
|
|
||||||
cvar_t *sv_airaccelerate;
|
cvar_t *sv_airaccelerate;
|
||||||
cvar_t *sv_wateraccelerate;
|
|
||||||
cvar_t *sv_accelerate;
|
|
||||||
cvar_t *sv_maxvelocity;
|
cvar_t *sv_maxvelocity;
|
||||||
cvar_t *sv_maxspeed;
|
|
||||||
cvar_t *sv_friction;
|
|
||||||
cvar_t *sv_gravity;
|
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 *sv_noreload; // don't reload level state when reentering
|
||||||
|
|
||||||
|
|
||||||
cvar_t *maxclients; // FIXME: rename sv_maxclients
|
cvar_t *maxclients; // FIXME: rename sv_maxclients
|
||||||
cvar_t *sv_showclamp;
|
cvar_t *sv_showclamp;
|
||||||
|
|
||||||
|
@ -86,7 +79,7 @@ void SV_DropClient (client_t *drop)
|
||||||
{
|
{
|
||||||
// call the prog function for removing a client
|
// call the prog function for removing a client
|
||||||
// this will remove the body, among other things
|
// this will remove the body, among other things
|
||||||
//ge->ClientDisconnect (drop->edict);
|
SV_ClientDisconnect(drop->edict);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drop->download)
|
if (drop->download)
|
||||||
|
@ -128,12 +121,12 @@ char *SV_StatusString (void)
|
||||||
strcat (status, "\n");
|
strcat (status, "\n");
|
||||||
statusLength = strlen(status);
|
statusLength = strlen(status);
|
||||||
|
|
||||||
for (i=0 ; i<host.maxclients ; i++)
|
for (i=0 ; i<maxclients->value ; i++)
|
||||||
{
|
{
|
||||||
cl = &svs.clients[i];
|
cl = &svs.clients[i];
|
||||||
if (cl->state == cs_connected || cl->state == cs_spawned )
|
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);
|
playerLength = strlen(player);
|
||||||
if (statusLength + playerLength >= sizeof(status) )
|
if (statusLength + playerLength >= sizeof(status) )
|
||||||
break; // can't hold any more
|
break; // can't hold any more
|
||||||
|
@ -182,7 +175,7 @@ void SVC_Info (void)
|
||||||
int i, count;
|
int i, count;
|
||||||
int version;
|
int version;
|
||||||
|
|
||||||
if (host.maxclients == 1)
|
if (maxclients->value == 1)
|
||||||
return; // ignore in single player
|
return; // ignore in single player
|
||||||
|
|
||||||
version = atoi (Cmd_Argv(1));
|
version = atoi (Cmd_Argv(1));
|
||||||
|
@ -192,11 +185,11 @@ void SVC_Info (void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
count = 0;
|
count = 0;
|
||||||
for (i=0 ; i<host.maxclients ; i++)
|
for (i=0 ; i<maxclients->value ; i++)
|
||||||
if (svs.clients[i].state >= cs_connected)
|
if (svs.clients[i].state >= cs_connected)
|
||||||
count++;
|
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);
|
Netchan_OutOfBandPrint (NS_SERVER, net_from, "info\n%s", string);
|
||||||
|
@ -252,7 +245,7 @@ void SVC_GetChallenge (void)
|
||||||
// overwrite the oldest
|
// overwrite the oldest
|
||||||
svs.challenges[oldest].challenge = rand() & 0x7fff;
|
svs.challenges[oldest].challenge = rand() & 0x7fff;
|
||||||
svs.challenges[oldest].adr = net_from;
|
svs.challenges[oldest].adr = net_from;
|
||||||
svs.challenges[oldest].time = host.realtime;
|
svs.challenges[oldest].time = curtime;
|
||||||
i = oldest;
|
i = oldest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +267,7 @@ void SVC_DirectConnect (void)
|
||||||
int i;
|
int i;
|
||||||
client_t *cl, *newcl;
|
client_t *cl, *newcl;
|
||||||
client_t temp;
|
client_t temp;
|
||||||
prvm_edict_t *ent;
|
edict_t *ent;
|
||||||
int edictnum;
|
int edictnum;
|
||||||
int version;
|
int version;
|
||||||
int qport;
|
int qport;
|
||||||
|
@ -336,7 +329,7 @@ void SVC_DirectConnect (void)
|
||||||
memset (newcl, 0, sizeof(client_t));
|
memset (newcl, 0, sizeof(client_t));
|
||||||
|
|
||||||
// if there is already a slot for this ip, reuse it
|
// 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)
|
if (cl->state == cs_free)
|
||||||
continue;
|
continue;
|
||||||
|
@ -344,7 +337,7 @@ void SVC_DirectConnect (void)
|
||||||
&& ( cl->netchan.qport == qport
|
&& ( cl->netchan.qport == qport
|
||||||
|| adr.port == cl->netchan.remote_address.port ) )
|
|| 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));
|
MsgWarn("SVC_DirectConnect: %s:reconnect rejected : too soon\n", NET_AdrToString (adr));
|
||||||
return;
|
return;
|
||||||
|
@ -357,7 +350,7 @@ void SVC_DirectConnect (void)
|
||||||
|
|
||||||
// find a client slot
|
// find a client slot
|
||||||
newcl = NULL;
|
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)
|
if (cl->state == cs_free)
|
||||||
{
|
{
|
||||||
|
@ -380,22 +373,19 @@ gotnewcl:
|
||||||
sv_client = newcl;
|
sv_client = newcl;
|
||||||
edictnum = (newcl - svs.clients) + 1;
|
edictnum = (newcl - svs.clients) + 1;
|
||||||
|
|
||||||
ent = PRVM_EDICT_NUM(edictnum);
|
ent = EDICT_NUM(edictnum);
|
||||||
newcl->edict = ent;
|
newcl->edict = ent;
|
||||||
newcl->challenge = challenge; // save challenge for checksumming
|
newcl->challenge = challenge; // save challenge for checksumming
|
||||||
|
|
||||||
prog->globals.server->time = sv.time;
|
// get the game a chance to reject this connection or modify the userinfo
|
||||||
prog->globals.server->self = PRVM_EDICT_TO_PROG(sv_client->edict);
|
if (!(SV_ClientConnect(ent, userinfo)))
|
||||||
PRVM_ExecuteProgram (prog->globals.server->ClientConnect, "QC function ClientConnect is missing");
|
{
|
||||||
|
|
||||||
//if (!(ge->ClientConnect (ent, userinfo)))
|
|
||||||
/*{
|
|
||||||
if (*Info_ValueForKey (userinfo, "rejmsg"))
|
if (*Info_ValueForKey (userinfo, "rejmsg"))
|
||||||
Netchan_OutOfBandPrint (NS_SERVER, adr, "print\n%s\nConnection refused.\n", 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" );
|
else Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nConnection refused.\n" );
|
||||||
MsgWarn("SVC_DirectConnect: Game rejected a connection.\n");
|
MsgWarn("SVC_DirectConnect: Game rejected a connection.\n");
|
||||||
return;
|
return;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
// parse some info from the info strings
|
// parse some info from the info strings
|
||||||
strncpy (newcl->userinfo, userinfo, sizeof(newcl->userinfo)-1);
|
strncpy (newcl->userinfo, userinfo, sizeof(newcl->userinfo)-1);
|
||||||
|
@ -514,7 +504,7 @@ void SV_CalcPings (void)
|
||||||
client_t *cl;
|
client_t *cl;
|
||||||
int total, count;
|
int total, count;
|
||||||
|
|
||||||
for (i=0 ; i<host.maxclients ; i++)
|
for (i=0 ; i<maxclients->value ; i++)
|
||||||
{
|
{
|
||||||
cl = &svs.clients[i];
|
cl = &svs.clients[i];
|
||||||
if (cl->state != cs_spawned )
|
if (cl->state != cs_spawned )
|
||||||
|
@ -547,7 +537,7 @@ void SV_CalcPings (void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// let the game dll know about the ping
|
// 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;
|
int i;
|
||||||
client_t *cl;
|
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];
|
cl = &svs.clients[i];
|
||||||
|
|
||||||
if (cl->state == cs_free )
|
if (cl->state == cs_free )
|
||||||
continue;
|
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;
|
qport = MSG_ReadShort (&net_message) & 0xffff;
|
||||||
|
|
||||||
// check for packets from connected clients
|
// 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)
|
if (cl->state == cs_free)
|
||||||
continue;
|
continue;
|
||||||
|
@ -622,8 +612,7 @@ void SV_ReadPackets (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Netchan_Process(&cl->netchan, &net_message))
|
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)
|
if (cl->state != cs_zombie)
|
||||||
{
|
{
|
||||||
cl->lastmessage = svs.realtime; // don't timeout
|
cl->lastmessage = svs.realtime; // don't timeout
|
||||||
|
@ -633,7 +622,7 @@ void SV_ReadPackets (void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != host.maxclients)
|
if (i != maxclients->value)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -658,15 +647,17 @@ void SV_CheckTimeouts (void)
|
||||||
int droppoint;
|
int droppoint;
|
||||||
int zombiepoint;
|
int zombiepoint;
|
||||||
|
|
||||||
droppoint = svs.realtime - timeout->value;
|
droppoint = svs.realtime - 1000*timeout->value;
|
||||||
zombiepoint = svs.realtime - zombietime->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
|
// 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
|
cl->state = cs_free; // can now be reused
|
||||||
continue;
|
continue;
|
||||||
|
@ -691,15 +682,53 @@ player processing happens outside RunWorldFrame
|
||||||
*/
|
*/
|
||||||
void SV_PrepWorldFrame (void)
|
void SV_PrepWorldFrame (void)
|
||||||
{
|
{
|
||||||
prvm_edict_t *ent;
|
edict_t *ent;
|
||||||
int i;
|
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
|
// 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
|
time_before_game = time_after_game = 0;
|
||||||
if (!svs.initialized) return;
|
|
||||||
|
|
||||||
svs.realtime += host.realtime;
|
// if server is not active, do nothing
|
||||||
|
if (!svs.initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
svs.realtime += msec;
|
||||||
|
|
||||||
// keep the random time dependent
|
// keep the random time dependent
|
||||||
rand ();
|
rand ();
|
||||||
|
|
||||||
// setup the VM frame
|
|
||||||
SV_VM_Begin();
|
|
||||||
|
|
||||||
// check timeouts
|
// check timeouts
|
||||||
SV_CheckTimeouts ();
|
SV_CheckTimeouts ();
|
||||||
|
|
||||||
// get packets from clients
|
// get packets from clients
|
||||||
SV_ReadPackets ();
|
SV_ReadPackets ();
|
||||||
|
|
||||||
|
@ -731,12 +760,13 @@ void SV_Frame (float time)
|
||||||
if (!sv_timedemo->value && svs.realtime < sv.time)
|
if (!sv_timedemo->value && svs.realtime < sv.time)
|
||||||
{
|
{
|
||||||
// never let the time get too far off
|
// 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");
|
if (sv_showclamp->value)
|
||||||
svs.realtime = sv.time - 0.1;
|
Msg ("sv lowclamp\n");
|
||||||
|
svs.realtime = sv.time - 100;
|
||||||
}
|
}
|
||||||
NET_Sleep((sv.time - svs.realtime) * 0.001);
|
NET_Sleep(sv.time - svs.realtime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,7 +777,7 @@ void SV_Frame (float time)
|
||||||
SV_GiveMsec ();
|
SV_GiveMsec ();
|
||||||
|
|
||||||
// let everything in the world think and move
|
// let everything in the world think and move
|
||||||
SV_Physics();
|
SV_RunGameFrame ();
|
||||||
|
|
||||||
// send messages back to the clients that had packets read this frame
|
// send messages back to the clients that had packets read this frame
|
||||||
SV_SendClientMessages ();
|
SV_SendClientMessages ();
|
||||||
|
@ -761,8 +791,6 @@ void SV_Frame (float time)
|
||||||
// clear teleport flags, etc for next frame
|
// clear teleport flags, etc for next frame
|
||||||
SV_PrepWorldFrame ();
|
SV_PrepWorldFrame ();
|
||||||
|
|
||||||
// end the server VM frame
|
|
||||||
SV_VM_End();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
@ -781,8 +809,9 @@ void Master_Heartbeat (void)
|
||||||
char *string;
|
char *string;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// only dedicated servers send heartbeats
|
// pgm post3.19 change, cvar pointer not validated before dereferencing
|
||||||
if (host.type == HOST_NORMAL) return;
|
if (!dedicated || !dedicated->value)
|
||||||
|
return; // only dedicated servers send heartbeats
|
||||||
|
|
||||||
// pgm post3.19 change, cvar pointer not validated before dereferencing
|
// pgm post3.19 change, cvar pointer not validated before dereferencing
|
||||||
if (!public_server || !public_server->value)
|
if (!public_server || !public_server->value)
|
||||||
|
@ -792,7 +821,7 @@ void Master_Heartbeat (void)
|
||||||
if (svs.last_heartbeat > svs.realtime)
|
if (svs.last_heartbeat > svs.realtime)
|
||||||
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
|
return; // not time to send yet
|
||||||
|
|
||||||
svs.last_heartbeat = svs.realtime;
|
svs.last_heartbeat = svs.realtime;
|
||||||
|
@ -801,14 +830,12 @@ void Master_Heartbeat (void)
|
||||||
string = SV_StatusString();
|
string = SV_StatusString();
|
||||||
|
|
||||||
// send to group master
|
// send to group master
|
||||||
for (i = 0; i < MAX_MASTERS; i++)
|
for (i=0 ; i<MAX_MASTERS ; i++)
|
||||||
{
|
|
||||||
if (master_adr[i].port)
|
if (master_adr[i].port)
|
||||||
{
|
{
|
||||||
Msg ("Sending heartbeat to %s\n", NET_AdrToString (master_adr[i]));
|
Msg ("Sending heartbeat to %s\n", NET_AdrToString (master_adr[i]));
|
||||||
Netchan_OutOfBandPrint (NS_SERVER, master_adr[i], "heartbeat\n%s", string);
|
Netchan_OutOfBandPrint (NS_SERVER, master_adr[i], "heartbeat\n%s", string);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -822,21 +849,22 @@ void Master_Shutdown (void)
|
||||||
{
|
{
|
||||||
int i;
|
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
|
// pgm post3.19 change, cvar pointer not validated before dereferencing
|
||||||
if (!public_server || !public_server->value)
|
if (!public_server || !public_server->value)
|
||||||
return; // a private dedicated game
|
return; // a private dedicated game
|
||||||
|
|
||||||
// send to group master
|
// send to group master
|
||||||
for ( i = 0; i < MAX_MASTERS; i++)
|
for (i=0 ; i<MAX_MASTERS ; i++)
|
||||||
{
|
|
||||||
if (master_adr[i].port)
|
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");
|
Netchan_OutOfBandPrint (NS_SERVER, master_adr[i], "shutdown");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
@ -856,7 +884,7 @@ void SV_UserinfoChanged (client_t *cl)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// call prog code to allow overrides
|
// call prog code to allow overrides
|
||||||
//ge->ClientUserinfoChanged (cl->edict, cl->userinfo);
|
SV_ClientUserinfoChanged(cl->edict, cl->userinfo);
|
||||||
|
|
||||||
// name for C code
|
// name for C code
|
||||||
strncpy (cl->name, Info_ValueForKey (cl->userinfo, "name"), sizeof(cl->name)-1);
|
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 ("timelimit", "0", CVAR_SERVERINFO);
|
||||||
Cvar_Get ("cheats", "0", CVAR_SERVERINFO|CVAR_LATCH);
|
Cvar_Get ("cheats", "0", CVAR_SERVERINFO|CVAR_LATCH);
|
||||||
Cvar_Get ("protocol", va("%i", PROTOCOL_VERSION), CVAR_SERVERINFO|CVAR_NOSET);;
|
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);
|
timeout = Cvar_Get ("timeout", "125", 0);
|
||||||
zombietime = Cvar_Get ("zombietime", "2", 0);
|
zombietime = Cvar_Get ("zombietime", "2", 0);
|
||||||
sv_showclamp = Cvar_Get ("showclamp", "0", 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_noreload = Cvar_Get ("sv_noreload", "0", 0);
|
||||||
|
|
||||||
sv_wateraccelerate = Cvar_Get("sv_wateraccelerate", "-1", CVAR_ARCHIVE);
|
sv_airaccelerate = Cvar_Get("sv_airaccelerate", "0", CVAR_LATCH);
|
||||||
sv_airaccelerate = Cvar_Get("sv_airaccelerate", "-1", CVAR_ARCHIVE);
|
sv_maxvelocity = Cvar_Get("sv_maxvelocity", "2000", 0 );
|
||||||
sv_accelerate = Cvar_Get("sv_accelerate", "10", CVAR_ARCHIVE);
|
sv_gravity = Cvar_Get("sv_gravity", "800", 0 );
|
||||||
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);
|
|
||||||
|
|
||||||
public_server = Cvar_Get ("public", "0", 0);
|
public_server = Cvar_Get ("public", "0", 0);
|
||||||
|
|
||||||
sv_reconnect_limit = Cvar_Get ("sv_reconnect_limit", "3", CVAR_ARCHIVE);
|
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
|
// send it twice
|
||||||
// stagger the packets to crutch operating system limited buffers
|
// 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)
|
if (cl->state >= cs_connected)
|
||||||
Netchan_Transmit (&cl->netchan, net_message.cursize
|
Netchan_Transmit (&cl->netchan, net_message.cursize
|
||||||
, net_message.data);
|
, 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)
|
if (cl->state >= cs_connected)
|
||||||
Netchan_Transmit (&cl->netchan, net_message.cursize
|
Netchan_Transmit (&cl->netchan, net_message.cursize
|
||||||
, net_message.data);
|
, net_message.data);
|
||||||
|
@ -1000,7 +1022,7 @@ void SV_Shutdown (char *finalmsg, bool reconnect)
|
||||||
if (svs.clients) SV_FinalMessage (finalmsg, reconnect);
|
if (svs.clients) SV_FinalMessage (finalmsg, reconnect);
|
||||||
|
|
||||||
Master_Shutdown ();
|
Master_Shutdown ();
|
||||||
//SV_ShutdownGameProgs ();
|
SV_ShutdownGameProgs ();
|
||||||
|
|
||||||
// free current level
|
// free current level
|
||||||
if (sv.demofile) FS_Close (sv.demofile);
|
if (sv.demofile) FS_Close (sv.demofile);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -65,7 +65,7 @@ size_t COM_UnpackString( byte *buffer, int pos, char *string )
|
||||||
if(!buffer || !string) return 0;
|
if(!buffer || !string) return 0;
|
||||||
in = buffer + pos;
|
in = buffer + pos;
|
||||||
|
|
||||||
do { in++, strsize++; } while(in && *in != '\0');
|
do { in++, strsize++; } while(*in != '\0' && in != NULL );
|
||||||
|
|
||||||
strlcpy( string, in - (strsize - 1), strsize );
|
strlcpy( string, in - (strsize - 1), strsize );
|
||||||
return pos + strsize;
|
return pos + strsize;
|
||||||
|
|
|
@ -99,20 +99,19 @@ void SV_BroadcastPrintf (int level, char *fmt, ...)
|
||||||
va_end (argptr);
|
va_end (argptr);
|
||||||
|
|
||||||
// echo to console
|
// echo to console
|
||||||
if (host.type == HOST_DEDICATED)
|
if (dedicated->value)
|
||||||
{
|
{
|
||||||
char copy[1024];
|
char copy[1024];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// mask off high bits
|
// mask off high bits
|
||||||
for (i = 0; i < 1023 && string[i]; i++)
|
for (i=0 ; i<1023 && string[i] ; i++)
|
||||||
copy[i] = string[i] & 127;
|
copy[i] = string[i]&127;
|
||||||
|
copy[i] = 0;
|
||||||
copy[i] = 0; //write null terminator
|
|
||||||
Msg ("%s", copy);
|
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)
|
if (level < cl->messagelevel)
|
||||||
continue;
|
continue;
|
||||||
|
@ -160,12 +159,12 @@ MULTICAST_PVS send to clients potentially visible from org
|
||||||
MULTICAST_PHS send to clients potentially hearable 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;
|
byte *mask = NULL;
|
||||||
int leafnum = 0, cluster = 0;
|
int leafnum = 0, cluster = 0;
|
||||||
int area1 = 0, area2 = 0;
|
int area1 = 0, area2 = 0;
|
||||||
int j, numclients = host.maxclients;
|
int j, numclients = maxclients->value;
|
||||||
client_t *client, *current = svs.clients;
|
client_t *client, *current = svs.clients;
|
||||||
bool reliable = false;
|
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
|
reliable = true; // intentional fallthrough
|
||||||
case MSG_ONE:
|
case MSG_ONE:
|
||||||
if(ent == NULL) return;
|
if(ent == NULL) return;
|
||||||
j = PRVM_NUM_FOR_EDICT(ent);
|
j = NUM_FOR_EDICT(ent);
|
||||||
if (j < 1 || j > numclients) return;
|
if (j < 1 || j > numclients) return;
|
||||||
current = svs.clients + (j - 1);
|
current = svs.clients + (j - 1);
|
||||||
numclients = 1; // send to one
|
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);
|
area2 = CM_LeafArea (leafnum);
|
||||||
cluster = CM_LeafCluster (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 (!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);
|
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.
|
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;
|
int i, ent, flags, sendchan;
|
||||||
vec3_t origin_v;
|
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);
|
MsgWarn("SV_StartSound: timeofs = %f\n", timeofs);
|
||||||
timeofs = bound(0, timeofs, 0.255 );
|
timeofs = bound(0, timeofs, 0.255 );
|
||||||
}
|
}
|
||||||
ent = PRVM_NUM_FOR_EDICT(entity);
|
ent = NUM_FOR_EDICT(entity);
|
||||||
|
|
||||||
if (channel & 8) // no PHS flag
|
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 client doesn't know that bmodels have weird origins
|
||||||
// the origin can also be explicitly set
|
// 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;
|
flags |= SND_POS;
|
||||||
|
|
||||||
// always send the entity number for channel overrides
|
// 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)
|
if (!origin)
|
||||||
{
|
{
|
||||||
origin = origin_v;
|
origin = origin_v;
|
||||||
if (entity->fields.sv->solid == SOLID_BSP)
|
if (entity->solid == SOLID_BSP)
|
||||||
{
|
{
|
||||||
for (i = 0; i < 3; i++)
|
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
|
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);
|
SZ_Clear (&client->datagram);
|
||||||
|
|
||||||
if (msg.overflowed)
|
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);
|
Msg ("WARNING: msg overflowed for %s\n", client->name);
|
||||||
SZ_Clear (&msg);
|
SZ_Clear (&msg);
|
||||||
}
|
}
|
||||||
|
@ -492,8 +490,9 @@ SV_SendClientMessages
|
||||||
*/
|
*/
|
||||||
void SV_SendClientMessages (void)
|
void SV_SendClientMessages (void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int msglen;
|
client_t *c;
|
||||||
|
int msglen;
|
||||||
byte msgbuf[MAX_MSGLEN];
|
byte msgbuf[MAX_MSGLEN];
|
||||||
|
|
||||||
msglen = 0;
|
msglen = 0;
|
||||||
|
@ -501,7 +500,8 @@ void SV_SendClientMessages (void)
|
||||||
// read the next demo message if needed
|
// read the next demo message if needed
|
||||||
if (sv.state == ss_demo && sv.demofile)
|
if (sv.state == ss_demo && sv.demofile)
|
||||||
{
|
{
|
||||||
if (sv_paused->value) msglen = 0;
|
if (sv_paused->value)
|
||||||
|
msglen = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// get the next message
|
// get the next message
|
||||||
|
@ -527,37 +527,39 @@ void SV_SendClientMessages (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// send a message to each connected client
|
// 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 (!c->state)
|
||||||
|
continue;
|
||||||
// if the reliable message overflowed, drop the client
|
// if the reliable message overflowed,
|
||||||
if (sv_client->netchan.message.overflowed)
|
// drop the client
|
||||||
|
if (c->netchan.message.overflowed)
|
||||||
{
|
{
|
||||||
SZ_Clear (&sv_client->netchan.message);
|
SZ_Clear (&c->netchan.message);
|
||||||
SZ_Clear (&sv_client->datagram);
|
SZ_Clear (&c->datagram);
|
||||||
SV_BroadcastPrintf (PRINT_HIGH, "%s overflowed\n", sv_client->name);
|
SV_BroadcastPrintf (PRINT_HIGH, "%s overflowed\n", c->name);
|
||||||
SV_DropClient (sv_client);
|
SV_DropClient (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sv.state == ss_cinematic || sv.state == ss_demo || sv.state == ss_pic)
|
if (sv.state == ss_cinematic
|
||||||
{
|
|| sv.state == ss_demo
|
||||||
Netchan_Transmit (&sv_client->netchan, msglen, msgbuf);
|
|| sv.state == ss_pic
|
||||||
}
|
)
|
||||||
else if (sv_client->state == cs_spawned)
|
Netchan_Transmit (&c->netchan, msglen, msgbuf);
|
||||||
|
else if (c->state == cs_spawned)
|
||||||
{
|
{
|
||||||
// don't overrun bandwidth
|
// don't overrun bandwidth
|
||||||
if (SV_RateDrop (sv_client)) continue;
|
if (SV_RateDrop (c))
|
||||||
SV_SendClientDatagram (sv_client);
|
continue;
|
||||||
|
|
||||||
|
SV_SendClientDatagram (c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// just update reliable if needed
|
// just update reliable if needed
|
||||||
if (sv_client->netchan.message.cursize || host.realtime - sv_client->netchan.last_sent > 1.0f)
|
if (c->netchan.message.cursize || curtime - c->netchan.last_sent > 1000 )
|
||||||
Netchan_Transmit (&sv_client->netchan, 0, NULL);
|
Netchan_Transmit (&c->netchan, 0, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -19,7 +19,8 @@ int SV_StudioExtractBbox( studiohdr_t *phdr, int sequence, float *mins, float *m
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte *SV_GetModelPtr(prvm_edict_t *ent)
|
byte *SV_GetModelPtr(edict_t *ent)
|
||||||
{
|
{
|
||||||
|
if(!ent) return NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
|
@ -22,17 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
extern cvar_t *sv_maxspeed;
|
edict_t *sv_player;
|
||||||
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;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
============================================================
|
============================================================
|
||||||
|
@ -70,7 +60,7 @@ void SV_New_f (void)
|
||||||
{
|
{
|
||||||
char *gamedir;
|
char *gamedir;
|
||||||
int playernum;
|
int playernum;
|
||||||
prvm_edict_t *ent;
|
edict_t *ent;
|
||||||
|
|
||||||
if (sv_client->state != cs_connected)
|
if (sv_client->state != cs_connected)
|
||||||
{
|
{
|
||||||
|
@ -108,8 +98,8 @@ void SV_New_f (void)
|
||||||
if (sv.state == ss_game)
|
if (sv.state == ss_game)
|
||||||
{
|
{
|
||||||
// set up the entity for the client
|
// set up the entity for the client
|
||||||
ent = PRVM_EDICT_NUM(playernum+1);
|
ent = EDICT_NUM(playernum+1);
|
||||||
ent->priv.sv->state.number = playernum+1;
|
ent->s.number = playernum+1;
|
||||||
sv_client->edict = ent;
|
sv_client->edict = ent;
|
||||||
memset (&sv_client->lastcmd, 0, sizeof(sv_client->lastcmd));
|
memset (&sv_client->lastcmd, 0, sizeof(sv_client->lastcmd));
|
||||||
|
|
||||||
|
@ -204,8 +194,7 @@ void SV_Baselines_f (void)
|
||||||
|
|
||||||
// write a packet full of data
|
// write a packet full of data
|
||||||
|
|
||||||
while ( sv_client->netchan.message.cursize < MAX_MSGLEN/2
|
while ( sv_client->netchan.message.cursize < MAX_MSGLEN/2 && start < MAX_EDICTS)
|
||||||
&& start < MAX_EDICTS)
|
|
||||||
{
|
{
|
||||||
base = &sv.baselines[start];
|
base = &sv.baselines[start];
|
||||||
if (base->modelindex || base->sound || base->effects)
|
if (base->modelindex || base->sound || base->effects)
|
||||||
|
@ -237,8 +226,6 @@ SV_Begin_f
|
||||||
*/
|
*/
|
||||||
void SV_Begin_f (void)
|
void SV_Begin_f (void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
// handle the case of a level changing while a client was connecting
|
// handle the case of a level changing while a client was connecting
|
||||||
if ( atoi(Cmd_Argv(1)) != svs.spawncount )
|
if ( atoi(Cmd_Argv(1)) != svs.spawncount )
|
||||||
{
|
{
|
||||||
|
@ -248,22 +235,9 @@ void SV_Begin_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
sv_client->state = cs_spawned;
|
sv_client->state = cs_spawned;
|
||||||
|
|
||||||
if(!sv_player->priv.sv->free)
|
// call the game begin function
|
||||||
{
|
SV_ClientBegin(sv_player);
|
||||||
// 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;
|
|
||||||
|
|
||||||
Cbuf_InsertFromDefer ();
|
Cbuf_InsertFromDefer ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,7 +344,7 @@ void SV_BeginDownload_f(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
SV_NextDownload_f ();
|
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)
|
if (!u->name && sv.state == ss_game)
|
||||||
//ge->ClientCommand (sv_player);
|
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;
|
cl->commandMsec -= cmd->msec;
|
||||||
|
|
||||||
if (cl->commandMsec < 0 && sv_enforcetime->value )
|
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);
|
MsgWarn("SV_ClientThink: commandMsec underflow from %s\n", cl->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ClientThink (cl->edict, cmd);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -885,13 +497,13 @@ void SV_ExecuteClientMessage (client_t *cl)
|
||||||
int c;
|
int c;
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
usercmd_t nullcmd;
|
usercmd_t nullcmd;
|
||||||
usercmd_t oldest, oldcmd, newcmd;
|
usercmd_t oldest, oldcmd, newcmd;
|
||||||
int net_drop;
|
int net_drop;
|
||||||
int stringCmdCount;
|
int stringCmdCount;
|
||||||
int checksum, calculatedChecksum;
|
int checksum, calculatedChecksum;
|
||||||
int checksumIndex;
|
int checksumIndex;
|
||||||
bool move_issued;
|
bool move_issued;
|
||||||
int lastframe;
|
int lastframe;
|
||||||
|
|
||||||
sv_client = cl;
|
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);
|
MsgWarn("SV_ExecuteClientMessage: failed command checksum for %s (%d != %d)/%d\n", cl->name, calculatedChecksum, checksum, cl->netchan.incoming_sequence);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Msg("sv_paused->value %g\n", sv_paused->value );
|
|
||||||
|
|
||||||
if (!sv_paused->value)
|
if (!sv_paused->value)
|
||||||
{
|
{
|
||||||
net_drop = cl->netchan.dropped;
|
net_drop = cl->netchan.dropped;
|
||||||
|
@ -973,13 +583,13 @@ void SV_ExecuteClientMessage (client_t *cl)
|
||||||
{
|
{
|
||||||
while (net_drop > 2)
|
while (net_drop > 2)
|
||||||
{
|
{
|
||||||
SV_ClientRun (cl, &cl->lastcmd);
|
SV_ClientThink (cl, &cl->lastcmd);
|
||||||
net_drop--;
|
net_drop--;
|
||||||
}
|
}
|
||||||
if (net_drop > 1) SV_ClientRun (cl, &oldest);
|
if (net_drop > 1) SV_ClientThink (cl, &oldest);
|
||||||
if (net_drop > 0) SV_ClientRun (cl, &oldcmd);
|
if (net_drop > 0) SV_ClientThink (cl, &oldcmd);
|
||||||
}
|
}
|
||||||
SV_ClientRun (cl, &newcmd);
|
SV_ClientThink (cl, &newcmd);
|
||||||
}
|
}
|
||||||
cl->lastcmd = newcmd;
|
cl->lastcmd = newcmd;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -30,6 +30,14 @@ ENTITY AREA CHECKING
|
||||||
FIXME: this use of "area" is different from the bsp file use
|
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
|
typedef struct areanode_s
|
||||||
{
|
{
|
||||||
int axis; // -1 = leaf node
|
int axis; // -1 = leaf node
|
||||||
|
@ -45,12 +53,12 @@ typedef struct areanode_s
|
||||||
areanode_t sv_areanodes[AREA_NODES];
|
areanode_t sv_areanodes[AREA_NODES];
|
||||||
int sv_numareanodes;
|
int sv_numareanodes;
|
||||||
|
|
||||||
float *area_mins, *area_maxs;
|
float *area_mins, *area_maxs;
|
||||||
prvm_edict_t **area_list;
|
edict_t **area_list;
|
||||||
int area_count, area_maxcount;
|
int area_count, area_maxcount;
|
||||||
int area_type;
|
int area_type;
|
||||||
|
|
||||||
int SV_HullForEntity (prvm_edict_t *ent);
|
int SV_HullForEntity (edict_t *ent);
|
||||||
|
|
||||||
|
|
||||||
// ClearLink is used for new headnodes
|
// ClearLink is used for new headnodes
|
||||||
|
@ -65,9 +73,8 @@ void RemoveLink (link_t *l)
|
||||||
l->prev->next = l->next;
|
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->next = before;
|
||||||
l->prev = before->prev;
|
l->prev = before->prev;
|
||||||
l->prev->next = l;
|
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
|
if (!ent->area.prev)
|
||||||
RemoveLink (&ent->priv.sv->area);
|
return; // not linked in anywhere
|
||||||
ent->priv.sv->area.prev = ent->priv.sv->area.next = NULL;
|
RemoveLink (&ent->area);
|
||||||
|
ent->area.prev = ent->area.next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,95 +163,90 @@ SV_LinkEdict
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
#define MAX_TOTAL_ENT_LEAFS 128
|
#define MAX_TOTAL_ENT_LEAFS 128
|
||||||
void SV_LinkEdict (prvm_edict_t *ent)
|
void SV_LinkEdict (edict_t *ent)
|
||||||
{
|
{
|
||||||
areanode_t *node;
|
areanode_t *node;
|
||||||
int leafs[MAX_TOTAL_ENT_LEAFS];
|
int leafs[MAX_TOTAL_ENT_LEAFS];
|
||||||
int clusters[MAX_TOTAL_ENT_LEAFS];
|
int clusters[MAX_TOTAL_ENT_LEAFS];
|
||||||
int num_leafs;
|
int num_leafs;
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
int area;
|
int area;
|
||||||
int topnode;
|
int topnode;
|
||||||
|
|
||||||
if (ent->priv.sv->area.prev) SV_UnlinkEdict (ent); // unlink from old position
|
if (ent->area.prev) SV_UnlinkEdict (ent); // unlink from old position
|
||||||
if (ent == prog->edicts) return; // don't add the world
|
if (ent == ge->edicts) return; // don't add the world
|
||||||
if (ent->priv.sv->free)
|
if (!ent->inuse) return;
|
||||||
{
|
|
||||||
Msg("Can't link entity [%d]\n", ent->priv.sv->state.number );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the size
|
// 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
|
// 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
|
// assume that x/y are equal and symetric
|
||||||
i = ent->fields.sv->maxs[0]/8;
|
i = ent->maxs[0]/8;
|
||||||
if(i < 1) i = 1;
|
if (i<1) i = 1;
|
||||||
if(i > 31) i = 31;
|
if (i>31) i = 31;
|
||||||
|
|
||||||
// z is not symetric
|
// z is not symetric
|
||||||
j = (-ent->fields.sv->mins[2])/8;
|
j = (-ent->mins[2])/8;
|
||||||
if (j < 1) j = 1;
|
if (j < 1) j = 1;
|
||||||
if (j > 31) j = 31;
|
if (j > 31) j = 31;
|
||||||
|
|
||||||
// and z maxs can be negative...
|
// and z maxs can be negative...
|
||||||
k = (ent->fields.sv->maxs[2]+32)/8;
|
k = (ent->maxs[2]+32)/8;
|
||||||
if (k < 1) k = 1;
|
if (k<1) k = 1;
|
||||||
if (k > 63) k = 63;
|
if (k>63) k = 63;
|
||||||
ent->fields.sv->solid = (k<<10) | (j<<5) | i;
|
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
|
// 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
|
// expand for rotation
|
||||||
float max = 0, v;
|
float max = 0, v;
|
||||||
int i;
|
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;
|
if (v > max) max = v;
|
||||||
v =fabs( ent->fields.sv->maxs[i]);
|
v =fabs( ent->maxs[i]);
|
||||||
if (v > max) max = v;
|
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->absmin[i] = ent->s.origin[i] - max;
|
||||||
ent->fields.sv->absmax[i] = ent->fields.sv->origin[i] + max;
|
ent->absmax[i] = ent->s.origin[i] + max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{ // normal
|
||||||
// normal
|
VectorAdd (ent->s.origin, ent->mins, ent->absmin);
|
||||||
VectorAdd (ent->fields.sv->origin, ent->fields.sv->mins, ent->fields.sv->absmin);
|
VectorAdd (ent->s.origin, ent->maxs, ent->absmax);
|
||||||
VectorAdd (ent->fields.sv->origin, ent->fields.sv->maxs, ent->fields.sv->absmax);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// because movement is clipped an epsilon away from an actual edge,
|
// because movement is clipped an epsilon away from an actual edge,
|
||||||
// we must fully check even when bounding boxes don't quite touch
|
// we must fully check even when bounding boxes don't quite touch
|
||||||
ent->fields.sv->absmin[0] -= 1;
|
ent->absmin[0] -= 1;
|
||||||
ent->fields.sv->absmin[1] -= 1;
|
ent->absmin[1] -= 1;
|
||||||
ent->fields.sv->absmin[2] -= 1;
|
ent->absmin[2] -= 1;
|
||||||
ent->fields.sv->absmax[0] += 1;
|
ent->absmax[0] += 1;
|
||||||
ent->fields.sv->absmax[1] += 1;
|
ent->absmax[1] += 1;
|
||||||
ent->fields.sv->absmax[2] += 1;
|
ent->absmax[2] += 1;
|
||||||
|
|
||||||
// link to PVS leafs
|
// link to PVS leafs
|
||||||
ent->priv.sv->num_clusters = 0;
|
ent->num_clusters = 0;
|
||||||
ent->priv.sv->areanum = 0;
|
ent->areanum = 0;
|
||||||
ent->priv.sv->areanum2 = 0;
|
ent->areanum2 = 0;
|
||||||
|
|
||||||
//get all leafs, including solids
|
//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
|
// set areas
|
||||||
for (i = 0; i < num_leafs; i++)
|
for (i = 0; i < num_leafs; i++)
|
||||||
|
@ -253,25 +256,25 @@ void SV_LinkEdict (prvm_edict_t *ent)
|
||||||
if (area)
|
if (area)
|
||||||
{ // doors may legally straggle two areas,
|
{ // doors may legally straggle two areas,
|
||||||
// but nothing should evern need more than that
|
// 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)
|
if (ent->areanum2 && ent->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]);
|
MsgWarn("SV_LinkEdict: object touching 3 areas at %f %f %f\n", ent->absmin[0], ent->absmin[1], ent->absmin[2]);
|
||||||
ent->priv.sv->areanum2 = area;
|
ent->areanum2 = area;
|
||||||
}
|
}
|
||||||
else ent->priv.sv->areanum = area;
|
else ent->areanum = area;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_leafs >= MAX_TOTAL_ENT_LEAFS)
|
if (num_leafs >= MAX_TOTAL_ENT_LEAFS)
|
||||||
{
|
{
|
||||||
// assume we missed some leafs, and mark by headnode
|
// assume we missed some leafs, and mark by headnode
|
||||||
ent->priv.sv->num_clusters = -1;
|
ent->num_clusters = -1;
|
||||||
ent->priv.sv->headnode = topnode;
|
ent->headnode = topnode;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ent->priv.sv->num_clusters = 0;
|
ent->num_clusters = 0;
|
||||||
for (i = 0; i < num_leafs; i++)
|
for (i = 0; i < num_leafs; i++)
|
||||||
{
|
{
|
||||||
if (clusters[i] == -1) continue; // not a visible leaf
|
if (clusters[i] == -1) continue; // not a visible leaf
|
||||||
|
@ -281,43 +284,42 @@ void SV_LinkEdict (prvm_edict_t *ent)
|
||||||
}
|
}
|
||||||
if (j == i)
|
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
|
// assume we missed some leafs, and mark by headnode
|
||||||
ent->priv.sv->num_clusters = -1;
|
ent->num_clusters = -1;
|
||||||
ent->priv.sv->headnode = topnode;
|
ent->headnode = topnode;
|
||||||
break;
|
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 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
|
// find the first node that the ent's box crosses
|
||||||
node = sv_areanodes;
|
node = sv_areanodes;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (node->axis == -1) break;
|
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];
|
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];
|
node = node->children[1];
|
||||||
else break; // crosses the node
|
else break; // crosses the node
|
||||||
}
|
}
|
||||||
|
|
||||||
// link it in
|
// link it in
|
||||||
if (ent->fields.sv->solid == SOLID_TRIGGER)
|
if (ent->solid == SOLID_TRIGGER) InsertLinkBefore (&ent->area, &node->trigger_edicts);
|
||||||
InsertLinkBefore (&ent->priv.sv->area, &node->trigger_edicts, PRVM_NUM_FOR_EDICT(ent));
|
else InsertLinkBefore (&ent->area, &node->solid_edicts);
|
||||||
else InsertLinkBefore (&ent->priv.sv->area, &node->solid_edicts, PRVM_NUM_FOR_EDICT(ent));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +333,7 @@ SV_AreaEdicts_r
|
||||||
void SV_AreaEdicts_r (areanode_t *node)
|
void SV_AreaEdicts_r (areanode_t *node)
|
||||||
{
|
{
|
||||||
link_t *l, *next, *start;
|
link_t *l, *next, *start;
|
||||||
prvm_edict_t *check;
|
edict_t *check;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
// touch linked edicts
|
// touch linked edicts
|
||||||
|
@ -342,11 +344,11 @@ void SV_AreaEdicts_r (areanode_t *node)
|
||||||
for (l = start->next; l != start; l = next)
|
for (l = start->next; l != start; l = next)
|
||||||
{
|
{
|
||||||
next = 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->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]
|
if (check->absmin[0] > area_maxs[0] || check->absmin[1] > area_maxs[1] || check->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])
|
|| check->absmax[0] < area_mins[0] || check->absmax[1] < area_mins[1] || check->absmax[2] < area_mins[2])
|
||||||
continue; // not touching
|
continue; // not touching
|
||||||
|
|
||||||
if (area_count == area_maxcount)
|
if (area_count == area_maxcount)
|
||||||
|
@ -362,8 +364,10 @@ void SV_AreaEdicts_r (areanode_t *node)
|
||||||
if (node->axis == -1) return; // terminal node
|
if (node->axis == -1) return; // terminal node
|
||||||
|
|
||||||
// recurse down both sides
|
// recurse down both sides
|
||||||
if ( area_maxs[node->axis] > node->dist ) SV_AreaEdicts_r ( node->children[0] );
|
if ( area_maxs[node->axis] > node->dist )
|
||||||
if ( area_mins[node->axis] < node->dist ) SV_AreaEdicts_r ( node->children[1] );
|
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
|
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_mins = mins;
|
||||||
area_maxs = maxs;
|
area_maxs = maxs;
|
||||||
|
@ -395,7 +399,7 @@ SV_PointContents
|
||||||
*/
|
*/
|
||||||
int SV_PointContents (vec3_t p)
|
int SV_PointContents (vec3_t p)
|
||||||
{
|
{
|
||||||
prvm_edict_t *touch[MAX_EDICTS], *hit;
|
edict_t *touch[MAX_EDICTS], *hit;
|
||||||
int i, num;
|
int i, num;
|
||||||
int contents, c2;
|
int contents, c2;
|
||||||
int headnode;
|
int headnode;
|
||||||
|
@ -413,14 +417,30 @@ int SV_PointContents (vec3_t p)
|
||||||
|
|
||||||
// might intersect, so do an exact clip
|
// might intersect, so do an exact clip
|
||||||
headnode = SV_HullForEntity (hit);
|
headnode = SV_HullForEntity (hit);
|
||||||
angles = hit->fields.sv->angles;
|
angles = hit->s.angles;
|
||||||
if (hit->fields.sv->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
|
if (hit->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
|
||||||
c2 = CM_TransformedPointContents (p, headnode, hit->fields.sv->origin, hit->fields.sv->angles);
|
c2 = CM_TransformedPointContents (p, headnode, hit->s.origin, hit->s.angles);
|
||||||
contents |= c2;
|
contents |= c2;
|
||||||
}
|
}
|
||||||
return contents;
|
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
|
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.
|
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;
|
cmodel_t *model;
|
||||||
|
|
||||||
// decide which clipping hull to use, based on the size
|
// 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
|
// explicit hulls in the BSP model
|
||||||
model = sv.models[ (int)ent->fields.sv->modelindex ];
|
model = sv.models[ ent->s.modelindex ];
|
||||||
|
|
||||||
if (!model)
|
if (!model)
|
||||||
{
|
{
|
||||||
|
@ -450,7 +470,7 @@ int SV_HullForEntity (prvm_edict_t *ent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a temp hull from bounding box sizes
|
// 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 )
|
void SV_ClipMoveToEntities ( moveclip_t *clip )
|
||||||
{
|
{
|
||||||
int i, num;
|
int i, num;
|
||||||
prvm_edict_t *touchlist[MAX_EDICTS], *touch;
|
edict_t *touchlist[MAX_EDICTS], *touch;
|
||||||
trace_t trace;
|
trace_t trace;
|
||||||
int headnode;
|
int headnode;
|
||||||
float *angles;
|
float *angles;
|
||||||
|
@ -474,32 +494,30 @@ void SV_ClipMoveToEntities ( moveclip_t *clip )
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
touch = touchlist[i];
|
touch = touchlist[i];
|
||||||
if (touch->fields.sv->solid == SOLID_NOT) continue;
|
if (touch->solid == SOLID_NOT) continue;
|
||||||
if (touch == clip->passedict) continue;
|
if (touch == clip->passedict) continue;
|
||||||
if (clip->trace.allsolid) return;
|
if (clip->trace.allsolid) return;
|
||||||
if (clip->passedict)
|
if (clip->passedict)
|
||||||
{
|
{
|
||||||
if (PRVM_PROG_TO_EDICT(touch->fields.sv->owner) == clip->passedict)
|
if (touch->owner == clip->passedict) continue; // don't clip against own missiles
|
||||||
continue; // don't clip against own missiles
|
if (clip->passedict->owner == touch) continue; // don't clip against owner
|
||||||
if (PRVM_PROG_TO_EDICT(clip->passedict->fields.sv->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;
|
continue;
|
||||||
|
|
||||||
// might intersect, so do an exact clip
|
// might intersect, so do an exact clip
|
||||||
headnode = SV_HullForEntity (touch);
|
headnode = SV_HullForEntity (touch);
|
||||||
angles = touch->fields.sv->angles;
|
angles = touch->s.angles;
|
||||||
if (touch->fields.sv->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
|
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
|
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)
|
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 clip->trace = trace;
|
||||||
}
|
}
|
||||||
else if (trace.startsolid)
|
else if (trace.startsolid) clip->trace.startsolid = true;
|
||||||
{
|
|
||||||
clip->trace.startsolid = true;
|
|
||||||
//clip->trace.startstuck = 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;
|
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 to world
|
||||||
clip.trace = CM_BoxTrace (start, end, mins, maxs, 0, contentmask);
|
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
|
if (clip.trace.fraction == 0) return clip.trace; // blocked by the world
|
||||||
|
|
||||||
clip.contentmask = contentmask;
|
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;
|
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);
|
|
||||||
}
|
|
|
@ -53,8 +53,8 @@ vec3_t listener_up;
|
||||||
|
|
||||||
bool s_registering;
|
bool s_registering;
|
||||||
|
|
||||||
float soundtime; // sample PAIRS
|
int soundtime; // sample PAIRS
|
||||||
float paintedtime; // sample PAIRS
|
int paintedtime; // sample PAIRS
|
||||||
|
|
||||||
// during registration it is possible to have more sounds
|
// during registration it is possible to have more sounds
|
||||||
// than could actually be referenced during gameplay,
|
// than could actually be referenced during gameplay,
|
||||||
|
@ -80,7 +80,7 @@ cvar_t *s_mixahead;
|
||||||
cvar_t *s_primary;
|
cvar_t *s_primary;
|
||||||
|
|
||||||
|
|
||||||
float s_rawend;
|
int s_rawend;
|
||||||
portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
|
portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
|
||||||
|
|
||||||
|
|
||||||
|
@ -120,7 +120,8 @@ void S_Init (void)
|
||||||
Msg("\n------- sound initialization -------\n");
|
Msg("\n------- sound initialization -------\n");
|
||||||
|
|
||||||
cv = Cvar_Get ("s_initsound", "1", 0);
|
cv = Cvar_Get ("s_initsound", "1", 0);
|
||||||
if (!cv->value) Msg ("not initializing.\n");
|
if (!cv->value)
|
||||||
|
Msg ("not initializing.\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s_volume = Cvar_Get ("s_volume", "0.7", CVAR_ARCHIVE);
|
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("soundlist", S_SoundList);
|
||||||
Cmd_AddCommand("soundinfo", S_SoundInfo_f);
|
Cmd_AddCommand("soundinfo", S_SoundInfo_f);
|
||||||
|
|
||||||
if (!SNDDMA_Init()) return;
|
if (!SNDDMA_Init())
|
||||||
|
return;
|
||||||
|
|
||||||
S_InitScaletable ();
|
S_InitScaletable ();
|
||||||
|
|
||||||
|
@ -147,6 +149,7 @@ void S_Init (void)
|
||||||
paintedtime = 0;
|
paintedtime = 0;
|
||||||
|
|
||||||
Msg ("sound sampling rate: %i\n", dma.speed);
|
Msg ("sound sampling rate: %i\n", dma.speed);
|
||||||
|
|
||||||
S_StopAllSounds ();
|
S_StopAllSounds ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +166,8 @@ void S_Shutdown(void)
|
||||||
int i;
|
int i;
|
||||||
sfx_t *sfx;
|
sfx_t *sfx;
|
||||||
|
|
||||||
if (!sound_started) return;
|
if (!sound_started)
|
||||||
|
return;
|
||||||
|
|
||||||
SNDDMA_Shutdown();
|
SNDDMA_Shutdown();
|
||||||
|
|
||||||
|
@ -177,10 +181,13 @@ void S_Shutdown(void)
|
||||||
// free all sounds
|
// free all sounds
|
||||||
for (i=0, sfx=known_sfx ; i < num_sfx ; i++,sfx++)
|
for (i=0, sfx=known_sfx ; i < num_sfx ; i++,sfx++)
|
||||||
{
|
{
|
||||||
if (!sfx->name[0]) continue;
|
if (!sfx->name[0])
|
||||||
if (sfx->cache) Z_Free (sfx->cache);
|
continue;
|
||||||
|
if (sfx->cache)
|
||||||
|
Z_Free (sfx->cache);
|
||||||
memset (sfx, 0, sizeof(*sfx));
|
memset (sfx, 0, sizeof(*sfx));
|
||||||
}
|
}
|
||||||
|
|
||||||
num_sfx = 0;
|
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;
|
int i;
|
||||||
sfx_t *sfx;
|
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;
|
sfx_t *sfx;
|
||||||
|
|
||||||
|
@ -364,19 +371,18 @@ S_PickChannel
|
||||||
*/
|
*/
|
||||||
channel_t *S_PickChannel(int entnum, int entchannel)
|
channel_t *S_PickChannel(int entnum, int entchannel)
|
||||||
{
|
{
|
||||||
int ch_idx;
|
int ch_idx;
|
||||||
int first_to_die;
|
int first_to_die;
|
||||||
float life_left;
|
int life_left;
|
||||||
channel_t *ch;
|
channel_t *ch;
|
||||||
|
|
||||||
if (entchannel<0)
|
if (entchannel<0)
|
||||||
Com_Error (ERR_DROP, "S_PickChannel: entchannel<0");
|
Com_Error (ERR_DROP, "S_PickChannel: entchannel<0");
|
||||||
|
|
||||||
// Check for replacement sound, or find the best one to replace
|
// Check for replacement sound, or find the best one to replace
|
||||||
first_to_die = -1;
|
first_to_die = -1;
|
||||||
life_left = 32768.0;
|
life_left = 0x7fffffff;
|
||||||
|
for (ch_idx=0 ; ch_idx < MAX_CHANNELS ; ch_idx++)
|
||||||
for (ch_idx = 0; ch_idx < MAX_CHANNELS; ch_idx++)
|
|
||||||
{
|
{
|
||||||
if (entchannel != 0 // channel 0 never overrides
|
if (entchannel != 0 // channel 0 never overrides
|
||||||
&& channels[ch_idx].entnum == entnum
|
&& 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;
|
ps->sfx = sfx;
|
||||||
|
|
||||||
// drift s_beginofs
|
// drift s_beginofs
|
||||||
start = cl.frame.servertime * dma.speed + s_beginofs;
|
start = cl.frame.servertime * 0.001 * dma.speed + s_beginofs;
|
||||||
if (start < paintedtime)
|
if (start < paintedtime)
|
||||||
{
|
{
|
||||||
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)
|
else if (start > paintedtime + 0.3 * dma.speed)
|
||||||
{
|
{
|
||||||
start = paintedtime + 0.1 * 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
|
else
|
||||||
{
|
{
|
||||||
|
@ -726,7 +732,7 @@ void S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float f
|
||||||
S_StartLocalSound
|
S_StartLocalSound
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
int S_StartLocalSound (const char *sound)
|
int S_StartLocalSound (char *sound)
|
||||||
{
|
{
|
||||||
sfx_t *sfx;
|
sfx_t *sfx;
|
||||||
|
|
||||||
|
@ -886,7 +892,7 @@ void S_AddLoopSounds (void)
|
||||||
ch->rightvol = right_total;
|
ch->rightvol = right_total;
|
||||||
ch->autosound = true; // remove next frame
|
ch->autosound = true; // remove next frame
|
||||||
ch->sfx = sfx;
|
ch->sfx = sfx;
|
||||||
ch->pos = fmod(paintedtime, sc->length);
|
ch->pos = paintedtime % sc->length;
|
||||||
ch->end = paintedtime + sc->length - ch->pos;
|
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
|
{ // optimized case
|
||||||
for (i=0 ; i<samples ; i++)
|
for (i=0 ; i<samples ; i++)
|
||||||
{
|
{
|
||||||
dst = (int)s_rawend & (MAX_RAW_SAMPLES - 1);
|
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||||
s_rawend++;
|
s_rawend++;
|
||||||
s_rawsamples[dst].left =
|
s_rawsamples[dst].left =
|
||||||
LittleShort(((short *)data)[i*2]) << 8;
|
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;
|
src = i*scale;
|
||||||
if (src >= samples)
|
if (src >= samples)
|
||||||
break;
|
break;
|
||||||
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
|
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||||
s_rawend++;
|
s_rawend++;
|
||||||
s_rawsamples[dst].left =
|
s_rawsamples[dst].left =
|
||||||
LittleShort(((short *)data)[src*2]) << 8;
|
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;
|
src = i*scale;
|
||||||
if (src >= samples)
|
if (src >= samples)
|
||||||
break;
|
break;
|
||||||
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
|
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||||
s_rawend++;
|
s_rawend++;
|
||||||
s_rawsamples[dst].left =
|
s_rawsamples[dst].left =
|
||||||
LittleShort(((short *)data)[src]) << 8;
|
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;
|
src = i*scale;
|
||||||
if (src >= samples)
|
if (src >= samples)
|
||||||
break;
|
break;
|
||||||
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
|
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||||
s_rawend++;
|
s_rawend++;
|
||||||
s_rawsamples[dst].left =
|
s_rawsamples[dst].left =
|
||||||
((char *)data)[src*2] << 16;
|
((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;
|
src = i*scale;
|
||||||
if (src >= samples)
|
if (src >= samples)
|
||||||
break;
|
break;
|
||||||
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
|
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||||
s_rawend++;
|
s_rawend++;
|
||||||
s_rawsamples[dst].left =
|
s_rawsamples[dst].left =
|
||||||
(((byte *)data)[src]-128) << 16;
|
(((byte *)data)[src]-128) << 16;
|
||||||
|
@ -1104,8 +1110,8 @@ void GetSoundtime(void)
|
||||||
|
|
||||||
void S_Update_(void)
|
void S_Update_(void)
|
||||||
{
|
{
|
||||||
uint endtime;
|
unsigned endtime;
|
||||||
int samps;
|
int samps;
|
||||||
|
|
||||||
if (!sound_started)
|
if (!sound_started)
|
||||||
return;
|
return;
|
||||||
|
@ -1121,7 +1127,7 @@ void S_Update_(void)
|
||||||
// check to make sure that we haven't overshot
|
// check to make sure that we haven't overshot
|
||||||
if (paintedtime < soundtime)
|
if (paintedtime < soundtime)
|
||||||
{
|
{
|
||||||
MsgWarn("S_Update_: overflow [%g]\n", soundtime - paintedtime);
|
MsgWarn("S_Update_: overflow\n");
|
||||||
paintedtime = soundtime;
|
paintedtime = soundtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ typedef struct
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
float length;
|
int length;
|
||||||
int loopstart;
|
int loopstart;
|
||||||
int speed; // not needed, because converted on load?
|
int speed; // not needed, because converted on load?
|
||||||
int width;
|
int width;
|
||||||
|
@ -39,7 +39,7 @@ typedef struct
|
||||||
typedef struct sfx_s
|
typedef struct sfx_s
|
||||||
{
|
{
|
||||||
char name[MAX_QPATH];
|
char name[MAX_QPATH];
|
||||||
int registration_sequence;
|
int registration_sequence;
|
||||||
sfxcache_t *cache;
|
sfxcache_t *cache;
|
||||||
char *truename;
|
char *truename;
|
||||||
} sfx_t;
|
} sfx_t;
|
||||||
|
@ -53,21 +53,21 @@ typedef struct playsound_s
|
||||||
sfx_t *sfx;
|
sfx_t *sfx;
|
||||||
float volume;
|
float volume;
|
||||||
float attenuation;
|
float attenuation;
|
||||||
int entnum;
|
int entnum;
|
||||||
int entchannel;
|
int entchannel;
|
||||||
bool fixed_origin; // use origin field instead of entnum's origin
|
bool fixed_origin; // use origin field instead of entnum's origin
|
||||||
vec3_t origin;
|
vec3_t origin;
|
||||||
float begin; // begin on this sample
|
unsigned begin; // begin on this sample
|
||||||
} playsound_t;
|
} playsound_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int channels;
|
int channels;
|
||||||
int samples; // mono samples in buffer
|
int samples; // mono samples in buffer
|
||||||
int submission_chunk; // don't mix less than this #
|
int submission_chunk; // don't mix less than this #
|
||||||
int samplepos; // in mono samples
|
int samplepos; // in mono samples
|
||||||
int samplebits;
|
int samplebits;
|
||||||
int speed;
|
int speed;
|
||||||
byte *buffer;
|
byte *buffer;
|
||||||
} dma_t;
|
} dma_t;
|
||||||
|
|
||||||
|
@ -75,18 +75,18 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
sfx_t *sfx; // sfx number
|
sfx_t *sfx; // sfx number
|
||||||
int leftvol; // 0-255 volume
|
int leftvol; // 0-255 volume
|
||||||
int rightvol; // 0-255 volume
|
int rightvol; // 0-255 volume
|
||||||
float end; // end time in global paintsamples
|
int end; // end time in global paintsamples
|
||||||
int pos; // sample position in sfx
|
int pos; // sample position in sfx
|
||||||
int looping; // where to loop, -1 = no looping OBSOLETE?
|
int looping; // where to loop, -1 = no looping OBSOLETE?
|
||||||
int entnum; // to allow overriding a specific sound
|
int entnum; // to allow overriding a specific sound
|
||||||
int entchannel; //
|
int entchannel; //
|
||||||
vec3_t origin; // only use if fixed_origin is set
|
vec3_t origin; // only use if fixed_origin is set
|
||||||
vec_t dist_mult; // distance multiplier (attenuation/clipK)
|
vec_t dist_mult; // distance multiplier (attenuation/clipK)
|
||||||
int master_vol; // 0-255 master volume
|
int master_vol; // 0-255 master volume
|
||||||
bool fixed_origin; // use origin instead of fetching entnum's origin
|
bool fixed_origin; // use origin instead of fetching entnum's origin
|
||||||
bool autosound; // from an entity->sound, cleared each frame
|
bool autosound; // from an entity->sound, cleared each frame
|
||||||
} channel_t;
|
} channel_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -126,8 +126,8 @@ void SNDDMA_Submit(void);
|
||||||
#define MAX_CHANNELS 32
|
#define MAX_CHANNELS 32
|
||||||
extern channel_t channels[MAX_CHANNELS];
|
extern channel_t channels[MAX_CHANNELS];
|
||||||
|
|
||||||
extern float paintedtime;
|
extern int paintedtime;
|
||||||
extern float s_rawend;
|
extern int s_rawend;
|
||||||
extern vec3_t listener_origin;
|
extern vec3_t listener_origin;
|
||||||
extern vec3_t listener_forward;
|
extern vec3_t listener_forward;
|
||||||
extern vec3_t listener_right;
|
extern vec3_t listener_right;
|
||||||
|
@ -155,7 +155,7 @@ sfxcache_t *S_LoadSound (sfx_t *s);
|
||||||
|
|
||||||
void S_IssuePlaysound (playsound_t *ps);
|
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
|
// picks a channel based on priorities, empty slots, number of channels
|
||||||
channel_t *S_PickChannel(int entnum, int entchannel);
|
channel_t *S_PickChannel(int entnum, int entchannel);
|
||||||
|
|
|
@ -109,17 +109,17 @@ S_TransferPaintBuffer
|
||||||
|
|
||||||
===================
|
===================
|
||||||
*/
|
*/
|
||||||
void S_TransferPaintBuffer(float endtime)
|
void S_TransferPaintBuffer(int endtime)
|
||||||
{
|
{
|
||||||
int out_idx;
|
int out_idx;
|
||||||
float count;
|
int count;
|
||||||
int out_mask;
|
int out_mask;
|
||||||
int *p;
|
int *p;
|
||||||
int step;
|
int step;
|
||||||
int val;
|
int val;
|
||||||
dword *pbuf;
|
unsigned long *pbuf;
|
||||||
|
|
||||||
pbuf = (dword*)dma.buffer;
|
pbuf = (unsigned long *)dma.buffer;
|
||||||
|
|
||||||
if (s_testsound->value)
|
if (s_testsound->value)
|
||||||
{
|
{
|
||||||
|
@ -129,7 +129,7 @@ void S_TransferPaintBuffer(float endtime)
|
||||||
// write a fixed sine wave
|
// write a fixed sine wave
|
||||||
count = (endtime - paintedtime);
|
count = (endtime - paintedtime);
|
||||||
for (i=0 ; i<count ; i++)
|
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;
|
p = (int *) paintbuffer;
|
||||||
count = (endtime - paintedtime) * dma.channels;
|
count = (endtime - paintedtime) * dma.channels;
|
||||||
out_mask = dma.samples - 1;
|
out_mask = dma.samples - 1;
|
||||||
out_idx = (int)(paintedtime * dma.channels) & out_mask;
|
out_idx = paintedtime * dma.channels & out_mask;
|
||||||
step = 3 - dma.channels;
|
step = 3 - dma.channels;
|
||||||
|
|
||||||
if (dma.samplebits == 16)
|
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_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_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime, int offset);
|
||||||
|
|
||||||
void S_PaintChannels(float endtime)
|
void S_PaintChannels(int endtime)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
float end;
|
int end;
|
||||||
channel_t *ch;
|
channel_t *ch;
|
||||||
sfxcache_t *sc;
|
sfxcache_t *sc;
|
||||||
float ltime, count;
|
int ltime, count;
|
||||||
playsound_t *ps;
|
playsound_t *ps;
|
||||||
|
|
||||||
snd_vol = s_volume->value*256;
|
snd_vol = s_volume->value*256;
|
||||||
|
|
||||||
//Msg ("%i to %i\n", paintedtime, endtime);
|
//Msg ("%i to %i\n", paintedtime, endtime);
|
||||||
while (paintedtime < endtime)
|
while (paintedtime < endtime)
|
||||||
{
|
{
|
||||||
// if paintbuffer is smaller than DMA buffer
|
// if paintbuffer is smaller than DMA buffer
|
||||||
|
@ -221,11 +221,12 @@ void S_PaintChannels(float endtime)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps->begin < end) end = ps->begin;// stop here
|
if (ps->begin < end)
|
||||||
|
end = ps->begin; // stop here
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear the paint buffer
|
// clear the paint buffer
|
||||||
if (s_rawend < paintedtime)
|
if (s_rawend < paintedtime)
|
||||||
{
|
{
|
||||||
// Msg ("clear\n");
|
// Msg ("clear\n");
|
||||||
|
@ -241,7 +242,7 @@ void S_PaintChannels(float endtime)
|
||||||
for (i=paintedtime ; i<stop ; i++)
|
for (i=paintedtime ; i<stop ; i++)
|
||||||
{
|
{
|
||||||
s = i&(MAX_RAW_SAMPLES-1);
|
s = i&(MAX_RAW_SAMPLES-1);
|
||||||
paintbuffer[(int)(i - paintedtime)] = s_rawsamples[s];
|
paintbuffer[i-paintedtime] = s_rawsamples[s];
|
||||||
}
|
}
|
||||||
// if (i != end)
|
// if (i != end)
|
||||||
// Msg ("partial stream\n");
|
// Msg ("partial stream\n");
|
||||||
|
@ -249,8 +250,8 @@ void S_PaintChannels(float endtime)
|
||||||
// Msg ("full stream\n");
|
// Msg ("full stream\n");
|
||||||
for ( ; i<end ; i++)
|
for ( ; i<end ; i++)
|
||||||
{
|
{
|
||||||
paintbuffer[(int)(i - paintedtime)].left =
|
paintbuffer[i-paintedtime].left =
|
||||||
paintbuffer[(int)(i - paintedtime)].right = 0;
|
paintbuffer[i-paintedtime].right = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ void S_Shutdown (void);
|
||||||
|
|
||||||
// if origin is NULL, the sound will be dynamically sourced from the entity
|
// 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);
|
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);
|
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_Activate (bool active);
|
||||||
|
|
||||||
void S_BeginRegistration (void);
|
void S_BeginRegistration (void);
|
||||||
struct sfx_s *S_RegisterSound (const char *sample);
|
struct sfx_s *S_RegisterSound (char *sample);
|
||||||
void S_EndRegistration (void);
|
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
|
// the sound code makes callbacks to the client for entitiy position
|
||||||
// information, so entities can be dynamically re-spatialized
|
// information, so entities can be dynamically re-spatialized
|
||||||
|
|
134
engine/system.c
134
engine/system.c
|
@ -27,6 +27,10 @@ extern HWND cl_hwnd;
|
||||||
//engine builddate
|
//engine builddate
|
||||||
char *buildstring = __TIME__ " " __DATE__;
|
char *buildstring = __TIME__ " " __DATE__;
|
||||||
stdinout_api_t std;
|
stdinout_api_t std;
|
||||||
|
uint sys_msg_time;
|
||||||
|
uint sys_frame_time;
|
||||||
|
|
||||||
|
int starttime;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
@ -79,34 +83,12 @@ void Sys_Init (void)
|
||||||
{
|
{
|
||||||
OSVERSIONINFO vinfo;
|
OSVERSIONINFO vinfo;
|
||||||
|
|
||||||
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
|
|
||||||
|
|
||||||
timeBeginPeriod( 1 );
|
timeBeginPeriod( 1 );
|
||||||
|
|
||||||
|
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
|
||||||
|
|
||||||
if (!GetVersionEx (&vinfo)) Sys_Error ("Couldn't get OS info");
|
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);
|
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)
|
void Sys_SendKeyEvents (void)
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
|
||||||
rand();
|
|
||||||
|
|
||||||
while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
|
while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
|
||||||
{
|
{
|
||||||
if (!GetMessage (&msg, NULL, 0, 0)) Sys_Quit ();
|
if (!GetMessage (&msg, NULL, 0, 0)) Sys_Quit ();
|
||||||
host.sv_timer = msg.time;
|
sys_msg_time = msg.time;
|
||||||
TranslateMessage (&msg);
|
TranslateMessage (&msg);
|
||||||
DispatchMessage (&msg);
|
DispatchMessage (&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// grab frame time
|
// 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;
|
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 );
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
renderer_exp_t *re;
|
renderer_exp_t *re;
|
||||||
|
|
||||||
extern HWND cl_hwnd;
|
extern HWND cl_hwnd;
|
||||||
|
extern bool ActiveApp, Minimized;
|
||||||
extern HINSTANCE global_hInstance;
|
extern HINSTANCE global_hInstance;
|
||||||
|
|
||||||
#ifndef WM_MOUSEWHEEL
|
#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 );
|
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;
|
Minimized = minimize;
|
||||||
else if(fMinimize) host.state = HOST_SLEEP;
|
|
||||||
else host.state = HOST_NOFOCUS;
|
|
||||||
|
|
||||||
Key_ClearStates();
|
Key_ClearStates();
|
||||||
|
|
||||||
// minimize/restore mouse-capture on demand
|
// we don't want to act like we're active if we're minimized
|
||||||
if(host.state == HOST_FRAME)
|
if (fActive && !Minimized)
|
||||||
{
|
ActiveApp = true;
|
||||||
IN_Activate (true);
|
|
||||||
S_Activate (true);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
ActiveApp = false;
|
||||||
|
|
||||||
|
// minimize/restore mouse-capture on demand
|
||||||
|
if (!ActiveApp)
|
||||||
{
|
{
|
||||||
IN_Activate (false);
|
IN_Activate (false);
|
||||||
S_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 )
|
if ( ( ( int ) wParam ) > 0 )
|
||||||
{
|
{
|
||||||
Key_Event( K_MWHEELUP, true, host.sv_timer );
|
Key_Event( K_MWHEELUP, true, sys_msg_time );
|
||||||
Key_Event( K_MWHEELUP, false, host.sv_timer );
|
Key_Event( K_MWHEELUP, false, sys_msg_time );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Key_Event( K_MWHEELDOWN, true, host.sv_timer );
|
Key_Event( K_MWHEELDOWN, true, sys_msg_time );
|
||||||
Key_Event( K_MWHEELDOWN, false, host.sv_timer );
|
Key_Event( K_MWHEELDOWN, false, sys_msg_time );
|
||||||
}
|
}
|
||||||
return DefWindowProc (hWnd, uMsg, wParam, lParam);
|
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 )
|
if ( ( short ) HIWORD( wParam ) > 0 )
|
||||||
{
|
{
|
||||||
Key_Event( K_MWHEELUP, true, host.sv_timer );
|
Key_Event( K_MWHEELUP, true, sys_msg_time );
|
||||||
Key_Event( K_MWHEELUP, false, host.sv_timer );
|
Key_Event( K_MWHEELUP, false, sys_msg_time );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Key_Event( K_MWHEELDOWN, true, host.sv_timer );
|
Key_Event( K_MWHEELDOWN, true, sys_msg_time );
|
||||||
Key_Event( K_MWHEELDOWN, false, host.sv_timer );
|
Key_Event( K_MWHEELDOWN, false, sys_msg_time );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -297,7 +305,7 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
Cvar_SetValue( "vid_ypos", yPos + r.top);
|
Cvar_SetValue( "vid_ypos", yPos + r.top);
|
||||||
vid_xpos->modified = false;
|
vid_xpos->modified = false;
|
||||||
vid_ypos->modified = false;
|
vid_ypos->modified = false;
|
||||||
if (host.state == HOST_FRAME)
|
if (ActiveApp)
|
||||||
IN_Activate (true);
|
IN_Activate (true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,11 +351,11 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
Key_Event( MapKey( lParam ), true, host.sv_timer);
|
Key_Event( MapKey( lParam ), true, sys_msg_time);
|
||||||
break;
|
break;
|
||||||
case WM_SYSKEYUP:
|
case WM_SYSKEYUP:
|
||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
Key_Event( MapKey( lParam ), false, host.sv_timer);
|
Key_Event( MapKey( lParam ), false, sys_msg_time);
|
||||||
break;
|
break;
|
||||||
default: // pass all unhandled messages to DefWindowProc
|
default: // pass all unhandled messages to DefWindowProc
|
||||||
return DefWindowProc (hWnd, uMsg, wParam, lParam);
|
return DefWindowProc (hWnd, uMsg, wParam, lParam);
|
||||||
|
@ -462,12 +470,6 @@ char *FS_Title( void )
|
||||||
return GI.title;
|
return GI.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
cvar_t *VID_Cvar_Set (const char *var_name, const char *value)
|
|
||||||
{
|
|
||||||
return Cvar_Set( var_name, value );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============
|
==============
|
||||||
VID_InitRenderer
|
VID_InitRenderer
|
||||||
|
@ -496,7 +498,7 @@ void VID_InitRenderer( void )
|
||||||
ri.gamedir = FS_Gamedir;
|
ri.gamedir = FS_Gamedir;
|
||||||
ri.title = FS_Title;
|
ri.title = FS_Title;
|
||||||
ri.Cvar_Get = Cvar_Get;
|
ri.Cvar_Get = Cvar_Get;
|
||||||
ri.Cvar_Set = VID_Cvar_Set;
|
ri.Cvar_Set = Cvar_Set;
|
||||||
ri.Cvar_SetValue = Cvar_SetValue;
|
ri.Cvar_SetValue = Cvar_SetValue;
|
||||||
ri.Vid_GetModeInfo = VID_GetModeInfo;
|
ri.Vid_GetModeInfo = VID_GetModeInfo;
|
||||||
ri.Vid_MenuInit = VID_MenuInit;
|
ri.Vid_MenuInit = VID_MenuInit;
|
||||||
|
|
|
@ -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 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 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];}
|
#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 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 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 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])
|
#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)
|
_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];
|
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)
|
_inline void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross)
|
||||||
{
|
{
|
||||||
cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
|
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);
|
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;
|
float angle;
|
||||||
static float sr, sp, sy, cr, cp, cy;
|
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[1] = cp*sy;
|
||||||
forward[2] = -sp;
|
forward[2] = -sp;
|
||||||
}
|
}
|
||||||
if (right || up)
|
if (right)
|
||||||
{
|
{
|
||||||
if (angles[ROLL])
|
right[0] = (-1*sr*sp*cy+-1*cr*-sy);
|
||||||
{
|
right[1] = (-1*sr*sp*sy+-1*cr*cy);
|
||||||
angle = angles[ROLL] * (M_PI*2 / 360);
|
right[2] = -1*sr*cp;
|
||||||
sr = sin(angle);
|
}
|
||||||
cr = cos(angle);
|
if (up)
|
||||||
if (right)
|
{
|
||||||
{
|
up[0] = (cr*sp*cy+-sr*-sy);
|
||||||
right[0] = -1*(sr*sp*cy+cr*-sy);
|
up[1] = (cr*sp*sy+-sr*cy);
|
||||||
right[1] = -1*(sr*sp*sy+cr*cy);
|
up[2] = cr*cp;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_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;
|
float angle;
|
||||||
static float sr, sp, sy, cr, cp, cy;
|
static float sr, sp, sy, cr, cp, cy;
|
||||||
|
|
|
@ -44,6 +44,8 @@ typedef struct vfile_s vfile_t;
|
||||||
typedef struct image_s image_t;
|
typedef struct image_s image_t;
|
||||||
typedef struct model_s model_t;
|
typedef struct model_s model_t;
|
||||||
typedef int func_t;
|
typedef int func_t;
|
||||||
|
typedef struct edict_s edict_t;
|
||||||
|
typedef struct gclient_s gclient_t;
|
||||||
typedef int string_t;
|
typedef int string_t;
|
||||||
typedef int progsnum_t;
|
typedef int progsnum_t;
|
||||||
typedef struct progfuncs_s progfuncs_t;
|
typedef struct progfuncs_s progfuncs_t;
|
||||||
|
|
|
@ -207,15 +207,6 @@ typedef struct cmodel_s
|
||||||
vec3_t mins, maxs; // boundbox
|
vec3_t mins, maxs; // boundbox
|
||||||
vec3_t origin; // for sounds or lights
|
vec3_t origin; // for sounds or lights
|
||||||
int headnode; // bsp info
|
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
|
int numframes; //sprite framecount
|
||||||
void *extradata; //for studio models
|
void *extradata; //for studio models
|
||||||
|
|
101
public/const.h
101
public/const.h
|
@ -79,10 +79,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#define PRINT_HIGH 2 // critical messages
|
#define PRINT_HIGH 2 // critical messages
|
||||||
#define PRINT_CHAT 3 // chat messages
|
#define PRINT_CHAT 3 // chat messages
|
||||||
|
|
||||||
#define SPAWNFLAG_NOT_EASY 256
|
#define SPAWNFLAG_NOT_EASY 0x00000100
|
||||||
#define SPAWNFLAG_NOT_MEDIUM 512
|
#define SPAWNFLAG_NOT_MEDIUM 0x00000200
|
||||||
#define SPAWNFLAG_NOT_HARD 1024
|
#define SPAWNFLAG_NOT_HARD 0x00000400
|
||||||
#define SPAWNFLAG_NOT_DEATHMATCH 2048
|
#define SPAWNFLAG_NOT_DEATHMATCH 0x00000800
|
||||||
|
|
||||||
// entity_state_t->renderfx flags
|
// entity_state_t->renderfx flags
|
||||||
#define RF_MINLIGHT 1 // allways have some light (viewmodel)
|
#define RF_MINLIGHT 1 // allways have some light (viewmodel)
|
||||||
|
@ -148,29 +148,23 @@ typedef enum
|
||||||
WEAPON_FIRING
|
WEAPON_FIRING
|
||||||
} weaponstate_t;
|
} weaponstate_t;
|
||||||
|
|
||||||
typedef enum
|
#define MOVETYPE_NONE 0 // never moves
|
||||||
{
|
#define MOVETYPE_NOCLIP 1 // origin and angles change with no interaction
|
||||||
SOLID_NOT, // no interaction with other objects
|
#define MOVETYPE_PUSH 2 // no clip to world, push on box contact
|
||||||
SOLID_TRIGGER, // only touch when inside, after moving
|
#define MOVETYPE_STOP 3 // no clip to world, stops on box contact
|
||||||
SOLID_BBOX, // touch on edge
|
#define MOVETYPE_WALK 4 // gravity
|
||||||
SOLID_BSP // bsp clip, touch on edge
|
#define MOVETYPE_STEP 5 // gravity, special edge handling
|
||||||
} solid_t;
|
#define MOVETYPE_FLY 6
|
||||||
|
#define MOVETYPE_TOSS 7 // gravity
|
||||||
typedef enum
|
#define MOVETYPE_FLYMISSILE 8 // extra size to monsters
|
||||||
{
|
#define MOVETYPE_BOUNCE 9
|
||||||
MOVETYPE_NONE = 0, // never moves, but can collide
|
#define MOVETYPE_FOLLOW 10 // attached models
|
||||||
MOVETYPE_NOCLIP, // origin and angles change with no interaction
|
#define MOVETYPE_VEHICLE 11
|
||||||
MOVETYPE_PUSH, // no clip to world, push on box contact
|
#define MOVETYPE_PUSHABLE 12
|
||||||
MOVETYPE_WALK, // player case
|
#define MOVETYPE_DEBRIS 13 // non-solid debris that can still hurt you
|
||||||
MOVETYPE_STEP, // monster case (get rid of this)
|
#define MOVETYPE_RAIN 14 // identical to MOVETYPE_FLYMISSILE, but doesn't cause splash noises when touching water.
|
||||||
MOVETYPE_FLY, // ignore gravity
|
#define MOVETYPE_PENDULUM 15 // same as MOVETYPE_PUSH, but used only for pendulums to grab special-case problems
|
||||||
MOVETYPE_TOSS, // gravity
|
#define MOVETYPE_CONVEYOR 16
|
||||||
MOVETYPE_BOUNCE,
|
|
||||||
MOVETYPE_FOLLOW, // attached models
|
|
||||||
MOVETYPE_COMPLEX, // complex moving ents (parent system)
|
|
||||||
MOVETYPE_RAGDOLL, // npc ragdoll (not implemented yet)
|
|
||||||
|
|
||||||
} movetype_t;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================
|
==============================================================
|
||||||
|
@ -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 PerpendicularVector( vec3_t dst, const vec3_t src );
|
||||||
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );
|
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Com_PageInMemory (byte *buffer, int size);
|
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
|
// a trace is returned when a box is swept through the world
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
bool allsolid; // if true, plane is not valid
|
bool allsolid; // if true, plane is not valid
|
||||||
bool startsolid; // if true, the initial point was in a solid area
|
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
|
||||||
|
|
||||||
float fraction; // time completed, 1.0 = didn't hit anything
|
|
||||||
vec3_t endpos; // final position
|
vec3_t endpos; // final position
|
||||||
cplane_t plane; // surface normal at impact
|
cplane_t plane; // surface normal at impact
|
||||||
csurface_t *surface; // surface hit
|
csurface_t *surface; // surface hit
|
||||||
int contents; // contents on other side of surface hit
|
int contents; // contents on other side of surface hit
|
||||||
prvm_edict_t *ent; // not set by CM_*() functions
|
struct edict_s *ent; // not set by CM_*() functions
|
||||||
} trace_t;
|
} trace_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -298,7 +312,7 @@ typedef struct
|
||||||
byte pm_time; // each unit = 8 ms
|
byte pm_time; // each unit = 8 ms
|
||||||
short gravity;
|
short gravity;
|
||||||
short delta_angles[3]; // add to command angles to get view direction
|
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;
|
} pmove_state_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -324,7 +338,6 @@ typedef struct usercmd_s
|
||||||
short forwardmove, sidemove, upmove;
|
short forwardmove, sidemove, upmove;
|
||||||
byte impulse; // remove?
|
byte impulse; // remove?
|
||||||
byte lightlevel; // light level the player is standing on
|
byte lightlevel; // light level the player is standing on
|
||||||
|
|
||||||
} usercmd_t;
|
} usercmd_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -340,14 +353,14 @@ typedef struct
|
||||||
|
|
||||||
// results (out)
|
// results (out)
|
||||||
int numtouch;
|
int numtouch;
|
||||||
prvm_edict_t *touchents[MAXTOUCH];
|
struct edict_s *touchents[MAXTOUCH];
|
||||||
|
|
||||||
vec3_t viewangles; // clamped
|
vec3_t viewangles; // clamped
|
||||||
float viewheight;
|
float viewheight;
|
||||||
|
|
||||||
vec3_t mins, maxs; // bounding box size
|
vec3_t mins, maxs; // bounding box size
|
||||||
|
|
||||||
prvm_edict_t *groundentity;
|
struct edict_s *groundentity;
|
||||||
int watertype;
|
int watertype;
|
||||||
int waterlevel;
|
int waterlevel;
|
||||||
|
|
||||||
|
@ -790,16 +803,16 @@ typedef struct
|
||||||
|
|
||||||
// these fields do not need to be communicated bit-precise
|
// these fields do not need to be communicated bit-precise
|
||||||
|
|
||||||
vec3_t viewangles; // for fixed views
|
vec3_t viewangles; // for fixed views
|
||||||
vec3_t viewoffset; // add to pmovestate->origin
|
vec3_t viewoffset; // add to pmovestate->origin
|
||||||
vec3_t kick_angles; // add to view direction to get render angles
|
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 gunangles;
|
||||||
vec3_t gunoffset;
|
vec3_t gunoffset;
|
||||||
int gunindex;
|
int gunindex;
|
||||||
int gunframe; // studio frame
|
int gunframe; // studio frame
|
||||||
int sequence; // studio animation sequence
|
int sequence; // stuido animation sequence
|
||||||
int gunbody;
|
int gunbody;
|
||||||
int gunskin;
|
int gunskin;
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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);
|
|
|
@ -293,7 +293,7 @@ typedef struct
|
||||||
float vieworg[3];
|
float vieworg[3];
|
||||||
float viewangles[3];
|
float viewangles[3];
|
||||||
float blend[4]; // rgba 0-1 full screen blend
|
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
|
int rdflags; // RDF_UNDERWATER, etc
|
||||||
|
|
||||||
byte *areabits; // if not NULL, only areas with set bits will be drawn
|
byte *areabits; // if not NULL, only areas with set bits will be drawn
|
||||||
|
|
|
@ -24,7 +24,7 @@ if errorlevel 1 set BUILD_ERROR=1
|
||||||
%MSDEV% renderer/renderer.dsp %CONFIG%"renderer - Win32 Release" %build_target%
|
%MSDEV% renderer/renderer.dsp %CONFIG%"renderer - Win32 Release" %build_target%
|
||||||
if errorlevel 1 set BUILD_ERROR=1
|
if errorlevel 1 set BUILD_ERROR=1
|
||||||
|
|
||||||
progs\qcclib.exe -O3
|
progs\qcclib.exe
|
||||||
if errorlevel 1 set BUILD_ERROR=1
|
if errorlevel 1 set BUILD_ERROR=1
|
||||||
|
|
||||||
if "%BUILD_ERROR%"=="" goto build_ok
|
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 Build succeeded!
|
||||||
echo Please wait. Xash is now loading
|
echo Please wait. Xash is now loading
|
||||||
cd D:\Xash3D\
|
cd D:\Xash3D\
|
||||||
xash.exe +map qctest
|
xash.exe -game valve +map skytest -debug
|
||||||
:done
|
:done
|
|
@ -125,7 +125,7 @@ void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
|
||||||
|
|
||||||
// move should be the delta back to the previous frame * backlerp
|
// move should be the delta back to the previous frame * backlerp
|
||||||
VectorSubtract (currententity->oldorigin, currententity->origin, delta);
|
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[0] = DotProduct (delta, vectors[0]); // forward
|
||||||
move[1] = -DotProduct (delta, vectors[1]); // left
|
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 );
|
VectorCopy( e->angles, angles );
|
||||||
angles[YAW] = -angles[YAW];
|
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++ )
|
for ( i = 0; i < 8; i++ )
|
||||||
{
|
{
|
||||||
|
|
|
@ -499,7 +499,7 @@ void R_SetupFrame (void)
|
||||||
// build the transformation matrix for the given view angles
|
// build the transformation matrix for the given view angles
|
||||||
VectorCopy (r_newrefdef.vieworg, r_origin);
|
VectorCopy (r_newrefdef.vieworg, r_origin);
|
||||||
|
|
||||||
AngleVectorsRight(r_newrefdef.viewangles, vforward, vright, vup);
|
AngleVectors(r_newrefdef.viewangles, vforward, vright, vup);
|
||||||
|
|
||||||
// current viewcluster
|
// current viewcluster
|
||||||
if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
|
if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
|
||||||
|
|
|
@ -976,7 +976,7 @@ void R_DrawBrushModel ( int passnum )
|
||||||
vec3_t forward, right, up;
|
vec3_t forward, right, up;
|
||||||
|
|
||||||
VectorCopy (modelorg, temp);
|
VectorCopy (modelorg, temp);
|
||||||
AngleVectorsRight(e->angles, forward, right, up);
|
AngleVectors(e->angles, forward, right, up);
|
||||||
modelorg[0] = DotProduct (temp, forward);
|
modelorg[0] = DotProduct (temp, forward);
|
||||||
modelorg[1] = -DotProduct (temp, right);
|
modelorg[1] = -DotProduct (temp, right);
|
||||||
modelorg[2] = DotProduct (temp, up);
|
modelorg[2] = DotProduct (temp, up);
|
||||||
|
|
|
@ -281,7 +281,7 @@ void R_DrawSpriteModel( int passnum )
|
||||||
switch( psprite->type )
|
switch( psprite->type )
|
||||||
{
|
{
|
||||||
case SPR_ORIENTED:
|
case SPR_ORIENTED:
|
||||||
AngleVectorsRight(e->angles, forward, right, up);
|
AngleVectors(e->angles, forward, right, up);
|
||||||
VectorScale(forward, 0.01, forward );//offset for decals
|
VectorScale(forward, 0.01, forward );//offset for decals
|
||||||
VectorSubtract(e->origin, forward, e->origin );
|
VectorSubtract(e->origin, forward, e->origin );
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1012,7 +1012,7 @@ static bool R_StudioComputeBBox( vec3_t *bbox )
|
||||||
//rotate the bounding box
|
//rotate the bounding box
|
||||||
VectorCopy( e->angles, angles );
|
VectorCopy( e->angles, angles );
|
||||||
angles[PITCH] = -angles[PITCH];
|
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++ )
|
for ( i = 0; i < 8; i++ )
|
||||||
{
|
{
|
||||||
|
|
Reference in New Issue