summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2001-08-03 02:05:01 +0000
committerTim Angus <tim@ngus.net>2001-08-03 02:05:01 +0000
commit20591193bd705c876d1c1d21383438200f017407 (patch)
tree129a72ec49b772d029d7cd0106532024143e00cc /src
parentde7fdcb516d39976affbea3b69b5a32e11fc4a6a (diff)
1.29h upgrade.. oooo particles hehehehehehe
Diffstat (limited to 'src')
-rw-r--r--src/cgame/cg_particles.c1997
-rw-r--r--src/game/bg_pmove.c4
-rw-r--r--src/game/g_combat.c4
-rw-r--r--src/game/q_math.c134
-rw-r--r--src/game/q_shared.c178
-rw-r--r--src/game/q_shared.h1325
-rw-r--r--src/game/surfaceflags.h4
7 files changed, 2955 insertions, 691 deletions
diff --git a/src/cgame/cg_particles.c b/src/cgame/cg_particles.c
new file mode 100644
index 00000000..ac709a1b
--- /dev/null
+++ b/src/cgame/cg_particles.c
@@ -0,0 +1,1997 @@
+// Rafael particles
+// cg_particles.c
+
+#include "cg_local.h"
+
+#define BLOODRED 2
+#define EMISIVEFADE 3
+#define GREY75 4
+
+typedef struct particle_s
+{
+ struct particle_s *next;
+
+ float time;
+ float endtime;
+
+ vec3_t org;
+ vec3_t vel;
+ vec3_t accel;
+ int color;
+ float colorvel;
+ float alpha;
+ float alphavel;
+ int type;
+ qhandle_t pshader;
+
+ float height;
+ float width;
+
+ float endheight;
+ float endwidth;
+
+ float start;
+ float end;
+
+ float startfade;
+ qboolean rotate;
+ int snum;
+
+ qboolean link;
+
+ // Ridah
+ int shaderAnim;
+ int roll;
+
+ int accumroll;
+
+} cparticle_t;
+
+typedef enum
+{
+ P_NONE,
+ P_WEATHER,
+ P_FLAT,
+ P_SMOKE,
+ P_ROTATE,
+ P_WEATHER_TURBULENT,
+ P_ANIM, // Ridah
+ P_BAT,
+ P_BLEED,
+ P_FLAT_SCALEUP,
+ P_FLAT_SCALEUP_FADE,
+ P_WEATHER_FLURRY,
+ P_SMOKE_IMPACT,
+ P_BUBBLE,
+ P_BUBBLE_TURBULENT,
+ P_SPRITE
+} particle_type_t;
+
+#define MAX_SHADER_ANIMS 32
+#define MAX_SHADER_ANIM_FRAMES 64
+
+static char *shaderAnimNames[MAX_SHADER_ANIMS] = {
+ "explode1",
+ "blacksmokeanim",
+ "twiltb2",
+ "expblue",
+ "blacksmokeanimb", // uses 'explode1' sequence
+ "blood",
+ NULL
+};
+static qhandle_t shaderAnims[MAX_SHADER_ANIMS][MAX_SHADER_ANIM_FRAMES];
+static int shaderAnimCounts[MAX_SHADER_ANIMS] = {
+ 23,
+ 25,
+ 45,
+ 25,
+ 23,
+ 5,
+};
+static float shaderAnimSTRatio[MAX_SHADER_ANIMS] = {
+ 1.405f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+};
+static int numShaderAnims;
+// done.
+
+#define PARTICLE_GRAVITY 40
+#define MAX_PARTICLES 1024 * 8
+
+cparticle_t *active_particles, *free_particles;
+cparticle_t particles[MAX_PARTICLES];
+int cl_numparticles = MAX_PARTICLES;
+
+qboolean initparticles = qfalse;
+vec3_t vforward, vright, vup;
+vec3_t rforward, rright, rup;
+
+float oldtime;
+
+/*
+===============
+CL_ClearParticles
+===============
+*/
+void CG_ClearParticles (void)
+{
+ int i;
+
+ memset( particles, 0, sizeof(particles) );
+
+ free_particles = &particles[0];
+ active_particles = NULL;
+
+ for (i=0 ;i<cl_numparticles ; i++)
+ {
+ particles[i].next = &particles[i+1];
+ particles[i].type = 0;
+ }
+ particles[cl_numparticles-1].next = NULL;
+
+ oldtime = cg.time;
+
+ // Ridah, init the shaderAnims
+ for (i=0; shaderAnimNames[i]; i++) {
+ int j;
+
+ for (j=0; j<shaderAnimCounts[i]; j++) {
+ shaderAnims[i][j] = trap_R_RegisterShader( va("%s%i", shaderAnimNames[i], j+1) );
+ }
+ }
+ numShaderAnims = i;
+ // done.
+
+ initparticles = qtrue;
+}
+
+
+/*
+=====================
+CG_AddParticleToScene
+=====================
+*/
+void CG_AddParticleToScene (cparticle_t *p, vec3_t org, float alpha)
+{
+
+ vec3_t point;
+ polyVert_t verts[4];
+ float width;
+ float height;
+ float time, time2;
+ float ratio;
+ float invratio;
+ vec3_t color;
+ polyVert_t TRIverts[3];
+ vec3_t rright2, rup2;
+
+ if (p->type == P_WEATHER || p->type == P_WEATHER_TURBULENT || p->type == P_WEATHER_FLURRY
+ || p->type == P_BUBBLE || p->type == P_BUBBLE_TURBULENT)
+ {// create a front facing polygon
+
+ if (p->type != P_WEATHER_FLURRY)
+ {
+ if (p->type == P_BUBBLE || p->type == P_BUBBLE_TURBULENT)
+ {
+ if (org[2] > p->end)
+ {
+ p->time = cg.time;
+ VectorCopy (org, p->org); // Ridah, fixes rare snow flakes that flicker on the ground
+
+ p->org[2] = ( p->start + crandom () * 4 );
+
+
+ if (p->type == P_BUBBLE_TURBULENT)
+ {
+ p->vel[0] = crandom() * 4;
+ p->vel[1] = crandom() * 4;
+ }
+
+ }
+ }
+ else
+ {
+ if (org[2] < p->end)
+ {
+ p->time = cg.time;
+ VectorCopy (org, p->org); // Ridah, fixes rare snow flakes that flicker on the ground
+
+ while (p->org[2] < p->end)
+ {
+ p->org[2] += (p->start - p->end);
+ }
+
+
+ if (p->type == P_WEATHER_TURBULENT)
+ {
+ p->vel[0] = crandom() * 16;
+ p->vel[1] = crandom() * 16;
+ }
+
+ }
+ }
+
+
+ // Rafael snow pvs check
+ if (!p->link)
+ return;
+
+ p->alpha = 1;
+ }
+
+ // Ridah, had to do this or MAX_POLYS is being exceeded in village1.bsp
+ if (Distance( cg.snap->ps.origin, org ) > 1024) {
+ return;
+ }
+ // done.
+
+ if (p->type == P_BUBBLE || p->type == P_BUBBLE_TURBULENT)
+ {
+ VectorMA (org, -p->height, vup, point);
+ VectorMA (point, -p->width, vright, point);
+ VectorCopy (point, verts[0].xyz);
+ verts[0].st[0] = 0;
+ verts[0].st[1] = 0;
+ verts[0].modulate[0] = 255;
+ verts[0].modulate[1] = 255;
+ verts[0].modulate[2] = 255;
+ verts[0].modulate[3] = 255 * p->alpha;
+
+ VectorMA (org, -p->height, vup, point);
+ VectorMA (point, p->width, vright, point);
+ VectorCopy (point, verts[1].xyz);
+ verts[1].st[0] = 0;
+ verts[1].st[1] = 1;
+ verts[1].modulate[0] = 255;
+ verts[1].modulate[1] = 255;
+ verts[1].modulate[2] = 255;
+ verts[1].modulate[3] = 255 * p->alpha;
+
+ VectorMA (org, p->height, vup, point);
+ VectorMA (point, p->width, vright, point);
+ VectorCopy (point, verts[2].xyz);
+ verts[2].st[0] = 1;
+ verts[2].st[1] = 1;
+ verts[2].modulate[0] = 255;
+ verts[2].modulate[1] = 255;
+ verts[2].modulate[2] = 255;
+ verts[2].modulate[3] = 255 * p->alpha;
+
+ VectorMA (org, p->height, vup, point);
+ VectorMA (point, -p->width, vright, point);
+ VectorCopy (point, verts[3].xyz);
+ verts[3].st[0] = 1;
+ verts[3].st[1] = 0;
+ verts[3].modulate[0] = 255;
+ verts[3].modulate[1] = 255;
+ verts[3].modulate[2] = 255;
+ verts[3].modulate[3] = 255 * p->alpha;
+ }
+ else
+ {
+ VectorMA (org, -p->height, vup, point);
+ VectorMA (point, -p->width, vright, point);
+ VectorCopy( point, TRIverts[0].xyz );
+ TRIverts[0].st[0] = 1;
+ TRIverts[0].st[1] = 0;
+ TRIverts[0].modulate[0] = 255;
+ TRIverts[0].modulate[1] = 255;
+ TRIverts[0].modulate[2] = 255;
+ TRIverts[0].modulate[3] = 255 * p->alpha;
+
+ VectorMA (org, p->height, vup, point);
+ VectorMA (point, -p->width, vright, point);
+ VectorCopy (point, TRIverts[1].xyz);
+ TRIverts[1].st[0] = 0;
+ TRIverts[1].st[1] = 0;
+ TRIverts[1].modulate[0] = 255;
+ TRIverts[1].modulate[1] = 255;
+ TRIverts[1].modulate[2] = 255;
+ TRIverts[1].modulate[3] = 255 * p->alpha;
+
+ VectorMA (org, p->height, vup, point);
+ VectorMA (point, p->width, vright, point);
+ VectorCopy (point, TRIverts[2].xyz);
+ TRIverts[2].st[0] = 0;
+ TRIverts[2].st[1] = 1;
+ TRIverts[2].modulate[0] = 255;
+ TRIverts[2].modulate[1] = 255;
+ TRIverts[2].modulate[2] = 255;
+ TRIverts[2].modulate[3] = 255 * p->alpha;
+ }
+
+ }
+ else if (p->type == P_SPRITE)
+ {
+ vec3_t rr, ru;
+ vec3_t rotate_ang;
+
+ VectorSet (color, 1.0, 1.0, 1.0);
+ time = cg.time - p->time;
+ time2 = p->endtime - p->time;
+ ratio = time / time2;
+
+ width = p->width + ( ratio * ( p->endwidth - p->width) );
+ height = p->height + ( ratio * ( p->endheight - p->height) );
+
+ if (p->roll) {
+ vectoangles( cg.refdef.viewaxis[0], rotate_ang );
+ rotate_ang[ROLL] += p->roll;
+ AngleVectors ( rotate_ang, NULL, rr, ru);
+ }
+
+ if (p->roll) {
+ VectorMA (org, -height, ru, point);
+ VectorMA (point, -width, rr, point);
+ } else {
+ VectorMA (org, -height, vup, point);
+ VectorMA (point, -width, vright, point);
+ }
+ VectorCopy (point, verts[0].xyz);
+ verts[0].st[0] = 0;
+ verts[0].st[1] = 0;
+ verts[0].modulate[0] = 255;
+ verts[0].modulate[1] = 255;
+ verts[0].modulate[2] = 255;
+ verts[0].modulate[3] = 255;
+
+ if (p->roll) {
+ VectorMA (point, 2*height, ru, point);
+ } else {
+ VectorMA (point, 2*height, vup, point);
+ }
+ VectorCopy (point, verts[1].xyz);
+ verts[1].st[0] = 0;
+ verts[1].st[1] = 1;
+ verts[1].modulate[0] = 255;
+ verts[1].modulate[1] = 255;
+ verts[1].modulate[2] = 255;
+ verts[1].modulate[3] = 255;
+
+ if (p->roll) {
+ VectorMA (point, 2*width, rr, point);
+ } else {
+ VectorMA (point, 2*width, vright, point);
+ }
+ VectorCopy (point, verts[2].xyz);
+ verts[2].st[0] = 1;
+ verts[2].st[1] = 1;
+ verts[2].modulate[0] = 255;
+ verts[2].modulate[1] = 255;
+ verts[2].modulate[2] = 255;
+ verts[2].modulate[3] = 255;
+
+ if (p->roll) {
+ VectorMA (point, -2*height, ru, point);
+ } else {
+ VectorMA (point, -2*height, vup, point);
+ }
+ VectorCopy (point, verts[3].xyz);
+ verts[3].st[0] = 1;
+ verts[3].st[1] = 0;
+ verts[3].modulate[0] = 255;
+ verts[3].modulate[1] = 255;
+ verts[3].modulate[2] = 255;
+ verts[3].modulate[3] = 255;
+ }
+ else if (p->type == P_SMOKE || p->type == P_SMOKE_IMPACT)
+ {// create a front rotating facing polygon
+
+ if ( p->type == P_SMOKE_IMPACT && Distance( cg.snap->ps.origin, org ) > 1024) {
+ return;
+ }
+
+ if (p->color == BLOODRED)
+ VectorSet (color, 0.22f, 0.0f, 0.0f);
+ else if (p->color == GREY75)
+ {
+ float len;
+ float greyit;
+ float val;
+ len = Distance (cg.snap->ps.origin, org);
+ if (!len)
+ len = 1;
+
+ val = 4096/len;
+ greyit = 0.25 * val;
+ if (greyit > 0.5)
+ greyit = 0.5;
+
+ VectorSet (color, greyit, greyit, greyit);
+ }
+ else
+ VectorSet (color, 1.0, 1.0, 1.0);
+
+ time = cg.time - p->time;
+ time2 = p->endtime - p->time;
+ ratio = time / time2;
+
+ if (cg.time > p->startfade)
+ {
+ invratio = 1 - ( (cg.time - p->startfade) / (p->endtime - p->startfade) );
+
+ if (p->color == EMISIVEFADE)
+ {
+ float fval;
+ fval = (invratio * invratio);
+ if (fval < 0)
+ fval = 0;
+ VectorSet (color, fval , fval , fval );
+ }
+ invratio *= p->alpha;
+ }
+ else
+ invratio = 1 * p->alpha;
+
+ if ( cgs.glconfig.hardwareType == GLHW_RAGEPRO )
+ invratio = 1;
+
+ if (invratio > 1)
+ invratio = 1;
+
+ width = p->width + ( ratio * ( p->endwidth - p->width) );
+ height = p->height + ( ratio * ( p->endheight - p->height) );
+
+ if (p->type != P_SMOKE_IMPACT)
+ {
+ vec3_t temp;
+
+ vectoangles (rforward, temp);
+ p->accumroll += p->roll;
+ temp[ROLL] += p->accumroll * 0.1;
+ AngleVectors ( temp, NULL, rright2, rup2);
+ }
+ else
+ {
+ VectorCopy (rright, rright2);
+ VectorCopy (rup, rup2);
+ }
+
+ if (p->rotate)
+ {
+ VectorMA (org, -height, rup2, point);
+ VectorMA (point, -width, rright2, point);
+ }
+ else
+ {
+ VectorMA (org, -p->height, vup, point);
+ VectorMA (point, -p->width, vright, point);
+ }
+ VectorCopy (point, verts[0].xyz);
+ verts[0].st[0] = 0;
+ verts[0].st[1] = 0;
+ verts[0].modulate[0] = 255 * color[0];
+ verts[0].modulate[1] = 255 * color[1];
+ verts[0].modulate[2] = 255 * color[2];
+ verts[0].modulate[3] = 255 * invratio;
+
+ if (p->rotate)
+ {
+ VectorMA (org, -height, rup2, point);
+ VectorMA (point, width, rright2, point);
+ }
+ else
+ {
+ VectorMA (org, -p->height, vup, point);
+ VectorMA (point, p->width, vright, point);
+ }
+ VectorCopy (point, verts[1].xyz);
+ verts[1].st[0] = 0;
+ verts[1].st[1] = 1;
+ verts[1].modulate[0] = 255 * color[0];
+ verts[1].modulate[1] = 255 * color[1];
+ verts[1].modulate[2] = 255 * color[2];
+ verts[1].modulate[3] = 255 * invratio;
+
+ if (p->rotate)
+ {
+ VectorMA (org, height, rup2, point);
+ VectorMA (point, width, rright2, point);
+ }
+ else
+ {
+ VectorMA (org, p->height, vup, point);
+ VectorMA (point, p->width, vright, point);
+ }
+ VectorCopy (point, verts[2].xyz);
+ verts[2].st[0] = 1;
+ verts[2].st[1] = 1;
+ verts[2].modulate[0] = 255 * color[0];
+ verts[2].modulate[1] = 255 * color[1];
+ verts[2].modulate[2] = 255 * color[2];
+ verts[2].modulate[3] = 255 * invratio;
+
+ if (p->rotate)
+ {
+ VectorMA (org, height, rup2, point);
+ VectorMA (point, -width, rright2, point);
+ }
+ else
+ {
+ VectorMA (org, p->height, vup, point);
+ VectorMA (point, -p->width, vright, point);
+ }
+ VectorCopy (point, verts[3].xyz);
+ verts[3].st[0] = 1;
+ verts[3].st[1] = 0;
+ verts[3].modulate[0] = 255 * color[0];
+ verts[3].modulate[1] = 255 * color[1];
+ verts[3].modulate[2] = 255 * color[2];
+ verts[3].modulate[3] = 255 * invratio;
+
+ }
+ else if (p->type == P_BLEED)
+ {
+ vec3_t rr, ru;
+ vec3_t rotate_ang;
+ float alpha;
+
+ alpha = p->alpha;
+
+ if ( cgs.glconfig.hardwareType == GLHW_RAGEPRO )
+ alpha = 1;
+
+ if (p->roll)
+ {
+ vectoangles( cg.refdef.viewaxis[0], rotate_ang );
+ rotate_ang[ROLL] += p->roll;
+ AngleVectors ( rotate_ang, NULL, rr, ru);
+ }
+ else
+ {
+ VectorCopy (vup, ru);
+ VectorCopy (vright, rr);
+ }
+
+ VectorMA (org, -p->height, ru, point);
+ VectorMA (point, -p->width, rr, point);
+ VectorCopy (point, verts[0].xyz);
+ verts[0].st[0] = 0;
+ verts[0].st[1] = 0;
+ verts[0].modulate[0] = 111;
+ verts[0].modulate[1] = 19;
+ verts[0].modulate[2] = 9;
+ verts[0].modulate[3] = 255 * alpha;
+
+ VectorMA (org, -p->height, ru, point);
+ VectorMA (point, p->width, rr, point);
+ VectorCopy (point, verts[1].xyz);
+ verts[1].st[0] = 0;
+ verts[1].st[1] = 1;
+ verts[1].modulate[0] = 111;
+ verts[1].modulate[1] = 19;
+ verts[1].modulate[2] = 9;
+ verts[1].modulate[3] = 255 * alpha;
+
+ VectorMA (org, p->height, ru, point);
+ VectorMA (point, p->width, rr, point);
+ VectorCopy (point, verts[2].xyz);
+ verts[2].st[0] = 1;
+ verts[2].st[1] = 1;
+ verts[2].modulate[0] = 111;
+ verts[2].modulate[1] = 19;
+ verts[2].modulate[2] = 9;
+ verts[2].modulate[3] = 255 * alpha;
+
+ VectorMA (org, p->height, ru, point);
+ VectorMA (point, -p->width, rr, point);
+ VectorCopy (point, verts[3].xyz);
+ verts[3].st[0] = 1;
+ verts[3].st[1] = 0;
+ verts[3].modulate[0] = 111;
+ verts[3].modulate[1] = 19;
+ verts[3].modulate[2] = 9;
+ verts[3].modulate[3] = 255 * alpha;
+
+ }
+ else if (p->type == P_FLAT_SCALEUP)
+ {
+ float width, height;
+ float sinR, cosR;
+
+ if (p->color == BLOODRED)
+ VectorSet (color, 1, 1, 1);
+ else
+ VectorSet (color, 0.5, 0.5, 0.5);
+
+ time = cg.time - p->time;
+ time2 = p->endtime - p->time;
+ ratio = time / time2;
+
+ width = p->width + ( ratio * ( p->endwidth - p->width) );
+ height = p->height + ( ratio * ( p->endheight - p->height) );
+
+ if (width > p->endwidth)
+ width = p->endwidth;
+
+ if (height > p->endheight)
+ height = p->endheight;
+
+ sinR = height * sin(DEG2RAD(p->roll)) * sqrt(2);
+ cosR = width * cos(DEG2RAD(p->roll)) * sqrt(2);
+
+ VectorCopy (org, verts[0].xyz);
+ verts[0].xyz[0] -= sinR;
+ verts[0].xyz[1] -= cosR;
+ verts[0].st[0] = 0;
+ verts[0].st[1] = 0;
+ verts[0].modulate[0] = 255 * color[0];
+ verts[0].modulate[1] = 255 * color[1];
+ verts[0].modulate[2] = 255 * color[2];
+ verts[0].modulate[3] = 255;
+
+ VectorCopy (org, verts[1].xyz);
+ verts[1].xyz[0] -= cosR;
+ verts[1].xyz[1] += sinR;
+ verts[1].st[0] = 0;
+ verts[1].st[1] = 1;
+ verts[1].modulate[0] = 255 * color[0];
+ verts[1].modulate[1] = 255 * color[1];
+ verts[1].modulate[2] = 255 * color[2];
+ verts[1].modulate[3] = 255;
+
+ VectorCopy (org, verts[2].xyz);
+ verts[2].xyz[0] += sinR;
+ verts[2].xyz[1] += cosR;
+ verts[2].st[0] = 1;
+ verts[2].st[1] = 1;
+ verts[2].modulate[0] = 255 * color[0];
+ verts[2].modulate[1] = 255 * color[1];
+ verts[2].modulate[2] = 255 * color[2];
+ verts[2].modulate[3] = 255;
+
+ VectorCopy (org, verts[3].xyz);
+ verts[3].xyz[0] += cosR;
+ verts[3].xyz[1] -= sinR;
+ verts[3].st[0] = 1;
+ verts[3].st[1] = 0;
+ verts[3].modulate[0] = 255 * color[0];
+ verts[3].modulate[1] = 255 * color[1];
+ verts[3].modulate[2] = 255 * color[2];
+ verts[3].modulate[3] = 255;
+ }
+ else if (p->type == P_FLAT)
+ {
+
+ VectorCopy (org, verts[0].xyz);
+ verts[0].xyz[0] -= p->height;
+ verts[0].xyz[1] -= p->width;
+ verts[0].st[0] = 0;
+ verts[0].st[1] = 0;
+ verts[0].modulate[0] = 255;
+ verts[0].modulate[1] = 255;
+ verts[0].modulate[2] = 255;
+ verts[0].modulate[3] = 255;
+
+ VectorCopy (org, verts[1].xyz);
+ verts[1].xyz[0] -= p->height;
+ verts[1].xyz[1] += p->width;
+ verts[1].st[0] = 0;
+ verts[1].st[1] = 1;
+ verts[1].modulate[0] = 255;
+ verts[1].modulate[1] = 255;
+ verts[1].modulate[2] = 255;
+ verts[1].modulate[3] = 255;
+
+ VectorCopy (org, verts[2].xyz);
+ verts[2].xyz[0] += p->height;
+ verts[2].xyz[1] += p->width;
+ verts[2].st[0] = 1;
+ verts[2].st[1] = 1;
+ verts[2].modulate[0] = 255;
+ verts[2].modulate[1] = 255;
+ verts[2].modulate[2] = 255;
+ verts[2].modulate[3] = 255;
+
+ VectorCopy (org, verts[3].xyz);
+ verts[3].xyz[0] += p->height;
+ verts[3].xyz[1] -= p->width;
+ verts[3].st[0] = 1;
+ verts[3].st[1] = 0;
+ verts[3].modulate[0] = 255;
+ verts[3].modulate[1] = 255;
+ verts[3].modulate[2] = 255;
+ verts[3].modulate[3] = 255;
+
+ }
+ // Ridah
+ else if (p->type == P_ANIM) {
+ vec3_t rr, ru;
+ vec3_t rotate_ang;
+ int i, j;
+
+ time = cg.time - p->time;
+ time2 = p->endtime - p->time;
+ ratio = time / time2;
+ if (ratio >= 1.0f) {
+ ratio = 0.9999f;
+ }
+
+ width = p->width + ( ratio * ( p->endwidth - p->width) );
+ height = p->height + ( ratio * ( p->endheight - p->height) );
+
+ // if we are "inside" this sprite, don't draw
+ if (Distance( cg.snap->ps.origin, org ) < width/1.5) {
+ return;
+ }
+
+ i = p->shaderAnim;
+ j = (int)floor(ratio * shaderAnimCounts[p->shaderAnim]);
+ p->pshader = shaderAnims[i][j];
+
+ if (p->roll) {
+ vectoangles( cg.refdef.viewaxis[0], rotate_ang );
+ rotate_ang[ROLL] += p->roll;
+ AngleVectors ( rotate_ang, NULL, rr, ru);
+ }
+
+ if (p->roll) {
+ VectorMA (org, -height, ru, point);
+ VectorMA (point, -width, rr, point);
+ } else {
+ VectorMA (org, -height, vup, point);
+ VectorMA (point, -width, vright, point);
+ }
+ VectorCopy (point, verts[0].xyz);
+ verts[0].st[0] = 0;
+ verts[0].st[1] = 0;
+ verts[0].modulate[0] = 255;
+ verts[0].modulate[1] = 255;
+ verts[0].modulate[2] = 255;
+ verts[0].modulate[3] = 255;
+
+ if (p->roll) {
+ VectorMA (point, 2*height, ru, point);
+ } else {
+ VectorMA (point, 2*height, vup, point);
+ }
+ VectorCopy (point, verts[1].xyz);
+ verts[1].st[0] = 0;
+ verts[1].st[1] = 1;
+ verts[1].modulate[0] = 255;
+ verts[1].modulate[1] = 255;
+ verts[1].modulate[2] = 255;
+ verts[1].modulate[3] = 255;
+
+ if (p->roll) {
+ VectorMA (point, 2*width, rr, point);
+ } else {
+ VectorMA (point, 2*width, vright, point);
+ }
+ VectorCopy (point, verts[2].xyz);
+ verts[2].st[0] = 1;
+ verts[2].st[1] = 1;
+ verts[2].modulate[0] = 255;
+ verts[2].modulate[1] = 255;
+ verts[2].modulate[2] = 255;
+ verts[2].modulate[3] = 255;
+
+ if (p->roll) {
+ VectorMA (point, -2*height, ru, point);
+ } else {
+ VectorMA (point, -2*height, vup, point);
+ }
+ VectorCopy (point, verts[3].xyz);
+ verts[3].st[0] = 1;
+ verts[3].st[1] = 0;
+ verts[3].modulate[0] = 255;
+ verts[3].modulate[1] = 255;
+ verts[3].modulate[2] = 255;
+ verts[3].modulate[3] = 255;
+ }
+ // done.
+
+ if (!p->pshader) {
+// (SA) temp commented out for DM
+// CG_Printf ("CG_AddParticleToScene type %d p->pshader == ZERO\n", p->type);
+ return;
+ }
+
+ if (p->type == P_WEATHER || p->type == P_WEATHER_TURBULENT || p->type == P_WEATHER_FLURRY)
+ trap_R_AddPolyToScene( p->pshader, 3, TRIverts );
+ else
+ trap_R_AddPolyToScene( p->pshader, 4, verts );
+
+}
+
+// Ridah, made this static so it doesn't interfere with other files
+static float roll = 0.0;
+
+/*
+===============
+CG_AddParticles
+===============
+*/
+void CG_AddParticles (void)
+{
+ cparticle_t *p, *next;
+ float alpha;
+ float time, time2;
+ vec3_t org;
+ int color;
+ cparticle_t *active, *tail;
+ int type;
+ vec3_t rotate_ang;
+
+ if (!initparticles)
+ CG_ClearParticles ();
+
+ VectorCopy( cg.refdef.viewaxis[0], vforward );
+ VectorCopy( cg.refdef.viewaxis[1], vright );
+ VectorCopy( cg.refdef.viewaxis[2], vup );
+
+ vectoangles( cg.refdef.viewaxis[0], rotate_ang );
+ roll += ((cg.time - oldtime) * 0.1) ;
+ rotate_ang[ROLL] += (roll*0.9);
+ AngleVectors ( rotate_ang, rforward, rright, rup);
+
+ oldtime = cg.time;
+
+ active = NULL;
+ tail = NULL;
+
+ for (p=active_particles ; p ; p=next)
+ {
+
+ next = p->next;
+
+ time = (cg.time - p->time)*0.001;
+
+ alpha = p->alpha + time*p->alphavel;
+ if (alpha <= 0)
+ { // faded out
+ p->next = free_particles;
+ free_particles = p;
+ p->type = 0;
+ p->color = 0;
+ p->alpha = 0;
+ continue;
+ }
+
+ if (p->type == P_SMOKE || p->type == P_ANIM || p->type == P_BLEED || p->type == P_SMOKE_IMPACT)
+ {
+ if (cg.time > p->endtime)
+ {
+ p->next = free_particles;
+ free_particles = p;
+ p->type = 0;
+ p->color = 0;
+ p->alpha = 0;
+
+ continue;
+ }
+
+ }
+
+ if (p->type == P_WEATHER_FLURRY)
+ {
+ if (cg.time > p->endtime)
+ {
+ p->next = free_particles;
+ free_particles = p;
+ p->type = 0;
+ p->color = 0;
+ p->alpha = 0;
+
+ continue;
+ }
+ }
+
+
+ if (p->type == P_FLAT_SCALEUP_FADE)
+ {
+ if (cg.time > p->endtime)
+ {
+ p->next = free_particles;
+ free_particles = p;
+ p->type = 0;
+ p->color = 0;
+ p->alpha = 0;
+ continue;
+ }
+
+ }
+
+ if ((p->type == P_BAT || p->type == P_SPRITE) && p->endtime < 0) {
+ // temporary sprite
+ CG_AddParticleToScene (p, p->org, alpha);
+ p->next = free_particles;
+ free_particles = p;
+ p->type = 0;
+ p->color = 0;
+ p->alpha = 0;
+ continue;
+ }
+
+ p->next = NULL;
+ if (!tail)
+ active = tail = p;
+ else
+ {
+ tail->next = p;
+ tail = p;
+ }
+
+ if (alpha > 1.0)
+ alpha = 1;
+
+ color = p->color;
+
+ time2 = time*time;
+
+ org[0] = p->org[0] + p->vel[0]*time + p->accel[0]*time2;
+ org[1] = p->org[1] + p->vel[1]*time + p->accel[1]*time2;
+ org[2] = p->org[2] + p->vel[2]*time + p->accel[2]*time2;
+
+ type = p->type;
+
+ CG_AddParticleToScene (p, org, alpha);
+ }
+
+ active_particles = active;
+}
+
+/*
+======================
+CG_AddParticles
+======================
+*/
+void CG_ParticleSnowFlurry (qhandle_t pshader, centity_t *cent)
+{
+ cparticle_t *p;
+ qboolean turb = qtrue;
+
+ if (!pshader)
+ CG_Printf ("CG_ParticleSnowFlurry pshader == ZERO!\n");
+
+ if (!free_particles)
+ return;
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+ p->time = cg.time;
+ p->color = 0;
+ p->alpha = 0.90f;
+ p->alphavel = 0;
+
+ p->start = cent->currentState.origin2[0];
+ p->end = cent->currentState.origin2[1];
+
+ p->endtime = cg.time + cent->currentState.time;
+ p->startfade = cg.time + cent->currentState.time2;
+
+ p->pshader = pshader;
+
+ if (rand()%100 > 90)
+ {
+ p->height = 32;
+ p->width = 32;
+ p->alpha = 0.10f;
+ }
+ else
+ {
+ p->height = 1;
+ p->width = 1;
+ }
+
+ p->vel[2] = -20;
+
+ p->type = P_WEATHER_FLURRY;
+
+ if (turb)
+ p->vel[2] = -10;
+
+ VectorCopy(cent->currentState.origin, p->org);
+
+ p->org[0] = p->org[0];
+ p->org[1] = p->org[1];
+ p->org[2] = p->org[2];
+
+ p->vel[0] = p->vel[1] = 0;
+
+ p->accel[0] = p->accel[1] = p->accel[2] = 0;
+
+ p->vel[0] += cent->currentState.angles[0] * 32 + (crandom() * 16);
+ p->vel[1] += cent->currentState.angles[1] * 32 + (crandom() * 16);
+ p->vel[2] += cent->currentState.angles[2];
+
+ if (turb)
+ {
+ p->accel[0] = crandom () * 16;
+ p->accel[1] = crandom () * 16;
+ }
+
+}
+
+void CG_ParticleSnow (qhandle_t pshader, vec3_t origin, vec3_t origin2, int turb, float range, int snum)
+{
+ cparticle_t *p;
+
+ if (!pshader)
+ CG_Printf ("CG_ParticleSnow pshader == ZERO!\n");
+
+ if (!free_particles)
+ return;
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+ p->time = cg.time;
+ p->color = 0;
+ p->alpha = 0.40f;
+ p->alphavel = 0;
+ p->start = origin[2];
+ p->end = origin2[2];
+ p->pshader = pshader;
+ p->height = 1;
+ p->width = 1;
+
+ p->vel[2] = -50;
+
+ if (turb)
+ {
+ p->type = P_WEATHER_TURBULENT;
+ p->vel[2] = -50 * 1.3;
+ }
+ else
+ {
+ p->type = P_WEATHER;
+ }
+
+ VectorCopy(origin, p->org);
+
+ p->org[0] = p->org[0] + ( crandom() * range);
+ p->org[1] = p->org[1] + ( crandom() * range);
+ p->org[2] = p->org[2] + ( crandom() * (p->start - p->end));
+
+ p->vel[0] = p->vel[1] = 0;
+
+ p->accel[0] = p->accel[1] = p->accel[2] = 0;
+
+ if (turb)
+ {
+ p->vel[0] = crandom() * 16;
+ p->vel[1] = crandom() * 16;
+ }
+
+ // Rafael snow pvs check
+ p->snum = snum;
+ p->link = qtrue;
+
+}
+
+void CG_ParticleBubble (qhandle_t pshader, vec3_t origin, vec3_t origin2, int turb, float range, int snum)
+{
+ cparticle_t *p;
+ float randsize;
+
+ if (!pshader)
+ CG_Printf ("CG_ParticleSnow pshader == ZERO!\n");
+
+ if (!free_particles)
+ return;
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+ p->time = cg.time;
+ p->color = 0;
+ p->alpha = 0.40f;
+ p->alphavel = 0;
+ p->start = origin[2];
+ p->end = origin2[2];
+ p->pshader = pshader;
+
+ randsize = 1 + (crandom() * 0.5);
+
+ p->height = randsize;
+ p->width = randsize;
+
+ p->vel[2] = 50 + ( crandom() * 10 );
+
+ if (turb)
+ {
+ p->type = P_BUBBLE_TURBULENT;
+ p->vel[2] = 50 * 1.3;
+ }
+ else
+ {
+ p->type = P_BUBBLE;
+ }
+
+ VectorCopy(origin, p->org);
+
+ p->org[0] = p->org[0] + ( crandom() * range);
+ p->org[1] = p->org[1] + ( crandom() * range);
+ p->org[2] = p->org[2] + ( crandom() * (p->start - p->end));
+
+ p->vel[0] = p->vel[1] = 0;
+
+ p->accel[0] = p->accel[1] = p->accel[2] = 0;
+
+ if (turb)
+ {
+ p->vel[0] = crandom() * 4;
+ p->vel[1] = crandom() * 4;
+ }
+
+ // Rafael snow pvs check
+ p->snum = snum;
+ p->link = qtrue;
+
+}
+
+void CG_ParticleSmoke (qhandle_t pshader, centity_t *cent)
+{
+
+ // using cent->density = enttime
+ // cent->frame = startfade
+ cparticle_t *p;
+
+ if (!pshader)
+ CG_Printf ("CG_ParticleSmoke == ZERO!\n");
+
+ if (!free_particles)
+ return;
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+ p->time = cg.time;
+
+ p->endtime = cg.time + cent->currentState.time;
+ p->startfade = cg.time + cent->currentState.time2;
+
+ p->color = 0;
+ p->alpha = 1.0;
+ p->alphavel = 0;
+ p->start = cent->currentState.origin[2];
+ p->end = cent->currentState.origin2[2];
+ p->pshader = pshader;
+ p->rotate = qfalse;
+ p->height = 8;
+ p->width = 8;
+ p->endheight = 32;
+ p->endwidth = 32;
+ p->type = P_SMOKE;
+
+ VectorCopy(cent->currentState.origin, p->org);
+
+ p->vel[0] = p->vel[1] = 0;
+ p->accel[0] = p->accel[1] = p->accel[2] = 0;
+
+ p->vel[2] = 5;
+
+ if (cent->currentState.frame == 1)// reverse gravity
+ p->vel[2] *= -1;
+
+ p->roll = 8 + (crandom() * 4);
+}
+
+
+void CG_ParticleBulletDebris (vec3_t org, vec3_t vel, int duration)
+{
+
+ cparticle_t *p;
+
+ if (!free_particles)
+ return;
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+ p->time = cg.time;
+
+ p->endtime = cg.time + duration;
+ p->startfade = cg.time + duration/2;
+
+ p->color = EMISIVEFADE;
+ p->alpha = 1.0;
+ p->alphavel = 0;
+
+ p->height = 0.5;
+ p->width = 0.5;
+ p->endheight = 0.5;
+ p->endwidth = 0.5;
+
+ p->pshader = cgs.media.tracerShader;
+
+ p->type = P_SMOKE;
+
+ VectorCopy(org, p->org);
+
+ p->vel[0] = vel[0];
+ p->vel[1] = vel[1];
+ p->vel[2] = vel[2];
+ p->accel[0] = p->accel[1] = p->accel[2] = 0;
+
+ p->accel[2] = -60;
+ p->vel[2] += -20;
+
+}
+
+/*
+======================
+CG_ParticleExplosion
+======================
+*/
+
+void CG_ParticleExplosion (char *animStr, vec3_t origin, vec3_t vel, int duration, int sizeStart, int sizeEnd)
+{
+ cparticle_t *p;
+ int anim;
+
+ if (animStr < (char *)10)
+ CG_Error( "CG_ParticleExplosion: animStr is probably an index rather than a string" );
+
+ // find the animation string
+ for (anim=0; shaderAnimNames[anim]; anim++) {
+ if (!Q_stricmp( animStr, shaderAnimNames[anim] ))
+ break;
+ }
+ if (!shaderAnimNames[anim]) {
+ CG_Error("CG_ParticleExplosion: unknown animation string: %s\n", animStr);
+ return;
+ }
+
+ if (!free_particles)
+ return;
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+ p->time = cg.time;
+ p->alpha = 1.0;
+ p->alphavel = 0;
+
+ if (duration < 0) {
+ duration *= -1;
+ p->roll = 0;
+ } else {
+ p->roll = crandom()*179;
+ }
+
+ p->shaderAnim = anim;
+
+ p->width = sizeStart;
+ p->height = sizeStart*shaderAnimSTRatio[anim]; // for sprites that are stretch in either direction
+
+ p->endheight = sizeEnd;
+ p->endwidth = sizeEnd*shaderAnimSTRatio[anim];
+
+ p->endtime = cg.time + duration;
+
+ p->type = P_ANIM;
+
+ VectorCopy( origin, p->org );
+ VectorCopy( vel, p->vel );
+ VectorClear( p->accel );
+
+}
+
+// Rafael Shrapnel
+void CG_AddParticleShrapnel (localEntity_t *le)
+{
+ return;
+}
+// done.
+
+int CG_NewParticleArea (int num)
+{
+ // const char *str;
+ char *str;
+ char *token;
+ int type;
+ vec3_t origin, origin2;
+ int i;
+ float range = 0;
+ int turb;
+ int numparticles;
+ int snum;
+
+ str = (char *) CG_ConfigString (num);
+ if (!str[0])
+ return (0);
+
+ // returns type 128 64 or 32
+ token = COM_Parse (&str);
+ type = atoi (token);
+
+ if (type == 1)
+ range = 128;
+ else if (type == 2)
+ range = 64;
+ else if (type == 3)
+ range = 32;
+ else if (type == 0)
+ range = 256;
+ else if (type == 4)
+ range = 8;
+ else if (type == 5)
+ range = 16;
+ else if (type == 6)
+ range = 32;
+ else if (type == 7)
+ range = 64;
+
+
+ for (i=0; i<3; i++)
+ {
+ token = COM_Parse (&str);
+ origin[i] = atof (token);
+ }
+
+ for (i=0; i<3; i++)
+ {
+ token = COM_Parse (&str);
+ origin2[i] = atof (token);
+ }
+
+ token = COM_Parse (&str);
+ numparticles = atoi (token);
+
+ token = COM_Parse (&str);
+ turb = atoi (token);
+
+ token = COM_Parse (&str);
+ snum = atoi (token);
+
+ for (i=0; i<numparticles; i++)
+ {
+ if (type >= 4)
+ CG_ParticleBubble (cgs.media.waterBubbleShader, origin, origin2, turb, range, snum);
+ else
+ CG_ParticleSnow (cgs.media.waterBubbleShader, origin, origin2, turb, range, snum);
+ }
+
+ return (1);
+}
+
+void CG_SnowLink (centity_t *cent, qboolean particleOn)
+{
+ cparticle_t *p, *next;
+ int id;
+
+ id = cent->currentState.frame;
+
+ for (p=active_particles ; p ; p=next)
+ {
+ next = p->next;
+
+ if (p->type == P_WEATHER || p->type == P_WEATHER_TURBULENT)
+ {
+ if (p->snum == id)
+ {
+ if (particleOn)
+ p->link = qtrue;
+ else
+ p->link = qfalse;
+ }
+ }
+
+ }
+}
+
+void CG_ParticleImpactSmokePuff (qhandle_t pshader, vec3_t origin)
+{
+ cparticle_t *p;
+
+ if (!pshader)
+ CG_Printf ("CG_ParticleImpactSmokePuff pshader == ZERO!\n");
+
+ if (!free_particles)
+ return;
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+ p->time = cg.time;
+ p->alpha = 0.25;
+ p->alphavel = 0;
+ p->roll = crandom()*179;
+
+ p->pshader = pshader;
+
+ p->endtime = cg.time + 1000;
+ p->startfade = cg.time + 100;
+
+ p->width = rand()%4 + 8;
+ p->height = rand()%4 + 8;
+
+ p->endheight = p->height *2;
+ p->endwidth = p->width * 2;
+
+ p->endtime = cg.time + 500;
+
+ p->type = P_SMOKE_IMPACT;
+
+ VectorCopy( origin, p->org );
+ VectorSet(p->vel, 0, 0, 20);
+ VectorSet(p->accel, 0, 0, 20);
+
+ p->rotate = qtrue;
+}
+
+void CG_Particle_Bleed (qhandle_t pshader, vec3_t start, vec3_t dir, int fleshEntityNum, int duration)
+{
+ cparticle_t *p;
+
+ if (!pshader)
+ CG_Printf ("CG_Particle_Bleed pshader == ZERO!\n");
+
+ if (!free_particles)
+ return;
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+ p->time = cg.time;
+ p->alpha = 1.0;
+ p->alphavel = 0;
+ p->roll = 0;
+
+ p->pshader = pshader;
+
+ p->endtime = cg.time + duration;
+
+ if (fleshEntityNum)
+ p->startfade = cg.time;
+ else
+ p->startfade = cg.time + 100;
+
+ p->width = 4;
+ p->height = 4;
+
+ p->endheight = 4+rand()%3;
+ p->endwidth = p->endheight;
+
+ p->type = P_SMOKE;
+
+ VectorCopy( start, p->org );
+ p->vel[0] = 0;
+ p->vel[1] = 0;
+ p->vel[2] = -20;
+ VectorClear( p->accel );
+
+ p->rotate = qfalse;
+
+ p->roll = rand()%179;
+
+ p->color = BLOODRED;
+ p->alpha = 0.75;
+
+}
+
+void CG_Particle_OilParticle (qhandle_t pshader, centity_t *cent)
+{
+ cparticle_t *p;
+
+ int time;
+ int time2;
+ float ratio;
+
+ float duration = 1500;
+
+ time = cg.time;
+ time2 = cg.time + cent->currentState.time;
+
+ ratio =(float)1 - ((float)time / (float)time2);
+
+ if (!pshader)
+ CG_Printf ("CG_Particle_OilParticle == ZERO!\n");
+
+ if (!free_particles)
+ return;
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+ p->time = cg.time;
+ p->alpha = 1.0;
+ p->alphavel = 0;
+ p->roll = 0;
+
+ p->pshader = pshader;
+
+ p->endtime = cg.time + duration;
+
+ p->startfade = p->endtime;
+
+ p->width = 1;
+ p->height = 3;
+
+ p->endheight = 3;
+ p->endwidth = 1;
+
+ p->type = P_SMOKE;
+
+ VectorCopy(cent->currentState.origin, p->org );
+
+ p->vel[0] = (cent->currentState.origin2[0] * (16 * ratio));
+ p->vel[1] = (cent->currentState.origin2[1] * (16 * ratio));
+ p->vel[2] = (cent->currentState.origin2[2]);
+
+ p->snum = 1.0f;
+
+ VectorClear( p->accel );
+
+ p->accel[2] = -20;
+
+ p->rotate = qfalse;
+
+ p->roll = rand()%179;
+
+ p->alpha = 0.75;
+
+}
+
+
+void CG_Particle_OilSlick (qhandle_t pshader, centity_t *cent)
+{
+ cparticle_t *p;
+
+ if (!pshader)
+ CG_Printf ("CG_Particle_OilSlick == ZERO!\n");
+
+ if (!free_particles)
+ return;
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+ p->time = cg.time;
+
+ if (cent->currentState.angles2[2])
+ p->endtime = cg.time + cent->currentState.angles2[2];
+ else
+ p->endtime = cg.time + 60000;
+
+ p->startfade = p->endtime;
+
+ p->alpha = 1.0;
+ p->alphavel = 0;
+ p->roll = 0;
+
+ p->pshader = pshader;
+
+ if (cent->currentState.angles2[0] || cent->currentState.angles2[1])
+ {
+ p->width = cent->currentState.angles2[0];
+ p->height = cent->currentState.angles2[0];
+
+ p->endheight = cent->currentState.angles2[1];
+ p->endwidth = cent->currentState.angles2[1];
+ }
+ else
+ {
+ p->width = 8;
+ p->height = 8;
+
+ p->endheight = 16;
+ p->endwidth = 16;
+ }
+
+ p->type = P_FLAT_SCALEUP;
+
+ p->snum = 1.0;
+
+ VectorCopy(cent->currentState.origin, p->org );
+
+ p->org[2]+= 0.55 + (crandom() * 0.5);
+
+ p->vel[0] = 0;
+ p->vel[1] = 0;
+ p->vel[2] = 0;
+ VectorClear( p->accel );
+
+ p->rotate = qfalse;
+
+ p->roll = rand()%179;
+
+ p->alpha = 0.75;
+
+}
+
+void CG_OilSlickRemove (centity_t *cent)
+{
+ cparticle_t *p, *next;
+ int id;
+
+ id = 1.0f;
+
+ if (!id)
+ CG_Printf ("CG_OilSlickRevove NULL id\n");
+
+ for (p=active_particles ; p ; p=next)
+ {
+ next = p->next;
+
+ if (p->type == P_FLAT_SCALEUP)
+ {
+ if (p->snum == id)
+ {
+ p->endtime = cg.time + 100;
+ p->startfade = p->endtime;
+ p->type = P_FLAT_SCALEUP_FADE;
+
+ }
+ }
+
+ }
+}
+
+qboolean ValidBloodPool (vec3_t start)
+{
+#define EXTRUDE_DIST 0.5
+
+ vec3_t angles;
+ vec3_t right, up;
+ vec3_t this_pos, x_pos, center_pos, end_pos;
+ float x, y;
+ float fwidth, fheight;
+ trace_t trace;
+ vec3_t normal;
+
+ fwidth = 16;
+ fheight = 16;
+
+ VectorSet (normal, 0, 0, 1);
+
+ vectoangles (normal, angles);
+ AngleVectors (angles, NULL, right, up);
+
+ VectorMA (start, EXTRUDE_DIST, normal, center_pos);
+
+ for (x= -fwidth/2; x<fwidth; x+= fwidth)
+ {
+ VectorMA (center_pos, x, right, x_pos);
+
+ for (y= -fheight/2; y<fheight; y+= fheight)
+ {
+ VectorMA (x_pos, y, up, this_pos);
+ VectorMA (this_pos, -EXTRUDE_DIST*2, normal, end_pos);
+
+ CG_Trace (&trace, this_pos, NULL, NULL, end_pos, -1, CONTENTS_SOLID);
+
+
+ if (trace.entityNum < (MAX_ENTITIES - 1)) // may only land on world
+ return qfalse;
+
+ if (!(!trace.startsolid && trace.fraction < 1))
+ return qfalse;
+
+ }
+ }
+
+ return qtrue;
+}
+
+void CG_BloodPool (localEntity_t *le, qhandle_t pshader, trace_t *tr)
+{
+ cparticle_t *p;
+ qboolean legit;
+ vec3_t start;
+ float rndSize;
+
+ if (!pshader)
+ CG_Printf ("CG_BloodPool pshader == ZERO!\n");
+
+ if (!free_particles)
+ return;
+
+ VectorCopy (tr->endpos, start);
+ legit = ValidBloodPool (start);
+
+ if (!legit)
+ return;
+
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+ p->time = cg.time;
+
+ p->endtime = cg.time + 3000;
+ p->startfade = p->endtime;
+
+ p->alpha = 1.0;
+ p->alphavel = 0;
+ p->roll = 0;
+
+ p->pshader = pshader;
+
+ rndSize = 0.4 + random()*0.6;
+
+ p->width = 8*rndSize;
+ p->height = 8*rndSize;
+
+ p->endheight = 16*rndSize;
+ p->endwidth = 16*rndSize;
+
+ p->type = P_FLAT_SCALEUP;
+
+ VectorCopy(start, p->org );
+
+ p->vel[0] = 0;
+ p->vel[1] = 0;
+ p->vel[2] = 0;
+ VectorClear( p->accel );
+
+ p->rotate = qfalse;
+
+ p->roll = rand()%179;
+
+ p->alpha = 0.75;
+
+ p->color = BLOODRED;
+}
+
+#define NORMALSIZE 16
+#define LARGESIZE 32
+
+void CG_ParticleBloodCloud (centity_t *cent, vec3_t origin, vec3_t dir)
+{
+ float length;
+ float dist;
+ float crittersize;
+ vec3_t angles, forward;
+ vec3_t point;
+ cparticle_t *p;
+ int i;
+
+ dist = 0;
+
+ length = VectorLength (dir);
+ vectoangles (dir, angles);
+ AngleVectors (angles, forward, NULL, NULL);
+
+ crittersize = LARGESIZE;
+
+ if (length)
+ dist = length / crittersize;
+
+ if (dist < 1)
+ dist = 1;
+
+ VectorCopy (origin, point);
+
+ for (i=0; i<dist; i++)
+ {
+ VectorMA (point, crittersize, forward, point);
+
+ if (!free_particles)
+ return;
+
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+
+ p->time = cg.time;
+ p->alpha = 1.0;
+ p->alphavel = 0;
+ p->roll = 0;
+
+ p->pshader = cgs.media.smokePuffShader;
+
+ p->endtime = cg.time + 350 + (crandom() * 100);
+
+ p->startfade = cg.time;
+
+ p->width = LARGESIZE;
+ p->height = LARGESIZE;
+ p->endheight = LARGESIZE;
+ p->endwidth = LARGESIZE;
+
+ p->type = P_SMOKE;
+
+ VectorCopy( origin, p->org );
+
+ p->vel[0] = 0;
+ p->vel[1] = 0;
+ p->vel[2] = -1;
+
+ VectorClear( p->accel );
+
+ p->rotate = qfalse;
+
+ p->roll = rand()%179;
+
+ p->color = BLOODRED;
+
+ p->alpha = 0.75;
+
+ }
+
+
+}
+
+void CG_ParticleSparks (vec3_t org, vec3_t vel, int duration, float x, float y, float speed)
+{
+ cparticle_t *p;
+
+ if (!free_particles)
+ return;
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+ p->time = cg.time;
+
+ p->endtime = cg.time + duration;
+ p->startfade = cg.time + duration/2;
+
+ p->color = EMISIVEFADE;
+ p->alpha = 0.4f;
+ p->alphavel = 0;
+
+ p->height = 0.5;
+ p->width = 0.5;
+ p->endheight = 0.5;
+ p->endwidth = 0.5;
+
+ p->pshader = cgs.media.tracerShader;
+
+ p->type = P_SMOKE;
+
+ VectorCopy(org, p->org);
+
+ p->org[0] += (crandom() * x);
+ p->org[1] += (crandom() * y);
+
+ p->vel[0] = vel[0];
+ p->vel[1] = vel[1];
+ p->vel[2] = vel[2];
+
+ p->accel[0] = p->accel[1] = p->accel[2] = 0;
+
+ p->vel[0] += (crandom() * 4);
+ p->vel[1] += (crandom() * 4);
+ p->vel[2] += (20 + (crandom() * 10)) * speed;
+
+ p->accel[0] = crandom () * 4;
+ p->accel[1] = crandom () * 4;
+
+}
+
+void CG_ParticleDust (centity_t *cent, vec3_t origin, vec3_t dir)
+{
+ float length;
+ float dist;
+ float crittersize;
+ vec3_t angles, forward;
+ vec3_t point;
+ cparticle_t *p;
+ int i;
+
+ dist = 0;
+
+ VectorNegate (dir, dir);
+ length = VectorLength (dir);
+ vectoangles (dir, angles);
+ AngleVectors (angles, forward, NULL, NULL);
+
+ crittersize = LARGESIZE;
+
+ if (length)
+ dist = length / crittersize;
+
+ if (dist < 1)
+ dist = 1;
+
+ VectorCopy (origin, point);
+
+ for (i=0; i<dist; i++)
+ {
+ VectorMA (point, crittersize, forward, point);
+
+ if (!free_particles)
+ return;
+
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+
+ p->time = cg.time;
+ p->alpha = 5.0;
+ p->alphavel = 0;
+ p->roll = 0;
+
+ p->pshader = cgs.media.smokePuffShader;
+
+ // RF, stay around for long enough to expand and dissipate naturally
+ if (length)
+ p->endtime = cg.time + 4500 + (crandom() * 3500);
+ else
+ p->endtime = cg.time + 750 + (crandom() * 500);
+
+ p->startfade = cg.time;
+
+ p->width = LARGESIZE;
+ p->height = LARGESIZE;
+
+ // RF, expand while falling
+ p->endheight = LARGESIZE*3.0;
+ p->endwidth = LARGESIZE*3.0;
+
+ if (!length)
+ {
+ p->width *= 0.2f;
+ p->height *= 0.2f;
+
+ p->endheight = NORMALSIZE;
+ p->endwidth = NORMALSIZE;
+ }
+
+ p->type = P_SMOKE;
+
+ VectorCopy( point, p->org );
+
+ p->vel[0] = crandom()*6;
+ p->vel[1] = crandom()*6;
+ p->vel[2] = random()*20;
+
+ // RF, add some gravity/randomness
+ p->accel[0] = crandom()*3;
+ p->accel[1] = crandom()*3;
+ p->accel[2] = -PARTICLE_GRAVITY*0.4;
+
+ VectorClear( p->accel );
+
+ p->rotate = qfalse;
+
+ p->roll = rand()%179;
+
+ p->alpha = 0.75;
+
+ }
+
+
+}
+
+void CG_ParticleMisc (qhandle_t pshader, vec3_t origin, int size, int duration, float alpha)
+{
+ cparticle_t *p;
+
+ if (!pshader)
+ CG_Printf ("CG_ParticleImpactSmokePuff pshader == ZERO!\n");
+
+ if (!free_particles)
+ return;
+
+ p = free_particles;
+ free_particles = p->next;
+ p->next = active_particles;
+ active_particles = p;
+ p->time = cg.time;
+ p->alpha = 1.0;
+ p->alphavel = 0;
+ p->roll = rand()%179;
+
+ p->pshader = pshader;
+
+ if (duration > 0)
+ p->endtime = cg.time + duration;
+ else
+ p->endtime = duration;
+
+ p->startfade = cg.time;
+
+ p->width = size;
+ p->height = size;
+
+ p->endheight = size;
+ p->endwidth = size;
+
+ p->type = P_SPRITE;
+
+ VectorCopy( origin, p->org );
+
+ p->rotate = qfalse;
+}
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index 037ab92c..694a484d 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -1435,9 +1435,13 @@ static void PM_GroundClimbTrace( void )
//TA: If we're on the ceiling then grapplePoint is a rotation normal.. otherwise its a surface normal.
// would have been nice if Carmack had left a few random variables in the ps struct for mod makers
if( pm->ps->stats[ STAT_STATE ] & SS_GPISROTVEC )
+ {
VectorCopy( ceilingNormal, surfNormal );
+ }
else
+ {
VectorCopy( pm->ps->grapplePoint, surfNormal );
+ }
//construct a vector which reflects the direction the player is looking wrt the surface normal
AngleVectors( wcl[ pm->ps->clientNum ].nonSvangles, forward, NULL, NULL );
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index fb4e073e..bf36808a 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -873,9 +873,13 @@ float G_CalcDamageModifier( vec3_t point, gentity_t *targ, gentity_t *attacker,
clientHeight = targ->r.maxs[ 2 ] - targ->r.mins[ 2 ];
if( targ->client->ps.stats[ STAT_STATE ] & SS_WALLCLIMBING )
+ {
VectorCopy( targ->client->ps.grapplePoint, normal );
+ }
else
+ {
VectorSet( normal, 0, 0, 1 );
+ }
VectorMA( targ->r.currentOrigin, targ->r.mins[ 2 ], normal, floor );
VectorSubtract( point, floor, pMINUSfloor );
diff --git a/src/game/q_math.c b/src/game/q_math.c
index 33a29fe9..63884614 100644
--- a/src/game/q_math.c
+++ b/src/game/q_math.c
@@ -158,6 +158,62 @@ float Q_crandom( int *seed ) {
return 2.0 * ( Q_random( seed ) - 0.5 );
}
+#ifdef __LCC__
+
+int VectorCompare( const vec3_t v1, const vec3_t v2 ) {
+ if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) {
+ return 0;
+ }
+ return 1;
+}
+
+vec_t VectorLength( const vec3_t v ) {
+ return (vec_t)sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
+}
+
+vec_t VectorLengthSquared( const vec3_t v ) {
+ return (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
+}
+
+vec_t Distance( const vec3_t p1, const vec3_t p2 ) {
+ vec3_t v;
+
+ VectorSubtract (p2, p1, v);
+ return VectorLength( v );
+}
+
+vec_t DistanceSquared( const vec3_t p1, const vec3_t p2 ) {
+ vec3_t v;
+
+ VectorSubtract (p2, p1, v);
+ return v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
+}
+
+// fast vector normalize routine that does not check to make sure
+// that length != 0, nor does it return length, uses rsqrt approximation
+void VectorNormalizeFast( vec3_t v )
+{
+ float ilength;
+
+ ilength = Q_rsqrt( DotProduct( v, v ) );
+
+ v[0] *= ilength;
+ v[1] *= ilength;
+ v[2] *= ilength;
+}
+
+void VectorInverse( vec3_t v ){
+ v[0] = -v[0];
+ v[1] = -v[1];
+ v[2] = -v[2];
+}
+
+void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross ) {
+ cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
+ cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
+ cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
+}
+#endif
//=======================================================
@@ -499,6 +555,11 @@ void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
inv_denom = 1.0F / DotProduct( normal, normal );
+#ifndef Q3_VM
+ assert( Q_fabs(inv_denom) != 0.0f ); // bk010122 - zero vectors get here
+#endif
+ inv_denom = 1.0f / inv_denom;
+
d = DotProduct( normal, p ) * inv_denom;
n[0] = normal[0] * inv_denom;
@@ -543,6 +604,7 @@ void VectorRotate( vec3_t in, vec3_t matrix[3], vec3_t out )
//============================================================================
+#if !idppc
/*
** float q_rsqrt( float number )
*/
@@ -560,8 +622,15 @@ float Q_rsqrt( float number )
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
+#ifndef Q3_VM
+#ifdef __linux__
+ assert( !isnan(y) ); // bk010122 - FPE?
+#endif
+#endif
+
return y;
}
+#endif
float Q_fabs( float f ) {
int tmp = * ( int * ) &f;
@@ -728,8 +797,8 @@ int BoxOnPlaneSide2 (vec3_t emins, vec3_t emaxs, struct cplane_s *p)
==================
*/
-#if !(defined __linux__ && defined __i386__ && !defined C_ONLY)
-#if defined __LCC__ || defined C_ONLY || !id386
+#if !( (defined __linux__ || __FreeBSD__) && (defined __i386__) && (!defined C_ONLY)) // rb010123
+#if defined __LCC__ || defined C_ONLY || !id386 || defined __VECTORC
int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p)
{
@@ -1080,15 +1149,6 @@ void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs ) {
}
-int VectorCompare( const vec3_t v1, const vec3_t v2 ) {
- if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) {
- return 0;
- }
-
- return 1;
-}
-
-
vec_t VectorNormalize( vec3_t v ) {
float length, ilength;
@@ -1105,21 +1165,6 @@ vec_t VectorNormalize( vec3_t v ) {
return length;
}
-//
-// fast vector normalize routine that does not check to make sure
-// that length != 0, nor does it return length
-//
-void VectorNormalizeFast( vec3_t v )
-{
- float ilength;
-
- ilength = Q_rsqrt( DotProduct( v, v ) );
-
- v[0] *= ilength;
- v[1] *= ilength;
- v[2] *= ilength;
-}
-
vec_t VectorNormalize2( const vec3_t v, vec3_t out) {
float length, ilength;
@@ -1175,43 +1220,6 @@ void _VectorScale( const vec3_t in, vec_t scale, vec3_t out ) {
out[2] = in[2]*scale;
}
-void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross ) {
- cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
- cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
- cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
-}
-
-vec_t VectorLength( const vec3_t v ) {
- return sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
-}
-
-
-vec_t VectorLengthSquared( const vec3_t v ) {
- return (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
-}
-
-
-vec_t Distance( const vec3_t p1, const vec3_t p2 ) {
- vec3_t v;
-
- VectorSubtract (p2, p1, v);
- return VectorLength( v );
-}
-
-vec_t DistanceSquared( const vec3_t p1, const vec3_t p2 ) {
- vec3_t v;
-
- VectorSubtract (p2, p1, v);
- return v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
-}
-
-
-void VectorInverse( vec3_t v ){
- v[0] = -v[0];
- v[1] = -v[1];
- v[2] = -v[2];
-}
-
void Vector4Scale( const vec4_t in, vec_t scale, vec4_t out ) {
out[0] = in[0]*scale;
out[1] = in[1]*scale;
diff --git a/src/game/q_shared.c b/src/game/q_shared.c
index 73b960e8..91784e93 100644
--- a/src/game/q_shared.c
+++ b/src/game/q_shared.c
@@ -107,14 +107,14 @@ void COM_DefaultExtension (char *path, int maxSize, const char *extension ) {
// can't just use function pointers, or dll linkage can
// mess up when qcommon is included in multiple places
-static short (*_BigShort) (short l);
+/*static short (*_BigShort) (short l);
static short (*_LittleShort) (short l);
static int (*_BigLong) (int l);
static int (*_LittleLong) (int l);
static qint64 (*_BigLong64) (qint64 l);
static qint64 (*_LittleLong64) (qint64 l);
-static float (*_BigFloat) (float l);
-static float (*_LittleFloat) (float l);
+static float (*_BigFloat) (const float *l);
+static float (*_LittleFloat) (const float *l);
short BigShort(short l){return _BigShort(l);}
short LittleShort(short l) {return _LittleShort(l);}
@@ -122,8 +122,8 @@ int BigLong (int l) {return _BigLong(l);}
int LittleLong (int l) {return _LittleLong(l);}
qint64 BigLong64 (qint64 l) {return _BigLong64(l);}
qint64 LittleLong64 (qint64 l) {return _LittleLong64(l);}
-float BigFloat (float l) {return _BigFloat(l);}
-float LittleFloat (float l) {return _LittleFloat(l);}
+float BigFloat (const float *l) {return _BigFloat(l);}
+float LittleFloat (const float *l) {return _LittleFloat(l);}*/
short ShortSwap (short l)
{
@@ -178,27 +178,24 @@ qint64 Long64NoSwap (qint64 ll)
return ll;
}
+typedef union {
+ float f;
+ unsigned int i;
+} _FloatByteUnion;
-float FloatSwap (float f)
-{
- union
- {
- float f;
- byte b[4];
- } dat1, dat2;
+float FloatSwap (const float *f) {
+ const _FloatByteUnion *in;
+ _FloatByteUnion out;
+ in = (_FloatByteUnion *)f;
+ out.i = LongSwap(in->i);
- dat1.f = f;
- dat2.b[0] = dat1.b[3];
- dat2.b[1] = dat1.b[2];
- dat2.b[2] = dat1.b[1];
- dat2.b[3] = dat1.b[0];
- return dat2.f;
+ return out.f;
}
-float FloatNoSwap (float f)
+float FloatNoSwap (const float *f)
{
- return f;
+ return *f;
}
/*
@@ -208,7 +205,7 @@ Swap_Init
*/
void Swap_Init (void)
{
- byte swaptest[2] = {1,0};
+/* byte swaptest[2] = {1,0};
// set the byte swapping variables in a portable manner
if ( *(short *)swaptest == 1)
@@ -233,7 +230,7 @@ void Swap_Init (void)
_BigFloat = FloatNoSwap;
_LittleFloat = FloatSwap;
}
-
+*/
}
@@ -322,58 +319,73 @@ static char *SkipWhitespace( char *data, qboolean *hasNewLines ) {
int COM_Compress( char *data_p ) {
- char *datai, *datao;
- int c, pc, size;
- qboolean ws = qfalse;
-
- size = 0;
- pc = 0;
- datai = datao = data_p;
- if (datai) {
- while ((c = *datai) != 0) {
- if (c == 13 || c == 10) {
- *datao = c;
- datao++;
- ws = qfalse;
- pc = c;
- datai++;
- size++;
- // skip double slash comments
- } else if ( c == '/' && datai[1] == '/' ) {
- while (*datai && *datai != '\n') {
- datai++;
- }
- ws = qfalse;
- // skip /* */ comments
- } else if ( c=='/' && datai[1] == '*' ) {
- while ( *datai && ( *datai != '*' || datai[1] != '/' ) )
- {
- datai++;
- }
- if ( *datai )
- {
- datai += 2;
- }
- ws = qfalse;
- } else {
- if (ws) {
- *datao = ' ';
- datao++;
- }
- *datao = c;
- datao++;
- datai++;
- ws = qfalse;
- pc = c;
- size++;
- }
- }
- }
- *datao = 0;
- return size;
+ char *in, *out;
+ int c;
+ qboolean newline = qfalse, whitespace = qfalse;
+
+ in = out = data_p;
+ if (in) {
+ while ((c = *in) != 0) {
+ // skip double slash comments
+ if ( c == '/' && in[1] == '/' ) {
+ while (*in && *in != '\n') {
+ in++;
+ }
+ // skip /* */ comments
+ } else if ( c == '/' && in[1] == '*' ) {
+ while ( *in && ( *in != '*' || in[1] != '/' ) )
+ in++;
+ if ( *in )
+ in += 2;
+ // record when we hit a newline
+ } else if ( c == '\n' || c == '\r' ) {
+ newline = qtrue;
+ in++;
+ // record when we hit whitespace
+ } else if ( c == ' ' || c == '\t') {
+ whitespace = qtrue;
+ in++;
+ // an actual token
+ } else {
+ // if we have a pending newline, emit it (and it counts as whitespace)
+ if (newline) {
+ *out++ = '\n';
+ newline = qfalse;
+ whitespace = qfalse;
+ } if (whitespace) {
+ *out++ = ' ';
+ whitespace = qfalse;
+ }
+
+ // copy quoted strings unmolested
+ if (c == '"') {
+ *out++ = c;
+ in++;
+ while (1) {
+ c = *in;
+ if (c && c != '"') {
+ *out++ = c;
+ in++;
+ } else {
+ break;
+ }
+ }
+ if (c == '"') {
+ *out++ = c;
+ in++;
+ }
+ } else {
+ *out = c;
+ out++;
+ in++;
+ }
+ }
+ }
+ }
+ *out = 0;
+ return out - data_p;
}
-
char *COM_ParseExt( char **data_p, qboolean allowLineBreaks )
{
int c = 0, len;
@@ -703,6 +715,10 @@ Safe strncpy that ensures a trailing zero
=============
*/
void Q_strncpyz( char *dest, const char *src, int destsize ) {
+ // bk001129 - also NULL dest
+ if ( !dest ) {
+ Com_Error( ERR_FATAL, "Q_strncpyz: NULL dest" );
+ }
if ( !src ) {
Com_Error( ERR_FATAL, "Q_strncpyz: NULL src" );
}
@@ -717,6 +733,16 @@ void Q_strncpyz( char *dest, const char *src, int destsize ) {
int Q_stricmpn (const char *s1, const char *s2, int n) {
int c1, c2;
+ // bk001129 - moved in 1.17 fix not in id codebase
+ if ( s1 == NULL ) {
+ if ( s2 == NULL )
+ return 0;
+ else
+ return -1;
+ }
+ else if ( s2==NULL )
+ return 1;
+
do {
c1 = *s1++;
c2 = *s2++;
@@ -859,6 +885,11 @@ void QDECL Com_sprintf( char *dest, int size, const char *fmt, ...) {
if (len >= size) {
Com_Printf ("Com_sprintf: overflow of %i in %i\n", len, size);
}
+#ifdef _DEBUG
+ __asm {
+ int 3;
+ }
+#endif
Q_strncpyz (dest, bigbuffer, size );
}
@@ -1171,7 +1202,8 @@ void Info_SetValueForKey( char *s, const char *key, const char *value ) {
return;
}
- strcat (s, newi);
+ strcat (newi, s);
+ strcpy (s, newi);
}
//====================================================================
diff --git a/src/game/q_shared.h b/src/game/q_shared.h
index 26678db0..3bb7e433 100644
--- a/src/game/q_shared.h
+++ b/src/game/q_shared.h
@@ -31,10 +31,9 @@
// q_shared.h -- included first by ALL program modules.
// A user mod should never modify this file
-#define Q3_VERSION "Q3 1.27g"
+#define Q3_VERSION "Q3 1.29h"
-#define NEW_ANIMS
#define MAX_TEAMNAME 32
#ifdef _WIN32
@@ -42,28 +41,24 @@
#pragma warning(disable : 4018) // signed/unsigned mismatch
#pragma warning(disable : 4032)
#pragma warning(disable : 4051)
-#pragma warning(disable : 4057) // slightly different base types
-#pragma warning(disable : 4100) // unreferenced formal parameter
+#pragma warning(disable : 4057) // slightly different base types
+#pragma warning(disable : 4100) // unreferenced formal parameter
#pragma warning(disable : 4115)
-#pragma warning(disable : 4125) // decimal digit terminates octal escape sequence
-#pragma warning(disable : 4127) // conditional expression is constant
+#pragma warning(disable : 4125) // decimal digit terminates octal escape sequence
+#pragma warning(disable : 4127) // conditional expression is constant
#pragma warning(disable : 4136)
-#pragma warning(disable : 4152) // nonstandard extension, function/data pointer conversion in expression
+#pragma warning(disable : 4152) // nonstandard extension, function/data pointer conversion in expression
//#pragma warning(disable : 4201)
//#pragma warning(disable : 4214)
#pragma warning(disable : 4244)
-#pragma warning(disable : 4142) // benign redefinition
-//#pragma warning(disable : 4305) // truncation from const double to float
-//#pragma warning(disable : 4310) // cast truncates constant value
-//#pragma warning(disable: 4505) // unreferenced local function has been removed
+#pragma warning(disable : 4142) // benign redefinition
+//#pragma warning(disable : 4305) // truncation from const double to float
+//#pragma warning(disable : 4310) // cast truncates constant value
+//#pragma warning(disable: 4505) // unreferenced local function has been removed
#pragma warning(disable : 4514)
-#pragma warning(disable : 4702) // unreachable code
-#pragma warning(disable : 4711) // selected for automatic inline expansion
-#pragma warning(disable : 4220) // varargs matches remaining parameters
-#endif
-
-#if defined(ppc) || defined(__ppc) || defined(__ppc__) || defined(__POWERPC__)
-#define idppc 1
+#pragma warning(disable : 4702) // unreachable code
+#pragma warning(disable : 4711) // selected for automatic inline expansion
+#pragma warning(disable : 4220) // varargs matches remaining parameters
#endif
/**********************************************************************
@@ -109,64 +104,113 @@
// this is the define for determining if we have an asm version of a C function
#if (defined _M_IX86 || defined __i386__) && !defined __sun__ && !defined __LCC__
-#define id386 1
+#define id386 1
+#else
+#define id386 0
+#endif
+
+#if (defined(powerc) || defined(powerpc) || defined(ppc) || defined(__ppc) || defined(__ppc__)) && !defined(C_ONLY)
+#define idppc 1
#else
-#define id386 0
+#define idppc 0
#endif
// for windows fastcall option
-#define QDECL
+#define QDECL
+
+short ShortSwap (short l);
+int LongSwap (int l);
+float FloatSwap (const float *f);
//======================= WIN32 DEFINES =================================
#ifdef WIN32
-#define MAC_STATIC
+#define MAC_STATIC
#undef QDECL
-#define QDECL __cdecl
+#define QDECL __cdecl
// buildstring will be incorporated into the version string
#ifdef NDEBUG
#ifdef _M_IX86
-#define CPUSTRING "win-x86"
+#define CPUSTRING "win-x86"
#elif defined _M_ALPHA
-#define CPUSTRING "win-AXP"
+#define CPUSTRING "win-AXP"
#endif
#else
#ifdef _M_IX86
-#define CPUSTRING "win-x86-debug"
+#define CPUSTRING "win-x86-debug"
#elif defined _M_ALPHA
-#define CPUSTRING "win-AXP-debug"
+#define CPUSTRING "win-AXP-debug"
#endif
#endif
+#define ID_INLINE __inline
+
+static ID_INLINE short BigShort( short l) { return ShortSwap(l); }
+#define LittleShort
+static ID_INLINE int BigLong(int l) { LongSwap(l); }
+#define LittleLong
+static ID_INLINE float BigFloat(const float *l) { FloatSwap(l); }
+#define LittleFloat
-#define PATH_SEP '\\'
+#define PATH_SEP '\\'
#endif
-//======================= MAC OS X SERVER DEFINES =====================
+//======================= MAC OS X DEFINES =====================
-#if defined(__MACH__) && defined(__APPLE__)
+#if defined(MACOS_X)
#define MAC_STATIC
+#define __cdecl
+#define __declspec(x)
+#define stricmp strcasecmp
+#define ID_INLINE inline
#ifdef __ppc__
-#define CPUSTRING "MacOSXS-ppc"
+#define CPUSTRING "MacOSX-ppc"
#elif defined __i386__
-#define CPUSTRING "MacOSXS-i386"
+#define CPUSTRING "MacOSX-i386"
#else
-#define CPUSTRING "MacOSXS-other"
+#define CPUSTRING "MacOSX-other"
#endif
-#define PATH_SEP '/'
+#define PATH_SEP '/'
+
+#define __rlwimi(out, in, shift, maskBegin, maskEnd) asm("rlwimi %0,%1,%2,%3,%4" : "=r" (out) : "r" (in), "i" (shift), "i" (maskBegin), "i" (maskEnd))
+#define __dcbt(addr, offset) asm("dcbt %0,%1" : : "b" (addr), "r" (offset))
+
+static inline unsigned int __lwbrx(register void *addr, register int offset) {
+ register unsigned int word;
+
+ asm("lwbrx %0,%2,%1" : "=r" (word) : "r" (addr), "b" (offset));
+ return word;
+}
+
+static inline unsigned short __lhbrx(register void *addr, register int offset) {
+ register unsigned short halfword;
+
+ asm("lhbrx %0,%2,%1" : "=r" (halfword) : "r" (addr), "b" (offset));
+ return halfword;
+}
-#define GAME_HARD_LINKED
-#define CGAME_HARD_LINKED
-#define UI_HARD_LINKED
-#define BOTLIB_HARD_LINKED
+static inline float __fctiw(register float f) {
+ register float fi;
+
+ asm("fctiw %0,%1" : "=f" (fi) : "f" (f));
+
+ return fi;
+}
+
+#define BigShort
+static inline short LittleShort(short l) { return ShortSwap(l); }
+#define BigLong
+static inline int LittleLong (int l) { return LongSwap(l); }
+#define BigFloat
+static inline float LittleFloat (const float l) { return FloatSwap(&l); }
#endif
@@ -175,20 +219,22 @@
#ifdef __MACOS__
#include <MacTypes.h>
+#define MAC_STATIC
+#define ID_INLINE inline
-#define MAC_STATIC static
-
-#define CPUSTRING "MacOS-PPC"
+#define CPUSTRING "MacOS-PPC"
-#define PATH_SEP ':'
-
-#define GAME_HARD_LINKED
-#define CGAME_HARD_LINKED
-#define UI_HARD_LINKED
-#define BOTLIB_HARD_LINKED
+#define PATH_SEP ':'
void Sys_PumpEvents( void );
+#define BigShort
+static inline short LittleShort(short l) { return ShortSwap(l); }
+#define BigLong
+static inline int LittleLong (int l) { return LongSwap(l); }
+#define BigFloat
+static inline float LittleFloat (const float l) { return FloatSwap(&l); }
+
#endif
//======================= LINUX DEFINES =================================
@@ -197,151 +243,227 @@ void Sys_PumpEvents( void );
// just waste space and make big arrays static...
#ifdef __linux__
+// bk001205 - from Makefile
+#define stricmp strcasecmp
+
+#define MAC_STATIC // bk: FIXME
+#define ID_INLINE inline
+
+#ifdef __i386__
+#define CPUSTRING "linux-i386"
+#elif defined __axp__
+#define CPUSTRING "linux-alpha"
+#else
+#define CPUSTRING "linux-other"
+#endif
+
+#define PATH_SEP '/'
+
+// bk001205 - try
+#ifdef Q3_STATIC
+#define GAME_HARD_LINKED
+#define CGAME_HARD_LINKED
+#define UI_HARD_LINKED
+#define BOTLIB_HARD_LINKED
+#endif
+
+#if !idppc
+inline static short BigShort( short l) { return ShortSwap(l); }
+#define LittleShort
+inline static int BigLong(int l) { return LongSwap(l); }
+#define LittleLong
+inline static float BigFloat(const float *l) { return FloatSwap(l); }
+#define LittleFloat
+#else
+#define BigShort
+inline static short LittleShort(short l) { return ShortSwap(l); }
+#define BigLong
+inline static int LittleLong (int l) { return LongSwap(l); }
+#define BigFloat
+inline static float LittleFloat (const float *l) { return FloatSwap(l); }
+#endif
+
+#endif
+
+//======================= FreeBSD DEFINES =====================
+#ifdef __FreeBSD__ // rb010123
+
+#define stricmp strcasecmp
+
#define MAC_STATIC
+#define ID_INLINE inline
#ifdef __i386__
-#define CPUSTRING "linux-i386"
+#define CPUSTRING "freebsd-i386"
#elif defined __axp__
-#define CPUSTRING "linux-alpha"
+#define CPUSTRING "freebsd-alpha"
#else
-#define CPUSTRING "linux-other"
+#define CPUSTRING "freebsd-other"
#endif
-#define PATH_SEP '/'
+#define PATH_SEP '/'
+// bk010116 - omitted Q3STATIC (see Linux above), broken target
+
+#if !idppc
+static short BigShort( short l) { return ShortSwap(l); }
+#define LittleShort
+static int BigLong(int l) { LongSwap(l); }
+#define LittleLong
+static float BigFloat(const float *l) { FloatSwap(l); }
+#define LittleFloat
+#else
+#define BigShort
+static short LittleShort(short l) { return ShortSwap(l); }
+#define BigLong
+static int LittleLong (int l) { return LongSwap(l); }
+#define BigFloat
+static float LittleFloat (const float *l) { return FloatSwap(l); }
#endif
-//=============================================================
+#endif
+//=============================================================
-typedef unsigned char byte;
+typedef unsigned char byte;
-typedef enum {qfalse, qtrue} qboolean;
+typedef enum {qfalse, qtrue} qboolean;
-typedef int qhandle_t;
-typedef int sfxHandle_t;
-typedef int fileHandle_t;
-typedef int clipHandle_t;
+typedef int qhandle_t;
+typedef int sfxHandle_t;
+typedef int fileHandle_t;
+typedef int clipHandle_t;
#ifndef NULL
#define NULL ((void *)0)
#endif
-#define MAX_QINT 0x7fffffff
-#define MIN_QINT (-MAX_QINT-1)
+#define MAX_QINT 0x7fffffff
+#define MIN_QINT (-MAX_QINT-1)
// angle indexes
-#define PITCH 0 // up / down
-#define YAW 1 // left / right
-#define ROLL 2 // fall over
+#define PITCH 0 // up / down
+#define YAW 1 // left / right
+#define ROLL 2 // fall over
// the game guarantees that no string from the network will ever
// exceed MAX_STRING_CHARS
-#define MAX_STRING_CHARS 1024 // max length of a string passed to Cmd_TokenizeString
-#define MAX_STRING_TOKENS 256 // max tokens resulting from Cmd_TokenizeString
-#define MAX_TOKEN_CHARS 1024 // max length of an individual token
+#define MAX_STRING_CHARS 1024 // max length of a string passed to Cmd_TokenizeString
+#define MAX_STRING_TOKENS 1024 // max tokens resulting from Cmd_TokenizeString
+#define MAX_TOKEN_CHARS 1024 // max length of an individual token
-#define MAX_INFO_STRING 1024
-#define MAX_INFO_KEY 1024
-#define MAX_INFO_VALUE 1024
+#define MAX_INFO_STRING 1024
+#define MAX_INFO_KEY 1024
+#define MAX_INFO_VALUE 1024
-#define BIG_INFO_STRING 8192 // used for system info key only
-#define BIG_INFO_KEY 8192
-#define BIG_INFO_VALUE 8192
+#define BIG_INFO_STRING 8192 // used for system info key only
+#define BIG_INFO_KEY 8192
+#define BIG_INFO_VALUE 8192
-#define MAX_QPATH 64 // max length of a quake game pathname
-#define MAX_OSPATH 256 // max length of a filesystem pathname
-#define MAX_NAME_LENGTH 32 // max length of a client name
+#define MAX_QPATH 64 // max length of a quake game pathname
+#ifdef PATH_MAX
+#define MAX_OSPATH PATH_MAX
+#else
+#define MAX_OSPATH 256 // max length of a filesystem pathname
+#endif
+
+#define MAX_NAME_LENGTH 32 // max length of a client name
-#define MAX_SAY_TEXT 150
+#define MAX_SAY_TEXT 150
// paramters for command buffer stuffing
typedef enum {
- EXEC_NOW, // don't return until completed, a VM should NEVER use this,
- // because some commands might cause the VM to be unloaded...
- EXEC_INSERT, // insert at current position, but don't run yet
- EXEC_APPEND // add to end of the command buffer (normal case)
+ EXEC_NOW, // don't return until completed, a VM should NEVER use this,
+ // because some commands might cause the VM to be unloaded...
+ EXEC_INSERT, // insert at current position, but don't run yet
+ EXEC_APPEND // add to end of the command buffer (normal case)
} cbufExec_t;
//
// these aren't needed by any of the VMs. put in another header?
//
-#define MAX_MAP_AREA_BYTES 32 // bit vector of area visibility
+#define MAX_MAP_AREA_BYTES 32 // bit vector of area visibility
// print levels from renderer (FIXME: set up for game / cgame?)
typedef enum {
- PRINT_ALL,
- PRINT_DEVELOPER, // only print when "developer 1"
- PRINT_WARNING,
- PRINT_ERROR
+ PRINT_ALL,
+ PRINT_DEVELOPER, // only print when "developer 1"
+ PRINT_WARNING,
+ PRINT_ERROR
} printParm_t;
+
#ifdef ERR_FATAL
-#undef ERR_FATAL // this is be defined in malloc.h
+#undef ERR_FATAL // this is be defined in malloc.h
#endif
// parameters to the main Error routine
typedef enum {
- ERR_FATAL, // exit the entire game with a popup window
- ERR_DROP, // print to console and disconnect from game
- ERR_SERVERDISCONNECT, // don't kill server
- ERR_DISCONNECT, // client disconnected from the server
- ERR_NEED_CD // pop up the need-cd dialog
+ ERR_FATAL, // exit the entire game with a popup window
+ ERR_DROP, // print to console and disconnect from game
+ ERR_SERVERDISCONNECT, // don't kill server
+ ERR_DISCONNECT, // client disconnected from the server
+ ERR_NEED_CD // pop up the need-cd dialog
} errorParm_t;
// font rendering values used by ui and cgame
-#define PROP_GAP_WIDTH 3
-#define PROP_SPACE_WIDTH 8
-#define PROP_HEIGHT 27
-#define PROP_SMALL_SIZE_SCALE 0.75
-
-#define BLINK_DIVISOR 200
-#define PULSE_DIVISOR 75
-
-#define UI_LEFT 0x00000000 // default
-#define UI_CENTER 0x00000001
-#define UI_RIGHT 0x00000002
-#define UI_FORMATMASK 0x00000007
-#define UI_SMALLFONT 0x00000010
-#define UI_BIGFONT 0x00000020 // default
-#define UI_GIANTFONT 0x00000040
-#define UI_DROPSHADOW 0x00000800
-#define UI_BLINK 0x00001000
-#define UI_INVERSE 0x00002000
-#define UI_PULSE 0x00004000
+#define PROP_GAP_WIDTH 3
+#define PROP_SPACE_WIDTH 8
+#define PROP_HEIGHT 27
+#define PROP_SMALL_SIZE_SCALE 0.75
+
+#define BLINK_DIVISOR 200
+#define PULSE_DIVISOR 75
+
+#define UI_LEFT 0x00000000 // default
+#define UI_CENTER 0x00000001
+#define UI_RIGHT 0x00000002
+#define UI_FORMATMASK 0x00000007
+#define UI_SMALLFONT 0x00000010
+#define UI_BIGFONT 0x00000020 // default
+#define UI_GIANTFONT 0x00000040
+#define UI_DROPSHADOW 0x00000800
+#define UI_BLINK 0x00001000
+#define UI_INVERSE 0x00002000
+#define UI_PULSE 0x00004000
#if defined(_DEBUG) && !defined(BSPC)
- #define HUNK_DEBUG
+ #define HUNK_DEBUG
#endif
typedef enum {
- h_high,
- h_low,
- h_dontcare
+ h_high,
+ h_low,
+ h_dontcare
} ha_pref;
#ifdef HUNK_DEBUG
-#define Hunk_Alloc( size, preference ) Hunk_AllocDebug(size, preference, #size, __FILE__, __LINE__)
+#define Hunk_Alloc( size, preference ) Hunk_AllocDebug(size, preference, #size, __FILE__, __LINE__)
void *Hunk_AllocDebug( int size, ha_pref preference, char *label, char *file, int line );
#else
void *Hunk_Alloc( int size, ha_pref preference );
#endif
+#if !( defined __VECTORC )
void Com_Memset (void* dest, const int val, const size_t count);
void Com_Memcpy (void* dest, const void* src, const size_t count);
+#else
+#define Com_Memset memset
+#define Com_Memcpy memcpy
+#endif
-#define CIN_system 1
-#define CIN_loop 2
-#define CIN_hold 4
-#define CIN_silent 8
-#define CIN_shader 16
+#define CIN_system 1
+#define CIN_loop 2
+#define CIN_hold 4
+#define CIN_silent 8
+#define CIN_shader 16
/*
==============================================================
@@ -358,94 +480,119 @@ typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
typedef vec_t vec5_t[5];
-typedef int fixed4_t;
-typedef int fixed8_t;
-typedef int fixed16_t;
+typedef int fixed4_t;
+typedef int fixed8_t;
+typedef int fixed16_t;
#ifndef M_PI
-#define M_PI 3.14159265358979323846f // matches value in gcc v2 math.h
+#define M_PI 3.14159265358979323846f // matches value in gcc v2 math.h
#endif
-//TA: stop telling others not to edit q_* <:)
#ifndef M_SQRT2
#define M_SQRT2 1.414213562f
#endif
-#define NUMVERTEXNORMALS 162
-extern vec3_t bytedirs[NUMVERTEXNORMALS];
+#define NUMVERTEXNORMALS 162
+extern vec3_t bytedirs[NUMVERTEXNORMALS];
// all drawing is done to a 640*480 virtual screen size
// and will be automatically scaled to the real resolution
-#define SCREEN_WIDTH 640
-#define SCREEN_HEIGHT 480
-
-#define TINYCHAR_WIDTH (SMALLCHAR_WIDTH)
-#define TINYCHAR_HEIGHT (SMALLCHAR_HEIGHT/2)
-
-#define SMALLCHAR_WIDTH 8
-#define SMALLCHAR_HEIGHT 16
-
-#define BIGCHAR_WIDTH 16
-#define BIGCHAR_HEIGHT 16
-
-#define GIANTCHAR_WIDTH 32
-#define GIANTCHAR_HEIGHT 48
-
-extern vec4_t colorBlack;
-extern vec4_t colorRed;
-extern vec4_t colorGreen;
-extern vec4_t colorBlue;
-extern vec4_t colorYellow;
-extern vec4_t colorMagenta;
-extern vec4_t colorCyan;
-extern vec4_t colorWhite;
-extern vec4_t colorLtGrey;
-extern vec4_t colorMdGrey;
-extern vec4_t colorDkGrey;
-
-#define Q_COLOR_ESCAPE '^'
-#define Q_IsColorString(p) ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE )
-
-#define COLOR_BLACK '0'
-#define COLOR_RED '1'
-#define COLOR_GREEN '2'
-#define COLOR_YELLOW '3'
-#define COLOR_BLUE '4'
-#define COLOR_CYAN '5'
-#define COLOR_MAGENTA '6'
-#define COLOR_WHITE '7'
-#define ColorIndex(c) ( ( (c) - '0' ) & 7 )
-
-#define S_COLOR_BLACK "^0"
-#define S_COLOR_RED "^1"
-#define S_COLOR_GREEN "^2"
-#define S_COLOR_YELLOW "^3"
-#define S_COLOR_BLUE "^4"
-#define S_COLOR_CYAN "^5"
-#define S_COLOR_MAGENTA "^6"
-#define S_COLOR_WHITE "^7"
-
-extern vec4_t g_color_table[8];
-
-#define MAKERGB( v, r, g, b ) v[0]=r;v[1]=g;v[2]=b
-#define MAKERGBA( v, r, g, b, a ) v[0]=r;v[1]=g;v[2]=b;v[3]=a
+#define SCREEN_WIDTH 640
+#define SCREEN_HEIGHT 480
+
+#define TINYCHAR_WIDTH (SMALLCHAR_WIDTH)
+#define TINYCHAR_HEIGHT (SMALLCHAR_HEIGHT/2)
+
+#define SMALLCHAR_WIDTH 8
+#define SMALLCHAR_HEIGHT 16
+
+#define BIGCHAR_WIDTH 16
+#define BIGCHAR_HEIGHT 16
+
+#define GIANTCHAR_WIDTH 32
+#define GIANTCHAR_HEIGHT 48
+
+extern vec4_t colorBlack;
+extern vec4_t colorRed;
+extern vec4_t colorGreen;
+extern vec4_t colorBlue;
+extern vec4_t colorYellow;
+extern vec4_t colorMagenta;
+extern vec4_t colorCyan;
+extern vec4_t colorWhite;
+extern vec4_t colorLtGrey;
+extern vec4_t colorMdGrey;
+extern vec4_t colorDkGrey;
+
+#define Q_COLOR_ESCAPE '^'
+#define Q_IsColorString(p) ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE )
+
+#define COLOR_BLACK '0'
+#define COLOR_RED '1'
+#define COLOR_GREEN '2'
+#define COLOR_YELLOW '3'
+#define COLOR_BLUE '4'
+#define COLOR_CYAN '5'
+#define COLOR_MAGENTA '6'
+#define COLOR_WHITE '7'
+#define ColorIndex(c) ( ( (c) - '0' ) & 7 )
+
+#define S_COLOR_BLACK "^0"
+#define S_COLOR_RED "^1"
+#define S_COLOR_GREEN "^2"
+#define S_COLOR_YELLOW "^3"
+#define S_COLOR_BLUE "^4"
+#define S_COLOR_CYAN "^5"
+#define S_COLOR_MAGENTA "^6"
+#define S_COLOR_WHITE "^7"
+
+extern vec4_t g_color_table[8];
+
+#define MAKERGB( v, r, g, b ) v[0]=r;v[1]=g;v[2]=b
+#define MAKERGBA( v, r, g, b, a ) v[0]=r;v[1]=g;v[2]=b;v[3]=a
#define DEG2RAD( a ) ( ( (a) * M_PI ) / 180.0F )
#define RAD2DEG( a ) ( ( (a) * 180.0f ) / M_PI )
struct cplane_s;
-extern vec3_t vec3_origin;
-extern vec3_t axisDefault[3];
+extern vec3_t vec3_origin;
+extern vec3_t axisDefault[3];
+
+#define nanmask (255<<23)
-#define nanmask (255<<23)
+#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
-#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
+#if idppc
+static inline float Q_rsqrt( float number ) {
+ float x = 0.5f * number;
+ float y;
+#ifdef __GNUC__
+ asm("frsqrte %0,%1" : "=f" (y) : "f" (number));
+#else
+ y = __frsqrte( number );
+#endif
+ return y * (1.5f - (x * y * y));
+ }
+
+#ifdef __GNUC__
+static inline float Q_fabs(float x) {
+ float abs_x;
+
+ asm("fabs %0,%1" : "=f" (abs_x) : "f" (x));
+ return abs_x;
+}
+#else
+#define Q_fabs __fabsf
+#endif
+
+#else
float Q_fabs( float f );
-float Q_rsqrt( float f ); // reciprocal square root
+float Q_rsqrt( float f ); // reciprocal square root
+#endif
-#define SQRTFAST( x ) ( 1.0f / Q_rsqrt( x ) )
+#define SQRTFAST( x ) ( (x) * Q_rsqrt( x ) )
signed char ClampChar( int i );
signed short ClampShort( int i );
@@ -454,23 +601,23 @@ signed short ClampShort( int i );
int DirToByte( vec3_t dir );
void ByteToDir( int b, vec3_t dir );
-#if 1
+#if 1
-#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
-#define VectorSubtract(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2])
-#define VectorAdd(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2])
-#define VectorCopy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2])
-#define VectorScale(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s))
-#define VectorMA(v, s, b, o) ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s))
+#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
+#define VectorSubtract(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2])
+#define VectorAdd(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2])
+#define VectorCopy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2])
+#define VectorScale(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s))
+#define VectorMA(v, s, b, o) ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s))
#else
-#define DotProduct(x,y) _DotProduct(x,y)
-#define VectorSubtract(a,b,c) _VectorSubtract(a,b,c)
-#define VectorAdd(a,b,c) _VectorAdd(a,b,c)
-#define VectorCopy(a,b) _VectorCopy(a,b)
-#define VectorScale(v, s, o) _VectorScale(v,s,o)
-#define VectorMA(v, s, b, o) _VectorMA(v,s,b,o)
+#define DotProduct(x,y) _DotProduct(x,y)
+#define VectorSubtract(a,b,c) _VectorSubtract(a,b,c)
+#define VectorAdd(a,b,c) _VectorAdd(a,b,c)
+#define VectorCopy(a,b) _VectorCopy(a,b)
+#define VectorScale(v, s, o) _VectorScale(v,s,o)
+#define VectorMA(v, s, b, o) _VectorMA(v,s,b,o)
#endif
@@ -479,19 +626,19 @@ void ByteToDir( int b, vec3_t dir );
#undef VectorCopy
// this is a little hack to get more efficient copies in our interpreter
typedef struct {
- float v[3];
+ float v[3];
} vec3struct_t;
-#define VectorCopy(a,b) *(vec3struct_t *)b=*(vec3struct_t *)a;
+#define VectorCopy(a,b) *(vec3struct_t *)b=*(vec3struct_t *)a;
+#define ID_INLINE static
#endif
#endif
-#define VectorClear(a) ((a)[0]=(a)[1]=(a)[2]=0)
-#define VectorNegate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2])
-#define VectorSet(v, x, y, z) ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z))
-#define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
-
-#define SnapVector(v) {v[0]=((int)(v[0]));v[1]=((int)(v[1]));v[2]=((int)(v[2]));}
+#define VectorClear(a) ((a)[0]=(a)[1]=(a)[2]=0)
+#define VectorNegate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2])
+#define VectorSet(v, x, y, z) ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z))
+#define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
+#define SnapVector(v) {v[0]=((int)(v[0]));v[1]=((int)(v[1]));v[2]=((int)(v[2]));}
// just in case you do't want to use the macros
vec_t _DotProduct( const vec3_t v1, const vec3_t v2 );
void _VectorSubtract( const vec3_t veca, const vec3_t vecb, vec3_t out );
@@ -508,28 +655,95 @@ float NormalizeColor( const vec3_t in, vec3_t out );
float RadiusFromBounds( const vec3_t mins, const vec3_t maxs );
void ClearBounds( vec3_t mins, vec3_t maxs );
void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs );
+
+#ifndef __LCC__
+static ID_INLINE int VectorCompare( const vec3_t v1, const vec3_t v2 ) {
+ if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) {
+ return 0;
+ }
+ return 1;
+}
+
+static ID_INLINE vec_t VectorLength( const vec3_t v ) {
+ return (vec_t)sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
+}
+
+static ID_INLINE vec_t VectorLengthSquared( const vec3_t v ) {
+ return (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
+}
+
+static ID_INLINE vec_t Distance( const vec3_t p1, const vec3_t p2 ) {
+ vec3_t v;
+
+ VectorSubtract (p2, p1, v);
+ return VectorLength( v );
+}
+
+static ID_INLINE vec_t DistanceSquared( const vec3_t p1, const vec3_t p2 ) {
+ vec3_t v;
+
+ VectorSubtract (p2, p1, v);
+ return v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
+}
+
+// fast vector normalize routine that does not check to make sure
+// that length != 0, nor does it return length, uses rsqrt approximation
+static ID_INLINE void VectorNormalizeFast( vec3_t v )
+{
+ float ilength;
+
+ ilength = Q_rsqrt( DotProduct( v, v ) );
+
+ v[0] *= ilength;
+ v[1] *= ilength;
+ v[2] *= ilength;
+}
+
+static ID_INLINE void VectorInverse( vec3_t v ){
+ v[0] = -v[0];
+ v[1] = -v[1];
+ v[2] = -v[2];
+}
+
+static ID_INLINE void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross ) {
+ cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
+ cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
+ cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
+}
+
+#else
int VectorCompare( const vec3_t v1, const vec3_t v2 );
+
vec_t VectorLength( const vec3_t v );
+
vec_t VectorLengthSquared( const vec3_t v );
+
vec_t Distance( const vec3_t p1, const vec3_t p2 );
+
vec_t DistanceSquared( const vec3_t p1, const vec3_t p2 );
+
+void VectorNormalizeFast( vec3_t v );
+
+void VectorInverse( vec3_t v );
+
void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross );
-vec_t VectorNormalize (vec3_t v); // returns vector length
-void VectorNormalizeFast(vec3_t v); // does NOT return vector length, uses rsqrt approximation
+
+#endif
+
+vec_t VectorNormalize (vec3_t v); // returns vector length
vec_t VectorNormalize2( const vec3_t v, vec3_t out );
-void VectorInverse (vec3_t v);
void Vector4Scale( const vec4_t in, vec_t scale, vec4_t out );
void VectorRotate( vec3_t in, vec3_t matrix[3], vec3_t out );
int Q_log2(int val);
float Q_acos(float c);
-int Q_rand( int *seed );
-float Q_random( int *seed );
-float Q_crandom( int *seed );
+int Q_rand( int *seed );
+float Q_random( int *seed );
+float Q_crandom( int *seed );
-#define random() ((rand () & 0x7fff) / ((float)0x7fff))
-#define crandom() (2.0 * (random() - 0.5))
+#define random() ((rand () & 0x7fff) / ((float)0x7fff))
+#define crandom() (2.0 * (random() - 0.5))
void vectoangles( const vec3_t value1, vec3_t angles);
void AnglesToAxis( const vec3_t angles, vec3_t axis[3] );
@@ -540,10 +754,10 @@ void AxisCopy( vec3_t in[3], vec3_t out[3] );
void SetPlaneSignbits( struct cplane_s *out );
int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *plane);
-float AngleMod(float a);
-float LerpAngle (float from, float to, float frac);
-float AngleSubtract( float a1, float a2 );
-void AnglesSubtract( vec3_t v1, vec3_t v2, vec3_t v3 );
+float AngleMod(float a);
+float LerpAngle (float from, float to, float frac);
+float AngleSubtract( float a1, float a2 );
+void AnglesSubtract( vec3_t v1, vec3_t v2, vec3_t v3 );
float AngleNormalize360 ( float angle );
float AngleNormalize180 ( float angle );
@@ -556,52 +770,53 @@ void RotateAroundDirection( vec3_t axis[3], float yaw );
void MakeNormalVectors( const vec3_t forward, vec3_t right, vec3_t up );
// perpendicular vector could be replaced by this
-//int PlaneTypeForNormal (vec3_t normal);
+//int PlaneTypeForNormal (vec3_t normal);
void MatrixMultiply(float in1[3][3], float in2[3][3], float out[3][3]);
void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
void PerpendicularVector( vec3_t dst, const vec3_t src );
+
//=============================================
float Com_Clamp( float min, float max, float value );
-char *COM_SkipPath( char *pathname );
-void COM_StripExtension( const char *in, char *out );
-void COM_DefaultExtension( char *path, int maxSize, const char *extension );
+char *COM_SkipPath( char *pathname );
+void COM_StripExtension( const char *in, char *out );
+void COM_DefaultExtension( char *path, int maxSize, const char *extension );
-void COM_BeginParseSession( const char *name );
-int COM_GetCurrentParseLine( void );
-char *COM_Parse( char **data_p );
-char *COM_ParseExt( char **data_p, qboolean allowLineBreak );
-int COM_Compress( char *data_p );
-void COM_ParseError( char *format, ... );
-void COM_ParseWarning( char *format, ... );
-//int COM_ParseInfos( char *buf, int max, char infos[][MAX_INFO_STRING] );
+void COM_BeginParseSession( const char *name );
+int COM_GetCurrentParseLine( void );
+char *COM_Parse( char **data_p );
+char *COM_ParseExt( char **data_p, qboolean allowLineBreak );
+int COM_Compress( char *data_p );
+void COM_ParseError( char *format, ... );
+void COM_ParseWarning( char *format, ... );
+//int COM_ParseInfos( char *buf, int max, char infos[][MAX_INFO_STRING] );
-#define MAX_TOKENLENGTH 1024
+#define MAX_TOKENLENGTH 1024
#ifndef TT_STRING
//token types
-#define TT_STRING 1 // string
-#define TT_LITERAL 2 // literal
-#define TT_NUMBER 3 // number
-#define TT_NAME 4 // name
-#define TT_PUNCTUATION 5 // punctuation
+#define TT_STRING 1 // string
+#define TT_LITERAL 2 // literal
+#define TT_NUMBER 3 // number
+#define TT_NAME 4 // name
+#define TT_PUNCTUATION 5 // punctuation
#endif
typedef struct pc_token_s
{
- int type;
- int subtype;
- int intvalue;
- float floatvalue;
- char string[MAX_TOKENLENGTH];
+ int type;
+ int subtype;
+ int intvalue;
+ float floatvalue;
+ char string[MAX_TOKENLENGTH];
} pc_token_t;
// data is an in/out parm, returns a parsed out token
-void COM_MatchToken( char**buf_p, char *match );
+void COM_MatchToken( char**buf_p, char *match );
void SkipBracedSection (char **program);
void SkipRestOfLine ( char **data );
@@ -610,21 +825,21 @@ void Parse1DMatrix (char **buf_p, int x, float *m);
void Parse2DMatrix (char **buf_p, int y, int x, float *m);
void Parse3DMatrix (char **buf_p, int z, int y, int x, float *m);
-void QDECL Com_sprintf (char *dest, int size, const char *fmt, ...);
+void QDECL Com_sprintf (char *dest, int size, const char *fmt, ...);
// mode parm for FS_FOpenFile
typedef enum {
- FS_READ,
- FS_WRITE,
- FS_APPEND,
- FS_APPEND_SYNC
+ FS_READ,
+ FS_WRITE,
+ FS_APPEND,
+ FS_APPEND_SYNC
} fsMode_t;
typedef enum {
- FS_SEEK_CUR,
- FS_SEEK_END,
- FS_SEEK_SET
+ FS_SEEK_CUR,
+ FS_SEEK_END,
+ FS_SEEK_SET
} fsOrigin_t;
//=============================================
@@ -635,16 +850,16 @@ int Q_isupper( int c );
int Q_isalpha( int c );
// portable case insensitive compare
-int Q_stricmp (const char *s1, const char *s2);
-int Q_strncmp (const char *s1, const char *s2, int n);
-int Q_stricmpn (const char *s1, const char *s2, int n);
-char *Q_strlwr( char *s1 );
-char *Q_strupr( char *s1 );
-char *Q_strrchr( const char* string, int c );
+int Q_stricmp (const char *s1, const char *s2);
+int Q_strncmp (const char *s1, const char *s2, int n);
+int Q_stricmpn (const char *s1, const char *s2, int n);
+char *Q_strlwr( char *s1 );
+char *Q_strupr( char *s1 );
+char *Q_strrchr( const char* string, int c );
// buffer size safe library replacements
-void Q_strncpyz( char *dest, const char *src, int destsize );
-void Q_strcat( char *dest, int size, const char *src );
+void Q_strncpyz( char *dest, const char *src, int destsize );
+void Q_strcat( char *dest, int size, const char *src );
// strlen that discounts Quake color sequences
int Q_PrintStrlen( const char *string );
@@ -657,29 +872,30 @@ char *Q_CleanStr( char *string );
// implemented as a struct for qvm compatibility
typedef struct
{
- byte b0;
- byte b1;
- byte b2;
- byte b3;
- byte b4;
- byte b5;
- byte b6;
- byte b7;
+ byte b0;
+ byte b1;
+ byte b2;
+ byte b3;
+ byte b4;
+ byte b5;
+ byte b6;
+ byte b7;
} qint64;
//=============================================
-
-short BigShort(short l);
-short LittleShort(short l);
-int BigLong (int l);
-int LittleLong (int l);
+/*
+short BigShort(short l);
+short LittleShort(short l);
+int BigLong (int l);
+int LittleLong (int l);
qint64 BigLong64 (qint64 l);
qint64 LittleLong64 (qint64 l);
-float BigFloat (float l);
-float LittleFloat (float l);
+float BigFloat (const float *l);
+float LittleFloat (const float *l);
-void Swap_Init (void);
-char * QDECL va(char *format, ...);
+void Swap_Init (void);
+*/
+char * QDECL va(char *format, ...);
//=============================================
@@ -695,8 +911,8 @@ qboolean Info_Validate( const char *s );
void Info_NextPair( const char **s, char *key, char *value );
// this is only here so the functions in q_shared.c and bg_*.c can link
-void QDECL Com_Error( int level, const char *error, ... );
-void QDECL Com_Printf( const char *msg, ... );
+void QDECL Com_Error( int level, const char *error, ... );
+void QDECL Com_Printf( const char *msg, ... );
/*
@@ -710,52 +926,52 @@ default values.
==========================================================
*/
-#define CVAR_ARCHIVE 1 // set to cause it to be saved to vars.rc
- // used for system variables, not for player
- // specific configurations
-#define CVAR_USERINFO 2 // sent to server on connect or change
-#define CVAR_SERVERINFO 4 // sent in response to front end requests
-#define CVAR_SYSTEMINFO 8 // these cvars will be duplicated on all clients
-#define CVAR_INIT 16 // don't allow change from console at all,
- // but can be set from the command line
-#define CVAR_LATCH 32 // will only change when C code next does
- // a Cvar_Get(), so it can't be changed
- // without proper initialization. modified
- // will be set, even though the value hasn't
- // changed yet
-#define CVAR_ROM 64 // display only, cannot be set by user at all
-#define CVAR_USER_CREATED 128 // created by a set command
-#define CVAR_TEMP 256 // can be set even when cheats are disabled, but is not archived
-#define CVAR_CHEAT 512 // can not be changed if cheats are disabled
-#define CVAR_NORESTART 1024 // do not clear when a cvar_restart is issued
+#define CVAR_ARCHIVE 1 // set to cause it to be saved to vars.rc
+ // used for system variables, not for player
+ // specific configurations
+#define CVAR_USERINFO 2 // sent to server on connect or change
+#define CVAR_SERVERINFO 4 // sent in response to front end requests
+#define CVAR_SYSTEMINFO 8 // these cvars will be duplicated on all clients
+#define CVAR_INIT 16 // don't allow change from console at all,
+ // but can be set from the command line
+#define CVAR_LATCH 32 // will only change when C code next does
+ // a Cvar_Get(), so it can't be changed
+ // without proper initialization. modified
+ // will be set, even though the value hasn't
+ // changed yet
+#define CVAR_ROM 64 // display only, cannot be set by user at all
+#define CVAR_USER_CREATED 128 // created by a set command
+#define CVAR_TEMP 256 // can be set even when cheats are disabled, but is not archived
+#define CVAR_CHEAT 512 // can not be changed if cheats are disabled
+#define CVAR_NORESTART 1024 // do not clear when a cvar_restart is issued
// nothing outside the Cvar_*() functions should modify these fields!
typedef struct cvar_s {
- char *name;
- char *string;
- char *resetString; // cvar_restart will reset to this value
- char *latchedString; // for CVAR_LATCH vars
- int flags;
- qboolean modified; // set each time the cvar is changed
- int modificationCount; // incremented each time the cvar is changed
- float value; // atof( string )
- int integer; // atoi( string )
- struct cvar_s *next;
- struct cvar_s *hashNext;
+ char *name;
+ char *string;
+ char *resetString; // cvar_restart will reset to this value
+ char *latchedString; // for CVAR_LATCH vars
+ int flags;
+ qboolean modified; // set each time the cvar is changed
+ int modificationCount; // incremented each time the cvar is changed
+ float value; // atof( string )
+ int integer; // atoi( string )
+ struct cvar_s *next;
+ struct cvar_s *hashNext;
} cvar_t;
-#define MAX_CVAR_VALUE_STRING 256
+#define MAX_CVAR_VALUE_STRING 256
-typedef int cvarHandle_t;
+typedef int cvarHandle_t;
// the modules that run in the virtual machine can't access the cvar_t directly,
// so they must ask for structured updates
typedef struct {
- cvarHandle_t handle;
- int modificationCount;
- float value;
- int integer;
- char string[MAX_CVAR_VALUE_STRING];
+ cvarHandle_t handle;
+ int modificationCount;
+ float value;
+ int integer;
+ char string[MAX_CVAR_VALUE_STRING];
} vmCvar_t;
/*
@@ -766,14 +982,15 @@ COLLISION DETECTION
==============================================================
*/
-#include "surfaceflags.h" // shared with the q3map utility
+#include "surfaceflags.h" // shared with the q3map utility
// plane types are used to speed some tests
// 0-2 are axial planes
-#define PLANE_X 0
-#define PLANE_Y 1
-#define PLANE_Z 2
-#define PLANE_NON_AXIAL 3
+#define PLANE_X 0
+#define PLANE_Y 1
+#define PLANE_Z 2
+#define PLANE_NON_AXIAL 3
+
/*
=================
@@ -786,24 +1003,24 @@ PlaneTypeForNormal
// plane_t structure
// !!! if this is changed, it must be changed in asm code too !!!
typedef struct cplane_s {
- vec3_t normal;
- float dist;
- byte type; // for fast side tests: 0,1,2 = axial, 3 = nonaxial
- byte signbits; // signx + (signy<<1) + (signz<<2), used as lookup during collision
- byte pad[2];
+ vec3_t normal;
+ float dist;
+ byte type; // for fast side tests: 0,1,2 = axial, 3 = nonaxial
+ byte signbits; // signx + (signy<<1) + (signz<<2), used as lookup during collision
+ byte pad[2];
} cplane_t;
// a trace is returned when a box is swept through the world
typedef struct {
- qboolean allsolid; // if true, plane is not valid
- qboolean startsolid; // if true, the initial point was in a solid area
- float fraction; // time completed, 1.0 = didn't hit anything
- vec3_t endpos; // final position
- cplane_t plane; // surface normal at impact, transformed to world space
- int surfaceFlags; // surface hit
- int contents; // contents on other side of surface hit
- int entityNum; // entity the contacted sirface is a part of
+ qboolean allsolid; // if true, plane is not valid
+ qboolean startsolid; // if true, the initial point was in a solid area
+ float fraction; // time completed, 1.0 = didn't hit anything
+ vec3_t endpos; // final position
+ cplane_t plane; // surface normal at impact, transformed to world space
+ int surfaceFlags; // surface hit
+ int contents; // contents on other side of surface hit
+ int entityNum; // entity the contacted sirface is a part of
} trace_t;
// trace->entityNum can also be 0 to (MAX_GENTITIES-1)
@@ -812,15 +1029,15 @@ typedef struct {
// markfragments are returned by CM_MarkFragments()
typedef struct {
- int firstPoint;
- int numPoints;
+ int firstPoint;
+ int numPoints;
} markFragment_t;
typedef struct {
- vec3_t origin;
- vec3_t axis[3];
+ vec3_t origin;
+ vec3_t axis[3];
} orientation_t;
//=====================================================================
@@ -828,23 +1045,24 @@ typedef struct {
// in order from highest priority to lowest
// if none of the catchers are active, bound key strings will be executed
-#define KEYCATCH_CONSOLE 0x0001
-#define KEYCATCH_UI 0x0002
-#define KEYCATCH_MESSAGE 0x0004
-#define KEYCATCH_CGAME 0x0008
+#define KEYCATCH_CONSOLE 0x0001
+#define KEYCATCH_UI 0x0002
+#define KEYCATCH_MESSAGE 0x0004
+#define KEYCATCH_CGAME 0x0008
+
// sound channels
// channel 0 never willingly overrides
// other channels will allways override a playing sound on that channel
typedef enum {
- CHAN_AUTO,
- CHAN_LOCAL, // menu sounds, etc
- CHAN_WEAPON,
- CHAN_VOICE,
- CHAN_ITEM,
- CHAN_BODY,
- CHAN_LOCAL_SOUND, // chat messages, etc
- CHAN_ANNOUNCER // announcer voices, etc
+ CHAN_AUTO,
+ CHAN_LOCAL, // menu sounds, etc
+ CHAN_WEAPON,
+ CHAN_VOICE,
+ CHAN_ITEM,
+ CHAN_BODY,
+ CHAN_LOCAL_SOUND, // chat messages, etc
+ CHAN_ANNOUNCER // announcer voices, etc
} soundChannel_t;
@@ -856,61 +1074,61 @@ typedef enum {
========================================================================
*/
-#define ANGLE2SHORT(x) ((int)((x)*65536/360) & 65535)
-#define SHORT2ANGLE(x) ((x)*(360.0/65536))
+#define ANGLE2SHORT(x) ((int)((x)*65536/360) & 65535)
+#define SHORT2ANGLE(x) ((x)*(360.0/65536))
-#define SNAPFLAG_RATE_DELAYED 1
-#define SNAPFLAG_NOT_ACTIVE 2 // snapshot used during connection and for zombies
-#define SNAPFLAG_SERVERCOUNT 4 // toggled every map_restart so transitions can be detected
+#define SNAPFLAG_RATE_DELAYED 1
+#define SNAPFLAG_NOT_ACTIVE 2 // snapshot used during connection and for zombies
+#define SNAPFLAG_SERVERCOUNT 4 // toggled every map_restart so transitions can be detected
//
// per-level limits
//
-#define MAX_CLIENTS 64 // absolute limit
-#define MAX_LOCATIONS 64
+#define MAX_CLIENTS 64 // absolute limit
+#define MAX_LOCATIONS 64
-#define GENTITYNUM_BITS 10 // don't need to send any more
-#define MAX_GENTITIES (1<<GENTITYNUM_BITS)
+#define GENTITYNUM_BITS 10 // don't need to send any more
+#define MAX_GENTITIES (1<<GENTITYNUM_BITS)
// entitynums are communicated with GENTITY_BITS, so any reserved
// values thatare going to be communcated over the net need to
// also be in this range
-#define ENTITYNUM_NONE (MAX_GENTITIES-1)
-#define ENTITYNUM_WORLD (MAX_GENTITIES-2)
-#define ENTITYNUM_MAX_NORMAL (MAX_GENTITIES-2)
+#define ENTITYNUM_NONE (MAX_GENTITIES-1)
+#define ENTITYNUM_WORLD (MAX_GENTITIES-2)
+#define ENTITYNUM_MAX_NORMAL (MAX_GENTITIES-2)
-#define MAX_MODELS 256 // these are sent over the net as 8 bits
-#define MAX_SOUNDS 256 // so they cannot be blindly increased
+#define MAX_MODELS 256 // these are sent over the net as 8 bits
+#define MAX_SOUNDS 256 // so they cannot be blindly increased
-#define MAX_CONFIGSTRINGS 1024
+#define MAX_CONFIGSTRINGS 1024
// these are the only configstrings that the system reserves, all the
// other ones are strictly for servergame to clientgame communication
-#define CS_SERVERINFO 0 // an info string with all the serverinfo cvars
-#define CS_SYSTEMINFO 1 // an info string for server system to client system configuration (timescale, etc)
+#define CS_SERVERINFO 0 // an info string with all the serverinfo cvars
+#define CS_SYSTEMINFO 1 // an info string for server system to client system configuration (timescale, etc)
-#define RESERVED_CONFIGSTRINGS 2 // game can't modify below this, only the system can
+#define RESERVED_CONFIGSTRINGS 2 // game can't modify below this, only the system can
-#define MAX_GAMESTATE_CHARS 16000
+#define MAX_GAMESTATE_CHARS 16000
typedef struct {
- int stringOffsets[MAX_CONFIGSTRINGS];
- char stringData[MAX_GAMESTATE_CHARS];
- int dataCount;
+ int stringOffsets[MAX_CONFIGSTRINGS];
+ char stringData[MAX_GAMESTATE_CHARS];
+ int dataCount;
} gameState_t;
//=========================================================
// bit field limits
-#define MAX_STATS 16
-#define MAX_PERSISTANT 16
-#define MAX_POWERUPS 16
-#define MAX_WEAPONS 16
+#define MAX_STATS 16
+#define MAX_PERSISTANT 16
+#define MAX_POWERUPS 16
+#define MAX_WEAPONS 16
-#define MAX_PS_EVENTS 2
+#define MAX_PS_EVENTS 2
-#define PS_PMOVEFRAMECOUNTBITS 6
+#define PS_PMOVEFRAMECOUNTBITS 6
// playerState_t is the information needed by both the client and server
// to predict player motion and actions
@@ -923,75 +1141,72 @@ typedef struct {
// so if a playerState_t is transmitted, the entityState_t can be fully derived
// from it.
typedef struct playerState_s {
- int commandTime; // cmd->serverTime of last executed command
- int pm_type;
- int bobCycle; // for view bobbing and footstep generation
- int pm_flags; // ducked, jump_held, etc
- int pm_time;
-
- vec3_t origin;
- vec3_t velocity;
- int weaponTime;
- int gravity;
- int speed;
- int delta_angles[3]; // add to command angles to get view direction
- // changed by spawns, rotating objects, and teleporters
-
- int groundEntityNum;// ENTITYNUM_NONE = in air
-
- int legsTimer; // don't change low priority animations until this runs out
- int legsAnim; // mask off ANIM_TOGGLEBIT
-
- int torsoTimer; // don't change low priority animations until this runs out
- int torsoAnim; // mask off ANIM_TOGGLEBIT
-
- int movementDir; // a number 0 to 7 that represents the reletive angle
- // of movement to the view angle (axial and diagonals)
- // when at rest, the value will remain unchanged
- // used to twist the legs during strafing
-
- //TA: this is also used by wall climbing classes As I can't add anything to the
- // playerState_t struct.This means wall climbing classes won't ever be able to use
- // a grapple hook. Does this matter?
- vec3_t grapplePoint; // location of grapple to pull towards if PMF_GRAPPLE_PULL
-
- int eFlags; // copied to entityState_t->eFlags
-
- int eventSequence; // pmove generated events
- int events[MAX_PS_EVENTS];
- int eventParms[MAX_PS_EVENTS];
-
- int externalEvent; // events set on player from another source
- int externalEventParm;
- int externalEventTime;
-
- int clientNum; // ranges from 0 to MAX_CLIENTS-1
- int weapon; // copied to entityState_t->weapon
- int weaponstate;
-
- vec3_t viewangles; // for fixed views
- int viewheight;
-
- // damage feedback
- int damageEvent; // when it changes, latch the other parms
- int damageYaw;
- int damagePitch;
- int damageCount;
-
- int stats[MAX_STATS];
- int persistant[MAX_PERSISTANT]; // stats that aren't cleared on death
- int powerups[MAX_POWERUPS]; // level.time that the powerup runs out
- int ammo[MAX_WEAPONS];
-
- int generic1;
- int loopSound;
- int jumppad_ent; // jumppad entity hit this frame
-
- // not communicated over the net at all
- int ping; // server to game info for scoreboard
- int pmove_framecount; // FIXME: don't transmit over the network
- int jumppad_frame;
- int entityEventSequence;
+ int commandTime; // cmd->serverTime of last executed command
+ int pm_type;
+ int bobCycle; // for view bobbing and footstep generation
+ int pm_flags; // ducked, jump_held, etc
+ int pm_time;
+
+ vec3_t origin;
+ vec3_t velocity;
+ int weaponTime;
+ int gravity;
+ int speed;
+ int delta_angles[3]; // add to command angles to get view direction
+ // changed by spawns, rotating objects, and teleporters
+
+ int groundEntityNum;// ENTITYNUM_NONE = in air
+
+ int legsTimer; // don't change low priority animations until this runs out
+ int legsAnim; // mask off ANIM_TOGGLEBIT
+
+ int torsoTimer; // don't change low priority animations until this runs out
+ int torsoAnim; // mask off ANIM_TOGGLEBIT
+
+ int movementDir; // a number 0 to 7 that represents the reletive angle
+ // of movement to the view angle (axial and diagonals)
+ // when at rest, the value will remain unchanged
+ // used to twist the legs during strafing
+
+ vec3_t grapplePoint; // location of grapple to pull towards if PMF_GRAPPLE_PULL
+
+ int eFlags; // copied to entityState_t->eFlags
+
+ int eventSequence; // pmove generated events
+ int events[MAX_PS_EVENTS];
+ int eventParms[MAX_PS_EVENTS];
+
+ int externalEvent; // events set on player from another source
+ int externalEventParm;
+ int externalEventTime;
+
+ int clientNum; // ranges from 0 to MAX_CLIENTS-1
+ int weapon; // copied to entityState_t->weapon
+ int weaponstate;
+
+ vec3_t viewangles; // for fixed views
+ int viewheight;
+
+ // damage feedback
+ int damageEvent; // when it changes, latch the other parms
+ int damageYaw;
+ int damagePitch;
+ int damageCount;
+
+ int stats[MAX_STATS];
+ int persistant[MAX_PERSISTANT]; // stats that aren't cleared on death
+ int powerups[MAX_POWERUPS]; // level.time that the powerup runs out
+ int ammo[MAX_WEAPONS];
+
+ int generic1;
+ int loopSound;
+ int jumppad_ent; // jumppad entity hit this frame
+
+ // not communicated over the net at all
+ int ping; // server to game info for scoreboard
+ int pmove_framecount; // FIXME: don't transmit over the network
+ int jumppad_frame;
+ int entityEventSequence;
} playerState_t;
@@ -1002,58 +1217,57 @@ typedef struct playerState_s {
// usercmd_t->button bits, many of which are generated by the client system,
// so they aren't game/cgame only definitions
//
-#define BUTTON_ATTACK 1
-#define BUTTON_TALK 2 // displays talk balloon and disables actions
-#define BUTTON_USE_HOLDABLE 4
-#define BUTTON_GESTURE 8
-#define BUTTON_WALKING 16 // walking can't just be infered from MOVE_RUN
- // because a key pressed late in the frame will
- // only generate a small move value for that frame
- // walking will use different animations and
- // won't generate footsteps
+#define BUTTON_ATTACK 1
+#define BUTTON_TALK 2 // displays talk balloon and disables actions
+#define BUTTON_USE_HOLDABLE 4
+#define BUTTON_GESTURE 8
+#define BUTTON_WALKING 16 // walking can't just be infered from MOVE_RUN
+ // because a key pressed late in the frame will
+ // only generate a small move value for that frame
+ // walking will use different animations and
+ // won't generate footsteps
#define BUTTON_ATTACK2 32 //TA: should be safe to change from BUTTON_AFFIRMATIVE
-#define BUTTON_NEGATIVE 64
+#define BUTTON_NEGATIVE 64
-#define BUTTON_GETFLAG 128
-#define BUTTON_GUARDBASE 256
-#define BUTTON_PATROL 512
-#define BUTTON_FOLLOWME 1024
+#define BUTTON_GETFLAG 128
+#define BUTTON_GUARDBASE 256
+#define BUTTON_PATROL 512
+#define BUTTON_FOLLOWME 1024
-#define BUTTON_ANY 2048 // any key whatsoever
-
-#define MOVE_RUN 120 // if forwardmove or rightmove are >= MOVE_RUN,
- // then BUTTON_WALKING should be set
+#define BUTTON_ANY 2048 // any key whatsoever
+#define MOVE_RUN 120 // if forwardmove or rightmove are >= MOVE_RUN,
+ // then BUTTON_WALKING should be set
// usercmd_t is sent to the server each client frame
typedef struct usercmd_s {
- int serverTime;
- int angles[3];
- int buttons;
- byte weapon; //weapon
- signed char forwardmove, rightmove, upmove;
+ int serverTime;
+ int angles[3];
+ int buttons;
+ byte weapon; // weapon
+ signed char forwardmove, rightmove, upmove;
} usercmd_t;
//===================================================================
// if entityState->solid == SOLID_BMODEL, modelindex is an inline model number
-#define SOLID_BMODEL 0xffffff
+#define SOLID_BMODEL 0xffffff
typedef enum {
- TR_STATIONARY,
- TR_INTERPOLATE, // non-parametric, but interpolate between snapshots
- TR_LINEAR,
- TR_LINEAR_STOP,
- TR_SINE, // value = base + sin( time / duration ) * delta
- TR_GRAVITY
+ TR_STATIONARY,
+ TR_INTERPOLATE, // non-parametric, but interpolate between snapshots
+ TR_LINEAR,
+ TR_LINEAR_STOP,
+ TR_SINE, // value = base + sin( time / duration ) * delta
+ TR_GRAVITY
} trType_t;
typedef struct {
- trType_t trType;
- int trTime;
- int trDuration; // if non 0, trTime + trDuration = stop time
- vec3_t trBase;
- vec3_t trDelta; // velocity, etc
+ trType_t trType;
+ int trTime;
+ int trDuration; // if non 0, trTime + trDuration = stop time
+ vec3_t trBase;
+ vec3_t trDelta; // velocity, etc
} trajectory_t;
// entityState_t is the information conveyed from the server
@@ -1064,60 +1278,60 @@ typedef struct {
// the structure size is fairly large
typedef struct entityState_s {
- int number; // entity index
- int eType; // entityType_t
- int eFlags;
+ int number; // entity index
+ int eType; // entityType_t
+ int eFlags;
- trajectory_t pos; // for calculating position
- trajectory_t apos; // for calculating angles
+ trajectory_t pos; // for calculating position
+ trajectory_t apos; // for calculating angles
- int time;
- int time2;
+ int time;
+ int time2;
- vec3_t origin;
- vec3_t origin2;
+ vec3_t origin;
+ vec3_t origin2;
- vec3_t angles;
- vec3_t angles2;
+ vec3_t angles;
+ vec3_t angles2;
- int otherEntityNum; // shotgun sources, etc
- int otherEntityNum2;
+ int otherEntityNum; // shotgun sources, etc
+ int otherEntityNum2;
- int groundEntityNum; // -1 = in air
+ int groundEntityNum; // -1 = in air
- int constantLight; // r + (g<<8) + (b<<16) + (intensity<<24)
- int loopSound; // constantly loop this sound
+ int constantLight; // r + (g<<8) + (b<<16) + (intensity<<24)
+ int loopSound; // constantly loop this sound
- int modelindex;
- int modelindex2;
- int clientNum; // 0 to (MAX_CLIENTS - 1), for players and corpses
- int frame;
+ int modelindex;
+ int modelindex2;
+ int clientNum; // 0 to (MAX_CLIENTS - 1), for players and corpses
+ int frame;
- int solid; // for client side prediction, trap_linkentity sets this properly
+ int solid; // for client side prediction, trap_linkentity sets this properly
- int event; // impulse events -- muzzle flashes, footsteps, etc
- int eventParm;
+ int event; // impulse events -- muzzle flashes, footsteps, etc
+ int eventParm;
- // for players
- int powerups; // bit flags
- int weapon; // determines weapon and flash model, etc
- int legsAnim; // mask off ANIM_TOGGLEBIT
- int torsoAnim; // mask off ANIM_TOGGLEBIT
+ // for players
+ int powerups; // bit flags
+ int weapon; // determines weapon and flash model, etc
+ int legsAnim; // mask off ANIM_TOGGLEBIT
+ int torsoAnim; // mask off ANIM_TOGGLEBIT
- int generic1;
+ int generic1;
} entityState_t;
typedef enum {
- CA_UNINITIALIZED,
- CA_DISCONNECTED, // not talking to a server
- CA_AUTHORIZING, // not used any more, was checking cd key
- CA_CONNECTING, // sending request packets to the server
- CA_CHALLENGING, // sending challenge packets to the server
- CA_CONNECTED, // netchan_t established, getting gamestate
- CA_LOADING, // only during cgame initialization, never during main loop
- CA_PRIMED, // got gamestate, waiting for first frame
- CA_ACTIVE, // game views should be displayed
- CA_CINEMATIC // playing a cinematic or a static pic, not connected to a server
+ CA_UNINITIALIZED,
+ CA_DISCONNECTED, // not talking to a server
+ CA_AUTHORIZING, // not used any more, was checking cd key
+ CA_CONNECTING, // sending request packets to the server
+ CA_CHALLENGING, // sending challenge packets to the server
+ CA_CONNECTED, // netchan_t established, getting gamestate
+ CA_LOADING, // only during cgame initialization, never during main loop
+ CA_PRIMED, // got gamestate, waiting for first frame
+ CA_ACTIVE, // game views should be displayed
+ CA_CINEMATIC // playing a cinematic or a static pic, not connected to a server
} connstate_t;
// font support
@@ -1140,13 +1354,13 @@ typedef struct {
float s2;
float t2;
qhandle_t glyph; // handle to the shader with the glyph
- char shaderName[32];
+ char shaderName[32];
} glyphInfo_t;
typedef struct {
glyphInfo_t glyphs [GLYPHS_PER_FONT];
- float glyphScale;
- char name[MAX_QPATH];
+ float glyphScale;
+ char name[MAX_QPATH];
} fontInfo_t;
#define Square(x) ((x)*(x))
@@ -1156,56 +1370,57 @@ typedef struct {
typedef struct qtime_s {
- int tm_sec; /* seconds after the minute - [0,59] */
- int tm_min; /* minutes after the hour - [0,59] */
- int tm_hour; /* hours since midnight - [0,23] */
- int tm_mday; /* day of the month - [1,31] */
- int tm_mon; /* months since January - [0,11] */
- int tm_year; /* years since 1900 */
- int tm_wday; /* days since Sunday - [0,6] */
- int tm_yday; /* days since January 1 - [0,365] */
- int tm_isdst; /* daylight savings time flag */
+ int tm_sec; /* seconds after the minute - [0,59] */
+ int tm_min; /* minutes after the hour - [0,59] */
+ int tm_hour; /* hours since midnight - [0,23] */
+ int tm_mday; /* day of the month - [1,31] */
+ int tm_mon; /* months since January - [0,11] */
+ int tm_year; /* years since 1900 */
+ int tm_wday; /* days since Sunday - [0,6] */
+ int tm_yday; /* days since January 1 - [0,365] */
+ int tm_isdst; /* daylight savings time flag */
} qtime_t;
// server browser sources
-#define AS_LOCAL 0
-#define AS_MPLAYER 1
-#define AS_GLOBAL 2
-#define AS_FAVORITES 3
+#define AS_LOCAL 0
+#define AS_MPLAYER 1
+#define AS_GLOBAL 2
+#define AS_FAVORITES 3
// cinematic states
typedef enum {
- FMV_IDLE,
- FMV_PLAY, // play
- FMV_EOF, // all other conditions, i.e. stop/EOF/abort
- FMV_ID_BLT,
- FMV_ID_IDLE,
- FMV_LOOPED,
- FMV_ID_WAIT
+ FMV_IDLE,
+ FMV_PLAY, // play
+ FMV_EOF, // all other conditions, i.e. stop/EOF/abort
+ FMV_ID_BLT,
+ FMV_ID_IDLE,
+ FMV_LOOPED,
+ FMV_ID_WAIT
} e_status;
typedef enum _flag_status {
- FLAG_ATBASE = 0,
- FLAG_TAKEN, // CTF
- FLAG_TAKEN_RED, // One Flag CTF
- FLAG_TAKEN_BLUE, // One Flag CTF
- FLAG_DROPPED
+ FLAG_ATBASE = 0,
+ FLAG_TAKEN, // CTF
+ FLAG_TAKEN_RED, // One Flag CTF
+ FLAG_TAKEN_BLUE, // One Flag CTF
+ FLAG_DROPPED
} flagStatus_t;
-#define MAX_GLOBAL_SERVERS 2048
-#define MAX_OTHER_SERVERS 128
-#define MAX_PINGREQUESTS 32
-#define MAX_SERVERSTATUSREQUESTS 16
+#define MAX_GLOBAL_SERVERS 2048
+#define MAX_OTHER_SERVERS 128
+#define MAX_PINGREQUESTS 32
+#define MAX_SERVERSTATUSREQUESTS 16
-#define SAY_ALL 0
-#define SAY_TEAM 1
-#define SAY_TELL 2
+#define SAY_ALL 0
+#define SAY_TEAM 1
+#define SAY_TELL 2
#define CDKEY_LEN 16
#define CDCHKSUM_LEN 2
-#endif // __Q_SHARED_H
+
+#endif // __Q_SHARED_H
diff --git a/src/game/surfaceflags.h b/src/game/surfaceflags.h
index 5daa3b1d..a1454800 100644
--- a/src/game/surfaceflags.h
+++ b/src/game/surfaceflags.h
@@ -37,6 +37,10 @@
#define CONTENTS_WATER 32
#define CONTENTS_FOG 64
+#define CONTENTS_NOTTEAM1 0x0080
+#define CONTENTS_NOTTEAM2 0x0100
+#define CONTENTS_NOBOTCLIP 0x0200
+
#define CONTENTS_AREAPORTAL 0x8000
#define CONTENTS_PLAYERCLIP 0x10000