03 Sep 2007

This commit is contained in:
g-cont 2007-09-03 00:00:00 +04:00 committed by Alibek Omarov
parent 8cb4ca3d6d
commit 16edc07985
117 changed files with 13890 additions and 23282 deletions

View File

@ -1,13 +1,15 @@
Разработать концепцию языка VirtualC\VirtualC++ (базируется на QuakeC)
//==================================================
// FIXME
//==================================================
1. Раз и навсегда переписать SC_ParseToken и SC_ParseWord OK
2. Подогнать новую VFS под QCC
3. Парсинг выходного имени файла исправить qccmsource3
1. Переписать главный игровой цикл
2. Пофиксить физику
//==================================================
// то, что уже готово
//==================================================
+исправлен баг с кодом возвращаемой ошибки
+исправлен баг с выводом сообщений в консоль кварка\хаммера
+исправлены баги со studiomdl
+убраны лишние пункты в меню

View File

@ -23,7 +23,7 @@ if errorlevel 1 set BUILD_ERROR=1
%MSDEV% renderer/renderer.dsp %CONFIG%"renderer - Win32 Debug" %build_target%
if errorlevel 1 set BUILD_ERROR=1
%MSDEV% server/server.dsp %CONFIG%"server - Win32 Debug" %build_target%
resource\qcclib.exe
if errorlevel 1 set BUILD_ERROR=1
if "%BUILD_ERROR%"=="" goto build_ok
@ -50,6 +50,7 @@ if exist launcher\launcher.plg del /f /q launcher\launcher.plg
if exist platform\platform.plg del /f /q platform\platform.plg
if exist renderer\renderer.plg del /f /q renderer\renderer.plg
if exist server\server.plg del /f /q server\server.plg
if exist resource\server.dat copy resource\server.dat D:\Xash3D\xash\server.dat
echo Build succeeded!
echo Please wait. Xash is now loading

View File

@ -6,6 +6,38 @@
--------------------Configuration: editor - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\Temp\RSP2FD7.tmp" with contents
[
/nologo /MTd /W3 /Gm /Gi /GX /ZI /Od /I "../public" /I "../platform/formats" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\editor\!debug/" /Fo"..\temp\editor\!debug/" /Fd"..\temp\editor\!debug/" /FD /GZ /c
"D:\XASH3D\src_main\!source\editor\editor.c"
"D:\XASH3D\src_main\!source\editor\guiutils.c"
"D:\XASH3D\src_main\!source\editor\guiforms.c"
]
Creating command line "cl.exe @C:\Temp\RSP2FD7.tmp"
Creating temporary file "C:\Temp\RSP2FD8.tmp" with contents
[
kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib /nologo /dll /incremental:yes /pdb:"..\temp\editor\!debug/editor.pdb" /debug /machine:I386 /out:"..\temp\editor\!debug/editor.dll" /implib:"..\temp\editor\!debug/editor.lib" /pdbtype:sept
"\XASH3D\src_main\!source\temp\editor\!debug\editor.obj"
"\XASH3D\src_main\!source\temp\editor\!debug\guiutils.obj"
"\XASH3D\src_main\!source\temp\editor\!debug\guiforms.obj"
"\XASH3D\src_main\!source\temp\editor\!debug\editor.res"
]
Creating command line "link.exe @C:\Temp\RSP2FD8.tmp"
Creating temporary file "C:\Temp\RSP2FD9.bat" with contents
[
@echo off
copy \XASH3D\src_main\!source\temp\editor\!debug\editor.dll "D:\Xash3D\bin\editor.dll"
]
Creating command line "C:\Temp\RSP2FD9.bat"
Compiling...
editor.c
guiutils.c
guiforms.c
Generating Code...
Linking...
<h3>Output Window</h3>
Performing Custom Build Step on \XASH3D\src_main\!source\temp\editor\!debug\editor.dll
‘ª®¯¨à®¢ ­® ä ©«®¢: 1.

View File

@ -402,17 +402,17 @@ void SCR_RunCinematic (void)
if (cls.key_dest != key_game)
{ // pause if menu or console is up
cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14;
cl.cinematictime = cls.realtime - cl.cinematicframe/14;
return;
}
frame = (cls.realtime - cl.cinematictime)*14.0/1000;
frame = (cls.realtime - cl.cinematictime)*14.0;
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*1000/14;
cl.cinematictime = cls.realtime - cl.cinematicframe/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 = Sys_Milliseconds ();
cl.cinematictime = cls.realtime;
}

View File

@ -656,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*100;
cl.frame.servertime = cl.frame.serverframe * 0.1;
// BIG HACK to let old demos continue to work
if (cls.serverProtocol != 26)
@ -699,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 - 100)
cl.time = cl.frame.servertime - 100;
else if (cl.time < cl.frame.servertime - 0.1)
cl.time = cl.frame.servertime - 0.1;
// read areabits
len = MSG_ReadByte (&net_message);
@ -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/1000;
autoanim = 2 * cl.time;
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 / 100;
ent.frame = cl.time * 0.1;
else
ent.frame = s1->frame;
@ -974,7 +974,7 @@ void CL_AddPacketEntities (frame_t *frame)
vec3_t forward;
vec3_t start;
AngleVectors (ent.angles, forward, NULL, NULL);
AngleVectorsRight(ent.angles, forward, NULL, NULL);
VectorMA (ent.origin, 64, forward, start);
V_AddLight (start, 100, 1, 0, 0);
}
@ -1231,8 +1231,7 @@ void CL_CalcViewValues (void)
// smooth out stair climbing
delta = cls.realtime - cl.predicted_step_time;
if (delta < 100)
cl.refdef.vieworg[2] -= cl.predicted_step * (100 - delta) * 0.01;
if (delta < 0.1) cl.refdef.vieworg[2] -= cl.predicted_step * (0.1 - delta) * 100;
}
else
{ // just use interpolated values
@ -1257,7 +1256,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);
AngleVectors (cl.refdef.viewangles, cl.v_forward, cl.v_right, cl.v_up);
AngleVectorsRight(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);
@ -1289,15 +1288,14 @@ void CL_AddEntities (void)
cl.time = cl.frame.servertime;
cl.lerpfrac = 1.0;
}
else if (cl.time < cl.frame.servertime - 100)
else if (cl.time < cl.frame.servertime - 0.1)
{
if (cl_showclamp->value)
Msg ("low clamp %i\n", cl.frame.servertime-100 - cl.time);
cl.time = cl.frame.servertime - 100;
Msg ("low clamp %i\n", cl.frame.servertime - 0.1 - cl.time);
cl.time = cl.frame.servertime - 0.1;
cl.lerpfrac = 0;
}
else
cl.lerpfrac = 1.0 - (cl.frame.servertime - cl.time) * 0.01;
else cl.lerpfrac = 1.0 - (cl.frame.servertime - cl.time) * 100;
if (cl_timedemo->value)
cl.lerpfrac = 1.0;

View File

@ -69,7 +69,7 @@ void CL_RunLightStyles (void)
int i;
clightstyle_t *ls;
ofs = cl.time / 100;
ofs = cl.time * 0.1;
if (ofs == lastofs)
return;
lastofs = ofs;
@ -257,7 +257,7 @@ void CL_ParseMuzzleFlash (void)
dl = CL_AllocDlight (i);
VectorCopy (pl->current.origin, dl->origin);
AngleVectors (pl->current.angles, fv, rv, NULL);
AngleVectorsRight(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
AngleVectors (cl_entities[ent].current.angles, forward, right, NULL);
AngleVectorsRight(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 = (float)cl.time / 1000.0;
ltime = cl.time;
for (i=0 ; i<count ; i+=2)
{
angle = ltime * avelocities[i][0];
@ -1706,7 +1706,7 @@ void CL_BfgParticles (entity_t *ent)
}
ltime = (float)cl.time / 1000.0;
ltime = cl.time;
for (i=0 ; i<NUMVERTEXNORMALS ; i++)
{
angle = ltime * avelocities[i][0];

View File

@ -94,7 +94,7 @@ void KeyDown (kbutton_t *b)
c = Cmd_Argv(2);
b->downtime = atoi(c);
if (!b->downtime)
b->downtime = sys_frame_time - 100;
b->downtime = (uint)sys_frame_time - 0.1;
b->state |= 1 + 2; // down + impulse down
}
@ -354,8 +354,7 @@ void CL_FinishMove (usercmd_t *cmd)
// 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 ();
@ -483,7 +482,7 @@ void CL_SendCmd (void)
if ( cls.state == ca_connected)
{
if (cls.netchan.message.cursize || curtime - cls.netchan.last_sent > 1000 )
if (cls.netchan.message.cursize || curtime - cls.netchan.last_sent > 1.0f )
Netchan_Transmit (&cls.netchan, 0, buf.data);
return;
}
@ -498,7 +497,7 @@ void CL_SendCmd (void)
}
if (cmd->buttons && cl.cinematictime > 0 && !cl.attractloop
&& cls.realtime - cl.cinematictime > 1000)
&& cls.realtime - cl.cinematictime > 1.0f)
{ // skip the rest of the cinematic
SCR_FinishCinematic ();
}

View File

@ -618,12 +618,11 @@ void CL_Disconnect (void)
if (cl_timedemo && cl_timedemo->value)
{
int time;
float time;
time = Sys_Milliseconds () - cl.timedemo_start;
time = Sys_DoubleTime() - 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);
Msg ("%i frames, %3.1f seconds: %3.1f fps\n", cl.timedemo_frames, time, cl.timedemo_frames / time);
}
VectorClear (cl.refdef.blend);
@ -1021,8 +1020,7 @@ void CL_ReadPackets (void)
//
// check timeout
//
if (cls.state >= ca_connected
&& cls.realtime - cls.netchan.last_received > cl_timeout->value*1000)
if (cls.state >= ca_connected && cls.realtime - cls.netchan.last_received > cl_timeout->value)
{
if (++cl.timeoutcount > 5) // timeoutcount saves debugger
{
@ -1413,7 +1411,7 @@ CL_InitLocal
void CL_InitLocal (void)
{
cls.state = ca_disconnected;
cls.realtime = Sys_Milliseconds ();
cls.realtime = Sys_DoubleTime();
CL_InitInput ();
adr0 = Cvar_Get( "adr0", "", CVAR_ARCHIVE );
@ -1678,44 +1676,36 @@ CL_Frame
==================
*/
void CL_Frame (int msec)
void CL_Frame (float time)
{
static int extratime;
static int lasttimecalled;
static float extratime;
static float lasttimecalled;
if (dedicated->value)
return;
if (dedicated->value) return;
extratime += msec;
extratime += time;
if (!cl_timedemo->value)
{
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
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
}
// let the mouse activate or deactivate
IN_Frame ();
// decide the simulation time
cls.frametime = extratime/1000.0;
cls.frametime = extratime;
cl.time += extratime;
cls.realtime = curtime;
cls.realtime = Sys_DoubleTime();
extratime = 0;
#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 (cls.frametime > (1.0 / 5)) cls.frametime = (1.0 / 5);
// if in the debugger last frame, don't timeout
if (msec > 5000)
cls.netchan.last_received = Sys_Milliseconds ();
if (time > 1.0f) cls.netchan.last_received = Sys_DoubleTime();
// fetch results from server
CL_ReadPackets ();
@ -1732,11 +1722,9 @@ void CL_Frame (int msec)
CL_PrepRefresh ();
// update the screen
if (host_speeds->value)
time_before_ref = Sys_Milliseconds ();
if (host_speeds->value) time_before_ref = Sys_DoubleTime();
SCR_UpdateScreen ();
if (host_speeds->value)
time_after_ref = Sys_Milliseconds ();
if (host_speeds->value) time_after_ref = Sys_DoubleTime();
// update audio
S_Update (cl.refdef.vieworg, cl.v_forward, cl.v_right, cl.v_up);
@ -1748,27 +1736,6 @@ void CL_Frame (int msec)
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;
}
}
}
}

View File

@ -81,7 +81,7 @@ void CL_Flashlight (int ent, vec3_t pos)
VectorCopy (pos, dl->origin);
dl->radius = 400;
dl->minlight = 250;
dl->die = cl.time + 100;
dl->die = cl.time + 0.1;
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 + 100;
dl->die = cl.time + 0.1;
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 = (float) cl.time/1000.0;
ltime = cl.time;
// 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 = (float) cl.time/1000.0;
ltime = cl.time;
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 = (float) cl.time/1000.0;
ltime = cl.time;
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);
// AngleVectors (angle_dir, f, r, u);
// AngleVectorsRight (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);
AngleVectors (angle_dir, forward, right, up);
AngleVectorsRight (angle_dir, forward, right, up);
dec = 3;
VectorScale (vec, 3, vec);

View File

@ -125,7 +125,7 @@ void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
if (trace.allsolid || trace.startsolid ||
trace.fraction < tr->fraction)
{
trace.ent = (struct edict_s *)ent;
trace.ent = (prvm_edict_t *)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 = (struct edict_s *)1;
t.ent = (prvm_edict_t *)1;
// check all other solid models
CL_ClipMoveToEntities (start, mins, maxs, end, &t);

View File

@ -505,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
@ -513,14 +513,14 @@ void SCR_RunConsole (void)
if (scr_conlines < scr_con_current)
{
scr_con_current -= scr_conspeed->value*cls.frametime;
scr_con_current -= scr_conspeed->value * cls.frametime * 1000;
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;
scr_con_current += scr_conspeed->value * cls.frametime * 1000;
if (scr_conlines < scr_con_current)
scr_con_current = scr_conlines;
}
@ -583,7 +583,7 @@ void SCR_BeginLoadingPlaque (void)
else
scr_draw_loading = 1;
SCR_UpdateScreen ();
cls.disable_screen = Sys_Milliseconds ();
cls.disable_screen = Sys_DoubleTime();
cls.disable_servercount = cl.servercount;
}
@ -631,18 +631,19 @@ int entitycmpfnc( const entity_t *a, const entity_t *b )
void SCR_TimeRefresh_f (void)
{
int i;
int start, stop;
float time;
float start, stop;
float time;
if ( cls.state != ca_active )
return;
start = Sys_Milliseconds ();
start = Sys_DoubleTime();
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);
@ -661,8 +662,8 @@ void SCR_TimeRefresh_f (void)
}
}
stop = Sys_Milliseconds ();
time = (stop-start)/1000.0;
stop = Sys_DoubleTime();
time = (stop-start);
Msg ("%f seconds (%f fps)\n", time, 128/time);
}
@ -1268,7 +1269,7 @@ void SCR_UpdateScreen (void)
// do nothing at all
if (cls.disable_screen)
{
if (Sys_Milliseconds() - cls.disable_screen > 120000)
if (Sys_DoubleTime() - cls.disable_screen > 120.0f)
{
cls.disable_screen = 0;
Msg ("Loading plaque timed out.\n");

View File

@ -533,9 +533,6 @@ void V_RenderView( float stereo_separation )
re->RenderFrame (&cl.refdef);
if (cl_stats->value)
Msg ("ent:%i lt:%i part:%i\n", r_numentities, r_numdlights, r_numparticles);
if ( log_stats->value && ( log_stats_file != 0 ) )
FS_Printf( log_stats_file, "%i,%i,%i,",r_numentities, r_numdlights, r_numparticles);
SCR_AddDirtyPoint (scr_vrect.x, scr_vrect.y);
SCR_AddDirtyPoint (scr_vrect.x+scr_vrect.width-1,

View File

@ -34,27 +34,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
typedef struct
{
bool valid; // cleared if delta parsing was invalid
int serverframe;
int servertime; // server time the message is valid for (in msec)
int deltaframe;
byte areabits[MAX_MAP_AREAS/8]; // portalarea visibility bits
int serverframe;
float 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)
int fly_stoptime;
float 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;
int timedemo_start;
int timedemo_frames;
float 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
unsigned predicted_step_time;
float 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;
int time; // this is the time value that the client
// is rendering at. always <= cls.realtime
float 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;
int cinematictime; // cls.realtime for first cinematic frame
int cinematicframe;
float 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;
int realtime; // always increasing, no clamping, etc
float frametime; // seconds since last frame
double 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

View File

@ -59,12 +59,17 @@ typedef struct sizebuf_s
int errorcount; // cause by errors
} sizebuf_t;
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
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);
#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;
@ -87,26 +92,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, edict_t *ent, const char *filename, int fileline);
void _MSG_Send (msgtype_t to, vec3_t origin, prvm_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);
@ -139,7 +144,7 @@ int COM_CheckParm (char *parm);
void COM_Init (void);
void COM_InitArgv (int argc, char **argv);
char *CopyString (char *in);
char *CopyString (const char *in);
//============================================================================
@ -414,7 +419,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 (char *cmd_name);
bool Cmd_Exists (const char *cmd_name);
// used by the cvar code to check for cvar / command name overlap
char *Cmd_CompleteCommand (char *partial);
@ -428,11 +433,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 (char *text, bool macroExpand);
void Cmd_TokenizeString (const 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 (char *text);
void Cmd_ExecuteString (const char *text);
// Parses a single line of text into arguments and tries to execute it
// as if it was typed at the console
@ -457,33 +462,32 @@ 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];
unsigned short port;
word 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(float time);
//============================================================================
@ -499,8 +503,8 @@ typedef struct
int dropped; // between last packet and previous
int last_received; // for timeouts
int last_sent; // for retransmits
float last_received; // for timeouts
float last_sent; // for retransmits
netadr_t remote_address;
int qport; // qport value to write when transmitting
@ -517,16 +521,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];
@ -648,15 +652,12 @@ 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;
extern float time_before_game;
extern float time_after_game;
extern float time_before_ref;
extern float time_after_ref;
#define NUMVERTEXNORMALS 162
extern vec3_t bytedirs[NUMVERTEXNORMALS];
@ -697,12 +698,12 @@ CLIENT / SERVER SYSTEMS
void CL_Init (void);
void CL_Drop (void);
void CL_Shutdown (void);
void CL_Frame (int msec);
void CL_Frame (float time);
void Con_Print (char *text);
void SCR_BeginLoadingPlaque (void);
void SV_Init (void);
void SV_Shutdown (char *finalmsg, bool reconnect);
void SV_Frame (int msec);
void SV_Frame (float time);
#endif//COMMON_H

View File

@ -538,7 +538,7 @@ char *Cmd_Args (void)
Cmd_MacroExpandString
======================
*/
char *Cmd_MacroExpandString (char *text)
char *Cmd_MacroExpandString (const char *text)
{
int i, j, count, len;
bool inquote;
@ -548,7 +548,7 @@ char *Cmd_MacroExpandString (char *text)
char *token, *start;
inquote = false;
scan = text;
scan = (char *)text;
len = strlen (scan);
if (len >= MAX_STRING_CHARS)
@ -613,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 (char *text, bool macroExpand)
void Cmd_TokenizeString (const 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]);
@ -741,16 +741,15 @@ void Cmd_RemoveCommand (char *cmd_name)
Cmd_Exists
============
*/
bool Cmd_Exists (char *cmd_name)
bool Cmd_Exists (const 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;
}
@ -800,7 +799,7 @@ A complete command line has been parsed, so try to execute it
FIXME: lookupnoadd the token to speed search?
============
*/
void Cmd_ExecuteString (char *text)
void Cmd_ExecuteString (const char *text)
{
cmd_function_t *cmd;
cmdalias_t *a;

View File

@ -36,19 +36,19 @@ typedef struct
typedef struct
{
int contents;
int cluster;
int area;
unsigned short firstleafbrush;
unsigned short numleafbrushes;
int contents;
int cluster;
int area;
word firstleafbrush;
word 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]) )
{
AngleVectors (angles, forward, right, up);
AngleVectorsRight (angles, forward, right, up);
VectorCopy (p_l, temp);
p_l[0] = DotProduct (temp, forward);
@ -978,16 +978,15 @@ 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;
@ -995,8 +994,7 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
leavefrac = 1;
clipplane = NULL;
if (!brush->numsides)
return;
if (!brush->numsides) return;
c_brush_traces++;
@ -1004,7 +1002,7 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
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;
@ -1012,17 +1010,17 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
// 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;
@ -1035,17 +1033,13 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
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)
@ -1060,25 +1054,23 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
}
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);
@ -1192,7 +1184,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];
@ -1200,7 +1192,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)
@ -1339,15 +1331,12 @@ 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));
@ -1363,26 +1352,24 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end,
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)
@ -1392,9 +1379,7 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end,
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)
{
@ -1409,9 +1394,7 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end,
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)
@ -1420,7 +1403,7 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end,
}
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;
@ -1440,10 +1423,7 @@ 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;
@ -1457,15 +1437,14 @@ trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end,
VectorSubtract (end, origin, end_l);
// rotate start and end into the models frame of reference
if (headnode != box_headnode &&
(angles[0] || angles[1] || angles[2]) )
if (headnode != box_headnode && !VectorIsNull(angles))
rotated = true;
else
rotated = false;
if (rotated)
{
AngleVectors (angles, forward, right, up);
AngleVectorsRight (angles, forward, right, up);
VectorCopy (start_l, temp);
start_l[0] = DotProduct (temp, forward);
@ -1486,7 +1465,7 @@ trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end,
// FIXME: figure out how to do this with existing angles
VectorCopy( angles, a );
VectorNegate ( a, a );
AngleVectors (a, forward, right, up);
AngleVectorsRight (a, forward, right, up);
VectorCopy (trace.plane.normal, temp);
trace.plane.normal[0] = DotProduct (temp, forward);
@ -1741,15 +1720,15 @@ STUDIO SHARED CMODELS
===============================================================================
*/
#define NUM_HULL_ROUNDS 22
#define HULL_PRECISION 4
#define HULL_PRECISION 4 // precision factor
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 };
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))
void CM_LookUpHullSize(vec3_t size, bool down)
{
int i, j;
for(i = 0; i < 3; i++)
{
bool negative = false;
@ -1769,7 +1748,14 @@ void CM_LookUpHullSize(vec3_t size, bool down)
break;
}
}
size[i] = result;//copy new value
if(j == NUM_HULL_ROUNDS)
{
//catch an error
MsgWarn("CM_LookUpHullSize: hull size[%d] is too big, reset value to default\n", i );
size[i] = 16; //default value
}
else size[i] = result;//copy new value
}
}
@ -1819,7 +1805,7 @@ cmodel_t *CM_StudioModel (char *name, byte *buffer)
VectorSet(out->mins, -32, -32, -32 );
VectorSet(out->maxs, 32, 32, 32 );
}
numsmodels++;
return out;
}

View File

