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_ClipToLinks SV_ClipMoveToEntities
|
||||
|
||||
//==================================================
|
||||
// FIXME
|
||||
//==================================================
|
||||
1. Пофиксить движение игрока (сл. большая скорость)
|
||||
1. Перенести основные части gamed.dll в движок OK
|
||||
2. Попытка полностью отказаться от gamed.dll OK
|
||||
3. Перенести физику в движок OK
|
||||
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 Please wait. Xash is now loading
|
||||
cd D:\Xash3D\
|
||||
xash.exe +map qctest -debug
|
||||
xash.exe +map qctest -log
|
||||
:done
|
|
@ -402,17 +402,17 @@ void SCR_RunCinematic (void)
|
|||
|
||||
if (cls.key_dest != key_game)
|
||||
{ // pause if menu or console is up
|
||||
cl.cinematictime = cls.realtime - cl.cinematicframe/14;
|
||||
cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14;
|
||||
return;
|
||||
}
|
||||
|
||||
frame = (cls.realtime - cl.cinematictime)*14.0;
|
||||
frame = (cls.realtime - cl.cinematictime)*14.0/1000;
|
||||
if (frame <= cl.cinematicframe)
|
||||
return;
|
||||
if (frame > cl.cinematicframe+1)
|
||||
{
|
||||
Msg ("Dropped frame: %i > %i\n", frame, cl.cinematicframe+1);
|
||||
cl.cinematictime = cls.realtime - cl.cinematicframe/14;
|
||||
cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14;
|
||||
}
|
||||
if (cin.pic)
|
||||
Z_Free (cin.pic);
|
||||
|
@ -546,5 +546,5 @@ void SCR_PlayCinematic (char *arg)
|
|||
|
||||
cl.cinematicframe = 0;
|
||||
cin.pic = SCR_ReadNextFrame ();
|
||||
cl.cinematictime = cls.realtime;
|
||||
cl.cinematictime = Sys_Milliseconds ();
|
||||
}
|
||||
|
|
|
@ -323,8 +323,7 @@ void CL_DeltaEntity (frame_t *frame, int newnum, entity_state_t *old, int bits)
|
|||
}
|
||||
|
||||
if (ent->serverframe != cl.frame.serverframe - 1)
|
||||
{
|
||||
// wasn't in last update, so initialize some things
|
||||
{ // wasn't in last update, so initialize some things
|
||||
ent->trailcount = 1024; // for diminishing rocket / grenade trails
|
||||
// duplicate the current state so lerping doesn't hurt anything
|
||||
ent->prev = *state;
|
||||
|
@ -657,7 +656,7 @@ void CL_ParseFrame (void)
|
|||
|
||||
cl.frame.serverframe = MSG_ReadLong (&net_message);
|
||||
cl.frame.deltaframe = MSG_ReadLong (&net_message);
|
||||
cl.frame.servertime = cl.frame.serverframe * 0.1;
|
||||
cl.frame.servertime = cl.frame.serverframe*100;
|
||||
|
||||
// BIG HACK to let old demos continue to work
|
||||
if (cls.serverProtocol != 26)
|
||||
|
@ -700,8 +699,8 @@ void CL_ParseFrame (void)
|
|||
// clamp time
|
||||
if (cl.time > cl.frame.servertime)
|
||||
cl.time = cl.frame.servertime;
|
||||
else if (cl.time < cl.frame.servertime - 0.1)
|
||||
cl.time = cl.frame.servertime - 0.1;
|
||||
else if (cl.time < cl.frame.servertime - 100)
|
||||
cl.time = cl.frame.servertime - 100;
|
||||
|
||||
// read areabits
|
||||
len = MSG_ReadByte (&net_message);
|
||||
|
@ -739,8 +738,9 @@ void CL_ParseFrame (void)
|
|||
cl.predicted_origin[1] = cl.frame.playerstate.pmove.origin[1]*0.125;
|
||||
cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2]*0.125;
|
||||
VectorCopy (cl.frame.playerstate.viewangles, cl.predicted_angles);
|
||||
if (cls.disable_servercount != cl.servercount && cl.refresh_prepped)
|
||||
SCR_EndLoadingPlaque (); // get rid of loading plaque
|
||||
if (cls.disable_servercount != cl.servercount
|
||||
&& cl.refresh_prepped)
|
||||
SCR_EndLoadingPlaque (); // get rid of loading plaque
|
||||
}
|
||||
cl.sound_prepped = true; // can start mixing ambient sounds
|
||||
|
||||
|
@ -829,7 +829,7 @@ void CL_AddPacketEntities (frame_t *frame)
|
|||
autorotate = anglemod(cl.time/10);
|
||||
|
||||
// brush models can auto animate their frames
|
||||
autoanim = 2 * cl.time;
|
||||
autoanim = 2*cl.time/1000;
|
||||
|
||||
memset (&ent, 0, sizeof(ent));
|
||||
|
||||
|
@ -850,7 +850,7 @@ void CL_AddPacketEntities (frame_t *frame)
|
|||
else if (effects & EF_ANIM_ALL)
|
||||
ent.frame = autoanim;
|
||||
else if (effects & EF_ANIM_ALLFAST)
|
||||
ent.frame = cl.time * 0.1;
|
||||
ent.frame = cl.time / 100;
|
||||
else
|
||||
ent.frame = s1->frame;
|
||||
|
||||
|
@ -974,7 +974,7 @@ void CL_AddPacketEntities (frame_t *frame)
|
|||
vec3_t forward;
|
||||
vec3_t start;
|
||||
|
||||
AngleVectorsRight(ent.angles, forward, NULL, NULL);
|
||||
AngleVectors (ent.angles, forward, NULL, NULL);
|
||||
VectorMA (ent.origin, 64, forward, start);
|
||||
V_AddLight (start, 100, 1, 0, 0);
|
||||
}
|
||||
|
@ -1231,7 +1231,8 @@ void CL_CalcViewValues (void)
|
|||
|
||||
// smooth out stair climbing
|
||||
delta = cls.realtime - cl.predicted_step_time;
|
||||
if (delta < 0.1) cl.refdef.vieworg[2] -= cl.predicted_step * (0.1 - delta) * 100;
|
||||
if (delta < 100)
|
||||
cl.refdef.vieworg[2] -= cl.predicted_step * (100 - delta) * 0.01;
|
||||
}
|
||||
else
|
||||
{ // just use interpolated values
|
||||
|
@ -1256,7 +1257,7 @@ void CL_CalcViewValues (void)
|
|||
for (i=0 ; i<3 ; i++)
|
||||
cl.refdef.viewangles[i] += LerpAngle (ops->kick_angles[i], ps->kick_angles[i], lerp);
|
||||
|
||||
AngleVectorsRight(cl.refdef.viewangles, cl.v_forward, cl.v_right, cl.v_up);
|
||||
AngleVectors (cl.refdef.viewangles, cl.v_forward, cl.v_right, cl.v_up);
|
||||
|
||||
// interpolate field of view
|
||||
cl.refdef.fov_x = ops->fov + lerp * (ps->fov - ops->fov);
|
||||
|
@ -1288,14 +1289,15 @@ void CL_AddEntities (void)
|
|||
cl.time = cl.frame.servertime;
|
||||
cl.lerpfrac = 1.0;
|
||||
}
|
||||
else if (cl.time < cl.frame.servertime - 0.1)
|
||||
else if (cl.time < cl.frame.servertime - 100)
|
||||
{
|
||||
if (cl_showclamp->value)
|
||||
Msg ("low clamp %i\n", cl.frame.servertime - 0.1 - cl.time);
|
||||
cl.time = cl.frame.servertime - 0.1;
|
||||
Msg ("low clamp %i\n", cl.frame.servertime-100 - cl.time);
|
||||
cl.time = cl.frame.servertime - 100;
|
||||
cl.lerpfrac = 0;
|
||||
}
|
||||
else cl.lerpfrac = 1.0 - (cl.frame.servertime - cl.time) * 100;
|
||||
else
|
||||
cl.lerpfrac = 1.0 - (cl.frame.servertime - cl.time) * 0.01;
|
||||
|
||||
if (cl_timedemo->value)
|
||||
cl.lerpfrac = 1.0;
|
||||
|
|
|
@ -69,7 +69,7 @@ void CL_RunLightStyles (void)
|
|||
int i;
|
||||
clightstyle_t *ls;
|
||||
|
||||
ofs = cl.time * 0.1;
|
||||
ofs = cl.time / 100;
|
||||
if (ofs == lastofs)
|
||||
return;
|
||||
lastofs = ofs;
|
||||
|
@ -257,7 +257,7 @@ void CL_ParseMuzzleFlash (void)
|
|||
|
||||
dl = CL_AllocDlight (i);
|
||||
VectorCopy (pl->current.origin, dl->origin);
|
||||
AngleVectorsRight(pl->current.angles, fv, rv, NULL);
|
||||
AngleVectors (pl->current.angles, fv, rv, NULL);
|
||||
VectorMA (dl->origin, 18, fv, dl->origin);
|
||||
VectorMA (dl->origin, 16, rv, dl->origin);
|
||||
if (silenced)
|
||||
|
@ -398,7 +398,7 @@ void CL_ParseMuzzleFlash2 (void)
|
|||
flash_number = MSG_ReadByte (&net_message);
|
||||
|
||||
// locate the origin
|
||||
AngleVectorsRight(cl_entities[ent].current.angles, forward, right, NULL);
|
||||
AngleVectors (cl_entities[ent].current.angles, forward, right, NULL);
|
||||
origin[0] = cl_entities[ent].current.origin[0] + forward[0] + right[0];
|
||||
origin[1] = cl_entities[ent].current.origin[1] + forward[1] + right[1];
|
||||
origin[2] = cl_entities[ent].current.origin[2] + forward[2] + right[2];
|
||||
|
@ -1607,7 +1607,7 @@ void CL_FlyParticles (vec3_t origin, int count)
|
|||
}
|
||||
|
||||
|
||||
ltime = cl.time;
|
||||
ltime = (float)cl.time / 1000.0;
|
||||
for (i=0 ; i<count ; i+=2)
|
||||
{
|
||||
angle = ltime * avelocities[i][0];
|
||||
|
@ -1706,7 +1706,7 @@ void CL_BfgParticles (entity_t *ent)
|
|||
}
|
||||
|
||||
|
||||
ltime = cl.time;
|
||||
ltime = (float)cl.time / 1000.0;
|
||||
for (i=0 ; i<NUMVERTEXNORMALS ; i++)
|
||||
{
|
||||
angle = ltime * avelocities[i][0];
|
||||
|
|
|
@ -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;
|
||||
|
||||
uint frame_msec;
|
||||
uint old_sys_frame_time;
|
||||
extern unsigned sys_frame_time;
|
||||
unsigned frame_msec;
|
||||
unsigned old_sys_frame_time;
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
@ -93,7 +94,7 @@ void KeyDown (kbutton_t *b)
|
|||
c = Cmd_Argv(2);
|
||||
b->downtime = atoi(c);
|
||||
if (!b->downtime)
|
||||
b->downtime = host.cl_timer - 100;
|
||||
b->downtime = sys_frame_time - 100;
|
||||
|
||||
b->state |= 1 + 2; // down + impulse down
|
||||
}
|
||||
|
@ -193,8 +194,8 @@ float CL_KeyState (kbutton_t *key)
|
|||
|
||||
if (key->state)
|
||||
{ // still down
|
||||
msec += host.cl_timer - key->downtime;
|
||||
key->downtime = host.cl_timer;
|
||||
msec += sys_frame_time - key->downtime;
|
||||
key->downtime = sys_frame_time;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -205,8 +206,10 @@ float CL_KeyState (kbutton_t *key)
|
|||
#endif
|
||||
|
||||
val = (float)msec / frame_msec;
|
||||
if (val < 0) val = 0;
|
||||
if (val > 1) val = 1;
|
||||
if (val < 0)
|
||||
val = 0;
|
||||
if (val > 1)
|
||||
val = 1;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
@ -295,7 +298,9 @@ void CL_BaseMove (usercmd_t *cmd)
|
|||
cmd->forwardmove -= cl_forwardspeed->value * CL_KeyState (&in_back);
|
||||
}
|
||||
|
||||
// adjust for speed key / running
|
||||
//
|
||||
// adjust for speed key / running
|
||||
//
|
||||
if ( (in_speed.state & 1) ^ (int)(cl_run->value) )
|
||||
{
|
||||
cmd->forwardmove *= 2;
|
||||
|
@ -333,27 +338,34 @@ void CL_FinishMove (usercmd_t *cmd)
|
|||
int ms;
|
||||
int i;
|
||||
|
||||
// figure button bits
|
||||
if ( in_attack.state & 3 ) cmd->buttons |= BUTTON_ATTACK;
|
||||
//
|
||||
// figure button bits
|
||||
//
|
||||
if ( in_attack.state & 3 )
|
||||
cmd->buttons |= BUTTON_ATTACK;
|
||||
in_attack.state &= ~2;
|
||||
|
||||
if (in_use.state & 3) cmd->buttons |= BUTTON_USE;
|
||||
if (in_use.state & 3)
|
||||
cmd->buttons |= BUTTON_USE;
|
||||
in_use.state &= ~2;
|
||||
|
||||
if (anykeydown && cls.key_dest == key_game) cmd->buttons |= BUTTON_ANY;
|
||||
if (anykeydown && cls.key_dest == key_game)
|
||||
cmd->buttons |= BUTTON_ANY;
|
||||
|
||||
// send milliseconds of time to apply the move
|
||||
ms = cls.frametime * 1000;
|
||||
if (ms > 250) ms = 100; // time was unreasonable
|
||||
if (ms > 250)
|
||||
ms = 100; // time was unreasonable
|
||||
cmd->msec = ms;
|
||||
|
||||
CL_ClampPitch ();
|
||||
for (i = 0; i < 3; i++) cmd->angles[i] = ANGLE2SHORT(cl.viewangles[i]);
|
||||
for (i=0 ; i<3 ; i++)
|
||||
cmd->angles[i] = ANGLE2SHORT(cl.viewangles[i]);
|
||||
|
||||
cmd->impulse = in_impulse;
|
||||
in_impulse = 0;
|
||||
|
||||
// send the ambient light level at the player's current position
|
||||
// send the ambient light level at the player's current position
|
||||
cmd->lightlevel = (byte)cl_lightlevel->value;
|
||||
}
|
||||
|
||||
|
@ -366,8 +378,11 @@ usercmd_t CL_CreateCmd (void)
|
|||
{
|
||||
usercmd_t cmd;
|
||||
|
||||
frame_msec = host.cl_timer - old_sys_frame_time;
|
||||
frame_msec = bound(1, frame_msec, 200);
|
||||
frame_msec = sys_frame_time - old_sys_frame_time;
|
||||
if (frame_msec < 1)
|
||||
frame_msec = 1;
|
||||
if (frame_msec > 200)
|
||||
frame_msec = 200;
|
||||
|
||||
// get basic movement from keyboard
|
||||
CL_BaseMove (&cmd);
|
||||
|
@ -377,9 +392,9 @@ usercmd_t CL_CreateCmd (void)
|
|||
|
||||
CL_FinishMove (&cmd);
|
||||
|
||||
old_sys_frame_time = host.cl_timer;
|
||||
old_sys_frame_time = sys_frame_time;
|
||||
|
||||
//cmd.impulse = cls.framecount;
|
||||
//cmd.impulse = cls.framecount;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
@ -468,7 +483,7 @@ void CL_SendCmd (void)
|
|||
|
||||
if ( cls.state == ca_connected)
|
||||
{
|
||||
if (cls.netchan.message.cursize || host.realtime - cls.netchan.last_sent > 1.0f )
|
||||
if (cls.netchan.message.cursize || curtime - cls.netchan.last_sent > 1000 )
|
||||
Netchan_Transmit (&cls.netchan, 0, buf.data);
|
||||
return;
|
||||
}
|
||||
|
@ -483,7 +498,7 @@ void CL_SendCmd (void)
|
|||
}
|
||||
|
||||
if (cmd->buttons && cl.cinematictime > 0 && !cl.attractloop
|
||||
&& cls.realtime - cl.cinematictime > 1.0f)
|
||||
&& cls.realtime - cl.cinematictime > 1000)
|
||||
{ // skip the rest of the cinematic
|
||||
SCR_FinishCinematic ();
|
||||
}
|
||||
|
|
|
@ -364,7 +364,7 @@ CL_Pause_f
|
|||
void CL_Pause_f (void)
|
||||
{
|
||||
// never pause in multiplayer
|
||||
if (host.maxclients > 1 || !Com_ServerState ())
|
||||
if (Cvar_VariableValue ("maxclients") > 1 || !Com_ServerState ())
|
||||
{
|
||||
Cvar_SetValue ("paused", 0);
|
||||
return;
|
||||
|
@ -462,7 +462,7 @@ void CL_CheckForResend (void)
|
|||
if (cls.state != ca_connecting)
|
||||
return;
|
||||
|
||||
if (cls.realtime - cls.connect_time < 3.0f)
|
||||
if (cls.realtime - cls.connect_time < 3000)
|
||||
return;
|
||||
|
||||
if (!NET_StringToAdr (cls.servername, &adr))
|
||||
|
@ -616,6 +616,16 @@ void CL_Disconnect (void)
|
|||
if (cls.state == ca_disconnected)
|
||||
return;
|
||||
|
||||
if (cl_timedemo && cl_timedemo->value)
|
||||
{
|
||||
int time;
|
||||
|
||||
time = Sys_Milliseconds () - cl.timedemo_start;
|
||||
if (time > 0)
|
||||
Msg ("%i frames, %3.1f seconds: %3.1f fps\n", cl.timedemo_frames,
|
||||
time/1000.0, cl.timedemo_frames*1000.0 / time);
|
||||
}
|
||||
|
||||
VectorClear (cl.refdef.blend);
|
||||
re->CinematicSetPalette(NULL);
|
||||
|
||||
|
@ -717,7 +727,8 @@ void CL_Changing_f (void)
|
|||
{
|
||||
//ZOID
|
||||
//if we are downloading, we don't change! This so we don't suddenly stop downloading a map
|
||||
if (cls.download) return;
|
||||
if (cls.download)
|
||||
return;
|
||||
|
||||
SCR_BeginLoadingPlaque ();
|
||||
cls.state = ca_connected; // not active anymore, but not disconnected
|
||||
|
@ -751,7 +762,7 @@ void CL_Reconnect_f (void)
|
|||
if (*cls.servername) {
|
||||
if (cls.state >= ca_connected) {
|
||||
CL_Disconnect();
|
||||
cls.connect_time = cls.realtime - 1.5f;
|
||||
cls.connect_time = cls.realtime - 1500;
|
||||
} else
|
||||
cls.connect_time = -99999; // fire immediately
|
||||
|
||||
|
@ -1010,7 +1021,8 @@ void CL_ReadPackets (void)
|
|||
//
|
||||
// check timeout
|
||||
//
|
||||
if (cls.state >= ca_connected && cls.realtime - cls.netchan.last_received > cl_timeout->value)
|
||||
if (cls.state >= ca_connected
|
||||
&& cls.realtime - cls.netchan.last_received > cl_timeout->value*1000)
|
||||
{
|
||||
if (++cl.timeoutcount > 5) // timeoutcount saves debugger
|
||||
{
|
||||
|
@ -1401,8 +1413,7 @@ CL_InitLocal
|
|||
void CL_InitLocal (void)
|
||||
{
|
||||
cls.state = ca_disconnected;
|
||||
cls.realtime = Sys_DoubleTime();
|
||||
|
||||
cls.realtime = Sys_Milliseconds ();
|
||||
CL_InitInput ();
|
||||
|
||||
adr0 = Cvar_Get( "adr0", "", CVAR_ARCHIVE );
|
||||
|
@ -1415,9 +1426,9 @@ void CL_InitLocal (void)
|
|||
adr7 = Cvar_Get( "adr7", "", CVAR_ARCHIVE );
|
||||
adr8 = Cvar_Get( "adr8", "", CVAR_ARCHIVE );
|
||||
|
||||
//
|
||||
// register our variables
|
||||
//
|
||||
//
|
||||
// register our variables
|
||||
//
|
||||
cl_stereo_separation = Cvar_Get( "cl_stereo_separation", "0.4", CVAR_ARCHIVE );
|
||||
cl_stereo = Cvar_Get( "cl_stereo", "0", 0 );
|
||||
|
||||
|
@ -1606,8 +1617,9 @@ void CL_FixCvarCheats (void)
|
|||
int i;
|
||||
cheatvar_t *var;
|
||||
|
||||
if(!strcmp(cl.configstrings[CS_MAXCLIENTS], "1") || !cl.configstrings[CS_MAXCLIENTS][0] )
|
||||
return; // single player can cheat
|
||||
if ( !strcmp(cl.configstrings[CS_MAXCLIENTS], "1")
|
||||
|| !cl.configstrings[CS_MAXCLIENTS][0] )
|
||||
return; // single player can cheat
|
||||
|
||||
// find all the cvars if we haven't done it yet
|
||||
if (!numcheatvars)
|
||||
|
@ -1666,36 +1678,44 @@ CL_Frame
|
|||
|
||||
==================
|
||||
*/
|
||||
void CL_Frame (float time)
|
||||
void CL_Frame (int msec)
|
||||
{
|
||||
static float extratime;
|
||||
static float lasttimecalled;
|
||||
static int extratime;
|
||||
static int lasttimecalled;
|
||||
|
||||
if (host.type == HOST_DEDICATED) return;
|
||||
if (dedicated->value)
|
||||
return;
|
||||
|
||||
extratime += time;
|
||||
extratime += msec;
|
||||
|
||||
if (!cl_timedemo->value)
|
||||
{
|
||||
if (cls.state == ca_connected && extratime < 0.1f)
|
||||
return; // don't flood packets out while connecting
|
||||
if (extratime < 1.0f / cl_maxfps->value)
|
||||
return; // framerate is too high
|
||||
if (cls.state == ca_connected && extratime < 100)
|
||||
return; // don't flood packets out while connecting
|
||||
if (extratime < 1000/cl_maxfps->value)
|
||||
return; // framerate is too high
|
||||
}
|
||||
|
||||
// let the mouse activate or deactivate
|
||||
IN_Frame ();
|
||||
|
||||
// decide the simulation time
|
||||
cls.frametime = extratime;
|
||||
cls.frametime = extratime/1000.0;
|
||||
cl.time += extratime;
|
||||
cls.realtime = Sys_DoubleTime();
|
||||
cls.realtime = curtime;
|
||||
|
||||
extratime = 0;
|
||||
if (cls.frametime > (1.0 / 5)) cls.frametime = (1.0 / 5);
|
||||
#if 0
|
||||
if (cls.frametime > (1.0 / cl_minfps->value))
|
||||
cls.frametime = (1.0 / cl_minfps->value);
|
||||
#else
|
||||
if (cls.frametime > (1.0 / 5))
|
||||
cls.frametime = (1.0 / 5);
|
||||
#endif
|
||||
|
||||
// if in the debugger last frame, don't timeout
|
||||
if (time > 1.0f) cls.netchan.last_received = Sys_DoubleTime();
|
||||
if (msec > 5000)
|
||||
cls.netchan.last_received = Sys_Milliseconds ();
|
||||
|
||||
// fetch results from server
|
||||
CL_ReadPackets ();
|
||||
|
@ -1712,7 +1732,11 @@ void CL_Frame (float time)
|
|||
CL_PrepRefresh ();
|
||||
|
||||
// update the screen
|
||||
if (host_speeds->value)
|
||||
time_before_ref = Sys_Milliseconds ();
|
||||
SCR_UpdateScreen ();
|
||||
if (host_speeds->value)
|
||||
time_after_ref = Sys_Milliseconds ();
|
||||
|
||||
// update audio
|
||||
S_Update (cl.refdef.vieworg, cl.v_forward, cl.v_right, cl.v_up);
|
||||
|
@ -1724,6 +1748,27 @@ void CL_Frame (float time)
|
|||
SCR_RunConsole ();
|
||||
|
||||
cls.framecount++;
|
||||
|
||||
if ( log_stats->value )
|
||||
{
|
||||
if ( cls.state == ca_active )
|
||||
{
|
||||
if ( !lasttimecalled )
|
||||
{
|
||||
lasttimecalled = Sys_Milliseconds();
|
||||
if ( log_stats_file )
|
||||
FS_Printf( log_stats_file, "0\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
int now = Sys_Milliseconds();
|
||||
|
||||
if ( log_stats_file )
|
||||
FS_Printf( log_stats_file, "%d\n", now - lasttimecalled );
|
||||
lasttimecalled = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1736,8 +1781,8 @@ CL_Init
|
|||
*/
|
||||
void CL_Init (void)
|
||||
{
|
||||
// nothing running on the client
|
||||
if (host.type == HOST_DEDICATED) return;
|
||||
if (dedicated->value)
|
||||
return; // nothing running on the client
|
||||
|
||||
// all archived variables will now be loaded
|
||||
|
||||
|
@ -1754,7 +1799,6 @@ void CL_Init (void)
|
|||
SCR_Init ();
|
||||
cls.disable_screen = true; // don't draw yet
|
||||
|
||||
CL_InitGameProgs();
|
||||
CL_InitLocal ();
|
||||
IN_Init ();
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ void CL_Flashlight (int ent, vec3_t pos)
|
|||
VectorCopy (pos, dl->origin);
|
||||
dl->radius = 400;
|
||||
dl->minlight = 250;
|
||||
dl->die = cl.time + 0.1;
|
||||
dl->die = cl.time + 100;
|
||||
dl->color[0] = 1;
|
||||
dl->color[1] = 1;
|
||||
dl->color[2] = 1;
|
||||
|
@ -100,7 +100,7 @@ void CL_ColorFlash (vec3_t pos, int ent, int intensity, float r, float g, float
|
|||
VectorCopy (pos, dl->origin);
|
||||
dl->radius = intensity;
|
||||
dl->minlight = 250;
|
||||
dl->die = cl.time + 0.1;
|
||||
dl->die = cl.time + 100;
|
||||
dl->color[0] = r;
|
||||
dl->color[1] = g;
|
||||
dl->color[2] = b;
|
||||
|
@ -453,7 +453,7 @@ void CL_Heatbeam (vec3_t start, vec3_t end)
|
|||
VectorMA (move, -1, up, move);
|
||||
|
||||
VectorScale (vec, step, vec);
|
||||
ltime = cl.time;
|
||||
ltime = (float) cl.time/1000.0;
|
||||
|
||||
// for (i=0 ; i<len ; i++)
|
||||
for (i=0 ; i<len ; i+=step)
|
||||
|
@ -544,7 +544,7 @@ void CL_Heatbeam (vec3_t start, vec3_t forward)
|
|||
VectorMA (move, -0.5, up, move);
|
||||
|
||||
// otherwise assume SOFT
|
||||
ltime = cl.time;
|
||||
ltime = (float) cl.time/1000.0;
|
||||
start_pt = fmod(ltime*96.0,step);
|
||||
VectorMA (move, start_pt, vec, move);
|
||||
|
||||
|
@ -664,7 +664,7 @@ void CL_Heatbeam (vec3_t start, vec3_t end)
|
|||
}
|
||||
/*
|
||||
|
||||
ltime = cl.time;
|
||||
ltime = (float) cl.time/1000.0;
|
||||
start_pt = fmod(ltime*16.0,step);
|
||||
VectorMA (move, start_pt, vec, move);
|
||||
|
||||
|
@ -740,7 +740,7 @@ void CL_ParticleSteamEffect (vec3_t org, vec3_t dir, int color, int count, int m
|
|||
vec3_t r, u;
|
||||
|
||||
// vectoangles2 (dir, angle_dir);
|
||||
// AngleVectorsRight (angle_dir, f, r, u);
|
||||
// AngleVectors (angle_dir, f, r, u);
|
||||
|
||||
MakeNormalVectors (dir, r, u);
|
||||
|
||||
|
@ -797,7 +797,7 @@ void CL_TrackerTrail (vec3_t start, vec3_t end, int particleColor)
|
|||
|
||||
VectorCopy(vec, forward);
|
||||
vectoangles2 (forward, angle_dir);
|
||||
AngleVectorsRight (angle_dir, forward, right, up);
|
||||
AngleVectors (angle_dir, forward, right, up);
|
||||
|
||||
dec = 3;
|
||||
VectorScale (vec, 3, vec);
|
||||
|
|
|
@ -297,12 +297,13 @@ void CL_ParseServerData (void)
|
|||
int i;
|
||||
|
||||
MsgDev (D_INFO, "Serverdata packet received.\n");
|
||||
|
||||
// wipe the client_state_t struct
|
||||
//
|
||||
// wipe the client_state_t struct
|
||||
//
|
||||
CL_ClearState ();
|
||||
cls.state = ca_connected;
|
||||
|
||||
// parse protocol version number
|
||||
// parse protocol version number
|
||||
i = MSG_ReadLong (&net_message);
|
||||
cls.serverProtocol = i;
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
|
|||
if (trace.allsolid || trace.startsolid ||
|
||||
trace.fraction < tr->fraction)
|
||||
{
|
||||
trace.ent = (prvm_edict_t *)ent;
|
||||
trace.ent = (struct edict_s *)ent;
|
||||
if (tr->startsolid)
|
||||
{
|
||||
*tr = trace;
|
||||
|
@ -145,14 +145,14 @@ void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
|
|||
CL_PMTrace
|
||||
================
|
||||
*/
|
||||
trace_t CL_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
|
||||
trace_t CL_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
|
||||
{
|
||||
trace_t t;
|
||||
|
||||
// check against world
|
||||
t = CM_BoxTrace (start, end, mins, maxs, 0, MASK_PLAYERSOLID);
|
||||
if (t.fraction < 1.0)
|
||||
t.ent = (prvm_edict_t *)1;
|
||||
t.ent = (struct edict_s *)1;
|
||||
|
||||
// check all other solid models
|
||||
CL_ClipMoveToEntities (start, mins, maxs, end, &t);
|
||||
|
@ -214,9 +214,8 @@ void CL_PredictMovement (void)
|
|||
return;
|
||||
|
||||
if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
|
||||
{
|
||||
// just set angles
|
||||
for (i = 0; i < 3; i++)
|
||||
{ // just set angles
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
cl.predicted_angles[i] = cl.viewangles[i] + SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[i]);
|
||||
}
|
||||
|
|
|
@ -439,7 +439,8 @@ SCR_DrawNet
|
|||
*/
|
||||
void SCR_DrawNet (void)
|
||||
{
|
||||
if (cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged < CMD_BACKUP-1)
|
||||
if (cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged
|
||||
< CMD_BACKUP-1)
|
||||
return;
|
||||
|
||||
re->DrawPic (scr_vrect.x+64, scr_vrect.y, "net");
|
||||
|
@ -504,7 +505,7 @@ Scroll it up or down
|
|||
*/
|
||||
void SCR_RunConsole (void)
|
||||
{
|
||||
// decide on the height of the console
|
||||
// decide on the height of the console
|
||||
if (cls.key_dest == key_console)
|
||||
scr_conlines = 0.5; // half screen
|
||||
else
|
||||
|
@ -512,14 +513,14 @@ void SCR_RunConsole (void)
|
|||
|
||||
if (scr_conlines < scr_con_current)
|
||||
{
|
||||
scr_con_current -= scr_conspeed->value * cls.frametime * 1000;
|
||||
scr_con_current -= scr_conspeed->value*cls.frametime;
|
||||
if (scr_conlines > scr_con_current)
|
||||
scr_con_current = scr_conlines;
|
||||
|
||||
}
|
||||
else if (scr_conlines > scr_con_current)
|
||||
{
|
||||
scr_con_current += scr_conspeed->value * cls.frametime * 1000;
|
||||
scr_con_current += scr_conspeed->value*cls.frametime;
|
||||
if (scr_conlines < scr_con_current)
|
||||
scr_con_current = scr_conlines;
|
||||
}
|
||||
|
@ -569,19 +570,20 @@ SCR_BeginLoadingPlaque
|
|||
void SCR_BeginLoadingPlaque (void)
|
||||
{
|
||||
S_StopAllSounds ();
|
||||
cl.sound_prepped = false; // don't play ambients
|
||||
cl.sound_prepped = false; // don't play ambients
|
||||
if (cls.disable_screen) return;
|
||||
if (host.developer) return;
|
||||
|
||||
if (cls.state == ca_disconnected) return; // if at console, don't bring up the plaque
|
||||
if (developer->value)
|
||||
return;
|
||||
if (cls.state == ca_disconnected)
|
||||
return; // if at console, don't bring up the plaque
|
||||
if (cls.key_dest == key_console)
|
||||
return;
|
||||
if (cl.cinematictime > 0)
|
||||
scr_draw_loading = 2; // clear to black first
|
||||
else scr_draw_loading = 1;
|
||||
SCR_UpdateScreen();
|
||||
|
||||
cls.disable_screen = cls.realtime;
|
||||
scr_draw_loading = 2; // clear to black first
|
||||
else
|
||||
scr_draw_loading = 1;
|
||||
SCR_UpdateScreen ();
|
||||
cls.disable_screen = Sys_Milliseconds ();
|
||||
cls.disable_servercount = cl.servercount;
|
||||
}
|
||||
|
||||
|
@ -629,19 +631,18 @@ int entitycmpfnc( const entity_t *a, const entity_t *b )
|
|||
void SCR_TimeRefresh_f (void)
|
||||
{
|
||||
int i;
|
||||
float start, stop;
|
||||
float time;
|
||||
int start, stop;
|
||||
float time;
|
||||
|
||||
if ( cls.state != ca_active )
|
||||
return;
|
||||
|
||||
start = Sys_DoubleTime();
|
||||
start = Sys_Milliseconds ();
|
||||
|
||||
if (Cmd_Argc() == 2)
|
||||
{
|
||||
// run without page flipping
|
||||
{ // run without page flipping
|
||||
re->BeginFrame( 0 );
|
||||
for (i = 0; i < 128; i++)
|
||||
for (i=0 ; i<128 ; i++)
|
||||
{
|
||||
cl.refdef.viewangles[1] = i/128.0*360.0;
|
||||
re->RenderFrame (&cl.refdef);
|
||||
|
@ -660,8 +661,8 @@ void SCR_TimeRefresh_f (void)
|
|||
}
|
||||
}
|
||||
|
||||
stop = Sys_DoubleTime();
|
||||
time = (stop-start);
|
||||
stop = Sys_Milliseconds ();
|
||||
time = (stop-start)/1000.0;
|
||||
Msg ("%f seconds (%f fps)\n", time, 128/time);
|
||||
}
|
||||
|
||||
|
@ -1267,7 +1268,7 @@ void SCR_UpdateScreen (void)
|
|||
// do nothing at all
|
||||
if (cls.disable_screen)
|
||||
{
|
||||
if (cls.realtime - cls.disable_screen > 120.0f)
|
||||
if (Sys_Milliseconds() - cls.disable_screen > 120000)
|
||||
{
|
||||
cls.disable_screen = 0;
|
||||
Msg ("Loading plaque timed out.\n");
|
||||
|
|
|
@ -360,10 +360,16 @@ float CalcFov (float fov_x, float width, float height)
|
|||
float a;
|
||||
float x;
|
||||
|
||||
fov_x = bound(1, fov_x, 180);
|
||||
x = width / tan(fov_x / 360 * M_PI);
|
||||
a = atan (height / x);
|
||||
a = a * 360/M_PI;
|
||||
if (fov_x < 1 || fov_x > 179)
|
||||
{
|
||||
Com_Error (ERR_DROP, "Bad fov: %f", fov_x);
|
||||
}
|
||||
|
||||
x = width/tan(fov_x/360*M_PI);
|
||||
|
||||
a = atan (height/x);
|
||||
|
||||
a = a*360/M_PI;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
@ -439,6 +445,13 @@ void V_RenderView( float stereo_separation )
|
|||
if (!cl.refresh_prepped)
|
||||
return; // still loading
|
||||
|
||||
if (cl_timedemo->value)
|
||||
{
|
||||
if (!cl.timedemo_start)
|
||||
cl.timedemo_start = Sys_DoubleTime();
|
||||
cl.timedemo_frames++;
|
||||
}
|
||||
|
||||
// an invalid frame will just use the exact previous refdef
|
||||
// we can't use the old frame if the video mode has changed, though...
|
||||
if ( cl.frame.valid && (cl.force_refdef || !cl_paused->value) )
|
||||
|
@ -487,7 +500,7 @@ void V_RenderView( float stereo_separation )
|
|||
cl.refdef.width = scr_vrect.width;
|
||||
cl.refdef.height = scr_vrect.height;
|
||||
cl.refdef.fov_y = CalcFov (cl.refdef.fov_x, cl.refdef.width, cl.refdef.height);
|
||||
cl.refdef.time = cl.time;
|
||||
cl.refdef.time = (cl.time * 0.001); // render use realtime now
|
||||
|
||||
cl.refdef.areabits = cl.frame.areabits;
|
||||
|
||||
|
@ -520,6 +533,9 @@ void V_RenderView( float stereo_separation )
|
|||
re->RenderFrame (&cl.refdef);
|
||||
if (cl_stats->value)
|
||||
Msg ("ent:%i lt:%i part:%i\n", r_numentities, r_numdlights, r_numparticles);
|
||||
if ( log_stats->value && ( log_stats_file != 0 ) )
|
||||
FS_Printf( log_stats_file, "%i,%i,%i,",r_numentities, r_numdlights, r_numparticles);
|
||||
|
||||
|
||||
SCR_AddDirtyPoint (scr_vrect.x, scr_vrect.y);
|
||||
SCR_AddDirtyPoint (scr_vrect.x+scr_vrect.width-1,
|
||||
|
|
|
@ -34,27 +34,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
typedef struct
|
||||
{
|
||||
bool valid; // cleared if delta parsing was invalid
|
||||
int serverframe;
|
||||
float servertime; // server time the message is valid for (in msec)
|
||||
int deltaframe;
|
||||
byte areabits[MAX_MAP_AREAS/8]; // portalarea visibility bits
|
||||
int serverframe;
|
||||
int servertime; // server time the message is valid for (in msec)
|
||||
int deltaframe;
|
||||
byte areabits[MAX_MAP_AREAS/8]; // portalarea visibility bits
|
||||
player_state_t playerstate;
|
||||
int num_entities;
|
||||
int parse_entities; // non-masked index into cl_parse_entities array
|
||||
int num_entities;
|
||||
int parse_entities; // non-masked index into cl_parse_entities array
|
||||
} frame_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
entity_state_t baseline; // delta from this if not from a previous frame
|
||||
entity_state_t baseline; // delta from this if not from a previous frame
|
||||
entity_state_t current;
|
||||
entity_state_t prev; // will always be valid, but might just be a copy of current
|
||||
|
||||
int serverframe; // if not current, this ent isn't in the frame
|
||||
|
||||
int trailcount; // for diminishing grenade trails
|
||||
int trailcount; // for diminishing grenade trails
|
||||
vec3_t lerp_origin; // for trails (variable hz)
|
||||
|
||||
float fly_stoptime;
|
||||
int fly_stoptime;
|
||||
} centity_t;
|
||||
|
||||
#define MAX_CLIENTWEAPONMODELS 20 // PGM -- upped from 16 to fit the chainfist vwep
|
||||
|
@ -81,24 +81,24 @@ extern int num_cl_weaponmodels;
|
|||
//
|
||||
typedef struct
|
||||
{
|
||||
int timeoutcount;
|
||||
int timeoutcount;
|
||||
|
||||
int timedemo_frames;
|
||||
float timedemo_start;
|
||||
int timedemo_frames;
|
||||
int timedemo_start;
|
||||
|
||||
bool refresh_prepped; // false if on new level or new ref dll
|
||||
bool sound_prepped; // ambient sounds can start
|
||||
bool force_refdef; // vid has changed, so we can't use a paused refdef
|
||||
bool refresh_prepped; // false if on new level or new ref dll
|
||||
bool sound_prepped; // ambient sounds can start
|
||||
bool force_refdef; // vid has changed, so we can't use a paused refdef
|
||||
|
||||
int parse_entities; // index (not anded off) into cl_parse_entities[]
|
||||
int parse_entities; // index (not anded off) into cl_parse_entities[]
|
||||
|
||||
usercmd_t cmd;
|
||||
usercmd_t cmds[CMD_BACKUP]; // each mesage will send several old cmds
|
||||
int cmd_time[CMD_BACKUP]; // time sent, for calculating pings
|
||||
usercmd_t cmd;
|
||||
usercmd_t cmds[CMD_BACKUP]; // each mesage will send several old cmds
|
||||
int cmd_time[CMD_BACKUP]; // time sent, for calculating pings
|
||||
short predicted_origins[CMD_BACKUP][3]; // for debug comparing against server
|
||||
|
||||
float predicted_step; // for stair up smoothing
|
||||
float predicted_step_time;
|
||||
unsigned predicted_step_time;
|
||||
|
||||
vec3_t predicted_origin; // generated by CL_PredictMovement
|
||||
vec3_t predicted_angles;
|
||||
|
@ -115,11 +115,11 @@ typedef struct
|
|||
// and teleport direction changes
|
||||
vec3_t viewangles;
|
||||
|
||||
float time; // this is the time value that the client
|
||||
// is rendering at. always <= cls.realtime
|
||||
int time; // this is the time value that the client
|
||||
// is rendering at. always <= cls.realtime
|
||||
float lerpfrac; // between oldframe and frame
|
||||
|
||||
refdef_t refdef;
|
||||
refdef_t refdef;
|
||||
|
||||
vec3_t v_forward, v_right, v_up; // set when refdef.angles is set
|
||||
|
||||
|
@ -133,10 +133,10 @@ typedef struct
|
|||
// non-gameserver infornamtion
|
||||
// FIXME: move this cinematic stuff into the cin_t structure
|
||||
file_t *cinematic_file;
|
||||
float cinematictime; // cls.realtime for first cinematic frame
|
||||
int cinematicframe;
|
||||
int cinematictime; // cls.realtime for first cinematic frame
|
||||
int cinematicframe;
|
||||
char cinematicpalette[768];
|
||||
bool cinematicpalette_active;
|
||||
bool cinematicpalette_active;
|
||||
|
||||
//
|
||||
// server state information
|
||||
|
@ -196,11 +196,11 @@ typedef struct
|
|||
keydest_t key_dest;
|
||||
|
||||
int framecount;
|
||||
double realtime; // always increasing, no clamping, etc
|
||||
float frametime; // seconds since last frame
|
||||
int realtime; // always increasing, no clamping, etc
|
||||
float frametime; // seconds since last frame
|
||||
|
||||
// screen rendering information
|
||||
float disable_screen; // showing loading plaque between levels
|
||||
float disable_screen; // showing loading plaque between levels
|
||||
// or changing rendering dlls
|
||||
// if time gets > 30 seconds ahead, break it
|
||||
int disable_servercount; // when we receive a frame and cl.servercount
|
||||
|
@ -433,11 +433,6 @@ void CL_PingServers_f (void);
|
|||
void CL_Snd_Restart_f (void);
|
||||
void CL_RequestNextDownload (void);
|
||||
|
||||
//
|
||||
// cl_game
|
||||
//
|
||||
void CL_InitGameProgs (void);
|
||||
|
||||
//
|
||||
// cl_input
|
||||
//
|
||||
|
|
137
engine/common.h
137
engine/common.h
|
@ -59,17 +59,12 @@ typedef struct sizebuf_s
|
|||
int errorcount; // cause by errors
|
||||
} sizebuf_t;
|
||||
|
||||
void _SZ_Init (sizebuf_t *buf, byte *data, int length, const char *filename, int fileline);
|
||||
void _SZ_Write (sizebuf_t *buf, void *data, int length, const char *filename, int fileline);
|
||||
void *_SZ_GetSpace (sizebuf_t *buf, int length, const char *filename, int fileline);
|
||||
void _SZ_Print (sizebuf_t *buf, char *data, const char *filename, int fileline);
|
||||
void _SZ_Clear (sizebuf_t *buf, const char *filename, int fileline);
|
||||
void SZ_Init (sizebuf_t *buf, byte *data, int length);
|
||||
void SZ_Clear (sizebuf_t *buf);
|
||||
void *SZ_GetSpace (sizebuf_t *buf, int length);
|
||||
void SZ_Write (sizebuf_t *buf, void *data, int length);
|
||||
void SZ_Print (sizebuf_t *buf, char *data); // strcats onto the sizebuf
|
||||
|
||||
#define SZ_Init(buf, data, length) _SZ_Init( buf, data, length, __FILE__, __LINE__)
|
||||
#define SZ_Write(buf, data, length) _SZ_Write( buf, data, length, __FILE__, __LINE__)
|
||||
#define SZ_Print(buf, data ) _SZ_Print( buf, data, __FILE__, __LINE__)
|
||||
#define SZ_GetSpace(buf, length) _SZ_GetSpace( buf, length, __FILE__, __LINE__)
|
||||
#define SZ_Clear(buf) _SZ_Clear( buf, __FILE__, __LINE__)
|
||||
//============================================================================
|
||||
|
||||
struct usercmd_s;
|
||||
|
@ -92,26 +87,26 @@ void _MSG_WriteDeltaUsercmd (sizebuf_t *sb, struct usercmd_s *from, struct userc
|
|||
void _MSG_WriteDeltaEntity (struct entity_state_s *from, struct entity_state_s *to, sizebuf_t *msg, bool force, bool newentity, const char *filename, int fileline);
|
||||
void _MSG_WriteDir (sizebuf_t *sb, vec3_t vector, const char *filename, int fileline);
|
||||
void _MSG_WriteVector (sizebuf_t *sb, float *v, const char *filename, int fileline);
|
||||
void _MSG_Send (msgtype_t to, vec3_t origin, prvm_edict_t *ent, const char *filename, int fileline);
|
||||
void _MSG_Send (msgtype_t to, vec3_t origin, edict_t *ent, const char *filename, int fileline);
|
||||
|
||||
#define MSG_Begin( x ) _MSG_Begin( x, __FILE__, __LINE__)
|
||||
#define MSG_WriteChar(x,y) _MSG_WriteChar (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteByte(x,y) _MSG_WriteByte (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteShort(x,y) _MSG_WriteShort (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteWord(x,y) _MSG_WriteWord (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteLong(x,y) _MSG_WriteLong (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteFloat(x, y) _MSG_WriteFloat (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteString(x,y) _MSG_WriteString (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteCoord(x, y) _MSG_WriteCoord (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WritePos(x, y) _MSG_WritePos (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteAngle(x, y) _MSG_WriteAngle (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteAngle16(x, y) _MSG_WriteAngle16 (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteUnterminatedString(x, y) _MSG_WriteUnterminatedString (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteDeltaUsercmd(x, y, z) _MSG_WriteDeltaUsercmd (x, y, z, __FILE__, __LINE__)
|
||||
#define MSG_WriteDeltaEntity(x, y, z, t, m) _MSG_WriteDeltaEntity (x, y, z, t, m, __FILE__, __LINE__)
|
||||
#define MSG_WriteDir(x, y) _MSG_WriteDir (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteVector(x, y) _MSG_WriteVector (x, y, __FILE__, __LINE__)
|
||||
#define MSG_Send(x, y, z) _MSG_Send(x, y, z, __FILE__, __LINE__)
|
||||
#define MSG_Begin( x ) _MSG_Begin( x, __FILE__, __LINE__);
|
||||
#define MSG_WriteChar(x,y) _MSG_WriteChar (x, y, __FILE__, __LINE__);
|
||||
#define MSG_WriteByte(x,y) _MSG_WriteByte (x, y, __FILE__, __LINE__);
|
||||
#define MSG_WriteShort(x,y) _MSG_WriteShort (x, y, __FILE__, __LINE__);
|
||||
#define MSG_WriteWord(x,y) _MSG_WriteWord (x, y, __FILE__, __LINE__);
|
||||
#define MSG_WriteLong(x,y) _MSG_WriteLong (x, y, __FILE__, __LINE__);
|
||||
#define MSG_WriteFloat(x, y) _MSG_WriteFloat (x, y, __FILE__, __LINE__);
|
||||
#define MSG_WriteString(x,y) _MSG_WriteString (x, y, __FILE__, __LINE__);
|
||||
#define MSG_WriteCoord(x, y) _MSG_WriteCoord (x, y, __FILE__, __LINE__);
|
||||
#define MSG_WritePos(x, y) _MSG_WritePos (x, y, __FILE__, __LINE__);
|
||||
#define MSG_WriteAngle(x, y) _MSG_WriteAngle (x, y, __FILE__, __LINE__);
|
||||
#define MSG_WriteAngle16(x, y) _MSG_WriteAngle16 (x, y, __FILE__, __LINE__);
|
||||
#define MSG_WriteUnterminatedString(x, y) _MSG_WriteUnterminatedString (x, y, __FILE__, __LINE__);
|
||||
#define MSG_WriteDeltaUsercmd(x, y, z) _MSG_WriteDeltaUsercmd (x, y, z, __FILE__, __LINE__);
|
||||
#define MSG_WriteDeltaEntity(x, y, z, t, m) _MSG_WriteDeltaEntity (x, y, z, t, m, __FILE__, __LINE__);
|
||||
#define MSG_WriteDir(x, y) _MSG_WriteDir (x, y, __FILE__, __LINE__);
|
||||
#define MSG_WriteVector(x, y) _MSG_WriteVector (x, y, __FILE__, __LINE__);
|
||||
#define MSG_Send(x, y, z) _MSG_Send(x, y, z, __FILE__, __LINE__);
|
||||
|
||||
void MSG_BeginReading (sizebuf_t *sb);
|
||||
|
||||
|
@ -136,14 +131,15 @@ void MSG_ReadData (sizebuf_t *sb, void *buffer, int size);
|
|||
//============================================================================
|
||||
|
||||
|
||||
int COM_Argc (void);
|
||||
int COM_Argc (void);
|
||||
char *COM_Argv (int arg); // range and null checked
|
||||
void COM_ClearArgv (int arg);
|
||||
int COM_CheckParm (char *parm);
|
||||
|
||||
void COM_Init (void);
|
||||
void COM_InitArgv (int argc, char **argv);
|
||||
|
||||
char *CopyString (const char *in);
|
||||
char *CopyString (char *in);
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
@ -418,7 +414,7 @@ void Cmd_AddCommand (char *cmd_name, xcommand_t function);
|
|||
// as a clc_stringcmd instead of executed locally
|
||||
void Cmd_RemoveCommand (char *cmd_name);
|
||||
|
||||
bool Cmd_Exists (const char *cmd_name);
|
||||
bool Cmd_Exists (char *cmd_name);
|
||||
// used by the cvar code to check for cvar / command name overlap
|
||||
|
||||
char *Cmd_CompleteCommand (char *partial);
|
||||
|
@ -432,11 +428,11 @@ char *Cmd_Args (void);
|
|||
// functions. Cmd_Argv () will return an empty string, not a NULL
|
||||
// if arg > argc, so string operations are always safe.
|
||||
|
||||
void Cmd_TokenizeString (const char *text, bool macroExpand);
|
||||
void Cmd_TokenizeString (char *text, bool macroExpand);
|
||||
// Takes a null terminated string. Does not need to be /n terminated.
|
||||
// breaks the string up into arg tokens.
|
||||
|
||||
void Cmd_ExecuteString (const char *text);
|
||||
void Cmd_ExecuteString (char *text);
|
||||
// Parses a single line of text into arguments and tries to execute it
|
||||
// as if it was typed at the console
|
||||
|
||||
|
@ -461,32 +457,33 @@ NET
|
|||
#define PACKET_HEADER 10 // two ints and a short
|
||||
|
||||
typedef enum {NA_LOOPBACK, NA_BROADCAST, NA_IP, NA_IPX, NA_BROADCAST_IPX} netadrtype_t;
|
||||
|
||||
typedef enum {NS_CLIENT, NS_SERVER} netsrc_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
netadrtype_t type;
|
||||
|
||||
byte ip[4];
|
||||
byte ipx[10];
|
||||
byte ip[4];
|
||||
byte ipx[10];
|
||||
|
||||
word port;
|
||||
unsigned short port;
|
||||
} netadr_t;
|
||||
|
||||
void NET_Init (void);
|
||||
void NET_Shutdown (void);
|
||||
void NET_Init (void);
|
||||
void NET_Shutdown (void);
|
||||
|
||||
void NET_Config (bool multiplayer);
|
||||
void NET_Config (bool multiplayer);
|
||||
|
||||
bool NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message);
|
||||
void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to);
|
||||
void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to);
|
||||
|
||||
bool NET_CompareAdr (netadr_t a, netadr_t b);
|
||||
bool NET_CompareBaseAdr (netadr_t a, netadr_t b);
|
||||
bool NET_IsLocalAddress (netadr_t adr);
|
||||
char *NET_AdrToString (netadr_t a);
|
||||
char *NET_AdrToString (netadr_t a);
|
||||
bool NET_StringToAdr (char *s, netadr_t *a);
|
||||
void NET_Sleep(int msec);
|
||||
void NET_Sleep(int msec);
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
@ -503,12 +500,12 @@ typedef struct
|
|||
int dropped; // between last packet and previous
|
||||
|
||||
int last_received; // for timeouts
|
||||
int last_sent; // for retransmits
|
||||
int last_sent; // for retransmits
|
||||
|
||||
netadr_t remote_address;
|
||||
int qport; // qport value to write when transmitting
|
||||
|
||||
// sequencing variables
|
||||
// sequencing variables
|
||||
int incoming_sequence;
|
||||
int incoming_acknowledged;
|
||||
int incoming_reliable_acknowledged; // single bit
|
||||
|
@ -520,16 +517,16 @@ typedef struct
|
|||
int last_reliable_sequence; // sequence number of last send
|
||||
|
||||
// reliable staging and holding areas
|
||||
sizebuf_t message; // writing buffer to send to server
|
||||
byte message_buf[MAX_MSGLEN - 16]; // leave space for header
|
||||
sizebuf_t message; // writing buffer to send to server
|
||||
byte message_buf[MAX_MSGLEN-16]; // leave space for header
|
||||
|
||||
// message is copied to this buffer when it is first transfered
|
||||
int reliable_length;
|
||||
byte reliable_buf[MAX_MSGLEN - 16]; // unacked reliable message
|
||||
byte reliable_buf[MAX_MSGLEN-16]; // unacked reliable message
|
||||
} netchan_t;
|
||||
|
||||
extern netadr_t net_from;
|
||||
extern sizebuf_t net_message;
|
||||
extern netadr_t net_from;
|
||||
extern sizebuf_t net_message;
|
||||
extern byte net_message_buffer[MAX_MSGLEN];
|
||||
|
||||
|
||||
|
@ -627,25 +624,39 @@ MISC
|
|||
#define EXEC_INSERT 1 // insert at current position, but don't run yet
|
||||
#define EXEC_APPEND 2 // add to end of the command buffer
|
||||
|
||||
void Com_BeginRedirect (int target, char *buffer, int buffersize, void (*flush));
|
||||
void Com_EndRedirect (void);
|
||||
void Com_Printf (char *fmt, ...);
|
||||
void Com_DPrintf (int level, char *fmt, ...);
|
||||
void Com_DWarnf (char *fmt, ...);
|
||||
void Com_Error (int code, char *fmt, ...);
|
||||
void Com_Error_f ( void );
|
||||
void Com_Quit (void);
|
||||
#define PRINT_ALL 0
|
||||
#define PRINT_DEVELOPER 1 // only print when "developer 1"
|
||||
|
||||
int Com_ServerState (void); // this should have just been a cvar...
|
||||
void Com_SetServerState (int state);
|
||||
void Com_BeginRedirect (int target, char *buffer, int buffersize, void (*flush));
|
||||
void Com_EndRedirect (void);
|
||||
void Com_Printf (char *fmt, ...);
|
||||
void Com_DPrintf (int level, char *fmt, ...);
|
||||
void Com_DWarnf (char *fmt, ...);
|
||||
void Com_Error (int code, char *fmt, ...);
|
||||
void Com_Error_f ( void );
|
||||
void Com_Quit (void);
|
||||
|
||||
int Com_ServerState (void); // this should have just been a cvar...
|
||||
void Com_SetServerState (int state);
|
||||
|
||||
unsigned Com_BlockChecksum (void *buffer, int length);
|
||||
byte COM_BlockSequenceCRCByte (byte *base, int length, int sequence);
|
||||
byte COM_BlockSequenceCRCByte (byte *base, int length, int sequence);
|
||||
|
||||
float frand(void); // 0 to 1
|
||||
float crand(void); // -1 to 1
|
||||
|
||||
extern cvar_t *developer;
|
||||
extern cvar_t *dedicated;
|
||||
extern cvar_t *host_speeds;
|
||||
extern cvar_t *log_stats;
|
||||
|
||||
extern file_t *log_stats_file;
|
||||
|
||||
// host_speeds times
|
||||
extern int time_before_game;
|
||||
extern int time_after_game;
|
||||
extern int time_before_ref;
|
||||
extern int time_after_ref;
|
||||
|
||||
#define NUMVERTEXNORMALS 162
|
||||
extern vec3_t bytedirs[NUMVERTEXNORMALS];
|
||||
|
@ -686,12 +697,12 @@ CLIENT / SERVER SYSTEMS
|
|||
void CL_Init (void);
|
||||
void CL_Drop (void);
|
||||
void CL_Shutdown (void);
|
||||
void CL_Frame (float time);
|
||||
void CL_Frame (int msec);
|
||||
void Con_Print (char *text);
|
||||
void SCR_BeginLoadingPlaque (void);
|
||||
|
||||
void SV_Init (void);
|
||||
void SV_Shutdown (char *finalmsg, bool reconnect);
|
||||
void SV_Frame (float time);
|
||||
void SV_Frame (int msec);
|
||||
|
||||
#endif//COMMON_H
|
|
@ -234,7 +234,7 @@ void Cbuf_Execute (void)
|
|||
memmove (text, text+i, cmd_text.cursize);
|
||||
}
|
||||
|
||||
// execute the command line
|
||||
// execute the command line
|
||||
Cmd_ExecuteString (line);
|
||||
|
||||
if (cmd_wait)
|
||||
|
@ -301,7 +301,7 @@ bool Cbuf_AddLateCommands (void)
|
|||
int argc;
|
||||
bool ret;
|
||||
|
||||
// build the combined string to parse from
|
||||
// build the combined string to parse from
|
||||
s = 0;
|
||||
argc = COM_Argc();
|
||||
for (i=1 ; i<argc ; i++)
|
||||
|
@ -320,7 +320,7 @@ bool Cbuf_AddLateCommands (void)
|
|||
strcat (text, " ");
|
||||
}
|
||||
|
||||
// pull out the commands
|
||||
// pull out the commands
|
||||
build = Z_Malloc (s+1);
|
||||
build[0] = 0;
|
||||
|
||||
|
@ -344,7 +344,8 @@ bool Cbuf_AddLateCommands (void)
|
|||
}
|
||||
|
||||
ret = (build[0] != 0);
|
||||
if (ret) Cbuf_AddText (build);
|
||||
if (ret)
|
||||
Cbuf_AddText (build);
|
||||
|
||||
Z_Free (text);
|
||||
Z_Free (build);
|
||||
|
@ -537,7 +538,7 @@ char *Cmd_Args (void)
|
|||
Cmd_MacroExpandString
|
||||
======================
|
||||
*/
|
||||
char *Cmd_MacroExpandString (const char *text)
|
||||
char *Cmd_MacroExpandString (char *text)
|
||||
{
|
||||
int i, j, count, len;
|
||||
bool inquote;
|
||||
|
@ -547,7 +548,7 @@ char *Cmd_MacroExpandString (const char *text)
|
|||
char *token, *start;
|
||||
|
||||
inquote = false;
|
||||
scan = (char *)text;
|
||||
scan = text;
|
||||
|
||||
len = strlen (scan);
|
||||
if (len >= MAX_STRING_CHARS)
|
||||
|
@ -612,10 +613,10 @@ Parses the given string into command line tokens.
|
|||
$Cvars will be expanded unless they are in a quoted token
|
||||
============
|
||||
*/
|
||||
void Cmd_TokenizeString (const char *text, bool macroExpand)
|
||||
void Cmd_TokenizeString (char *text, bool macroExpand)
|
||||
{
|
||||
int i;
|
||||
char *token;
|
||||
char *token;
|
||||
|
||||
// clear the args from the last string
|
||||
for (i = 0; i < cmd_argc; i++) Z_Free (cmd_argv[i]);
|
||||
|
@ -740,15 +741,16 @@ void Cmd_RemoveCommand (char *cmd_name)
|
|||
Cmd_Exists
|
||||
============
|
||||
*/
|
||||
bool Cmd_Exists (const char *cmd_name)
|
||||
bool Cmd_Exists (char *cmd_name)
|
||||
{
|
||||
cmd_function_t *cmd;
|
||||
|
||||
for (cmd = cmd_functions; cmd; cmd = cmd->next)
|
||||
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
|
||||
{
|
||||
if (!strcmp (cmd_name,cmd->name))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -798,7 +800,7 @@ A complete command line has been parsed, so try to execute it
|
|||
FIXME: lookupnoadd the token to speed search?
|
||||
============
|
||||
*/
|
||||
void Cmd_ExecuteString (const char *text)
|
||||
void Cmd_ExecuteString (char *text)
|
||||
{
|
||||
cmd_function_t *cmd;
|
||||
cmdalias_t *a;
|
||||
|
|
|
@ -36,19 +36,19 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
int contents;
|
||||
int cluster;
|
||||
int area;
|
||||
word firstleafbrush;
|
||||
word numleafbrushes;
|
||||
int contents;
|
||||
int cluster;
|
||||
int area;
|
||||
unsigned short firstleafbrush;
|
||||
unsigned short numleafbrushes;
|
||||
} cleaf_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int contents;
|
||||
int numsides;
|
||||
int firstbrushside;
|
||||
int checkcount; // to avoid repeated testings
|
||||
int contents;
|
||||
int numsides;
|
||||
int firstbrushside;
|
||||
int checkcount; // to avoid repeated testings
|
||||
} cbrush_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -926,7 +926,7 @@ Handles offseting and rotation of the end points for moving and
|
|||
rotating entities
|
||||
==================
|
||||
*/
|
||||
int CM_TransformedPointContents (vec3_t p, int headnode, vec3_t origin, vec3_t angles)
|
||||
int CM_TransformedPointContents (vec3_t p, int headnode, vec3_t origin, vec3_t angles)
|
||||
{
|
||||
vec3_t p_l;
|
||||
vec3_t temp;
|
||||
|
@ -940,7 +940,7 @@ int CM_TransformedPointContents (vec3_t p, int headnode, vec3_t origin, vec3_t a
|
|||
if (headnode != box_headnode &&
|
||||
(angles[0] || angles[1] || angles[2]) )
|
||||
{
|
||||
AngleVectorsRight (angles, forward, right, up);
|
||||
AngleVectors (angles, forward, right, up);
|
||||
|
||||
VectorCopy (p_l, temp);
|
||||
p_l[0] = DotProduct (temp, forward);
|
||||
|
@ -978,15 +978,16 @@ bool trace_ispoint; // optimized case
|
|||
CM_ClipBoxToBrush
|
||||
================
|
||||
*/
|
||||
void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace_t *trace, cbrush_t *brush)
|
||||
void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
|
||||
trace_t *trace, cbrush_t *brush)
|
||||
{
|
||||
int i, j;
|
||||
cplane_t *plane, *clipplane;
|
||||
int i, j;
|
||||
cplane_t *plane, *clipplane;
|
||||
float dist;
|
||||
float enterfrac, leavefrac;
|
||||
vec3_t ofs;
|
||||
float d1, d2;
|
||||
bool getout, startout;
|
||||
bool getout, startout;
|
||||
float f;
|
||||
cbrushside_t *side, *leadside;
|
||||
|
||||
|
@ -994,7 +995,8 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace_t
|
|||
leavefrac = 1;
|
||||
clipplane = NULL;
|
||||
|
||||
if (!brush->numsides) return;
|
||||
if (!brush->numsides)
|
||||
return;
|
||||
|
||||
c_brush_traces++;
|
||||
|
||||
|
@ -1002,7 +1004,7 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace_t
|
|||
startout = false;
|
||||
leadside = NULL;
|
||||
|
||||
for (i = 0; i < brush->numsides; i++)
|
||||
for (i=0 ; i<brush->numsides ; i++)
|
||||
{
|
||||
side = &map_brushsides[brush->firstbrushside+i];
|
||||
plane = side->plane;
|
||||
|
@ -1010,17 +1012,17 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace_t
|
|||
// FIXME: special case for axial
|
||||
|
||||
if (!trace_ispoint)
|
||||
{
|
||||
// general box case
|
||||
{ // general box case
|
||||
|
||||
// push the plane out apropriately for mins/maxs
|
||||
|
||||
// FIXME: use signbits into 8 way lookup for each mins/maxs
|
||||
for (j = 0; j < 3; j++)
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
if (plane->normal[j] < 0)
|
||||
ofs[j] = maxs[j];
|
||||
else ofs[j] = mins[j];
|
||||
else
|
||||
ofs[j] = mins[j];
|
||||
}
|
||||
dist = DotProduct (ofs, plane->normal);
|
||||
dist = plane->dist - dist;
|
||||
|
@ -1033,13 +1035,17 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace_t
|
|||
d1 = DotProduct (p1, plane->normal) - dist;
|
||||
d2 = DotProduct (p2, plane->normal) - dist;
|
||||
|
||||
if (d2 > 0) getout = true; // endpoint is not in solid
|
||||
if (d1 > 0) startout = true;
|
||||
if (d2 > 0)
|
||||
getout = true; // endpoint is not in solid
|
||||
if (d1 > 0)
|
||||
startout = true;
|
||||
|
||||
// if completely in front of face, no intersection
|
||||
if (d1 > 0 && d2 >= d1) return;
|
||||
if (d1 > 0 && d2 >= d1)
|
||||
return;
|
||||
|
||||
if (d1 <= 0 && d2 <= 0) continue;
|
||||
if (d1 <= 0 && d2 <= 0)
|
||||
continue;
|
||||
|
||||
// crosses face
|
||||
if (d1 > d2)
|
||||
|
@ -1054,23 +1060,25 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace_t
|
|||
}
|
||||
else
|
||||
{ // leave
|
||||
f = (d1 + DIST_EPSILON) / (d1-d2);
|
||||
if (f < leavefrac) leavefrac = f;
|
||||
f = (d1+DIST_EPSILON) / (d1-d2);
|
||||
if (f < leavefrac)
|
||||
leavefrac = f;
|
||||
}
|
||||
}
|
||||
|
||||
if (!startout)
|
||||
{
|
||||
// original point was inside brush
|
||||
{ // original point was inside brush
|
||||
trace->startsolid = true;
|
||||
if (!getout) trace->allsolid = true;
|
||||
if (!getout)
|
||||
trace->allsolid = true;
|
||||
return;
|
||||
}
|
||||
if (enterfrac < leavefrac)
|
||||
{
|
||||
if (enterfrac > -1 && enterfrac < trace->fraction)
|
||||
{
|
||||
if (enterfrac < 0) enterfrac = 0;
|
||||
if (enterfrac < 0)
|
||||
enterfrac = 0;
|
||||
trace->fraction = enterfrac;
|
||||
trace->plane = *clipplane;
|
||||
trace->surface = &(leadside->surface->c);
|
||||
|
@ -1184,7 +1192,7 @@ void CM_TestInLeaf (int leafnum)
|
|||
if ( !(leaf->contents & trace_contents))
|
||||
return;
|
||||
// trace line against all brushes in the leaf
|
||||
for (k = 0; k < leaf->numleafbrushes; k++)
|
||||
for (k=0 ; k<leaf->numleafbrushes ; k++)
|
||||
{
|
||||
brushnum = map_leafbrushes[leaf->firstleafbrush+k];
|
||||
b = &map_brushes[brushnum];
|
||||
|
@ -1192,7 +1200,7 @@ void CM_TestInLeaf (int leafnum)
|
|||
continue; // already checked this brush in another leaf
|
||||
b->checkcount = checkcount;
|
||||
|
||||
if (!(b->contents & trace_contents))
|
||||
if ( !(b->contents & trace_contents))
|
||||
continue;
|
||||
CM_TestBoxInBrush (trace_mins, trace_maxs, trace_start, &trace_trace, b);
|
||||
if (!trace_trace.fraction)
|
||||
|
@ -1331,12 +1339,15 @@ return;
|
|||
CM_BoxTrace
|
||||
==================
|
||||
*/
|
||||
trace_t CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask)
|
||||
trace_t CM_BoxTrace (vec3_t start, vec3_t end,
|
||||
vec3_t mins, vec3_t maxs,
|
||||
int headnode, int brushmask)
|
||||
{
|
||||
int i;
|
||||
|
||||
checkcount++; // for multi-check avoidance
|
||||
c_traces++; // for statistics, may be zeroed
|
||||
checkcount++; // for multi-check avoidance
|
||||
|
||||
c_traces++; // for statistics, may be zeroed
|
||||
|
||||
// fill in a default trace
|
||||
memset (&trace_trace, 0, sizeof(trace_trace));
|
||||
|
@ -1352,24 +1363,26 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int hea
|
|||
VectorCopy (mins, trace_mins);
|
||||
VectorCopy (maxs, trace_maxs);
|
||||
|
||||
//
|
||||
// check for position test special case
|
||||
//
|
||||
if (start[0] == end[0] && start[1] == end[1] && start[2] == end[2])
|
||||
{
|
||||
int leafs[1024];
|
||||
int i, numleafs;
|
||||
vec3_t c1, c2;
|
||||
vec3_t c1, c2;
|
||||
int topnode;
|
||||
|
||||
VectorAdd (start, mins, c1);
|
||||
VectorAdd (start, maxs, c2);
|
||||
for (i = 0; i < 3; i++)
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
c1[i] -= 1;
|
||||
c2[i] += 1;
|
||||
}
|
||||
|
||||
numleafs = CM_BoxLeafnums_headnode (c1, c2, leafs, 1024, headnode, &topnode);
|
||||
for (i = 0; i < numleafs; i++)
|
||||
for (i=0 ; i<numleafs ; i++)
|
||||
{
|
||||
CM_TestInLeaf (leafs[i]);
|
||||
if (trace_trace.allsolid)
|
||||
|
@ -1379,7 +1392,9 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int hea
|
|||
return trace_trace;
|
||||
}
|
||||
|
||||
//
|
||||
// check for point special case
|
||||
//
|
||||
if (mins[0] == 0 && mins[1] == 0 && mins[2] == 0
|
||||
&& maxs[0] == 0 && maxs[1] == 0 && maxs[2] == 0)
|
||||
{
|
||||
|
@ -1394,7 +1409,9 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int hea
|
|||
trace_extents[2] = -mins[2] > maxs[2] ? -mins[2] : maxs[2];
|
||||
}
|
||||
|
||||
//
|
||||
// general sweeping through world
|
||||
//
|
||||
CM_RecursiveHullCheck (headnode, 0, 1, start, end);
|
||||
|
||||
if (trace_trace.fraction == 1)
|
||||
|
@ -1403,7 +1420,7 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int hea
|
|||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
for (i=0 ; i<3 ; i++)
|
||||
trace_trace.endpos[i] = start[i] + trace_trace.fraction * (end[i] - start[i]);
|
||||
}
|
||||
return trace_trace;
|
||||
|
@ -1423,7 +1440,10 @@ rotating entities
|
|||
#endif
|
||||
|
||||
|
||||
trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask, vec3_t origin, vec3_t angles)
|
||||
trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end,
|
||||
vec3_t mins, vec3_t maxs,
|
||||
int headnode, int brushmask,
|
||||
vec3_t origin, vec3_t angles)
|
||||
{
|
||||
trace_t trace;
|
||||
vec3_t start_l, end_l;
|
||||
|
@ -1437,14 +1457,15 @@ trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t ma
|
|||
VectorSubtract (end, origin, end_l);
|
||||
|
||||
// rotate start and end into the models frame of reference
|
||||
if (headnode != box_headnode && !VectorIsNull(angles))
|
||||
if (headnode != box_headnode &&
|
||||
(angles[0] || angles[1] || angles[2]) )
|
||||
rotated = true;
|
||||
else
|
||||
rotated = false;
|
||||
|
||||
if (rotated)
|
||||
{
|
||||
AngleVectorsRight (angles, forward, right, up);
|
||||
AngleVectors (angles, forward, right, up);
|
||||
|
||||
VectorCopy (start_l, temp);
|
||||
start_l[0] = DotProduct (temp, forward);
|
||||
|
@ -1465,7 +1486,7 @@ trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t ma
|
|||
// FIXME: figure out how to do this with existing angles
|
||||
VectorCopy( angles, a );
|
||||
VectorNegate ( a, a );
|
||||
AngleVectorsRight (a, forward, right, up);
|
||||
AngleVectors (a, forward, right, up);
|
||||
|
||||
VectorCopy (trace.plane.normal, temp);
|
||||
trace.plane.normal[0] = DotProduct (temp, forward);
|
||||
|
@ -1720,15 +1741,15 @@ STUDIO SHARED CMODELS
|
|||
|
||||
===============================================================================
|
||||
*/
|
||||
#define HULL_PRECISION 4 // precision factor
|
||||
#define NUM_HULL_ROUNDS 22
|
||||
#define HULL_PRECISION 4
|
||||
|
||||
word hull_table[] = { 0, 4, 8, 16, 18, 24, 28, 30, 32, 40, 48, 54, 56, 60, 64, 72, 80, 112, 120, 128, 140, 176 };
|
||||
#define NUM_HULL_ROUNDS (sizeof(hull_table) / sizeof(word))
|
||||
word hull_table[NUM_HULL_ROUNDS] = { 0, 4, 8, 16, 18, 24, 28, 30, 32, 40, 48, 54, 56, 60, 64, 72, 80, 112, 120, 128, 140, 176 };
|
||||
|
||||
void CM_LookUpHullSize(vec3_t size, bool down)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
bool negative = false;
|
||||
|
@ -1748,14 +1769,7 @@ void CM_LookUpHullSize(vec3_t size, bool down)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(j == NUM_HULL_ROUNDS)
|
||||
{
|
||||
//catch an error
|
||||
MsgWarn("CM_LookUpHullSize: hull size[%d] is too big, reset value to default\n", i );
|
||||
size[i] = 16; //default value
|
||||
}
|
||||
else size[i] = result;//copy new value
|
||||
size[i] = result;//copy new value
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1805,7 +1819,7 @@ cmodel_t *CM_StudioModel (char *name, byte *buffer)
|
|||
VectorSet(out->mins, -32, -32, -32 );
|
||||
VectorSet(out->maxs, 32, 32, 32 );
|
||||
}
|
||||
|
||||
|
||||
numsmodels++;
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -28,11 +28,24 @@ jmp_buf abortframe;
|
|||
|
||||
int com_argc;
|
||||
char *com_argv[MAX_NUM_ARGVS+1];
|
||||
double realtime;
|
||||
int realtime;
|
||||
|
||||
file_t *log_stats_file;
|
||||
|
||||
cvar_t *host_speeds;
|
||||
cvar_t *log_stats;
|
||||
cvar_t *developer;
|
||||
cvar_t *dedicated;
|
||||
|
||||
int server_state;
|
||||
|
||||
// host_speeds times
|
||||
int time_before_game;
|
||||
int time_after_game;
|
||||
int time_before_ref;
|
||||
int time_after_ref;
|
||||
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
|
@ -101,9 +114,7 @@ void Com_Error (int code, char *fmt, ...)
|
|||
va_start (argptr,fmt);
|
||||
vsprintf (msg,fmt,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
host.state = HOST_ERROR;
|
||||
|
||||
|
||||
if (code == ERR_DISCONNECT)
|
||||
{
|
||||
CL_Drop ();
|
||||
|
@ -163,7 +174,7 @@ void Com_Printf (char *fmt, ...)
|
|||
================
|
||||
Com_DPrintf
|
||||
|
||||
A Msg that only shows up in developer mode > 0
|
||||
A Msg that only shows up in debug mode
|
||||
================
|
||||
*/
|
||||
void Com_DPrintf (int level, char *fmt, ...)
|
||||
|
@ -301,7 +312,7 @@ COM_InitArgv
|
|||
*/
|
||||
void COM_InitArgv (int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
char dev_level[4];
|
||||
|
||||
if (argc > MAX_NUM_ARGVS)
|
||||
|
@ -325,9 +336,9 @@ void COM_InitArgv (int argc, char **argv)
|
|||
host.developer = atoi(dev_level);
|
||||
}
|
||||
|
||||
char *CopyString (const char *in)
|
||||
char *CopyString (char *in)
|
||||
{
|
||||
char *out;
|
||||
char *out;
|
||||
|
||||
out = Z_Malloc (strlen(in)+1);
|
||||
strcpy (out, in);
|
||||
|
|
|
@ -93,7 +93,7 @@ void Con_ToggleConsole_f (void)
|
|||
M_ForceMenuOff ();
|
||||
cls.key_dest = key_console;
|
||||
|
||||
if (host.maxclients == 1 && Com_ServerState())
|
||||
if (Cvar_VariableValue ("maxclients") == 1 && Com_ServerState ())
|
||||
Cvar_Set ("paused", "1");
|
||||
}
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ void Con_ClearNotify (void)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_CON_TIMES; i++)
|
||||
for (i=0 ; i<NUM_CON_TIMES ; i++)
|
||||
con.times[i] = 0;
|
||||
}
|
||||
|
||||
|
@ -389,8 +389,9 @@ void Con_Print (char *txt)
|
|||
if (!con.x)
|
||||
{
|
||||
Con_Linefeed ();
|
||||
// mark time for transparent overlay
|
||||
if (con.current >= 0) con.times[con.current % NUM_CON_TIMES] = cls.realtime;
|
||||
// mark time for transparent overlay
|
||||
if (con.current >= 0)
|
||||
con.times[con.current % NUM_CON_TIMES] = cls.realtime;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
|
@ -466,24 +467,24 @@ void Con_DrawInput (void)
|
|||
|
||||
text = key_lines[edit_line];
|
||||
|
||||
// add the cursor frame
|
||||
text[key_linepos] = 10 + ((int)(cls.realtime * 4.0f) & 1);
|
||||
// add the cursor frame
|
||||
text[key_linepos] = 10+((int)(cls.realtime>>8)&1);
|
||||
|
||||
// fill out remainder with spaces
|
||||
for (i = key_linepos + 1; i < con.linewidth; i++)
|
||||
// fill out remainder with spaces
|
||||
for (i=key_linepos+1 ; i< con.linewidth ; i++)
|
||||
text[i] = ' ';
|
||||
|
||||
// prestep if horizontally scrolling
|
||||
// prestep if horizontally scrolling
|
||||
if (key_linepos >= con.linewidth)
|
||||
text += 1 + key_linepos - con.linewidth;
|
||||
|
||||
// draw it
|
||||
// draw it
|
||||
y = con.vislines-16;
|
||||
|
||||
for (i=0 ; i<con.linewidth ; i++)
|
||||
re->DrawChar ( (i+1)<<3, con.vislines - 22, text[i]);
|
||||
|
||||
// remove cursor
|
||||
// remove cursor
|
||||
key_lines[edit_line][key_linepos] = 0;
|
||||
}
|
||||
|
||||
|
@ -500,19 +501,22 @@ void Con_DrawNotify (void)
|
|||
int x, v;
|
||||
char *text;
|
||||
int i;
|
||||
float time;
|
||||
int time;
|
||||
char *s;
|
||||
int skip;
|
||||
|
||||
v = 0;
|
||||
for (i= con.current-NUM_CON_TIMES+1 ; i<=con.current ; i++)
|
||||
{
|
||||
if (i < 0) continue;
|
||||
if (i < 0)
|
||||
continue;
|
||||
time = con.times[i % NUM_CON_TIMES];
|
||||
if (time == 0) continue;
|
||||
if (time == 0)
|
||||
continue;
|
||||
time = cls.realtime - time;
|
||||
if (time > con_notifytime->value) continue;
|
||||
text = con.text + (i % con.totallines) * con.linewidth;
|
||||
if (time > con_notifytime->value*1000)
|
||||
continue;
|
||||
text = con.text + (i % con.totallines)*con.linewidth;
|
||||
|
||||
for (x = 0 ; x < con.linewidth ; x++)
|
||||
re->DrawChar ( (x+1)<<3, v, text[x]);
|
||||
|
@ -543,7 +547,7 @@ void Con_DrawNotify (void)
|
|||
re->DrawChar ( (x+skip)<<3, v, s[x]);
|
||||
x++;
|
||||
}
|
||||
re->DrawChar ((x+skip)<<3, v, 10 + ((int)(cls.realtime * 4.0f) & 1));
|
||||
re->DrawChar ( (x+skip)<<3, v, 10+((cls.realtime>>8)&1));
|
||||
v += 8;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ cvar_t *cvar_vars;
|
|||
Cvar_InfoValidate
|
||||
============
|
||||
*/
|
||||
static bool Cvar_InfoValidate (const char *s)
|
||||
static bool Cvar_InfoValidate (char *s)
|
||||
{
|
||||
if (strstr (s, "\\"))
|
||||
return false;
|
||||
|
@ -44,11 +44,11 @@ static bool Cvar_InfoValidate (const char *s)
|
|||
Cvar_FindVar
|
||||
============
|
||||
*/
|
||||
cvar_t *Cvar_FindVar (const char *var_name)
|
||||
cvar_t *Cvar_FindVar (char *var_name)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
for (var = cvar_vars; var; var = var->next)
|
||||
for (var=cvar_vars ; var ; var=var->next)
|
||||
if (!strcmp (var_name, var->name))
|
||||
return var;
|
||||
|
||||
|
@ -60,12 +60,13 @@ cvar_t *Cvar_FindVar (const char *var_name)
|
|||
Cvar_VariableValue
|
||||
============
|
||||
*/
|
||||
float Cvar_VariableValue (const char *var_name)
|
||||
float Cvar_VariableValue (char *var_name)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
var = Cvar_FindVar (var_name);
|
||||
if (!var) return 0;
|
||||
if (!var)
|
||||
return 0;
|
||||
return atof (var->string);
|
||||
}
|
||||
|
||||
|
@ -75,12 +76,13 @@ float Cvar_VariableValue (const char *var_name)
|
|||
Cvar_VariableString
|
||||
============
|
||||
*/
|
||||
char *Cvar_VariableString (const char *var_name)
|
||||
char *Cvar_VariableString (char *var_name)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
var = Cvar_FindVar (var_name);
|
||||
if (!var) return "";
|
||||
if (!var)
|
||||
return "";
|
||||
return var->string;
|
||||
}
|
||||
|
||||
|
@ -93,15 +95,16 @@ Cvar_CompleteVariable
|
|||
char *Cvar_CompleteVariable (char *partial)
|
||||
{
|
||||
cvar_t *cvar;
|
||||
int len;
|
||||
int len;
|
||||
|
||||
len = strlen(partial);
|
||||
|
||||
if (!len) return NULL;
|
||||
if (!len)
|
||||
return NULL;
|
||||
|
||||
// check exact match
|
||||
for (cvar=cvar_vars ; cvar ; cvar=cvar->next)
|
||||
if (!strcmp (partial, cvar->name))
|
||||
if (!strcmp (partial,cvar->name))
|
||||
return cvar->name;
|
||||
|
||||
// check partial match
|
||||
|
@ -121,7 +124,7 @@ If the variable already exists, the value will not be set
|
|||
The flags will be or'ed in if the variable exists.
|
||||
============
|
||||
*/
|
||||
cvar_t *Cvar_Get (const char *var_name, const char *var_value, int flags)
|
||||
cvar_t *Cvar_Get (char *var_name, char *var_value, int flags)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
|
@ -173,12 +176,15 @@ cvar_t *Cvar_Get (const char *var_name, const char *var_value, int flags)
|
|||
Cvar_Set2
|
||||
============
|
||||
*/
|
||||
cvar_t *Cvar_Set2 (const char *var_name, const char *value, bool force)
|
||||
cvar_t *Cvar_Set2 (char *var_name, char *value, bool force)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
|
||||
var = Cvar_FindVar (var_name);
|
||||
if (!var) return Cvar_Get (var_name, value, 0); // create it
|
||||
if (!var)
|
||||
{ // create it
|
||||
return Cvar_Get (var_name, value, 0);
|
||||
}
|
||||
|
||||
if (var->flags & (CVAR_USERINFO | CVAR_SERVERINFO))
|
||||
{
|
||||
|
@ -238,13 +244,13 @@ cvar_t *Cvar_Set2 (const char *var_name, const char *value, bool force)
|
|||
|
||||
var->modified = true;
|
||||
|
||||
// transmit at next oportunity
|
||||
if (var->flags & CVAR_USERINFO) userinfo_modified = true;
|
||||
if (var->flags & CVAR_USERINFO)
|
||||
userinfo_modified = true; // transmit at next oportunity
|
||||
|
||||
Z_Free (var->string); // free the old value string
|
||||
Z_Free (var->string); // free the old value string
|
||||
|
||||
var->string = CopyString(value);
|
||||
var->value = atof(var->string);
|
||||
var->value = atof (var->string);
|
||||
|
||||
return var;
|
||||
}
|
||||
|
@ -254,7 +260,7 @@ cvar_t *Cvar_Set2 (const char *var_name, const char *value, bool force)
|
|||
Cvar_ForceSet
|
||||
============
|
||||
*/
|
||||
cvar_t *Cvar_ForceSet (const char *var_name, const char *value)
|
||||
cvar_t *Cvar_ForceSet (char *var_name, char *value)
|
||||
{
|
||||
return Cvar_Set2 (var_name, value, true);
|
||||
}
|
||||
|
@ -264,7 +270,7 @@ cvar_t *Cvar_ForceSet (const char *var_name, const char *value)
|
|||
Cvar_Set
|
||||
============
|
||||
*/
|
||||
cvar_t *_Cvar_Set (const char *var_name, const char *value, const char *filename, int fileline)
|
||||
cvar_t *Cvar_Set (char *var_name, char *value)
|
||||
{
|
||||
return Cvar_Set2 (var_name, value, false);
|
||||
}
|
||||
|
@ -346,13 +352,14 @@ Handles variable inspection and changing from the console
|
|||
*/
|
||||
bool Cvar_Command (void)
|
||||
{
|
||||
cvar_t *v;
|
||||
|
||||
// check variables
|
||||
cvar_t *v;
|
||||
|
||||
// check variables
|
||||
v = Cvar_FindVar (Cmd_Argv(0));
|
||||
if (!v) return false;
|
||||
if (!v)
|
||||
return false;
|
||||
|
||||
// perform a variable print or set
|
||||
// perform a variable print or set
|
||||
if (Cmd_Argc() == 1)
|
||||
{
|
||||
Msg ("\"%s\" is \"%s\"\n", v->name, v->string);
|
||||
|
@ -385,8 +392,10 @@ void Cvar_Set_f (void)
|
|||
|
||||
if (c == 4)
|
||||
{
|
||||
if (!strcmp(Cmd_Argv(3), "u")) flags = CVAR_USERINFO;
|
||||
else if (!strcmp(Cmd_Argv(3), "s")) flags = CVAR_SERVERINFO;
|
||||
if (!strcmp(Cmd_Argv(3), "u"))
|
||||
flags = CVAR_USERINFO;
|
||||
else if (!strcmp(Cmd_Argv(3), "s"))
|
||||
flags = CVAR_SERVERINFO;
|
||||
else
|
||||
{
|
||||
Msg ("flags can only be 'u' or 's'\n");
|
||||
|
@ -394,7 +403,8 @@ void Cvar_Set_f (void)
|
|||
}
|
||||
Cvar_FullSet (Cmd_Argv(1), Cmd_Argv(2), flags);
|
||||
}
|
||||
else Cvar_Set (Cmd_Argv(1), Cmd_Argv(2));
|
||||
else
|
||||
Cvar_Set (Cmd_Argv(1), Cmd_Argv(2));
|
||||
}
|
||||
|
||||
|
||||
|
@ -465,7 +475,7 @@ void Cvar_List_f (void)
|
|||
bool userinfo_modified;
|
||||
|
||||
|
||||
char *Cvar_BitInfo (int bit)
|
||||
char *Cvar_BitInfo (int bit)
|
||||
{
|
||||
static char info[MAX_INFO_STRING];
|
||||
cvar_t *var;
|
||||
|
@ -481,13 +491,13 @@ char *Cvar_BitInfo (int bit)
|
|||
}
|
||||
|
||||
// returns an info string containing all the CVAR_USERINFO cvars
|
||||
char *Cvar_Userinfo (void)
|
||||
char *Cvar_Userinfo (void)
|
||||
{
|
||||
return Cvar_BitInfo (CVAR_USERINFO);
|
||||
}
|
||||
|
||||
// returns an info string containing all the CVAR_SERVERINFO cvars
|
||||
char *Cvar_Serverinfo (void)
|
||||
char *Cvar_Serverinfo (void)
|
||||
{
|
||||
return Cvar_BitInfo (CVAR_SERVERINFO);
|
||||
}
|
||||
|
|
|
@ -6,18 +6,17 @@
|
|||
#define CVAR_H
|
||||
|
||||
extern cvar_t *cvar_vars;
|
||||
cvar_t *Cvar_FindVar (const char *var_name);
|
||||
cvar_t *Cvar_FindVar (char *var_name);
|
||||
|
||||
cvar_t *Cvar_Get (const char *var_name, const char *value, int flags);
|
||||
cvar_t *Cvar_Get (char *var_name, char *value, int flags);
|
||||
// creates the variable if it doesn't exist, or returns the existing one
|
||||
// if it exists, the value will not be changed, but flags will be ORed in
|
||||
// that allows variables to be unarchived without needing bitflags
|
||||
|
||||
#define Cvar_Set(name, val) _Cvar_Set (name, val, __FILE__, __LINE__)
|
||||
cvar_t *_Cvar_Set (const char *var_name, const char *value, const char *filename, int fileline);
|
||||
cvar_t *Cvar_Set (char *var_name, char *value);
|
||||
// will create the variable if it doesn't exist
|
||||
|
||||
cvar_t *Cvar_ForceSet (const char *var_name, const char *value);
|
||||
cvar_t *Cvar_ForceSet (char *var_name, char *value);
|
||||
// will set the variable even if NOSET or LATCH
|
||||
|
||||
cvar_t *Cvar_FullSet (char *var_name, char *value, int flags);
|
||||
|
@ -25,10 +24,10 @@ cvar_t *Cvar_FullSet (char *var_name, char *value, int flags);
|
|||
void Cvar_SetValue (char *var_name, float value);
|
||||
// expands value to a string and calls Cvar_Set
|
||||
|
||||
float Cvar_VariableValue (const char *var_name);
|
||||
float Cvar_VariableValue (char *var_name);
|
||||
// returns 0 if not defined or non numeric
|
||||
|
||||
char *Cvar_VariableString (const char *var_name);
|
||||
char *Cvar_VariableString (char *var_name);
|
||||
// returns an empty string if not defined
|
||||
|
||||
char *Cvar_CompleteVariable (char *partial);
|
||||
|
|
|
@ -737,7 +737,7 @@ Called by the system between frames for both key up and key down events
|
|||
Should NOT be called during an interrupt!
|
||||
===================
|
||||
*/
|
||||
void Key_Event (int key, bool down, uint msec)
|
||||
void Key_Event (int key, bool down, unsigned time)
|
||||
{
|
||||
char *kb;
|
||||
char cmd[1024];
|
||||
|
@ -835,7 +835,7 @@ void Key_Event (int key, bool down, uint msec)
|
|||
kb = keybindings[key];
|
||||
if (kb && kb[0] == '+')
|
||||
{
|
||||
sprintf (cmd, "-%s %i %i\n", kb+1, key, msec);
|
||||
sprintf (cmd, "-%s %i %i\n", kb+1, key, time);
|
||||
Cbuf_AddText (cmd);
|
||||
}
|
||||
if (keyshift[key] != key)
|
||||
|
@ -843,7 +843,7 @@ void Key_Event (int key, bool down, uint msec)
|
|||
kb = keybindings[keyshift[key]];
|
||||
if (kb && kb[0] == '+')
|
||||
{
|
||||
sprintf (cmd, "-%s %i %i\n", kb+1, key, msec);
|
||||
sprintf (cmd, "-%s %i %i\n", kb+1, key, time);
|
||||
Cbuf_AddText (cmd);
|
||||
}
|
||||
}
|
||||
|
@ -859,7 +859,7 @@ void Key_Event (int key, bool down, uint msec)
|
|||
if (kb[0] == '+')
|
||||
{
|
||||
// button commands add keynum and time as a parm
|
||||
sprintf (cmd, "%s %i %i\n", kb, key, msec);
|
||||
sprintf (cmd, "%s %i %i\n", kb, key, time);
|
||||
Cbuf_AddText (cmd);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -137,12 +137,10 @@ extern char chat_buffer[];
|
|||
extern int chat_bufferlen;
|
||||
extern bool chat_team;
|
||||
|
||||
void Key_Event (int key, bool down, uint msec);
|
||||
void Key_Event (int key, bool down, unsigned time);
|
||||
void Key_Init (void);
|
||||
void Key_WriteBindings (file_t *f);
|
||||
void Key_SetBinding (int keynum, char *binding);
|
||||
void Key_ClearStates (void);
|
||||
char *Key_KeynumToString (int keynum);
|
||||
int Key_StringToKeynum (char *str);
|
||||
int Key_GetKey (void);
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ void M_PushMenu ( void (*draw) (void), const char *(*key) (int k) )
|
|||
{
|
||||
int i;
|
||||
|
||||
if (host.maxclients == 1 && Com_ServerState ())
|
||||
if (Cvar_VariableValue ("maxclients") == 1 && Com_ServerState ())
|
||||
Cvar_Set ("paused", "1");
|
||||
|
||||
// if this menu is already present, drop back to that level
|
||||
|
@ -321,6 +321,7 @@ void M_DrawCursor( int x, int y, int f )
|
|||
for ( i = 0; i < NUM_CURSOR_FRAMES; i++ )
|
||||
{
|
||||
sprintf( cursorname, "m_cursor%d", i );
|
||||
|
||||
re->RegisterPic( cursorname );
|
||||
}
|
||||
cached = true;
|
||||
|
@ -424,7 +425,7 @@ void M_Main_Draw (void)
|
|||
strlcat( litname, "_sel", 80 );
|
||||
re->DrawPic( xoffset, ystart + m_main_cursor * 40 + 13, litname );
|
||||
|
||||
M_DrawCursor( xoffset - 25, ystart + m_main_cursor * 40 + 11, (int)(cls.realtime * 8.0f) % NUM_CURSOR_FRAMES );
|
||||
M_DrawCursor( xoffset - 25, ystart + m_main_cursor * 40 + 11, (int)(cls.realtime / 100)%NUM_CURSOR_FRAMES );
|
||||
|
||||
re->DrawGetPicSize( &w, &h, "m_main_plaque" );
|
||||
re->DrawPic( xoffset - 30 - w, ystart, "m_main_plaque" );
|
||||
|
@ -685,8 +686,10 @@ static void M_FindKeysForCommand (char *command, int *twokeys)
|
|||
|
||||
static void KeyCursorDrawFunc( menuframework_s *menu )
|
||||
{
|
||||
if ( bind_grab ) re->DrawChar( menu->x, menu->y + menu->cursor * 9, '=' );
|
||||
else re->DrawChar( menu->x, menu->y + menu->cursor * 9, 12 + ((int)(cls.realtime * 5.0f) & 1 ));
|
||||
if ( bind_grab )
|
||||
re->DrawChar( menu->x, menu->y + menu->cursor * 9, '=' );
|
||||
else
|
||||
re->DrawChar( menu->x, menu->y + menu->cursor * 9, 12 + ( ( int ) ( Sys_Milliseconds() / 250 ) & 1 ) );
|
||||
}
|
||||
|
||||
static void DrawKeyBindingFunc( void *self )
|
||||
|
@ -1360,7 +1363,7 @@ END GAME MENU
|
|||
|
||||
=============================================================================
|
||||
*/
|
||||
static float credits_start_time;
|
||||
static int credits_start_time;
|
||||
static const char **credits;
|
||||
static char *creditsIndex[256];
|
||||
static char *creditsBuffer;
|
||||
|
@ -1452,20 +1455,161 @@ static const char *idcredits[] =
|
|||
0
|
||||
};
|
||||
|
||||
static const char *xatcredits[] =
|
||||
{
|
||||
"+QUAKE II MISSION PACK: THE RECKONING",
|
||||
"+BY",
|
||||
"+XATRIX ENTERTAINMENT, INC.",
|
||||
"",
|
||||
"+DESIGN AND DIRECTION",
|
||||
"Drew Markham",
|
||||
"",
|
||||
"+PRODUCED BY",
|
||||
"Greg Goodrich",
|
||||
"",
|
||||
"+PROGRAMMING",
|
||||
"Rafael Paiz",
|
||||
"",
|
||||
"+LEVEL DESIGN / ADDITIONAL GAME DESIGN",
|
||||
"Alex Mayberry",
|
||||
"",
|
||||
"+LEVEL DESIGN",
|
||||
"Mal Blackwell",
|
||||
"Dan Koppel",
|
||||
"",
|
||||
"+ART DIRECTION",
|
||||
"Michael \"Maxx\" Kaufman",
|
||||
"",
|
||||
"+COMPUTER GRAPHICS SUPERVISOR AND",
|
||||
"+CHARACTER ANIMATION DIRECTION",
|
||||
"Barry Dempsey",
|
||||
"",
|
||||
"+SENIOR ANIMATOR AND MODELER",
|
||||
"Jason Hoover",
|
||||
"",
|
||||
"+CHARACTER ANIMATION AND",
|
||||
"+MOTION CAPTURE SPECIALIST",
|
||||
"Amit Doron",
|
||||
"",
|
||||
"+ART",
|
||||
"Claire Praderie-Markham",
|
||||
"Viktor Antonov",
|
||||
"Corky Lehmkuhl",
|
||||
"",
|
||||
"+INTRODUCTION ANIMATION",
|
||||
"Dominique Drozdz",
|
||||
"",
|
||||
"+ADDITIONAL LEVEL DESIGN",
|
||||
"Aaron Barber",
|
||||
"Rhett Baldwin",
|
||||
"",
|
||||
"+3D CHARACTER ANIMATION TOOLS",
|
||||
"Gerry Tyra, SA Technology",
|
||||
"",
|
||||
"+ADDITIONAL EDITOR TOOL PROGRAMMING",
|
||||
"Robert Duffy",
|
||||
"",
|
||||
"+ADDITIONAL PROGRAMMING",
|
||||
"Ryan Feltrin",
|
||||
"",
|
||||
"+PRODUCTION COORDINATOR",
|
||||
"Victoria Sylvester",
|
||||
"",
|
||||
"+SOUND DESIGN",
|
||||
"Gary Bradfield",
|
||||
"",
|
||||
"+MUSIC BY",
|
||||
"Sonic Mayhem",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"+SPECIAL THANKS",
|
||||
"+TO",
|
||||
"+OUR FRIENDS AT ID SOFTWARE",
|
||||
"",
|
||||
"John Carmack",
|
||||
"John Cash",
|
||||
"Brian Hook",
|
||||
"Adrian Carmack",
|
||||
"Kevin Cloud",
|
||||
"Paul Steed",
|
||||
"Tim Willits",
|
||||
"Christian Antkow",
|
||||
"Paul Jaquays",
|
||||
"Brandon James",
|
||||
"Todd Hollenshead",
|
||||
"Barrett (Bear) Alexander",
|
||||
"Dave \"Zoid\" Kirsch",
|
||||
"Donna Jackson",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"+THANKS TO ACTIVISION",
|
||||
"+IN PARTICULAR:",
|
||||
"",
|
||||
"Marty Stratton",
|
||||
"Henk \"The Original Ripper\" Hartong",
|
||||
"Kevin Kraff",
|
||||
"Jamey Gottlieb",
|
||||
"Chris Hepburn",
|
||||
"",
|
||||
"+AND THE GAME TESTERS",
|
||||
"",
|
||||
"Tim Vanlaw",
|
||||
"Doug Jacobs",
|
||||
"Steven Rosenthal",
|
||||
"David Baker",
|
||||
"Chris Campbell",
|
||||
"Aaron Casillas",
|
||||
"Steve Elwell",
|
||||
"Derek Johnstone",
|
||||
"Igor Krinitskiy",
|
||||
"Samantha Lee",
|
||||
"Michael Spann",
|
||||
"Chris Toft",
|
||||
"Juan Valdes",
|
||||
"",
|
||||
"+THANKS TO INTERGRAPH COMPUTER SYTEMS",
|
||||
"+IN PARTICULAR:",
|
||||
"",
|
||||
"Michael T. Nicolaou",
|
||||
"",
|
||||
"",
|
||||
"Quake II Mission Pack: The Reckoning",
|
||||
"(tm) (C)1998 Id Software, Inc. All",
|
||||
"Rights Reserved. Developed by Xatrix",
|
||||
"Entertainment, Inc. for Id Software,",
|
||||
"Inc. Distributed by Activision Inc.",
|
||||
"under license. Quake(R) is a",
|
||||
"registered trademark of Id Software,",
|
||||
"Inc. Quake II Mission Pack: The",
|
||||
"Reckoning(tm), Quake II(tm), the Id",
|
||||
"Software name, the \"Q II\"(tm) logo",
|
||||
"and id(tm) logo are trademarks of Id",
|
||||
"Software, Inc. Activision(R) is a",
|
||||
"registered trademark of Activision,",
|
||||
"Inc. Xatrix(R) is a registered",
|
||||
"trademark of Xatrix Entertainment,",
|
||||
"Inc. All other trademarks and trade",
|
||||
"names are properties of their",
|
||||
"respective owners.",
|
||||
0
|
||||
};
|
||||
|
||||
void M_Credits_MenuDraw( void )
|
||||
{
|
||||
int i;
|
||||
float y;
|
||||
int i, y;
|
||||
|
||||
/*
|
||||
** draw the credits
|
||||
*/
|
||||
for ( i = 0, y = viddef.height - (( cls.realtime - credits_start_time ) * 40.0f ); credits[i] && y < viddef.height; y += 10, i++ )
|
||||
for ( i = 0, y = viddef.height - ( ( cls.realtime - credits_start_time ) / 40.0F ); credits[i] && y < viddef.height; y += 10, i++ )
|
||||
{
|
||||
int j, stringoffset = 0;
|
||||
int bold = false;
|
||||
|
||||
if ( y <= -8 ) continue;
|
||||
if ( y <= -8 )
|
||||
continue;
|
||||
|
||||
if ( credits[i][0] == '+' )
|
||||
{
|
||||
|
@ -1484,13 +1628,15 @@ void M_Credits_MenuDraw( void )
|
|||
|
||||
x = ( viddef.width - strlen( credits[i] ) * 8 - stringoffset * 8 ) / 2 + ( j + stringoffset ) * 8;
|
||||
|
||||
if ( bold ) re->DrawChar( x, y, credits[i][j+stringoffset] + 128 );
|
||||
else re->DrawChar( x, y, credits[i][j+stringoffset] );
|
||||
if ( bold )
|
||||
re->DrawChar( x, y, credits[i][j+stringoffset] + 128 );
|
||||
else
|
||||
re->DrawChar( x, y, credits[i][j+stringoffset] );
|
||||
}
|
||||
}
|
||||
|
||||
// loop demonstration
|
||||
if ( y < 0 ) credits_start_time = cls.realtime;
|
||||
if ( y < 0 )
|
||||
credits_start_time = cls.realtime;
|
||||
}
|
||||
|
||||
const char *M_Credits_Key( int key )
|
||||
|
@ -1510,12 +1656,12 @@ void M_Menu_Credits_f( void )
|
|||
{
|
||||
int n;
|
||||
int count;
|
||||
char *p;
|
||||
char *p;
|
||||
int isdeveloper = 0;
|
||||
|
||||
creditsBuffer = NULL;
|
||||
creditsBuffer = FS_LoadFile ("scripts/credits.txt", &count );
|
||||
if (count)
|
||||
creditsBuffer = FS_LoadFile ("credits", &count );
|
||||
if (count != -1)
|
||||
{
|
||||
p = creditsBuffer;
|
||||
for (n = 0; n < 255; n++)
|
||||
|
@ -1524,15 +1670,18 @@ void M_Menu_Credits_f( void )
|
|||
while (*p != '\r' && *p != '\n')
|
||||
{
|
||||
p++;
|
||||
if (--count == 0) break;
|
||||
if (--count == 0)
|
||||
break;
|
||||
}
|
||||
if (*p == '\r')
|
||||
{
|
||||
*p++ = 0;
|
||||
if (--count == 0) break;
|
||||
if (--count == 0)
|
||||
break;
|
||||
}
|
||||
*p++ = 0;
|
||||
if (--count == 0) break;
|
||||
if (--count == 0)
|
||||
break;
|
||||
}
|
||||
creditsIndex[++n] = 0;
|
||||
credits = creditsIndex;
|
||||
|
@ -2086,8 +2235,7 @@ void StartServerActionFunc( void *self )
|
|||
timelimit = atoi( s_timelimit_field.buffer );
|
||||
fraglimit = atoi( s_fraglimit_field.buffer );
|
||||
|
||||
host.maxclients = maxclients;
|
||||
|
||||
Cvar_SetValue( "maxclients", ClampCvar( 0, maxclients, maxclients ) );
|
||||
Cvar_SetValue ("timelimit", ClampCvar( 0, timelimit, timelimit ) );
|
||||
Cvar_SetValue ("fraglimit", ClampCvar( 0, fraglimit, fraglimit ) );
|
||||
Cvar_Set("hostname", s_hostname_field.buffer );
|
||||
|
@ -2347,8 +2495,10 @@ void StartServer_MenuInit( void )
|
|||
s_maxclients_field.generic.statusbar = NULL;
|
||||
s_maxclients_field.length = 3;
|
||||
s_maxclients_field.visible_length = 3;
|
||||
if ( host.maxclients == 1 ) strcpy( s_maxclients_field.buffer, "8" );
|
||||
else strcpy( s_maxclients_field.buffer, "32" ); // just for test
|
||||
if ( Cvar_VariableValue( "maxclients" ) == 1 )
|
||||
strcpy( s_maxclients_field.buffer, "8" );
|
||||
else
|
||||
strcpy( s_maxclients_field.buffer, Cvar_VariableString("maxclients") );
|
||||
|
||||
s_hostname_field.generic.type = MTYPE_FIELD;
|
||||
s_hostname_field.generic.name = "hostname";
|
||||
|
@ -3338,7 +3488,7 @@ void PlayerConfig_MenuDraw( void )
|
|||
refdef.height = 168;
|
||||
refdef.fov_x = 40;
|
||||
refdef.fov_y = CalcFov( refdef.fov_x, refdef.width, refdef.height );
|
||||
refdef.time = cls.realtime;
|
||||
refdef.time = cls.realtime*0.001;
|
||||
|
||||
if ( s_pmi[s_player_model_box.curvalue].skindisplaynames )
|
||||
{
|
||||
|
@ -3527,7 +3677,8 @@ void M_Draw (void)
|
|||
SCR_DirtyScreen ();
|
||||
|
||||
// dim everything behind it down
|
||||
if (cl.cinematictime > 0) re->DrawFill (0, 0, viddef.width, viddef.height, 0);
|
||||
if (cl.cinematictime > 0)
|
||||
re->DrawFill (0, 0, viddef.width, viddef.height, 0);
|
||||
else re->DrawFadeScreen ();
|
||||
|
||||
m_drawfunc ();
|
||||
|
|
|
@ -93,7 +93,7 @@ void Netchan_Init (void)
|
|||
int port;
|
||||
|
||||
// pick a port value that should be nice and random
|
||||
port = RANDOM_LONG(1, 65535);
|
||||
port = Sys_Milliseconds() & 0xffff;
|
||||
|
||||
Msg("netchan port %d\n", port );
|
||||
|
||||
|
@ -158,7 +158,7 @@ void Netchan_Setup (netsrc_t sock, netchan_t *chan, netadr_t adr, int qport)
|
|||
chan->sock = sock;
|
||||
chan->remote_address = adr;
|
||||
chan->qport = qport;
|
||||
chan->last_received = host.realtime * 1000;
|
||||
chan->last_received = curtime;
|
||||
chan->incoming_sequence = 0;
|
||||
chan->outgoing_sequence = 1;
|
||||
|
||||
|
@ -218,11 +218,12 @@ void Netchan_Transmit (netchan_t *chan, int length, byte *data)
|
|||
bool send_reliable;
|
||||
unsigned w1, w2;
|
||||
|
||||
// check for message overflow
|
||||
// check for message overflow
|
||||
if (chan->message.overflowed)
|
||||
{
|
||||
chan->fatal_error = true;
|
||||
Msg ("%s:Outgoing message overflow\n", NET_AdrToString (chan->remote_address));
|
||||
Msg ("%s:Outgoing message overflow\n"
|
||||
, NET_AdrToString (chan->remote_address));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -230,21 +231,21 @@ void Netchan_Transmit (netchan_t *chan, int length, byte *data)
|
|||
|
||||
if (!chan->reliable_length && chan->message.cursize)
|
||||
{
|
||||
Mem_Copy (chan->reliable_buf, chan->message_buf, chan->message.cursize);
|
||||
memcpy (chan->reliable_buf, chan->message_buf, chan->message.cursize);
|
||||
chan->reliable_length = chan->message.cursize;
|
||||
chan->message.cursize = 0;
|
||||
chan->reliable_sequence ^= 1;
|
||||
}
|
||||
|
||||
|
||||
// write the packet header
|
||||
// write the packet header
|
||||
SZ_Init (&send, send_buf, sizeof(send_buf));
|
||||
|
||||
w1 = ( chan->outgoing_sequence & ~(1<<31) ) | (send_reliable<<31);
|
||||
w2 = ( chan->incoming_sequence & ~(1<<31) ) | (chan->incoming_reliable_sequence<<31);
|
||||
|
||||
chan->outgoing_sequence++;
|
||||
chan->last_sent = host.realtime * 1000;
|
||||
chan->last_sent = curtime;
|
||||
|
||||
MSG_WriteLong (&send, w1);
|
||||
MSG_WriteLong (&send, w2);
|
||||
|
@ -297,9 +298,9 @@ bool Netchan_Process (netchan_t *chan, sizebuf_t *msg)
|
|||
{
|
||||
unsigned sequence, sequence_ack;
|
||||
unsigned reliable_ack, reliable_message;
|
||||
int qport;
|
||||
int qport;
|
||||
|
||||
// get sequence numbers
|
||||
// get sequence numbers
|
||||
MSG_BeginReading (msg);
|
||||
sequence = MSG_ReadLong (msg);
|
||||
sequence_ack = MSG_ReadLong (msg);
|
||||
|
@ -351,22 +352,22 @@ bool Netchan_Process (netchan_t *chan, sizebuf_t *msg)
|
|||
if (chan->dropped > 0)
|
||||
{
|
||||
if (showdrop->value)
|
||||
Msg ("%s:Dropped %i packets at %i\n",
|
||||
NET_AdrToString (chan->remote_address),
|
||||
chan->dropped,
|
||||
sequence);
|
||||
Msg ("%s:Dropped %i packets at %i\n"
|
||||
, NET_AdrToString (chan->remote_address)
|
||||
, chan->dropped
|
||||
, sequence);
|
||||
}
|
||||
|
||||
//
|
||||
// if the current outgoing reliable message has been acknowledged
|
||||
// clear the buffer to make way for the next
|
||||
//
|
||||
//
|
||||
// if the current outgoing reliable message has been acknowledged
|
||||
// clear the buffer to make way for the next
|
||||
//
|
||||
if (reliable_ack == chan->reliable_sequence)
|
||||
chan->reliable_length = 0; // it has been received
|
||||
|
||||
//
|
||||
// if this message contains a reliable message, bump incoming_reliable_sequence
|
||||
//
|
||||
//
|
||||
// if this message contains a reliable message, bump incoming_reliable_sequence
|
||||
//
|
||||
chan->incoming_sequence = sequence;
|
||||
chan->incoming_acknowledged = sequence_ack;
|
||||
chan->incoming_reliable_acknowledged = reliable_ack;
|
||||
|
@ -375,10 +376,10 @@ bool Netchan_Process (netchan_t *chan, sizebuf_t *msg)
|
|||
chan->incoming_reliable_sequence ^= 1;
|
||||
}
|
||||
|
||||
//
|
||||
// the message can now be read from the current message pointer
|
||||
//
|
||||
chan->last_received = host.realtime * 1000;
|
||||
//
|
||||
// the message can now be read from the current message pointer
|
||||
//
|
||||
chan->last_received = curtime;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -536,37 +536,29 @@ void MSG_ReadData (sizebuf_t *msg_read, void *data, int len)
|
|||
=======================
|
||||
*/
|
||||
|
||||
void _SZ_Init (sizebuf_t *buf, byte *data, int length, const char *filename, int fileline)
|
||||
void SZ_Init (sizebuf_t *buf, byte *data, int length)
|
||||
{
|
||||
memset (buf, 0, sizeof(*buf));
|
||||
|
||||
if(buf == NULL) Sys_Error("SZ_Clear: sizebuf == NULL (called at %s:%i)\n", filename, fileline );
|
||||
if(data == NULL) Sys_Error("SZ_Init: data == NULL (called at %s:%i)\n", filename, fileline );
|
||||
if(length <= 0) Sys_Error("SZ_Init: length <= 0 (called at %s:%i)\n", filename, fileline );
|
||||
|
||||
buf->data = data;
|
||||
buf->maxsize = length;
|
||||
}
|
||||
|
||||
void _SZ_Clear (sizebuf_t *buf, const char *filename, int fileline)
|
||||
void SZ_Clear (sizebuf_t *buf)
|
||||
{
|
||||
if(buf == NULL) Sys_Error("SZ_Clear: sizebuf == NULL (called at %s:%i)\n", filename, fileline );
|
||||
if(buf->overflowed) MsgWarn("SZ_Clear: clearing buffer was overflowed\n");
|
||||
|
||||
buf->cursize = 0;
|
||||
buf->overflowed = false;
|
||||
}
|
||||
|
||||
void *_SZ_GetSpace (sizebuf_t *buf, int length, const char *filename, int fileline)
|
||||
void *SZ_GetSpace (sizebuf_t *buf, int length)
|
||||
{
|
||||
void *data;
|
||||
|
||||
if (buf->cursize + length > buf->maxsize)
|
||||
{
|
||||
if (length > buf->maxsize)
|
||||
Sys_Error("SZ_GetSpace: buf->cursize[%d] + length[%d] > buf->maxsize[%d](called at %s:%i)\n", buf->cursize, length, buf->maxsize, filename, fileline );
|
||||
Com_Error (ERR_DROP, "SZ_GetSpace: %i is > full buffer size", length);
|
||||
|
||||
Msg ("SZ_GetSpace: overflow [cursize %d maxsize %d](called at %s:%i)\n", buf->cursize + length, buf->maxsize, filename, fileline );
|
||||
Msg ("SZ_GetSpace: overflow [cursize %d maxsize %d]\n", buf->cursize + length, buf->maxsize );
|
||||
SZ_Clear (buf);
|
||||
buf->overflowed = true;
|
||||
}
|
||||
|
@ -576,20 +568,20 @@ void *_SZ_GetSpace (sizebuf_t *buf, int length, const char *filename, int fileli
|
|||
return data;
|
||||
}
|
||||
|
||||
void _SZ_Write (sizebuf_t *buf, void *data, int length, const char *filename, int fileline)
|
||||
void SZ_Write (sizebuf_t *buf, void *data, int length)
|
||||
{
|
||||
pi->Mem.Copy(_SZ_GetSpace(buf, length, filename, fileline), data, length, filename, fileline);
|
||||
Mem_Copy(SZ_GetSpace(buf, length), data, length);
|
||||
}
|
||||
|
||||
void _SZ_Print (sizebuf_t *buf, char *data, const char *filename, int fileline)
|
||||
void SZ_Print (sizebuf_t *buf, char *data)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = strlen(data) + 1;
|
||||
if (buf->cursize)
|
||||
{
|
||||
if (buf->data[buf->cursize - 1]) pi->Mem.Copy((byte *)_SZ_GetSpace(buf, len, filename, fileline), data, len, filename, fileline); // no trailing 0
|
||||
else pi->Mem.Copy((byte *)_SZ_GetSpace(buf, len - 1, filename, fileline) - 1, data, len, filename, fileline); // write over trailing 0
|
||||
if (buf->data[buf->cursize - 1]) Mem_Copy ((byte *)SZ_GetSpace(buf, len),data,len); //no trailing 0
|
||||
else Mem_Copy ((byte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0
|
||||
}
|
||||
else pi->Mem.Copy((byte *)_SZ_GetSpace(buf, len, filename, fileline), data, len, filename, fileline);
|
||||
else Mem_Copy ((byte *)SZ_GetSpace(buf, len),data,len);
|
||||
}
|
|
@ -367,9 +367,12 @@ bool NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (host.type == HOST_DEDICATED) // let dedicated servers continue after errors
|
||||
Msg ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(*net_from));
|
||||
else Com_Error (ERR_DROP, "NET_GetPacket: %s from %s", NET_ErrorString(), NET_AdrToString(*net_from));
|
||||
if (dedicated->value) // let dedicated servers continue after errors
|
||||
Msg ("NET_GetPacket: %s from %s\n", NET_ErrorString(),
|
||||
NET_AdrToString(*net_from));
|
||||
else
|
||||
Com_Error (ERR_DROP, "NET_GetPacket: %s from %s",
|
||||
NET_ErrorString(), NET_AdrToString(*net_from));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -441,9 +444,10 @@ void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to)
|
|||
if ((err == WSAEADDRNOTAVAIL) && ((to.type == NA_BROADCAST) || (to.type == NA_BROADCAST_IPX)))
|
||||
return;
|
||||
|
||||
if (host.type == HOST_DEDICATED) // let dedicated servers continue after errors
|
||||
if (dedicated->value) // let dedicated servers continue after errors
|
||||
{
|
||||
Msg ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(), NET_AdrToString (to));
|
||||
Msg ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(),
|
||||
NET_AdrToString (to));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -529,10 +533,13 @@ NET_OpenIP
|
|||
void NET_OpenIP (void)
|
||||
{
|
||||
cvar_t *ip;
|
||||
int port;
|
||||
int port;
|
||||
int dedicated;
|
||||
|
||||
ip = Cvar_Get ("ip", "localhost", CVAR_NOSET);
|
||||
|
||||
dedicated = Cvar_VariableValue ("dedicated");
|
||||
|
||||
if (!ip_sockets[NS_SERVER])
|
||||
{
|
||||
port = Cvar_Get("ip_hostport", "0", CVAR_NOSET)->value;
|
||||
|
@ -545,13 +552,12 @@ void NET_OpenIP (void)
|
|||
}
|
||||
}
|
||||
ip_sockets[NS_SERVER] = NET_IPSocket (ip->string, port);
|
||||
if (!ip_sockets[NS_SERVER] && host.type == HOST_DEDICATED)
|
||||
Sys_Error("Couldn't allocate dedicated server IP port");
|
||||
if (!ip_sockets[NS_SERVER] && dedicated) Sys_Error("Couldn't allocate dedicated server IP port");
|
||||
}
|
||||
|
||||
|
||||
// dedicated servers don't need client ports
|
||||
if (host.type == HOST_DEDICATED) return;
|
||||
if (dedicated) return;
|
||||
|
||||
if (!ip_sockets[NS_CLIENT])
|
||||
{
|
||||
|
@ -630,6 +636,9 @@ NET_OpenIPX
|
|||
void NET_OpenIPX (void)
|
||||
{
|
||||
int port;
|
||||
int dedicated;
|
||||
|
||||
dedicated = Cvar_VariableValue ("dedicated");
|
||||
|
||||
if (!ipx_sockets[NS_SERVER])
|
||||
{
|
||||
|
@ -646,7 +655,8 @@ void NET_OpenIPX (void)
|
|||
}
|
||||
|
||||
// dedicated servers don't need client ports
|
||||
if (host.type == HOST_DEDICATED) return;
|
||||
if (dedicated)
|
||||
return;
|
||||
|
||||
if (!ipx_sockets[NS_CLIENT])
|
||||
{
|
||||
|
@ -671,7 +681,7 @@ NET_Config
|
|||
A single player game will only use the loopback code
|
||||
====================
|
||||
*/
|
||||
void NET_Config (bool multiplayer)
|
||||
void NET_Config (bool multiplayer)
|
||||
{
|
||||
int i;
|
||||
static bool old_config;
|
||||
|
@ -709,26 +719,27 @@ void NET_Config (bool multiplayer)
|
|||
// sleeps msec or until net socket is ready
|
||||
void NET_Sleep(int msec)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set fdset;
|
||||
int i = 0;
|
||||
struct timeval timeout;
|
||||
fd_set fdset;
|
||||
extern cvar_t *dedicated;
|
||||
int i;
|
||||
|
||||
if (!dedicated || !dedicated->value)
|
||||
return; // we're not a server, just run full speed
|
||||
|
||||
// we're not a server, just run full speed
|
||||
if (host.type == HOST_NORMAL) return;
|
||||
FD_ZERO(&fdset);
|
||||
|
||||
if (ip_sockets[NS_SERVER])
|
||||
{
|
||||
i = 0;
|
||||
if (ip_sockets[NS_SERVER]) {
|
||||
FD_SET(ip_sockets[NS_SERVER], &fdset); // network socket
|
||||
i = ip_sockets[NS_SERVER];
|
||||
}
|
||||
if (ipx_sockets[NS_SERVER])
|
||||
{
|
||||
if (ipx_sockets[NS_SERVER]) {
|
||||
FD_SET(ipx_sockets[NS_SERVER], &fdset); // network socket
|
||||
if (ipx_sockets[NS_SERVER] > i) i = ipx_sockets[NS_SERVER];
|
||||
if (ipx_sockets[NS_SERVER] > i)
|
||||
i = ipx_sockets[NS_SERVER];
|
||||
}
|
||||
timeout.tv_sec = msec/1000;
|
||||
timeout.tv_usec = (msec%1000) * 1000;
|
||||
timeout.tv_usec = (msec%1000)*1000;
|
||||
select(i+1, &fdset, NULL, NULL, &timeout);
|
||||
}
|
||||
|
||||
|
|
|
@ -312,7 +312,7 @@ void PM_Friction (void)
|
|||
{
|
||||
friction = pm_friction;
|
||||
control = speed < pm_stopspeed ? pm_stopspeed : speed;
|
||||
drop += control*friction * pml.frametime;
|
||||
drop += control*friction*pml.frametime;
|
||||
}
|
||||
|
||||
// apply water friction
|
||||
|
@ -1083,7 +1083,7 @@ void PM_ClampAngles (void)
|
|||
else if (pm->viewangles[PITCH] < 271 && pm->viewangles[PITCH] >= 180)
|
||||
pm->viewangles[PITCH] = 271;
|
||||
}
|
||||
AngleVectorsRight (pm->viewangles, pml.forward, pml.right, pml.up);
|
||||
AngleVectors (pm->viewangles, pml.forward, pml.right, pml.up);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1173,8 +1173,7 @@ void Pmove (pmove_t *pmove)
|
|||
// teleport pause stays exactly in place
|
||||
}
|
||||
else if (pm->s.pm_flags & PMF_TIME_WATERJUMP)
|
||||
{
|
||||
// waterjump has no control, but falls
|
||||
{ // waterjump has no control, but falls
|
||||
pml.velocity[2] -= pm->s.gravity * pml.frametime;
|
||||
if (pml.velocity[2] < 0)
|
||||
{ // cancel as soon as we are falling down again
|
||||
|
@ -1199,7 +1198,7 @@ void Pmove (pmove_t *pmove)
|
|||
angles[PITCH] = angles[PITCH] - 360;
|
||||
angles[PITCH] /= 3;
|
||||
|
||||
AngleVectorsRight (angles, pml.forward, pml.right, pml.up);
|
||||
AngleVectors (angles, pml.forward, pml.right, pml.up);
|
||||
PM_AirMove ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,13 +116,17 @@ void Field_Draw( menufield_s *f )
|
|||
else
|
||||
offset = f->cursor;
|
||||
|
||||
if ((( int )( cls.realtime * 4.0f)) & 1 )
|
||||
if ( ( ( int ) ( Sys_Milliseconds() / 250 ) ) & 1 )
|
||||
{
|
||||
Draw_Char( f->generic.x + f->generic.parent->x + ( offset + 2 ) * 8 + 8, f->generic.y + f->generic.parent->y, 11 );
|
||||
Draw_Char( f->generic.x + f->generic.parent->x + ( offset + 2 ) * 8 + 8,
|
||||
f->generic.y + f->generic.parent->y,
|
||||
11 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Draw_Char( f->generic.x + f->generic.parent->x + ( offset + 2 ) * 8 + 8, f->generic.y + f->generic.parent->y, ' ' );
|
||||
Draw_Char( f->generic.x + f->generic.parent->x + ( offset + 2 ) * 8 + 8,
|
||||
f->generic.y + f->generic.parent->y,
|
||||
' ' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,11 +389,11 @@ void Menu_Draw( menuframework_s *menu )
|
|||
{
|
||||
if ( item->flags & QMF_LEFT_JUSTIFY )
|
||||
{
|
||||
Draw_Char( menu->x + item->x - 24 + item->cursor_offset, menu->y + item->y, 12 + ((int)(cls.realtime * 5.0f) & 1 ));
|
||||
Draw_Char( menu->x + item->x - 24 + item->cursor_offset, menu->y + item->y, 12 + ( ( int ) ( Sys_Milliseconds()/250 ) & 1 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Draw_Char( menu->x + item->cursor_offset, menu->y + item->y, 12 + ((int)(cls.realtime * 5.0f) & 1 ));
|
||||
Draw_Char( menu->x + item->cursor_offset, menu->y + item->y, 12 + ( ( int ) ( Sys_Milliseconds()/250 ) & 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ RSC=rc.exe
|
|||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /Ob0 /I "./" /I "prvm" /I "common" /I "server" /I "client" /I "../public" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /Ob0 /I "./" /I "prvm" /I "common" /I "server" /I "client" /I "../public" /I "../platform/formats" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
|
@ -80,7 +80,7 @@ SOURCE="$(InputPath)"
|
|||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "prvm" /I "common" /I "server" /I "client" /I "../public" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /FD /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "prvm" /I "common" /I "server" /I "client" /I "../public" /I "../platform/formats" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
|
@ -91,7 +91,7 @@ BSC32=bscmake.exe
|
|||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
|
||||
# ADD LINK32 gdi32.lib winmm.lib kernel32.lib user32.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 winmm.lib wsock32.lib kernel32.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# SUBTRACT LINK32 /incremental:no /map /nodefaultlib
|
||||
# Begin Custom Build
|
||||
TargetDir=\XASH3D\src_main\!source\temp\engine\!debug
|
||||
|
@ -126,10 +126,6 @@ SOURCE=.\client\cl_fx.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client\cl_game.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client\cl_input.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -278,6 +274,10 @@ SOURCE=.\server\sv_send.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\server\sv_spawn.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\server\sv_studio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -300,18 +300,6 @@ SOURCE=.\vid_dll.c
|
|||
|
||||
SOURCE=.\vid_menu.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\prvm\vm_cmds.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\prvm\vm_edict.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\prvm\vm_exec.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
|
@ -350,10 +338,6 @@ SOURCE=.\common\cvar.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\prvm\edict.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\engine.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -370,14 +354,6 @@ SOURCE=..\public\platform.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\prvm\progdefs.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\prvm\progsvm.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\public\qfiles.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -404,10 +380,6 @@ SOURCE=.\sound.h
|
|||
|
||||
SOURCE=.\common\vid.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\prvm\vm_cmds.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "basemath.h"
|
||||
#include "qfiles.h"
|
||||
#include <ref_system.h>
|
||||
#include "vprogs.h"
|
||||
#include "bspmodel.h"
|
||||
#include "const.h"
|
||||
#include "common.h"
|
||||
|
@ -32,8 +31,6 @@ extern platform_exp_t *pi;
|
|||
extern byte *zonepool;
|
||||
extern jmp_buf abortframe;
|
||||
|
||||
extern int host_debug;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HOST_INIT, // initalize operations
|
||||
|
@ -74,6 +71,8 @@ typedef struct host_parm_s
|
|||
|
||||
extern host_parm_t host;
|
||||
|
||||
int Sys_Milliseconds (void);
|
||||
|
||||
bool _GetParmFromCmdLine( char *parm, char *out, size_t size );
|
||||
#define GetParmFromCmdLine( parm, out ) _GetParmFromCmdLine( parm, out, sizeof(out))
|
||||
|
||||
|
@ -117,7 +116,6 @@ filesystem manager
|
|||
#define FS_FileBase( x, y ) pi->Fs.FileBase( x, y )
|
||||
#define FS_Find( x ) pi->Fs.Search( x, false )
|
||||
#define FS_Printf pi->Fs.Printf
|
||||
#define FS_Print pi->Fs.Print
|
||||
#define FS_Seek pi->Fs.Seek
|
||||
#define FS_Tell pi->Fs.Tell
|
||||
#define FS_Gets pi->Fs.Gets
|
||||
|
@ -170,10 +168,4 @@ void Host_Init ( char *funcname, int argc, char **argv );
|
|||
void Host_Main ( void );
|
||||
void Host_Free ( void );
|
||||
|
||||
//
|
||||
// in_win.c
|
||||
//
|
||||
extern int mouse_x, mouse_y, old_mouse_x, old_mouse_y, mx_accum, my_accum;
|
||||
|
||||
|
||||
#endif//ENGINE_H
|
|
@ -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 <dsound.h>
|
||||
#include "engine.h"
|
||||
#include "progsvm.h"
|
||||
|
||||
platform_exp_t *pi; // fundamental callbacks
|
||||
platform_exp_t *pi; // fundamental callbacks
|
||||
host_parm_t host; // host parms
|
||||
|
||||
byte *zonepool;
|
||||
int ActiveApp;
|
||||
|
||||
// host params
|
||||
bool Minimized;
|
||||
extern uint sys_msg_time;
|
||||
|
||||
void Key_Init (void);
|
||||
void SCR_EndLoadingPlaque (void);
|
||||
|
@ -91,11 +90,10 @@ void Host_Init (char *funcname, int argc, char **argv)
|
|||
|
||||
MsgDev(D_INFO, "------- Loading bin/engine.dll [%g] -------\n", ENGINE_VERSION );
|
||||
|
||||
Cbuf_Init();
|
||||
Cmd_Init();
|
||||
Cvar_Init();
|
||||
Key_Init();
|
||||
PRVM_Init();
|
||||
Cbuf_Init ();
|
||||
Cmd_Init ();
|
||||
Cvar_Init ();
|
||||
Key_Init ();
|
||||
|
||||
// we need to add the early commands twice, because
|
||||
// a basedir or cddir needs to be set before execing
|
||||
|
@ -113,17 +111,18 @@ void Host_Init (char *funcname, int argc, char **argv)
|
|||
Cmd_AddCommand ("error", Com_Error_f);
|
||||
|
||||
host_speeds = Cvar_Get ("host_speeds", "0", 0);
|
||||
log_stats = Cvar_Get ("log_stats", "0", 0);
|
||||
developer = Cvar_Get ("developer", "0", 0);
|
||||
timescale = Cvar_Get ("timescale", "1", 0);
|
||||
fixedtime = Cvar_Get ("fixedtime", "0", 0);
|
||||
showtrace = Cvar_Get ("showtrace", "0", 0);
|
||||
if(host.type == HOST_DEDICATED) dedicated = Cvar_Get ("dedicated", "1", CVAR_NOSET);
|
||||
else dedicated = Cvar_Get ("dedicated", "0", CVAR_NOSET);
|
||||
|
||||
s = va("%4.2f %s %s %s", VERSION, "x86", __DATE__, BUILDSTRING);
|
||||
Cvar_Get ("version", s, CVAR_SERVERINFO|CVAR_NOSET);
|
||||
|
||||
if (host.type == HOST_DEDICATED)
|
||||
{
|
||||
Cmd_AddCommand ("quit", Com_Quit);
|
||||
}
|
||||
if (dedicated->value) Cmd_AddCommand ("quit", Com_Quit);
|
||||
|
||||
Sys_Init();
|
||||
|
||||
|
@ -134,10 +133,10 @@ void Host_Init (char *funcname, int argc, char **argv)
|
|||
CL_Init();
|
||||
|
||||
// add + commands from command line
|
||||
if (!Cbuf_AddLateCommands())
|
||||
if (!Cbuf_AddLateCommands ())
|
||||
{
|
||||
// if the user didn't give any commands, run default action
|
||||
if(host.type == HOST_NORMAL) Cbuf_AddText ("d1\n");
|
||||
if (!dedicated->value) Cbuf_AddText ("d1\n");
|
||||
else Cbuf_AddText ("dedicated_start\n");
|
||||
Cbuf_Execute ();
|
||||
}
|
||||
|
@ -156,9 +155,34 @@ Host_Frame
|
|||
void Host_Frame (double time)
|
||||
{
|
||||
char *s;
|
||||
static double time_before, time_between, time_after;
|
||||
|
||||
if (setjmp (abortframe) ) return; // an ERR_DROP was thrown
|
||||
|
||||
if ( log_stats->modified )
|
||||
{
|
||||
log_stats->modified = false;
|
||||
if ( log_stats->value )
|
||||
{
|
||||
if ( log_stats_file )
|
||||
{
|
||||
FS_Close( log_stats_file );
|
||||
log_stats_file = 0;
|
||||
}
|
||||
log_stats_file = FS_Open( "stats.log", "w" );
|
||||
if ( log_stats_file )
|
||||
FS_Printf( log_stats_file, "entities,dlights,parts,frame time\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( log_stats_file )
|
||||
{
|
||||
FS_Close( log_stats_file );
|
||||
log_stats_file = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (showtrace->value)
|
||||
{
|
||||
extern int c_traces, c_brush_traces;
|
||||
|
@ -173,14 +197,32 @@ void Host_Frame (double time)
|
|||
do
|
||||
{
|
||||
s = Sys_ConsoleInput ();
|
||||
if(s) Cbuf_AddText (va("%s\n",s));
|
||||
if (s) Cbuf_AddText (va("%s\n",s));
|
||||
} while (s);
|
||||
Cbuf_Execute ();
|
||||
|
||||
|
||||
if (host_speeds->value) time_before = Sys_DoubleTime();
|
||||
|
||||
SV_Frame (time);
|
||||
|
||||
if (host_speeds->value) time_between = Sys_DoubleTime();
|
||||
|
||||
CL_Frame (time);
|
||||
|
||||
host.framecount++;
|
||||
if (host_speeds->value) time_after = Sys_DoubleTime();
|
||||
if (host_speeds->value)
|
||||
{
|
||||
double all, sv, gm, cl, rf;
|
||||
|
||||
all = time_after - time_before;
|
||||
sv = time_between - time_before;
|
||||
cl = time_after - time_between;
|
||||
gm = time_after_game - time_before_game;
|
||||
rf = time_after_ref - time_before_ref;
|
||||
sv -= gm;
|
||||
cl -= rf;
|
||||
Msg ("all:%.3f sv:%.3f gm:%.3f cl:%.3f rf:%.3f\n", all, sv, gm, cl, rf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -190,38 +232,36 @@ Host_Main
|
|||
*/
|
||||
void Host_Main( void )
|
||||
{
|
||||
MSG msg;
|
||||
static double oldtime, newtime;
|
||||
MSG msg;
|
||||
int time, oldtime, newtime;
|
||||
|
||||
host.state = HOST_FRAME;
|
||||
oldtime = Sys_DoubleTime(); //first call
|
||||
oldtime = Sys_Milliseconds ();
|
||||
|
||||
// main window message loop
|
||||
while (host.type != HOST_OFFLINE)
|
||||
while (1)
|
||||
{
|
||||
// if at a full screen console, don't update unless needed
|
||||
if (host.type == HOST_DEDICATED )
|
||||
if (Minimized || (dedicated && dedicated->value) )
|
||||
{
|
||||
Sleep( 1 );
|
||||
Sleep (1);
|
||||
}
|
||||
else if(host.state == HOST_SLEEP) Sleep( 100 );
|
||||
|
||||
|
||||
while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
|
||||
{
|
||||
if (!GetMessage (&msg, NULL, 0, 0)) Com_Quit ();
|
||||
host.sv_timer = msg.time;
|
||||
sys_msg_time = msg.time;
|
||||
TranslateMessage (&msg);
|
||||
DispatchMessage (&msg);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
newtime = Sys_DoubleTime();
|
||||
host.realtime = newtime - oldtime;
|
||||
newtime = Sys_Milliseconds ();
|
||||
time = newtime - oldtime;
|
||||
} while (time < 1);
|
||||
|
||||
} while (host.realtime < 0.001);
|
||||
_controlfp( _PC_24, _MCW_PC );
|
||||
Host_Frame (time);
|
||||
|
||||
Host_Frame (host.realtime);
|
||||
oldtime = newtime;
|
||||
}
|
||||
}
|
||||
|
@ -234,9 +274,6 @@ Host_Shutdown
|
|||
*/
|
||||
void Host_Free (void)
|
||||
{
|
||||
host.state = HOST_SHUTDOWN;
|
||||
|
||||
SV_Shutdown ("Server shutdown\n", false);
|
||||
CL_Shutdown ();
|
||||
Host_FreePlatform();
|
||||
}
|
|
@ -24,7 +24,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "engine.h"
|
||||
#include "./client/client.h"
|
||||
|
||||
extern unsigned sys_msg_time;
|
||||
extern HWND cl_hwnd;
|
||||
extern bool ActiveApp, Minimized;
|
||||
|
||||
// joystick defines and variables
|
||||
// where should defines be moved?
|
||||
|
@ -249,13 +251,13 @@ void IN_MouseEvent (int mstate)
|
|||
if ( (mstate & (1<<i)) &&
|
||||
!(mouse_oldbuttonstate & (1<<i)) )
|
||||
{
|
||||
Key_Event (K_MOUSE1 + i, true, host.sv_timer);
|
||||
Key_Event (K_MOUSE1 + i, true, sys_msg_time);
|
||||
}
|
||||
|
||||
if ( !(mstate & (1<<i)) &&
|
||||
(mouse_oldbuttonstate & (1<<i)) )
|
||||
{
|
||||
Key_Event (K_MOUSE1 + i, false, host.sv_timer);
|
||||
Key_Event (K_MOUSE1 + i, false, sys_msg_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -449,7 +451,7 @@ void IN_Move (usercmd_t *cmd)
|
|||
{
|
||||
IN_MouseMove (cmd);
|
||||
|
||||
if (host.state == HOST_FRAME)
|
||||
if (ActiveApp)
|
||||
IN_JoyMove (cmd);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
#ifndef SERVER_H
|
||||
#define SERVER_H
|
||||
|
||||
|
||||
//define PARANOID // speed sapping error checking
|
||||
|
||||
#include "progsvm.h"
|
||||
#include "vm_cmds.h"
|
||||
#include "ref_server.h"
|
||||
|
||||
//=============================================================================
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gclient_t *clients; // [maxclients]
|
||||
|
||||
int maxclients;
|
||||
int maxentities;
|
||||
|
||||
bool autosaved;
|
||||
} game_locals_t;
|
||||
|
||||
#define MAX_MASTERS 8 // max recipients for heartbeat packets
|
||||
|
||||
typedef enum {
|
||||
|
@ -45,18 +53,14 @@ typedef struct
|
|||
{
|
||||
server_state_t state; // precache commands are only valid during load
|
||||
|
||||
bool attractloop; // running cinematics and demos for the local system only
|
||||
bool loadgame; // client begins should reuse existing entity
|
||||
bool attractloop; // running cinematics and demos for the local system only
|
||||
bool loadgame; // client begins should reuse existing entity
|
||||
|
||||
unsigned time; // always sv.framenum * 100 msec
|
||||
int framenum;
|
||||
|
||||
float time; // always sv.framenum * 0.1 sec
|
||||
float frametime;
|
||||
float lastchecktime;
|
||||
int framenum;
|
||||
|
||||
int lastcheck;
|
||||
|
||||
char name[MAX_QPATH]; // map name, or cinematic name
|
||||
cmodel_t *models[MAX_MODELS];
|
||||
struct cmodel_s *models[MAX_MODELS];
|
||||
|
||||
char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH];
|
||||
entity_state_t baselines[MAX_EDICTS];
|
||||
|
@ -66,20 +70,23 @@ typedef struct
|
|||
sizebuf_t multicast;
|
||||
byte multicast_buf[MAX_MSGLEN];
|
||||
|
||||
prvm_edict_t **moved_edicts;
|
||||
|
||||
// demo server information
|
||||
file_t *demofile;
|
||||
bool timedemo; // don't time sync
|
||||
bool timedemo; // don't time sync
|
||||
|
||||
byte *mempool;
|
||||
} server_t;
|
||||
|
||||
#define EDICT_NUM(n) ((edict_t *)((byte *)ge->edicts + ge->edict_size * (n) ))
|
||||
#define NUM_FOR_EDICT(e) ( ((byte *)(e) - (byte *)ge->edicts ) / ge->edict_size)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
cs_free, // can be reused for a new connection
|
||||
cs_zombie, // client has been disconnected, but don't reuse
|
||||
// connection for a couple seconds
|
||||
cs_zombie, // client has been disconnected, but don't reuse
|
||||
// connection for a couple seconds
|
||||
cs_connected, // has been assigned to a client_t, but not in game yet
|
||||
cs_spawned // client is fully in game
|
||||
cs_spawned // client is fully in game
|
||||
} client_state_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -92,52 +99,49 @@ typedef struct
|
|||
int senttime; // for ping calculations
|
||||
} client_frame_t;
|
||||
|
||||
#define NUM_SPAWN_PARMS 16
|
||||
#define LATENCY_COUNTS 16
|
||||
#define RATE_MESSAGES 10
|
||||
|
||||
typedef struct client_s
|
||||
{
|
||||
client_state_t state;
|
||||
client_state_t state;
|
||||
|
||||
char userinfo[MAX_INFO_STRING]; // name, etc
|
||||
|
||||
int lastframe; // for delta compression
|
||||
usercmd_t lastcmd; // for filling in big drops
|
||||
int lastframe; // for delta compression
|
||||
usercmd_t lastcmd; // for filling in big drops
|
||||
|
||||
int commandMsec; // every seconds this is reset, if user
|
||||
// commands exhaust it, assume time cheating
|
||||
int commandMsec; // every seconds this is reset, if user
|
||||
// commands exhaust it, assume time cheating
|
||||
|
||||
int frame_latency[LATENCY_COUNTS];
|
||||
int ping;
|
||||
int frame_latency[LATENCY_COUNTS];
|
||||
int ping;
|
||||
|
||||
int message_size[RATE_MESSAGES]; // used to rate drop packets
|
||||
int rate;
|
||||
int surpressCount; // number of messages rate supressed
|
||||
int message_size[RATE_MESSAGES]; // used to rate drop packets
|
||||
int rate;
|
||||
int surpressCount; // number of messages rate supressed
|
||||
|
||||
float spawn_parms[NUM_SPAWN_PARMS]; // quake 1 legacy
|
||||
|
||||
prvm_edict_t *edict; // EDICT_NUM(clientnum+1)
|
||||
edict_t *edict; // EDICT_NUM(clientnum+1)
|
||||
char name[32]; // extracted from userinfo, high bits masked
|
||||
int messagelevel; // for filtering printed messages
|
||||
int messagelevel; // for filtering printed messages
|
||||
|
||||
// The datagram is written to by sound calls, prints, temp ents, etc.
|
||||
// It can be harmlessly overflowed.
|
||||
sizebuf_t datagram;
|
||||
sizebuf_t datagram;
|
||||
byte datagram_buf[MAX_MSGLEN];
|
||||
|
||||
client_frame_t frames[UPDATE_BACKUP]; // updates can be delta'd from here
|
||||
client_frame_t frames[UPDATE_BACKUP]; // updates can be delta'd from here
|
||||
|
||||
byte *download; // file being downloaded
|
||||
int downloadsize; // total bytes (can't use EOF because of paks)
|
||||
int downloadcount; // bytes sent
|
||||
int downloadsize; // total bytes (can't use EOF because of paks)
|
||||
int downloadcount; // bytes sent
|
||||
|
||||
float lastmessage; // sv.framenum when packet was last received
|
||||
float lastconnect;
|
||||
int lastmessage; // sv.framenum when packet was last received
|
||||
int lastconnect;
|
||||
|
||||
int challenge; // challenge of this user, randomly generated
|
||||
int challenge; // challenge of this user, randomly generated
|
||||
|
||||
netchan_t netchan;
|
||||
netchan_t netchan;
|
||||
} client_t;
|
||||
|
||||
// a client can leave the server in one of four ways:
|
||||
|
@ -164,9 +168,7 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
bool initialized; // sv_init has completed
|
||||
double realtime; // always increasing, no clamping, etc
|
||||
|
||||
int serverflags;
|
||||
int realtime; // always increasing, no clamping, etc
|
||||
|
||||
char mapcmd[MAX_TOKEN_CHARS]; // ie: *intro.cin+base
|
||||
char comment[MAX_TOKEN_CHARS]; // map name, e.t.c.
|
||||
|
@ -174,12 +176,12 @@ typedef struct
|
|||
int spawncount; // incremented each server start
|
||||
// used to check late spawns
|
||||
|
||||
client_t *clients; // [host.maxclients];
|
||||
int num_client_entities; // host.maxclients * UPDATE_BACKUP * MAX_PACKET_ENTITIES
|
||||
client_t *clients; // [maxclients->value];
|
||||
int num_client_entities; // maxclients->value*UPDATE_BACKUP*MAX_PACKET_ENTITIES
|
||||
int next_client_entities; // next client_entity to use
|
||||
entity_state_t *client_entities; // [num_client_entities]
|
||||
|
||||
float last_heartbeat;
|
||||
int last_heartbeat;
|
||||
|
||||
challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting
|
||||
|
||||
|
@ -189,17 +191,6 @@ typedef struct
|
|||
byte demo_multicast_buf[MAX_MSGLEN];
|
||||
} server_static_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t boxmins, boxmaxs; // enclose the test object along entire move
|
||||
float *mins, *maxs; // size of the moving object
|
||||
vec3_t mins2, maxs2; // size when clipping against mosnters
|
||||
float *start, *end;
|
||||
trace_t trace;
|
||||
prvm_edict_t *passedict;
|
||||
int contentmask;
|
||||
} moveclip_t;
|
||||
|
||||
//=============================================================================
|
||||
|
||||
extern netadr_t net_from;
|
||||
|
@ -211,13 +202,17 @@ extern server_static_t svs; // persistant server info
|
|||
extern server_t sv; // local server
|
||||
|
||||
extern cvar_t *sv_paused;
|
||||
extern cvar_t *maxclients;
|
||||
extern cvar_t *sv_noreload; // don't reload level state when reentering
|
||||
extern cvar_t *sv_airaccelerate; // don't reload level state when reentering
|
||||
extern cvar_t *sv_maxvelocity;
|
||||
extern cvar_t *sv_gravity;
|
||||
// development tool
|
||||
extern cvar_t *sv_enforcetime;
|
||||
|
||||
extern client_t *sv_client;
|
||||
extern prvm_edict_t *sv_player;
|
||||
extern client_t *sv_client;
|
||||
extern edict_t *sv_player;
|
||||
extern game_locals_t game;
|
||||
|
||||
//===========================================================
|
||||
|
||||
|
@ -227,9 +222,9 @@ extern prvm_edict_t *sv_player;
|
|||
void SV_FinalMessage (char *message, bool reconnect);
|
||||
void SV_DropClient (client_t *drop);
|
||||
|
||||
int SV_ModelIndex (const char *name);
|
||||
int SV_SoundIndex (const char *name);
|
||||
int SV_ImageIndex (const char *name);
|
||||
int SV_ModelIndex (char *name);
|
||||
int SV_SoundIndex (char *name);
|
||||
int SV_ImageIndex (char *name);
|
||||
|
||||
void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg);
|
||||
|
||||
|
@ -248,16 +243,15 @@ void Master_Packet (void);
|
|||
//
|
||||
void SV_InitGame (void);
|
||||
void SV_Map (bool attractloop, char *levelstring, char *savename, bool loadgame);
|
||||
void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_state_t serverstate, bool attractloop, bool loadgame);
|
||||
void SV_VM_Setup(void);
|
||||
void SV_VM_Begin(void);
|
||||
void SV_VM_End(void);
|
||||
|
||||
|
||||
//
|
||||
// sv_phys.c
|
||||
//
|
||||
void SV_PrepWorldFrame (void);
|
||||
void SV_Physics (void);
|
||||
void SV_Physics (edict_t *ent);
|
||||
void SV_DropToFloor (edict_t *ent);
|
||||
void SV_CheckGround (edict_t *ent);
|
||||
|
||||
//
|
||||
// sv_send.c
|
||||
|
@ -271,7 +265,7 @@ void SV_FlushRedirect (int sv_redirected, char *outputbuf);
|
|||
|
||||
void SV_DemoCompleted (void);
|
||||
void SV_SendClientMessages (void);
|
||||
void SV_StartSound (vec3_t origin, prvm_edict_t *entity, int channel,
|
||||
void SV_StartSound (vec3_t origin, edict_t *entity, int channel,
|
||||
int soundindex, float volume,
|
||||
float attenuation, float timeofs);
|
||||
void SV_ClientPrintf (client_t *cl, int level, char *fmt, ...);
|
||||
|
@ -283,8 +277,6 @@ void SV_BroadcastCommand (char *fmt, ...);
|
|||
//
|
||||
void SV_Nextserver (void);
|
||||
void SV_ExecuteClientMessage (client_t *cl);
|
||||
void SV_ApplyClientMove (void);
|
||||
void SV_ClientThink (void);
|
||||
|
||||
//
|
||||
// sv_ccmds.c
|
||||
|
@ -297,19 +289,50 @@ void SV_Status_f (void);
|
|||
void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg);
|
||||
void SV_RecordDemoMessage (void);
|
||||
void SV_BuildClientFrame (client_t *client);
|
||||
void SV_FatPVS (vec3_t org);
|
||||
|
||||
|
||||
void SV_Error (char *error, ...);
|
||||
void SV_InitEdict (prvm_edict_t *e);
|
||||
|
||||
//
|
||||
// sv_game.c
|
||||
//
|
||||
extern game_export_t *ge;
|
||||
|
||||
void SV_InitGameProgs (void);
|
||||
void SV_ShutdownGameProgs (void);
|
||||
void SV_InitEdict (edict_t *e);
|
||||
|
||||
// misc game funcs
|
||||
void PF_error (char *fmt, ...);
|
||||
void PF_Configstring (int index, char *val);
|
||||
void PF_setmodel (edict_t *ent, char *name);
|
||||
void PF_cprintf (edict_t *ent, int level, char *fmt, ...);
|
||||
bool PF_inPVS (vec3_t p1, vec3_t p2);
|
||||
void PF_StartSound (edict_t *entity, int channel, int sound_num, float volume, float attenuation, float timeofs);
|
||||
|
||||
//
|
||||
// sv_studio.c
|
||||
//
|
||||
|
||||
byte *SV_GetModelPtr(prvm_edict_t *ent);
|
||||
byte *SV_GetModelPtr(edict_t *ent);
|
||||
int SV_StudioExtractBbox( studiohdr_t *phdr, int sequence, float *mins, float *maxs );
|
||||
|
||||
//
|
||||
// sv_spawn.c
|
||||
//
|
||||
|
||||
void SV_SpawnEntities (char *mapname, char *entities, char *spawnpoint);
|
||||
void SV_FreeEdict (edict_t *ed);
|
||||
void SV_InitEdict (edict_t *e);
|
||||
edict_t *SV_Spawn (void);
|
||||
void SV_RunFrame (void);
|
||||
void SV_ClientUserinfoChanged (edict_t *ent, char *userinfo);
|
||||
bool SV_ClientConnect (edict_t *ent, char *userinfo);
|
||||
void SV_ClientBegin (edict_t *ent);
|
||||
void ClientThink (edict_t *ent, usercmd_t *ucmd);
|
||||
void SV_ClientDisconnect (edict_t *ent);
|
||||
void SV_ClientCommand (edict_t *ent);
|
||||
void SV_TouchTriggers (edict_t *ent);
|
||||
|
||||
//
|
||||
// sv_save.c
|
||||
|
@ -327,18 +350,18 @@ void SV_ReadLevelFile( char *name );
|
|||
void SV_ClearWorld (void);
|
||||
// called after the world model has been loaded, before linking any entities
|
||||
|
||||
void SV_UnlinkEdict (prvm_edict_t *ent);
|
||||
void SV_UnlinkEdict (edict_t *ent);
|
||||
// call before removing an entity, and before trying to move one,
|
||||
// so it doesn't clip against itself
|
||||
|
||||
void SV_LinkEdict (prvm_edict_t *ent);
|
||||
void SV_LinkEdict (edict_t *ent);
|
||||
// Needs to be called any time an entity changes origin, mins, maxs,
|
||||
// or solid. Automatically unlinks if needed.
|
||||
// sets ent->v.absmin and ent->v.absmax
|
||||
// sets ent->leafnums[] for pvs determination even if the entity
|
||||
// is not solid
|
||||
|
||||
int SV_AreaEdicts (vec3_t mins, vec3_t maxs, prvm_edict_t **list, int maxcount, int areatype);
|
||||
int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype);
|
||||
// fills in a table of edict pointers with edicts that have bounding boxes
|
||||
// that intersect the given area. It is possible for a non-axial bmodel
|
||||
// to be returned that doesn't actually intersect the area on an exact
|
||||
|
@ -356,10 +379,7 @@ int SV_PointContents (vec3_t p);
|
|||
// Quake 2 extends this to also check entities, to allow moving liquids
|
||||
|
||||
|
||||
trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, prvm_edict_t *passedict, int contentmask);
|
||||
trace_t SV_TraceToss (prvm_edict_t *tossent, prvm_edict_t *ignore);
|
||||
trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int contentsmask);
|
||||
|
||||
trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask);
|
||||
// mins and maxs are relative
|
||||
|
||||
// if the entire move stays in a solid volume, trace.allsolid will be set,
|
||||
|
@ -368,6 +388,4 @@ trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, vec3_t start, vec3_t mins, vec3_t
|
|||
// if the starting point is in a solid, it will be allowed to move out
|
||||
// to an open area
|
||||
|
||||
// passedict is explicitly excluded from clipping checks (normally NULL)
|
||||
|
||||
#endif//SERVER_H
|
||||
// passedict is explicitly excluded from clipping checks (normally NULL)
|
|
@ -43,7 +43,7 @@ void SV_SetMaster_f (void)
|
|||
int i, slot;
|
||||
|
||||
// only dedicated servers send heartbeats
|
||||
if (host.type == HOST_NORMAL)
|
||||
if (!dedicated->value)
|
||||
{
|
||||
Msg ("Only dedicated servers use masters.\n");
|
||||
return;
|
||||
|
@ -52,11 +52,11 @@ void SV_SetMaster_f (void)
|
|||
// make sure the server is listed public
|
||||
Cvar_Set ("public", "1");
|
||||
|
||||
for (i = 1; i < MAX_MASTERS; i++) memset (&master_adr[i], 0, sizeof(master_adr[i]));
|
||||
for (i=1 ; i<MAX_MASTERS ; i++)
|
||||
memset (&master_adr[i], 0, sizeof(master_adr[i]));
|
||||
|
||||
slot = 1; // slot 0 will always contain the id master
|
||||
|
||||
for (i = 1; i < Cmd_Argc(); i++)
|
||||
slot = 1; // slot 0 will always contain the id master
|
||||
for (i=1 ; i<Cmd_Argc() ; i++)
|
||||
{
|
||||
if (slot == MAX_MASTERS)
|
||||
break;
|
||||
|
@ -106,7 +106,7 @@ bool SV_SetPlayer (void)
|
|||
if (s[0] >= '0' && s[0] <= '9')
|
||||
{
|
||||
idnum = atoi(Cmd_Argv(1));
|
||||
if (idnum < 0 || idnum >= host.maxclients)
|
||||
if (idnum < 0 || idnum >= maxclients->value)
|
||||
{
|
||||
Msg ("Bad client slot: %i\n", idnum);
|
||||
return false;
|
||||
|
@ -123,7 +123,7 @@ bool SV_SetPlayer (void)
|
|||
}
|
||||
|
||||
// check for a name match
|
||||
for (i=0,cl=svs.clients ; i < host.maxclients; i++,cl++)
|
||||
for (i=0,cl=svs.clients ; i<maxclients->value; i++,cl++)
|
||||
{
|
||||
if (!cl->state)
|
||||
continue;
|
||||
|
@ -192,18 +192,18 @@ void SV_GameMap_f (void)
|
|||
// clear all the client inuse flags before saving so that
|
||||
// when the level is re-entered, the clients will spawn
|
||||
// at spawn points instead of occupying body shells
|
||||
savedInuse = Z_Malloc(host.maxclients * sizeof(bool));
|
||||
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
|
||||
savedInuse = Z_Malloc(maxclients->value * sizeof(bool));
|
||||
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
|
||||
{
|
||||
savedInuse[i] = cl->edict->priv.sv->free;
|
||||
cl->edict->priv.sv->free = true;
|
||||
savedInuse[i] = cl->edict->inuse;
|
||||
cl->edict->inuse = false;
|
||||
}
|
||||
|
||||
SV_WriteSaveFile( "save0" ); //autosave
|
||||
|
||||
// we must restore these for clients to transfer over correctly
|
||||
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
|
||||
cl->edict->priv.sv->free = savedInuse[i];
|
||||
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
|
||||
cl->edict->inuse = savedInuse[i];
|
||||
Z_Free (savedInuse);
|
||||
}
|
||||
}
|
||||
|
@ -225,28 +225,23 @@ For development work
|
|||
*/
|
||||
void SV_Map_f (void)
|
||||
{
|
||||
char level_path[MAX_QPATH];
|
||||
char *map;
|
||||
char expanded[MAX_QPATH];
|
||||
|
||||
sprintf(level_path, "maps/%s", Cmd_Argv(1));
|
||||
FS_DefaultExtension(level_path, ".bsp" );
|
||||
|
||||
if (FS_FileExists(level_path))
|
||||
// if not a pcx, demo, or cinematic, check to make sure the level exists
|
||||
map = Cmd_Argv(1);
|
||||
if (!strstr (map, "."))
|
||||
{
|
||||
sv.state = ss_dead; // don't save current level when changing
|
||||
|
||||
SV_InitGame ();
|
||||
Cvar_Set ("nextserver", ""); //reset demoloop
|
||||
|
||||
SCR_BeginLoadingPlaque (); // for local system
|
||||
SV_BroadcastCommand ("changing\n");
|
||||
|
||||
SV_SendClientMessages ();
|
||||
SV_SpawnServer (level_path, NULL, NULL, ss_game, false, false);
|
||||
Cbuf_CopyToDefer ();
|
||||
//FIXME//SV_BroadcastCommand ("reconnect\n");
|
||||
strncpy (svs.mapcmd, Cmd_Argv(1), sizeof(svs.mapcmd) - 1); // archive server state
|
||||
sprintf (expanded, "maps/%s.bsp", map);
|
||||
if (!FS_LoadFile (expanded, NULL))
|
||||
{
|
||||
Msg ("Can't find %s\n", expanded);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else Msg ("Can't loading %s\n", level_path);
|
||||
|
||||
sv.state = ss_dead; // don't save current level when changing
|
||||
SV_GameMap_f ();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -314,7 +309,7 @@ void SV_Savegame_f (void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (host.maxclients == 1 && svs.clients[0].edict->priv.sv->client->stats[STAT_HEALTH] <= 0)
|
||||
if (maxclients->value == 1 && svs.clients[0].edict->client->ps.stats[STAT_HEALTH] <= 0)
|
||||
{
|
||||
Msg ("\nCan't savegame while dead!\n");
|
||||
return;
|
||||
|
@ -382,11 +377,11 @@ void SV_Status_f (void)
|
|||
|
||||
Msg ("num score ping name lastmsg address qport \n");
|
||||
Msg ("--- ----- ---- --------------- ------- --------------------- ------\n");
|
||||
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
|
||||
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
|
||||
{
|
||||
if (!cl->state) continue;
|
||||
Msg ("%3i ", i);
|
||||
Msg ("%5i ", cl->edict->priv.sv->client->stats[STAT_FRAGS]);
|
||||
Msg ("%5i ", cl->edict->client->ps.stats[STAT_FRAGS]);
|
||||
|
||||
if (cl->state == cs_connected)
|
||||
Msg ("CNCT ");
|
||||
|
@ -403,7 +398,7 @@ void SV_Status_f (void)
|
|||
for (j=0 ; j<l ; j++)
|
||||
Msg (" ");
|
||||
|
||||
Msg ("%g ", svs.realtime - cl->lastmessage );
|
||||
Msg ("%7i ", svs.realtime - cl->lastmessage );
|
||||
|
||||
s = NET_AdrToString ( cl->netchan.remote_address);
|
||||
Msg ("%s", s);
|
||||
|
@ -444,7 +439,7 @@ void SV_ConSay_f(void)
|
|||
|
||||
strcat(text, p);
|
||||
|
||||
for (j = 0, client = svs.clients; j < host.maxclients; j++, client++)
|
||||
for (j = 0, client = svs.clients; j < maxclients->value; j++, client++)
|
||||
{
|
||||
if (client->state != cs_spawned)
|
||||
continue;
|
||||
|
@ -622,6 +617,22 @@ void SV_KillServer_f (void)
|
|||
NET_Config ( false ); // close network sockets
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
SV_ServerCommand_f
|
||||
|
||||
Let the game dll handle a command
|
||||
===============
|
||||
*/
|
||||
void SV_ServerCommand_f (void)
|
||||
{
|
||||
if (!ge)
|
||||
{
|
||||
Msg ("No game loaded.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================
|
||||
|
||||
/*
|
||||
|
@ -642,15 +653,13 @@ void SV_InitOperatorCommands (void)
|
|||
Cmd_AddCommand ("gamemap", SV_GameMap_f);
|
||||
Cmd_AddCommand ("setmaster", SV_SetMaster_f);
|
||||
|
||||
if (host.type == HOST_DEDICATED)
|
||||
{
|
||||
Cmd_AddCommand ("say", SV_ConSay_f);
|
||||
}
|
||||
if ( dedicated->value ) Cmd_AddCommand ("say", SV_ConSay_f);
|
||||
|
||||
Cmd_AddCommand ("serverrecord", SV_ServerRecord_f);
|
||||
Cmd_AddCommand ("serverstop", SV_ServerStop_f);
|
||||
Cmd_AddCommand ("save", SV_Savegame_f);
|
||||
Cmd_AddCommand ("load", SV_Loadgame_f);
|
||||
Cmd_AddCommand ("killserver", SV_KillServer_f);
|
||||
Cmd_AddCommand ("sv", SV_ServerCommand_f);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,11 +34,11 @@ Encode a client frame onto the network channel
|
|||
// because there can be a lot of projectiles, there is a special
|
||||
// network protocol for them
|
||||
#define MAX_PROJECTILES 64
|
||||
prvm_edict_t *projectiles[MAX_PROJECTILES];
|
||||
edict_t *projectiles[MAX_PROJECTILES];
|
||||
int numprojs;
|
||||
cvar_t *sv_projectiles;
|
||||
|
||||
bool SV_AddProjectileUpdate (prvm_edict_t *ent)
|
||||
bool SV_AddProjectileUpdate (edict_t *ent)
|
||||
{
|
||||
if (!sv_projectiles)
|
||||
sv_projectiles = Cvar_Get("sv_projectiles", "1", 0);
|
||||
|
@ -59,7 +59,7 @@ void SV_EmitProjectileUpdate (sizebuf_t *msg)
|
|||
{
|
||||
byte bits[16]; // [modelindex] [48 bits] xyz p y 12 12 12 8 8 [entitynum] [e2]
|
||||
int n, i;
|
||||
prvm_edict_t *ent;
|
||||
edict_t *ent;
|
||||
int x, y, z, p, yaw;
|
||||
int len;
|
||||
|
||||
|
@ -157,31 +157,29 @@ void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t
|
|||
}
|
||||
|
||||
if (newnum == oldnum)
|
||||
{
|
||||
// delta update from old position
|
||||
{ // delta update from old position
|
||||
// because the force parm is false, this will not result
|
||||
// in any bytes being emited if the entity has not changed at all
|
||||
// note that players are always 'newentities', this updates their oldorigin always
|
||||
// and prevents warping
|
||||
MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= host.maxclients);
|
||||
MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= maxclients->value);
|
||||
oldindex++;
|
||||
newindex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newnum < oldnum)
|
||||
{
|
||||
// this is a new entity, send it from the baseline
|
||||
{ // this is a new entity, send it from the baseline
|
||||
MSG_WriteDeltaEntity (&sv.baselines[newnum], newent, msg, true, true);
|
||||
newindex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newnum > oldnum)
|
||||
{
|
||||
// the old entity isn't present in the new message
|
||||
{ // the old entity isn't present in the new message
|
||||
bits = U_REMOVE;
|
||||
if (oldnum >= 256) bits |= U_NUMBER16 | U_MOREBITS1;
|
||||
if (oldnum >= 256)
|
||||
bits |= U_NUMBER16 | U_MOREBITS1;
|
||||
|
||||
MSG_WriteByte (msg, bits&255 );
|
||||
if (bits & 0x0000ff00)
|
||||
|
@ -201,6 +199,11 @@ void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t
|
|||
}
|
||||
|
||||
MSG_WriteShort (msg, 0); // end of packetentities
|
||||
|
||||
#if 0
|
||||
if (numprojs)
|
||||
SV_EmitProjectileUpdate(msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -228,32 +231,86 @@ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, size
|
|||
else ops = &from->ps;
|
||||
|
||||
// determine what needs to be sent
|
||||
if (ps->pmove.pm_type != ops->pmove.pm_type) pflags |= PS_M_TYPE;
|
||||
if (!VectorICompare(ps->pmove.origin, ops->pmove.origin)) pflags |= PS_M_ORIGIN;
|
||||
if (!VectorICompare(ps->pmove.velocity, ops->pmove.velocity)) pflags |= PS_M_VELOCITY;
|
||||
if (ps->pmove.pm_time != ops->pmove.pm_time) pflags |= PS_M_TIME;
|
||||
if (ps->pmove.pm_flags != ops->pmove.pm_flags) pflags |= PS_M_FLAGS;
|
||||
if (ps->pmove.gravity != ops->pmove.gravity) pflags |= PS_M_GRAVITY;
|
||||
if (!VectorICompare(ps->pmove.delta_angles, ops->pmove.delta_angles)) pflags |= PS_M_DELTA_ANGLES;
|
||||
if (!VectorCompare(ps->viewoffset, ops->viewoffset)) pflags |= PS_VIEWOFFSET;
|
||||
if (!VectorCompare(ps->viewangles, ops->viewangles)) pflags |= PS_VIEWANGLES;
|
||||
if (!VectorCompare(ps->kick_angles, ops->kick_angles)) pflags |= PS_KICKANGLES;
|
||||
if (!VectorCompare(ps->blend, ops->blend)) pflags |= PS_BLEND;
|
||||
if (ps->fov != ops->fov) pflags |= PS_FOV;
|
||||
if (ps->rdflags != ops->rdflags) pflags |= PS_RDFLAGS;
|
||||
if (ps->gunframe != ops->gunframe) pflags |= PS_WEAPONFRAME;
|
||||
if (ps->sequence != ops->sequence) pflags |= PS_WEAPONSEQUENCE;
|
||||
if (ps->gunbody != ops->gunbody) pflags |= PS_WEAPONBODY;
|
||||
if (ps->gunskin != ops->gunskin) pflags |= PS_WEAPONSKIN;
|
||||
if (ps->pmove.pm_type != ops->pmove.pm_type)
|
||||
pflags |= PS_M_TYPE;
|
||||
|
||||
if (ps->pmove.origin[0] != ops->pmove.origin[0]
|
||||
|| ps->pmove.origin[1] != ops->pmove.origin[1]
|
||||
|| ps->pmove.origin[2] != ops->pmove.origin[2] )
|
||||
pflags |= PS_M_ORIGIN;
|
||||
|
||||
if (ps->pmove.velocity[0] != ops->pmove.velocity[0]
|
||||
|| ps->pmove.velocity[1] != ops->pmove.velocity[1]
|
||||
|| ps->pmove.velocity[2] != ops->pmove.velocity[2] )
|
||||
pflags |= PS_M_VELOCITY;
|
||||
|
||||
if (ps->pmove.pm_time != ops->pmove.pm_time)
|
||||
pflags |= PS_M_TIME;
|
||||
|
||||
if (ps->pmove.pm_flags != ops->pmove.pm_flags)
|
||||
pflags |= PS_M_FLAGS;
|
||||
|
||||
if (ps->pmove.gravity != ops->pmove.gravity)
|
||||
pflags |= PS_M_GRAVITY;
|
||||
|
||||
if (ps->pmove.delta_angles[0] != ops->pmove.delta_angles[0]
|
||||
|| ps->pmove.delta_angles[1] != ops->pmove.delta_angles[1]
|
||||
|| ps->pmove.delta_angles[2] != ops->pmove.delta_angles[2] )
|
||||
pflags |= PS_M_DELTA_ANGLES;
|
||||
|
||||
|
||||
if (ps->viewoffset[0] != ops->viewoffset[0]
|
||||
|| ps->viewoffset[1] != ops->viewoffset[1]
|
||||
|| ps->viewoffset[2] != ops->viewoffset[2] )
|
||||
pflags |= PS_VIEWOFFSET;
|
||||
|
||||
if (ps->viewangles[0] != ops->viewangles[0]
|
||||
|| ps->viewangles[1] != ops->viewangles[1]
|
||||
|| ps->viewangles[2] != ops->viewangles[2] )
|
||||
pflags |= PS_VIEWANGLES;
|
||||
|
||||
if (ps->kick_angles[0] != ops->kick_angles[0]
|
||||
|| ps->kick_angles[1] != ops->kick_angles[1]
|
||||
|| ps->kick_angles[2] != ops->kick_angles[2] )
|
||||
pflags |= PS_KICKANGLES;
|
||||
|
||||
if (ps->blend[0] != ops->blend[0]
|
||||
|| ps->blend[1] != ops->blend[1]
|
||||
|| ps->blend[2] != ops->blend[2]
|
||||
|| ps->blend[3] != ops->blend[3] )
|
||||
pflags |= PS_BLEND;
|
||||
|
||||
if (ps->fov != ops->fov)
|
||||
pflags |= PS_FOV;
|
||||
|
||||
if (ps->rdflags != ops->rdflags)
|
||||
pflags |= PS_RDFLAGS;
|
||||
|
||||
if (ps->gunframe != ops->gunframe)
|
||||
pflags |= PS_WEAPONFRAME;
|
||||
|
||||
if (ps->sequence != ops->sequence)
|
||||
pflags |= PS_WEAPONSEQUENCE;
|
||||
|
||||
if (ps->gunbody != ops->gunbody)
|
||||
pflags |= PS_WEAPONBODY;
|
||||
|
||||
if (ps->gunskin != ops->gunskin)
|
||||
pflags |= PS_WEAPONSKIN;
|
||||
|
||||
pflags |= PS_WEAPONINDEX;
|
||||
|
||||
//
|
||||
// write it
|
||||
//
|
||||
MSG_WriteByte (msg, svc_playerinfo);
|
||||
MSG_WriteLong (msg, pflags);
|
||||
|
||||
//
|
||||
// write the pmove_state_t
|
||||
if (pflags & PS_M_TYPE) MSG_WriteByte (msg, ps->pmove.pm_type);
|
||||
//
|
||||
if (pflags & PS_M_TYPE)
|
||||
MSG_WriteByte (msg, ps->pmove.pm_type);
|
||||
|
||||
if (pflags & PS_M_ORIGIN)
|
||||
{
|
||||
|
@ -269,9 +326,14 @@ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, size
|
|||
MSG_WriteShort (msg, ps->pmove.velocity[2]);
|
||||
}
|
||||
|
||||
if (pflags & PS_M_TIME) MSG_WriteByte (msg, ps->pmove.pm_time);
|
||||
if (pflags & PS_M_FLAGS) MSG_WriteByte (msg, ps->pmove.pm_flags);
|
||||
if (pflags & PS_M_GRAVITY) MSG_WriteShort (msg, ps->pmove.gravity);
|
||||
if (pflags & PS_M_TIME)
|
||||
MSG_WriteByte (msg, ps->pmove.pm_time);
|
||||
|
||||
if (pflags & PS_M_FLAGS)
|
||||
MSG_WriteByte (msg, ps->pmove.pm_flags);
|
||||
|
||||
if (pflags & PS_M_GRAVITY)
|
||||
MSG_WriteShort (msg, ps->pmove.gravity);
|
||||
|
||||
if (pflags & PS_M_DELTA_ANGLES)
|
||||
{
|
||||
|
@ -280,7 +342,9 @@ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, size
|
|||
MSG_WriteShort (msg, ps->pmove.delta_angles[2]);
|
||||
}
|
||||
|
||||
//
|
||||
// write the rest of the player_state_t
|
||||
//
|
||||
if (pflags & PS_VIEWOFFSET)
|
||||
{
|
||||
MSG_WriteChar (msg, ps->viewoffset[0] * 4);
|
||||
|
@ -302,7 +366,11 @@ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, size
|
|||
MSG_WriteChar (msg, ps->kick_angles[2] * 4);
|
||||
}
|
||||
|
||||
if (pflags & PS_WEAPONINDEX) MSG_WriteByte (msg, ps->gunindex);
|
||||
if (pflags & PS_WEAPONINDEX)
|
||||
{
|
||||
MSG_WriteByte (msg, ps->gunindex);
|
||||
}
|
||||
|
||||
if (pflags & PS_WEAPONFRAME)
|
||||
{
|
||||
MSG_WriteByte (msg, ps->gunframe);
|
||||
|
@ -314,35 +382,42 @@ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, size
|
|||
MSG_WriteChar (msg, ps->gunangles[2]*4);
|
||||
}
|
||||
|
||||
if (pflags & PS_WEAPONSEQUENCE) MSG_WriteByte (msg, ps->sequence);
|
||||
if (pflags & PS_WEAPONBODY) MSG_WriteByte (msg, ps->gunbody);
|
||||
if (pflags & PS_WEAPONSKIN) MSG_WriteByte (msg, ps->gunskin);
|
||||
if (pflags & PS_WEAPONSEQUENCE)
|
||||
{
|
||||
MSG_WriteByte (msg, ps->sequence);
|
||||
}
|
||||
|
||||
if (pflags & PS_WEAPONBODY)
|
||||
{
|
||||
MSG_WriteByte (msg, ps->gunbody);
|
||||
}
|
||||
|
||||
if (pflags & PS_WEAPONSKIN)
|
||||
{
|
||||
MSG_WriteByte (msg, ps->gunskin);
|
||||
}
|
||||
|
||||
if (pflags & PS_BLEND)
|
||||
{
|
||||
MSG_WriteByte (msg, ps->blend[0] * 255);
|
||||
MSG_WriteByte (msg, ps->blend[1] * 255);
|
||||
MSG_WriteByte (msg, ps->blend[2] * 255);
|
||||
MSG_WriteByte (msg, ps->blend[3] * 255);
|
||||
MSG_WriteByte (msg, ps->blend[0]*255);
|
||||
MSG_WriteByte (msg, ps->blend[1]*255);
|
||||
MSG_WriteByte (msg, ps->blend[2]*255);
|
||||
MSG_WriteByte (msg, ps->blend[3]*255);
|
||||
}
|
||||
if (pflags & PS_FOV) MSG_WriteByte (msg, ps->fov);
|
||||
if (pflags & PS_RDFLAGS) MSG_WriteByte (msg, ps->rdflags);
|
||||
if (pflags & PS_FOV)
|
||||
MSG_WriteByte (msg, ps->fov);
|
||||
if (pflags & PS_RDFLAGS)
|
||||
MSG_WriteByte (msg, ps->rdflags);
|
||||
|
||||
// send stats
|
||||
statbits = 0;
|
||||
for (i = 0; i < MAX_STATS; i++)
|
||||
{
|
||||
for (i=0 ; i<MAX_STATS ; i++)
|
||||
if (ps->stats[i] != ops->stats[i])
|
||||
statbits |= 1<<i;
|
||||
}
|
||||
|
||||
MSG_WriteLong (msg, statbits);
|
||||
|
||||
for (i = 0; i < MAX_STATS; i++)
|
||||
{
|
||||
if(statbits & (1<<i) )
|
||||
for (i=0 ; i<MAX_STATS ; i++)
|
||||
if (statbits & (1<<i) )
|
||||
MSG_WriteShort (msg, ps->stats[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -361,21 +436,18 @@ void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg)
|
|||
frame = &client->frames[sv.framenum & UPDATE_MASK];
|
||||
|
||||
if (client->lastframe <= 0)
|
||||
{
|
||||
// client is asking for a retransmit
|
||||
{ // client is asking for a retransmit
|
||||
oldframe = NULL;
|
||||
lastframe = -1;
|
||||
}
|
||||
else if (sv.framenum - client->lastframe >= (UPDATE_BACKUP - 3) )
|
||||
{
|
||||
// client hasn't gotten a good message through in a long time
|
||||
{ // client hasn't gotten a good message through in a long time
|
||||
// Msg ("%s: Delta request from out-of-date packet.\n", client->name);
|
||||
oldframe = NULL;
|
||||
lastframe = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have a valid message to delta from
|
||||
{ // we have a valid message to delta from
|
||||
oldframe = &client->frames[client->lastframe & UPDATE_MASK];
|
||||
lastframe = client->lastframe;
|
||||
}
|
||||
|
@ -465,27 +537,29 @@ copies off the playerstat and areabits.
|
|||
void SV_BuildClientFrame (client_t *client)
|
||||
{
|
||||
int e, i;
|
||||
vec3_t org;
|
||||
prvm_edict_t *ent;
|
||||
prvm_edict_t *clent;
|
||||
vec3_t org;
|
||||
edict_t *ent;
|
||||
edict_t *clent;
|
||||
client_frame_t *frame;
|
||||
entity_state_t *state;
|
||||
int l;
|
||||
int clientarea, clientcluster;
|
||||
int leafnum;
|
||||
int c_fullsend;
|
||||
byte *clientphs;
|
||||
byte *bitvector;
|
||||
byte *clientphs;
|
||||
byte *bitvector;
|
||||
|
||||
clent = client->edict;
|
||||
if (!clent->priv.sv->client) return;// not in game yet
|
||||
if (!clent->client) return;// not in game yet
|
||||
|
||||
// this is the frame we are creating
|
||||
frame = &client->frames[sv.framenum & UPDATE_MASK];
|
||||
|
||||
frame->senttime = svs.realtime; // save it for ping calc later
|
||||
|
||||
// find the client's PVS
|
||||
for (i = 0; i < 3; i++) org[i] = clent->priv.sv->client->pmove.origin[i]*0.125 + clent->priv.sv->client->viewoffset[i];
|
||||
for (i=0 ; i<3 ; i++)
|
||||
org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i];
|
||||
|
||||
leafnum = CM_PointLeafnum (org);
|
||||
clientarea = CM_LeafArea (leafnum);
|
||||
|
@ -495,7 +569,8 @@ void SV_BuildClientFrame (client_t *client)
|
|||
frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea);
|
||||
|
||||
// grab the current player_state_t
|
||||
frame->ps = *clent->priv.sv->client;
|
||||
frame->ps = clent->client->ps;
|
||||
|
||||
|
||||
SV_FatPVS (org);
|
||||
clientphs = CM_ClusterPHS (clientcluster);
|
||||
|
@ -506,33 +581,34 @@ void SV_BuildClientFrame (client_t *client)
|
|||
|
||||
c_fullsend = 0;
|
||||
|
||||
ent = PRVM_NEXT_EDICT(prog->edicts);
|
||||
for (e = 1; e < prog->num_edicts; e++, ent = PRVM_NEXT_EDICT(ent))
|
||||
for (e = 1; e < ge->num_edicts ; e++)
|
||||
{
|
||||
ent = EDICT_NUM(e);
|
||||
|
||||
// ignore ents without visible models
|
||||
if ((int)ent->fields.sv->flags & SVF_NOCLIENT)
|
||||
if (ent->svflags & SVF_NOCLIENT)
|
||||
continue;
|
||||
|
||||
// ignore ents without visible models unless they have an effect
|
||||
if (!(int)ent->fields.sv->modelindex && !(int)ent->fields.sv->effects)
|
||||
if (!ent->s.modelindex && !ent->s.effects && !ent->s.sound && !ent->s.event)
|
||||
continue;
|
||||
|
||||
// ignore if not touching a PV leaf
|
||||
if (ent != clent)
|
||||
{
|
||||
// check area
|
||||
if (!CM_AreasConnected (clientarea, ent->priv.sv->areanum))
|
||||
{
|
||||
// doors can legally straddle two areas, so
|
||||
if (!CM_AreasConnected (clientarea, ent->areanum))
|
||||
{ // doors can legally straddle two areas, so
|
||||
// we may need to check another one
|
||||
if (!ent->priv.sv->areanum2 || !CM_AreasConnected (clientarea, ent->priv.sv->areanum2))
|
||||
continue; // blocked by a door
|
||||
if (!ent->areanum2
|
||||
|| !CM_AreasConnected (clientarea, ent->areanum2))
|
||||
continue; // blocked by a door
|
||||
}
|
||||
|
||||
// beams just check one point for PHS
|
||||
if ((int)ent->fields.sv->renderfx & RF_BEAM)
|
||||
if (ent->s.renderfx & RF_BEAM)
|
||||
{
|
||||
l = ent->priv.sv->clusternums[0];
|
||||
l = ent->clusternums[0];
|
||||
if ( !(clientphs[l >> 3] & (1 << (l&7) )) )
|
||||
continue;
|
||||
}
|
||||
|
@ -540,67 +616,55 @@ void SV_BuildClientFrame (client_t *client)
|
|||
{
|
||||
// FIXME: if an ent has a model and a sound, but isn't
|
||||
// in the PVS, only the PHS, clear the model
|
||||
if (ent->priv.sv->state.sound)
|
||||
if (ent->s.sound)
|
||||
{
|
||||
bitvector = fatpvs; //clientphs;
|
||||
}
|
||||
else bitvector = fatpvs;
|
||||
else
|
||||
bitvector = fatpvs;
|
||||
|
||||
if (ent->priv.sv->num_clusters == -1)
|
||||
{
|
||||
// too many leafs for individual check, go by headnode
|
||||
if (!CM_HeadnodeVisible (ent->priv.sv->headnode, bitvector))
|
||||
if (ent->num_clusters == -1)
|
||||
{ // too many leafs for individual check, go by headnode
|
||||
if (!CM_HeadnodeVisible (ent->headnode, bitvector))
|
||||
continue;
|
||||
c_fullsend++;
|
||||
}
|
||||
else
|
||||
{ // check individual leafs
|
||||
for (i=0 ; i < ent->priv.sv->num_clusters ; i++)
|
||||
for (i=0 ; i < ent->num_clusters ; i++)
|
||||
{
|
||||
l = ent->priv.sv->clusternums[i];
|
||||
l = ent->clusternums[i];
|
||||
if (bitvector[l >> 3] & (1 << (l&7) ))
|
||||
break;
|
||||
}
|
||||
if (i == ent->priv.sv->num_clusters)
|
||||
continue; // not visible
|
||||
if (i == ent->num_clusters)
|
||||
continue; // not visible
|
||||
}
|
||||
|
||||
if (!(int)ent->fields.sv->modelindex)
|
||||
{
|
||||
// don't send sounds if they will be attenuated away
|
||||
if (!ent->s.modelindex)
|
||||
{ // don't send sounds if they will be attenuated away
|
||||
vec3_t delta;
|
||||
float len;
|
||||
|
||||
VectorSubtract (org, ent->fields.sv->origin, delta);
|
||||
VectorSubtract (org, ent->s.origin, delta);
|
||||
len = VectorLength (delta);
|
||||
if (len > 400) continue;
|
||||
if (len > 400)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add it to the circular client_entities array
|
||||
state = &svs.client_entities[svs.next_client_entities % svs.num_client_entities];
|
||||
if (ent->priv.sv->state.number != e)
|
||||
if (ent->s.number != e)
|
||||
{
|
||||
MsgWarn ("SV_BuildClientFrame: invalid ent->priv.sv->state.number %d (must be %d)\n", ent->priv.sv->state.number, e );
|
||||
ent->priv.sv->state.number = e; // ptr to current entity such as entnumber
|
||||
MsgWarn ("SV_BuildClientFrame: invalid ent->s.number %d\n", ent->s.number );
|
||||
ent->s.number = e; // ptr to current entity such as entnumber
|
||||
}
|
||||
|
||||
// copy state from fields
|
||||
VectorCopy (ent->fields.sv->origin, ent->priv.sv->state.origin);
|
||||
VectorCopy (ent->fields.sv->angles, ent->priv.sv->state.angles);
|
||||
ent->priv.sv->state.frame = (int)ent->fields.sv->frame;
|
||||
ent->priv.sv->state.skin = (int)ent->fields.sv->skin;
|
||||
ent->priv.sv->state.body = (int)ent->fields.sv->body;
|
||||
ent->priv.sv->state.sequence = (int)ent->fields.sv->sequence;
|
||||
ent->priv.sv->state.effects = (int)ent->fields.sv->effects;
|
||||
ent->priv.sv->state.renderfx = (int)ent->fields.sv->renderfx;
|
||||
ent->priv.sv->state.solid = (int)ent->fields.sv->solid;
|
||||
|
||||
*state = ent->priv.sv->state;
|
||||
*state = ent->s;
|
||||
|
||||
// don't mark players missiles as solid
|
||||
if(PRVM_PROG_TO_EDICT(ent->fields.sv->owner) == client->edict) state->solid = 0;
|
||||
if (ent->owner == client->edict) state->solid = 0;
|
||||
|
||||
svs.next_client_entities++;
|
||||
frame->num_entities++;
|
||||
|
@ -619,7 +683,7 @@ Used for recording footage for merged or assembled demos
|
|||
void SV_RecordDemoMessage (void)
|
||||
{
|
||||
int e;
|
||||
prvm_edict_t *ent;
|
||||
edict_t *ent;
|
||||
entity_state_t nostate;
|
||||
sizebuf_t buf;
|
||||
byte buf_data[32768];
|
||||
|
@ -638,14 +702,18 @@ void SV_RecordDemoMessage (void)
|
|||
MSG_WriteByte (&buf, svc_packetentities);
|
||||
|
||||
e = 1;
|
||||
ent = PRVM_EDICT_NUM(e);
|
||||
while (e < prog->num_edicts)
|
||||
ent = EDICT_NUM(e);
|
||||
while (e < ge->num_edicts)
|
||||
{
|
||||
// ignore ents without visible models unless they have an effect
|
||||
if (!ent->priv.sv->free && ent->priv.sv->state.number && ((int)ent->fields.sv->modelindex || ent->fields.sv->effects || ent->priv.sv->state.sound || ent->priv.sv->state.event) && !((int)ent->fields.sv->flags & SVF_NOCLIENT))
|
||||
MSG_WriteDeltaEntity (&nostate, &ent->priv.sv->state, &buf, false, true);
|
||||
if (ent->inuse &&
|
||||
ent->s.number &&
|
||||
(ent->s.modelindex || ent->s.effects || ent->s.sound || ent->s.event) &&
|
||||
!(ent->svflags & SVF_NOCLIENT))
|
||||
MSG_WriteDeltaEntity (&nostate, &ent->s, &buf, false, true);
|
||||
|
||||
e++;
|
||||
ent = PRVM_EDICT_NUM(e);
|
||||
ent = EDICT_NUM(e);
|
||||
}
|
||||
|
||||
MSG_WriteShort (&buf, 0); // end of packetentities
|
||||
|
@ -660,4 +728,3 @@ void SV_RecordDemoMessage (void)
|
|||
FS_Write (svs.demofile, buf.data, buf.cursize);
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -24,120 +24,30 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
server_static_t svs; // persistant server info
|
||||
server_t sv; // local server
|
||||
|
||||
#define REQFIELDS (sizeof(reqfields) / sizeof(prvm_fieldvars_t))
|
||||
|
||||
prvm_fieldvars_t reqfields[] =
|
||||
{
|
||||
{0, 2, "modelindex"},
|
||||
{1, 3, "absmin"},
|
||||
{1, 2, "absmin_x"},
|
||||
{2, 2, "absmin_y"},
|
||||
{3, 2, "absmin_z"},
|
||||
{4, 3, "absmax"},
|
||||
{7, 2, "ltime"},
|
||||
{8, 2, "movetype"},
|
||||
{9, 2, "solid"},
|
||||
{10, 3, "origin"},
|
||||
{13, 3, "oldorigin"},
|
||||
{16, 3, "velocity"},
|
||||
{19, 3, "angles"},
|
||||
{22, 3, "avelocity"},
|
||||
{25, 3, "punchangle"},
|
||||
{28, 1, "classname"},
|
||||
{29, 1, "model"},
|
||||
{30, 2, "frame"},
|
||||
{31, 2, "skin"},
|
||||
{32, 2, "body"},
|
||||
{33, 2, "effects"},
|
||||
{34, 2, "sequence"},
|
||||
{35, 2, "renderfx"},
|
||||
{36, 3, "mins"},
|
||||
{39, 3, "maxs"},
|
||||
{42, 3, "size"},
|
||||
{45, 6, "touch"},
|
||||
{46, 6, "use"},
|
||||
{47, 6, "think"},
|
||||
{48, 6, "blocked"},
|
||||
{49, 2, "nextthink"},
|
||||
{50, 4, "groundentity"},
|
||||
{51, 2, "health"},
|
||||
{52, 2, "frags"},
|
||||
{53, 2, "weapon"},
|
||||
{54, 1, "weaponmodel"},
|
||||
{55, 2, "weaponframe"},
|
||||
{56, 2, "currentammo"},
|
||||
{57, 2, "ammo_shells"},
|
||||
{58, 2, "ammo_nails"},
|
||||
{59, 2, "ammo_rockets"},
|
||||
{60, 2, "ammo_cells"},
|
||||
{61, 2, "items"},
|
||||
{62, 2, "takedamage"},
|
||||
{63, 4, "chain"},
|
||||
{64, 2, "deadflag"},
|
||||
{65, 3, "view_ofs"},
|
||||
{68, 2, "button0"},
|
||||
{69, 2, "button1"},
|
||||
{70, 2, "button2"},
|
||||
{71, 2, "impulse"},
|
||||
{72, 2, "fixangle"},
|
||||
{73, 3, "v_angle"},
|
||||
{76, 2, "idealpitch"},
|
||||
{77, 1, "netname"},
|
||||
{78, 4, "enemy"},
|
||||
{79, 2, "flags"},
|
||||
{80, 2, "colormap"},
|
||||
{81, 2, "team"},
|
||||
{82, 2, "max_health"},
|
||||
{83, 2, "teleport_time"},
|
||||
{84, 2, "armortype"},
|
||||
{85, 2, "armorvalue"},
|
||||
{86, 2, "waterlevel"},
|
||||
{87, 2, "watertype"},
|
||||
{88, 2, "ideal_yaw"},
|
||||
{89, 2, "yaw_speed"},
|
||||
{90, 4, "aiment"},
|
||||
{91, 4, "goalentity"},
|
||||
{92, 2, "spawnflags"},
|
||||
{93, 1, "target"},
|
||||
{94, 1, "targetname"},
|
||||
{95, 2, "dmg_take"},
|
||||
{96, 2, "dmg_save"},
|
||||
{97, 4, "dmg_inflictor"},
|
||||
{98, 4, "owner"},
|
||||
{99, 3, "movedir"},
|
||||
{102, 1, "message"},
|
||||
{103, 2, "sounds"},
|
||||
{104, 1, "noise"},
|
||||
{105, 1, "noise1"},
|
||||
{106, 1, "noise2"},
|
||||
{107, 1, "noise3"}
|
||||
};
|
||||
|
||||
/*
|
||||
================
|
||||
SV_FindIndex
|
||||
|
||||
================
|
||||
*/
|
||||
int SV_FindIndex (const char *name, int start, int end, bool create)
|
||||
int SV_FindIndex (char *name, int start, int max, bool create)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!name || !name[0]) return 0;
|
||||
|
||||
for (i = 1; i < end && sv.configstrings[start + i][0]; i++)
|
||||
if(!strcmp(sv.configstrings[start + i], name))
|
||||
return i;
|
||||
if (!create) return 0;
|
||||
|
||||
if (i == end)
|
||||
{
|
||||
MsgWarn ("SV_FindIndex: %d out range [%d - %d]\n", start, end );
|
||||
if (!name || !name[0])
|
||||
return 0;
|
||||
}
|
||||
|
||||
// register new resource
|
||||
strncpy (sv.configstrings[start + i], name, sizeof(sv.configstrings[i]));
|
||||
for (i=1 ; i<max && sv.configstrings[start+i][0] ; i++)
|
||||
if (!strcmp(sv.configstrings[start+i], name))
|
||||
return i;
|
||||
|
||||
if (!create)
|
||||
return 0;
|
||||
|
||||
if (i == max)
|
||||
Com_Error (ERR_DROP, "*Index: overflow");
|
||||
|
||||
strncpy (sv.configstrings[start+i], name, sizeof(sv.configstrings[i]));
|
||||
|
||||
if (sv.state != ss_loading)
|
||||
{
|
||||
|
@ -145,24 +55,25 @@ int SV_FindIndex (const char *name, int start, int end, bool create)
|
|||
SZ_Clear (&sv.multicast);
|
||||
MSG_Begin(svc_configstring);
|
||||
MSG_WriteShort (&sv.multicast, start+i);
|
||||
MSG_WriteString (&sv.multicast, (char *)name);
|
||||
MSG_WriteString (&sv.multicast, name);
|
||||
MSG_Send(MSG_ALL_R, vec3_origin, NULL );
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
int SV_ModelIndex (const char *name)
|
||||
int SV_ModelIndex (char *name)
|
||||
{
|
||||
return SV_FindIndex (name, CS_MODELS, MAX_MODELS, true);
|
||||
}
|
||||
|
||||
int SV_SoundIndex (const char *name)
|
||||
int SV_SoundIndex (char *name)
|
||||
{
|
||||
return SV_FindIndex (name, CS_SOUNDS, MAX_SOUNDS, true);
|
||||
}
|
||||
|
||||
int SV_ImageIndex (const char *name)
|
||||
int SV_ImageIndex (char *name)
|
||||
{
|
||||
return SV_FindIndex (name, CS_IMAGES, MAX_IMAGES, true);
|
||||
}
|
||||
|
@ -179,78 +90,26 @@ baseline will be transmitted
|
|||
*/
|
||||
void SV_CreateBaseline (void)
|
||||
{
|
||||
prvm_edict_t *svent;
|
||||
edict_t *svent;
|
||||
int entnum;
|
||||
|
||||
for (entnum = 1; entnum < prog->num_edicts; entnum++)
|
||||
for (entnum = 1; entnum < ge->num_edicts ; entnum++)
|
||||
{
|
||||
svent = PRVM_EDICT_NUM(entnum);
|
||||
|
||||
if (svent->priv.sv->free)
|
||||
{
|
||||
Msg("Can't create baseline for entity [%d]\n", entnum );
|
||||
svent = EDICT_NUM(entnum);
|
||||
if (!svent->inuse)
|
||||
continue;
|
||||
}
|
||||
if (!(int)svent->fields.sv->modelindex && !(int)svent->priv.sv->state.sound && !(int)svent->fields.sv->effects)
|
||||
if (!svent->s.modelindex && !svent->s.sound && !svent->s.effects)
|
||||
continue;
|
||||
svent->s.number = entnum;
|
||||
|
||||
svent->priv.sv->state.number = entnum;
|
||||
|
||||
if (entnum > host.maxclients && !(int)svent->fields.sv->modelindex)
|
||||
continue;
|
||||
|
||||
// create entity baseline
|
||||
VectorCopy (svent->fields.sv->origin, svent->priv.sv->state.origin);
|
||||
VectorCopy (svent->priv.sv->state.origin, svent->priv.sv->state.old_origin);
|
||||
VectorCopy (svent->fields.sv->angles, svent->priv.sv->state.angles);
|
||||
svent->priv.sv->state.frame = (int)svent->fields.sv->frame;
|
||||
svent->priv.sv->state.skin = (int)svent->fields.sv->skin;
|
||||
svent->priv.sv->state.body = (int)svent->fields.sv->body;
|
||||
svent->priv.sv->state.sequence = (int)svent->fields.sv->sequence;
|
||||
svent->priv.sv->state.effects = (int)svent->fields.sv->effects;
|
||||
svent->priv.sv->state.renderfx = (int)svent->fields.sv->renderfx;
|
||||
svent->priv.sv->state.solid = (int)svent->fields.sv->solid;
|
||||
|
||||
if (entnum > 0 && entnum <= host.maxclients)
|
||||
{
|
||||
svent->priv.sv->state.modelindex = SV_ModelIndex("progs/player.mdl");
|
||||
}
|
||||
else
|
||||
{
|
||||
svent->priv.sv->state.modelindex = (int)svent->fields.sv->modelindex;
|
||||
}
|
||||
|
||||
//
|
||||
// take current state as baseline
|
||||
sv.baselines[entnum] = svent->priv.sv->state;
|
||||
//
|
||||
VectorCopy (svent->s.origin, svent->s.old_origin);
|
||||
sv.baselines[entnum] = svent->s;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SV_SaveSpawnparms
|
||||
|
||||
Grabs the current state of each client for saving across the
|
||||
transition to another level
|
||||
================
|
||||
*/
|
||||
void SV_SaveSpawnparms (void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
svs.serverflags = (int)prog->globals.server->serverflags;
|
||||
|
||||
for (i = 0, sv_client = svs.clients; i < host.maxclients; i++, sv_client++)
|
||||
{
|
||||
if (sv_client->state != cs_spawned)
|
||||
continue;
|
||||
|
||||
// call the progs to get default spawn parms for the new client
|
||||
prog->globals.server->self = PRVM_EDICT_TO_PROG(sv_client->edict);
|
||||
PRVM_ExecuteProgram (prog->globals.server->SetChangeParms, "QC function SetChangeParms is missing");
|
||||
for (j = 0; j < NUM_SPAWN_PARMS; j++)
|
||||
sv_client->spawn_parms[j] = prog->globals.server->parm[j];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -259,6 +118,7 @@ SV_CheckForSavegame
|
|||
*/
|
||||
void SV_CheckForSavegame (char *savename )
|
||||
{
|
||||
int i;
|
||||
char name[MAX_SYSPATH];
|
||||
|
||||
if (sv_noreload->value) return;
|
||||
|
@ -275,6 +135,22 @@ void SV_CheckForSavegame (char *savename )
|
|||
|
||||
// get configstrings and areaportals
|
||||
SV_ReadLevelFile ( savename );
|
||||
|
||||
if (!sv.loadgame)
|
||||
{ // coming back to a level after being in a different
|
||||
// level, so run it for ten seconds
|
||||
|
||||
// rlava2 was sending too many lightstyles, and overflowing the
|
||||
// reliable data. temporarily changing the server state to loading
|
||||
// prevents these from being passed down.
|
||||
server_state_t previousState; // PGM
|
||||
|
||||
previousState = sv.state; // PGM
|
||||
sv.state = ss_loading; // PGM
|
||||
for (i = 0; i < 100; i++) SV_RunFrame ();
|
||||
|
||||
sv.state = previousState; // PGM
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -289,8 +165,7 @@ clients along with it.
|
|||
*/
|
||||
void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_state_t serverstate, bool attractloop, bool loadgame)
|
||||
{
|
||||
uint i, checksum;
|
||||
prvm_edict_t *ent;
|
||||
uint i, checksum;
|
||||
|
||||
if (attractloop) Cvar_Set ("paused", "0");
|
||||
|
||||
|
@ -321,17 +196,11 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
|
|||
pm_airaccelerate = 0;
|
||||
}
|
||||
|
||||
SV_VM_Setup();
|
||||
|
||||
SZ_Init (&sv.multicast, sv.multicast_buf, sizeof(sv.multicast_buf));
|
||||
|
||||
strcpy (sv.name, server);
|
||||
strcpy (sv.configstrings[CS_NAME], server);
|
||||
|
||||
SV_VM_Begin();
|
||||
|
||||
// leave slots at start for clients only
|
||||
for (i = 0; i < host.maxclients; i++)
|
||||
for (i=0 ; i<maxclients->value ; i++)
|
||||
{
|
||||
// needs to reconnect
|
||||
if (svs.clients[i].state > cs_connected)
|
||||
|
@ -339,8 +208,10 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
|
|||
svs.clients[i].lastframe = -1;
|
||||
}
|
||||
|
||||
sv.state = ss_loading;
|
||||
prog->protect_world = false;
|
||||
sv.time = 1000;
|
||||
|
||||
strcpy (sv.name, server);
|
||||
strcpy (sv.configstrings[CS_NAME], server);
|
||||
|
||||
if (serverstate != ss_game)
|
||||
{
|
||||
|
@ -348,7 +219,7 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
|
|||
}
|
||||
else
|
||||
{
|
||||
strcpy (sv.configstrings[CS_MODELS+1], server);
|
||||
sprintf (sv.configstrings[CS_MODELS+1], "maps/%s.bsp", server);
|
||||
sv.models[1] = CM_LoadMap (sv.configstrings[CS_MODELS+1], false, &checksum);
|
||||
}
|
||||
sprintf (sv.configstrings[CS_MAPCHECKSUM],"%i", checksum);
|
||||
|
@ -362,61 +233,36 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
|
|||
sv.models[i+1] = CM_InlineModel (sv.configstrings[CS_MODELS+1+i]);
|
||||
}
|
||||
|
||||
ent = PRVM_EDICT_NUM(0);
|
||||
memset (ent->fields.sv, 0, prog->progs->entityfields * 4);
|
||||
ent->priv.sv->free = false;
|
||||
ent->fields.sv->model = PRVM_SetEngineString(sv.configstrings[CS_MODELS]);
|
||||
ent->fields.sv->modelindex = 1; // world model
|
||||
ent->fields.sv->solid = SOLID_BSP;
|
||||
ent->fields.sv->movetype = MOVETYPE_PUSH;
|
||||
|
||||
prog->globals.server->mapname = PRVM_SetEngineString(sv.name);
|
||||
//
|
||||
// spawn the rest of the entities on the map
|
||||
//
|
||||
|
||||
// precache and static commands can be issued during
|
||||
// map initialization
|
||||
sv.state = ss_loading;
|
||||
Com_SetServerState (sv.state);
|
||||
|
||||
// spawn the rest of the entities on the map
|
||||
sv.moved_edicts = (prvm_edict_t **)PRVM_Alloc(prog->max_edicts * sizeof(prvm_edict_t *));
|
||||
*prog->time = sv.time = 1.0;
|
||||
// load and spawn all other entities
|
||||
SV_SpawnEntities ( sv.name, CM_EntityString(), spawnpoint );
|
||||
|
||||
// serverflags are for cross level information (sigils)
|
||||
prog->globals.server->serverflags = svs.serverflags;
|
||||
|
||||
// we need to reset the spawned flag on all connected clients here so that
|
||||
// their thinks don't run during startup (before PutClientInServer)
|
||||
// we also need to set up the client entities now
|
||||
// and we need to set the ->edict pointers to point into the progs edicts
|
||||
for (i = 0, sv_client = svs.clients; i < host.maxclients; i++, sv_client++)
|
||||
{
|
||||
sv_client->state = cs_connected;
|
||||
sv_client->edict = PRVM_EDICT_NUM(i + 1);
|
||||
sv_client->edict->priv.sv->client = Z_Malloc(sizeof(player_state_t));
|
||||
ent->priv.sv->state.number = i + 1;
|
||||
memset (&sv_client->lastcmd, 0, sizeof(sv_client->lastcmd));
|
||||
PRVM_ED_ClearEdict(sv_client->edict);
|
||||
}
|
||||
|
||||
PRVM_ED_LoadFromFile (CM_EntityString());
|
||||
// run two frames to allow everything to settle
|
||||
SV_RunFrame ();
|
||||
SV_RunFrame ();
|
||||
|
||||
// all precaches are complete
|
||||
sv.state = serverstate;
|
||||
Com_SetServerState (sv.state);
|
||||
prog->protect_world = true;
|
||||
|
||||
// run two frames to allow everything to settle
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
sv.frametime = 0.1f;
|
||||
SV_Physics();
|
||||
}
|
||||
|
||||
// create a baseline for more efficient communications
|
||||
SV_CreateBaseline ();
|
||||
|
||||
// check for a savegame
|
||||
SV_CheckForSavegame ( savename );
|
||||
|
||||
// set serverinfo variable
|
||||
Cvar_FullSet ("mapname", sv.name, CVAR_SERVERINFO | CVAR_NOSET);
|
||||
|
||||
Msg ("-------------------------------------\n");
|
||||
|
||||
SV_VM_End();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -428,8 +274,8 @@ A brand new game has been started
|
|||
*/
|
||||
void SV_InitGame (void)
|
||||
{
|
||||
//int i;
|
||||
//prvm_edict_t *ent;
|
||||
int i;
|
||||
edict_t *ent;
|
||||
char idmaster[32];
|
||||
|
||||
if (svs.initialized)
|
||||
|
@ -457,38 +303,53 @@ void SV_InitGame (void)
|
|||
|
||||
// dedicated servers are can't be single player and are usually DM
|
||||
// so unless they explicity set coop, force it to deathmatch
|
||||
if (host.type == HOST_DEDICATED)
|
||||
if (dedicated->value)
|
||||
{
|
||||
if (!Cvar_VariableValue ("coop")) Cvar_FullSet ("deathmatch", "1", CVAR_SERVERINFO | CVAR_LATCH);
|
||||
if (!Cvar_VariableValue ("coop"))
|
||||
Cvar_FullSet ("deathmatch", "1", CVAR_SERVERINFO | CVAR_LATCH);
|
||||
}
|
||||
|
||||
// init clients
|
||||
if (Cvar_VariableValue ("deathmatch"))
|
||||
{
|
||||
if (host.maxclients <= 1) host.maxclients = 8;
|
||||
else if (host.maxclients > MAX_CLIENTS) host.maxclients = MAX_CLIENTS;
|
||||
if (maxclients->value <= 1)
|
||||
Cvar_FullSet ("maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH);
|
||||
else if (maxclients->value > MAX_CLIENTS)
|
||||
Cvar_FullSet ("maxclients", va("%i", MAX_CLIENTS), CVAR_SERVERINFO | CVAR_LATCH);
|
||||
}
|
||||
else if (Cvar_VariableValue ("coop"))
|
||||
{
|
||||
if (host.maxclients <= 1 || host.maxclients > 4) host.maxclients = 4;
|
||||
if (maxclients->value <= 1 || maxclients->value > 4)
|
||||
Cvar_FullSet ("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH);
|
||||
}
|
||||
else // non-deathmatch, non-coop is one player
|
||||
{
|
||||
host.maxclients = 1;
|
||||
Cvar_FullSet ("maxclients", "1", CVAR_SERVERINFO | CVAR_LATCH);
|
||||
}
|
||||
|
||||
svs.spawncount = rand();
|
||||
svs.clients = Z_Malloc (sizeof(client_t) * host.maxclients);
|
||||
svs.num_client_entities = host.maxclients * UPDATE_BACKUP * 64;
|
||||
svs.client_entities = Z_Malloc(sizeof(entity_state_t) * svs.num_client_entities);
|
||||
svs.clients = Z_Malloc (sizeof(client_t)*maxclients->value);
|
||||
svs.num_client_entities = maxclients->value*UPDATE_BACKUP*64;
|
||||
svs.client_entities = Z_Malloc (sizeof(entity_state_t)*svs.num_client_entities);
|
||||
|
||||
// init network stuff
|
||||
NET_Config ( (host.maxclients > 1) );
|
||||
NET_Config ( (maxclients->value > 1) );
|
||||
|
||||
// heartbeats will always be sent to the id master
|
||||
svs.last_heartbeat = -99999; // send immediately
|
||||
sprintf(idmaster, "192.246.40.37:%i", PORT_MASTER);
|
||||
NET_StringToAdr (idmaster, &master_adr[0]);
|
||||
|
||||
// init game
|
||||
SV_InitGameProgs ();
|
||||
|
||||
for (i = 0; i < maxclients->value; i++)
|
||||
{
|
||||
ent = EDICT_NUM(i + 1);
|
||||
ent->s.number = i + 1;
|
||||
svs.clients[i].edict = ent;
|
||||
memset (&svs.clients[i].lastcmd, 0, sizeof(svs.clients[i].lastcmd));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -577,145 +438,3 @@ void SV_Map (bool attractloop, char *levelstring, char *savename, bool loadgame)
|
|||
|
||||
SV_BroadcastCommand ("reconnect\n");
|
||||
}
|
||||
|
||||
void SV_VM_BeginIncreaseEdicts(void)
|
||||
{
|
||||
int i;
|
||||
prvm_edict_t *ent;
|
||||
|
||||
PRVM_Free( sv.moved_edicts );
|
||||
sv.moved_edicts = (prvm_edict_t **)PRVM_Alloc(prog->max_edicts * sizeof(prvm_edict_t *));
|
||||
|
||||
// links don't survive the transition, so unlink everything
|
||||
for (i = 0, ent = prog->edicts;i < prog->max_edicts;i++, ent++)
|
||||
{
|
||||
if (!ent->priv.sv->free) SV_UnlinkEdict(prog->edicts + i); //free old entity
|
||||
memset(&ent->priv.sv->clusternums, 0, sizeof(ent->priv.sv->clusternums));
|
||||
}
|
||||
SV_ClearWorld();
|
||||
}
|
||||
|
||||
void SV_VM_EndIncreaseEdicts(void)
|
||||
{
|
||||
int i;
|
||||
prvm_edict_t *ent;
|
||||
|
||||
for (i = 0, ent = prog->edicts;i < prog->max_edicts;i++, ent++)
|
||||
{
|
||||
// link every entity except world
|
||||
if (!ent->priv.sv->free) SV_LinkEdict(ent);
|
||||
}
|
||||
}
|
||||
|
||||
void SV_VM_InitEdict(prvm_edict_t *e)
|
||||
{
|
||||
int num = PRVM_NUM_FOR_EDICT(e) - 1;
|
||||
e->priv.sv->move = false; // don't move on first frame
|
||||
|
||||
// set here additional player effects: model, skin, etc...
|
||||
}
|
||||
|
||||
void SV_VM_FreeEdict(prvm_edict_t *ed)
|
||||
{
|
||||
SV_UnlinkEdict (ed); // unlink from world bsp
|
||||
|
||||
ed->fields.sv->model = 0;
|
||||
ed->fields.sv->takedamage = 0;
|
||||
ed->fields.sv->modelindex = 0;
|
||||
ed->fields.sv->colormap = 0;
|
||||
ed->fields.sv->skin = 0;
|
||||
ed->fields.sv->frame = 0;
|
||||
VectorClear(ed->fields.sv->origin);
|
||||
VectorClear(ed->fields.sv->angles);
|
||||
ed->fields.sv->nextthink = -1;
|
||||
ed->fields.sv->solid = 0;
|
||||
}
|
||||
|
||||
void SV_VM_CountEdicts( void )
|
||||
{
|
||||
int i;
|
||||
prvm_edict_t *ent;
|
||||
int active = 0, models = 0, solid = 0, step = 0;
|
||||
|
||||
for (i = 0; i < prog->num_edicts; i++)
|
||||
{
|
||||
ent = PRVM_EDICT_NUM(i);
|
||||
if (ent->priv.sv->free)
|
||||
continue;
|
||||
active++;
|
||||
if (ent->fields.sv->solid) solid++;
|
||||
if (ent->fields.sv->model) models++;
|
||||
if (ent->fields.sv->movetype == MOVETYPE_STEP) step++;
|
||||
}
|
||||
|
||||
Msg("num_edicts:%3i\n", prog->num_edicts);
|
||||
Msg("active :%3i\n", active);
|
||||
Msg("view :%3i\n", models);
|
||||
Msg("touch :%3i\n", solid);
|
||||
Msg("step :%3i\n", step);
|
||||
}
|
||||
|
||||
bool SV_VM_LoadEdict(prvm_edict_t *ent)
|
||||
{
|
||||
int current_skill = (int)Cvar_VariableValue ("skill");
|
||||
|
||||
// remove things from different skill levels or deathmatch
|
||||
if(Cvar_VariableValue ("deathmatch"))
|
||||
{
|
||||
if (((int)ent->fields.sv->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ((current_skill <= 0 && ((int)ent->fields.sv->spawnflags & SPAWNFLAG_NOT_EASY )) || (current_skill == 1 && ((int)ent->fields.sv->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || (current_skill >= 2 && ((int)ent->fields.sv->spawnflags & SPAWNFLAG_NOT_HARD )))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SV_VM_Setup( void )
|
||||
{
|
||||
PRVM_Begin;
|
||||
PRVM_InitProg( PRVM_SERVERPROG );
|
||||
|
||||
// allocate the mempools
|
||||
// TODO: move the magic numbers/constants into #defines [9/13/2006 Black]
|
||||
prog->progs_mempool = Mem_AllocPool("Server Progs" );
|
||||
prog->builtins = vm_sv_builtins;
|
||||
prog->numbuiltins = vm_sv_numbuiltins;
|
||||
prog->max_edicts = 512;
|
||||
prog->limit_edicts = MAX_EDICTS;
|
||||
prog->reserved_edicts = host.maxclients;
|
||||
prog->edictprivate_size = sizeof(server_edict_t);
|
||||
prog->name = "server";
|
||||
prog->extensionstring = "";
|
||||
prog->loadintoworld = true;
|
||||
|
||||
prog->begin_increase_edicts = SV_VM_BeginIncreaseEdicts;
|
||||
prog->end_increase_edicts = SV_VM_EndIncreaseEdicts;
|
||||
prog->init_edict = SV_VM_InitEdict;
|
||||
prog->free_edict = SV_VM_FreeEdict;
|
||||
prog->count_edicts = SV_VM_CountEdicts;
|
||||
prog->load_edict = SV_VM_LoadEdict;
|
||||
prog->init_cmd = VM_Cmd_Init;
|
||||
prog->reset_cmd = VM_Cmd_Reset;
|
||||
prog->error_cmd = VM_Error;
|
||||
|
||||
// TODO: add a requiredfuncs list (ask LH if this is necessary at all)
|
||||
PRVM_LoadProgs( "server.dat", 0, NULL, REQFIELDS, reqfields );
|
||||
PRVM_End;
|
||||
}
|
||||
|
||||
void SV_VM_Begin(void)
|
||||
{
|
||||
PRVM_Begin;
|
||||
PRVM_SetProg( PRVM_SERVERPROG );
|
||||
|
||||
*prog->time = sv.time;
|
||||
}
|
||||
|
||||
void SV_VM_End(void)
|
||||
{
|
||||
PRVM_End;
|
||||
}
|
|
@ -42,18 +42,11 @@ cvar_t *allow_download_sounds;
|
|||
cvar_t *allow_download_maps;
|
||||
|
||||
cvar_t *sv_airaccelerate;
|
||||
cvar_t *sv_wateraccelerate;
|
||||
cvar_t *sv_accelerate;
|
||||
cvar_t *sv_maxvelocity;
|
||||
cvar_t *sv_maxspeed;
|
||||
cvar_t *sv_friction;
|
||||
cvar_t *sv_gravity;
|
||||
cvar_t *sv_rollangle;
|
||||
cvar_t *sv_rollspeed;
|
||||
|
||||
cvar_t *sv_noreload; // don't reload level state when reentering
|
||||
|
||||
|
||||
cvar_t *maxclients; // FIXME: rename sv_maxclients
|
||||
cvar_t *sv_showclamp;
|
||||
|
||||
|
@ -86,7 +79,7 @@ void SV_DropClient (client_t *drop)
|
|||
{
|
||||
// call the prog function for removing a client
|
||||
// this will remove the body, among other things
|
||||
//ge->ClientDisconnect (drop->edict);
|
||||
SV_ClientDisconnect(drop->edict);
|
||||
}
|
||||
|
||||
if (drop->download)
|
||||
|
@ -128,12 +121,12 @@ char *SV_StatusString (void)
|
|||
strcat (status, "\n");
|
||||
statusLength = strlen(status);
|
||||
|
||||
for (i=0 ; i<host.maxclients ; i++)
|
||||
for (i=0 ; i<maxclients->value ; i++)
|
||||
{
|
||||
cl = &svs.clients[i];
|
||||
if (cl->state == cs_connected || cl->state == cs_spawned )
|
||||
{
|
||||
sprintf (player, "%i %i \"%s\"\n", cl->edict->priv.sv->client->stats[STAT_FRAGS], cl->ping, cl->name);
|
||||
sprintf (player, "%i %i \"%s\"\n", cl->edict->client->ps.stats[STAT_FRAGS], cl->ping, cl->name);
|
||||
playerLength = strlen(player);
|
||||
if (statusLength + playerLength >= sizeof(status) )
|
||||
break; // can't hold any more
|
||||
|
@ -182,7 +175,7 @@ void SVC_Info (void)
|
|||
int i, count;
|
||||
int version;
|
||||
|
||||
if (host.maxclients == 1)
|
||||
if (maxclients->value == 1)
|
||||
return; // ignore in single player
|
||||
|
||||
version = atoi (Cmd_Argv(1));
|
||||
|
@ -192,11 +185,11 @@ void SVC_Info (void)
|
|||
else
|
||||
{
|
||||
count = 0;
|
||||
for (i=0 ; i<host.maxclients ; i++)
|
||||
for (i=0 ; i<maxclients->value ; i++)
|
||||
if (svs.clients[i].state >= cs_connected)
|
||||
count++;
|
||||
|
||||
sprintf (string, "%16s %8s %2i/%2i\n", hostname->string, sv.name, count, (int)host.maxclients);
|
||||
sprintf (string, "%16s %8s %2i/%2i\n", hostname->string, sv.name, count, (int)maxclients->value);
|
||||
}
|
||||
|
||||
Netchan_OutOfBandPrint (NS_SERVER, net_from, "info\n%s", string);
|
||||
|
@ -252,7 +245,7 @@ void SVC_GetChallenge (void)
|
|||
// overwrite the oldest
|
||||
svs.challenges[oldest].challenge = rand() & 0x7fff;
|
||||
svs.challenges[oldest].adr = net_from;
|
||||
svs.challenges[oldest].time = host.realtime;
|
||||
svs.challenges[oldest].time = curtime;
|
||||
i = oldest;
|
||||
}
|
||||
|
||||
|
@ -274,7 +267,7 @@ void SVC_DirectConnect (void)
|
|||
int i;
|
||||
client_t *cl, *newcl;
|
||||
client_t temp;
|
||||
prvm_edict_t *ent;
|
||||
edict_t *ent;
|
||||
int edictnum;
|
||||
int version;
|
||||
int qport;
|
||||
|
@ -336,7 +329,7 @@ void SVC_DirectConnect (void)
|
|||
memset (newcl, 0, sizeof(client_t));
|
||||
|
||||
// if there is already a slot for this ip, reuse it
|
||||
for (i=0,cl=svs.clients ; i<host.maxclients ; i++,cl++)
|
||||
for (i=0,cl=svs.clients ; i<maxclients->value ; i++,cl++)
|
||||
{
|
||||
if (cl->state == cs_free)
|
||||
continue;
|
||||
|
@ -344,7 +337,7 @@ void SVC_DirectConnect (void)
|
|||
&& ( cl->netchan.qport == qport
|
||||
|| adr.port == cl->netchan.remote_address.port ) )
|
||||
{
|
||||
if (!NET_IsLocalAddress (adr) && (svs.realtime - cl->lastconnect) < ((int)sv_reconnect_limit->value))
|
||||
if (!NET_IsLocalAddress (adr) && (svs.realtime - cl->lastconnect) < ((int)sv_reconnect_limit->value * 1000))
|
||||
{
|
||||
MsgWarn("SVC_DirectConnect: %s:reconnect rejected : too soon\n", NET_AdrToString (adr));
|
||||
return;
|
||||
|
@ -357,7 +350,7 @@ void SVC_DirectConnect (void)
|
|||
|
||||
// find a client slot
|
||||
newcl = NULL;
|
||||
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
|
||||
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
|
||||
{
|
||||
if (cl->state == cs_free)
|
||||
{
|
||||
|
@ -380,22 +373,19 @@ gotnewcl:
|
|||
sv_client = newcl;
|
||||
edictnum = (newcl - svs.clients) + 1;
|
||||
|
||||
ent = PRVM_EDICT_NUM(edictnum);
|
||||
ent = EDICT_NUM(edictnum);
|
||||
newcl->edict = ent;
|
||||
newcl->challenge = challenge; // save challenge for checksumming
|
||||
|
||||
prog->globals.server->time = sv.time;
|
||||
prog->globals.server->self = PRVM_EDICT_TO_PROG(sv_client->edict);
|
||||
PRVM_ExecuteProgram (prog->globals.server->ClientConnect, "QC function ClientConnect is missing");
|
||||
|
||||
//if (!(ge->ClientConnect (ent, userinfo)))
|
||||
/*{
|
||||
// get the game a chance to reject this connection or modify the userinfo
|
||||
if (!(SV_ClientConnect(ent, userinfo)))
|
||||
{
|
||||
if (*Info_ValueForKey (userinfo, "rejmsg"))
|
||||
Netchan_OutOfBandPrint (NS_SERVER, adr, "print\n%s\nConnection refused.\n", Info_ValueForKey (userinfo, "rejmsg"));
|
||||
else Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nConnection refused.\n" );
|
||||
MsgWarn("SVC_DirectConnect: Game rejected a connection.\n");
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
|
||||
// parse some info from the info strings
|
||||
strncpy (newcl->userinfo, userinfo, sizeof(newcl->userinfo)-1);
|
||||
|
@ -514,7 +504,7 @@ void SV_CalcPings (void)
|
|||
client_t *cl;
|
||||
int total, count;
|
||||
|
||||
for (i=0 ; i<host.maxclients ; i++)
|
||||
for (i=0 ; i<maxclients->value ; i++)
|
||||
{
|
||||
cl = &svs.clients[i];
|
||||
if (cl->state != cs_spawned )
|
||||
|
@ -547,7 +537,7 @@ void SV_CalcPings (void)
|
|||
#endif
|
||||
|
||||
// let the game dll know about the ping
|
||||
//cl->edict->client->ping = cl->ping;
|
||||
cl->edict->client->ping = cl->ping;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -565,16 +555,16 @@ void SV_GiveMsec (void)
|
|||
int i;
|
||||
client_t *cl;
|
||||
|
||||
if (sv.framenum & 15) return;
|
||||
if (sv.framenum & 15)
|
||||
return;
|
||||
|
||||
for (i = 0; i < host.maxclients; i++)
|
||||
for (i=0 ; i<maxclients->value ; i++)
|
||||
{
|
||||
cl = &svs.clients[i];
|
||||
|
||||
if (cl->state == cs_free )
|
||||
continue;
|
||||
|
||||
cl->commandMsec = 1800; // 1600 + some slop
|
||||
cl->commandMsec = 1800; // 1600 + some slop
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -607,7 +597,7 @@ void SV_ReadPackets (void)
|
|||
qport = MSG_ReadShort (&net_message) & 0xffff;
|
||||
|
||||
// check for packets from connected clients
|
||||
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
|
||||
for (i=0, cl=svs.clients ; i<maxclients->value ; i++,cl++)
|
||||
{
|
||||
if (cl->state == cs_free)
|
||||
continue;
|
||||
|
@ -622,8 +612,7 @@ void SV_ReadPackets (void)
|
|||
}
|
||||
|
||||
if (Netchan_Process(&cl->netchan, &net_message))
|
||||
{
|
||||
// this is a valid, sequenced packet, so process it
|
||||
{ // this is a valid, sequenced packet, so process it
|
||||
if (cl->state != cs_zombie)
|
||||
{
|
||||
cl->lastmessage = svs.realtime; // don't timeout
|
||||
|
@ -633,7 +622,7 @@ void SV_ReadPackets (void)
|
|||
break;
|
||||
}
|
||||
|
||||
if (i != host.maxclients)
|
||||
if (i != maxclients->value)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -658,15 +647,17 @@ void SV_CheckTimeouts (void)
|
|||
int droppoint;
|
||||
int zombiepoint;
|
||||
|
||||
droppoint = svs.realtime - timeout->value;
|
||||
zombiepoint = svs.realtime - zombietime->value;
|
||||
droppoint = svs.realtime - 1000*timeout->value;
|
||||
zombiepoint = svs.realtime - 1000*zombietime->value;
|
||||
|
||||
for (i=0,cl=svs.clients ; i<host.maxclients ; i++,cl++)
|
||||
for (i=0,cl=svs.clients ; i<maxclients->value ; i++,cl++)
|
||||
{
|
||||
// message times may be wrong across a changelevel
|
||||
if (cl->lastmessage > svs.realtime) cl->lastmessage = svs.realtime;
|
||||
if (cl->lastmessage > svs.realtime)
|
||||
cl->lastmessage = svs.realtime;
|
||||
|
||||
if (cl->state == cs_zombie && cl->lastmessage < zombiepoint)
|
||||
if (cl->state == cs_zombie
|
||||
&& cl->lastmessage < zombiepoint)
|
||||
{
|
||||
cl->state = cs_free; // can now be reused
|
||||
continue;
|
||||
|
@ -691,15 +682,53 @@ player processing happens outside RunWorldFrame
|
|||
*/
|
||||
void SV_PrepWorldFrame (void)
|
||||
{
|
||||
prvm_edict_t *ent;
|
||||
edict_t *ent;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < prog->num_edicts ; i++, ent++)
|
||||
for (i=0 ; i<ge->num_edicts ; i++, ent++)
|
||||
{
|
||||
ent = PRVM_EDICT_NUM(i);
|
||||
ent = EDICT_NUM(i);
|
||||
// events only last for a single message
|
||||
ent->priv.sv->state.event = 0;
|
||||
ent->s.event = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_RunGameFrame
|
||||
=================
|
||||
*/
|
||||
void SV_RunGameFrame (void)
|
||||
{
|
||||
if (host_speeds->value)
|
||||
time_before_game = Sys_Milliseconds ();
|
||||
|
||||
// we always need to bump framenum, even if we
|
||||
// don't run the world, otherwise the delta
|
||||
// compression can get confused when a client
|
||||
// has the "current" frame
|
||||
sv.framenum++;
|
||||
sv.time = sv.framenum*100;
|
||||
|
||||
// don't run if paused
|
||||
if (!sv_paused->value || maxclients->value > 1)
|
||||
{
|
||||
SV_RunFrame ();
|
||||
|
||||
// never get more than one tic behind
|
||||
if (sv.time < svs.realtime)
|
||||
{
|
||||
if (sv_showclamp->value)
|
||||
Msg ("sv highclamp\n");
|
||||
svs.realtime = sv.time;
|
||||
}
|
||||
}
|
||||
|
||||
if (host_speeds->value)
|
||||
time_after_game = Sys_Milliseconds ();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -708,22 +737,22 @@ SV_Frame
|
|||
|
||||
==================
|
||||
*/
|
||||
void SV_Frame (float time)
|
||||
void SV_Frame (int msec)
|
||||
{
|
||||
// if server is not active, do nothing
|
||||
if (!svs.initialized) return;
|
||||
time_before_game = time_after_game = 0;
|
||||
|
||||
svs.realtime += host.realtime;
|
||||
// if server is not active, do nothing
|
||||
if (!svs.initialized)
|
||||
return;
|
||||
|
||||
svs.realtime += msec;
|
||||
|
||||
// keep the random time dependent
|
||||
rand ();
|
||||
|
||||
// setup the VM frame
|
||||
SV_VM_Begin();
|
||||
|
||||
// check timeouts
|
||||
SV_CheckTimeouts ();
|
||||
|
||||
|
||||
// get packets from clients
|
||||
SV_ReadPackets ();
|
||||
|
||||
|
@ -731,12 +760,13 @@ void SV_Frame (float time)
|
|||
if (!sv_timedemo->value && svs.realtime < sv.time)
|
||||
{
|
||||
// never let the time get too far off
|
||||
if (sv.time - svs.realtime > 0.1)
|
||||
if (sv.time - svs.realtime > 100)
|
||||
{
|
||||
if (sv_showclamp->value) Msg ("sv lowclamp\n");
|
||||
svs.realtime = sv.time - 0.1;
|
||||
if (sv_showclamp->value)
|
||||
Msg ("sv lowclamp\n");
|
||||
svs.realtime = sv.time - 100;
|
||||
}
|
||||
NET_Sleep((sv.time - svs.realtime) * 0.001);
|
||||
NET_Sleep(sv.time - svs.realtime);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -747,7 +777,7 @@ void SV_Frame (float time)
|
|||
SV_GiveMsec ();
|
||||
|
||||
// let everything in the world think and move
|
||||
SV_Physics();
|
||||
SV_RunGameFrame ();
|
||||
|
||||
// send messages back to the clients that had packets read this frame
|
||||
SV_SendClientMessages ();
|
||||
|
@ -761,8 +791,6 @@ void SV_Frame (float time)
|
|||
// clear teleport flags, etc for next frame
|
||||
SV_PrepWorldFrame ();
|
||||
|
||||
// end the server VM frame
|
||||
SV_VM_End();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -781,8 +809,9 @@ void Master_Heartbeat (void)
|
|||
char *string;
|
||||
int i;
|
||||
|
||||
// only dedicated servers send heartbeats
|
||||
if (host.type == HOST_NORMAL) return;
|
||||
// pgm post3.19 change, cvar pointer not validated before dereferencing
|
||||
if (!dedicated || !dedicated->value)
|
||||
return; // only dedicated servers send heartbeats
|
||||
|
||||
// pgm post3.19 change, cvar pointer not validated before dereferencing
|
||||
if (!public_server || !public_server->value)
|
||||
|
@ -792,7 +821,7 @@ void Master_Heartbeat (void)
|
|||
if (svs.last_heartbeat > svs.realtime)
|
||||
svs.last_heartbeat = svs.realtime;
|
||||
|
||||
if (svs.realtime - svs.last_heartbeat < HEARTBEAT_SECONDS)
|
||||
if (svs.realtime - svs.last_heartbeat < HEARTBEAT_SECONDS*1000)
|
||||
return; // not time to send yet
|
||||
|
||||
svs.last_heartbeat = svs.realtime;
|
||||
|
@ -801,14 +830,12 @@ void Master_Heartbeat (void)
|
|||
string = SV_StatusString();
|
||||
|
||||
// send to group master
|
||||
for (i = 0; i < MAX_MASTERS; i++)
|
||||
{
|
||||
for (i=0 ; i<MAX_MASTERS ; i++)
|
||||
if (master_adr[i].port)
|
||||
{
|
||||
Msg ("Sending heartbeat to %s\n", NET_AdrToString (master_adr[i]));
|
||||
Netchan_OutOfBandPrint (NS_SERVER, master_adr[i], "heartbeat\n%s", string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -822,21 +849,22 @@ void Master_Shutdown (void)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (host.type == HOST_NORMAL) return; // only dedicated servers send heartbeats
|
||||
// pgm post3.19 change, cvar pointer not validated before dereferencing
|
||||
if (!dedicated || !dedicated->value)
|
||||
return; // only dedicated servers send heartbeats
|
||||
|
||||
// pgm post3.19 change, cvar pointer not validated before dereferencing
|
||||
if (!public_server || !public_server->value)
|
||||
return; // a private dedicated game
|
||||
|
||||
// send to group master
|
||||
for ( i = 0; i < MAX_MASTERS; i++)
|
||||
{
|
||||
for (i=0 ; i<MAX_MASTERS ; i++)
|
||||
if (master_adr[i].port)
|
||||
{
|
||||
if (i > 0) Msg ("Sending heartbeat to %s\n", NET_AdrToString (master_adr[i]));
|
||||
if (i > 0)
|
||||
Msg ("Sending heartbeat to %s\n", NET_AdrToString (master_adr[i]));
|
||||
Netchan_OutOfBandPrint (NS_SERVER, master_adr[i], "shutdown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -856,7 +884,7 @@ void SV_UserinfoChanged (client_t *cl)
|
|||
int i;
|
||||
|
||||
// call prog code to allow overrides
|
||||
//ge->ClientUserinfoChanged (cl->edict, cl->userinfo);
|
||||
SV_ClientUserinfoChanged(cl->edict, cl->userinfo);
|
||||
|
||||
// name for C code
|
||||
strncpy (cl->name, Info_ValueForKey (cl->userinfo, "name"), sizeof(cl->name)-1);
|
||||
|
@ -910,7 +938,8 @@ void SV_Init (void)
|
|||
Cvar_Get ("timelimit", "0", CVAR_SERVERINFO);
|
||||
Cvar_Get ("cheats", "0", CVAR_SERVERINFO|CVAR_LATCH);
|
||||
Cvar_Get ("protocol", va("%i", PROTOCOL_VERSION), CVAR_SERVERINFO|CVAR_NOSET);;
|
||||
hostname = Cvar_Get ("hostname", "unnamed", CVAR_SERVERINFO | CVAR_ARCHIVE);
|
||||
maxclients = Cvar_Get ("maxclients", "1", CVAR_SERVERINFO | CVAR_LATCH);
|
||||
hostname = Cvar_Get ("hostname", "noname", CVAR_SERVERINFO | CVAR_ARCHIVE);
|
||||
timeout = Cvar_Get ("timeout", "125", 0);
|
||||
zombietime = Cvar_Get ("zombietime", "2", 0);
|
||||
sv_showclamp = Cvar_Get ("showclamp", "0", 0);
|
||||
|
@ -925,17 +954,10 @@ void SV_Init (void)
|
|||
|
||||
sv_noreload = Cvar_Get ("sv_noreload", "0", 0);
|
||||
|
||||
sv_wateraccelerate = Cvar_Get("sv_wateraccelerate", "-1", CVAR_ARCHIVE);
|
||||
sv_airaccelerate = Cvar_Get("sv_airaccelerate", "-1", CVAR_ARCHIVE);
|
||||
sv_accelerate = Cvar_Get("sv_accelerate", "10", CVAR_ARCHIVE);
|
||||
sv_maxvelocity = Cvar_Get("sv_maxvelocity", "2000", CVAR_ARCHIVE );
|
||||
sv_maxspeed = Cvar_Get("sv_maxspeed", "320", CVAR_ARCHIVE);
|
||||
sv_friction = Cvar_Get("sv_friction", "4", CVAR_ARCHIVE);
|
||||
sv_gravity = Cvar_Get("sv_gravity", "800", CVAR_ARCHIVE);
|
||||
|
||||
sv_rollangle = Cvar_Get("sv_rollangle", "2", CVAR_ARCHIVE);
|
||||
sv_rollspeed = Cvar_Get("sv_rollspeed", "200", CVAR_ARCHIVE);
|
||||
|
||||
sv_airaccelerate = Cvar_Get("sv_airaccelerate", "0", CVAR_LATCH);
|
||||
sv_maxvelocity = Cvar_Get("sv_maxvelocity", "2000", 0 );
|
||||
sv_gravity = Cvar_Get("sv_gravity", "800", 0 );
|
||||
|
||||
public_server = Cvar_Get ("public", "0", 0);
|
||||
|
||||
sv_reconnect_limit = Cvar_Get ("sv_reconnect_limit", "3", CVAR_ARCHIVE);
|
||||
|
@ -974,12 +996,12 @@ void SV_FinalMessage (char *message, bool reconnect)
|
|||
// send it twice
|
||||
// stagger the packets to crutch operating system limited buffers
|
||||
|
||||
for (i=0, cl = svs.clients ; i<host.maxclients ; i++, cl++)
|
||||
for (i=0, cl = svs.clients ; i<maxclients->value ; i++, cl++)
|
||||
if (cl->state >= cs_connected)
|
||||
Netchan_Transmit (&cl->netchan, net_message.cursize
|
||||
, net_message.data);
|
||||
|
||||
for (i=0, cl = svs.clients ; i<host.maxclients ; i++, cl++)
|
||||
for (i=0, cl = svs.clients ; i<maxclients->value ; i++, cl++)
|
||||
if (cl->state >= cs_connected)
|
||||
Netchan_Transmit (&cl->netchan, net_message.cursize
|
||||
, net_message.data);
|
||||
|
@ -1000,7 +1022,7 @@ void SV_Shutdown (char *finalmsg, bool reconnect)
|
|||
if (svs.clients) SV_FinalMessage (finalmsg, reconnect);
|
||||
|
||||
Master_Shutdown ();
|
||||
//SV_ShutdownGameProgs ();
|
||||
SV_ShutdownGameProgs ();
|
||||
|
||||
// free current level
|
||||
if (sv.demofile) FS_Close (sv.demofile);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -65,7 +65,7 @@ size_t COM_UnpackString( byte *buffer, int pos, char *string )
|
|||
if(!buffer || !string) return 0;
|
||||
in = buffer + pos;
|
||||
|
||||
do { in++, strsize++; } while(in && *in != '\0');
|
||||
do { in++, strsize++; } while(*in != '\0' && in != NULL );
|
||||
|
||||
strlcpy( string, in - (strsize - 1), strsize );
|
||||
return pos + strsize;
|
||||
|
|
|
@ -99,20 +99,19 @@ void SV_BroadcastPrintf (int level, char *fmt, ...)
|
|||
va_end (argptr);
|
||||
|
||||
// echo to console
|
||||
if (host.type == HOST_DEDICATED)
|
||||
if (dedicated->value)
|
||||
{
|
||||
char copy[1024];
|
||||
int i;
|
||||
|
||||
// mask off high bits
|
||||
for (i = 0; i < 1023 && string[i]; i++)
|
||||
copy[i] = string[i] & 127;
|
||||
|
||||
copy[i] = 0; //write null terminator
|
||||
for (i=0 ; i<1023 && string[i] ; i++)
|
||||
copy[i] = string[i]&127;
|
||||
copy[i] = 0;
|
||||
Msg ("%s", copy);
|
||||
}
|
||||
|
||||
for (i = 0, cl = svs.clients; i < host.maxclients; i++, cl++)
|
||||
for (i=0, cl = svs.clients ; i<maxclients->value; i++, cl++)
|
||||
{
|
||||
if (level < cl->messagelevel)
|
||||
continue;
|
||||
|
@ -160,12 +159,12 @@ MULTICAST_PVS send to clients potentially visible from org
|
|||
MULTICAST_PHS send to clients potentially hearable from org
|
||||
=================
|
||||
*/
|
||||
void _MSG_Send (msgtype_t to, vec3_t origin, prvm_edict_t *ent, const char *filename, int fileline)
|
||||
void _MSG_Send (msgtype_t to, vec3_t origin, edict_t *ent, const char *filename, int fileline)
|
||||
{
|
||||
byte *mask = NULL;
|
||||
int leafnum = 0, cluster = 0;
|
||||
int area1 = 0, area2 = 0;
|
||||
int j, numclients = host.maxclients;
|
||||
int j, numclients = maxclients->value;
|
||||
client_t *client, *current = svs.clients;
|
||||
bool reliable = false;
|
||||
|
||||
|
@ -209,7 +208,7 @@ void _MSG_Send (msgtype_t to, vec3_t origin, prvm_edict_t *ent, const char *file
|
|||
reliable = true; // intentional fallthrough
|
||||
case MSG_ONE:
|
||||
if(ent == NULL) return;
|
||||
j = PRVM_NUM_FOR_EDICT(ent);
|
||||
j = NUM_FOR_EDICT(ent);
|
||||
if (j < 1 || j > numclients) return;
|
||||
current = svs.clients + (j - 1);
|
||||
numclients = 1; // send to one
|
||||
|
@ -229,9 +228,9 @@ void _MSG_Send (msgtype_t to, vec3_t origin, prvm_edict_t *ent, const char *file
|
|||
{
|
||||
area2 = CM_LeafArea (leafnum);
|
||||
cluster = CM_LeafCluster (leafnum);
|
||||
leafnum = CM_PointLeafnum (client->edict->fields.sv->origin);
|
||||
leafnum = CM_PointLeafnum (client->edict->s.origin);
|
||||
if (!CM_AreasConnected (area1, area2)) continue;
|
||||
if ( mask && (!(mask[cluster>>3] & (1<<(cluster & 7))))) continue;
|
||||
if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7))))) continue;
|
||||
}
|
||||
|
||||
if (reliable) SZ_Write (&client->netchan.message, sv.multicast.data, sv.multicast.cursize);
|
||||
|
@ -279,7 +278,7 @@ If origin is NULL, the origin is determined from the entity origin
|
|||
or the midpoint of the entity box for bmodels.
|
||||
==================
|
||||
*/
|
||||
void SV_StartSound (vec3_t origin, prvm_edict_t *entity, int channel, int soundindex, float volume, float attenuation, float timeofs)
|
||||
void SV_StartSound (vec3_t origin, edict_t *entity, int channel, int soundindex, float volume, float attenuation, float timeofs)
|
||||
{
|
||||
int i, ent, flags, sendchan;
|
||||
vec3_t origin_v;
|
||||
|
@ -300,7 +299,7 @@ void SV_StartSound (vec3_t origin, prvm_edict_t *entity, int channel, int soundi
|
|||
MsgWarn("SV_StartSound: timeofs = %f\n", timeofs);
|
||||
timeofs = bound(0, timeofs, 0.255 );
|
||||
}
|
||||
ent = PRVM_NUM_FOR_EDICT(entity);
|
||||
ent = NUM_FOR_EDICT(entity);
|
||||
|
||||
if (channel & 8) // no PHS flag
|
||||
{
|
||||
|
@ -316,7 +315,7 @@ void SV_StartSound (vec3_t origin, prvm_edict_t *entity, int channel, int soundi
|
|||
|
||||
// the client doesn't know that bmodels have weird origins
|
||||
// the origin can also be explicitly set
|
||||
if (((int)entity->fields.sv->flags & SVF_NOCLIENT) || (entity->fields.sv->solid == SOLID_BSP) || origin )
|
||||
if ( (entity->svflags & SVF_NOCLIENT) || (entity->solid == SOLID_BSP) || origin )
|
||||
flags |= SND_POS;
|
||||
|
||||
// always send the entity number for channel overrides
|
||||
|
@ -328,16 +327,16 @@ void SV_StartSound (vec3_t origin, prvm_edict_t *entity, int channel, int soundi
|
|||
if (!origin)
|
||||
{
|
||||
origin = origin_v;
|
||||
if (entity->fields.sv->solid == SOLID_BSP)
|
||||
if (entity->solid == SOLID_BSP)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
origin_v[i] = entity->fields.sv->origin[i]+0.5*(entity->fields.sv->mins[i]+entity->fields.sv->maxs[i]);
|
||||
origin_v[i] = entity->s.origin[i]+0.5*(entity->mins[i]+entity->maxs[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy (entity->fields.sv->origin, origin_v);
|
||||
VectorCopy (entity->s.origin, origin_v);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,8 +418,7 @@ bool SV_SendClientDatagram (client_t *client)
|
|||
SZ_Clear (&client->datagram);
|
||||
|
||||
if (msg.overflowed)
|
||||
{
|
||||
// must have room left for the packet header
|
||||
{ // must have room left for the packet header
|
||||
Msg ("WARNING: msg overflowed for %s\n", client->name);
|
||||
SZ_Clear (&msg);
|
||||
}
|
||||
|
@ -492,8 +490,9 @@ SV_SendClientMessages
|
|||
*/
|
||||
void SV_SendClientMessages (void)
|
||||
{
|
||||
int i;
|
||||
int msglen;
|
||||
int i;
|
||||
client_t *c;
|
||||
int msglen;
|
||||
byte msgbuf[MAX_MSGLEN];
|
||||
|
||||
msglen = 0;
|
||||
|
@ -501,7 +500,8 @@ void SV_SendClientMessages (void)
|
|||
// read the next demo message if needed
|
||||
if (sv.state == ss_demo && sv.demofile)
|
||||
{
|
||||
if (sv_paused->value) msglen = 0;
|
||||
if (sv_paused->value)
|
||||
msglen = 0;
|
||||
else
|
||||
{
|
||||
// get the next message
|
||||
|
@ -527,37 +527,39 @@ void SV_SendClientMessages (void)
|
|||
}
|
||||
|
||||
// send a message to each connected client
|
||||
for (i = 0, sv_client = svs.clients; i < host.maxclients; i++, sv_client++)
|
||||
for (i=0, c = svs.clients ; i<maxclients->value; i++, c++)
|
||||
{
|
||||
if (sv_client->state == cs_free) continue;
|
||||
|
||||
// if the reliable message overflowed, drop the client
|
||||
if (sv_client->netchan.message.overflowed)
|
||||
if (!c->state)
|
||||
continue;
|
||||
// if the reliable message overflowed,
|
||||
// drop the client
|
||||
if (c->netchan.message.overflowed)
|
||||
{
|
||||
SZ_Clear (&sv_client->netchan.message);
|
||||
SZ_Clear (&sv_client->datagram);
|
||||
SV_BroadcastPrintf (PRINT_HIGH, "%s overflowed\n", sv_client->name);
|
||||
SV_DropClient (sv_client);
|
||||
SZ_Clear (&c->netchan.message);
|
||||
SZ_Clear (&c->datagram);
|
||||
SV_BroadcastPrintf (PRINT_HIGH, "%s overflowed\n", c->name);
|
||||
SV_DropClient (c);
|
||||
}
|
||||
|
||||
if (sv.state == ss_cinematic || sv.state == ss_demo || sv.state == ss_pic)
|
||||
{
|
||||
Netchan_Transmit (&sv_client->netchan, msglen, msgbuf);
|
||||
}
|
||||
else if (sv_client->state == cs_spawned)
|
||||
if (sv.state == ss_cinematic
|
||||
|| sv.state == ss_demo
|
||||
|| sv.state == ss_pic
|
||||
)
|
||||
Netchan_Transmit (&c->netchan, msglen, msgbuf);
|
||||
else if (c->state == cs_spawned)
|
||||
{
|
||||
// don't overrun bandwidth
|
||||
if (SV_RateDrop (sv_client)) continue;
|
||||
SV_SendClientDatagram (sv_client);
|
||||
if (SV_RateDrop (c))
|
||||
continue;
|
||||
|
||||
SV_SendClientDatagram (c);
|
||||
}
|
||||
else
|
||||
{
|
||||
// just update reliable if needed
|
||||
if (sv_client->netchan.message.cursize || host.realtime - sv_client->netchan.last_sent > 1.0f)
|
||||
Netchan_Transmit (&sv_client->netchan, 0, NULL);
|
||||
// just update reliable if needed
|
||||
if (c->netchan.message.cursize || curtime - c->netchan.last_sent > 1000 )
|
||||
Netchan_Transmit (&c->netchan, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
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;
|
||||
}
|
||||
|
||||
byte *SV_GetModelPtr(prvm_edict_t *ent)
|
||||
byte *SV_GetModelPtr(edict_t *ent)
|
||||
{
|
||||
if(!ent) return NULL;
|
||||
return NULL;
|
||||
}
|
|
@ -22,17 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "engine.h"
|
||||
#include "server.h"
|
||||
|
||||
extern cvar_t *sv_maxspeed;
|
||||
extern cvar_t *sv_accelerate;
|
||||
extern cvar_t *sv_wateraccelerate;
|
||||
extern cvar_t *sv_friction;
|
||||
extern cvar_t *sv_rollangle;
|
||||
extern cvar_t *sv_rollspeed;
|
||||
|
||||
prvm_edict_t *sv_player;
|
||||
static bool onground;
|
||||
static vec3_t wishdir, forward, right, up;
|
||||
static float wishspeed;
|
||||
edict_t *sv_player;
|
||||
|
||||
/*
|
||||
============================================================
|
||||
|
@ -70,7 +60,7 @@ void SV_New_f (void)
|
|||
{
|
||||
char *gamedir;
|
||||
int playernum;
|
||||
prvm_edict_t *ent;
|
||||
edict_t *ent;
|
||||
|
||||
if (sv_client->state != cs_connected)
|
||||
{
|
||||
|
@ -108,8 +98,8 @@ void SV_New_f (void)
|
|||
if (sv.state == ss_game)
|
||||
{
|
||||
// set up the entity for the client
|
||||
ent = PRVM_EDICT_NUM(playernum+1);
|
||||
ent->priv.sv->state.number = playernum+1;
|
||||
ent = EDICT_NUM(playernum+1);
|
||||
ent->s.number = playernum+1;
|
||||
sv_client->edict = ent;
|
||||
memset (&sv_client->lastcmd, 0, sizeof(sv_client->lastcmd));
|
||||
|
||||
|
@ -204,8 +194,7 @@ void SV_Baselines_f (void)
|
|||
|
||||
// write a packet full of data
|
||||
|
||||
while ( sv_client->netchan.message.cursize < MAX_MSGLEN/2
|
||||
&& start < MAX_EDICTS)
|
||||
while ( sv_client->netchan.message.cursize < MAX_MSGLEN/2 && start < MAX_EDICTS)
|
||||
{
|
||||
base = &sv.baselines[start];
|
||||
if (base->modelindex || base->sound || base->effects)
|
||||
|
@ -237,8 +226,6 @@ SV_Begin_f
|
|||
*/
|
||||
void SV_Begin_f (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
// handle the case of a level changing while a client was connecting
|
||||
if ( atoi(Cmd_Argv(1)) != svs.spawncount )
|
||||
{
|
||||
|
@ -248,22 +235,9 @@ void SV_Begin_f (void)
|
|||
}
|
||||
|
||||
sv_client->state = cs_spawned;
|
||||
|
||||
if(!sv_player->priv.sv->free)
|
||||
{
|
||||
// call the game begin function
|
||||
prog->globals.server->time = sv.time;
|
||||
prog->globals.server->self = PRVM_EDICT_TO_PROG(sv_client->edict);
|
||||
PRVM_ExecuteProgram (prog->globals.server->PutClientInServer, "QC function PutClientInServer is missing");
|
||||
}
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
sv_player->priv.sv->client->pmove.origin[i] = sv_player->priv.sv->state.origin[i] = sv_player->fields.sv->origin[i]*8.0;
|
||||
sv_player->priv.sv->client->pmove.velocity[i] = sv_player->fields.sv->velocity[i]*8.0;
|
||||
}
|
||||
sv_player->priv.sv->client->gunindex = SV_ModelIndex("models/weapons/v_glock.mdl" );
|
||||
sv_player->priv.sv->client->fov = 90;
|
||||
|
||||
|
||||
// call the game begin function
|
||||
SV_ClientBegin(sv_player);
|
||||
Cbuf_InsertFromDefer ();
|
||||
}
|
||||
|
||||
|
@ -370,7 +344,7 @@ void SV_BeginDownload_f(void)
|
|||
}
|
||||
|
||||
SV_NextDownload_f ();
|
||||
MsgDev(D_INFO, "Downloading %s to %s\n", name, sv_client->name);
|
||||
MsgDev (D_INFO, "Downloading %s to %s\n", name, sv_client->name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -485,8 +459,8 @@ void SV_ExecuteUserCommand (char *s)
|
|||
}
|
||||
}
|
||||
|
||||
//if (!u->name && sv.state == ss_game)
|
||||
//ge->ClientCommand (sv_player);
|
||||
if (!u->name && sv.state == ss_game)
|
||||
SV_ClientCommand(sv_player);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -497,18 +471,8 @@ USER CMD EXECUTION
|
|||
===========================================================================
|
||||
*/
|
||||
|
||||
trace_t PM_trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
|
||||
void SV_ClientThink (client_t *cl, usercmd_t *cmd)
|
||||
{
|
||||
return SV_Trace (start, mins, maxs, end, sv_client->edict, MASK_SOLID);
|
||||
}
|
||||
|
||||
void SV_ClientRun (client_t *cl, usercmd_t *cmd)
|
||||
{
|
||||
pmove_t pm;
|
||||
int i;
|
||||
|
||||
sv_client = cl;
|
||||
|
||||
cl->commandMsec -= cmd->msec;
|
||||
|
||||
if (cl->commandMsec < 0 && sv_enforcetime->value )
|
||||
|
@ -516,359 +480,7 @@ void SV_ClientRun (client_t *cl, usercmd_t *cmd)
|
|||
MsgWarn("SV_ClientThink: commandMsec underflow from %s\n", cl->name);
|
||||
return;
|
||||
}
|
||||
|
||||
// set up for pmove
|
||||
memset (&pm, 0, sizeof(pm));
|
||||
cl->edict->priv.sv->client->pmove.pm_flags |= PMF_NO_PREDICTION;
|
||||
|
||||
if (cl->edict->fields.sv->movetype == MOVETYPE_NOCLIP)
|
||||
cl->edict->priv.sv->client->pmove.pm_type = PM_SPECTATOR;
|
||||
else if (cl->edict->fields.sv->movetype == MOVETYPE_WALK)
|
||||
cl->edict->priv.sv->client->pmove.pm_type = PM_NORMAL;
|
||||
else if (cl->edict->fields.sv->movetype == MOVETYPE_NONE)
|
||||
cl->edict->priv.sv->client->pmove.pm_type = PM_FREEZE;
|
||||
cl->edict->priv.sv->client->pmove.gravity = 0;
|
||||
|
||||
pm.s = cl->edict->priv.sv->client->pmove;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
pm.s.origin[i] = cl->edict->fields.sv->origin[i] * 8;
|
||||
pm.s.velocity[i] = cl->edict->fields.sv->velocity[i] * 8;
|
||||
}
|
||||
pm.cmd = *cmd;
|
||||
|
||||
pm.trace = PM_trace; // adds default parms
|
||||
pm.pointcontents = SV_PointContents;
|
||||
|
||||
Msg("org before pmove [%i %i %i]\n", pm.s.origin[0], pm.s.origin[1], pm.s.origin[2] );
|
||||
|
||||
Pmove (&pm); //run pmove
|
||||
|
||||
// save results of pmove
|
||||
cl->edict->priv.sv->client->pmove = pm.s;
|
||||
|
||||
Msg("org after pmove [%i %i %i]\n", pm.s.origin[0], pm.s.origin[1], pm.s.origin[2] );
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
cl->edict->priv.sv->state.old_origin[i] = pm.s.origin[i]*0.125;
|
||||
cl->edict->fields.sv->origin[i] = pm.s.origin[i]*0.125;
|
||||
cl->edict->fields.sv->velocity[i] = pm.s.velocity[i]*0.125;
|
||||
}
|
||||
VectorCopy (pm.mins, cl->edict->fields.sv->mins);
|
||||
VectorCopy (pm.maxs, cl->edict->fields.sv->maxs);
|
||||
|
||||
VectorCopy (pm.viewangles, cl->edict->fields.sv->v_angle);
|
||||
VectorCopy (pm.viewangles, cl->edict->priv.sv->client->viewangles);
|
||||
VectorCopy(cl->edict->fields.sv->view_ofs, cl->edict->priv.sv->client->viewoffset );
|
||||
|
||||
SV_LinkEdict( cl->edict );
|
||||
|
||||
//SV_ClientThink();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
SV_CalcRoll
|
||||
|
||||
===============
|
||||
*/
|
||||
float SV_CalcRoll (vec3_t angles, vec3_t velocity)
|
||||
{
|
||||
float sign;
|
||||
float side;
|
||||
float value;
|
||||
|
||||
side = DotProduct (velocity, right);
|
||||
sign = side < 0 ? -1 : 1;
|
||||
side = fabs(side);
|
||||
|
||||
value = sv_rollangle->value;
|
||||
|
||||
if (side < sv_rollspeed->value)
|
||||
side = side * value / sv_rollspeed->value;
|
||||
else side = value;
|
||||
|
||||
return side*sign;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_UserFriction
|
||||
|
||||
==================
|
||||
*/
|
||||
void SV_UserFriction (void)
|
||||
{
|
||||
float speed, newspeed, control, friction;
|
||||
vec3_t start, stop;
|
||||
trace_t trace;
|
||||
|
||||
speed = sqrt(sv_client->edict->fields.sv->velocity[0]*sv_client->edict->fields.sv->velocity[0]+sv_client->edict->fields.sv->velocity[1]*sv_client->edict->fields.sv->velocity[1]);
|
||||
if (!speed) return;
|
||||
|
||||
// if the leading edge is over a dropoff, increase friction
|
||||
start[0] = stop[0] = sv_client->edict->fields.sv->origin[0] + sv_client->edict->fields.sv->velocity[0]/speed*16;
|
||||
start[1] = stop[1] = sv_client->edict->fields.sv->origin[1] + sv_client->edict->fields.sv->velocity[1]/speed*16;
|
||||
start[2] = sv_client->edict->fields.sv->origin[2] + sv_client->edict->fields.sv->mins[2];
|
||||
stop[2] = start[2] - 34;
|
||||
|
||||
trace = SV_Trace (start, vec3_origin, vec3_origin, stop, sv_client->edict, MASK_SOLID );
|
||||
|
||||
if (trace.fraction == 1.0) friction = sv_friction->value * 2;
|
||||
else friction = sv_friction->value;
|
||||
|
||||
// apply friction
|
||||
|
||||
control = max(speed, 100);
|
||||
newspeed = speed - sv.frametime * control * friction;
|
||||
|
||||
if (newspeed < 0) newspeed = 0;
|
||||
else newspeed /= speed;
|
||||
|
||||
VectorScale(sv_client->edict->fields.sv->velocity, newspeed, sv_client->edict->fields.sv->velocity);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SV_Accelerate
|
||||
==============
|
||||
*/
|
||||
void SV_Accelerate (void)
|
||||
{
|
||||
int i;
|
||||
float addspeed, accelspeed, currentspeed;
|
||||
|
||||
currentspeed = DotProduct (sv_client->edict->fields.sv->velocity, wishdir);
|
||||
addspeed = wishspeed - currentspeed;
|
||||
if (addspeed <= 0) return;
|
||||
accelspeed = sv_accelerate->value * sv.frametime * wishspeed;
|
||||
|
||||
if (accelspeed > addspeed) accelspeed = addspeed;
|
||||
|
||||
for (i = 0; i < 3; i++) sv_client->edict->fields.sv->velocity[i] += accelspeed * wishdir[i];
|
||||
}
|
||||
|
||||
void SV_AirAccelerate (vec3_t wishveloc)
|
||||
{
|
||||
int i;
|
||||
float addspeed, wishspd, accelspeed, currentspeed;
|
||||
|
||||
wishspd = VectorNormalize (wishveloc);
|
||||
if (wishspd > sv_maxspeed->value / 10) wishspd = sv_maxspeed->value / 10;
|
||||
currentspeed = DotProduct (sv_client->edict->fields.sv->velocity, wishveloc);
|
||||
addspeed = wishspd - currentspeed;
|
||||
if (addspeed <= 0) return;
|
||||
accelspeed = (sv_airaccelerate->value < 0 ? sv_accelerate->value : sv_airaccelerate->value) * wishspeed * sv.frametime;
|
||||
if (accelspeed > addspeed) accelspeed = addspeed;
|
||||
|
||||
for (i = 0; i < 3; i++) sv_client->edict->fields.sv->velocity[i] += accelspeed*wishveloc[i];
|
||||
}
|
||||
|
||||
void DropPunchAngle (void)
|
||||
{
|
||||
float len;
|
||||
|
||||
len = VectorNormalize(sv_client->edict->fields.sv->punchangle);
|
||||
|
||||
len -= 10 * sv.frametime;
|
||||
if (len < 0) len = 0;
|
||||
VectorScale (sv_client->edict->fields.sv->punchangle, len, sv_client->edict->fields.sv->punchangle);
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
SV_AirMove
|
||||
|
||||
===================
|
||||
*/
|
||||
void SV_AirMove (void)
|
||||
{
|
||||
int i;
|
||||
vec3_t wishvel;
|
||||
float fmove, smove, temp;
|
||||
|
||||
wishvel[0] = wishvel[2] = 0;
|
||||
wishvel[1] = sv_client->edict->fields.sv->angles[1];
|
||||
AngleVectorsRight (wishvel, forward, right, up);
|
||||
|
||||
fmove = 0;//cmd.forwardmove;
|
||||
smove = 0;//cmd.sidemove;
|
||||
|
||||
// hack to not let you back into teleporter
|
||||
if (sv.time < sv_client->edict->fields.sv->teleport_time && fmove < 0)
|
||||
fmove = 0;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
wishvel[i] = forward[i]*fmove + right[i]*smove;
|
||||
|
||||
if ((int)sv_client->edict->fields.sv->movetype != MOVETYPE_WALK)
|
||||
wishvel[2] += fmove;
|
||||
|
||||
VectorCopy (wishvel, wishdir);
|
||||
wishspeed = VectorNormalize(wishdir);
|
||||
if (wishspeed > sv_maxspeed->value)
|
||||
{
|
||||
temp = sv_maxspeed->value/wishspeed;
|
||||
VectorScale (wishvel, temp, wishvel);
|
||||
wishspeed = sv_maxspeed->value;
|
||||
}
|
||||
|
||||
if (sv_client->edict->fields.sv->movetype == MOVETYPE_NOCLIP)
|
||||
{
|
||||
// noclip
|
||||
VectorCopy (wishvel, sv_client->edict->fields.sv->velocity);
|
||||
}
|
||||
else if (onground && (!(sv_client->edict->fields.sv->button2)))
|
||||
{
|
||||
SV_UserFriction ();
|
||||
SV_Accelerate ();
|
||||
}
|
||||
else
|
||||
{
|
||||
// not on ground, so little effect on velocity
|
||||
SV_AirAccelerate (wishvel);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
SV_WaterMove
|
||||
|
||||
===================
|
||||
*/
|
||||
void SV_WaterMove (void)
|
||||
{
|
||||
int i;
|
||||
vec3_t wishvel;
|
||||
float speed, newspeed, wishspeed, addspeed, accelspeed, temp;
|
||||
|
||||
// user intentions
|
||||
AngleVectorsRight (sv_client->edict->fields.sv->v_angle, forward, right, up);
|
||||
|
||||
/*for (i = 0; i < 3; i++)
|
||||
wishvel[i] = forward[i]*cmd.forwardmove + right[i]*cmd.sidemove;
|
||||
|
||||
if (!cmd.forwardmove && !cmd.sidemove && !cmd.upmove)
|
||||
wishvel[2] -= 60; // drift towards bottom
|
||||
else
|
||||
wishvel[2] += cmd.upmove;
|
||||
|
||||
*/
|
||||
wishspeed = VectorLength(wishvel);
|
||||
if (wishspeed > sv_maxspeed->value)
|
||||
{
|
||||
temp = sv_maxspeed->value/wishspeed;
|
||||
VectorScale (wishvel, temp, wishvel);
|
||||
wishspeed = sv_maxspeed->value;
|
||||
}
|
||||
wishspeed *= 0.7;
|
||||
|
||||
// water friction
|
||||
speed = VectorLength(sv_client->edict->fields.sv->velocity);
|
||||
if (speed)
|
||||
{
|
||||
newspeed = speed - sv.frametime * speed * -1;
|
||||
if (newspeed < 0)
|
||||
newspeed = 0;
|
||||
temp = newspeed/speed;
|
||||
VectorScale(sv_client->edict->fields.sv->velocity, temp, sv_client->edict->fields.sv->velocity);
|
||||
}
|
||||
else
|
||||
newspeed = 0;
|
||||
|
||||
// water acceleration
|
||||
if (!wishspeed)
|
||||
return;
|
||||
|
||||
addspeed = wishspeed - newspeed;
|
||||
if (addspeed <= 0)
|
||||
return;
|
||||
|
||||
VectorNormalize (wishvel);
|
||||
accelspeed = (sv_wateraccelerate->value < 0 ? sv_accelerate->value : sv_wateraccelerate->value) * wishspeed * sv.frametime;
|
||||
if (accelspeed > addspeed) accelspeed = addspeed;
|
||||
|
||||
for (i = 0; i < 3; i++) sv_client->edict->fields.sv->velocity[i] += accelspeed * wishvel[i];
|
||||
}
|
||||
|
||||
void SV_WaterJump (void)
|
||||
{
|
||||
if (sv.time > sv_client->edict->fields.sv->teleport_time || !sv_client->edict->fields.sv->waterlevel)
|
||||
{
|
||||
sv_client->edict->fields.sv->flags = (int)sv_client->edict->fields.sv->flags & ~FL_WATERJUMP;
|
||||
sv_client->edict->fields.sv->teleport_time = 0;
|
||||
}
|
||||
sv_client->edict->fields.sv->velocity[0] = sv_client->edict->fields.sv->movedir[0];
|
||||
sv_client->edict->fields.sv->velocity[1] = sv_client->edict->fields.sv->movedir[1];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
SV_ClientThink
|
||||
|
||||
the move fields specify an intended velocity in pix/sec
|
||||
the angle fields specify an exact angular motion in degrees
|
||||
===================
|
||||
*/
|
||||
void SV_ClientThink (void)
|
||||
{
|
||||
vec3_t v_angle;
|
||||
|
||||
if (sv_client->edict->fields.sv->movetype == MOVETYPE_NONE)
|
||||
return;
|
||||
|
||||
onground = (int)sv_client->edict->fields.sv->flags & FL_ONGROUND;
|
||||
|
||||
DropPunchAngle ();
|
||||
|
||||
// if dead, behave differently
|
||||
if (sv_client->edict->fields.sv->health <= 0) return;
|
||||
|
||||
// angles
|
||||
// show 1/3 the pitch angle and all the roll angle
|
||||
VectorAdd (sv_client->edict->fields.sv->v_angle, sv_client->edict->fields.sv->punchangle, v_angle);
|
||||
sv_client->edict->fields.sv->angles[ROLL] = SV_CalcRoll (sv_client->edict->fields.sv->angles, sv_client->edict->fields.sv->velocity)*4;
|
||||
if (!sv_client->edict->fields.sv->fixangle)
|
||||
{
|
||||
sv_client->edict->fields.sv->angles[PITCH] = -v_angle[PITCH]/3;
|
||||
sv_client->edict->fields.sv->angles[YAW] = v_angle[YAW];
|
||||
}
|
||||
|
||||
if ( (int)sv_client->edict->fields.sv->flags & FL_WATERJUMP )
|
||||
{
|
||||
SV_WaterJump ();
|
||||
return;
|
||||
}
|
||||
|
||||
// walk
|
||||
if ((sv_client->edict->fields.sv->waterlevel >= 2) && (sv_client->edict->fields.sv->movetype != MOVETYPE_NOCLIP))
|
||||
{
|
||||
SV_WaterMove();
|
||||
return;
|
||||
}
|
||||
|
||||
SV_AirMove();
|
||||
}
|
||||
|
||||
void SV_ApplyClientMove (void)
|
||||
{
|
||||
usercmd_t *move = &sv_client->lastcmd;
|
||||
|
||||
if (!move->msec) return;
|
||||
|
||||
// set the edict fields
|
||||
sv_client->edict->fields.sv->button0 = move->buttons & 1;
|
||||
sv_client->edict->fields.sv->button2 = (move->buttons & 2)>>1;
|
||||
if (move->impulse) sv_client->edict->fields.sv->impulse = move->impulse;
|
||||
|
||||
// only send the impulse to qc once
|
||||
move->impulse = 0;
|
||||
VectorCopy(sv_client->edict->priv.sv->client->viewangles, sv_client->edict->fields.sv->v_angle);
|
||||
ClientThink (cl->edict, cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -885,13 +497,13 @@ void SV_ExecuteClientMessage (client_t *cl)
|
|||
int c;
|
||||
char *s;
|
||||
|
||||
usercmd_t nullcmd;
|
||||
usercmd_t oldest, oldcmd, newcmd;
|
||||
usercmd_t nullcmd;
|
||||
usercmd_t oldest, oldcmd, newcmd;
|
||||
int net_drop;
|
||||
int stringCmdCount;
|
||||
int checksum, calculatedChecksum;
|
||||
int checksumIndex;
|
||||
bool move_issued;
|
||||
bool move_issued;
|
||||
int lastframe;
|
||||
|
||||
sv_client = cl;
|
||||
|
@ -963,9 +575,7 @@ void SV_ExecuteClientMessage (client_t *cl)
|
|||
MsgWarn("SV_ExecuteClientMessage: failed command checksum for %s (%d != %d)/%d\n", cl->name, calculatedChecksum, checksum, cl->netchan.incoming_sequence);
|
||||
return;
|
||||
}
|
||||
|
||||
//Msg("sv_paused->value %g\n", sv_paused->value );
|
||||
|
||||
|
||||
if (!sv_paused->value)
|
||||
{
|
||||
net_drop = cl->netchan.dropped;
|
||||
|
@ -973,13 +583,13 @@ void SV_ExecuteClientMessage (client_t *cl)
|
|||
{
|
||||
while (net_drop > 2)
|
||||
{
|
||||
SV_ClientRun (cl, &cl->lastcmd);
|
||||
SV_ClientThink (cl, &cl->lastcmd);
|
||||
net_drop--;
|
||||
}
|
||||
if (net_drop > 1) SV_ClientRun (cl, &oldest);
|
||||
if (net_drop > 0) SV_ClientRun (cl, &oldcmd);
|
||||
if (net_drop > 1) SV_ClientThink (cl, &oldest);
|
||||
if (net_drop > 0) SV_ClientThink (cl, &oldcmd);
|
||||
}
|
||||
SV_ClientRun (cl, &newcmd);
|
||||
SV_ClientThink (cl, &newcmd);
|
||||
}
|
||||
cl->lastcmd = newcmd;
|
||||
break;
|
||||
|
|
|
@ -30,6 +30,14 @@ ENTITY AREA CHECKING
|
|||
FIXME: this use of "area" is different from the bsp file use
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
// (type *)STRUCT_FROM_LINK(link_t *link, type, member)
|
||||
// ent = STRUCT_FROM_LINK(link,entity_t,order)
|
||||
// FIXME: remove this mess!
|
||||
#define STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (int)&(((t *)0)->m)))
|
||||
|
||||
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
|
||||
|
||||
typedef struct areanode_s
|
||||
{
|
||||
int axis; // -1 = leaf node
|
||||
|
@ -45,12 +53,12 @@ typedef struct areanode_s
|
|||
areanode_t sv_areanodes[AREA_NODES];
|
||||
int sv_numareanodes;
|
||||
|
||||
float *area_mins, *area_maxs;
|
||||
prvm_edict_t **area_list;
|
||||
float *area_mins, *area_maxs;
|
||||
edict_t **area_list;
|
||||
int area_count, area_maxcount;
|
||||
int area_type;
|
||||
|
||||
int SV_HullForEntity (prvm_edict_t *ent);
|
||||
int SV_HullForEntity (edict_t *ent);
|
||||
|
||||
|
||||
// ClearLink is used for new headnodes
|
||||
|
@ -65,9 +73,8 @@ void RemoveLink (link_t *l)
|
|||
l->prev->next = l->next;
|
||||
}
|
||||
|
||||
void InsertLinkBefore (link_t *l, link_t *before, int entnum)
|
||||
void InsertLinkBefore (link_t *l, link_t *before)
|
||||
{
|
||||
l->entnum = entnum;
|
||||
l->next = before;
|
||||
l->prev = before->prev;
|
||||
l->prev->next = l;
|
||||
|
@ -140,11 +147,12 @@ SV_UnlinkEdict
|
|||
|
||||
===============
|
||||
*/
|
||||
void SV_UnlinkEdict (prvm_edict_t *ent)
|
||||
void SV_UnlinkEdict (edict_t *ent)
|
||||
{
|
||||
if (!ent->priv.sv->area.prev) return; // not linked in anywhere
|
||||
RemoveLink (&ent->priv.sv->area);
|
||||
ent->priv.sv->area.prev = ent->priv.sv->area.next = NULL;
|
||||
if (!ent->area.prev)
|
||||
return; // not linked in anywhere
|
||||
RemoveLink (&ent->area);
|
||||
ent->area.prev = ent->area.next = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -155,95 +163,90 @@ SV_LinkEdict
|
|||
===============
|
||||
*/
|
||||
#define MAX_TOTAL_ENT_LEAFS 128
|
||||
void SV_LinkEdict (prvm_edict_t *ent)
|
||||
void SV_LinkEdict (edict_t *ent)
|
||||
{
|
||||
areanode_t *node;
|
||||
int leafs[MAX_TOTAL_ENT_LEAFS];
|
||||
int clusters[MAX_TOTAL_ENT_LEAFS];
|
||||
int num_leafs;
|
||||
int i, j, k;
|
||||
int area;
|
||||
int topnode;
|
||||
int leafs[MAX_TOTAL_ENT_LEAFS];
|
||||
int clusters[MAX_TOTAL_ENT_LEAFS];
|
||||
int num_leafs;
|
||||
int i, j, k;
|
||||
int area;
|
||||
int topnode;
|
||||
|
||||
if (ent->priv.sv->area.prev) SV_UnlinkEdict (ent); // unlink from old position
|
||||
if (ent == prog->edicts) return; // don't add the world
|
||||
if (ent->priv.sv->free)
|
||||
{
|
||||
Msg("Can't link entity [%d]\n", ent->priv.sv->state.number );
|
||||
return;
|
||||
}
|
||||
if (ent->area.prev) SV_UnlinkEdict (ent); // unlink from old position
|
||||
if (ent == ge->edicts) return; // don't add the world
|
||||
if (!ent->inuse) return;
|
||||
|
||||
// set the size
|
||||
VectorSubtract (ent->fields.sv->maxs, ent->fields.sv->mins, ent->fields.sv->size);
|
||||
VectorSubtract (ent->maxs, ent->mins, ent->size);
|
||||
|
||||
// encode the size into the entity_state for client prediction
|
||||
if (ent->fields.sv->solid == SOLID_BBOX && !((int)ent->fields.sv->flags & SVF_DEADMONSTER))
|
||||
if (ent->solid == SOLID_BBOX && !(ent->svflags & SVF_DEADMONSTER))
|
||||
{
|
||||
// assume that x/y are equal and symetric
|
||||
i = ent->fields.sv->maxs[0]/8;
|
||||
if(i < 1) i = 1;
|
||||
if(i > 31) i = 31;
|
||||
i = ent->maxs[0]/8;
|
||||
if (i<1) i = 1;
|
||||
if (i>31) i = 31;
|
||||
|
||||
// z is not symetric
|
||||
j = (-ent->fields.sv->mins[2])/8;
|
||||
j = (-ent->mins[2])/8;
|
||||
if (j < 1) j = 1;
|
||||
if (j > 31) j = 31;
|
||||
|
||||
// and z maxs can be negative...
|
||||
k = (ent->fields.sv->maxs[2]+32)/8;
|
||||
if (k < 1) k = 1;
|
||||
if (k > 63) k = 63;
|
||||
ent->fields.sv->solid = (k<<10) | (j<<5) | i;
|
||||
k = (ent->maxs[2]+32)/8;
|
||||
if (k<1) k = 1;
|
||||
if (k>63) k = 63;
|
||||
ent->s.solid = (k<<10) | (j<<5) | i;
|
||||
}
|
||||
else if (ent->fields.sv->solid == SOLID_BSP)
|
||||
else if (ent->solid == SOLID_BSP)
|
||||
{
|
||||
ent->fields.sv->solid = 31; // a solid_bbox will never create this value
|
||||
ent->s.solid = 31; // a solid_bbox will never create this value
|
||||
}
|
||||
else ent->fields.sv->solid = 0;
|
||||
else ent->s.solid = 0;
|
||||
|
||||
// set the abs box
|
||||
if (ent->fields.sv->solid == SOLID_BSP && (!VectorIsNull(ent->fields.sv->angles)))
|
||||
if (ent->solid == SOLID_BSP && (ent->s.angles[0] || ent->s.angles[1] || ent->s.angles[2]) )
|
||||
{
|
||||
// expand for rotation
|
||||
float max = 0, v;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
v =fabs( ent->fields.sv->mins[i]);
|
||||
v =fabs( ent->mins[i]);
|
||||
if (v > max) max = v;
|
||||
v =fabs( ent->fields.sv->maxs[i]);
|
||||
v =fabs( ent->maxs[i]);
|
||||
if (v > max) max = v;
|
||||
}
|
||||
for (i = 0; i < 3; i++)
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
ent->fields.sv->absmin[i] = ent->fields.sv->origin[i] - max;
|
||||
ent->fields.sv->absmax[i] = ent->fields.sv->origin[i] + max;
|
||||
ent->absmin[i] = ent->s.origin[i] - max;
|
||||
ent->absmax[i] = ent->s.origin[i] + max;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal
|
||||
VectorAdd (ent->fields.sv->origin, ent->fields.sv->mins, ent->fields.sv->absmin);
|
||||
VectorAdd (ent->fields.sv->origin, ent->fields.sv->maxs, ent->fields.sv->absmax);
|
||||
{ // normal
|
||||
VectorAdd (ent->s.origin, ent->mins, ent->absmin);
|
||||
VectorAdd (ent->s.origin, ent->maxs, ent->absmax);
|
||||
}
|
||||
|
||||
// because movement is clipped an epsilon away from an actual edge,
|
||||
// we must fully check even when bounding boxes don't quite touch
|
||||
ent->fields.sv->absmin[0] -= 1;
|
||||
ent->fields.sv->absmin[1] -= 1;
|
||||
ent->fields.sv->absmin[2] -= 1;
|
||||
ent->fields.sv->absmax[0] += 1;
|
||||
ent->fields.sv->absmax[1] += 1;
|
||||
ent->fields.sv->absmax[2] += 1;
|
||||
ent->absmin[0] -= 1;
|
||||
ent->absmin[1] -= 1;
|
||||
ent->absmin[2] -= 1;
|
||||
ent->absmax[0] += 1;
|
||||
ent->absmax[1] += 1;
|
||||
ent->absmax[2] += 1;
|
||||
|
||||
// link to PVS leafs
|
||||
ent->priv.sv->num_clusters = 0;
|
||||
ent->priv.sv->areanum = 0;
|
||||
ent->priv.sv->areanum2 = 0;
|
||||
ent->num_clusters = 0;
|
||||
ent->areanum = 0;
|
||||
ent->areanum2 = 0;
|
||||
|
||||
//get all leafs, including solids
|
||||
num_leafs = CM_BoxLeafnums (ent->fields.sv->absmin, ent->fields.sv->absmax, leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
|
||||
num_leafs = CM_BoxLeafnums (ent->absmin, ent->absmax, leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
|
||||
|
||||
// set areas
|
||||
for (i = 0; i < num_leafs; i++)
|
||||
|
@ -253,25 +256,25 @@ void SV_LinkEdict (prvm_edict_t *ent)
|
|||
if (area)
|
||||
{ // doors may legally straggle two areas,
|
||||
// but nothing should evern need more than that
|
||||
if (ent->priv.sv->areanum && ent->priv.sv->areanum != area)
|
||||
if (ent->areanum && ent->areanum != area)
|
||||
{
|
||||
if (ent->priv.sv->areanum2 && ent->priv.sv->areanum2 != area && sv.state == ss_loading)
|
||||
MsgWarn("SV_LinkEdict: object touching 3 areas at %f %f %f\n", ent->fields.sv->absmin[0], ent->fields.sv->absmin[1], ent->fields.sv->absmin[2]);
|
||||
ent->priv.sv->areanum2 = area;
|
||||
if (ent->areanum2 && ent->areanum2 != area && sv.state == ss_loading)
|
||||
MsgWarn("SV_LinkEdict: object touching 3 areas at %f %f %f\n", ent->absmin[0], ent->absmin[1], ent->absmin[2]);
|
||||
ent->areanum2 = area;
|
||||
}
|
||||
else ent->priv.sv->areanum = area;
|
||||
else ent->areanum = area;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_leafs >= MAX_TOTAL_ENT_LEAFS)
|
||||
{
|
||||
// assume we missed some leafs, and mark by headnode
|
||||
ent->priv.sv->num_clusters = -1;
|
||||
ent->priv.sv->headnode = topnode;
|
||||
ent->num_clusters = -1;
|
||||
ent->headnode = topnode;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->priv.sv->num_clusters = 0;
|
||||
ent->num_clusters = 0;
|
||||
for (i = 0; i < num_leafs; i++)
|
||||
{
|
||||
if (clusters[i] == -1) continue; // not a visible leaf
|
||||
|
@ -281,43 +284,42 @@ void SV_LinkEdict (prvm_edict_t *ent)
|
|||
}
|
||||
if (j == i)
|
||||
{
|
||||
if (ent->priv.sv->num_clusters == MAX_ENT_CLUSTERS)
|
||||
if (ent->num_clusters == MAX_ENT_CLUSTERS)
|
||||
{
|
||||
// assume we missed some leafs, and mark by headnode
|
||||
ent->priv.sv->num_clusters = -1;
|
||||
ent->priv.sv->headnode = topnode;
|
||||
ent->num_clusters = -1;
|
||||
ent->headnode = topnode;
|
||||
break;
|
||||
}
|
||||
ent->priv.sv->clusternums[ent->priv.sv->num_clusters++] = clusters[i];
|
||||
ent->clusternums[ent->num_clusters++] = clusters[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if first time, make sure old_origin is valid
|
||||
if (!ent->priv.sv->linkcount)
|
||||
if (!ent->linkcount)
|
||||
{
|
||||
VectorCopy (ent->fields.sv->origin, ent->fields.sv->oldorigin);
|
||||
VectorCopy (ent->s.origin, ent->s.old_origin);
|
||||
}
|
||||
ent->priv.sv->linkcount++;
|
||||
ent->linkcount++;
|
||||
|
||||
if (ent->fields.sv->solid == SOLID_NOT) return;
|
||||
if (ent->solid == SOLID_NOT) return;
|
||||
|
||||
// find the first node that the ent's box crosses
|
||||
node = sv_areanodes;
|
||||
while (1)
|
||||
{
|
||||
if (node->axis == -1) break;
|
||||
if (ent->fields.sv->absmin[node->axis] > node->dist)
|
||||
if (ent->absmin[node->axis] > node->dist)
|
||||
node = node->children[0];
|
||||
else if (ent->fields.sv->absmax[node->axis] < node->dist)
|
||||
else if (ent->absmax[node->axis] < node->dist)
|
||||
node = node->children[1];
|
||||
else break; // crosses the node
|
||||
}
|
||||
|
||||
// link it in
|
||||
if (ent->fields.sv->solid == SOLID_TRIGGER)
|
||||
InsertLinkBefore (&ent->priv.sv->area, &node->trigger_edicts, PRVM_NUM_FOR_EDICT(ent));
|
||||
else InsertLinkBefore (&ent->priv.sv->area, &node->solid_edicts, PRVM_NUM_FOR_EDICT(ent));
|
||||
if (ent->solid == SOLID_TRIGGER) InsertLinkBefore (&ent->area, &node->trigger_edicts);
|
||||
else InsertLinkBefore (&ent->area, &node->solid_edicts);
|
||||
|
||||
}
|
||||
|
||||
|
@ -331,7 +333,7 @@ SV_AreaEdicts_r
|
|||
void SV_AreaEdicts_r (areanode_t *node)
|
||||
{
|
||||
link_t *l, *next, *start;
|
||||
prvm_edict_t *check;
|
||||
edict_t *check;
|
||||
int count = 0;
|
||||
|
||||
// touch linked edicts
|
||||
|
@ -342,11 +344,11 @@ void SV_AreaEdicts_r (areanode_t *node)
|
|||
for (l = start->next; l != start; l = next)
|
||||
{
|
||||
next = l->next;
|
||||
check = PRVM_EDICT_NUM_UNSIGNED(l->entnum);
|
||||
check = EDICT_FROM_AREA(l);
|
||||
|
||||
if (check->fields.sv->solid == SOLID_NOT) continue; // deactivated
|
||||
if (check->fields.sv->absmin[0] > area_maxs[0] || check->fields.sv->absmin[1] > area_maxs[1] || check->fields.sv->absmin[2] > area_maxs[2]
|
||||
|| check->fields.sv->absmax[0] < area_mins[0] || check->fields.sv->absmax[1] < area_mins[1] || check->fields.sv->absmax[2] < area_mins[2])
|
||||
if (check->solid == SOLID_NOT) continue; // deactivated
|
||||
if (check->absmin[0] > area_maxs[0] || check->absmin[1] > area_maxs[1] || check->absmin[2] > area_maxs[2]
|
||||
|| check->absmax[0] < area_mins[0] || check->absmax[1] < area_mins[1] || check->absmax[2] < area_mins[2])
|
||||
continue; // not touching
|
||||
|
||||
if (area_count == area_maxcount)
|
||||
|
@ -362,8 +364,10 @@ void SV_AreaEdicts_r (areanode_t *node)
|
|||
if (node->axis == -1) return; // terminal node
|
||||
|
||||
// recurse down both sides
|
||||
if ( area_maxs[node->axis] > node->dist ) SV_AreaEdicts_r ( node->children[0] );
|
||||
if ( area_mins[node->axis] < node->dist ) SV_AreaEdicts_r ( node->children[1] );
|
||||
if ( area_maxs[node->axis] > node->dist )
|
||||
SV_AreaEdicts_r ( node->children[0] );
|
||||
if ( area_mins[node->axis] < node->dist )
|
||||
SV_AreaEdicts_r ( node->children[1] );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -371,7 +375,7 @@ void SV_AreaEdicts_r (areanode_t *node)
|
|||
SV_AreaEdicts
|
||||
================
|
||||
*/
|
||||
int SV_AreaEdicts (vec3_t mins, vec3_t maxs, prvm_edict_t **list, int maxcount, int areatype)
|
||||
int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype)
|
||||
{
|
||||
area_mins = mins;
|
||||
area_maxs = maxs;
|
||||
|
@ -395,7 +399,7 @@ SV_PointContents
|
|||
*/
|
||||
int SV_PointContents (vec3_t p)
|
||||
{
|
||||
prvm_edict_t *touch[MAX_EDICTS], *hit;
|
||||
edict_t *touch[MAX_EDICTS], *hit;
|
||||
int i, num;
|
||||
int contents, c2;
|
||||
int headnode;
|
||||
|
@ -413,14 +417,30 @@ int SV_PointContents (vec3_t p)
|
|||
|
||||
// might intersect, so do an exact clip
|
||||
headnode = SV_HullForEntity (hit);
|
||||
angles = hit->fields.sv->angles;
|
||||
if (hit->fields.sv->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
|
||||
c2 = CM_TransformedPointContents (p, headnode, hit->fields.sv->origin, hit->fields.sv->angles);
|
||||
angles = hit->s.angles;
|
||||
if (hit->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
|
||||
c2 = CM_TransformedPointContents (p, headnode, hit->s.origin, hit->s.angles);
|
||||
contents |= c2;
|
||||
}
|
||||
return contents;
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t boxmins, boxmaxs;// enclose the test object along entire move
|
||||
float *mins, *maxs; // size of the moving object
|
||||
vec3_t mins2, maxs2; // size when clipping against mosnters
|
||||
float *start, *end;
|
||||
trace_t trace;
|
||||
edict_t *passedict;
|
||||
int contentmask;
|
||||
|
||||
} moveclip_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
SV_HullForEntity
|
||||
|
@ -431,15 +451,15 @@ Offset is filled in to contain the adjustment that must be added to the
|
|||
testing object's origin to get a point to use with the returned hull.
|
||||
================
|
||||
*/
|
||||
int SV_HullForEntity (prvm_edict_t *ent)
|
||||
int SV_HullForEntity (edict_t *ent)
|
||||
{
|
||||
cmodel_t *model;
|
||||
|
||||
// decide which clipping hull to use, based on the size
|
||||
if (ent->fields.sv->solid == SOLID_BSP)
|
||||
if (ent->solid == SOLID_BSP)
|
||||
{
|
||||
// explicit hulls in the BSP model
|
||||
model = sv.models[ (int)ent->fields.sv->modelindex ];
|
||||
model = sv.models[ ent->s.modelindex ];
|
||||
|
||||
if (!model)
|
||||
{
|
||||
|
@ -450,7 +470,7 @@ int SV_HullForEntity (prvm_edict_t *ent)
|
|||
}
|
||||
|
||||
// create a temp hull from bounding box sizes
|
||||
return CM_HeadnodeForBox (ent->fields.sv->mins, ent->fields.sv->maxs);
|
||||
return CM_HeadnodeForBox (ent->mins, ent->maxs);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -462,7 +482,7 @@ SV_ClipMoveToEntities
|
|||
void SV_ClipMoveToEntities ( moveclip_t *clip )
|
||||
{
|
||||
int i, num;
|
||||
prvm_edict_t *touchlist[MAX_EDICTS], *touch;
|
||||
edict_t *touchlist[MAX_EDICTS], *touch;
|
||||
trace_t trace;
|
||||
int headnode;
|
||||
float *angles;
|
||||
|
@ -474,32 +494,30 @@ void SV_ClipMoveToEntities ( moveclip_t *clip )
|
|||
for (i = 0; i < num; i++)
|
||||
{
|
||||
touch = touchlist[i];
|
||||
if (touch->fields.sv->solid == SOLID_NOT) continue;
|
||||
if (touch->solid == SOLID_NOT) continue;
|
||||
if (touch == clip->passedict) continue;
|
||||
if (clip->trace.allsolid) return;
|
||||
if (clip->passedict)
|
||||
{
|
||||
if (PRVM_PROG_TO_EDICT(touch->fields.sv->owner) == clip->passedict)
|
||||
continue; // don't clip against own missiles
|
||||
if (PRVM_PROG_TO_EDICT(clip->passedict->fields.sv->owner) == touch)
|
||||
continue; // don't clip against owner
|
||||
if (touch->owner == clip->passedict) continue; // don't clip against own missiles
|
||||
if (clip->passedict->owner == touch) continue; // don't clip against owner
|
||||
}
|
||||
|
||||
if ( !(clip->contentmask & CONTENTS_DEADMONSTER) && ((int)touch->fields.sv->flags & SVF_DEADMONSTER) )
|
||||
if ( !(clip->contentmask & CONTENTS_DEADMONSTER) && (touch->svflags & SVF_DEADMONSTER) )
|
||||
continue;
|
||||
|
||||
// might intersect, so do an exact clip
|
||||
headnode = SV_HullForEntity (touch);
|
||||
angles = touch->fields.sv->angles;
|
||||
if (touch->fields.sv->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
|
||||
angles = touch->s.angles;
|
||||
if (touch->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
|
||||
|
||||
if ((int)touch->fields.sv->flags & SVF_MONSTER)
|
||||
if (touch->svflags & SVF_MONSTER)
|
||||
{
|
||||
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins2, clip->maxs2, headnode, clip->contentmask, touch->fields.sv->origin, angles);
|
||||
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins2, clip->maxs2, headnode, clip->contentmask, touch->s.origin, angles);
|
||||
}
|
||||
else
|
||||
{
|
||||
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins, clip->maxs, headnode, clip->contentmask, touch->fields.sv->origin, angles);
|
||||
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins, clip->maxs, headnode, clip->contentmask, touch->s.origin, angles);
|
||||
}
|
||||
if (trace.allsolid || trace.startsolid || trace.fraction < clip->trace.fraction)
|
||||
{
|
||||
|
@ -511,11 +529,7 @@ void SV_ClipMoveToEntities ( moveclip_t *clip )
|
|||
}
|
||||
else clip->trace = trace;
|
||||
}
|
||||
else if (trace.startsolid)
|
||||
{
|
||||
clip->trace.startsolid = true;
|
||||
//clip->trace.startstuck = true;
|
||||
}
|
||||
else if (trace.startsolid) clip->trace.startsolid = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -554,7 +568,7 @@ Passedict and edicts owned by passedict are explicitly not checked.
|
|||
|
||||
==================
|
||||
*/
|
||||
trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, prvm_edict_t *passedict, int contentmask)
|
||||
trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask)
|
||||
{
|
||||
moveclip_t clip;
|
||||
|
||||
|
@ -565,7 +579,7 @@ trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, prvm_edict
|
|||
|
||||
// clip to world
|
||||
clip.trace = CM_BoxTrace (start, end, mins, maxs, 0, contentmask);
|
||||
clip.trace.ent = prog->edicts;
|
||||
clip.trace.ent = ge->edicts;
|
||||
if (clip.trace.fraction == 0) return clip.trace; // blocked by the world
|
||||
|
||||
clip.contentmask = contentmask;
|
||||
|
@ -587,8 +601,3 @@ trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, prvm_edict
|
|||
return clip.trace;
|
||||
}
|
||||
|
||||
trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int contentsmask)
|
||||
{
|
||||
// correct ??
|
||||
return CM_BoxTrace(start, end, mins, maxs, ent->priv.sv->headnode, contentsmask);
|
||||
}
|
|
@ -53,8 +53,8 @@ vec3_t listener_up;
|
|||
|
||||
bool s_registering;
|
||||
|
||||
float soundtime; // sample PAIRS
|
||||
float paintedtime; // sample PAIRS
|
||||
int soundtime; // sample PAIRS
|
||||
int paintedtime; // sample PAIRS
|
||||
|
||||
// during registration it is possible to have more sounds
|
||||
// than could actually be referenced during gameplay,
|
||||
|
@ -80,7 +80,7 @@ cvar_t *s_mixahead;
|
|||
cvar_t *s_primary;
|
||||
|
||||
|
||||
float s_rawend;
|
||||
int s_rawend;
|
||||
portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
|
||||
|
||||
|
||||
|
@ -120,7 +120,8 @@ void S_Init (void)
|
|||
Msg("\n------- sound initialization -------\n");
|
||||
|
||||
cv = Cvar_Get ("s_initsound", "1", 0);
|
||||
if (!cv->value) Msg ("not initializing.\n");
|
||||
if (!cv->value)
|
||||
Msg ("not initializing.\n");
|
||||
else
|
||||
{
|
||||
s_volume = Cvar_Get ("s_volume", "0.7", CVAR_ARCHIVE);
|
||||
|
@ -136,7 +137,8 @@ void S_Init (void)
|
|||
Cmd_AddCommand("soundlist", S_SoundList);
|
||||
Cmd_AddCommand("soundinfo", S_SoundInfo_f);
|
||||
|
||||
if (!SNDDMA_Init()) return;
|
||||
if (!SNDDMA_Init())
|
||||
return;
|
||||
|
||||
S_InitScaletable ();
|
||||
|
||||
|
@ -147,6 +149,7 @@ void S_Init (void)
|
|||
paintedtime = 0;
|
||||
|
||||
Msg ("sound sampling rate: %i\n", dma.speed);
|
||||
|
||||
S_StopAllSounds ();
|
||||
}
|
||||
|
||||
|
@ -163,7 +166,8 @@ void S_Shutdown(void)
|
|||
int i;
|
||||
sfx_t *sfx;
|
||||
|
||||
if (!sound_started) return;
|
||||
if (!sound_started)
|
||||
return;
|
||||
|
||||
SNDDMA_Shutdown();
|
||||
|
||||
|
@ -177,10 +181,13 @@ void S_Shutdown(void)
|
|||
// free all sounds
|
||||
for (i=0, sfx=known_sfx ; i < num_sfx ; i++,sfx++)
|
||||
{
|
||||
if (!sfx->name[0]) continue;
|
||||
if (sfx->cache) Z_Free (sfx->cache);
|
||||
if (!sfx->name[0])
|
||||
continue;
|
||||
if (sfx->cache)
|
||||
Z_Free (sfx->cache);
|
||||
memset (sfx, 0, sizeof(*sfx));
|
||||
}
|
||||
|
||||
num_sfx = 0;
|
||||
}
|
||||
|
||||
|
@ -195,7 +202,7 @@ S_FindName
|
|||
|
||||
==================
|
||||
*/
|
||||
sfx_t *S_FindName (const char *name, bool create)
|
||||
sfx_t *S_FindName (char *name, bool create)
|
||||
{
|
||||
int i;
|
||||
sfx_t *sfx;
|
||||
|
@ -295,7 +302,7 @@ S_RegisterSound
|
|||
|
||||
==================
|
||||
*/
|
||||
sfx_t *S_RegisterSound (const char *name)
|
||||
sfx_t *S_RegisterSound (char *name)
|
||||
{
|
||||
sfx_t *sfx;
|
||||
|
||||
|
@ -364,19 +371,18 @@ S_PickChannel
|
|||
*/
|
||||
channel_t *S_PickChannel(int entnum, int entchannel)
|
||||
{
|
||||
int ch_idx;
|
||||
int first_to_die;
|
||||
float life_left;
|
||||
int ch_idx;
|
||||
int first_to_die;
|
||||
int life_left;
|
||||
channel_t *ch;
|
||||
|
||||
if (entchannel<0)
|
||||
Com_Error (ERR_DROP, "S_PickChannel: entchannel<0");
|
||||
|
||||
// Check for replacement sound, or find the best one to replace
|
||||
first_to_die = -1;
|
||||
life_left = 32768.0;
|
||||
|
||||
for (ch_idx = 0; ch_idx < MAX_CHANNELS; ch_idx++)
|
||||
// Check for replacement sound, or find the best one to replace
|
||||
first_to_die = -1;
|
||||
life_left = 0x7fffffff;
|
||||
for (ch_idx=0 ; ch_idx < MAX_CHANNELS ; ch_idx++)
|
||||
{
|
||||
if (entchannel != 0 // channel 0 never overrides
|
||||
&& channels[ch_idx].entnum == entnum
|
||||
|
@ -686,16 +692,16 @@ void S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float f
|
|||
ps->sfx = sfx;
|
||||
|
||||
// drift s_beginofs
|
||||
start = cl.frame.servertime * dma.speed + s_beginofs;
|
||||
start = cl.frame.servertime * 0.001 * dma.speed + s_beginofs;
|
||||
if (start < paintedtime)
|
||||
{
|
||||
start = paintedtime;
|
||||
s_beginofs = start - (cl.frame.servertime * dma.speed);
|
||||
s_beginofs = start - (cl.frame.servertime * 0.001 * dma.speed);
|
||||
}
|
||||
else if (start > paintedtime + 0.3 * dma.speed)
|
||||
{
|
||||
start = paintedtime + 0.1 * dma.speed;
|
||||
s_beginofs = start - (cl.frame.servertime * dma.speed);
|
||||
s_beginofs = start - (cl.frame.servertime * 0.001 * dma.speed);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -726,7 +732,7 @@ void S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float f
|
|||
S_StartLocalSound
|
||||
==================
|
||||
*/
|
||||
int S_StartLocalSound (const char *sound)
|
||||
int S_StartLocalSound (char *sound)
|
||||
{
|
||||
sfx_t *sfx;
|
||||
|
||||
|
@ -886,7 +892,7 @@ void S_AddLoopSounds (void)
|
|||
ch->rightvol = right_total;
|
||||
ch->autosound = true; // remove next frame
|
||||
ch->sfx = sfx;
|
||||
ch->pos = fmod(paintedtime, sc->length);
|
||||
ch->pos = paintedtime % sc->length;
|
||||
ch->end = paintedtime + sc->length - ch->pos;
|
||||
}
|
||||
}
|
||||
|
@ -920,7 +926,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
|
|||
{ // optimized case
|
||||
for (i=0 ; i<samples ; i++)
|
||||
{
|
||||
dst = (int)s_rawend & (MAX_RAW_SAMPLES - 1);
|
||||
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left =
|
||||
LittleShort(((short *)data)[i*2]) << 8;
|
||||
|
@ -935,7 +941,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
|
|||
src = i*scale;
|
||||
if (src >= samples)
|
||||
break;
|
||||
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
|
||||
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left =
|
||||
LittleShort(((short *)data)[src*2]) << 8;
|
||||
|
@ -951,7 +957,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
|
|||
src = i*scale;
|
||||
if (src >= samples)
|
||||
break;
|
||||
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
|
||||
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left =
|
||||
LittleShort(((short *)data)[src]) << 8;
|
||||
|
@ -966,7 +972,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
|
|||
src = i*scale;
|
||||
if (src >= samples)
|
||||
break;
|
||||
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
|
||||
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left =
|
||||
((char *)data)[src*2] << 16;
|
||||
|
@ -981,7 +987,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
|
|||
src = i*scale;
|
||||
if (src >= samples)
|
||||
break;
|
||||
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
|
||||
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left =
|
||||
(((byte *)data)[src]-128) << 16;
|
||||
|
@ -1104,8 +1110,8 @@ void GetSoundtime(void)
|
|||
|
||||
void S_Update_(void)
|
||||
{
|
||||
uint endtime;
|
||||
int samps;
|
||||
unsigned endtime;
|
||||
int samps;
|
||||
|
||||
if (!sound_started)
|
||||
return;
|
||||
|
@ -1121,7 +1127,7 @@ void S_Update_(void)
|
|||
// check to make sure that we haven't overshot
|
||||
if (paintedtime < soundtime)
|
||||
{
|
||||
MsgWarn("S_Update_: overflow [%g]\n", soundtime - paintedtime);
|
||||
MsgWarn("S_Update_: overflow\n");
|
||||
paintedtime = soundtime;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
float length;
|
||||
int length;
|
||||
int loopstart;
|
||||
int speed; // not needed, because converted on load?
|
||||
int width;
|
||||
|
@ -39,7 +39,7 @@ typedef struct
|
|||
typedef struct sfx_s
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
int registration_sequence;
|
||||
int registration_sequence;
|
||||
sfxcache_t *cache;
|
||||
char *truename;
|
||||
} sfx_t;
|
||||
|
@ -53,21 +53,21 @@ typedef struct playsound_s
|
|||
sfx_t *sfx;
|
||||
float volume;
|
||||
float attenuation;
|
||||
int entnum;
|
||||
int entchannel;
|
||||
bool fixed_origin; // use origin field instead of entnum's origin
|
||||
int entnum;
|
||||
int entchannel;
|
||||
bool fixed_origin; // use origin field instead of entnum's origin
|
||||
vec3_t origin;
|
||||
float begin; // begin on this sample
|
||||
unsigned begin; // begin on this sample
|
||||
} playsound_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int channels;
|
||||
int samples; // mono samples in buffer
|
||||
int submission_chunk; // don't mix less than this #
|
||||
int samplepos; // in mono samples
|
||||
int samplebits;
|
||||
int speed;
|
||||
int channels;
|
||||
int samples; // mono samples in buffer
|
||||
int submission_chunk; // don't mix less than this #
|
||||
int samplepos; // in mono samples
|
||||
int samplebits;
|
||||
int speed;
|
||||
byte *buffer;
|
||||
} dma_t;
|
||||
|
||||
|
@ -75,18 +75,18 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
sfx_t *sfx; // sfx number
|
||||
int leftvol; // 0-255 volume
|
||||
int rightvol; // 0-255 volume
|
||||
float end; // end time in global paintsamples
|
||||
int leftvol; // 0-255 volume
|
||||
int rightvol; // 0-255 volume
|
||||
int end; // end time in global paintsamples
|
||||
int pos; // sample position in sfx
|
||||
int looping; // where to loop, -1 = no looping OBSOLETE?
|
||||
int entnum; // to allow overriding a specific sound
|
||||
int entchannel; //
|
||||
int looping; // where to loop, -1 = no looping OBSOLETE?
|
||||
int entnum; // to allow overriding a specific sound
|
||||
int entchannel; //
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
vec_t dist_mult; // distance multiplier (attenuation/clipK)
|
||||
int master_vol; // 0-255 master volume
|
||||
bool fixed_origin; // use origin instead of fetching entnum's origin
|
||||
bool autosound; // from an entity->sound, cleared each frame
|
||||
int master_vol; // 0-255 master volume
|
||||
bool fixed_origin; // use origin instead of fetching entnum's origin
|
||||
bool autosound; // from an entity->sound, cleared each frame
|
||||
} channel_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -126,8 +126,8 @@ void SNDDMA_Submit(void);
|
|||
#define MAX_CHANNELS 32
|
||||
extern channel_t channels[MAX_CHANNELS];
|
||||
|
||||
extern float paintedtime;
|
||||
extern float s_rawend;
|
||||
extern int paintedtime;
|
||||
extern int s_rawend;
|
||||
extern vec3_t listener_origin;
|
||||
extern vec3_t listener_forward;
|
||||
extern vec3_t listener_right;
|
||||
|
@ -155,7 +155,7 @@ sfxcache_t *S_LoadSound (sfx_t *s);
|
|||
|
||||
void S_IssuePlaysound (playsound_t *ps);
|
||||
|
||||
void S_PaintChannels(float endtime);
|
||||
void S_PaintChannels(int endtime);
|
||||
|
||||
// picks a channel based on priorities, empty slots, number of channels
|
||||
channel_t *S_PickChannel(int entnum, int entchannel);
|
||||
|
|
|
@ -109,17 +109,17 @@ S_TransferPaintBuffer
|
|||
|
||||
===================
|
||||
*/
|
||||
void S_TransferPaintBuffer(float endtime)
|
||||
void S_TransferPaintBuffer(int endtime)
|
||||
{
|
||||
int out_idx;
|
||||
float count;
|
||||
int count;
|
||||
int out_mask;
|
||||
int *p;
|
||||
int step;
|
||||
int val;
|
||||
dword *pbuf;
|
||||
int val;
|
||||
unsigned long *pbuf;
|
||||
|
||||
pbuf = (dword*)dma.buffer;
|
||||
pbuf = (unsigned long *)dma.buffer;
|
||||
|
||||
if (s_testsound->value)
|
||||
{
|
||||
|
@ -129,7 +129,7 @@ void S_TransferPaintBuffer(float endtime)
|
|||
// write a fixed sine wave
|
||||
count = (endtime - paintedtime);
|
||||
for (i=0 ; i<count ; i++)
|
||||
paintbuffer[i].left = paintbuffer[i].right = sin((paintedtime+i)*0.1)*20*256;
|
||||
paintbuffer[i].left = paintbuffer[i].right = sin((paintedtime+i)*0.1)*20000*256;
|
||||
}
|
||||
|
||||
|
||||
|
@ -142,7 +142,7 @@ void S_TransferPaintBuffer(float endtime)
|
|||
p = (int *) paintbuffer;
|
||||
count = (endtime - paintedtime) * dma.channels;
|
||||
out_mask = dma.samples - 1;
|
||||
out_idx = (int)(paintedtime * dma.channels) & out_mask;
|
||||
out_idx = paintedtime * dma.channels & out_mask;
|
||||
step = 3 - dma.channels;
|
||||
|
||||
if (dma.samplebits == 16)
|
||||
|
@ -190,18 +190,18 @@ CHANNEL MIXING
|
|||
void S_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int endtime, int offset);
|
||||
void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime, int offset);
|
||||
|
||||
void S_PaintChannels(float endtime)
|
||||
void S_PaintChannels(int endtime)
|
||||
{
|
||||
int i;
|
||||
float end;
|
||||
channel_t *ch;
|
||||
int i;
|
||||
int end;
|
||||
channel_t *ch;
|
||||
sfxcache_t *sc;
|
||||
float ltime, count;
|
||||
int ltime, count;
|
||||
playsound_t *ps;
|
||||
|
||||
snd_vol = s_volume->value*256;
|
||||
|
||||
//Msg ("%i to %i\n", paintedtime, endtime);
|
||||
//Msg ("%i to %i\n", paintedtime, endtime);
|
||||
while (paintedtime < endtime)
|
||||
{
|
||||
// if paintbuffer is smaller than DMA buffer
|
||||
|
@ -221,11 +221,12 @@ void S_PaintChannels(float endtime)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (ps->begin < end) end = ps->begin;// stop here
|
||||
if (ps->begin < end)
|
||||
end = ps->begin; // stop here
|
||||
break;
|
||||
}
|
||||
|
||||
// clear the paint buffer
|
||||
// clear the paint buffer
|
||||
if (s_rawend < paintedtime)
|
||||
{
|
||||
// Msg ("clear\n");
|
||||
|
@ -241,7 +242,7 @@ void S_PaintChannels(float endtime)
|
|||
for (i=paintedtime ; i<stop ; i++)
|
||||
{
|
||||
s = i&(MAX_RAW_SAMPLES-1);
|
||||
paintbuffer[(int)(i - paintedtime)] = s_rawsamples[s];
|
||||
paintbuffer[i-paintedtime] = s_rawsamples[s];
|
||||
}
|
||||
// if (i != end)
|
||||
// Msg ("partial stream\n");
|
||||
|
@ -249,8 +250,8 @@ void S_PaintChannels(float endtime)
|
|||
// Msg ("full stream\n");
|
||||
for ( ; i<end ; i++)
|
||||
{
|
||||
paintbuffer[(int)(i - paintedtime)].left =
|
||||
paintbuffer[(int)(i - paintedtime)].right = 0;
|
||||
paintbuffer[i-paintedtime].left =
|
||||
paintbuffer[i-paintedtime].right = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ void S_Shutdown (void);
|
|||
|
||||
// if origin is NULL, the sound will be dynamically sourced from the entity
|
||||
void S_StartSound (vec3_t origin, int entnum, int entchannel, struct sfx_s *sfx, float fvol, float attenuation, float timeofs);
|
||||
int S_StartLocalSound (const char *s);
|
||||
int S_StartLocalSound (char *s);
|
||||
|
||||
void S_RawSamples (int samples, int rate, int width, int channels, byte *data);
|
||||
|
||||
|
@ -35,10 +35,10 @@ void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up);
|
|||
void S_Activate (bool active);
|
||||
|
||||
void S_BeginRegistration (void);
|
||||
struct sfx_s *S_RegisterSound (const char *sample);
|
||||
struct sfx_s *S_RegisterSound (char *sample);
|
||||
void S_EndRegistration (void);
|
||||
|
||||
struct sfx_s *S_FindName (const char *name, bool create);
|
||||
struct sfx_s *S_FindName (char *name, bool create);
|
||||
|
||||
// the sound code makes callbacks to the client for entitiy position
|
||||
// information, so entities can be dynamically re-spatialized
|
||||
|
|
134
engine/system.c
134
engine/system.c
|
@ -27,6 +27,10 @@ extern HWND cl_hwnd;
|
|||
//engine builddate
|
||||
char *buildstring = __TIME__ " " __DATE__;
|
||||
stdinout_api_t std;
|
||||
uint sys_msg_time;
|
||||
uint sys_frame_time;
|
||||
|
||||
int starttime;
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
@ -79,34 +83,12 @@ void Sys_Init (void)
|
|||
{
|
||||
OSVERSIONINFO vinfo;
|
||||
|
||||
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
|
||||
|
||||
timeBeginPeriod( 1 );
|
||||
|
||||
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
|
||||
|
||||
if (!GetVersionEx (&vinfo)) Sys_Error ("Couldn't get OS info");
|
||||
if (vinfo.dwMajorVersion < 4) Sys_Error ("%s requires windows version 4 or greater", GI.title);
|
||||
srand(time(NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_Milliseconds
|
||||
================
|
||||
*/
|
||||
int Sys_Milliseconds ( void )
|
||||
{
|
||||
int sys_curtime;
|
||||
static int sys_timeBase;
|
||||
static bool init = false;
|
||||
|
||||
if (!init)
|
||||
{
|
||||
sys_timeBase = timeGetTime();
|
||||
init = true;
|
||||
}
|
||||
sys_curtime = timeGetTime() - sys_timeBase;
|
||||
|
||||
return sys_curtime;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -118,20 +100,18 @@ Send Key_Event calls
|
|||
*/
|
||||
void Sys_SendKeyEvents (void)
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
rand();
|
||||
MSG msg;
|
||||
|
||||
while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
|
||||
{
|
||||
if (!GetMessage (&msg, NULL, 0, 0)) Sys_Quit ();
|
||||
host.sv_timer = msg.time;
|
||||
sys_msg_time = msg.time;
|
||||
TranslateMessage (&msg);
|
||||
DispatchMessage (&msg);
|
||||
}
|
||||
|
||||
// grab frame time
|
||||
host.cl_timer = timeGetTime(); // FIXME: should this be at start?
|
||||
sys_frame_time = timeGetTime(); // FIXME: should this be at start?
|
||||
}
|
||||
|
||||
|
||||
|
@ -165,6 +145,28 @@ char *Sys_GetClipboardData( void )
|
|||
return data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_Milliseconds
|
||||
================
|
||||
*/
|
||||
int curtime;
|
||||
int Sys_Milliseconds (void)
|
||||
{
|
||||
static int sys_timeBase;
|
||||
static bool init = false;
|
||||
|
||||
if (!init)
|
||||
{
|
||||
sys_timeBase = timeGetTime();
|
||||
init = true;
|
||||
}
|
||||
curtime = timeGetTime() - sys_timeBase;
|
||||
|
||||
return curtime;
|
||||
}
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
|
@ -184,80 +186,6 @@ void Sys_AppActivate (void)
|
|||
SetForegroundWindow ( cl_hwnd );
|
||||
}
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
GAME DLL
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
/*
|
||||
=================
|
||||
Sys_UnloadGame
|
||||
=================
|
||||
*/
|
||||
void Sys_UnloadGame( void *hinstance )
|
||||
{
|
||||
if(!hinstance) return;
|
||||
FreeLibrary(hinstance);
|
||||
hinstance = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_LoadGame
|
||||
|
||||
Loads the game dll
|
||||
=================
|
||||
*/
|
||||
void *Sys_LoadGame (const char* procname, void *hinstance, void *parms)
|
||||
{
|
||||
void *(*GetGameAPI) (void *);
|
||||
char basepath[MAX_SYSPATH];
|
||||
search_t *gamedll;
|
||||
int i;
|
||||
|
||||
Sys_UnloadGame( hinstance );
|
||||
|
||||
//find server.dll
|
||||
gamedll = FS_Search( "bin/*.dll" );
|
||||
if(!gamedll)
|
||||
{
|
||||
Com_Error (ERR_DROP, "Can't find game.dll\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// now run through the search paths
|
||||
for( i = 0; i < gamedll->numfilenames; i++ )
|
||||
{
|
||||
sprintf(basepath, "%s/%s", GI.gamedir, gamedll->filenames[i]);
|
||||
hinstance = LoadLibrary ( basepath );
|
||||
|
||||
if (!hinstance)
|
||||
{
|
||||
sprintf(basepath, "%s/%s", GI.basedir, gamedll->filenames[i]);
|
||||
hinstance = LoadLibrary ( basepath );
|
||||
}
|
||||
|
||||
if (hinstance)
|
||||
{
|
||||
if (( GetGameAPI = (void *)GetProcAddress( hinstance, procname )) == 0 )
|
||||
Sys_UnloadGame( hinstance );
|
||||
else break;
|
||||
}
|
||||
else MsgWarn("Can't loading %s\n", gamedll->filenames[i] );
|
||||
}
|
||||
|
||||
GetGameAPI = (void *)GetProcAddress (hinstance, procname );
|
||||
|
||||
if (!GetGameAPI)
|
||||
{
|
||||
Sys_UnloadGame( hinstance );
|
||||
return NULL;
|
||||
}
|
||||
return GetGameAPI (parms);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
||||
/*
|
||||
|
|
|
@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
renderer_exp_t *re;
|
||||
|
||||
extern HWND cl_hwnd;
|
||||
extern bool ActiveApp, Minimized;
|
||||
extern HINSTANCE global_hInstance;
|
||||
|
||||
#ifndef WM_MOUSEWHEEL
|
||||
|
@ -54,6 +55,9 @@ HWND cl_hwnd; // Main window handle for life of program
|
|||
|
||||
LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
|
||||
extern unsigned sys_msg_time;
|
||||
|
||||
/*
|
||||
==========================================================================
|
||||
|
||||
|
@ -179,25 +183,29 @@ int MapKey (int key)
|
|||
}
|
||||
}
|
||||
|
||||
void AppActivate(bool fActive, bool fMinimize)
|
||||
void AppActivate(BOOL fActive, BOOL minimize)
|
||||
{
|
||||
if(fActive && !fMinimize) host.state = HOST_FRAME;
|
||||
else if(fMinimize) host.state = HOST_SLEEP;
|
||||
else host.state = HOST_NOFOCUS;
|
||||
Minimized = minimize;
|
||||
|
||||
Key_ClearStates();
|
||||
|
||||
// minimize/restore mouse-capture on demand
|
||||
if(host.state == HOST_FRAME)
|
||||
{
|
||||
IN_Activate (true);
|
||||
S_Activate (true);
|
||||
}
|
||||
// we don't want to act like we're active if we're minimized
|
||||
if (fActive && !Minimized)
|
||||
ActiveApp = true;
|
||||
else
|
||||
ActiveApp = false;
|
||||
|
||||
// minimize/restore mouse-capture on demand
|
||||
if (!ActiveApp)
|
||||
{
|
||||
IN_Activate (false);
|
||||
S_Activate (false);
|
||||
}
|
||||
else
|
||||
{
|
||||
IN_Activate (true);
|
||||
S_Activate (true);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -215,13 +223,13 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
{
|
||||
if ( ( ( int ) wParam ) > 0 )
|
||||
{
|
||||
Key_Event( K_MWHEELUP, true, host.sv_timer );
|
||||
Key_Event( K_MWHEELUP, false, host.sv_timer );
|
||||
Key_Event( K_MWHEELUP, true, sys_msg_time );
|
||||
Key_Event( K_MWHEELUP, false, sys_msg_time );
|
||||
}
|
||||
else
|
||||
{
|
||||
Key_Event( K_MWHEELDOWN, true, host.sv_timer );
|
||||
Key_Event( K_MWHEELDOWN, false, host.sv_timer );
|
||||
Key_Event( K_MWHEELDOWN, true, sys_msg_time );
|
||||
Key_Event( K_MWHEELDOWN, false, sys_msg_time );
|
||||
}
|
||||
return DefWindowProc (hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
@ -235,13 +243,13 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
*/
|
||||
if ( ( short ) HIWORD( wParam ) > 0 )
|
||||
{
|
||||
Key_Event( K_MWHEELUP, true, host.sv_timer );
|
||||
Key_Event( K_MWHEELUP, false, host.sv_timer );
|
||||
Key_Event( K_MWHEELUP, true, sys_msg_time );
|
||||
Key_Event( K_MWHEELUP, false, sys_msg_time );
|
||||
}
|
||||
else
|
||||
{
|
||||
Key_Event( K_MWHEELDOWN, true, host.sv_timer );
|
||||
Key_Event( K_MWHEELDOWN, false, host.sv_timer );
|
||||
Key_Event( K_MWHEELDOWN, true, sys_msg_time );
|
||||
Key_Event( K_MWHEELDOWN, false, sys_msg_time );
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -297,7 +305,7 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
Cvar_SetValue( "vid_ypos", yPos + r.top);
|
||||
vid_xpos->modified = false;
|
||||
vid_ypos->modified = false;
|
||||
if (host.state == HOST_FRAME)
|
||||
if (ActiveApp)
|
||||
IN_Activate (true);
|
||||
}
|
||||
}
|
||||
|
@ -343,11 +351,11 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
// fall through
|
||||
case WM_KEYDOWN:
|
||||
Key_Event( MapKey( lParam ), true, host.sv_timer);
|
||||
Key_Event( MapKey( lParam ), true, sys_msg_time);
|
||||
break;
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
Key_Event( MapKey( lParam ), false, host.sv_timer);
|
||||
Key_Event( MapKey( lParam ), false, sys_msg_time);
|
||||
break;
|
||||
default: // pass all unhandled messages to DefWindowProc
|
||||
return DefWindowProc (hWnd, uMsg, wParam, lParam);
|
||||
|
@ -462,12 +470,6 @@ char *FS_Title( void )
|
|||
return GI.title;
|
||||
}
|
||||
|
||||
cvar_t *VID_Cvar_Set (const char *var_name, const char *value)
|
||||
{
|
||||
return Cvar_Set( var_name, value );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
VID_InitRenderer
|
||||
|
@ -496,7 +498,7 @@ void VID_InitRenderer( void )
|
|||
ri.gamedir = FS_Gamedir;
|
||||
ri.title = FS_Title;
|
||||
ri.Cvar_Get = Cvar_Get;
|
||||
ri.Cvar_Set = VID_Cvar_Set;
|
||||
ri.Cvar_Set = Cvar_Set;
|
||||
ri.Cvar_SetValue = Cvar_SetValue;
|
||||
ri.Vid_GetModeInfo = VID_GetModeInfo;
|
||||
ri.Vid_MenuInit = VID_MenuInit;
|
||||
|
|
|
@ -33,13 +33,12 @@ _inline void VectorScale(const vec3_t a, const float b, vec3_t c){c[0]=b*a[0];c[
|
|||
#define VectorSet(v, x, y, z) {v[0] = x; v[1] = y; v[2] = z;}
|
||||
#define VectorClear(x) {x[0] = x[1] = x[2] = 0;}
|
||||
#define VectorNegate(x, y) {y[0] =-x[0]; y[1]=-x[1]; y[2]=-x[2];}
|
||||
_inline float anglemod(const float a){return(360.0/65536) * ((int)(a*(65536/360.0)) & 65535);}
|
||||
|
||||
#define VectorM(scale1, b1, c) ((c)[0] = (scale1) * (b1)[0],(c)[1] = (scale1) * (b1)[1],(c)[2] = (scale1) * (b1)[2])
|
||||
#define VectorMA(a, scale, b, c) ((c)[0] = (a)[0] + (scale) * (b)[0],(c)[1] = (a)[1] + (scale) * (b)[1],(c)[2] = (a)[2] + (scale) * (b)[2])
|
||||
#define VectorMAM(scale1, b1, scale2, b2, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2])
|
||||
#define VectorMAMAM(scale1, b1, scale2, b2, scale3, b3, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0] + (scale3) * (b3)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1] + (scale3) * (b3)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2] + (scale3) * (b3)[2])
|
||||
#define VectorMAMAMAM(scale1, b1, scale2, b2, scale3, b3, scale4, b4, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0] + (scale3) * (b3)[0] + (scale4) * (b4)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1] + (scale3) * (b3)[1] + (scale4) * (b4)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2] + (scale3) * (b3)[2] + (scale4) * (b4)[2])
|
||||
|
||||
_inline float anglemod(const float a){return(360.0/65536) * ((int)(a*(65536/360.0)) & 65535);}
|
||||
|
||||
_inline void VectorBound(const float min, vec3_t v, const float max)
|
||||
{
|
||||
|
@ -130,13 +129,6 @@ _inline void VectorIRotate (const vec3_t in1, const matrix3x4 in2, vec3_t out)
|
|||
out[2] = in1[0] * in2[0][2] + in1[1] * in2[1][2] + in1[2] * in2[2][2];
|
||||
}
|
||||
|
||||
_inline void VectorMA (vec3_t va, double scale, vec3_t vb, vec3_t vc)
|
||||
{
|
||||
vc[0] = va[0] + scale * vb[0];
|
||||
vc[1] = va[1] + scale * vb[1];
|
||||
vc[2] = va[2] + scale * vb[2];
|
||||
}
|
||||
|
||||
_inline void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross)
|
||||
{
|
||||
cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
|
||||
|
@ -177,7 +169,7 @@ _inline void VectorVectors(vec3_t forward, vec3_t right, vec3_t up)
|
|||
CrossProduct(right, forward, up);
|
||||
}
|
||||
|
||||
_inline void AngleVectorsRight(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
|
||||
_inline void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
|
||||
{
|
||||
float angle;
|
||||
static float sr, sp, sy, cr, cp, cy;
|
||||
|
@ -199,45 +191,21 @@ _inline void AngleVectorsRight(vec3_t angles, vec3_t forward, vec3_t right, vec3
|
|||
forward[1] = cp*sy;
|
||||
forward[2] = -sp;
|
||||
}
|
||||
if (right || up)
|
||||
if (right)
|
||||
{
|
||||
if (angles[ROLL])
|
||||
{
|
||||
angle = angles[ROLL] * (M_PI*2 / 360);
|
||||
sr = sin(angle);
|
||||
cr = cos(angle);
|
||||
if (right)
|
||||
{
|
||||
right[0] = -1*(sr*sp*cy+cr*-sy);
|
||||
right[1] = -1*(sr*sp*sy+cr*cy);
|
||||
right[2] = -1*(sr*cp);
|
||||
}
|
||||
if (up)
|
||||
{
|
||||
up[0] = (cr*sp*cy+-sr*-sy);
|
||||
up[1] = (cr*sp*sy+-sr*cy);
|
||||
up[2] = cr*cp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (right)
|
||||
{
|
||||
right[0] = sy;
|
||||
right[1] = -cy;
|
||||
right[2] = 0;
|
||||
}
|
||||
if (up)
|
||||
{
|
||||
up[0] = (sp*cy);
|
||||
up[1] = (sp*sy);
|
||||
up[2] = cp;
|
||||
}
|
||||
}
|
||||
right[0] = (-1*sr*sp*cy+-1*cr*-sy);
|
||||
right[1] = (-1*sr*sp*sy+-1*cr*cy);
|
||||
right[2] = -1*sr*cp;
|
||||
}
|
||||
if (up)
|
||||
{
|
||||
up[0] = (cr*sp*cy+-sr*-sy);
|
||||
up[1] = (cr*sp*sy+-sr*cy);
|
||||
up[2] = cr*cp;
|
||||
}
|
||||
}
|
||||
|
||||
_inline void AngleVectorsLeft(const vec3_t angles, vec3_t forward, vec3_t left, vec3_t up)
|
||||
_inline void AngleVectorsFLU(const vec3_t angles, vec3_t forward, vec3_t left, vec3_t up)
|
||||
{
|
||||
float angle;
|
||||
static float sr, sp, sy, cr, cp, cy;
|
||||
|
|
|
@ -44,6 +44,8 @@ typedef struct vfile_s vfile_t;
|
|||
typedef struct image_s image_t;
|
||||
typedef struct model_s model_t;
|
||||
typedef int func_t;
|
||||
typedef struct edict_s edict_t;
|
||||
typedef struct gclient_s gclient_t;
|
||||
typedef int string_t;
|
||||
typedef int progsnum_t;
|
||||
typedef struct progfuncs_s progfuncs_t;
|
||||
|
|
|
@ -207,15 +207,6 @@ typedef struct cmodel_s
|
|||
vec3_t mins, maxs; // boundbox
|
||||
vec3_t origin; // for sounds or lights
|
||||
int headnode; // bsp info
|
||||
|
||||
vec3_t normalmins; // bounding box at angles '0 0 0'
|
||||
vec3_t normalmaxs;
|
||||
|
||||
vec3_t yawmins; // bounding box if yaw angle is not 0, but pitch and roll are used
|
||||
vec3_t yawmaxs;
|
||||
|
||||
vec3_t rotatedmins; // bounding box if pitch or roll are used
|
||||
vec3_t rotatedmaxs;
|
||||
|
||||
int numframes; //sprite framecount
|
||||
void *extradata; //for studio models
|
||||
|
|
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_CHAT 3 // chat messages
|
||||
|
||||
#define SPAWNFLAG_NOT_EASY 256
|
||||
#define SPAWNFLAG_NOT_MEDIUM 512
|
||||
#define SPAWNFLAG_NOT_HARD 1024
|
||||
#define SPAWNFLAG_NOT_DEATHMATCH 2048
|
||||
#define SPAWNFLAG_NOT_EASY 0x00000100
|
||||
#define SPAWNFLAG_NOT_MEDIUM 0x00000200
|
||||
#define SPAWNFLAG_NOT_HARD 0x00000400
|
||||
#define SPAWNFLAG_NOT_DEATHMATCH 0x00000800
|
||||
|
||||
// entity_state_t->renderfx flags
|
||||
#define RF_MINLIGHT 1 // allways have some light (viewmodel)
|
||||
|
@ -148,29 +148,23 @@ typedef enum
|
|||
WEAPON_FIRING
|
||||
} weaponstate_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SOLID_NOT, // no interaction with other objects
|
||||
SOLID_TRIGGER, // only touch when inside, after moving
|
||||
SOLID_BBOX, // touch on edge
|
||||
SOLID_BSP // bsp clip, touch on edge
|
||||
} solid_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MOVETYPE_NONE = 0, // never moves, but can collide
|
||||
MOVETYPE_NOCLIP, // origin and angles change with no interaction
|
||||
MOVETYPE_PUSH, // no clip to world, push on box contact
|
||||
MOVETYPE_WALK, // player case
|
||||
MOVETYPE_STEP, // monster case (get rid of this)
|
||||
MOVETYPE_FLY, // ignore gravity
|
||||
MOVETYPE_TOSS, // gravity
|
||||
MOVETYPE_BOUNCE,
|
||||
MOVETYPE_FOLLOW, // attached models
|
||||
MOVETYPE_COMPLEX, // complex moving ents (parent system)
|
||||
MOVETYPE_RAGDOLL, // npc ragdoll (not implemented yet)
|
||||
|
||||
} movetype_t;
|
||||
#define MOVETYPE_NONE 0 // never moves
|
||||
#define MOVETYPE_NOCLIP 1 // origin and angles change with no interaction
|
||||
#define MOVETYPE_PUSH 2 // no clip to world, push on box contact
|
||||
#define MOVETYPE_STOP 3 // no clip to world, stops on box contact
|
||||
#define MOVETYPE_WALK 4 // gravity
|
||||
#define MOVETYPE_STEP 5 // gravity, special edge handling
|
||||
#define MOVETYPE_FLY 6
|
||||
#define MOVETYPE_TOSS 7 // gravity
|
||||
#define MOVETYPE_FLYMISSILE 8 // extra size to monsters
|
||||
#define MOVETYPE_BOUNCE 9
|
||||
#define MOVETYPE_FOLLOW 10 // attached models
|
||||
#define MOVETYPE_VEHICLE 11
|
||||
#define MOVETYPE_PUSHABLE 12
|
||||
#define MOVETYPE_DEBRIS 13 // non-solid debris that can still hurt you
|
||||
#define MOVETYPE_RAIN 14 // identical to MOVETYPE_FLYMISSILE, but doesn't cause splash noises when touching water.
|
||||
#define MOVETYPE_PENDULUM 15 // same as MOVETYPE_PUSH, but used only for pendulums to grab special-case problems
|
||||
#define MOVETYPE_CONVEYOR 16
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
@ -217,8 +211,30 @@ void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal );
|
|||
void PerpendicularVector( vec3_t dst, const vec3_t src );
|
||||
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );
|
||||
|
||||
|
||||
|
||||
void Com_PageInMemory (byte *buffer, int size);
|
||||
|
||||
//=============================================
|
||||
|
||||
//
|
||||
// key / value info strings
|
||||
//
|
||||
char *Info_ValueForKey (char *s, char *key);
|
||||
void Info_RemoveKey (char *s, char *key);
|
||||
void Info_SetValueForKey (char *s, char *key, char *value);
|
||||
bool Info_Validate (char *s);
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
||||
SYSTEM SPECIFIC
|
||||
|
||||
==============================================================
|
||||
*/
|
||||
|
||||
extern int curtime; // time returned by last Sys_Milliseconds
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
||||
|
@ -247,16 +263,14 @@ COLLISION DETECTION
|
|||
// a trace is returned when a box is swept through the world
|
||||
typedef struct
|
||||
{
|
||||
bool allsolid; // if true, plane is not valid
|
||||
bool startsolid; // if true, the initial point was in a solid area
|
||||
bool startstuck; // if true, the initial point was stuck into SOLID_BSP model
|
||||
|
||||
float fraction; // time completed, 1.0 = didn't hit anything
|
||||
bool allsolid; // if true, plane is not valid
|
||||
bool startsolid; // if true, the initial point was in a solid area
|
||||
float fraction; // time completed, 1.0 = didn't hit anything
|
||||
vec3_t endpos; // final position
|
||||
cplane_t plane; // surface normal at impact
|
||||
csurface_t *surface; // surface hit
|
||||
int contents; // contents on other side of surface hit
|
||||
prvm_edict_t *ent; // not set by CM_*() functions
|
||||
cplane_t plane; // surface normal at impact
|
||||
csurface_t *surface; // surface hit
|
||||
int contents; // contents on other side of surface hit
|
||||
struct edict_s *ent; // not set by CM_*() functions
|
||||
} trace_t;
|
||||
|
||||
|
||||
|
@ -298,7 +312,7 @@ typedef struct
|
|||
byte pm_time; // each unit = 8 ms
|
||||
short gravity;
|
||||
short delta_angles[3]; // add to command angles to get view direction
|
||||
// changed by spawns, rotating objects, and teleporters
|
||||
// changed by spawns, rotating objects, and teleporters
|
||||
} pmove_state_t;
|
||||
|
||||
|
||||
|
@ -324,7 +338,6 @@ typedef struct usercmd_s
|
|||
short forwardmove, sidemove, upmove;
|
||||
byte impulse; // remove?
|
||||
byte lightlevel; // light level the player is standing on
|
||||
|
||||
} usercmd_t;
|
||||
|
||||
|
||||
|
@ -340,14 +353,14 @@ typedef struct
|
|||
|
||||
// results (out)
|
||||
int numtouch;
|
||||
prvm_edict_t *touchents[MAXTOUCH];
|
||||
struct edict_s *touchents[MAXTOUCH];
|
||||
|
||||
vec3_t viewangles; // clamped
|
||||
float viewheight;
|
||||
|
||||
vec3_t mins, maxs; // bounding box size
|
||||
|
||||
prvm_edict_t *groundentity;
|
||||
struct edict_s *groundentity;
|
||||
int watertype;
|
||||
int waterlevel;
|
||||
|
||||
|
@ -790,16 +803,16 @@ typedef struct
|
|||
|
||||
// these fields do not need to be communicated bit-precise
|
||||
|
||||
vec3_t viewangles; // for fixed views
|
||||
vec3_t viewoffset; // add to pmovestate->origin
|
||||
vec3_t viewangles; // for fixed views
|
||||
vec3_t viewoffset; // add to pmovestate->origin
|
||||
vec3_t kick_angles; // add to view direction to get render angles
|
||||
// set by weapon kicks, pain effects, etc
|
||||
// set by weapon kicks, pain effects, etc
|
||||
|
||||
vec3_t gunangles;
|
||||
vec3_t gunoffset;
|
||||
int gunindex;
|
||||
int gunframe; // studio frame
|
||||
int sequence; // studio animation sequence
|
||||
int sequence; // stuido animation sequence
|
||||
int gunbody;
|
||||
int gunskin;
|
||||
|
||||
|
|
|
@ -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 viewangles[3];
|
||||
float blend[4]; // rgba 0-1 full screen blend
|
||||
double time; // time is used to auto animate
|
||||
float time; // time is used to auto animate
|
||||
int rdflags; // RDF_UNDERWATER, etc
|
||||
|
||||
byte *areabits; // if not NULL, only areas with set bits will be drawn
|
||||
|
|
|
@ -24,7 +24,7 @@ if errorlevel 1 set BUILD_ERROR=1
|
|||
%MSDEV% renderer/renderer.dsp %CONFIG%"renderer - Win32 Release" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
progs\qcclib.exe -O3
|
||||
progs\qcclib.exe
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
if "%BUILD_ERROR%"=="" goto build_ok
|
||||
|
@ -56,5 +56,5 @@ if exist progs\server.dat copy progs\server.dat D:\Xash3D\xash\server.dat
|
|||
echo Build succeeded!
|
||||
echo Please wait. Xash is now loading
|
||||
cd D:\Xash3D\
|
||||
xash.exe +map qctest
|
||||
xash.exe -game valve +map skytest -debug
|
||||
:done
|
|
@ -125,7 +125,7 @@ void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
|
|||
|
||||
// move should be the delta back to the previous frame * backlerp
|
||||
VectorSubtract (currententity->oldorigin, currententity->origin, delta);
|
||||
AngleVectorsRight(currententity->angles, vectors[0], vectors[1], vectors[2]);
|
||||
AngleVectors(currententity->angles, vectors[0], vectors[1], vectors[2]);
|
||||
|
||||
move[0] = DotProduct (delta, vectors[0]); // forward
|
||||
move[1] = -DotProduct (delta, vectors[1]); // left
|
||||
|
@ -454,7 +454,7 @@ static bool R_CullAliasModel( vec3_t bbox[8], entity_t *e )
|
|||
*/
|
||||
VectorCopy( e->angles, angles );
|
||||
angles[YAW] = -angles[YAW];
|
||||
AngleVectorsRight( angles, vectors[0], vectors[1], vectors[2] );
|
||||
AngleVectors( angles, vectors[0], vectors[1], vectors[2] );
|
||||
|
||||
for ( i = 0; i < 8; i++ )
|
||||
{
|
||||
|
|
|
@ -499,7 +499,7 @@ void R_SetupFrame (void)
|
|||
// build the transformation matrix for the given view angles
|
||||
VectorCopy (r_newrefdef.vieworg, r_origin);
|
||||
|
||||
AngleVectorsRight(r_newrefdef.viewangles, vforward, vright, vup);
|
||||
AngleVectors(r_newrefdef.viewangles, vforward, vright, vup);
|
||||
|
||||
// current viewcluster
|
||||
if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
|
||||
|
|
|
@ -976,7 +976,7 @@ void R_DrawBrushModel ( int passnum )
|
|||
vec3_t forward, right, up;
|
||||
|
||||
VectorCopy (modelorg, temp);
|
||||
AngleVectorsRight(e->angles, forward, right, up);
|
||||
AngleVectors(e->angles, forward, right, up);
|
||||
modelorg[0] = DotProduct (temp, forward);
|
||||
modelorg[1] = -DotProduct (temp, right);
|
||||
modelorg[2] = DotProduct (temp, up);
|
||||
|
|
|
@ -281,7 +281,7 @@ void R_DrawSpriteModel( int passnum )
|
|||
switch( psprite->type )
|
||||
{
|
||||
case SPR_ORIENTED:
|
||||
AngleVectorsRight(e->angles, forward, right, up);
|
||||
AngleVectors(e->angles, forward, right, up);
|
||||
VectorScale(forward, 0.01, forward );//offset for decals
|
||||
VectorSubtract(e->origin, forward, e->origin );
|
||||
break;
|
||||
|
|
|
@ -1012,7 +1012,7 @@ static bool R_StudioComputeBBox( vec3_t *bbox )
|
|||
//rotate the bounding box
|
||||
VectorCopy( e->angles, angles );
|
||||
angles[PITCH] = -angles[PITCH];
|
||||
AngleVectorsRight( angles, vectors[0], vectors[1], vectors[2] );
|
||||
AngleVectors( angles, vectors[0], vectors[1], vectors[2] );
|
||||
|
||||
for ( i = 0; i < 8; i++ )
|
||||
{
|
||||
|
|
Reference in New Issue