mirror of
https://git.code.sf.net/p/quake/quakeforge-old
synced 2025-02-21 02:50:56 +00:00
pandr's pr_* merge..
This commit is contained in:
parent
d5217418ec
commit
d0674e837c
9 changed files with 470 additions and 3855 deletions
1
AUTHORS
1
AUTHORS
|
@ -18,6 +18,7 @@ QW/Q1 tree merging:
|
|||
Nelson J. Rush <chesterrr@att.net>
|
||||
Eric Windisch <windisch@nni.com>
|
||||
Joseph Carter <knghtbrd@debian.org>
|
||||
Peter Andreasen <pandr@pandr.dk>
|
||||
|
||||
Autoconf support:
|
||||
Loring Holden <lsh@cs.brown.edu>
|
||||
|
|
|
@ -17,8 +17,11 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "qwsvdef.h"
|
||||
#ifdef QUAKEWORLD
|
||||
# include "qwsvdef.h"
|
||||
#else
|
||||
# include "quakedef.h"
|
||||
#endif
|
||||
|
||||
#define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e))
|
||||
#define RETURN_STRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_SetString(s))
|
||||
|
@ -65,7 +68,11 @@ void PF_error (void)
|
|||
ed = PROG_TO_EDICT(pr_global_struct->self);
|
||||
ED_Print (ed);
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("Program error");
|
||||
#else
|
||||
Host_Error ("Program error");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -89,7 +96,11 @@ void PF_objerror (void)
|
|||
ED_Print (ed);
|
||||
ED_Free (ed);
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("Program error");
|
||||
#else
|
||||
Host_Error ("Program error");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -111,8 +122,7 @@ void PF_makevectors (void)
|
|||
=================
|
||||
PF_setorigin
|
||||
|
||||
This is the only valid way to move an object without using the physics of the world (setting velocity and waiting). Directly changing origin will not set internal links correctly, so clipping would be messed up. This should be called when an object is s
|
||||
pawned, and then only if it is teleported.
|
||||
This is the only valid way to move an object without using the physics of the world (setting velocity and waiting). Directly changing origin will not set internal links correctly, so clipping would be messed up. This should be called when an object is spawned, and then only if it is teleported.
|
||||
|
||||
setorigin (entity, origin)
|
||||
=================
|
||||
|
@ -128,6 +138,86 @@ void PF_setorigin (void)
|
|||
SV_LinkEdict (e, false);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
QUAKEWORLD: Note, the function SetMinMaxSize is only used for UQUAKE
|
||||
===============
|
||||
*/
|
||||
|
||||
void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
|
||||
{
|
||||
float *angles;
|
||||
vec3_t rmin, rmax;
|
||||
float bounds[2][3];
|
||||
float xvector[2], yvector[2];
|
||||
float a;
|
||||
vec3_t base, transformed;
|
||||
int i, j, k, l;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
if (min[i] > max[i])
|
||||
PR_RunError ("backwards mins/maxs");
|
||||
|
||||
rotate = false; // FIXME: implement rotation properly again
|
||||
|
||||
if (!rotate)
|
||||
{
|
||||
VectorCopy (min, rmin);
|
||||
VectorCopy (max, rmax);
|
||||
}
|
||||
else
|
||||
{
|
||||
// find min / max for rotations
|
||||
angles = e->v.angles;
|
||||
|
||||
a = angles[1]/180 * M_PI;
|
||||
|
||||
xvector[0] = cos(a);
|
||||
xvector[1] = sin(a);
|
||||
yvector[0] = -sin(a);
|
||||
yvector[1] = cos(a);
|
||||
|
||||
VectorCopy (min, bounds[0]);
|
||||
VectorCopy (max, bounds[1]);
|
||||
|
||||
rmin[0] = rmin[1] = rmin[2] = 9999;
|
||||
rmax[0] = rmax[1] = rmax[2] = -9999;
|
||||
|
||||
for (i=0 ; i<= 1 ; i++)
|
||||
{
|
||||
base[0] = bounds[i][0];
|
||||
for (j=0 ; j<= 1 ; j++)
|
||||
{
|
||||
base[1] = bounds[j][1];
|
||||
for (k=0 ; k<= 1 ; k++)
|
||||
{
|
||||
base[2] = bounds[k][2];
|
||||
|
||||
// transform the point
|
||||
transformed[0] = xvector[0]*base[0] + yvector[0]*base[1];
|
||||
transformed[1] = xvector[1]*base[0] + yvector[1]*base[1];
|
||||
transformed[2] = base[2];
|
||||
|
||||
for (l=0 ; l<3 ; l++)
|
||||
{
|
||||
if (transformed[l] < rmin[l])
|
||||
rmin[l] = transformed[l];
|
||||
if (transformed[l] > rmax[l])
|
||||
rmax[l] = transformed[l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set derived values
|
||||
VectorCopy (rmin, e->v.mins);
|
||||
VectorCopy (rmax, e->v.maxs);
|
||||
VectorSubtract (max, min, e->v.size);
|
||||
|
||||
SV_LinkEdict (e, false);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -146,10 +236,14 @@ void PF_setsize (void)
|
|||
e = G_EDICT(OFS_PARM0);
|
||||
min = G_VECTOR(OFS_PARM1);
|
||||
max = G_VECTOR(OFS_PARM2);
|
||||
#ifdef QUAKEWORLD
|
||||
VectorCopy (min, e->v.mins);
|
||||
VectorCopy (max, e->v.maxs);
|
||||
VectorSubtract (max, min, e->v.size);
|
||||
SV_LinkEdict (e, false);
|
||||
#else
|
||||
SetMinMaxSize (e, min, max, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -182,6 +276,7 @@ void PF_setmodel (void)
|
|||
e->v.model = PR_SetString(m);
|
||||
e->v.modelindex = i;
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
// if it is an inline model, get the size information for it
|
||||
if (m[0] == '*')
|
||||
{
|
||||
|
@ -191,6 +286,14 @@ void PF_setmodel (void)
|
|||
VectorSubtract (mod->maxs, mod->mins, e->v.size);
|
||||
SV_LinkEdict (e, false);
|
||||
}
|
||||
#else
|
||||
mod = sv.models[ (int)e->v.modelindex]; // Mod_ForName (m, true);
|
||||
|
||||
if (mod)
|
||||
SetMinMaxSize (e, mod->mins, mod->maxs, true);
|
||||
else
|
||||
SetMinMaxSize (e, vec3_origin, vec3_origin, true);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -208,10 +311,16 @@ void PF_bprint (void)
|
|||
char *s;
|
||||
int level;
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
level = G_FLOAT(OFS_PARM0);
|
||||
|
||||
s = PF_VarString(1);
|
||||
SV_BroadcastPrintf (level, "%s", s);
|
||||
#else
|
||||
s = PF_VarString(0);
|
||||
SV_BroadcastPrintf ("%s", s);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -231,11 +340,20 @@ void PF_sprint (void)
|
|||
int level;
|
||||
|
||||
entnum = G_EDICTNUM(OFS_PARM0);
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
level = G_FLOAT(OFS_PARM1);
|
||||
|
||||
s = PF_VarString(2);
|
||||
#else
|
||||
s = PF_VarString(1);
|
||||
#endif
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
if (entnum < 1 || entnum > MAX_CLIENTS)
|
||||
#else
|
||||
if (entnum < 1 || entnum > svs.maxclients)
|
||||
#endif
|
||||
{
|
||||
Con_Printf ("tried to sprint to a non-client\n");
|
||||
return;
|
||||
|
@ -243,7 +361,12 @@ void PF_sprint (void)
|
|||
|
||||
client = &svs.clients[entnum-1];
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
SV_ClientPrintf (client, level, "%s", s);
|
||||
#else
|
||||
MSG_WriteChar (&client->message,svc_print);
|
||||
MSG_WriteString (&client->message, s );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -265,7 +388,11 @@ void PF_centerprint (void)
|
|||
entnum = G_EDICTNUM(OFS_PARM0);
|
||||
s = PF_VarString(1);
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
if (entnum < 1 || entnum > MAX_CLIENTS)
|
||||
#else
|
||||
if (entnum < 1 || entnum > svs.maxclients)
|
||||
#endif
|
||||
{
|
||||
Con_Printf ("tried to sprint to a non-client\n");
|
||||
return;
|
||||
|
@ -273,8 +400,13 @@ void PF_centerprint (void)
|
|||
|
||||
cl = &svs.clients[entnum-1];
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
ClientReliableWrite_Begin (cl, svc_centerprint, 2 + strlen(s));
|
||||
ClientReliableWrite_String (cl, s);
|
||||
#else
|
||||
MSG_WriteChar (&cl->message,svc_centerprint);
|
||||
MSG_WriteString (&cl->message, s );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -414,6 +546,27 @@ void PF_random (void)
|
|||
G_FLOAT(OFS_RETURN) = num;
|
||||
}
|
||||
|
||||
#ifndef QUAKEWORLD /* !QUAKEWORLD */
|
||||
/*
|
||||
=================
|
||||
PF_particle
|
||||
|
||||
particle(origin, color, count)
|
||||
=================
|
||||
*/
|
||||
void PF_particle (void)
|
||||
{
|
||||
float *org, *dir;
|
||||
float color;
|
||||
float count;
|
||||
|
||||
org = G_VECTOR(OFS_PARM0);
|
||||
dir = G_VECTOR(OFS_PARM1);
|
||||
color = G_FLOAT(OFS_PARM2);
|
||||
count = G_FLOAT(OFS_PARM3);
|
||||
SV_StartParticle (org, dir, color, count);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -486,6 +639,17 @@ void PF_sound (void)
|
|||
sample = G_STRING(OFS_PARM2);
|
||||
volume = G_FLOAT(OFS_PARM3) * 255;
|
||||
attenuation = G_FLOAT(OFS_PARM4);
|
||||
|
||||
#ifndef QUAKEWORLD
|
||||
if (volume < 0 || volume > 255)
|
||||
Sys_Error ("SV_StartSound: volume = %i", volume);
|
||||
|
||||
if (attenuation < 0 || attenuation > 4)
|
||||
Sys_Error ("SV_StartSound: attenuation = %f", attenuation);
|
||||
|
||||
if (channel < 0 || channel > 7)
|
||||
Sys_Error ("SV_StartSound: channel = %i", channel);
|
||||
#endif
|
||||
|
||||
SV_StartSound (entity, channel, sample, volume, attenuation);
|
||||
}
|
||||
|
@ -573,6 +737,8 @@ int PF_newcheckclient (int check)
|
|||
|
||||
if (check < 1)
|
||||
check = 1;
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
if (check > MAX_CLIENTS)
|
||||
check = MAX_CLIENTS;
|
||||
|
||||
|
@ -580,10 +746,23 @@ int PF_newcheckclient (int check)
|
|||
i = 1;
|
||||
else
|
||||
i = check + 1;
|
||||
#else
|
||||
if (check > svs.maxclients)
|
||||
check = svs.maxclients;
|
||||
|
||||
if (check == svs.maxclients)
|
||||
i = 1;
|
||||
else
|
||||
i = check + 1;
|
||||
#endif
|
||||
|
||||
for ( ; ; i++)
|
||||
{
|
||||
#ifdef QUAKEWORLD
|
||||
if (i == MAX_CLIENTS+1)
|
||||
#else
|
||||
if (i == svs.maxclients+1)
|
||||
#endif
|
||||
i = 1;
|
||||
|
||||
ent = EDICT_NUM(i);
|
||||
|
@ -686,12 +865,17 @@ void PF_stuffcmd (void)
|
|||
client_t *cl;
|
||||
|
||||
entnum = G_EDICTNUM(OFS_PARM0);
|
||||
#ifdef QUAKEWORLD
|
||||
if (entnum < 1 || entnum > MAX_CLIENTS)
|
||||
#else
|
||||
if (entnum < 1 || entnum > svs.maxclients)
|
||||
#endif
|
||||
PR_RunError ("Parm 0 not a client");
|
||||
str = G_STRING(OFS_PARM1);
|
||||
|
||||
cl = &svs.clients[entnum-1];
|
||||
|
||||
#if QUAKEWORLD
|
||||
if (strcmp(str, "disconnect\n") == 0) {
|
||||
// so long and thanks for all the fish
|
||||
cl->drop = true;
|
||||
|
@ -700,6 +884,12 @@ void PF_stuffcmd (void)
|
|||
|
||||
ClientReliableWrite_Begin (cl, svc_stufftext, 2+strlen(str));
|
||||
ClientReliableWrite_String (cl, str);
|
||||
#else
|
||||
cl = host_client;
|
||||
host_client = &svs.clients[entnum-1];
|
||||
Host_ClientCommands ("%s", str);
|
||||
host_client = cl;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -801,7 +991,11 @@ PF_dprint
|
|||
*/
|
||||
void PF_dprint (void)
|
||||
{
|
||||
#ifdef QUAKEWORLD
|
||||
Con_Printf ("%s",PF_VarString(0));
|
||||
#else
|
||||
Con_DPrintf ("%s",PF_VarString(0));
|
||||
#endif
|
||||
}
|
||||
|
||||
char pr_string_temp[128];
|
||||
|
@ -932,6 +1126,9 @@ void PF_precache_model (void)
|
|||
if (!sv.model_precache[i])
|
||||
{
|
||||
sv.model_precache[i] = s;
|
||||
#ifndef QUAKEWORLD
|
||||
sv.models[i] = Mod_ForName (s, true);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (!strcmp(sv.model_precache[i], s))
|
||||
|
@ -1060,6 +1257,7 @@ void PF_lightstyle (void)
|
|||
if (sv.state != ss_active)
|
||||
return;
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
for (j=0, client = svs.clients ; j<MAX_CLIENTS ; j++, client++)
|
||||
if ( client->state == cs_spawned )
|
||||
{
|
||||
|
@ -1067,6 +1265,15 @@ void PF_lightstyle (void)
|
|||
ClientReliableWrite_Char (client, style);
|
||||
ClientReliableWrite_String (client, val);
|
||||
}
|
||||
#else
|
||||
for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
|
||||
if (client->active || client->spawned)
|
||||
{
|
||||
MSG_WriteChar (&client->message, svc_lightstyle);
|
||||
MSG_WriteChar (&client->message,style);
|
||||
MSG_WriteString (&client->message, val);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void PF_rint (void)
|
||||
|
@ -1154,8 +1361,11 @@ Pick a vector for the player to shoot along
|
|||
vector aim(entity, missilespeed)
|
||||
=============
|
||||
*/
|
||||
//cvar_t sv_aim = {"sv_aim", "0.93"};
|
||||
#ifdef QUAKEWORLD
|
||||
cvar_t sv_aim = {"sv_aim", "2"};
|
||||
#else
|
||||
cvar_t sv_aim = {"sv_aim", "0.93"};
|
||||
#endif
|
||||
void PF_aim (void)
|
||||
{
|
||||
edict_t *ent, *check, *bestent;
|
||||
|
@ -1172,6 +1382,7 @@ void PF_aim (void)
|
|||
VectorCopy (ent->v.origin, start);
|
||||
start[2] += 20;
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
// noaim option
|
||||
i = NUM_FOR_EDICT(ent);
|
||||
if (i>0 && i<MAX_CLIENTS)
|
||||
|
@ -1183,6 +1394,7 @@ void PF_aim (void)
|
|||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// try sending a trace straight
|
||||
VectorCopy (pr_global_struct->v_forward, dir);
|
||||
|
@ -1301,9 +1513,9 @@ MESSAGE WRITING
|
|||
|
||||
sizebuf_t *WriteDest (void)
|
||||
{
|
||||
// int entnum;
|
||||
int entnum;
|
||||
int dest;
|
||||
// edict_t *ent;
|
||||
edict_t *ent;
|
||||
|
||||
dest = G_FLOAT(OFS_PARM0);
|
||||
switch (dest)
|
||||
|
@ -1312,25 +1524,29 @@ sizebuf_t *WriteDest (void)
|
|||
return &sv.datagram;
|
||||
|
||||
case MSG_ONE:
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error("Shouldn't be at MSG_ONE");
|
||||
#if 0
|
||||
return &svs.clients[entnum-1].netchan.message;
|
||||
#else
|
||||
ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
|
||||
entnum = NUM_FOR_EDICT(ent);
|
||||
if (entnum < 1 || entnum > MAX_CLIENTS)
|
||||
if (entnum < 1 || entnum > svs.maxclients)
|
||||
PR_RunError ("WriteDest: not a client");
|
||||
return &svs.clients[entnum-1].netchan.message;
|
||||
return &svs.clients[entnum-1].message;
|
||||
#endif
|
||||
|
||||
case MSG_ALL:
|
||||
return &sv.reliable_datagram;
|
||||
|
||||
case MSG_INIT:
|
||||
#ifdef QUAKEWORLD
|
||||
if (sv.state != ss_loading)
|
||||
PR_RunError ("PF_Write_*: MSG_INIT can only be written in spawn functions");
|
||||
return &sv.signon;
|
||||
|
||||
case MSG_MULTICAST:
|
||||
return &sv.multicast;
|
||||
#endif
|
||||
|
||||
default:
|
||||
PR_RunError ("WriteDest: bad destination");
|
||||
|
@ -1340,6 +1556,7 @@ sizebuf_t *WriteDest (void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
static client_t *Write_GetClient(void)
|
||||
{
|
||||
int entnum;
|
||||
|
@ -1351,86 +1568,103 @@ static client_t *Write_GetClient(void)
|
|||
PR_RunError ("WriteDest: not a client");
|
||||
return &svs.clients[entnum-1];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void PF_WriteByte (void)
|
||||
{
|
||||
#ifdef QUAKEWORLD
|
||||
if (G_FLOAT(OFS_PARM0) == MSG_ONE) {
|
||||
client_t *cl = Write_GetClient();
|
||||
ClientReliableCheckBlock(cl, 1);
|
||||
ClientReliableWrite_Byte(cl, G_FLOAT(OFS_PARM1));
|
||||
} else
|
||||
#endif
|
||||
MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
|
||||
void PF_WriteChar (void)
|
||||
{
|
||||
#ifdef QUAKEWORLD
|
||||
if (G_FLOAT(OFS_PARM0) == MSG_ONE) {
|
||||
client_t *cl = Write_GetClient();
|
||||
ClientReliableCheckBlock(cl, 1);
|
||||
ClientReliableWrite_Char(cl, G_FLOAT(OFS_PARM1));
|
||||
} else
|
||||
#endif
|
||||
MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
|
||||
void PF_WriteShort (void)
|
||||
{
|
||||
#ifdef QUAKEWORLD
|
||||
if (G_FLOAT(OFS_PARM0) == MSG_ONE) {
|
||||
client_t *cl = Write_GetClient();
|
||||
ClientReliableCheckBlock(cl, 2);
|
||||
ClientReliableWrite_Short(cl, G_FLOAT(OFS_PARM1));
|
||||
} else
|
||||
#endif
|
||||
MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
|
||||
void PF_WriteLong (void)
|
||||
{
|
||||
#ifdef QUAKEWORLD
|
||||
if (G_FLOAT(OFS_PARM0) == MSG_ONE) {
|
||||
client_t *cl = Write_GetClient();
|
||||
ClientReliableCheckBlock(cl, 4);
|
||||
ClientReliableWrite_Long(cl, G_FLOAT(OFS_PARM1));
|
||||
} else
|
||||
#endif
|
||||
MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
|
||||
void PF_WriteAngle (void)
|
||||
{
|
||||
#ifdef QUAKEWORLD
|
||||
if (G_FLOAT(OFS_PARM0) == MSG_ONE) {
|
||||
client_t *cl = Write_GetClient();
|
||||
ClientReliableCheckBlock(cl, 1);
|
||||
ClientReliableWrite_Angle(cl, G_FLOAT(OFS_PARM1));
|
||||
} else
|
||||
#endif
|
||||
MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
|
||||
void PF_WriteCoord (void)
|
||||
{
|
||||
#ifdef QUAKEWORLD
|
||||
if (G_FLOAT(OFS_PARM0) == MSG_ONE) {
|
||||
client_t *cl = Write_GetClient();
|
||||
ClientReliableCheckBlock(cl, 2);
|
||||
ClientReliableWrite_Coord(cl, G_FLOAT(OFS_PARM1));
|
||||
} else
|
||||
#endif
|
||||
MSG_WriteCoord (WriteDest(), G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
|
||||
void PF_WriteString (void)
|
||||
{
|
||||
#ifdef QUAKEWORLD
|
||||
if (G_FLOAT(OFS_PARM0) == MSG_ONE) {
|
||||
client_t *cl = Write_GetClient();
|
||||
ClientReliableCheckBlock(cl, 1+strlen(G_STRING(OFS_PARM1)));
|
||||
ClientReliableWrite_String(cl, G_STRING(OFS_PARM1));
|
||||
} else
|
||||
#endif
|
||||
MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
|
||||
}
|
||||
|
||||
|
||||
void PF_WriteEntity (void)
|
||||
{
|
||||
#ifdef QUAKEWORLD
|
||||
if (G_FLOAT(OFS_PARM0) == MSG_ONE) {
|
||||
client_t *cl = Write_GetClient();
|
||||
ClientReliableCheckBlock(cl, 2);
|
||||
ClientReliableWrite_Short(cl, G_EDICTNUM(OFS_PARM1));
|
||||
} else
|
||||
#endif
|
||||
MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
|
||||
}
|
||||
|
||||
|
@ -1477,7 +1711,11 @@ void PF_setspawnparms (void)
|
|||
|
||||
ent = G_EDICT(OFS_PARM0);
|
||||
i = NUM_FOR_EDICT(ent);
|
||||
#ifdef QUAKEWORLD
|
||||
if (i < 1 || i > MAX_CLIENTS)
|
||||
#else
|
||||
if (i < 1 || i > svs.maxclients)
|
||||
#endif
|
||||
PR_RunError ("Entity is not a client");
|
||||
|
||||
// copy spawn parms out of the client_t
|
||||
|
@ -1498,15 +1736,27 @@ void PF_changelevel (void)
|
|||
static int last_spawncount;
|
||||
|
||||
// make sure we don't issue two changelevels
|
||||
#ifdef QUAKEWORLD
|
||||
if (svs.spawncount == last_spawncount)
|
||||
return;
|
||||
last_spawncount = svs.spawncount;
|
||||
#else
|
||||
if (svs.changelevel_issued)
|
||||
return;
|
||||
svs.changelevel_issued = true;
|
||||
#endif
|
||||
|
||||
s = G_STRING(OFS_PARM0);
|
||||
#ifdef QUAKEWORLD
|
||||
Cbuf_AddText (va("map %s\n",s));
|
||||
#else
|
||||
Cbuf_AddText (va("changelevel %s\n",s));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
|
||||
/*
|
||||
==============
|
||||
PF_logfrag
|
||||
|
@ -1613,6 +1863,7 @@ void PF_multicast (void)
|
|||
SV_Multicast (o, to);
|
||||
}
|
||||
|
||||
#endif /* QUAKEWORLD */
|
||||
|
||||
void PF_Fixme (void)
|
||||
{
|
||||
|
@ -1671,7 +1922,11 @@ PF_aim,
|
|||
PF_cvar,
|
||||
PF_localcmd,
|
||||
PF_nextent,
|
||||
#ifdef QUAKEWORLD
|
||||
PF_Fixme,
|
||||
#else
|
||||
PF_particle,
|
||||
#endif
|
||||
PF_changeyaw,
|
||||
PF_Fixme,
|
||||
PF_vectoangles,
|
||||
|
@ -1709,13 +1964,16 @@ PF_precache_model,
|
|||
PF_precache_sound, // precache_sound2 is different only for qcc
|
||||
PF_precache_file,
|
||||
|
||||
PF_setspawnparms,
|
||||
PF_setspawnparms
|
||||
#ifdef QUAKEWORLD
|
||||
,
|
||||
|
||||
PF_logfrag,
|
||||
|
||||
PF_infokey,
|
||||
PF_stof,
|
||||
PF_multicast
|
||||
#endif
|
||||
};
|
||||
|
||||
builtin_t *pr_builtins = pr_builtin;
|
|
@ -19,7 +19,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
// sv_edict.c -- entity dictionary
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
#include "qwsvdef.h"
|
||||
#else
|
||||
#include "quakedef.h"
|
||||
#endif
|
||||
|
||||
dprograms_t *progs;
|
||||
dfunction_t *pr_functions;
|
||||
|
@ -31,11 +35,30 @@ globalvars_t *pr_global_struct;
|
|||
float *pr_globals; // same as pr_global_struct
|
||||
int pr_edict_size; // in bytes
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
int type_size[8] = {1,sizeof(void *)/4,1,3,1,1,sizeof(void *)/4,sizeof(void *)/4};
|
||||
#else
|
||||
unsigned short pr_crc;
|
||||
int type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4};
|
||||
#endif
|
||||
|
||||
ddef_t *ED_FieldAtOfs (int ofs);
|
||||
qboolean ED_ParseEpair (void *base, ddef_t *key, char *s);
|
||||
|
||||
#ifndef QUAKEWORLD
|
||||
cvar_t nomonsters = {"nomonsters", "0"};
|
||||
cvar_t gamecfg = {"gamecfg", "0"};
|
||||
cvar_t scratch1 = {"scratch1", "0"};
|
||||
cvar_t scratch2 = {"scratch2", "0"};
|
||||
cvar_t scratch3 = {"scratch3", "0"};
|
||||
cvar_t scratch4 = {"scratch4", "0"};
|
||||
cvar_t savedgamecfg = {"savedgamecfg", "0", true};
|
||||
cvar_t saved1 = {"saved1", "0", true};
|
||||
cvar_t saved2 = {"saved2", "0", true};
|
||||
cvar_t saved3 = {"saved3", "0", true};
|
||||
cvar_t saved4 = {"saved4", "0", true};
|
||||
#endif
|
||||
|
||||
#define MAX_FIELD_LEN 64
|
||||
#define GEFV_CACHESIZE 2
|
||||
|
||||
|
@ -46,9 +69,11 @@ typedef struct {
|
|||
|
||||
static gefv_cache gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}};
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
func_t SpectatorConnect;
|
||||
func_t SpectatorThink;
|
||||
func_t SpectatorDisconnect;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -80,7 +105,11 @@ edict_t *ED_Alloc (void)
|
|||
int i;
|
||||
edict_t *e;
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
for ( i=MAX_CLIENTS+1 ; i<sv.num_edicts ; i++)
|
||||
#else
|
||||
for ( i=svs.maxclients+1 ; i<sv.num_edicts ; i++)
|
||||
#endif
|
||||
{
|
||||
e = EDICT_NUM(i);
|
||||
// the first couple seconds of server time can involve a lot of
|
||||
|
@ -93,6 +122,7 @@ edict_t *ED_Alloc (void)
|
|||
}
|
||||
|
||||
if (i == MAX_EDICTS)
|
||||
#ifdef QUAKEWORLD
|
||||
{
|
||||
Con_Printf ("WARNING: ED_Alloc: no free edicts\n");
|
||||
i--; // step on whatever is the last edict
|
||||
|
@ -101,6 +131,12 @@ edict_t *ED_Alloc (void)
|
|||
}
|
||||
else
|
||||
sv.num_edicts++;
|
||||
#else
|
||||
Sys_Error ("ED_Alloc: no free edicts");
|
||||
|
||||
sv.num_edicts++;
|
||||
#endif
|
||||
|
||||
e = EDICT_NUM(i);
|
||||
ED_ClearEdict (e);
|
||||
|
||||
|
@ -551,7 +587,15 @@ void ED_PrintEdict_f (void)
|
|||
int i;
|
||||
|
||||
i = Q_atoi (Cmd_Argv(1));
|
||||
#ifdef QUAKEWORLD
|
||||
Con_Printf ("\n EDICT %i:\n",i);
|
||||
#else
|
||||
if (i >= sv.num_edicts)
|
||||
{
|
||||
Con_Printf("Bad edict number\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
ED_PrintNum (i);
|
||||
}
|
||||
|
||||
|
@ -650,17 +694,29 @@ void ED_ParseGlobals (char *data)
|
|||
if (com_token[0] == '}')
|
||||
break;
|
||||
if (!data)
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("ED_ParseEntity: EOF without closing brace");
|
||||
#else
|
||||
Sys_Error ("ED_ParseEntity: EOF without closing brace");
|
||||
#endif
|
||||
|
||||
strcpy (keyname, com_token);
|
||||
|
||||
// parse value
|
||||
data = COM_Parse (data);
|
||||
if (!data)
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("ED_ParseEntity: EOF without closing brace");
|
||||
#else
|
||||
Sys_Error ("ED_ParseEntity: EOF without closing brace");
|
||||
#endif
|
||||
|
||||
if (com_token[0] == '}')
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("ED_ParseEntity: closing brace without data");
|
||||
#else
|
||||
Sys_Error ("ED_ParseEntity: closing brace without data");
|
||||
#endif
|
||||
|
||||
key = ED_FindGlobal (keyname);
|
||||
if (!key)
|
||||
|
@ -670,7 +726,11 @@ void ED_ParseGlobals (char *data)
|
|||
}
|
||||
|
||||
if (!ED_ParseEpair ((void *)pr_globals, key, com_token))
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("ED_ParseGlobals: parse error");
|
||||
#else
|
||||
Host_Error ("ED_ParseGlobals: parse error");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -797,6 +857,7 @@ char *ED_ParseEdict (char *data, edict_t *ent)
|
|||
qboolean anglehack;
|
||||
qboolean init;
|
||||
char keyname[256];
|
||||
int n;
|
||||
|
||||
init = false;
|
||||
|
||||
|
@ -812,7 +873,11 @@ char *ED_ParseEdict (char *data, edict_t *ent)
|
|||
if (com_token[0] == '}')
|
||||
break;
|
||||
if (!data)
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("ED_ParseEntity: EOF without closing brace");
|
||||
#else
|
||||
Sys_Error ("ED_ParseEntity: EOF without closing brace");
|
||||
#endif
|
||||
|
||||
// anglehack is to allow QuakeEd to write single scalar angles
|
||||
// and allow them to be turned into vectors. (FIXME...)
|
||||
|
@ -829,14 +894,32 @@ if (!strcmp(com_token, "light"))
|
|||
strcpy (com_token, "light_lev"); // hack for single light def
|
||||
|
||||
strcpy (keyname, com_token);
|
||||
|
||||
#ifndef QUAKEWORLD
|
||||
// another hack to fix heynames with trailing spaces
|
||||
n = strlen(keyname);
|
||||
while (n && keyname[n-1] == ' ')
|
||||
{
|
||||
keyname[n-1] = 0;
|
||||
n--;
|
||||
}
|
||||
#endif
|
||||
|
||||
// parse value
|
||||
data = COM_Parse (data);
|
||||
if (!data)
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("ED_ParseEntity: EOF without closing brace");
|
||||
#else
|
||||
Sys_Error ("ED_ParseEntity: EOF without closing brace");
|
||||
#endif
|
||||
|
||||
if (com_token[0] == '}')
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("ED_ParseEntity: closing brace without data");
|
||||
#else
|
||||
Sys_Error ("ED_ParseEntity: closing brace without data");
|
||||
#endif
|
||||
|
||||
init = true;
|
||||
|
||||
|
@ -860,7 +943,11 @@ sprintf (com_token, "0 %s 0", temp);
|
|||
}
|
||||
|
||||
if (!ED_ParseEpair ((void *)&ent->v, key, com_token))
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("ED_ParseEdict: parse error");
|
||||
#else
|
||||
Host_Error ("ED_ParseEdict: parse error");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!init)
|
||||
|
@ -903,7 +990,11 @@ void ED_LoadFromFile (char *data)
|
|||
if (!data)
|
||||
break;
|
||||
if (com_token[0] != '{')
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
|
||||
#else
|
||||
Sys_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
|
||||
#endif
|
||||
|
||||
if (!ent)
|
||||
ent = EDICT_NUM(0);
|
||||
|
@ -912,12 +1003,27 @@ void ED_LoadFromFile (char *data)
|
|||
data = ED_ParseEdict (data, ent);
|
||||
|
||||
// remove things from different skill levels or deathmatch
|
||||
if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
|
||||
#ifndef QUAKEWORLD
|
||||
if (deathmatch.value)
|
||||
{
|
||||
#endif
|
||||
if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
|
||||
{
|
||||
ED_Free (ent);
|
||||
inhibit++;
|
||||
continue;
|
||||
}
|
||||
#ifndef QUAKEWORLD
|
||||
}
|
||||
else if ((current_skill == 0 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_EASY))
|
||||
|| (current_skill == 1 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_MEDIUM))
|
||||
|| (current_skill >= 2 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_HARD)) )
|
||||
{
|
||||
ED_Free (ent);
|
||||
inhibit++;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// immediately call spawn function
|
||||
|
@ -943,7 +1049,9 @@ void ED_LoadFromFile (char *data)
|
|||
|
||||
pr_global_struct->self = EDICT_TO_PROG(ent);
|
||||
PR_ExecuteProgram (func - pr_functions);
|
||||
#ifdef QUAKEWORLD
|
||||
SV_FlushSignon();
|
||||
#endif
|
||||
}
|
||||
|
||||
Con_DPrintf ("%i entities inhibited\n", inhibit);
|
||||
|
@ -965,25 +1073,48 @@ void PR_LoadProgs (void)
|
|||
for (i=0 ; i<GEFV_CACHESIZE ; i++)
|
||||
gefvCache[i].field[0] = 0;
|
||||
|
||||
#ifndef QUAKEWORLD
|
||||
CRC_Init (&pr_crc);
|
||||
#endif
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
progs = (dprograms_t *)COM_LoadHunkFile ("qwprogs.dat");
|
||||
if (!progs)
|
||||
#endif
|
||||
progs = (dprograms_t *)COM_LoadHunkFile ("progs.dat");
|
||||
if (!progs)
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("PR_LoadProgs: couldn't load progs.dat");
|
||||
#else
|
||||
Sys_Error ("PR_LoadProgs: couldn't load progs.dat");
|
||||
#endif
|
||||
Con_DPrintf ("Programs occupy %iK.\n", com_filesize/1024);
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
// add prog crc to the serverinfo
|
||||
sprintf (num, "%i", CRC_Block ((byte *)progs, com_filesize));
|
||||
Info_SetValueForStarKey (svs.info, "*progs", num, MAX_SERVERINFO_STRING);
|
||||
#else
|
||||
for (i=0 ; i<com_filesize ; i++)
|
||||
CRC_ProcessByte (&pr_crc, ((byte *)progs)[i]);
|
||||
#endif
|
||||
|
||||
// byte swap the header
|
||||
for (i=0 ; i<sizeof(*progs)/4 ; i++)
|
||||
((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
|
||||
|
||||
if (progs->version != PROG_VERSION)
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
|
||||
#else
|
||||
Sys_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
|
||||
#endif
|
||||
if (progs->crc != PROGHEADER_CRC)
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("You must have the progs.dat from QuakeWorld installed");
|
||||
#else
|
||||
Sys_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
|
||||
#endif
|
||||
|
||||
pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions);
|
||||
pr_strings = (char *)progs + progs->ofs_strings;
|
||||
|
@ -991,7 +1122,9 @@ void PR_LoadProgs (void)
|
|||
pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs);
|
||||
pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements);
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
num_prstr = 0;
|
||||
#endif
|
||||
|
||||
pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals);
|
||||
pr_globals = (float *)pr_global_struct;
|
||||
|
@ -1028,7 +1161,11 @@ void PR_LoadProgs (void)
|
|||
{
|
||||
pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type);
|
||||
if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
|
||||
#else
|
||||
Sys_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
|
||||
#endif
|
||||
pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs);
|
||||
pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name);
|
||||
}
|
||||
|
@ -1036,6 +1173,7 @@ void PR_LoadProgs (void)
|
|||
for (i=0 ; i<progs->numglobals ; i++)
|
||||
((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
// Zoid, find the spectator functions
|
||||
SpectatorConnect = SpectatorThink = SpectatorDisconnect = 0;
|
||||
|
||||
|
@ -1045,6 +1183,7 @@ void PR_LoadProgs (void)
|
|||
SpectatorThink = (func_t)(f - pr_functions);
|
||||
if ((f = ED_FindFunction ("SpectatorDisconnect")) != NULL)
|
||||
SpectatorDisconnect = (func_t)(f - pr_functions);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1059,6 +1198,19 @@ void PR_Init (void)
|
|||
Cmd_AddCommand ("edicts", ED_PrintEdicts);
|
||||
Cmd_AddCommand ("edictcount", ED_Count);
|
||||
Cmd_AddCommand ("profile", PR_Profile_f);
|
||||
#ifndef QUAKEWORLD
|
||||
Cvar_RegisterVariable (&nomonsters);
|
||||
Cvar_RegisterVariable (&gamecfg);
|
||||
Cvar_RegisterVariable (&scratch1);
|
||||
Cvar_RegisterVariable (&scratch2);
|
||||
Cvar_RegisterVariable (&scratch3);
|
||||
Cvar_RegisterVariable (&scratch4);
|
||||
Cvar_RegisterVariable (&savedgamecfg);
|
||||
Cvar_RegisterVariable (&saved1);
|
||||
Cvar_RegisterVariable (&saved2);
|
||||
Cvar_RegisterVariable (&saved3);
|
||||
Cvar_RegisterVariable (&saved4);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1066,7 +1218,11 @@ void PR_Init (void)
|
|||
edict_t *EDICT_NUM(int n)
|
||||
{
|
||||
if (n < 0 || n >= MAX_EDICTS)
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("EDICT_NUM: bad number %i", n);
|
||||
#else
|
||||
Sys_Error ("EDICT_NUM: bad number %i", n);
|
||||
#endif
|
||||
return (edict_t *)((byte *)sv.edicts+ (n)*pr_edict_size);
|
||||
}
|
||||
|
||||
|
@ -1078,7 +1234,11 @@ int NUM_FOR_EDICT(edict_t *e)
|
|||
b = b / pr_edict_size;
|
||||
|
||||
if (b < 0 || b >= sv.num_edicts)
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("NUM_FOR_EDICT: bad pointer");
|
||||
#else
|
||||
Sys_Error ("NUM_FOR_EDICT: bad pointer");
|
||||
#endif
|
||||
return b;
|
||||
}
|
||||
|
|
@ -18,7 +18,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
*/
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
#include "qwsvdef.h"
|
||||
#else
|
||||
#include "quakedef.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -271,9 +275,13 @@ void PR_RunError (char *error, ...)
|
|||
PR_StackTrace ();
|
||||
Con_Printf ("%s\n", string);
|
||||
|
||||
pr_depth = 0; // dump the stack so SV_Error can shutdown functions
|
||||
pr_depth = 0; // dump the stack so {SV|Host}_Error can shutdown functions
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("Program error");
|
||||
#else
|
||||
Host_Error ("Program error");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -335,7 +343,11 @@ int PR_LeaveFunction (void)
|
|||
int i, c;
|
||||
|
||||
if (pr_depth <= 0)
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("prog stack underflow");
|
||||
#else
|
||||
Sys_Error ("prog stack underflow");
|
||||
#endif
|
||||
|
||||
// restore locals from the stack
|
||||
c = pr_xfunction->locals;
|
||||
|
@ -374,7 +386,11 @@ void PR_ExecuteProgram (func_t fnum)
|
|||
{
|
||||
if (pr_global_struct->self)
|
||||
ED_Print (PROG_TO_EDICT(pr_global_struct->self));
|
||||
#ifdef QUAKEWORLD
|
||||
SV_Error ("PR_ExecuteProgram: NULL function");
|
||||
#else
|
||||
Host_Error ("PR_ExecuteProgram: NULL function");
|
||||
#endif
|
||||
}
|
||||
|
||||
f = &pr_functions[fnum];
|
||||
|
@ -648,7 +664,16 @@ while (1)
|
|||
|
||||
case OP_STATE:
|
||||
ed = PROG_TO_EDICT(pr_global_struct->self);
|
||||
#ifdef QUAKEWORLD
|
||||
ed->v.nextthink = pr_global_struct->time + 0.1;
|
||||
#else
|
||||
# ifdef FPS_20
|
||||
ed->v.nextthink = pr_global_struct->time + 0.05;
|
||||
# else
|
||||
ed->v.nextthink = pr_global_struct->time + 0.1;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if (a->_float != ed->v.frame)
|
||||
{
|
||||
ed->v.frame = a->_float;
|
||||
|
@ -665,15 +690,22 @@ while (1)
|
|||
|
||||
/*----------------------*/
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
|
||||
char *pr_strtbl[MAX_PRSTR];
|
||||
int num_prstr;
|
||||
|
||||
#endif
|
||||
|
||||
char *PR_GetString(int num)
|
||||
{
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
if (num < 0) {
|
||||
//Con_DPrintf("GET:%d == %s\n", num, pr_strtbl[-num]);
|
||||
return pr_strtbl[-num];
|
||||
}
|
||||
#endif
|
||||
return pr_strings + num;
|
||||
}
|
||||
|
||||
|
@ -681,6 +713,7 @@ int PR_SetString(char *s)
|
|||
{
|
||||
int i;
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
if (s - pr_strings < 0) {
|
||||
for (i = 0; i <= num_prstr; i++)
|
||||
if (pr_strtbl[i] == s)
|
||||
|
@ -694,6 +727,7 @@ int PR_SetString(char *s)
|
|||
//Con_DPrintf("SET:%d == %s\n", -num_prstr, s);
|
||||
return -num_prstr;
|
||||
}
|
||||
#endif
|
||||
return (int)(s - pr_strings);
|
||||
}
|
||||
|
|
@ -123,9 +123,13 @@ extern qboolean pr_trace;
|
|||
extern dfunction_t *pr_xfunction;
|
||||
extern int pr_xstatement;
|
||||
|
||||
#ifdef QUAKEWORLD
|
||||
extern func_t SpectatorConnect;
|
||||
extern func_t SpectatorThink;
|
||||
extern func_t SpectatorDisconnect;
|
||||
#else
|
||||
extern unsigned short pr_crc;
|
||||
#endif
|
||||
|
||||
void PR_RunError (char *error, ...);
|
||||
|
1934
uquake/pr_cmds.c
1934
uquake/pr_cmds.c
File diff suppressed because it is too large
Load diff
1106
uquake/pr_edict.c
1106
uquake/pr_edict.c
File diff suppressed because it is too large
Load diff
668
uquake/pr_exec.c
668
uquake/pr_exec.c
|
@ -1,668 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int s;
|
||||
dfunction_t *f;
|
||||
} prstack_t;
|
||||
|
||||
#define MAX_STACK_DEPTH 32
|
||||
prstack_t pr_stack[MAX_STACK_DEPTH];
|
||||
int pr_depth;
|
||||
|
||||
#define LOCALSTACK_SIZE 2048
|
||||
int localstack[LOCALSTACK_SIZE];
|
||||
int localstack_used;
|
||||
|
||||
|
||||
qboolean pr_trace;
|
||||
dfunction_t *pr_xfunction;
|
||||
int pr_xstatement;
|
||||
|
||||
|
||||
int pr_argc;
|
||||
|
||||
char *pr_opnames[] =
|
||||
{
|
||||
"DONE",
|
||||
|
||||
"MUL_F",
|
||||
"MUL_V",
|
||||
"MUL_FV",
|
||||
"MUL_VF",
|
||||
|
||||
"DIV",
|
||||
|
||||
"ADD_F",
|
||||
"ADD_V",
|
||||
|
||||
"SUB_F",
|
||||
"SUB_V",
|
||||
|
||||
"EQ_F",
|
||||
"EQ_V",
|
||||
"EQ_S",
|
||||
"EQ_E",
|
||||
"EQ_FNC",
|
||||
|
||||
"NE_F",
|
||||
"NE_V",
|
||||
"NE_S",
|
||||
"NE_E",
|
||||
"NE_FNC",
|
||||
|
||||
"LE",
|
||||
"GE",
|
||||
"LT",
|
||||
"GT",
|
||||
|
||||
"INDIRECT",
|
||||
"INDIRECT",
|
||||
"INDIRECT",
|
||||
"INDIRECT",
|
||||
"INDIRECT",
|
||||
"INDIRECT",
|
||||
|
||||
"ADDRESS",
|
||||
|
||||
"STORE_F",
|
||||
"STORE_V",
|
||||
"STORE_S",
|
||||
"STORE_ENT",
|
||||
"STORE_FLD",
|
||||
"STORE_FNC",
|
||||
|
||||
"STOREP_F",
|
||||
"STOREP_V",
|
||||
"STOREP_S",
|
||||
"STOREP_ENT",
|
||||
"STOREP_FLD",
|
||||
"STOREP_FNC",
|
||||
|
||||
"RETURN",
|
||||
|
||||
"NOT_F",
|
||||
"NOT_V",
|
||||
"NOT_S",
|
||||
"NOT_ENT",
|
||||
"NOT_FNC",
|
||||
|
||||
"IF",
|
||||
"IFNOT",
|
||||
|
||||
"CALL0",
|
||||
"CALL1",
|
||||
"CALL2",
|
||||
"CALL3",
|
||||
"CALL4",
|
||||
"CALL5",
|
||||
"CALL6",
|
||||
"CALL7",
|
||||
"CALL8",
|
||||
|
||||
"STATE",
|
||||
|
||||
"GOTO",
|
||||
|
||||
"AND",
|
||||
"OR",
|
||||
|
||||
"BITAND",
|
||||
"BITOR"
|
||||
};
|
||||
|
||||
char *PR_GlobalString (int ofs);
|
||||
char *PR_GlobalStringNoContents (int ofs);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
=================
|
||||
PR_PrintStatement
|
||||
=================
|
||||
*/
|
||||
void PR_PrintStatement (dstatement_t *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( (unsigned)s->op < sizeof(pr_opnames)/sizeof(pr_opnames[0]))
|
||||
{
|
||||
Con_Printf ("%s ", pr_opnames[s->op]);
|
||||
i = strlen(pr_opnames[s->op]);
|
||||
for ( ; i<10 ; i++)
|
||||
Con_Printf (" ");
|
||||
}
|
||||
|
||||
if (s->op == OP_IF || s->op == OP_IFNOT)
|
||||
Con_Printf ("%sbranch %i",PR_GlobalString(s->a),s->b);
|
||||
else if (s->op == OP_GOTO)
|
||||
{
|
||||
Con_Printf ("branch %i",s->a);
|
||||
}
|
||||
else if ( (unsigned)(s->op - OP_STORE_F) < 6)
|
||||
{
|
||||
Con_Printf ("%s",PR_GlobalString(s->a));
|
||||
Con_Printf ("%s", PR_GlobalStringNoContents(s->b));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s->a)
|
||||
Con_Printf ("%s",PR_GlobalString(s->a));
|
||||
if (s->b)
|
||||
Con_Printf ("%s",PR_GlobalString(s->b));
|
||||
if (s->c)
|
||||
Con_Printf ("%s", PR_GlobalStringNoContents(s->c));
|
||||
}
|
||||
Con_Printf ("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
PR_StackTrace
|
||||
============
|
||||
*/
|
||||
void PR_StackTrace (void)
|
||||
{
|
||||
dfunction_t *f;
|
||||
int i;
|
||||
|
||||
if (pr_depth == 0)
|
||||
{
|
||||
Con_Printf ("<NO STACK>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pr_stack[pr_depth].f = pr_xfunction;
|
||||
for (i=pr_depth ; i>=0 ; i--)
|
||||
{
|
||||
f = pr_stack[i].f;
|
||||
|
||||
if (!f)
|
||||
{
|
||||
Con_Printf ("<NO FUNCTION>\n");
|
||||
}
|
||||
else
|
||||
Con_Printf ("%12s : %s\n", pr_strings + f->s_file, pr_strings + f->s_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
PR_Profile_f
|
||||
|
||||
============
|
||||
*/
|
||||
void PR_Profile_f (void)
|
||||
{
|
||||
dfunction_t *f, *best;
|
||||
int max;
|
||||
int num;
|
||||
int i;
|
||||
|
||||
num = 0;
|
||||
do
|
||||
{
|
||||
max = 0;
|
||||
best = NULL;
|
||||
for (i=0 ; i<progs->numfunctions ; i++)
|
||||
{
|
||||
f = &pr_functions[i];
|
||||
if (f->profile > max)
|
||||
{
|
||||
max = f->profile;
|
||||
best = f;
|
||||
}
|
||||
}
|
||||
if (best)
|
||||
{
|
||||
if (num < 10)
|
||||
Con_Printf ("%7i %s\n", best->profile, pr_strings+best->s_name);
|
||||
num++;
|
||||
best->profile = 0;
|
||||
}
|
||||
} while (best);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
PR_RunError
|
||||
|
||||
Aborts the currently executing function
|
||||
============
|
||||
*/
|
||||
void PR_RunError (char *error, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
|
||||
va_start (argptr,error);
|
||||
vsprintf (string,error,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
PR_PrintStatement (pr_statements + pr_xstatement);
|
||||
PR_StackTrace ();
|
||||
Con_Printf ("%s\n", string);
|
||||
|
||||
pr_depth = 0; // dump the stack so host_error can shutdown functions
|
||||
|
||||
Host_Error ("Program error");
|
||||
}
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
PR_ExecuteProgram
|
||||
|
||||
The interpretation main loop
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
====================
|
||||
PR_EnterFunction
|
||||
|
||||
Returns the new program statement counter
|
||||
====================
|
||||
*/
|
||||
int PR_EnterFunction (dfunction_t *f)
|
||||
{
|
||||
int i, j, c, o;
|
||||
|
||||
pr_stack[pr_depth].s = pr_xstatement;
|
||||
pr_stack[pr_depth].f = pr_xfunction;
|
||||
pr_depth++;
|
||||
if (pr_depth >= MAX_STACK_DEPTH)
|
||||
PR_RunError ("stack overflow");
|
||||
|
||||
// save off any locals that the new function steps on
|
||||
c = f->locals;
|
||||
if (localstack_used + c > LOCALSTACK_SIZE)
|
||||
PR_RunError ("PR_ExecuteProgram: locals stack overflow\n");
|
||||
|
||||
for (i=0 ; i < c ; i++)
|
||||
localstack[localstack_used+i] = ((int *)pr_globals)[f->parm_start + i];
|
||||
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 *)pr_globals)[o] = ((int *)pr_globals)[OFS_PARM0+i*3+j];
|
||||
o++;
|
||||
}
|
||||
}
|
||||
|
||||
pr_xfunction = f;
|
||||
return f->first_statement - 1; // offset the s++
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
PR_LeaveFunction
|
||||
====================
|
||||
*/
|
||||
int PR_LeaveFunction (void)
|
||||
{
|
||||
int i, c;
|
||||
|
||||
if (pr_depth <= 0)
|
||||
Sys_Error ("prog stack underflow");
|
||||
|
||||
// restore locals from the stack
|
||||
c = pr_xfunction->locals;
|
||||
localstack_used -= c;
|
||||
if (localstack_used < 0)
|
||||
PR_RunError ("PR_ExecuteProgram: locals stack underflow\n");
|
||||
|
||||
for (i=0 ; i < c ; i++)
|
||||
((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used+i];
|
||||
|
||||
// up stack
|
||||
pr_depth--;
|
||||
pr_xfunction = pr_stack[pr_depth].f;
|
||||
return pr_stack[pr_depth].s;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
PR_ExecuteProgram
|
||||
====================
|
||||
*/
|
||||
void PR_ExecuteProgram (func_t fnum)
|
||||
{
|
||||
eval_t *a, *b, *c;
|
||||
int s;
|
||||
dstatement_t *st;
|
||||
dfunction_t *f, *newf;
|
||||
int runaway;
|
||||
int i;
|
||||
edict_t *ed;
|
||||
int exitdepth;
|
||||
eval_t *ptr;
|
||||
|
||||
if (!fnum || fnum >= progs->numfunctions)
|
||||
{
|
||||
if (pr_global_struct->self)
|
||||
ED_Print (PROG_TO_EDICT(pr_global_struct->self));
|
||||
Host_Error ("PR_ExecuteProgram: NULL function");
|
||||
}
|
||||
|
||||
f = &pr_functions[fnum];
|
||||
|
||||
runaway = 100000;
|
||||
pr_trace = false;
|
||||
|
||||
// make a stack frame
|
||||
exitdepth = pr_depth;
|
||||
|
||||
s = PR_EnterFunction (f);
|
||||
|
||||
while (1)
|
||||
{
|
||||
s++; // next statement
|
||||
|
||||
st = &pr_statements[s];
|
||||
a = (eval_t *)&pr_globals[st->a];
|
||||
b = (eval_t *)&pr_globals[st->b];
|
||||
c = (eval_t *)&pr_globals[st->c];
|
||||
|
||||
if (!--runaway)
|
||||
PR_RunError ("runaway loop error");
|
||||
|
||||
pr_xfunction->profile++;
|
||||
pr_xstatement = s;
|
||||
|
||||
if (pr_trace)
|
||||
PR_PrintStatement (st);
|
||||
|
||||
switch (st->op)
|
||||
{
|
||||
case OP_ADD_F:
|
||||
c->_float = a->_float + b->_float;
|
||||
break;
|
||||
case OP_ADD_V:
|
||||
c->vector[0] = a->vector[0] + b->vector[0];
|
||||
c->vector[1] = a->vector[1] + b->vector[1];
|
||||
c->vector[2] = a->vector[2] + b->vector[2];
|
||||
break;
|
||||
|
||||
case OP_SUB_F:
|
||||
c->_float = a->_float - b->_float;
|
||||
break;
|
||||
case OP_SUB_V:
|
||||
c->vector[0] = a->vector[0] - b->vector[0];
|
||||
c->vector[1] = a->vector[1] - b->vector[1];
|
||||
c->vector[2] = a->vector[2] - b->vector[2];
|
||||
break;
|
||||
|
||||
case OP_MUL_F:
|
||||
c->_float = a->_float * b->_float;
|
||||
break;
|
||||
case OP_MUL_V:
|
||||
c->_float = a->vector[0]*b->vector[0]
|
||||
+ a->vector[1]*b->vector[1]
|
||||
+ a->vector[2]*b->vector[2];
|
||||
break;
|
||||
case OP_MUL_FV:
|
||||
c->vector[0] = a->_float * b->vector[0];
|
||||
c->vector[1] = a->_float * b->vector[1];
|
||||
c->vector[2] = a->_float * b->vector[2];
|
||||
break;
|
||||
case OP_MUL_VF:
|
||||
c->vector[0] = b->_float * a->vector[0];
|
||||
c->vector[1] = b->_float * a->vector[1];
|
||||
c->vector[2] = b->_float * a->vector[2];
|
||||
break;
|
||||
|
||||
case OP_DIV_F:
|
||||
c->_float = a->_float / b->_float;
|
||||
break;
|
||||
|
||||
case OP_BITAND:
|
||||
c->_float = (int)a->_float & (int)b->_float;
|
||||
break;
|
||||
|
||||
case OP_BITOR:
|
||||
c->_float = (int)a->_float | (int)b->_float;
|
||||
break;
|
||||
|
||||
|
||||
case OP_GE:
|
||||
c->_float = a->_float >= b->_float;
|
||||
break;
|
||||
case OP_LE:
|
||||
c->_float = a->_float <= b->_float;
|
||||
break;
|
||||
case OP_GT:
|
||||
c->_float = a->_float > b->_float;
|
||||
break;
|
||||
case OP_LT:
|
||||
c->_float = a->_float < b->_float;
|
||||
break;
|
||||
case OP_AND:
|
||||
c->_float = a->_float && b->_float;
|
||||
break;
|
||||
case OP_OR:
|
||||
c->_float = a->_float || b->_float;
|
||||
break;
|
||||
|
||||
case OP_NOT_F:
|
||||
c->_float = !a->_float;
|
||||
break;
|
||||
case OP_NOT_V:
|
||||
c->_float = !a->vector[0] && !a->vector[1] && !a->vector[2];
|
||||
break;
|
||||
case OP_NOT_S:
|
||||
c->_float = !a->string || !pr_strings[a->string];
|
||||
break;
|
||||
case OP_NOT_FNC:
|
||||
c->_float = !a->function;
|
||||
break;
|
||||
case OP_NOT_ENT:
|
||||
c->_float = (PROG_TO_EDICT(a->edict) == sv.edicts);
|
||||
break;
|
||||
|
||||
case OP_EQ_F:
|
||||
c->_float = a->_float == b->_float;
|
||||
break;
|
||||
case OP_EQ_V:
|
||||
c->_float = (a->vector[0] == b->vector[0]) &&
|
||||
(a->vector[1] == b->vector[1]) &&
|
||||
(a->vector[2] == b->vector[2]);
|
||||
break;
|
||||
case OP_EQ_S:
|
||||
c->_float = !strcmp(pr_strings+a->string,pr_strings+b->string);
|
||||
break;
|
||||
case OP_EQ_E:
|
||||
c->_float = a->_int == b->_int;
|
||||
break;
|
||||
case OP_EQ_FNC:
|
||||
c->_float = a->function == b->function;
|
||||
break;
|
||||
|
||||
|
||||
case OP_NE_F:
|
||||
c->_float = a->_float != b->_float;
|
||||
break;
|
||||
case OP_NE_V:
|
||||
c->_float = (a->vector[0] != b->vector[0]) ||
|
||||
(a->vector[1] != b->vector[1]) ||
|
||||
(a->vector[2] != b->vector[2]);
|
||||
break;
|
||||
case OP_NE_S:
|
||||
c->_float = strcmp(pr_strings+a->string,pr_strings+b->string);
|
||||
break;
|
||||
case OP_NE_E:
|
||||
c->_float = a->_int != b->_int;
|
||||
break;
|
||||
case OP_NE_FNC:
|
||||
c->_float = a->function != b->function;
|
||||
break;
|
||||
|
||||
//==================
|
||||
case OP_STORE_F:
|
||||
case OP_STORE_ENT:
|
||||
case OP_STORE_FLD: // integers
|
||||
case OP_STORE_S:
|
||||
case OP_STORE_FNC: // pointers
|
||||
b->_int = a->_int;
|
||||
break;
|
||||
case OP_STORE_V:
|
||||
b->vector[0] = a->vector[0];
|
||||
b->vector[1] = a->vector[1];
|
||||
b->vector[2] = a->vector[2];
|
||||
break;
|
||||
|
||||
case OP_STOREP_F:
|
||||
case OP_STOREP_ENT:
|
||||
case OP_STOREP_FLD: // integers
|
||||
case OP_STOREP_S:
|
||||
case OP_STOREP_FNC: // pointers
|
||||
ptr = (eval_t *)((byte *)sv.edicts + b->_int);
|
||||
ptr->_int = a->_int;
|
||||
break;
|
||||
case OP_STOREP_V:
|
||||
ptr = (eval_t *)((byte *)sv.edicts + b->_int);
|
||||
ptr->vector[0] = a->vector[0];
|
||||
ptr->vector[1] = a->vector[1];
|
||||
ptr->vector[2] = a->vector[2];
|
||||
break;
|
||||
|
||||
case OP_ADDRESS:
|
||||
ed = PROG_TO_EDICT(a->edict);
|
||||
#ifdef PARANOID
|
||||
NUM_FOR_EDICT(ed); // make sure it's in range
|
||||
#endif
|
||||
if (ed == (edict_t *)sv.edicts && sv.state == ss_active)
|
||||
PR_RunError ("assignment to world entity");
|
||||
c->_int = (byte *)((int *)&ed->v + b->_int) - (byte *)sv.edicts;
|
||||
break;
|
||||
|
||||
case OP_LOAD_F:
|
||||
case OP_LOAD_FLD:
|
||||
case OP_LOAD_ENT:
|
||||
case OP_LOAD_S:
|
||||
case OP_LOAD_FNC:
|
||||
ed = PROG_TO_EDICT(a->edict);
|
||||
#ifdef PARANOID
|
||||
NUM_FOR_EDICT(ed); // make sure it's in range
|
||||
#endif
|
||||
a = (eval_t *)((int *)&ed->v + b->_int);
|
||||
c->_int = a->_int;
|
||||
break;
|
||||
|
||||
case OP_LOAD_V:
|
||||
ed = PROG_TO_EDICT(a->edict);
|
||||
#ifdef PARANOID
|
||||
NUM_FOR_EDICT(ed); // make sure it's in range
|
||||
#endif
|
||||
a = (eval_t *)((int *)&ed->v + b->_int);
|
||||
c->vector[0] = a->vector[0];
|
||||
c->vector[1] = a->vector[1];
|
||||
c->vector[2] = a->vector[2];
|
||||
break;
|
||||
|
||||
//==================
|
||||
|
||||
case OP_IFNOT:
|
||||
if (!a->_int)
|
||||
s += st->b - 1; // offset the s++
|
||||
break;
|
||||
|
||||
case OP_IF:
|
||||
if (a->_int)
|
||||
s += st->b - 1; // offset the s++
|
||||
break;
|
||||
|
||||
case OP_GOTO:
|
||||
s += st->a - 1; // offset the s++
|
||||
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:
|
||||
pr_argc = st->op - OP_CALL0;
|
||||
if (!a->function)
|
||||
PR_RunError ("NULL function");
|
||||
|
||||
newf = &pr_functions[a->function];
|
||||
|
||||
if (newf->first_statement < 0)
|
||||
{ // negative statements are built in functions
|
||||
i = -newf->first_statement;
|
||||
if (i >= pr_numbuiltins)
|
||||
PR_RunError ("Bad builtin call number");
|
||||
pr_builtins[i] ();
|
||||
break;
|
||||
}
|
||||
|
||||
s = PR_EnterFunction (newf);
|
||||
break;
|
||||
|
||||
case OP_DONE:
|
||||
case OP_RETURN:
|
||||
pr_globals[OFS_RETURN] = pr_globals[st->a];
|
||||
pr_globals[OFS_RETURN+1] = pr_globals[st->a+1];
|
||||
pr_globals[OFS_RETURN+2] = pr_globals[st->a+2];
|
||||
|
||||
s = PR_LeaveFunction ();
|
||||
if (pr_depth == exitdepth)
|
||||
return; // all done
|
||||
break;
|
||||
|
||||
case OP_STATE:
|
||||
ed = PROG_TO_EDICT(pr_global_struct->self);
|
||||
#ifdef FPS_20
|
||||
ed->v.nextthink = pr_global_struct->time + 0.05;
|
||||
#else
|
||||
ed->v.nextthink = pr_global_struct->time + 0.1;
|
||||
#endif
|
||||
if (a->_float != ed->v.frame)
|
||||
{
|
||||
ed->v.frame = a->_float;
|
||||
}
|
||||
ed->v.think = b->function;
|
||||
break;
|
||||
|
||||
default:
|
||||
PR_RunError ("Bad opcode %i", st->op);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
134
uquake/progs.h
134
uquake/progs.h
|
@ -1,134 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "pr_comp.h" // defs shared with qcc
|
||||
#include "progdefs.h" // generated by program cdefs
|
||||
|
||||
typedef union eval_s
|
||||
{
|
||||
string_t string;
|
||||
float _float;
|
||||
float vector[3];
|
||||
func_t function;
|
||||
int _int;
|
||||
int edict;
|
||||
} eval_t;
|
||||
|
||||
#define MAX_ENT_LEAFS 16
|
||||
typedef struct edict_s
|
||||
{
|
||||
qboolean free;
|
||||
link_t area; // linked to a division node or leaf
|
||||
|
||||
int num_leafs;
|
||||
short leafnums[MAX_ENT_LEAFS];
|
||||
|
||||
entity_state_t baseline;
|
||||
|
||||
float freetime; // sv.time when the object was freed
|
||||
entvars_t v; // C exported fields from progs
|
||||
// other fields from progs come immediately after
|
||||
} edict_t;
|
||||
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
|
||||
|
||||
//============================================================================
|
||||
|
||||
extern dprograms_t *progs;
|
||||
extern dfunction_t *pr_functions;
|
||||
extern char *pr_strings;
|
||||
extern ddef_t *pr_globaldefs;
|
||||
extern ddef_t *pr_fielddefs;
|
||||
extern dstatement_t *pr_statements;
|
||||
extern globalvars_t *pr_global_struct;
|
||||
extern float *pr_globals; // same as pr_global_struct
|
||||
|
||||
extern int pr_edict_size; // in bytes
|
||||
|
||||
//============================================================================
|
||||
|
||||
void PR_Init (void);
|
||||
|
||||
void PR_ExecuteProgram (func_t fnum);
|
||||
void PR_LoadProgs (void);
|
||||
|
||||
void PR_Profile_f (void);
|
||||
|
||||
edict_t *ED_Alloc (void);
|
||||
void ED_Free (edict_t *ed);
|
||||
|
||||
char *ED_NewString (char *string);
|
||||
// returns a copy of the string allocated from the server's string heap
|
||||
|
||||
void ED_Print (edict_t *ed);
|
||||
void ED_Write (FILE *f, edict_t *ed);
|
||||
char *ED_ParseEdict (char *data, edict_t *ent);
|
||||
|
||||
void ED_WriteGlobals (FILE *f);
|
||||
void ED_ParseGlobals (char *data);
|
||||
|
||||
void ED_LoadFromFile (char *data);
|
||||
|
||||
//define EDICT_NUM(n) ((edict_t *)(sv.edicts+ (n)*pr_edict_size))
|
||||
//define NUM_FOR_EDICT(e) (((byte *)(e) - sv.edicts)/pr_edict_size)
|
||||
|
||||
edict_t *EDICT_NUM(int n);
|
||||
int NUM_FOR_EDICT(edict_t *e);
|
||||
|
||||
#define NEXT_EDICT(e) ((edict_t *)( (byte *)e + pr_edict_size))
|
||||
|
||||
#define EDICT_TO_PROG(e) ((byte *)e - (byte *)sv.edicts)
|
||||
#define PROG_TO_EDICT(e) ((edict_t *)((byte *)sv.edicts + e))
|
||||
|
||||
//============================================================================
|
||||
|
||||
#define G_FLOAT(o) (pr_globals[o])
|
||||
#define G_INT(o) (*(int *)&pr_globals[o])
|
||||
#define G_EDICT(o) ((edict_t *)((byte *)sv.edicts+ *(int *)&pr_globals[o]))
|
||||
#define G_EDICTNUM(o) NUM_FOR_EDICT(G_EDICT(o))
|
||||
#define G_VECTOR(o) (&pr_globals[o])
|
||||
#define G_STRING(o) (pr_strings + *(string_t *)&pr_globals[o])
|
||||
#define G_FUNCTION(o) (*(func_t *)&pr_globals[o])
|
||||
|
||||
#define E_FLOAT(e,o) (((float*)&e->v)[o])
|
||||
#define E_INT(e,o) (*(int *)&((float*)&e->v)[o])
|
||||
#define E_VECTOR(e,o) (&((float*)&e->v)[o])
|
||||
#define E_STRING(e,o) (pr_strings + *(string_t *)&((float*)&e->v)[o])
|
||||
|
||||
extern int type_size[8];
|
||||
|
||||
typedef void (*builtin_t) (void);
|
||||
extern builtin_t *pr_builtins;
|
||||
extern int pr_numbuiltins;
|
||||
|
||||
extern int pr_argc;
|
||||
|
||||
extern qboolean pr_trace;
|
||||
extern dfunction_t *pr_xfunction;
|
||||
extern int pr_xstatement;
|
||||
|
||||
extern unsigned short pr_crc;
|
||||
|
||||
void PR_RunError (char *error, ...);
|
||||
|
||||
void ED_PrintEdicts (void);
|
||||
void ED_PrintNum (int ent);
|
||||
|
||||
eval_t *GetEdictFieldValue(edict_t *ed, char *field);
|
||||
|
Loading…
Reference in a new issue