@ -28,22 +28,19 @@ jmp_buf abortframe;
int com_argc;
char *com_argv[MAX_NUM_ARGVS+1];
int realtime;
file_t *log_stats_file;
double realtime;
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;
float time_before_game;
float time_after_game;
float time_before_ref;
float time_after_ref;
/*
@ -317,9 +314,9 @@ void COM_InitArgv (int argc, char **argv)
}
}
char *CopyString (char *in)
char *CopyString (const char *in)
{
char *out;
char *out;
out = Z_Malloc (strlen(in)+1);
strcpy (out, in);

View File

@ -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,9 +389,8 @@ 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)
@ -467,24 +466,24 @@ void Con_DrawInput (void)
text = key_lines[edit_line];
// add the cursor frame
text[key_linepos] = 10+((int)(cls.realtime>>8)&1);
// add the cursor frame
text[key_linepos] = 10 + ((int)(cls.realtime * 4.0f) & 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;
}
@ -501,22 +500,19 @@ void Con_DrawNotify (void)
int x, v;
char *text;
int i;
int time;
float 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*1000)
continue;
text = con.text + (i % con.totallines)*con.linewidth;
if (time > con_notifytime->value) continue;
text = con.text + (i % con.totallines) * con.linewidth;
for (x = 0 ; x < con.linewidth ; x++)
re->DrawChar ( (x+1)<<3, v, text[x]);
@ -547,7 +543,7 @@ void Con_DrawNotify (void)
re->DrawChar ( (x+skip)<<3, v, s[x]);
x++;
}
re->DrawChar ( (x+skip)<<3, v, 10+((cls.realtime>>8)&1));
re->DrawChar ((x+skip)<<3, v, 10 + ((int)(cls.realtime * 4.0f) & 1));
v += 8;
}

View File

@ -28,7 +28,7 @@ cvar_t *cvar_vars;
Cvar_InfoValidate
============
*/
static bool Cvar_InfoValidate (char *s)
static bool Cvar_InfoValidate (const char *s)
{
if (strstr (s, "\\"))
return false;
@ -44,7 +44,7 @@ static bool Cvar_InfoValidate (char *s)
Cvar_FindVar
============
*/
cvar_t *Cvar_FindVar (char *var_name)
cvar_t *Cvar_FindVar (const char *var_name)
{
cvar_t *var;
@ -60,13 +60,12 @@ cvar_t *Cvar_FindVar (char *var_name)
Cvar_VariableValue
============
*/
float Cvar_VariableValue (char *var_name)
float Cvar_VariableValue (const char *var_name)
{
cvar_t *var;
var = Cvar_FindVar (var_name);
if (!var)
return 0;
if (!var) return 0;
return atof (var->string);
}
@ -76,13 +75,12 @@ float Cvar_VariableValue (char *var_name)
Cvar_VariableString
============
*/
char *Cvar_VariableString (char *var_name)
char *Cvar_VariableString (const char *var_name)
{
cvar_t *var;
var = Cvar_FindVar (var_name);
if (!var)
return "";
if (!var) return "";
return var->string;
}
@ -124,7 +122,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 (char *var_name, char *var_value, int flags)
cvar_t *Cvar_Get (const char *var_name, const char *var_value, int flags)
{
cvar_t *var;
@ -176,7 +174,7 @@ cvar_t *Cvar_Get (char *var_name, char *var_value, int flags)
Cvar_Set2
============
*/
cvar_t *Cvar_Set2 (char *var_name, char *value, bool force)
cvar_t *Cvar_Set2 (const char *var_name, const char *value, bool force)
{
cvar_t *var;
@ -260,7 +258,7 @@ cvar_t *Cvar_Set2 (char *var_name, char *value, bool force)
Cvar_ForceSet
============
*/
cvar_t *Cvar_ForceSet (char *var_name, char *value)
cvar_t *Cvar_ForceSet (const char *var_name, const char *value)
{
return Cvar_Set2 (var_name, value, true);
}
@ -270,7 +268,7 @@ cvar_t *Cvar_ForceSet (char *var_name, char *value)
Cvar_Set
============
*/
cvar_t *Cvar_Set (char *var_name, char *value)
cvar_t *Cvar_Set (const char *var_name, const char *value)
{
return Cvar_Set2 (var_name, value, false);
}

View File

@ -6,17 +6,17 @@
#define CVAR_H
extern cvar_t *cvar_vars;
cvar_t *Cvar_FindVar (char *var_name);
cvar_t *Cvar_FindVar (const char *var_name);
cvar_t *Cvar_Get (char *var_name, char *value, int flags);
cvar_t *Cvar_Get (const char *var_name, const 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
cvar_t *Cvar_Set (char *var_name, char *value);
cvar_t *Cvar_Set (const char *var_name, const char *value);
// will create the variable if it doesn't exist
cvar_t *Cvar_ForceSet (char *var_name, char *value);
cvar_t *Cvar_ForceSet (const char *var_name, const char *value);
// will set the variable even if NOSET or LATCH
cvar_t *Cvar_FullSet (char *var_name, char *value, int flags);
@ -24,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 (char *var_name);
float Cvar_VariableValue (const char *var_name);
// returns 0 if not defined or non numeric
char *Cvar_VariableString (char *var_name);
char *Cvar_VariableString (const char *var_name);
// returns an empty string if not defined
char *Cvar_CompleteVariable (char *partial);

View File

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

View File

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

View File

@ -321,7 +321,6 @@ 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;
@ -425,7 +424,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 / 100)%NUM_CURSOR_FRAMES );
M_DrawCursor( xoffset - 25, ystart + m_main_cursor * 40 + 11, (int)(cls.realtime * 8.0f) % NUM_CURSOR_FRAMES );
re->DrawGetPicSize( &w, &h, "m_main_plaque" );
re->DrawPic( xoffset - 30 - w, ystart, "m_main_plaque" );
@ -686,10 +685,8 @@ 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 ) ( Sys_Milliseconds() / 250 ) & 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)(cls.realtime * 5.0f) & 1 ));
}
static void DrawKeyBindingFunc( void *self )
@ -1363,7 +1360,7 @@ END GAME MENU
=============================================================================
*/
static int credits_start_time;
static float credits_start_time;
static const char **credits;
static char *creditsIndex[256];
static char *creditsBuffer;
@ -1455,161 +1452,20 @@ 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, y;
int i;
float 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] == '+' )
{
@ -1628,15 +1484,13 @@ 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] );
}
}
if ( y < 0 )
credits_start_time = cls.realtime;
// loop demonstration
if ( y < 0 ) credits_start_time = cls.realtime;
}
const char *M_Credits_Key( int key )
@ -1656,12 +1510,12 @@ void M_Menu_Credits_f( void )
{
int n;
int count;
char *p;
char *p;
int isdeveloper = 0;
creditsBuffer = NULL;
creditsBuffer = FS_LoadFile ("credits", &count );
if (count != -1)
creditsBuffer = FS_LoadFile ("scripts/credits.txt", &count );
if (count)
{
p = creditsBuffer;
for (n = 0; n < 255; n++)
@ -1670,18 +1524,15 @@ 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;
@ -3488,7 +3339,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*0.001;
refdef.time = cls.realtime;
if ( s_pmi[s_player_model_box.curvalue].skindisplaynames )
{
@ -3677,8 +3528,7 @@ void M_Draw (void)
SCR_DirtyScreen ();
// dim everything behind it down
if (cl.cinematictime > 0)
re->DrawFill (0, 0, viddef.width, viddef.height, 0);
if (cl.cinematictime > 0) re->DrawFill (0, 0, viddef.width, viddef.height, 0);
else re->DrawFadeScreen ();
m_drawfunc ();

View File

@ -93,7 +93,7 @@ void Netchan_Init (void)
int port;
// pick a port value that should be nice and random
port = Sys_Milliseconds() & 0xffff;
port = RANDOM_LONG(1, 65535);
Msg("netchan port %d\n", port );

View File

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

View File

@ -717,9 +717,9 @@ void NET_Config (bool multiplayer)
}
// sleeps msec or until net socket is ready
void NET_Sleep(int msec)
void NET_Sleep(float time)
{
struct timeval timeout;
struct timeval timeout;
fd_set fdset;
extern cvar_t *dedicated;
int i;
@ -738,8 +738,8 @@ void NET_Sleep(int msec)
if (ipx_sockets[NS_SERVER] > i)
i = ipx_sockets[NS_SERVER];
}
timeout.tv_sec = msec/1000;
timeout.tv_usec = (msec%1000)*1000;
timeout.tv_sec = time;
timeout.tv_usec = fmod(time, 1.0f) * 1.0f;
select(i+1, &fdset, NULL, NULL, &timeout);
}

View File

@ -312,7 +312,7 @@ void PM_Friction (void)
{
friction = pm_friction;
control = speed < pm_stopspeed ? pm_stopspeed : speed;
drop += control*friction*pml.frametime;
drop += control*friction * pml.frametime;
}
// apply water friction
@ -1083,7 +1083,7 @@ void PM_ClampAngles (void)
else if (pm->viewangles[PITCH] < 271 && pm->viewangles[PITCH] >= 180)
pm->viewangles[PITCH] = 271;
}
AngleVectors (pm->viewangles, pml.forward, pml.right, pml.up);
AngleVectorsRight (pm->viewangles, pml.forward, pml.right, pml.up);
}
/*
@ -1198,7 +1198,7 @@ void Pmove (pmove_t *pmove)
angles[PITCH] = angles[PITCH] - 360;
angles[PITCH] /= 3;
AngleVectors (angles, pml.forward, pml.right, pml.up);
AngleVectorsRight (angles, pml.forward, pml.right, pml.up);
PM_AirMove ();
}
}

View File

@ -116,17 +116,13 @@ void Field_Draw( menufield_s *f )
else
offset = f->cursor;
if ( ( ( int ) ( Sys_Milliseconds() / 250 ) ) & 1 )
if ((( int )( cls.realtime * 4.0f)) & 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, ' ' );
}
}
}
@ -389,11 +385,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 ) ( Sys_Milliseconds()/250 ) & 1 ) );
Draw_Char( menu->x + item->x - 24 + item->cursor_offset, menu->y + item->y, 12 + ((int)(cls.realtime * 5.0f) & 1 ));
}
else
{
Draw_Char( menu->x + item->cursor_offset, menu->y + item->y, 12 + ( ( int ) ( Sys_Milliseconds()/250 ) & 1 ) );
Draw_Char( menu->x + item->cursor_offset, menu->y + item->y, 12 + ((int)(cls.realtime * 5.0f) & 1 ));
}
}

View File

@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MT /W3 /GX /O2 /Ob0 /I "./" /I "prvm" /I "common" /I "server" /I "client" /I "../public" /I "../platform/formats" /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" /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" /I "../platform/formats" /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" /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 winmm.lib wsock32.lib kernel32.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 gdi32.lib winmm.lib kernel32.lib user32.lib wsock32.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
@ -266,6 +266,10 @@ SOURCE=.\server\sv_main.c
# End Source File
# Begin Source File
SOURCE=.\server\sv_phys.c
# End Source File
# Begin Source File
SOURCE=.\server\sv_save.c
# End Source File
# Begin Source File
@ -296,6 +300,18 @@ 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"
@ -334,6 +350,10 @@ 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
@ -350,6 +370,14 @@ 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
@ -376,6 +404,14 @@ SOURCE=.\sound.h
SOURCE=.\common\vid.h
# End Source File
# Begin Source File
SOURCE=.\prvm\vm_cmds.h
# End Source File
# Begin Source File
SOURCE=.\prvm\vm_exec.h
# End Source File
# End Group
# End Target
# End Project

View File

@ -21,6 +21,7 @@
#include "basemath.h"
#include "qfiles.h"
#include <ref_system.h>
#include "vprogs.h"
#include "bspmodel.h"
#include "const.h"
#include "common.h"
@ -75,6 +76,7 @@ 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
@ -127,4 +129,10 @@ 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

89
engine/engine.plg Normal file
View File

@ -0,0 +1,89 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: engine - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\Temp\RSP31BD.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\system.c"
]
Creating command line "cl.exe @C:\Temp\RSP31BD.tmp"
Creating temporary file "C:\Temp\RSP31BE.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\RSP31BE.tmp"
Creating temporary file "C:\Temp\RSP31BF.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\RSP31BF.bat"
Compiling...
system.c
Linking...
<h3>Output Window</h3>
Performing Custom Build Step on \XASH3D\src_main\!source\temp\engine\!debug\engine.dll
‘ª®¯¨à®¢ ­® ä ©«®¢: 1.
<h3>Results</h3>
engine.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -7,6 +7,7 @@
#include <windows.h>
#include <dsound.h>
#include "engine.h"
#include "progsvm.h"
platform_exp_t *pi; //fundamental callbacks
@ -16,6 +17,8 @@ bool Minimized;
bool is_dedicated;
extern uint sys_msg_time;
dword host_framecount = 0;
void Key_Init (void);
void SCR_EndLoadingPlaque (void);
@ -96,6 +99,8 @@ void Host_Init (char *funcname, int argc, char **argv)
Key_Init ();
PRVM_Init();
// we need to add the early commands twice, because
// a basedir or cddir needs to be set before execing
// config files, but we want other parms to override
@ -112,7 +117,6 @@ 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);
@ -160,30 +164,6 @@ void Host_Frame (double time)
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;
@ -198,10 +178,10 @@ 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);
@ -211,6 +191,7 @@ void Host_Frame (double time)
CL_Frame (time);
if (host_speeds->value) time_after = Sys_DoubleTime();
if (host_speeds->value)
{
double all, sv, gm, cl, rf;
@ -234,9 +215,9 @@ Host_Main
void Host_Main( void )
{
MSG msg;
int time, oldtime, newtime;
float oldtime, newtime;
oldtime = Sys_Milliseconds ();
oldtime = Sys_DoubleTime(); //first call
// main window message loop
while (1)
@ -244,7 +225,7 @@ void Host_Main( void )
// if at a full screen console, don't update unless needed
if (Minimized || (dedicated && dedicated->value) )
{
Sleep (1);
Sleep(1);
}
while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
@ -254,15 +235,11 @@ void Host_Main( void )
TranslateMessage (&msg);
DispatchMessage (&msg);
}
do
{
newtime = Sys_Milliseconds ();
time = newtime - oldtime;
} while (time < 1);
_controlfp( _PC_24, _MCW_PC );
Host_Frame (time);
newtime = Sys_DoubleTime();
curtime = newtime - oldtime;
Host_Frame (curtime);
oldtime = newtime;
}
}

70
engine/prvm/edict.h Normal file
View File

@ -0,0 +1,70 @@
/*
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 entitynumber;
} 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

139
engine/prvm/progdefs.h Normal file
View File

@ -0,0 +1,139 @@
#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

407
engine/prvm/progsvm.h Normal file
View File

@ -0,0 +1,407 @@
/*
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; // LordHavoc: 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;
unsigned char *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 allowworldwrites;
// 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;
// now passes as parameter of PRVM_LoadProgs
// char **required_func;
// int numrequiredfunc;
//============================================================================
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;
#define PRVM_MAXPROGS 3
#define PRVM_SERVERPROG 0 // actually not used at the moment
#define PRVM_CLIENTPROG 1
#define PRVM_MENUPROG 2
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);
mfunction_t *PRVM_ED_FindFunction (const char *name);
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_EDICT_FROM_AREA(l) ((prvm_edict_t *)((byte *)l - (int)&(((prvm_edict_t *)0)->priv.sv->area)))
//int NUM_FOR_EDICT_ERROR(prvm_edict_t *e);
#define PRVM_NUM_FOR_EDICT(e) ((int)((prvm_edict_t *)(e) - prog->edicts))
//int PRVM_NUM_FOR_EDICT(prvm_edict_t *e);
#define PRVM_NEXT_EDICT(e) ((e) + 1)
#define PRVM_EDICT_TO_PROG(e) (PRVM_NUM_FOR_EDICT(e))
//int PRVM_EDICT_TO_PROG(prvm_edict_t *e);
#define PRVM_PROG_TO_EDICT(n) (PRVM_EDICT_NUM(n))
//prvm_edict_t *PRVM_PROG_TO_EDICT(int 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);
//============================================================================
// used as replacement for a prog stack
//#define PRVM_DEBUGPRSTACK
#ifdef PRVM_DEBUGPRSTACK
#define PRVM_Begin if(prog != 0) Con_Printf("prog not 0(prog = %i) in file: %s line: %i!\n", PRVM_GetProgNr(), __FILE__, __LINE__)
#define PRVM_End prog = 0
#else
#define PRVM_Begin
#define PRVM_End prog = 0
#endif
//#define PRVM_SAFENAME
#ifndef PRVM_SAFENAME
# define PRVM_NAME (prog->name)
#else
# define PRVM_NAME (prog->name ? prog->name : "Unknown prog name")
#endif
// 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

3154
engine/prvm/vm_cmds.c Normal file

File diff suppressed because it is too large Load Diff

343
engine/prvm/vm_cmds.h Normal file
View File

@ -0,0 +1,343 @@
// 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);

1984
engine/prvm/vm_edict.c Normal file

File diff suppressed because it is too large Load Diff

588
engine/prvm/vm_exec.c Normal file
View File

@ -0,0 +1,588 @@
/*
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.
*/
#include "engine.h"
#include "progsvm.h"
char *prvm_opnames[] =
{
"^5DONE",
"MUL_F",
"MUL_V",
"MUL_FV",
"MUL_VF",
"DIV",
"ADD_F",
"ADD_V",
"SUB_F",
"SUB_V",
"^2EQ_F",
"^2EQ_V",
"^2EQ_S",
"^2EQ_E",
"^2EQ_FNC",
"^2NE_F",
"^2NE_V",
"^2NE_S",
"^2NE_E",
"^2NE_FNC",
"^2LE",
"^2GE",
"^2LT",
"^2GT",
"^6FIELD_F",
"^6FIELD_V",
"^6FIELD_S",
"^6FIELD_ENT",
"^6FIELD_FLD",
"^6FIELD_FNC",
"^1ADDRESS",
"STORE_F",
"STORE_V",
"STORE_S",
"STORE_ENT",
"STORE_FLD",
"STORE_FNC",
"^1STOREP_F",
"^1STOREP_V",
"^1STOREP_S",
"^1STOREP_ENT",
"^1STOREP_FLD",
"^1STOREP_FNC",
"^5RETURN",
"^2NOT_F",
"^2NOT_V",
"^2NOT_S",
"^2NOT_ENT",
"^2NOT_FNC",
"^5IF",
"^5IFNOT",
"^3CALL0",
"^3CALL1",
"^3CALL2",
"^3CALL3",
"^3CALL4",
"^3CALL5",
"^3CALL6",
"^3CALL7",
"^3CALL8",
"^1STATE",
"^5GOTO",
"^2AND",
"^2OR",
"BITAND",
"BITOR"
};
char *PRVM_GlobalString (int ofs);
char *PRVM_GlobalStringNoContents (int ofs);
//=============================================================================
/*
=================
PRVM_PrintStatement
=================
*/
extern cvar_t *prvm_statementprofiling;
void PRVM_PrintStatement (dstatement_t *s)
{
size_t i;
int opnum = (int)(s - prog->statements);
Msg("s%i: ", opnum);
if( prog->statement_linenums )
Msg( "%s:%i: ", PRVM_GetString( prog->xfunction->s_file ), prog->statement_linenums[ opnum ] );
if (prvm_statementprofiling->value)
Msg("%7.0f ", prog->statement_profile[s - prog->statements]);
if ( (unsigned)s->op < sizeof(prvm_opnames)/sizeof(prvm_opnames[0]))
{
Msg("%s ", prvm_opnames[s->op]);
i = strlen(prvm_opnames[s->op]);
// don't count a preceding color tag when padding the name
if (prvm_opnames[s->op][0] == STRING_COLOR_TAG)
i -= 2;
for ( ; i<10 ; i++)
Con_Print(" ");
}
if (s->op == OP_IF || s->op == OP_IFNOT)
Msg("%s, s%i",PRVM_GlobalString((unsigned short) s->a),(signed short)s->b + opnum);
else if (s->op == OP_GOTO)
Msg("s%i",(signed short)s->a + opnum);
else if ( (unsigned)(s->op - OP_STORE_F) < 6)
{
Con_Print(PRVM_GlobalString((unsigned short) s->a));
Con_Print(", ");
Con_Print(PRVM_GlobalStringNoContents((unsigned short) s->b));
}
else if (s->op == OP_ADDRESS || (unsigned)(s->op - OP_LOAD_F) < 6)
{
if (s->a)
Con_Print(PRVM_GlobalString((unsigned short) s->a));
if (s->b)
{
Con_Print(", ");
Con_Print(PRVM_GlobalStringNoContents((unsigned short) s->b));
}
if (s->c)
{
Con_Print(", ");
Con_Print(PRVM_GlobalStringNoContents((unsigned short) s->c));
}
}
else
{
if (s->a)
Con_Print(PRVM_GlobalString((unsigned short) s->a));
if (s->b)
{
Con_Print(", ");
Con_Print(PRVM_GlobalString((unsigned short) s->b));
}
if (s->c)
{
Con_Print(", ");
Con_Print(PRVM_GlobalStringNoContents((unsigned short) s->c));
}
}
Con_Print("\n");
}
void PRVM_PrintFunctionStatements (const char *name)
{
int i, firststatement, endstatement;
mfunction_t *func;
func = PRVM_ED_FindFunction (name);
if (!func)
{
Msg("%s progs: no function named %s\n", PRVM_NAME, name);
return;
}
firststatement = func->first_statement;
if (firststatement < 0)
{
Msg("%s progs: function %s is builtin #%i\n", PRVM_NAME, name, -firststatement);
return;
}
// find the end statement
endstatement = prog->progs->numstatements;
for (i = 0;i < prog->progs->numfunctions;i++)
if (endstatement > prog->functions[i].first_statement && firststatement < prog->functions[i].first_statement)
endstatement = prog->functions[i].first_statement;
// now print the range of statements
Msg("%s progs: disassembly of function %s (statements %i-%i):\n", PRVM_NAME, name, firststatement, endstatement);
for (i = firststatement;i < endstatement;i++)
{
PRVM_PrintStatement(prog->statements + i);
prog->statement_profile[i] = 0;
}
}
/*
============
PRVM_PrintFunction_f
============
*/
void PRVM_PrintFunction_f (void)
{
if (Cmd_Argc() != 3)
{
Msg("usage: prvm_printfunction <program name> <function name>\n");
return;
}
PRVM_Begin;
if(!PRVM_SetProgFromString(Cmd_Argv(1)))
return;
PRVM_PrintFunctionStatements(Cmd_Argv(2));
PRVM_End;
}
/*
============
PRVM_StackTrace
============
*/
void PRVM_StackTrace (void)
{
mfunction_t *f;
int i;
prog->stack[prog->depth].s = prog->xstatement;
prog->stack[prog->depth].f = prog->xfunction;
for (i = prog->depth;i > 0;i--)
{
f = prog->stack[i].f;
if (!f)
Con_Print("<NULL FUNCTION>\n");
else
Msg("%12s : %s : statement %i\n", PRVM_GetString(f->s_file), PRVM_GetString(f->s_name), prog->stack[i].s - f->first_statement);
}
}
void PRVM_Profile (int maxfunctions, int mininstructions)
{
mfunction_t *f, *best;
int i, num;
double max;
Msg( "%s Profile:\n[CallCount] [Statements] [BuiltinCost]\n", PRVM_NAME );
num = 0;
do
{
max = 0;
best = NULL;
for (i=0 ; i<prog->progs->numfunctions ; i++)
{
f = &prog->functions[i];
if (max < f->profile + f->builtinsprofile + f->callcount)
{
max = f->profile + f->builtinsprofile + f->callcount;
best = f;
}
}
if (best)
{
if (num < maxfunctions && max >= mininstructions)
{
if (best->first_statement < 0)
Msg("%9.0f ----- builtin ----- %s\n", best->callcount, PRVM_GetString(best->s_name));
else
Msg("%9.0f %9.0f %9.0f %s\n", best->callcount, best->profile, best->builtinsprofile, PRVM_GetString(best->s_name));
}
num++;
best->profile = 0;
best->builtinsprofile = 0;
best->callcount = 0;
}
} while (best);
}
/*
============
PRVM_Profile_f
============
*/
void PRVM_Profile_f (void)
{
int howmany;
howmany = 1<<30;
if (Cmd_Argc() == 3)
howmany = atoi(Cmd_Argv(2));
else if (Cmd_Argc() != 2)
{
Con_Print("prvm_profile <program name>\n");
return;
}
PRVM_Begin;
if(!PRVM_SetProgFromString(Cmd_Argv(1)))
return;
PRVM_Profile(howmany, 1);
PRVM_End;
}
void PRVM_CrashAll()
{
int i;
prvm_prog_t *oldprog = prog;
for(i = 0; i < PRVM_MAXPROGS; i++)
{
if(!PRVM_ProgLoaded(i))
continue;
PRVM_SetProg(i);
PRVM_Crash();
}
prog = oldprog;
}
void PRVM_PrintState(void)
{
int i;
if (prog->xfunction)
{
for (i = -7; i <= 0;i++)
if (prog->xstatement + i >= prog->xfunction->first_statement)
PRVM_PrintStatement (prog->statements + prog->xstatement + i);
}
else
Con_Print("null function executing??\n");
PRVM_StackTrace ();
}
void PRVM_Crash()
{
if (prog == NULL)
return;
if( prog->depth > 0 )
{
Msg("QuakeC crash report for %s:\n", PRVM_NAME);
PRVM_PrintState();
}
// dump the stack so host_error can shutdown functions
prog->depth = 0;
prog->localstack_used = 0;
// reset the prog pointer
prog = NULL;
}
/*
============================================================================
PRVM_ExecuteProgram
The interpretation main loop
============================================================================
*/
/*
====================
PRVM_EnterFunction
Returns the new program statement counter
====================
*/
int PRVM_EnterFunction (mfunction_t *f)
{
int i, j, c, o;
if (!f)
PRVM_ERROR ("PRVM_EnterFunction: NULL function in %s", PRVM_NAME);
prog->stack[prog->depth].s = prog->xstatement;
prog->stack[prog->depth].f = prog->xfunction;
prog->depth++;
if (prog->depth >=PRVM_MAX_STACK_DEPTH)
PRVM_ERROR ("stack overflow");
// save off any locals that the new function steps on
c = f->locals;
if (prog->localstack_used + c > PRVM_LOCALSTACK_SIZE)
PRVM_ERROR ("PRVM_ExecuteProgram: locals stack overflow in %s", PRVM_NAME);
for (i=0 ; i < c ; i++)
prog->localstack[prog->localstack_used+i] = ((int *)prog->globals.generic)[f->parm_start + i];
prog->localstack_used += c;
// copy parameters
o = f->parm_start;
for (i=0 ; i<f->numparms ; i++)
{
for (j=0 ; j<f->parm_size[i] ; j++)
{
((int *)prog->globals.generic)[o] = ((int *)prog->globals.generic)[OFS_PARM0+i*3+j];
o++;
}
}
prog->xfunction = f;
return f->first_statement - 1; // offset the s++
}
/*
====================
PRVM_LeaveFunction
====================
*/
int PRVM_LeaveFunction (void)
{
int i, c;
if (prog->depth <= 0)
PRVM_ERROR ("prog stack underflow in %s", PRVM_NAME);
if (!prog->xfunction)
PRVM_ERROR ("PR_LeaveFunction: NULL function in %s", PRVM_NAME);
// restore locals from the stack
c = prog->xfunction->locals;
prog->localstack_used -= c;
if (prog->localstack_used < 0)
PRVM_ERROR ("PRVM_ExecuteProgram: locals stack underflow in %s", PRVM_NAME);
for (i=0 ; i < c ; i++)
((int *)prog->globals.generic)[prog->xfunction->parm_start + i] = prog->localstack[prog->localstack_used+i];
// up stack
prog->depth--;
prog->xfunction = prog->stack[prog->depth].f;
return prog->stack[prog->depth].s;
}
void PRVM_Init_Exec(void)
{
// dump the stack
prog->depth = 0;
prog->localstack_used = 0;
// reset the string table
// nothing here yet
}
/*
====================
PRVM_ExecuteProgram
====================
*/
// LordHavoc: optimized
#define OPA ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->a])
#define OPB ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->b])
#define OPC ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->c])
extern cvar_t *prvm_boundscheck;
extern cvar_t *prvm_traceqc;
extern cvar_t *prvm_statementprofiling;
extern int PRVM_ED_FindFieldOffset (const char *field);
extern ddef_t* PRVM_ED_FindGlobal(const char *name);
void PRVM_ExecuteProgram (func_t fnum, const char *errormessage)
{
dstatement_t *st, *startst;
mfunction_t *f, *newf;
prvm_edict_t *ed;
prvm_eval_t *ptr;
int jumpcount, cachedpr_trace, exitdepth;
if (!fnum || fnum >= (unsigned int)prog->progs->numfunctions)
{
if (prog->self && PRVM_G_INT(prog->self->ofs))
PRVM_ED_Print(PRVM_PROG_TO_EDICT(PRVM_G_INT(prog->self->ofs)));
PRVM_ERROR ("PRVM_ExecuteProgram: %s", errormessage);
}
f = &prog->functions[fnum];
prog->trace = prvm_traceqc->value;
// we know we're done when pr_depth drops to this
exitdepth = prog->depth;
// make a stack frame
st = &prog->statements[PRVM_EnterFunction (f)];
// save the starting statement pointer for profiling
// (when the function exits or jumps, the (st - startst) integer value is
// added to the function's profile counter)
startst = st;
// instead of counting instructions, we count jumps
jumpcount = 0;
// add one to the callcount of this function because otherwise engine-called functions aren't counted
prog->xfunction->callcount++;
chooseexecprogram:
cachedpr_trace = prog->trace;
if (prvm_statementprofiling->value)
{
#define PRVMSTATEMENTPROFILING 1
if (prvm_boundscheck->value)
{
#define PRVMBOUNDSCHECK 1
if (prog->trace)
{
#define PRVMTRACE 1
#include "vm_exec.h"
#undef PRVMTRACE
}
else
{
#include "vm_exec.h"
}
#undef PRVMBOUNDSCHECK
}
else
{
if (prog->trace)
{
#define PRVMTRACE 1
#include "vm_exec.h"
#undef PRVMTRACE
}
else
{
#include "vm_exec.h"
}
}
#undef PRVMSTATEMENTPROFILING
}
else
{
if (prvm_boundscheck->value)
{
#define PRVMBOUNDSCHECK 1
if (prog->trace)
{
#define PRVMTRACE 1
#include "vm_exec.h"
#undef PRVMTRACE
}
else
{
#include "vm_exec.h"
}
#undef PRVMBOUNDSCHECK
}
else
{
if (prog->trace)
{
#define PRVMTRACE 1
#include "vm_exec.h"
#undef PRVMTRACE
}
else
{
#include "vm_exec.h"
}
}
}
}

