diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/cgame/cg_particles.c | 1997 | ||||
-rw-r--r-- | src/game/bg_pmove.c | 4 | ||||
-rw-r--r-- | src/game/g_combat.c | 4 | ||||
-rw-r--r-- | src/game/q_math.c | 134 | ||||
-rw-r--r-- | src/game/q_shared.c | 178 | ||||
-rw-r--r-- | src/game/q_shared.h | 1325 | ||||
-rw-r--r-- | src/game/surfaceflags.h | 4 |
8 files changed, 2956 insertions, 692 deletions
@@ -186,7 +186,7 @@ SED=sed # --qvm building config-- LCC_CPP=q3cpp -LCC_CPP_FLAGS=-DQ3_VM +LCC_CPP_FLAGS=-DQ3_VM -D__LCC__ LCC_INCLUDES=-I$(CGDIR) -I$(GDIR) -I$(UIDIR) LCC_RCC=q3rcc 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 |