628
engine/prvm/vm_exec.h Normal file
View File

@ -0,0 +1,628 @@
// This code isn't #ifdef/#define protectable, don't try.
while (1)
{
st++;
#if PRVMTRACE
PRVM_PrintStatement(st);
#endif
#if PRVMSTATEMENTPROFILING
prog->statement_profile[st - prog->statements]++;
#endif
switch (st->op)
{
case OP_ADD_F:
OPC->_float = OPA->_float + OPB->_float;
break;
case OP_ADD_V:
OPC->vector[0] = OPA->vector[0] + OPB->vector[0];
OPC->vector[1] = OPA->vector[1] + OPB->vector[1];
OPC->vector[2] = OPA->vector[2] + OPB->vector[2];
break;
case OP_SUB_F:
OPC->_float = OPA->_float - OPB->_float;
break;
case OP_SUB_V:
OPC->vector[0] = OPA->vector[0] - OPB->vector[0];
OPC->vector[1] = OPA->vector[1] - OPB->vector[1];
OPC->vector[2] = OPA->vector[2] - OPB->vector[2];
break;
case OP_MUL_F:
OPC->_float = OPA->_float * OPB->_float;
break;
case OP_MUL_V:
OPC->_float = OPA->vector[0]*OPB->vector[0] + OPA->vector[1]*OPB->vector[1] + OPA->vector[2]*OPB->vector[2];
break;
case OP_MUL_FV:
OPC->vector[0] = OPA->_float * OPB->vector[0];
OPC->vector[1] = OPA->_float * OPB->vector[1];
OPC->vector[2] = OPA->_float * OPB->vector[2];
break;
case OP_MUL_VF:
OPC->vector[0] = OPB->_float * OPA->vector[0];
OPC->vector[1] = OPB->_float * OPA->vector[1];
OPC->vector[2] = OPB->_float * OPA->vector[2];
break;
case OP_DIV_F:
if( OPB->_float != 0.0f )
{
OPC->_float = OPA->_float / OPB->_float;
}
else
{
if( developer->value >= 1 )
{
prog->xfunction->profile += (st - startst);
startst = st;
prog->xstatement = st - prog->statements;
VM_Warning( "Attempted division by zero in %s\n", PRVM_NAME );
}
OPC->_float = 0.0f;
}
break;
case OP_BITAND:
OPC->_float = (int)OPA->_float & (int)OPB->_float;
break;
case OP_BITOR:
OPC->_float = (int)OPA->_float | (int)OPB->_float;
break;
case OP_GE:
OPC->_float = OPA->_float >= OPB->_float;
break;
case OP_LE:
OPC->_float = OPA->_float <= OPB->_float;
break;
case OP_GT:
OPC->_float = OPA->_float > OPB->_float;
break;
case OP_LT:
OPC->_float = OPA->_float < OPB->_float;
break;
case OP_AND:
OPC->_float = OPA->_float && OPB->_float;
break;
case OP_OR:
OPC->_float = OPA->_float || OPB->_float;
break;
case OP_NOT_F:
OPC->_float = !OPA->_float;
break;
case OP_NOT_V:
OPC->_float = !OPA->vector[0] && !OPA->vector[1] && !OPA->vector[2];
break;
case OP_NOT_S:
OPC->_float = !OPA->string || !*PRVM_GetString(OPA->string);
break;
case OP_NOT_FNC:
OPC->_float = !OPA->function;
break;
case OP_NOT_ENT:
OPC->_float = (OPA->edict == 0);
break;
case OP_EQ_F:
OPC->_float = OPA->_float == OPB->_float;
break;
case OP_EQ_V:
OPC->_float = (OPA->vector[0] == OPB->vector[0]) && (OPA->vector[1] == OPB->vector[1]) && (OPA->vector[2] == OPB->vector[2]);
break;
case OP_EQ_S:
OPC->_float = !strcmp(PRVM_GetString(OPA->string),PRVM_GetString(OPB->string));
break;
case OP_EQ_E:
OPC->_float = OPA->_int == OPB->_int;
break;
case OP_EQ_FNC:
OPC->_float = OPA->function == OPB->function;
break;
case OP_NE_F:
OPC->_float = OPA->_float != OPB->_float;
break;
case OP_NE_V:
OPC->_float = (OPA->vector[0] != OPB->vector[0]) || (OPA->vector[1] != OPB->vector[1]) || (OPA->vector[2] != OPB->vector[2]);
break;
case OP_NE_S:
OPC->_float = strcmp(PRVM_GetString(OPA->string),PRVM_GetString(OPB->string));
break;
case OP_NE_E:
OPC->_float = OPA->_int != OPB->_int;
break;
case OP_NE_FNC:
OPC->_float = OPA->function != OPB->function;
break;
//==================
case OP_STORE_F:
case OP_STORE_ENT:
case OP_STORE_FLD: // integers
case OP_STORE_S:
case OP_STORE_FNC: // pointers
OPB->_int = OPA->_int;
break;
case OP_STORE_V:
OPB->ivector[0] = OPA->ivector[0];
OPB->ivector[1] = OPA->ivector[1];
OPB->ivector[2] = OPA->ivector[2];
break;
case OP_STOREP_F:
case OP_STOREP_ENT:
case OP_STOREP_FLD: // integers
case OP_STOREP_S:
case OP_STOREP_FNC: // pointers
#if PRVMBOUNDSCHECK
if (OPB->_int < 0 || OPB->_int + 4 > prog->edictareasize)
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)", PRVM_NAME, OPB->_int);
return;
}
#endif
ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int);
ptr->_int = OPA->_int;
break;
case OP_STOREP_V:
#if PRVMBOUNDSCHECK
if (OPB->_int < 0 || OPB->_int + 12 > prog->edictareasize)
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)", PRVM_NAME, OPB->_int);
return;
}
#endif
ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int);
ptr->vector[0] = OPA->vector[0];
ptr->vector[1] = OPA->vector[1];
ptr->vector[2] = OPA->vector[2];
break;
case OP_ADDRESS:
#if PRVMBOUNDSCHECK
if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->progs->entityfields))
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR("%s attempted to address an invalid field (%i) in an edict", PRVM_NAME, OPB->_int);
return;
}
#endif
if (OPA->edict == 0 && !prog->allowworldwrites)
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR("forbidden assignment to null/world entity in %s", PRVM_NAME);
return;
}
ed = PRVM_PROG_TO_EDICT(OPA->edict);
OPC->_int = (unsigned char *)((int *)ed->fields.vp + OPB->_int) - (unsigned char *)prog->edictsfields;
break;
case OP_LOAD_F:
case OP_LOAD_FLD:
case OP_LOAD_ENT:
case OP_LOAD_S:
case OP_LOAD_FNC:
#if PRVMBOUNDSCHECK
if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->progs->entityfields))
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)", PRVM_NAME, OPB->_int);
return;
}
#endif
ed = PRVM_PROG_TO_EDICT(OPA->edict);
OPC->_int = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->_int;
break;
case OP_LOAD_V:
#if PRVMBOUNDSCHECK
if (OPB->_int < 0 || OPB->_int + 2 >= prog->progs->entityfields)
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)", PRVM_NAME, OPB->_int);
return;
}
#endif
ed = PRVM_PROG_TO_EDICT(OPA->edict);
OPC->vector[0] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[0];
OPC->vector[1] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[1];
OPC->vector[2] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[2];
break;
//==================
case OP_IFNOT:
if (!OPA->_int)
{
prog->xfunction->profile += (st - startst);
st += st->b - 1; // offset the s++
startst = st;
if (++jumpcount == 10000000)
{
prog->xstatement = st - prog->statements;
PRVM_Profile(1<<30, 1000000);
PRVM_ERROR("runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", jumpcount, PRVM_NAME);
}
}
break;
case OP_IF:
if (OPA->_int)
{
prog->xfunction->profile += (st - startst);
st += st->b - 1; // offset the s++
startst = st;
if (++jumpcount == 10000000)
{
prog->xstatement = st - prog->statements;
PRVM_Profile(1<<30, 1000000);
PRVM_ERROR("runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", jumpcount, PRVM_NAME);
}
}
break;
case OP_GOTO:
prog->xfunction->profile += (st - startst);
st += st->a - 1; // offset the s++
startst = st;
if (++jumpcount == 10000000)
{
prog->xstatement = st - prog->statements;
PRVM_Profile(1<<30, 1000000);
PRVM_ERROR("runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", jumpcount, PRVM_NAME);
}
break;
case OP_CALL0:
case OP_CALL1:
case OP_CALL2:
case OP_CALL3:
case OP_CALL4:
case OP_CALL5:
case OP_CALL6:
case OP_CALL7:
case OP_CALL8:
prog->xfunction->profile += (st - startst);
startst = st;
prog->xstatement = st - prog->statements;
prog->argc = st->op - OP_CALL0;
if (!OPA->function) PRVM_ERROR("NULL function in %s", PRVM_NAME);
newf = &prog->functions[OPA->function];
newf->callcount++;
if (newf->first_statement < 0)
{
// negative statements are built in functions
int builtinnumber = -newf->first_statement;
prog->xfunction->builtinsprofile++;
if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber])
prog->builtins[builtinnumber]();
else PRVM_ERROR("No such builtin #%i in %s", builtinnumber, PRVM_NAME);
}
else st = prog->statements + PRVM_EnterFunction(newf);
startst = st;
break;
case OP_DONE:
case OP_RETURN:
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
prog->globals.generic[OFS_RETURN+0] = prog->globals.generic[(word) st->a+0];
prog->globals.generic[OFS_RETURN+1] = prog->globals.generic[(word) st->a+1];
prog->globals.generic[OFS_RETURN+2] = prog->globals.generic[(word) st->a+2];
st = prog->statements + PRVM_LeaveFunction();
startst = st;
if (prog->depth <= exitdepth)
return; // all done
if (prog->trace != cachedpr_trace)
goto chooseexecprogram;
break;
case OP_STATE:
if(prog->flag & PRVM_OP_STATE)
{
ed = PRVM_PROG_TO_EDICT(PRVM_G_INT(prog->self->ofs));
PRVM_E_FLOAT(ed, PRVM_ED_FindField ("nextthink")->ofs) = *prog->time + 0.1;
PRVM_E_FLOAT(ed, PRVM_ED_FindField ("frame")->ofs) = OPA->_float;
*(func_t *)((float*)ed->fields.vp + PRVM_ED_FindField ("think")->ofs) = OPB->function;
}
else
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR("OP_STATE not supported by %s", PRVM_NAME);
}
break;
// LordHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized
/*
case OP_ADD_I:
OPC->_int = OPA->_int + OPB->_int;
break;
case OP_ADD_IF:
OPC->_int = OPA->_int + (int) OPB->_float;
break;
case OP_ADD_FI:
OPC->_float = OPA->_float + (float) OPB->_int;
break;
case OP_SUB_I:
OPC->_int = OPA->_int - OPB->_int;
break;
case OP_SUB_IF:
OPC->_int = OPA->_int - (int) OPB->_float;
break;
case OP_SUB_FI:
OPC->_float = OPA->_float - (float) OPB->_int;
break;
case OP_MUL_I:
OPC->_int = OPA->_int * OPB->_int;
break;
case OP_MUL_IF:
OPC->_int = OPA->_int * (int) OPB->_float;
break;
case OP_MUL_FI:
OPC->_float = OPA->_float * (float) OPB->_int;
break;
case OP_MUL_VI:
OPC->vector[0] = (float) OPB->_int * OPA->vector[0];
OPC->vector[1] = (float) OPB->_int * OPA->vector[1];
OPC->vector[2] = (float) OPB->_int * OPA->vector[2];
break;
case OP_DIV_VF:
{
float temp = 1.0f / OPB->_float;
OPC->vector[0] = temp * OPA->vector[0];
OPC->vector[1] = temp * OPA->vector[1];
OPC->vector[2] = temp * OPA->vector[2];
}
break;
case OP_DIV_I:
OPC->_int = OPA->_int / OPB->_int;
break;
case OP_DIV_IF:
OPC->_int = OPA->_int / (int) OPB->_float;
break;
case OP_DIV_FI:
OPC->_float = OPA->_float / (float) OPB->_int;
break;
case OP_CONV_IF:
OPC->_float = OPA->_int;
break;
case OP_CONV_FI:
OPC->_int = OPA->_float;
break;
case OP_BITAND_I:
OPC->_int = OPA->_int & OPB->_int;
break;
case OP_BITOR_I:
OPC->_int = OPA->_int | OPB->_int;
break;
case OP_BITAND_IF:
OPC->_int = OPA->_int & (int)OPB->_float;
break;
case OP_BITOR_IF:
OPC->_int = OPA->_int | (int)OPB->_float;
break;
case OP_BITAND_FI:
OPC->_float = (int)OPA->_float & OPB->_int;
break;
case OP_BITOR_FI:
OPC->_float = (int)OPA->_float | OPB->_int;
break;
case OP_GE_I:
OPC->_float = OPA->_int >= OPB->_int;
break;
case OP_LE_I:
OPC->_float = OPA->_int <= OPB->_int;
break;
case OP_GT_I:
OPC->_float = OPA->_int > OPB->_int;
break;
case OP_LT_I:
OPC->_float = OPA->_int < OPB->_int;
break;
case OP_AND_I:
OPC->_float = OPA->_int && OPB->_int;
break;
case OP_OR_I:
OPC->_float = OPA->_int || OPB->_int;
break;
case OP_GE_IF:
OPC->_float = (float)OPA->_int >= OPB->_float;
break;
case OP_LE_IF:
OPC->_float = (float)OPA->_int <= OPB->_float;
break;
case OP_GT_IF:
OPC->_float = (float)OPA->_int > OPB->_float;
break;
case OP_LT_IF:
OPC->_float = (float)OPA->_int < OPB->_float;
break;
case OP_AND_IF:
OPC->_float = (float)OPA->_int && OPB->_float;
break;
case OP_OR_IF:
OPC->_float = (float)OPA->_int || OPB->_float;
break;
case OP_GE_FI:
OPC->_float = OPA->_float >= (float)OPB->_int;
break;
case OP_LE_FI:
OPC->_float = OPA->_float <= (float)OPB->_int;
break;
case OP_GT_FI:
OPC->_float = OPA->_float > (float)OPB->_int;
break;
case OP_LT_FI:
OPC->_float = OPA->_float < (float)OPB->_int;
break;
case OP_AND_FI:
OPC->_float = OPA->_float && (float)OPB->_int;
break;
case OP_OR_FI:
OPC->_float = OPA->_float || (float)OPB->_int;
break;
case OP_NOT_I:
OPC->_float = !OPA->_int;
break;
case OP_EQ_I:
OPC->_float = OPA->_int == OPB->_int;
break;
case OP_EQ_IF:
OPC->_float = (float)OPA->_int == OPB->_float;
break;
case OP_EQ_FI:
OPC->_float = OPA->_float == (float)OPB->_int;
break;
case OP_NE_I:
OPC->_float = OPA->_int != OPB->_int;
break;
case OP_NE_IF:
OPC->_float = (float)OPA->_int != OPB->_float;
break;
case OP_NE_FI:
OPC->_float = OPA->_float != (float)OPB->_int;
break;
case OP_STORE_I:
OPB->_int = OPA->_int;
break;
case OP_STOREP_I:
#if PRBOUNDSCHECK
if (OPB->_int < 0 || OPB->_int + 4 > pr_edictareasize)
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR ("%s Progs attempted to write to an out of bounds edict", PRVM_NAME);
return;
}
#endif
ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int);
ptr->_int = OPA->_int;
break;
case OP_LOAD_I:
#if PRBOUNDSCHECK
if (OPA->edict < 0 || OPA->edict >= pr_edictareasize)
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR ("%s Progs attempted to read an out of bounds edict number", PRVM_NAME);
return;
}
if (OPB->_int < 0 || OPB->_int >= progs->entityfields)
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR ("%s Progs attempted to read an invalid field in an edict", PRVM_NAME);
return;
}
#endif
ed = PRVM_PROG_TO_EDICT(OPA->edict);
OPC->_int = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->_int;
break;
case OP_GSTOREP_I:
case OP_GSTOREP_F:
case OP_GSTOREP_ENT:
case OP_GSTOREP_FLD: // integers
case OP_GSTOREP_S:
case OP_GSTOREP_FNC: // pointers
#if PRBOUNDSCHECK
if (OPB->_int < 0 || OPB->_int >= pr_globaldefs)
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR ("%s Progs attempted to write to an invalid indexed global", PRVM_NAME);
return;
}
#endif
pr_globals[OPB->_int] = OPA->_float;
break;
case OP_GSTOREP_V:
#if PRBOUNDSCHECK
if (OPB->_int < 0 || OPB->_int + 2 >= pr_globaldefs)
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR ("%s Progs attempted to write to an invalid indexed global", PRVM_NAME);
return;
}
#endif
pr_globals[OPB->_int ] = OPA->vector[0];
pr_globals[OPB->_int+1] = OPA->vector[1];
pr_globals[OPB->_int+2] = OPA->vector[2];
break;
case OP_GADDRESS:
i = OPA->_int + (int) OPB->_float;
#if PRBOUNDSCHECK
if (i < 0 || i >= pr_globaldefs)
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR ("%s Progs attempted to address an out of bounds global", PRVM_NAME);
return;
}
#endif
OPC->_float = pr_globals[i];
break;
case OP_GLOAD_I:
case OP_GLOAD_F:
case OP_GLOAD_FLD:
case OP_GLOAD_ENT:
case OP_GLOAD_S:
case OP_GLOAD_FNC:
#if PRBOUNDSCHECK
if (OPA->_int < 0 || OPA->_int >= pr_globaldefs)
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR ("%s Progs attempted to read an invalid indexed global", PRVM_NAME);
return;
}
#endif
OPC->_float = pr_globals[OPA->_int];
break;
case OP_GLOAD_V:
#if PRBOUNDSCHECK
if (OPA->_int < 0 || OPA->_int + 2 >= pr_globaldefs)
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR ("%s Progs attempted to read an invalid indexed global", PRVM_NAME);
return;
}
#endif
OPC->vector[0] = pr_globals[OPA->_int ];
OPC->vector[1] = pr_globals[OPA->_int+1];
OPC->vector[2] = pr_globals[OPA->_int+2];
break;
case OP_BOUNDCHECK:
if (OPA->_int < 0 || OPA->_int >= st->b)
{
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR ("%s Progs boundcheck failed at line number %d, value is < 0 or >= %d", PRVM_NAME, st->b, st->c);
return;
}
break;
*/
default:
prog->xfunction->profile += (st - startst);
prog->xstatement = st - prog->statements;
PRVM_ERROR ("Bad opcode %i in %s", st->op, PRVM_NAME);
}
}

View File

@ -18,11 +18,13 @@ 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 "ref_server.h"
#include "progsvm.h"
#include "vm_cmds.h"
//=============================================================================
@ -43,14 +45,18 @@ 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
unsigned time; // always sv.framenum * 100 msec
int framenum;
bool attractloop; // running cinematics and demos for the local system only
bool loadgame; // client begins should reuse existing entity
float time; // always sv.framenum * 100 msec
float frametime;
float lastchecktime;
int framenum;
int lastcheck;
char name[MAX_QPATH]; // map name, or cinematic name
struct cmodel_s *models[MAX_MODELS];
cmodel_t *models[MAX_MODELS];
char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH];
entity_state_t baselines[MAX_EDICTS];
@ -60,6 +66,8 @@ 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
@ -87,49 +95,52 @@ 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
edict_t *edict; // EDICT_NUM(clientnum+1)
float spawn_parms[NUM_SPAWN_PARMS]; // quake 1 legacy
prvm_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
int lastmessage; // sv.framenum when packet was last received
int 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:
@ -156,7 +167,9 @@ typedef struct
typedef struct
{
bool initialized; // sv_init has completed
int realtime; // always increasing, no clamping, etc
double realtime; // always increasing, no clamping, etc
int serverflags;
char mapcmd[MAX_TOKEN_CHARS]; // ie: *intro.cin+base
char comment[MAX_TOKEN_CHARS]; // map name, e.t.c.
@ -169,7 +182,7 @@ typedef struct
int next_client_entities; // next client_entity to use
entity_state_t *client_entities; // [num_client_entities]
int last_heartbeat;
float last_heartbeat;
challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting
@ -179,6 +192,17 @@ 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;
@ -197,7 +221,7 @@ extern cvar_t *sv_airaccelerate; // don't reload level state when reentering
extern cvar_t *sv_enforcetime;
extern client_t *sv_client;
extern edict_t *sv_player;
extern prvm_edict_t *sv_player;
//===========================================================
@ -207,9 +231,9 @@ extern edict_t *sv_player;
void SV_FinalMessage (char *message, bool reconnect);
void SV_DropClient (client_t *drop);
int SV_ModelIndex (char *name);
int SV_SoundIndex (char *name);
int SV_ImageIndex (char *name);
int SV_ModelIndex (const char *name);
int SV_SoundIndex (const char *name);
int SV_ImageIndex (const char *name);
void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg);
@ -228,12 +252,16 @@ 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);
//
// sv_send.c
@ -247,7 +275,7 @@ void SV_FlushRedirect (int sv_redirected, char *outputbuf);
void SV_DemoCompleted (void);
void SV_SendClientMessages (void);
void SV_StartSound (vec3_t origin, edict_t *entity, int channel,
void SV_StartSound (vec3_t origin, prvm_edict_t *entity, int channel,
int soundindex, float volume,
float attenuation, float timeofs);
void SV_ClientPrintf (client_t *cl, int level, char *fmt, ...);
@ -259,6 +287,8 @@ 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
@ -271,24 +301,17 @@ 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, ...);
//
// sv_game.c
//
extern game_export_t *ge;
void SV_InitGameProgs (void);
void SV_ShutdownGameProgs (void);
void SV_InitEdict (edict_t *e);
void SV_InitEdict (prvm_edict_t *e);
//
// sv_studio.c
//
byte *SV_GetModelPtr(edict_t *ent);
byte *SV_GetModelPtr(prvm_edict_t *ent);
int SV_StudioExtractBbox( studiohdr_t *phdr, int sequence, float *mins, float *maxs );
@ -308,18 +331,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 (edict_t *ent);
void SV_UnlinkEdict (prvm_edict_t *ent);
// call before removing an entity, and before trying to move one,
// so it doesn't clip against itself
void SV_LinkEdict (edict_t *ent);
void SV_LinkEdict (prvm_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, edict_t **list, int maxcount, int areatype);
int SV_AreaEdicts (vec3_t mins, vec3_t maxs, prvm_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
@ -337,7 +360,10 @@ 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, edict_t *passedict, int contentmask);
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, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int contentsmask);
// mins and maxs are relative
// if the entire move stays in a solid volume, trace.allsolid will be set,
@ -346,4 +372,6 @@ trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *p
// 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)
// passedict is explicitly excluded from clipping checks (normally NULL)
#endif//SERVER_H

View File

@ -195,15 +195,15 @@ void SV_GameMap_f (void)
savedInuse = Z_Malloc(maxclients->value * sizeof(bool));
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
{
savedInuse[i] = cl->edict->inuse;
cl->edict->inuse = false;
savedInuse[i] = cl->edict->priv.sv->free;
cl->edict->priv.sv->free = false;
}
SV_WriteSaveFile( "save0" ); //autosave
// we must restore these for clients to transfer over correctly
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
cl->edict->inuse = savedInuse[i];
cl->edict->priv.sv->free = savedInuse[i];
Z_Free (savedInuse);
}
}
@ -225,23 +225,28 @@ For development work
*/
void SV_Map_f (void)
{
char *map;
char expanded[MAX_QPATH];
char level_path[MAX_QPATH];
// if not a pcx, demo, or cinematic, check to make sure the level exists
map = Cmd_Argv(1);
if (!strstr (map, "."))
sprintf(level_path, "maps/%s", Cmd_Argv(1));
FS_DefaultExtension(level_path, ".bsp" );
if (FS_FileExists(level_path))
{
sprintf (expanded, "maps/%s.bsp", map);
if (!FS_LoadFile (expanded, NULL))
{
Msg ("Can't find %s\n", expanded);
return;
}
}
sv.state = ss_dead; // don't save current level when changing
sv.state = ss_dead; // don't save current level when changing
SV_GameMap_f ();
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 ();
SV_BroadcastCommand ("reconnect\n");
strncpy (svs.mapcmd, Cmd_Argv(1), sizeof(svs.mapcmd) - 1); // archive server state
}
else Msg ("Can't loading %s\n", level_path);
}
/*
@ -309,7 +314,7 @@ void SV_Savegame_f (void)
return;
}
if (maxclients->value == 1 && svs.clients[0].edict->client->ps.stats[STAT_HEALTH] <= 0)
if (maxclients->value == 1 && svs.clients[0].edict->priv.sv->client->stats[STAT_HEALTH] <= 0)
{
Msg ("\nCan't savegame while dead!\n");
return;
@ -381,7 +386,7 @@ void SV_Status_f (void)
{
if (!cl->state) continue;
Msg ("%3i ", i);
Msg ("%5i ", cl->edict->client->ps.stats[STAT_FRAGS]);
Msg ("%5i ", cl->edict->priv.sv->client->stats[STAT_FRAGS]);
if (cl->state == cs_connected)
Msg ("CNCT ");
@ -617,23 +622,6 @@ 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;
}
ge->ServerCommand();
}
//===========================================================
/*
@ -661,6 +649,5 @@ void SV_InitOperatorCommands (void)
Cmd_AddCommand ("save", SV_Savegame_f);
Cmd_AddCommand ("load", SV_Loadgame_f);
Cmd_AddCommand ("killserver", SV_KillServer_f);
Cmd_AddCommand ("sv", SV_ServerCommand_f);
}

View File

@ -34,11 +34,11 @@ Encode a client frame onto the network channel
// because there can be a lot of projectiles, there is a special
// network protocol for them
#define MAX_PROJECTILES 64
edict_t *projectiles[MAX_PROJECTILES];
prvm_edict_t *projectiles[MAX_PROJECTILES];
int numprojs;
cvar_t *sv_projectiles;
bool SV_AddProjectileUpdate (edict_t *ent)
bool SV_AddProjectileUpdate (prvm_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;
edict_t *ent;
prvm_edict_t *ent;
int x, y, z, p, yaw;
int len;
@ -157,7 +157,8 @@ 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
@ -169,17 +170,18 @@ void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t
}
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)
@ -199,11 +201,6 @@ 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
}
@ -231,86 +228,32 @@ 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 (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;
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;
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)
{
@ -326,14 +269,9 @@ 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)
{
@ -342,9 +280,7 @@ 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);
@ -366,11 +302,7 @@ 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);
@ -382,42 +314,35 @@ 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]);
}
}
@ -436,18 +361,21 @@ 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;
}
@ -537,29 +465,45 @@ copies off the playerstat and areabits.
void SV_BuildClientFrame (client_t *client)
{
int e, i;
vec3_t org;
edict_t *ent;
edict_t *clent;
vec3_t org;
prvm_edict_t *ent;
prvm_edict_t *clent;
client_frame_t *frame;
entity_state_t *state;
player_state_t local_state;
int l;
int clientarea, clientcluster;
int leafnum;
int c_fullsend;
byte *clientphs;
byte *bitvector;
byte *clientphs;
byte *bitvector;
clent = client->edict;
if (!clent->client) return;// not in game yet
if (!clent->priv.sv->client) return;// not in game yet
memset(&local_state, 0, sizeof(player_state_t));
// copy player state from prvm fields
VectorSet(local_state.viewoffset, 0, 0, -72 );
local_state.fov = 90;
local_state.pmove.pm_type = PM_SPECTATOR;
local_state.pmove.pm_time = 14;
local_state.pmove.gravity = 800;
for( i = 0; i < 3; i++)
local_state.pmove.origin[i] = (short)clent->fields.sv->origin[i];
for( i = 0; i < 3; i++)
local_state.pmove.velocity[i] = (short)clent->fields.sv->velocity[i];
clent->priv.sv->client = &local_state;
// 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->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i];
for (i = 0; i < 3; i++)
org[i] = clent->priv.sv->client->pmove.origin[i]*0.125 + clent->priv.sv->client->viewoffset[i];
leafnum = CM_PointLeafnum (org);
clientarea = CM_LeafArea (leafnum);
@ -569,7 +513,7 @@ void SV_BuildClientFrame (client_t *client)
frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea);
// grab the current player_state_t
frame->ps = clent->client->ps;
frame->ps = *clent->priv.sv->client;
SV_FatPVS (org);
@ -581,34 +525,33 @@ void SV_BuildClientFrame (client_t *client)
c_fullsend = 0;
for (e = 1; e < ge->num_edicts ; e++)
for (e = 1; e < prog->num_edicts ; e++)
{
ent = EDICT_NUM(e);
ent = PRVM_EDICT_NUM(e);
// ignore ents without visible models
if (ent->svflags & SVF_NOCLIENT)
if (ent->priv.sv->flags & SVF_NOCLIENT)
continue;
// ignore ents without visible models unless they have an effect
if (!ent->s.modelindex && !ent->s.effects && !ent->s.sound && !ent->s.event)
if (!ent->priv.sv->state.modelindex && !ent->priv.sv->state.effects && !ent->priv.sv->state.sound && !ent->priv.sv->state.event)
continue;
// ignore if not touching a PV leaf
if (ent != clent)
{
// check area
if (!CM_AreasConnected (clientarea, ent->areanum))
if (!CM_AreasConnected (clientarea, ent->priv.sv->areanum))
{ // doors can legally straddle two areas, so
// we may need to check another one
if (!ent->areanum2
|| !CM_AreasConnected (clientarea, ent->areanum2))
continue; // blocked by a door
if (!ent->priv.sv->areanum2 || !CM_AreasConnected (clientarea, ent->priv.sv->areanum2))
continue; // blocked by a door
}
// beams just check one point for PHS
if (ent->s.renderfx & RF_BEAM)
if (ent->priv.sv->state.renderfx & RF_BEAM)
{
l = ent->clusternums[0];
l = ent->priv.sv->clusternums[0];
if ( !(clientphs[l >> 3] & (1 << (l&7) )) )
continue;
}
@ -616,37 +559,37 @@ 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->s.sound)
if (ent->priv.sv->state.sound)
{
bitvector = fatpvs; //clientphs;
}
else
bitvector = fatpvs;
if (ent->num_clusters == -1)
if (ent->priv.sv->num_clusters == -1)
{ // too many leafs for individual check, go by headnode
if (!CM_HeadnodeVisible (ent->headnode, bitvector))
if (!CM_HeadnodeVisible (ent->priv.sv->headnode, bitvector))
continue;
c_fullsend++;
}
else
{ // check individual leafs
for (i=0 ; i < ent->num_clusters ; i++)
for (i=0 ; i < ent->priv.sv->num_clusters ; i++)
{
l = ent->clusternums[i];
l = ent->priv.sv->clusternums[i];
if (bitvector[l >> 3] & (1 << (l&7) ))
break;
}
if (i == ent->num_clusters)
if (i == ent->priv.sv->num_clusters)
continue; // not visible
}
if (!ent->s.modelindex)
if (!ent->priv.sv->state.modelindex)
{ // don't send sounds if they will be attenuated away
vec3_t delta;
float len;
VectorSubtract (org, ent->s.origin, delta);
VectorSubtract (org, ent->priv.sv->state.origin, delta);
len = VectorLength (delta);
if (len > 400)
continue;
@ -656,15 +599,15 @@ void SV_BuildClientFrame (client_t *client)
// add it to the circular client_entities array
state = &svs.client_entities[svs.next_client_entities % svs.num_client_entities];
if (ent->s.number != e)
if (ent->priv.sv->state.number != e)
{
MsgWarn ("SV_BuildClientFrame: invalid ent->s.number %d\n", ent->s.number );
ent->s.number = e; // ptr to current entity such as entnumber
MsgWarn ("SV_BuildClientFrame: invalid ent->priv.sv->state.number %d\n", ent->priv.sv->state.number );
ent->priv.sv->state.number = e; // ptr to current entity such as entnumber
}
*state = ent->s;
*state = ent->priv.sv->state;
// don't mark players missiles as solid
if (ent->owner == client->edict) state->solid = 0;
if (ent->priv.sv->owner == client->edict->priv.sv) state->solid = 0;
svs.next_client_entities++;
frame->num_entities++;
@ -683,7 +626,7 @@ Used for recording footage for merged or assembled demos
void SV_RecordDemoMessage (void)
{
int e;
edict_t *ent;
prvm_edict_t *ent;
entity_state_t nostate;
sizebuf_t buf;
byte buf_data[32768];
@ -702,18 +645,14 @@ void SV_RecordDemoMessage (void)
MSG_WriteByte (&buf, svc_packetentities);
e = 1;
ent = EDICT_NUM(e);
while (e < ge->num_edicts)
ent = PRVM_EDICT_NUM(e);
while (e < prog->num_edicts)
{
// ignore ents without visible models unless they have an effect
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);
if (ent->priv.sv->free && ent->priv.sv->state.number && (ent->priv.sv->state.modelindex || ent->priv.sv->state.effects || ent->priv.sv->state.sound || ent->priv.sv->state.event) && !(ent->priv.sv->flags & SVF_NOCLIENT))
MSG_WriteDeltaEntity (&nostate, &ent->priv.sv->state, &buf, false, true);
e++;
ent = EDICT_NUM(e);
ent = PRVM_EDICT_NUM(e);
}
MSG_WriteShort (&buf, 0); // end of packetentities

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
/*
===============
PF_dprintf
Debug print to server console
===============
*/
void PF_dprintf (char *fmt, ...)
{
char msg[1024];
va_list argptr;
va_start (argptr,fmt);
vsprintf (msg, fmt, argptr);
va_end (argptr);
Msg ("%s", msg);
}

View File

@ -24,30 +24,120 @@ 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 (char *name, int start, int max, bool create)
int SV_FindIndex (const char *name, int start, int end, bool create)
{
int i;
if (!name || !name[0])
return 0;
if (!name || !name[0]) return 0;
for (i=1 ; i<max && sv.configstrings[start+i][0] ; i++)
if (!strcmp(sv.configstrings[start+i], name))
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 (!create)
if (i == end)
{
MsgWarn ("SV_FindIndex: %d out range [%d - %d]\n", start, end );
return 0;
}
if (i == max)
Com_Error (ERR_DROP, "*Index: overflow");
strncpy (sv.configstrings[start+i], name, sizeof(sv.configstrings[i]));
// register new resource
strncpy (sv.configstrings[start + i], name, sizeof(sv.configstrings[i]));
if (sv.state != ss_loading)
{
@ -55,25 +145,24 @@ int SV_FindIndex (char *name, int start, int max, bool create)
SZ_Clear (&sv.multicast);
MSG_Begin(svc_configstring);
MSG_WriteShort (&sv.multicast, start+i);
MSG_WriteString (&sv.multicast, name);
MSG_WriteString (&sv.multicast, (char *)name);
MSG_Send(MSG_ALL_R, vec3_origin, NULL );
}
return i;
}
int SV_ModelIndex (char *name)
int SV_ModelIndex (const char *name)
{
return SV_FindIndex (name, CS_MODELS, MAX_MODELS, true);
}
int SV_SoundIndex (char *name)
int SV_SoundIndex (const char *name)
{
return SV_FindIndex (name, CS_SOUNDS, MAX_SOUNDS, true);
}
int SV_ImageIndex (char *name)
int SV_ImageIndex (const char *name)
{
return SV_FindIndex (name, CS_IMAGES, MAX_IMAGES, true);
}
@ -90,26 +179,74 @@ baseline will be transmitted
*/
void SV_CreateBaseline (void)
{
edict_t *svent;
prvm_edict_t *svent;
int entnum;
for (entnum = 1; entnum < ge->num_edicts ; entnum++)
for (entnum = 1; entnum < prog->num_edicts; entnum++)
{
svent = EDICT_NUM(entnum);
if (!svent->inuse)
continue;
if (!svent->s.modelindex && !svent->s.sound && !svent->s.effects)
continue;
svent->s.number = entnum;
svent = PRVM_EDICT_NUM(entnum);
if (!svent->priv.sv->free) continue;
if (!svent->priv.sv->state.modelindex && !svent->priv.sv->state.sound && !svent->priv.sv->state.effects)
continue;
svent->priv.sv->state.number = entnum;
if (entnum > maxclients->value && !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 <= maxclients->value)
{
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
//
VectorCopy (svent->s.origin, svent->s.old_origin);
sv.baselines[entnum] = svent->s;
sv.baselines[entnum] = svent->priv.sv->state;
}
}
/*
================
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 < maxclients->value; 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];
}
}
/*
=================
@ -118,7 +255,6 @@ SV_CheckForSavegame
*/
void SV_CheckForSavegame (char *savename )
{
int i;
char name[MAX_SYSPATH];
if (sv_noreload->value) return;
@ -135,22 +271,6 @@ 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++) ge->RunFrame ();
sv.state = previousState; // PGM
}
}
@ -165,7 +285,8 @@ clients along with it.
*/
void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_state_t serverstate, bool attractloop, bool loadgame)
{
uint i, checksum;
uint i, checksum;
prvm_edict_t *ent;
if (attractloop) Cvar_Set ("paused", "0");
@ -200,7 +321,7 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
strcpy (sv.name, server);
// leave slots at start for clients only
for (i=0 ; i<maxclients->value ; i++)
for (i=0 ; i < maxclients->value ; i++)
{
// needs to reconnect
if (svs.clients[i].state > cs_connected)
@ -208,7 +329,7 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
svs.clients[i].lastframe = -1;
}
sv.time = 1000;
sv.time = 1;
strcpy (sv.name, server);
strcpy (sv.configstrings[CS_NAME], server);
@ -219,7 +340,7 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
}
else
{
sprintf (sv.configstrings[CS_MODELS+1], "maps/%s.bsp", server);
strcpy (sv.configstrings[CS_MODELS+1], server);
sv.models[1] = CM_LoadMap (sv.configstrings[CS_MODELS+1], false, &checksum);
}
sprintf (sv.configstrings[CS_MAPCHECKSUM],"%i", checksum);
@ -233,6 +354,8 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
sv.models[i+1] = CM_InlineModel (sv.configstrings[CS_MODELS+1+i]);
}
SV_VM_Setup();
//
// spawn the rest of the entities on the map
//
@ -242,12 +365,46 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
sv.state = ss_loading;
Com_SetServerState (sv.state);
// load and spawn all other entities
ge->SpawnEntities ( sv.name, CM_EntityString(), spawnpoint );
SV_VM_Begin();
sv.moved_edicts = (prvm_edict_t **)PRVM_Alloc(prog->max_edicts * sizeof(prvm_edict_t *));
*prog->time = sv.time;
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);
// 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 < maxclients->value; 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
ge->RunFrame ();
ge->RunFrame ();
for (i = 0; i < 2; i++)
{
sv.frametime = 0.1f;
SV_Physics();
}
// all precaches are complete
sv.state = serverstate;
@ -256,8 +413,15 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat
// create a baseline for more efficient communications
SV_CreateBaseline ();
// call the progs to get default spawn parms for the new client
// set self to world to intentionally cause errors with broken SetNewParms code in some mods
prog->globals.server->self = 0;
PRVM_ExecuteProgram (prog->globals.server->SetNewParms, "QC function SetNewParms is missing");
for (i = 0; i < NUM_SPAWN_PARMS; i++)
sv_client->spawn_parms[i] = prog->globals.server->parm[i];
// check for a savegame
SV_CheckForSavegame ( savename );
//SV_CheckForSavegame ( savename );
// set serverinfo variable
Cvar_FullSet ("mapname", sv.name, CVAR_SERVERINFO | CVAR_NOSET);
@ -274,8 +438,8 @@ A brand new game has been started
*/
void SV_InitGame (void)
{
int i;
edict_t *ent;
//int i;
//prvm_edict_t *ent;
char idmaster[32];
if (svs.initialized)
@ -328,9 +492,9 @@ void SV_InitGame (void)
}
svs.spawncount = rand();
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);
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 ( (maxclients->value > 1) );
@ -339,17 +503,6 @@ void SV_InitGame (void)
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));
}
}
@ -438,3 +591,145 @@ 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);
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 = maxclients->value;
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 = (float)sv.time;
}
void SV_VM_End(void)
{
PRVM_End;
}

View File

@ -41,10 +41,19 @@ cvar_t *allow_download_models;
cvar_t *allow_download_sounds;
cvar_t *allow_download_maps;
cvar_t *sv_airaccelerate;
cvar_t *sv_airaccelerate;
cvar_t *sv_wateraccelerate;
cvar_t *sv_accelerate;
cvar_t *sv_maxvelocity;
cvar_t *sv_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;
@ -77,7 +86,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);
//ge->ClientDisconnect (drop->edict);
}
if (drop->download)
@ -124,7 +133,7 @@ char *SV_StatusString (void)
cl = &svs.clients[i];
if (cl->state == cs_connected || cl->state == cs_spawned )
{
sprintf (player, "%i %i \"%s\"\n", cl->edict->client->ps.stats[STAT_FRAGS], cl->ping, cl->name);
sprintf (player, "%i %i \"%s\"\n", cl->edict->priv.sv->client->stats[STAT_FRAGS], cl->ping, cl->name);
playerLength = strlen(player);
if (statusLength + playerLength >= sizeof(status) )
break; // can't hold any more
@ -265,7 +274,7 @@ void SVC_DirectConnect (void)
int i;
client_t *cl, *newcl;
client_t temp;
edict_t *ent;
prvm_edict_t *ent;
int edictnum;
int version;
int qport;
@ -335,7 +344,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 * 1000))
if (!NET_IsLocalAddress (adr) && (svs.realtime - cl->lastconnect) < ((int)sv_reconnect_limit->value))
{
MsgWarn("SVC_DirectConnect: %s:reconnect rejected : too soon\n", NET_AdrToString (adr));
return;
@ -371,19 +380,23 @@ gotnewcl:
sv_client = newcl;
edictnum = (newcl - svs.clients) + 1;
ent = EDICT_NUM(edictnum);
ent = PRVM_EDICT_NUM(edictnum);
newcl->edict = ent;
newcl->challenge = challenge; // save challenge for checksumming
// get the game a chance to reject this connection or modify the userinfo
if (!(ge->ClientConnect (ent, userinfo)))
{
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");
PRVM_ExecuteProgram (prog->globals.server->PutClientInServer, "QC function PutClientInServer is missing");
//if (!(ge->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);
@ -535,7 +548,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;
}
}
@ -595,7 +608,7 @@ void SV_ReadPackets (void)
qport = MSG_ReadShort (&net_message) & 0xffff;
// check for packets from connected clients
for (i=0, cl=svs.clients ; i<maxclients->value ; i++,cl++)
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
{
if (cl->state == cs_free)
continue;
@ -610,7 +623,8 @@ 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
@ -645,17 +659,15 @@ void SV_CheckTimeouts (void)
int droppoint;
int zombiepoint;
droppoint = svs.realtime - 1000*timeout->value;
zombiepoint = svs.realtime - 1000*zombietime->value;
droppoint = svs.realtime - timeout->value;
zombiepoint = svs.realtime - zombietime->value;
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;
@ -680,16 +692,15 @@ player processing happens outside RunWorldFrame
*/
void SV_PrepWorldFrame (void)
{
edict_t *ent;
prvm_edict_t *ent;
int i;
for (i=0 ; i<ge->num_edicts ; i++, ent++)
for (i = 0; i < prog->num_edicts ; i++, ent++)
{
ent = EDICT_NUM(i);
ent = PRVM_EDICT_NUM(i);
// events only last for a single message
ent->s.event = 0;
ent->priv.sv->state.event = 0;
}
}
@ -700,20 +711,20 @@ SV_RunGameFrame
*/
void SV_RunGameFrame (void)
{
if (host_speeds->value)
time_before_game = Sys_Milliseconds ();
if (host_speeds->value) time_before_game = Sys_DoubleTime();
// 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;
sv.time = sv.framenum * 0.1;
// don't run if paused
if (!sv_paused->value || maxclients->value > 1)
{
ge->RunFrame ();
SV_Physics();
// never get more than one tic behind
if (sv.time < svs.realtime)
@ -724,9 +735,7 @@ void SV_RunGameFrame (void)
}
}
if (host_speeds->value)
time_after_game = Sys_Milliseconds ();
if (host_speeds->value) time_after_game = Sys_DoubleTime();
}
/*
@ -735,22 +744,24 @@ SV_Frame
==================
*/
void SV_Frame (int msec)
void SV_Frame (float time)
{
time_before_game = time_after_game = 0;
// if server is not active, do nothing
if (!svs.initialized)
return;
if (!svs.initialized) return;
svs.realtime += msec;
svs.realtime += time;
// keep the random time dependent
rand ();
// setup the VM frame
SV_VM_Begin();
// check timeouts
SV_CheckTimeouts ();
// get packets from clients
SV_ReadPackets ();
@ -758,11 +769,10 @@ void SV_Frame (int msec)
if (!sv_timedemo->value && svs.realtime < sv.time)
{
// never let the time get too far off
if (sv.time - svs.realtime > 100)
if (sv.time - svs.realtime > 0.1)
{
if (sv_showclamp->value)
Msg ("sv lowclamp\n");
svs.realtime = sv.time - 100;
if (sv_showclamp->value) Msg ("sv lowclamp\n");
svs.realtime = sv.time - 0.1;
}
NET_Sleep(sv.time - svs.realtime);
return;
@ -789,6 +799,8 @@ void SV_Frame (int msec)
// clear teleport flags, etc for next frame
SV_PrepWorldFrame ();
// end the server VM frame
SV_VM_End();
}
//============================================================================
@ -819,7 +831,7 @@ void Master_Heartbeat (void)
if (svs.last_heartbeat > svs.realtime)
svs.last_heartbeat = svs.realtime;
if (svs.realtime - svs.last_heartbeat < HEARTBEAT_SECONDS*1000)
if (svs.realtime - svs.last_heartbeat < HEARTBEAT_SECONDS)
return; // not time to send yet
svs.last_heartbeat = svs.realtime;
@ -828,12 +840,14 @@ 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);
}
}
}
/*
@ -848,7 +862,7 @@ void Master_Shutdown (void)
int i;
// pgm post3.19 change, cvar pointer not validated before dereferencing
if (!dedicated || !dedicated->value)
if (!dedicated && !dedicated->value)
return; // only dedicated servers send heartbeats
// pgm post3.19 change, cvar pointer not validated before dereferencing
@ -882,7 +896,7 @@ void SV_UserinfoChanged (client_t *cl)
int i;
// call prog code to allow overrides
ge->ClientUserinfoChanged (cl->edict, cl->userinfo);
//ge->ClientUserinfoChanged (cl->edict, cl->userinfo);
// name for C code
strncpy (cl->name, Info_ValueForKey (cl->userinfo, "name"), sizeof(cl->name)-1);
@ -952,7 +966,16 @@ void SV_Init (void)
sv_noreload = Cvar_Get ("sv_noreload", "0", 0);
sv_airaccelerate = Cvar_Get("sv_airaccelerate", "0", CVAR_LATCH);
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);
public_server = Cvar_Get ("public", "0", 0);
@ -1018,7 +1041,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);

1387
engine/server/sv_phys.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -65,7 +65,7 @@ size_t COM_UnpackString( byte *buffer, int pos, char *string )
if(!buffer || !string) return 0;
in = buffer + pos;
do { in++, strsize++; } while(*in != '\0' && in != NULL );
do { in++, strsize++; } while(in && *in != '\0');
strlcpy( string, in - (strsize - 1), strsize );
return pos + strsize;
@ -160,10 +160,10 @@ void SV_WriteSaveFile( char *name )
SV_AddSaveLump( header, savfile, LUMP_COMMENTS, comment, sizeof(comment));
SV_AddCStrLump( header, savfile );
SV_AddSaveLump( header, savfile, LUMP_AREASTATE, portalopen, sizeof(portalopen));
ge->WriteLump ( header, savfile, LUMP_GAMELEVEL, autosave );
//ge->WriteLump ( header, savfile, LUMP_GAMELEVEL, autosave );
SV_AddSaveLump( header, savfile, LUMP_MAPCMDS, svs.mapcmd, sizeof(svs.mapcmd));
SV_AddCvarLump( header, savfile );
ge->WriteLump ( header, savfile, LUMP_GAMELOCAL, autosave );
//ge->WriteLump ( header, savfile, LUMP_GAMELOCAL, autosave );
//merge header
FS_Seek( savfile, 0, SEEK_SET );
@ -278,7 +278,7 @@ void SV_ReadSaveFile( char *name )
SV_InitGame (); // start a new game fresh with new cvars
Sav_LoadMapCmds(&header->lumps[LUMP_MAPCMDS]);
ge->ReadLump( sav_base, &header->lumps[LUMP_GAMELOCAL], LUMP_GAMELOCAL );
//ge->ReadLump( sav_base, &header->lumps[LUMP_GAMELOCAL], LUMP_GAMELOCAL );
}
/*
@ -313,7 +313,7 @@ void SV_ReadLevelFile( char *name )
Sav_LoadCfgString(&header->lumps[LUMP_CFGSTRING]);
Sav_LoadAreaPortals(&header->lumps[LUMP_AREASTATE]);
ge->ReadLump( sav_base, &header->lumps[LUMP_GAMELEVEL], LUMP_GAMELEVEL );
//ge->ReadLump( sav_base, &header->lumps[LUMP_GAMELEVEL], LUMP_GAMELEVEL );
}
bool Menu_ReadComment( char *comment, int savenum )

View File

@ -135,7 +135,7 @@ void SV_BroadcastCommand (char *fmt, ...)
va_list argptr;
char string[1024];
if (!sv.state) return;
if (sv.state != ss_loading) return;
va_start (argptr,fmt);
vsprintf (string, fmt,argptr);
va_end (argptr);
@ -159,7 +159,7 @@ 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, edict_t *ent, const char *filename, int fileline)
void _MSG_Send (msgtype_t to, vec3_t origin, prvm_edict_t *ent, const char *filename, int fileline)
{
byte *mask = NULL;
int leafnum = 0, cluster = 0;
@ -208,7 +208,7 @@ void _MSG_Send (msgtype_t to, vec3_t origin, edict_t *ent, const char *filename,
reliable = true; // intentional fallthrough
case MSG_ONE:
if(ent == NULL) return;
j = NUM_FOR_EDICT(ent);
j = PRVM_NUM_FOR_EDICT(ent);
if (j < 1 || j > numclients) return;
current = svs.clients + (j - 1);
numclients = 1; // send to one
@ -228,9 +228,9 @@ void _MSG_Send (msgtype_t to, vec3_t origin, edict_t *ent, const char *filename,
{
area2 = CM_LeafArea (leafnum);
cluster = CM_LeafCluster (leafnum);
leafnum = CM_PointLeafnum (client->edict->s.origin);
leafnum = CM_PointLeafnum (client->edict->priv.sv->state.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);
@ -278,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, edict_t *entity, int channel, int soundindex, float volume, float attenuation, float timeofs)
void SV_StartSound (vec3_t origin, prvm_edict_t *entity, int channel, int soundindex, float volume, float attenuation, float timeofs)
{
int i, ent, flags, sendchan;
vec3_t origin_v;
@ -299,7 +299,7 @@ void SV_StartSound (vec3_t origin, edict_t *entity, int channel, int soundindex,
MsgWarn("SV_StartSound: timeofs = %f\n", timeofs);
timeofs = bound(0, timeofs, 0.255 );
}
ent = NUM_FOR_EDICT(entity);
ent = PRVM_NUM_FOR_EDICT(entity);
if (channel & 8) // no PHS flag
{
@ -315,7 +315,7 @@ void SV_StartSound (vec3_t origin, edict_t *entity, int channel, int soundindex,
// the client doesn't know that bmodels have weird origins
// the origin can also be explicitly set
if ( (entity->svflags & SVF_NOCLIENT) || (entity->solid == SOLID_BSP) || origin )
if ( (entity->priv.sv->flags & SVF_NOCLIENT) || (entity->priv.sv->solid == SOLID_BSP) || origin )
flags |= SND_POS;
// always send the entity number for channel overrides
@ -327,16 +327,16 @@ void SV_StartSound (vec3_t origin, edict_t *entity, int channel, int soundindex,
if (!origin)
{
origin = origin_v;
if (entity->solid == SOLID_BSP)
if (entity->priv.sv->solid == SOLID_BSP)
{
for (i = 0; i < 3; i++)
{
origin_v[i] = entity->s.origin[i]+0.5*(entity->mins[i]+entity->maxs[i]);
origin_v[i] = entity->priv.sv->state.origin[i]+0.5*(entity->priv.sv->mins[i]+entity->priv.sv->maxs[i]);
}
}
else
{
VectorCopy (entity->s.origin, origin_v);
VectorCopy (entity->priv.sv->state.origin, origin_v);
}
}
@ -490,9 +490,9 @@ SV_SendClientMessages
*/
void SV_SendClientMessages (void)
{
int i;
client_t *c;
int msglen;
int i;
client_t *c;
int msglen;
byte msgbuf[MAX_MSGLEN];
msglen = 0;
@ -500,8 +500,7 @@ 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,10 +526,9 @@ void SV_SendClientMessages (void)
}
// send a message to each connected client
for (i=0, c = svs.clients ; i<maxclients->value; i++, c++)
for (i = 0, c = svs.clients; i < maxclients->value; i++, c++)
{
if (!c->state)
continue;
if (!c->state) continue;
// if the reliable message overflowed,
// drop the client
if (c->netchan.message.overflowed)
@ -541,23 +539,19 @@ void SV_SendClientMessages (void)
SV_DropClient (c);
}
if (sv.state == ss_cinematic
|| sv.state == ss_demo
|| sv.state == ss_pic
)
if (sv.state == ss_cinematic || sv.state == ss_demo || sv.state == ss_pic)
Netchan_Transmit (&c->netchan, msglen, msgbuf);
else if (c->state == cs_spawned)
{
// don't overrun bandwidth
if (SV_RateDrop (c))
continue;
SV_SendClientDatagram (c);
}
else
{
// just update reliable if needed
if (c->netchan.message.cursize || curtime - c->netchan.last_sent > 1000 )
// just update reliable if needed
if (c->netchan.message.cursize || curtime - c->netchan.last_sent > 1.0f)
Netchan_Transmit (&c->netchan, 0, NULL);
}
}

View File

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

View File

@ -22,7 +22,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "engine.h"
#include "server.h"
edict_t *sv_player;
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 usercmd_t cmd;
static vec3_t wishdir, forward, right, up;
static float wishspeed;
/*
============================================================
@ -60,7 +71,7 @@ void SV_New_f (void)
{
char *gamedir;
int playernum;
edict_t *ent;
prvm_edict_t *ent;
if (sv_client->state != cs_connected)
{
@ -98,8 +109,8 @@ void SV_New_f (void)
if (sv.state == ss_game)
{
// set up the entity for the client
ent = EDICT_NUM(playernum+1);
ent->s.number = playernum+1;
ent = PRVM_EDICT_NUM(playernum+1);
ent->priv.sv->state.number = playernum+1;
sv_client->edict = ent;
memset (&sv_client->lastcmd, 0, sizeof(sv_client->lastcmd));
@ -238,7 +249,7 @@ void SV_Begin_f (void)
sv_client->state = cs_spawned;
// call the game begin function
ge->ClientBegin (sv_player);
//ge->ClientBegin (sv_player);
Cbuf_InsertFromDefer ();
}
@ -460,8 +471,8 @@ void SV_ExecuteUserCommand (char *s)
}
}
if (!u->name && sv.state == ss_game)
ge->ClientCommand (sv_player);
//if (!u->name && sv.state == ss_game)
//ge->ClientCommand (sv_player);
}
/*
@ -471,17 +482,324 @@ USER CMD EXECUTION
===========================================================================
*/
void SV_ClientThink (client_t *cl, usercmd_t *cmd)
void SV_ClientRun (client_t *cl, usercmd_t *curcmd)
{
cl->commandMsec -= cmd->msec;
sv_client = cl;
cmd = *curcmd;
cl->commandMsec -= curcmd->msec;
if (cl->commandMsec < 0 && sv_enforcetime->value )
{
MsgWarn("SV_ClientThink: commandMsec underflow from %s\n", cl->name);
return;
}
ge->ClientThink (cl->edict, cmd);
//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 = cmd.forwardmove;
smove = 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] += cmd.upmove;
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;
cmd = sv_client->lastcmd;
sv_client->commandMsec -= cmd.msec;
// 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);
}
/*
@ -498,8 +816,8 @@ 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;
@ -584,13 +902,13 @@ void SV_ExecuteClientMessage (client_t *cl)
{
while (net_drop > 2)
{
SV_ClientThink (cl, &cl->lastcmd);
SV_ClientRun (cl, &cl->lastcmd);
net_drop--;
}
if (net_drop > 1) SV_ClientThink (cl, &oldest);
if (net_drop > 0) SV_ClientThink (cl, &oldcmd);
if (net_drop > 1) SV_ClientRun (cl, &oldest);
if (net_drop > 0) SV_ClientRun (cl, &oldcmd);
}
SV_ClientThink (cl, &newcmd);
SV_ClientRun (cl, &newcmd);
}
cl->lastcmd = newcmd;
break;
@ -604,5 +922,4 @@ void SV_ExecuteClientMessage (client_t *cl)
break;
}
}
}
}

View File

@ -30,14 +30,6 @@ 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
@ -53,12 +45,12 @@ typedef struct areanode_s
areanode_t sv_areanodes[AREA_NODES];
int sv_numareanodes;
float *area_mins, *area_maxs;
edict_t **area_list;
float *area_mins, *area_maxs;
prvm_edict_t **area_list;
int area_count, area_maxcount;
int area_type;
int SV_HullForEntity (edict_t *ent);
int SV_HullForEntity (prvm_edict_t *ent);
// ClearLink is used for new headnodes
@ -147,12 +139,11 @@ SV_UnlinkEdict
===============
*/
void SV_UnlinkEdict (edict_t *ent)
void SV_UnlinkEdict (prvm_edict_t *ent)
{
if (!ent->area.prev)
return; // not linked in anywhere
RemoveLink (&ent->area);
ent->area.prev = ent->area.next = NULL;
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;
}
@ -163,7 +154,7 @@ SV_LinkEdict
===============
*/
#define MAX_TOTAL_ENT_LEAFS 128
void SV_LinkEdict (edict_t *ent)
void SV_LinkEdict (prvm_edict_t *ent)
{
areanode_t *node;
int leafs[MAX_TOTAL_ENT_LEAFS];
@ -173,80 +164,80 @@ void SV_LinkEdict (edict_t *ent)
int area;
int topnode;
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;
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) return;
// set the size
VectorSubtract (ent->maxs, ent->mins, ent->size);
VectorSubtract (ent->priv.sv->maxs, ent->priv.sv->mins, ent->priv.sv->size);
// encode the size into the entity_state for client prediction
if (ent->solid == SOLID_BBOX && !(ent->svflags & SVF_DEADMONSTER))
if (ent->priv.sv->solid == SOLID_BBOX && !(ent->priv.sv->flags & SVF_DEADMONSTER))
{
// assume that x/y are equal and symetric
i = ent->maxs[0]/8;
i = ent->priv.sv->maxs[0]/8;
if (i<1) i = 1;
if (i>31) i = 31;
// z is not symetric
j = (-ent->mins[2])/8;
j = (-ent->priv.sv->mins[2])/8;
if (j < 1) j = 1;
if (j > 31) j = 31;
// and z maxs can be negative...
k = (ent->maxs[2]+32)/8;
k = (ent->priv.sv->maxs[2]+32)/8;
if (k<1) k = 1;
if (k>63) k = 63;
ent->s.solid = (k<<10) | (j<<5) | i;
ent->priv.sv->state.solid = (k<<10) | (j<<5) | i;
}
else if (ent->solid == SOLID_BSP)
else if (ent->priv.sv->solid == SOLID_BSP)
{
ent->s.solid = 31; // a solid_bbox will never create this value
ent->priv.sv->state.solid = 31; // a solid_bbox will never create this value
}
else ent->s.solid = 0;
else ent->priv.sv->state.solid = 0;
// set the abs box
if (ent->solid == SOLID_BSP && (ent->s.angles[0] || ent->s.angles[1] || ent->s.angles[2]) )
if (ent->priv.sv->solid == SOLID_BSP && (ent->priv.sv->state.angles[0] || ent->priv.sv->state.angles[1] || ent->priv.sv->state.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->mins[i]);
v =fabs( ent->priv.sv->mins[i]);
if (v > max) max = v;
v =fabs( ent->maxs[i]);
v =fabs( ent->priv.sv->maxs[i]);
if (v > max) max = v;
}
for (i=0 ; i<3 ; i++)
for (i = 0; i < 3; i++)
{
ent->absmin[i] = ent->s.origin[i] - max;
ent->absmax[i] = ent->s.origin[i] + max;
ent->priv.sv->absmin[i] = ent->priv.sv->state.origin[i] - max;
ent->priv.sv->absmax[i] = ent->priv.sv->state.origin[i] + max;
}
}
else
{ // normal
VectorAdd (ent->s.origin, ent->mins, ent->absmin);
VectorAdd (ent->s.origin, ent->maxs, ent->absmax);
VectorAdd (ent->priv.sv->state.origin, ent->priv.sv->mins, ent->priv.sv->absmin);
VectorAdd (ent->priv.sv->state.origin, ent->priv.sv->maxs, ent->priv.sv->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->absmin[0] -= 1;
ent->absmin[1] -= 1;
ent->absmin[2] -= 1;
ent->absmax[0] += 1;
ent->absmax[1] += 1;
ent->absmax[2] += 1;
ent->priv.sv->absmin[0] -= 1;
ent->priv.sv->absmin[1] -= 1;
ent->priv.sv->absmin[2] -= 1;
ent->priv.sv->absmax[0] += 1;
ent->priv.sv->absmax[1] += 1;
ent->priv.sv->absmax[2] += 1;
// link to PVS leafs
ent->num_clusters = 0;
ent->areanum = 0;
ent->areanum2 = 0;
ent->priv.sv->num_clusters = 0;
ent->priv.sv->areanum = 0;
ent->priv.sv->areanum2 = 0;
//get all leafs, including solids
num_leafs = CM_BoxLeafnums (ent->absmin, ent->absmax, leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
num_leafs = CM_BoxLeafnums (ent->priv.sv->absmin, ent->priv.sv->absmax, leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
// set areas
for (i = 0; i < num_leafs; i++)
@ -256,25 +247,25 @@ void SV_LinkEdict (edict_t *ent)
if (area)
{ // doors may legally straggle two areas,
// but nothing should evern need more than that
if (ent->areanum && ent->areanum != area)
if (ent->priv.sv->areanum && ent->priv.sv->areanum != 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;
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->priv.sv->absmin[0], ent->priv.sv->absmin[1], ent->priv.sv->absmin[2]);
ent->priv.sv->areanum2 = area;
}
else ent->areanum = area;
else ent->priv.sv->areanum = area;
}
}
if (num_leafs >= MAX_TOTAL_ENT_LEAFS)
{
// assume we missed some leafs, and mark by headnode
ent->num_clusters = -1;
ent->headnode = topnode;
ent->priv.sv->num_clusters = -1;
ent->priv.sv->headnode = topnode;
}
else
{
ent->num_clusters = 0;
ent->priv.sv->num_clusters = 0;
for (i = 0; i < num_leafs; i++)
{
if (clusters[i] == -1) continue; // not a visible leaf
@ -284,42 +275,42 @@ void SV_LinkEdict (edict_t *ent)
}
if (j == i)
{
if (ent->num_clusters == MAX_ENT_CLUSTERS)
if (ent->priv.sv->num_clusters == MAX_ENT_CLUSTERS)
{
// assume we missed some leafs, and mark by headnode
ent->num_clusters = -1;
ent->headnode = topnode;
ent->priv.sv->num_clusters = -1;
ent->priv.sv->headnode = topnode;
break;
}
ent->clusternums[ent->num_clusters++] = clusters[i];
ent->priv.sv->clusternums[ent->priv.sv->num_clusters++] = clusters[i];
}
}
}
// if first time, make sure old_origin is valid
if (!ent->linkcount)
if (!ent->priv.sv->linkcount)
{
VectorCopy (ent->s.origin, ent->s.old_origin);
VectorCopy (ent->priv.sv->state.origin, ent->priv.sv->state.old_origin);
}
ent->linkcount++;
ent->priv.sv->linkcount++;
if (ent->solid == SOLID_NOT) return;
if (ent->priv.sv->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->absmin[node->axis] > node->dist)
if (ent->priv.sv->absmin[node->axis] > node->dist)
node = node->children[0];
else if (ent->absmax[node->axis] < node->dist)
else if (ent->priv.sv->absmax[node->axis] < node->dist)
node = node->children[1];
else break; // crosses the node
}
// link it in
if (ent->solid == SOLID_TRIGGER) InsertLinkBefore (&ent->area, &node->trigger_edicts);
else InsertLinkBefore (&ent->area, &node->solid_edicts);
if (ent->priv.sv->solid == SOLID_TRIGGER) InsertLinkBefore (&ent->priv.sv->area, &node->trigger_edicts);
else InsertLinkBefore (&ent->priv.sv->area, &node->solid_edicts);
}
@ -333,7 +324,7 @@ SV_AreaEdicts_r
void SV_AreaEdicts_r (areanode_t *node)
{
link_t *l, *next, *start;
edict_t *check;
prvm_edict_t *check;
int count = 0;
// touch linked edicts
@ -344,11 +335,11 @@ void SV_AreaEdicts_r (areanode_t *node)
for (l = start->next; l != start; l = next)
{
next = l->next;
check = EDICT_FROM_AREA(l);
check = PRVM_EDICT_FROM_AREA(l);
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])
if (check->priv.sv->solid == SOLID_NOT) continue; // deactivated
if (check->priv.sv->absmin[0] > area_maxs[0] || check->priv.sv->absmin[1] > area_maxs[1] || check->priv.sv->absmin[2] > area_maxs[2]
|| check->priv.sv->absmax[0] < area_mins[0] || check->priv.sv->absmax[1] < area_mins[1] || check->priv.sv->absmax[2] < area_mins[2])
continue; // not touching
if (area_count == area_maxcount)
@ -375,7 +366,7 @@ void SV_AreaEdicts_r (areanode_t *node)
SV_AreaEdicts
================
*/
int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype)
int SV_AreaEdicts (vec3_t mins, vec3_t maxs, prvm_edict_t **list, int maxcount, int areatype)
{
area_mins = mins;
area_maxs = maxs;
@ -399,7 +390,7 @@ SV_PointContents
*/
int SV_PointContents (vec3_t p)
{
edict_t *touch[MAX_EDICTS], *hit;
prvm_edict_t *touch[MAX_EDICTS], *hit;
int i, num;
int contents, c2;
int headnode;
@ -417,30 +408,14 @@ int SV_PointContents (vec3_t p)
// might intersect, so do an exact clip
headnode = SV_HullForEntity (hit);
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);
angles = hit->priv.sv->state.angles;
if (hit->priv.sv->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
c2 = CM_TransformedPointContents (p, headnode, hit->priv.sv->state.origin, hit->priv.sv->state.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
@ -451,15 +426,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 (edict_t *ent)
int SV_HullForEntity (prvm_edict_t *ent)
{
cmodel_t *model;
// decide which clipping hull to use, based on the size
if (ent->solid == SOLID_BSP)
if (ent->priv.sv->solid == SOLID_BSP)
{
// explicit hulls in the BSP model
model = sv.models[ ent->s.modelindex ];
model = sv.models[ ent->priv.sv->state.modelindex ];
if (!model)
{
@ -470,7 +445,7 @@ int SV_HullForEntity (edict_t *ent)
}
// create a temp hull from bounding box sizes
return CM_HeadnodeForBox (ent->mins, ent->maxs);
return CM_HeadnodeForBox (ent->priv.sv->mins, ent->priv.sv->maxs);
}
/*
@ -482,7 +457,7 @@ SV_ClipMoveToEntities
void SV_ClipMoveToEntities ( moveclip_t *clip )
{
int i, num;
edict_t *touchlist[MAX_EDICTS], *touch;
prvm_edict_t *touchlist[MAX_EDICTS], *touch;
trace_t trace;
int headnode;
float *angles;
@ -494,30 +469,30 @@ void SV_ClipMoveToEntities ( moveclip_t *clip )
for (i = 0; i < num; i++)
{
touch = touchlist[i];
if (touch->solid == SOLID_NOT) continue;
if (touch->priv.sv->solid == SOLID_NOT) continue;
if (touch == clip->passedict) continue;
if (clip->trace.allsolid) return;
if (clip->passedict)
{
if (touch->owner == clip->passedict) continue; // don't clip against own missiles
if (clip->passedict->owner == touch) continue; // don't clip against owner
if (touch->priv.sv->owner == clip->passedict->priv.sv) continue; // don't clip against own missiles
if (clip->passedict->priv.sv->owner == touch->priv.sv) continue; // don't clip against owner
}
if ( !(clip->contentmask & CONTENTS_DEADMONSTER) && (touch->svflags & SVF_DEADMONSTER) )
if ( !(clip->contentmask & CONTENTS_DEADMONSTER) && (touch->priv.sv->flags & SVF_DEADMONSTER) )
continue;
// might intersect, so do an exact clip
headnode = SV_HullForEntity (touch);
angles = touch->s.angles;
if (touch->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
angles = touch->priv.sv->state.angles;
if (touch->priv.sv->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate
if (touch->svflags & SVF_MONSTER)
if (touch->priv.sv->flags & SVF_MONSTER)
{
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins2, clip->maxs2, headnode, clip->contentmask, touch->s.origin, angles);
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins2, clip->maxs2, headnode, clip->contentmask, touch->priv.sv->state.origin, angles);
}
else
{
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins, clip->maxs, headnode, clip->contentmask, touch->s.origin, angles);
trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins, clip->maxs, headnode, clip->contentmask, touch->priv.sv->state.origin, angles);
}
if (trace.allsolid || trace.startsolid || trace.fraction < clip->trace.fraction)
{
@ -529,7 +504,11 @@ void SV_ClipMoveToEntities ( moveclip_t *clip )
}
else clip->trace = trace;
}
else if (trace.startsolid) clip->trace.startsolid = true;
else if (trace.startsolid)
{
clip->trace.startsolid = true;
//clip->trace.startstuck = true;
}
}
}
@ -568,7 +547,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, edict_t *passedict, int contentmask)
trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, prvm_edict_t *passedict, int contentmask)
{
moveclip_t clip;
@ -579,7 +558,7 @@ trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *p
// clip to world
clip.trace = CM_BoxTrace (start, end, mins, maxs, 0, contentmask);
clip.trace.ent = ge->edicts;
clip.trace.ent = prog->edicts;
if (clip.trace.fraction == 0) return clip.trace; // blocked by the world
clip.contentmask = contentmask;
@ -601,3 +580,28 @@ trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *p
return clip.trace;
}
trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int contentsmask)
{
moveclip_t clip;
memset( &clip, 0, sizeof(moveclip_t));
clip.passedict = ent;
clip.contentmask = contentsmask;
VectorCopy(start, clip.start);
VectorCopy(end, clip.end);
VectorCopy(mins, clip.mins);
VectorCopy(maxs, clip.maxs);
VectorCopy(mins, clip.mins2);
VectorCopy(maxs, clip.maxs2);
// create the bounding box of the entire move
SV_TraceBounds ( clip.start, clip.mins2, clip.maxs2, clip.end, clip.boxmins, clip.boxmaxs );
// all prepares finished
SV_ClipMoveToEntities( &clip );
return clip.trace;
}

View File

@ -53,8 +53,8 @@ vec3_t listener_up;
bool s_registering;
int soundtime; // sample PAIRS
int paintedtime; // sample PAIRS
float soundtime; // sample PAIRS
float 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;
int s_rawend;
float s_rawend;
portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
@ -120,8 +120,7 @@ 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);
@ -137,8 +136,7 @@ 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 ();
@ -149,7 +147,6 @@ void S_Init (void)
paintedtime = 0;
Msg ("sound sampling rate: %i\n", dma.speed);
S_StopAllSounds ();
}
@ -166,8 +163,7 @@ void S_Shutdown(void)
int i;
sfx_t *sfx;
if (!sound_started)
return;
if (!sound_started) return;
SNDDMA_Shutdown();
@ -181,13 +177,10 @@ 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;
}
@ -202,7 +195,7 @@ S_FindName
==================
*/
sfx_t *S_FindName (char *name, bool create)
sfx_t *S_FindName (const char *name, bool create)
{
int i;
sfx_t *sfx;
@ -302,7 +295,7 @@ S_RegisterSound
==================
*/
sfx_t *S_RegisterSound (char *name)
sfx_t *S_RegisterSound (const char *name)
{
sfx_t *sfx;
@ -371,18 +364,19 @@ S_PickChannel
*/
channel_t *S_PickChannel(int entnum, int entchannel)
{
int ch_idx;
int first_to_die;
int life_left;
int ch_idx;
int first_to_die;
float 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 = 0x7fffffff;
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 = 32768.0;
for (ch_idx = 0; ch_idx < MAX_CHANNELS; ch_idx++)
{
if (entchannel != 0 // channel 0 never overrides
&& channels[ch_idx].entnum == entnum
@ -692,16 +686,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 * 0.001 * dma.speed + s_beginofs;
start = cl.frame.servertime * dma.speed + s_beginofs;
if (start < paintedtime)
{
start = paintedtime;
s_beginofs = start - (cl.frame.servertime * 0.001 * dma.speed);
s_beginofs = start - (cl.frame.servertime * dma.speed);
}
else if (start > paintedtime + 0.3 * dma.speed)
{
start = paintedtime + 0.1 * dma.speed;
s_beginofs = start - (cl.frame.servertime * 0.001 * dma.speed);
s_beginofs = start - (cl.frame.servertime * dma.speed);
}
else
{
@ -732,7 +726,7 @@ void S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float f
S_StartLocalSound
==================
*/
int S_StartLocalSound (char *sound)
int S_StartLocalSound (const char *sound)
{
sfx_t *sfx;
@ -892,7 +886,7 @@ void S_AddLoopSounds (void)
ch->rightvol = right_total;
ch->autosound = true; // remove next frame
ch->sfx = sfx;
ch->pos = paintedtime % sc->length;
ch->pos = fmod(paintedtime, sc->length);
ch->end = paintedtime + sc->length - ch->pos;
}
}
@ -926,7 +920,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
{ // optimized case
for (i=0 ; i<samples ; i++)
{
dst = s_rawend&(MAX_RAW_SAMPLES-1);
dst = (int)s_rawend & (MAX_RAW_SAMPLES - 1);
s_rawend++;
s_rawsamples[dst].left =
LittleShort(((short *)data)[i*2]) << 8;
@ -941,7 +935,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
src = i*scale;
if (src >= samples)
break;
dst = s_rawend&(MAX_RAW_SAMPLES-1);
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
s_rawend++;
s_rawsamples[dst].left =
LittleShort(((short *)data)[src*2]) << 8;
@ -957,7 +951,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
src = i*scale;
if (src >= samples)
break;
dst = s_rawend&(MAX_RAW_SAMPLES-1);
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
s_rawend++;
s_rawsamples[dst].left =
LittleShort(((short *)data)[src]) << 8;
@ -972,7 +966,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
src = i*scale;
if (src >= samples)
break;
dst = s_rawend&(MAX_RAW_SAMPLES-1);
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
s_rawend++;
s_rawsamples[dst].left =
((char *)data)[src*2] << 16;
@ -987,7 +981,7 @@ void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
src = i*scale;
if (src >= samples)
break;
dst = s_rawend&(MAX_RAW_SAMPLES-1);
dst = (int)s_rawend & (MAX_RAW_SAMPLES-1);
s_rawend++;
s_rawsamples[dst].left =
(((byte *)data)[src]-128) << 16;

View File

@ -28,7 +28,7 @@ typedef struct
typedef struct
{
int length;
float 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;
unsigned begin; // begin on this sample
float 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
int end; // end time in global paintsamples
int leftvol; // 0-255 volume
int rightvol; // 0-255 volume
float 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 int paintedtime;
extern int s_rawend;
extern float paintedtime;
extern float 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(int endtime);
void S_PaintChannels(float endtime);
// picks a channel based on priorities, empty slots, number of channels
channel_t *S_PickChannel(int entnum, int entchannel);

View File

@ -109,17 +109,17 @@ S_TransferPaintBuffer
===================
*/
void S_TransferPaintBuffer(int endtime)
void S_TransferPaintBuffer(float endtime)
{
int out_idx;
int count;
float count;
int out_mask;
int *p;
int step;
int val;
unsigned long *pbuf;
int val;
dword *pbuf;
pbuf = (unsigned long *)dma.buffer;
pbuf = (dword*)dma.buffer;
if (s_testsound->value)
{
@ -129,7 +129,7 @@ void S_TransferPaintBuffer(int 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)*20000*256;
paintbuffer[i].left = paintbuffer[i].right = sin((paintedtime+i)*0.1)*20*256;
}
@ -142,7 +142,7 @@ void S_TransferPaintBuffer(int endtime)
p = (int *) paintbuffer;
count = (endtime - paintedtime) * dma.channels;
out_mask = dma.samples - 1;
out_idx = paintedtime * dma.channels & out_mask;
out_idx = (int)(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(int endtime)
void S_PaintChannels(float endtime)
{
int i;
int end;
channel_t *ch;
int i;
float end;
channel_t *ch;
sfxcache_t *sc;
int ltime, count;
float 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,12 +221,11 @@ void S_PaintChannels(int 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");
@ -242,7 +241,7 @@ void S_PaintChannels(int endtime)
for (i=paintedtime ; i<stop ; i++)
{
s = i&(MAX_RAW_SAMPLES-1);
paintbuffer[i-paintedtime] = s_rawsamples[s];
paintbuffer[(int)(i - paintedtime)] = s_rawsamples[s];
}
// if (i != end)
// Msg ("partial stream\n");
@ -250,8 +249,8 @@ void S_PaintChannels(int endtime)
// Msg ("full stream\n");
for ( ; i<end ; i++)
{
paintbuffer[i-paintedtime].left =
paintbuffer[i-paintedtime].right = 0;
paintbuffer[(int)(i - paintedtime)].left =
paintbuffer[(int)(i - paintedtime)].right = 0;
}
}

View File

@ -25,7 +25,7 @@ void S_Shutdown (void);
// if origin is NULL, the sound will be dynamically sourced from the entity
void S_StartSound (vec3_t origin, int entnum, int entchannel, struct sfx_s *sfx, float fvol, float attenuation, float timeofs);
int S_StartLocalSound (char *s);
int S_StartLocalSound (const 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 (char *sample);
struct sfx_s *S_RegisterSound (const char *sample);
void S_EndRegistration (void);
struct sfx_s *S_FindName (char *name, bool create);
struct sfx_s *S_FindName (const char *name, bool create);
// the sound code makes callbacks to the client for entitiy position
// information, so entities can be dynamically re-spatialized

View File

@ -28,9 +28,8 @@ extern HWND cl_hwnd;
char *buildstring = __TIME__ " " __DATE__;
stdinout_api_t std;
uint sys_msg_time;
uint sys_frame_time;
int starttime;
float sys_frame_time;
double curtime;
/*
===============================================================================
@ -83,8 +82,6 @@ void Sys_Init (void)
{
OSVERSIONINFO vinfo;
timeBeginPeriod( 1 );
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
if (!GetVersionEx (&vinfo)) Sys_Error ("Couldn't get OS info");
@ -109,9 +106,8 @@ void Sys_SendKeyEvents (void)
TranslateMessage (&msg);
DispatchMessage (&msg);
}
// grab frame time
sys_frame_time = timeGetTime(); // FIXME: should this be at start?
sys_frame_time = Sys_DoubleTime();
}
@ -145,30 +141,6 @@ char *Sys_GetClipboardData( void )
return data;
}
/*
================
Sys_Milliseconds
================
*/
int curtime;
int Sys_Milliseconds (void)
{
static int base;
static bool initialized = false;
//return (int)(pi.DoubleTime() * 1000);
if (!initialized)
{ // let base retain 16 bits of effectively random data
base = timeGetTime() & 0xffff0000;
initialized = true;
}
curtime = timeGetTime() - base;
return curtime;
}
/*
==============================================================================

View File

@ -15,7 +15,7 @@ RES = $(MAINTARGET).rc
default: $(MAINTARGET).exe
$(MAINTARGET).exe: $(MAINTARGET).obj bsplib.res
$(link) $(OBJS) $(LLDLIBS) bsplib.res /out:"bsplib.exe" /subsystem:windows
$(link) $(OBJS) $(LLDLIBS) bsplib.res /out:"bsplib.exe" /subsystem:windows /opt:nowin98
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp $(MAINTARGET).res > nul
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
@del $(MAINTARGET).exe

View File

@ -260,7 +260,7 @@ print into cmd32 console
*/
void Sys_PrintA(const char *pMsg)
{
printf( pMsg );
fprintf (stdout, pMsg );
fflush (stdout); //refresh message
}
@ -509,7 +509,7 @@ void Sys_ErrorW(char *error, ...)
SetFocus( s_wcd.hWnd );
// wait for the user to quit
while(msg.message != WM_QUIT)
while(!hooked_out && msg.message != WM_QUIT)
{
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{

View File

@ -11,6 +11,7 @@ bool hooked_out = false;
bool log_active = false;
bool show_always = true;
bool about_mode = false;
bool sys_error = false;
char dllname[64];
const char *show_credits = "\n\n\n\n\tCopyright XashXT Group 2007 Š\n\t All Rights Reserved\n\n\t Visit www.xash.ru\n";
@ -138,30 +139,29 @@ void PlatformInit ( char *funcname, int argc, char **argv )
pi->Init( argc, argv );
if(!GetParmFromCmdLine("-game", gamedir ))
strncpy(gamedir, "xash", sizeof(gamedir));
if(!GetParmFromCmdLine("+map", source ))
strncpy(source, "newmap", sizeof(source));
if(!GetParmFromCmdLine("+dat", source ))
strncpy(source, "progs", sizeof(source));
if(CheckParm("-vis")) bspflags |= BSP_ONLYVIS;
if(CheckParm("-rad")) bspflags |= BSP_ONLYRAD;
if(CheckParm("-full")) bspflags |= BSP_FULLCOMPILE;
if(CheckParm("-onlyents")) bspflags |= BSP_ONLYENTS;
if(CheckParm("-progdefs")) qccflags |= QCC_PROGDEFS;
if(CheckParm("/O0")) qccflags |= QCC_OPT_LEVEL_0;
if(CheckParm("/O1")) qccflags |= QCC_OPT_LEVEL_1;
if(CheckParm("/O2")) qccflags |= QCC_OPT_LEVEL_2;
if(CheckParm("/O2")) qccflags |= QCC_OPT_LEVEL_3;
switch(app_name)
{
case BSPLIB:
if(!GetParmFromCmdLine("-game", gamedir ))
strncpy(gamedir, "xash", sizeof(gamedir));
if(!GetParmFromCmdLine("+map", source ))
strncpy(source, "newmap", sizeof(source));
if(CheckParm("-vis")) bspflags |= BSP_ONLYVIS;
if(CheckParm("-rad")) bspflags |= BSP_ONLYRAD;
if(CheckParm("-full")) bspflags |= BSP_FULLCOMPILE;
if(CheckParm("-onlyents")) bspflags |= BSP_ONLYENTS;
pi->Compile.PrepareBSP( gamedir, source, bspflags );
break;
case QCCLIB:
if(!GetParmFromCmdLine("+dat", source ))
strncpy(source, "progs", sizeof(source));
if(CheckParm("-progdefs")) qccflags |= QCC_PROGDEFS;
if(CheckParm("/O0")) qccflags |= QCC_OPT_LEVEL_0;
if(CheckParm("/O1")) qccflags |= QCC_OPT_LEVEL_1;
if(CheckParm("/O2")) qccflags |= QCC_OPT_LEVEL_2;
if(CheckParm("/O2")) qccflags |= QCC_OPT_LEVEL_3;
pi->Compile.PrepareDAT( gamedir, source, qccflags );
break;
case SPRITE:

View File

@ -53,8 +53,8 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# 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 /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib /nologo /dll /pdb:none /machine:I386
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /opt:nowin98
# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib /nologo /dll /pdb:none /machine:I386 /opt:nowin98
# Begin Custom Build
TargetDir=\Xash3D\src_main\!source\temp\launcher\!release
InputPath=\Xash3D\src_main\!source\temp\launcher\!release\launcher.dll

View File

@ -36,6 +36,7 @@ extern HINSTANCE base_hInstance;
extern HINSTANCE linked_dll;
extern bool debug_mode;
extern bool log_active;
extern bool hooked_out;
extern int com_argc;
extern char *com_argv[MAX_NUM_ARGVS];
extern char sys_rootdir[ MAX_SYSPATH ];
@ -43,8 +44,8 @@ extern char log_path[256];
extern bool console_read_only;
extern bool show_always;
extern bool about_mode;
extern bool sys_error;
char *va(const char *format, ...);
static int sys_error = false;
const char* Log_Timestamp( void );
int CheckParm (const char *parm);

View File

@ -103,7 +103,7 @@ void *_Mem_Realloc(byte *poolptr, void *memptr, size_t size, const char *filenam
char *nb;
memheader_t *hdr;
if (size <= 0) return memptr;//no need to reallocate
if (size <= 0) return memptr; //no need to reallocate
nb = _Mem_Alloc(poolptr, size, filename, fileline);
if (memptr) //first allocate?
@ -113,7 +113,6 @@ void *_Mem_Realloc(byte *poolptr, void *memptr, size_t size, const char *filenam
_Mem_Copy( nb, memptr, hdr->size, filename, fileline );
_Mem_Free( memptr, filename, fileline);//free unused old block
}
else MsgWarn("Mem_Realloc: memptr == NULL (called at %s:%i)\n", filename, fileline);
return (void *)nb;
}

View File

@ -999,7 +999,7 @@ void LoadMapFile (void)
nummapbrushsides = 0;
num_entities = 0;
if(!load) Sys_Error("can't loading map file\n");
if(!load) Sys_Error("can't loading map file %s\n", path );
Msg ("reading %s\n", path);
while (ParseMapEntity ()){}

View File

@ -53,8 +53,8 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# 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 /dll /machine:I386
# ADD LINK32 kernel32.lib winmm.lib user32.lib /nologo /dll /pdb:none /machine:I386
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /opt:nowin98
# ADD LINK32 kernel32.lib winmm.lib user32.lib /nologo /dll /pdb:none /machine:I386 /opt:nowin98
# Begin Custom Build
TargetDir=\XASH3D\src_main\!source\temp\platform\!release
InputPath=\XASH3D\src_main\!source\temp\platform\!release\platform.dll

View File

@ -1,73 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: platform - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\Temp\RSPF6D.tmp" with contents
[
/nologo /ML /W3 /GX /O2 /Ob0 /I "./" /I "../public" /I "./bsplib/" /I "./qcclib" /I "./mdllib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fo"..\temp\platform\!release/" /Fd"..\temp\platform\!release/" /FD /c
"D:\XASH3D\src_main\!source\platform\qcclib\qccmain.c"
]
Creating command line "cl.exe @C:\Temp\RSPF6D.tmp"
Creating temporary file "C:\Temp\RSPF6E.tmp" with contents
[
kernel32.lib winmm.lib user32.lib /nologo /dll /pdb:none /machine:I386 /out:"..\temp\platform\!release/platform.dll" /implib:"..\temp\platform\!release/platform.lib"
"\XASH3D\src_main\!source\temp\platform\!release\basemem.obj"
"\XASH3D\src_main\!source\temp\platform\!release\baseutils.obj"
"\XASH3D\src_main\!source\temp\platform\!release\brushbsp.obj"
"\XASH3D\src_main\!source\temp\platform\!release\bspfile.obj"
"\XASH3D\src_main\!source\temp\platform\!release\csg.obj"
"\XASH3D\src_main\!source\temp\platform\!release\faces.obj"
"\XASH3D\src_main\!source\temp\platform\!release\filesystem.obj"
"\XASH3D\src_main\!source\temp\platform\!release\flow.obj"
"\XASH3D\src_main\!source\temp\platform\!release\imglib.obj"
"\XASH3D\src_main\!source\temp\platform\!release\leakfile.obj"
"\XASH3D\src_main\!source\temp\platform\!release\lightmap.obj"
"\XASH3D\src_main\!source\temp\platform\!release\map.obj"
"\XASH3D\src_main\!source\temp\platform\!release\patches.obj"
"\XASH3D\src_main\!source\temp\platform\!release\platform.obj"
"\XASH3D\src_main\!source\temp\platform\!release\portals.obj"
"\XASH3D\src_main\!source\temp\platform\!release\pr_comp.obj"
"\XASH3D\src_main\!source\temp\platform\!release\pr_lex.obj"
"\XASH3D\src_main\!source\temp\platform\!release\prtfile.obj"
"\XASH3D\src_main\!source\temp\platform\!release\qbsp3.obj"
"\XASH3D\src_main\!source\temp\platform\!release\qcc_utils.obj"
"\XASH3D\src_main\!source\temp\platform\!release\qccmain.obj"
"\XASH3D\src_main\!source\temp\platform\!release\qrad3.obj"
"\XASH3D\src_main\!source\temp\platform\!release\qvis3.obj"
"\XASH3D\src_main\!source\temp\platform\!release\shaders.obj"
"\XASH3D\src_main\!source\temp\platform\!release\spritegen.obj"
"\XASH3D\src_main\!source\temp\platform\!release\studio.obj"
"\XASH3D\src_main\!source\temp\platform\!release\studio_utils.obj"
"\XASH3D\src_main\!source\temp\platform\!release\textures.obj"
"\XASH3D\src_main\!source\temp\platform\!release\trace.obj"
"\XASH3D\src_main\!source\temp\platform\!release\tree.obj"
"\XASH3D\src_main\!source\temp\platform\!release\winding.obj"
"\XASH3D\src_main\!source\temp\platform\!release\writebsp.obj"
"\XASH3D\src_main\!source\temp\platform\!release\ziplib.obj"
]
Creating command line "link.exe @C:\Temp\RSPF6E.tmp"
Creating temporary file "C:\Temp\RSPF6F.bat" with contents
[
@echo off
copy \XASH3D\src_main\!source\temp\platform\!release\platform.dll "D:\Xash3D\bin\platform.dll"
]
Creating command line "C:\Temp\RSPF6F.bat"
Compiling...
qccmain.c
Linking...
Creating library ..\temp\platform\!release/platform.lib and object ..\temp\platform\!release/platform.exp
<h3>Output Window</h3>
Performing Custom Build Step on \XASH3D\src_main\!source\temp\platform\!release\platform.dll
‘ª®¯¨à®¢ ­® ä ©«®¢: 1.
<h3>Results</h3>
platform.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -7063,6 +7063,7 @@ def_t *PR_GetDef (type_t *type, char *name, def_t *scope, bool allocate, int arr
{
def->nextlocal = pr.localvars;
pr.localvars = def;
def->local = true;
}
return def;

View File

@ -2197,10 +2197,8 @@ void PR_Warning (int type, char *file, int line, char *error, ...)
va_end (argptr);
PR_PrintScope();
if (file)
Msg ("%s:%i: warning: %s\n", file, line, string);
else
Msg ("warning: %s\n", string);
if (file) Msg ("%s(%i) : warning C%i: %s\n", file, line, type, string);
else Msg ("warning C%i: %s\n", type, string);
pr_warning_count++;
}

View File

@ -207,14 +207,15 @@ typedef struct def_s
type_t *type;
char *name;
struct def_s *next;
struct def_s *nextlocal; //provides a chain of local variables
gofs_t ofs; //for the opt_locals_marshalling optimisation.
struct def_s *nextlocal; // provides a chain of local variables
gofs_t ofs; // for the opt_locals_marshalling optimisation.
struct def_s *scope; // function the var was defined in, or NULL
int initialized; // 1 when a declaration included "= immediate"
int constant; // 1 says we can use the value over and over again
bool local; // 1 indices local variable
int references;
int timescalled; //part of the opt_stripfunctions optimisation.
int timescalled; // part of the opt_stripfunctions optimisation.
int s_file;
int s_line;
@ -390,6 +391,7 @@ typedef enum {
ERR_INVALIDSTRINGIMMEDIATE,
ERR_BADCHARACTURECODE,
ERR_BADPARMS,
ERR_EXCEEDERRCOUNT,
WARN_MAX,
};

View File

@ -11,7 +11,8 @@ extern int optres_test1;
extern int optres_test2;
int writeasm;
int level;
cachedsourcefile_t *sourcefile;
bool PR_SimpleGetToken (void);
void PR_LexWhitespace (void);
@ -553,14 +554,14 @@ void PR_WriteData (int crc)
}
//compression of blocks?
if (compressoutput) progs.blockscompressed |=1; //statements
if (compressoutput) progs.blockscompressed |=2; //defs
if (compressoutput) progs.blockscompressed |=4; //fields
if (compressoutput) progs.blockscompressed |=8; //functions
if (compressoutput) progs.blockscompressed |=16; //strings
if (compressoutput) progs.blockscompressed |=32; //globals
if (compressoutput) progs.blockscompressed |=64; //line numbers
if (compressoutput) progs.blockscompressed |=128; //types
if (compressoutput) progs.blockscompressed |=1; //statements
if (compressoutput) progs.blockscompressed |=2; //defs
if (compressoutput) progs.blockscompressed |=4; //fields
if (compressoutput) progs.blockscompressed |=8; //functions
if (compressoutput) progs.blockscompressed |=16; //strings
if (compressoutput) progs.blockscompressed |=32; //globals
if (compressoutput) progs.blockscompressed |=64; //line numbers
if (compressoutput) progs.blockscompressed |=128; //types
//include a type block?
types = debugtarget;//!!PR_CheckCompConstDefined("TYPES"); //useful for debugging and saving (maybe, anyway...).
@ -621,9 +622,7 @@ void PR_WriteData (int crc)
}
if (def->references <= 0)
{
if (def->constant) PR_Warning(WARN_NOTREFERENCEDCONST, strings + def->s_file, def->s_line, "%s no references", def->name);
else PR_Warning(WARN_NOTREFERENCED, strings + def->s_file, def->s_line, "%s no references", def->name);
if(def->local) PR_Warning(WARN_NOTREFERENCED, strings + def->s_file, def->s_line, "'%s' : unreferenced local variable", def->name);
if (opt_unreferenced && def->type->type != ev_field)
{
optres_unreferenced++;
@ -2060,7 +2059,6 @@ void PR_FinishCompile(void);
void PR_SetDefaultProperties (void)
{
extern int ForcedCRC;
int level;
int i;
Hash_InitTable(&compconstantstable, MAX_CONSTANTS, Qalloc(BytesForBuckets(MAX_CONSTANTS)));
@ -2279,13 +2277,10 @@ void PR_main ( void ) //as part of the quake engine
}
else *qccmsourcedir = '\0';
//autoprototype = true;
PR_InitData ();
PR_BeginCompilation (Qalloc (0x100000), 0x100000);
sprintf (qccmprogsdat, "%sprogs.src", qccmsourcedir);
Msg ("Source file: %s\n", qccmprogsdat);
qccmsrc = QCC_LoadFile (qccmprogsdat);
if (writeasm)
@ -2299,7 +2294,10 @@ void PR_main ( void ) //as part of the quake engine
pr_file_p = SC_ParseToken(&qccmsrc);
strcpy (destfile, token);
Msg ("outputfile: %s\n", destfile);
FS_StripExtension( token );
// msvc6.0 style message
Msg("--------------------Configuration: %s - Vm16 %s--------------------\n", token, level <= 0 ? "Debug" : "Release" );
pr_dumpasm = false;
currentchunk = NULL;
@ -2322,6 +2320,7 @@ void PR_ContinueCompile(void)
qccmsrc = originalqccmsrc;
PR_SetDefaultProperties();
autoprototype = false;
Msg("Compiling...\n");
return;
}
PR_FinishCompile();
@ -2356,13 +2355,12 @@ void PR_ContinueCompile(void)
break;
}
strcat (qccmfilename, s);
if (autoprototype) Msg ("prototyping %s\n", qccmfilename);
else Msg ("compiling %s\n", qccmfilename);
Msg ("%s\n", qccmfilename);
qccmsrc2 = QCC_LoadFile (qccmfilename);
if(!PR_CompileFile (qccmsrc2, qccmfilename))
{
Msg("Compile errors limit exceeded %i, stop compilation\n", MAX_ERRORS);
Msg("error count exceeds %i; stopping compilation\n", MAX_ERRORS);
Sys_Error("%s - %i error(s), %i warning(s)\n", destfile, pr_error_count, pr_warning_count);
}
}
@ -2384,8 +2382,6 @@ void PR_FinishCompile(void)
// report / copy the data files
PR_CopyFiles ();
Msg ("Compile Complete\n\n");
if (optres_shortenifnots) Msg("optres_shortenifnots %i\n", optres_shortenifnots);
if (optres_overlaptemps) Msg("optres_overlaptemps %i\n", optres_overlaptemps);
if (optres_noduplicatestrings) Msg("optres_noduplicatestrings %i\n", optres_noduplicatestrings);
@ -2411,7 +2407,7 @@ void PR_FinishCompile(void)
if (optres_test1) Msg("optres_test1 %i\n", optres_test1);
if (optres_test2) Msg("optres_test2 %i\n", optres_test2);
Msg("numtemps %i\n", numtemps);
Msg ("‘ª®¯¨à®¢ ­® ä ©«®¢: 1.\n\n");// enigma from M$ :)
Msg("%s - %i error(s), %i warning(s)\n", destfile, pr_error_count, pr_warning_count);
qcc_compileactive = false;
@ -2431,6 +2427,8 @@ bool CompileDATProgs ( void )
{
PR_main();
if (autoprototype) Msg ("Prototyping...\n");
else Msg("Compiling...\n");
while(qcc_compileactive)
PR_ContinueCompile();

View File

@ -13,6 +13,7 @@
#define SIDE_ON 2
#define EQUAL_EPSILON 0.001
#define STOP_EPSILON 0.1
#define DEG2RAD( a ) ( a * M_PI ) / 180.0F
#ifndef M_PI
@ -34,6 +35,12 @@ _inline void VectorScale(const vec3_t a, const float b, vec3_t c){c[0]=b*a[0];c[
#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 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 void VectorBound(const float min, vec3_t v, const float max)
{
v[0] = bound(min, v[0], max);
@ -79,6 +86,16 @@ _inline bool VectorCompare (const vec3_t v1, const vec3_t v2)
return true;
}
_inline bool VectorICompare (const short* v1, const short* v2)
{
int i;
for (i = 0; i < 3; i++ )
if (abs(v1[i] - v2[i]) > 0)
return false;
return true;
}
_inline vec_t VectorNormalize (vec3_t v)
{
float length, ilength;
@ -160,7 +177,7 @@ _inline void VectorVectors(vec3_t forward, vec3_t right, vec3_t up)
CrossProduct(right, forward, up);
}
_inline void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
_inline void AngleVectorsRight(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
{
float angle;
static float sr, sp, sy, cr, cp, cy;
@ -182,17 +199,98 @@ _inline void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t u
forward[1] = cp*sy;
forward[2] = -sp;
}
if (right)
if (right || up)
{
right[0] = (-1*sr*sp*cy+-1*cr*-sy);
right[1] = (-1*sr*sp*sy+-1*cr*cy);
right[2] = -1*sr*cp;
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;
}
}
}
if (up)
}
_inline void AngleVectorsLeft(const vec3_t angles, vec3_t forward, vec3_t left, vec3_t up)
{
float angle;
static float sr, sp, sy, cr, cp, cy;
// static to help MS compiler fp bugs
angle = angles[YAW] * (M_PI*2 / 360);
sy = sin(angle);
cy = cos(angle);
angle = angles[PITCH] * (M_PI*2 / 360);
sp = sin(angle);
cp = cos(angle);
if (forward)
{
up[0] = (cr*sp*cy+-sr*-sy);
up[1] = (cr*sp*sy+-sr*cy);
up[2] = cr*cp;
forward[0] = cp*cy;
forward[1] = cp*sy;
forward[2] = -sp;
}
if (left || up)
{
if (angles[ROLL])
{
angle = angles[ROLL] * (M_PI*2 / 360);
sr = sin(angle);
cr = cos(angle);
if (left)
{
left[0] = sr*sp*cy+cr*-sy;
left[1] = sr*sp*sy+cr*cy;
left[2] = sr*cp;
}
if (up)
{
up[0] = cr*sp*cy+-sr*-sy;
up[1] = cr*sp*sy+-sr*cy;
up[2] = cr*cp;
}
}
else
{
if (left)
{
left[0] = -sy;
left[1] = cy;
left[2] = 0;
}
if (up)
{
up[0] = sp*cy;
up[1] = sp*sy;
up[2] = cp;
}
}
}
}

View File

@ -41,12 +41,10 @@ typedef unsigned int uint;
typedef signed __int64 int64;
typedef struct file_s file_t;
typedef struct vfile_s vfile_t;
typedef struct edict_s edict_t;
typedef int func_t;
typedef struct image_s image_t;
typedef struct model_s model_t;
typedef int func_t;
typedef int string_t;
typedef struct gclient_s gclient_t;
typedef int progsnum_t;
typedef struct progfuncs_s progfuncs_t;
typedef float vec_t;
@ -54,6 +52,7 @@ typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
typedef long fs_offset_t;
typedef vec_t matrix3x4[3][4];
typedef struct prvm_edict_s prvm_edict_t;
typedef struct { int fileofs; int filelen; }lump_t;
typedef struct { byte r; byte g; byte b; } color24;
typedef struct { uint b:5; uint g:6; uint r:5; } color16;

View File

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

View File

@ -79,10 +79,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PRINT_HIGH 2 // critical messages
#define PRINT_CHAT 3 // chat messages
#define SPAWNFLAG_NOT_EASY 0x00000100
#define SPAWNFLAG_NOT_MEDIUM 0x00000200
#define SPAWNFLAG_NOT_HARD 0x00000400
#define SPAWNFLAG_NOT_DEATHMATCH 0x00000800
#define SPAWNFLAG_NOT_EASY 256
#define SPAWNFLAG_NOT_MEDIUM 512
#define SPAWNFLAG_NOT_HARD 1024
#define SPAWNFLAG_NOT_DEATHMATCH 2048
// entity_state_t->renderfx flags
#define RF_MINLIGHT 1 // allways have some light (viewmodel)
@ -148,23 +148,29 @@ typedef enum
WEAPON_FIRING
} weaponstate_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
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;
/*
==============================================================
@ -233,7 +239,7 @@ SYSTEM SPECIFIC
==============================================================
*/
extern int curtime; // time returned by last Sys_Milliseconds
extern double curtime;
void Sys_Error (char *error, ...);
void Com_Printf (char *msg, ...);
@ -267,14 +273,16 @@ 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
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
bool startstuck; // if true, the initial point was stuck into SOLID_BSP model
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
struct edict_s *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
prvm_edict_t *ent; // not set by CM_*() functions
} trace_t;
@ -316,7 +324,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;
@ -342,6 +350,7 @@ typedef struct usercmd_s
short forwardmove, sidemove, upmove;
byte impulse; // remove?
byte lightlevel; // light level the player is standing on
} usercmd_t;
@ -357,14 +366,14 @@ typedef struct
// results (out)
int numtouch;
struct edict_s *touchents[MAXTOUCH];
prvm_edict_t *touchents[MAXTOUCH];
vec3_t viewangles; // clamped
float viewheight;
vec3_t mins, maxs; // bounding box size
struct edict_s *groundentity;
prvm_edict_t *groundentity;
int watertype;
int waterlevel;
@ -807,16 +816,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; // stuido animation sequence
int sequence; // studio animation sequence
int gunbody;
int gunskin;

View File

@ -286,7 +286,7 @@ typedef struct
float vieworg[3];
float viewangles[3];
float blend[4]; // rgba 0-1 full screen blend
float time; // time is used to auto animate
double 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
@ -439,51 +439,6 @@ typedef struct scriptsystem_api_s
/*
==============================================================================
NETWORK MESSAGES INTERFACE
==============================================================================
*/
typedef struct message_write_s
{
//interface validator
size_t api_size; // must matched with sizeof(message_write_t)
void (*Begin)( int dest ); // marker of start message
void (*WriteChar) (int c);
void (*WriteByte) (int c);
void (*WriteWord) (int c);
void (*WriteShort) (int c);
void (*WriteLong) (int c);
void (*WriteFloat) (float f);
void (*WriteString) (char *s);
void (*WriteCoord) (vec3_t pos); // some fractional bits
void (*WriteDir) (vec3_t pos); // single byte encoded, very coarse
void (*WriteAngle) (float f);
void (*Send)( msgtype_t type, vec3_t origin, edict_t *ent );// end of message
} message_write_t;
typedef struct message_read_s
{
//interface validator
size_t api_size; // must matched with sizeof(message_read_t)
void (*Begin)( void ); // begin reading
int (*ReadChar) ( void );
int (*ReadByte) ( void );
int (*ReadLong) ( void );
int (*ReadShort) ( void );
float *(*ReadDir) ( void ); // return value from anorms.h
float (*ReadFloat) ( void );
float (*ReadAngle) ( void );
void *(*ReadData) (int len );
float *(*ReadCoord) ( void ); // x, y, z coords
char *(*ReadString) ( bool line ); // get line once only
void (*End)( void ); // message received
} message_read_t;
/*
==============================================================================
INTERNAL COMPILERS INTERFACE
==============================================================================
*/
@ -623,7 +578,7 @@ typedef struct renderer_exp_s
void (*DrawGetPicSize) (int *w, int *h, char *name); // will return 0 0 if not found
void (*DrawPic) (int x, int y, char *name);
void (*DrawStretchPic) (int x, int y, int w, int h, char *name);
void (*DrawChar) (int x, int y, int c);
void (*DrawChar) (float x, float y, int c);
void (*DrawString) (int x, int y, char *str);
void (*DrawTileClear) (int x, int y, int w, int h, char *name);
void (*DrawFill) (int x, int y, int w, int h, int c);

View File

@ -41,6 +41,7 @@ a internal virtual machine like as QuakeC, but it has more extensions
#define MAX_PARMS 8
// 16-bit mode
#define dstatement_t dstatement16_t
#define ddef_t ddef16_t //these should be the same except the string type
@ -320,14 +321,14 @@ enum {
typedef struct statement16_s
{
word op;
word a,b,c;
short a,b,c;
} dstatement16_t;
typedef struct statement32_s
{
dword op;
dword a,b,c;
long a,b,c;
} dstatement32_t;

View File

@ -24,7 +24,8 @@ if errorlevel 1 set BUILD_ERROR=1
%MSDEV% renderer/renderer.dsp %CONFIG%"renderer - Win32 Release" %build_target%
if errorlevel 1 set BUILD_ERROR=1
%MSDEV% server/server.dsp %CONFIG%"server - Win32 Release" %build_target%
resource\qcclib.exe -O3
if errorlevel 0 copy resource\server.dat D:\Xash3D\xash\server.dat
if errorlevel 1 set BUILD_ERROR=1
if "%BUILD_ERROR%"=="" goto build_ok

View File

@ -60,18 +60,16 @@ void Draw_String (int x, int y, char *str)
}
}
void Draw_Char (int x, int y, int num)
void Draw_Char (float x, float y, int num)
{
int row, col;
float frow, fcol, size;
int row, col;
float frow, fcol, size;
num &= 255;
if ( (num&127) == 32 )
return; // space
if ( (num & 127) == 32 ) return;// space
if (y <= -8)
return; // totally off screen
if (y <= -8) return; // totally off screen
row = num>>4;
col = num&15;

View File

@ -414,7 +414,7 @@ void COM_FileBase (char *in, char *out);
void Draw_GetPicSize (int *w, int *h, char *name);
void Draw_Pic (int x, int y, char *name);
void Draw_StretchPic (int x, int y, int w, int h, char *name);
void Draw_Char (int x, int y, int c);
void Draw_Char (float x, float y, int c);
void Draw_String (int x, int y, char *str);
void Draw_TileClear (int x, int y, int w, int h, char *name);
void Draw_Fill (int x, int y, int w, int h, int c);

View File

@ -125,7 +125,7 @@ void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
// move should be the delta back to the previous frame * backlerp
VectorSubtract (currententity->oldorigin, currententity->origin, delta);
AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]);
AngleVectorsRight(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];
AngleVectors( angles, vectors[0], vectors[1], vectors[2] );
AngleVectorsRight( angles, vectors[0], vectors[1], vectors[2] );
for ( i = 0; i < 8; i++ )
{
@ -604,12 +604,13 @@ void R_DrawAliasModel ( int passnum )
}
if ( currententity->flags & RF_GLOW )
{ // bonus items will pulse with time
{
// bonus items will pulse with time
float scale;
float min;
scale = 0.1 * sin(r_newrefdef.time*7);
for (i=0 ; i<3 ; i++)
scale = 0.1 * sin(r_newrefdef.time * 0.7);
for (i = 0; i < 3; i++)
{
min = shadelight[i] * 0.8;
shadelight[i] += scale;

View File

@ -499,7 +499,7 @@ void R_SetupFrame (void)
// build the transformation matrix for the given view angles
VectorCopy (r_newrefdef.vieworg, r_origin);
AngleVectors (r_newrefdef.viewangles, vforward, vright, vup);
AngleVectorsRight(r_newrefdef.viewangles, vforward, vright, vup);
// current viewcluster
if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
@ -1511,7 +1511,7 @@ void R_RenderFrame (refdef_t *fd);
image_t *Draw_FindPic (char *name);
void Draw_Pic (int x, int y, char *name);
void Draw_Char (int x, int y, int c);
void Draw_Char (float x, float y, int c);
void Draw_TileClear (int x, int y, int w, int h, char *name);
void Draw_Fill (int x, int y, int w, int h, int c);
void Draw_FadeScreen (void);

View File

@ -117,10 +117,10 @@ glpoly_t *WaterWarpPolyVerts (glpoly_t *p)
out->numverts = p->numverts;
v = p->verts[0];
nv = out->verts[0];
for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE, nv+=VERTEXSIZE)
for (i = 0; i < p->numverts; i++, v+= VERTEXSIZE, nv+=VERTEXSIZE)
{
nv[0] = v[0] + 4*sin(v[1]*0.05+r_newrefdef.time)*sin(v[2]*0.05+r_newrefdef.time);
nv[1] = v[1] + 4*sin(v[0]*0.05+r_newrefdef.time)*sin(v[2]*0.05+r_newrefdef.time);
nv[0] = v[0] + 4*sin(v[1] * 0.05 + r_newrefdef.time) * sin(v[2] * 0.05 + r_newrefdef.time);
nv[1] = v[1] + 4*sin(v[0] * 0.05 + r_newrefdef.time) * sin(v[2] * 0.05 + r_newrefdef.time);
nv[2] = v[2];
nv[3] = v[3];
@ -207,13 +207,12 @@ void DrawGLFlowingPoly (msurface_t *fa)
p = fa->polys;
scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
if(scroll == 0.0)
scroll = -64.0;
scroll = -64 * ((r_newrefdef.time * 0.4) - (int)(r_newrefdef.time * 0.4) );
if(scroll == 0.0) scroll = -64.0;
qglBegin (GL_POLYGON);
v = p->verts[0];
for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
for (i = 0; i < p->numverts; i++, v+= VERTEXSIZE)
{
qglTexCoord2f ((v[3] + scroll), v[4]);
qglVertex3fv (v);
@ -762,9 +761,8 @@ dynamic:
{
float scroll;
scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
if(scroll == 0.0)
scroll = -64.0;
scroll = -64 * ( (r_newrefdef.time * 0.4) - (int)(r_newrefdef.time * 0.4) );
if(scroll == 0.0) scroll = -64.0;
for ( p = surf->polys; p; p = p->chain )
{
@ -810,7 +808,7 @@ dynamic:
{
float scroll;
scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
scroll = -64 * ((r_newrefdef.time * 0.4) - (int)(r_newrefdef.time * 0.4));
if(scroll == 0.0)
scroll = -64.0;
@ -978,7 +976,7 @@ void R_DrawBrushModel ( int passnum )
vec3_t forward, right, up;
VectorCopy (modelorg, temp);
AngleVectors (e->angles, forward, right, up);
AngleVectorsRight(e->angles, forward, right, up);
modelorg[0] = DotProduct (temp, forward);
modelorg[1] = -DotProduct (temp, right);
modelorg[2] = DotProduct (temp, up);
@ -1193,7 +1191,7 @@ void R_DrawWorld (void)
// auto cycle the world frame for texture animation
memset (&ent, 0, sizeof(ent));
ent.frame = (int)(r_newrefdef.time*2);
ent.frame = (int)(r_newrefdef.time * 0.5);
currententity = &ent;
gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;

View File

@ -213,13 +213,12 @@ void EmitWaterPolys (msurface_t *fa)
int i;
float s, t, os, ot;
float scroll;
float rdt = r_newrefdef.time;
if (fa->texinfo->flags & SURF_FLOWING)
scroll = -64 * ( (r_newrefdef.time*0.5) - (int)(r_newrefdef.time*0.5) );
scroll = -64 * ( (r_newrefdef.time * 0.5) - (int)(r_newrefdef.time * 0.5));
else
scroll = 0;
for (bp=fa->polys ; bp ; bp=bp->next)
for (bp = fa->polys; bp; bp = bp->next)
{
p = bp;
@ -229,11 +228,11 @@ void EmitWaterPolys (msurface_t *fa)
os = v[3];
ot = v[4];
s = os + r_turbsin[(int)((ot*0.125+r_newrefdef.time) * TURBSCALE) & 255];
s = os + r_turbsin[(int)((ot * 0.125 + r_newrefdef.time) * TURBSCALE) & 255];
s += scroll;
s *= (1.0/64);
t = ot + r_turbsin[(int)((os*0.125+rdt) * TURBSCALE) & 255];
t = ot + r_turbsin[(int)((os * 0.125 + r_newrefdef.time) * TURBSCALE) & 255];
t *= (1.0/64);
qglTexCoord2f (s, t);

View File

@ -244,13 +244,13 @@ mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
void R_DrawSpriteModel( int passnum )
{
float alpha = 1.0F;
float alpha= 1.0F;
mspriteframe_t *frame;
vec3_t point, forward, right, up;
msprite_t *psprite;
entity_t *e = currententity;
model_t *mod = currentmodel;
float realtime = r_newrefdef.time / 1000.000f;
float realtime = r_newrefdef.time;
if ( (e->flags & RF_TRANSLUCENT) && (passnum == RENDERPASS_SOLID)) return;// solid
if (!(e->flags & RF_TRANSLUCENT) && (passnum == RENDERPASS_ALPHA)) return;// solid
@ -281,7 +281,7 @@ void R_DrawSpriteModel( int passnum )
switch( psprite->type )
{
case SPR_ORIENTED:
AngleVectors (e->angles, forward, right, up);
AngleVectorsRight(e->angles, forward, right, up);
VectorScale(forward, 0.01, forward );//offset for decals
VectorSubtract(e->origin, forward, e->origin );
break;

View File

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

16
renderer/renderer.plg Normal file
View File

@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: renderer - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
renderer.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

49
resource/PROGS.SRC Normal file
View File

@ -0,0 +1,49 @@
// +-----+
// |Progs|
// +-----+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
// | Scratch Http://www.admdev.com/scratch |
// +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-+
// | This file contains all a list of QuakeC files to compile into the final |
// | output file (progs.dat by default) |
// +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-+
server.dat // Output File
defs.c // Definitions
main.c // Main subroutines
damage.c
player.c
client.c // Client subroutines
dummys.c // Null spawn functions
ents/internal.c // Entity Management
ents/lights.c // Light Entities
ents/ambient.c // Ambient Sounds
ents/ccam.c // Chasecam Effect
//TRIGGERS
ents/triggers/triggers.c // Ambient Sounds
ents/triggers/trigger_generic.c
ents/triggers/trigger_once.c
ents/triggers/trigger_sequence.c
ents/triggers/trigger_message.c
ents/triggers/trigger_counter.c
ents/triggers/trigger_setviewpoint.c
ents/triggers/trigger_teleport.c
ents/triggers/trigger_hurt.c
ents/triggers/trigger_push.c
ents/triggers/trigger_changelevel.c
ents/triggers/trigger_setskill.c
ents/triggers/trigger_secret.c
//FUNCS
ents/funcs/funcs.c
ents/funcs/func_mover.c
ents/funcs/func_door.c
ents/funcs/func_button.c
ents/funcs/func_path_corner.c
ents/funcs/func_train.c
//ITEMS
ents/items/items.c
impulses.c // Should ALWAYS remain at bottom.

291
resource/client.c Normal file
View File

@ -0,0 +1,291 @@
/*
+------+
|Client|
+------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Scratch Http://www.admdev.com/scratch |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Handle's "clients" (eg, Players) connecting, disconnecting, etc. |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
*/
//DEFS;
void() CCamChasePlayer; // From Ccam.qc
void() CheckImpulses; // From Impulses.QC
void() PutClientInServer; //From Client.QC
//END DEFS;
/*
+=========+
|PPRINT():|
+=========+==============================================================================+
|Description: |
|This function prints a server wide(bprint) 'entity' 'did' 'what" message... v useful for all those|
|client joining, leaving msgs etc.. saves a fair amount of code i hope.. [8 lines i think..] |
+========================================================================================+
*/
void(entity dude, string did, string what)pprint =
{
bprint("\n");
bprint(dude.netname);
bprint(did);
bprint(what);
bprint("\n");
};
/*
CLIENTRESPAWN();
*/
void() ClientRespawn =
{
if (coop)
{
// get the spawn parms as they were at level start
GetLevelParms();
// respawn
PutClientInServer();
}
else if (deathmatch)
{
// set default spawn parms
SetNewParms();
// respawn
PutClientInServer();
}
else
{ // restart the entire server
localcmd ("restart\n");
}
};
/*
CLIENTOBITURARY()
Description;
Describes the entity 'who_died' in relation to enitity 'who_killed'.
Called when a player gets 'killed' by KILLED(); [DAMAGE.QC]
*/
void(entity who_died, entity who_killed) ClientObiturary =
{
local string deathstring;
local string who;
local float rnum, msgdt, fragnum;
rnum = random();
if(who_died.flags & FL_CLIENT)
{
if(who_killed == world)
{
deathstring = "was killed";
if(who_died.watertype == CONTENT_WATER)
deathstring = " drowned";
else if(who_died.watertype == CONTENT_SLIME)
deathstring = " melted";
else if(who_died.watertype == CONTENT_LAVA)
deathstring = " got incinerated";
msgdt = TRUE;
}
if(who_killed.classname == "door")
{
if(rnum < 0.25)
{
deathstring = " got crushed";
}
else
deathstring = " angered the ";
}
if(who_killed.classname == "button")
{
if(rnum < 0.25)
{
deathstring = " pushed it the wrong way";
msgdt = TRUE;
}
else
deathstring = " angered the ";
}
if(who_killed.classname == "train")
{
deathstring = " jumped infront the ";
}
if(who_killed.classname == "teledeath")
{
deathstring = " was telefragged by ";
}
if(who_killed.classname == "t_hurt")
{
deathstring = " got hurt too much...";
}
if(who_killed.classname == "t_push")
{
deathstring = " got pushed too far...";
}
if(who_killed == who_died)
{
deathstring = " killed themselves...";
msgdt = TRUE;
}
bprint(who_died.netname);
bprint(deathstring);
if(msgdt != TRUE)
{
if(who_killed.flags & FL_CLIENT)
bprint(who_killed.netname);
else
bprint(who_killed.classname);
}
bprint("\n");
}
};
/*
===============
|CLIENTKILL():|
=================================================================================
Description:
This function is called when the player enters the 'kill' command in the console.
=================================================================================
*/
void() ClientKill =
{
//pprint(self, " has", " killed themselves.");
T_Damage(self, self, self, self.health);
ClientRespawn();
};
/*
==================
|CLIENTCONNECT():|
=================================================================================
Description:
This function is called when the player connects to the server.
=================================================================================
*/
void() ClientConnect =
{
pprint(self, " has", " joined the game.");
configstring (2, "sky"); //CS_SKY
configstring (30, "4" ); //CS_MAXCLIENTS
};
/*
==================
|CLIENTDISCONNECT():|
=================================================================================
Description:
This function is called when the player disconnects from the server.
=================================================================================
*/
void() ClientDisconnect =
{
pprint(self, " has", " left the game.");
};
/*
====================
|PLAYERPRETHINK():|
===========================================================
Description:
This function is called every frame *BEFORE* world physics.
===========================================================
*/
void() PlayerPreThink =
{
WaterMove ();
SetClientFrame ();
CheckImpulses();
};
/*
====================
|PLAYERPOSTTHINK():|
===========================================================
Description:
This function is called every frame *AFTER* world physics.
===========================================================
*/
void() PlayerPostThink = {};
/*
======================
|PUTCLIENTINSERVER():|
===========================================================
Description:
This function is called whenever a client enters the world.
It sets up the player entity.
===========================================================
*/
entity() find_spawnspot =
{
local entity spot;
local string a;
if(deathmatch == 1)
a = "info_player_deathmatch";
else if(coop == 1)
a = "info_player_coop";
else if(!deathmatch || !coop)
a = "info_player_start";
spot = find (world, classname, a);
return spot;
};
void() PutClientInServer =
{
local entity spawn_spot; // This holds where we want to spawn
spawn_spot = find_spawnspot(); //find (world, classname, "info_player_start"); // Find it :)
self.classname = "player"; // I'm a player!
self.health = self.max_health = 100; // My health (and my max) is 100
self.takedamage = DAMAGE_AIM; // I can be fired at
self.solid = SOLID_SLIDEBOX; // Things sort of 'slide' past me
self.movetype = MOVETYPE_WALK; // Yep, I want to walk.
self.flags = FL_CLIENT; // Yes, I'm a client.
self.origin = spawn_spot.origin + '0 0 1'; // Move to the spawnspot location
self.angles = spawn_spot.angles; // Face the angle the spawnspot indicates
self.fixangle = TRUE; // Turn this way immediately
setmodel (self, "progs/player.mdl"); // Set my player to the player model
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX); // Set my size
self.view_ofs = '0 0 22'; // Center my view
if (self.aflag)
CCamChasePlayer ();
self.velocity = '0 0 0'; // Stop any old movement
self.th_pain = PlayerPain;
self.th_die = PlayerDie;
GetLevelParms();
};

163
resource/damage.c Normal file
View File

@ -0,0 +1,163 @@
/*
+------+
|Damage|
+------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Scratch http://www.inside3d.com/qctut/scratch.shtml |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| T_Damage and other like functions |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
*/
//DEFS
void(entity who_died, entity who_killed) ClientObiturary;
//END DEFS
/*
=-=-=-=-=
Killed
=-=-=-=-=
*/
void(entity targ, entity attacker) Killed =
{
local entity oself;
if (targ.health < -99)
targ.health = -99; // don't let sbar look bad if a player
targ.takedamage = DAMAGE_NO;
targ.touch = SUB_Null;
oself = self;
self = targ; // self must be targ for th_die
self.th_die ();
self = oself;
ClientObiturary(targ, attacker);
};
/*
+=======+
|T_Heal|
+=======+
|Heal entity e for healamount possibly ignoring max health.|
+======================================================+
*/
void(entity e, float healamount, float ignore) T_Heal =
{
if (e.health <= 0)
return;
if ((!ignore) && (e.health >= other.max_health))
return;
healamount = ceil(healamount);
e.health = e.health + healamount;
if ((!ignore) && (e.health >= other.max_health))
e.health = other.max_health;
};
/*
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
T_Damage
The damage is coming from inflictor, but get mad at attacker
This should be the only function that ever reduces health.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
*/
void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
{
local vector dir;
local entity oldself;
if (!targ.takedamage)
return;
// used by buttons and triggers to set activator for target firing
damage_attacker = attacker;
// figure momentum add
if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
{
dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
dir = normalize(dir);
targ.velocity = targ.velocity + dir*damage*8;
}
// check for godmode
if (targ.flags & FL_GODMODE)
return;
// add to the damage total for clients, which will be sent as a single
// message at the end of the frame
if (targ.flags & FL_CLIENT)
{
targ.dmg_take = targ.dmg_take + damage;
targ.dmg_save = targ.dmg_save + damage;
targ.dmg_inflictor = inflictor;
}
// team play damage avoidance
if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) )
return;
// do the damage
targ.health = targ.health - damage;
if (targ.health <= 0)
{
Killed (targ, attacker);
return;
}
// react to the damage
oldself = self;
self = targ;
if (self.th_pain)
self.th_pain (attacker, damage);
self = oldself;
};
/*
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
WaterMove
Can be used for clients or monsters
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
*/
void() WaterMove =
{
if (self.movetype == MOVETYPE_NOCLIP)
return;
if (self.health < 0)
return;
if (self.waterlevel != 3)
{
self.air_finished = time + 12;
self.dmg = 2;
}
else if (self.air_finished < time && self.pain_finished < time)
{ // drown!
self.dmg = self.dmg + 2;
if (self.dmg > 15)
self.dmg = 10;
T_Damage (self, world, world, self.dmg);
self.pain_finished = time + 1;
}
if (self.watertype == CONTENT_LAVA && self.dmgtime < time)
{ // do damage
self.dmgtime = time + 0.2;
T_Damage (self, world, world, 6*self.waterlevel);
}
else if (self.watertype == CONTENT_SLIME && self.dmgtime < time)
{ // do damage
self.dmgtime = time + 1;
T_Damage (self, world, world, 4*self.waterlevel);
}
};

414
resource/defs.c Normal file
View File

@ -0,0 +1,414 @@
/*
+----+
|Defs|
+----+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Scratch Http://www.admdev.com/scratch |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| This contains necessary definitions from the original V1.06 defs.qc file. |
| This includes some basic constants, the built in function definitions, and |
| some variable's used by the Quake Engine internally. |
| Certain lines in this file are hardcoded into Quake engine, and -must- be |
| present and unchanged, in the order they are shown. Otherwise Quake will |
| refuse to run. |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
*/
// These lines CANNOT be altered/moved
entity self;
entity other;
entity world;
float time;
float frametime;
float force_retouch; // force all entities to touch triggers
string mapname;
float deathmatch;
float coop;
float teamplay;
float serverflags; // propagated from level to level, used to
float total_secrets;
float total_monsters;
float found_secrets; // number of secrets found
float killed_monsters; // number of monsters killed
float parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8, parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16;
vector v_forward, v_up, v_right; // set by makevectors()
float trace_allsolid;
float trace_startsolid;
float trace_fraction;
vector trace_endpos;
vector trace_plane_normal;
float trace_plane_dist;
entity trace_ent;
float trace_inopen;
float trace_inwater;
entity msg_entity; // destination of single entity writes
void() main; // only for testing
void() StartFrame;
void() EndFrame;
void() PlayerPreThink;
void() PlayerPostThink;
void() ClientKill;
void() ClientConnect;
void() PutClientInServer; // call after setting the parm1... parms
void() ClientDisconnect;
void() SetNewParms; // called when a client first connects to
void() SetChangeParms; // call to set parms for self so they can
void end_sys_globals; // flag for structure dumping
.float modelindex; // *** model index in the precached list
.vector absmin, absmax; // *** origin + mins / maxs
.float ltime; // local time for entity
.float movetype;
.float solid;
.vector origin; // ***
.vector oldorigin; // ***
.vector velocity;
.vector angles;
.vector avelocity;
.vector punchangle; // temp angle adjust from damage or recoil
.string classname; // spawn function
.string model;
.float frame;
.float skin;
.float body;
.float effects;
.float sequence;
.float renderfx;
.vector mins, maxs; // bounding box extents reletive to origin
.vector size; // maxs - mins
.void() touch;
.void() use;
.void() think;
.void() blocked; // for doors or plats, called when can't push other
.float nextthink;
.entity groundentity;
.float health;
.float frags;
.float weapon; // one of the IT_SHOTGUN, etc flags
.string weaponmodel;
.float weaponframe;
.float currentammo;
.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
.float items; // bit flags
.float takedamage;
.entity chain;
.float deadflag;
.vector view_ofs; // add to origin to get eye point
.float button0; // fire
.float button1; // use
.float button2; // jump
.float impulse; // weapon changes
.float fixangle;
.vector v_angle; // view / targeting angle for players
.float idealpitch; // calculated pitch angle for lookup up slopes
.string netname;
.entity enemy;
.float flags;
.float colormap;
.float team;
.float max_health; // players maximum health is stored here
.float teleport_time; // don't back up
.float armortype; // save this fraction of incoming damage
.float armorvalue;
.float waterlevel; // 0 = not in, 1 = feet, 2 = wast, 3 = eyes
.float watertype; // a contents value
.float ideal_yaw;
.float yaw_speed;
.entity aiment;
.entity goalentity; // a movetarget or an enemy
.float spawnflags;
.string target;
.string targetname;
.float dmg_take;
.float dmg_save;
.entity dmg_inflictor;
.entity owner; // who launched a missile
.vector movedir; // mostly for doors, but also used for waterjump
.string message; // trigger messages
.float sounds; // either a cd track number or sound number
.string noise, noise1, noise2, noise3; // contains names of wavs to play
void end_sys_fields; // flag for structure dumping
// End. Lines below this MAY be altered, to some extent
// Built In functions
void(vector ang) makevectors = #1; // sets v_forward, etc globals
void(entity e, vector o) setorigin = #2;
void(entity e, string m) setmodel = #3; // set movetype and solid first
void(entity e, vector min, vector max) setsize = #4;
void() break = #6;
float() random = #7; // returns 0 - 1
void(entity e, float chan, string samp, float vol, float atten) sound = #8;
vector(vector v) normalize = #9;
void(string e) error = #10;
void(string e) objerror = #11;
float(vector v) vlen = #12;
float(vector v) vectoyaw = #13;
entity() spawn = #14;
void(entity e) remove = #15;
void(vector v1, vector v2, float nomonsters, entity forent) traceline = #16;
entity() checkclient = #17; // returns a client to look for
entity(entity start, .string fld, string match) find = #18;
string(string s) precache_sound = #19;
string(string s) precache_model = #20;
void(entity client, string s)stuffcmd = #21;
entity(vector org, float rad) findradius = #22;
void(string s) dprint = #25;
string(float f) ftos = #26;
string(vector v) vtos = #27;
void() coredump = #28; // prints all edicts
void() traceon = #29; // turns statment trace on
void() traceoff = #30;
void(entity e) eprint = #31; // prints an entire edict
float(float yaw, float dist) walkmove = #32; // returns TRUE or FALSE
float() droptofloor = #34; // TRUE if landed on floor
void(float style, string value) lightstyle = #35;
float(float v) rint = #36; // round to nearest int
float(float v) floor = #37; // largest integer <= v
float(float v) ceil = #38; // smallest integer >= v
float(entity e) checkbottom = #40; // true if self is on ground
float(vector v) pointcontents = #41; // returns a CONTENT_*
float(float f) fabs = #43;
vector(entity e, float speed) aim = #44; // returns the shooting vector
float(string s) cvar = #45; // return cvar.value
void(string s) localcmd = #46; // put string into local que
entity(entity e) nextent = #47; // for looping through all ents
void() ChangeYaw = #49; // turn towards self.ideal_yaw
vector(vector v) vectoangles = #51;
void(float f) WriteByte = #52;
void(float f) WriteChar = #53;
void(float f) WriteShort = #54;
void(float f) WriteWord = #55;
void(float f) WriteLong = #56;
void(vector v) WriteCoord = #57;
void(float f) WriteAngle = #58;
void(string s) WriteString = #59;
void(entity s) WriteEntity = #60;
void(entity s) WriteFloat = #61;
void(vector v) WriteDir = #62;
void(float dest) MsgBegin = #63;
void(float to, vector v, entity e) MsgEnd = #64;
void(float num, string s) configstring = #65;
string(string s) precache_file = #68; // no effect except for -copy
void(entity e) makestatic = #69;
void(string s) changelevel = #70;
void(string var, string val) cvar_set = #72; // sets cvar.value
void(entity client, string s) centerprint = #73; // sprint, but in middle
void(entity client, string s, string s) centerprint2 = #73;
void(entity client, string s, string s, string s) centerprint3 = #73;
void(entity client, string s, string s, string s, string s) centerprint4 = #73;
void(entity client, string s, string s, string s, string s, string s) centerprint5 = #73;
void(entity client, string s, string s, string s, string s, string s, string s) centerprint6 = #73;
void(entity client, string s, string s, string s, string s, string s, string s, string s) centerprint7 = #73;
void(vector pos, string samp, float vol, float atten) ambientsound = #74;
string(string s) precache_model2 = #75; // registered version only
string(string s) precache_sound2 = #76; // registered version only
string(string s) precache_file2 = #77; // registered version only
void(entity e) setspawnparms = #78; // set parm1... to the
//
// constants
//
float FALSE = 0;
float TRUE = 1;
// edict.flags
float FL_FLY = 1;
float FL_SWIM = 2;
float FL_CLIENT = 8; // set for all client edicts
float FL_INWATER = 16; // for enter / leave water splash
float FL_MONSTER = 32;
float FL_GODMODE = 64; // player cheat
float FL_NOTARGET = 128; // player cheat
float FL_ITEM = 256; // extra wide size for bonus items
float FL_ONGROUND = 512; // standing on something
float FL_PARTIALGROUND = 1024; // not all corners are valid
float FL_WATERJUMP = 2048; // player jumping out of water
float FL_JUMPRELEASED = 4096; // for jump debouncing
// edict.movetype values
float MOVETYPE_NONE = 0; // never moves
float MOVETYPE_ANGLENOCLIP = 1;
float MOVETYPE_ANGLECLIP = 2;
float MOVETYPE_WALK = 3; // players only
float MOVETYPE_STEP = 4; // discrete, not real time unless fall
float MOVETYPE_FLY = 5;
float MOVETYPE_TOSS = 6; // gravity
float MOVETYPE_PUSH = 7; // no clip to world, push and crush
float MOVETYPE_NOCLIP = 8;
float MOVETYPE_FLYMISSILE = 9; // fly with extra size against monsters
float MOVETYPE_BOUNCE = 10;
float MOVETYPE_BOUNCEMISSILE = 11; // bounce with extra size
// edict.solid values
float SOLID_NOT = 0; // no interaction with other objects
float SOLID_TRIGGER = 1; // touch on edge, but not blocking
float SOLID_BBOX = 2; // touch on edge, block
float SOLID_SLIDEBOX = 3; // touch on edge, but not an onground
float SOLID_BSP = 4; // bsp clip, touch on edge, block
// range values
float RANGE_MELEE = 0;
float RANGE_NEAR = 1;
float RANGE_MID = 2;
float RANGE_FAR = 3;
// deadflag values
float DEAD_NO = 0;
float DEAD_DYING = 1;
float DEAD_DEAD = 2;
float DEAD_RESPAWNABLE = 3;
// takedamage values
float DAMAGE_NO = 0;
float DAMAGE_YES = 1;
float DAMAGE_AIM = 2;
.void() th_stand;
.void() th_walk;
.void() th_run;
.void(entity attacker, float damage) th_pain;
.void() th_die;
.void() th_missile;
.void() th_melee;
// point content values
float CONTENT_EMPTY = -1;
float CONTENT_SOLID = -2;
float CONTENT_WATER = -3;
float CONTENT_SLIME = -4;
float CONTENT_LAVA = -5;
float CONTENT_SKY = -6;
float STATE_RAISED = 0;
float STATE_LOWERED = 1;
float STATE_UP = 2;
float STATE_DOWN = 3;
vector VEC_ORIGIN = '0 0 0';
vector VEC_HULL_MIN = '-16 -16 -24';
vector VEC_HULL_MAX = '16 16 32';
vector VEC_HULL2_MIN = '-32 -32 -24';
vector VEC_HULL2_MAX = '32 32 64';
// protocol bytes
float SVC_BAD = 0;
float SVC_NOP = 1;
float SVC_DISCONNECT = 2;
float SVC_UPDATESTAT = 3;
float SVC_VERSION = 4;
float SVC_SETVIEW = 5;
float SVC_SOUND = 6;
float SVC_TIME = 7;
float SVC_PRINT = 8;
float SVC_STUFFTEXT = 9;
float SVC_SETANGLE = 10;
float SVC_SERVERINFO = 11;
float SVC_LIGHTSTYLE = 12;
float SVC_UPDATENAME = 13;
float SVC_UPDATEFRAGS = 14;
float SVC_CLIENTDATA = 15;
float SVC_STOPSOUND = 16;
float SVC_UPDATECOLORS = 17;
float SVC_PARTICLE = 18;
float SVC_DAMAGE = 19;
float SVC_SPAWNSTATIC = 20;
float SVC_SPAWNBINARY = 21;
float SVC_SPAWNBASELINE = 22;
float SVC_TEMPENTITY = 23;
float SVC_SETPAUSE = 24;
float SVC_SIGNONNUM = 25;
float SVC_CENTERPRINT = 26;
float SVC_KILLEDMONSTER = 27;
float SVC_FOUNDSECRET = 28;
float SVC_SPAWNSTATICSOUND = 29; // 1998-08-08 Complete SVC list by Zhenga
float SVC_INTERMISSION = 30;
float SVC_FINALE = 31;
float SVC_CDTRACK = 32;
float SVC_SELLSCREEN = 33;
float SVC_CUTSCENE = 34; // 1998-08-08 Complete SVC list by Zhenga
float TE_SPIKE = 0;
float TE_SUPERSPIKE = 1;
float TE_GUNSHOT = 2;
float TE_EXPLOSION = 3;
float TE_TAREXPLOSION = 4;
float TE_LIGHTNING1 = 5;
float TE_LIGHTNING2 = 6;
float TE_WIZSPIKE = 7;
float TE_KNIGHTSPIKE = 8;
float TE_LIGHTNING3 = 9;
float TE_LAVASPLASH = 10;
float TE_TELEPORT = 11;
// sound channels
// channel 0 never willingly overrides
// other channels (1-7) allways override a playing sound on that channel
float CHAN_AUTO = 0;
float CHAN_WEAPON = 1;
float CHAN_VOICE = 2;
float CHAN_ITEM = 3;
float CHAN_BODY = 4;
float ATTN_NONE = 0;
float ATTN_NORM = 1;
float ATTN_IDLE = 2;
float ATTN_STATIC = 3;
// update types
float UPDATE_GENERAL = 0;
float UPDATE_STATIC = 1;
float UPDATE_BINARY = 2;
float UPDATE_TEMP = 3;
// entity effects
float EF_BRIGHTFIELD = 1;
float EF_MUZZLEFLASH = 2;
float EF_BRIGHTLIGHT = 4;
float EF_DIMLIGHT = 8;
// messages
float MSG_BROADCAST = 0; // unreliable to all
float MSG_ONE = 1; // reliable to one (msg_entity)
float MSG_ALL = 2; // reliable to all
float MSG_INIT = 3; // write to the init string
float AS_STRAIGHT = 1;
float AS_SLIDING = 2;
float AS_MELEE = 3;
float AS_MISSILE = 4;
void() SUB_Null = {};
void() SUB_Null2 = {};
// Quake assumes these are defined.
entity activator;
string string_null; // null string, nothing should be held here
.string wad, map;
.float worldtype, delay, wait, lip, light_lev, speed, style, skill;
.string killtarget;
.vector pos1, pos2, mangle;
void(vector o, vector d, float color, float count) particle = #48;// start a particle effect
void(string s) bprint = #23;
void(entity client, string s) sprint = #24;
void() SUB_Remove = {remove(self);};
// End
// Damage.qc
entity damage_attacker;
.float pain_finished, air_finished, dmg, dmgtime;
//ChaseCAm
.vector camview;
.float aflag;
.entity trigger_field;

132
resource/dummys.c Normal file
View File

@ -0,0 +1,132 @@
/*
+------+
|Dummys|
+------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Scratch Http://www.admdev.com/scratch |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| This file contains remove(self); statements for entities not yet coded. |
| This avoids Quake spewing out pages and pages of error messages when |
| loading maps. |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
*/
// General Junk
void() event_lightning = {remove(self);};
void() misc_fireball = {remove(self);};
void() misc_explobox2 = {remove(self);};
void() trap_spikeshooter = {remove(self);};
void() trap_shooter = {remove(self);};
void() func_bossgate = {remove(self);};
void() func_episodegate = {remove(self);};
//void() func_illusionary = {remove(self);};
//void() func_train = {remove(self);};
//void() func_button = {remove(self);};
//void() func_door = {remove(self);};
void() func_door_secret = {remove(self);};
void() func_plat = {remove(self);};
void() func_wall = {remove(self);};
void() info_intermission = {remove(self);};
void() info_null = {remove(self);};
//void() info_teleport_destination= {remove(self);};
//void() path_corner = {remove(self);};
// Triggers
//void() trigger_relay = {remove(self);};
//void() trigger_multiple = {remove(self);};
//void() trigger_once = {remove(self);};
//void() trigger_changelevel = {remove(self);};
//void() trigger_counter = {remove(self);};
//void() trigger_teleport = {remove(self);};
//void() trigger_secret = {remove(self);};
//void() trigger_setskill = {remove(self);};
void() trigger_monsterjump = {remove(self);};
void() trigger_onlyregistered = {remove(self);};
//void() trigger_push = {remove(self);};
//void() trigger_hurt = {remove(self);};
// Player Starts
void() info_player_start = {};
//void() info_player_start2 = {};
void() info_player_deathmatch = {};
void() info_player_coop = {};
// Weapons
void() weapon_supershotgun = {remove(self);};
void() weapon_nailgun = {remove(self);};
void() weapon_supernailgun = {remove(self);};
void() weapon_grenadelauncher = {remove(self);};
void() weapon_rocketlauncher = {remove(self);};
void() weapon_lightning = {remove(self);};
// Monsters
void() monster_enforcer = {remove(self);};
void() monster_ogre = {remove(self);};
void() monster_demon1 = {remove(self);};
void() monster_shambler = {remove(self);};
void() monster_knight = {remove(self);};
void() monster_army = {remove(self);};
void() monster_wizard = {remove(self);};
void() monster_dog = {remove(self);};
void() monster_zombie = {remove(self);};
void() monster_boss = {remove(self);};
void() monster_tarbaby = {remove(self);};
void() monster_hell_knight = {remove(self);};
void() monster_fish = {remove(self);};
void() monster_shalrath = {remove(self);};
void() monster_oldone = {remove(self);};
void() item_health = {remove(self);};
void() item_megahealth_rot = {remove(self);};
void() item_armor1 = {remove(self);};
void() item_armor2 = {remove(self);};
void() item_armorInv = {remove(self);};
void() item_shells = {remove(self);};
void() item_spikes = {remove(self);};
void() item_rockets = {remove(self);};
void() item_cells = {remove(self);};
void() item_key1 = {remove(self);};
void() item_key2 = {remove(self);};
void() item_artifact_invulnerability = {remove(self);};
void() item_artifact_envirosuit = {remove(self);};
void() item_artifact_invisibility = {remove(self);};
void() item_artifact_super_damage = {remove(self);};
void barrel_spawn(string netname1, string model1, string deathmessage, float damage)
{
local float oldz;
precache_model (model1);
precache_sound ("weapons/r_exp3.wav");
if (!self.dmg) self.dmg = damage;
self.netname = netname1;
self.owner = self;
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_NONE;
setmodel (self, model1);
self.health = 20;
self.th_die = SUB_Null;
self.takedamage = DAMAGE_AIM;
self.think = SUB_Null;
self.nextthink = -1;
self.flags = 0;
self.origin_z = self.origin_z + 2;
oldz = self.origin_z;
droptofloor();
if (oldz - self.origin_z > 250)
{
dprint ("explosive box fell out of level at ");
dprint (vtos(self.origin));
dprint ("\n");
remove(self);
}
}
void() misc_explobox =
{
float f, g;
barrel_spawn("Large exploding box", "models/barrel.mdl", " was blown up by an explosive box", 750);
};

35
resource/impulses.c Normal file
View File

@ -0,0 +1,35 @@
/*
+--------+
|Impulses|
+--------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Scratch Http://www.admdev.com/scratch |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Handle and execute "Impulse" commands - as entered from console. |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
*/
void() CheckImpulses =
{
if (self.impulse == 15)
CCam ();
if(self.impulse == 10)
{
local string a;
a = ftos(self.items);
sprint(self, a);
sprint(self, "Items Printed\n");
}
if(self.impulse == 11)
{
self.items = self.items + 8;
sprint(self, "Items added to\{136}\n");
}
if(self.impulse == 150)
{
IEM_effects(TE_TELEPORT, self.origin);
}
self.impulse = 0; // Clear impulse list.
};

137
resource/main.c Normal file
View File

@ -0,0 +1,137 @@
/*
+----+
|Main|
+----+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Scratch Http://www.admdev.com/scratch |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Contains some 'base' subroutines. As a general rule nothing in this file |
| does much, except to setup basic variables and entities. |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
*/
//INCLUDES;
void() LightStyles_setup; // Entities/Lights.QC
void() precaches;
//END INCLUDES;
void() main = {};
/*
================
|SETNEWPARMS():|
=================================================================================
Description:
This function is called to set up new player info.
=================================================================================
*/
void() SetNewParms = //Sets up start game parms
{
parm1 = 10;
parm2 = 100;
};
/*
==================
|SETCHANGEPARMS():|
=================================================================================
Description:
This function is called when the player hits a change level. Stores player info for
loading upon next level.
=================================================================================
*/
void() SetChangeParms = //called on changelevel; command
{
if (self.health <= 0)
{
SetNewParms();
return;
}
parm1 = self.items;
parm2 = self.health;
};
/*
==================
|GETLEVELPARMS():|
=================================================================================
Description:
This function is called by 'PUTCLIENTINSERVER(); in (CLIENT.QC)' and carries over
information in between level loads, or sets new parms at start map.
Information stored in .parms which are the ONLY floats to be stored in memory in
between level loads.
=================================================================================
*/
void() GetLevelParms =
{
if (world.model == "maps/start.bsp")
SetNewParms (); // take away all stuff on starting new episode
self.items = parm1;
self.health = parm2;
};
void() StartFrame = {};
void() EndFrame = {};
/*
===============
|WORLDSPAWN():|
=================================================================================
Description:
This function is called when the world spawns.
=================================================================================
*/
void() worldspawn =
{
precaches();
LightStyles_setup();
};
/*
==============
|PRECACHES():|
=================================================================================
Description:
Precaches for the game.
=================================================================================
*/
void() precaches =
{
precache_model ("progs/player.mdl");
precache_model("progs/s_bubble.spr");
precache_model("progs/eyes.mdl");
precache_model ("progs/enforcer.mdl"); //testing only
// pain sounds
precache_sound ("player/drown1.wav"); // drowning pain
precache_sound ("player/drown2.wav"); // drowning pain
precache_sound ("player/lburn1.wav"); // slime/lava burn
precache_sound ("player/lburn2.wav"); // slime/lava burn
precache_sound ("player/pain1.wav");
precache_sound ("player/pain2.wav");
precache_sound ("player/pain3.wav");
precache_sound ("player/pain4.wav");
precache_sound ("player/pain5.wav");
precache_sound ("player/pain6.wav");
// death sounds
precache_sound ("player/h2odeath.wav"); // drowning death
precache_sound ("player/death1.wav");
precache_sound ("player/death2.wav");
precache_sound ("player/death3.wav");
precache_sound ("player/death4.wav");
precache_sound ("player/death5.wav");
};

248
resource/player.c Normal file
View File

@ -0,0 +1,248 @@
/*
+------+
|Player|
+------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Scratch http://www.inside3d.com/qctut/scratch.shtml |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Handle player animations and other misc player functions |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
*/
.float anim_time; // used for animation timing
.float anim_end; // end frame for current scene
.float anim_priority; // prioritize animations
.float anim_run; // running or not
// client_t->anim_priority
float ANIM_BASIC = 0; // stand / run
float ANIM_PAIN = 1;
float ANIM_ATTACK = 2;
float ANIM_DEATH = 3;
// running
$frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6
$frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6
// standing
$frame stand1 stand2 stand3 stand4 stand5
$frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6
$frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12
// pain
$frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6
$frame pain1 pain2 pain3 pain4 pain5 pain6
// death
$frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6
$frame axdeth7 axdeth8 axdeth9
$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
$frame deatha9 deatha10 deatha11
$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
$frame deathb9
$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
$frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
$frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
$frame deathd8 deathd9
$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
$frame deathe8 deathe9
// attacks
$frame nailatt1 nailatt2
$frame light1 light2
$frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
$frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
$frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
$frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
$frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
void () SetClientFrame =
{
// note: call whenever weapon frames are called!
if (self.anim_time > time)
return; //don't call every frame, if it is the animations will play too fast
self.anim_time = time + 0.1;
local float anim_change, run;
if (self.velocity_x || self.velocity_y)
run = TRUE;
else
run = FALSE;
anim_change = FALSE;
// check for stop/go and animation transitions
if (run != self.anim_run && self.anim_priority == ANIM_BASIC)
anim_change = TRUE;
if (anim_change != TRUE)
{
if (self.frame < self.anim_end)
{ // continue an animation
self.frame = self.frame + 1;
return;
}
if (self.anim_priority == ANIM_DEATH)
{
if (self.deadflag == DEAD_DYING)
{
self.nextthink = -1;
self.deadflag = DEAD_DEAD;
}
return; // stay there
}
}
// return to either a running or standing frame
self.anim_priority = ANIM_BASIC;
self.anim_run = run;
if (self.velocity_x || self.velocity_y)
{ // running
self.frame = $rockrun1;
self.anim_end = $rockrun6;
}
else
{ // standing
self.frame = $stand1;
self.anim_end = $stand5;
}
};
/*
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Pain sound, and Pain animation function
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
*/
void() PainSound =
{
if (self.health < 0)
return;
self.noise = "";
if (self.watertype == CONTENT_WATER && self.waterlevel == 3)
{ // water pain sounds
if (random() <= 0.5)
self.noise = "player/drown1.wav";
else
self.noise = "player/drown2.wav";
}
else if (self.watertype == CONTENT_SLIME || self.watertype == CONTENT_LAVA)
{ // slime/lava pain sounds
if (random() <= 0.5)
self.noise = "player/lburn1.wav";
else
self.noise = "player/lburn2.wav";
}
if (self.noise)
{
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
return;
}
//don't make multiple pain sounds right after each other
if (self.pain_finished > time)
return;
self.pain_finished = time + 0.5;
local float rs;
rs = rint((random() * 5) + 1); // rs = 1-6
if (rs == 1)
self.noise = "player/pain1.wav";
else if (rs == 2)
self.noise = "player/pain2.wav";
else if (rs == 3)
self.noise = "player/pain3.wav";
else if (rs == 4)
self.noise = "player/pain4.wav";
else if (rs == 5)
self.noise = "player/pain5.wav";
else
self.noise = "player/pain6.wav";
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
};
void () PlayerPain =
{
if (self.anim_priority < ANIM_PAIN) // call only if not attacking and not already in pain
{
self.anim_priority = ANIM_PAIN;
self.frame = $pain1;
self.anim_end = $pain6;
}
PainSound ();
};
/*
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Death sound, and Death function
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
*/
void() DeathSound =
{
local float rs;
rs = rint ((random() * 4) + 1); // rs = 1-5
if (self.waterlevel == 3) // water death sound
self.noise = "player/h2odeath.wav";
else if (rs == 1)
self.noise = "player/death1.wav";
else if (rs == 2)
self.noise = "player/death2.wav";
else if (rs == 3)
self.noise = "player/death3.wav";
else if (rs == 4)
self.noise = "player/death4.wav";
else if (rs == 5)
self.noise = "player/death5.wav";
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NONE);
};
void () PlayerDie =
{
self.view_ofs = '0 0 -8';
self.angles_x = self.angles_z = 0;
self.deadflag = DEAD_DYING;
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_TOSS;
self.flags = self.flags - (self.flags & FL_ONGROUND);
if (self.velocity_z < 10)
self.velocity_z = self.velocity_z + random()*300;
local float rand;
rand = rint ((random() * 4) + 1); // rand = 1-5
self.anim_priority = ANIM_DEATH;
if (rand == 1)
{
self.frame = $deatha1;
self.anim_end = $deatha11;
}
else if (rand == 2)
{
self.frame = $deathb1;
self.anim_end = $deathb9;
}
else if (rand == 3)
{
self.frame = $deathc1;
self.anim_end = $deathc15;
}
else if (rand == 4)
{
self.frame = $deathd1;
self.anim_end = $deathd9;
}
else
{
self.frame = $deathe1;
self.anim_end = $deathe9;
}
DeathSound();
};

287
resource/progdefs.h Normal file
View File

@ -0,0 +1,287 @@
/* File generated by FTEQCC, relevent for engine modding only, the generated crc must be the same as your engine expects. */
typedef struct globalvars_s
{ int pad;
int ofs_return[3];
int ofs_parm0[3];
int ofs_parm1[3];
int ofs_parm2[3];
int ofs_parm3[3];
int ofs_parm4[3];
int ofs_parm5[3];
int ofs_parm6[3];
int ofs_parm7[3];
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 parm1;
float parm2;
float parm3;
float parm4;
float parm5;
float parm6;
float parm7;
float parm8;
float parm9;
float parm10;
float parm11;
float parm12;
float parm13;
float parm14;
float parm15;
float parm16;
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;
func_t main;
func_t StartFrame;
func_t EndFrame;
func_t PlayerPreThink;
func_t PlayerPostThink;
func_t ClientKill;
func_t ClientConnect;
func_t PutClientInServer;
func_t 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;
//with this the crc isn't needed for fields.
struct fieldvars_s
{
int ofs;
int type;
char *name;
} fieldvars[] = {
{0, 2, "modelindex"},
{1, 3, "absmin"},
{1, 2, "absmin_x"},
{2, 2, "absmin_y"},
{3, 2, "absmin_z"},
{4, 3, "absmax"},
{4, 2, "absmax_x"},
{5, 2, "absmax_y"},
{6, 2, "absmax_z"},
{7, 2, "ltime"},
{8, 2, "movetype"},
{9, 2, "solid"},
{10, 3, "origin"},
{10, 2, "origin_x"},
{11, 2, "origin_y"},
{12, 2, "origin_z"},
{13, 3, "oldorigin"},
{13, 2, "oldorigin_x"},
{14, 2, "oldorigin_y"},
{15, 2, "oldorigin_z"},
{16, 3, "velocity"},
{16, 2, "velocity_x"},
{17, 2, "velocity_y"},
{18, 2, "velocity_z"},
{19, 3, "angles"},
{19, 2, "angles_x"},
{20, 2, "angles_y"},
{21, 2, "angles_z"},
{22, 3, "avelocity"},
{22, 2, "avelocity_x"},
{23, 2, "avelocity_y"},
{24, 2, "avelocity_z"},
{25, 3, "punchangle"},
{25, 2, "punchangle_x"},
{26, 2, "punchangle_y"},
{27, 2, "punchangle_z"},
{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"},
{36, 2, "mins_x"},
{37, 2, "mins_y"},
{38, 2, "mins_z"},
{39, 3, "maxs"},
{39, 2, "maxs_x"},
{40, 2, "maxs_y"},
{41, 2, "maxs_z"},
{42, 3, "size"},
{42, 2, "size_x"},
{43, 2, "size_y"},
{44, 2, "size_z"},
{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"},
{65, 2, "view_ofs_x"},
{66, 2, "view_ofs_y"},
{67, 2, "view_ofs_z"},
{68, 2, "button0"},
{69, 2, "button1"},
{70, 2, "button2"},
{71, 2, "impulse"},
{72, 2, "fixangle"},
{73, 3, "v_angle"},
{73, 2, "v_angle_x"},
{74, 2, "v_angle_y"},
{75, 2, "v_angle_z"},
{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"},
{99, 2, "movedir_x"},
{100, 2, "movedir_y"},
{101, 2, "movedir_z"},
{102, 1, "message"},
{103, 2, "sounds"},
{104, 1, "noise"},
{105, 1, "noise1"},
{106, 1, "noise2"},
{107, 1, "noise3"}
};
#define PROGHEADER_CRC 21645

BIN
resource/qcclib.exe Normal file

Binary file not shown.

View File

@ -1,6 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2007
// baseentity.h - main game definitions
//=======================================================================
#include "g_local.h"

View File

@ -1,89 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2007
// client.cpp - client/server game specific stuff
//=======================================================================
#include "baseentity.h"
void ClientUserinfoChanged (edict_t *ent, char *userinfo);
/*
===========
ClientConnect
Called when a player begins connecting to the server.
============
*/
bool ClientConnect (edict_t *ent, char *userinfo)
{
char *value;
// check to see if they are on the banned IP list
value = Info_ValueForKey (userinfo, "ip");
if (SV_FilterPacket(value))
{
Info_SetValueForKey(userinfo, "rejmsg", "Banned.");
return false;
}
// check for a spectator
value = Info_ValueForKey (userinfo, "spectator");
if (deathmatch->value && *value && strcmp(value, "0"))
{
int i, numspec;
if (*spectator_password->string && strcmp(spectator_password->string, "none") && strcmp(spectator_password->string, value))
{
Info_SetValueForKey(userinfo, "rejmsg", "Spectator password required or incorrect.");
return false;
}
// count spectators
for (i = numspec = 0; i < maxclients->value; i++)
{
if (g_edicts[i+1].inuse && g_edicts[i+1].client->pers.spectator)
numspec++;
}
if (numspec >= maxspectators->value)
{
Info_SetValueForKey(userinfo, "rejmsg", "Server spectator limit is full.");
return false;
}
}
else
{
// check for a password
value = Info_ValueForKey (userinfo, "password");
if (*password->string && strcmp(password->string, "none") && strcmp(password->string, value))
{
Info_SetValueForKey(userinfo, "rejmsg", "Password required or incorrect.");
return false;
}
}
// they can connect
ent->client = game.clients + (ent - g_edicts - 1);
// if there is already a body waiting for us (a loadgame), just
// take it, otherwise spawn one from scratch
if (ent->inuse == false)
{
// clear the respawning variables
InitClientResp (ent->client);
if (!game.autosaved || !ent->client->pers.weapon)
{
InitClientPersistant (ent->client,world->style);
}
}
ClientUserinfoChanged (ent, userinfo);
if (game.maxclients > 1) gi.dprintf ("%s connected\n", ent->client->pers.netname);
ent->svflags = 0; // make sure we start with known default
ent->client->pers.connected = true;
return true;
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More