summaryrefslogtreecommitdiff
path: root/src/cgame
diff options
context:
space:
mode:
Diffstat (limited to 'src/cgame')
-rw-r--r--src/cgame/cg_animation.c101
-rw-r--r--src/cgame/cg_animmapobj.c193
-rw-r--r--src/cgame/cg_attachment.c395
-rw-r--r--src/cgame/cg_buildable.c1051
-rw-r--r--src/cgame/cg_consolecmds.c279
-rw-r--r--src/cgame/cg_draw.c3393
-rw-r--r--src/cgame/cg_drawtools.c308
-rw-r--r--src/cgame/cg_ents.c1225
-rw-r--r--src/cgame/cg_event.c1011
-rw-r--r--src/cgame/cg_local.h2003
-rw-r--r--src/cgame/cg_main.c1801
-rw-r--r--src/cgame/cg_marks.c280
-rw-r--r--src/cgame/cg_mem.c191
-rw-r--r--src/cgame/cg_particles.c2551
-rw-r--r--src/cgame/cg_players.c2575
-rw-r--r--src/cgame/cg_playerstate.c308
-rw-r--r--src/cgame/cg_predict.c615
-rw-r--r--src/cgame/cg_ptr.c71
-rw-r--r--src/cgame/cg_public.h227
-rw-r--r--src/cgame/cg_scanner.c355
-rw-r--r--src/cgame/cg_servercmds.c1130
-rw-r--r--src/cgame/cg_snapshot.c402
-rw-r--r--src/cgame/cg_syscalls.asm105
-rw-r--r--src/cgame/cg_syscalls.c507
-rw-r--r--src/cgame/cg_trails.c1489
-rw-r--r--src/cgame/cg_view.c1330
-rw-r--r--src/cgame/cg_weapons.c1810
-rw-r--r--src/cgame/tr_types.h225
28 files changed, 0 insertions, 25931 deletions
diff --git a/src/cgame/cg_animation.c b/src/cgame/cg_animation.c
deleted file mode 100644
index 5295998e..00000000
--- a/src/cgame/cg_animation.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-/*
-===============
-CG_RunLerpFrame
-
-Sets cg.snap, cg.oldFrame, and cg.backlerp
-cg.time should be between oldFrameTime and frameTime after exit
-===============
-*/
-void CG_RunLerpFrame( lerpFrame_t *lf )
-{
- int f, numFrames;
- animation_t *anim;
-
- // debugging tool to get no animations
- if( cg_animSpeed.integer == 0 )
- {
- lf->oldFrame = lf->frame = lf->backlerp = 0;
- return;
- }
-
- // if we have passed the current frame, move it to
- // oldFrame and calculate a new frame
- if( cg.time >= lf->frameTime )
- {
- lf->oldFrame = lf->frame;
- lf->oldFrameTime = lf->frameTime;
-
- // get the next frame based on the animation
- anim = lf->animation;
- if( !anim->frameLerp )
- return; // shouldn't happen
-
- if( cg.time < lf->animationTime )
- lf->frameTime = lf->animationTime; // initial lerp
- else
- lf->frameTime = lf->oldFrameTime + anim->frameLerp;
-
- f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp;
- numFrames = anim->numFrames;
- if( anim->flipflop )
- numFrames *= 2;
-
- if( f >= numFrames )
- {
- f -= numFrames;
- if( anim->loopFrames )
- {
- f %= anim->loopFrames;
- f += anim->numFrames - anim->loopFrames;
- }
- else
- {
- f = numFrames - 1;
- // the animation is stuck at the end, so it
- // can immediately transition to another sequence
- lf->frameTime = cg.time;
- }
- }
-
- if( anim->reversed )
- lf->frame = anim->firstFrame + anim->numFrames - 1 - f;
- else if( anim->flipflop && f >= anim->numFrames )
- lf->frame = anim->firstFrame + anim->numFrames - 1 - ( f % anim->numFrames );
- else
- lf->frame = anim->firstFrame + f;
-
- if( cg.time > lf->frameTime )
- {
- lf->frameTime = cg.time;
- if( cg_debugAnim.integer )
- CG_Printf( "Clamp lf->frameTime\n" );
- }
- }
-
- if( lf->frameTime > cg.time + 200 )
- lf->frameTime = cg.time;
-
- if( lf->oldFrameTime > cg.time )
- lf->oldFrameTime = cg.time;
-
- // calculate current lerp value
- if( lf->frameTime == lf->oldFrameTime )
- lf->backlerp = 0;
- else
- lf->backlerp = 1.0 - (float)( cg.time - lf->oldFrameTime ) / ( lf->frameTime - lf->oldFrameTime );
-}
diff --git a/src/cgame/cg_animmapobj.c b/src/cgame/cg_animmapobj.c
deleted file mode 100644
index f0e964bf..00000000
--- a/src/cgame/cg_animmapobj.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-
-/*
-===============
-CG_DoorAnimation
-===============
-*/
-static void CG_DoorAnimation( centity_t *cent, int *old, int *now, float *backLerp )
-{
- CG_RunLerpFrame( &cent->lerpFrame );
-
- *old = cent->lerpFrame.oldFrame;
- *now = cent->lerpFrame.frame;
- *backLerp = cent->lerpFrame.backlerp;
-}
-
-
-/*
-===============
-CG_ModelDoor
-===============
-*/
-void CG_ModelDoor( centity_t *cent )
-{
- refEntity_t ent;
- entityState_t *es;
- animation_t anim;
- lerpFrame_t *lf = &cent->lerpFrame;
-
- es = &cent->currentState;
-
- if( !es->modelindex )
- return;
-
- //create the render entity
- memset( &ent, 0, sizeof( ent ) );
- VectorCopy( cent->lerpOrigin, ent.origin );
- VectorCopy( cent->lerpOrigin, ent.oldorigin );
- AnglesToAxis( cent->lerpAngles, ent.axis );
-
- ent.renderfx = RF_NOSHADOW;
-
- //add the door model
- ent.skinNum = 0;
- ent.hModel = cgs.gameModels[ es->modelindex ];
-
- //scale the door
- VectorScale( ent.axis[ 0 ], es->origin2[ 0 ], ent.axis[ 0 ] );
- VectorScale( ent.axis[ 1 ], es->origin2[ 1 ], ent.axis[ 1 ] );
- VectorScale( ent.axis[ 2 ], es->origin2[ 2 ], ent.axis[ 2 ] );
- ent.nonNormalizedAxes = qtrue;
-
- //setup animation
- anim.firstFrame = es->powerups;
- anim.numFrames = es->weapon;
- anim.reversed = !es->legsAnim;
- anim.flipflop = qfalse;
- anim.loopFrames = 0;
- anim.frameLerp = 1000 / es->torsoAnim;
- anim.initialLerp = 1000 / es->torsoAnim;
-
- //door changed state
- if( es->legsAnim != cent->doorState )
- {
- lf->animationTime = lf->frameTime + anim.initialLerp;
- cent->doorState = es->legsAnim;
- }
-
- lf->animation = &anim;
-
- //run animation
- CG_DoorAnimation( cent, &ent.oldframe, &ent.frame, &ent.backlerp );
-
- trap_R_AddRefEntityToScene( &ent );
-}
-
-
-/*
-===============
-CG_AMOAnimation
-===============
-*/
-static void CG_AMOAnimation( centity_t *cent, int *old, int *now, float *backLerp )
-{
- if( !( cent->currentState.eFlags & EF_MOVER_STOP ) )
- {
- int delta = cg.time - cent->miscTime;
-
- //hack to prevent "pausing" mucking up the lerping
- if( delta > 900 )
- {
- cent->lerpFrame.oldFrameTime += delta;
- cent->lerpFrame.frameTime += delta;
- }
-
- CG_RunLerpFrame( &cent->lerpFrame );
- cent->miscTime = cg.time;
- }
-
- *old = cent->lerpFrame.oldFrame;
- *now = cent->lerpFrame.frame;
- *backLerp = cent->lerpFrame.backlerp;
-}
-
-
-/*
-==================
-CG_animMapObj
-==================
-*/
-void CG_AnimMapObj( centity_t *cent )
-{
- refEntity_t ent;
- entityState_t *es;
- float scale;
- animation_t anim;
-
- es = &cent->currentState;
-
- // if set to invisible, skip
- if( !es->modelindex || ( es->eFlags & EF_NODRAW ) )
- return;
-
- memset( &ent, 0, sizeof( ent ) );
-
- VectorCopy( es->angles, cent->lerpAngles );
- AnglesToAxis( cent->lerpAngles, ent.axis );
-
- ent.hModel = cgs.gameModels[ es->modelindex ];
-
- VectorCopy( cent->lerpOrigin, ent.origin);
- VectorCopy( cent->lerpOrigin, ent.oldorigin);
-
- ent.nonNormalizedAxes = qfalse;
-
- //scale the model
- if( es->angles2[ 0 ] )
- {
- scale = es->angles2[ 0 ];
- VectorScale( ent.axis[ 0 ], scale, ent.axis[ 0 ] );
- VectorScale( ent.axis[ 1 ], scale, ent.axis[ 1 ] );
- VectorScale( ent.axis[ 2 ], scale, ent.axis[ 2 ] );
- ent.nonNormalizedAxes = qtrue;
- }
-
- //setup animation
- anim.firstFrame = es->powerups;
- anim.numFrames = es->weapon;
- anim.reversed = qfalse;
- anim.flipflop = qfalse;
-
- // if numFrames is negative the animation is reversed
- if( anim.numFrames < 0 )
- {
- anim.numFrames = -anim.numFrames;
- anim.reversed = qtrue;
- }
-
- anim.loopFrames = es->torsoAnim;
-
- if( !es->legsAnim )
- {
- anim.frameLerp = 1000;
- anim.initialLerp = 1000;
- }
- else
- {
- anim.frameLerp = 1000 / es->legsAnim;
- anim.initialLerp = 1000 / es->legsAnim;
- }
-
- cent->lerpFrame.animation = &anim;
-
- //run animation
- CG_AMOAnimation( cent, &ent.oldframe, &ent.frame, &ent.backlerp );
-
- // add to refresh list
- trap_R_AddRefEntityToScene(&ent);
-}
diff --git a/src/cgame/cg_attachment.c b/src/cgame/cg_attachment.c
deleted file mode 100644
index a256318b..00000000
--- a/src/cgame/cg_attachment.c
+++ /dev/null
@@ -1,395 +0,0 @@
-// cg_attachment.c -- an abstract attachment system
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-/*
-===============
-CG_AttachmentPoint
-
-Return the attachment point
-===============
-*/
-qboolean CG_AttachmentPoint( attachment_t *a, vec3_t v )
-{
- centity_t *cent;
-
- if( !a )
- return qfalse;
-
- // if it all breaks, then use the last point we know was correct
- VectorCopy( a->lastValidAttachmentPoint, v );
-
- switch( a->type )
- {
- case AT_STATIC:
- if( !a->staticValid )
- return qfalse;
-
- VectorCopy( a->origin, v );
- break;
-
- case AT_TAG:
- if( !a->tagValid )
- return qfalse;
-
- AxisCopy( axisDefault, a->re.axis );
- CG_PositionRotatedEntityOnTag( &a->re, &a->parent,
- a->model, a->tagName );
- VectorCopy( a->re.origin, v );
- break;
-
- case AT_CENT:
- if( !a->centValid )
- return qfalse;
-
- if( a->centNum == cg.predictedPlayerState.clientNum )
- {
- // this is smoother if it's the local client
- VectorCopy( cg.predictedPlayerState.origin, v );
- }
- else
- {
- cent = &cg_entities[ a->centNum ];
- VectorCopy( cent->lerpOrigin, v );
- }
- break;
-
- case AT_PARTICLE:
- if( !a->particleValid )
- return qfalse;
-
- if( !a->particle->valid )
- {
- a->particleValid = qfalse;
- return qfalse;
- }
- else
- VectorCopy( a->particle->origin, v );
- break;
-
- default:
- CG_Printf( S_COLOR_RED "ERROR: Invalid attachmentType_t in attachment\n" );
- break;
- }
-
- if( a->hasOffset )
- VectorAdd( v, a->offset, v );
-
- VectorCopy( v, a->lastValidAttachmentPoint );
-
- return qtrue;
-}
-
-/*
-===============
-CG_AttachmentDir
-
-Return the attachment direction
-===============
-*/
-qboolean CG_AttachmentDir( attachment_t *a, vec3_t v )
-{
- vec3_t forward;
- centity_t *cent;
-
- if( !a )
- return qfalse;
-
- switch( a->type )
- {
- case AT_STATIC:
- return qfalse;
- break;
-
- case AT_TAG:
- if( !a->tagValid )
- return qfalse;
-
- VectorCopy( a->re.axis[ 0 ], v );
- break;
-
- case AT_CENT:
- if( !a->centValid )
- return qfalse;
-
- cent = &cg_entities[ a->centNum ];
- AngleVectors( cent->lerpAngles, forward, NULL, NULL );
- VectorCopy( forward, v );
- break;
-
- case AT_PARTICLE:
- if( !a->particleValid )
- return qfalse;
-
- if( !a->particle->valid )
- {
- a->particleValid = qfalse;
- return qfalse;
- }
- else
- VectorCopy( a->particle->velocity, v );
- break;
-
- default:
- CG_Printf( S_COLOR_RED "ERROR: Invalid attachmentType_t in attachment\n" );
- break;
- }
-
- VectorNormalize( v );
- return qtrue;
-}
-
-/*
-===============
-CG_AttachmentAxis
-
-Return the attachment axis
-===============
-*/
-qboolean CG_AttachmentAxis( attachment_t *a, vec3_t axis[ 3 ] )
-{
- centity_t *cent;
-
- if( !a )
- return qfalse;
-
- switch( a->type )
- {
- case AT_STATIC:
- return qfalse;
- break;
-
- case AT_TAG:
- if( !a->tagValid )
- return qfalse;
-
- AxisCopy( a->re.axis, axis );
- break;
-
- case AT_CENT:
- if( !a->centValid )
- return qfalse;
-
- cent = &cg_entities[ a->centNum ];
- AnglesToAxis( cent->lerpAngles, axis );
- break;
-
- case AT_PARTICLE:
- return qfalse;
- break;
-
- default:
- CG_Printf( S_COLOR_RED "ERROR: Invalid attachmentType_t in attachment\n" );
- break;
- }
-
- return qtrue;
-}
-
-/*
-===============
-CG_AttachmentVelocity
-
-If the attachment can have velocity, return it
-===============
-*/
-qboolean CG_AttachmentVelocity( attachment_t *a, vec3_t v )
-{
- if( !a )
- return qfalse;
-
- if( a->particleValid && a->particle->valid )
- {
- VectorCopy( a->particle->velocity, v );
- return qtrue;
- }
- else if( a->centValid )
- {
- centity_t *cent = &cg_entities[ a->centNum ];
-
- VectorCopy( cent->currentState.pos.trDelta, v );
- return qtrue;
- }
-
- return qfalse;
-}
-
-/*
-===============
-CG_AttachmentCentNum
-
-If the attachment has a centNum, return it
-===============
-*/
-int CG_AttachmentCentNum( attachment_t *a )
-{
- if( !a || !a->centValid )
- return -1;
-
- return a->centNum;
-}
-
-/*
-===============
-CG_Attached
-
-If the attachment is valid, return qtrue
-===============
-*/
-qboolean CG_Attached( attachment_t *a )
-{
- if( !a )
- return qfalse;
-
- return a->attached;
-}
-
-/*
-===============
-CG_AttachToPoint
-
-Attach to a point in space
-===============
-*/
-void CG_AttachToPoint( attachment_t *a )
-{
- if( !a || !a->staticValid )
- return;
-
- a->type = AT_STATIC;
- a->attached = qtrue;
-}
-
-/*
-===============
-CG_AttachToCent
-
-Attach to a centity_t
-===============
-*/
-void CG_AttachToCent( attachment_t *a )
-{
- if( !a || !a->centValid )
- return;
-
- a->type = AT_CENT;
- a->attached = qtrue;
-}
-
-/*
-===============
-CG_AttachToTag
-
-Attach to a model tag
-===============
-*/
-void CG_AttachToTag( attachment_t *a )
-{
- if( !a || !a->tagValid )
- return;
-
- a->type = AT_TAG;
- a->attached = qtrue;
-}
-
-/*
-===============
-CG_AttachToParticle
-
-Attach to a particle
-===============
-*/
-void CG_AttachToParticle( attachment_t *a )
-{
- if( !a || !a->particleValid )
- return;
-
- a->type = AT_PARTICLE;
- a->attached = qtrue;
-}
-
-/*
-===============
-CG_SetAttachmentPoint
-===============
-*/
-void CG_SetAttachmentPoint( attachment_t *a, vec3_t v )
-{
- if( !a )
- return;
-
- VectorCopy( v, a->origin );
- a->staticValid = qtrue;
-}
-
-/*
-===============
-CG_SetAttachmentCent
-===============
-*/
-void CG_SetAttachmentCent( attachment_t *a, centity_t *cent )
-{
- if( !a || !cent )
- return;
-
- a->centNum = cent->currentState.number;
- a->centValid = qtrue;
-}
-
-/*
-===============
-CG_SetAttachmentTag
-===============
-*/
-void CG_SetAttachmentTag( attachment_t *a, refEntity_t parent,
- qhandle_t model, char *tagName )
-{
- if( !a )
- return;
-
- a->parent = parent;
- a->model = model;
- strncpy( a->tagName, tagName, MAX_STRING_CHARS );
- a->tagValid = qtrue;
-}
-
-/*
-===============
-CG_SetAttachmentParticle
-===============
-*/
-void CG_SetAttachmentParticle( attachment_t *a, particle_t *p )
-{
- if( !a )
- return;
-
- a->particle = p;
- a->particleValid = qtrue;
-}
-
-/*
-===============
-CG_SetAttachmentOffset
-===============
-*/
-void CG_SetAttachmentOffset( attachment_t *a, vec3_t v )
-{
- if( !a )
- return;
-
- VectorCopy( v, a->offset );
- a->hasOffset = qtrue;
-}
diff --git a/src/cgame/cg_buildable.c b/src/cgame/cg_buildable.c
deleted file mode 100644
index 348bb433..00000000
--- a/src/cgame/cg_buildable.c
+++ /dev/null
@@ -1,1051 +0,0 @@
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-char *cg_buildableSoundNames[ MAX_BUILDABLE_ANIMATIONS ] =
-{
- "construct1.wav",
- "construct2.wav",
- "idle1.wav",
- "idle2.wav",
- "idle3.wav",
- "attack1.wav",
- "attack2.wav",
- "spawn1.wav",
- "spawn2.wav",
- "pain1.wav",
- "pain2.wav",
- "destroy1.wav",
- "destroy2.wav",
- "destroyed.wav"
-};
-
-static sfxHandle_t defaultAlienSounds[ MAX_BUILDABLE_ANIMATIONS ];
-static sfxHandle_t defaultHumanSounds[ MAX_BUILDABLE_ANIMATIONS ];
-
-/*
-===================
-CG_AlienBuildableExplosion
-
-Generated a bunch of gibs launching out from a location
-===================
-*/
-void CG_AlienBuildableExplosion( vec3_t origin, vec3_t dir )
-{
- particleSystem_t *ps;
-
- trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.alienBuildableExplosion );
-
- //particle system
- ps = CG_SpawnNewParticleSystem( cgs.media.alienBuildableDestroyedPS );
-
- if( CG_IsParticleSystemValid( &ps ) )
- {
- CG_SetAttachmentPoint( &ps->attachment, origin );
- CG_SetParticleSystemNormal( ps, dir );
- CG_AttachToPoint( &ps->attachment );
- }
-}
-
-/*
-=================
-CG_HumanBuildableExplosion
-
-Called for human buildables as they are destroyed
-=================
-*/
-void CG_HumanBuildableExplosion( vec3_t origin, vec3_t dir )
-{
- particleSystem_t *ps;
-
- trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.humanBuildableExplosion );
-
- //particle system
- ps = CG_SpawnNewParticleSystem( cgs.media.humanBuildableDestroyedPS );
-
- if( CG_IsParticleSystemValid( &ps ) )
- {
- CG_SetAttachmentPoint( &ps->attachment, origin );
- CG_SetParticleSystemNormal( ps, dir );
- CG_AttachToPoint( &ps->attachment );
- }
-}
-
-
-#define CREEP_SIZE 64.0f
-
-/*
-==================
-CG_Creep
-==================
-*/
-static void CG_Creep( centity_t *cent )
-{
- int msec;
- float size, frac;
- trace_t tr;
- vec3_t temp, origin;
- int scaleUpTime = BG_FindBuildTimeForBuildable( cent->currentState.modelindex );
- int time;
-
- time = cent->currentState.time;
-
- //should the creep be growing or receding?
- if( time >= 0 )
- {
- msec = cg.time - time;
- if( msec >= 0 && msec < scaleUpTime )
- frac = (float)msec / scaleUpTime;
- else
- frac = 1.0f;
- }
- else if( time < 0 )
- {
- msec = cg.time + time;
- if( msec >= 0 && msec < CREEP_SCALEDOWN_TIME )
- frac = 1.0f - ( (float)msec / CREEP_SCALEDOWN_TIME );
- else
- frac = 0.0f;
- }
-
- VectorCopy( cent->currentState.origin2, temp );
- VectorScale( temp, -4096, temp );
- VectorAdd( temp, cent->lerpOrigin, temp );
-
- CG_Trace( &tr, cent->lerpOrigin, NULL, NULL, temp, cent->currentState.number, MASK_SOLID );
-
- VectorCopy( tr.endpos, origin );
-
- size = CREEP_SIZE * frac;
-
- if( size > 0.0f )
- CG_ImpactMark( cgs.media.creepShader, origin, cent->currentState.origin2,
- 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, qfalse, size, qtrue );
-}
-
-/*
-======================
-CG_ParseBuildableAnimationFile
-
-Read a configuration file containing animation counts and rates
-models/buildables/hivemind/animation.cfg, etc
-======================
-*/
-static qboolean CG_ParseBuildableAnimationFile( const char *filename, buildable_t buildable )
-{
- char *text_p;
- int len;
- int i;
- char *token;
- float fps;
- char text[ 20000 ];
- fileHandle_t f;
- animation_t *animations;
-
- animations = cg_buildables[ buildable ].animations;
-
- // load the file
- len = trap_FS_FOpenFile( filename, &f, FS_READ );
- if( len <= 0 )
- return qfalse;
-
- if( len >= sizeof( text ) - 1 )
- {
- CG_Printf( "File %s too long\n", filename );
- return qfalse;
- }
-
- trap_FS_Read( text, len, f );
- text[ len ] = 0;
- trap_FS_FCloseFile( f );
-
- // parse the text
- text_p = text;
-
- // read information for each frame
- for( i = BANIM_NONE + 1; i < MAX_BUILDABLE_ANIMATIONS; i++ )
- {
-
- token = COM_Parse( &text_p );
- if( !*token )
- break;
-
- animations[ i ].firstFrame = atoi( token );
-
- token = COM_Parse( &text_p );
- if( !*token )
- break;
-
- animations[ i ].numFrames = atoi( token );
- animations[ i ].reversed = qfalse;
- animations[ i ].flipflop = qfalse;
-
- // if numFrames is negative the animation is reversed
- if( animations[ i ].numFrames < 0 )
- {
- animations[ i ].numFrames = -animations[ i ].numFrames;
- animations[ i ].reversed = qtrue;
- }
-
- token = COM_Parse( &text_p );
- if ( !*token )
- break;
-
- animations[i].loopFrames = atoi( token );
-
- token = COM_Parse( &text_p );
- if( !*token )
- break;
-
- fps = atof( token );
- if( fps == 0 )
- fps = 1;
-
- animations[ i ].frameLerp = 1000 / fps;
- animations[ i ].initialLerp = 1000 / fps;
- }
-
- if( i != MAX_BUILDABLE_ANIMATIONS )
- {
- CG_Printf( "Error parsing animation file: %s\n", filename );
- return qfalse;
- }
-
- return qtrue;
-}
-
-/*
-======================
-CG_ParseBuildableSoundFile
-
-Read a configuration file containing sound properties
-sound/buildables/hivemind/sound.cfg, etc
-======================
-*/
-static qboolean CG_ParseBuildableSoundFile( const char *filename, buildable_t buildable )
-{
- char *text_p;
- int len;
- int i;
- char *token;
- char text[ 20000 ];
- fileHandle_t f;
- sound_t *sounds;
-
- sounds = cg_buildables[ buildable ].sounds;
-
- // load the file
- len = trap_FS_FOpenFile( filename, &f, FS_READ );
- if ( len <= 0 )
- return qfalse;
-
- if ( len >= sizeof( text ) - 1 )
- {
- CG_Printf( "File %s too long\n", filename );
- return qfalse;
- }
-
- trap_FS_Read( text, len, f );
- text[len] = 0;
- trap_FS_FCloseFile( f );
-
- // parse the text
- text_p = text;
-
- // read information for each frame
- for( i = BANIM_NONE + 1; i < MAX_BUILDABLE_ANIMATIONS; i++ )
- {
-
- token = COM_Parse( &text_p );
- if ( !*token )
- break;
-
- sounds[ i ].enabled = atoi( token );
-
- token = COM_Parse( &text_p );
- if ( !*token )
- break;
-
- sounds[ i ].looped = atoi( token );
-
- }
-
- if( i != MAX_BUILDABLE_ANIMATIONS )
- {
- CG_Printf( "Error parsing sound file: %s\n", filename );
- return qfalse;
- }
-
- return qtrue;
-}
-/*
-===============
-CG_InitBuildables
-
-Initialises the animation db
-===============
-*/
-void CG_InitBuildables( void )
-{
- char filename[ MAX_QPATH ];
- char soundfile[ MAX_QPATH ];
- char *buildableName;
- char *modelFile;
- int i;
- int j;
- fileHandle_t f;
-
- memset( cg_buildables, 0, sizeof( cg_buildables ) );
-
- //default sounds
- for( j = BANIM_NONE + 1; j < MAX_BUILDABLE_ANIMATIONS; j++ )
- {
- strcpy( soundfile, cg_buildableSoundNames[ j - 1 ] );
-
- Com_sprintf( filename, sizeof( filename ), "sound/buildables/alien/%s", soundfile );
- defaultAlienSounds[ j ] = trap_S_RegisterSound( filename, qfalse );
-
- Com_sprintf( filename, sizeof( filename ), "sound/buildables/human/%s", soundfile );
- defaultHumanSounds[ j ] = trap_S_RegisterSound( filename, qfalse );
- }
-
- cg.buildablesFraction = 0.0f;
-
- for( i = BA_NONE + 1; i < BA_NUM_BUILDABLES; i++ )
- {
- buildableName = BG_FindNameForBuildable( i );
-
- //animation.cfg
- Com_sprintf( filename, sizeof( filename ), "models/buildables/%s/animation.cfg", buildableName );
- if ( !CG_ParseBuildableAnimationFile( filename, i ) )
- Com_Printf( S_COLOR_YELLOW "WARNING: failed to load animation file %s\n", filename );
-
- //sound.cfg
- Com_sprintf( filename, sizeof( filename ), "sound/buildables/%s/sound.cfg", buildableName );
- if ( !CG_ParseBuildableSoundFile( filename, i ) )
- Com_Printf( S_COLOR_YELLOW "WARNING: failed to load sound file %s\n", filename );
-
- //models
- for( j = 0; j <= 3; j++ )
- {
- if( ( modelFile = BG_FindModelsForBuildable( i, j ) ) )
- cg_buildables[ i ].models[ j ] = trap_R_RegisterModel( modelFile );
- }
-
- //sounds
- for( j = BANIM_NONE + 1; j < MAX_BUILDABLE_ANIMATIONS; j++ )
- {
- strcpy( soundfile, cg_buildableSoundNames[ j - 1 ] );
- Com_sprintf( filename, sizeof( filename ), "sound/buildables/%s/%s", buildableName, soundfile );
-
- if( cg_buildables[ i ].sounds[ j ].enabled )
- {
- if( trap_FS_FOpenFile( filename, &f, FS_READ ) > 0 )
- {
- //file exists so close it
- trap_FS_FCloseFile( f );
-
- cg_buildables[ i ].sounds[ j ].sound = trap_S_RegisterSound( filename, qfalse );
- }
- else
- {
- //file doesn't exist - use default
- if( BG_FindTeamForBuildable( i ) == BIT_ALIENS )
- cg_buildables[ i ].sounds[ j ].sound = defaultAlienSounds[ j ];
- else
- cg_buildables[ i ].sounds[ j ].sound = defaultHumanSounds[ j ];
- }
- }
- }
-
- cg.buildablesFraction = (float)i / (float)( BA_NUM_BUILDABLES - 1 );
- trap_UpdateScreen( );
- }
-
- cgs.media.teslaZapTS = CG_RegisterTrailSystem( "models/buildables/tesla/zap" );
-}
-
-/*
-===============
-CG_SetBuildableLerpFrameAnimation
-
-may include ANIM_TOGGLEBIT
-===============
-*/
-static void CG_SetBuildableLerpFrameAnimation( buildable_t buildable, lerpFrame_t *lf, int newAnimation )
-{
- animation_t *anim;
-
- lf->animationNumber = newAnimation;
-
- if( newAnimation < 0 || newAnimation >= MAX_BUILDABLE_ANIMATIONS )
- CG_Error( "Bad animation number: %i", newAnimation );
-
- anim = &cg_buildables[ buildable ].animations[ newAnimation ];
-
- //this item has just spawned so lf->frameTime will be zero
- if( !lf->animation )
- lf->frameTime = cg.time + 1000; //1 sec delay before starting the spawn anim
-
- lf->animation = anim;
- lf->animationTime = lf->frameTime + anim->initialLerp;
-
- if( cg_debugAnim.integer )
- CG_Printf( "Anim: %i\n", newAnimation );
-}
-
-/*
-===============
-CG_RunBuildableLerpFrame
-
-Sets cg.snap, cg.oldFrame, and cg.backlerp
-cg.time should be between oldFrameTime and frameTime after exit
-===============
-*/
-static void CG_RunBuildableLerpFrame( centity_t *cent )
-{
- int f, numFrames;
- buildable_t buildable = cent->currentState.modelindex;
- lerpFrame_t *lf = &cent->lerpFrame;
- animation_t *anim;
- buildableAnimNumber_t newAnimation = cent->buildableAnim & ~( ANIM_TOGGLEBIT|ANIM_FORCEBIT );
-
- // debugging tool to get no animations
- if( cg_animSpeed.integer == 0 )
- {
- lf->oldFrame = lf->frame = lf->backlerp = 0;
- return;
- }
-
- // see if the animation sequence is switching
- if( newAnimation != lf->animationNumber || !lf->animation )
- {
- if( cg_debugRandom.integer )
- CG_Printf( "newAnimation: %d lf->animationNumber: %d lf->animation: %d\n",
- newAnimation, lf->animationNumber, lf->animation );
-
- CG_SetBuildableLerpFrameAnimation( buildable, lf, newAnimation );
-
- if( !cg_buildables[ buildable ].sounds[ newAnimation ].looped &&
- cg_buildables[ buildable ].sounds[ newAnimation ].enabled )
- {
- if( cg_debugRandom.integer )
- CG_Printf( "Sound for animation %d for a %s\n",
- newAnimation, BG_FindHumanNameForBuildable( buildable ) );
-
- trap_S_StartSound( cent->lerpOrigin, cent->currentState.number, CHAN_AUTO,
- cg_buildables[ buildable ].sounds[ newAnimation ].sound );
- }
- }
-
- if( cg_buildables[ buildable ].sounds[ lf->animationNumber ].looped &&
- cg_buildables[ buildable ].sounds[ lf->animationNumber ].enabled )
- trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin,
- cg_buildables[ buildable ].sounds[ lf->animationNumber ].sound );
-
- // if we have passed the current frame, move it to
- // oldFrame and calculate a new frame
- if( cg.time >= lf->frameTime )
- {
- lf->oldFrame = lf->frame;
- lf->oldFrameTime = lf->frameTime;
-
- // get the next frame based on the animation
- anim = lf->animation;
- if( !anim->frameLerp )
- return; // shouldn't happen
-
- if ( cg.time < lf->animationTime )
- lf->frameTime = lf->animationTime; // initial lerp
- else
- lf->frameTime = lf->oldFrameTime + anim->frameLerp;
-
- f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp;
- numFrames = anim->numFrames;
- if(anim->flipflop)
- numFrames *= 2;
-
- if( f >= numFrames )
- {
- f -= numFrames;
- if( anim->loopFrames )
- {
- f %= anim->loopFrames;
- f += anim->numFrames - anim->loopFrames;
- }
- else
- {
- f = numFrames - 1;
- // the animation is stuck at the end, so it
- // can immediately transition to another sequence
- lf->frameTime = cg.time;
- cent->buildableAnim = cent->currentState.torsoAnim;
- }
- }
-
- if( anim->reversed )
- lf->frame = anim->firstFrame + anim->numFrames - 1 - f;
- else if( anim->flipflop && f >= anim->numFrames )
- lf->frame = anim->firstFrame + anim->numFrames - 1 - ( f % anim->numFrames );
- else
- lf->frame = anim->firstFrame + f;
-
- if( cg.time > lf->frameTime )
- {
- lf->frameTime = cg.time;
- if( cg_debugAnim.integer )
- CG_Printf( "Clamp lf->frameTime\n");
- }
- }
-
- if( lf->frameTime > cg.time + 200 )
- lf->frameTime = cg.time;
-
- if( lf->oldFrameTime > cg.time )
- lf->oldFrameTime = cg.time;
-
- // calculate current lerp value
- if( lf->frameTime == lf->oldFrameTime )
- lf->backlerp = 0;
- else
- lf->backlerp = 1.0 - (float)( cg.time - lf->oldFrameTime ) / ( lf->frameTime - lf->oldFrameTime );
-}
-
-/*
-===============
-CG_BuildableAnimation
-===============
-*/
-static void CG_BuildableAnimation( centity_t *cent, int *old, int *now, float *backLerp )
-{
- entityState_t *es = &cent->currentState;
-
- //if no animation is set default to idle anim
- if( cent->buildableAnim == BANIM_NONE )
- cent->buildableAnim = es->torsoAnim;
-
- //display the first frame of the construction anim if not yet spawned
- if( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) )
- {
- animation_t *anim = &cg_buildables[ es->modelindex ].animations[ BANIM_CONSTRUCT1 ];
-
- //so that when animation starts for real it has sensible numbers
- cent->lerpFrame.oldFrameTime =
- cent->lerpFrame.frameTime =
- cent->lerpFrame.animationTime =
- cg.time;
-
- *old = cent->lerpFrame.oldFrame = anim->firstFrame;
- *now = cent->lerpFrame.frame = anim->firstFrame;
- *backLerp = cent->lerpFrame.backlerp = 0.0f;
-
- //ensure that an animation is triggered once the buildable has spawned
- cent->oldBuildableAnim = BANIM_NONE;
- }
- else
- {
- if( ( cent->oldBuildableAnim ^ es->legsAnim ) & ANIM_TOGGLEBIT )
- {
- if( cg_debugAnim.integer )
- CG_Printf( "%d->%d l:%d t:%d %s(%d)\n",
- cent->oldBuildableAnim, cent->buildableAnim,
- es->legsAnim, es->torsoAnim,
- BG_FindHumanNameForBuildable( es->modelindex ), es->number );
-
- if( cent->buildableAnim == es->torsoAnim || es->legsAnim & ANIM_FORCEBIT )
- cent->buildableAnim = cent->oldBuildableAnim = es->legsAnim;
- else
- cent->buildableAnim = cent->oldBuildableAnim = es->torsoAnim;
- }
-
- CG_RunBuildableLerpFrame( cent );
-
- *old = cent->lerpFrame.oldFrame;
- *now = cent->lerpFrame.frame;
- *backLerp = cent->lerpFrame.backlerp;
- }
-}
-
-#define TRACE_DEPTH 64.0f
-
-/*
-===============
-CG_PositionAndOrientateBuildable
-===============
-*/
-static void CG_PositionAndOrientateBuildable( const vec3_t angles, const vec3_t inOrigin,
- const vec3_t normal, const int skipNumber,
- const vec3_t mins, const vec3_t maxs,
- vec3_t outAxis[ 3 ], vec3_t outOrigin )
-{
- vec3_t forward, start, end;
- trace_t tr;
-
- AngleVectors( angles, forward, NULL, NULL );
- VectorCopy( normal, outAxis[ 2 ] );
- ProjectPointOnPlane( outAxis[ 0 ], forward, outAxis[ 2 ] );
-
- if( !VectorNormalize( outAxis[ 0 ] ) )
- {
- AngleVectors( angles, NULL, NULL, forward );
- ProjectPointOnPlane( outAxis[ 0 ], forward, outAxis[ 2 ] );
- VectorNormalize( outAxis[ 0 ] );
- }
-
- CrossProduct( outAxis[ 0 ], outAxis[ 2 ], outAxis[ 1 ] );
- outAxis[ 1 ][ 0 ] = -outAxis[ 1 ][ 0 ];
- outAxis[ 1 ][ 1 ] = -outAxis[ 1 ][ 1 ];
- outAxis[ 1 ][ 2 ] = -outAxis[ 1 ][ 2 ];
-
- VectorMA( inOrigin, -TRACE_DEPTH, normal, end );
- VectorMA( inOrigin, 1.0f, normal, start );
- CG_CapTrace( &tr, start, mins, maxs, end, skipNumber, MASK_SOLID );
-
- if( tr.fraction == 1.0f )
- {
- //erm we missed completely - try again with a box trace
- CG_Trace( &tr, start, mins, maxs, end, skipNumber, MASK_SOLID );
- }
-
- VectorMA( inOrigin, tr.fraction * -TRACE_DEPTH, normal, outOrigin );
-}
-
-/*
-==================
-CG_GhostBuildable
-==================
-*/
-void CG_GhostBuildable( buildable_t buildable )
-{
- refEntity_t ent;
- playerState_t *ps;
- vec3_t angles, entity_origin;
- vec3_t mins, maxs;
- trace_t tr;
- float scale;
-
- ps = &cg.predictedPlayerState;
-
- memset( &ent, 0, sizeof( ent ) );
-
- BG_FindBBoxForBuildable( buildable, mins, maxs );
-
- BG_PositionBuildableRelativeToPlayer( ps, mins, maxs, CG_Trace, entity_origin, angles, &tr );
-
- CG_PositionAndOrientateBuildable( ps->viewangles, entity_origin, tr.plane.normal, ps->clientNum,
- mins, maxs, ent.axis, ent.origin );
-
- //offset on the Z axis if required
- VectorMA( ent.origin, BG_FindZOffsetForBuildable( buildable ), tr.plane.normal, ent.origin );
-
- VectorCopy( ent.origin, ent.lightingOrigin );
- VectorCopy( ent.origin, ent.oldorigin ); // don't positionally lerp at all
-
- ent.hModel = cg_buildables[ buildable ].models[ 0 ];
-
- if( ps->stats[ STAT_BUILDABLE ] & SB_VALID_TOGGLEBIT )
- ent.customShader = cgs.media.greenBuildShader;
- else
- ent.customShader = cgs.media.redBuildShader;
-
- //rescale the model
- scale = BG_FindModelScaleForBuildable( buildable );
-
- if( scale != 1.0f )
- {
- VectorScale( ent.axis[ 0 ], scale, ent.axis[ 0 ] );
- VectorScale( ent.axis[ 1 ], scale, ent.axis[ 1 ] );
- VectorScale( ent.axis[ 2 ], scale, ent.axis[ 2 ] );
-
- ent.nonNormalizedAxes = qtrue;
- }
- else
- ent.nonNormalizedAxes = qfalse;
-
- // add to refresh list
- trap_R_AddRefEntityToScene( &ent );
-}
-
-/*
-==================
-CG_BuildableParticleEffects
-==================
-*/
-static void CG_BuildableParticleEffects( centity_t *cent )
-{
- entityState_t *es = &cent->currentState;
- buildableTeam_t team = BG_FindTeamForBuildable( es->modelindex );
- int health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT );
- float healthFrac = (float)health / B_HEALTH_SCALE;
-
- if( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) )
- return;
-
- if( team == BIT_HUMANS )
- {
- if( healthFrac < 0.33f && !CG_IsParticleSystemValid( &cent->buildablePS ) )
- {
- cent->buildablePS = CG_SpawnNewParticleSystem( cgs.media.humanBuildableDamagedPS );
-
- if( CG_IsParticleSystemValid( &cent->buildablePS ) )
- {
- CG_SetAttachmentCent( &cent->buildablePS->attachment, cent );
- CG_AttachToCent( &cent->buildablePS->attachment );
- }
- }
- else if( healthFrac >= 0.33f && CG_IsParticleSystemValid( &cent->buildablePS ) )
- CG_DestroyParticleSystem( &cent->buildablePS );
- }
- else if( team == BIT_ALIENS )
- {
- if( healthFrac < 0.33f && !CG_IsParticleSystemValid( &cent->buildablePS ) )
- {
- cent->buildablePS = CG_SpawnNewParticleSystem( cgs.media.alienBuildableDamagedPS );
-
- if( CG_IsParticleSystemValid( &cent->buildablePS ) )
- {
- CG_SetAttachmentCent( &cent->buildablePS->attachment, cent );
- CG_SetParticleSystemNormal( cent->buildablePS, es->origin2 );
- CG_AttachToCent( &cent->buildablePS->attachment );
- }
- }
- else if( healthFrac >= 0.33f && CG_IsParticleSystemValid( &cent->buildablePS ) )
- CG_DestroyParticleSystem( &cent->buildablePS );
- }
-}
-
-
-#define HEALTH_BAR_WIDTH 50.0f
-#define HEALTH_BAR_HEIGHT 5.0f
-
-/*
-==================
-CG_BuildableHealthBar
-==================
-*/
-static void CG_BuildableHealthBar( centity_t *cent )
-{
- vec3_t origin, origin2, down, right, back, downLength, rightLength;
- float rimWidth = HEALTH_BAR_HEIGHT / 15.0f;
- float doneWidth, leftWidth, progress;
- int health;
- qhandle_t shader;
- entityState_t *es;
- vec3_t mins, maxs;
-
- es = &cent->currentState;
-
- health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT );
- progress = (float)health / B_HEALTH_SCALE;
-
- if( progress < 0.0f )
- progress = 0.0f;
- else if( progress > 1.0f )
- progress = 1.0f;
-
- if( progress < 0.33f )
- shader = cgs.media.redBuildShader;
- else
- shader = cgs.media.greenBuildShader;
-
- doneWidth = ( HEALTH_BAR_WIDTH - 2 * rimWidth ) * progress;
- leftWidth = ( HEALTH_BAR_WIDTH - 2 * rimWidth ) - doneWidth;
-
- VectorCopy( cg.refdef.viewaxis[ 2 ], down );
- VectorInverse( down );
- VectorCopy( cg.refdef.viewaxis[ 1 ], right );
- VectorInverse( right );
- VectorSubtract( cg.refdef.vieworg, cent->lerpOrigin, back );
- VectorNormalize( back );
- VectorCopy( cent->lerpOrigin, origin );
-
- BG_FindBBoxForBuildable( es->modelindex, mins, maxs );
- VectorMA( origin, 48.0f, es->origin2, origin );
- VectorMA( origin, -HEALTH_BAR_WIDTH / 2.0f, right, origin );
- VectorMA( origin, maxs[ 0 ] + 8.0f, back, origin );
-
- VectorCopy( origin, origin2 );
- VectorScale( right, rimWidth + doneWidth, rightLength );
- VectorScale( down, HEALTH_BAR_HEIGHT, downLength );
- CG_DrawPlane( origin2, downLength, rightLength, shader );
-
- VectorMA( origin, rimWidth + doneWidth, right, origin2 );
- VectorScale( right, leftWidth, rightLength );
- VectorScale( down, rimWidth, downLength );
- CG_DrawPlane( origin2, downLength, rightLength, shader );
-
- VectorMA( origin, rimWidth + doneWidth, right, origin2 );
- VectorMA( origin2, HEALTH_BAR_HEIGHT - rimWidth, down, origin2 );
- VectorScale( right, leftWidth, rightLength );
- VectorScale( down, rimWidth, downLength );
- CG_DrawPlane( origin2, downLength, rightLength, shader );
-
- VectorMA( origin, HEALTH_BAR_WIDTH - rimWidth, right, origin2 );
- VectorScale( right, rimWidth, rightLength );
- VectorScale( down, HEALTH_BAR_HEIGHT, downLength );
- CG_DrawPlane( origin2, downLength, rightLength, shader );
-
- if( !( es->generic1 & B_POWERED_TOGGLEBIT ) &&
- BG_FindTeamForBuildable( es->modelindex ) == BIT_HUMANS )
- {
- VectorMA( origin, 15.0f, right, origin2 );
- VectorMA( origin2, HEALTH_BAR_HEIGHT + 5.0f, down, origin2 );
- VectorScale( right, HEALTH_BAR_WIDTH / 2.0f - 5.0f, rightLength );
- VectorScale( down, HEALTH_BAR_WIDTH / 2.0f - 5.0f, downLength );
- CG_DrawPlane( origin2, downLength, rightLength, cgs.media.noPowerShader );
- }
-}
-
-#define BUILDABLE_SOUND_PERIOD 500
-
-/*
-==================
-CG_Buildable
-==================
-*/
-void CG_Buildable( centity_t *cent )
-{
- refEntity_t ent;
- entityState_t *es = &cent->currentState;
- vec3_t angles;
- vec3_t surfNormal, xNormal, mins, maxs;
- vec3_t refNormal = { 0.0f, 0.0f, 1.0f };
- float rotAngle;
- buildableTeam_t team = BG_FindTeamForBuildable( es->modelindex );
- float scale;
- int health;
- float healthScale;
-
- //must be before EF_NODRAW check
- if( team == BIT_ALIENS )
- CG_Creep( cent );
-
- // if set to invisible, skip
- if( es->eFlags & EF_NODRAW )
- {
- if( CG_IsParticleSystemValid( &cent->buildablePS ) )
- CG_DestroyParticleSystem( &cent->buildablePS );
-
- return;
- }
-
- memset ( &ent, 0, sizeof( ent ) );
-
- VectorCopy( cent->lerpOrigin, ent.origin );
- VectorCopy( cent->lerpOrigin, ent.oldorigin );
- VectorCopy( cent->lerpOrigin, ent.lightingOrigin );
-
- VectorCopy( es->origin2, surfNormal );
-
- VectorCopy( es->angles, angles );
- BG_FindBBoxForBuildable( es->modelindex, mins, maxs );
-
- if( es->pos.trType == TR_STATIONARY )
- CG_PositionAndOrientateBuildable( angles, ent.origin, surfNormal, es->number,
- mins, maxs, ent.axis, ent.origin );
-
- //offset on the Z axis if required
- VectorMA( ent.origin, BG_FindZOffsetForBuildable( es->modelindex ), surfNormal, ent.origin );
-
- VectorCopy( ent.origin, ent.oldorigin ); // don't positionally lerp at all
- VectorCopy( ent.origin, ent.lightingOrigin );
-
- ent.hModel = cg_buildables[ es->modelindex ].models[ 0 ];
-
- if( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) )
- {
- sfxHandle_t prebuildSound = cgs.media.humanBuildablePrebuild;
-
- if( team == BIT_HUMANS )
- {
- ent.customShader = cgs.media.humanSpawningShader;
- prebuildSound = cgs.media.humanBuildablePrebuild;
- }
- else if( team == BIT_ALIENS )
- prebuildSound = cgs.media.alienBuildablePrebuild;
-
- trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, prebuildSound );
- }
-
- CG_BuildableAnimation( cent, &ent.oldframe, &ent.frame, &ent.backlerp );
-
- //rescale the model
- scale = BG_FindModelScaleForBuildable( es->modelindex );
-
- if( scale != 1.0f )
- {
- VectorScale( ent.axis[ 0 ], scale, ent.axis[ 0 ] );
- VectorScale( ent.axis[ 1 ], scale, ent.axis[ 1 ] );
- VectorScale( ent.axis[ 2 ], scale, ent.axis[ 2 ] );
-
- ent.nonNormalizedAxes = qtrue;
- }
- else
- ent.nonNormalizedAxes = qfalse;
-
-
- //add to refresh list
- trap_R_AddRefEntityToScene( &ent );
-
- CrossProduct( surfNormal, refNormal, xNormal );
- VectorNormalize( xNormal );
- rotAngle = RAD2DEG( acos( DotProduct( surfNormal, refNormal ) ) );
-
- //turret barrel bit
- if( cg_buildables[ es->modelindex ].models[ 1 ] )
- {
- refEntity_t turretBarrel;
- vec3_t flatAxis[ 3 ];
-
- memset( &turretBarrel, 0, sizeof( turretBarrel ) );
-
- turretBarrel.hModel = cg_buildables[ es->modelindex ].models[ 1 ];
-
- CG_PositionEntityOnTag( &turretBarrel, &ent, ent.hModel, "tag_turret" );
- VectorCopy( cent->lerpOrigin, turretBarrel.lightingOrigin );
- AnglesToAxis( es->angles2, flatAxis );
-
- RotatePointAroundVector( turretBarrel.axis[ 0 ], xNormal, flatAxis[ 0 ], -rotAngle );
- RotatePointAroundVector( turretBarrel.axis[ 1 ], xNormal, flatAxis[ 1 ], -rotAngle );
- RotatePointAroundVector( turretBarrel.axis[ 2 ], xNormal, flatAxis[ 2 ], -rotAngle );
-
- turretBarrel.oldframe = ent.oldframe;
- turretBarrel.frame = ent.frame;
- turretBarrel.backlerp = ent.backlerp;
-
- turretBarrel.customShader = ent.customShader;
-
- if( scale != 1.0f )
- {
- VectorScale( turretBarrel.axis[ 0 ], scale, turretBarrel.axis[ 0 ] );
- VectorScale( turretBarrel.axis[ 1 ], scale, turretBarrel.axis[ 1 ] );
- VectorScale( turretBarrel.axis[ 2 ], scale, turretBarrel.axis[ 2 ] );
-
- turretBarrel.nonNormalizedAxes = qtrue;
- }
- else
- turretBarrel.nonNormalizedAxes = qfalse;
-
- trap_R_AddRefEntityToScene( &turretBarrel );
- }
-
- //turret barrel bit
- if( cg_buildables[ es->modelindex ].models[ 2 ] )
- {
- refEntity_t turretTop;
- vec3_t flatAxis[ 3 ];
- vec3_t swivelAngles;
-
- memset( &turretTop, 0, sizeof( turretTop ) );
-
- VectorCopy( es->angles2, swivelAngles );
- swivelAngles[ PITCH ] = 0.0f;
-
- turretTop.hModel = cg_buildables[ es->modelindex ].models[ 2 ];
-
- CG_PositionRotatedEntityOnTag( &turretTop, &ent, ent.hModel, "tag_turret" );
- VectorCopy( cent->lerpOrigin, turretTop.lightingOrigin );
- AnglesToAxis( swivelAngles, flatAxis );
-
- RotatePointAroundVector( turretTop.axis[ 0 ], xNormal, flatAxis[ 0 ], -rotAngle );
- RotatePointAroundVector( turretTop.axis[ 1 ], xNormal, flatAxis[ 1 ], -rotAngle );
- RotatePointAroundVector( turretTop.axis[ 2 ], xNormal, flatAxis[ 2 ], -rotAngle );
-
- turretTop.oldframe = ent.oldframe;
- turretTop.frame = ent.frame;
- turretTop.backlerp = ent.backlerp;
-
- turretTop.customShader = ent.customShader;
-
- if( scale != 1.0f )
- {
- VectorScale( turretTop.axis[ 0 ], scale, turretTop.axis[ 0 ] );
- VectorScale( turretTop.axis[ 1 ], scale, turretTop.axis[ 1 ] );
- VectorScale( turretTop.axis[ 2 ], scale, turretTop.axis[ 2 ] );
-
- turretTop.nonNormalizedAxes = qtrue;
- }
- else
- turretTop.nonNormalizedAxes = qfalse;
-
- trap_R_AddRefEntityToScene( &turretTop );
- }
-
- switch( cg.predictedPlayerState.weapon )
- {
- case WP_ABUILD:
- case WP_ABUILD2:
- case WP_HBUILD:
- case WP_HBUILD2:
- if( BG_FindTeamForBuildable( es->modelindex ) ==
- BG_FindTeamForWeapon( cg.predictedPlayerState.weapon ) )
- CG_BuildableHealthBar( cent );
- break;
-
- default:
- break;
- }
-
- //weapon effects for turrets
- if( es->eFlags & EF_FIRING )
- {
- weaponInfo_t *weapon = &cg_weapons[ es->weapon ];
-
- if( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME ||
- BG_FindProjTypeForBuildable( es->modelindex ) == WP_TESLAGEN )
- {
- if( weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 0 ] ||
- weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 1 ] ||
- weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 2 ] )
- {
- trap_R_AddLightToScene( cent->lerpOrigin, 300 + ( rand( ) & 31 ),
- weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 0 ],
- weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 1 ],
- weapon->wim[ WPM_PRIMARY ].flashDlightColor[ 2 ] );
- }
- }
-
- if( weapon->wim[ WPM_PRIMARY ].firingSound )
- {
- trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin,
- weapon->wim[ WPM_PRIMARY ].firingSound );
- }
- else if( weapon->readySound )
- trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, weapon->readySound );
- }
-
- health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT );
- healthScale = (float)health / B_HEALTH_SCALE;
-
- if( healthScale < cent->lastBuildableHealthScale && ( es->generic1 & B_SPAWNED_TOGGLEBIT ) )
- {
- if( cent->lastBuildableDamageSoundTime + BUILDABLE_SOUND_PERIOD < cg.time )
- {
- if( team == BIT_HUMANS )
- {
- int i = rand( ) % 4;
- trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.humanBuildableDamage[ i ] );
- }
- else if( team == BIT_ALIENS )
- trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.alienBuildableDamage );
-
- cent->lastBuildableDamageSoundTime = cg.time;
- }
- }
-
- cent->lastBuildableHealthScale = healthScale;
-
- //smoke etc for damaged buildables
- CG_BuildableParticleEffects( cent );
-}
diff --git a/src/cgame/cg_consolecmds.c b/src/cgame/cg_consolecmds.c
deleted file mode 100644
index c875fa48..00000000
--- a/src/cgame/cg_consolecmds.c
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_consolecmds.c -- text commands typed in at the local console, or
-// executed by a key binding
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-
-
-void CG_TargetCommand_f( void )
-{
- int targetNum;
- char test[ 4 ];
-
- targetNum = CG_CrosshairPlayer( );
- if( !targetNum )
- return;
-
- trap_Argv( 1, test, 4 );
- trap_SendConsoleCommand( va( "gc %i %i", targetNum, atoi( test ) ) );
-}
-
-
-
-/*
-=================
-CG_SizeUp_f
-
-Keybinding command
-=================
-*/
-static void CG_SizeUp_f( void )
-{
- trap_Cvar_Set( "cg_viewsize", va( "%i", (int)( cg_viewsize.integer + 10 ) ) );
-}
-
-
-/*
-=================
-CG_SizeDown_f
-
-Keybinding command
-=================
-*/
-static void CG_SizeDown_f( void )
-{
- trap_Cvar_Set( "cg_viewsize", va( "%i", (int)( cg_viewsize.integer - 10 ) ) );
-}
-
-
-/*
-=============
-CG_Viewpos_f
-
-Debugging command to print the current position
-=============
-*/
-static void CG_Viewpos_f( void )
-{
- CG_Printf( "(%i %i %i) : %i\n", (int)cg.refdef.vieworg[ 0 ],
- (int)cg.refdef.vieworg[ 1 ], (int)cg.refdef.vieworg[ 2 ],
- (int)cg.refdefViewAngles[ YAW ] );
-}
-
-
-static void CG_ScoresDown_f( void )
-{
- if( cg.scoresRequestTime + 2000 < cg.time )
- {
- // the scores are more than two seconds out of data,
- // so request new ones
- cg.scoresRequestTime = cg.time;
- //TA: added \n SendClientCommand doesn't call flush( )?
- trap_SendClientCommand( "score\n" );
-
- // leave the current scores up if they were already
- // displayed, but if this is the first hit, clear them out
- if( !cg.showScores )
- {
- if( cg_debugRandom.integer )
- CG_Printf( "CG_ScoresDown_f: scores out of date\n" );
-
- cg.showScores = qtrue;
- cg.numScores = 0;
- }
- }
- else
- {
- // show the cached contents even if they just pressed if it
- // is within two seconds
- cg.showScores = qtrue;
- }
-}
-
-static void CG_ScoresUp_f( void )
-{
- if( cg.showScores )
- {
- cg.showScores = qfalse;
- cg.scoreFadeTime = cg.time;
- }
-}
-
-static void CG_TellTarget_f( void )
-{
- int clientNum;
- char command[ 128 ];
- char message[ 128 ];
-
- clientNum = CG_CrosshairPlayer( );
- if( clientNum == -1 )
- return;
-
- trap_Args( message, 128 );
- Com_sprintf( command, 128, "tell %i %s", clientNum, message );
- trap_SendClientCommand( command );
-}
-
-static void CG_TellAttacker_f( void )
-{
- int clientNum;
- char command[ 128 ];
- char message[ 128 ];
-
- clientNum = CG_LastAttacker( );
- if( clientNum == -1 )
- return;
-
- trap_Args( message, 128 );
- Com_sprintf( command, 128, "tell %i %s", clientNum, message );
- trap_SendClientCommand( command );
-}
-
-typedef struct
-{
- char *cmd;
- void (*function)( void );
-} consoleCommand_t;
-
-static consoleCommand_t commands[ ] =
-{
- { "testgun", CG_TestGun_f },
- { "testmodel", CG_TestModel_f },
- { "nextframe", CG_TestModelNextFrame_f },
- { "prevframe", CG_TestModelPrevFrame_f },
- { "nextskin", CG_TestModelNextSkin_f },
- { "prevskin", CG_TestModelPrevSkin_f },
- { "viewpos", CG_Viewpos_f },
- { "+scores", CG_ScoresDown_f },
- { "-scores", CG_ScoresUp_f },
- { "+zoom", CG_ZoomDown_f },
- { "-zoom", CG_ZoomUp_f },
- { "sizeup", CG_SizeUp_f },
- { "sizedown", CG_SizeDown_f },
- { "weapnext", CG_NextWeapon_f },
- { "weapprev", CG_PrevWeapon_f },
- { "weapon", CG_Weapon_f },
- { "tell_target", CG_TellTarget_f },
- { "tell_attacker", CG_TellAttacker_f },
- { "tcmd", CG_TargetCommand_f },
- { "testPS", CG_TestPS_f },
- { "destroyTestPS", CG_DestroyTestPS_f },
- { "testTS", CG_TestTS_f },
- { "destroyTestTS", CG_DestroyTestTS_f },
-};
-
-
-/*
-=================
-CG_ConsoleCommand
-
-The string has been tokenized and can be retrieved with
-Cmd_Argc() / Cmd_Argv()
-=================
-*/
-qboolean CG_ConsoleCommand( void )
-{
- const char *cmd;
- const char *arg1;
- int i;
-
- cmd = CG_Argv( 0 );
-
- //TA: ugly hacky special case
- if( !Q_stricmp( cmd, "ui_menu" ) )
- {
- arg1 = CG_Argv( 1 );
- trap_SendConsoleCommand( va( "menu %s\n", arg1 ) );
- return qtrue;
- }
-
- for( i = 0; i < sizeof( commands ) / sizeof( commands[ 0 ] ); i++ )
- {
- if( !Q_stricmp( cmd, commands[ i ].cmd ) )
- {
- commands[ i ].function( );
- return qtrue;
- }
- }
-
- return qfalse;
-}
-
-
-/*
-=================
-CG_InitConsoleCommands
-
-Let the client system know about all of our commands
-so it can perform tab completion
-=================
-*/
-void CG_InitConsoleCommands( void )
-{
- int i;
-
- for( i = 0 ; i < sizeof( commands ) / sizeof( commands[ 0 ] ) ; i++ )
- trap_AddCommand( commands[ i ].cmd );
-
- //
- // the game server will interpret these commands, which will be automatically
- // forwarded to the server after they are not recognized locally
- //
- trap_AddCommand( "kill" );
- trap_AddCommand( "say" );
- trap_AddCommand( "say_team" );
- trap_AddCommand( "tell" );
- trap_AddCommand( "vsay" );
- trap_AddCommand( "vsay_team" );
- trap_AddCommand( "vtell" );
- trap_AddCommand( "vtaunt" );
- trap_AddCommand( "vosay" );
- trap_AddCommand( "vosay_team" );
- trap_AddCommand( "votell" );
- trap_AddCommand( "give" );
- trap_AddCommand( "god" );
- trap_AddCommand( "notarget" );
- trap_AddCommand( "noclip" );
- trap_AddCommand( "team" );
- trap_AddCommand( "follow" );
- trap_AddCommand( "levelshot" );
- trap_AddCommand( "addbot" );
- trap_AddCommand( "setviewpos" );
- trap_AddCommand( "callvote" );
- trap_AddCommand( "vote" );
- trap_AddCommand( "callteamvote" );
- trap_AddCommand( "teamvote" );
- trap_AddCommand( "stats" );
- trap_AddCommand( "teamtask" );
- trap_AddCommand( "class" );
- trap_AddCommand( "build" );
- trap_AddCommand( "buy" );
- trap_AddCommand( "sell" );
- trap_AddCommand( "reload" );
- trap_AddCommand( "itemact" );
- trap_AddCommand( "itemdeact" );
- trap_AddCommand( "itemtoggle" );
- trap_AddCommand( "destroy" );
- trap_AddCommand( "deconstruct" );
- trap_AddCommand( "menu" );
- trap_AddCommand( "ui_menu" );
- trap_AddCommand( "mapRotation" );
- trap_AddCommand( "stopMapRotation" );
- trap_AddCommand( "alienWin" );
- trap_AddCommand( "humanWin" );
-}
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c
deleted file mode 100644
index d7c07036..00000000
--- a/src/cgame/cg_draw.c
+++ /dev/null
@@ -1,3393 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_draw.c -- draw all of the graphical elements during
-// active (after loading) gameplay
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-#include "../ui/ui_shared.h"
-
-// used for scoreboard
-extern displayContextDef_t cgDC;
-menuDef_t *menuScoreboard = NULL;
-
-int drawTeamOverlayModificationCount = -1;
-
-int sortedTeamPlayers[ TEAM_MAXOVERLAY ];
-int numSortedTeamPlayers;
-char systemChat[ 256 ];
-char teamChat1[ 256 ];
-char teamChat2[ 256 ];
-
-//TA UI
-int CG_Text_Width( const char *text, float scale, int limit )
-{
- int count,len;
- float out;
- glyphInfo_t *glyph;
- float useScale;
-// FIXME: see ui_main.c, same problem
-// const unsigned char *s = text;
- const char *s = text;
- fontInfo_t *font = &cgDC.Assets.textFont;
-
- if( scale <= cg_smallFont.value )
- font = &cgDC.Assets.smallFont;
- else if( scale > cg_bigFont.value )
- font = &cgDC.Assets.bigFont;
-
- useScale = scale * font->glyphScale;
- out = 0;
-
- if( text )
- {
- len = strlen( text );
- if( limit > 0 && len > limit )
- len = limit;
-
- count = 0;
- while( s && *s && count < len )
- {
- if( Q_IsColorString( s ) )
- {
- s += 2;
- continue;
- }
- else
- {
- glyph = &font->glyphs[ (int)*s ];
- //TTimo: FIXME: getting nasty warnings without the cast,
- //hopefully this doesn't break the VM build
- out += glyph->xSkip;
- s++;
- count++;
- }
- }
- }
-
- return out * useScale;
-}
-
-int CG_Text_Height( const char *text, float scale, int limit )
-{
- int len, count;
- float max;
- glyphInfo_t *glyph;
- float useScale;
-// TTimo: FIXME
-// const unsigned char *s = text;
- const char *s = text;
- fontInfo_t *font = &cgDC.Assets.textFont;
-
- if( scale <= cg_smallFont.value )
- font = &cgDC.Assets.smallFont;
- else if( scale > cg_bigFont.value )
- font = &cgDC.Assets.bigFont;
-
- useScale = scale * font->glyphScale;
- max = 0;
-
- if( text )
- {
- len = strlen( text );
- if( limit > 0 && len > limit )
- len = limit;
-
- count = 0;
- while( s && *s && count < len )
- {
- if( Q_IsColorString( s ) )
- {
- s += 2;
- continue;
- }
- else
- {
- glyph = &font->glyphs[ (int)*s ];
- //TTimo: FIXME: getting nasty warnings without the cast,
- //hopefully this doesn't break the VM build
- if( max < glyph->height )
- max = glyph->height;
-
- s++;
- count++;
- }
- }
- }
-
- return max * useScale;
-}
-
-void CG_Text_PaintChar( float x, float y, float width, float height, float scale,
- float s, float t, float s2, float t2, qhandle_t hShader )
-{
- float w, h;
- w = width * scale;
- h = height * scale;
- CG_AdjustFrom640( &x, &y, &w, &h );
- trap_R_DrawStretchPic( x, y, w, h, s, t, s2, t2, hShader );
-}
-
-void CG_Text_Paint( float x, float y, float scale, vec4_t color, const char *text,
- float adjust, int limit, int style )
-{
- int len, count;
- vec4_t newColor;
- glyphInfo_t *glyph;
- float useScale;
- fontInfo_t *font = &cgDC.Assets.textFont;
-
- if( scale <= cg_smallFont.value )
- font = &cgDC.Assets.smallFont;
- else if( scale > cg_bigFont.value )
- font = &cgDC.Assets.bigFont;
-
- useScale = scale * font->glyphScale;
- if( text )
- {
-// TTimo: FIXME
-// const unsigned char *s = text;
- const char *s = text;
-
- trap_R_SetColor( color );
- memcpy( &newColor[ 0 ], &color[ 0 ], sizeof( vec4_t ) );
- len = strlen( text );
-
- if( limit > 0 && len > limit )
- len = limit;
-
- count = 0;
- while( s && *s && count < len )
- {
- glyph = &font->glyphs[ (int)*s ];
- //TTimo: FIXME: getting nasty warnings without the cast,
- //hopefully this doesn't break the VM build
-
- if( Q_IsColorString( s ) )
- {
- memcpy( newColor, g_color_table[ ColorIndex( *( s + 1 ) ) ], sizeof( newColor ) );
- newColor[ 3 ] = color[ 3 ];
- trap_R_SetColor( newColor );
- s += 2;
- continue;
- }
- else
- {
- float yadj = useScale * glyph->top;
- if( style == ITEM_TEXTSTYLE_SHADOWED ||
- style == ITEM_TEXTSTYLE_SHADOWEDMORE )
- {
- int ofs = style == ITEM_TEXTSTYLE_SHADOWED ? 1 : 2;
- colorBlack[ 3 ] = newColor[ 3 ];
- trap_R_SetColor( colorBlack );
- CG_Text_PaintChar( x + ofs, y - yadj + ofs,
- glyph->imageWidth,
- glyph->imageHeight,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph );
-
- colorBlack[ 3 ] = 1.0;
- trap_R_SetColor( newColor );
- }
- else if( style == ITEM_TEXTSTYLE_NEON )
- {
- vec4_t glow, outer, inner, white;
-
- glow[ 0 ] = newColor[ 0 ] * 0.5;
- glow[ 1 ] = newColor[ 1 ] * 0.5;
- glow[ 2 ] = newColor[ 2 ] * 0.5;
- glow[ 3 ] = newColor[ 3 ] * 0.2;
-
- outer[ 0 ] = newColor[ 0 ];
- outer[ 1 ] = newColor[ 1 ];
- outer[ 2 ] = newColor[ 2 ];
- outer[ 3 ] = newColor[ 3 ];
-
- inner[ 0 ] = newColor[ 0 ] * 1.5 > 1.0f ? 1.0f : newColor[ 0 ] * 1.5;
- inner[ 1 ] = newColor[ 1 ] * 1.5 > 1.0f ? 1.0f : newColor[ 1 ] * 1.5;
- inner[ 2 ] = newColor[ 2 ] * 1.5 > 1.0f ? 1.0f : newColor[ 2 ] * 1.5;
- inner[ 3 ] = newColor[ 3 ];
-
- white[ 0 ] = white[ 1 ] = white[ 2 ] = white[ 3 ] = 1.0f;
-
- trap_R_SetColor( glow );
- CG_Text_PaintChar( x - 3, y - yadj - 3,
- glyph->imageWidth + 6,
- glyph->imageHeight + 6,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph );
-
- trap_R_SetColor( outer );
- CG_Text_PaintChar( x - 1, y - yadj - 1,
- glyph->imageWidth + 2,
- glyph->imageHeight + 2,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph );
-
- trap_R_SetColor( inner );
- CG_Text_PaintChar( x - 0.5, y - yadj - 0.5,
- glyph->imageWidth + 1,
- glyph->imageHeight + 1,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph );
-
- trap_R_SetColor( white );
- }
-
-
- CG_Text_PaintChar( x, y - yadj,
- glyph->imageWidth,
- glyph->imageHeight,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph );
-
- x += ( glyph->xSkip * useScale ) + adjust;
- s++;
- count++;
- }
- }
-
- trap_R_SetColor( NULL );
- }
-}
-
-/*
-==============
-CG_DrawFieldPadded
-
-Draws large numbers for status bar and powerups
-==============
-*/
-static void CG_DrawFieldPadded( int x, int y, int width, int cw, int ch, int value )
-{
- char num[ 16 ], *ptr;
- int l, orgL;
- int frame;
- int charWidth, charHeight;
-
- if( !( charWidth = cw ) )
- charWidth = CHAR_WIDTH;
-
- if( !( charHeight = ch ) )
- charWidth = CHAR_HEIGHT;
-
- if( width < 1 )
- return;
-
- // draw number string
- if( width > 4 )
- width = 4;
-
- switch( width )
- {
- case 1:
- value = value > 9 ? 9 : value;
- value = value < 0 ? 0 : value;
- break;
- case 2:
- value = value > 99 ? 99 : value;
- value = value < -9 ? -9 : value;
- break;
- case 3:
- value = value > 999 ? 999 : value;
- value = value < -99 ? -99 : value;
- break;
- case 4:
- value = value > 9999 ? 9999 : value;
- value = value < -999 ? -999 : value;
- break;
- }
-
- Com_sprintf( num, sizeof( num ), "%d", value );
- l = strlen( num );
-
- if( l > width )
- l = width;
-
- orgL = l;
-
- x += 2;
-
- ptr = num;
- while( *ptr && l )
- {
- if( width > orgL )
- {
- CG_DrawPic( x,y, charWidth, charHeight, cgs.media.numberShaders[ 0 ] );
- width--;
- x += charWidth;
- continue;
- }
-
- if( *ptr == '-' )
- frame = STAT_MINUS;
- else
- frame = *ptr - '0';
-
- CG_DrawPic( x,y, charWidth, charHeight, cgs.media.numberShaders[ frame ] );
- x += charWidth;
- ptr++;
- l--;
- }
-}
-
-/*
-==============
-CG_DrawField
-
-Draws large numbers for status bar and powerups
-==============
-*/
-static void CG_DrawField( int x, int y, int width, int cw, int ch, int value )
-{
- char num[ 16 ], *ptr;
- int l;
- int frame;
- int charWidth, charHeight;
-
- if( !( charWidth = cw ) )
- charWidth = CHAR_WIDTH;
-
- if( !( charHeight = ch ) )
- charWidth = CHAR_HEIGHT;
-
- if( width < 1 )
- return;
-
- // draw number string
- if( width > 4 )
- width = 4;
-
- switch( width )
- {
- case 1:
- value = value > 9 ? 9 : value;
- value = value < 0 ? 0 : value;
- break;
- case 2:
- value = value > 99 ? 99 : value;
- value = value < -9 ? -9 : value;
- break;
- case 3:
- value = value > 999 ? 999 : value;
- value = value < -99 ? -99 : value;
- break;
- case 4:
- value = value > 9999 ? 9999 : value;
- value = value < -999 ? -999 : value;
- break;
- }
-
- Com_sprintf( num, sizeof( num ), "%d", value );
- l = strlen( num );
-
- if( l > width )
- l = width;
-
- x += 2 + charWidth * ( width - l );
-
- ptr = num;
- while( *ptr && l )
- {
- if( *ptr == '-' )
- frame = STAT_MINUS;
- else
- frame = *ptr -'0';
-
- CG_DrawPic( x,y, charWidth, charHeight, cgs.media.numberShaders[ frame ] );
- x += charWidth;
- ptr++;
- l--;
- }
-}
-
-static void CG_DrawProgressBar( rectDef_t *rect, vec4_t color, float scale,
- int align, int textStyle, int special, float progress )
-{
- float rimWidth = rect->h / 20.0f;
- float doneWidth, leftWidth;
- float tx, ty, tw, th;
- char textBuffer[ 8 ];
-
- if( rimWidth < 0.6f )
- rimWidth = 0.6f;
-
- if( special >= 0.0f )
- rimWidth = special;
-
- if( progress < 0.0f )
- progress = 0.0f;
- else if( progress > 1.0f )
- progress = 1.0f;
-
- doneWidth = ( rect->w - 2 * rimWidth ) * progress;
- leftWidth = ( rect->w - 2 * rimWidth ) - doneWidth;
-
- trap_R_SetColor( color );
-
- //draw rim and bar
- if( align == ITEM_ALIGN_RIGHT )
- {
- CG_DrawPic( rect->x, rect->y, rimWidth, rect->h, cgs.media.whiteShader );
- CG_DrawPic( rect->x + rimWidth, rect->y,
- leftWidth, rimWidth, cgs.media.whiteShader );
- CG_DrawPic( rect->x + rimWidth, rect->y + rect->h - rimWidth,
- leftWidth, rimWidth, cgs.media.whiteShader );
- CG_DrawPic( rect->x + rimWidth + leftWidth, rect->y,
- rimWidth + doneWidth, rect->h, cgs.media.whiteShader );
- }
- else
- {
- CG_DrawPic( rect->x, rect->y, rimWidth + doneWidth, rect->h, cgs.media.whiteShader );
- CG_DrawPic( rimWidth + rect->x + doneWidth, rect->y,
- leftWidth, rimWidth, cgs.media.whiteShader );
- CG_DrawPic( rimWidth + rect->x + doneWidth, rect->y + rect->h - rimWidth,
- leftWidth, rimWidth, cgs.media.whiteShader );
- CG_DrawPic( rect->x + rect->w - rimWidth, rect->y, rimWidth, rect->h, cgs.media.whiteShader );
- }
-
- trap_R_SetColor( NULL );
-
- //draw text
- if( scale > 0.0 )
- {
- Com_sprintf( textBuffer, sizeof( textBuffer ), "%d%%", (int)( progress * 100 ) );
- tw = CG_Text_Width( textBuffer, scale, 0 );
- th = scale * 40.0f;
-
- switch( align )
- {
- case ITEM_ALIGN_LEFT:
- tx = rect->x + ( rect->w / 10.0f );
- ty = rect->y + ( rect->h / 2.0f ) + ( th / 2.0f );
- break;
-
- case ITEM_ALIGN_RIGHT:
- tx = rect->x + rect->w - ( rect->w / 10.0f ) - tw;
- ty = rect->y + ( rect->h / 2.0f ) + ( th / 2.0f );
- break;
-
- case ITEM_ALIGN_CENTER:
- tx = rect->x + ( rect->w / 2.0f ) - ( tw / 2.0f );
- ty = rect->y + ( rect->h / 2.0f ) + ( th / 2.0f );
- break;
-
- default:
- tx = ty = 0.0f;
- }
-
- CG_Text_Paint( tx, ty, scale, color, textBuffer, 0, 0, textStyle );
- }
-}
-
-//=============== TA: was cg_newdraw.c
-
-void CG_InitTeamChat( void )
-{
- memset( teamChat1, 0, sizeof( teamChat1 ) );
- memset( teamChat2, 0, sizeof( teamChat2 ) );
- memset( systemChat, 0, sizeof( systemChat ) );
-}
-
-void CG_SetPrintString( int type, const char *p )
-{
- if( type == SYSTEM_PRINT )
- {
- strcpy( systemChat, p );
- }
- else
- {
- strcpy( teamChat2, teamChat1 );
- strcpy( teamChat1, p );
- }
-}
-
-/*
-===============
-CG_AtHighestClass
-
-Is the local client at the highest class possible?
-===============
-*/
-static qboolean CG_AtHighestClass( void )
-{
- int i;
- qboolean superiorClasses = qfalse;
-
- for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ )
- {
- if( BG_ClassCanEvolveFromTo(
- cg.predictedPlayerState.stats[ STAT_PCLASS ], i,
- ALIEN_MAX_KILLS, 0 ) >= 0 &&
- BG_FindStagesForClass( i, cgs.alienStage )
- /*FIXME && G_ClassIsAllowed( i )*/ )
- {
- superiorClasses = qtrue;
- break;
- }
- }
-
- return !superiorClasses;
-}
-
-#define NO_CREDITS_TIME 2000
-
-static void CG_DrawPlayerCreditsValue( rectDef_t *rect, vec4_t color, qboolean padding )
-{
- int value;
- playerState_t *ps;
- centity_t *cent;
-
- cent = &cg_entities[ cg.snap->ps.clientNum ];
- ps = &cg.snap->ps;
-
- //if the build timer pie is showing don't show this
- if( ( cent->currentState.weapon == WP_ABUILD ||
- cent->currentState.weapon == WP_ABUILD2 ) && ps->stats[ STAT_MISC ] )
- return;
-
- value = ps->persistant[ PERS_CREDIT ];
- if( value > -1 )
- {
- if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS &&
- !CG_AtHighestClass( ) )
- {
- if( cg.time - cg.lastEvolveAttempt <= NO_CREDITS_TIME )
- {
- if( ( ( cg.time - cg.lastEvolveAttempt ) / 300 ) % 2 )
- color[ 3 ] = 0.0f;
- }
- }
-
- trap_R_SetColor( color );
-
- if( padding )
- CG_DrawFieldPadded( rect->x, rect->y, 4, rect->w / 4, rect->h, value );
- else
- CG_DrawField( rect->x, rect->y, 1, rect->w, rect->h, value );
-
- trap_R_SetColor( NULL );
- }
-}
-
-static void CG_DrawPlayerBankValue( rectDef_t *rect, vec4_t color, qboolean padding )
-{
- int value;
- playerState_t *ps;
-
- ps = &cg.snap->ps;
-
- value = ps->persistant[ PERS_BANK ];
- if( value > -1 )
- {
- trap_R_SetColor( color );
-
- if( padding )
- CG_DrawFieldPadded( rect->x, rect->y, 4, rect->w / 4, rect->h, value );
- else
- CG_DrawField( rect->x, rect->y, 1, rect->w, rect->h, value );
-
- trap_R_SetColor( NULL );
- }
-}
-
-#define HH_MIN_ALPHA 0.2f
-#define HH_MAX_ALPHA 0.8f
-#define HH_ALPHA_DIFF (HH_MAX_ALPHA-HH_MIN_ALPHA)
-
-#define AH_MIN_ALPHA 0.2f
-#define AH_MAX_ALPHA 0.8f
-#define AH_ALPHA_DIFF (AH_MAX_ALPHA-AH_MIN_ALPHA)
-
-/*
-==============
-CG_DrawPlayerStamina1
-==============
-*/
-static void CG_DrawPlayerStamina1( rectDef_t *rect, vec4_t color, qhandle_t shader )
-{
- playerState_t *ps = &cg.snap->ps;
- float stamina = ps->stats[ STAT_STAMINA ];
- float maxStaminaBy3 = (float)MAX_STAMINA / 3.0f;
- float progress;
-
- stamina -= ( 2 * (int)maxStaminaBy3 );
- progress = stamina / maxStaminaBy3;
-
- if( progress > 1.0f )
- progress = 1.0f;
- else if( progress < 0.0f )
- progress = 0.0f;
-
- color[ 3 ] = HH_MIN_ALPHA + ( progress * HH_ALPHA_DIFF );
-
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
- trap_R_SetColor( NULL );
-}
-
-/*
-==============
-CG_DrawPlayerStamina2
-==============
-*/
-static void CG_DrawPlayerStamina2( rectDef_t *rect, vec4_t color, qhandle_t shader )
-{
- playerState_t *ps = &cg.snap->ps;
- float stamina = ps->stats[ STAT_STAMINA ];
- float maxStaminaBy3 = (float)MAX_STAMINA / 3.0f;
- float progress;
-
- stamina -= (int)maxStaminaBy3;
- progress = stamina / maxStaminaBy3;
-
- if( progress > 1.0f )
- progress = 1.0f;
- else if( progress < 0.0f )
- progress = 0.0f;
-
- color[ 3 ] = HH_MIN_ALPHA + ( progress * HH_ALPHA_DIFF );
-
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
- trap_R_SetColor( NULL );
-}
-
-/*
-==============
-CG_DrawPlayerStamina3
-==============
-*/
-static void CG_DrawPlayerStamina3( rectDef_t *rect, vec4_t color, qhandle_t shader )
-{
- playerState_t *ps = &cg.snap->ps;
- float stamina = ps->stats[ STAT_STAMINA ];
- float maxStaminaBy3 = (float)MAX_STAMINA / 3.0f;
- float progress;
-
- progress = stamina / maxStaminaBy3;
-
- if( progress > 1.0f )
- progress = 1.0f;
- else if( progress < 0.0f )
- progress = 0.0f;
-
- color[ 3 ] = HH_MIN_ALPHA + ( progress * HH_ALPHA_DIFF );
-
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
- trap_R_SetColor( NULL );
-}
-
-/*
-==============
-CG_DrawPlayerStamina4
-==============
-*/
-static void CG_DrawPlayerStamina4( rectDef_t *rect, vec4_t color, qhandle_t shader )
-{
- playerState_t *ps = &cg.snap->ps;
- float stamina = ps->stats[ STAT_STAMINA ];
- float progress;
-
- stamina += (float)MAX_STAMINA;
- progress = stamina / (float)MAX_STAMINA;
-
- if( progress > 1.0f )
- progress = 1.0f;
- else if( progress < 0.0f )
- progress = 0.0f;
-
- color[ 3 ] = HH_MIN_ALPHA + ( progress * HH_ALPHA_DIFF );
-
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
- trap_R_SetColor( NULL );
-}
-
-/*
-==============
-CG_DrawPlayerStaminaBolt
-==============
-*/
-static void CG_DrawPlayerStaminaBolt( rectDef_t *rect, vec4_t color, qhandle_t shader )
-{
- playerState_t *ps = &cg.snap->ps;
- float stamina = ps->stats[ STAT_STAMINA ];
-
- if( stamina < 0 )
- color[ 3 ] = HH_MIN_ALPHA;
- else
- color[ 3 ] = HH_MAX_ALPHA;
-
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
- trap_R_SetColor( NULL );
-}
-
-/*
-==============
-CG_DrawPlayerClipsRing
-==============
-*/
-static void CG_DrawPlayerClipsRing( rectDef_t *rect, vec4_t color, qhandle_t shader )
-{
- playerState_t *ps = &cg.snap->ps;
- centity_t *cent;
- float buildTime = ps->stats[ STAT_MISC ];
- float progress;
- float maxDelay;
-
- cent = &cg_entities[ cg.snap->ps.clientNum ];
-
- switch( cent->currentState.weapon )
- {
- case WP_ABUILD:
- case WP_ABUILD2:
- case WP_HBUILD:
- case WP_HBUILD2:
- maxDelay = (float)BG_FindBuildDelayForWeapon( cent->currentState.weapon );
-
- if( buildTime > maxDelay )
- buildTime = maxDelay;
-
- progress = ( maxDelay - buildTime ) / maxDelay;
-
- color[ 3 ] = HH_MIN_ALPHA + ( progress * HH_ALPHA_DIFF );
- break;
-
- default:
- if( ps->weaponstate == WEAPON_RELOADING )
- {
- maxDelay = (float)BG_FindReloadTimeForWeapon( cent->currentState.weapon );
- progress = ( maxDelay - (float)ps->weaponTime ) / maxDelay;
-
- color[ 3 ] = HH_MIN_ALPHA + ( progress * HH_ALPHA_DIFF );
- }
- break;
- }
-
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
- trap_R_SetColor( NULL );
-}
-
-/*
-==============
-CG_DrawPlayerBuildTimerRing
-==============
-*/
-static void CG_DrawPlayerBuildTimerRing( rectDef_t *rect, vec4_t color, qhandle_t shader )
-{
- playerState_t *ps = &cg.snap->ps;
- centity_t *cent;
- float buildTime = ps->stats[ STAT_MISC ];
- float progress;
- float maxDelay;
-
- cent = &cg_entities[ cg.snap->ps.clientNum ];
-
- maxDelay = (float)BG_FindBuildDelayForWeapon( cent->currentState.weapon );
-
- if( buildTime > maxDelay )
- buildTime = maxDelay;
-
- progress = ( maxDelay - buildTime ) / maxDelay;
-
- color[ 3 ] = AH_MIN_ALPHA + ( progress * AH_ALPHA_DIFF );
-
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
- trap_R_SetColor( NULL );
-}
-
-/*
-==============
-CG_DrawPlayerBoosted
-==============
-*/
-static void CG_DrawPlayerBoosted( rectDef_t *rect, vec4_t color, qhandle_t shader )
-{
- playerState_t *ps = &cg.snap->ps;
- qboolean boosted = ps->stats[ STAT_STATE ] & SS_BOOSTED;
-
- if( boosted )
- color[ 3 ] = AH_MAX_ALPHA;
- else
- color[ 3 ] = AH_MIN_ALPHA;
-
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
- trap_R_SetColor( NULL );
-}
-
-/*
-==============
-CG_DrawPlayerBoosterBolt
-==============
-*/
-static void CG_DrawPlayerBoosterBolt( rectDef_t *rect, vec4_t color, qhandle_t shader )
-{
- playerState_t *ps = &cg.snap->ps;
- qboolean boosted = ps->stats[ STAT_STATE ] & SS_BOOSTED;
- vec4_t localColor;
-
- Vector4Copy( color, localColor );
-
- if( boosted )
- {
- if( ps->stats[ STAT_BOOSTTIME ] > BOOST_TIME - 3000 )
- {
- qboolean flash = ( ps->stats[ STAT_BOOSTTIME ] / 500 ) % 2;
-
- if( flash )
- localColor[ 3 ] = 1.0f;
- }
- }
-
- trap_R_SetColor( localColor );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
- trap_R_SetColor( NULL );
-}
-
-/*
-==============
-CG_DrawPlayerPoisonBarbs
-==============
-*/
-static void CG_DrawPlayerPoisonBarbs( rectDef_t *rect, vec4_t color, qhandle_t shader )
-{
- playerState_t *ps = &cg.snap->ps;
- int x = rect->x;
- int y = rect->y;
- int width = rect->w;
- int height = rect->h;
- qboolean vertical;
- int iconsize, numBarbs, i;
-
- BG_UnpackAmmoArray( ps->weapon, ps->ammo, ps->powerups, &numBarbs, NULL );
-
- if( height > width )
- {
- vertical = qtrue;
- iconsize = width;
- }
- else if( height <= width )
- {
- vertical = qfalse;
- iconsize = height;
- }
-
- if( color[ 3 ] != 0.0 )
- trap_R_SetColor( color );
-
- for( i = 0; i < numBarbs; i ++ )
- {
- if( vertical )
- y += iconsize;
- else
- x += iconsize;
-
- CG_DrawPic( x, y, iconsize, iconsize, shader );
- }
-
- trap_R_SetColor( NULL );
-}
-
-/*
-==============
-CG_DrawPlayerWallclimbing
-==============
-*/
-static void CG_DrawPlayerWallclimbing( rectDef_t *rect, vec4_t color, qhandle_t shader )
-{
- playerState_t *ps = &cg.snap->ps;
- qboolean ww = ps->stats[ STAT_STATE ] & SS_WALLCLIMBING;
-
- if( ww )
- color[ 3 ] = AH_MAX_ALPHA;
- else
- color[ 3 ] = AH_MIN_ALPHA;
-
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
- trap_R_SetColor( NULL );
-}
-
-static void CG_DrawPlayerStamina( rectDef_t *rect, vec4_t color, float scale,
- int align, int textStyle, int special )
-{
- playerState_t *ps = &cg.snap->ps;
- int stamina = ps->stats[ STAT_STAMINA ];
- float progress = ( (float)stamina + (float)MAX_STAMINA ) / ( (float)MAX_STAMINA * 2.0f );
-
- CG_DrawProgressBar( rect, color, scale, align, textStyle, special, progress );
-}
-
-static void CG_DrawPlayerAmmoValue( rectDef_t *rect, vec4_t color )
-{
- int value;
- centity_t *cent;
- playerState_t *ps;
-
- cent = &cg_entities[ cg.snap->ps.clientNum ];
- ps = &cg.snap->ps;
-
- if( cent->currentState.weapon )
- {
- switch( cent->currentState.weapon )
- {
- case WP_ABUILD:
- case WP_ABUILD2:
- //percentage of BP remaining
- value = cgs.alienBuildPoints;
- break;
-
- case WP_HBUILD:
- case WP_HBUILD2:
- //percentage of BP remaining
- value = cgs.humanBuildPoints;
- break;
-
- default:
- BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups, &value, NULL );
- break;
- }
-
- if( value > 999 )
- value = 999;
-
- if( value > -1 )
- {
- trap_R_SetColor( color );
- CG_DrawField( rect->x, rect->y, 4, rect->w / 4, rect->h, value );
- trap_R_SetColor( NULL );
- }
- }
-}
-
-
-/*
-==============
-CG_DrawAlienSense
-==============
-*/
-static void CG_DrawAlienSense( rectDef_t *rect )
-{
- if( BG_ClassHasAbility( cg.snap->ps.stats[ STAT_PCLASS ], SCA_ALIENSENSE ) )
- CG_AlienSense( rect );
-}
-
-
-/*
-==============
-CG_DrawHumanScanner
-==============
-*/
-static void CG_DrawHumanScanner( rectDef_t *rect, qhandle_t shader, vec4_t color )
-{
- if( BG_InventoryContainsUpgrade( UP_HELMET, cg.snap->ps.stats ) )
- CG_Scanner( rect, shader, color );
-}
-
-
-/*
-==============
-CG_DrawUsableBuildable
-==============
-*/
-static void CG_DrawUsableBuildable( rectDef_t *rect, qhandle_t shader, vec4_t color )
-{
- vec3_t view, point;
- trace_t trace;
- entityState_t *es;
-
- AngleVectors( cg.refdefViewAngles, view, NULL, NULL );
- VectorMA( cg.refdef.vieworg, 64, view, point );
- CG_Trace( &trace, cg.refdef.vieworg, NULL, NULL,
- point, cg.predictedPlayerState.clientNum, MASK_SHOT );
-
- es = &cg_entities[ trace.entityNum ].currentState;
-
- if( es->eType == ET_BUILDABLE && BG_FindUsableForBuildable( es->modelindex ) &&
- cg.predictedPlayerState.stats[ STAT_PTEAM ] == BG_FindTeamForBuildable( es->modelindex ) )
- {
- //hack to prevent showing the usable buildable when you aren't carrying an energy weapon
- if( ( es->modelindex == BA_H_REACTOR || es->modelindex == BA_H_REPEATER ) &&
- ( !BG_FindUsesEnergyForWeapon( cg.snap->ps.weapon ) ||
- BG_FindInfinteAmmoForWeapon( cg.snap->ps.weapon ) ) )
- return;
-
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
- trap_R_SetColor( NULL );
- }
-}
-
-
-#define BUILD_DELAY_TIME 2000
-
-static void CG_DrawPlayerBuildTimer( rectDef_t *rect, vec4_t color )
-{
- float progress;
- int index;
- centity_t *cent;
- playerState_t *ps;
-
- cent = &cg_entities[ cg.snap->ps.clientNum ];
- ps = &cg.snap->ps;
-
- if( cent->currentState.weapon )
- {
- switch( cent->currentState.weapon )
- {
- case WP_ABUILD:
- progress = (float)ps->stats[ STAT_MISC ] / (float)ABUILDER_BASE_DELAY;
- break;
-
- case WP_ABUILD2:
- progress = (float)ps->stats[ STAT_MISC ] / (float)ABUILDER_ADV_DELAY;
- break;
-
- case WP_HBUILD:
- progress = (float)ps->stats[ STAT_MISC ] / (float)HBUILD_DELAY;
- break;
-
- case WP_HBUILD2:
- progress = (float)ps->stats[ STAT_MISC ] / (float)HBUILD2_DELAY;
- break;
-
- default:
- return;
- break;
- }
-
- if( !ps->stats[ STAT_MISC ] )
- return;
-
- index = (int)( progress * 8.0f );
-
- if( index > 7 )
- index = 7;
- else if( index < 0 )
- index = 0;
-
- if( cg.time - cg.lastBuildAttempt <= BUILD_DELAY_TIME )
- {
- if( ( ( cg.time - cg.lastBuildAttempt ) / 300 ) % 2 )
- {
- color[ 0 ] = 1.0f;
- color[ 1 ] = color[ 2 ] = 0.0f;
- color[ 3 ] = 1.0f;
- }
- }
-
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h,
- cgs.media.buildWeaponTimerPie[ index ] );
- trap_R_SetColor( NULL );
- }
-}
-
-static void CG_DrawPlayerClipsValue( rectDef_t *rect, vec4_t color )
-{
- int value;
- centity_t *cent;
- playerState_t *ps;
-
- cent = &cg_entities[ cg.snap->ps.clientNum ];
- ps = &cg.snap->ps;
-
- if( cent->currentState.weapon )
- {
- switch( cent->currentState.weapon )
- {
- case WP_ABUILD:
- case WP_ABUILD2:
- case WP_HBUILD:
- case WP_HBUILD2:
- break;
-
- default:
- BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups, NULL, &value );
-
- if( value > -1 )
- {
- trap_R_SetColor( color );
- CG_DrawField( rect->x, rect->y, 4, rect->w / 4, rect->h, value );
- trap_R_SetColor( NULL );
- }
- break;
- }
- }
-}
-
-static void CG_DrawPlayerHealthValue( rectDef_t *rect, vec4_t color )
-{
- playerState_t *ps;
- int value;
-
- ps = &cg.snap->ps;
-
- value = ps->stats[ STAT_HEALTH ];
-
- trap_R_SetColor( color );
- CG_DrawField( rect->x, rect->y, 4, rect->w / 4, rect->h, value );
- trap_R_SetColor( NULL );
-}
-
-static void CG_DrawPlayerHealthBar( rectDef_t *rect, vec4_t color, float scale,
- int align, int textStyle, int special )
-{
- playerState_t *ps;
- float total;
-
- ps = &cg.snap->ps;
-
- total = ( (float)ps->stats[ STAT_HEALTH ] / (float)ps->stats[ STAT_MAX_HEALTH ] );
- CG_DrawProgressBar( rect, color, scale, align, textStyle, special, total );
-}
-
-/*
-==============
-CG_DrawPlayerHealthCross
-==============
-*/
-static void CG_DrawPlayerHealthCross( rectDef_t *rect, vec4_t color, qhandle_t shader )
-{
- playerState_t *ps = &cg.snap->ps;
- int health = ps->stats[ STAT_HEALTH ];
-
- if( health < 10 )
- {
- color[ 0 ] = 1.0f;
- color[ 1 ] = color[ 2 ] = 0.0f;
- }
-
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
- trap_R_SetColor( NULL );
-}
-
-static void CG_DrawProgressLabel( rectDef_t *rect, float text_x, float text_y, vec4_t color,
- float scale, int align, const char *s, float fraction )
-{
- vec4_t white = { 1.0f, 1.0f, 1.0f, 1.0f };
- float tx, tw = CG_Text_Width( s, scale, 0 );
-
- switch( align )
- {
- case ITEM_ALIGN_LEFT:
- tx = 0.0f;
- break;
-
- case ITEM_ALIGN_RIGHT:
- tx = rect->w - tw;
- break;
-
- case ITEM_ALIGN_CENTER:
- tx = ( rect->w / 2.0f ) - ( tw / 2.0f );
- break;
-
- default:
- tx = 0.0f;
- }
-
- if( fraction < 1.0f )
- CG_Text_Paint( rect->x + text_x + tx, rect->y + text_y, scale, white,
- s, 0, 0, ITEM_TEXTSTYLE_NORMAL );
- else
- CG_Text_Paint( rect->x + text_x + tx, rect->y + text_y, scale, color,
- s, 0, 0, ITEM_TEXTSTYLE_NEON );
-}
-
-static void CG_DrawMediaProgress( rectDef_t *rect, vec4_t color, float scale,
- int align, int textStyle, int special )
-{
- CG_DrawProgressBar( rect, color, scale, align, textStyle, special, cg.mediaFraction );
-}
-
-static void CG_DrawMediaProgressLabel( rectDef_t *rect, float text_x, float text_y,
- vec4_t color, float scale, int align )
-{
- CG_DrawProgressLabel( rect, text_x, text_y, color, scale, align, "Map and Textures", cg.mediaFraction );
-}
-
-static void CG_DrawBuildablesProgress( rectDef_t *rect, vec4_t color, float scale,
- int align, int textStyle, int special )
-{
- CG_DrawProgressBar( rect, color, scale, align, textStyle, special, cg.buildablesFraction );
-}
-
-static void CG_DrawBuildablesProgressLabel( rectDef_t *rect, float text_x, float text_y,
- vec4_t color, float scale, int align )
-{
- CG_DrawProgressLabel( rect, text_x, text_y, color, scale, align, "Buildable Models", cg.buildablesFraction );
-}
-
-static void CG_DrawCharModelProgress( rectDef_t *rect, vec4_t color, float scale,
- int align, int textStyle, int special )
-{
- CG_DrawProgressBar( rect, color, scale, align, textStyle, special, cg.charModelFraction );
-}
-
-static void CG_DrawCharModelProgressLabel( rectDef_t *rect, float text_x, float text_y,
- vec4_t color, float scale, int align )
-{
- CG_DrawProgressLabel( rect, text_x, text_y, color, scale, align, "Character Models", cg.charModelFraction );
-}
-
-static void CG_DrawOverallProgress( rectDef_t *rect, vec4_t color, float scale,
- int align, int textStyle, int special )
-{
- float total;
-
- total = ( cg.charModelFraction + cg.buildablesFraction + cg.mediaFraction ) / 3.0f;
- CG_DrawProgressBar( rect, color, scale, align, textStyle, special, total );
-}
-
-static void CG_DrawLevelShot( rectDef_t *rect )
-{
- const char *s;
- const char *info;
- qhandle_t levelshot;
- qhandle_t detail;
-
- info = CG_ConfigString( CS_SERVERINFO );
- s = Info_ValueForKey( info, "mapname" );
- levelshot = trap_R_RegisterShaderNoMip( va( "levelshots/%s.tga", s ) );
-
- if( !levelshot )
- levelshot = trap_R_RegisterShaderNoMip( "gfx/2d/load_screen" );
-
- trap_R_SetColor( NULL );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, levelshot );
-
- // blend a detail texture over it
- detail = trap_R_RegisterShader( "levelShotDetail" );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, detail );
-}
-
-static void CG_DrawLoadingString( rectDef_t *rect, float text_x, float text_y, vec4_t color,
- float scale, int align, int textStyle, const char *s )
-{
- float tw, th, tx;
- int pos, i;
- char buffer[ 1024 ];
- char *end;
-
- if( !s[ 0 ] )
- return;
-
- strcpy( buffer, s );
- tw = CG_Text_Width( s, scale, 0 );
- th = scale * 40.0f;
-
- pos = i = 0;
-
- while( pos < strlen( s ) )
- {
- strcpy( buffer, &s[ pos ] );
- tw = CG_Text_Width( buffer, scale, 0 );
-
- while( tw > rect->w )
- {
- end = strrchr( buffer, ' ' );
-
- if( end == NULL )
- break;
-
- *end = '\0';
- tw = CG_Text_Width( buffer, scale, 0 );
- }
-
- switch( align )
- {
- case ITEM_ALIGN_LEFT:
- tx = rect->x;
- break;
-
- case ITEM_ALIGN_RIGHT:
- tx = rect->x + rect->w - tw;
- break;
-
- case ITEM_ALIGN_CENTER:
- tx = rect->x + ( rect->w / 2.0f ) - ( tw / 2.0f );
- break;
-
- default:
- tx = 0.0f;
- }
-
- CG_Text_Paint( tx + text_x, rect->y + text_y + i * ( th + 3 ), scale, color,
- buffer, 0, 0, textStyle );
-
- pos += strlen( buffer ) + 1;
- i++;
- }
-}
-
-static void CG_DrawLevelName( rectDef_t *rect, float text_x, float text_y,
- vec4_t color, float scale, int align, int textStyle )
-{
- const char *s;
-
- s = CG_ConfigString( CS_MESSAGE );
-
- CG_DrawLoadingString( rect, text_x, text_y, color, scale, align, textStyle, s );
-}
-
-static void CG_DrawMOTD( rectDef_t *rect, float text_x, float text_y,
- vec4_t color, float scale, int align, int textStyle )
-{
- const char *s;
-
- s = CG_ConfigString( CS_MOTD );
-
- CG_DrawLoadingString( rect, text_x, text_y, color, scale, align, textStyle, s );
-}
-
-static void CG_DrawHostname( rectDef_t *rect, float text_x, float text_y,
- vec4_t color, float scale, int align, int textStyle )
-{
- char buffer[ 1024 ];
- const char *info;
-
- info = CG_ConfigString( CS_SERVERINFO );
-
- Q_strncpyz( buffer, Info_ValueForKey( info, "sv_hostname" ), 1024 );
- Q_CleanStr( buffer );
-
- CG_DrawLoadingString( rect, text_x, text_y, color, scale, align, textStyle, buffer );
-}
-
-/*
-======================
-CG_UpdateMediaFraction
-
-======================
-*/
-void CG_UpdateMediaFraction( float newFract )
-{
- cg.mediaFraction = newFract;
-
- trap_UpdateScreen( );
-}
-
-/*
-====================
-CG_DrawLoadingScreen
-
-Draw all the status / pacifier stuff during level loading
-====================
-*/
-void CG_DrawLoadingScreen( void )
-{
- Menu_Paint( Menus_FindByName( "Loading" ), qtrue );
-}
-
-float CG_GetValue( int ownerDraw )
-{
- centity_t *cent;
- playerState_t *ps;
-
- cent = &cg_entities[ cg.snap->ps.clientNum ];
- ps = &cg.snap->ps;
-
- switch( ownerDraw )
- {
- case CG_PLAYER_AMMO_VALUE:
- if( cent->currentState.weapon )
- {
- int value;
-
- BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups,
- &value, NULL );
-
- return value;
- }
- break;
- case CG_PLAYER_CLIPS_VALUE:
- if( cent->currentState.weapon )
- {
- int value;
-
- BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups,
- NULL, &value );
-
- return value;
- }
- break;
- case CG_PLAYER_HEALTH:
- return ps->stats[ STAT_HEALTH ];
- break;
- default:
- break;
- }
-
- return -1;
-}
-
-static void CG_DrawAreaSystemChat( rectDef_t *rect, float scale, vec4_t color, qhandle_t shader )
-{
- CG_Text_Paint( rect->x, rect->y + rect->h, scale, color, systemChat, 0, 0, 0 );
-}
-
-static void CG_DrawAreaTeamChat( rectDef_t *rect, float scale, vec4_t color, qhandle_t shader )
-{
- CG_Text_Paint( rect->x, rect->y + rect->h, scale, color,teamChat1, 0, 0, 0 );
-}
-
-static void CG_DrawAreaChat(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader)
-{
- CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, teamChat2, 0, 0, 0);
-}
-
-const char *CG_GetKillerText( )
-{
- const char *s = "";
- if( cg.killerName[ 0 ] )
- s = va( "Fragged by %s", cg.killerName );
-
- return s;
-}
-
-
-static void CG_DrawKiller( rectDef_t *rect, float scale, vec4_t color,
- qhandle_t shader, int textStyle )
-{
- // fragged by ... line
- if( cg.killerName[ 0 ] )
- {
- int x = rect->x + rect->w / 2;
- CG_Text_Paint( x - CG_Text_Width( CG_GetKillerText( ), scale, 0 ) / 2,
- rect->y + rect->h, scale, color, CG_GetKillerText( ), 0, 0, textStyle );
- }
-}
-
-
-static void CG_Text_Paint_Limit( float *maxX, float x, float y, float scale,
- vec4_t color, const char* text, float adjust, int limit )
-{
- int len, count;
- vec4_t newColor;
- glyphInfo_t *glyph;
-
- if( text )
- {
-// TTimo: FIXME
-// const unsigned char *s = text; // bk001206 - unsigned
- const char *s = text;
- float max = *maxX;
- float useScale;
- fontInfo_t *font = &cgDC.Assets.textFont;
-
- if( scale <= cg_smallFont.value )
- font = &cgDC.Assets.smallFont;
- else if( scale > cg_bigFont.value )
- font = &cgDC.Assets.bigFont;
-
- useScale = scale * font->glyphScale;
- trap_R_SetColor( color );
- len = strlen( text );
-
- if( limit > 0 && len > limit )
- len = limit;
-
- count = 0;
-
- while( s && *s && count < len )
- {
- glyph = &font->glyphs[ (int)*s ];
- //TTimo: FIXME: getting nasty warnings without the cast,
- //hopefully this doesn't break the VM build
-
- if( Q_IsColorString( s ) )
- {
- memcpy( newColor, g_color_table[ ColorIndex( *(s+1) ) ], sizeof( newColor ) );
- newColor[ 3 ] = color[ 3 ];
- trap_R_SetColor( newColor );
- s += 2;
- continue;
- }
- else
- {
- float yadj = useScale * glyph->top;
-
- if( CG_Text_Width( s, useScale, 1 ) + x > max )
- {
- *maxX = 0;
- break;
- }
-
- CG_Text_PaintChar( x, y - yadj,
- glyph->imageWidth,
- glyph->imageHeight,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph );
- x += ( glyph->xSkip * useScale ) + adjust;
- *maxX = x;
- count++;
- s++;
- }
- }
-
- trap_R_SetColor( NULL );
- }
-}
-
-static void CG_DrawTeamSpectators( rectDef_t *rect, float scale, vec4_t color, qhandle_t shader )
-{
- if( cg.spectatorLen )
- {
- float maxX;
-
- if( cg.spectatorWidth == -1 )
- {
- cg.spectatorWidth = 0;
- cg.spectatorPaintX = rect->x + 1;
- cg.spectatorPaintX2 = -1;
- }
-
- if( cg.spectatorOffset > cg.spectatorLen )
- {
- cg.spectatorOffset = 0;
- cg.spectatorPaintX = rect->x + 1;
- cg.spectatorPaintX2 = -1;
- }
-
- if( cg.time > cg.spectatorTime )
- {
- cg.spectatorTime = cg.time + 10;
-
- if( cg.spectatorPaintX <= rect->x + 2 )
- {
- if( cg.spectatorOffset < cg.spectatorLen )
- {
- //TA: skip colour directives
- if( Q_IsColorString( &cg.spectatorList[ cg.spectatorOffset ] ) )
- cg.spectatorOffset += 2;
- else
- {
- cg.spectatorPaintX += CG_Text_Width( &cg.spectatorList[ cg.spectatorOffset ], scale, 1 ) - 1;
- cg.spectatorOffset++;
- }
- }
- else
- {
- cg.spectatorOffset = 0;
-
- if( cg.spectatorPaintX2 >= 0 )
- cg.spectatorPaintX = cg.spectatorPaintX2;
- else
- cg.spectatorPaintX = rect->x + rect->w - 2;
-
- cg.spectatorPaintX2 = -1;
- }
- }
- else
- {
- cg.spectatorPaintX--;
-
- if( cg.spectatorPaintX2 >= 0 )
- cg.spectatorPaintX2--;
- }
- }
-
- maxX = rect->x + rect->w - 2;
-
- CG_Text_Paint_Limit( &maxX, cg.spectatorPaintX, rect->y + rect->h - 3, scale, color,
- &cg.spectatorList[ cg.spectatorOffset ], 0, 0 );
-
- if( cg.spectatorPaintX2 >= 0 )
- {
- float maxX2 = rect->x + rect->w - 2;
- CG_Text_Paint_Limit( &maxX2, cg.spectatorPaintX2, rect->y + rect->h - 3, scale,
- color, cg.spectatorList, 0, cg.spectatorOffset );
- }
-
- if( cg.spectatorOffset && maxX > 0 )
- {
- // if we have an offset ( we are skipping the first part of the string ) and we fit the string
- if( cg.spectatorPaintX2 == -1 )
- cg.spectatorPaintX2 = rect->x + rect->w - 2;
- }
- else
- cg.spectatorPaintX2 = -1;
- }
-}
-
-/*
-==================
-CG_DrawStageReport
-==================
-*/
-static void CG_DrawStageReport( rectDef_t *rect, float text_x, float text_y,
- vec4_t color, float scale, int align, int textStyle )
-{
- char s[ MAX_TOKEN_CHARS ];
- int tx, w, kills;
-
- if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR && !cg.intermissionStarted )
- return;
-
- if( cg.intermissionStarted )
- {
- Com_sprintf( s, MAX_TOKEN_CHARS,
- "Stage %d" //PH34R MY MAD-LEET CODING SKILLZ
- " "
- "Stage %d",
- cgs.alienStage + 1, cgs.humanStage + 1 );
- }
- else if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
- {
- kills = cgs.alienNextStageThreshold - cgs.alienKills;
-
- if( cgs.alienNextStageThreshold < 0 )
- Com_sprintf( s, MAX_TOKEN_CHARS, "Stage %d", cgs.alienStage + 1 );
- else if( kills == 1 )
- Com_sprintf( s, MAX_TOKEN_CHARS, "Stage %d, %d kill for next stage",
- cgs.alienStage + 1, kills );
- else
- Com_sprintf( s, MAX_TOKEN_CHARS, "Stage %d, %d kills for next stage",
- cgs.alienStage + 1, kills );
- }
- else if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
- {
- kills = cgs.humanNextStageThreshold - cgs.humanKills;
-
- if( cgs.humanNextStageThreshold < 0 )
- Com_sprintf( s, MAX_TOKEN_CHARS, "Stage %d", cgs.humanStage + 1 );
- else if( kills == 1 )
- Com_sprintf( s, MAX_TOKEN_CHARS, "Stage %d, %d kill for next stage",
- cgs.humanStage + 1, kills );
- else
- Com_sprintf( s, MAX_TOKEN_CHARS, "Stage %d, %d kills for next stage",
- cgs.humanStage + 1, kills );
- }
-
- w = CG_Text_Width( s, scale, 0 );
-
- switch( align )
- {
- case ITEM_ALIGN_LEFT:
- tx = rect->x;
- break;
-
- case ITEM_ALIGN_RIGHT:
- tx = rect->x + rect->w - w;
- break;
-
- case ITEM_ALIGN_CENTER:
- tx = rect->x + ( rect->w / 2.0f ) - ( w / 2.0f );
- break;
-
- default:
- tx = 0.0f;
- }
-
- CG_Text_Paint( text_x + tx, rect->y + text_y, scale, color, s, 0, 0, textStyle );
-}
-
-/*
-==================
-CG_DrawFPS
-==================
-*/
-//TA: personally i think this should be longer - it should really be a cvar
-#define FPS_FRAMES 20
-#define FPS_STRING "fps"
-static void CG_DrawFPS( rectDef_t *rect, float text_x, float text_y,
- float scale, vec4_t color, int align, int textStyle,
- qboolean scalableText )
-{
- char *s;
- int tx, w, totalWidth, strLength;
- static int previousTimes[ FPS_FRAMES ];
- static int index;
- int i, total;
- int fps;
- static int previous;
- int t, frameTime;
-
- if( !cg_drawFPS.integer )
- return;
-
- // don't use serverTime, because that will be drifting to
- // correct for internet lag changes, timescales, timedemos, etc
- t = trap_Milliseconds( );
- frameTime = t - previous;
- previous = t;
-
- previousTimes[ index % FPS_FRAMES ] = frameTime;
- index++;
-
- if( index > FPS_FRAMES )
- {
- // average multiple frames together to smooth changes out a bit
- total = 0;
-
- for( i = 0 ; i < FPS_FRAMES ; i++ )
- total += previousTimes[ i ];
-
- if( !total )
- total = 1;
-
- fps = 1000 * FPS_FRAMES / total;
-
- s = va( "%d", fps );
- w = CG_Text_Width( "0", scale, 0 );
- strLength = CG_DrawStrlen( s );
- totalWidth = CG_Text_Width( FPS_STRING, scale, 0 ) + w * strLength;
-
- switch( align )
- {
- case ITEM_ALIGN_LEFT:
- tx = rect->x;
- break;
-
- case ITEM_ALIGN_RIGHT:
- tx = rect->x + rect->w - totalWidth;
- break;
-
- case ITEM_ALIGN_CENTER:
- tx = rect->x + ( rect->w / 2.0f ) - ( totalWidth / 2.0f );
- break;
-
- default:
- tx = 0.0f;
- }
-
- if( scalableText )
- {
- for( i = 0; i < strLength; i++ )
- {
- char c[ 2 ];
-
- c[ 0 ] = s[ i ];
- c[ 1 ] = '\0';
-
- CG_Text_Paint( text_x + tx + i * w, rect->y + text_y, scale, color, c, 0, 0, textStyle );
- }
- }
- else
- {
- trap_R_SetColor( color );
- CG_DrawField( rect->x, rect->y, 3, rect->w / 3, rect->h, fps );
- trap_R_SetColor( NULL );
- }
-
- if( scalableText )
- CG_Text_Paint( text_x + tx + i * w, rect->y + text_y, scale, color, FPS_STRING, 0, 0, textStyle );
- }
-}
-
-
-/*
-=================
-CG_DrawTimerMins
-=================
-*/
-static void CG_DrawTimerMins( rectDef_t *rect, vec4_t color )
-{
- int mins, seconds;
- int msec;
-
- if( !cg_drawTimer.integer )
- return;
-
- msec = cg.time - cgs.levelStartTime;
-
- seconds = msec / 1000;
- mins = seconds / 60;
- seconds -= mins * 60;
-
- trap_R_SetColor( color );
- CG_DrawField( rect->x, rect->y, 3, rect->w / 3, rect->h, mins );
- trap_R_SetColor( NULL );
-}
-
-
-/*
-=================
-CG_DrawTimerSecs
-=================
-*/
-static void CG_DrawTimerSecs( rectDef_t *rect, vec4_t color )
-{
- int mins, seconds;
- int msec;
-
- if( !cg_drawTimer.integer )
- return;
-
- msec = cg.time - cgs.levelStartTime;
-
- seconds = msec / 1000;
- mins = seconds / 60;
- seconds -= mins * 60;
-
- trap_R_SetColor( color );
- CG_DrawFieldPadded( rect->x, rect->y, 2, rect->w / 2, rect->h, seconds );
- trap_R_SetColor( NULL );
-}
-
-
-/*
-=================
-CG_DrawTimer
-=================
-*/
-static void CG_DrawTimer( rectDef_t *rect, float text_x, float text_y,
- float scale, vec4_t color, int align, int textStyle )
-{
- char *s;
- int i, tx, w, totalWidth, strLength;
- int mins, seconds, tens;
- int msec;
-
- if( !cg_drawTimer.integer )
- return;
-
- msec = cg.time - cgs.levelStartTime;
-
- seconds = msec / 1000;
- mins = seconds / 60;
- seconds -= mins * 60;
- tens = seconds / 10;
- seconds -= tens * 10;
-
- s = va( "%d:%d%d", mins, tens, seconds );
- w = CG_Text_Width( "0", scale, 0 );
- strLength = CG_DrawStrlen( s );
- totalWidth = w * strLength;
-
- switch( align )
- {
- case ITEM_ALIGN_LEFT:
- tx = rect->x;
- break;
-
- case ITEM_ALIGN_RIGHT:
- tx = rect->x + rect->w - totalWidth;
- break;
-
- case ITEM_ALIGN_CENTER:
- tx = rect->x + ( rect->w / 2.0f ) - ( totalWidth / 2.0f );
- break;
-
- default:
- tx = 0.0f;
- }
-
- for( i = 0; i < strLength; i++ )
- {
- char c[ 2 ];
-
- c[ 0 ] = s[ i ];
- c[ 1 ] = '\0';
-
- CG_Text_Paint( text_x + tx + i * w, rect->y + text_y, scale, color, c, 0, 0, textStyle );
- }
-}
-
-/*
-==================
-CG_DrawSnapshot
-==================
-*/
-static void CG_DrawSnapshot( rectDef_t *rect, float text_x, float text_y,
- float scale, vec4_t color, int align, int textStyle )
-{
- char *s;
- int w, tx;
-
- if( !cg_drawSnapshot.integer )
- return;
-
- s = va( "time:%d snap:%d cmd:%d", cg.snap->serverTime,
- cg.latestSnapshotNum, cgs.serverCommandSequence );
- w = CG_Text_Width( s, scale, 0 );
-
- switch( align )
- {
- case ITEM_ALIGN_LEFT:
- tx = rect->x;
- break;
-
- case ITEM_ALIGN_RIGHT:
- tx = rect->x + rect->w - w;
- break;
-
- case ITEM_ALIGN_CENTER:
- tx = rect->x + ( rect->w / 2.0f ) - ( w / 2.0f );
- break;
-
- default:
- tx = 0.0f;
- }
-
- CG_Text_Paint( text_x + tx, rect->y + text_y, scale, color, s, 0, 0, textStyle );
-}
-
-/*
-===============================================================================
-
-LAGOMETER
-
-===============================================================================
-*/
-
-#define LAG_SAMPLES 128
-
-typedef struct
-{
- int frameSamples[ LAG_SAMPLES ];
- int frameCount;
- int snapshotFlags[ LAG_SAMPLES ];
- int snapshotSamples[ LAG_SAMPLES ];
- int snapshotCount;
-} lagometer_t;
-
-lagometer_t lagometer;
-
-/*
-==============
-CG_AddLagometerFrameInfo
-
-Adds the current interpolate / extrapolate bar for this frame
-==============
-*/
-void CG_AddLagometerFrameInfo( void )
-{
- int offset;
-
- offset = cg.time - cg.latestSnapshotTime;
- lagometer.frameSamples[ lagometer.frameCount & ( LAG_SAMPLES - 1 ) ] = offset;
- lagometer.frameCount++;
-}
-
-/*
-==============
-CG_AddLagometerSnapshotInfo
-
-Each time a snapshot is received, log its ping time and
-the number of snapshots that were dropped before it.
-
-Pass NULL for a dropped packet.
-==============
-*/
-void CG_AddLagometerSnapshotInfo( snapshot_t *snap )
-{
- // dropped packet
- if( !snap )
- {
- lagometer.snapshotSamples[ lagometer.snapshotCount & ( LAG_SAMPLES - 1 ) ] = -1;
- lagometer.snapshotCount++;
- return;
- }
-
- // add this snapshot's info
- lagometer.snapshotSamples[ lagometer.snapshotCount & ( LAG_SAMPLES - 1 ) ] = snap->ping;
- lagometer.snapshotFlags[ lagometer.snapshotCount & ( LAG_SAMPLES - 1 ) ] = snap->snapFlags;
- lagometer.snapshotCount++;
-}
-
-/*
-==============
-CG_DrawDisconnect
-
-Should we draw something differnet for long lag vs no packets?
-==============
-*/
-static void CG_DrawDisconnect( void )
-{
- float x, y;
- int cmdNum;
- usercmd_t cmd;
- const char *s;
- int w;
- vec4_t color = { 1.0f, 1.0f, 1.0f, 1.0f };
-
- // draw the phone jack if we are completely past our buffers
- cmdNum = trap_GetCurrentCmdNumber( ) - CMD_BACKUP + 1;
- trap_GetUserCmd( cmdNum, &cmd );
-
- // special check for map_restart
- if( cmd.serverTime <= cg.snap->ps.commandTime || cmd.serverTime > cg.time )
- return;
-
- // also add text in center of screen
- s = "Connection Interrupted";
- w = CG_Text_Width( s, 0.7f, 0 );
- CG_Text_Paint( 320 - w / 2, 100, 0.7f, color, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED );
-
- // blink the icon
- if( ( cg.time >> 9 ) & 1 )
- return;
-
- x = 640 - 48;
- y = 480 - 48;
-
- CG_DrawPic( x, y, 48, 48, trap_R_RegisterShader( "gfx/2d/net.tga" ) );
-}
-
-#define MAX_LAGOMETER_PING 900
-#define MAX_LAGOMETER_RANGE 300
-
-#define PING_FRAMES 40
-
-/*
-==============
-CG_DrawLagometer
-==============
-*/
-static void CG_DrawLagometer( rectDef_t *rect, float text_x, float text_y,
- float scale, vec4_t textColor )
-{
- int a, x, y, i;
- float v;
- float ax, ay, aw, ah, mid, range;
- int color;
- vec4_t adjustedColor;
- float vscale;
- vec4_t white = { 1.0f, 1.0f, 1.0f, 1.0f };
-
- if( cg.snap->ps.pm_type == PM_INTERMISSION )
- return;
-
- if( !cg_lagometer.integer )
- return;
-
- if( cg.demoPlayback )
- return;
-
- Vector4Copy( textColor, adjustedColor );
- adjustedColor[ 3 ] = 0.25f;
-
- trap_R_SetColor( adjustedColor );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cgs.media.whiteShader );
- trap_R_SetColor( NULL );
-
- //
- // draw the graph
- //
- ax = x = rect->x;
- ay = y = rect->y;
- aw = rect->w;
- ah = rect->h;
-
- trap_R_SetColor( NULL );
-
- CG_AdjustFrom640( &ax, &ay, &aw, &ah );
-
- color = -1;
- range = ah / 3;
- mid = ay + range;
-
- vscale = range / MAX_LAGOMETER_RANGE;
-
- // draw the frame interpoalte / extrapolate graph
- for( a = 0 ; a < aw ; a++ )
- {
- i = ( lagometer.frameCount - 1 - a ) & ( LAG_SAMPLES - 1 );
- v = lagometer.frameSamples[ i ];
- v *= vscale;
-
- if( v > 0 )
- {
- if( color != 1 )
- {
- color = 1;
- trap_R_SetColor( g_color_table[ ColorIndex( COLOR_YELLOW ) ] );
- }
-
- if( v > range )
- v = range;
-
- trap_R_DrawStretchPic( ax + aw - a, mid - v, 1, v, 0, 0, 0, 0, cgs.media.whiteShader );
- }
- else if( v < 0 )
- {
- if( color != 2 )
- {
- color = 2;
- trap_R_SetColor( g_color_table[ ColorIndex( COLOR_BLUE ) ] );
- }
-
- v = -v;
- if( v > range )
- v = range;
-
- trap_R_DrawStretchPic( ax + aw - a, mid, 1, v, 0, 0, 0, 0, cgs.media.whiteShader );
- }
- }
-
- // draw the snapshot latency / drop graph
- range = ah / 2;
- vscale = range / MAX_LAGOMETER_PING;
-
- for( a = 0 ; a < aw ; a++ )
- {
- i = ( lagometer.snapshotCount - 1 - a ) & ( LAG_SAMPLES - 1 );
- v = lagometer.snapshotSamples[ i ];
-
- if( v > 0 )
- {
- if( lagometer.snapshotFlags[ i ] & SNAPFLAG_RATE_DELAYED )
- {
- if( color != 5 )
- {
- color = 5; // YELLOW for rate delay
- trap_R_SetColor( g_color_table[ ColorIndex( COLOR_YELLOW ) ] );
- }
- }
- else
- {
- if( color != 3 )
- {
- color = 3;
-
- trap_R_SetColor( g_color_table[ ColorIndex( COLOR_GREEN ) ] );
- }
- }
-
- v = v * vscale;
-
- if( v > range )
- v = range;
-
- trap_R_DrawStretchPic( ax + aw - a, ay + ah - v, 1, v, 0, 0, 0, 0, cgs.media.whiteShader );
- }
- else if( v < 0 )
- {
- if( color != 4 )
- {
- color = 4; // RED for dropped snapshots
- trap_R_SetColor( g_color_table[ ColorIndex( COLOR_RED ) ] );
- }
-
- trap_R_DrawStretchPic( ax + aw - a, ay + ah - range, 1, range, 0, 0, 0, 0, cgs.media.whiteShader );
- }
- }
-
- trap_R_SetColor( NULL );
-
- if( cg_nopredict.integer || cg_synchronousClients.integer )
- CG_Text_Paint( ax, ay, 0.5, white, "snc", 0, 0, ITEM_TEXTSTYLE_NORMAL );
- else
- {
- static int previousPings[ PING_FRAMES ];
- static int index;
- int i, ping = 0;
- char *s;
-
- previousPings[ index++ ] = cg.snap->ping;
- index = index % PING_FRAMES;
-
- for( i = 0; i < PING_FRAMES; i++ )
- ping += previousPings[ i ];
-
- ping /= PING_FRAMES;
-
- s = va( "%d", ping );
- ax = rect->x + ( rect->w / 2.0f ) - ( CG_Text_Width( s, scale, 0 ) / 2.0f ) + text_x;
- ay = rect->y + ( rect->h / 2.0f ) + ( CG_Text_Height( s, scale, 0 ) / 2.0f ) + text_y;
-
- Vector4Copy( textColor, adjustedColor );
- adjustedColor[ 3 ] = 0.5f;
- CG_Text_Paint( ax, ay, scale, adjustedColor, s, 0, 0, ITEM_TEXTSTYLE_NORMAL );
- }
-
- CG_DrawDisconnect( );
-}
-
-/*
-==============
-CG_DrawConsole
-==============
-*/
-static void CG_DrawConsole( rectDef_t *rect, float text_x, float text_y, vec4_t color,
- float scale, int align, int textStyle )
-{
- float x, y, w, h;
-
- //for some reason if these are stored locally occasionally rendering fails
- //even though they are both live until the end of the function, hence static
- //possible compiler bug??
- static menuDef_t dummyParent;
- static itemDef_t textItem;
-
- //offset the text
- x = rect->x;
- y = rect->y;
- w = rect->w - ( 16 + ( 2 * text_x ) ); //16 to ensure text within frame
- h = rect->h;
-
- textItem.text = cg.consoleText;
-
- textItem.parent = &dummyParent;
- memcpy( textItem.window.foreColor, color, sizeof( vec4_t ) );
- textItem.window.flags = 0;
-
- switch( align )
- {
- case ITEM_ALIGN_LEFT:
- textItem.window.rect.x = x;
- break;
-
- case ITEM_ALIGN_RIGHT:
- textItem.window.rect.x = x + w;
- break;
-
- case ITEM_ALIGN_CENTER:
- textItem.window.rect.x = x + ( w / 2 );
- break;
-
- default:
- textItem.window.rect.x = x;
- break;
- }
-
- textItem.window.rect.y = y;
- textItem.window.rect.w = w;
- textItem.window.rect.h = h;
- textItem.window.borderSize = 0;
- textItem.textRect.x = 0;
- textItem.textRect.y = 0;
- textItem.textRect.w = 0;
- textItem.textRect.h = 0;
- textItem.textalignment = align;
- textItem.textalignx = text_x;
- textItem.textaligny = text_y;
- textItem.textscale = scale;
- textItem.textStyle = textStyle;
-
- //hack to utilise existing autowrap code
- Item_Text_AutoWrapped_Paint( &textItem );
-}
-
-/*
-===================
-CG_DrawWeaponIcon
-===================
-*/
-void CG_DrawWeaponIcon( rectDef_t *rect, vec4_t color )
-{
- int ammo, clips, maxAmmo;
- centity_t *cent;
- playerState_t *ps;
-
- cent = &cg_entities[ cg.snap->ps.clientNum ];
- ps = &cg.snap->ps;
-
- BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups, &ammo, &clips );
- BG_FindAmmoForWeapon( cent->currentState.weapon, &maxAmmo, NULL );
-
- // don't display if dead
- if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 )
- return;
-
- if( cent->currentState.weapon == 0 )
- return;
-
- CG_RegisterWeapon( cent->currentState.weapon );
-
- if( clips == 0 && !BG_FindInfinteAmmoForWeapon( cent->currentState.weapon ) )
- {
- float ammoPercent = (float)ammo / (float)maxAmmo;
-
- if( ammoPercent < 0.33f )
- {
- color[ 0 ] = 1.0f;
- color[ 1 ] = color[ 2 ] = 0.0f;
- }
- }
-
- if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS && CG_AtHighestClass( ) )
- {
- if( cg.time - cg.lastEvolveAttempt <= NO_CREDITS_TIME )
- {
- if( ( ( cg.time - cg.lastEvolveAttempt ) / 300 ) % 2 )
- color[ 3 ] = 0.0f;
- }
- }
-
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cg_weapons[ cent->currentState.weapon ].weaponIcon );
- trap_R_SetColor( NULL );
-}
-
-
-
-/*
-================================================================================
-
-CROSSHAIR
-
-================================================================================
-*/
-
-
-/*
-=================
-CG_DrawCrosshair
-=================
-*/
-static void CG_DrawCrosshair( void )
-{
- float w, h;
- qhandle_t hShader;
- float x, y;
- weaponInfo_t *wi;
-
- if( !cg_drawCrosshair.integer )
- return;
-
- if( ( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) ||
- ( cg.snap->ps.stats[ STAT_STATE ] & SS_INFESTING ) ||
- ( cg.snap->ps.stats[ STAT_STATE ] & SS_HOVELING ) )
- return;
-
- if( cg.renderingThirdPerson )
- return;
-
- wi = &cg_weapons[ cg.snap->ps.weapon ];
-
- w = h = wi->crossHairSize;
-
- x = cg_crosshairX.integer;
- y = cg_crosshairY.integer;
- CG_AdjustFrom640( &x, &y, &w, &h );
-
- hShader = wi->crossHair;
-
- if( hShader != 0 )
- {
- trap_R_DrawStretchPic( x + cg.refdef.x + 0.5 * ( cg.refdef.width - w ),
- y + cg.refdef.y + 0.5 * ( cg.refdef.height - h ),
- w, h, 0, 0, 1, 1, hShader );
- }
-}
-
-
-
-/*
-=================
-CG_ScanForCrosshairEntity
-=================
-*/
-static void CG_ScanForCrosshairEntity( void )
-{
- trace_t trace;
- vec3_t start, end;
- int content;
- pTeam_t team;
-
- VectorCopy( cg.refdef.vieworg, start );
- VectorMA( start, 131072, cg.refdef.viewaxis[ 0 ], end );
-
- CG_Trace( &trace, start, vec3_origin, vec3_origin, end,
- cg.snap->ps.clientNum, CONTENTS_SOLID|CONTENTS_BODY );
-
- if( trace.entityNum >= MAX_CLIENTS )
- return;
-
- // if the player is in fog, don't show it
- content = trap_CM_PointContents( trace.endpos, 0 );
- if( content & CONTENTS_FOG )
- return;
-
- team = cgs.clientinfo[ trace.entityNum ].team;
-
- if( cg.snap->ps.persistant[ PERS_TEAM ] != TEAM_SPECTATOR )
- {
- //only display team names of those on the same team as this player
- if( team != cg.snap->ps.stats[ STAT_PTEAM ] )
- return;
- }
-
- // update the fade timer
- cg.crosshairClientNum = trace.entityNum;
- cg.crosshairClientTime = cg.time;
-}
-
-
-/*
-=====================
-CG_DrawCrosshairNames
-=====================
-*/
-static void CG_DrawCrosshairNames( rectDef_t *rect, float scale, int textStyle )
-{
- float *color;
- char *name;
- float w, x;
-
- if( !cg_drawCrosshair.integer )
- return;
-
- if( !cg_drawCrosshairNames.integer )
- return;
-
- if( cg.renderingThirdPerson )
- return;
-
- // scan the known entities to see if the crosshair is sighted on one
- CG_ScanForCrosshairEntity( );
-
- // draw the name of the player being looked at
- color = CG_FadeColor( cg.crosshairClientTime, 1000 );
- if( !color )
- {
- trap_R_SetColor( NULL );
- return;
- }
-
- name = cgs.clientinfo[ cg.crosshairClientNum ].name;
- w = CG_Text_Width( name, scale, 0 );
- x = rect->x + rect->w / 2;
- CG_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle );
- trap_R_SetColor( NULL );
-}
-
-
-/*
-===============
-CG_OwnerDraw
-
-Draw an owner drawn item
-===============
-*/
-void CG_OwnerDraw( float x, float y, float w, float h, float text_x,
- float text_y, int ownerDraw, int ownerDrawFlags,
- int align, float special, float scale, vec4_t color,
- qhandle_t shader, int textStyle )
-{
- rectDef_t rect;
-
- if( cg_drawStatus.integer == 0 )
- return;
-
- rect.x = x;
- rect.y = y;
- rect.w = w;
- rect.h = h;
-
- switch( ownerDraw )
- {
- case CG_PLAYER_CREDITS_VALUE:
- CG_DrawPlayerCreditsValue( &rect, color, qtrue );
- break;
- case CG_PLAYER_BANK_VALUE:
- CG_DrawPlayerBankValue( &rect, color, qtrue );
- break;
- case CG_PLAYER_CREDITS_VALUE_NOPAD:
- CG_DrawPlayerCreditsValue( &rect, color, qfalse );
- break;
- case CG_PLAYER_BANK_VALUE_NOPAD:
- CG_DrawPlayerBankValue( &rect, color, qfalse );
- break;
- case CG_PLAYER_STAMINA:
- CG_DrawPlayerStamina( &rect, color, scale, align, textStyle, special );
- break;
- case CG_PLAYER_STAMINA_1:
- CG_DrawPlayerStamina1( &rect, color, shader );
- break;
- case CG_PLAYER_STAMINA_2:
- CG_DrawPlayerStamina2( &rect, color, shader );
- break;
- case CG_PLAYER_STAMINA_3:
- CG_DrawPlayerStamina3( &rect, color, shader );
- break;
- case CG_PLAYER_STAMINA_4:
- CG_DrawPlayerStamina4( &rect, color, shader );
- break;
- case CG_PLAYER_STAMINA_BOLT:
- CG_DrawPlayerStaminaBolt( &rect, color, shader );
- break;
- case CG_PLAYER_AMMO_VALUE:
- CG_DrawPlayerAmmoValue( &rect, color );
- break;
- case CG_PLAYER_CLIPS_VALUE:
- CG_DrawPlayerClipsValue( &rect, color );
- break;
- case CG_PLAYER_BUILD_TIMER:
- CG_DrawPlayerBuildTimer( &rect, color );
- break;
- case CG_PLAYER_HEALTH:
- CG_DrawPlayerHealthValue( &rect, color );
- break;
- case CG_PLAYER_HEALTH_BAR:
- CG_DrawPlayerHealthBar( &rect, color, scale, align, textStyle, special );
- break;
- case CG_PLAYER_HEALTH_CROSS:
- CG_DrawPlayerHealthCross( &rect, color, shader );
- break;
- case CG_PLAYER_CLIPS_RING:
- CG_DrawPlayerClipsRing( &rect, color, shader );
- break;
- case CG_PLAYER_BUILD_TIMER_RING:
- CG_DrawPlayerBuildTimerRing( &rect, color, shader );
- break;
- case CG_PLAYER_WALLCLIMBING:
- CG_DrawPlayerWallclimbing( &rect, color, shader );
- break;
- case CG_PLAYER_BOOSTED:
- CG_DrawPlayerBoosted( &rect, color, shader );
- break;
- case CG_PLAYER_BOOST_BOLT:
- CG_DrawPlayerBoosterBolt( &rect, color, shader );
- break;
- case CG_PLAYER_POISON_BARBS:
- CG_DrawPlayerPoisonBarbs( &rect, color, shader );
- break;
- case CG_PLAYER_ALIEN_SENSE:
- CG_DrawAlienSense( &rect );
- break;
- case CG_PLAYER_HUMAN_SCANNER:
- CG_DrawHumanScanner( &rect, shader, color );
- break;
- case CG_PLAYER_USABLE_BUILDABLE:
- CG_DrawUsableBuildable( &rect, shader, color );
- break;
- case CG_AREA_SYSTEMCHAT:
- CG_DrawAreaSystemChat( &rect, scale, color, shader );
- break;
- case CG_AREA_TEAMCHAT:
- CG_DrawAreaTeamChat( &rect, scale, color, shader );
- break;
- case CG_AREA_CHAT:
- CG_DrawAreaChat( &rect, scale, color, shader );
- break;
- case CG_KILLER:
- CG_DrawKiller( &rect, scale, color, shader, textStyle );
- break;
- case CG_PLAYER_SELECT:
- CG_DrawItemSelect( &rect, color );
- break;
- case CG_PLAYER_WEAPONICON:
- CG_DrawWeaponIcon( &rect, color );
- break;
- case CG_PLAYER_SELECTTEXT:
- CG_DrawItemSelectText( &rect, scale, textStyle );
- break;
- case CG_SPECTATORS:
- CG_DrawTeamSpectators( &rect, scale, color, shader );
- break;
- case CG_PLAYER_CROSSHAIRNAMES:
- CG_DrawCrosshairNames( &rect, scale, textStyle );
- break;
- case CG_STAGE_REPORT_TEXT:
- CG_DrawStageReport( &rect, text_x, text_y, color, scale, align, textStyle );
- break;
-
- //loading screen
- case CG_LOAD_LEVELSHOT:
- CG_DrawLevelShot( &rect );
- break;
- case CG_LOAD_MEDIA:
- CG_DrawMediaProgress( &rect, color, scale, align, textStyle, special );
- break;
- case CG_LOAD_MEDIA_LABEL:
- CG_DrawMediaProgressLabel( &rect, text_x, text_y, color, scale, align );
- break;
- case CG_LOAD_BUILDABLES:
- CG_DrawBuildablesProgress( &rect, color, scale, align, textStyle, special );
- break;
- case CG_LOAD_BUILDABLES_LABEL:
- CG_DrawBuildablesProgressLabel( &rect, text_x, text_y, color, scale, align );
- break;
- case CG_LOAD_CHARMODEL:
- CG_DrawCharModelProgress( &rect, color, scale, align, textStyle, special );
- break;
- case CG_LOAD_CHARMODEL_LABEL:
- CG_DrawCharModelProgressLabel( &rect, text_x, text_y, color, scale, align );
- break;
- case CG_LOAD_OVERALL:
- CG_DrawOverallProgress( &rect, color, scale, align, textStyle, special );
- break;
- case CG_LOAD_LEVELNAME:
- CG_DrawLevelName( &rect, text_x, text_y, color, scale, align, textStyle );
- break;
- case CG_LOAD_MOTD:
- CG_DrawMOTD( &rect, text_x, text_y, color, scale, align, textStyle );
- break;
- case CG_LOAD_HOSTNAME:
- CG_DrawHostname( &rect, text_x, text_y, color, scale, align, textStyle );
- break;
-
- case CG_FPS:
- CG_DrawFPS( &rect, text_x, text_y, scale, color, align, textStyle, qtrue );
- break;
- case CG_FPS_FIXED:
- CG_DrawFPS( &rect, text_x, text_y, scale, color, align, textStyle, qfalse );
- break;
- case CG_TIMER:
- CG_DrawTimer( &rect, text_x, text_y, scale, color, align, textStyle );
- break;
- case CG_TIMER_MINS:
- CG_DrawTimerMins( &rect, color );
- break;
- case CG_TIMER_SECS:
- CG_DrawTimerSecs( &rect, color );
- break;
- case CG_SNAPSHOT:
- CG_DrawSnapshot( &rect, text_x, text_y, scale, color, align, textStyle );
- break;
- case CG_LAGOMETER:
- CG_DrawLagometer( &rect, text_x, text_y, scale, color );
- break;
-
- case CG_CONSOLE:
- CG_DrawConsole( &rect, text_x, text_y, color, scale, align, textStyle );
- break;
-
- default:
- break;
- }
-}
-
-void CG_MouseEvent( int x, int y )
-{
- int n;
-
- if( ( cg.predictedPlayerState.pm_type == PM_NORMAL ||
- cg.predictedPlayerState.pm_type == PM_SPECTATOR ) &&
- cg.showScores == qfalse )
- {
- trap_Key_SetCatcher( 0 );
- return;
- }
-
- cgs.cursorX += x;
- if( cgs.cursorX < 0 )
- cgs.cursorX = 0;
- else if( cgs.cursorX > 640 )
- cgs.cursorX = 640;
-
- cgs.cursorY += y;
- if( cgs.cursorY < 0 )
- cgs.cursorY = 0;
- else if( cgs.cursorY > 480 )
- cgs.cursorY = 480;
-
- n = Display_CursorType( cgs.cursorX, cgs.cursorY );
- cgs.activeCursor = 0;
- if( n == CURSOR_ARROW )
- cgs.activeCursor = cgs.media.selectCursor;
- else if( n == CURSOR_SIZER )
- cgs.activeCursor = cgs.media.sizeCursor;
-
- if( cgs.capturedItem )
- Display_MouseMove( cgs.capturedItem, x, y );
- else
- Display_MouseMove( NULL, cgs.cursorX, cgs.cursorY );
-}
-
-/*
-==================
-CG_HideTeamMenus
-==================
-
-*/
-void CG_HideTeamMenu( )
-{
- Menus_CloseByName( "teamMenu" );
- Menus_CloseByName( "getMenu" );
-}
-
-/*
-==================
-CG_ShowTeamMenus
-==================
-
-*/
-void CG_ShowTeamMenu( )
-{
- Menus_OpenByName( "teamMenu" );
-}
-
-/*
-==================
-CG_EventHandling
-==================
- type 0 - no event handling
- 1 - team menu
- 2 - hud editor
-
-*/
-void CG_EventHandling( int type )
-{
- cgs.eventHandling = type;
-
- if( type == CGAME_EVENT_NONE )
- CG_HideTeamMenu( );
-}
-
-
-
-void CG_KeyEvent( int key, qboolean down )
-{
- if( !down )
- return;
-
- if( cg.predictedPlayerState.pm_type == PM_NORMAL ||
- ( cg.predictedPlayerState.pm_type == PM_SPECTATOR &&
- cg.showScores == qfalse ) )
- {
- CG_EventHandling( CGAME_EVENT_NONE );
- trap_Key_SetCatcher( 0 );
- return;
- }
-
- Display_HandleKey( key, down, cgs.cursorX, cgs.cursorY );
-
- if( cgs.capturedItem )
- cgs.capturedItem = NULL;
- else
- {
- if( key == K_MOUSE2 && down )
- cgs.capturedItem = Display_CaptureItem( cgs.cursorX, cgs.cursorY );
- }
-}
-
-int CG_ClientNumFromName( const char *p )
-{
- int i;
-
- for( i = 0; i < cgs.maxclients; i++ )
- {
- if( cgs.clientinfo[ i ].infoValid &&
- Q_stricmp( cgs.clientinfo[ i ].name, p ) == 0 )
- return i;
- }
-
- return -1;
-}
-
-void CG_RunMenuScript( char **args )
-{
-}
-
-
-void CG_GetTeamColor( vec4_t *color )
-{
- (*color)[ 0 ] = (*color)[ 2 ] = 0.0f;
- (*color)[ 1 ] = 0.17f;
- (*color)[ 3 ] = 0.25f;
-}
-//END TA UI
-
-
-/*
-================
-CG_DrawLighting
-
-================
-*/
-static void CG_DrawLighting( void )
-{
- centity_t *cent;
-
- cent = &cg_entities[ cg.snap->ps.clientNum ];
-
- //fade to black if stamina is low
- if( ( cg.snap->ps.stats[ STAT_STAMINA ] < -800 ) &&
- ( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) )
- {
- vec4_t black = { 0, 0, 0, 0 };
- black[ 3 ] = 1.0 - ( (float)( cg.snap->ps.stats[ STAT_STAMINA ] + 1000 ) / 200.0f );
- trap_R_SetColor( black );
- CG_DrawPic( 0, 0, 640, 480, cgs.media.whiteShader );
- trap_R_SetColor( NULL );
- }
-}
-
-/*
-===============================================================================
-
-CENTER PRINTING
-
-===============================================================================
-*/
-
-
-/*
-==============
-CG_CenterPrint
-
-Called for important messages that should stay in the center of the screen
-for a few moments
-==============
-*/
-void CG_CenterPrint( const char *str, int y, int charWidth )
-{
- char *s;
-
- Q_strncpyz( cg.centerPrint, str, sizeof( cg.centerPrint ) );
-
- cg.centerPrintTime = cg.time;
- cg.centerPrintY = y;
- cg.centerPrintCharWidth = charWidth;
-
- // count the number of lines for centering
- cg.centerPrintLines = 1;
- s = cg.centerPrint;
- while( *s )
- {
- if( *s == '\n' )
- cg.centerPrintLines++;
-
- s++;
- }
-}
-
-
-/*
-===================
-CG_DrawCenterString
-===================
-*/
-static void CG_DrawCenterString( void )
-{
- char *start;
- int l;
- int x, y, w;
- int h;
- float *color;
-
- if( !cg.centerPrintTime )
- return;
-
- color = CG_FadeColor( cg.centerPrintTime, 1000 * cg_centertime.value );
- if( !color )
- return;
-
- trap_R_SetColor( color );
-
- start = cg.centerPrint;
-
- y = cg.centerPrintY - cg.centerPrintLines * BIGCHAR_HEIGHT / 2;
-
- while( 1 )
- {
- char linebuffer[ 1024 ];
-
- for( l = 0; l < 50; l++ )
- {
- if( !start[ l ] || start[ l ] == '\n' )
- break;
-
- linebuffer[ l ] = start[ l ];
- }
-
- linebuffer[ l ] = 0;
-
- w = CG_Text_Width( linebuffer, 0.5, 0 );
- h = CG_Text_Height( linebuffer, 0.5, 0 );
- x = ( SCREEN_WIDTH - w ) / 2;
- CG_Text_Paint( x, y + h, 0.5, color, linebuffer, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE );
- y += h + 6;
-
- while( *start && ( *start != '\n' ) )
- start++;
-
- if( !*start )
- break;
-
- start++;
- }
-
- trap_R_SetColor( NULL );
-}
-
-
-
-
-
-//==============================================================================
-
-//FIXME: both vote notes are hardcoded, change to ownerdrawn?
-
-/*
-=================
-CG_DrawVote
-=================
-*/
-static void CG_DrawVote( void )
-{
- char *s;
- int sec;
- vec4_t white = { 1.0f, 1.0f, 1.0f, 1.0f };
-
- if( !cgs.voteTime )
- return;
-
- // play a talk beep whenever it is modified
- if( cgs.voteModified )
- {
- cgs.voteModified = qfalse;
- trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
- }
-
- sec = ( VOTE_TIME - ( cg.time - cgs.voteTime ) ) / 1000;
-
- if( sec < 0 )
- sec = 0;
-
- s = va( "VOTE(%i): \"%s\" Yes:%i No:%i", sec, cgs.voteString, cgs.voteYes, cgs.voteNo );
- CG_Text_Paint( 8, 340, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL );
-}
-
-/*
-=================
-CG_DrawTeamVote
-=================
-*/
-static void CG_DrawTeamVote( void )
-{
- char *s;
- int sec, cs_offset;
- vec4_t white = { 1.0f, 1.0f, 1.0f, 1.0f };
-
- if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS )
- cs_offset = 0;
- else if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS )
- cs_offset = 1;
- else
- return;
-
- if( !cgs.teamVoteTime[ cs_offset ] )
- return;
-
- // play a talk beep whenever it is modified
- if ( cgs.teamVoteModified[ cs_offset ] )
- {
- cgs.teamVoteModified[ cs_offset ] = qfalse;
- trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
- }
-
- sec = ( VOTE_TIME - ( cg.time - cgs.teamVoteTime[ cs_offset ] ) ) / 1000;
-
- if( sec < 0 )
- sec = 0;
-
- s = va( "TEAMVOTE(%i): \"%s\" Yes:%i No:%i", sec, cgs.teamVoteString[ cs_offset ],
- cgs.teamVoteYes[cs_offset], cgs.teamVoteNo[ cs_offset ] );
-
- CG_Text_Paint( 8, 360, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL );
-}
-
-
-static qboolean CG_DrawScoreboard( void )
-{
- static qboolean firstTime = qtrue;
- float fade, *fadeColor;
-
- if( menuScoreboard )
- menuScoreboard->window.flags &= ~WINDOW_FORCED;
-
- if( cg_paused.integer )
- {
- cg.deferredPlayerLoading = 0;
- firstTime = qtrue;
- return qfalse;
- }
-
- if( cg.showScores ||
- cg.predictedPlayerState.pm_type == PM_INTERMISSION )
- {
- fade = 1.0;
- fadeColor = colorWhite;
- }
- else
- {
- cg.deferredPlayerLoading = 0;
- cg.killerName[ 0 ] = 0;
- firstTime = qtrue;
- return qfalse;
- }
-
-
- if( menuScoreboard == NULL )
- menuScoreboard = Menus_FindByName( "teamscore_menu" );
-
- if( menuScoreboard )
- {
- if( firstTime )
- {
- CG_SetScoreSelection( menuScoreboard );
- firstTime = qfalse;
- }
-
- Menu_Paint( menuScoreboard, qtrue );
- }
-
- return qtrue;
-}
-
-/*
-=================
-CG_DrawIntermission
-=================
-*/
-static void CG_DrawIntermission( void )
-{
- if( cg_drawStatus.integer )
- Menu_Paint( Menus_FindByName( "default_hud" ), qtrue );
-
- cg.scoreFadeTime = cg.time;
- cg.scoreBoardShowing = CG_DrawScoreboard( );
-}
-
-#define FOLLOWING_STRING "following "
-
-/*
-=================
-CG_DrawFollow
-=================
-*/
-static qboolean CG_DrawFollow( void )
-{
- float w;
- vec4_t color;
- char buffer[ MAX_STRING_CHARS ];
-
- if( !( cg.snap->ps.pm_flags & PMF_FOLLOW ) )
- return qfalse;
-
- color[ 0 ] = 1;
- color[ 1 ] = 1;
- color[ 2 ] = 1;
- color[ 3 ] = 1;
-
- strcpy( buffer, FOLLOWING_STRING );
- strcat( buffer, cgs.clientinfo[ cg.snap->ps.clientNum ].name );
-
- w = CG_Text_Width( buffer, 0.7f, 0 );
- CG_Text_Paint( 320 - w / 2, 400, 0.7f, color, buffer, 0, 0, ITEM_TEXTSTYLE_SHADOWED );
-
- return qtrue;
-}
-
-/*
-=================
-CG_DrawQueue
-=================
-*/
-static qboolean CG_DrawQueue( void )
-{
- float w;
- vec4_t color;
- char buffer[ MAX_STRING_CHARS ];
-
- if( !( cg.snap->ps.pm_flags & PMF_QUEUED ) )
- return qfalse;
-
- color[ 0 ] = 1;
- color[ 1 ] = 1;
- color[ 2 ] = 1;
- color[ 3 ] = 1;
-
- Com_sprintf( buffer, MAX_STRING_CHARS, "You are in position %d of the spawn queue.",
- cg.snap->ps.persistant[ PERS_QUEUEPOS ] + 1 );
-
- w = CG_Text_Width( buffer, 0.7f, 0 );
- CG_Text_Paint( 320 - w / 2, 360, 0.7f, color, buffer, 0, 0, ITEM_TEXTSTYLE_SHADOWED );
-
- if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
- {
- if( cgs.numAlienSpawns == 1 )
- Com_sprintf( buffer, MAX_STRING_CHARS, "There is 1 spawn remaining." );
- else
- Com_sprintf( buffer, MAX_STRING_CHARS, "There are %d spawns remaining.",
- cgs.numAlienSpawns );
- }
- else if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
- {
- if( cgs.numHumanSpawns == 1 )
- Com_sprintf( buffer, MAX_STRING_CHARS, "There is 1 spawn remaining." );
- else
- Com_sprintf( buffer, MAX_STRING_CHARS, "There are %d spawns remaining.",
- cgs.numHumanSpawns );
- }
-
- w = CG_Text_Width( buffer, 0.7f, 0 );
- CG_Text_Paint( 320 - w / 2, 400, 0.7f, color, buffer, 0, 0, ITEM_TEXTSTYLE_SHADOWED );
-
- return qtrue;
-}
-
-//==================================================================================
-
-#define SPECTATOR_STRING "SPECTATOR"
-/*
-=================
-CG_Draw2D
-=================
-*/
-static void CG_Draw2D( void )
-{
- vec4_t color;
- float w;
- menuDef_t *menu = NULL, *defaultMenu;
-
- color[ 0 ] = color[ 1 ] = color[ 2 ] = color[ 3 ] = 1.0f;
-
- // if we are taking a levelshot for the menu, don't draw anything
- if( cg.levelShot )
- return;
-
- if( cg_draw2D.integer == 0 )
- return;
-
- if( cg.snap->ps.pm_type == PM_INTERMISSION )
- {
- CG_DrawIntermission( );
- return;
- }
-
- //TA: draw the lighting effects e.g. nvg
- CG_DrawLighting( );
-
-
- defaultMenu = Menus_FindByName( "default_hud" );
-
- if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
- {
- w = CG_Text_Width( SPECTATOR_STRING, 0.7f, 0 );
- CG_Text_Paint( 320 - w / 2, 440, 0.7f, color, SPECTATOR_STRING, 0, 0, ITEM_TEXTSTYLE_SHADOWED );
- }
- else
- menu = Menus_FindByName( BG_FindHudNameForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] ) );
-
- if( !( cg.snap->ps.stats[ STAT_STATE ] & SS_INFESTING ) &&
- !( cg.snap->ps.stats[ STAT_STATE ] & SS_HOVELING ) && menu &&
- ( cg.snap->ps.stats[ STAT_HEALTH ] > 0 ) )
- {
- if( cg_drawStatus.integer )
- Menu_Paint( menu, qtrue );
-
- CG_DrawCrosshair( );
- }
- else if( cg_drawStatus.integer )
- Menu_Paint( defaultMenu, qtrue );
-
- CG_DrawVote( );
- CG_DrawTeamVote( );
- CG_DrawFollow( );
- CG_DrawQueue( );
-
- // don't draw center string if scoreboard is up
- cg.scoreBoardShowing = CG_DrawScoreboard( );
-
- if( !cg.scoreBoardShowing )
- CG_DrawCenterString( );
-}
-
-#define PAINBLEND_BORDER_W 0.15f
-#define PAINBLEND_BORDER_H 0.07f
-
-/*
-===============
-CG_PainBlend
-===============
-*/
-static void CG_PainBlend( void )
-{
- vec4_t color;
- int damage;
- float damageAsFracOfMax;
- qhandle_t shader = cgs.media.viewBloodShader;
- float x, y, w, h;
-
- damage = cg.lastHealth - cg.snap->ps.stats[ STAT_HEALTH ];
-
- if( damage < 0 )
- damage = 0;
-
- damageAsFracOfMax = (float)damage / cg.snap->ps.stats[ STAT_MAX_HEALTH ];
- cg.lastHealth = cg.snap->ps.stats[ STAT_HEALTH ];
-
- cg.painBlendValue += damageAsFracOfMax * cg_painBlendScale.value;
-
- if( cg.painBlendValue > 0.0f )
- {
- cg.painBlendValue -= ( cg.frametime / 1000.0f ) *
- cg_painBlendDownRate.value;
- }
-
- if( cg.painBlendValue > 1.0f )
- cg.painBlendValue = 1.0f;
- else if( cg.painBlendValue <= 0.0f )
- {
- cg.painBlendValue = 0.0f;
- return;
- }
-
- if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
- VectorSet( color, 0.43f, 0.8f, 0.37f );
- else if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
- VectorSet( color, 0.8f, 0.0f, 0.0f );
-
- if( cg.painBlendValue > cg.painBlendTarget )
- {
- cg.painBlendTarget += ( cg.frametime / 1000.0f ) *
- cg_painBlendUpRate.value;
- }
- else if( cg.painBlendValue < cg.painBlendTarget )
- cg.painBlendTarget = cg.painBlendValue;
-
- if( cg.painBlendTarget > cg_painBlendMax.value )
- cg.painBlendTarget = cg_painBlendMax.value;
-
- color[ 3 ] = cg.painBlendTarget;
-
- trap_R_SetColor( color );
-
- //left
- x = 0.0f; y = 0.0f;
- w = PAINBLEND_BORDER_W * 640.0f; h = 480.0f;
- CG_AdjustFrom640( &x, &y, &w, &h );
- trap_R_DrawStretchPic( x, y, w, h,
- cg_painBlendZoom.value, cg_painBlendZoom.value,
- cg_painBlendZoom.value + PAINBLEND_BORDER_W, 1.0f - cg_painBlendZoom.value,
- shader );
-
- //right
- x = 640.0f - ( PAINBLEND_BORDER_W * 640.0f ); y = 0.0f;
- w = PAINBLEND_BORDER_W * 640.0f; h = 480.0f;
- CG_AdjustFrom640( &x, &y, &w, &h );
- trap_R_DrawStretchPic( x, y, w, h,
- 1.0f - cg_painBlendZoom.value - PAINBLEND_BORDER_W, cg_painBlendZoom.value,
- 1.0f - cg_painBlendZoom.value, 1.0f - cg_painBlendZoom.value,
- shader );
-
- //top
- x = PAINBLEND_BORDER_W * 640.0f; y = 0.0f;
- w = 640.0f - ( 2 * PAINBLEND_BORDER_W * 640.0f ); h = PAINBLEND_BORDER_H * 480.0f;
- CG_AdjustFrom640( &x, &y, &w, &h );
- trap_R_DrawStretchPic( x, y, w, h,
- cg_painBlendZoom.value + PAINBLEND_BORDER_W, cg_painBlendZoom.value,
- 1.0f - cg_painBlendZoom.value - PAINBLEND_BORDER_W, cg_painBlendZoom.value + PAINBLEND_BORDER_H,
- shader );
-
- //bottom
- x = PAINBLEND_BORDER_W * 640.0f; y = 480.0f - ( PAINBLEND_BORDER_H * 480.0f );
- w = 640.0f - ( 2 * PAINBLEND_BORDER_W * 640.0f ); h = PAINBLEND_BORDER_H * 480.0f;
- CG_AdjustFrom640( &x, &y, &w, &h );
- trap_R_DrawStretchPic( x, y, w, h,
- cg_painBlendZoom.value + PAINBLEND_BORDER_W, 1.0f - cg_painBlendZoom.value - PAINBLEND_BORDER_H,
- 1.0f - cg_painBlendZoom.value - PAINBLEND_BORDER_W, 1.0f - cg_painBlendZoom.value,
- shader );
-
- trap_R_SetColor( NULL );
-}
-
-/*
-=====================
-CG_ResetPainBlend
-=====================
-*/
-void CG_ResetPainBlend( void )
-{
- cg.painBlendValue = 0.0f;
- cg.painBlendTarget = 0.0f;
- cg.lastHealth = cg.snap->ps.stats[ STAT_MAX_HEALTH ];
-}
-
-/*
-=====================
-CG_DrawActive
-
-Perform all drawing needed to completely fill the screen
-=====================
-*/
-void CG_DrawActive( stereoFrame_t stereoView )
-{
- float separation;
- vec3_t baseOrg;
-
- // optionally draw the info screen instead
- if( !cg.snap )
- return;
-
- switch ( stereoView )
- {
- case STEREO_CENTER:
- separation = 0;
- break;
- case STEREO_LEFT:
- separation = -cg_stereoSeparation.value / 2;
- break;
- case STEREO_RIGHT:
- separation = cg_stereoSeparation.value / 2;
- break;
- default:
- separation = 0;
- CG_Error( "CG_DrawActive: Undefined stereoView" );
- }
-
- // clear around the rendered view if sized down
- CG_TileClear( );
-
- // offset vieworg appropriately if we're doing stereo separation
- VectorCopy( cg.refdef.vieworg, baseOrg );
-
- if( separation != 0 )
- VectorMA( cg.refdef.vieworg, -separation, cg.refdef.viewaxis[ 1 ],
- cg.refdef.vieworg );
-
- // draw 3D view
- trap_R_RenderScene( &cg.refdef );
-
- // restore original viewpoint if running stereo
- if( separation != 0 )
- VectorCopy( baseOrg, cg.refdef.vieworg );
-
- // first person blend blobs, done after AnglesToAxis
- if( !cg.renderingThirdPerson )
- CG_PainBlend( );
-
- // draw status bar and other floating elements
- CG_Draw2D( );
-}
-
-
diff --git a/src/cgame/cg_drawtools.c b/src/cgame/cg_drawtools.c
deleted file mode 100644
index b1f0d9ab..00000000
--- a/src/cgame/cg_drawtools.c
+++ /dev/null
@@ -1,308 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_drawtools.c -- helper functions called by cg_draw, cg_scoreboard, cg_info, etc
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-/*
-===============
-CG_DrawPlane
-
-Draw a quad in 3 space - basically CG_DrawPic in 3 space
-===============
-*/
-void CG_DrawPlane( vec3_t origin, vec3_t down, vec3_t right, qhandle_t shader )
-{
- polyVert_t verts[ 4 ];
- vec3_t temp;
-
- VectorCopy( origin, 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;
-
- VectorAdd( origin, right, temp );
- VectorCopy( temp, verts[ 1 ].xyz );
- verts[ 1 ].st[ 0 ] = 1;
- verts[ 1 ].st[ 1 ] = 0;
- verts[ 1 ].modulate[ 0 ] = 255;
- verts[ 1 ].modulate[ 1 ] = 255;
- verts[ 1 ].modulate[ 2 ] = 255;
- verts[ 1 ].modulate[ 3 ] = 255;
-
- VectorAdd( origin, right, temp );
- VectorAdd( temp, down, temp );
- VectorCopy( temp, 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;
-
- VectorAdd( origin, down, temp );
- VectorCopy( temp, verts[ 3 ].xyz );
- verts[ 3 ].st[ 0 ] = 0;
- verts[ 3 ].st[ 1 ] = 1;
- verts[ 3 ].modulate[ 0 ] = 255;
- verts[ 3 ].modulate[ 1 ] = 255;
- verts[ 3 ].modulate[ 2 ] = 255;
- verts[ 3 ].modulate[ 3 ] = 255;
-
- trap_R_AddPolyToScene( shader, 4, verts );
-}
-
-/*
-================
-CG_AdjustFrom640
-
-Adjusted for resolution and screen aspect ratio
-================
-*/
-void CG_AdjustFrom640( float *x, float *y, float *w, float *h )
-{
-#if 0
- // adjust for wide screens
- if ( cgs.glconfig.vidWidth * 480 > cgs.glconfig.vidHeight * 640 ) {
- *x += 0.5 * ( cgs.glconfig.vidWidth - ( cgs.glconfig.vidHeight * 640 / 480 ) );
- }
-#endif
- // scale for screen sizes
- *x *= cgs.screenXScale;
- *y *= cgs.screenYScale;
- *w *= cgs.screenXScale;
- *h *= cgs.screenYScale;
-}
-
-/*
-================
-CG_FillRect
-
-Coordinates are 640*480 virtual values
-=================
-*/
-void CG_FillRect( float x, float y, float width, float height, const float *color )
-{
- trap_R_SetColor( color );
-
- CG_AdjustFrom640( &x, &y, &width, &height );
- trap_R_DrawStretchPic( x, y, width, height, 0, 0, 0, 0, cgs.media.whiteShader );
-
- trap_R_SetColor( NULL );
-}
-
-
-/*
-================
-CG_DrawSides
-
-Coords are virtual 640x480
-================
-*/
-void CG_DrawSides( float x, float y, float w, float h, float size )
-{
- CG_AdjustFrom640( &x, &y, &w, &h );
- size *= cgs.screenXScale;
- trap_R_DrawStretchPic( x, y, size, h, 0, 0, 0, 0, cgs.media.whiteShader );
- trap_R_DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, cgs.media.whiteShader );
-}
-
-void CG_DrawTopBottom( float x, float y, float w, float h, float size )
-{
- CG_AdjustFrom640( &x, &y, &w, &h );
- size *= cgs.screenYScale;
- trap_R_DrawStretchPic( x, y, w, size, 0, 0, 0, 0, cgs.media.whiteShader );
- trap_R_DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, cgs.media.whiteShader );
-}
-
-
-/*
-================
-CG_DrawRect
-
-Coordinates are 640*480 virtual values
-=================
-*/
-void CG_DrawRect( float x, float y, float width, float height, float size, const float *color )
-{
- trap_R_SetColor( color );
-
- CG_DrawTopBottom( x, y, width, height, size );
- CG_DrawSides( x, y, width, height, size );
-
- trap_R_SetColor( NULL );
-}
-
-
-/*
-================
-CG_DrawPic
-
-Coordinates are 640*480 virtual values
-=================
-*/
-void CG_DrawPic( float x, float y, float width, float height, qhandle_t hShader )
-{
- CG_AdjustFrom640( &x, &y, &width, &height );
- trap_R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, hShader );
-}
-
-
-
-/*
-================
-CG_DrawFadePic
-
-Coordinates are 640*480 virtual values
-=================
-*/
-void CG_DrawFadePic( float x, float y, float width, float height, vec4_t fcolor,
- vec4_t tcolor, float amount, qhandle_t hShader )
-{
- vec4_t finalcolor;
- float inverse;
-
- inverse = 100 - amount;
-
- CG_AdjustFrom640( &x, &y, &width, &height );
-
- finalcolor[ 0 ] = ( ( inverse * fcolor[ 0 ] ) + ( amount * tcolor[ 0 ] ) ) / 100;
- finalcolor[ 1 ] = ( ( inverse * fcolor[ 1 ] ) + ( amount * tcolor[ 1 ] ) ) / 100;
- finalcolor[ 2 ] = ( ( inverse * fcolor[ 2 ] ) + ( amount * tcolor[ 2 ] ) ) / 100;
- finalcolor[ 3 ] = ( ( inverse * fcolor[ 3 ] ) + ( amount * tcolor[ 3 ] ) ) / 100;
-
- trap_R_SetColor( finalcolor );
- trap_R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, hShader );
- trap_R_SetColor( NULL );
-}
-
-/*
-=================
-CG_DrawStrlen
-
-Returns character count, skiping color escape codes
-=================
-*/
-int CG_DrawStrlen( const char *str )
-{
- const char *s = str;
- int count = 0;
-
- while( *s )
- {
- if( Q_IsColorString( s ) )
- s += 2;
- else
- {
- count++;
- s++;
- }
- }
-
- return count;
-}
-
-/*
-=============
-CG_TileClearBox
-
-This repeats a 64*64 tile graphic to fill the screen around a sized down
-refresh window.
-=============
-*/
-static void CG_TileClearBox( int x, int y, int w, int h, qhandle_t hShader )
-{
- float s1, t1, s2, t2;
-
- s1 = x / 64.0;
- t1 = y / 64.0;
- s2 = ( x + w ) / 64.0;
- t2 = ( y + h ) / 64.0;
- trap_R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, hShader );
-}
-
-
-
-/*
-==============
-CG_TileClear
-
-Clear around a sized down screen
-==============
-*/
-void CG_TileClear( void )
-{
- int top, bottom, left, right;
- int w, h;
-
- w = cgs.glconfig.vidWidth;
- h = cgs.glconfig.vidHeight;
-
- if( cg.refdef.x == 0 && cg.refdef.y == 0 &&
- cg.refdef.width == w && cg.refdef.height == h )
- return; // full screen rendering
-
- top = cg.refdef.y;
- bottom = top + cg.refdef.height - 1;
- left = cg.refdef.x;
- right = left + cg.refdef.width - 1;
-
- // clear above view screen
- CG_TileClearBox( 0, 0, w, top, cgs.media.backTileShader );
-
- // clear below view screen
- CG_TileClearBox( 0, bottom, w, h - bottom, cgs.media.backTileShader );
-
- // clear left of view screen
- CG_TileClearBox( 0, top, left, bottom - top + 1, cgs.media.backTileShader );
-
- // clear right of view screen
- CG_TileClearBox( right, top, w - right, bottom - top + 1, cgs.media.backTileShader );
-}
-
-
-
-/*
-================
-CG_FadeColor
-================
-*/
-float *CG_FadeColor( int startMsec, int totalMsec )
-{
- static vec4_t color;
- int t;
-
- if( startMsec == 0 )
- return NULL;
-
- t = cg.time - startMsec;
-
- if( t >= totalMsec )
- return NULL;
-
- // fade out
- if( totalMsec - t < FADE_TIME )
- color[ 3 ] = ( totalMsec - t ) * 1.0 / FADE_TIME;
- else
- color[ 3 ] = 1.0;
-
- color[ 0 ] = color[ 1 ] = color[ 2 ] = 1;
-
- return color;
-}
diff --git a/src/cgame/cg_ents.c b/src/cgame/cg_ents.c
deleted file mode 100644
index b622d2f3..00000000
--- a/src/cgame/cg_ents.c
+++ /dev/null
@@ -1,1225 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_ents.c -- present snapshot entities, happens every single frame
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-/*
-======================
-CG_DrawBoxFace
-
-Draws a bounding box face
-======================
-*/
-static void CG_DrawBoxFace( vec3_t a, vec3_t b, vec3_t c, vec3_t d )
-{
- polyVert_t verts[ 4 ];
- vec4_t color = { 255.0f, 0.0f, 0.0f, 128.0f };
-
- VectorCopy( d, verts[ 0 ].xyz );
- verts[ 0 ].st[ 0 ] = 1;
- verts[ 0 ].st[ 1 ] = 1;
- Vector4Copy( color, verts[ 0 ].modulate );
-
- VectorCopy( c, verts[ 1 ].xyz );
- verts[ 1 ].st[ 0 ] = 1;
- verts[ 1 ].st[ 1 ] = 0;
- Vector4Copy( color, verts[ 1 ].modulate );
-
- VectorCopy( b, verts[ 2 ].xyz );
- verts[ 2 ].st[ 0 ] = 0;
- verts[ 2 ].st[ 1 ] = 0;
- Vector4Copy( color, verts[ 2 ].modulate );
-
- VectorCopy( a, verts[ 3 ].xyz );
- verts[ 3 ].st[ 0 ] = 0;
- verts[ 3 ].st[ 1 ] = 1;
- Vector4Copy( color, verts[ 3 ].modulate );
-
- trap_R_AddPolyToScene( cgs.media.outlineShader, 4, verts );
-}
-
-/*
-======================
-CG_DrawBoundingBox
-
-Draws a bounding box
-======================
-*/
-void CG_DrawBoundingBox( vec3_t origin, vec3_t mins, vec3_t maxs )
-{
- vec3_t ppp, mpp, mmp, pmp;
- vec3_t mmm, pmm, ppm, mpm;
-
- ppp[ 0 ] = origin[ 0 ] + maxs[ 0 ];
- ppp[ 1 ] = origin[ 1 ] + maxs[ 1 ];
- ppp[ 2 ] = origin[ 2 ] + maxs[ 2 ];
-
- mpp[ 0 ] = origin[ 0 ] + mins[ 0 ];
- mpp[ 1 ] = origin[ 1 ] + maxs[ 1 ];
- mpp[ 2 ] = origin[ 2 ] + maxs[ 2 ];
-
- mmp[ 0 ] = origin[ 0 ] + mins[ 0 ];
- mmp[ 1 ] = origin[ 1 ] + mins[ 1 ];
- mmp[ 2 ] = origin[ 2 ] + maxs[ 2 ];
-
- pmp[ 0 ] = origin[ 0 ] + maxs[ 0 ];
- pmp[ 1 ] = origin[ 1 ] + mins[ 1 ];
- pmp[ 2 ] = origin[ 2 ] + maxs[ 2 ];
-
- ppm[ 0 ] = origin[ 0 ] + maxs[ 0 ];
- ppm[ 1 ] = origin[ 1 ] + maxs[ 1 ];
- ppm[ 2 ] = origin[ 2 ] + mins[ 2 ];
-
- mpm[ 0 ] = origin[ 0 ] + mins[ 0 ];
- mpm[ 1 ] = origin[ 1 ] + maxs[ 1 ];
- mpm[ 2 ] = origin[ 2 ] + mins[ 2 ];
-
- mmm[ 0 ] = origin[ 0 ] + mins[ 0 ];
- mmm[ 1 ] = origin[ 1 ] + mins[ 1 ];
- mmm[ 2 ] = origin[ 2 ] + mins[ 2 ];
-
- pmm[ 0 ] = origin[ 0 ] + maxs[ 0 ];
- pmm[ 1 ] = origin[ 1 ] + mins[ 1 ];
- pmm[ 2 ] = origin[ 2 ] + mins[ 2 ];
-
- //phew!
-
- CG_DrawBoxFace( ppp, mpp, mmp, pmp );
- CG_DrawBoxFace( ppp, pmp, pmm, ppm );
- CG_DrawBoxFace( mpp, ppp, ppm, mpm );
- CG_DrawBoxFace( mmp, mpp, mpm, mmm );
- CG_DrawBoxFace( pmp, mmp, mmm, pmm );
- CG_DrawBoxFace( mmm, mpm, ppm, pmm );
-}
-
-
-/*
-======================
-CG_PositionEntityOnTag
-
-Modifies the entities position and axis by the given
-tag location
-======================
-*/
-void CG_PositionEntityOnTag( refEntity_t *entity, const refEntity_t *parent,
- qhandle_t parentModel, char *tagName )
-{
- int i;
- orientation_t lerped;
-
- // lerp the tag
- trap_R_LerpTag( &lerped, parentModel, parent->oldframe, parent->frame,
- 1.0 - parent->backlerp, tagName );
-
- // FIXME: allow origin offsets along tag?
- VectorCopy( parent->origin, entity->origin );
- for( i = 0; i < 3; i++ )
- VectorMA( entity->origin, lerped.origin[ i ], parent->axis[ i ], entity->origin );
-
- // had to cast away the const to avoid compiler problems...
- MatrixMultiply( lerped.axis, ( (refEntity_t *)parent )->axis, entity->axis );
- entity->backlerp = parent->backlerp;
-}
-
-
-/*
-======================
-CG_PositionRotatedEntityOnTag
-
-Modifies the entities position and axis by the given
-tag location
-======================
-*/
-void CG_PositionRotatedEntityOnTag( refEntity_t *entity, const refEntity_t *parent,
- qhandle_t parentModel, char *tagName )
-{
- int i;
- orientation_t lerped;
- vec3_t tempAxis[ 3 ];
-
-//AxisClear( entity->axis );
- // lerp the tag
- trap_R_LerpTag( &lerped, parentModel, parent->oldframe, parent->frame,
- 1.0 - parent->backlerp, tagName );
-
- // FIXME: allow origin offsets along tag?
- VectorCopy( parent->origin, entity->origin );
- for( i = 0; i < 3; i++ )
- VectorMA( entity->origin, lerped.origin[ i ], parent->axis[ i ], entity->origin );
-
- // had to cast away the const to avoid compiler problems...
- MatrixMultiply( entity->axis, lerped.axis, tempAxis );
- MatrixMultiply( tempAxis, ( (refEntity_t *)parent )->axis, entity->axis );
-}
-
-
-
-/*
-==========================================================================
-
-FUNCTIONS CALLED EACH FRAME
-
-==========================================================================
-*/
-
-/*
-======================
-CG_SetEntitySoundPosition
-
-Also called by event processing code
-======================
-*/
-void CG_SetEntitySoundPosition( centity_t *cent )
-{
- if( cent->currentState.solid == SOLID_BMODEL )
- {
- vec3_t origin;
- float *v;
-
- v = cgs.inlineModelMidpoints[ cent->currentState.modelindex ];
- VectorAdd( cent->lerpOrigin, v, origin );
- trap_S_UpdateEntityPosition( cent->currentState.number, origin );
- }
- else
- trap_S_UpdateEntityPosition( cent->currentState.number, cent->lerpOrigin );
-}
-
-/*
-==================
-CG_EntityEffects
-
-Add continuous entity effects, like local entity emission and lighting
-==================
-*/
-static void CG_EntityEffects( centity_t *cent )
-{
- // update sound origins
- CG_SetEntitySoundPosition( cent );
-
- // add loop sound
- if( cent->currentState.loopSound )
- {
- if( cent->currentState.eType != ET_SPEAKER )
- {
- trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin,
- cgs.gameSounds[ cent->currentState.loopSound ] );
- }
- else
- {
- trap_S_AddRealLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin,
- cgs.gameSounds[ cent->currentState.loopSound ] );
- }
- }
-
-
- // constant light glow
- if ( cent->currentState.constantLight )
- {
- int cl;
- int i, r, g, b;
-
- cl = cent->currentState.constantLight;
- r = cl & 255;
- g = ( cl >> 8 ) & 255;
- b = ( cl >> 16 ) & 255;
- i = ( ( cl >> 24 ) & 255 ) * 4;
- trap_R_AddLightToScene( cent->lerpOrigin, i, r, g, b );
- }
-
- if( cg.time > cent->muzzleTSDeathTime && CG_IsTrailSystemValid( &cent->muzzleTS ) )
- CG_DestroyTrailSystem( &cent->muzzleTS );
-}
-
-
-/*
-==================
-CG_General
-==================
-*/
-static void CG_General( centity_t *cent )
-{
- refEntity_t ent;
- entityState_t *s1;
-
- s1 = &cent->currentState;
-
- // if set to invisible, skip
- if( !s1->modelindex )
- return;
-
- memset( &ent, 0, sizeof( ent ) );
-
- // set frame
-
- ent.frame = s1->frame;
- ent.oldframe = ent.frame;
- ent.backlerp = 0;
-
- VectorCopy( cent->lerpOrigin, ent.origin);
- VectorCopy( cent->lerpOrigin, ent.oldorigin);
-
- ent.hModel = cgs.gameModels[ s1->modelindex ];
-
- // player model
- if( s1->number == cg.snap->ps.clientNum )
- ent.renderfx |= RF_THIRD_PERSON; // only draw from mirrors
-
- // convert angles to axis
- AnglesToAxis( cent->lerpAngles, ent.axis );
-
- // add to refresh list
- trap_R_AddRefEntityToScene( &ent );
-}
-
-/*
-==================
-CG_Speaker
-
-Speaker entities can automatically play sounds
-==================
-*/
-static void CG_Speaker( centity_t *cent )
-{
- if( ! cent->currentState.clientNum )
- { // FIXME: use something other than clientNum...
- return; // not auto triggering
- }
-
- if( cg.time < cent->miscTime )
- return;
-
- trap_S_StartSound( NULL, cent->currentState.number, CHAN_ITEM, cgs.gameSounds[ cent->currentState.eventParm ] );
-
- // ent->s.frame = ent->wait * 10;
- // ent->s.clientNum = ent->random * 10;
- cent->miscTime = cg.time + cent->currentState.frame * 100 + cent->currentState.clientNum * 100 * crandom( );
-}
-
-
-//============================================================================
-
-/*
-===============
-CG_LaunchMissile
-===============
-*/
-static void CG_LaunchMissile( centity_t *cent )
-{
- entityState_t *es;
- const weaponInfo_t *wi;
- particleSystem_t *ps;
- trailSystem_t *ts;
- weapon_t weapon;
- weaponMode_t weaponMode;
-
- es = &cent->currentState;
-
- weapon = es->weapon;
- if( weapon > WP_NUM_WEAPONS )
- weapon = WP_NONE;
-
- wi = &cg_weapons[ weapon ];
- weaponMode = es->generic1;
-
- if( wi->wim[ weaponMode ].missileParticleSystem )
- {
- ps = CG_SpawnNewParticleSystem( wi->wim[ weaponMode ].missileParticleSystem );
-
- if( CG_IsParticleSystemValid( &ps ) )
- {
- CG_SetAttachmentCent( &ps->attachment, cent );
- CG_AttachToCent( &ps->attachment );
- }
- }
-
- if( wi->wim[ weaponMode ].missileTrailSystem )
- {
- ts = CG_SpawnNewTrailSystem( wi->wim[ weaponMode ].missileTrailSystem );
-
- if( CG_IsTrailSystemValid( &ts ) )
- {
- CG_SetAttachmentCent( &ts->frontAttachment, cent );
- CG_AttachToCent( &ts->frontAttachment );
- }
- }
-}
-
-/*
-===============
-CG_Missile
-===============
-*/
-static void CG_Missile( centity_t *cent )
-{
- refEntity_t ent;
- entityState_t *es;
- const weaponInfo_t *wi;
- weapon_t weapon;
- weaponMode_t weaponMode;
- const weaponInfoMode_t *wim;
-
- es = &cent->currentState;
-
- weapon = es->weapon;
- if( weapon > WP_NUM_WEAPONS )
- weapon = WP_NONE;
-
- wi = &cg_weapons[ weapon ];
- weaponMode = es->generic1;
-
- wim = &wi->wim[ weaponMode ];
-
- // calculate the axis
- VectorCopy( es->angles, cent->lerpAngles );
-
- // add dynamic light
- if( wim->missileDlight )
- {
- trap_R_AddLightToScene( cent->lerpOrigin, wim->missileDlight,
- wim->missileDlightColor[ 0 ],
- wim->missileDlightColor[ 1 ],
- wim->missileDlightColor[ 2 ] );
- }
-
- // add missile sound
- if( wim->missileSound )
- {
- vec3_t velocity;
-
- BG_EvaluateTrajectoryDelta( &cent->currentState.pos, cg.time, velocity );
-
- trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, velocity, wim->missileSound );
- }
-
- // create the render entity
- memset( &ent, 0, sizeof( ent ) );
- VectorCopy( cent->lerpOrigin, ent.origin );
- VectorCopy( cent->lerpOrigin, ent.oldorigin );
-
- if( wim->usesSpriteMissle )
- {
- ent.reType = RT_SPRITE;
- ent.radius = wim->missileSpriteSize;
- ent.rotation = 0;
- ent.customShader = wim->missileSprite;
- ent.shaderRGBA[ 0 ] = 0xFF;
- ent.shaderRGBA[ 1 ] = 0xFF;
- ent.shaderRGBA[ 2 ] = 0xFF;
- ent.shaderRGBA[ 3 ] = 0xFF;
- }
- else
- {
- ent.hModel = wim->missileModel;
- ent.renderfx = wim->missileRenderfx | RF_NOSHADOW;
-
- // convert direction of travel into axis
- if( VectorNormalize2( es->pos.trDelta, ent.axis[ 0 ] ) == 0 )
- ent.axis[ 0 ][ 2 ] = 1;
-
- // spin as it moves
- if( es->pos.trType != TR_STATIONARY && wim->missileRotates )
- RotateAroundDirection( ent.axis, cg.time / 4 );
- else
- RotateAroundDirection( ent.axis, es->time );
-
- if( wim->missileAnimates )
- {
- int timeSinceStart = cg.time - es->time;
-
- if( wim->missileAnimLooping )
- {
- ent.frame = wim->missileAnimStartFrame +
- (int)( ( timeSinceStart / 1000.0f ) * wim->missileAnimFrameRate ) %
- wim->missileAnimNumFrames;
- }
- else
- {
- ent.frame = wim->missileAnimStartFrame +
- (int)( ( timeSinceStart / 1000.0f ) * wim->missileAnimFrameRate );
-
- if( ent.frame > ( wim->missileAnimStartFrame + wim->missileAnimNumFrames ) )
- ent.frame = wim->missileAnimStartFrame + wim->missileAnimNumFrames;
- }
- }
- }
-
- //only refresh if there is something to display
- if( wim->missileSprite || wim->missileModel )
- trap_R_AddRefEntityToScene( &ent );
-}
-
-/*
-===============
-CG_Mover
-===============
-*/
-static void CG_Mover( centity_t *cent )
-{
- refEntity_t ent;
- entityState_t *s1;
-
- s1 = &cent->currentState;
-
- // create the render entity
- memset( &ent, 0, sizeof( ent ) );
- VectorCopy( cent->lerpOrigin, ent.origin );
- VectorCopy( cent->lerpOrigin, ent.oldorigin );
- AnglesToAxis( cent->lerpAngles, ent.axis );
-
- ent.renderfx = RF_NOSHADOW;
-
- // flicker between two skins (FIXME?)
- ent.skinNum = ( cg.time >> 6 ) & 1;
-
- // get the model, either as a bmodel or a modelindex
- if( s1->solid == SOLID_BMODEL )
- ent.hModel = cgs.inlineDrawModel[ s1->modelindex ];
- else
- ent.hModel = cgs.gameModels[ s1->modelindex ];
-
- // add to refresh list
- trap_R_AddRefEntityToScene( &ent );
-
- // add the secondary model
- if( s1->modelindex2 )
- {
- ent.skinNum = 0;
- ent.hModel = cgs.gameModels[ s1->modelindex2 ];
- trap_R_AddRefEntityToScene( &ent );
- }
-
-}
-
-/*
-===============
-CG_Beam
-
-Also called as an event
-===============
-*/
-void CG_Beam( centity_t *cent )
-{
- refEntity_t ent;
- entityState_t *s1;
-
- s1 = &cent->currentState;
-
- // create the render entity
- memset( &ent, 0, sizeof( ent ) );
- VectorCopy( s1->pos.trBase, ent.origin );
- VectorCopy( s1->origin2, ent.oldorigin );
- AxisClear( ent.axis );
- ent.reType = RT_BEAM;
-
- ent.renderfx = RF_NOSHADOW;
-
- // add to refresh list
- trap_R_AddRefEntityToScene( &ent );
-}
-
-
-/*
-===============
-CG_Portal
-===============
-*/
-static void CG_Portal( centity_t *cent )
-{
- refEntity_t ent;
- entityState_t *s1;
-
- s1 = &cent->currentState;
-
- // create the render entity
- memset( &ent, 0, sizeof( ent ) );
- VectorCopy( cent->lerpOrigin, ent.origin );
- VectorCopy( s1->origin2, ent.oldorigin );
- ByteToDir( s1->eventParm, ent.axis[ 0 ] );
- PerpendicularVector( ent.axis[ 1 ], ent.axis[ 0 ] );
-
- // negating this tends to get the directions like they want
- // we really should have a camera roll value
- VectorSubtract( vec3_origin, ent.axis[ 1 ], ent.axis[ 1 ] );
-
- CrossProduct( ent.axis[ 0 ], ent.axis[ 1 ], ent.axis[ 2 ] );
- ent.reType = RT_PORTALSURFACE;
- ent.oldframe = s1->powerups;
- ent.frame = s1->frame; // rotation speed
- ent.skinNum = s1->clientNum / 256.0 * 360; // roll offset
-
- // add to refresh list
- trap_R_AddRefEntityToScene( &ent );
-}
-
-//============================================================================
-
-#define SETBOUNDS(v1,v2,r) ((v1)[0]=(-r/2),(v1)[1]=(-r/2),(v1)[2]=(-r/2),\
- (v2)[0]=(r/2),(v2)[1]=(r/2),(v2)[2]=(r/2))
-#define RADIUSSTEP 0.5f
-
-#define FLARE_OFF 0
-#define FLARE_NOFADE 1
-#define FLARE_TIMEFADE 2
-#define FLARE_REALFADE 3
-
-/*
-=========================
-CG_LightFlare
-=========================
-*/
-static void CG_LightFlare( centity_t *cent )
-{
- refEntity_t flare;
- entityState_t *es;
- vec3_t forward, delta;
- float len;
- trace_t tr;
- float maxAngle;
- vec3_t mins, maxs, start, end;
- float srcRadius, srLocal, ratio = 1.0f;
- int entityNum;
-
- es = &cent->currentState;
-
- if( cg.renderingThirdPerson )
- entityNum = MAGIC_TRACE_HACK;
- else
- entityNum = cg.predictedPlayerState.clientNum;
-
- //don't draw light flares
- if( cg_lightFlare.integer == FLARE_OFF )
- return;
-
- //flare is "off"
- if( es->eFlags & EF_NODRAW )
- return;
-
- CG_Trace( &tr, cg.refdef.vieworg, NULL, NULL, es->angles2,
- entityNum, MASK_SHOT );
-
- //if there is no los between the view and the flare source
- //it definately cannot be seen
- if( tr.fraction < 1.0f || tr.allsolid )
- return;
-
- memset( &flare, 0, sizeof( flare ) );
-
- flare.reType = RT_SPRITE;
- flare.customShader = cgs.gameShaders[ es->modelindex ];
- flare.shaderRGBA[ 0 ] = 0xFF;
- flare.shaderRGBA[ 1 ] = 0xFF;
- flare.shaderRGBA[ 2 ] = 0xFF;
- flare.shaderRGBA[ 3 ] = 0xFF;
-
- //flares always drawn before the rest of the scene
- flare.renderfx |= RF_DEPTHHACK;
-
- //bunch of geometry
- AngleVectors( es->angles, forward, NULL, NULL );
- VectorCopy( cent->lerpOrigin, flare.origin );
- VectorSubtract( flare.origin, cg.refdef.vieworg, delta );
- len = VectorLength( delta );
- VectorNormalize( delta );
-
- //flare is too close to camera to be drawn
- if( len < es->generic1 )
- return;
-
- //don't bother for flares behind the view plane
- if( DotProduct( delta, cg.refdef.viewaxis[ 0 ] ) < 0.0 )
- return;
-
- //only recalculate radius and ratio every three frames
- if( !( cg.clientFrame % 2 ) )
- {
- //can only see the flare when in front of it
- flare.radius = len / es->origin2[ 0 ];
-
- if( es->origin2[ 2 ] == 0 )
- srcRadius = srLocal = flare.radius / 2.0f;
- else
- srcRadius = srLocal = len / es->origin2[ 2 ];
-
- maxAngle = es->origin2[ 1 ];
-
- if( maxAngle > 0.0f )
- {
- float radiusMod = 1.0f - ( 180.0f - RAD2DEG(
- acos( DotProduct( delta, forward ) ) ) ) / maxAngle;
-
- if( es->eFlags & EF_NODRAW )
- flare.radius *= radiusMod;
- else if( radiusMod < 0.0f )
- flare.radius = 0.0f;
- }
-
- if( flare.radius < 0.0f )
- flare.radius = 0.0f;
-
- VectorMA( flare.origin, -flare.radius, delta, end );
- VectorMA( cg.refdef.vieworg, flare.radius, delta, start );
-
- if( cg_lightFlare.integer == FLARE_REALFADE )
- {
- //draw "correct" albeit inefficient flares
- srLocal = cent->lfs.lastSrcRadius;
-
- //flare radius is likely to be the same as last frame so start with it
- do
- {
- srLocal += RADIUSSTEP;
- SETBOUNDS( mins, maxs, srLocal );
- CG_Trace( &tr, start, mins, maxs, end,
- entityNum, MASK_SHOT );
-
- } while( ( tr.fraction == 1.0f && !tr.startsolid ) && ( srLocal < srcRadius ) );
-
- srLocal -= RADIUSSTEP;
-
- //shink the flare until there is a los
- do
- {
- SETBOUNDS( mins, maxs, srLocal );
- CG_Trace( &tr, start, mins, maxs, end,
- entityNum, MASK_SHOT );
-
- srLocal -= RADIUSSTEP;
- } while( ( tr.fraction < 1.0f || tr.startsolid ) && ( srLocal > 0.0f ) );
-
- ratio = srLocal / srcRadius;
-
- cent->lfs.lastSrcRadius = srLocal;
- }
- else if( cg_lightFlare.integer == FLARE_TIMEFADE )
- {
- //draw timed flares
- SETBOUNDS( mins, maxs, srcRadius );
- CG_Trace( &tr, start, mins, maxs, end,
- entityNum, MASK_SHOT );
-
- if( ( tr.fraction < 1.0f || tr.startsolid ) && cent->lfs.status )
- {
- cent->lfs.status = qfalse;
- cent->lfs.lastTime = cg.time;
- }
- else if( ( tr.fraction == 1.0f && !tr.startsolid ) && !cent->lfs.status )
- {
- cent->lfs.status = qtrue;
- cent->lfs.lastTime = cg.time;
- }
-
- //fade flare up
- if( cent->lfs.status )
- {
- if( cent->lfs.lastTime + es->time > cg.time )
- ratio = (float)( cg.time - cent->lfs.lastTime ) / es->time;
- }
-
- //fade flare down
- if( !cent->lfs.status )
- {
- if( cent->lfs.lastTime + es->time > cg.time )
- {
- ratio = (float)( cg.time - cent->lfs.lastTime ) / es->time;
- ratio = 1.0f - ratio;
- }
- else
- ratio = 0.0f;
- }
- }
- else if( cg_lightFlare.integer == FLARE_NOFADE )
- {
- //draw nofade flares
- SETBOUNDS( mins, maxs, srcRadius );
- CG_Trace( &tr, start, mins, maxs, end,
- entityNum, MASK_SHOT );
-
- //flare source occluded
- if( ( tr.fraction < 1.0f || tr.startsolid ) )
- ratio = 0.0f;
- }
- }
- else
- {
- ratio = cent->lfs.lastRatio;
- flare.radius = cent->lfs.lastRadius;
- }
-
- cent->lfs.lastRatio = ratio;
- cent->lfs.lastRadius = flare.radius;
-
- if( ratio < 1.0f )
- {
- flare.radius *= ratio;
- flare.shaderRGBA[ 3 ] = (byte)( (float)flare.shaderRGBA[ 3 ] * ratio );
- }
-
- if( flare.radius <= 0.0f )
- return;
-
- trap_R_AddRefEntityToScene( &flare );
-}
-
-/*
-=========================
-CG_Lev2ZapChain
-=========================
-*/
-static void CG_Lev2ZapChain( centity_t *cent )
-{
- int i;
- entityState_t *es;
- centity_t *source, *target;
-
- es = &cent->currentState;
-
- for( i = 0; i <= 2; i++ )
- {
- switch( i )
- {
- case 0:
- if( es->time <= 0 )
- continue;
-
- source = &cg_entities[ es->powerups ];
- target = &cg_entities[ es->time ];
- break;
-
- case 1:
- if( es->time2 <= 0 )
- continue;
-
- source = &cg_entities[ es->time ];
- target = &cg_entities[ es->time2 ];
- break;
-
- case 2:
- if( es->constantLight <= 0 )
- continue;
-
- source = &cg_entities[ es->time2 ];
- target = &cg_entities[ es->constantLight ];
- break;
- }
-
- if( !CG_IsTrailSystemValid( &cent->level2ZapTS[ i ] ) )
- cent->level2ZapTS[ i ] = CG_SpawnNewTrailSystem( cgs.media.level2ZapTS );
-
- if( CG_IsTrailSystemValid( &cent->level2ZapTS[ i ] ) )
- {
- CG_SetAttachmentCent( &cent->level2ZapTS[ i ]->frontAttachment, source );
- CG_SetAttachmentCent( &cent->level2ZapTS[ i ]->backAttachment, target );
- CG_AttachToCent( &cent->level2ZapTS[ i ]->frontAttachment );
- CG_AttachToCent( &cent->level2ZapTS[ i ]->backAttachment );
- }
- }
-}
-
-/*
-=========================
-CG_AdjustPositionForMover
-
-Also called by client movement prediction code
-=========================
-*/
-void CG_AdjustPositionForMover( const vec3_t in, int moverNum, int fromTime, int toTime, vec3_t out )
-{
- centity_t *cent;
- vec3_t oldOrigin, origin, deltaOrigin;
- vec3_t oldAngles, angles, deltaAngles;
-
- if( moverNum <= 0 || moverNum >= ENTITYNUM_MAX_NORMAL )
- {
- VectorCopy( in, out );
- return;
- }
-
- cent = &cg_entities[ moverNum ];
-
- if( cent->currentState.eType != ET_MOVER )
- {
- VectorCopy( in, out );
- return;
- }
-
- BG_EvaluateTrajectory( &cent->currentState.pos, fromTime, oldOrigin );
- BG_EvaluateTrajectory( &cent->currentState.apos, fromTime, oldAngles );
-
- BG_EvaluateTrajectory( &cent->currentState.pos, toTime, origin );
- BG_EvaluateTrajectory( &cent->currentState.apos, toTime, angles );
-
- VectorSubtract( origin, oldOrigin, deltaOrigin );
- VectorSubtract( angles, oldAngles, deltaAngles );
-
- VectorAdd( in, deltaOrigin, out );
-
- // FIXME: origin change when on a rotating object
-}
-
-
-/*
-=============================
-CG_InterpolateEntityPosition
-=============================
-*/
-static void CG_InterpolateEntityPosition( centity_t *cent )
-{
- vec3_t current, next;
- float f;
-
- // it would be an internal error to find an entity that interpolates without
- // a snapshot ahead of the current one
- if( cg.nextSnap == NULL )
- CG_Error( "CG_InterpoateEntityPosition: cg.nextSnap == NULL" );
-
- f = cg.frameInterpolation;
-
- // this will linearize a sine or parabolic curve, but it is important
- // to not extrapolate player positions if more recent data is available
- BG_EvaluateTrajectory( &cent->currentState.pos, cg.snap->serverTime, current );
- BG_EvaluateTrajectory( &cent->nextState.pos, cg.nextSnap->serverTime, next );
-
- cent->lerpOrigin[ 0 ] = current[ 0 ] + f * ( next[ 0 ] - current[ 0 ] );
- cent->lerpOrigin[ 1 ] = current[ 1 ] + f * ( next[ 1 ] - current[ 1 ] );
- cent->lerpOrigin[ 2 ] = current[ 2 ] + f * ( next[ 2 ] - current[ 2 ] );
-
- BG_EvaluateTrajectory( &cent->currentState.apos, cg.snap->serverTime, current );
- BG_EvaluateTrajectory( &cent->nextState.apos, cg.nextSnap->serverTime, next );
-
- cent->lerpAngles[ 0 ] = LerpAngle( current[ 0 ], next[ 0 ], f );
- cent->lerpAngles[ 1 ] = LerpAngle( current[ 1 ], next[ 1 ], f );
- cent->lerpAngles[ 2 ] = LerpAngle( current[ 2 ], next[ 2 ], f );
-
-}
-
-/*
-===============
-CG_CalcEntityLerpPositions
-
-===============
-*/
-static void CG_CalcEntityLerpPositions( centity_t *cent )
-{
- // if this player does not want to see extrapolated players
- if( !cg_smoothClients.integer )
- {
- // make sure the clients use TR_INTERPOLATE
- if( cent->currentState.number < MAX_CLIENTS )
- {
- cent->currentState.pos.trType = TR_INTERPOLATE;
- cent->nextState.pos.trType = TR_INTERPOLATE;
- }
- }
-
- if( cent->interpolate && cent->currentState.pos.trType == TR_INTERPOLATE )
- {
- CG_InterpolateEntityPosition( cent );
- return;
- }
-
- // first see if we can interpolate between two snaps for
- // linear extrapolated clients
- if( cent->interpolate && cent->currentState.pos.trType == TR_LINEAR_STOP &&
- cent->currentState.number < MAX_CLIENTS )
- {
- CG_InterpolateEntityPosition( cent );
- return;
- }
-
- // just use the current frame and evaluate as best we can
- BG_EvaluateTrajectory( &cent->currentState.pos, cg.time, cent->lerpOrigin );
- BG_EvaluateTrajectory( &cent->currentState.apos, cg.time, cent->lerpAngles );
-
- // adjust for riding a mover if it wasn't rolled into the predicted
- // player state
- if( cent != &cg.predictedPlayerEntity )
- {
- CG_AdjustPositionForMover( cent->lerpOrigin, cent->currentState.groundEntityNum,
- cg.snap->serverTime, cg.time, cent->lerpOrigin );
- }
-}
-
-
-/*
-===============
-CG_CEntityPVSEnter
-
-===============
-*/
-static void CG_CEntityPVSEnter( centity_t *cent )
-{
- entityState_t *es = &cent->currentState;
-
- if( cg_debugPVS.integer )
- CG_Printf( "Entity %d entered PVS\n", cent->currentState.number );
-
- switch( es->eType )
- {
- case ET_MISSILE:
- CG_LaunchMissile( cent );
- break;
- }
-
- //clear any particle systems from previous uses of this centity_t
- cent->muzzlePS = NULL;
- cent->muzzlePsTrigger = qfalse;
- cent->jetPackPS = NULL;
- cent->jetPackState = JPS_OFF;
- cent->buildablePS = NULL;
- cent->entityPS = NULL;
- cent->entityPSMissing = qfalse;
-
- //make sure that the buildable animations are in a consistent state
- //when a buildable enters the PVS
- cent->buildableAnim = cent->lerpFrame.animationNumber = BANIM_NONE;
- cent->oldBuildableAnim = es->legsAnim;
-}
-
-
-/*
-===============
-CG_CEntityPVSLeave
-
-===============
-*/
-static void CG_CEntityPVSLeave( centity_t *cent )
-{
- int i;
- entityState_t *es = &cent->currentState;
-
- if( cg_debugPVS.integer )
- CG_Printf( "Entity %d left PVS\n", cent->currentState.number );
-
- switch( es->eType )
- {
- case ET_LEV2_ZAP_CHAIN:
- for( i = 0; i <= 2; i++ )
- {
- if( CG_IsTrailSystemValid( &cent->level2ZapTS[ i ] ) )
- CG_DestroyTrailSystem( &cent->level2ZapTS[ i ] );
- }
- break;
- }
-}
-
-
-/*
-===============
-CG_AddCEntity
-
-===============
-*/
-static void CG_AddCEntity( centity_t *cent )
-{
- // event-only entities will have been dealt with already
- if( cent->currentState.eType >= ET_EVENTS )
- return;
-
- // calculate the current origin
- CG_CalcEntityLerpPositions( cent );
-
- // add automatic effects
- CG_EntityEffects( cent );
-
- switch( cent->currentState.eType )
- {
- default:
- CG_Error( "Bad entity type: %i\n", cent->currentState.eType );
- break;
-
- case ET_INVISIBLE:
- case ET_PUSH_TRIGGER:
- case ET_TELEPORT_TRIGGER:
- break;
-
- case ET_GENERAL:
- CG_General( cent );
- break;
-
- case ET_CORPSE:
- CG_Corpse( cent );
- break;
-
- case ET_PLAYER:
- CG_Player( cent );
- break;
-
- case ET_BUILDABLE:
- CG_Buildable( cent );
- break;
-
- case ET_MISSILE:
- CG_Missile( cent );
- break;
-
- case ET_MOVER:
- CG_Mover( cent );
- break;
-
- case ET_BEAM:
- CG_Beam( cent );
- break;
-
- case ET_PORTAL:
- CG_Portal( cent );
- break;
-
- case ET_SPEAKER:
- CG_Speaker( cent );
- break;
-
- case ET_PARTICLE_SYSTEM:
- CG_ParticleSystemEntity( cent );
- break;
-
- case ET_ANIMMAPOBJ:
- CG_AnimMapObj( cent );
- break;
-
- case ET_MODELDOOR:
- CG_ModelDoor( cent );
- break;
-
- case ET_LIGHTFLARE:
- CG_LightFlare( cent );
- break;
-
- case ET_LEV2_ZAP_CHAIN:
- CG_Lev2ZapChain( cent );
- break;
- }
-}
-
-/*
-===============
-CG_AddPacketEntities
-
-===============
-*/
-void CG_AddPacketEntities( void )
-{
- int num;
- centity_t *cent;
- playerState_t *ps;
-
- // set cg.frameInterpolation
- if( cg.nextSnap )
- {
- int delta;
-
- delta = ( cg.nextSnap->serverTime - cg.snap->serverTime );
-
- if( delta == 0 )
- cg.frameInterpolation = 0;
- else
- cg.frameInterpolation = (float)( cg.time - cg.snap->serverTime ) / delta;
- }
- else
- {
- cg.frameInterpolation = 0; // actually, it should never be used, because
- // no entities should be marked as interpolating
- }
-
- // the auto-rotating items will all have the same axis
- cg.autoAngles[ 0 ] = 0;
- cg.autoAngles[ 1 ] = ( cg.time & 2047 ) * 360 / 2048.0;
- cg.autoAngles[ 2 ] = 0;
-
- cg.autoAnglesFast[ 0 ] = 0;
- cg.autoAnglesFast[ 1 ] = ( cg.time & 1023 ) * 360 / 1024.0f;
- cg.autoAnglesFast[ 2 ] = 0;
-
- AnglesToAxis( cg.autoAngles, cg.autoAxis );
- AnglesToAxis( cg.autoAnglesFast, cg.autoAxisFast );
-
- // generate and add the entity from the playerstate
- ps = &cg.predictedPlayerState;
- BG_PlayerStateToEntityState( ps, &cg.predictedPlayerEntity.currentState, qfalse );
- cg.predictedPlayerEntity.valid = qtrue;
- CG_AddCEntity( &cg.predictedPlayerEntity );
-
- // lerp the non-predicted value for lightning gun origins
- CG_CalcEntityLerpPositions( &cg_entities[ cg.snap->ps.clientNum ] );
-
- // scanner
- CG_UpdateEntityPositions( );
-
- for( num = 0; num < MAX_GENTITIES; num++ )
- cg_entities[ num ].valid = qfalse;
-
- // add each entity sent over by the server
- for( num = 0; num < cg.snap->numEntities; num++ )
- {
- cent = &cg_entities[ cg.snap->entities[ num ].number ];
- cent->valid = qtrue;
- }
-
- for( num = 0; num < MAX_GENTITIES; num++ )
- {
- cent = &cg_entities[ num ];
-
- if( cent->valid && !cent->oldValid )
- CG_CEntityPVSEnter( cent );
- else if( !cent->valid && cent->oldValid )
- CG_CEntityPVSLeave( cent );
-
- cent->oldValid = cent->valid;
- }
-
- // add each entity sent over by the server
- for( num = 0; num < cg.snap->numEntities; num++ )
- {
- cent = &cg_entities[ cg.snap->entities[ num ].number ];
- CG_AddCEntity( cent );
- }
-
- //make an attempt at drawing bounding boxes of selected entity types
- if( cg_drawBBOX.integer )
- {
- for( num = 0; num < cg.snap->numEntities; num++ )
- {
- float x, zd, zu;
- vec3_t mins, maxs;
- entityState_t *es;
-
- cent = &cg_entities[ cg.snap->entities[ num ].number ];
- es = &cent->currentState;
-
- switch( es->eType )
- {
- case ET_BUILDABLE:
- case ET_MISSILE:
- case ET_CORPSE:
- x = ( es->solid & 255 );
- zd = ( ( es->solid >> 8 ) & 255 );
- zu = ( ( es->solid >> 16 ) & 255 ) - 32;
-
- mins[ 0 ] = mins[ 1 ] = -x;
- maxs[ 0 ] = maxs[ 1 ] = x;
- mins[ 2 ] = -zd;
- maxs[ 2 ] = zu;
-
- CG_DrawBoundingBox( cent->lerpOrigin, mins, maxs );
- break;
-
- default:
- break;
- }
- }
- }
-}
-
diff --git a/src/cgame/cg_event.c b/src/cgame/cg_event.c
deleted file mode 100644
index b89c8e7c..00000000
--- a/src/cgame/cg_event.c
+++ /dev/null
@@ -1,1011 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_event.c -- handle entity events at snapshot or playerstate transitions
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-/*
-=============
-CG_Obituary
-=============
-*/
-static void CG_Obituary( entityState_t *ent )
-{
- int mod;
- int target, attacker;
- char *message;
- char *message2;
- const char *targetInfo;
- const char *attackerInfo;
- char targetName[ 32 ];
- char attackerName[ 32 ];
- char className[ 64 ];
- gender_t gender;
- clientInfo_t *ci;
-
- target = ent->otherEntityNum;
- attacker = ent->otherEntityNum2;
- mod = ent->eventParm;
-
- if( target < 0 || target >= MAX_CLIENTS )
- CG_Error( "CG_Obituary: target out of range" );
-
- ci = &cgs.clientinfo[ target ];
-
- if( attacker < 0 || attacker >= MAX_CLIENTS )
- {
- attacker = ENTITYNUM_WORLD;
- attackerInfo = NULL;
- }
- else
- attackerInfo = CG_ConfigString( CS_PLAYERS + attacker );
-
- targetInfo = CG_ConfigString( CS_PLAYERS + target );
-
- if( !targetInfo )
- return;
-
- Q_strncpyz( targetName, Info_ValueForKey( targetInfo, "n" ), sizeof( targetName ) - 2 );
- strcat( targetName, S_COLOR_WHITE );
-
- message2 = "";
-
- // check for single client messages
-
- switch( mod )
- {
- case MOD_SUICIDE:
- message = "suicides";
- break;
- case MOD_FALLING:
- message = "fell fowl to gravity";
- break;
- case MOD_CRUSH:
- message = "was squished";
- break;
- case MOD_WATER:
- message = "forgot to pack a snorkel";
- break;
- case MOD_SLIME:
- message = "melted";
- break;
- case MOD_LAVA:
- message = "does a back flip into the lava";
- break;
- case MOD_TARGET_LASER:
- message = "saw the light";
- break;
- case MOD_TRIGGER_HURT:
- message = "was in the wrong place";
- break;
- case MOD_HSPAWN:
- message = "should have ran further";
- break;
- case MOD_ASPAWN:
- message = "shouldn't have trod in the acid";
- break;
- case MOD_MGTURRET:
- message = "was gunned down by a turret";
- break;
- case MOD_TESLAGEN:
- message = "was zapped by a tesla generator";
- break;
- case MOD_ATUBE:
- message = "was melted by an acid tube";
- break;
- case MOD_OVERMIND:
- message = "got too close to the overmind";
- break;
- case MOD_REACTOR:
- message = "got too close to the reactor";
- break;
- case MOD_SLOWBLOB:
- message = "should have visited a medical station";
- break;
- case MOD_SWARM:
- message = "was hunted down by the swarm";
- break;
- default:
- message = NULL;
- break;
- }
-
- if( attacker == target )
- {
- gender = ci->gender;
- switch( mod )
- {
- case MOD_FLAMER_SPLASH:
- if( gender == GENDER_FEMALE )
- message = "toasted herself";
- else if( gender == GENDER_NEUTER )
- message = "toasted itself";
- else
- message = "toasted himself";
- break;
-
- case MOD_LCANNON_SPLASH:
- if( gender == GENDER_FEMALE )
- message = "irradiated herself";
- else if( gender == GENDER_NEUTER )
- message = "irradiated itself";
- else
- message = "irradiated himself";
- break;
-
- case MOD_GRENADE:
- if( gender == GENDER_FEMALE )
- message = "blew herself up";
- else if( gender == GENDER_NEUTER )
- message = "blew itself up";
- else
- message = "blew himself up";
- break;
-
- default:
- if( gender == GENDER_FEMALE )
- message = "killed herself";
- else if( gender == GENDER_NEUTER )
- message = "killed itself";
- else
- message = "killed himself";
- break;
- }
- }
-
- if( message )
- {
- CG_Printf( "%s %s.\n", targetName, message );
- return;
- }
-
- // check for double client messages
- if( !attackerInfo )
- {
- attacker = ENTITYNUM_WORLD;
- strcpy( attackerName, "noname" );
- }
- else
- {
- Q_strncpyz( attackerName, Info_ValueForKey( attackerInfo, "n" ), sizeof( attackerName ) - 2);
- strcat( attackerName, S_COLOR_WHITE );
- // check for kill messages about the current clientNum
- if( target == cg.snap->ps.clientNum )
- Q_strncpyz( cg.killerName, attackerName, sizeof( cg.killerName ) );
- }
-
- if( attacker != ENTITYNUM_WORLD )
- {
- switch( mod )
- {
- case MOD_PAINSAW:
- message = "was sawn by";
- break;
- case MOD_BLASTER:
- message = "was blasted by";
- break;
- case MOD_MACHINEGUN:
- message = "was machinegunned by";
- break;
- case MOD_CHAINGUN:
- message = "was chaingunned by";
- break;
- case MOD_SHOTGUN:
- message = "was gunned down by";
- break;
- case MOD_PRIFLE:
- message = "was pulse rifled by";
- break;
- case MOD_MDRIVER:
- message = "was mass driven by";
- break;
- case MOD_LASGUN:
- message = "was lasgunned by";
- break;
- case MOD_FLAMER:
- message = "was grilled by";
- message2 = "'s flamer";
- break;
- case MOD_FLAMER_SPLASH:
- message = "was toasted by";
- message2 = "'s flamer";
- break;
- case MOD_LCANNON:
- message = "felt the full force of";
- message2 = "'s lucifer cannon";
- break;
- case MOD_LCANNON_SPLASH:
- message = "was caught in the fallout of";
- message2 = "'s lucifer cannon";
- break;
- case MOD_GRENADE:
- message = "couldn't escape";
- message2 = "'s grenade";
- break;
-
- case MOD_ABUILDER_CLAW:
- message = "should leave";
- message2 = "'s buildings alone";
- break;
- case MOD_LEVEL0_BITE:
- message = "was bitten by";
- break;
- case MOD_LEVEL1_CLAW:
- message = "was swiped by";
- Com_sprintf( className, 64, "'s %s",
- BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL1 ) );
- message2 = className;
- break;
- case MOD_LEVEL2_CLAW:
- message = "was clawed by";
- Com_sprintf( className, 64, "'s %s",
- BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL2 ) );
- message2 = className;
- break;
- case MOD_LEVEL2_ZAP:
- message = "was zapped by";
- Com_sprintf( className, 64, "'s %s",
- BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL2 ) );
- message2 = className;
- break;
- case MOD_LEVEL3_CLAW:
- message = "was chomped by";
- Com_sprintf( className, 64, "'s %s",
- BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL3 ) );
- message2 = className;
- break;
- case MOD_LEVEL3_POUNCE:
- message = "was pounced upon by";
- Com_sprintf( className, 64, "'s %s",
- BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL3 ) );
- message2 = className;
- break;
- case MOD_LEVEL3_BOUNCEBALL:
- message = "was sniped by";
- Com_sprintf( className, 64, "'s %s",
- BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL3 ) );
- message2 = className;
- break;
- case MOD_LEVEL4_CLAW:
- message = "was mauled by";
- Com_sprintf( className, 64, "'s %s",
- BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL4 ) );
- message2 = className;
- break;
- case MOD_LEVEL4_CHARGE:
- message = "should have gotten out of the way of";
- Com_sprintf( className, 64, "'s %s",
- BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL4 ) );
- message2 = className;
- break;
-
- case MOD_POISON:
- message = "should have used a medkit against";
- message2 = "'s poison";
- break;
- case MOD_LEVEL1_PCLOUD:
- message = "was gassed by";
- Com_sprintf( className, 64, "'s %s",
- BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL1 ) );
- message2 = className;
- break;
-
-
- case MOD_TELEFRAG:
- message = "tried to invade";
- message2 = "'s personal space";
- break;
- default:
- message = "was killed by";
- break;
- }
-
- if( message )
- {
- CG_Printf( "%s %s %s%s\n",
- targetName, message, attackerName, message2 );
- return;
- }
- }
-
- // we don't know what it was
- CG_Printf( "%s died.\n", targetName );
-}
-
-//==========================================================================
-
-/*
-================
-CG_PainEvent
-
-Also called by playerstate transition
-================
-*/
-void CG_PainEvent( centity_t *cent, int health )
-{
- char *snd;
-
- // don't do more than two pain sounds a second
- if( cg.time - cent->pe.painTime < 500 )
- return;
-
- if( health < 25 )
- snd = "*pain25_1.wav";
- else if( health < 50 )
- snd = "*pain50_1.wav";
- else if( health < 75 )
- snd = "*pain75_1.wav";
- else
- snd = "*pain100_1.wav";
-
- trap_S_StartSound( NULL, cent->currentState.number, CHAN_VOICE,
- CG_CustomSound( cent->currentState.number, snd ) );
-
- // save pain time for programitic twitch animation
- cent->pe.painTime = cg.time;
- cent->pe.painDirection ^= 1;
-}
-
-/*
-==============
-CG_EntityEvent
-
-An entity has an event value
-also called by CG_CheckPlayerstateEvents
-==============
-*/
-#define DEBUGNAME(x) if(cg_debugEvents.integer){CG_Printf(x"\n");}
-void CG_EntityEvent( centity_t *cent, vec3_t position )
-{
- entityState_t *es;
- int event;
- vec3_t dir;
- const char *s;
- int clientNum;
- clientInfo_t *ci;
- int steptime;
-
- if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
- steptime = 200;
- else
- steptime = BG_FindSteptimeForClass( cg.snap->ps.stats[ STAT_PCLASS ] );
-
- es = &cent->currentState;
- event = es->event & ~EV_EVENT_BITS;
-
- if( cg_debugEvents.integer )
- CG_Printf( "ent:%3i event:%3i ", es->number, event );
-
- if( !event )
- {
- DEBUGNAME("ZEROEVENT");
- return;
- }
-
- clientNum = es->clientNum;
- if( clientNum < 0 || clientNum >= MAX_CLIENTS )
- clientNum = 0;
-
- ci = &cgs.clientinfo[ clientNum ];
-
- switch( event )
- {
- //
- // movement generated events
- //
- case EV_FOOTSTEP:
- DEBUGNAME( "EV_FOOTSTEP" );
- if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE )
- {
- if( ci->footsteps == FOOTSTEP_CUSTOM )
- trap_S_StartSound( NULL, es->number, CHAN_BODY,
- ci->customFootsteps[ rand( ) & 3 ] );
- else
- trap_S_StartSound( NULL, es->number, CHAN_BODY,
- cgs.media.footsteps[ ci->footsteps ][ rand( ) & 3 ] );
- }
- break;
-
- case EV_FOOTSTEP_METAL:
- DEBUGNAME( "EV_FOOTSTEP_METAL" );
- if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE )
- {
- if( ci->footsteps == FOOTSTEP_CUSTOM )
- trap_S_StartSound( NULL, es->number, CHAN_BODY,
- ci->customMetalFootsteps[ rand( ) & 3 ] );
- else
- trap_S_StartSound( NULL, es->number, CHAN_BODY,
- cgs.media.footsteps[ FOOTSTEP_METAL ][ rand( ) & 3 ] );
- }
- break;
-
- case EV_FOOTSTEP_SQUELCH:
- DEBUGNAME( "EV_FOOTSTEP_SQUELCH" );
- if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE )
- {
- trap_S_StartSound( NULL, es->number, CHAN_BODY,
- cgs.media.footsteps[ FOOTSTEP_FLESH ][ rand( ) & 3 ] );
- }
- break;
-
- case EV_FOOTSPLASH:
- DEBUGNAME( "EV_FOOTSPLASH" );
- if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE )
- {
- trap_S_StartSound( NULL, es->number, CHAN_BODY,
- cgs.media.footsteps[ FOOTSTEP_SPLASH ][ rand( ) & 3 ] );
- }
- break;
-
- case EV_FOOTWADE:
- DEBUGNAME( "EV_FOOTWADE" );
- if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE )
- {
- trap_S_StartSound( NULL, es->number, CHAN_BODY,
- cgs.media.footsteps[ FOOTSTEP_SPLASH ][ rand( ) & 3 ] );
- }
- break;
-
- case EV_SWIM:
- DEBUGNAME( "EV_SWIM" );
- if( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE )
- {
- trap_S_StartSound( NULL, es->number, CHAN_BODY,
- cgs.media.footsteps[ FOOTSTEP_SPLASH ][ rand( ) & 3 ] );
- }
- break;
-
-
- case EV_FALL_SHORT:
- DEBUGNAME( "EV_FALL_SHORT" );
- trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.landSound );
-
- if( clientNum == cg.predictedPlayerState.clientNum )
- {
- // smooth landing z changes
- cg.landChange = -8;
- cg.landTime = cg.time;
- }
- break;
-
- case EV_FALL_MEDIUM:
- DEBUGNAME( "EV_FALL_MEDIUM" );
- // use normal pain sound
- trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*pain100_1.wav" ) );
-
- if( clientNum == cg.predictedPlayerState.clientNum )
- {
- // smooth landing z changes
- cg.landChange = -16;
- cg.landTime = cg.time;
- }
- break;
-
- case EV_FALL_FAR:
- DEBUGNAME( "EV_FALL_FAR" );
- trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*fall1.wav" ) );
- cent->pe.painTime = cg.time; // don't play a pain sound right after this
-
- if( clientNum == cg.predictedPlayerState.clientNum )
- {
- // smooth landing z changes
- cg.landChange = -24;
- cg.landTime = cg.time;
- }
- break;
-
- case EV_FALLING:
- DEBUGNAME( "EV_FALLING" );
- trap_S_StartSound( NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*falling1.wav" ) );
- break;
-
- case EV_STEP_4:
- case EV_STEP_8:
- case EV_STEP_12:
- case EV_STEP_16: // smooth out step up transitions
- case EV_STEPDN_4:
- case EV_STEPDN_8:
- case EV_STEPDN_12:
- case EV_STEPDN_16: // smooth out step down transitions
- DEBUGNAME( "EV_STEP" );
- {
- float oldStep;
- int delta;
- int step;
-
- if( clientNum != cg.predictedPlayerState.clientNum )
- break;
-
- // if we are interpolating, we don't need to smooth steps
- if( cg.demoPlayback || ( cg.snap->ps.pm_flags & PMF_FOLLOW ) ||
- cg_nopredict.integer || cg_synchronousClients.integer )
- break;
-
- // check for stepping up before a previous step is completed
- delta = cg.time - cg.stepTime;
-
- if( delta < steptime )
- oldStep = cg.stepChange * ( steptime - delta ) / steptime;
- else
- oldStep = 0;
-
- // add this amount
- if( event >= EV_STEPDN_4 )
- {
- step = 4 * ( event - EV_STEPDN_4 + 1 );
- cg.stepChange = oldStep - step;
- }
- else
- {
- step = 4 * ( event - EV_STEP_4 + 1 );
- cg.stepChange = oldStep + step;
- }
-
- if( cg.stepChange > MAX_STEP_CHANGE )
- cg.stepChange = MAX_STEP_CHANGE;
- else if( cg.stepChange < -MAX_STEP_CHANGE )
- cg.stepChange = -MAX_STEP_CHANGE;
-
- cg.stepTime = cg.time;
- break;
- }
-
- case EV_JUMP:
- DEBUGNAME( "EV_JUMP" );
- trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) );
-
- if( BG_ClassHasAbility( cg.predictedPlayerState.stats[ STAT_PCLASS ], SCA_WALLJUMPER ) )
- {
- vec3_t surfNormal, refNormal = { 0.0f, 0.0f, 1.0f };
- vec3_t rotAxis;
-
- if( clientNum != cg.predictedPlayerState.clientNum )
- break;
-
- //set surfNormal
- VectorCopy( cg.predictedPlayerState.grapplePoint, surfNormal );
-
- //if we are moving from one surface to another smooth the transition
- if( !VectorCompare( surfNormal, cg.lastNormal ) && surfNormal[ 2 ] != 1.0f )
- {
- CrossProduct( refNormal, surfNormal, rotAxis );
- VectorNormalize( rotAxis );
-
- //add the op
- CG_addSmoothOp( rotAxis, 15.0f, 1.0f );
- }
-
- //copy the current normal to the lastNormal
- VectorCopy( surfNormal, cg.lastNormal );
- }
-
- break;
-
- case EV_LEV1_GRAB:
- DEBUGNAME( "EV_LEV1_GRAB" );
- trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL1Grab );
- break;
-
- case EV_LEV4_CHARGE_PREPARE:
- DEBUGNAME( "EV_LEV4_CHARGE_PREPARE" );
- trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL4ChargePrepare );
- break;
-
- case EV_LEV4_CHARGE_START:
- DEBUGNAME( "EV_LEV4_CHARGE_START" );
- //FIXME: stop cgs.media.alienL4ChargePrepare playing here
- trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL4ChargeStart );
- break;
-
- case EV_TAUNT:
- DEBUGNAME( "EV_TAUNT" );
- trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*taunt.wav" ) );
- break;
-
- case EV_WATER_TOUCH:
- DEBUGNAME( "EV_WATER_TOUCH" );
- trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.watrInSound );
- break;
-
- case EV_WATER_LEAVE:
- DEBUGNAME( "EV_WATER_LEAVE" );
- trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound );
- break;
-
- case EV_WATER_UNDER:
- DEBUGNAME( "EV_WATER_UNDER" );
- trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound );
- break;
-
- case EV_WATER_CLEAR:
- DEBUGNAME( "EV_WATER_CLEAR" );
- trap_S_StartSound( NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*gasp.wav" ) );
- break;
-
- //
- // weapon events
- //
- case EV_NOAMMO:
- DEBUGNAME( "EV_NOAMMO" );
- {
- }
- break;
-
- case EV_CHANGE_WEAPON:
- DEBUGNAME( "EV_CHANGE_WEAPON" );
- trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.selectSound );
- break;
-
- case EV_FIRE_WEAPON:
- DEBUGNAME( "EV_FIRE_WEAPON" );
- CG_FireWeapon( cent, WPM_PRIMARY );
- break;
-
- case EV_FIRE_WEAPON2:
- DEBUGNAME( "EV_FIRE_WEAPON2" );
- CG_FireWeapon( cent, WPM_SECONDARY );
- break;
-
- case EV_FIRE_WEAPON3:
- DEBUGNAME( "EV_FIRE_WEAPON3" );
- CG_FireWeapon( cent, WPM_TERTIARY );
- break;
-
- //=================================================================
-
- //
- // other events
- //
- case EV_PLAYER_TELEPORT_IN:
- DEBUGNAME( "EV_PLAYER_TELEPORT_IN" );
- //deprecated
- break;
-
- case EV_PLAYER_TELEPORT_OUT:
- DEBUGNAME( "EV_PLAYER_TELEPORT_OUT" );
- CG_PlayerDisconnect( position );
- break;
-
- case EV_BUILD_CONSTRUCT:
- DEBUGNAME( "EV_BUILD_CONSTRUCT" );
- //do something useful here
- break;
-
- case EV_BUILD_DESTROY:
- DEBUGNAME( "EV_BUILD_DESTROY" );
- //do something useful here
- break;
-
- case EV_RPTUSE_SOUND:
- DEBUGNAME( "EV_RPTUSE_SOUND" );
- trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.repeaterUseSound );
- break;
-
- case EV_GRENADE_BOUNCE:
- DEBUGNAME( "EV_GRENADE_BOUNCE" );
- if( rand( ) & 1 )
- trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.hgrenb1aSound );
- else
- trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.hgrenb2aSound );
- break;
-
- //
- // missile impacts
- //
- case EV_MISSILE_HIT:
- DEBUGNAME( "EV_MISSILE_HIT" );
- ByteToDir( es->eventParm, dir );
- CG_MissileHitPlayer( es->weapon, es->generic1, position, dir, es->otherEntityNum );
- break;
-
- case EV_MISSILE_MISS:
- DEBUGNAME( "EV_MISSILE_MISS" );
- ByteToDir( es->eventParm, dir );
- CG_MissileHitWall( es->weapon, es->generic1, 0, position, dir, IMPACTSOUND_DEFAULT );
- break;
-
- case EV_MISSILE_MISS_METAL:
- DEBUGNAME( "EV_MISSILE_MISS_METAL" );
- ByteToDir( es->eventParm, dir );
- CG_MissileHitWall( es->weapon, es->generic1, 0, position, dir, IMPACTSOUND_METAL );
- break;
-
- case EV_HUMAN_BUILDABLE_EXPLOSION:
- DEBUGNAME( "EV_HUMAN_BUILDABLE_EXPLOSION" );
- ByteToDir( es->eventParm, dir );
- CG_HumanBuildableExplosion( position, dir );
- break;
-
- case EV_ALIEN_BUILDABLE_EXPLOSION:
- DEBUGNAME( "EV_ALIEN_BUILDABLE_EXPLOSION" );
- ByteToDir( es->eventParm, dir );
- CG_AlienBuildableExplosion( position, dir );
- break;
-
- case EV_TESLATRAIL:
- DEBUGNAME( "EV_TESLATRAIL" );
- cent->currentState.weapon = WP_TESLAGEN;
- {
- centity_t *source = &cg_entities[ es->generic1 ];
- centity_t *target = &cg_entities[ es->clientNum ];
- vec3_t sourceOffset = { 0.0f, 0.0f, 28.0f };
-
- if( !CG_IsTrailSystemValid( &source->muzzleTS ) )
- {
- source->muzzleTS = CG_SpawnNewTrailSystem( cgs.media.teslaZapTS );
-
- if( CG_IsTrailSystemValid( &source->muzzleTS ) )
- {
- CG_SetAttachmentCent( &source->muzzleTS->frontAttachment, source );
- CG_SetAttachmentCent( &source->muzzleTS->backAttachment, target );
- CG_AttachToCent( &source->muzzleTS->frontAttachment );
- CG_AttachToCent( &source->muzzleTS->backAttachment );
- CG_SetAttachmentOffset( &source->muzzleTS->frontAttachment, sourceOffset );
-
- source->muzzleTSDeathTime = cg.time + cg_teslaTrailTime.integer;
- }
- }
- }
- break;
-
- case EV_BULLET_HIT_WALL:
- DEBUGNAME( "EV_BULLET_HIT_WALL" );
- ByteToDir( es->eventParm, dir );
- CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD );
- break;
-
- case EV_BULLET_HIT_FLESH:
- DEBUGNAME( "EV_BULLET_HIT_FLESH" );
- CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm );
- break;
-
- case EV_SHOTGUN:
- DEBUGNAME( "EV_SHOTGUN" );
- CG_ShotgunFire( es );
- break;
-
- case EV_GENERAL_SOUND:
- DEBUGNAME( "EV_GENERAL_SOUND" );
- if( cgs.gameSounds[ es->eventParm ] )
- trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ] );
- else
- {
- s = CG_ConfigString( CS_SOUNDS + es->eventParm );
- trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, s ) );
- }
- break;
-
- case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes
- DEBUGNAME( "EV_GLOBAL_SOUND" );
- if( cgs.gameSounds[ es->eventParm ] )
- trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[ es->eventParm ] );
- else
- {
- s = CG_ConfigString( CS_SOUNDS + es->eventParm );
- trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound( es->number, s ) );
- }
- break;
-
- case EV_PAIN:
- // local player sounds are triggered in CG_CheckLocalSounds,
- // so ignore events on the player
- DEBUGNAME( "EV_PAIN" );
- if( cent->currentState.number != cg.snap->ps.clientNum )
- CG_PainEvent( cent, es->eventParm );
- break;
-
- case EV_DEATH1:
- case EV_DEATH2:
- case EV_DEATH3:
- DEBUGNAME( "EV_DEATHx" );
- trap_S_StartSound( NULL, es->number, CHAN_VOICE,
- CG_CustomSound( es->number, va( "*death%i.wav", event - EV_DEATH1 + 1 ) ) );
- break;
-
- case EV_OBITUARY:
- DEBUGNAME( "EV_OBITUARY" );
- CG_Obituary( es );
- break;
-
- case EV_GIB_PLAYER:
- DEBUGNAME( "EV_GIB_PLAYER" );
- // no gibbing
- break;
-
- case EV_STOPLOOPINGSOUND:
- DEBUGNAME( "EV_STOPLOOPINGSOUND" );
- trap_S_StopLoopingSound( es->number );
- es->loopSound = 0;
- break;
-
- case EV_DEBUG_LINE:
- DEBUGNAME( "EV_DEBUG_LINE" );
- CG_Beam( cent );
- break;
-
- case EV_BUILD_DELAY:
- DEBUGNAME( "EV_BUILD_DELAY" );
- if( clientNum == cg.predictedPlayerState.clientNum )
- {
- trap_S_StartLocalSound( cgs.media.buildableRepairedSound, CHAN_LOCAL_SOUND );
- cg.lastBuildAttempt = cg.time;
- }
- break;
-
- case EV_BUILD_REPAIR:
- DEBUGNAME( "EV_BUILD_REPAIR" );
- trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.buildableRepairSound );
- break;
-
- case EV_BUILD_REPAIRED:
- DEBUGNAME( "EV_BUILD_REPAIRED" );
- trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.buildableRepairedSound );
- break;
-
- case EV_OVERMIND_ATTACK:
- DEBUGNAME( "EV_OVERMIND_ATTACK" );
- if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS )
- {
- trap_S_StartLocalSound( cgs.media.alienOvermindAttack, CHAN_ANNOUNCER );
- CG_CenterPrint( "The Overmind is under attack!", 200, GIANTCHAR_WIDTH * 4 );
- }
- break;
-
- case EV_OVERMIND_DYING:
- DEBUGNAME( "EV_OVERMIND_DYING" );
- if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS )
- {
- trap_S_StartLocalSound( cgs.media.alienOvermindDying, CHAN_ANNOUNCER );
- CG_CenterPrint( "The Overmind is dying!", 200, GIANTCHAR_WIDTH * 4 );
- }
- break;
-
- case EV_DCC_ATTACK:
- DEBUGNAME( "EV_DCC_ATTACK" );
- if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS )
- {
- //trap_S_StartLocalSound( cgs.media.humanDCCAttack, CHAN_ANNOUNCER );
- CG_CenterPrint( "Our base is under attack!", 200, GIANTCHAR_WIDTH * 4 );
- }
- break;
-
- case EV_OVERMIND_SPAWNS:
- DEBUGNAME( "EV_OVERMIND_SPAWNS" );
- if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS )
- {
- trap_S_StartLocalSound( cgs.media.alienOvermindSpawns, CHAN_ANNOUNCER );
- CG_CenterPrint( "The Overmind needs spawns!", 200, GIANTCHAR_WIDTH * 4 );
- }
- break;
-
- case EV_ALIEN_EVOLVE:
- DEBUGNAME( "EV_ALIEN_EVOLVE" );
- trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.alienEvolveSound );
- {
- particleSystem_t *ps = CG_SpawnNewParticleSystem( cgs.media.alienEvolvePS );
-
- if( CG_IsParticleSystemValid( &ps ) )
- {
- CG_SetAttachmentCent( &ps->attachment, cent );
- CG_AttachToCent( &ps->attachment );
- }
- }
-
- if( es->number == cg.clientNum )
- {
- CG_ResetPainBlend( );
- cg.spawnTime = cg.time;
- }
- break;
-
- case EV_ALIEN_EVOLVE_FAILED:
- DEBUGNAME( "EV_ALIEN_EVOLVE_FAILED" );
- if( clientNum == cg.predictedPlayerState.clientNum )
- {
- //FIXME: change to "negative" sound
- trap_S_StartLocalSound( cgs.media.buildableRepairedSound, CHAN_LOCAL_SOUND );
- cg.lastEvolveAttempt = cg.time;
- }
- break;
-
- case EV_ALIEN_ACIDTUBE:
- DEBUGNAME( "EV_ALIEN_ACIDTUBE" );
- {
- particleSystem_t *ps = CG_SpawnNewParticleSystem( cgs.media.alienAcidTubePS );
-
- if( CG_IsParticleSystemValid( &ps ) )
- {
- CG_SetAttachmentCent( &ps->attachment, cent );
- ByteToDir( es->eventParm, dir );
- CG_SetParticleSystemNormal( ps, dir );
- CG_AttachToCent( &ps->attachment );
- }
- }
- break;
-
- case EV_MEDKIT_USED:
- DEBUGNAME( "EV_MEDKIT_USED" );
- trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.medkitUseSound );
- break;
-
- case EV_PLAYER_RESPAWN:
- DEBUGNAME( "EV_PLAYER_RESPAWN" );
- if( es->number == cg.clientNum )
- cg.spawnTime = cg.time;
- break;
-
- default:
- DEBUGNAME( "UNKNOWN" );
- CG_Error( "Unknown event: %i", event );
- break;
- }
-}
-
-
-/*
-==============
-CG_CheckEvents
-
-==============
-*/
-void CG_CheckEvents( centity_t *cent )
-{
- entity_event_t event;
- entity_event_t oldEvent = EV_NONE;
-
- // check for event-only entities
- if( cent->currentState.eType > ET_EVENTS )
- {
- event = cent->currentState.eType - ET_EVENTS;
-
- if( cent->previousEvent )
- return; // already fired
-
- cent->previousEvent = 1;
-
- cent->currentState.event = cent->currentState.eType - ET_EVENTS;
-
- // Move the pointer to the entity that the
- // event was originally attached to
- if( cent->currentState.eFlags & EF_PLAYER_EVENT )
- {
- cent = &cg_entities[ cent->currentState.otherEntityNum ];
- oldEvent = cent->currentState.event;
- cent->currentState.event = event;
- }
- }
- else
- {
- // check for events riding with another entity
- if( cent->currentState.event == cent->previousEvent )
- return;
-
- cent->previousEvent = cent->currentState.event;
- if( ( cent->currentState.event & ~EV_EVENT_BITS ) == 0 )
- return;
- }
-
- // calculate the position at exactly the frame time
- BG_EvaluateTrajectory( &cent->currentState.pos, cg.snap->serverTime, cent->lerpOrigin );
- CG_SetEntitySoundPosition( cent );
-
- CG_EntityEvent( cent, cent->lerpOrigin );
-
- // If this was a reattached spilled event, restore the original event
- if( oldEvent != EV_NONE )
- cent->currentState.event = oldEvent;
-}
-
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
deleted file mode 100644
index 88df61ba..00000000
--- a/src/cgame/cg_local.h
+++ /dev/null
@@ -1,2003 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "../game/q_shared.h"
-#include "tr_types.h"
-#include "../game/bg_public.h"
-#include "cg_public.h"
-#include "../ui/ui_shared.h"
-
-// The entire cgame module is unloaded and reloaded on each level change,
-// so there is NO persistant data between levels on the client side.
-// If you absolutely need something stored, it can either be kept
-// by the server in the server stored userinfos, or stashed in a cvar.
-
-#define CG_FONT_THRESHOLD 0.1
-
-#define POWERUP_BLINKS 5
-
-#define POWERUP_BLINK_TIME 1000
-#define FADE_TIME 200
-#define PULSE_TIME 200
-#define DAMAGE_DEFLECT_TIME 100
-#define DAMAGE_RETURN_TIME 400
-#define DAMAGE_TIME 500
-#define LAND_DEFLECT_TIME 150
-#define LAND_RETURN_TIME 300
-#define DUCK_TIME 100
-#define PAIN_TWITCH_TIME 200
-#define WEAPON_SELECT_TIME 1400
-#define ITEM_SCALEUP_TIME 1000
-#define ZOOM_TIME 150
-#define ITEM_BLOB_TIME 200
-#define MUZZLE_FLASH_TIME 20
-#define SINK_TIME 1000 // time for fragments to sink into ground before going away
-#define ATTACKER_HEAD_TIME 10000
-#define REWARD_TIME 3000
-
-#define PULSE_SCALE 1.5 // amount to scale up the icons when activating
-
-#define MAX_STEP_CHANGE 32
-
-#define MAX_VERTS_ON_POLY 10
-#define MAX_MARK_POLYS 256
-
-#define STAT_MINUS 10 // num frame for '-' stats digit
-
-#define ICON_SIZE 48
-#define CHAR_WIDTH 32
-#define CHAR_HEIGHT 48
-#define TEXT_ICON_SPACE 4
-
-#define TEAMCHAT_WIDTH 80
-#define TEAMCHAT_HEIGHT 8
-
-// very large characters
-#define GIANT_WIDTH 32
-#define GIANT_HEIGHT 48
-
-#define NUM_CROSSHAIRS 10
-
-#define TEAM_OVERLAY_MAXNAME_WIDTH 12
-#define TEAM_OVERLAY_MAXLOCATION_WIDTH 16
-
-#define DEFAULT_MODEL "sarge"
-#define DEFAULT_TEAM_MODEL "sarge"
-#define DEFAULT_TEAM_HEAD "sarge"
-
-#define DEFAULT_REDTEAM_NAME "Stroggs"
-#define DEFAULT_BLUETEAM_NAME "Pagans"
-
-typedef enum
-{
- FOOTSTEP_NORMAL,
- FOOTSTEP_BOOT,
- FOOTSTEP_FLESH,
- FOOTSTEP_MECH,
- FOOTSTEP_ENERGY,
- FOOTSTEP_METAL,
- FOOTSTEP_SPLASH,
- FOOTSTEP_CUSTOM,
- FOOTSTEP_NONE,
-
- FOOTSTEP_TOTAL
-} footstep_t;
-
-typedef enum
-{
- IMPACTSOUND_DEFAULT,
- IMPACTSOUND_METAL,
- IMPACTSOUND_FLESH
-} impactSound_t;
-
-typedef enum
-{
- JPS_OFF,
- JPS_DESCENDING,
- JPS_HOVERING,
- JPS_ASCENDING
-} jetPackState_t;
-
-//======================================================================
-
-// when changing animation, set animationTime to frameTime + lerping time
-// The current lerp will finish out, then it will lerp to the new animation
-typedef struct
-{
- int oldFrame;
- int oldFrameTime; // time when ->oldFrame was exactly on
-
- int frame;
- int frameTime; // time when ->frame will be exactly on
-
- float backlerp;
-
- float yawAngle;
- qboolean yawing;
- float pitchAngle;
- qboolean pitching;
-
- int animationNumber; // may include ANIM_TOGGLEBIT
- animation_t *animation;
- int animationTime; // time when the first frame of the animation will be exact
-} lerpFrame_t;
-
-//======================================================================
-
-//attachment system
-typedef enum
-{
- AT_STATIC,
- AT_TAG,
- AT_CENT,
- AT_PARTICLE
-} attachmentType_t;
-
-//forward declaration for particle_t
-struct particle_s;
-
-typedef struct attachment_s
-{
- attachmentType_t type;
- qboolean attached;
-
- qboolean staticValid;
- qboolean tagValid;
- qboolean centValid;
- qboolean particleValid;
-
- qboolean hasOffset;
- vec3_t offset;
-
- vec3_t lastValidAttachmentPoint;
-
- //AT_STATIC
- vec3_t origin;
-
- //AT_TAG
- refEntity_t re; //FIXME: should be pointers?
- refEntity_t parent; //
- qhandle_t model;
- char tagName[ MAX_STRING_CHARS ];
-
- //AT_CENT
- int centNum;
-
- //AT_PARTICLE
- struct particle_s *particle;
-} attachment_t;
-
-//======================================================================
-
-//particle system stuff
-#define MAX_PS_SHADER_FRAMES 32
-#define MAX_PS_MODELS 8
-#define MAX_EJECTORS_PER_SYSTEM 4
-#define MAX_PARTICLES_PER_EJECTOR 4
-
-#define MAX_BASEPARTICLE_SYSTEMS 192
-#define MAX_BASEPARTICLE_EJECTORS MAX_BASEPARTICLE_SYSTEMS*MAX_EJECTORS_PER_SYSTEM
-#define MAX_BASEPARTICLES MAX_BASEPARTICLE_EJECTORS*MAX_PARTICLES_PER_EJECTOR
-
-#define MAX_PARTICLE_SYSTEMS 48
-#define MAX_PARTICLE_EJECTORS MAX_PARTICLE_SYSTEMS*MAX_EJECTORS_PER_SYSTEM
-#define MAX_PARTICLES MAX_PARTICLE_EJECTORS*5
-
-#define PARTICLES_INFINITE -1
-#define PARTICLES_SAME_AS_INITIAL -2
-
-//COMPILE TIME STRUCTURES
-typedef enum
-{
- PMT_STATIC,
- PMT_STATIC_TRANSFORM,
- PMT_TAG,
- PMT_CENT_ANGLES,
- PMT_NORMAL
-} pMoveType_t;
-
-typedef enum
-{
- PMD_LINEAR,
- PMD_POINT
-} pDirType_t;
-
-typedef struct pMoveValues_u
-{
- pDirType_t dirType;
-
- //PMD_LINEAR
- vec3_t dir;
- float dirRandAngle;
-
- //PMD_POINT
- vec3_t point;
- float pointRandAngle;
-
- float mag;
- float magRandFrac;
-
- float parentVelFrac;
- float parentVelFracRandFrac;
-} pMoveValues_t;
-
-typedef struct pLerpValues_s
-{
- int delay;
- float delayRandFrac;
-
- float initial;
- float initialRandFrac;
-
- float final;
- float finalRandFrac;
-
- float randFrac;
-} pLerpValues_t;
-
-//particle template
-typedef struct baseParticle_s
-{
- vec3_t displacement;
- float randDisplacement;
- float normalDisplacement;
-
- pMoveType_t velMoveType;
- pMoveValues_t velMoveValues;
-
- pMoveType_t accMoveType;
- pMoveValues_t accMoveValues;
-
- int lifeTime;
- float lifeTimeRandFrac;
-
- float bounceFrac;
- float bounceFracRandFrac;
- qboolean bounceCull;
-
- char bounceMarkName[ MAX_QPATH ];
- qhandle_t bounceMark;
- float bounceMarkRadius;
- float bounceMarkRadiusRandFrac;
- float bounceMarkCount;
- float bounceMarkCountRandFrac;
-
- char bounceSoundName[ MAX_QPATH ];
- qhandle_t bounceSound;
- float bounceSoundCount;
- float bounceSoundCountRandFrac;
-
- pLerpValues_t radius;
- pLerpValues_t alpha;
- pLerpValues_t rotation;
-
- qboolean dynamicLight;
- pLerpValues_t dLightRadius;
- byte dLightColor[ 3 ];
-
- int colorDelay;
- float colorDelayRandFrac;
- byte initialColor[ 3 ];
- byte finalColor[ 3 ];
-
- char childSystemName[ MAX_QPATH ];
- qhandle_t childSystemHandle;
-
- char onDeathSystemName[ MAX_QPATH ];
- qhandle_t onDeathSystemHandle;
-
- char childTrailSystemName[ MAX_QPATH ];
- qhandle_t childTrailSystemHandle;
-
- //particle invariant stuff
- char shaderNames[ MAX_PS_SHADER_FRAMES ][ MAX_QPATH ];
- qhandle_t shaders[ MAX_PS_SHADER_FRAMES ];
- int numFrames;
- float framerate;
-
- char modelNames[ MAX_PS_MODELS ][ MAX_QPATH ];
- qhandle_t models[ MAX_PS_MODELS ];
- int numModels;
- animation_t modelAnimation;
-
- qboolean overdrawProtection;
- qboolean realLight;
- qboolean cullOnStartSolid;
-} baseParticle_t;
-
-
-//ejector template
-typedef struct baseParticleEjector_s
-{
- baseParticle_t *particles[ MAX_PARTICLES_PER_EJECTOR ];
- int numParticles;
-
- pLerpValues_t eject; //zero period indicates creation of all particles at once
-
- int totalParticles; //can be infinite
- float totalParticlesRandFrac;
-} baseParticleEjector_t;
-
-
-//particle system template
-typedef struct baseParticleSystem_s
-{
- char name[ MAX_QPATH ];
- baseParticleEjector_t *ejectors[ MAX_EJECTORS_PER_SYSTEM ];
- int numEjectors;
-
- qboolean thirdPersonOnly;
- qboolean registered; //whether or not the assets for this particle have been loaded
-} baseParticleSystem_t;
-
-
-//RUN TIME STRUCTURES
-typedef struct particleSystem_s
-{
- baseParticleSystem_t *class;
-
- attachment_t attachment;
-
- qboolean valid;
- qboolean lazyRemove; //mark this system for later removal
-
- //for PMT_NORMAL
- qboolean normalValid;
- vec3_t normal;
-} particleSystem_t;
-
-
-typedef struct particleEjector_s
-{
- baseParticleEjector_t *class;
- particleSystem_t *parent;
-
- pLerpValues_t ejectPeriod;
-
- int count;
- int totalParticles;
-
- int nextEjectionTime;
-
- qboolean valid;
-} particleEjector_t;
-
-
-//used for actual particle evaluation
-typedef struct particle_s
-{
- baseParticle_t *class;
- particleEjector_t *parent;
-
- int birthTime;
- int lifeTime;
-
- float bounceMarkRadius;
- int bounceMarkCount;
- int bounceSoundCount;
- qboolean atRest;
-
- vec3_t origin;
- vec3_t velocity;
-
- pMoveType_t accMoveType;
- pMoveValues_t accMoveValues;
-
- int lastEvalTime;
-
- int nextChildTime;
-
- pLerpValues_t radius;
- pLerpValues_t alpha;
- pLerpValues_t rotation;
-
- pLerpValues_t dLightRadius;
-
- int colorDelay;
-
- qhandle_t model;
- lerpFrame_t lf;
- vec3_t lastAxis[ 3 ];
-
- qboolean valid;
- int frameWhenInvalidated;
-
- int sortKey;
-} particle_t;
-
-//======================================================================
-
-//trail system stuff
-#define MAX_BEAMS_PER_SYSTEM 4
-
-#define MAX_BASETRAIL_SYSTEMS 64
-#define MAX_BASETRAIL_BEAMS MAX_BASETRAIL_SYSTEMS*MAX_BEAMS_PER_SYSTEM
-
-#define MAX_TRAIL_SYSTEMS 32
-#define MAX_TRAIL_BEAMS MAX_TRAIL_SYSTEMS*MAX_BEAMS_PER_SYSTEM
-#define MAX_TRAIL_BEAM_NODES 128
-
-#define MAX_TRAIL_BEAM_JITTERS 4
-
-typedef enum
-{
- TBTT_STRETCH,
- TBTT_REPEAT
-} trailBeamTextureType_t;
-
-typedef struct baseTrailJitter_s
-{
- float magnitude;
- int period;
-} baseTrailJitter_t;
-
-//beam template
-typedef struct baseTrailBeam_s
-{
- int numSegments;
- float frontWidth;
- float backWidth;
- float frontAlpha;
- float backAlpha;
- byte frontColor[ 3 ];
- byte backColor[ 3 ];
-
- // the time it takes for a segment to vanish (single attached only)
- int segmentTime;
-
- // the time it takes for a beam to fade out (double attached only)
- int fadeOutTime;
-
- char shaderName[ MAX_QPATH ];
- qhandle_t shader;
-
- trailBeamTextureType_t textureType;
-
- //TBTT_STRETCH
- float frontTextureCoord;
- float backTextureCoord;
-
- //TBTT_REPEAT
- float repeatLength;
- qboolean clampToBack;
-
- qboolean realLight;
-
- int numJitters;
- baseTrailJitter_t jitters[ MAX_TRAIL_BEAM_JITTERS ];
- qboolean jitterAttachments;
-} baseTrailBeam_t;
-
-
-//trail system template
-typedef struct baseTrailSystem_s
-{
- char name[ MAX_QPATH ];
- baseTrailBeam_t *beams[ MAX_BEAMS_PER_SYSTEM ];
- int numBeams;
-
- qboolean thirdPersonOnly;
- qboolean registered; //whether or not the assets for this trail have been loaded
-} baseTrailSystem_t;
-
-typedef struct trailSystem_s
-{
- baseTrailSystem_t *class;
-
- attachment_t frontAttachment;
- attachment_t backAttachment;
-
- int destroyTime;
- qboolean valid;
-} trailSystem_t;
-
-typedef struct trailBeamNode_s
-{
- vec3_t refPosition;
- vec3_t position;
-
- int timeLeft;
-
- float textureCoord;
- float halfWidth;
- byte alpha;
- byte color[ 3 ];
-
- vec2_t jitters[ MAX_TRAIL_BEAM_JITTERS ];
-
- struct trailBeamNode_s *prev;
- struct trailBeamNode_s *next;
-
- qboolean used;
-} trailBeamNode_t;
-
-typedef struct trailBeam_s
-{
- baseTrailBeam_t *class;
- trailSystem_t *parent;
-
- trailBeamNode_t nodePool[ MAX_TRAIL_BEAM_NODES ];
- trailBeamNode_t *nodes;
-
- int lastEvalTime;
-
- qboolean valid;
-
- int nextJitterTimes[ MAX_TRAIL_BEAM_JITTERS ];
-} trailBeam_t;
-
-//======================================================================
-
-// player entities need to track more information
-// than any other type of entity.
-
-// note that not every player entity is a client entity,
-// because corpses after respawn are outside the normal
-// client numbering range
-
-//TA: smoothing of view and model for WW transitions
-#define MAXSMOOTHS 32
-
-typedef struct
-{
- float time;
- float timeMod;
-
- vec3_t rotAxis;
- float rotAngle;
-} smooth_t;
-
-
-typedef struct
-{
- lerpFrame_t legs, torso, flag, nonseg;
- int painTime;
- int painDirection; // flip from 0 to 1
-
- // machinegun spinning
- float barrelAngle;
- int barrelTime;
- qboolean barrelSpinning;
-
- vec3_t lastNormal;
- vec3_t lastAxis[ 3 ];
- smooth_t sList[ MAXSMOOTHS ];
-} playerEntity_t;
-
-typedef struct lightFlareStatus_s
-{
- float lastSrcRadius; //caching of likely flare source radius
- float lastRadius; //caching of likely flare radius
- float lastRatio; //caching of likely flare ratio
- int lastTime; //last time flare was visible/occluded
- qboolean status; //flare is visble?
-} lightFlareStatus_t;
-
-//=================================================
-
-// centity_t have a direct corespondence with gentity_t in the game, but
-// only the entityState_t is directly communicated to the cgame
-typedef struct centity_s
-{
- entityState_t currentState; // from cg.frame
- entityState_t nextState; // from cg.nextFrame, if available
- qboolean interpolate; // true if next is valid to interpolate to
- qboolean currentValid; // true if cg.frame holds this entity
-
- int muzzleFlashTime; // move to playerEntity?
- int muzzleFlashTime2; // move to playerEntity?
- int muzzleFlashTime3; // move to playerEntity?
- int previousEvent;
- int teleportFlag;
-
- int trailTime; // so missile trails can handle dropped initial packets
- int dustTrailTime;
- int miscTime;
- int snapShotTime; // last time this entity was found in a snapshot
-
- playerEntity_t pe;
-
- int errorTime; // decay the error from this time
- vec3_t errorOrigin;
- vec3_t errorAngles;
-
- qboolean extrapolated; // false if origin / angles is an interpolation
- vec3_t rawOrigin;
- vec3_t rawAngles;
-
- vec3_t beamEnd;
-
- // exact interpolated position of entity on this frame
- vec3_t lerpOrigin;
- vec3_t lerpAngles;
-
- lerpFrame_t lerpFrame;
-
- //TA:
- buildableAnimNumber_t buildableAnim; //persistant anim number
- buildableAnimNumber_t oldBuildableAnim; //to detect when new anims are set
- particleSystem_t *buildablePS;
- float lastBuildableHealthScale;
- int lastBuildableDamageSoundTime;
-
- lightFlareStatus_t lfs;
-
- qboolean doorState;
-
- particleSystem_t *muzzlePS;
- qboolean muzzlePsTrigger;
-
- particleSystem_t *jetPackPS;
- jetPackState_t jetPackState;
-
- particleSystem_t *entityPS;
- qboolean entityPSMissing;
-
- trailSystem_t *level2ZapTS[ 3 ];
-
- trailSystem_t *muzzleTS; //used for the tesla and reactor
- int muzzleTSDeathTime;
-
- qboolean valid;
- qboolean oldValid;
-} centity_t;
-
-
-//======================================================================
-
-typedef struct markPoly_s
-{
- struct markPoly_s *prevMark, *nextMark;
- int time;
- qhandle_t markShader;
- qboolean alphaFade; // fade alpha instead of rgb
- float color[ 4 ];
- poly_t poly;
- polyVert_t verts[ MAX_VERTS_ON_POLY ];
-} markPoly_t;
-
-//======================================================================
-
-
-typedef struct
-{
- int client;
- int score;
- int ping;
- int time;
- int team;
- weapon_t weapon;
- upgrade_t upgrade;
-} score_t;
-
-// each client has an associated clientInfo_t
-// that contains media references necessary to present the
-// client model and other color coded effects
-// this is regenerated each time a client's configstring changes,
-// usually as a result of a userinfo (name, model, etc) change
-#define MAX_CUSTOM_SOUNDS 32
-typedef struct
-{
- qboolean infoValid;
-
- char name[ MAX_QPATH ];
- pTeam_t team;
-
- int botSkill; // 0 = not bot, 1-5 = bot
-
- vec3_t color1;
- vec3_t color2;
-
- int score; // updated by score servercmds
- int location; // location index for team mode
- int health; // you only get this info about your teammates
- int armor;
- int curWeapon;
-
- int handicap;
- int wins, losses; // in tourney mode
-
- int teamTask; // task in teamplay (offence/defence)
- qboolean teamLeader; // true when this is a team leader
-
- int powerups; // so can display quad/flag status
-
- int medkitUsageTime;
- int invulnerabilityStartTime;
- int invulnerabilityStopTime;
-
- int breathPuffTime;
-
- // when clientinfo is changed, the loading of models/skins/sounds
- // can be deferred until you are dead, to prevent hitches in
- // gameplay
- char modelName[ MAX_QPATH ];
- char skinName[ MAX_QPATH ];
- char headModelName[ MAX_QPATH ];
- char headSkinName[ MAX_QPATH ];
- char redTeam[ MAX_TEAMNAME ];
- char blueTeam[ MAX_TEAMNAME ];
-
- qboolean newAnims; // true if using the new mission pack animations
- qboolean fixedlegs; // true if legs yaw is always the same as torso yaw
- qboolean fixedtorso; // true if torso never changes yaw
- qboolean nonsegmented; // true if model is Q2 style nonsegmented
-
- vec3_t headOffset; // move head in icon views
- footstep_t footsteps;
- gender_t gender; // from model
-
- qhandle_t legsModel;
- qhandle_t legsSkin;
-
- qhandle_t torsoModel;
- qhandle_t torsoSkin;
-
- qhandle_t headModel;
- qhandle_t headSkin;
-
- qhandle_t nonSegModel; //non-segmented model system
- qhandle_t nonSegSkin; //non-segmented model system
-
- qhandle_t modelIcon;
-
- animation_t animations[ MAX_PLAYER_TOTALANIMATIONS ];
-
- sfxHandle_t sounds[ MAX_CUSTOM_SOUNDS ];
-
- sfxHandle_t customFootsteps[ 4 ];
- sfxHandle_t customMetalFootsteps[ 4 ];
-} clientInfo_t;
-
-
-typedef struct weaponInfoMode_s
-{
- float flashDlight;
- vec3_t flashDlightColor;
- sfxHandle_t flashSound[ 4 ]; // fast firing weapons randomly choose
- qboolean continuousFlash;
-
- qhandle_t missileModel;
- sfxHandle_t missileSound;
- float missileDlight;
- vec3_t missileDlightColor;
- int missileRenderfx;
- qboolean usesSpriteMissle;
- qhandle_t missileSprite;
- int missileSpriteSize;
- qhandle_t missileParticleSystem;
- qhandle_t missileTrailSystem;
- qboolean missileRotates;
- qboolean missileAnimates;
- int missileAnimStartFrame;
- int missileAnimNumFrames;
- int missileAnimFrameRate;
- int missileAnimLooping;
-
- sfxHandle_t firingSound;
- qboolean loopFireSound;
-
- qhandle_t muzzleParticleSystem;
-
- qboolean alwaysImpact;
- qhandle_t impactParticleSystem;
- qhandle_t impactMark;
- qhandle_t impactMarkSize;
- sfxHandle_t impactSound[ 4 ]; //random impact sound
- sfxHandle_t impactFleshSound[ 4 ]; //random impact sound
-} weaponInfoMode_t;
-
-// each WP_* weapon enum has an associated weaponInfo_t
-// that contains media references necessary to present the
-// weapon and its effects
-typedef struct weaponInfo_s
-{
- qboolean registered;
- char *humanName;
-
- qhandle_t handsModel; // the hands don't actually draw, they just position the weapon
- qhandle_t weaponModel;
- qhandle_t barrelModel;
- qhandle_t flashModel;
-
- vec3_t weaponMidpoint; // so it will rotate centered instead of by tag
-
- qhandle_t weaponIcon;
- qhandle_t ammoIcon;
-
- qhandle_t crossHair;
- int crossHairSize;
-
- sfxHandle_t readySound;
-
- qboolean disableIn3rdPerson;
-
- weaponInfoMode_t wim[ WPM_NUM_WEAPONMODES ];
-} weaponInfo_t;
-
-typedef struct upgradeInfo_s
-{
- qboolean registered;
- char *humanName;
-
- qhandle_t upgradeIcon;
-} upgradeInfo_t;
-
-typedef struct
-{
- qboolean looped;
- qboolean enabled;
-
- sfxHandle_t sound;
-} sound_t;
-
-typedef struct
-{
- qhandle_t models[ MAX_BUILDABLE_MODELS ];
- animation_t animations[ MAX_BUILDABLE_ANIMATIONS ];
-
- //same number of sounds as animations
- sound_t sounds[ MAX_BUILDABLE_ANIMATIONS ];
-} buildableInfo_t;
-
-#define MAX_REWARDSTACK 10
-#define MAX_SOUNDBUFFER 20
-
-//======================================================================
-
-//TA:
-typedef struct
-{
- vec3_t alienBuildablePos[ MAX_GENTITIES ];
- int alienBuildableTimes[ MAX_GENTITIES ];
- int numAlienBuildables;
-
- vec3_t humanBuildablePos[ MAX_GENTITIES ];
- int numHumanBuildables;
-
- vec3_t alienClientPos[ MAX_CLIENTS ];
- int numAlienClients;
-
- vec3_t humanClientPos[ MAX_CLIENTS ];
- int numHumanClients;
-
- int lastUpdateTime;
- vec3_t origin;
- vec3_t vangles;
-} entityPos_t;
-
-typedef struct
-{
- int time;
- int length;
-} consoleLine_t;
-
-#define MAX_CONSOLE_TEXT 8192
-#define MAX_CONSOLE_LINES 32
-
-// all cg.stepTime, cg.duckTime, cg.landTime, etc are set to cg.time when the action
-// occurs, and they will have visible effects for #define STEP_TIME or whatever msec after
-
-#define MAX_PREDICTED_EVENTS 16
-
-typedef struct
-{
- int clientFrame; // incremented each frame
-
- int clientNum;
-
- qboolean demoPlayback;
- qboolean levelShot; // taking a level menu screenshot
- int deferredPlayerLoading;
- qboolean loading; // don't defer players at initial startup
- qboolean intermissionStarted; // don't play voice rewards, because game will end shortly
-
- // there are only one or two snapshot_t that are relevent at a time
- int latestSnapshotNum; // the number of snapshots the client system has received
- int latestSnapshotTime; // the time from latestSnapshotNum, so we don't need to read the snapshot yet
-
- snapshot_t *snap; // cg.snap->serverTime <= cg.time
- snapshot_t *nextSnap; // cg.nextSnap->serverTime > cg.time, or NULL
- snapshot_t activeSnapshots[ 2 ];
-
- float frameInterpolation; // (float)( cg.time - cg.frame->serverTime ) /
- // (cg.nextFrame->serverTime - cg.frame->serverTime)
-
- qboolean thisFrameTeleport;
- qboolean nextFrameTeleport;
-
- int frametime; // cg.time - cg.oldTime
-
- int time; // this is the time value that the client
- // is rendering at.
- int oldTime; // time at last frame, used for missile trails and prediction checking
-
- int physicsTime; // either cg.snap->time or cg.nextSnap->time
-
- int timelimitWarnings; // 5 min, 1 min, overtime
- int fraglimitWarnings;
-
- qboolean mapRestart; // set on a map restart to set back the weapon
-
- qboolean renderingThirdPerson; // during deaths, chasecams, etc
-
- // prediction state
- qboolean hyperspace; // true if prediction has hit a trigger_teleport
- playerState_t predictedPlayerState;
- centity_t predictedPlayerEntity;
- qboolean validPPS; // clear until the first call to CG_PredictPlayerState
- int predictedErrorTime;
- vec3_t predictedError;
-
- int eventSequence;
- int predictableEvents[MAX_PREDICTED_EVENTS];
-
- float stepChange; // for stair up smoothing
- int stepTime;
-
- float duckChange; // for duck viewheight smoothing
- int duckTime;
-
- float landChange; // for landing hard
- int landTime;
-
- // input state sent to server
- int weaponSelect;
-
- // auto rotating items
- vec3_t autoAngles;
- vec3_t autoAxis[ 3 ];
- vec3_t autoAnglesFast;
- vec3_t autoAxisFast[ 3 ];
-
- // view rendering
- refdef_t refdef;
- vec3_t refdefViewAngles; // will be converted to refdef.viewaxis
-
- // zoom key
- qboolean zoomed;
- int zoomTime;
- float zoomSensitivity;
-
- // information screen text during loading
- char infoScreenText[ MAX_STRING_CHARS ];
-
- // scoreboard
- int scoresRequestTime;
- int numScores;
- int selectedScore;
- int teamScores[ 2 ];
- score_t scores[MAX_CLIENTS];
- qboolean showScores;
- qboolean scoreBoardShowing;
- int scoreFadeTime;
- char killerName[ MAX_NAME_LENGTH ];
- char spectatorList[ MAX_STRING_CHARS ]; // list of names
- int spectatorLen; // length of list
- float spectatorWidth; // width in device units
- int spectatorTime; // next time to offset
- int spectatorPaintX; // current paint x
- int spectatorPaintX2; // current paint x
- int spectatorOffset; // current offset from start
- int spectatorPaintLen; // current offset from start
-
- // centerprinting
- int centerPrintTime;
- int centerPrintCharWidth;
- int centerPrintY;
- char centerPrint[ 1024 ];
- int centerPrintLines;
-
- // low ammo warning state
- int lowAmmoWarning; // 1 = low, 2 = empty
-
- // kill timers for carnage reward
- int lastKillTime;
-
- // crosshair client ID
- int crosshairClientNum;
- int crosshairClientTime;
-
- // powerup active flashing
- int powerupActive;
- int powerupTime;
-
- // attacking player
- int attackerTime;
- int voiceTime;
-
- // reward medals
- int rewardStack;
- int rewardTime;
- int rewardCount[ MAX_REWARDSTACK ];
- qhandle_t rewardShader[ MAX_REWARDSTACK ];
- qhandle_t rewardSound[ MAX_REWARDSTACK ];
-
- // sound buffer mainly for announcer sounds
- int soundBufferIn;
- int soundBufferOut;
- int soundTime;
- qhandle_t soundBuffer[ MAX_SOUNDBUFFER ];
-
- // for voice chat buffer
- int voiceChatTime;
- int voiceChatBufferIn;
- int voiceChatBufferOut;
-
- // warmup countdown
- int warmup;
- int warmupCount;
-
- //==========================
-
- int itemPickup;
- int itemPickupTime;
- int itemPickupBlendTime; // the pulse around the crosshair is timed seperately
-
- int weaponSelectTime;
- int weaponAnimation;
- int weaponAnimationTime;
-
- // blend blobs
- float damageTime;
- float damageX, damageY, damageValue;
-
- // status bar head
- float headYaw;
- float headEndPitch;
- float headEndYaw;
- int headEndTime;
- float headStartPitch;
- float headStartYaw;
- int headStartTime;
-
- // view movement
- float v_dmg_time;
- float v_dmg_pitch;
- float v_dmg_roll;
-
- vec3_t kick_angles; // weapon kicks
- vec3_t kick_origin;
-
- // temp working variables for player view
- float bobfracsin;
- int bobcycle;
- float xyspeed;
- int nextOrbitTime;
-
- // development tool
- refEntity_t testModelEntity;
- refEntity_t testModelBarrelEntity;
- char testModelName[MAX_QPATH];
- char testModelBarrelName[MAX_QPATH];
- qboolean testGun;
-
- int spawnTime; //TA: fovwarp
- int weapon1Time; //TA: time when BUTTON_ATTACK went t->f f->t
- int weapon2Time; //TA: time when BUTTON_ATTACK2 went t->f f->t
- int weapon3Time; //TA: time when BUTTON_USE_HOLDABLE went t->f f->t
- qboolean weapon1Firing;
- qboolean weapon2Firing;
- qboolean weapon3Firing;
-
- int poisonedTime;
-
- vec3_t lastNormal; //TA: view smoothage
- vec3_t lastVangles; //TA: view smoothage
- smooth_t sList[ MAXSMOOTHS ]; //TA: WW smoothing
-
- int forwardMoveTime; //TA: for struggling
- int rightMoveTime;
- int upMoveTime;
-
- float charModelFraction; //TA: loading percentages
- float mediaFraction;
- float buildablesFraction;
-
- int lastBuildAttempt;
- int lastEvolveAttempt;
-
- char consoleText[ MAX_CONSOLE_TEXT ];
- consoleLine_t consoleLines[ MAX_CONSOLE_LINES ];
- int numConsoleLines;
- qboolean consoleValid;
-
- particleSystem_t *poisonCloudPS;
-
- float painBlendValue;
- float painBlendTarget;
- int lastHealth;
-} cg_t;
-
-
-// all of the model, shader, and sound references that are
-// loaded at gamestate time are stored in cgMedia_t
-// Other media that can be tied to clients, weapons, or items are
-// stored in the clientInfo_t, itemInfo_t, weaponInfo_t, and powerupInfo_t
-typedef struct
-{
- qhandle_t charsetShader;
- qhandle_t whiteShader;
- qhandle_t outlineShader;
-
- qhandle_t level2ZapTS;
-
- qhandle_t balloonShader;
- qhandle_t connectionShader;
-
- qhandle_t selectShader;
- qhandle_t viewBloodShader;
- qhandle_t tracerShader;
- qhandle_t crosshairShader[ WP_NUM_WEAPONS ];
- qhandle_t backTileShader;
-
- qhandle_t creepShader;
-
- qhandle_t scannerShader;
- qhandle_t scannerBlipShader;
- qhandle_t scannerLineShader;
-
-
- qhandle_t numberShaders[ 11 ];
-
- qhandle_t shadowMarkShader;
- qhandle_t wakeMarkShader;
-
- // buildable shaders
- qhandle_t greenBuildShader;
- qhandle_t redBuildShader;
- qhandle_t noPowerShader;
- qhandle_t humanSpawningShader;
-
- // disconnect
- qhandle_t disconnectPS;
- qhandle_t disconnectSound;
-
- // sounds
- sfxHandle_t tracerSound;
- sfxHandle_t selectSound;
- sfxHandle_t footsteps[ FOOTSTEP_TOTAL ][ 4 ];
- sfxHandle_t talkSound;
- sfxHandle_t landSound;
- sfxHandle_t fallSound;
-
- sfxHandle_t hgrenb1aSound;
- sfxHandle_t hgrenb2aSound;
-
- sfxHandle_t voteNow;
- sfxHandle_t votePassed;
- sfxHandle_t voteFailed;
-
- sfxHandle_t watrInSound;
- sfxHandle_t watrOutSound;
- sfxHandle_t watrUnSound;
-
- sfxHandle_t jetpackDescendSound;
- sfxHandle_t jetpackIdleSound;
- sfxHandle_t jetpackAscendSound;
-
- qhandle_t jetPackDescendPS;
- qhandle_t jetPackHoverPS;
- qhandle_t jetPackAscendPS;
-
- sfxHandle_t medkitUseSound;
-
- sfxHandle_t alienStageTransition;
- sfxHandle_t humanStageTransition;
-
- sfxHandle_t alienOvermindAttack;
- sfxHandle_t alienOvermindDying;
- sfxHandle_t alienOvermindSpawns;
-
- sfxHandle_t alienBuildableExplosion;
- sfxHandle_t alienBuildableDamage;
- sfxHandle_t alienBuildablePrebuild;
- sfxHandle_t humanBuildableExplosion;
- sfxHandle_t humanBuildablePrebuild;
- sfxHandle_t humanBuildableDamage[ 4 ];
-
- sfxHandle_t alienL1Grab;
- sfxHandle_t alienL4ChargePrepare;
- sfxHandle_t alienL4ChargeStart;
-
- qhandle_t cursor;
- qhandle_t selectCursor;
- qhandle_t sizeCursor;
-
- //light armour
- qhandle_t larmourHeadSkin;
- qhandle_t larmourLegsSkin;
- qhandle_t larmourTorsoSkin;
-
- qhandle_t jetpackModel;
- qhandle_t jetpackFlashModel;
- qhandle_t battpackModel;
-
- sfxHandle_t repeaterUseSound;
-
- sfxHandle_t buildableRepairSound;
- sfxHandle_t buildableRepairedSound;
-
- qhandle_t poisonCloudPS;
- qhandle_t alienEvolvePS;
- qhandle_t alienAcidTubePS;
-
- sfxHandle_t alienEvolveSound;
-
- qhandle_t humanBuildableDamagedPS;
- qhandle_t humanBuildableDestroyedPS;
- qhandle_t alienBuildableDamagedPS;
- qhandle_t alienBuildableDestroyedPS;
-
- qhandle_t alienBleedPS;
- qhandle_t humanBleedPS;
-
- qhandle_t teslaZapTS;
-
- sfxHandle_t lCannonWarningSound;
-
- qhandle_t buildWeaponTimerPie[ 8 ];
- qhandle_t upgradeClassIconShader;
-} cgMedia_t;
-
-
-// The client game static (cgs) structure hold everything
-// loaded or calculated from the gamestate. It will NOT
-// be cleared when a tournement restart is done, allowing
-// all clients to begin playing instantly
-typedef struct
-{
- gameState_t gameState; // gamestate from server
- glconfig_t glconfig; // rendering configuration
- float screenXScale; // derived from glconfig
- float screenYScale;
- float screenXBias;
-
- int serverCommandSequence; // reliable command stream counter
- int processedSnapshotNum; // the number of snapshots cgame has requested
-
- qboolean localServer; // detected on startup by checking sv_running
-
- // parsed from serverinfo
- int dmflags;
- int teamflags;
- int timelimit;
- int maxclients;
- char mapname[ MAX_QPATH ];
-
- int voteTime;
- int voteYes;
- int voteNo;
- qboolean voteModified; // beep whenever changed
- char voteString[ MAX_STRING_TOKENS ];
-
- int teamVoteTime[ 2 ];
- int teamVoteYes[ 2 ];
- int teamVoteNo[ 2 ];
- qboolean teamVoteModified[ 2 ]; // beep whenever changed
- char teamVoteString[ 2 ][ MAX_STRING_TOKENS ];
-
- int levelStartTime;
-
- int scores1, scores2; // from configstrings
-
- qboolean newHud;
-
- int alienBuildPoints;
- int alienBuildPointsTotal;
- int humanBuildPoints;
- int humanBuildPointsTotal;
- int humanBuildPointsPowered;
-
- int alienStage;
- int humanStage;
- int alienKills;
- int humanKills;
- int alienNextStageThreshold;
- int humanNextStageThreshold;
-
- int numAlienSpawns;
- int numHumanSpawns;
-
- //
- // locally derived information from gamestate
- //
- qhandle_t gameModels[ MAX_MODELS ];
- qhandle_t gameShaders[ MAX_SHADERS ];
- qhandle_t gameParticleSystems[ MAX_GAME_PARTICLE_SYSTEMS ];
- sfxHandle_t gameSounds[ MAX_SOUNDS ];
-
- int numInlineModels;
- qhandle_t inlineDrawModel[ MAX_MODELS ];
- vec3_t inlineModelMidpoints[ MAX_MODELS ];
-
- clientInfo_t clientinfo[ MAX_CLIENTS ];
-
- //TA: corpse info
- clientInfo_t corpseinfo[ MAX_CLIENTS ];
-
- // teamchat width is *3 because of embedded color codes
- char teamChatMsgs[ TEAMCHAT_HEIGHT ][ TEAMCHAT_WIDTH * 3 + 1 ];
- int teamChatMsgTimes[ TEAMCHAT_HEIGHT ];
- int teamChatPos;
- int teamLastChatPos;
-
- int cursorX;
- int cursorY;
- qboolean eventHandling;
- qboolean mouseCaptured;
- qboolean sizingHud;
- void *capturedItem;
- qhandle_t activeCursor;
-
- // media
- cgMedia_t media;
-} cgs_t;
-
-//==============================================================================
-
-extern cgs_t cgs;
-extern cg_t cg;
-extern centity_t cg_entities[ MAX_GENTITIES ];
-
-//TA: weapon limit expanded:
-//extern weaponInfo_t cg_weapons[MAX_WEAPONS];
-extern weaponInfo_t cg_weapons[ 32 ];
-//TA: upgrade infos:
-extern upgradeInfo_t cg_upgrades[ 32 ];
-
-//TA: buildable infos:
-extern buildableInfo_t cg_buildables[ BA_NUM_BUILDABLES ];
-
-extern markPoly_t cg_markPolys[ MAX_MARK_POLYS ];
-
-extern vmCvar_t cg_centertime;
-extern vmCvar_t cg_runpitch;
-extern vmCvar_t cg_runroll;
-extern vmCvar_t cg_bobup;
-extern vmCvar_t cg_bobpitch;
-extern vmCvar_t cg_bobroll;
-extern vmCvar_t cg_swingSpeed;
-extern vmCvar_t cg_shadows;
-extern vmCvar_t cg_gibs;
-extern vmCvar_t cg_drawTimer;
-extern vmCvar_t cg_drawFPS;
-extern vmCvar_t cg_drawSnapshot;
-extern vmCvar_t cg_draw3dIcons;
-extern vmCvar_t cg_drawIcons;
-extern vmCvar_t cg_drawAmmoWarning;
-extern vmCvar_t cg_drawCrosshair;
-extern vmCvar_t cg_drawCrosshairNames;
-extern vmCvar_t cg_drawRewards;
-extern vmCvar_t cg_drawTeamOverlay;
-extern vmCvar_t cg_teamOverlayUserinfo;
-extern vmCvar_t cg_crosshairX;
-extern vmCvar_t cg_crosshairY;
-extern vmCvar_t cg_drawStatus;
-extern vmCvar_t cg_draw2D;
-extern vmCvar_t cg_animSpeed;
-extern vmCvar_t cg_debugAnim;
-extern vmCvar_t cg_debugPosition;
-extern vmCvar_t cg_debugEvents;
-extern vmCvar_t cg_teslaTrailTime;
-extern vmCvar_t cg_railTrailTime;
-extern vmCvar_t cg_errorDecay;
-extern vmCvar_t cg_nopredict;
-extern vmCvar_t cg_debugMove;
-extern vmCvar_t cg_noPlayerAnims;
-extern vmCvar_t cg_showmiss;
-extern vmCvar_t cg_footsteps;
-extern vmCvar_t cg_addMarks;
-extern vmCvar_t cg_brassTime;
-extern vmCvar_t cg_gun_frame;
-extern vmCvar_t cg_gun_x;
-extern vmCvar_t cg_gun_y;
-extern vmCvar_t cg_gun_z;
-extern vmCvar_t cg_drawGun;
-extern vmCvar_t cg_viewsize;
-extern vmCvar_t cg_tracerChance;
-extern vmCvar_t cg_tracerWidth;
-extern vmCvar_t cg_tracerLength;
-extern vmCvar_t cg_autoswitch;
-extern vmCvar_t cg_ignore;
-extern vmCvar_t cg_simpleItems;
-extern vmCvar_t cg_fov;
-extern vmCvar_t cg_zoomFov;
-extern vmCvar_t cg_thirdPersonRange;
-extern vmCvar_t cg_thirdPersonAngle;
-extern vmCvar_t cg_thirdPerson;
-extern vmCvar_t cg_stereoSeparation;
-extern vmCvar_t cg_lagometer;
-extern vmCvar_t cg_drawAttacker;
-extern vmCvar_t cg_synchronousClients;
-extern vmCvar_t cg_teamChatTime;
-extern vmCvar_t cg_teamChatHeight;
-extern vmCvar_t cg_stats;
-extern vmCvar_t cg_forceModel;
-extern vmCvar_t cg_buildScript;
-extern vmCvar_t cg_paused;
-extern vmCvar_t cg_blood;
-extern vmCvar_t cg_predictItems;
-extern vmCvar_t cg_deferPlayers;
-extern vmCvar_t cg_drawFriend;
-extern vmCvar_t cg_teamChatsOnly;
-extern vmCvar_t cg_noVoiceChats;
-extern vmCvar_t cg_noVoiceText;
-extern vmCvar_t cg_scorePlum;
-extern vmCvar_t cg_smoothClients;
-extern vmCvar_t pmove_fixed;
-extern vmCvar_t pmove_msec;
-//extern vmCvar_t cg_pmove_fixed;
-extern vmCvar_t cg_cameraOrbit;
-extern vmCvar_t cg_cameraOrbitDelay;
-extern vmCvar_t cg_timescaleFadeEnd;
-extern vmCvar_t cg_timescaleFadeSpeed;
-extern vmCvar_t cg_timescale;
-extern vmCvar_t cg_cameraMode;
-extern vmCvar_t cg_smallFont;
-extern vmCvar_t cg_bigFont;
-extern vmCvar_t cg_noTaunt;
-extern vmCvar_t cg_noProjectileTrail;
-extern vmCvar_t cg_oldRail;
-extern vmCvar_t cg_oldRocket;
-extern vmCvar_t cg_oldPlasma;
-extern vmCvar_t cg_trueLightning;
-extern vmCvar_t cg_creepRes;
-extern vmCvar_t cg_drawSurfNormal;
-extern vmCvar_t cg_drawBBOX;
-extern vmCvar_t cg_debugAlloc;
-extern vmCvar_t cg_wwSmoothTime;
-extern vmCvar_t cg_wwFollow;
-extern vmCvar_t cg_wwToggle;
-extern vmCvar_t cg_depthSortParticles;
-extern vmCvar_t cg_consoleLatency;
-extern vmCvar_t cg_lightFlare;
-extern vmCvar_t cg_debugParticles;
-extern vmCvar_t cg_debugTrails;
-extern vmCvar_t cg_debugPVS;
-extern vmCvar_t cg_disableWarningDialogs;
-extern vmCvar_t cg_disableScannerPlane;
-
-extern vmCvar_t cg_painBlendUpRate;
-extern vmCvar_t cg_painBlendDownRate;
-extern vmCvar_t cg_painBlendMax;
-extern vmCvar_t cg_painBlendScale;
-extern vmCvar_t cg_painBlendZoom;
-
-//TA: hack to get class an carriage through to UI module
-extern vmCvar_t ui_currentClass;
-extern vmCvar_t ui_carriage;
-extern vmCvar_t ui_stages;
-extern vmCvar_t ui_dialog;
-extern vmCvar_t ui_loading;
-extern vmCvar_t ui_voteActive;
-extern vmCvar_t ui_alienTeamVoteActive;
-extern vmCvar_t ui_humanTeamVoteActive;
-
-extern vmCvar_t cg_debugRandom;
-
-//
-// cg_main.c
-//
-const char *CG_ConfigString( int index );
-const char *CG_Argv( int arg );
-
-void CG_TAUIConsole( const char *text );
-void QDECL CG_Printf( const char *msg, ... );
-void QDECL CG_Error( const char *msg, ... );
-
-void CG_StartMusic( void );
-
-void CG_UpdateCvars( void );
-
-int CG_CrosshairPlayer( void );
-int CG_LastAttacker( void );
-void CG_LoadMenus( const char *menuFile );
-void CG_KeyEvent( int key, qboolean down );
-void CG_MouseEvent( int x, int y );
-void CG_EventHandling( int type );
-void CG_SetScoreSelection( void *menu );
-void CG_BuildSpectatorString( void );
-
-qboolean CG_FileExists( char *filename );
-void CG_RemoveConsoleLine( void );
-
-
-//
-// cg_view.c
-//
-void CG_addSmoothOp( vec3_t rotAxis, float rotAngle, float timeMod ); //TA
-void CG_TestModel_f( void );
-void CG_TestGun_f( void );
-void CG_TestModelNextFrame_f( void );
-void CG_TestModelPrevFrame_f( void );
-void CG_TestModelNextSkin_f( void );
-void CG_TestModelPrevSkin_f( void );
-void CG_ZoomDown_f( void );
-void CG_ZoomUp_f( void );
-void CG_AddBufferedSound( sfxHandle_t sfx );
-void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback );
-
-
-//
-// cg_drawtools.c
-//
-void CG_DrawPlane( vec3_t origin, vec3_t down, vec3_t right, qhandle_t shader );
-void CG_AdjustFrom640( float *x, float *y, float *w, float *h );
-void CG_FillRect( float x, float y, float width, float height, const float *color );
-void CG_DrawPic( float x, float y, float width, float height, qhandle_t hShader );
-void CG_DrawFadePic( float x, float y, float width, float height, vec4_t fcolor,
- vec4_t tcolor, float amount, qhandle_t hShader );
-
-int CG_DrawStrlen( const char *str );
-
-float *CG_FadeColor( int startMsec, int totalMsec );
-void CG_TileClear( void );
-void CG_ColorForHealth( vec4_t hcolor );
-void CG_GetColorForHealth( int health, int armor, vec4_t hcolor );
-
-void CG_DrawRect( float x, float y, float width, float height, float size, const float *color );
-void CG_DrawSides(float x, float y, float w, float h, float size);
-void CG_DrawTopBottom(float x, float y, float w, float h, float size);
-
-
-//
-// cg_draw.c
-//
-extern int sortedTeamPlayers[ TEAM_MAXOVERLAY ];
-extern int numSortedTeamPlayers;
-extern char systemChat[ 256 ];
-extern char teamChat1[ 256 ];
-extern char teamChat2[ 256 ];
-
-void CG_AddLagometerFrameInfo( void );
-void CG_AddLagometerSnapshotInfo( snapshot_t *snap );
-void CG_CenterPrint( const char *str, int y, int charWidth );
-void CG_DrawActive( stereoFrame_t stereoView );
-void CG_OwnerDraw( float x, float y, float w, float h, float text_x, float text_y,
- int ownerDraw, int ownerDrawFlags, int align, float special,
- float scale, vec4_t color, qhandle_t shader, int textStyle);
-void CG_Text_Paint( float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style );
-int CG_Text_Width( const char *text, float scale, int limit );
-int CG_Text_Height( const char *text, float scale, int limit );
-float CG_GetValue(int ownerDraw);
-void CG_RunMenuScript(char **args);
-void CG_SetPrintString( int type, const char *p );
-void CG_InitTeamChat( void );
-void CG_GetTeamColor( vec4_t *color );
-const char *CG_GetKillerText();
-void CG_Text_PaintChar( float x, float y, float width, float height, float scale,
- float s, float t, float s2, float t2, qhandle_t hShader );
-void CG_DrawLoadingScreen( void );
-void CG_UpdateMediaFraction( float newFract );
-void CG_ResetPainBlend( void );
-
-//
-// cg_players.c
-//
-void CG_Player( centity_t *cent );
-void CG_Corpse( centity_t *cent );
-void CG_ResetPlayerEntity( centity_t *cent );
-void CG_AddRefEntityWithPowerups( refEntity_t *ent, int powerups, int team );
-void CG_NewClientInfo( int clientNum );
-void CG_PrecacheClientInfo( pClass_t class, char *model, char *skin );
-sfxHandle_t CG_CustomSound( int clientNum, const char *soundName );
-void CG_PlayerDisconnect( vec3_t org );
-void CG_Bleed( vec3_t origin, vec3_t normal, int entityNum );
-
-//
-// cg_buildable.c
-//
-void CG_GhostBuildable( buildable_t buildable );
-void CG_Buildable( centity_t *cent );
-void CG_InitBuildables( void );
-void CG_HumanBuildableExplosion( vec3_t origin, vec3_t dir );
-void CG_AlienBuildableExplosion( vec3_t origin, vec3_t dir );
-
-//
-// cg_animation.c
-//
-void CG_RunLerpFrame( lerpFrame_t *lf );
-
-//
-// cg_animmapobj.c
-//
-void CG_AnimMapObj( centity_t *cent );
-void CG_ModelDoor( centity_t *cent );
-
-//
-// cg_predict.c
-//
-
-#define MAGIC_TRACE_HACK -2
-
-void CG_BuildSolidList( void );
-int CG_PointContents( const vec3_t point, int passEntityNum );
-void CG_Trace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
- int skipNumber, int mask );
-void CG_CapTrace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
- int skipNumber, int mask );
-void CG_PredictPlayerState( void );
-
-
-//
-// cg_events.c
-//
-void CG_CheckEvents( centity_t *cent );
-void CG_EntityEvent( centity_t *cent, vec3_t position );
-void CG_PainEvent( centity_t *cent, int health );
-
-
-//
-// cg_ents.c
-//
-void CG_DrawBoundingBox( vec3_t origin, vec3_t mins, vec3_t maxs );
-void CG_SetEntitySoundPosition( centity_t *cent );
-void CG_AddPacketEntities( void );
-void CG_Beam( centity_t *cent );
-void CG_AdjustPositionForMover( const vec3_t in, int moverNum, int fromTime, int toTime, vec3_t out );
-
-void CG_PositionEntityOnTag( refEntity_t *entity, const refEntity_t *parent,
- qhandle_t parentModel, char *tagName );
-void CG_PositionRotatedEntityOnTag( refEntity_t *entity, const refEntity_t *parent,
- qhandle_t parentModel, char *tagName );
-
-
-
-
-//
-// cg_weapons.c
-//
-void CG_NextWeapon_f( void );
-void CG_PrevWeapon_f( void );
-void CG_Weapon_f( void );
-
-void CG_InitUpgrades( );
-void CG_RegisterUpgrade( int upgradeNum );
-void CG_InitWeapons( );
-void CG_RegisterWeapon( int weaponNum );
-
-void CG_FireWeapon( centity_t *cent, weaponMode_t weaponMode );
-void CG_MissileHitWall( weapon_t weapon, weaponMode_t weaponMode, int clientNum,
- vec3_t origin, vec3_t dir, impactSound_t soundType );
-void CG_MissileHitPlayer( weapon_t weapon, weaponMode_t weaponMode, vec3_t origin, vec3_t dir, int entityNum );
-void CG_Bullet( vec3_t origin, int sourceEntityNum, vec3_t normal, qboolean flesh, int fleshEntityNum );
-void CG_ShotgunFire( entityState_t *es );
-
-void CG_AddViewWeapon (playerState_t *ps);
-void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent );
-void CG_DrawItemSelect( rectDef_t *rect, vec4_t color );
-void CG_DrawItemSelectText( rectDef_t *rect, float scale, int textStyle );
-
-
-//
-// cg_scanner.c
-//
-void CG_UpdateEntityPositions( void );
-void CG_Scanner( rectDef_t *rect, qhandle_t shader, vec4_t color );
-void CG_AlienSense( rectDef_t *rect );
-
-//
-// cg_marks.c
-//
-void CG_InitMarkPolys( void );
-void CG_AddMarks( void );
-void CG_ImpactMark( qhandle_t markShader,
- const vec3_t origin, const vec3_t dir,
- float orientation,
- float r, float g, float b, float a,
- qboolean alphaFade,
- float radius, qboolean temporary );
-
-//
-// cg_snapshot.c
-//
-void CG_ProcessSnapshots( void );
-
-//
-// cg_consolecmds.c
-//
-qboolean CG_ConsoleCommand( void );
-void CG_InitConsoleCommands( void );
-
-//
-// cg_servercmds.c
-//
-void CG_ExecuteNewServerCommands( int latestSequence );
-void CG_ParseServerinfo( void );
-void CG_SetConfigValues( void );
-void CG_ShaderStateChanged(void);
-
-//
-// cg_playerstate.c
-//
-void CG_Respawn( void );
-void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops );
-void CG_CheckChangedPredictableEvents( playerState_t *ps );
-
-//
-// cg_mem.c
-//
-void CG_InitMemory( void );
-void *CG_Alloc( int size );
-void CG_Free( void *ptr );
-void CG_DefragmentMemory( void );
-
-//
-// cg_attachment.c
-//
-qboolean CG_AttachmentPoint( attachment_t *a, vec3_t v );
-qboolean CG_AttachmentDir( attachment_t *a, vec3_t v );
-qboolean CG_AttachmentAxis( attachment_t *a, vec3_t axis[ 3 ] );
-qboolean CG_AttachmentVelocity( attachment_t *a, vec3_t v );
-int CG_AttachmentCentNum( attachment_t *a );
-
-qboolean CG_Attached( attachment_t *a );
-
-void CG_AttachToPoint( attachment_t *a );
-void CG_AttachToCent( attachment_t *a );
-void CG_AttachToTag( attachment_t *a );
-void CG_AttachToParticle( attachment_t *a );
-void CG_SetAttachmentPoint( attachment_t *a, vec3_t v );
-void CG_SetAttachmentCent( attachment_t *a, centity_t *cent );
-void CG_SetAttachmentTag( attachment_t *a, refEntity_t parent,
- qhandle_t model, char *tagName );
-void CG_SetAttachmentParticle( attachment_t *a, particle_t *p );
-
-void CG_SetAttachmentOffset( attachment_t *a, vec3_t v );
-
-//
-// cg_particles.c
-//
-void CG_LoadParticleSystems( void );
-qhandle_t CG_RegisterParticleSystem( char *name );
-
-particleSystem_t *CG_SpawnNewParticleSystem( qhandle_t psHandle );
-void CG_DestroyParticleSystem( particleSystem_t **ps );
-
-qboolean CG_IsParticleSystemInfinite( particleSystem_t *ps );
-qboolean CG_IsParticleSystemValid( particleSystem_t **ps );
-
-void CG_SetParticleSystemNormal( particleSystem_t *ps, vec3_t normal );
-
-void CG_AddParticles( void );
-
-void CG_ParticleSystemEntity( centity_t *cent );
-
-void CG_TestPS_f( void );
-void CG_DestroyTestPS_f( void );
-
-//
-// cg_trails.c
-//
-void CG_LoadTrailSystems( void );
-qhandle_t CG_RegisterTrailSystem( char *name );
-
-trailSystem_t *CG_SpawnNewTrailSystem( qhandle_t psHandle );
-void CG_DestroyTrailSystem( trailSystem_t **ts );
-
-qboolean CG_IsTrailSystemValid( trailSystem_t **ts );
-
-void CG_AddTrails( void );
-
-void CG_TestTS_f( void );
-void CG_DestroyTestTS_f( void );
-
-//
-// cg_ptr.c
-//
-int CG_ReadPTRCode( void );
-void CG_WritePTRCode( int code );
-
-//
-//===============================================
-
-//
-// system traps
-// These functions are how the cgame communicates with the main game system
-//
-
-
-// print message on the local console
-void trap_Print( const char *fmt );
-
-// abort the game
-void trap_Error( const char *fmt );
-
-// milliseconds should only be used for performance tuning, never
-// for anything game related. Get time from the CG_DrawActiveFrame parameter
-int trap_Milliseconds( void );
-
-// console variable interaction
-void trap_Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags );
-void trap_Cvar_Update( vmCvar_t *vmCvar );
-void trap_Cvar_Set( const char *var_name, const char *value );
-void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize );
-
-// ServerCommand and ConsoleCommand parameter access
-int trap_Argc( void );
-void trap_Argv( int n, char *buffer, int bufferLength );
-void trap_Args( char *buffer, int bufferLength );
-
-// filesystem access
-// returns length of file
-int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode );
-void trap_FS_Read( void *buffer, int len, fileHandle_t f );
-void trap_FS_Write( const void *buffer, int len, fileHandle_t f );
-void trap_FS_FCloseFile( fileHandle_t f );
-void trap_FS_Seek( fileHandle_t f, long offset, fsOrigin_t origin ); // fsOrigin_t
-
-// add commands to the local console as if they were typed in
-// for map changing, etc. The command is not executed immediately,
-// but will be executed in order the next time console commands
-// are processed
-void trap_SendConsoleCommand( const char *text );
-
-// register a command name so the console can perform command completion.
-// FIXME: replace this with a normal console command "defineCommand"?
-void trap_AddCommand( const char *cmdName );
-
-// send a string to the server over the network
-void trap_SendClientCommand( const char *s );
-
-// force a screen update, only used during gamestate load
-void trap_UpdateScreen( void );
-
-// model collision
-void trap_CM_LoadMap( const char *mapname );
-int trap_CM_NumInlineModels( void );
-clipHandle_t trap_CM_InlineModel( int index ); // 0 = world, 1+ = bmodels
-clipHandle_t trap_CM_TempBoxModel( const vec3_t mins, const vec3_t maxs );
-int trap_CM_PointContents( const vec3_t p, clipHandle_t model );
-int trap_CM_TransformedPointContents( const vec3_t p, clipHandle_t model, const vec3_t origin, const vec3_t angles );
-void trap_CM_BoxTrace( trace_t *results, const vec3_t start, const vec3_t end,
- const vec3_t mins, const vec3_t maxs,
- clipHandle_t model, int brushmask );
-void trap_CM_TransformedBoxTrace( trace_t *results, const vec3_t start, const vec3_t end,
- const vec3_t mins, const vec3_t maxs,
- clipHandle_t model, int brushmask,
- const vec3_t origin, const vec3_t angles );
-void trap_CM_CapsuleTrace( trace_t *results, const vec3_t start, const vec3_t end,
- const vec3_t mins, const vec3_t maxs,
- clipHandle_t model, int brushmask );
-void trap_CM_TransformedCapsuleTrace( trace_t *results, const vec3_t start, const vec3_t end,
- const vec3_t mins, const vec3_t maxs,
- clipHandle_t model, int brushmask,
- const vec3_t origin, const vec3_t angles );
-
-// Returns the projection of a polygon onto the solid brushes in the world
-int trap_CM_MarkFragments( int numPoints, const vec3_t *points,
- const vec3_t projection,
- int maxPoints, vec3_t pointBuffer,
- int maxFragments, markFragment_t *fragmentBuffer );
-
-// normal sounds will have their volume dynamically changed as their entity
-// moves and the listener moves
-void trap_S_StartSound( vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfx );
-void trap_S_StopLoopingSound( int entnum );
-
-// a local sound is always played full volume
-void trap_S_StartLocalSound( sfxHandle_t sfx, int channelNum );
-void trap_S_ClearLoopingSounds( qboolean killall );
-void trap_S_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx );
-void trap_S_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx );
-void trap_S_UpdateEntityPosition( int entityNum, const vec3_t origin );
-
-// respatialize recalculates the volumes of sound as they should be heard by the
-// given entityNum and position
-void trap_S_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater );
-sfxHandle_t trap_S_RegisterSound( const char *sample, qboolean compressed ); // returns buzz if not found
-void trap_S_StartBackgroundTrack( const char *intro, const char *loop ); // empty name stops music
-void trap_S_StopBackgroundTrack( void );
-
-
-void trap_R_LoadWorldMap( const char *mapname );
-
-// all media should be registered during level startup to prevent
-// hitches during gameplay
-qhandle_t trap_R_RegisterModel( const char *name ); // returns rgb axis if not found
-qhandle_t trap_R_RegisterSkin( const char *name ); // returns all white if not found
-qhandle_t trap_R_RegisterShader( const char *name ); // returns all white if not found
-qhandle_t trap_R_RegisterShaderNoMip( const char *name ); // returns all white if not found
-
-// a scene is built up by calls to R_ClearScene and the various R_Add functions.
-// Nothing is drawn until R_RenderScene is called.
-void trap_R_ClearScene( void );
-void trap_R_AddRefEntityToScene( const refEntity_t *re );
-
-// polys are intended for simple wall marks, not really for doing
-// significant construction
-void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts );
-void trap_R_AddPolysToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts, int numPolys );
-void trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b );
-void trap_R_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, float g, float b );
-int trap_R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir );
-void trap_R_RenderScene( const refdef_t *fd );
-void trap_R_SetColor( const float *rgba ); // NULL = 1,1,1,1
-void trap_R_DrawStretchPic( float x, float y, float w, float h,
- float s1, float t1, float s2, float t2, qhandle_t hShader );
-void trap_R_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs );
-int trap_R_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame,
- float frac, const char *tagName );
-void trap_R_RemapShader( const char *oldShader, const char *newShader, const char *timeOffset );
-
-// The glconfig_t will not change during the life of a cgame.
-// If it needs to change, the entire cgame will be restarted, because
-// all the qhandle_t are then invalid.
-void trap_GetGlconfig( glconfig_t *glconfig );
-
-// the gamestate should be grabbed at startup, and whenever a
-// configstring changes
-void trap_GetGameState( gameState_t *gamestate );
-
-// cgame will poll each frame to see if a newer snapshot has arrived
-// that it is interested in. The time is returned seperately so that
-// snapshot latency can be calculated.
-void trap_GetCurrentSnapshotNumber( int *snapshotNumber, int *serverTime );
-
-// a snapshot get can fail if the snapshot (or the entties it holds) is so
-// old that it has fallen out of the client system queue
-qboolean trap_GetSnapshot( int snapshotNumber, snapshot_t *snapshot );
-
-// retrieve a text command from the server stream
-// the current snapshot will hold the number of the most recent command
-// qfalse can be returned if the client system handled the command
-// argc() / argv() can be used to examine the parameters of the command
-qboolean trap_GetServerCommand( int serverCommandNumber );
-
-// returns the most recent command number that can be passed to GetUserCmd
-// this will always be at least one higher than the number in the current
-// snapshot, and it may be quite a few higher if it is a fast computer on
-// a lagged connection
-int trap_GetCurrentCmdNumber( void );
-
-qboolean trap_GetUserCmd( int cmdNumber, usercmd_t *ucmd );
-
-// used for the weapon select and zoom
-void trap_SetUserCmdValue( int stateValue, float sensitivityScale );
-
-// aids for VM testing
-void testPrintInt( char *string, int i );
-void testPrintFloat( char *string, float f );
-
-int trap_MemoryRemaining( void );
-void trap_R_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font);
-qboolean trap_Key_IsDown( int keynum );
-int trap_Key_GetCatcher( void );
-void trap_Key_SetCatcher( int catcher );
-int trap_Key_GetKey( const char *binding );
-
-typedef enum
-{
- SYSTEM_PRINT,
- CHAT_PRINT,
- TEAMCHAT_PRINT
-} q3print_t;
-
-
-int trap_CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits );
-e_status trap_CIN_StopCinematic( int handle );
-e_status trap_CIN_RunCinematic( int handle );
-void trap_CIN_DrawCinematic( int handle );
-void trap_CIN_SetExtents( int handle, int x, int y, int w, int h );
-
-void trap_SnapVector( float *v );
-
-qboolean trap_loadCamera( const char *name );
-void trap_startCamera( int time );
-qboolean trap_getCameraInfo( int time, vec3_t *origin, vec3_t *angles );
-
-qboolean trap_GetEntityToken( char *buffer, int bufferSize );
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
deleted file mode 100644
index 81470e0e..00000000
--- a/src/cgame/cg_main.c
+++ /dev/null
@@ -1,1801 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_main.c -- initialization and primary entry point for cgame
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-#include "../ui/ui_shared.h"
-// display context for new ui stuff
-displayContextDef_t cgDC;
-
-int forceModelModificationCount = -1;
-
-void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum );
-void CG_Shutdown( void );
-
-/*
-================
-vmMain
-
-This is the only way control passes into the module.
-This must be the very first function compiled into the .q3vm file
-================
-*/
-long vmMain( long command, long arg0, long arg1, long arg2, long arg3,
- long arg4, long arg5, long arg6, long arg7,
- long arg8, long arg9, long arg10, long arg11 )
-{
- switch( command )
- {
- case CG_INIT:
- CG_Init( arg0, arg1, arg2 );
- return 0;
-
- case CG_SHUTDOWN:
- CG_Shutdown( );
- return 0;
-
- case CG_CONSOLE_COMMAND:
- return CG_ConsoleCommand( );
-
- case CG_DRAW_ACTIVE_FRAME:
- CG_DrawActiveFrame( arg0, arg1, arg2 );
- return 0;
-
- case CG_CROSSHAIR_PLAYER:
- return CG_CrosshairPlayer( );
-
- case CG_LAST_ATTACKER:
- return CG_LastAttacker( );
-
- case CG_KEY_EVENT:
- CG_KeyEvent( arg0, arg1 );
- return 0;
-
- case CG_MOUSE_EVENT:
- cgDC.cursorx = cgs.cursorX;
- cgDC.cursory = cgs.cursorY;
- CG_MouseEvent( arg0, arg1 );
- return 0;
-
- case CG_EVENT_HANDLING:
- CG_EventHandling( arg0 );
- return 0;
-
- default:
- CG_Error( "vmMain: unknown command %i", command );
- break;
- }
-
- return -1;
-}
-
-
-cg_t cg;
-cgs_t cgs;
-centity_t cg_entities[ MAX_GENTITIES ];
-
-//TA: weapons limit expanded:
-//weaponInfo_t cg_weapons[MAX_WEAPONS];
-weaponInfo_t cg_weapons[ 32 ];
-upgradeInfo_t cg_upgrades[ 32 ];
-
-buildableInfo_t cg_buildables[ BA_NUM_BUILDABLES ];
-
-vmCvar_t cg_teslaTrailTime;
-vmCvar_t cg_railTrailTime;
-vmCvar_t cg_centertime;
-vmCvar_t cg_runpitch;
-vmCvar_t cg_runroll;
-vmCvar_t cg_bobup;
-vmCvar_t cg_bobpitch;
-vmCvar_t cg_bobroll;
-vmCvar_t cg_swingSpeed;
-vmCvar_t cg_shadows;
-vmCvar_t cg_gibs;
-vmCvar_t cg_drawTimer;
-vmCvar_t cg_drawFPS;
-vmCvar_t cg_drawSnapshot;
-vmCvar_t cg_draw3dIcons;
-vmCvar_t cg_drawIcons;
-vmCvar_t cg_drawAmmoWarning;
-vmCvar_t cg_drawCrosshair;
-vmCvar_t cg_drawCrosshairNames;
-vmCvar_t cg_drawRewards;
-vmCvar_t cg_crosshairX;
-vmCvar_t cg_crosshairY;
-vmCvar_t cg_draw2D;
-vmCvar_t cg_drawStatus;
-vmCvar_t cg_animSpeed;
-vmCvar_t cg_debugAnim;
-vmCvar_t cg_debugPosition;
-vmCvar_t cg_debugEvents;
-vmCvar_t cg_errorDecay;
-vmCvar_t cg_nopredict;
-vmCvar_t cg_debugMove;
-vmCvar_t cg_noPlayerAnims;
-vmCvar_t cg_showmiss;
-vmCvar_t cg_footsteps;
-vmCvar_t cg_addMarks;
-vmCvar_t cg_brassTime;
-vmCvar_t cg_viewsize;
-vmCvar_t cg_drawGun;
-vmCvar_t cg_gun_frame;
-vmCvar_t cg_gun_x;
-vmCvar_t cg_gun_y;
-vmCvar_t cg_gun_z;
-vmCvar_t cg_tracerChance;
-vmCvar_t cg_tracerWidth;
-vmCvar_t cg_tracerLength;
-vmCvar_t cg_autoswitch;
-vmCvar_t cg_ignore;
-vmCvar_t cg_simpleItems;
-vmCvar_t cg_fov;
-vmCvar_t cg_zoomFov;
-vmCvar_t cg_thirdPerson;
-vmCvar_t cg_thirdPersonRange;
-vmCvar_t cg_thirdPersonAngle;
-vmCvar_t cg_stereoSeparation;
-vmCvar_t cg_lagometer;
-vmCvar_t cg_drawAttacker;
-vmCvar_t cg_synchronousClients;
-vmCvar_t cg_teamChatTime;
-vmCvar_t cg_teamChatHeight;
-vmCvar_t cg_stats;
-vmCvar_t cg_buildScript;
-vmCvar_t cg_forceModel;
-vmCvar_t cg_paused;
-vmCvar_t cg_blood;
-vmCvar_t cg_predictItems;
-vmCvar_t cg_deferPlayers;
-vmCvar_t cg_drawTeamOverlay;
-vmCvar_t cg_teamOverlayUserinfo;
-vmCvar_t cg_drawFriend;
-vmCvar_t cg_teamChatsOnly;
-vmCvar_t cg_noVoiceChats;
-vmCvar_t cg_noVoiceText;
-vmCvar_t cg_hudFiles;
-vmCvar_t cg_scorePlum;
-vmCvar_t cg_smoothClients;
-vmCvar_t pmove_fixed;
-//vmCvar_t cg_pmove_fixed;
-vmCvar_t pmove_msec;
-vmCvar_t cg_pmove_msec;
-vmCvar_t cg_cameraMode;
-vmCvar_t cg_cameraOrbit;
-vmCvar_t cg_cameraOrbitDelay;
-vmCvar_t cg_timescaleFadeEnd;
-vmCvar_t cg_timescaleFadeSpeed;
-vmCvar_t cg_timescale;
-vmCvar_t cg_smallFont;
-vmCvar_t cg_bigFont;
-vmCvar_t cg_noTaunt;
-vmCvar_t cg_noProjectileTrail;
-vmCvar_t cg_oldRail;
-vmCvar_t cg_oldRocket;
-vmCvar_t cg_oldPlasma;
-vmCvar_t cg_trueLightning;
-vmCvar_t cg_creepRes;
-vmCvar_t cg_drawSurfNormal;
-vmCvar_t cg_drawBBOX;
-vmCvar_t cg_debugAlloc;
-vmCvar_t cg_wwSmoothTime;
-vmCvar_t cg_wwFollow;
-vmCvar_t cg_wwToggle;
-vmCvar_t cg_depthSortParticles;
-vmCvar_t cg_consoleLatency;
-vmCvar_t cg_lightFlare;
-vmCvar_t cg_debugParticles;
-vmCvar_t cg_debugTrails;
-vmCvar_t cg_debugPVS;
-vmCvar_t cg_disableWarningDialogs;
-vmCvar_t cg_disableScannerPlane;
-
-vmCvar_t cg_painBlendUpRate;
-vmCvar_t cg_painBlendDownRate;
-vmCvar_t cg_painBlendMax;
-vmCvar_t cg_painBlendScale;
-vmCvar_t cg_painBlendZoom;
-
-//TA: hack to get class and carriage through to UI module
-vmCvar_t ui_currentClass;
-vmCvar_t ui_carriage;
-vmCvar_t ui_stages;
-vmCvar_t ui_dialog;
-vmCvar_t ui_loading;
-vmCvar_t ui_voteActive;
-vmCvar_t ui_alienTeamVoteActive;
-vmCvar_t ui_humanTeamVoteActive;
-
-vmCvar_t cg_debugRandom;
-
-
-typedef struct
-{
- vmCvar_t *vmCvar;
- char *cvarName;
- char *defaultString;
- int cvarFlags;
-} cvarTable_t;
-
-static cvarTable_t cvarTable[ ] =
-{
- { &cg_ignore, "cg_ignore", "0", 0 }, // used for debugging
- { &cg_autoswitch, "cg_autoswitch", "1", CVAR_ARCHIVE },
- { &cg_drawGun, "cg_drawGun", "1", CVAR_ARCHIVE },
- { &cg_zoomFov, "cg_zoomfov", "22.5", CVAR_ARCHIVE },
- { &cg_fov, "cg_fov", "90", CVAR_ARCHIVE },
- { &cg_viewsize, "cg_viewsize", "100", CVAR_ARCHIVE },
- { &cg_stereoSeparation, "cg_stereoSeparation", "0.4", CVAR_ARCHIVE },
- { &cg_shadows, "cg_shadows", "1", CVAR_ARCHIVE },
- { &cg_gibs, "cg_gibs", "1", CVAR_ARCHIVE },
- { &cg_draw2D, "cg_draw2D", "1", CVAR_ARCHIVE },
- { &cg_drawStatus, "cg_drawStatus", "1", CVAR_ARCHIVE },
- { &cg_drawTimer, "cg_drawTimer", "1", CVAR_ARCHIVE },
- { &cg_drawFPS, "cg_drawFPS", "1", CVAR_ARCHIVE },
- { &cg_drawSnapshot, "cg_drawSnapshot", "0", CVAR_ARCHIVE },
- { &cg_draw3dIcons, "cg_draw3dIcons", "1", CVAR_ARCHIVE },
- { &cg_drawIcons, "cg_drawIcons", "1", CVAR_ARCHIVE },
- { &cg_drawAmmoWarning, "cg_drawAmmoWarning", "1", CVAR_ARCHIVE },
- { &cg_drawAttacker, "cg_drawAttacker", "1", CVAR_ARCHIVE },
- { &cg_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE },
- { &cg_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE },
- { &cg_drawRewards, "cg_drawRewards", "1", CVAR_ARCHIVE },
- { &cg_crosshairX, "cg_crosshairX", "0", CVAR_ARCHIVE },
- { &cg_crosshairY, "cg_crosshairY", "0", CVAR_ARCHIVE },
- { &cg_brassTime, "cg_brassTime", "2500", CVAR_ARCHIVE },
- { &cg_simpleItems, "cg_simpleItems", "0", CVAR_ARCHIVE },
- { &cg_addMarks, "cg_marks", "1", CVAR_ARCHIVE },
- { &cg_lagometer, "cg_lagometer", "0", CVAR_ARCHIVE },
- { &cg_teslaTrailTime, "cg_teslaTrailTime", "250", CVAR_ARCHIVE },
- { &cg_railTrailTime, "cg_railTrailTime", "400", CVAR_ARCHIVE },
- { &cg_gun_x, "cg_gunX", "0", CVAR_CHEAT },
- { &cg_gun_y, "cg_gunY", "0", CVAR_CHEAT },
- { &cg_gun_z, "cg_gunZ", "0", CVAR_CHEAT },
- { &cg_centertime, "cg_centertime", "3", CVAR_CHEAT },
- { &cg_runpitch, "cg_runpitch", "0.002", CVAR_ARCHIVE},
- { &cg_runroll, "cg_runroll", "0.005", CVAR_ARCHIVE },
- { &cg_bobup , "cg_bobup", "0.005", CVAR_CHEAT },
- { &cg_bobpitch, "cg_bobpitch", "0.002", CVAR_ARCHIVE },
- { &cg_bobroll, "cg_bobroll", "0.002", CVAR_ARCHIVE },
- { &cg_swingSpeed, "cg_swingSpeed", "0.3", CVAR_CHEAT },
- { &cg_animSpeed, "cg_animspeed", "1", CVAR_CHEAT },
- { &cg_debugAnim, "cg_debuganim", "0", CVAR_CHEAT },
- { &cg_debugPosition, "cg_debugposition", "0", CVAR_CHEAT },
- { &cg_debugEvents, "cg_debugevents", "0", CVAR_CHEAT },
- { &cg_errorDecay, "cg_errordecay", "100", 0 },
- { &cg_nopredict, "cg_nopredict", "0", 0 },
- { &cg_debugMove, "cg_debugMove", "0", 0 },
- { &cg_noPlayerAnims, "cg_noplayeranims", "0", CVAR_CHEAT },
- { &cg_showmiss, "cg_showmiss", "0", 0 },
- { &cg_footsteps, "cg_footsteps", "1", CVAR_CHEAT },
- { &cg_tracerChance, "cg_tracerchance", "0.4", CVAR_CHEAT },
- { &cg_tracerWidth, "cg_tracerwidth", "1", CVAR_CHEAT },
- { &cg_tracerLength, "cg_tracerlength", "100", CVAR_CHEAT },
- { &cg_thirdPersonRange, "cg_thirdPersonRange", "40", CVAR_CHEAT },
- { &cg_thirdPersonAngle, "cg_thirdPersonAngle", "0", CVAR_CHEAT },
- { &cg_thirdPerson, "cg_thirdPerson", "0", CVAR_CHEAT },
- { &cg_teamChatTime, "cg_teamChatTime", "3000", CVAR_ARCHIVE },
- { &cg_teamChatHeight, "cg_teamChatHeight", "0", CVAR_ARCHIVE },
- { &cg_forceModel, "cg_forceModel", "0", CVAR_ARCHIVE },
- { &cg_predictItems, "cg_predictItems", "1", CVAR_ARCHIVE },
- { &cg_deferPlayers, "cg_deferPlayers", "1", CVAR_ARCHIVE },
- { &cg_drawTeamOverlay, "cg_drawTeamOverlay", "0", CVAR_ARCHIVE },
- { &cg_teamOverlayUserinfo, "teamoverlay", "0", CVAR_ROM | CVAR_USERINFO },
- { &cg_stats, "cg_stats", "0", 0 },
- { &cg_drawFriend, "cg_drawFriend", "1", CVAR_ARCHIVE },
- { &cg_teamChatsOnly, "cg_teamChatsOnly", "0", CVAR_ARCHIVE },
- { &cg_noVoiceChats, "cg_noVoiceChats", "0", CVAR_ARCHIVE },
- { &cg_noVoiceText, "cg_noVoiceText", "0", CVAR_ARCHIVE },
- { &cg_creepRes, "cg_creepRes", "16", CVAR_ARCHIVE },
- { &cg_drawSurfNormal, "cg_drawSurfNormal", "0", CVAR_CHEAT },
- { &cg_drawBBOX, "cg_drawBBOX", "0", CVAR_CHEAT },
- { &cg_debugAlloc, "cg_debugAlloc", "0", 0 },
- { &cg_wwSmoothTime, "cg_wwSmoothTime", "300", CVAR_ARCHIVE },
- { &cg_wwFollow, "cg_wwFollow", "1", CVAR_ARCHIVE|CVAR_USERINFO },
- { &cg_wwToggle, "cg_wwToggle", "1", CVAR_ARCHIVE|CVAR_USERINFO },
- { &cg_depthSortParticles, "cg_depthSortParticles", "1", CVAR_ARCHIVE },
- { &cg_consoleLatency, "cg_consoleLatency", "3000", CVAR_ARCHIVE },
- { &cg_lightFlare, "cg_lightFlare", "3", CVAR_ARCHIVE },
- { &cg_debugParticles, "cg_debugParticles", "0", CVAR_CHEAT },
- { &cg_debugTrails, "cg_debugTrails", "0", CVAR_CHEAT },
- { &cg_debugPVS, "cg_debugPVS", "0", CVAR_CHEAT },
- { &cg_disableWarningDialogs, "cg_disableWarningDialogs", "0", CVAR_ARCHIVE },
- { &cg_disableScannerPlane, "cg_disableScannerPlane", "0", CVAR_ARCHIVE },
- { &cg_hudFiles, "cg_hudFiles", "ui/hud.txt", CVAR_ARCHIVE},
-
- { &cg_painBlendUpRate, "cg_painBlendUpRate", "10.0", 0 },
- { &cg_painBlendDownRate, "cg_painBlendDownRate", "0.5", 0 },
- { &cg_painBlendMax, "cg_painBlendMax", "0.7", 0 },
- { &cg_painBlendScale, "cg_painBlendScale", "7.0", 0 },
- { &cg_painBlendZoom, "cg_painBlendZoom", "0.18", 0 },
-
- { &ui_currentClass, "ui_currentClass", "0", 0 },
- { &ui_carriage, "ui_carriage", "", 0 },
- { &ui_stages, "ui_stages", "0 0", 0 },
- { &ui_dialog, "ui_dialog", "Text not set", 0 },
- { &ui_loading, "ui_loading", "0", 0 },
- { &ui_voteActive, "ui_voteActive", "0", 0 },
- { &ui_humanTeamVoteActive, "ui_humanTeamVoteActive", "0", 0 },
- { &ui_alienTeamVoteActive, "ui_alienTeamVoteActive", "0", 0 },
-
- { &cg_debugRandom, "cg_debugRandom", "0", 0 },
-
- // the following variables are created in other parts of the system,
- // but we also reference them here
-
- { &cg_buildScript, "com_buildScript", "0", 0 }, // force loading of all possible data amd error on failures
- { &cg_paused, "cl_paused", "0", CVAR_ROM },
- { &cg_blood, "com_blood", "1", CVAR_ARCHIVE },
- { &cg_synchronousClients, "g_synchronousClients", "0", 0 }, // communicated by systeminfo
- { &cg_cameraOrbit, "cg_cameraOrbit", "0", CVAR_CHEAT},
- { &cg_cameraOrbitDelay, "cg_cameraOrbitDelay", "50", CVAR_ARCHIVE},
- { &cg_timescaleFadeEnd, "cg_timescaleFadeEnd", "1", 0},
- { &cg_timescaleFadeSpeed, "cg_timescaleFadeSpeed", "0", 0},
- { &cg_timescale, "timescale", "1", 0},
- { &cg_scorePlum, "cg_scorePlums", "1", CVAR_USERINFO | CVAR_ARCHIVE},
- { &cg_smoothClients, "cg_smoothClients", "0", CVAR_USERINFO | CVAR_ARCHIVE},
- { &cg_cameraMode, "com_cameraMode", "0", CVAR_CHEAT},
-
- { &pmove_fixed, "pmove_fixed", "0", 0},
- { &pmove_msec, "pmove_msec", "8", 0},
- { &cg_noTaunt, "cg_noTaunt", "0", CVAR_ARCHIVE},
- { &cg_noProjectileTrail, "cg_noProjectileTrail", "0", CVAR_ARCHIVE},
- { &cg_smallFont, "ui_smallFont", "0.2", CVAR_ARCHIVE},
- { &cg_bigFont, "ui_bigFont", "0.5", CVAR_ARCHIVE},
- { &cg_oldRail, "cg_oldRail", "1", CVAR_ARCHIVE},
- { &cg_oldRocket, "cg_oldRocket", "1", CVAR_ARCHIVE},
- { &cg_oldPlasma, "cg_oldPlasma", "1", CVAR_ARCHIVE},
- { &cg_trueLightning, "cg_trueLightning", "0.0", CVAR_ARCHIVE}
-// { &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE }
-};
-
-static int cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] );
-
-/*
-=================
-CG_RegisterCvars
-=================
-*/
-void CG_RegisterCvars( void )
-{
- int i;
- cvarTable_t *cv;
- char var[ MAX_TOKEN_CHARS ];
-
- for( i = 0, cv = cvarTable; i < cvarTableSize; i++, cv++ )
- {
- trap_Cvar_Register( cv->vmCvar, cv->cvarName,
- cv->defaultString, cv->cvarFlags );
- }
-
- //repress standard Q3 console
- trap_Cvar_Set( "con_notifytime", "-2" );
-
- // see if we are also running the server on this machine
- trap_Cvar_VariableStringBuffer( "sv_running", var, sizeof( var ) );
- cgs.localServer = atoi( var );
- forceModelModificationCount = cg_forceModel.modificationCount;
-
- trap_Cvar_Register( NULL, "model", DEFAULT_MODEL, CVAR_USERINFO | CVAR_ARCHIVE );
- trap_Cvar_Register( NULL, "headmodel", DEFAULT_MODEL, CVAR_USERINFO | CVAR_ARCHIVE );
- trap_Cvar_Register( NULL, "team_model", DEFAULT_TEAM_MODEL, CVAR_USERINFO | CVAR_ARCHIVE );
- trap_Cvar_Register( NULL, "team_headmodel", DEFAULT_TEAM_HEAD, CVAR_USERINFO | CVAR_ARCHIVE );
-}
-
-
-/*
-===================
-CG_ForceModelChange
-===================
-*/
-static void CG_ForceModelChange( void )
-{
- int i;
-
- for( i = 0; i < MAX_CLIENTS; i++ )
- {
- const char *clientInfo;
-
- clientInfo = CG_ConfigString( CS_PLAYERS + i );
-
- if( !clientInfo[ 0 ] )
- continue;
-
- CG_NewClientInfo( i );
- }
-}
-
-
-/*
-=================
-CG_UpdateCvars
-=================
-*/
-void CG_UpdateCvars( void )
-{
- int i;
- cvarTable_t *cv;
-
- for( i = 0, cv = cvarTable; i < cvarTableSize; i++, cv++ )
- trap_Cvar_Update( cv->vmCvar );
-
- // check for modications here
-
- // if force model changed
- if( forceModelModificationCount != cg_forceModel.modificationCount )
- {
- forceModelModificationCount = cg_forceModel.modificationCount;
- CG_ForceModelChange( );
- }
-}
-
-
-int CG_CrosshairPlayer( void )
-{
- if( cg.time > ( cg.crosshairClientTime + 1000 ) )
- return -1;
-
- return cg.crosshairClientNum;
-}
-
-
-int CG_LastAttacker( void )
-{
- if( !cg.attackerTime )
- return -1;
-
- return cg.snap->ps.persistant[ PERS_ATTACKER ];
-}
-
-void CG_RemoveConsoleLine( void )
-{
- int i, offset, totalLength;
-
- if( cg.numConsoleLines == 0 )
- return;
-
- offset = cg.consoleLines[ 0 ].length;
- totalLength = strlen( cg.consoleText ) - offset;
-
- //slide up consoleText
- for( i = 0; i <= totalLength; i++ )
- cg.consoleText[ i ] = cg.consoleText[ i + offset ];
-
- //pop up the first consoleLine
- for( i = 0; i < cg.numConsoleLines; i++ )
- cg.consoleLines[ i ] = cg.consoleLines[ i + 1 ];
-
- cg.numConsoleLines--;
-}
-
-//TA: team arena UI based console
-void CG_TAUIConsole( const char *text )
-{
- if( cg.numConsoleLines == MAX_CONSOLE_LINES )
- CG_RemoveConsoleLine( );
-
- if( cg.consoleValid )
- {
- strcat( cg.consoleText, text );
- cg.consoleLines[ cg.numConsoleLines ].time = cg.time;
- cg.consoleLines[ cg.numConsoleLines ].length = strlen( text );
- cg.numConsoleLines++;
- }
-
-}
-
-void QDECL CG_Printf( const char *msg, ... )
-{
- va_list argptr;
- char text[ 1024 ];
-
- va_start( argptr, msg );
- vsprintf( text, msg, argptr );
- va_end( argptr );
-
- CG_TAUIConsole( text );
-
- trap_Print( text );
-}
-
-void QDECL CG_Error( const char *msg, ... )
-{
- va_list argptr;
- char text[ 1024 ];
-
- va_start( argptr, msg );
- vsprintf( text, msg, argptr );
- va_end( argptr );
-
- trap_Error( text );
-}
-
-void QDECL Com_Error( int level, const char *error, ... )
-{
- va_list argptr;
- char text[1024];
-
- va_start( argptr, error );
- vsprintf( text, error, argptr );
- va_end( argptr );
-
- CG_Error( "%s", text );
-}
-
-void QDECL Com_Printf( const char *msg, ... ) {
- va_list argptr;
- char text[1024];
-
- va_start (argptr, msg);
- vsprintf (text, msg, argptr);
- va_end (argptr);
-
- //TA: team arena UI based console
- if( cg.numConsoleLines == MAX_CONSOLE_LINES )
- CG_RemoveConsoleLine( );
-
- if( cg.consoleValid )
- {
- strcat( cg.consoleText, text );
- cg.consoleLines[ cg.numConsoleLines ].time = cg.time;
- cg.consoleLines[ cg.numConsoleLines ].length = strlen( text );
- cg.numConsoleLines++;
- }
-
- CG_Printf ("%s", text);
-}
-
-
-
-/*
-================
-CG_Argv
-================
-*/
-const char *CG_Argv( int arg )
-{
- static char buffer[ MAX_STRING_CHARS ];
-
- trap_Argv( arg, buffer, sizeof( buffer ) );
-
- return buffer;
-}
-
-
-//========================================================================
-
-/*
-=================
-CG_FileExists
-
-Test if a specific file exists or not
-=================
-*/
-qboolean CG_FileExists( char *filename )
-{
- fileHandle_t f;
-
- if( trap_FS_FOpenFile( filename, &f, FS_READ ) > 0 )
- {
- //file exists so close it
- trap_FS_FCloseFile( f );
-
- return qtrue;
- }
- else
- return qfalse;
-}
-
-/*
-=================
-CG_RegisterSounds
-
-called during a precache command
-=================
-*/
-static void CG_RegisterSounds( void )
-{
- int i;
- char name[ MAX_QPATH ];
- const char *soundName;
-
- cgs.media.alienStageTransition = trap_S_RegisterSound( "sound/announcements/overmindevolved.wav", qtrue );
- cgs.media.humanStageTransition = trap_S_RegisterSound( "sound/announcements/reinforcement.wav", qtrue );
-
- cgs.media.alienOvermindAttack = trap_S_RegisterSound( "sound/announcements/overmindattack.wav", qtrue );
- cgs.media.alienOvermindDying = trap_S_RegisterSound( "sound/announcements/overminddying.wav", qtrue );
- cgs.media.alienOvermindSpawns = trap_S_RegisterSound( "sound/announcements/overmindspawns.wav", qtrue );
-
- cgs.media.alienL1Grab = trap_S_RegisterSound( "sound/player/level1/grab.wav", qtrue );
- cgs.media.alienL4ChargePrepare = trap_S_RegisterSound( "sound/player/level4/charge_prepare.wav", qtrue );
- cgs.media.alienL4ChargeStart = trap_S_RegisterSound( "sound/player/level4/charge_start.wav", qtrue );
-
- cgs.media.tracerSound = trap_S_RegisterSound( "sound/weapons/machinegun/buletby1.wav", qfalse ); //FIXME
- cgs.media.selectSound = trap_S_RegisterSound( "sound/weapons/change.wav", qfalse );
-
- cgs.media.talkSound = trap_S_RegisterSound( "sound/player/talk.wav", qfalse ); //FIXME
- cgs.media.landSound = trap_S_RegisterSound( "sound/player/land1.wav", qfalse ); //FIXME
-
- cgs.media.watrInSound = trap_S_RegisterSound( "sound/player/watr_in.wav", qfalse ); //FIXME
- cgs.media.watrOutSound = trap_S_RegisterSound( "sound/player/watr_out.wav", qfalse ); //FIXME
- cgs.media.watrUnSound = trap_S_RegisterSound( "sound/player/watr_un.wav", qfalse ); //FIXME
-
- cgs.media.disconnectSound = trap_S_RegisterSound( "sound/world/telein.wav", qfalse ); //FIXME
-
- //FIXME
- for( i = 0; i < 4; i++ )
- {
- Com_sprintf( name, sizeof( name ), "sound/player/footsteps/step%i.wav", i + 1 );
- cgs.media.footsteps[ FOOTSTEP_NORMAL ][ i ] = trap_S_RegisterSound( name, qfalse );
-
- Com_sprintf( name, sizeof( name ), "sound/player/footsteps/boot%i.wav", i + 1 );
- cgs.media.footsteps[ FOOTSTEP_BOOT ][ i ] = trap_S_RegisterSound( name, qfalse );
-
- Com_sprintf( name, sizeof( name ), "sound/player/footsteps/flesh%i.wav", i + 1 );
- cgs.media.footsteps[ FOOTSTEP_FLESH ][ i ] = trap_S_RegisterSound( name, qfalse );
-
- Com_sprintf( name, sizeof( name ), "sound/player/footsteps/mech%i.wav", i + 1 );
- cgs.media.footsteps[ FOOTSTEP_MECH ][ i ] = trap_S_RegisterSound( name, qfalse );
-
- Com_sprintf( name, sizeof( name ), "sound/player/footsteps/energy%i.wav", i + 1 );
- cgs.media.footsteps[ FOOTSTEP_ENERGY ][ i ] = trap_S_RegisterSound( name, qfalse );
-
- Com_sprintf( name, sizeof( name ), "sound/player/footsteps/splash%i.wav", i + 1 );
- cgs.media.footsteps[ FOOTSTEP_SPLASH ][ i ] = trap_S_RegisterSound( name, qfalse );
-
- Com_sprintf( name, sizeof( name ), "sound/player/footsteps/clank%i.wav", i + 1 );
- cgs.media.footsteps[ FOOTSTEP_METAL ][ i ] = trap_S_RegisterSound( name, qfalse );
- }
-
- for( i = 1 ; i < MAX_SOUNDS ; i++ )
- {
- soundName = CG_ConfigString( CS_SOUNDS + i );
-
- if( !soundName[ 0 ] )
- break;
-
- if( soundName[ 0 ] == '*' )
- continue; // custom sound
-
- cgs.gameSounds[ i ] = trap_S_RegisterSound( soundName, qfalse );
- }
-
- cgs.media.jetpackDescendSound = trap_S_RegisterSound( "sound/upgrades/jetpack/low.wav", qfalse );
- cgs.media.jetpackIdleSound = trap_S_RegisterSound( "sound/upgrades/jetpack/idle.wav", qfalse );
- cgs.media.jetpackAscendSound = trap_S_RegisterSound( "sound/upgrades/jetpack/hi.wav", qfalse );
-
- cgs.media.medkitUseSound = trap_S_RegisterSound( "sound/upgrades/medkit/medkit.wav", qfalse );
-
- cgs.media.alienEvolveSound = trap_S_RegisterSound( "sound/player/alienevolve.wav", qfalse );
-
- cgs.media.alienBuildableExplosion = trap_S_RegisterSound( "sound/buildables/alien/explosion.wav", qfalse );
- cgs.media.alienBuildableDamage = trap_S_RegisterSound( "sound/buildables/alien/damage.wav", qfalse );
- cgs.media.alienBuildablePrebuild = trap_S_RegisterSound( "sound/buildables/alien/prebuild.wav", qfalse );
-
- cgs.media.humanBuildableExplosion = trap_S_RegisterSound( "sound/buildables/human/explosion.wav", qfalse );
- cgs.media.humanBuildablePrebuild = trap_S_RegisterSound( "sound/buildables/human/prebuild.wav", qfalse );
-
- for( i = 0; i < 4; i++ )
- cgs.media.humanBuildableDamage[ i ] = trap_S_RegisterSound(
- va( "sound/buildables/human/damage%d.wav", i ), qfalse );
-
- cgs.media.hgrenb1aSound = trap_S_RegisterSound( "sound/weapons/grenade/hgrenb1a.wav", qfalse ); //FIXME
- cgs.media.hgrenb2aSound = trap_S_RegisterSound( "sound/weapons/grenade/hgrenb2a.wav", qfalse ); //FIXME
-
- cgs.media.repeaterUseSound = trap_S_RegisterSound( "sound/buildables/repeater/use.wav", qfalse );
-
- cgs.media.buildableRepairSound = trap_S_RegisterSound( "sound/buildables/human/repair.wav", qfalse );
- cgs.media.buildableRepairedSound = trap_S_RegisterSound( "sound/buildables/human/repaired.wav", qfalse );
-
- cgs.media.lCannonWarningSound = trap_S_RegisterSound( "models/weapons/lcannon/warning.wav", qfalse );
-}
-
-
-//===================================================================================
-
-
-/*
-=================
-CG_RegisterGraphics
-
-This function may execute for a couple of minutes with a slow disk.
-=================
-*/
-static void CG_RegisterGraphics( void )
-{
- int i;
- static char *sb_nums[ 11 ] =
- {
- "gfx/2d/numbers/zero_32b",
- "gfx/2d/numbers/one_32b",
- "gfx/2d/numbers/two_32b",
- "gfx/2d/numbers/three_32b",
- "gfx/2d/numbers/four_32b",
- "gfx/2d/numbers/five_32b",
- "gfx/2d/numbers/six_32b",
- "gfx/2d/numbers/seven_32b",
- "gfx/2d/numbers/eight_32b",
- "gfx/2d/numbers/nine_32b",
- "gfx/2d/numbers/minus_32b",
- };
- static char *buildWeaponTimerPieShaders[ 8 ] =
- {
- "ui/assets/neutral/1_5pie",
- "ui/assets/neutral/3_0pie",
- "ui/assets/neutral/4_5pie",
- "ui/assets/neutral/6_0pie",
- "ui/assets/neutral/7_5pie",
- "ui/assets/neutral/9_0pie",
- "ui/assets/neutral/10_5pie",
- "ui/assets/neutral/12_0pie",
- };
-
- // clear any references to old media
- memset( &cg.refdef, 0, sizeof( cg.refdef ) );
- trap_R_ClearScene( );
-
- trap_R_LoadWorldMap( cgs.mapname );
- CG_UpdateMediaFraction( 0.66f );
-
- for( i = 0; i < 11; i++ )
- cgs.media.numberShaders[ i ] = trap_R_RegisterShader( sb_nums[ i ] );
-
- cgs.media.viewBloodShader = trap_R_RegisterShader( "gfx/damage/fullscreen_painblend" ); //FIXME
-
- cgs.media.connectionShader = trap_R_RegisterShader( "disconnected" ); //FIXME?
-
- cgs.media.creepShader = trap_R_RegisterShader( "creep" );
-
- cgs.media.scannerBlipShader = trap_R_RegisterShader( "gfx/2d/blip" );
- cgs.media.scannerLineShader = trap_R_RegisterShader( "gfx/2d/stalk" );
-
- cgs.media.tracerShader = trap_R_RegisterShader( "gfx/misc/tracer" ); //FIXME
- cgs.media.selectShader = trap_R_RegisterShader( "gfx/2d/select" );
-
- cgs.media.backTileShader = trap_R_RegisterShader( "gfx/2d/backtile" ); //FIXME
-
-
- //TA: building shaders
- cgs.media.greenBuildShader = trap_R_RegisterShader("gfx/2d/greenbuild" );
- cgs.media.redBuildShader = trap_R_RegisterShader("gfx/2d/redbuild" );
- cgs.media.noPowerShader = trap_R_RegisterShader("gfx/2d/nopower" );
- cgs.media.humanSpawningShader = trap_R_RegisterShader("models/buildables/telenode/rep_cyl" );
-
- for( i = 0; i < 8; i++ )
- cgs.media.buildWeaponTimerPie[ i ] = trap_R_RegisterShader( buildWeaponTimerPieShaders[ i ] );
-
- cgs.media.upgradeClassIconShader = trap_R_RegisterShader( "icons/icona_upgrade.tga" );
-
- cgs.media.balloonShader = trap_R_RegisterShader( "sprites/balloon3" ); //FIXME?
-
- cgs.media.disconnectPS = CG_RegisterParticleSystem( "disconnectPS" );
-
- CG_UpdateMediaFraction( 0.7f );
-
- memset( cg_weapons, 0, sizeof( cg_weapons ) );
- memset( cg_upgrades, 0, sizeof( cg_upgrades ) );
-
- cgs.media.shadowMarkShader = trap_R_RegisterShader( "markShadow" ); //FIXME
- cgs.media.wakeMarkShader = trap_R_RegisterShader( "wake" ); //FIXME
-
- cgs.media.poisonCloudPS = CG_RegisterParticleSystem( "poisonCloudPS" );
- cgs.media.alienEvolvePS = CG_RegisterParticleSystem( "alienEvolvePS" );
- cgs.media.alienAcidTubePS = CG_RegisterParticleSystem( "alienAcidTubePS" );
-
- cgs.media.jetPackDescendPS = CG_RegisterParticleSystem( "jetPackDescendPS" );
- cgs.media.jetPackHoverPS = CG_RegisterParticleSystem( "jetPackHoverPS" );
- cgs.media.jetPackAscendPS = CG_RegisterParticleSystem( "jetPackAscendPS" );
-
- cgs.media.humanBuildableDamagedPS = CG_RegisterParticleSystem( "humanBuildableDamagedPS" );
- cgs.media.alienBuildableDamagedPS = CG_RegisterParticleSystem( "alienBuildableDamagedPS" );
- cgs.media.humanBuildableDestroyedPS = CG_RegisterParticleSystem( "humanBuildableDestroyedPS" );
- cgs.media.alienBuildableDestroyedPS = CG_RegisterParticleSystem( "alienBuildableDestroyedPS" );
-
- cgs.media.alienBleedPS = CG_RegisterParticleSystem( "alienBleedPS" );
- cgs.media.humanBleedPS = CG_RegisterParticleSystem( "humanBleedPS" );
-
- // register the inline models
- cgs.numInlineModels = trap_CM_NumInlineModels( );
-
- for( i = 1; i < cgs.numInlineModels; i++ )
- {
- char name[ 10 ];
- vec3_t mins, maxs;
- int j;
-
- Com_sprintf( name, sizeof( name ), "*%i", i );
-
- cgs.inlineDrawModel[ i ] = trap_R_RegisterModel( name );
- trap_R_ModelBounds( cgs.inlineDrawModel[ i ], mins, maxs );
-
- for( j = 0 ; j < 3 ; j++ )
- cgs.inlineModelMidpoints[ i ][ j ] = mins[ j ] + 0.5 * ( maxs[ j ] - mins[ j ] );
- }
-
- // register all the server specified models
- for( i = 1; i < MAX_MODELS; i++ )
- {
- const char *modelName;
-
- modelName = CG_ConfigString( CS_MODELS + i );
-
- if( !modelName[ 0 ] )
- break;
-
- cgs.gameModels[ i ] = trap_R_RegisterModel( modelName );
- }
-
- CG_UpdateMediaFraction( 0.8f );
-
- // register all the server specified shaders
- for( i = 1; i < MAX_SHADERS; i++ )
- {
- const char *shaderName;
-
- shaderName = CG_ConfigString( CS_SHADERS + i );
-
- if( !shaderName[ 0 ] )
- break;
-
- cgs.gameShaders[ i ] = trap_R_RegisterShader( shaderName );
- }
-
- CG_UpdateMediaFraction( 0.9f );
-
- // register all the server specified particle systems
- for( i = 1; i < MAX_GAME_PARTICLE_SYSTEMS; i++ )
- {
- const char *psName;
-
- psName = CG_ConfigString( CS_PARTICLE_SYSTEMS + i );
-
- if( !psName[ 0 ] )
- break;
-
- cgs.gameParticleSystems[ i ] = CG_RegisterParticleSystem( (char *)psName );
- }
-}
-
-
-/*
-=======================
-CG_BuildSpectatorString
-
-=======================
-*/
-void CG_BuildSpectatorString( void )
-{
- int i;
-
- cg.spectatorList[ 0 ] = 0;
-
- for( i = 0; i < MAX_CLIENTS; i++ )
- {
- if( cgs.clientinfo[ i ].infoValid && cgs.clientinfo[ i ].team == PTE_NONE )
- Q_strcat( cg.spectatorList, sizeof( cg.spectatorList ), va( "%s " S_COLOR_WHITE, cgs.clientinfo[ i ].name ) );
- }
-
- i = strlen( cg.spectatorList );
-
- if( i != cg.spectatorLen )
- {
- cg.spectatorLen = i;
- cg.spectatorWidth = -1;
- }
-}
-
-
-
-/*
-===================
-CG_RegisterClients
-
-===================
-*/
-static void CG_RegisterClients( void )
-{
- int i;
-
- cg.charModelFraction = 0.0f;
-
- //precache all the models/sounds/etc
- for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ )
- {
- CG_PrecacheClientInfo( i, BG_FindModelNameForClass( i ),
- BG_FindSkinNameForClass( i ) );
-
- cg.charModelFraction = (float)i / (float)PCL_NUM_CLASSES;
- trap_UpdateScreen( );
- }
-
- cgs.media.larmourHeadSkin = trap_R_RegisterSkin( "models/players/human_base/head_light.skin" );
- cgs.media.larmourLegsSkin = trap_R_RegisterSkin( "models/players/human_base/lower_light.skin" );
- cgs.media.larmourTorsoSkin = trap_R_RegisterSkin( "models/players/human_base/upper_light.skin" );
-
- cgs.media.jetpackModel = trap_R_RegisterModel( "models/players/human_base/jetpack.md3" );
- cgs.media.jetpackFlashModel = trap_R_RegisterModel( "models/players/human_base/jetpack_flash.md3" );
- cgs.media.battpackModel = trap_R_RegisterModel( "models/players/human_base/battpack.md3" );
-
- cg.charModelFraction = 1.0f;
- trap_UpdateScreen( );
-
- //load all the clientinfos of clients already connected to the server
- for( i = 0; i < MAX_CLIENTS; i++ )
- {
- const char *clientInfo;
-
- clientInfo = CG_ConfigString( CS_PLAYERS + i );
- if( !clientInfo[ 0 ] )
- continue;
-
- CG_NewClientInfo( i );
- }
-
- CG_BuildSpectatorString( );
-}
-
-//===========================================================================
-
-/*
-=================
-CG_ConfigString
-=================
-*/
-const char *CG_ConfigString( int index )
-{
- if( index < 0 || index >= MAX_CONFIGSTRINGS )
- CG_Error( "CG_ConfigString: bad index: %i", index );
-
- return cgs.gameState.stringData + cgs.gameState.stringOffsets[ index ];
-}
-
-//==================================================================
-
-/*
-======================
-CG_StartMusic
-
-======================
-*/
-void CG_StartMusic( void )
-{
- char *s;
- char parm1[ MAX_QPATH ], parm2[ MAX_QPATH ];
-
- // start the background music
- s = (char *)CG_ConfigString( CS_MUSIC );
- Q_strncpyz( parm1, COM_Parse( &s ), sizeof( parm1 ) );
- Q_strncpyz( parm2, COM_Parse( &s ), sizeof( parm2 ) );
-
- trap_S_StartBackgroundTrack( parm1, parm2 );
-}
-
-//
-// ==============================
-// new hud stuff ( mission pack )
-// ==============================
-//
-char *CG_GetMenuBuffer( const char *filename )
-{
- int len;
- fileHandle_t f;
- static char buf[ MAX_MENUFILE ];
-
- len = trap_FS_FOpenFile( filename, &f, FS_READ );
-
- if( !f )
- {
- trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", filename ) );
- return NULL;
- }
-
- if( len >= MAX_MENUFILE )
- {
- trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i",
- filename, len, MAX_MENUFILE ) );
- trap_FS_FCloseFile( f );
- return NULL;
- }
-
- trap_FS_Read( buf, len, f );
- buf[len] = 0;
- trap_FS_FCloseFile( f );
-
- return buf;
-}
-
-qboolean CG_Asset_Parse( int handle )
-{
- pc_token_t token;
- const char *tempStr;
-
- if( !trap_PC_ReadToken( handle, &token ) )
- return qfalse;
-
- if( Q_stricmp( token.string, "{" ) != 0 )
- return qfalse;
-
- while( 1 )
- {
- if( !trap_PC_ReadToken( handle, &token ) )
- return qfalse;
-
- if( Q_stricmp( token.string, "}" ) == 0 )
- return qtrue;
-
- // font
- if( Q_stricmp( token.string, "font" ) == 0 )
- {
- int pointSize;
-
- if( !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) )
- return qfalse;
-
- cgDC.registerFont( tempStr, pointSize, &cgDC.Assets.textFont );
- continue;
- }
-
- // smallFont
- if( Q_stricmp( token.string, "smallFont" ) == 0 )
- {
- int pointSize;
-
- if( !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) )
- return qfalse;
-
- cgDC.registerFont( tempStr, pointSize, &cgDC.Assets.smallFont );
- continue;
- }
-
- // font
- if( Q_stricmp( token.string, "bigfont" ) == 0 )
- {
- int pointSize;
-
- if( !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) )
- return qfalse;
-
- cgDC.registerFont( tempStr, pointSize, &cgDC.Assets.bigFont );
- continue;
- }
-
- // gradientbar
- if( Q_stricmp( token.string, "gradientbar" ) == 0 )
- {
- if( !PC_String_Parse( handle, &tempStr ) )
- return qfalse;
-
- cgDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( tempStr );
- continue;
- }
-
- // enterMenuSound
- if( Q_stricmp( token.string, "menuEnterSound" ) == 0 )
- {
- if( !PC_String_Parse( handle, &tempStr ) )
- return qfalse;
-
- cgDC.Assets.menuEnterSound = trap_S_RegisterSound( tempStr, qfalse );
- continue;
- }
-
- // exitMenuSound
- if( Q_stricmp( token.string, "menuExitSound" ) == 0 )
- {
- if( !PC_String_Parse( handle, &tempStr ) )
- return qfalse;
-
- cgDC.Assets.menuExitSound = trap_S_RegisterSound( tempStr, qfalse );
- continue;
- }
-
- // itemFocusSound
- if( Q_stricmp( token.string, "itemFocusSound" ) == 0 )
- {
- if( !PC_String_Parse( handle, &tempStr ) )
- return qfalse;
-
- cgDC.Assets.itemFocusSound = trap_S_RegisterSound( tempStr, qfalse );
- continue;
- }
-
- // menuBuzzSound
- if( Q_stricmp( token.string, "menuBuzzSound" ) == 0 )
- {
- if( !PC_String_Parse( handle, &tempStr ) )
- return qfalse;
-
- cgDC.Assets.menuBuzzSound = trap_S_RegisterSound( tempStr, qfalse );
- continue;
- }
-
- if( Q_stricmp( token.string, "cursor" ) == 0 )
- {
- if( !PC_String_Parse( handle, &cgDC.Assets.cursorStr ) )
- return qfalse;
-
- cgDC.Assets.cursor = trap_R_RegisterShaderNoMip( cgDC.Assets.cursorStr );
- continue;
- }
-
- if( Q_stricmp( token.string, "fadeClamp" ) == 0 )
- {
- if( !PC_Float_Parse( handle, &cgDC.Assets.fadeClamp ) )
- return qfalse;
-
- continue;
- }
-
- if( Q_stricmp( token.string, "fadeCycle" ) == 0 )
- {
- if( !PC_Int_Parse( handle, &cgDC.Assets.fadeCycle ) )
- return qfalse;
-
- continue;
- }
-
- if( Q_stricmp( token.string, "fadeAmount" ) == 0 )
- {
- if( !PC_Float_Parse( handle, &cgDC.Assets.fadeAmount ) )
- return qfalse;
-
- continue;
- }
-
- if( Q_stricmp( token.string, "shadowX" ) == 0 )
- {
- if( !PC_Float_Parse( handle, &cgDC.Assets.shadowX ) )
- return qfalse;
-
- continue;
- }
-
- if( Q_stricmp( token.string, "shadowY" ) == 0 )
- {
- if( !PC_Float_Parse( handle, &cgDC.Assets.shadowY ) )
- return qfalse;
-
- continue;
- }
-
- if( Q_stricmp( token.string, "shadowColor" ) == 0 )
- {
- if( !PC_Color_Parse( handle, &cgDC.Assets.shadowColor ) )
- return qfalse;
-
- cgDC.Assets.shadowFadeClamp = cgDC.Assets.shadowColor[ 3 ];
- continue;
- }
- }
-
- return qfalse; // bk001204 - why not?
-}
-
-void CG_ParseMenu( const char *menuFile )
-{
- pc_token_t token;
- int handle;
-
- handle = trap_PC_LoadSource( menuFile );
-
- if( !handle )
- handle = trap_PC_LoadSource( "ui/testhud.menu" );
-
- if( !handle )
- return;
-
- while( 1 )
- {
- if( !trap_PC_ReadToken( handle, &token ) )
- break;
-
- //if ( Q_stricmp( token, "{" ) ) {
- // Com_Printf( "Missing { in menu file\n" );
- // break;
- //}
-
- //if ( menuCount == MAX_MENUS ) {
- // Com_Printf( "Too many menus!\n" );
- // break;
- //}
-
- if( token.string[ 0 ] == '}' )
- break;
-
- if( Q_stricmp( token.string, "assetGlobalDef" ) == 0 )
- {
- if( CG_Asset_Parse( handle ) )
- continue;
- else
- break;
- }
-
-
- if( Q_stricmp( token.string, "menudef" ) == 0 )
- {
- // start a new menu
- Menu_New( handle );
- }
- }
-
- trap_PC_FreeSource( handle );
-}
-
-qboolean CG_Load_Menu( char **p )
-{
- char *token;
-
- token = COM_ParseExt( p, qtrue );
-
- if( token[ 0 ] != '{' )
- return qfalse;
-
- while( 1 )
- {
- token = COM_ParseExt( p, qtrue );
-
- if( Q_stricmp( token, "}" ) == 0 )
- return qtrue;
-
- if( !token || token[ 0 ] == 0 )
- return qfalse;
-
- CG_ParseMenu( token );
- }
- return qfalse;
-}
-
-
-
-void CG_LoadMenus( const char *menuFile )
-{
- char *token;
- char *p;
- int len, start;
- fileHandle_t f;
- static char buf[ MAX_MENUDEFFILE ];
-
- start = trap_Milliseconds( );
-
- len = trap_FS_FOpenFile( menuFile, &f, FS_READ );
-
- if( !f )
- {
- trap_Error( va( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile ) );
- len = trap_FS_FOpenFile( "ui/hud.txt", &f, FS_READ );
-
- if( !f )
- trap_Error( va( S_COLOR_RED "default menu file not found: ui/hud.txt, unable to continue!\n", menuFile ) );
- }
-
- if( len >= MAX_MENUDEFFILE )
- {
- trap_Error( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i",
- menuFile, len, MAX_MENUDEFFILE ) );
- trap_FS_FCloseFile( f );
- return;
- }
-
- trap_FS_Read( buf, len, f );
- buf[ len ] = 0;
- trap_FS_FCloseFile( f );
-
- COM_Compress( buf );
-
- Menu_Reset( );
-
- p = buf;
-
- while( 1 )
- {
- token = COM_ParseExt( &p, qtrue );
-
- if( !token || token[ 0 ] == 0 || token[ 0 ] == '}' )
- break;
-
- if( Q_stricmp( token, "}" ) == 0 )
- break;
-
- if( Q_stricmp( token, "loadmenu" ) == 0 )
- {
- if( CG_Load_Menu( &p ) )
- continue;
- else
- break;
- }
- }
-
- Com_Printf( "UI menu load time = %d milli seconds\n", trap_Milliseconds( ) - start );
-}
-
-
-
-static qboolean CG_OwnerDrawHandleKey( int ownerDraw, int flags, float *special, int key )
-{
- return qfalse;
-}
-
-
-static int CG_FeederCount( float feederID )
-{
- int i, count = 0;
-
- if( feederID == FEEDER_ALIENTEAM_LIST )
- {
- for( i = 0; i < cg.numScores; i++ )
- {
- if( cg.scores[ i ].team == PTE_ALIENS )
- count++;
- }
- }
- else if( feederID == FEEDER_HUMANTEAM_LIST )
- {
- for( i = 0; i < cg.numScores; i++ )
- {
- if( cg.scores[ i ].team == PTE_HUMANS )
- count++;
- }
- }
-
- return count;
-}
-
-
-void CG_SetScoreSelection( void *p )
-{
- menuDef_t *menu = (menuDef_t*)p;
- playerState_t *ps = &cg.snap->ps;
- int i, alien, human;
- int feeder;
-
- alien = human = 0;
-
- for( i = 0; i < cg.numScores; i++ )
- {
- if( cg.scores[ i ].team == PTE_ALIENS )
- alien++;
- else if( cg.scores[ i ].team == PTE_HUMANS )
- human++;
-
- if( ps->clientNum == cg.scores[ i ].client )
- cg.selectedScore = i;
- }
-
- if( menu == NULL )
- // just interested in setting the selected score
- return;
-
- feeder = FEEDER_ALIENTEAM_LIST;
- i = alien;
-
- if( cg.scores[ cg.selectedScore ].team == PTE_HUMANS )
- {
- feeder = FEEDER_HUMANTEAM_LIST;
- i = human;
- }
-
- Menu_SetFeederSelection(menu, feeder, i, NULL);
-}
-
-// FIXME: might need to cache this info
-static clientInfo_t * CG_InfoFromScoreIndex( int index, int team, int *scoreIndex )
-{
- int i, count;
- count = 0;
-
- for( i = 0; i < cg.numScores; i++ )
- {
- if( cg.scores[ i ].team == team )
- {
- if( count == index )
- {
- *scoreIndex = i;
- return &cgs.clientinfo[ cg.scores[ i ].client ];
- }
- count++;
- }
- }
-
- *scoreIndex = index;
- return &cgs.clientinfo[ cg.scores[ index ].client ];
-}
-
-static const char *CG_FeederItemText( float feederID, int index, int column, qhandle_t *handle )
-{
- int scoreIndex = 0;
- clientInfo_t *info = NULL;
- int team = -1;
- score_t *sp = NULL;
- qboolean showIcons = qfalse;
-
- *handle = -1;
-
- if( feederID == FEEDER_ALIENTEAM_LIST )
- team = PTE_ALIENS;
- else if( feederID == FEEDER_HUMANTEAM_LIST )
- team = PTE_HUMANS;
-
- info = CG_InfoFromScoreIndex( index, team, &scoreIndex );
- sp = &cg.scores[ scoreIndex ];
-
- if( ( atoi( CG_ConfigString( CS_CLIENTS_READY ) ) & ( 1 << sp->client ) ) &&
- cg.intermissionStarted )
- showIcons = qfalse;
- else if( cg.snap->ps.pm_type == PM_SPECTATOR || cg.snap->ps.pm_flags & PMF_FOLLOW ||
- team == cg.snap->ps.stats[ STAT_PTEAM ] || cg.intermissionStarted )
- showIcons = qtrue;
-
- if( info && info->infoValid )
- {
- switch( column )
- {
- case 0:
- if( showIcons )
- {
- if( sp->weapon != WP_NONE )
- *handle = cg_weapons[ sp->weapon ].weaponIcon;
- }
- break;
-
- case 1:
- if( showIcons )
- {
- if( sp->team == PTE_HUMANS && sp->upgrade != UP_NONE )
- *handle = cg_upgrades[ sp->upgrade ].upgradeIcon;
- else if( sp->team == PTE_ALIENS )
- {
- switch( sp->weapon )
- {
- case WP_ABUILD2:
- case WP_ALEVEL1_UPG:
- case WP_ALEVEL2_UPG:
- case WP_ALEVEL3_UPG:
- *handle = cgs.media.upgradeClassIconShader;
- break;
-
- default:
- break;
- }
- }
- }
- break;
-
- case 2:
- if( ( atoi( CG_ConfigString( CS_CLIENTS_READY ) ) & ( 1 << sp->client ) ) &&
- cg.intermissionStarted )
- return "Ready";
- break;
-
- case 3:
- return info->name;
- break;
-
- case 4:
- return va( "%d", info->score );
- break;
-
- case 5:
- return va( "%4d", sp->time );
- break;
-
- case 6:
- if( sp->ping == -1 )
- return "connecting";
-
- return va( "%4d", sp->ping );
- break;
- }
- }
-
- return "";
-}
-
-static qhandle_t CG_FeederItemImage( float feederID, int index )
-{
- return 0;
-}
-
-static void CG_FeederSelection( float feederID, int index )
-{
- int i, count;
- int team = ( feederID == FEEDER_ALIENTEAM_LIST ) ? PTE_ALIENS : PTE_HUMANS;
- count = 0;
-
- for( i = 0; i < cg.numScores; i++ )
- {
- if( cg.scores[ i ].team == team )
- {
- if( index == count )
- cg.selectedScore = i;
-
- count++;
- }
- }
-}
-
-static float CG_Cvar_Get( const char *cvar )
-{
- char buff[ 128 ];
-
- memset( buff, 0, sizeof( buff ) );
- trap_Cvar_VariableStringBuffer( cvar, buff, sizeof( buff ) );
- return atof( buff );
-}
-
-void CG_Text_PaintWithCursor( float x, float y, float scale, vec4_t color, const char *text,
- int cursorPos, char cursor, int limit, int style )
-{
- CG_Text_Paint( x, y, scale, color, text, 0, limit, style );
-}
-
-static int CG_OwnerDrawWidth( int ownerDraw, float scale )
-{
- switch( ownerDraw )
- {
- case CG_KILLER:
- return CG_Text_Width( CG_GetKillerText( ), scale, 0 );
- break;
- }
-
- return 0;
-}
-
-static int CG_PlayCinematic( const char *name, float x, float y, float w, float h )
-{
- return trap_CIN_PlayCinematic( name, x, y, w, h, CIN_loop );
-}
-
-static void CG_StopCinematic( int handle )
-{
- trap_CIN_StopCinematic( handle );
-}
-
-static void CG_DrawCinematic( int handle, float x, float y, float w, float h )
-{
- trap_CIN_SetExtents( handle, x, y, w, h );
- trap_CIN_DrawCinematic( handle );
-}
-
-static void CG_RunCinematicFrame( int handle )
-{
- trap_CIN_RunCinematic( handle );
-}
-
-//TA: hack to prevent warning
-static qboolean CG_OwnerDrawVisible( int parameter )
-{
- return qfalse;
-}
-
-/*
-=================
-CG_LoadHudMenu
-=================
-*/
-void CG_LoadHudMenu( void )
-{
- char buff[ 1024 ];
- const char *hudSet;
-
- cgDC.registerShaderNoMip = &trap_R_RegisterShaderNoMip;
- cgDC.setColor = &trap_R_SetColor;
- cgDC.drawHandlePic = &CG_DrawPic;
- cgDC.drawStretchPic = &trap_R_DrawStretchPic;
- cgDC.drawText = &CG_Text_Paint;
- cgDC.textWidth = &CG_Text_Width;
- cgDC.textHeight = &CG_Text_Height;
- cgDC.registerModel = &trap_R_RegisterModel;
- cgDC.modelBounds = &trap_R_ModelBounds;
- cgDC.fillRect = &CG_FillRect;
- cgDC.drawRect = &CG_DrawRect;
- cgDC.drawSides = &CG_DrawSides;
- cgDC.drawTopBottom = &CG_DrawTopBottom;
- cgDC.clearScene = &trap_R_ClearScene;
- cgDC.addRefEntityToScene = &trap_R_AddRefEntityToScene;
- cgDC.renderScene = &trap_R_RenderScene;
- cgDC.registerFont = &trap_R_RegisterFont;
- cgDC.ownerDrawItem = &CG_OwnerDraw;
- cgDC.getValue = &CG_GetValue;
- cgDC.ownerDrawVisible = &CG_OwnerDrawVisible;
- cgDC.runScript = &CG_RunMenuScript;
- cgDC.getTeamColor = &CG_GetTeamColor;
- cgDC.setCVar = trap_Cvar_Set;
- cgDC.getCVarString = trap_Cvar_VariableStringBuffer;
- cgDC.getCVarValue = CG_Cvar_Get;
- cgDC.drawTextWithCursor = &CG_Text_PaintWithCursor;
- //cgDC.setOverstrikeMode = &trap_Key_SetOverstrikeMode;
- //cgDC.getOverstrikeMode = &trap_Key_GetOverstrikeMode;
- cgDC.startLocalSound = &trap_S_StartLocalSound;
- cgDC.ownerDrawHandleKey = &CG_OwnerDrawHandleKey;
- cgDC.feederCount = &CG_FeederCount;
- cgDC.feederItemImage = &CG_FeederItemImage;
- cgDC.feederItemText = &CG_FeederItemText;
- cgDC.feederSelection = &CG_FeederSelection;
- //cgDC.setBinding = &trap_Key_SetBinding;
- //cgDC.getBindingBuf = &trap_Key_GetBindingBuf;
- //cgDC.keynumToStringBuf = &trap_Key_KeynumToStringBuf;
- //cgDC.executeText = &trap_Cmd_ExecuteText;
- cgDC.Error = &Com_Error;
- cgDC.Print = &Com_Printf;
- cgDC.ownerDrawWidth = &CG_OwnerDrawWidth;
- //cgDC.Pause = &CG_Pause;
- cgDC.registerSound = &trap_S_RegisterSound;
- cgDC.startBackgroundTrack = &trap_S_StartBackgroundTrack;
- cgDC.stopBackgroundTrack = &trap_S_StopBackgroundTrack;
- cgDC.playCinematic = &CG_PlayCinematic;
- cgDC.stopCinematic = &CG_StopCinematic;
- cgDC.drawCinematic = &CG_DrawCinematic;
- cgDC.runCinematicFrame = &CG_RunCinematicFrame;
-
- Init_Display( &cgDC );
-
- Menu_Reset( );
-
- trap_Cvar_VariableStringBuffer( "cg_hudFiles", buff, sizeof( buff ) );
- hudSet = buff;
-
- if( hudSet[ 0 ] == '\0' )
- hudSet = "ui/hud.txt";
-
- CG_LoadMenus( hudSet );
-}
-
-void CG_AssetCache( void )
-{
- cgDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( ASSET_GRADIENTBAR );
- cgDC.Assets.scrollBar = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR );
- cgDC.Assets.scrollBarArrowDown = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWDOWN );
- cgDC.Assets.scrollBarArrowUp = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWUP );
- cgDC.Assets.scrollBarArrowLeft = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWLEFT );
- cgDC.Assets.scrollBarArrowRight = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWRIGHT );
- cgDC.Assets.scrollBarThumb = trap_R_RegisterShaderNoMip( ASSET_SCROLL_THUMB );
- cgDC.Assets.sliderBar = trap_R_RegisterShaderNoMip( ASSET_SLIDER_BAR );
- cgDC.Assets.sliderThumb = trap_R_RegisterShaderNoMip( ASSET_SLIDER_THUMB );
-}
-
-/*
-=================
-CG_Init
-
-Called after every level change or subsystem restart
-Will perform callbacks to make the loading info screen update.
-=================
-*/
-void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum )
-{
- const char *s;
-
- // clear everything
- memset( &cgs, 0, sizeof( cgs ) );
- memset( &cg, 0, sizeof( cg ) );
- memset( cg_entities, 0, sizeof( cg_entities ) );
-
- cg.clientNum = clientNum;
-
- cgs.processedSnapshotNum = serverMessageNum;
- cgs.serverCommandSequence = serverCommandSequence;
-
- // load a few needed things before we do any screen updates
- cgs.media.whiteShader = trap_R_RegisterShader( "white" );
- cgs.media.charsetShader = trap_R_RegisterShader( "gfx/2d/bigchars" );
- cgs.media.outlineShader = trap_R_RegisterShader( "outline" );
-
- //inform UI to repress cursor whilst loading
- trap_Cvar_Set( "ui_loading", "1" );
-
- //TA: load overrides
- BG_InitClassOverrides( );
- BG_InitBuildableOverrides( );
-
- //TA: dyn memory
- CG_InitMemory( );
-
- CG_RegisterCvars( );
-
- CG_InitConsoleCommands( );
-
- //TA: moved up for LoadHudMenu
- String_Init( );
-
- //TA: TA UI
- CG_AssetCache( );
- CG_LoadHudMenu( ); // load new hud stuff
-
- cg.weaponSelect = WP_NONE;
-
- // old servers
-
- // get the rendering configuration from the client system
- trap_GetGlconfig( &cgs.glconfig );
- cgs.screenXScale = cgs.glconfig.vidWidth / 640.0;
- cgs.screenYScale = cgs.glconfig.vidHeight / 480.0;
-
- // get the gamestate from the client system
- trap_GetGameState( &cgs.gameState );
-
- // check version
- s = CG_ConfigString( CS_GAME_VERSION );
-
- if( strcmp( s, GAME_VERSION ) )
- CG_Error( "Client/Server game mismatch: %s/%s", GAME_VERSION, s );
-
- s = CG_ConfigString( CS_LEVEL_START_TIME );
- cgs.levelStartTime = atoi( s );
-
- CG_ParseServerinfo( );
-
- // load the new map
- trap_CM_LoadMap( cgs.mapname );
-
- cg.loading = qtrue; // force players to load instead of defer
-
- CG_LoadTrailSystems( );
- CG_UpdateMediaFraction( 0.05f );
-
- CG_LoadParticleSystems( );
- CG_UpdateMediaFraction( 0.05f );
-
- CG_RegisterSounds( );
- CG_UpdateMediaFraction( 0.60f );
-
- CG_RegisterGraphics( );
- CG_UpdateMediaFraction( 0.90f );
-
- CG_InitWeapons( );
- CG_UpdateMediaFraction( 0.95f );
-
- CG_InitUpgrades( );
- CG_UpdateMediaFraction( 1.0f );
-
- //TA:
- CG_InitBuildables( );
-
- CG_RegisterClients( ); // if low on memory, some clients will be deferred
-
- cg.loading = qfalse; // future players will be deferred
-
- CG_InitMarkPolys( );
-
- // remove the last loading update
- cg.infoScreenText[ 0 ] = 0;
-
- // Make sure we have update values (scores)
- CG_SetConfigValues( );
-
- CG_StartMusic( );
-
- CG_ShaderStateChanged( );
-
- trap_S_ClearLoopingSounds( qtrue );
-
- cg.consoleValid = qtrue;
-
- trap_Cvar_Set( "ui_loading", "0" );
-}
-
-/*
-=================
-CG_Shutdown
-
-Called before every level change or subsystem restart
-=================
-*/
-void CG_Shutdown( void )
-{
- // some mods may need to do cleanup work here,
- // like closing files or archiving session data
-}
diff --git a/src/cgame/cg_marks.c b/src/cgame/cg_marks.c
deleted file mode 100644
index cc8979de..00000000
--- a/src/cgame/cg_marks.c
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_marks.c -- wall marks
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-/*
-===================================================================
-
-MARK POLYS
-
-===================================================================
-*/
-
-
-markPoly_t cg_activeMarkPolys; // double linked list
-markPoly_t *cg_freeMarkPolys; // single linked list
-markPoly_t cg_markPolys[ MAX_MARK_POLYS ];
-static int markTotal;
-
-/*
-===================
-CG_InitMarkPolys
-
-This is called at startup and for tournement restarts
-===================
-*/
-void CG_InitMarkPolys( void )
-{
- int i;
-
- memset( cg_markPolys, 0, sizeof( cg_markPolys ) );
-
- cg_activeMarkPolys.nextMark = &cg_activeMarkPolys;
- cg_activeMarkPolys.prevMark = &cg_activeMarkPolys;
- cg_freeMarkPolys = cg_markPolys;
-
- for( i = 0; i < MAX_MARK_POLYS - 1; i++ )
- cg_markPolys[ i ].nextMark = &cg_markPolys[ i + 1 ];
-}
-
-
-/*
-==================
-CG_FreeMarkPoly
-==================
-*/
-void CG_FreeMarkPoly( markPoly_t *le )
-{
- if( !le->prevMark )
- CG_Error( "CG_FreeLocalEntity: not active" );
-
- // remove from the doubly linked active list
- le->prevMark->nextMark = le->nextMark;
- le->nextMark->prevMark = le->prevMark;
-
- // the free list is only singly linked
- le->nextMark = cg_freeMarkPolys;
- cg_freeMarkPolys = le;
-}
-
-/*
-===================
-CG_AllocMark
-
-Will allways succeed, even if it requires freeing an old active mark
-===================
-*/
-markPoly_t *CG_AllocMark( void )
-{
- markPoly_t *le;
- int time;
-
- if( !cg_freeMarkPolys )
- {
- // no free entities, so free the one at the end of the chain
- // remove the oldest active entity
- time = cg_activeMarkPolys.prevMark->time;
-
- while( cg_activeMarkPolys.prevMark && time == cg_activeMarkPolys.prevMark->time )
- CG_FreeMarkPoly( cg_activeMarkPolys.prevMark );
- }
-
- le = cg_freeMarkPolys;
- cg_freeMarkPolys = cg_freeMarkPolys->nextMark;
-
- memset( le, 0, sizeof( *le ) );
-
- // link into the active list
- le->nextMark = cg_activeMarkPolys.nextMark;
- le->prevMark = &cg_activeMarkPolys;
- cg_activeMarkPolys.nextMark->prevMark = le;
- cg_activeMarkPolys.nextMark = le;
- return le;
-}
-
-
-
-/*
-=================
-CG_ImpactMark
-
-origin should be a point within a unit of the plane
-dir should be the plane normal
-
-temporary marks will not be stored or randomly oriented, but immediately
-passed to the renderer.
-=================
-*/
-#define MAX_MARK_FRAGMENTS 128
-#define MAX_MARK_POINTS 384
-
-void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir,
- float orientation, float red, float green, float blue, float alpha,
- qboolean alphaFade, float radius, qboolean temporary )
-{
- vec3_t axis[ 3 ];
- float texCoordScale;
- vec3_t originalPoints[ 4 ];
- byte colors[ 4 ];
- int i, j;
- int numFragments;
- markFragment_t markFragments[ MAX_MARK_FRAGMENTS ], *mf;
- vec3_t markPoints[ MAX_MARK_POINTS ];
- vec3_t projection;
-
- if( !cg_addMarks.integer )
- return;
-
- if( radius <= 0 )
- CG_Error( "CG_ImpactMark called with <= 0 radius" );
-
- //if ( markTotal >= MAX_MARK_POLYS ) {
- // return;
- //}
-
- // create the texture axis
- VectorNormalize2( dir, axis[ 0 ] );
- PerpendicularVector( axis[ 1 ], axis[ 0 ] );
- RotatePointAroundVector( axis[ 2 ], axis[ 0 ], axis[ 1 ], orientation );
- CrossProduct( axis[ 0 ], axis[ 2 ], axis[ 1 ] );
-
- texCoordScale = 0.5 * 1.0 / radius;
-
- // create the full polygon
- for( i = 0; i < 3; i++ )
- {
- originalPoints[ 0 ][ i ] = origin[ i ] - radius * axis[ 1 ][ i ] - radius * axis[ 2 ][ i ];
- originalPoints[ 1 ][ i ] = origin[ i ] + radius * axis[ 1 ][ i ] - radius * axis[ 2 ][ i ];
- originalPoints[ 2 ][ i ] = origin[ i ] + radius * axis[ 1 ][ i ] + radius * axis[ 2 ][ i ];
- originalPoints[ 3 ][ i ] = origin[ i ] - radius * axis[ 1 ][ i ] + radius * axis[ 2 ][ i ];
- }
-
- // get the fragments
- VectorScale( dir, -20, projection );
- numFragments = trap_CM_MarkFragments( 4, (void *)originalPoints,
- projection, MAX_MARK_POINTS, markPoints[ 0 ],
- MAX_MARK_FRAGMENTS, markFragments );
-
- colors[ 0 ] = red * 255;
- colors[ 1 ] = green * 255;
- colors[ 2 ] = blue * 255;
- colors[ 3 ] = alpha * 255;
-
- for( i = 0, mf = markFragments; i < numFragments; i++, mf++ )
- {
- polyVert_t *v;
- polyVert_t verts[ MAX_VERTS_ON_POLY ];
- markPoly_t *mark;
-
- // we have an upper limit on the complexity of polygons
- // that we store persistantly
- if( mf->numPoints > MAX_VERTS_ON_POLY )
- mf->numPoints = MAX_VERTS_ON_POLY;
-
- for( j = 0, v = verts; j < mf->numPoints; j++, v++ )
- {
- vec3_t delta;
-
- VectorCopy( markPoints[ mf->firstPoint + j ], v->xyz );
-
- VectorSubtract( v->xyz, origin, delta );
- v->st[ 0 ] = 0.5 + DotProduct( delta, axis[ 1 ] ) * texCoordScale;
- v->st[ 1 ] = 0.5 + DotProduct( delta, axis[ 2 ] ) * texCoordScale;
- *(int *)v->modulate = *(int *)colors;
- }
-
- // if it is a temporary (shadow) mark, add it immediately and forget about it
- if( temporary )
- {
- trap_R_AddPolyToScene( markShader, mf->numPoints, verts );
- continue;
- }
-
- // otherwise save it persistantly
- mark = CG_AllocMark( );
- mark->time = cg.time;
- mark->alphaFade = alphaFade;
- mark->markShader = markShader;
- mark->poly.numVerts = mf->numPoints;
- mark->color[ 0 ] = red;
- mark->color[ 1 ] = green;
- mark->color[ 2 ] = blue;
- mark->color[ 3 ] = alpha;
- memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[ 0 ] ) );
- markTotal++;
- }
-}
-
-
-/*
-===============
-CG_AddMarks
-===============
-*/
-#define MARK_TOTAL_TIME 10000
-#define MARK_FADE_TIME 1000
-
-void CG_AddMarks( void )
-{
- int j;
- markPoly_t *mp, *next;
- int t;
- int fade;
-
- if( !cg_addMarks.integer )
- return;
-
- mp = cg_activeMarkPolys.nextMark;
- for ( ; mp != &cg_activeMarkPolys; mp = next )
- {
- // grab next now, so if the local entity is freed we
- // still have it
- next = mp->nextMark;
-
- // see if it is time to completely remove it
- if( cg.time > mp->time + MARK_TOTAL_TIME )
- {
- CG_FreeMarkPoly( mp );
- continue;
- }
-
- // fade all marks out with time
- t = mp->time + MARK_TOTAL_TIME - cg.time;
- if( t < MARK_FADE_TIME )
- {
- fade = 255 * t / MARK_FADE_TIME;
- if( mp->alphaFade )
- {
- for( j = 0; j < mp->poly.numVerts; j++ )
- mp->verts[ j ].modulate[ 3 ] = fade;
- }
- else
- {
- for( j = 0; j < mp->poly.numVerts; j++ )
- {
- mp->verts[ j ].modulate[ 0 ] = mp->color[ 0 ] * fade;
- mp->verts[ j ].modulate[ 1 ] = mp->color[ 1 ] * fade;
- mp->verts[ j ].modulate[ 2 ] = mp->color[ 2 ] * fade;
- }
- }
- }
-
- trap_R_AddPolyToScene( mp->markShader, mp->poly.numVerts, mp->verts );
- }
-}
-
diff --git a/src/cgame/cg_mem.c b/src/cgame/cg_mem.c
deleted file mode 100644
index 959bd4b0..00000000
--- a/src/cgame/cg_mem.c
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-//
-// cg_mem.c
-//
-// Golliwog: All rewritten to allow deallocation
-//
-// TA: (very) minor changes for client side operation
-// thanks to Golliwog of Quake 3 Fortress ( http://www.q3f.com )
-// for this.
-
-
-#include "cg_local.h"
-
-#define POOLSIZE (256 * 1024)
-#define FREEMEMCOOKIE ((int)0xDEADBE3F) // Any unlikely to be used value
-#define ROUNDBITS 31 // Round to 32 bytes
-
-struct freememnode
-{
- // Size of ROUNDBITS
- int cookie, size; // Size includes node (obviously)
- struct freememnode *prev, *next;
-};
-
-static char memoryPool[ POOLSIZE ];
-static struct freememnode *freehead;
-static int freemem;
-
-void *CG_Alloc( int size )
-{
- // Find a free block and allocate.
- // Does two passes, attempts to fill same-sized free slot first.
-
- struct freememnode *fmn, *prev, *next, *smallest;
- int allocsize, smallestsize;
- char *endptr;
- int *ptr;
-
- allocsize = ( size + sizeof(int) + ROUNDBITS ) & ~ROUNDBITS; // Round to 32-byte boundary
- ptr = NULL;
-
- smallest = NULL;
- smallestsize = POOLSIZE + 1; // Guaranteed not to miss any slots :)
- for( fmn = freehead; fmn; fmn = fmn->next )
- {
- if( fmn->cookie != FREEMEMCOOKIE )
- CG_Error( "CG_Alloc: Memory corruption detected!\n" );
-
- if( fmn->size >= allocsize )
- {
- // We've got a block
- if( fmn->size == allocsize )
- {
- // Same size, just remove
-
- prev = fmn->prev;
- next = fmn->next;
- if( prev )
- prev->next = next; // Point previous node to next
- if( next )
- next->prev = prev; // Point next node to previous
- if( fmn == freehead )
- freehead = next; // Set head pointer to next
- ptr = (int *) fmn;
- break; // Stop the loop, this is fine
- }
- else
- {
- // Keep track of the smallest free slot
- if( fmn->size < smallestsize )
- {
- smallest = fmn;
- smallestsize = fmn->size;
- }
- }
- }
- }
-
- if( !ptr && smallest )
- {
- // We found a slot big enough
- smallest->size -= allocsize;
- endptr = (char *) smallest + smallest->size;
- ptr = (int *) endptr;
- }
-
- if( ptr )
- {
- freemem -= allocsize;
- if( cg_debugAlloc.integer )
- CG_Printf( "CG_Alloc of %i bytes (%i left)\n", allocsize, freemem );
- memset( ptr, 0, allocsize );
- *ptr++ = allocsize; // Store a copy of size for deallocation
- return( (void *) ptr );
- }
-
- CG_Error( "CG_Alloc: failed on allocation of %i bytes\n", size );
- return( NULL );
-}
-
-void CG_Free( void *ptr )
-{
- // Release allocated memory, add it to the free list.
-
- struct freememnode *fmn;
- char *freeend;
- int *freeptr;
-
- freeptr = ptr;
- freeptr--;
-
- freemem += *freeptr;
- if( cg_debugAlloc.integer )
- CG_Printf( "CG_Free of %i bytes (%i left)\n", *freeptr, freemem );
-
- for( fmn = freehead; fmn; fmn = fmn->next )
- {
- freeend = ((char *) fmn) + fmn->size;
- if( freeend == (char *) freeptr )
- {
- // Released block can be merged to an existing node
-
- fmn->size += *freeptr; // Add size of node.
- return;
- }
- }
- // No merging, add to head of list
-
- fmn = (struct freememnode *) freeptr;
- fmn->size = *freeptr; // Set this first to avoid corrupting *freeptr
- fmn->cookie = FREEMEMCOOKIE;
- fmn->prev = NULL;
- fmn->next = freehead;
- freehead->prev = fmn;
- freehead = fmn;
-}
-
-void CG_InitMemory( void )
-{
- // Set up the initial node
-
- freehead = (struct freememnode *) memoryPool;
- freehead->cookie = FREEMEMCOOKIE;
- freehead->size = POOLSIZE;
- freehead->next = NULL;
- freehead->prev = NULL;
- freemem = sizeof(memoryPool);
-}
-
-void CG_DefragmentMemory( void )
-{
- // If there's a frenzy of deallocation and we want to
- // allocate something big, this is useful. Otherwise...
- // not much use.
-
- struct freememnode *startfmn, *endfmn, *fmn;
-
- for( startfmn = freehead; startfmn; )
- {
- endfmn = (struct freememnode *)(((char *) startfmn) + startfmn->size);
- for( fmn = freehead; fmn; )
- {
- if( fmn->cookie != FREEMEMCOOKIE )
- CG_Error( "CG_DefragmentMemory: Memory corruption detected!\n" );
-
- if( fmn == endfmn )
- {
- // We can add fmn onto startfmn.
-
- if( fmn->prev )
- fmn->prev->next = fmn->next;
- if( fmn->next )
- {
- if( !(fmn->next->prev = fmn->prev) )
- freehead = fmn->next; // We're removing the head node
- }
- startfmn->size += fmn->size;
- memset( fmn, 0, sizeof(struct freememnode) ); // A redundant call, really.
-
- startfmn = freehead;
- endfmn = fmn = NULL; // Break out of current loop
- }
- else
- fmn = fmn->next;
- }
-
- if( endfmn )
- startfmn = startfmn->next; // endfmn acts as a 'restart' flag here
- }
-}
diff --git a/src/cgame/cg_particles.c b/src/cgame/cg_particles.c
deleted file mode 100644
index 64587360..00000000
--- a/src/cgame/cg_particles.c
+++ /dev/null
@@ -1,2551 +0,0 @@
-// cg_particles.c -- the particle system
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-static baseParticleSystem_t baseParticleSystems[ MAX_BASEPARTICLE_SYSTEMS ];
-static baseParticleEjector_t baseParticleEjectors[ MAX_BASEPARTICLE_EJECTORS ];
-static baseParticle_t baseParticles[ MAX_BASEPARTICLES ];
-static int numBaseParticleSystems = 0;
-static int numBaseParticleEjectors = 0;
-static int numBaseParticles = 0;
-
-static particleSystem_t particleSystems[ MAX_PARTICLE_SYSTEMS ];
-static particleEjector_t particleEjectors[ MAX_PARTICLE_EJECTORS ];
-static particle_t particles[ MAX_PARTICLES ];
-static particle_t *sortedParticles[ MAX_PARTICLES ];
-static particle_t *radixBuffer[ MAX_PARTICLES ];
-
-/*
-===============
-CG_LerpValues
-
-Lerp between two values
-===============
-*/
-static float CG_LerpValues( float a, float b, float f )
-{
- if( b == PARTICLES_SAME_AS_INITIAL )
- return a;
- else
- return ( (a) + (f) * ( (b) - (a) ) );
-}
-
-/*
-===============
-CG_RandomiseValue
-
-Randomise some value by some variance
-===============
-*/
-static float CG_RandomiseValue( float value, float variance )
-{
- if( value != 0.0f )
- return value * ( 1.0f + ( random( ) * variance ) );
- else
- return random( ) * variance;
-}
-
-/*
-===============
-CG_SpreadVector
-
-Randomly spread a vector by some amount
-===============
-*/
-static void CG_SpreadVector( vec3_t v, float spread )
-{
- vec3_t p, r1, r2;
- float randomSpread = crandom( ) * spread;
- float randomRotation = random( ) * 360.0f;
-
- PerpendicularVector( p, v );
-
- RotatePointAroundVector( r1, p, v, randomSpread );
- RotatePointAroundVector( r2, v, r1, randomRotation );
-
- VectorCopy( r2, v );
-}
-
-/*
-===============
-CG_DestroyParticle
-
-Destroy an individual particle
-===============
-*/
-static void CG_DestroyParticle( particle_t *p, vec3_t impactNormal )
-{
- //this particle has an onDeath particle system attached
- if( p->class->onDeathSystemName[ 0 ] != '\0' )
- {
- particleSystem_t *ps;
-
- ps = CG_SpawnNewParticleSystem( p->class->onDeathSystemHandle );
-
- if( CG_IsParticleSystemValid( &ps ) )
- {
- if( impactNormal )
- CG_SetParticleSystemNormal( ps, impactNormal );
-
- CG_SetAttachmentPoint( &ps->attachment, p->origin );
- CG_AttachToPoint( &ps->attachment );
- }
- }
-
- p->valid = qfalse;
-
- //this gives other systems a couple of
- //frames to realise the particle is gone
- p->frameWhenInvalidated = cg.clientFrame;
-}
-
-/*
-===============
-CG_SpawnNewParticle
-
-Introduce a new particle into the world
-===============
-*/
-static particle_t *CG_SpawnNewParticle( baseParticle_t *bp, particleEjector_t *parent )
-{
- int i, j;
- particle_t *p = NULL;
- particleEjector_t *pe = parent;
- particleSystem_t *ps = parent->parent;
- vec3_t attachmentPoint, attachmentVelocity;
- vec3_t transform[ 3 ];
-
- for( i = 0; i < MAX_PARTICLES; i++ )
- {
- p = &particles[ i ];
-
- //FIXME: the + 1 may be unnecessary
- if( !p->valid && cg.clientFrame > p->frameWhenInvalidated + 1 )
- {
- memset( p, 0, sizeof( particle_t ) );
-
- //found a free slot
- p->class = bp;
- p->parent = pe;
-
- p->birthTime = cg.time;
- p->lifeTime = (int)CG_RandomiseValue( (float)bp->lifeTime, bp->lifeTimeRandFrac );
-
- p->radius.delay = (int)CG_RandomiseValue( (float)bp->radius.delay, bp->radius.delayRandFrac );
- p->radius.initial = CG_RandomiseValue( bp->radius.initial, bp->radius.initialRandFrac );
- p->radius.final = CG_RandomiseValue( bp->radius.final, bp->radius.finalRandFrac );
-
- p->alpha.delay = (int)CG_RandomiseValue( (float)bp->alpha.delay, bp->alpha.delayRandFrac );
- p->alpha.initial = CG_RandomiseValue( bp->alpha.initial, bp->alpha.initialRandFrac );
- p->alpha.final = CG_RandomiseValue( bp->alpha.final, bp->alpha.finalRandFrac );
-
- p->rotation.delay = (int)CG_RandomiseValue( (float)bp->rotation.delay, bp->rotation.delayRandFrac );
- p->rotation.initial = CG_RandomiseValue( bp->rotation.initial, bp->rotation.initialRandFrac );
- p->rotation.final = CG_RandomiseValue( bp->rotation.final, bp->rotation.finalRandFrac );
-
- p->dLightRadius.delay =
- (int)CG_RandomiseValue( (float)bp->dLightRadius.delay, bp->dLightRadius.delayRandFrac );
- p->dLightRadius.initial =
- CG_RandomiseValue( bp->dLightRadius.initial, bp->dLightRadius.initialRandFrac );
- p->dLightRadius.final =
- CG_RandomiseValue( bp->dLightRadius.final, bp->dLightRadius.finalRandFrac );
-
- p->colorDelay = CG_RandomiseValue( bp->colorDelay, bp->colorDelayRandFrac );
-
- p->bounceMarkRadius = CG_RandomiseValue( bp->bounceMarkRadius, bp->bounceMarkRadiusRandFrac );
- p->bounceMarkCount =
- round( CG_RandomiseValue( (float)bp->bounceMarkCount, bp->bounceMarkCountRandFrac ) );
- p->bounceSoundCount =
- round( CG_RandomiseValue( (float)bp->bounceSoundCount, bp->bounceSoundCountRandFrac ) );
-
- if( bp->numModels )
- {
- p->model = bp->models[ rand( ) % bp->numModels ];
-
- if( bp->modelAnimation.frameLerp < 0 )
- {
- bp->modelAnimation.frameLerp = p->lifeTime / bp->modelAnimation.numFrames;
- bp->modelAnimation.initialLerp = p->lifeTime / bp->modelAnimation.numFrames;
- }
- }
-
- if( !CG_AttachmentPoint( &ps->attachment, attachmentPoint ) )
- return NULL;
-
- VectorCopy( attachmentPoint, p->origin );
-
- if( CG_AttachmentAxis( &ps->attachment, transform ) )
- {
- vec3_t transDisplacement;
-
- VectorMatrixMultiply( bp->displacement, transform, transDisplacement );
- VectorAdd( p->origin, transDisplacement, p->origin );
- }
- else
- VectorAdd( p->origin, bp->displacement, p->origin );
-
- for( j = 0; j <= 2; j++ )
- p->origin[ j ] += ( crandom( ) * bp->randDisplacement );
-
- switch( bp->velMoveType )
- {
- case PMT_STATIC:
- if( bp->velMoveValues.dirType == PMD_POINT )
- VectorSubtract( bp->velMoveValues.point, p->origin, p->velocity );
- else if( bp->velMoveValues.dirType == PMD_LINEAR )
- VectorCopy( bp->velMoveValues.dir, p->velocity );
- break;
-
- case PMT_STATIC_TRANSFORM:
- if( !CG_AttachmentAxis( &ps->attachment, transform ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: a particle with velocityType "
- "static_transform is not attached to something which can "
- "provide a transformation\n" );
- return NULL;
- }
-
- if( bp->velMoveValues.dirType == PMD_POINT )
- {
- vec3_t transPoint;
-
- VectorMatrixMultiply( bp->velMoveValues.point, transform, transPoint );
- VectorSubtract( transPoint, p->origin, p->velocity );
- }
- else if( bp->velMoveValues.dirType == PMD_LINEAR )
- VectorMatrixMultiply( bp->velMoveValues.dir, transform, p->velocity );
- break;
-
- case PMT_TAG:
- case PMT_CENT_ANGLES:
- if( bp->velMoveValues.dirType == PMD_POINT )
- VectorSubtract( attachmentPoint, p->origin, p->velocity );
- else if( bp->velMoveValues.dirType == PMD_LINEAR )
- {
- if( !CG_AttachmentDir( &ps->attachment, p->velocity ) )
- return NULL;
- }
- break;
-
- case PMT_NORMAL:
- if( !ps->normalValid )
- {
- CG_Printf( S_COLOR_RED "ERROR: a particle with velocityType "
- "normal has no normal\n" );
- return NULL;
- }
-
- VectorCopy( ps->normal, p->velocity );
-
- //normal displacement
- VectorNormalize( p->velocity );
- VectorMA( p->origin, bp->normalDisplacement, p->velocity, p->origin );
- break;
- }
-
- VectorNormalize( p->velocity );
- CG_SpreadVector( p->velocity, bp->velMoveValues.dirRandAngle );
- VectorScale( p->velocity,
- CG_RandomiseValue( bp->velMoveValues.mag, bp->velMoveValues.magRandFrac ),
- p->velocity );
-
- if( CG_AttachmentVelocity( &ps->attachment, attachmentVelocity ) )
- {
- VectorMA( p->velocity,
- CG_RandomiseValue( bp->velMoveValues.parentVelFrac,
- bp->velMoveValues.parentVelFracRandFrac ), attachmentVelocity, p->velocity );
- }
-
- p->lastEvalTime = cg.time;
-
- p->valid = qtrue;
-
- //this particle has a child particle system attached
- if( bp->childSystemName[ 0 ] != '\0' )
- {
- particleSystem_t *ps = CG_SpawnNewParticleSystem( bp->childSystemHandle );
-
- if( CG_IsParticleSystemValid( &ps ) )
- {
- CG_SetAttachmentParticle( &ps->attachment, p );
- CG_AttachToParticle( &ps->attachment );
- }
- }
-
- //this particle has a child trail system attached
- if( bp->childTrailSystemName[ 0 ] != '\0' )
- {
- trailSystem_t *ts = CG_SpawnNewTrailSystem( bp->childTrailSystemHandle );
-
- if( CG_IsTrailSystemValid( &ts ) )
- {
- CG_SetAttachmentParticle( &ts->frontAttachment, p );
- CG_AttachToParticle( &ts->frontAttachment );
- }
- }
-
- break;
- }
- }
-
- return p;
-}
-
-
-/*
-===============
-CG_SpawnNewParticles
-
-Check if there are any ejectors that should be
-introducing new particles
-===============
-*/
-static void CG_SpawnNewParticles( void )
-{
- int i, j;
- particle_t *p;
- particleSystem_t *ps;
- particleEjector_t *pe;
- baseParticleEjector_t *bpe;
- float lerpFrac;
- int count;
-
- for( i = 0; i < MAX_PARTICLE_EJECTORS; i++ )
- {
- pe = &particleEjectors[ i ];
- ps = pe->parent;
-
- if( pe->valid )
- {
- //a non attached particle system can't make particles
- if( !CG_Attached( &ps->attachment ) )
- continue;
-
- bpe = particleEjectors[ i ].class;
-
- //if this system is scheduled for removal don't make any new particles
- if( !ps->lazyRemove )
- {
- while( pe->nextEjectionTime <= cg.time &&
- ( pe->count > 0 || pe->totalParticles == PARTICLES_INFINITE ) )
- {
- for( j = 0; j < bpe->numParticles; j++ )
- CG_SpawnNewParticle( bpe->particles[ j ], pe );
-
- if( pe->count > 0 )
- pe->count--;
-
- //calculate next ejection time
- lerpFrac = 1.0 - ( (float)pe->count / (float)pe->totalParticles );
- pe->nextEjectionTime = cg.time + (int)CG_RandomiseValue(
- CG_LerpValues( pe->ejectPeriod.initial,
- pe->ejectPeriod.final,
- lerpFrac ),
- pe->ejectPeriod.randFrac );
- }
- }
-
- if( pe->count == 0 || ps->lazyRemove )
- {
- count = 0;
-
- //wait for child particles to die before declaring this pe invalid
- for( j = 0; j < MAX_PARTICLES; j++ )
- {
- p = &particles[ j ];
-
- if( p->valid && p->parent == pe )
- count++;
- }
-
- if( !count )
- pe->valid = qfalse;
- }
- }
- }
-}
-
-
-/*
-===============
-CG_SpawnNewParticleEjector
-
-Allocate a new particle ejector
-===============
-*/
-static particleEjector_t *CG_SpawnNewParticleEjector( baseParticleEjector_t *bpe,
- particleSystem_t *parent )
-{
- int i;
- particleEjector_t *pe = NULL;
- particleSystem_t *ps = parent;
-
- for( i = 0; i < MAX_PARTICLE_EJECTORS; i++ )
- {
- pe = &particleEjectors[ i ];
-
- if( !pe->valid )
- {
- memset( pe, 0, sizeof( particleEjector_t ) );
-
- //found a free slot
- pe->class = bpe;
- pe->parent = ps;
-
- pe->ejectPeriod.initial = bpe->eject.initial;
- pe->ejectPeriod.final = bpe->eject.final;
- pe->ejectPeriod.randFrac = bpe->eject.randFrac;
-
- pe->nextEjectionTime = cg.time +
- (int)CG_RandomiseValue( (float)bpe->eject.delay, bpe->eject.delayRandFrac );
- pe->count = pe->totalParticles =
- (int)round( CG_RandomiseValue( (float)bpe->totalParticles, bpe->totalParticlesRandFrac ) );
-
- pe->valid = qtrue;
-
- if( cg_debugParticles.integer >= 1 )
- CG_Printf( "PE %s created\n", ps->class->name );
-
- break;
- }
- }
-
- return pe;
-}
-
-
-/*
-===============
-CG_SpawnNewParticleSystem
-
-Allocate a new particle system
-===============
-*/
-particleSystem_t *CG_SpawnNewParticleSystem( qhandle_t psHandle )
-{
- int i, j;
- particleSystem_t *ps = NULL;
- baseParticleSystem_t *bps = &baseParticleSystems[ psHandle - 1 ];
-
- if( !bps->registered )
- {
- CG_Printf( S_COLOR_RED "ERROR: a particle system has not been registered yet\n" );
- return NULL;
- }
-
- for( i = 0; i < MAX_PARTICLE_SYSTEMS; i++ )
- {
- ps = &particleSystems[ i ];
-
- if( !ps->valid )
- {
- memset( ps, 0, sizeof( particleSystem_t ) );
-
- //found a free slot
- ps->class = bps;
-
- ps->valid = qtrue;
- ps->lazyRemove = qfalse;
-
- for( j = 0; j < bps->numEjectors; j++ )
- CG_SpawnNewParticleEjector( bps->ejectors[ j ], ps );
-
- if( cg_debugParticles.integer >= 1 )
- CG_Printf( "PS %s created\n", bps->name );
-
- break;
- }
- }
-
- return ps;
-}
-
-/*
-===============
-CG_RegisterParticleSystem
-
-Load the shaders required for a particle system
-===============
-*/
-qhandle_t CG_RegisterParticleSystem( char *name )
-{
- int i, j, k, l;
- baseParticleSystem_t *bps;
- baseParticleEjector_t *bpe;
- baseParticle_t *bp;
-
- for( i = 0; i < MAX_BASEPARTICLE_SYSTEMS; i++ )
- {
- bps = &baseParticleSystems[ i ];
-
- if( !Q_stricmpn( bps->name, name, MAX_QPATH ) )
- {
- //already registered
- if( bps->registered )
- return i + 1;
-
- for( j = 0; j < bps->numEjectors; j++ )
- {
- bpe = bps->ejectors[ j ];
-
- for( l = 0; l < bpe->numParticles; l++ )
- {
- bp = bpe->particles[ l ];
-
- for( k = 0; k < bp->numFrames; k++ )
- bp->shaders[ k ] = trap_R_RegisterShader( bp->shaderNames[ k ] );
-
- for( k = 0; k < bp->numModels; k++ )
- bp->models[ k ] = trap_R_RegisterModel( bp->modelNames[ k ] );
-
- if( bp->bounceMarkName[ 0 ] != '\0' )
- bp->bounceMark = trap_R_RegisterShader( bp->bounceMarkName );
-
- if( bp->bounceSoundName[ 0 ] != '\0' )
- bp->bounceSound = trap_S_RegisterSound( bp->bounceSoundName, qfalse );
-
- //recursively register any children
- if( bp->childSystemName[ 0 ] != '\0' )
- {
- //don't care about a handle for children since
- //the system deals with it
- CG_RegisterParticleSystem( bp->childSystemName );
- }
-
- if( bp->onDeathSystemName[ 0 ] != '\0' )
- {
- //don't care about a handle for children since
- //the system deals with it
- CG_RegisterParticleSystem( bp->onDeathSystemName );
- }
-
- if( bp->childTrailSystemName[ 0 ] != '\0' )
- bp->childTrailSystemHandle = CG_RegisterTrailSystem( bp->childTrailSystemName );
- }
- }
-
- if( cg_debugParticles.integer >= 1 )
- CG_Printf( "Registered particle system %s\n", name );
-
- bps->registered = qtrue;
-
- //avoid returning 0
- return i + 1;
- }
- }
-
- CG_Printf( S_COLOR_RED "ERROR: failed to register particle system %s\n", name );
- return 0;
-}
-
-
-/*
-===============
-CG_ParseValueAndVariance
-
-Parse a value and its random variance
-===============
-*/
-static void CG_ParseValueAndVariance( char *token, float *value, float *variance, qboolean allowNegative )
-{
- char valueBuffer[ 16 ];
- char varianceBuffer[ 16 ];
- char *variancePtr = NULL, *varEndPointer = NULL;
- float localValue = 0.0f;
- float localVariance = 0.0f;
-
- Q_strncpyz( valueBuffer, token, sizeof( valueBuffer ) );
- Q_strncpyz( varianceBuffer, token, sizeof( varianceBuffer ) );
-
- variancePtr = strchr( valueBuffer, '~' );
-
- //variance included
- if( variancePtr )
- {
- variancePtr[ 0 ] = '\0';
- variancePtr++;
-
- localValue = atof_neg( valueBuffer, allowNegative );
-
- varEndPointer = strchr( variancePtr, '%' );
-
- if( varEndPointer )
- {
- varEndPointer[ 0 ] = '\0';
- localVariance = atof_neg( variancePtr, qfalse ) / 100.0f;
- }
- else
- {
- if( localValue != 0.0f )
- localVariance = atof_neg( variancePtr, qfalse ) / localValue;
- else
- localVariance = atof_neg( variancePtr, qfalse );
- }
- }
- else
- localValue = atof_neg( valueBuffer, allowNegative );
-
- if( value != NULL )
- *value = localValue;
-
- if( variance != NULL )
- *variance = localVariance;
-}
-
-/*
-===============
-CG_ParseColor
-===============
-*/
-static qboolean CG_ParseColor( byte *c, char **text_p )
-{
- char *token;
- int i;
-
- for( i = 0; i <= 2; i++ )
- {
- token = COM_Parse( text_p );
-
- if( !Q_stricmp( token, "" ) )
- return qfalse;
-
- c[ i ] = (int)( (float)0xFF * atof_neg( token, qfalse ) );
- }
-
- return qtrue;
-}
-
-/*
-===============
-CG_ParseParticle
-
-Parse a particle section
-===============
-*/
-static qboolean CG_ParseParticle( baseParticle_t *bp, char **text_p )
-{
- char *token;
- float number, randFrac;
- int i;
-
- // read optional parameters
- while( 1 )
- {
- token = COM_Parse( text_p );
-
- if( !token )
- break;
-
- if( !Q_stricmp( token, "" ) )
- return qfalse;
-
- if( !Q_stricmp( token, "bounce" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- if( !Q_stricmp( token, "cull" ) )
- {
- bp->bounceCull = qtrue;
-
- bp->bounceFrac = -1.0f;
- bp->bounceFracRandFrac = 0.0f;
- }
- else
- {
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->bounceFrac = number;
- bp->bounceFracRandFrac = randFrac;
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "bounceMark" ) )
- {
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->bounceMarkCount = number;
- bp->bounceMarkCountRandFrac = randFrac;
-
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->bounceMarkRadius = number;
- bp->bounceMarkRadiusRandFrac = randFrac;
-
- token = COM_ParseExt( text_p, qfalse );
- if( !*token )
- break;
-
- Q_strncpyz( bp->bounceMarkName, token, MAX_QPATH );
-
- continue;
- }
- else if( !Q_stricmp( token, "bounceSound" ) )
- {
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->bounceSoundCount = number;
- bp->bounceSoundCountRandFrac = randFrac;
-
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- Q_strncpyz( bp->bounceSoundName, token, MAX_QPATH );
-
- continue;
- }
- else if( !Q_stricmp( token, "shader" ) )
- {
- if( bp->numModels > 0 )
- {
- CG_Printf( S_COLOR_RED "ERROR: 'shader' not allowed in "
- "conjunction with 'model'\n", token );
- break;
- }
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- if( !Q_stricmp( token, "sync" ) )
- bp->framerate = 0.0f;
- else
- bp->framerate = atof_neg( token, qfalse );
-
- token = COM_ParseExt( text_p, qfalse );
- if( !*token )
- break;
-
- while( *token && bp->numFrames < MAX_PS_SHADER_FRAMES )
- {
- Q_strncpyz( bp->shaderNames[ bp->numFrames++ ], token, MAX_QPATH );
- token = COM_ParseExt( text_p, qfalse );
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "model" ) )
- {
- if( bp->numFrames > 0 )
- {
- CG_Printf( S_COLOR_RED "ERROR: 'model' not allowed in "
- "conjunction with 'shader'\n", token );
- break;
- }
-
- token = COM_ParseExt( text_p, qfalse );
- if( !*token )
- break;
-
- while( *token && bp->numModels < MAX_PS_MODELS )
- {
- Q_strncpyz( bp->modelNames[ bp->numModels++ ], token, MAX_QPATH );
- token = COM_ParseExt( text_p, qfalse );
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "modelAnimation" ) )
- {
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- bp->modelAnimation.firstFrame = atoi_neg( token, qfalse );
-
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- bp->modelAnimation.numFrames = atoi( token );
- bp->modelAnimation.reversed = qfalse;
- bp->modelAnimation.flipflop = qfalse;
-
- // if numFrames is negative the animation is reversed
- if( bp->modelAnimation.numFrames < 0 )
- {
- bp->modelAnimation.numFrames = -bp->modelAnimation.numFrames;
- bp->modelAnimation.reversed = qtrue;
- }
-
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- bp->modelAnimation.loopFrames = atoi( token );
-
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- if( !Q_stricmp( token, "sync" ) )
- {
- bp->modelAnimation.frameLerp = -1;
- bp->modelAnimation.initialLerp = -1;
- }
- else
- {
- float fps = atof_neg( token, qfalse );
-
- if( fps == 0.0f )
- fps = 1.0f;
-
- bp->modelAnimation.frameLerp = 1000 / fps;
- bp->modelAnimation.initialLerp = 1000 / fps;
- }
-
- continue;
- }
- ///
- else if( !Q_stricmp( token, "velocityType" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- if( !Q_stricmp( token, "static" ) )
- bp->velMoveType = PMT_STATIC;
- else if( !Q_stricmp( token, "static_transform" ) )
- bp->velMoveType = PMT_STATIC_TRANSFORM;
- else if( !Q_stricmp( token, "tag" ) )
- bp->velMoveType = PMT_TAG;
- else if( !Q_stricmp( token, "cent" ) )
- bp->velMoveType = PMT_CENT_ANGLES;
- else if( !Q_stricmp( token, "normal" ) )
- bp->velMoveType = PMT_NORMAL;
-
- continue;
- }
- else if( !Q_stricmp( token, "velocityDir" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- if( !Q_stricmp( token, "linear" ) )
- bp->velMoveValues.dirType = PMD_LINEAR;
- else if( !Q_stricmp( token, "point" ) )
- bp->velMoveValues.dirType = PMD_POINT;
-
- continue;
- }
- else if( !Q_stricmp( token, "velocityMagnitude" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->velMoveValues.mag = number;
- bp->velMoveValues.magRandFrac = randFrac;
-
- continue;
- }
- else if( !Q_stricmp( token, "parentVelocityFraction" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->velMoveValues.parentVelFrac = number;
- bp->velMoveValues.parentVelFracRandFrac = randFrac;
-
- continue;
- }
- else if( !Q_stricmp( token, "velocity" ) )
- {
- for( i = 0; i <= 2; i++ )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- bp->velMoveValues.dir[ i ] = atof_neg( token, qtrue );
- }
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, NULL, &randFrac, qfalse );
-
- bp->velMoveValues.dirRandAngle = randFrac;
-
- continue;
- }
- else if( !Q_stricmp( token, "velocityPoint" ) )
- {
- for( i = 0; i <= 2; i++ )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- bp->velMoveValues.point[ i ] = atof_neg( token, qtrue );
- }
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, NULL, &randFrac, qfalse );
-
- bp->velMoveValues.pointRandAngle = randFrac;
-
- continue;
- }
- ///
- else if( !Q_stricmp( token, "accelerationType" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- if( !Q_stricmp( token, "static" ) )
- bp->accMoveType = PMT_STATIC;
- else if( !Q_stricmp( token, "static_transform" ) )
- bp->accMoveType = PMT_STATIC_TRANSFORM;
- else if( !Q_stricmp( token, "tag" ) )
- bp->accMoveType = PMT_TAG;
- else if( !Q_stricmp( token, "cent" ) )
- bp->accMoveType = PMT_CENT_ANGLES;
- else if( !Q_stricmp( token, "normal" ) )
- bp->accMoveType = PMT_NORMAL;
-
- continue;
- }
- else if( !Q_stricmp( token, "accelerationDir" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- if( !Q_stricmp( token, "linear" ) )
- bp->accMoveValues.dirType = PMD_LINEAR;
- else if( !Q_stricmp( token, "point" ) )
- bp->accMoveValues.dirType = PMD_POINT;
-
- continue;
- }
- else if( !Q_stricmp( token, "accelerationMagnitude" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->accMoveValues.mag = number;
- bp->accMoveValues.magRandFrac = randFrac;
-
- continue;
- }
- else if( !Q_stricmp( token, "acceleration" ) )
- {
- for( i = 0; i <= 2; i++ )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- bp->accMoveValues.dir[ i ] = atof_neg( token, qtrue );
- }
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, NULL, &randFrac, qfalse );
-
- bp->accMoveValues.dirRandAngle = randFrac;
-
- continue;
- }
- else if( !Q_stricmp( token, "accelerationPoint" ) )
- {
- for( i = 0; i <= 2; i++ )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- bp->accMoveValues.point[ i ] = atof_neg( token, qtrue );
- }
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, NULL, &randFrac, qfalse );
-
- bp->accMoveValues.pointRandAngle = randFrac;
-
- continue;
- }
- ///
- else if( !Q_stricmp( token, "displacement" ) )
- {
- for( i = 0; i <= 2; i++ )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- bp->displacement[ i ] = atof_neg( token, qtrue );
- }
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, NULL, &randFrac, qfalse );
-
- bp->randDisplacement = randFrac;
-
- continue;
- }
- else if( !Q_stricmp( token, "normalDisplacement" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- bp->normalDisplacement = atof_neg( token, qtrue );
-
- continue;
- }
- else if( !Q_stricmp( token, "overdrawProtection" ) )
- {
- bp->overdrawProtection = qtrue;
-
- continue;
- }
- else if( !Q_stricmp( token, "realLight" ) )
- {
- bp->realLight = qtrue;
-
- continue;
- }
- else if( !Q_stricmp( token, "dynamicLight" ) )
- {
- bp->dynamicLight = qtrue;
-
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->dLightRadius.delay = (int)number;
- bp->dLightRadius.delayRandFrac = randFrac;
-
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->dLightRadius.initial = number;
- bp->dLightRadius.initialRandFrac = randFrac;
-
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- if( !Q_stricmp( token, "-" ) )
- {
- bp->dLightRadius.final = PARTICLES_SAME_AS_INITIAL;
- bp->dLightRadius.finalRandFrac = 0.0f;
- }
- else
- {
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->dLightRadius.final = number;
- bp->dLightRadius.finalRandFrac = randFrac;
- }
-
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- if( !Q_stricmp( token, "{" ) )
- {
- if( !CG_ParseColor( bp->dLightColor, text_p ) )
- break;
-
- token = COM_Parse( text_p );
- if( Q_stricmp( token, "}" ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: missing '}'\n" );
- break;
- }
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "cullOnStartSolid" ) )
- {
- bp->cullOnStartSolid = qtrue;
-
- continue;
- }
- else if( !Q_stricmp( token, "radius" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->radius.delay = (int)number;
- bp->radius.delayRandFrac = randFrac;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->radius.initial = number;
- bp->radius.initialRandFrac = randFrac;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- if( !Q_stricmp( token, "-" ) )
- {
- bp->radius.final = PARTICLES_SAME_AS_INITIAL;
- bp->radius.finalRandFrac = 0.0f;
- }
- else
- {
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->radius.final = number;
- bp->radius.finalRandFrac = randFrac;
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "alpha" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->alpha.delay = (int)number;
- bp->alpha.delayRandFrac = randFrac;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->alpha.initial = number;
- bp->alpha.initialRandFrac = randFrac;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- if( !Q_stricmp( token, "-" ) )
- {
- bp->alpha.final = PARTICLES_SAME_AS_INITIAL;
- bp->alpha.finalRandFrac = 0.0f;
- }
- else
- {
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->alpha.final = number;
- bp->alpha.finalRandFrac = randFrac;
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "color" ) )
- {
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->colorDelay = (int)number;
- bp->colorDelayRandFrac = randFrac;
-
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- if( !Q_stricmp( token, "{" ) )
- {
- if( !CG_ParseColor( bp->initialColor, text_p ) )
- break;
-
- token = COM_Parse( text_p );
- if( Q_stricmp( token, "}" ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: missing '}'\n" );
- break;
- }
-
- token = COM_Parse( text_p );
- if( !*token )
- break;
-
- if( !Q_stricmp( token, "-" ) )
- {
- bp->finalColor[ 0 ] = bp->initialColor[ 0 ];
- bp->finalColor[ 1 ] = bp->initialColor[ 1 ];
- bp->finalColor[ 2 ] = bp->initialColor[ 2 ];
- }
- else if( !Q_stricmp( token, "{" ) )
- {
- if( !CG_ParseColor( bp->finalColor, text_p ) )
- break;
-
- token = COM_Parse( text_p );
- if( Q_stricmp( token, "}" ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: missing '}'\n" );
- break;
- }
- }
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: missing '{'\n" );
- break;
- }
- }
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: missing '{'\n" );
- break;
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "rotation" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->rotation.delay = (int)number;
- bp->rotation.delayRandFrac = randFrac;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qtrue );
-
- bp->rotation.initial = number;
- bp->rotation.initialRandFrac = randFrac;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- if( !Q_stricmp( token, "-" ) )
- {
- bp->rotation.final = PARTICLES_SAME_AS_INITIAL;
- bp->rotation.finalRandFrac = 0.0f;
- }
- else
- {
- CG_ParseValueAndVariance( token, &number, &randFrac, qtrue );
-
- bp->rotation.final = number;
- bp->rotation.finalRandFrac = randFrac;
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "lifeTime" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bp->lifeTime = (int)number;
- bp->lifeTimeRandFrac = randFrac;
-
- continue;
- }
- else if( !Q_stricmp( token, "childSystem" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- Q_strncpyz( bp->childSystemName, token, MAX_QPATH );
-
- continue;
- }
- else if( !Q_stricmp( token, "onDeathSystem" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- Q_strncpyz( bp->onDeathSystemName, token, MAX_QPATH );
-
- continue;
- }
- else if( !Q_stricmp( token, "childTrailSystem" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- Q_strncpyz( bp->childTrailSystemName, token, MAX_QPATH );
-
- continue;
- }
- else if( !Q_stricmp( token, "}" ) )
- return qtrue; //reached the end of this particle
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: unknown token '%s' in particle\n", token );
- return qfalse;
- }
- }
-
- return qfalse;
-}
-
-/*
-===============
-CG_InitialiseBaseParticle
-===============
-*/
-static void CG_InitialiseBaseParticle( baseParticle_t *bp )
-{
- memset( bp, 0, sizeof( baseParticle_t ) );
-
- memset( bp->initialColor, 0xFF, sizeof( bp->initialColor ) );
- memset( bp->finalColor, 0xFF, sizeof( bp->finalColor ) );
-}
-
-/*
-===============
-CG_ParseParticleEjector
-
-Parse a particle ejector section
-===============
-*/
-static qboolean CG_ParseParticleEjector( baseParticleEjector_t *bpe, char **text_p )
-{
- char *token;
- float number, randFrac;
-
- // read optional parameters
- while( 1 )
- {
- token = COM_Parse( text_p );
-
- if( !token )
- break;
-
- if( !Q_stricmp( token, "" ) )
- return qfalse;
-
- if( !Q_stricmp( token, "{" ) )
- {
- CG_InitialiseBaseParticle( &baseParticles[ numBaseParticles ] );
-
- if( !CG_ParseParticle( &baseParticles[ numBaseParticles ], text_p ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: failed to parse particle\n" );
- return qfalse;
- }
-
- if( bpe->numParticles == MAX_PARTICLES_PER_EJECTOR )
- {
- CG_Printf( S_COLOR_RED "ERROR: ejector has > %d particles\n", MAX_PARTICLES_PER_EJECTOR );
- return qfalse;
- }
- else if( numBaseParticles == MAX_BASEPARTICLES )
- {
- CG_Printf( S_COLOR_RED "ERROR: maximum number of particles (%d) reached\n", MAX_BASEPARTICLES );
- return qfalse;
- }
- else
- {
- //start parsing particles again
- bpe->particles[ bpe->numParticles ] = &baseParticles[ numBaseParticles ];
- bpe->numParticles++;
- numBaseParticles++;
- }
- continue;
- }
- else if( !Q_stricmp( token, "delay" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bpe->eject.delay = (int)number;
- bpe->eject.delayRandFrac = randFrac;
-
- continue;
- }
- else if( !Q_stricmp( token, "period" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- bpe->eject.initial = atoi_neg( token, qfalse );
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- if( !Q_stricmp( token, "-" ) )
- bpe->eject.final = PARTICLES_SAME_AS_INITIAL;
- else
- bpe->eject.final = atoi_neg( token, qfalse );
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- CG_ParseValueAndVariance( token, NULL, &bpe->eject.randFrac, qfalse );
-
- continue;
- }
- else if( !Q_stricmp( token, "count" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- if( !Q_stricmp( token, "infinite" ) )
- {
- bpe->totalParticles = PARTICLES_INFINITE;
- bpe->totalParticlesRandFrac = 0.0f;
- }
- else
- {
- CG_ParseValueAndVariance( token, &number, &randFrac, qfalse );
-
- bpe->totalParticles = (int)number;
- bpe->totalParticlesRandFrac = randFrac;
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "particle" ) ) //acceptable text
- continue;
- else if( !Q_stricmp( token, "}" ) )
- return qtrue; //reached the end of this particle ejector
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: unknown token '%s' in particle ejector\n", token );
- return qfalse;
- }
- }
-
- return qfalse;
-}
-
-
-/*
-===============
-CG_ParseParticleSystem
-
-Parse a particle system section
-===============
-*/
-static qboolean CG_ParseParticleSystem( baseParticleSystem_t *bps, char **text_p, const char *name )
-{
- char *token;
- baseParticleEjector_t *bpe;
-
- // read optional parameters
- while( 1 )
- {
- token = COM_Parse( text_p );
-
- if( !token )
- break;
-
- if( !Q_stricmp( token, "" ) )
- return qfalse;
-
- if( !Q_stricmp( token, "{" ) )
- {
- if( !CG_ParseParticleEjector( &baseParticleEjectors[ numBaseParticleEjectors ], text_p ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: failed to parse particle ejector\n" );
- return qfalse;
- }
-
- bpe = &baseParticleEjectors[ numBaseParticleEjectors ];
-
- //check for infinite count + zero period
- if( bpe->totalParticles == PARTICLES_INFINITE &&
- ( bpe->eject.initial == 0.0f || bpe->eject.final == 0.0f ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: ejector with 'count infinite' potentially has zero period\n" );
- return qfalse;
- }
-
- if( bps->numEjectors == MAX_EJECTORS_PER_SYSTEM )
- {
- CG_Printf( S_COLOR_RED "ERROR: particle system has > %d ejectors\n", MAX_EJECTORS_PER_SYSTEM );
- return qfalse;
- }
- else if( numBaseParticleEjectors == MAX_BASEPARTICLE_EJECTORS )
- {
- CG_Printf( S_COLOR_RED "ERROR: maximum number of particle ejectors (%d) reached\n",
- MAX_BASEPARTICLE_EJECTORS );
- return qfalse;
- }
- else
- {
- //start parsing ejectors again
- bps->ejectors[ bps->numEjectors ] = &baseParticleEjectors[ numBaseParticleEjectors ];
- bps->numEjectors++;
- numBaseParticleEjectors++;
- }
- continue;
- }
- else if( !Q_stricmp( token, "thirdPersonOnly" ) )
- bps->thirdPersonOnly = qtrue;
- else if( !Q_stricmp( token, "ejector" ) ) //acceptable text
- continue;
- else if( !Q_stricmp( token, "}" ) )
- {
- if( cg_debugParticles.integer >= 1 )
- CG_Printf( "Parsed particle system %s\n", name );
-
- return qtrue; //reached the end of this particle system
- }
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: unknown token '%s' in particle system %s\n", token, bps->name );
- return qfalse;
- }
- }
-
- return qfalse;
-}
-
-/*
-===============
-CG_ParseParticleFile
-
-Load the particle systems from a particle file
-===============
-*/
-static qboolean CG_ParseParticleFile( const char *fileName )
-{
- char *text_p;
- int i;
- int len;
- char *token;
- char text[ 32000 ];
- char psName[ MAX_QPATH ];
- qboolean psNameSet = qfalse;
- fileHandle_t f;
-
- // load the file
- len = trap_FS_FOpenFile( fileName, &f, FS_READ );
- if( len <= 0 )
- return qfalse;
-
- if( len >= sizeof( text ) - 1 )
- {
- CG_Printf( S_COLOR_RED "ERROR: particle file %s too long\n", fileName );
- return qfalse;
- }
-
- trap_FS_Read( text, len, f );
- text[ len ] = 0;
- trap_FS_FCloseFile( f );
-
- // parse the text
- text_p = text;
-
- // read optional parameters
- while( 1 )
- {
- token = COM_Parse( &text_p );
-
- if( !Q_stricmp( token, "" ) )
- break;
-
- if( !Q_stricmp( token, "{" ) )
- {
- if( psNameSet )
- {
- //check for name space clashes
- for( i = 0; i < numBaseParticleSystems; i++ )
- {
- if( !Q_stricmp( baseParticleSystems[ i ].name, psName ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: a particle system is already named %s\n", psName );
- return qfalse;
- }
- }
-
- Q_strncpyz( baseParticleSystems[ numBaseParticleSystems ].name, psName, MAX_QPATH );
-
- if( !CG_ParseParticleSystem( &baseParticleSystems[ numBaseParticleSystems ], &text_p, psName ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: %s: failed to parse particle system %s\n", fileName, psName );
- return qfalse;
- }
-
- //start parsing particle systems again
- psNameSet = qfalse;
-
- if( numBaseParticleSystems == MAX_BASEPARTICLE_SYSTEMS )
- {
- CG_Printf( S_COLOR_RED "ERROR: maximum number of particle systems (%d) reached\n",
- MAX_BASEPARTICLE_SYSTEMS );
- return qfalse;
- }
- else
- numBaseParticleSystems++;
-
- continue;
- }
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: unamed particle system\n" );
- return qfalse;
- }
- }
-
- if( !psNameSet )
- {
- Q_strncpyz( psName, token, sizeof( psName ) );
- psNameSet = qtrue;
- }
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: particle system already named\n" );
- return qfalse;
- }
- }
-
- return qtrue;
-}
-
-
-/*
-===============
-CG_LoadParticleSystems
-
-Load particle systems from .particle files
-===============
-*/
-void CG_LoadParticleSystems( void )
-{
- int i, j;
- const char *s[ MAX_PARTICLE_FILES ];
-
- //clear out the old
- numBaseParticleSystems = 0;
- numBaseParticleEjectors = 0;
- numBaseParticles = 0;
-
- for( i = 0; i < MAX_BASEPARTICLE_SYSTEMS; i++ )
- {
- baseParticleSystem_t *bps = &baseParticleSystems[ i ];
- memset( bps, 0, sizeof( baseParticleSystem_t ) );
- }
-
- for( i = 0; i < MAX_BASEPARTICLE_EJECTORS; i++ )
- {
- baseParticleEjector_t *bpe = &baseParticleEjectors[ i ];
- memset( bpe, 0, sizeof( baseParticleEjector_t ) );
- }
-
- for( i = 0; i < MAX_BASEPARTICLES; i++ )
- {
- baseParticle_t *bp = &baseParticles[ i ];
- memset( bp, 0, sizeof( baseParticle_t ) );
- }
-
-
- //and bring in the new
- for( i = 0; i < MAX_PARTICLE_FILES; i++ )
- {
- s[ i ] = CG_ConfigString( CS_PARTICLE_FILES + i );
-
- if( strlen( s[ i ] ) > 0 )
- {
- CG_Printf( "...loading '%s'\n", s[ i ] );
- CG_ParseParticleFile( s[ i ] );
- }
- else
- break;
- }
-
- //connect any child systems to their psHandle
- for( i = 0; i < numBaseParticles; i++ )
- {
- baseParticle_t *bp = &baseParticles[ i ];
-
- if( bp->childSystemName[ 0 ] )
- {
- //particle class has a child, resolve the name
- for( j = 0; j < numBaseParticleSystems; j++ )
- {
- baseParticleSystem_t *bps = &baseParticleSystems[ j ];
-
- if( !Q_stricmp( bps->name, bp->childSystemName ) )
- {
- //FIXME: add checks for cycles and infinite children
-
- bp->childSystemHandle = j + 1;
-
- break;
- }
- }
-
- if( j == numBaseParticleSystems )
- {
- //couldn't find named particle system
- CG_Printf( S_COLOR_YELLOW "WARNING: failed to find child %s\n", bp->childSystemName );
- bp->childSystemName[ 0 ] = '\0';
- }
- }
-
- if( bp->onDeathSystemName[ 0 ] )
- {
- //particle class has a child, resolve the name
- for( j = 0; j < numBaseParticleSystems; j++ )
- {
- baseParticleSystem_t *bps = &baseParticleSystems[ j ];
-
- if( !Q_stricmp( bps->name, bp->onDeathSystemName ) )
- {
- //FIXME: add checks for cycles and infinite children
-
- bp->onDeathSystemHandle = j + 1;
-
- break;
- }
- }
-
- if( j == numBaseParticleSystems )
- {
- //couldn't find named particle system
- CG_Printf( S_COLOR_YELLOW "WARNING: failed to find onDeath system %s\n", bp->onDeathSystemName );
- bp->onDeathSystemName[ 0 ] = '\0';
- }
- }
- }
-}
-
-/*
-===============
-CG_SetParticleSystemNormal
-===============
-*/
-void CG_SetParticleSystemNormal( particleSystem_t *ps, vec3_t normal )
-{
- if( ps == NULL || !ps->valid )
- {
- CG_Printf( S_COLOR_YELLOW "WARNING: tried to modify a NULL particle system\n" );
- return;
- }
-
- ps->normalValid = qtrue;
- VectorCopy( normal, ps->normal );
- VectorNormalize( ps->normal );
-}
-
-
-/*
-===============
-CG_DestroyParticleSystem
-
-Destroy a particle system
-
-This doesn't actually invalidate anything, it just stops
-particle ejectors from producing new particles so the
-garbage collector will eventually remove this system.
-However is does set the pointer to NULL so the user is
-unable to manipulate this particle system any longer.
-===============
-*/
-void CG_DestroyParticleSystem( particleSystem_t **ps )
-{
- int i;
- particleEjector_t *pe;
-
- if( *ps == NULL || !(*ps)->valid )
- {
- CG_Printf( S_COLOR_YELLOW "WARNING: tried to destroy a NULL particle system\n" );
- return;
- }
-
- if( cg_debugParticles.integer >= 1 )
- CG_Printf( "PS destroyed\n" );
-
- for( i = 0; i < MAX_PARTICLE_EJECTORS; i++ )
- {
- pe = &particleEjectors[ i ];
-
- if( pe->valid && pe->parent == *ps )
- pe->totalParticles = pe->count = 0;
- }
-
- *ps = NULL;
-}
-
-/*
-===============
-CG_IsParticleSystemInfinite
-
-Test a particle system for 'count infinite' ejectors
-===============
-*/
-qboolean CG_IsParticleSystemInfinite( particleSystem_t *ps )
-{
- int i;
- particleEjector_t *pe;
-
- if( ps == NULL )
- {
- CG_Printf( S_COLOR_YELLOW "WARNING: tried to test a NULL particle system\n" );
- return qfalse;
- }
-
- if( !ps->valid )
- {
- CG_Printf( S_COLOR_YELLOW "WARNING: tried to test an invalid particle system\n" );
- return qfalse;
- }
-
- //don't bother checking already invalid systems
- if( !ps->valid )
- return qfalse;
-
- for( i = 0; i < MAX_PARTICLE_EJECTORS; i++ )
- {
- pe = &particleEjectors[ i ];
-
- if( pe->valid && pe->parent == ps )
- {
- if( pe->totalParticles == PARTICLES_INFINITE )
- return qtrue;
- }
- }
-
- return qfalse;
-}
-
-/*
-===============
-CG_IsParticleSystemValid
-
-Test a particle system for validity
-===============
-*/
-qboolean CG_IsParticleSystemValid( particleSystem_t **ps )
-{
- if( *ps == NULL || ( *ps && !(*ps)->valid ) )
- {
- if( *ps && !(*ps)->valid )
- *ps = NULL;
-
- return qfalse;
- }
-
- return qtrue;
-}
-
-/*
-===============
-CG_GarbageCollectParticleSystems
-
-Destroy inactive particle systems
-===============
-*/
-static void CG_GarbageCollectParticleSystems( void )
-{
- int i, j, count;
- particleSystem_t *ps;
- particleEjector_t *pe;
- int centNum;
-
- for( i = 0; i < MAX_PARTICLE_SYSTEMS; i++ )
- {
- ps = &particleSystems[ i ];
- count = 0;
-
- //don't bother checking already invalid systems
- if( !ps->valid )
- continue;
-
- for( j = 0; j < MAX_PARTICLE_EJECTORS; j++ )
- {
- pe = &particleEjectors[ j ];
-
- if( pe->valid && pe->parent == ps )
- count++;
- }
-
- if( !count )
- ps->valid = qfalse;
-
- //check systems where the parent cent has left the PVS
- //( local player entity is always valid )
- if( ( centNum = CG_AttachmentCentNum( &ps->attachment ) ) >= 0 &&
- centNum != cg.snap->ps.clientNum )
- {
- if( !cg_entities[ centNum ].valid )
- ps->lazyRemove = qtrue;
- }
-
- if( cg_debugParticles.integer >= 1 && !ps->valid )
- CG_Printf( "PS %s garbage collected\n", ps->class->name );
- }
-}
-
-
-/*
-===============
-CG_CalculateTimeFrac
-
-Calculate the fraction of time passed
-===============
-*/
-static float CG_CalculateTimeFrac( int birth, int life, int delay )
-{
- float frac;
-
- frac = ( (float)cg.time - (float)( birth + delay ) ) / (float)( life - delay );
-
- if( frac < 0.0f )
- frac = 0.0f;
- else if( frac > 1.0f )
- frac = 1.0f;
-
- return frac;
-}
-
-/*
-===============
-CG_EvaluateParticlePhysics
-
-Compute the physics on a specific particle
-===============
-*/
-static void CG_EvaluateParticlePhysics( particle_t *p )
-{
- particleSystem_t *ps = p->parent->parent;
- baseParticle_t *bp = p->class;
- vec3_t acceleration, newOrigin;
- vec3_t mins, maxs;
- float deltaTime, bounce, radius, dot;
- trace_t trace;
- vec3_t transform[ 3 ];
-
- if( p->atRest )
- {
- VectorClear( p->velocity );
- return;
- }
-
- switch( bp->accMoveType )
- {
- case PMT_STATIC:
- if( bp->accMoveValues.dirType == PMD_POINT )
- VectorSubtract( bp->accMoveValues.point, p->origin, acceleration );
- else if( bp->accMoveValues.dirType == PMD_LINEAR )
- VectorCopy( bp->accMoveValues.dir, acceleration );
-
- break;
-
- case PMT_STATIC_TRANSFORM:
- if( !CG_AttachmentAxis( &ps->attachment, transform ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: a particle with accelerationType "
- "static_transform is not attached to something which can "
- "provide a transformation\n" );
- return;
- }
-
- if( bp->accMoveValues.dirType == PMD_POINT )
- {
- vec3_t transPoint;
-
- VectorMatrixMultiply( bp->accMoveValues.point, transform, transPoint );
- VectorSubtract( transPoint, p->origin, acceleration );
- }
- else if( bp->accMoveValues.dirType == PMD_LINEAR )
- VectorMatrixMultiply( bp->accMoveValues.dir, transform, acceleration );
- break;
-
- case PMT_TAG:
- case PMT_CENT_ANGLES:
- if( bp->accMoveValues.dirType == PMD_POINT )
- {
- vec3_t point;
-
- if( !CG_AttachmentPoint( &ps->attachment, point ) )
- return;
-
- VectorSubtract( point, p->origin, acceleration );
- }
- else if( bp->accMoveValues.dirType == PMD_LINEAR )
- {
- if( !CG_AttachmentDir( &ps->attachment, acceleration ) )
- return;
- }
- break;
-
- case PMT_NORMAL:
- if( !ps->normalValid )
- return;
-
- VectorCopy( ps->normal, acceleration );
-
- break;
- }
-
-#define MAX_ACC_RADIUS 1000.0f
-
- if( bp->accMoveValues.dirType == PMD_POINT )
- {
- //FIXME: so this fall off is a bit... odd -- it works..
- float r2 = DotProduct( acceleration, acceleration ); // = radius^2
- float scale = ( MAX_ACC_RADIUS - r2 ) / MAX_ACC_RADIUS;
-
- if( scale > 1.0f )
- scale = 1.0f;
- else if( scale < 0.1f )
- scale = 0.1f;
-
- scale *= CG_RandomiseValue( bp->accMoveValues.mag, bp->accMoveValues.magRandFrac );
-
- VectorNormalize( acceleration );
- CG_SpreadVector( acceleration, bp->accMoveValues.dirRandAngle );
- VectorScale( acceleration, scale, acceleration );
- }
- else if( bp->accMoveValues.dirType == PMD_LINEAR )
- {
- VectorNormalize( acceleration );
- CG_SpreadVector( acceleration, bp->accMoveValues.dirRandAngle );
- VectorScale( acceleration,
- CG_RandomiseValue( bp->accMoveValues.mag, bp->accMoveValues.magRandFrac ),
- acceleration );
- }
-
- radius = CG_LerpValues( p->radius.initial,
- p->radius.final,
- CG_CalculateTimeFrac( p->birthTime,
- p->lifeTime,
- p->radius.delay ) );
-
- VectorSet( mins, -radius, -radius, -radius );
- VectorSet( maxs, radius, radius, radius );
-
- bounce = CG_RandomiseValue( bp->bounceFrac, bp->bounceFracRandFrac );
-
- deltaTime = (float)( cg.time - p->lastEvalTime ) * 0.001;
- VectorMA( p->velocity, deltaTime, acceleration, p->velocity );
- VectorMA( p->origin, deltaTime, p->velocity, newOrigin );
- p->lastEvalTime = cg.time;
-
- CG_Trace( &trace, p->origin, mins, maxs, newOrigin,
- CG_AttachmentCentNum( &ps->attachment ), CONTENTS_SOLID );
-
- //not hit anything or not a collider
- if( trace.fraction == 1.0f || bounce == 0.0f )
- {
- VectorCopy( newOrigin, p->origin );
- return;
- }
-
- //remove particles that get into a CONTENTS_NODROP brush
- if( ( trap_CM_PointContents( trace.endpos, 0 ) & CONTENTS_NODROP ) ||
- ( bp->cullOnStartSolid && trace.startsolid ) )
- {
- CG_DestroyParticle( p, NULL );
- return;
- }
- else if( bp->bounceCull )
- {
- CG_DestroyParticle( p, trace.plane.normal );
- return;
- }
-
- //reflect the velocity on the trace plane
- dot = DotProduct( p->velocity, trace.plane.normal );
- VectorMA( p->velocity, -2.0f * dot, trace.plane.normal, p->velocity );
-
- VectorScale( p->velocity, bounce, p->velocity );
-
- if( trace.plane.normal[ 2 ] > 0.5f &&
- ( p->velocity[ 2 ] < 40.0f ||
- p->velocity[ 2 ] < -cg.frametime * p->velocity[ 2 ] ) )
- p->atRest = qtrue;
-
- if( bp->bounceMarkName[ 0 ] && p->bounceMarkCount > 0 )
- {
- CG_ImpactMark( bp->bounceMark, trace.endpos, trace.plane.normal,
- random( ) * 360, 1, 1, 1, 1, qtrue, bp->bounceMarkRadius, qfalse );
- p->bounceMarkCount--;
- }
-
- if( bp->bounceSoundName[ 0 ] && p->bounceSoundCount > 0 )
- {
- trap_S_StartSound( trace.endpos, ENTITYNUM_WORLD, CHAN_AUTO, bp->bounceSound );
- p->bounceSoundCount--;
- }
-
- VectorCopy( trace.endpos, p->origin );
-}
-
-
-#define GETKEY(x,y) (((x)>>y)&0xFF)
-
-/*
-===============
-CG_Radix
-===============
-*/
-static void CG_Radix( int bits, int size, particle_t **source, particle_t **dest )
-{
- int count[ 256 ];
- int index[ 256 ];
- int i;
-
- memset( count, 0, sizeof( count ) );
-
- for( i = 0; i < size; i++ )
- count[ GETKEY( source[ i ]->sortKey, bits ) ]++;
-
- index[ 0 ] = 0;
-
- for( i = 1; i < 256; i++ )
- index[ i ] = index[ i - 1 ] + count[ i - 1 ];
-
- for( i = 0; i < size; i++ )
- dest[ index[ GETKEY( source[ i ]->sortKey, bits ) ]++ ] = source[ i ];
-}
-
-/*
-===============
-CG_RadixSort
-
-Radix sort with 4 byte size buckets
-===============
-*/
-static void CG_RadixSort( particle_t **source, particle_t **temp, int size )
-{
- CG_Radix( 0, size, source, temp );
- CG_Radix( 8, size, temp, source );
- CG_Radix( 16, size, source, temp );
- CG_Radix( 24, size, temp, source );
-}
-
-/*
-===============
-CG_CompactAndSortParticles
-
-Depth sort the particles
-===============
-*/
-static void CG_CompactAndSortParticles( void )
-{
- int i, j = 0;
- int numParticles;
- vec3_t delta;
-
- for( i = 0; i < MAX_PARTICLES; i++ )
- sortedParticles[ i ] = &particles[ i ];
-
- for( i = MAX_PARTICLES - 1; i >= 0; i-- )
- {
- if( sortedParticles[ i ]->valid )
- {
- //find the first hole
- while( sortedParticles[ j ]->valid )
- j++;
-
- //no more holes
- if( j >= i )
- break;
-
- sortedParticles[ j ] = sortedParticles[ i ];
- }
- }
-
- numParticles = i;
-
- //set sort keys
- for( i = 0; i < numParticles; i++ )
- {
- VectorSubtract( sortedParticles[ i ]->origin, cg.refdef.vieworg, delta );
- sortedParticles[ i ]->sortKey = (int)DotProduct( delta, delta );
- }
-
- CG_RadixSort( sortedParticles, radixBuffer, numParticles );
-
- //FIXME: wtf?
- //reverse order of particles array
- for( i = 0; i < numParticles; i++ )
- radixBuffer[ i ] = sortedParticles[ numParticles - i - 1 ];
-
- for( i = 0; i < numParticles; i++ )
- sortedParticles[ i ] = radixBuffer[ i ];
-}
-
-/*
-===============
-CG_RenderParticle
-
-Actually render a particle
-===============
-*/
-static void CG_RenderParticle( particle_t *p )
-{
- refEntity_t re;
- float timeFrac, scale;
- int index;
- baseParticle_t *bp = p->class;
- particleSystem_t *ps = p->parent->parent;
- baseParticleSystem_t *bps = ps->class;
- vec3_t alight, dlight, lightdir;
- int i;
- vec3_t up = { 0.0f, 0.0f, 1.0f };
-
- memset( &re, 0, sizeof( refEntity_t ) );
-
- timeFrac = CG_CalculateTimeFrac( p->birthTime, p->lifeTime, 0 );
-
- scale = CG_LerpValues( p->radius.initial,
- p->radius.final,
- CG_CalculateTimeFrac( p->birthTime,
- p->lifeTime,
- p->radius.delay ) );
-
- re.shaderTime = p->birthTime / 1000.0f;
-
- if( bp->numFrames ) //shader based
- {
- re.reType = RT_SPRITE;
-
- //apply environmental lighting to the particle
- if( bp->realLight )
- {
- trap_R_LightForPoint( p->origin, alight, dlight, lightdir );
- for( i = 0; i <= 2; i++ )
- re.shaderRGBA[ i ] = (byte)alight[ i ];
- }
- else
- {
- vec3_t colorRange;
-
- VectorSubtract( bp->finalColor,
- bp->initialColor, colorRange );
-
- VectorMA( bp->initialColor,
- CG_CalculateTimeFrac( p->birthTime,
- p->lifeTime,
- p->colorDelay ),
- colorRange, re.shaderRGBA );
- }
-
- re.shaderRGBA[ 3 ] = (byte)( (float)0xFF *
- CG_LerpValues( p->alpha.initial,
- p->alpha.final,
- CG_CalculateTimeFrac( p->birthTime,
- p->lifeTime,
- p->alpha.delay ) ) );
-
- re.radius = scale;
-
- re.rotation = CG_LerpValues( p->rotation.initial,
- p->rotation.final,
- CG_CalculateTimeFrac( p->birthTime,
- p->lifeTime,
- p->rotation.delay ) );
-
- // if the view would be "inside" the sprite, kill the sprite
- // so it doesn't add too much overdraw
- if( Distance( p->origin, cg.refdef.vieworg ) < re.radius && bp->overdrawProtection )
- return;
-
- if( bp->framerate == 0.0f )
- {
- //sync animation time to lifeTime of particle
- index = (int)( timeFrac * ( bp->numFrames + 1 ) );
-
- if( index >= bp->numFrames )
- index = bp->numFrames - 1;
-
- re.customShader = bp->shaders[ index ];
- }
- else
- {
- //looping animation
- index = (int)( bp->framerate * timeFrac * p->lifeTime * 0.001 ) % bp->numFrames;
- re.customShader = bp->shaders[ index ];
- }
-
- }
- else if( bp->numModels ) //model based
- {
- re.reType = RT_MODEL;
-
- re.hModel = p->model;
-
- if( p->atRest )
- AxisCopy( p->lastAxis, re.axis );
- else
- {
- // convert direction of travel into axis
- VectorNormalize2( p->velocity, re.axis[ 0 ] );
-
- if( re.axis[ 0 ][ 0 ] == 0.0f && re.axis[ 0 ][ 1 ] == 0.0f )
- AxisCopy( axisDefault, re.axis );
- else
- {
- ProjectPointOnPlane( re.axis[ 2 ], up, re.axis[ 0 ] );
- VectorNormalize( re.axis[ 2 ] );
- CrossProduct( re.axis[ 2 ], re.axis[ 0 ], re.axis[ 1 ] );
- }
-
- AxisCopy( re.axis, p->lastAxis );
- }
-
- if( scale != 1.0f )
- {
- VectorScale( re.axis[ 0 ], scale, re.axis[ 0 ] );
- VectorScale( re.axis[ 1 ], scale, re.axis[ 1 ] );
- VectorScale( re.axis[ 2 ], scale, re.axis[ 2 ] );
- re.nonNormalizedAxes = qtrue;
- }
- else
- re.nonNormalizedAxes = qfalse;
-
- p->lf.animation = &bp->modelAnimation;
-
- //run animation
- CG_RunLerpFrame( &p->lf );
-
- re.oldframe = p->lf.oldFrame;
- re.frame = p->lf.frame;
- re.backlerp = p->lf.backlerp;
- }
-
- if( bps->thirdPersonOnly &&
- CG_AttachmentCentNum( &ps->attachment ) == cg.snap->ps.clientNum &&
- !cg.renderingThirdPerson )
- re.renderfx |= RF_THIRD_PERSON;
-
- if( bp->dynamicLight && !( re.renderfx & RF_THIRD_PERSON ) )
- {
- trap_R_AddLightToScene( p->origin,
- CG_LerpValues( p->dLightRadius.initial, p->dLightRadius.final,
- CG_CalculateTimeFrac( p->birthTime, p->lifeTime, p->dLightRadius.delay ) ),
- (float)bp->dLightColor[ 0 ] / (float)0xFF,
- (float)bp->dLightColor[ 1 ] / (float)0xFF,
- (float)bp->dLightColor[ 2 ] / (float)0xFF );
- }
-
- VectorCopy( p->origin, re.origin );
-
- trap_R_AddRefEntityToScene( &re );
-}
-
-/*
-===============
-CG_AddParticles
-
-Add particles to the scene
-===============
-*/
-void CG_AddParticles( void )
-{
- int i;
- particle_t *p;
- int numPS = 0, numPE = 0, numP = 0;
-
- //remove expired particle systems
- CG_GarbageCollectParticleSystems( );
-
- //check each ejector and introduce any new particles
- CG_SpawnNewParticles( );
-
- //sorting
- if( cg_depthSortParticles.integer )
- CG_CompactAndSortParticles( );
-
- for( i = 0; i < MAX_PARTICLES; i++ )
- {
- p = sortedParticles[ i ];
-
- if( p->valid )
- {
- if( p->birthTime + p->lifeTime > cg.time )
- {
- //particle is active
- CG_EvaluateParticlePhysics( p );
- CG_RenderParticle( p );
- }
- else
- CG_DestroyParticle( p, NULL );
- }
- }
-
- if( cg_debugParticles.integer >= 2 )
- {
- for( i = 0; i < MAX_PARTICLE_SYSTEMS; i++ )
- if( particleSystems[ i ].valid )
- numPS++;
-
- for( i = 0; i < MAX_PARTICLE_EJECTORS; i++ )
- if( particleEjectors[ i ].valid )
- numPE++;
-
- for( i = 0; i < MAX_PARTICLES; i++ )
- if( particles[ i ].valid )
- numP++;
-
- CG_Printf( "PS: %d PE: %d P: %d\n", numPS, numPE, numP );
- }
-}
-
-/*
-===============
-CG_ParticleSystemEntity
-
-Particle system entity client code
-===============
-*/
-void CG_ParticleSystemEntity( centity_t *cent )
-{
- entityState_t *es;
-
- es = &cent->currentState;
-
- if( es->eFlags & EF_NODRAW )
- {
- if( CG_IsParticleSystemValid( &cent->entityPS ) && CG_IsParticleSystemInfinite( cent->entityPS ) )
- CG_DestroyParticleSystem( &cent->entityPS );
-
- return;
- }
-
- if( !CG_IsParticleSystemValid( &cent->entityPS ) && !cent->entityPSMissing )
- {
- cent->entityPS = CG_SpawnNewParticleSystem( cgs.gameParticleSystems[ es->modelindex ] );
-
- if( CG_IsParticleSystemValid( &cent->entityPS ) )
- {
- CG_SetAttachmentPoint( &cent->entityPS->attachment, cent->lerpOrigin );
- CG_SetAttachmentCent( &cent->entityPS->attachment, cent );
- CG_AttachToPoint( &cent->entityPS->attachment );
- }
- else
- cent->entityPSMissing = qtrue;
- }
-}
-
-static particleSystem_t *testPS;
-static qhandle_t testPSHandle;
-
-/*
-===============
-CG_DestroyTestPS_f
-
-Destroy the test a particle system
-===============
-*/
-void CG_DestroyTestPS_f( void )
-{
- if( CG_IsParticleSystemValid( &testPS ) )
- CG_DestroyParticleSystem( &testPS );
-}
-
-/*
-===============
-CG_TestPS_f
-
-Test a particle system
-===============
-*/
-void CG_TestPS_f( void )
-{
- vec3_t origin;
- vec3_t up = { 0.0f, 0.0f, 1.0f };
- char psName[ MAX_QPATH ];
-
- if( trap_Argc( ) < 2 )
- return;
-
- Q_strncpyz( psName, CG_Argv( 1 ), MAX_QPATH );
- testPSHandle = CG_RegisterParticleSystem( psName );
-
- if( testPSHandle )
- {
- CG_DestroyTestPS_f( );
-
- testPS = CG_SpawnNewParticleSystem( testPSHandle );
-
- VectorMA( cg.refdef.vieworg, 100, cg.refdef.viewaxis[ 0 ], origin );
-
- if( CG_IsParticleSystemValid( &testPS ) )
- {
- CG_SetAttachmentPoint( &testPS->attachment, origin );
- CG_SetParticleSystemNormal( testPS, up );
- CG_AttachToPoint( &testPS->attachment );
- }
- }
-}
diff --git a/src/cgame/cg_players.c b/src/cgame/cg_players.c
deleted file mode 100644
index ac1ec181..00000000
--- a/src/cgame/cg_players.c
+++ /dev/null
@@ -1,2575 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_players.c -- handle the media and animation for player entities
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-char *cg_customSoundNames[ MAX_CUSTOM_SOUNDS ] =
-{
- "*death1.wav",
- "*death2.wav",
- "*death3.wav",
- "*jump1.wav",
- "*pain25_1.wav",
- "*pain50_1.wav",
- "*pain75_1.wav",
- "*pain100_1.wav",
- "*falling1.wav",
- "*gasp.wav",
- "*drown.wav",
- "*fall1.wav",
- "*taunt.wav"
-};
-
-
-/*
-================
-CG_CustomSound
-
-================
-*/
-sfxHandle_t CG_CustomSound( int clientNum, const char *soundName )
-{
- clientInfo_t *ci;
- int i;
-
- if( soundName[ 0 ] != '*' )
- return trap_S_RegisterSound( soundName, qfalse );
-
- if( clientNum < 0 || clientNum >= MAX_CLIENTS )
- clientNum = 0;
-
- ci = &cgs.clientinfo[ clientNum ];
-
- for( i = 0; i < MAX_CUSTOM_SOUNDS && cg_customSoundNames[ i ]; i++ )
- {
- if( !strcmp( soundName, cg_customSoundNames[ i ] ) )
- return ci->sounds[ i ];
- }
-
- CG_Error( "Unknown custom sound: %s", soundName );
- return 0;
-}
-
-
-
-/*
-=============================================================================
-
-CLIENT INFO
-
-=============================================================================
-*/
-
-/*
-======================
-CG_ParseAnimationFile
-
-Read a configuration file containing animation coutns and rates
-models/players/visor/animation.cfg, etc
-======================
-*/
-static qboolean CG_ParseAnimationFile( const char *filename, clientInfo_t *ci )
-{
- char *text_p, *prev;
- int len;
- int i;
- char *token;
- float fps;
- int skip;
- char text[ 20000 ];
- fileHandle_t f;
- animation_t *animations;
-
- animations = ci->animations;
-
- // load the file
- len = trap_FS_FOpenFile( filename, &f, FS_READ );
- if( len <= 0 )
- return qfalse;
-
- if( len >= sizeof( text ) - 1 )
- {
- CG_Printf( "File %s too long\n", filename );
- trap_FS_FCloseFile( f );
- return qfalse;
- }
-
- trap_FS_Read( text, len, f );
- text[ len ] = 0;
- trap_FS_FCloseFile( f );
-
- // parse the text
- text_p = text;
- skip = 0; // quite the compiler warning
-
- ci->footsteps = FOOTSTEP_NORMAL;
- VectorClear( ci->headOffset );
- ci->gender = GENDER_MALE;
- ci->fixedlegs = qfalse;
- ci->fixedtorso = qfalse;
- ci->nonsegmented = qfalse;
-
- // read optional parameters
- while( 1 )
- {
- prev = text_p; // so we can unget
- token = COM_Parse( &text_p );
-
- if( !token )
- break;
-
- if( !Q_stricmp( token, "footsteps" ) )
- {
- token = COM_Parse( &text_p );
- if( !token )
- break;
-
- if( !Q_stricmp( token, "default" ) || !Q_stricmp( token, "normal" ) )
- ci->footsteps = FOOTSTEP_NORMAL;
- else if( !Q_stricmp( token, "boot" ) )
- ci->footsteps = FOOTSTEP_BOOT;
- else if( !Q_stricmp( token, "flesh" ) )
- ci->footsteps = FOOTSTEP_FLESH;
- else if( !Q_stricmp( token, "mech" ) )
- ci->footsteps = FOOTSTEP_MECH;
- else if( !Q_stricmp( token, "energy" ) )
- ci->footsteps = FOOTSTEP_ENERGY;
- else if( !Q_stricmp( token, "none" ) )
- ci->footsteps = FOOTSTEP_NONE;
- else if( !Q_stricmp( token, "custom" ) )
- ci->footsteps = FOOTSTEP_CUSTOM;
- else
- CG_Printf( "Bad footsteps parm in %s: %s\n", filename, token );
-
- continue;
- }
- else if( !Q_stricmp( token, "headoffset" ) )
- {
- for( i = 0 ; i < 3 ; i++ )
- {
- token = COM_Parse( &text_p );
- if( !token )
- break;
-
- ci->headOffset[ i ] = atof( token );
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "sex" ) )
- {
- token = COM_Parse( &text_p );
-
- if( !token )
- break;
-
- if( token[ 0 ] == 'f' || token[ 0 ] == 'F' )
- ci->gender = GENDER_FEMALE;
- else if( token[ 0 ] == 'n' || token[ 0 ] == 'N' )
- ci->gender = GENDER_NEUTER;
- else
- ci->gender = GENDER_MALE;
-
- continue;
- }
- else if( !Q_stricmp( token, "fixedlegs" ) )
- {
- ci->fixedlegs = qtrue;
- continue;
- }
- else if( !Q_stricmp( token, "fixedtorso" ) )
- {
- ci->fixedtorso = qtrue;
- continue;
- }
- else if( !Q_stricmp( token, "nonsegmented" ) )
- {
- ci->nonsegmented = qtrue;
- continue;
- }
-
- // if it is a number, start parsing animations
- if( token[ 0 ] >= '0' && token[ 0 ] <= '9' )
- {
- text_p = prev; // unget the token
- break;
- }
-
- Com_Printf( "unknown token '%s' is %s\n", token, filename );
- }
-
- if( !ci->nonsegmented )
- {
- // read information for each frame
- for( i = 0; i < MAX_PLAYER_ANIMATIONS; i++ )
- {
- token = COM_Parse( &text_p );
-
- if( !*token )
- {
- if( i >= TORSO_GETFLAG && i <= TORSO_NEGATIVE )
- {
- animations[ i ].firstFrame = animations[ TORSO_GESTURE ].firstFrame;
- animations[ i ].frameLerp = animations[ TORSO_GESTURE ].frameLerp;
- animations[ i ].initialLerp = animations[ TORSO_GESTURE ].initialLerp;
- animations[ i ].loopFrames = animations[ TORSO_GESTURE ].loopFrames;
- animations[ i ].numFrames = animations[ TORSO_GESTURE ].numFrames;
- animations[ i ].reversed = qfalse;
- animations[ i ].flipflop = qfalse;
- continue;
- }
-
- break;
- }
-
- animations[ i ].firstFrame = atoi( token );
-
- // leg only frames are adjusted to not count the upper body only frames
- if( i == LEGS_WALKCR )
- skip = animations[ LEGS_WALKCR ].firstFrame - animations[ TORSO_GESTURE ].firstFrame;
-
- if( i >= LEGS_WALKCR && i<TORSO_GETFLAG )
- animations[ i ].firstFrame -= skip;
-
- token = COM_Parse( &text_p );
- if( !*token )
- break;
-
- animations[ i ].numFrames = atoi( token );
- animations[ i ].reversed = qfalse;
- animations[ i ].flipflop = qfalse;
-
- // if numFrames is negative the animation is reversed
- if( animations[ i ].numFrames < 0 )
- {
- animations[ i ].numFrames = -animations[ i ].numFrames;
- animations[ i ].reversed = qtrue;
- }
-
- token = COM_Parse( &text_p );
-
- if( !*token )
- break;
-
- animations[ i ].loopFrames = atoi( token );
-
- token = COM_Parse( &text_p );
-
- if( !*token )
- break;
-
- fps = atof( token );
- if( fps == 0 )
- fps = 1;
-
- animations[ i ].frameLerp = 1000 / fps;
- animations[ i ].initialLerp = 1000 / fps;
- }
-
- if( i != MAX_PLAYER_ANIMATIONS )
- {
- CG_Printf( "Error parsing animation file: %s", filename );
- return qfalse;
- }
- // crouch backward animation
- memcpy( &animations[ LEGS_BACKCR ], &animations[ LEGS_WALKCR ], sizeof( animation_t ) );
- animations[ LEGS_BACKCR ].reversed = qtrue;
- // walk backward animation
- memcpy( &animations[ LEGS_BACKWALK ], &animations[ LEGS_WALK ], sizeof( animation_t ) );
- animations[ LEGS_BACKWALK ].reversed = qtrue;
- // flag moving fast
- animations[ FLAG_RUN ].firstFrame = 0;
- animations[ FLAG_RUN ].numFrames = 16;
- animations[ FLAG_RUN ].loopFrames = 16;
- animations[ FLAG_RUN ].frameLerp = 1000 / 15;
- animations[ FLAG_RUN ].initialLerp = 1000 / 15;
- animations[ FLAG_RUN ].reversed = qfalse;
- // flag not moving or moving slowly
- animations[ FLAG_STAND ].firstFrame = 16;
- animations[ FLAG_STAND ].numFrames = 5;
- animations[ FLAG_STAND ].loopFrames = 0;
- animations[ FLAG_STAND ].frameLerp = 1000 / 20;
- animations[ FLAG_STAND ].initialLerp = 1000 / 20;
- animations[ FLAG_STAND ].reversed = qfalse;
- // flag speeding up
- animations[ FLAG_STAND2RUN ].firstFrame = 16;
- animations[ FLAG_STAND2RUN ].numFrames = 5;
- animations[ FLAG_STAND2RUN ].loopFrames = 1;
- animations[ FLAG_STAND2RUN ].frameLerp = 1000 / 15;
- animations[ FLAG_STAND2RUN ].initialLerp = 1000 / 15;
- animations[ FLAG_STAND2RUN ].reversed = qtrue;
- }
- else
- {
- // read information for each frame
- for( i = 0; i < MAX_NONSEG_PLAYER_ANIMATIONS; i++ )
- {
- token = COM_Parse( &text_p );
-
- if( !*token )
- break;
-
- animations[ i ].firstFrame = atoi( token );
-
- token = COM_Parse( &text_p );
- if( !*token )
- break;
-
- animations[ i ].numFrames = atoi( token );
- animations[ i ].reversed = qfalse;
- animations[ i ].flipflop = qfalse;
-
- // if numFrames is negative the animation is reversed
- if( animations[ i ].numFrames < 0 )
- {
- animations[ i ].numFrames = -animations[ i ].numFrames;
- animations[ i ].reversed = qtrue;
- }
-
- token = COM_Parse( &text_p );
-
- if( !*token )
- break;
-
- animations[ i ].loopFrames = atoi( token );
-
- token = COM_Parse( &text_p );
-
- if( !*token )
- break;
-
- fps = atof( token );
- if( fps == 0 )
- fps = 1;
-
- animations[ i ].frameLerp = 1000 / fps;
- animations[ i ].initialLerp = 1000 / fps;
- }
-
- if( i != MAX_NONSEG_PLAYER_ANIMATIONS )
- {
- CG_Printf( "Error parsing animation file: %s", filename );
- return qfalse;
- }
-
- // walk backward animation
- memcpy( &animations[ NSPA_WALKBACK ], &animations[ NSPA_WALK ], sizeof( animation_t ) );
- animations[ NSPA_WALKBACK ].reversed = qtrue;
- }
-
- return qtrue;
-}
-
-/*
-==========================
-CG_RegisterClientSkin
-==========================
-*/
-static qboolean CG_RegisterClientSkin( clientInfo_t *ci, const char *modelName, const char *skinName )
-{
- char filename[ MAX_QPATH ];
-
- if( !ci->nonsegmented )
- {
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/lower_%s.skin", modelName, skinName );
- ci->legsSkin = trap_R_RegisterSkin( filename );
- if( !ci->legsSkin )
- Com_Printf( "Leg skin load failure: %s\n", filename );
-
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/upper_%s.skin", modelName, skinName );
- ci->torsoSkin = trap_R_RegisterSkin( filename );
- if( !ci->torsoSkin )
- Com_Printf( "Torso skin load failure: %s\n", filename );
-
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/head_%s.skin", modelName, skinName );
- ci->headSkin = trap_R_RegisterSkin( filename );
- if( !ci->headSkin )
- Com_Printf( "Head skin load failure: %s\n", filename );
-
- if( !ci->legsSkin || !ci->torsoSkin || !ci->headSkin )
- return qfalse;
- }
- else
- {
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/nonseg_%s.skin", modelName, skinName );
- ci->nonSegSkin = trap_R_RegisterSkin( filename );
- if( !ci->nonSegSkin )
- Com_Printf( "Non-segmented skin load failure: %s\n", filename );
-
- if( !ci->nonSegSkin )
- return qfalse;
- }
-
- return qtrue;
-}
-
-/*
-==========================
-CG_RegisterClientModelname
-==========================
-*/
-static qboolean CG_RegisterClientModelname( clientInfo_t *ci, const char *modelName, const char *skinName )
-{
- char filename[ MAX_QPATH * 2 ];
-
- //TA: do this first so the nonsegmented property is set
- // load the animations
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg", modelName );
- if( !CG_ParseAnimationFile( filename, ci ) )
- {
- Com_Printf( "Failed to load animation file %s\n", filename );
- return qfalse;
- }
-
- // load cmodels before models so filecache works
-
- if( !ci->nonsegmented )
- {
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/lower.md3", modelName );
- ci->legsModel = trap_R_RegisterModel( filename );
- if( !ci->legsModel )
- {
- Com_Printf( "Failed to load model file %s\n", filename );
- return qfalse;
- }
-
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/upper.md3", modelName );
- ci->torsoModel = trap_R_RegisterModel( filename );
- if( !ci->torsoModel )
- {
- Com_Printf( "Failed to load model file %s\n", filename );
- return qfalse;
- }
-
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/head.md3", modelName );
- ci->headModel = trap_R_RegisterModel( filename );
- if( !ci->headModel )
- {
- Com_Printf( "Failed to load model file %s\n", filename );
- return qfalse;
- }
- }
- else
- {
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/nonseg.md3", modelName );
- ci->nonSegModel = trap_R_RegisterModel( filename );
- if( !ci->nonSegModel )
- {
- Com_Printf( "Failed to load model file %s\n", filename );
- return qfalse;
- }
- }
-
- // if any skins failed to load, return failure
- if( !CG_RegisterClientSkin( ci, modelName, skinName ) )
- {
- Com_Printf( "Failed to load skin file: %s : %s\n", modelName, skinName );
- return qfalse;
- }
-
- //FIXME: skins do not load without icon present. do we want icons anyway?
-/* Com_sprintf( filename, sizeof( filename ), "models/players/%s/icon_%s.tga", modelName, skinName );
- ci->modelIcon = trap_R_RegisterShaderNoMip( filename );
- if( !ci->modelIcon )
- {
- Com_Printf( "Failed to load icon file: %s\n", filename );
- return qfalse;
- }*/
-
- return qtrue;
-}
-
-/*
-====================
-CG_ColorFromString
-====================
-*/
-static void CG_ColorFromString( const char *v, vec3_t color )
-{
- int val;
-
- VectorClear( color );
-
- val = atoi( v );
-
- if( val < 1 || val > 7 )
- {
- VectorSet( color, 1, 1, 1 );
- return;
- }
-
- if( val & 1 )
- color[ 2 ] = 1.0f;
-
- if( val & 2 )
- color[ 1 ] = 1.0f;
-
- if( val & 4 )
- color[ 0 ] = 1.0f;
-}
-
-
-/*
-===================
-CG_LoadClientInfo
-
-Load it now, taking the disk hits
-===================
-*/
-static void CG_LoadClientInfo( clientInfo_t *ci )
-{
- const char *dir, *fallback;
- int i;
- const char *s;
- int clientNum;
-
- if( !CG_RegisterClientModelname( ci, ci->modelName, ci->skinName ) )
- {
- if( cg_buildScript.integer )
- CG_Error( "CG_RegisterClientModelname( %s, %s ) failed", ci->modelName, ci->skinName );
-
- // fall back
- if( !CG_RegisterClientModelname( ci, DEFAULT_MODEL, "default" ) )
- CG_Error( "DEFAULT_MODEL (%s) failed to register", DEFAULT_MODEL );
- }
-
- // sounds
- dir = ci->modelName;
- fallback = DEFAULT_MODEL;
-
- for( i = 0; i < MAX_CUSTOM_SOUNDS; i++ )
- {
- s = cg_customSoundNames[ i ];
-
- if( !s )
- break;
-
- // fanny about a bit with sounds that are missing
- if( !CG_FileExists( va( "sound/player/%s/%s", dir, s + 1 ) ) )
- {
- //file doesn't exist
-
- if( i == 11 || i == 8 ) //fall or falling
- {
- ci->sounds[ i ] = trap_S_RegisterSound( "sound/null.wav", qfalse );
- }
- else
- {
- if( i == 9 ) //gasp
- s = cg_customSoundNames[ 7 ]; //pain100_1
- else if( i == 10 ) //drown
- s = cg_customSoundNames[ 0 ]; //death1
-
- ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", dir, s + 1 ), qfalse );
- if( !ci->sounds[ i ] )
- ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", fallback, s + 1 ), qfalse );
- }
- }
- else
- {
- ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", dir, s + 1 ), qfalse );
- if( !ci->sounds[ i ] )
- ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", fallback, s + 1 ), qfalse );
- }
- }
-
- if( ci->footsteps == FOOTSTEP_CUSTOM )
- {
- for( i = 0; i < 4; i++ )
- {
- ci->customFootsteps[ i ] = trap_S_RegisterSound( va( "sound/player/%s/step%d.wav", dir, i + 1 ), qfalse );
- if( !ci->customFootsteps[ i ] )
- ci->customFootsteps[ i ] = trap_S_RegisterSound( va( "sound/player/footsteps/step%d.wav", i + 1 ), qfalse );
-
- ci->customMetalFootsteps[ i ] = trap_S_RegisterSound( va( "sound/player/%s/clank%d.wav", dir, i + 1 ), qfalse );
- if( !ci->customMetalFootsteps[ i ] )
- ci->customMetalFootsteps[ i ] = trap_S_RegisterSound( va( "sound/player/footsteps/clank%d.wav", i + 1 ), qfalse );
- }
- }
-
- // reset any existing players and bodies, because they might be in bad
- // frames for this new model
- clientNum = ci - cgs.clientinfo;
- for( i = 0; i < MAX_GENTITIES; i++ )
- {
- if( cg_entities[ i ].currentState.clientNum == clientNum &&
- cg_entities[ i ].currentState.eType == ET_PLAYER )
- CG_ResetPlayerEntity( &cg_entities[ i ] );
- }
-}
-
-/*
-======================
-CG_CopyClientInfoModel
-======================
-*/
-static void CG_CopyClientInfoModel( clientInfo_t *from, clientInfo_t *to )
-{
- VectorCopy( from->headOffset, to->headOffset );
- to->footsteps = from->footsteps;
- to->gender = from->gender;
-
- to->legsModel = from->legsModel;
- to->legsSkin = from->legsSkin;
- to->torsoModel = from->torsoModel;
- to->torsoSkin = from->torsoSkin;
- to->headModel = from->headModel;
- to->headSkin = from->headSkin;
- to->nonSegModel = from->nonSegModel;
- to->nonSegSkin = from->nonSegSkin;
- to->nonsegmented = from->nonsegmented;
- to->modelIcon = from->modelIcon;
-
- memcpy( to->animations, from->animations, sizeof( to->animations ) );
- memcpy( to->sounds, from->sounds, sizeof( to->sounds ) );
- memcpy( to->customFootsteps, from->customFootsteps, sizeof( to->customFootsteps ) );
- memcpy( to->customMetalFootsteps, from->customMetalFootsteps, sizeof( to->customMetalFootsteps ) );
-}
-
-
-/*
-======================
-CG_GetCorpseNum
-======================
-*/
-static int CG_GetCorpseNum( pClass_t class )
-{
- int i;
- clientInfo_t *match;
- char *modelName;
- char *skinName;
-
- modelName = BG_FindModelNameForClass( class );
- skinName = BG_FindSkinNameForClass( class );
-
- for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ )
- {
- match = &cgs.corpseinfo[ i ];
-
- if( !match->infoValid )
- continue;
-
- if( !Q_stricmp( modelName, match->modelName )
- && !Q_stricmp( skinName, match->skinName ) )
- {
- // this clientinfo is identical, so use it's handles
- return i;
- }
- }
-
- //something has gone horribly wrong
- return -1;
-}
-
-
-/*
-======================
-CG_ScanForExistingClientInfo
-======================
-*/
-static qboolean CG_ScanForExistingClientInfo( clientInfo_t *ci )
-{
- int i;
- clientInfo_t *match;
-
- for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ )
- {
- match = &cgs.corpseinfo[ i ];
-
- if( !match->infoValid )
- continue;
-
- if( !Q_stricmp( ci->modelName, match->modelName ) &&
- !Q_stricmp( ci->skinName, match->skinName ) )
- {
- // this clientinfo is identical, so use it's handles
- CG_CopyClientInfoModel( match, ci );
-
- return qtrue;
- }
- }
-
- //TA: shouldn't happen
- return qfalse;
-}
-
-
-/*
-======================
-CG_PrecacheClientInfo
-======================
-*/
-void CG_PrecacheClientInfo( pClass_t class, char *model, char *skin )
-{
- clientInfo_t *ci;
- clientInfo_t newInfo;
-
- ci = &cgs.corpseinfo[ class ];
-
- // the old value
- memset( &newInfo, 0, sizeof( newInfo ) );
-
- // model
- Q_strncpyz( newInfo.modelName, model, sizeof( newInfo.modelName ) );
- Q_strncpyz( newInfo.headModelName, model, sizeof( newInfo.headModelName ) );
-
- // modelName didn not include a skin name
- if( !skin )
- {
- Q_strncpyz( newInfo.skinName, "default", sizeof( newInfo.skinName ) );
- Q_strncpyz( newInfo.headSkinName, "default", sizeof( newInfo.headSkinName ) );
- }
- else
- {
- Q_strncpyz( newInfo.skinName, skin, sizeof( newInfo.skinName ) );
- Q_strncpyz( newInfo.headSkinName, skin, sizeof( newInfo.headSkinName ) );
- }
-
- newInfo.infoValid = qtrue;
-
- //TA: actually register the models
- *ci = newInfo;
- CG_LoadClientInfo( ci );
-}
-
-
-/*
-======================
-CG_NewClientInfo
-======================
-*/
-void CG_NewClientInfo( int clientNum )
-{
- clientInfo_t *ci;
- clientInfo_t newInfo;
- const char *configstring;
- const char *v;
- char *slash;
-
- ci = &cgs.clientinfo[ clientNum ];
-
- configstring = CG_ConfigString( clientNum + CS_PLAYERS );
- if( !configstring[ 0 ] )
- {
- memset( ci, 0, sizeof( *ci ) );
- return; // player just left
- }
-
- // the old value
- memset( &newInfo, 0, sizeof( newInfo ) );
-
- // isolate the player's name
- v = Info_ValueForKey( configstring, "n" );
- Q_strncpyz( newInfo.name, v, sizeof( newInfo.name ) );
-
- // colors
- v = Info_ValueForKey( configstring, "c1" );
- CG_ColorFromString( v, newInfo.color1 );
-
- v = Info_ValueForKey( configstring, "c2" );
- CG_ColorFromString( v, newInfo.color2 );
-
- // bot skill
- v = Info_ValueForKey( configstring, "skill" );
- newInfo.botSkill = atoi( v );
-
- // handicap
- v = Info_ValueForKey( configstring, "hc" );
- newInfo.handicap = atoi( v );
-
- // wins
- v = Info_ValueForKey( configstring, "w" );
- newInfo.wins = atoi( v );
-
- // losses
- v = Info_ValueForKey( configstring, "l" );
- newInfo.losses = atoi( v );
-
- // team
- v = Info_ValueForKey( configstring, "t" );
- newInfo.team = atoi( v );
-
- // team task
- v = Info_ValueForKey( configstring, "tt" );
- newInfo.teamTask = atoi( v );
-
- // team leader
- v = Info_ValueForKey( configstring, "tl" );
- newInfo.teamLeader = atoi( v );
-
- v = Info_ValueForKey( configstring, "g_redteam" );
- Q_strncpyz( newInfo.redTeam, v, MAX_TEAMNAME );
-
- v = Info_ValueForKey( configstring, "g_blueteam" );
- Q_strncpyz( newInfo.blueTeam, v, MAX_TEAMNAME );
-
- // model
- v = Info_ValueForKey( configstring, "model" );
- Q_strncpyz( newInfo.modelName, v, sizeof( newInfo.modelName ) );
-
- slash = strchr( newInfo.modelName, '/' );
-
- if( !slash )
- {
- // modelName didn not include a skin name
- Q_strncpyz( newInfo.skinName, "default", sizeof( newInfo.skinName ) );
- }
- else
- {
- Q_strncpyz( newInfo.skinName, slash + 1, sizeof( newInfo.skinName ) );
- // truncate modelName
- *slash = 0;
- }
-
- //CG_Printf( "NCI: %s\n", v );
-
- // head model
- v = Info_ValueForKey( configstring, "hmodel" );
- Q_strncpyz( newInfo.headModelName, v, sizeof( newInfo.headModelName ) );
-
- slash = strchr( newInfo.headModelName, '/' );
-
- if( !slash )
- {
- // modelName didn not include a skin name
- Q_strncpyz( newInfo.headSkinName, "default", sizeof( newInfo.headSkinName ) );
- }
- else
- {
- Q_strncpyz( newInfo.headSkinName, slash + 1, sizeof( newInfo.headSkinName ) );
- // truncate modelName
- *slash = 0;
- }
-
- // replace whatever was there with the new one
- newInfo.infoValid = qtrue;
- *ci = newInfo;
-
- // scan for an existing clientinfo that matches this modelname
- // so we can avoid loading checks if possible
- if( !CG_ScanForExistingClientInfo( ci ) )
- CG_LoadClientInfo( ci );
-}
-
-
-
-/*
-=============================================================================
-
-PLAYER ANIMATION
-
-=============================================================================
-*/
-
-
-/*
-===============
-CG_SetLerpFrameAnimation
-
-may include ANIM_TOGGLEBIT
-===============
-*/
-static void CG_SetLerpFrameAnimation( clientInfo_t *ci, lerpFrame_t *lf, int newAnimation )
-{
- animation_t *anim;
-
- lf->animationNumber = newAnimation;
- newAnimation &= ~ANIM_TOGGLEBIT;
-
- if( newAnimation < 0 || newAnimation >= MAX_PLAYER_TOTALANIMATIONS )
- CG_Error( "Bad animation number: %i", newAnimation );
-
- anim = &ci->animations[ newAnimation ];
-
- lf->animation = anim;
- lf->animationTime = lf->frameTime + anim->initialLerp;
-
- if( cg_debugAnim.integer )
- CG_Printf( "Anim: %i\n", newAnimation );
-}
-
-/*
-===============
-CG_RunPlayerLerpFrame
-
-Sets cg.snap, cg.oldFrame, and cg.backlerp
-cg.time should be between oldFrameTime and frameTime after exit
-===============
-*/
-static void CG_RunPlayerLerpFrame( clientInfo_t *ci, lerpFrame_t *lf, int newAnimation, float speedScale )
-{
- int f, numFrames;
- animation_t *anim;
-
- // debugging tool to get no animations
- if( cg_animSpeed.integer == 0 )
- {
- lf->oldFrame = lf->frame = lf->backlerp = 0;
- return;
- }
-
- // see if the animation sequence is switching
- if( newAnimation != lf->animationNumber || !lf->animation )
- {
- CG_SetLerpFrameAnimation( ci, lf, newAnimation );
- }
-
- // if we have passed the current frame, move it to
- // oldFrame and calculate a new frame
- if( cg.time >= lf->frameTime )
- {
- lf->oldFrame = lf->frame;
- lf->oldFrameTime = lf->frameTime;
-
- // get the next frame based on the animation
- anim = lf->animation;
- if( !anim->frameLerp )
- return; // shouldn't happen
-
- if( cg.time < lf->animationTime )
- lf->frameTime = lf->animationTime; // initial lerp
- else
- lf->frameTime = lf->oldFrameTime + anim->frameLerp;
-
- f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp;
- f *= speedScale; // adjust for haste, etc
- numFrames = anim->numFrames;
-
- if( anim->flipflop )
- numFrames *= 2;
-
- if( f >= numFrames )
- {
- f -= numFrames;
- if( anim->loopFrames )
- {
- f %= anim->loopFrames;
- f += anim->numFrames - anim->loopFrames;
- }
- else
- {
- f = numFrames - 1;
- // the animation is stuck at the end, so it
- // can immediately transition to another sequence
- lf->frameTime = cg.time;
- }
- }
-
- if( anim->reversed )
- lf->frame = anim->firstFrame + anim->numFrames - 1 - f;
- else if( anim->flipflop && f>=anim->numFrames )
- lf->frame = anim->firstFrame + anim->numFrames - 1 - ( f % anim->numFrames );
- else
- lf->frame = anim->firstFrame + f;
-
- if( cg.time > lf->frameTime )
- {
- lf->frameTime = cg.time;
-
- if( cg_debugAnim.integer )
- CG_Printf( "Clamp lf->frameTime\n" );
- }
- }
-
- if( lf->frameTime > cg.time + 200 )
- lf->frameTime = cg.time;
-
- if( lf->oldFrameTime > cg.time )
- lf->oldFrameTime = cg.time;
-
- // calculate current lerp value
- if( lf->frameTime == lf->oldFrameTime )
- lf->backlerp = 0;
- else
- lf->backlerp = 1.0 - (float)( cg.time - lf->oldFrameTime ) / ( lf->frameTime - lf->oldFrameTime );
-}
-
-
-/*
-===============
-CG_ClearLerpFrame
-===============
-*/
-static void CG_ClearLerpFrame( clientInfo_t *ci, lerpFrame_t *lf, int animationNumber )
-{
- lf->frameTime = lf->oldFrameTime = cg.time;
- CG_SetLerpFrameAnimation( ci, lf, animationNumber );
- lf->oldFrame = lf->frame = lf->animation->firstFrame;
-}
-
-
-/*
-===============
-CG_PlayerAnimation
-===============
-*/
-static void CG_PlayerAnimation( centity_t *cent, int *legsOld, int *legs, float *legsBackLerp,
- int *torsoOld, int *torso, float *torsoBackLerp )
-{
- clientInfo_t *ci;
- int clientNum;
- float speedScale = 1.0f;
-
- clientNum = cent->currentState.clientNum;
-
- if( cg_noPlayerAnims.integer )
- {
- *legsOld = *legs = *torsoOld = *torso = 0;
- return;
- }
-
- ci = &cgs.clientinfo[ clientNum ];
-
- // do the shuffle turn frames locally
- if( cent->pe.legs.yawing && ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_IDLE )
- CG_RunPlayerLerpFrame( ci, &cent->pe.legs, LEGS_TURN, speedScale );
- else
- CG_RunPlayerLerpFrame( ci, &cent->pe.legs, cent->currentState.legsAnim, speedScale );
-
- *legsOld = cent->pe.legs.oldFrame;
- *legs = cent->pe.legs.frame;
- *legsBackLerp = cent->pe.legs.backlerp;
-
- CG_RunPlayerLerpFrame( ci, &cent->pe.torso, cent->currentState.torsoAnim, speedScale );
-
- *torsoOld = cent->pe.torso.oldFrame;
- *torso = cent->pe.torso.frame;
- *torsoBackLerp = cent->pe.torso.backlerp;
-}
-
-
-/*
-===============
-CG_PlayerNonSegAnimation
-===============
-*/
-static void CG_PlayerNonSegAnimation( centity_t *cent, int *nonSegOld,
- int *nonSeg, float *nonSegBackLerp )
-{
- clientInfo_t *ci;
- int clientNum;
- float speedScale = 1.0f;
-
- clientNum = cent->currentState.clientNum;
-
- if( cg_noPlayerAnims.integer )
- {
- *nonSegOld = *nonSeg = 0;
- return;
- }
-
- ci = &cgs.clientinfo[ clientNum ];
-
- // do the shuffle turn frames locally
- if( cent->pe.nonseg.yawing && ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) == NSPA_STAND )
- CG_RunPlayerLerpFrame( ci, &cent->pe.nonseg, NSPA_TURN, speedScale );
- else
- CG_RunPlayerLerpFrame( ci, &cent->pe.nonseg, cent->currentState.legsAnim, speedScale );
-
- *nonSegOld = cent->pe.nonseg.oldFrame;
- *nonSeg = cent->pe.nonseg.frame;
- *nonSegBackLerp = cent->pe.nonseg.backlerp;
-}
-
-/*
-=============================================================================
-
-PLAYER ANGLES
-
-=============================================================================
-*/
-
-/*
-==================
-CG_SwingAngles
-==================
-*/
-static void CG_SwingAngles( float destination, float swingTolerance, float clampTolerance,
- float speed, float *angle, qboolean *swinging )
-{
- float swing;
- float move;
- float scale;
-
- if( !*swinging )
- {
- // see if a swing should be started
- swing = AngleSubtract( *angle, destination );
-
- if( swing > swingTolerance || swing < -swingTolerance )
- *swinging = qtrue;
- }
-
- if( !*swinging )
- return;
-
- // modify the speed depending on the delta
- // so it doesn't seem so linear
- swing = AngleSubtract( destination, *angle );
- scale = fabs( swing );
-
- if( scale < swingTolerance * 0.5 )
- scale = 0.5;
- else if( scale < swingTolerance )
- scale = 1.0;
- else
- scale = 2.0;
-
- // swing towards the destination angle
- if( swing >= 0 )
- {
- move = cg.frametime * scale * speed;
-
- if( move >= swing )
- {
- move = swing;
- *swinging = qfalse;
- }
- *angle = AngleMod( *angle + move );
- }
- else if( swing < 0 )
- {
- move = cg.frametime * scale * -speed;
-
- if( move <= swing )
- {
- move = swing;
- *swinging = qfalse;
- }
- *angle = AngleMod( *angle + move );
- }
-
- // clamp to no more than tolerance
- swing = AngleSubtract( destination, *angle );
- if( swing > clampTolerance )
- *angle = AngleMod( destination - ( clampTolerance - 1 ) );
- else if( swing < -clampTolerance )
- *angle = AngleMod( destination + ( clampTolerance - 1 ) );
-}
-
-/*
-=================
-CG_AddPainTwitch
-=================
-*/
-static void CG_AddPainTwitch( centity_t *cent, vec3_t torsoAngles )
-{
- int t;
- float f;
-
- t = cg.time - cent->pe.painTime;
-
- if( t >= PAIN_TWITCH_TIME )
- return;
-
- f = 1.0 - (float)t / PAIN_TWITCH_TIME;
-
- if( cent->pe.painDirection )
- torsoAngles[ ROLL ] += 20 * f;
- else
- torsoAngles[ ROLL ] -= 20 * f;
-}
-
-
-/*
-===============
-CG_PlayerAngles
-
-Handles seperate torso motion
-
- legs pivot based on direction of movement
-
- head always looks exactly at cent->lerpAngles
-
- if motion < 20 degrees, show in head only
- if < 45 degrees, also show in torso
-===============
-*/
-static void CG_PlayerAngles( centity_t *cent, vec3_t srcAngles,
- vec3_t legs[ 3 ], vec3_t torso[ 3 ], vec3_t head[ 3 ] )
-{
- vec3_t legsAngles, torsoAngles, headAngles;
- float dest;
- static int movementOffsets[ 8 ] = { 0, 22, 45, -22, 0, 22, -45, -22 };
- vec3_t velocity;
- float speed;
- int dir, clientNum;
- clientInfo_t *ci;
-
- VectorCopy( srcAngles, headAngles );
- headAngles[ YAW ] = AngleMod( headAngles[ YAW ] );
- VectorClear( legsAngles );
- VectorClear( torsoAngles );
-
- // --------- yaw -------------
-
- // allow yaw to drift a bit
- if( ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) != LEGS_IDLE ||
- ( cent->currentState.torsoAnim & ~ANIM_TOGGLEBIT ) != TORSO_STAND )
- {
- // if not standing still, always point all in the same direction
- cent->pe.torso.yawing = qtrue; // always center
- cent->pe.torso.pitching = qtrue; // always center
- cent->pe.legs.yawing = qtrue; // always center
- }
-
- // adjust legs for movement dir
- if( cent->currentState.eFlags & EF_DEAD )
- {
- // don't let dead bodies twitch
- dir = 0;
- }
- else
- {
- //TA: did use angles2.. now uses time2.. looks a bit funny but time2 isn't used othwise
- dir = cent->currentState.time2;
- if( dir < 0 || dir > 7 )
- CG_Error( "Bad player movement angle" );
- }
-
- legsAngles[ YAW ] = headAngles[ YAW ] + movementOffsets[ dir ];
- torsoAngles[ YAW ] = headAngles[ YAW ] + 0.25 * movementOffsets[ dir ];
-
- // torso
- if( cent->currentState.eFlags & EF_DEAD )
- {
- CG_SwingAngles( torsoAngles[ YAW ], 0, 0, cg_swingSpeed.value,
- &cent->pe.torso.yawAngle, &cent->pe.torso.yawing );
- CG_SwingAngles( legsAngles[ YAW ], 0, 0, cg_swingSpeed.value,
- &cent->pe.legs.yawAngle, &cent->pe.legs.yawing );
- }
- else
- {
- CG_SwingAngles( torsoAngles[ YAW ], 25, 90, cg_swingSpeed.value,
- &cent->pe.torso.yawAngle, &cent->pe.torso.yawing );
- CG_SwingAngles( legsAngles[ YAW ], 40, 90, cg_swingSpeed.value,
- &cent->pe.legs.yawAngle, &cent->pe.legs.yawing );
- }
-
- torsoAngles[ YAW ] = cent->pe.torso.yawAngle;
- legsAngles[ YAW ] = cent->pe.legs.yawAngle;
-
- // --------- pitch -------------
-
- // only show a fraction of the pitch angle in the torso
- if( headAngles[ PITCH ] > 180 )
- dest = ( -360 + headAngles[ PITCH ] ) * 0.75f;
- else
- dest = headAngles[ PITCH ] * 0.75f;
-
- CG_SwingAngles( dest, 15, 30, 0.1f, &cent->pe.torso.pitchAngle, &cent->pe.torso.pitching );
- torsoAngles[ PITCH ] = cent->pe.torso.pitchAngle;
-
- //
- clientNum = cent->currentState.clientNum;
-
- if( clientNum >= 0 && clientNum < MAX_CLIENTS )
- {
- ci = &cgs.clientinfo[ clientNum ];
- if( ci->fixedtorso )
- torsoAngles[ PITCH ] = 0.0f;
- }
-
- // --------- roll -------------
-
-
- // lean towards the direction of travel
- VectorCopy( cent->currentState.pos.trDelta, velocity );
- speed = VectorNormalize( velocity );
-
- if( speed )
- {
- vec3_t axis[ 3 ];
- float side;
-
- speed *= 0.05f;
-
- AnglesToAxis( legsAngles, axis );
- side = speed * DotProduct( velocity, axis[ 1 ] );
- legsAngles[ ROLL ] -= side;
-
- side = speed * DotProduct( velocity, axis[ 0 ] );
- legsAngles[ PITCH ] += side;
- }
-
- //
- clientNum = cent->currentState.clientNum;
-
- if( clientNum >= 0 && clientNum < MAX_CLIENTS )
- {
- ci = &cgs.clientinfo[ clientNum ];
-
- if( ci->fixedlegs )
- {
- legsAngles[ YAW ] = torsoAngles[ YAW ];
- legsAngles[ PITCH ] = 0.0f;
- legsAngles[ ROLL ] = 0.0f;
- }
- }
-
- // pain twitch
- CG_AddPainTwitch( cent, torsoAngles );
-
- // pull the angles back out of the hierarchial chain
- AnglesSubtract( headAngles, torsoAngles, headAngles );
- AnglesSubtract( torsoAngles, legsAngles, torsoAngles );
- AnglesToAxis( legsAngles, legs );
- AnglesToAxis( torsoAngles, torso );
- AnglesToAxis( headAngles, head );
-}
-
-#define MODEL_WWSMOOTHTIME 200
-
-/*
-===============
-CG_PlayerWWSmoothing
-
-Smooth the angles of transitioning wall walkers
-===============
-*/
-static void CG_PlayerWWSmoothing( centity_t *cent, vec3_t in[ 3 ], vec3_t out[ 3 ] )
-{
- entityState_t *es = &cent->currentState;
- int i;
- vec3_t surfNormal, rotAxis, temp;
- vec3_t refNormal = { 0.0f, 0.0f, 1.0f };
- vec3_t ceilingNormal = { 0.0f, 0.0f, -1.0f };
- float stLocal, sFraction, rotAngle;
- vec3_t inAxis[ 3 ], lastAxis[ 3 ], outAxis[ 3 ];
-
- //set surfNormal
- if( !(es->eFlags & EF_WALLCLIMB ) )
- VectorCopy( refNormal, surfNormal );
- else if( !( es->eFlags & EF_WALLCLIMBCEILING ) )
- VectorCopy( es->angles2, surfNormal );
- else
- VectorCopy( ceilingNormal, surfNormal );
-
- AxisCopy( in, inAxis );
-
- if( !VectorCompare( surfNormal, cent->pe.lastNormal ) )
- {
- //if we moving from the ceiling to the floor special case
- //( x product of colinear vectors is undefined)
- if( VectorCompare( ceilingNormal, cent->pe.lastNormal ) &&
- VectorCompare( refNormal, surfNormal ) )
- {
- VectorCopy( in[ 1 ], rotAxis );
- rotAngle = 180.0f;
- }
- else
- {
- AxisCopy( cent->pe.lastAxis, lastAxis );
- rotAngle = DotProduct( inAxis[ 0 ], lastAxis[ 0 ] ) +
- DotProduct( inAxis[ 1 ], lastAxis[ 1 ] ) +
- DotProduct( inAxis[ 2 ], lastAxis[ 2 ] );
-
- rotAngle = RAD2DEG( acos( ( rotAngle - 1.0f ) / 2.0f ) );
-
- CrossProduct( lastAxis[ 0 ], inAxis[ 0 ], temp );
- VectorCopy( temp, rotAxis );
- CrossProduct( lastAxis[ 1 ], inAxis[ 1 ], temp );
- VectorAdd( rotAxis, temp, rotAxis );
- CrossProduct( lastAxis[ 2 ], inAxis[ 2 ], temp );
- VectorAdd( rotAxis, temp, rotAxis );
-
- VectorNormalize( rotAxis );
- }
-
- //iterate through smooth array
- for( i = 0; i < MAXSMOOTHS; i++ )
- {
- //found an unused index in the smooth array
- if( cent->pe.sList[ i ].time + MODEL_WWSMOOTHTIME < cg.time )
- {
- //copy to array and stop
- VectorCopy( rotAxis, cent->pe.sList[ i ].rotAxis );
- cent->pe.sList[ i ].rotAngle = rotAngle;
- cent->pe.sList[ i ].time = cg.time;
- break;
- }
- }
- }
-
- //iterate through ops
- for( i = MAXSMOOTHS - 1; i >= 0; i-- )
- {
- //if this op has time remaining, perform it
- if( cg.time < cent->pe.sList[ i ].time + MODEL_WWSMOOTHTIME )
- {
- stLocal = 1.0f - ( ( ( cent->pe.sList[ i ].time + MODEL_WWSMOOTHTIME ) - cg.time ) / MODEL_WWSMOOTHTIME );
- sFraction = -( cos( stLocal * M_PI ) + 1.0f ) / 2.0f;
-
- RotatePointAroundVector( outAxis[ 0 ], cent->pe.sList[ i ].rotAxis,
- inAxis[ 0 ], sFraction * cent->pe.sList[ i ].rotAngle );
- RotatePointAroundVector( outAxis[ 1 ], cent->pe.sList[ i ].rotAxis,
- inAxis[ 1 ], sFraction * cent->pe.sList[ i ].rotAngle );
- RotatePointAroundVector( outAxis[ 2 ], cent->pe.sList[ i ].rotAxis,
- inAxis[ 2 ], sFraction * cent->pe.sList[ i ].rotAngle );
-
- AxisCopy( outAxis, inAxis );
- }
- }
-
- //outAxis has been copied to inAxis
- AxisCopy( inAxis, out );
-}
-
-/*
-===============
-CG_PlayerNonSegAngles
-
-Resolve angles for non-segmented models
-===============
-*/
-static void CG_PlayerNonSegAngles( centity_t *cent, vec3_t srcAngles, vec3_t nonSegAxis[ 3 ] )
-{
- vec3_t localAngles;
- vec3_t velocity;
- float speed;
- int dir;
- entityState_t *es = &cent->currentState;
- vec3_t surfNormal;
- vec3_t ceilingNormal = { 0.0f, 0.0f, -1.0f };
-
- VectorCopy( srcAngles, localAngles );
- localAngles[ YAW ] = AngleMod( localAngles[ YAW ] );
- localAngles[ PITCH ] = 0.0f;
- localAngles[ ROLL ] = 0.0f;
-
- //set surfNormal
- if( !( es->eFlags & EF_WALLCLIMBCEILING ) )
- VectorCopy( es->angles2, surfNormal );
- else
- VectorCopy( ceilingNormal, surfNormal );
-
- //make sure that WW transitions don't cause the swing stuff to go nuts
- if( !VectorCompare( surfNormal, cent->pe.lastNormal ) )
- {
- //stop CG_SwingAngles having an eppy
- cent->pe.nonseg.yawAngle = localAngles[ YAW ];
- cent->pe.nonseg.yawing = qfalse;
- }
-
- // --------- yaw -------------
-
- // allow yaw to drift a bit
- if( ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) != NSPA_STAND )
- {
- // if not standing still, always point all in the same direction
- cent->pe.nonseg.yawing = qtrue; // always center
- }
-
- // adjust legs for movement dir
- if( cent->currentState.eFlags & EF_DEAD )
- {
- // don't let dead bodies twitch
- dir = 0;
- }
- else
- {
- //TA: did use angles2.. now uses time2.. looks a bit funny but time2 isn't used othwise
- dir = cent->currentState.time2;
- if( dir < 0 || dir > 7 )
- CG_Error( "Bad player movement angle" );
- }
-
- // torso
- if( cent->currentState.eFlags & EF_DEAD )
- {
- CG_SwingAngles( localAngles[ YAW ], 0, 0, cg_swingSpeed.value,
- &cent->pe.nonseg.yawAngle, &cent->pe.nonseg.yawing );
- }
- else
- {
- CG_SwingAngles( localAngles[ YAW ], 40, 90, cg_swingSpeed.value,
- &cent->pe.nonseg.yawAngle, &cent->pe.nonseg.yawing );
- }
-
- localAngles[ YAW ] = cent->pe.nonseg.yawAngle;
-
- // --------- pitch -------------
-
- //NO PITCH!
-
-
- // --------- roll -------------
-
-
- // lean towards the direction of travel
- VectorCopy( cent->currentState.pos.trDelta, velocity );
- speed = VectorNormalize( velocity );
-
- if( speed )
- {
- vec3_t axis[ 3 ];
- float side;
-
- //much less than with the regular model system
- speed *= 0.01f;
-
- AnglesToAxis( localAngles, axis );
- side = speed * DotProduct( velocity, axis[ 1 ] );
- localAngles[ ROLL ] -= side;
-
- side = speed * DotProduct( velocity, axis[ 0 ] );
- localAngles[ PITCH ] += side;
- }
-
- //FIXME: PAIN[123] animations?
- // pain twitch
- //CG_AddPainTwitch( cent, torsoAngles );
-
- AnglesToAxis( localAngles, nonSegAxis );
-}
-
-
-//==========================================================================
-
-/*
-===============
-CG_PlayerUpgrade
-===============
-*/
-static void CG_PlayerUpgrades( centity_t *cent, refEntity_t *torso )
-{
- int held, active;
- refEntity_t jetpack;
- refEntity_t battpack;
- refEntity_t flash;
- entityState_t *es = &cent->currentState;
-
- held = es->modelindex;
- active = es->modelindex2;
-
- if( held & ( 1 << UP_JETPACK ) )
- {
- memset( &jetpack, 0, sizeof( jetpack ) );
- VectorCopy( torso->lightingOrigin, jetpack.lightingOrigin );
- jetpack.shadowPlane = torso->shadowPlane;
- jetpack.renderfx = torso->renderfx;
-
- jetpack.hModel = cgs.media.jetpackModel;
-
- //identity matrix
- AxisCopy( axisDefault, jetpack.axis );
-
- //FIXME: change to tag_back when it exists
- CG_PositionRotatedEntityOnTag( &jetpack, torso, torso->hModel, "tag_head" );
-
- trap_R_AddRefEntityToScene( &jetpack );
-
- if( active & ( 1 << UP_JETPACK ) )
- {
- if( es->pos.trDelta[ 2 ] > 10.0f )
- {
- if( cent->jetPackState != JPS_ASCENDING )
- {
- if( CG_IsParticleSystemValid( &cent->jetPackPS ) )
- CG_DestroyParticleSystem( &cent->jetPackPS );
-
- cent->jetPackPS = CG_SpawnNewParticleSystem( cgs.media.jetPackAscendPS );
- cent->jetPackState = JPS_ASCENDING;
- }
-
- trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin,
- vec3_origin, cgs.media.jetpackAscendSound );
- }
- else if( es->pos.trDelta[ 2 ] < -10.0f )
- {
- if( cent->jetPackState != JPS_DESCENDING )
- {
- if( CG_IsParticleSystemValid( &cent->jetPackPS ) )
- CG_DestroyParticleSystem( &cent->jetPackPS );
-
- cent->jetPackPS = CG_SpawnNewParticleSystem( cgs.media.jetPackDescendPS );
- cent->jetPackState = JPS_DESCENDING;
- }
-
- trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin,
- vec3_origin, cgs.media.jetpackDescendSound );
- }
- else
- {
- if( cent->jetPackState != JPS_HOVERING )
- {
- if( CG_IsParticleSystemValid( &cent->jetPackPS ) )
- CG_DestroyParticleSystem( &cent->jetPackPS );
-
- cent->jetPackPS = CG_SpawnNewParticleSystem( cgs.media.jetPackHoverPS );
- cent->jetPackState = JPS_HOVERING;
- }
-
- trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin,
- vec3_origin, cgs.media.jetpackIdleSound );
- }
-
- memset( &flash, 0, sizeof( flash ) );
- VectorCopy( torso->lightingOrigin, flash.lightingOrigin );
- flash.shadowPlane = torso->shadowPlane;
- flash.renderfx = torso->renderfx;
-
- flash.hModel = cgs.media.jetpackFlashModel;
- if( !flash.hModel )
- return;
-
- AxisCopy( axisDefault, flash.axis );
-
- CG_PositionRotatedEntityOnTag( &flash, &jetpack, jetpack.hModel, "tag_flash" );
- trap_R_AddRefEntityToScene( &flash );
-
- if( CG_IsParticleSystemValid( &cent->jetPackPS ) )
- {
- CG_SetAttachmentTag( &cent->jetPackPS->attachment,
- jetpack, jetpack.hModel, "tag_flash" );
- CG_SetAttachmentCent( &cent->jetPackPS->attachment, cent );
- CG_AttachToTag( &cent->jetPackPS->attachment );
- }
- }
- else if( CG_IsParticleSystemValid( &cent->jetPackPS ) )
- {
- CG_DestroyParticleSystem( &cent->jetPackPS );
- cent->jetPackState = JPS_OFF;
- }
- }
- else if( CG_IsParticleSystemValid( &cent->jetPackPS ) )
- {
- CG_DestroyParticleSystem( &cent->jetPackPS );
- cent->jetPackState = JPS_OFF;
- }
-
- if( held & ( 1 << UP_BATTPACK ) )
- {
- memset( &battpack, 0, sizeof( battpack ) );
- VectorCopy( torso->lightingOrigin, battpack.lightingOrigin );
- battpack.shadowPlane = torso->shadowPlane;
- battpack.renderfx = torso->renderfx;
-
- battpack.hModel = cgs.media.battpackModel;
-
- //identity matrix
- AxisCopy( axisDefault, battpack.axis );
-
- //FIXME: change to tag_back when it exists
- CG_PositionRotatedEntityOnTag( &battpack, torso, torso->hModel, "tag_head" );
-
- trap_R_AddRefEntityToScene( &battpack );
- }
-
- if( es->eFlags & EF_BLOBLOCKED )
- {
- vec3_t temp, origin, up = { 0.0f, 0.0f, 1.0f };
- trace_t tr;
- float size;
-
- VectorCopy( es->pos.trBase, temp );
- temp[ 2 ] -= 4096.0f;
-
- CG_Trace( &tr, es->pos.trBase, NULL, NULL, temp, es->number, MASK_SOLID );
- VectorCopy( tr.endpos, origin );
-
- size = 32.0f;
-
- if( size > 0.0f )
- CG_ImpactMark( cgs.media.creepShader, origin, up,
- 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, qfalse, size, qtrue );
- }
-}
-
-
-/*
-===============
-CG_PlayerFloatSprite
-
-Float a sprite over the player's head
-===============
-*/
-static void CG_PlayerFloatSprite( centity_t *cent, qhandle_t shader )
-{
- int rf;
- refEntity_t ent;
-
- if( cent->currentState.number == cg.snap->ps.clientNum && !cg.renderingThirdPerson )
- rf = RF_THIRD_PERSON; // only show in mirrors
- else
- rf = 0;
-
- memset( &ent, 0, sizeof( ent ) );
- VectorCopy( cent->lerpOrigin, ent.origin );
- ent.origin[ 2 ] += 48;
- ent.reType = RT_SPRITE;
- ent.customShader = shader;
- ent.radius = 10;
- ent.renderfx = rf;
- ent.shaderRGBA[ 0 ] = 255;
- ent.shaderRGBA[ 1 ] = 255;
- ent.shaderRGBA[ 2 ] = 255;
- ent.shaderRGBA[ 3 ] = 255;
- trap_R_AddRefEntityToScene( &ent );
-}
-
-
-
-/*
-===============
-CG_PlayerSprites
-
-Float sprites over the player's head
-===============
-*/
-static void CG_PlayerSprites( centity_t *cent )
-{
- if( cent->currentState.eFlags & EF_CONNECTION )
- {
- CG_PlayerFloatSprite( cent, cgs.media.connectionShader );
- return;
- }
-
- if( cent->currentState.eFlags & EF_TALK )
- {
- //TA: the masses have decreed this to be wrong
-/* CG_PlayerFloatSprite( cent, cgs.media.balloonShader );
- return;*/
- }
-}
-
-/*
-===============
-CG_PlayerShadow
-
-Returns the Z component of the surface being shadowed
-
- should it return a full plane instead of a Z?
-===============
-*/
-#define SHADOW_DISTANCE 128
-static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane, pClass_t class )
-{
- vec3_t end, mins, maxs;
- trace_t trace;
- float alpha;
- entityState_t *es = &cent->currentState;
- vec3_t surfNormal = { 0.0f, 0.0f, 1.0f };
-
- BG_FindBBoxForClass( class, mins, maxs, NULL, NULL, NULL );
- mins[ 2 ] = 0.0f;
- maxs[ 2 ] = 2.0f;
-
- if( es->eFlags & EF_WALLCLIMB )
- {
- if( es->eFlags & EF_WALLCLIMBCEILING )
- VectorSet( surfNormal, 0.0f, 0.0f, -1.0f );
- else
- VectorCopy( es->angles2, surfNormal );
- }
-
- *shadowPlane = 0;
-
- if( cg_shadows.integer == 0 )
- return qfalse;
-
- // send a trace down from the player to the ground
- VectorCopy( cent->lerpOrigin, end );
- VectorMA( cent->lerpOrigin, -SHADOW_DISTANCE, surfNormal, end );
-
- trap_CM_BoxTrace( &trace, cent->lerpOrigin, end, mins, maxs, 0, MASK_PLAYERSOLID );
-
- // no shadow if too high
- if( trace.fraction == 1.0 || trace.startsolid || trace.allsolid )
- return qfalse;
-
- //TA: FIXME: stencil shadows will be broken for walls.
- // Unfortunately there isn't much that can be
- // done since Q3 references only the Z coord
- // of the shadowPlane
- if( surfNormal[ 2 ] < 0.0f )
- *shadowPlane = trace.endpos[ 2 ] - 1.0f;
- else
- *shadowPlane = trace.endpos[ 2 ] + 1.0f;
-
- if( cg_shadows.integer != 1 ) // no mark for stencil or projection shadows
- return qtrue;
-
- // fade the shadow out with height
- alpha = 1.0 - trace.fraction;
-
- // add the mark as a temporary, so it goes directly to the renderer
- // without taking a spot in the cg_marks array
- CG_ImpactMark( cgs.media.shadowMarkShader, trace.endpos, trace.plane.normal,
- cent->pe.legs.yawAngle, alpha, alpha, alpha, 1, qfalse,
- 24.0f * BG_FindShadowScaleForClass( class ), qtrue );
-
- return qtrue;
-}
-
-
-/*
-===============
-CG_PlayerSplash
-
-Draw a mark at the water surface
-===============
-*/
-static void CG_PlayerSplash( centity_t *cent )
-{
- vec3_t start, end;
- trace_t trace;
- int contents;
- polyVert_t verts[ 4 ];
-
- if( !cg_shadows.integer )
- return;
-
- VectorCopy( cent->lerpOrigin, end );
- end[ 2 ] -= 24;
-
- // if the feet aren't in liquid, don't make a mark
- // this won't handle moving water brushes, but they wouldn't draw right anyway...
- contents = trap_CM_PointContents( end, 0 );
-
- if( !( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ) )
- return;
-
- VectorCopy( cent->lerpOrigin, start );
- start[ 2 ] += 32;
-
- // if the head isn't out of liquid, don't make a mark
- contents = trap_CM_PointContents( start, 0 );
-
- if( contents & ( CONTENTS_SOLID | CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) )
- return;
-
- // trace down to find the surface
- trap_CM_BoxTrace( &trace, start, end, NULL, NULL, 0, ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) );
-
- if( trace.fraction == 1.0 )
- return;
-
- // create a mark polygon
- VectorCopy( trace.endpos, verts[ 0 ].xyz );
- verts[ 0 ].xyz[ 0 ] -= 32;
- verts[ 0 ].xyz[ 1 ] -= 32;
- 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( trace.endpos, verts[ 1 ].xyz );
- verts[ 1 ].xyz[ 0 ] -= 32;
- verts[ 1 ].xyz[ 1 ] += 32;
- 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( trace.endpos, verts[ 2 ].xyz );
- verts[ 2 ].xyz[ 0 ] += 32;
- verts[ 2 ].xyz[ 1 ] += 32;
- 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( trace.endpos, verts[ 3 ].xyz );
- verts[ 3 ].xyz[ 0 ] += 32;
- verts[ 3 ].xyz[ 1 ] -= 32;
- 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;
-
- trap_R_AddPolyToScene( cgs.media.wakeMarkShader, 4, verts );
-}
-
-
-/*
-=================
-CG_LightVerts
-=================
-*/
-int CG_LightVerts( vec3_t normal, int numVerts, polyVert_t *verts )
-{
- int i, j;
- float incoming;
- vec3_t ambientLight;
- vec3_t lightDir;
- vec3_t directedLight;
-
- trap_R_LightForPoint( verts[ 0 ].xyz, ambientLight, directedLight, lightDir );
-
- for( i = 0; i < numVerts; i++ )
- {
- incoming = DotProduct( normal, lightDir );
-
- if( incoming <= 0 )
- {
- verts[ i ].modulate[ 0 ] = ambientLight[ 0 ];
- verts[ i ].modulate[ 1 ] = ambientLight[ 1 ];
- verts[ i ].modulate[ 2 ] = ambientLight[ 2 ];
- verts[ i ].modulate[ 3 ] = 255;
- continue;
- }
-
- j = ( ambientLight[ 0 ] + incoming * directedLight[ 0 ] );
-
- if( j > 255 )
- j = 255;
-
- verts[ i ].modulate[ 0 ] = j;
-
- j = ( ambientLight[ 1 ] + incoming * directedLight[ 1 ] );
-
- if( j > 255 )
- j = 255;
-
- verts[ i ].modulate[ 1 ] = j;
-
- j = ( ambientLight[ 2 ] + incoming * directedLight[ 2 ] );
-
- if( j > 255 )
- j = 255;
-
- verts[ i ].modulate[ 2 ] = j;
-
- verts[ i ].modulate[ 3 ] = 255;
- }
- return qtrue;
-}
-
-
-/*
-=================
-CG_LightFromDirection
-=================
-*/
-int CG_LightFromDirection( vec3_t point, vec3_t direction )
-{
- int j;
- float incoming;
- vec3_t ambientLight;
- vec3_t lightDir;
- vec3_t directedLight;
- vec3_t result;
-
- trap_R_LightForPoint( point, ambientLight, directedLight, lightDir );
-
- incoming = DotProduct( direction, lightDir );
-
- if( incoming <= 0 )
- {
- result[ 0 ] = ambientLight[ 0 ];
- result[ 1 ] = ambientLight[ 1 ];
- result[ 2 ] = ambientLight[ 2 ];
- return (int)( (float)( result[ 0 ] + result[ 1 ] + result[ 2 ] ) / 3.0f );
- }
-
- j = ( ambientLight[ 0 ] + incoming * directedLight[ 0 ] );
-
- if( j > 255 )
- j = 255;
-
- result[ 0 ] = j;
-
- j = ( ambientLight[ 1 ] + incoming * directedLight[ 1 ] );
-
- if( j > 255 )
- j = 255;
-
- result[ 1 ] = j;
-
- j = ( ambientLight[ 2 ] + incoming * directedLight[ 2 ] );
-
- if( j > 255 )
- j = 255;
-
- result[ 2 ] = j;
-
- return (int)((float)( result[ 0 ] + result[ 1 ] + result[ 2 ] ) / 3.0f );
-}
-
-
-/*
-=================
-CG_AmbientLight
-=================
-*/
-int CG_AmbientLight( vec3_t point )
-{
- vec3_t ambientLight;
- vec3_t lightDir;
- vec3_t directedLight;
- vec3_t result;
-
- trap_R_LightForPoint( point, ambientLight, directedLight, lightDir );
-
- result[ 0 ] = ambientLight[ 0 ];
- result[ 1 ] = ambientLight[ 1 ];
- result[ 2 ] = ambientLight[ 2 ];
- return (int)((float)( result[ 0 ] + result[ 1 ] + result[ 2 ] ) / 3.0f );
-}
-
-#define TRACE_DEPTH 32.0f
-
-/*
-===============
-CG_Player
-===============
-*/
-void CG_Player( centity_t *cent )
-{
- clientInfo_t *ci;
-
- //TA: NOTE: legs is used for nonsegmented models
- // this helps reduce code to be changed
- refEntity_t legs;
- refEntity_t torso;
- refEntity_t head;
- int clientNum;
- int renderfx;
- qboolean shadow = qfalse;
- float shadowPlane;
- entityState_t *es = &cent->currentState;
- pClass_t class = ( es->powerups >> 8 ) & 0xFF;
- float scale;
- vec3_t tempAxis[ 3 ], tempAxis2[ 3 ];
- vec3_t angles;
- int held = es->modelindex;
- vec3_t surfNormal = { 0.0f, 0.0f, 1.0f };
-
- // the client number is stored in clientNum. It can't be derived
- // from the entity number, because a single client may have
- // multiple corpses on the level using the same clientinfo
- clientNum = es->clientNum;
- if( clientNum < 0 || clientNum >= MAX_CLIENTS )
- CG_Error( "Bad clientNum on player entity" );
-
- ci = &cgs.clientinfo[ clientNum ];
-
- // it is possible to see corpses from disconnected players that may
- // not have valid clientinfo
- if( !ci->infoValid )
- return;
-
- //don't draw
- if( es->eFlags & EF_NODRAW )
- return;
-
- // get the player model information
- renderfx = 0;
- if( es->number == cg.snap->ps.clientNum )
- {
- if( !cg.renderingThirdPerson )
- renderfx = RF_THIRD_PERSON; // only draw in mirrors
- else if( cg_cameraMode.integer )
- return;
- }
-
- if( cg_drawBBOX.integer )
- {
- vec3_t mins, maxs;
-
- BG_FindBBoxForClass( class, mins, maxs, NULL, NULL, NULL );
- CG_DrawBoundingBox( cent->lerpOrigin, mins, maxs );
- }
-
- memset( &legs, 0, sizeof( legs ) );
- memset( &torso, 0, sizeof( torso ) );
- memset( &head, 0, sizeof( head ) );
-
- VectorCopy( cent->lerpAngles, angles );
- AnglesToAxis( cent->lerpAngles, tempAxis );
-
- //rotate lerpAngles to floor
- if( es->eFlags & EF_WALLCLIMB &&
- BG_RotateAxis( es->angles2, tempAxis, tempAxis2, qtrue, es->eFlags & EF_WALLCLIMBCEILING ) )
- AxisToAngles( tempAxis2, angles );
- else
- VectorCopy( cent->lerpAngles, angles );
-
- //normalise the pitch
- if( angles[ PITCH ] < -180.0f )
- angles[ PITCH ] += 360.0f;
-
- // get the rotation information
- if( !ci->nonsegmented )
- CG_PlayerAngles( cent, angles, legs.axis, torso.axis, head.axis );
- else
- CG_PlayerNonSegAngles( cent, angles, legs.axis );
-
- AxisCopy( legs.axis, tempAxis );
-
- //rotate the legs axis to back to the wall
- if( es->eFlags & EF_WALLCLIMB &&
- BG_RotateAxis( es->angles2, legs.axis, tempAxis, qfalse, es->eFlags & EF_WALLCLIMBCEILING ) )
- AxisCopy( tempAxis, legs.axis );
-
- //smooth out WW transitions so the model doesn't hop around
- CG_PlayerWWSmoothing( cent, legs.axis, legs.axis );
-
- AxisCopy( tempAxis, cent->pe.lastAxis );
-
- // get the animation state (after rotation, to allow feet shuffle)
- if( !ci->nonsegmented )
- CG_PlayerAnimation( cent, &legs.oldframe, &legs.frame, &legs.backlerp,
- &torso.oldframe, &torso.frame, &torso.backlerp );
- else
- CG_PlayerNonSegAnimation( cent, &legs.oldframe, &legs.frame, &legs.backlerp );
-
- // add the talk baloon or disconnect icon
- CG_PlayerSprites( cent );
-
- // add the shadow
- if( ( es->number == cg.snap->ps.clientNum && cg.renderingThirdPerson ) ||
- es->number != cg.snap->ps.clientNum )
- shadow = CG_PlayerShadow( cent, &shadowPlane, class );
-
- // add a water splash if partially in and out of water
- CG_PlayerSplash( cent );
-
- if( cg_shadows.integer == 3 && shadow )
- renderfx |= RF_SHADOW_PLANE;
-
- renderfx |= RF_LIGHTING_ORIGIN; // use the same origin for all
-
- //
- // add the legs
- //
- if( !ci->nonsegmented )
- {
- legs.hModel = ci->legsModel;
-
- if( held & ( 1 << UP_LIGHTARMOUR ) )
- legs.customSkin = cgs.media.larmourLegsSkin;
- else
- legs.customSkin = ci->legsSkin;
- }
- else
- {
- legs.hModel = ci->nonSegModel;
- legs.customSkin = ci->nonSegSkin;
- }
-
- VectorCopy( cent->lerpOrigin, legs.origin );
-
- VectorCopy( cent->lerpOrigin, legs.lightingOrigin );
- legs.shadowPlane = shadowPlane;
- legs.renderfx = renderfx;
- VectorCopy( legs.origin, legs.oldorigin ); // don't positionally lerp at all
-
- //move the origin closer into the wall with a CapTrace
- if( es->eFlags & EF_WALLCLIMB && !( es->eFlags & EF_DEAD ) && !( cg.intermissionStarted ) )
- {
- vec3_t start, end, mins, maxs;
- trace_t tr;
-
- if( es->eFlags & EF_WALLCLIMBCEILING )
- VectorSet( surfNormal, 0.0f, 0.0f, -1.0f );
- else
- VectorCopy( es->angles2, surfNormal );
-
- BG_FindBBoxForClass( class, mins, maxs, NULL, NULL, NULL );
-
- VectorMA( legs.origin, -TRACE_DEPTH, surfNormal, end );
- VectorMA( legs.origin, 1.0f, surfNormal, start );
- CG_CapTrace( &tr, start, mins, maxs, end, es->number, MASK_PLAYERSOLID );
-
- //if the trace misses completely then just use legs.origin
- //apparently capsule traces are "smaller" than box traces
- if( tr.fraction != 1.0f )
- VectorMA( legs.origin, tr.fraction * -TRACE_DEPTH, surfNormal, legs.origin );
-
- VectorCopy( legs.origin, legs.lightingOrigin );
- VectorCopy( legs.origin, legs.oldorigin ); // don't positionally lerp at all
- }
-
- //rescale the model
- scale = BG_FindModelScaleForClass( class );
-
- if( scale != 1.0f )
- {
- VectorScale( legs.axis[ 0 ], scale, legs.axis[ 0 ] );
- VectorScale( legs.axis[ 1 ], scale, legs.axis[ 1 ] );
- VectorScale( legs.axis[ 2 ], scale, legs.axis[ 2 ] );
-
- legs.nonNormalizedAxes = qtrue;
- }
-
- //offset on the Z axis if required
- VectorMA( legs.origin, BG_FindZOffsetForClass( class ), surfNormal, legs.origin );
- VectorCopy( legs.origin, legs.lightingOrigin );
- VectorCopy( legs.origin, legs.oldorigin ); // don't positionally lerp at all
-
- trap_R_AddRefEntityToScene( &legs );
-
- // if the model failed, allow the default nullmodel to be displayed
- if( !legs.hModel )
- return;
-
- if( !ci->nonsegmented )
- {
- //
- // add the torso
- //
- torso.hModel = ci->torsoModel;
-
- if( held & ( 1 << UP_LIGHTARMOUR ) )
- torso.customSkin = cgs.media.larmourTorsoSkin;
- else
- torso.customSkin = ci->torsoSkin;
-
- if( !torso.hModel )
- return;
-
- VectorCopy( cent->lerpOrigin, torso.lightingOrigin );
-
- CG_PositionRotatedEntityOnTag( &torso, &legs, ci->legsModel, "tag_torso" );
-
- torso.shadowPlane = shadowPlane;
- torso.renderfx = renderfx;
-
- trap_R_AddRefEntityToScene( &torso );
-
- //
- // add the head
- //
- head.hModel = ci->headModel;
-
- if( held & ( 1 << UP_HELMET ) )
- head.customSkin = cgs.media.larmourHeadSkin;
- else
- head.customSkin = ci->headSkin;
-
- if( !head.hModel )
- return;
-
- VectorCopy( cent->lerpOrigin, head.lightingOrigin );
-
- CG_PositionRotatedEntityOnTag( &head, &torso, ci->torsoModel, "tag_head" );
-
- head.shadowPlane = shadowPlane;
- head.renderfx = renderfx;
-
- trap_R_AddRefEntityToScene( &head );
- }
-
- //
- // add the gun / barrel / flash
- //
- if( es->weapon != WP_NONE )
- {
- if( !ci->nonsegmented )
- CG_AddPlayerWeapon( &torso, NULL, cent );
- else
- CG_AddPlayerWeapon( &legs, NULL, cent );
- }
-
- CG_PlayerUpgrades( cent, &torso );
-
- //sanity check that particle systems are stopped when dead
- if( es->eFlags & EF_DEAD )
- {
- if( CG_IsParticleSystemValid( &cent->muzzlePS ) )
- CG_DestroyParticleSystem( &cent->muzzlePS );
-
- if( CG_IsParticleSystemValid( &cent->jetPackPS ) )
- CG_DestroyParticleSystem( &cent->jetPackPS );
- }
-
- VectorCopy( surfNormal, cent->pe.lastNormal );
-}
-
-/*
-===============
-CG_Corpse
-===============
-*/
-void CG_Corpse( centity_t *cent )
-{
- clientInfo_t *ci;
- refEntity_t legs;
- refEntity_t torso;
- refEntity_t head;
- entityState_t *es = &cent->currentState;
- int corpseNum;
- int renderfx;
- qboolean shadow = qfalse;
- float shadowPlane;
- vec3_t origin, liveZ, deadZ;
- float scale;
-
- corpseNum = CG_GetCorpseNum( es->clientNum );
-
- if( corpseNum < 0 || corpseNum >= MAX_CLIENTS )
- CG_Error( "Bad corpseNum on corpse entity: %d", corpseNum );
-
- ci = &cgs.corpseinfo[ corpseNum ];
-
- // it is possible to see corpses from disconnected players that may
- // not have valid clientinfo
- if( !ci->infoValid )
- return;
-
- memset( &legs, 0, sizeof( legs ) );
- memset( &torso, 0, sizeof( torso ) );
- memset( &head, 0, sizeof( head ) );
-
- VectorCopy( cent->lerpOrigin, origin );
- BG_FindBBoxForClass( es->clientNum, liveZ, NULL, NULL, deadZ, NULL );
- origin[ 2 ] -= ( liveZ[ 2 ] - deadZ[ 2 ] );
-
- VectorCopy( es->angles, cent->lerpAngles );
-
- // get the rotation information
- if( !ci->nonsegmented )
- CG_PlayerAngles( cent, cent->lerpAngles, legs.axis, torso.axis, head.axis );
- else
- CG_PlayerNonSegAngles( cent, cent->lerpAngles, legs.axis );
-
- //set the correct frame (should always be dead)
- if( cg_noPlayerAnims.integer )
- legs.oldframe = legs.frame = torso.oldframe = torso.frame = 0;
- else if( !ci->nonsegmented )
- {
- memset( &cent->pe.legs, 0, sizeof( lerpFrame_t ) );
- CG_RunPlayerLerpFrame( ci, &cent->pe.legs, es->legsAnim, 1 );
- legs.oldframe = cent->pe.legs.oldFrame;
- legs.frame = cent->pe.legs.frame;
- legs.backlerp = cent->pe.legs.backlerp;
-
- memset( &cent->pe.torso, 0, sizeof( lerpFrame_t ) );
- CG_RunPlayerLerpFrame( ci, &cent->pe.torso, es->torsoAnim, 1 );
- torso.oldframe = cent->pe.torso.oldFrame;
- torso.frame = cent->pe.torso.frame;
- torso.backlerp = cent->pe.torso.backlerp;
- }
- else
- {
- memset( &cent->pe.nonseg, 0, sizeof( lerpFrame_t ) );
- CG_RunPlayerLerpFrame( ci, &cent->pe.nonseg, es->legsAnim, 1 );
- legs.oldframe = cent->pe.nonseg.oldFrame;
- legs.frame = cent->pe.nonseg.frame;
- legs.backlerp = cent->pe.nonseg.backlerp;
- }
-
- // add the shadow
- shadow = CG_PlayerShadow( cent, &shadowPlane, es->clientNum );
-
- // get the player model information
- renderfx = 0;
-
- if( cg_shadows.integer == 3 && shadow )
- renderfx |= RF_SHADOW_PLANE;
-
- renderfx |= RF_LIGHTING_ORIGIN; // use the same origin for all
-
- //
- // add the legs
- //
- if( !ci->nonsegmented )
- {
- legs.hModel = ci->legsModel;
- legs.customSkin = ci->legsSkin;
- }
- else
- {
- legs.hModel = ci->nonSegModel;
- legs.customSkin = ci->nonSegSkin;
- }
-
- VectorCopy( origin, legs.origin );
-
- VectorCopy( origin, legs.lightingOrigin );
- legs.shadowPlane = shadowPlane;
- legs.renderfx = renderfx;
- legs.origin[ 2 ] += BG_FindZOffsetForClass( es->clientNum );
- VectorCopy( legs.origin, legs.oldorigin ); // don't positionally lerp at all
-
- //rescale the model
- scale = BG_FindModelScaleForClass( es->clientNum );
-
- if( scale != 1.0f )
- {
- VectorScale( legs.axis[ 0 ], scale, legs.axis[ 0 ] );
- VectorScale( legs.axis[ 1 ], scale, legs.axis[ 1 ] );
- VectorScale( legs.axis[ 2 ], scale, legs.axis[ 2 ] );
-
- legs.nonNormalizedAxes = qtrue;
- }
-
- //CG_AddRefEntityWithPowerups( &legs, es->powerups, ci->team );
- trap_R_AddRefEntityToScene( &legs );
-
- // if the model failed, allow the default nullmodel to be displayed
- if( !legs.hModel )
- return;
-
- if( !ci->nonsegmented )
- {
- //
- // add the torso
- //
- torso.hModel = ci->torsoModel;
- if( !torso.hModel )
- return;
-
- torso.customSkin = ci->torsoSkin;
-
- VectorCopy( origin, torso.lightingOrigin );
-
- CG_PositionRotatedEntityOnTag( &torso, &legs, ci->legsModel, "tag_torso" );
-
- torso.shadowPlane = shadowPlane;
- torso.renderfx = renderfx;
-
- //CG_AddRefEntityWithPowerups( &torso, es->powerups, ci->team );
- trap_R_AddRefEntityToScene( &torso );
-
- //
- // add the head
- //
- head.hModel = ci->headModel;
- if( !head.hModel )
- return;
-
- head.customSkin = ci->headSkin;
-
- VectorCopy( origin, head.lightingOrigin );
-
- CG_PositionRotatedEntityOnTag( &head, &torso, ci->torsoModel, "tag_head");
-
- head.shadowPlane = shadowPlane;
- head.renderfx = renderfx;
-
- //CG_AddRefEntityWithPowerups( &head, es->powerups, ci->team );
- trap_R_AddRefEntityToScene( &head );
- }
-}
-
-
-//=====================================================================
-
-/*
-===============
-CG_ResetPlayerEntity
-
-A player just came into view or teleported, so reset all animation info
-===============
-*/
-void CG_ResetPlayerEntity( centity_t *cent )
-{
- cent->errorTime = -99999; // guarantee no error decay added
- cent->extrapolated = qfalse;
-
- CG_ClearLerpFrame( &cgs.clientinfo[ cent->currentState.clientNum ],
- &cent->pe.legs, cent->currentState.legsAnim );
- CG_ClearLerpFrame( &cgs.clientinfo[ cent->currentState.clientNum ],
- &cent->pe.torso, cent->currentState.torsoAnim );
- CG_ClearLerpFrame( &cgs.clientinfo[ cent->currentState.clientNum ],
- &cent->pe.nonseg, cent->currentState.legsAnim );
-
- BG_EvaluateTrajectory( &cent->currentState.pos, cg.time, cent->lerpOrigin );
- BG_EvaluateTrajectory( &cent->currentState.apos, cg.time, cent->lerpAngles );
-
- VectorCopy( cent->lerpOrigin, cent->rawOrigin );
- VectorCopy( cent->lerpAngles, cent->rawAngles );
-
- memset( &cent->pe.legs, 0, sizeof( cent->pe.legs ) );
- cent->pe.legs.yawAngle = cent->rawAngles[ YAW ];
- cent->pe.legs.yawing = qfalse;
- cent->pe.legs.pitchAngle = 0;
- cent->pe.legs.pitching = qfalse;
-
- memset( &cent->pe.torso, 0, sizeof( cent->pe.legs ) );
- cent->pe.torso.yawAngle = cent->rawAngles[ YAW ];
- cent->pe.torso.yawing = qfalse;
- cent->pe.torso.pitchAngle = cent->rawAngles[ PITCH ];
- cent->pe.torso.pitching = qfalse;
-
- memset( &cent->pe.nonseg, 0, sizeof( cent->pe.nonseg ) );
- cent->pe.nonseg.yawAngle = cent->rawAngles[ YAW ];
- cent->pe.nonseg.yawing = qfalse;
- cent->pe.nonseg.pitchAngle = cent->rawAngles[ PITCH ];
- cent->pe.nonseg.pitching = qfalse;
-
- if( cg_debugPosition.integer )
- CG_Printf( "%i ResetPlayerEntity yaw=%i\n", cent->currentState.number, cent->pe.torso.yawAngle );
-}
-
-/*
-==================
-CG_PlayerDisconnect
-
-Player disconnecting
-==================
-*/
-void CG_PlayerDisconnect( vec3_t org )
-{
- particleSystem_t *ps;
-
- trap_S_StartSound( org, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.disconnectSound );
-
- ps = CG_SpawnNewParticleSystem( cgs.media.disconnectPS );
-
- if( CG_IsParticleSystemValid( &ps ) )
- {
- CG_SetAttachmentPoint( &ps->attachment, org );
- CG_AttachToPoint( &ps->attachment );
- }
-}
-
-/*
-=================
-CG_Bleed
-
-This is the spurt of blood when a character gets hit
-=================
-*/
-void CG_Bleed( vec3_t origin, vec3_t normal, int entityNum )
-{
- pTeam_t team = cgs.clientinfo[ entityNum ].team;
- qhandle_t bleedPS;
- particleSystem_t *ps;
-
- if( !cg_blood.integer )
- return;
-
- if( team == PTE_ALIENS )
- bleedPS = cgs.media.alienBleedPS;
- else if( team == PTE_HUMANS )
- bleedPS = cgs.media.humanBleedPS;
- else
- return;
-
- ps = CG_SpawnNewParticleSystem( bleedPS );
-
- if( CG_IsParticleSystemValid( &ps ) )
- {
- CG_SetAttachmentPoint( &ps->attachment, origin );
- CG_SetAttachmentCent( &ps->attachment, &cg_entities[ entityNum ] );
- CG_AttachToPoint( &ps->attachment );
-
- CG_SetParticleSystemNormal( ps, normal );
- }
-}
diff --git a/src/cgame/cg_playerstate.c b/src/cgame/cg_playerstate.c
deleted file mode 100644
index 489b024d..00000000
--- a/src/cgame/cg_playerstate.c
+++ /dev/null
@@ -1,308 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_playerstate.c -- this file acts on changes in a new playerState_t
-// With normal play, this will be done after local prediction, but when
-// following another player or playing back a demo, it will be checked
-// when the snapshot transitions like all the other entities
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-/*
-==============
-CG_DamageFeedback
-==============
-*/
-void CG_DamageFeedback( int yawByte, int pitchByte, int damage )
-{
- float left, front, up;
- float kick;
- int health;
- float scale;
- vec3_t dir;
- vec3_t angles;
- float dist;
- float yaw, pitch;
-
- // show the attacking player's head and name in corner
- cg.attackerTime = cg.time;
-
- // the lower on health you are, the greater the view kick will be
- health = cg.snap->ps.stats[STAT_HEALTH];
-
- if( health < 40 )
- scale = 1;
- else
- scale = 40.0 / health;
-
- kick = damage * scale;
-
- if( kick < 5 )
- kick = 5;
-
- if( kick > 10 )
- kick = 10;
-
- // if yaw and pitch are both 255, make the damage always centered (falling, etc)
- if( yawByte == 255 && pitchByte == 255 )
- {
- cg.damageX = 0;
- cg.damageY = 0;
- cg.v_dmg_roll = 0;
- cg.v_dmg_pitch = -kick;
- }
- else
- {
- // positional
- pitch = pitchByte / 255.0 * 360;
- yaw = yawByte / 255.0 * 360;
-
- angles[ PITCH ] = pitch;
- angles[ YAW ] = yaw;
- angles[ ROLL ] = 0;
-
- AngleVectors( angles, dir, NULL, NULL );
- VectorSubtract( vec3_origin, dir, dir );
-
- front = DotProduct( dir, cg.refdef.viewaxis[ 0 ] );
- left = DotProduct( dir, cg.refdef.viewaxis[ 1 ] );
- up = DotProduct( dir, cg.refdef.viewaxis[ 2 ] );
-
- dir[ 0 ] = front;
- dir[ 1 ] = left;
- dir[ 2 ] = 0;
- dist = VectorLength( dir );
-
- if( dist < 0.1f )
- dist = 0.1f;
-
- cg.v_dmg_roll = kick * left;
-
- cg.v_dmg_pitch = -kick * front;
-
- if( front <= 0.1 )
- front = 0.1f;
-
- cg.damageX = -left / front;
- cg.damageY = up / dist;
- }
-
- // clamp the position
- if( cg.damageX > 1.0 )
- cg.damageX = 1.0;
-
- if( cg.damageX < - 1.0 )
- cg.damageX = -1.0;
-
- if( cg.damageY > 1.0 )
- cg.damageY = 1.0;
-
- if( cg.damageY < - 1.0 )
- cg.damageY = -1.0;
-
- // don't let the screen flashes vary as much
- if( kick > 10 )
- kick = 10;
-
- cg.damageValue = kick;
- cg.v_dmg_time = cg.time + DAMAGE_TIME;
- cg.damageTime = cg.snap->serverTime;
-}
-
-
-
-
-/*
-================
-CG_Respawn
-
-A respawn happened this snapshot
-================
-*/
-void CG_Respawn( void )
-{
- // no error decay on player movement
- cg.thisFrameTeleport = qtrue;
-
- // display weapons available
- cg.weaponSelectTime = cg.time;
-
- // select the weapon the server says we are using
- cg.weaponSelect = cg.snap->ps.weapon;
-
- CG_ResetPainBlend( );
-}
-
-/*
-==============
-CG_CheckPlayerstateEvents
-
-==============
-*/
-void CG_CheckPlayerstateEvents( playerState_t *ps, playerState_t *ops )
-{
- int i;
- int event;
- centity_t *cent;
-
- if( ps->externalEvent && ps->externalEvent != ops->externalEvent )
- {
- cent = &cg_entities[ ps->clientNum ];
- cent->currentState.event = ps->externalEvent;
- cent->currentState.eventParm = ps->externalEventParm;
- CG_EntityEvent( cent, cent->lerpOrigin );
- }
-
- cent = &cg.predictedPlayerEntity; // cg_entities[ ps->clientNum ];
-
- // go through the predictable events buffer
- for( i = ps->eventSequence - MAX_PS_EVENTS; i < ps->eventSequence; i++ )
- {
- // if we have a new predictable event
- if( i >= ops->eventSequence ||
- // or the server told us to play another event instead of a predicted event we already issued
- // or something the server told us changed our prediction causing a different event
- ( i > ops->eventSequence - MAX_PS_EVENTS && ps->events[ i & ( MAX_PS_EVENTS - 1 ) ] !=
- ops->events[ i & ( MAX_PS_EVENTS - 1 ) ] ) )
- {
- event = ps->events[ i & ( MAX_PS_EVENTS - 1 ) ];
-
- cent->currentState.event = event;
- cent->currentState.eventParm = ps->eventParms[ i & ( MAX_PS_EVENTS - 1 ) ];
- CG_EntityEvent( cent, cent->lerpOrigin );
- cg.predictableEvents[ i & ( MAX_PREDICTED_EVENTS - 1 ) ] = event;
-
- cg.eventSequence++;
- }
- }
-}
-
-
-/*
-==================
-CG_CheckChangedPredictableEvents
-==================
-*/
-void CG_CheckChangedPredictableEvents( playerState_t *ps )
-{
- int i;
- int event;
- centity_t *cent;
-
- cent = &cg.predictedPlayerEntity;
-
- for( i = ps->eventSequence - MAX_PS_EVENTS; i < ps->eventSequence; i++ )
- {
- //
- if( i >= cg.eventSequence )
- continue;
-
- // if this event is not further back in than the maximum predictable events we remember
- if( i > cg.eventSequence - MAX_PREDICTED_EVENTS )
- {
- // if the new playerstate event is different from a previously predicted one
- if( ps->events[ i & ( MAX_PS_EVENTS - 1 ) ] != cg.predictableEvents[ i & ( MAX_PREDICTED_EVENTS - 1 ) ] )
- {
- event = ps->events[ i & ( MAX_PS_EVENTS - 1 ) ];
- cent->currentState.event = event;
- cent->currentState.eventParm = ps->eventParms[ i & ( MAX_PS_EVENTS - 1 ) ];
- CG_EntityEvent( cent, cent->lerpOrigin );
-
- cg.predictableEvents[ i & ( MAX_PREDICTED_EVENTS - 1 ) ] = event;
-
- if( cg_showmiss.integer )
- CG_Printf( "WARNING: changed predicted event\n" );
- }
- }
- }
-}
-
-/*
-==================
-CG_CheckLocalSounds
-==================
-*/
-void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops )
-{
- int reward;
-
- // don't play the sounds if the player just changed teams
- if( ps->persistant[ PERS_TEAM ] != ops->persistant[ PERS_TEAM ] )
- return;
-
- // health changes of more than -1 should make pain sounds
- if( ps->stats[ STAT_HEALTH ] < ops->stats[ STAT_HEALTH ] - 1 )
- {
- if( ps->stats[ STAT_HEALTH ] > 0 )
- CG_PainEvent( &cg.predictedPlayerEntity, ps->stats[ STAT_HEALTH ] );
- }
-
-
- // if we are going into the intermission, don't start any voices
- if( cg.intermissionStarted )
- return;
-
- // reward sounds
- reward = qfalse;
-}
-
-
-/*
-===============
-CG_TransitionPlayerState
-
-===============
-*/
-void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops )
-{
- // check for changing follow mode
- if( ps->clientNum != ops->clientNum )
- {
- cg.thisFrameTeleport = qtrue;
- // make sure we don't get any unwanted transition effects
- *ops = *ps;
-
- CG_ResetPainBlend( );
- }
-
- // damage events (player is getting wounded)
- if( ps->damageEvent != ops->damageEvent && ps->damageCount )
- CG_DamageFeedback( ps->damageYaw, ps->damagePitch, ps->damageCount );
-
- // respawning
- if( ps->persistant[ PERS_SPAWN_COUNT ] != ops->persistant[ PERS_SPAWN_COUNT ] )
- CG_Respawn( );
-
- if( cg.mapRestart )
- {
- CG_Respawn( );
- cg.mapRestart = qfalse;
- }
-
- if( cg.snap->ps.pm_type != PM_INTERMISSION &&
- ps->persistant[ PERS_TEAM ] != TEAM_SPECTATOR )
- CG_CheckLocalSounds( ps, ops );
-
- // run events
- CG_CheckPlayerstateEvents( ps, ops );
-
- // smooth the ducking viewheight change
- if( ps->viewheight != ops->viewheight )
- {
- cg.duckChange = ps->viewheight - ops->viewheight;
- cg.duckTime = cg.time;
- }
-}
-
diff --git a/src/cgame/cg_predict.c b/src/cgame/cg_predict.c
deleted file mode 100644
index dc6c9dd5..00000000
--- a/src/cgame/cg_predict.c
+++ /dev/null
@@ -1,615 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_predict.c -- this file generates cg.predictedPlayerState by either
-// interpolating between snapshots from the server or locally predicting
-// ahead the client's movement.
-// It also handles local physics interaction, like fragments bouncing off walls
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-static pmove_t cg_pmove;
-
-static int cg_numSolidEntities;
-static centity_t *cg_solidEntities[MAX_ENTITIES_IN_SNAPSHOT];
-static int cg_numTriggerEntities;
-static centity_t *cg_triggerEntities[MAX_ENTITIES_IN_SNAPSHOT];
-
-/*
-====================
-CG_BuildSolidList
-
-When a new cg.snap has been set, this function builds a sublist
-of the entities that are actually solid, to make for more
-efficient collision detection
-====================
-*/
-void CG_BuildSolidList( void )
-{
- int i;
- centity_t *cent;
- snapshot_t *snap;
- entityState_t *ent;
-
- cg_numSolidEntities = 0;
- cg_numTriggerEntities = 0;
-
- if( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport )
- snap = cg.nextSnap;
- else
- snap = cg.snap;
-
- for( i = 0; i < snap->numEntities; i++ )
- {
- cent = &cg_entities[ snap->entities[ i ].number ];
- ent = &cent->currentState;
-
- if( ent->eType == ET_ITEM || ent->eType == ET_PUSH_TRIGGER || ent->eType == ET_TELEPORT_TRIGGER )
- {
- cg_triggerEntities[ cg_numTriggerEntities ] = cent;
- cg_numTriggerEntities++;
- continue;
- }
-
- if( cent->nextState.solid && ent->eType != ET_MISSILE )
- {
- cg_solidEntities[ cg_numSolidEntities ] = cent;
- cg_numSolidEntities++;
- continue;
- }
- }
-}
-
-/*
-====================
-CG_ClipMoveToEntities
-
-====================
-*/
-static void CG_ClipMoveToEntities ( const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
- int skipNumber, int mask, trace_t *tr, qboolean capsule )
-{
- int i, j, x, zd, zu;
- trace_t trace;
- entityState_t *ent;
- clipHandle_t cmodel;
- vec3_t bmins, bmaxs;
- vec3_t origin, angles;
- centity_t *cent;
-
- //SUPAR HACK
- //this causes a trace to collide with the local player
- if( skipNumber == MAGIC_TRACE_HACK )
- j = cg_numSolidEntities + 1;
- else
- j = cg_numSolidEntities;
-
- for( i = 0; i < j; i++ )
- {
- if( i < cg_numSolidEntities )
- cent = cg_solidEntities[ i ];
- else
- cent = &cg.predictedPlayerEntity;
-
- ent = &cent->currentState;
-
- if( ent->number == skipNumber )
- continue;
-
- if( ent->solid == SOLID_BMODEL )
- {
- // special value for bmodel
- cmodel = trap_CM_InlineModel( ent->modelindex );
- VectorCopy( cent->lerpAngles, angles );
- BG_EvaluateTrajectory( &cent->currentState.pos, cg.physicsTime, origin );
- }
- else
- {
- // encoded bbox
- x = ( ent->solid & 255 );
- zd = ( ( ent->solid >> 8 ) & 255 );
- zu = ( ( ent->solid >> 16 ) & 255 ) - 32;
-
- bmins[ 0 ] = bmins[ 1 ] = -x;
- bmaxs[ 0 ] = bmaxs[ 1 ] = x;
- bmins[ 2 ] = -zd;
- bmaxs[ 2 ] = zu;
-
- if( i == cg_numSolidEntities )
- BG_FindBBoxForClass( ( ent->powerups >> 8 ) & 0xFF, bmins, bmaxs, NULL, NULL, NULL );
-
- cmodel = trap_CM_TempBoxModel( bmins, bmaxs );
- VectorCopy( vec3_origin, angles );
- VectorCopy( cent->lerpOrigin, origin );
- }
-
-
- if( capsule )
- {
- trap_CM_TransformedCapsuleTrace ( &trace, start, end,
- mins, maxs, cmodel, mask, origin, angles );
- }
- else
- {
- trap_CM_TransformedBoxTrace ( &trace, start, end,
- mins, maxs, cmodel, mask, origin, angles );
- }
-
- if( trace.allsolid || trace.fraction < tr->fraction )
- {
- trace.entityNum = ent->number;
- *tr = trace;
- }
- else if( trace.startsolid )
- tr->startsolid = qtrue;
-
- if( tr->allsolid )
- return;
- }
-}
-
-/*
-================
-CG_Trace
-================
-*/
-void CG_Trace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
- int skipNumber, int mask )
-{
- trace_t t;
-
- trap_CM_BoxTrace( &t, start, end, mins, maxs, 0, mask );
- t.entityNum = t.fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE;
- // check all other solid models
- CG_ClipMoveToEntities( start, mins, maxs, end, skipNumber, mask, &t, qfalse );
-
- *result = t;
-}
-
-/*
-================
-CG_CapTrace
-================
-*/
-void CG_CapTrace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
- int skipNumber, int mask )
-{
- trace_t t;
-
- trap_CM_CapsuleTrace( &t, start, end, mins, maxs, 0, mask );
- t.entityNum = t.fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE;
- // check all other solid models
- CG_ClipMoveToEntities( start, mins, maxs, end, skipNumber, mask, &t, qtrue );
-
- *result = t;
-}
-
-/*
-================
-CG_PointContents
-================
-*/
-int CG_PointContents( const vec3_t point, int passEntityNum )
-{
- int i;
- entityState_t *ent;
- centity_t *cent;
- clipHandle_t cmodel;
- int contents;
-
- contents = trap_CM_PointContents (point, 0);
-
- for( i = 0; i < cg_numSolidEntities; i++ )
- {
- cent = cg_solidEntities[ i ];
-
- ent = &cent->currentState;
-
- if( ent->number == passEntityNum )
- continue;
-
- if( ent->solid != SOLID_BMODEL ) // special value for bmodel
- continue;
-
- cmodel = trap_CM_InlineModel( ent->modelindex );
-
- if( !cmodel )
- continue;
-
- contents |= trap_CM_TransformedPointContents( point, cmodel, ent->origin, ent->angles );
- }
-
- return contents;
-}
-
-
-/*
-========================
-CG_InterpolatePlayerState
-
-Generates cg.predictedPlayerState by interpolating between
-cg.snap->player_state and cg.nextFrame->player_state
-========================
-*/
-static void CG_InterpolatePlayerState( qboolean grabAngles )
-{
- float f;
- int i;
- playerState_t *out;
- snapshot_t *prev, *next;
-
- out = &cg.predictedPlayerState;
- prev = cg.snap;
- next = cg.nextSnap;
-
- *out = cg.snap->ps;
-
- // if we are still allowing local input, short circuit the view angles
- if( grabAngles )
- {
- usercmd_t cmd;
- int cmdNum;
-
- cmdNum = trap_GetCurrentCmdNumber( );
- trap_GetUserCmd( cmdNum, &cmd );
-
- PM_UpdateViewAngles( out, &cmd );
- }
-
- // if the next frame is a teleport, we can't lerp to it
- if( cg.nextFrameTeleport )
- return;
-
- if( !next || next->serverTime <= prev->serverTime )
- return;
-
- f = (float)( cg.time - prev->serverTime ) / ( next->serverTime - prev->serverTime );
-
- i = next->ps.bobCycle;
- if( i < prev->ps.bobCycle )
- i += 256; // handle wraparound
-
- out->bobCycle = prev->ps.bobCycle + f * ( i - prev->ps.bobCycle );
-
- for( i = 0; i < 3; i++ )
- {
- out->origin[ i ] = prev->ps.origin[ i ] + f * ( next->ps.origin[ i ] - prev->ps.origin[ i ] );
-
- if( !grabAngles )
- out->viewangles[ i ] = LerpAngle( prev->ps.viewangles[ i ], next->ps.viewangles[ i ], f );
-
- out->velocity[ i ] = prev->ps.velocity[ i ] +
- f * (next->ps.velocity[ i ] - prev->ps.velocity[ i ] );
- }
-}
-
-
-/*
-=========================
-CG_TouchTriggerPrediction
-
-Predict push triggers and items
-=========================
-*/
-static void CG_TouchTriggerPrediction( void )
-{
- int i;
- trace_t trace;
- entityState_t *ent;
- clipHandle_t cmodel;
- centity_t *cent;
- qboolean spectator;
-
- // dead clients don't activate triggers
- if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 )
- return;
-
- spectator = ( cg.predictedPlayerState.pm_type == PM_SPECTATOR );
-
- if( cg.predictedPlayerState.pm_type != PM_NORMAL && !spectator )
- return;
-
- for( i = 0; i < cg_numTriggerEntities; i++ )
- {
- cent = cg_triggerEntities[ i ];
- ent = &cent->currentState;
-
- if( ent->solid != SOLID_BMODEL )
- continue;
-
- cmodel = trap_CM_InlineModel( ent->modelindex );
- if( !cmodel )
- continue;
-
- trap_CM_BoxTrace( &trace, cg.predictedPlayerState.origin, cg.predictedPlayerState.origin,
- cg_pmove.mins, cg_pmove.maxs, cmodel, -1 );
-
- if( !trace.startsolid )
- continue;
-
- if( ent->eType == ET_TELEPORT_TRIGGER )
- cg.hyperspace = qtrue;
- }
-
- // if we didn't touch a jump pad this pmove frame
- if( cg.predictedPlayerState.jumppad_frame != cg.predictedPlayerState.pmove_framecount )
- {
- cg.predictedPlayerState.jumppad_frame = 0;
- cg.predictedPlayerState.jumppad_ent = 0;
- }
-}
-
-
-
-/*
-=================
-CG_PredictPlayerState
-
-Generates cg.predictedPlayerState for the current cg.time
-cg.predictedPlayerState is guaranteed to be valid after exiting.
-
-For demo playback, this will be an interpolation between two valid
-playerState_t.
-
-For normal gameplay, it will be the result of predicted usercmd_t on
-top of the most recent playerState_t received from the server.
-
-Each new snapshot will usually have one or more new usercmd over the last,
-but we simulate all unacknowledged commands each time, not just the new ones.
-This means that on an internet connection, quite a few pmoves may be issued
-each frame.
-
-OPTIMIZE: don't re-simulate unless the newly arrived snapshot playerState_t
-differs from the predicted one. Would require saving all intermediate
-playerState_t during prediction.
-
-We detect prediction errors and allow them to be decayed off over several frames
-to ease the jerk.
-=================
-*/
-void CG_PredictPlayerState( void )
-{
- int cmdNum, current, i;
- playerState_t oldPlayerState;
- qboolean moved;
- usercmd_t oldestCmd;
- usercmd_t latestCmd;
-
- cg.hyperspace = qfalse; // will be set if touching a trigger_teleport
-
- // if this is the first frame we must guarantee
- // predictedPlayerState is valid even if there is some
- // other error condition
- if( !cg.validPPS )
- {
- cg.validPPS = qtrue;
- cg.predictedPlayerState = cg.snap->ps;
- }
-
-
- // demo playback just copies the moves
- if( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) )
- {
- CG_InterpolatePlayerState( qfalse );
- return;
- }
-
- // non-predicting local movement will grab the latest angles
- if( cg_nopredict.integer || cg_synchronousClients.integer )
- {
- CG_InterpolatePlayerState( qtrue );
- return;
- }
-
- // prepare for pmove
- cg_pmove.ps = &cg.predictedPlayerState;
- cg_pmove.trace = CG_Trace;
- cg_pmove.pointcontents = CG_PointContents;
- cg_pmove.debugLevel = cg_debugMove.integer;
-
- if( cg_pmove.ps->pm_type == PM_DEAD )
- cg_pmove.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY;
- else
- cg_pmove.tracemask = MASK_PLAYERSOLID;
-
- if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
- cg_pmove.tracemask &= ~CONTENTS_BODY; // spectators can fly through bodies
-
- cg_pmove.noFootsteps = 0;
-
- // save the state before the pmove so we can detect transitions
- oldPlayerState = cg.predictedPlayerState;
-
- current = trap_GetCurrentCmdNumber( );
-
- // if we don't have the commands right after the snapshot, we
- // can't accurately predict a current position, so just freeze at
- // the last good position we had
- cmdNum = current - CMD_BACKUP + 1;
- trap_GetUserCmd( cmdNum, &oldestCmd );
-
- if( oldestCmd.serverTime > cg.snap->ps.commandTime &&
- oldestCmd.serverTime < cg.time )
- { // special check for map_restart
- if( cg_showmiss.integer )
- CG_Printf( "exceeded PACKET_BACKUP on commands\n" );
-
- return;
- }
-
- // get the latest command so we can know which commands are from previous map_restarts
- trap_GetUserCmd( current, &latestCmd );
-
- // get the most recent information we have, even if
- // the server time is beyond our current cg.time,
- // because predicted player positions are going to
- // be ahead of everything else anyway
- if( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport )
- {
- cg.predictedPlayerState = cg.nextSnap->ps;
- cg.physicsTime = cg.nextSnap->serverTime;
- }
- else
- {
- cg.predictedPlayerState = cg.snap->ps;
- cg.physicsTime = cg.snap->serverTime;
- }
-
- if( pmove_msec.integer < 8 )
- trap_Cvar_Set( "pmove_msec", "8" );
- else if( pmove_msec.integer > 33 )
- trap_Cvar_Set( "pmove_msec", "33" );
-
- cg_pmove.pmove_fixed = pmove_fixed.integer;// | cg_pmove_fixed.integer;
- cg_pmove.pmove_msec = pmove_msec.integer;
-
- // run cmds
- moved = qfalse;
-
- for( cmdNum = current - CMD_BACKUP + 1; cmdNum <= current; cmdNum++ )
- {
- // get the command
- trap_GetUserCmd( cmdNum, &cg_pmove.cmd );
-
- if( cg_pmove.pmove_fixed )
- PM_UpdateViewAngles( cg_pmove.ps, &cg_pmove.cmd );
-
- // don't do anything if the time is before the snapshot player time
- if( cg_pmove.cmd.serverTime <= cg.predictedPlayerState.commandTime )
- continue;
-
- // don't do anything if the command was from a previous map_restart
- if( cg_pmove.cmd.serverTime > latestCmd.serverTime )
- continue;
-
- // check for a prediction error from last frame
- // on a lan, this will often be the exact value
- // from the snapshot, but on a wan we will have
- // to predict several commands to get to the point
- // we want to compare
- if( cg.predictedPlayerState.commandTime == oldPlayerState.commandTime )
- {
- vec3_t delta;
- float len;
-
- if( cg.thisFrameTeleport )
- {
- // a teleport will not cause an error decay
- VectorClear( cg.predictedError );
-
- if( cg_showmiss.integer )
- CG_Printf( "PredictionTeleport\n" );
-
- cg.thisFrameTeleport = qfalse;
- }
- else
- {
- vec3_t adjusted;
- CG_AdjustPositionForMover( cg.predictedPlayerState.origin,
- cg.predictedPlayerState.groundEntityNum, cg.physicsTime, cg.oldTime, adjusted );
-
- if( cg_showmiss.integer )
- {
- if( !VectorCompare( oldPlayerState.origin, adjusted ) )
- CG_Printf("prediction error\n");
- }
-
- VectorSubtract( oldPlayerState.origin, adjusted, delta );
- len = VectorLength( delta );
-
- if( len > 0.1 )
- {
- if( cg_showmiss.integer )
- CG_Printf( "Prediction miss: %f\n", len );
-
- if( cg_errorDecay.integer )
- {
- int t;
- float f;
-
- t = cg.time - cg.predictedErrorTime;
- f = ( cg_errorDecay.value - t ) / cg_errorDecay.value;
-
- if( f < 0 )
- f = 0;
-
- if( f > 0 && cg_showmiss.integer )
- CG_Printf( "Double prediction decay: %f\n", f );
-
- VectorScale( cg.predictedError, f, cg.predictedError );
- }
- else
- VectorClear( cg.predictedError );
-
- VectorAdd( delta, cg.predictedError, cg.predictedError );
- cg.predictedErrorTime = cg.oldTime;
- }
- }
- }
-
- // don't predict gauntlet firing, which is only supposed to happen
- // when it actually inflicts damage
- for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
- cg_pmove.autoWeaponHit[ i ] = qfalse;
-
- if( cg_pmove.pmove_fixed )
- cg_pmove.cmd.serverTime = ( ( cg_pmove.cmd.serverTime + pmove_msec.integer - 1 ) /
- pmove_msec.integer ) * pmove_msec.integer;
-
- Pmove( &cg_pmove );
-
- moved = qtrue;
-
- // add push trigger movement effects
- CG_TouchTriggerPrediction( );
-
- // check for predictable events that changed from previous predictions
- //CG_CheckChangedPredictableEvents(&cg.predictedPlayerState);
- }
-
- if( cg_showmiss.integer > 1 )
- CG_Printf( "[%i : %i] ", cg_pmove.cmd.serverTime, cg.time );
-
- if( !moved )
- {
- if( cg_showmiss.integer )
- CG_Printf( "not moved\n" );
-
- return;
- }
-
- // adjust for the movement of the groundentity
- CG_AdjustPositionForMover( cg.predictedPlayerState.origin,
- cg.predictedPlayerState.groundEntityNum,
- cg.physicsTime, cg.time, cg.predictedPlayerState.origin );
-
- if( cg_showmiss.integer )
- {
- if( cg.predictedPlayerState.eventSequence > oldPlayerState.eventSequence + MAX_PS_EVENTS )
- CG_Printf( "WARNING: dropped event\n" );
- }
-
- // fire events and other transition triggered things
- CG_TransitionPlayerState( &cg.predictedPlayerState, &oldPlayerState );
-
- if( cg_showmiss.integer )
- {
- if( cg.eventSequence > cg.predictedPlayerState.eventSequence )
- {
- CG_Printf( "WARNING: double event\n" );
- cg.eventSequence = cg.predictedPlayerState.eventSequence;
- }
- }
-}
diff --git a/src/cgame/cg_ptr.c b/src/cgame/cg_ptr.c
deleted file mode 100644
index c31e5e40..00000000
--- a/src/cgame/cg_ptr.c
+++ /dev/null
@@ -1,71 +0,0 @@
-// cg_ptr.c -- post timeout restoration handling
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-#define PTRC_FILE "ptrc.cfg"
-
-/*
-===============
-CG_ReadPTRCode
-
-Read a PTR code from disk
-===============
-*/
-int CG_ReadPTRCode( void )
-{
- int len;
- char text[ 16 ];
- fileHandle_t f;
-
- // load the file
- len = trap_FS_FOpenFile( PTRC_FILE, &f, FS_READ );
- if( len <= 0 )
- return 0;
-
- // should never happen - malformed write
- if( len >= sizeof( text ) - 1 )
- return 0;
-
- trap_FS_Read( text, len, f );
- text[ len ] = 0;
- trap_FS_FCloseFile( f );
-
- return atoi( text );
-}
-
-/*
-===============
-CG_WritePTRCode
-
-Write a PTR code to disk
-===============
-*/
-void CG_WritePTRCode( int code )
-{
- char text[ 16 ];
- fileHandle_t f;
-
- Com_sprintf( text, 16, "%d", code );
-
- // open file
- if( trap_FS_FOpenFile( PTRC_FILE, &f, FS_WRITE ) < 0 )
- return;
-
- // write the code
- trap_FS_Write( text, strlen( text ), f );
-
- trap_FS_FCloseFile( f );
-}
diff --git a/src/cgame/cg_public.h b/src/cgame/cg_public.h
deleted file mode 100644
index 39d1a402..00000000
--- a/src/cgame/cg_public.h
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#define CMD_BACKUP 64
-#define CMD_MASK (CMD_BACKUP - 1)
-// allow a lot of command backups for very fast systems
-// multiple commands may be combined into a single packet, so this
-// needs to be larger than PACKET_BACKUP
-
-
-#define MAX_ENTITIES_IN_SNAPSHOT 256
-
-// snapshots are a view of the server at a given time
-
-// Snapshots are generated at regular time intervals by the server,
-// but they may not be sent if a client's rate level is exceeded, or
-// they may be dropped by the network.
-typedef struct
-{
- int snapFlags; // SNAPFLAG_RATE_DELAYED, etc
- int ping;
-
- int serverTime; // server time the message is valid for (in msec)
-
- byte areamask[ MAX_MAP_AREA_BYTES ]; // portalarea visibility bits
-
- playerState_t ps; // complete information about the current player at this time
-
- int numEntities; // all of the entities that need to be presented
- entityState_t entities[ MAX_ENTITIES_IN_SNAPSHOT ]; // at the time of this snapshot
-
- int numServerCommands; // text based server commands to execute when this
- int serverCommandSequence; // snapshot becomes current
-} snapshot_t;
-
-enum
-{
- CGAME_EVENT_NONE,
- CGAME_EVENT_TEAMMENU,
- CGAME_EVENT_SCOREBOARD,
- CGAME_EVENT_EDITHUD
-};
-
-/*
-==================================================================
-
-functions imported from the main executable
-
-==================================================================
-*/
-
-#define CGAME_IMPORT_API_VERSION 4
-
-typedef enum
-{
- CG_PRINT,
- CG_ERROR,
- CG_MILLISECONDS,
- CG_CVAR_REGISTER,
- CG_CVAR_UPDATE,
- CG_CVAR_SET,
- CG_CVAR_VARIABLESTRINGBUFFER,
- CG_ARGC,
- CG_ARGV,
- CG_ARGS,
- CG_FS_FOPENFILE,
- CG_FS_READ,
- CG_FS_WRITE,
- CG_FS_FCLOSEFILE,
- CG_SENDCONSOLECOMMAND,
- CG_ADDCOMMAND,
- CG_SENDCLIENTCOMMAND,
- CG_UPDATESCREEN,
- CG_CM_LOADMAP,
- CG_CM_NUMINLINEMODELS,
- CG_CM_INLINEMODEL,
- CG_CM_LOADMODEL,
- CG_CM_TEMPBOXMODEL,
- CG_CM_POINTCONTENTS,
- CG_CM_TRANSFORMEDPOINTCONTENTS,
- CG_CM_BOXTRACE,
- CG_CM_TRANSFORMEDBOXTRACE,
- CG_CM_MARKFRAGMENTS,
- CG_S_STARTSOUND,
- CG_S_STARTLOCALSOUND,
- CG_S_CLEARLOOPINGSOUNDS,
- CG_S_ADDLOOPINGSOUND,
- CG_S_UPDATEENTITYPOSITION,
- CG_S_RESPATIALIZE,
- CG_S_REGISTERSOUND,
- CG_S_STARTBACKGROUNDTRACK,
- CG_R_LOADWORLDMAP,
- CG_R_REGISTERMODEL,
- CG_R_REGISTERSKIN,
- CG_R_REGISTERSHADER,
- CG_R_CLEARSCENE,
- CG_R_ADDREFENTITYTOSCENE,
- CG_R_ADDPOLYTOSCENE,
- CG_R_ADDLIGHTTOSCENE,
- CG_R_RENDERSCENE,
- CG_R_SETCOLOR,
- CG_R_DRAWSTRETCHPIC,
- CG_R_MODELBOUNDS,
- CG_R_LERPTAG,
- CG_GETGLCONFIG,
- CG_GETGAMESTATE,
- CG_GETCURRENTSNAPSHOTNUMBER,
- CG_GETSNAPSHOT,
- CG_GETSERVERCOMMAND,
- CG_GETCURRENTCMDNUMBER,
- CG_GETUSERCMD,
- CG_SETUSERCMDVALUE,
- CG_R_REGISTERSHADERNOMIP,
- CG_MEMORY_REMAINING,
- CG_R_REGISTERFONT,
- CG_KEY_ISDOWN,
- CG_KEY_GETCATCHER,
- CG_KEY_SETCATCHER,
- CG_KEY_GETKEY,
- CG_PC_ADD_GLOBAL_DEFINE,
- CG_PC_LOAD_SOURCE,
- CG_PC_FREE_SOURCE,
- CG_PC_READ_TOKEN,
- CG_PC_SOURCE_FILE_AND_LINE,
- CG_S_STOPBACKGROUNDTRACK,
- CG_REAL_TIME,
- CG_SNAPVECTOR,
- CG_REMOVECOMMAND,
- CG_R_LIGHTFORPOINT,
- CG_CIN_PLAYCINEMATIC,
- CG_CIN_STOPCINEMATIC,
- CG_CIN_RUNCINEMATIC,
- CG_CIN_DRAWCINEMATIC,
- CG_CIN_SETEXTENTS,
- CG_R_REMAP_SHADER,
- CG_S_ADDREALLOOPINGSOUND,
- CG_S_STOPLOOPINGSOUND,
-
- CG_CM_TEMPCAPSULEMODEL,
- CG_CM_CAPSULETRACE,
- CG_CM_TRANSFORMEDCAPSULETRACE,
- CG_R_ADDADDITIVELIGHTTOSCENE,
- CG_GET_ENTITY_TOKEN,
- CG_R_ADDPOLYSTOSCENE,
- CG_R_INPVS,
- CG_FS_SEEK,
-
- CG_MEMSET = 100,
- CG_MEMCPY,
- CG_STRNCPY,
- CG_SIN,
- CG_COS,
- CG_ATAN2,
- CG_SQRT,
- CG_FLOOR,
- CG_CEIL,
-
- CG_TESTPRINTINT,
- CG_TESTPRINTFLOAT,
- CG_ACOS
-} cgameImport_t;
-
-
-/*
-==================================================================
-
-functions exported to the main executable
-
-==================================================================
-*/
-
-typedef enum
-{
- CG_INIT,
- // void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum )
- // called when the level loads or when the renderer is restarted
- // all media should be registered at this time
- // cgame will display loading status by calling SCR_Update, which
- // will call CG_DrawInformation during the loading process
- // reliableCommandSequence will be 0 on fresh loads, but higher for
- // demos, tourney restarts, or vid_restarts
-
- CG_SHUTDOWN,
- // void (*CG_Shutdown)( void );
- // oportunity to flush and close any open files
-
- CG_CONSOLE_COMMAND,
- // qboolean (*CG_ConsoleCommand)( void );
- // a console command has been issued locally that is not recognized by the
- // main game system.
- // use Cmd_Argc() / Cmd_Argv() to read the command, return qfalse if the
- // command is not known to the game
-
- CG_DRAW_ACTIVE_FRAME,
- // void (*CG_DrawActiveFrame)( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback );
- // Generates and draws a game scene and status information at the given time.
- // If demoPlayback is set, local movement prediction will not be enabled
-
- CG_CROSSHAIR_PLAYER,
- // int (*CG_CrosshairPlayer)( void );
-
- CG_LAST_ATTACKER,
- // int (*CG_LastAttacker)( void );
-
- CG_KEY_EVENT,
- // void (*CG_KeyEvent)( int key, qboolean down );
-
- CG_MOUSE_EVENT,
- // void (*CG_MouseEvent)( int dx, int dy );
- CG_EVENT_HANDLING
- // void (*CG_EventHandling)(int type);
-} cgameExport_t;
-
-//----------------------------------------------
diff --git a/src/cgame/cg_scanner.c b/src/cgame/cg_scanner.c
deleted file mode 100644
index 6c2a9997..00000000
--- a/src/cgame/cg_scanner.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-static entityPos_t entityPositions;
-
-#define HUMAN_SCANNER_UPDATE_PERIOD 700
-
-/*
-=============
-CG_UpdateEntityPositions
-
-Update this client's perception of entity positions
-=============
-*/
-void CG_UpdateEntityPositions( void )
-{
- centity_t *cent = NULL;
- int i;
-
- if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS )
- {
- if( entityPositions.lastUpdateTime + HUMAN_SCANNER_UPDATE_PERIOD > cg.time )
- return;
- }
-
- VectorCopy( cg.refdef.vieworg, entityPositions.origin );
- VectorCopy( cg.refdefViewAngles, entityPositions.vangles );
- entityPositions.lastUpdateTime = cg.time;
-
- entityPositions.numAlienBuildables = 0;
- entityPositions.numHumanBuildables = 0;
- entityPositions.numAlienClients = 0;
- entityPositions.numHumanClients = 0;
-
- for( i = 0; i < cg.snap->numEntities; i++ )
- {
- cent = &cg_entities[ cg.snap->entities[ i ].number ];
-
- if( cent->currentState.eType == ET_BUILDABLE )
- {
- //TA: add to list of item positions (for creep)
- if( cent->currentState.modelindex2 == BIT_ALIENS )
- {
- VectorCopy( cent->lerpOrigin, entityPositions.alienBuildablePos[
- entityPositions.numAlienBuildables ] );
- entityPositions.alienBuildableTimes[
- entityPositions.numAlienBuildables ] = cent->miscTime;
-
- if( entityPositions.numAlienBuildables < MAX_GENTITIES )
- entityPositions.numAlienBuildables++;
- }
- else if( cent->currentState.modelindex2 == BIT_HUMANS )
- {
- VectorCopy( cent->lerpOrigin, entityPositions.humanBuildablePos[
- entityPositions.numHumanBuildables ] );
-
- if( entityPositions.numHumanBuildables < MAX_GENTITIES )
- entityPositions.numHumanBuildables++;
- }
- }
- else if( cent->currentState.eType == ET_PLAYER )
- {
- int team = cent->currentState.powerups & 0x00FF;
-
- if( team == PTE_ALIENS )
- {
- VectorCopy( cent->lerpOrigin, entityPositions.alienClientPos[
- entityPositions.numAlienClients ] );
-
- if( entityPositions.numAlienClients < MAX_CLIENTS )
- entityPositions.numAlienClients++;
- }
- else if( team == PTE_HUMANS )
- {
- VectorCopy( cent->lerpOrigin, entityPositions.humanClientPos[
- entityPositions.numHumanClients ] );
-
- if( entityPositions.numHumanClients < MAX_CLIENTS )
- entityPositions.numHumanClients++;
- }
- }
- }
-}
-
-#define STALKWIDTH 2.0f
-#define BLIPX 16.0f
-#define BLIPY 8.0f
-#define FAR_ALPHA 0.8f
-#define NEAR_ALPHA 1.2f
-
-/*
-=============
-CG_DrawBlips
-
-Draw blips and stalks for the human scanner
-=============
-*/
-static void CG_DrawBlips( rectDef_t *rect, vec3_t origin, vec4_t colour )
-{
- vec3_t drawOrigin;
- vec3_t up = { 0, 0, 1 };
- float alphaMod = 1.0f;
- float timeFractionSinceRefresh = 1.0f -
- ( (float)( cg.time - entityPositions.lastUpdateTime ) /
- (float)HUMAN_SCANNER_UPDATE_PERIOD );
- vec4_t localColour;
-
- Vector4Copy( colour, localColour );
-
- RotatePointAroundVector( drawOrigin, up, origin, -entityPositions.vangles[ 1 ] - 90 );
- drawOrigin[ 0 ] /= ( 2 * HELMET_RANGE / rect->w );
- drawOrigin[ 1 ] /= ( 2 * HELMET_RANGE / rect->h );
- drawOrigin[ 2 ] /= ( 2 * HELMET_RANGE / rect->w );
-
- alphaMod = FAR_ALPHA +
- ( ( drawOrigin[ 1 ] + ( rect->h / 2.0f ) ) / rect->h ) * ( NEAR_ALPHA - FAR_ALPHA );
-
- localColour[ 3 ] *= alphaMod;
- localColour[ 3 ] *= ( 0.5f + ( timeFractionSinceRefresh * 0.5f ) );
-
- if( localColour[ 3 ] > 1.0f )
- localColour[ 3 ] = 1.0f;
- else if( localColour[ 3 ] < 0.0f )
- localColour[ 3 ] = 0.0f;
-
- trap_R_SetColor( localColour );
-
- if( drawOrigin[ 2 ] > 0 )
- CG_DrawPic( rect->x + ( rect->w / 2 ) - ( STALKWIDTH / 2 ) - drawOrigin[ 0 ],
- rect->y + ( rect->h / 2 ) + drawOrigin[ 1 ] - drawOrigin[ 2 ],
- STALKWIDTH, drawOrigin[ 2 ], cgs.media.scannerLineShader );
- else
- CG_DrawPic( rect->x + ( rect->w / 2 ) - ( STALKWIDTH / 2 ) - drawOrigin[ 0 ],
- rect->y + ( rect->h / 2 ) + drawOrigin[ 1 ],
- STALKWIDTH, -drawOrigin[ 2 ], cgs.media.scannerLineShader );
-
- CG_DrawPic( rect->x + ( rect->w / 2 ) - ( BLIPX / 2 ) - drawOrigin[ 0 ],
- rect->y + ( rect->h / 2 ) - ( BLIPY / 2 ) + drawOrigin[ 1 ] - drawOrigin[ 2 ],
- BLIPX, BLIPY, cgs.media.scannerBlipShader );
- trap_R_SetColor( NULL );
-}
-
-#define BLIPX2 24.0f
-#define BLIPY2 24.0f
-
-/*
-=============
-CG_DrawDir
-
-Draw dot marking the direction to an enemy
-=============
-*/
-static void CG_DrawDir( rectDef_t *rect, vec3_t origin, vec4_t colour )
-{
- vec3_t drawOrigin;
- vec3_t noZOrigin;
- vec3_t normal, antinormal, normalDiff;
- vec3_t view, noZview;
- vec3_t up = { 0.0f, 0.0f, 1.0f };
- vec3_t top = { 0.0f, -1.0f, 0.0f };
- float angle;
- playerState_t *ps = &cg.snap->ps;
-
- if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING )
- {
- if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING )
- VectorSet( normal, 0.0f, 0.0f, -1.0f );
- else
- VectorCopy( ps->grapplePoint, normal );
- }
- else
- VectorSet( normal, 0.0f, 0.0f, 1.0f );
-
- AngleVectors( entityPositions.vangles, view, NULL, NULL );
-
- ProjectPointOnPlane( noZOrigin, origin, normal );
- ProjectPointOnPlane( noZview, view, normal );
- VectorNormalize( noZOrigin );
- VectorNormalize( noZview );
-
- //calculate the angle between the images of the blip and the view
- angle = RAD2DEG( acos( DotProduct( noZOrigin, noZview ) ) );
- CrossProduct( noZOrigin, noZview, antinormal );
- VectorNormalize( antinormal );
-
- //decide which way to rotate
- VectorSubtract( normal, antinormal, normalDiff );
- if( VectorLength( normalDiff ) < 1.0f )
- angle = 360.0f - angle;
-
- RotatePointAroundVector( drawOrigin, up, top, angle );
-
- trap_R_SetColor( colour );
- CG_DrawPic( rect->x + ( rect->w / 2 ) - ( BLIPX2 / 2 ) - drawOrigin[ 0 ] * ( rect->w / 2 ),
- rect->y + ( rect->h / 2 ) - ( BLIPY2 / 2 ) + drawOrigin[ 1 ] * ( rect->h / 2 ),
- BLIPX2, BLIPY2, cgs.media.scannerBlipShader );
- trap_R_SetColor( NULL );
-}
-
-/*
-=============
-CG_AlienSense
-=============
-*/
-void CG_AlienSense( rectDef_t *rect )
-{
- int i;
- vec3_t origin;
- vec3_t relOrigin;
- vec4_t buildable = { 1.0f, 0.0f, 0.0f, 0.7f };
- vec4_t client = { 0.0f, 0.0f, 1.0f, 0.7f };
-
- VectorCopy( entityPositions.origin, origin );
-
- //draw human buildables
- for( i = 0; i < entityPositions.numHumanBuildables; i++ )
- {
- VectorClear( relOrigin );
- VectorSubtract( entityPositions.humanBuildablePos[ i ], origin, relOrigin );
-
- if( VectorLength( relOrigin ) < ALIENSENSE_RANGE )
- CG_DrawDir( rect, relOrigin, buildable );
- }
-
- //draw human clients
- for( i = 0; i < entityPositions.numHumanClients; i++ )
- {
- VectorClear( relOrigin );
- VectorSubtract( entityPositions.humanClientPos[ i ], origin, relOrigin );
-
- if( VectorLength( relOrigin ) < ALIENSENSE_RANGE )
- CG_DrawDir( rect, relOrigin, client );
- }
-}
-
-/*
-=============
-CG_Scanner
-=============
-*/
-void CG_Scanner( rectDef_t *rect, qhandle_t shader, vec4_t color )
-{
- int i;
- vec3_t origin;
- vec3_t relOrigin;
- vec4_t hIabove;
- vec4_t hIbelow;
- vec4_t aIabove = { 1.0f, 0.0f, 0.0f, 0.75f };
- vec4_t aIbelow = { 1.0f, 0.0f, 0.0f, 0.5f };
-
- Vector4Copy( color, hIabove );
- hIabove[ 3 ] *= 1.5f;
- Vector4Copy( color, hIbelow );
-
- VectorCopy( entityPositions.origin, origin );
-
- //draw human buildables below scanner plane
- for( i = 0; i < entityPositions.numHumanBuildables; i++ )
- {
- VectorClear( relOrigin );
- VectorSubtract( entityPositions.humanBuildablePos[ i ], origin, relOrigin );
-
- if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] < 0 ) )
- CG_DrawBlips( rect, relOrigin, hIbelow );
- }
-
- //draw alien buildables below scanner plane
- for( i = 0; i < entityPositions.numAlienBuildables; i++ )
- {
- VectorClear( relOrigin );
- VectorSubtract( entityPositions.alienBuildablePos[ i ], origin, relOrigin );
-
- if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] < 0 ) )
- CG_DrawBlips( rect, relOrigin, aIbelow );
- }
-
- //draw human clients below scanner plane
- for( i = 0; i < entityPositions.numHumanClients; i++ )
- {
- VectorClear( relOrigin );
- VectorSubtract( entityPositions.humanClientPos[ i ], origin, relOrigin );
-
- if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] < 0 ) )
- CG_DrawBlips( rect, relOrigin, hIbelow );
- }
-
- //draw alien buildables below scanner plane
- for( i = 0; i < entityPositions.numAlienClients; i++ )
- {
- VectorClear( relOrigin );
- VectorSubtract( entityPositions.alienClientPos[ i ], origin, relOrigin );
-
- if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] < 0 ) )
- CG_DrawBlips( rect, relOrigin, aIbelow );
- }
-
- if( !cg_disableScannerPlane.integer )
- {
- trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
- trap_R_SetColor( NULL );
- }
-
- //draw human buildables above scanner plane
- for( i = 0; i < entityPositions.numHumanBuildables; i++ )
- {
- VectorClear( relOrigin );
- VectorSubtract( entityPositions.humanBuildablePos[ i ], origin, relOrigin );
-
- if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] > 0 ) )
- CG_DrawBlips( rect, relOrigin, hIabove );
- }
-
- //draw alien buildables above scanner plane
- for( i = 0; i < entityPositions.numAlienBuildables; i++ )
- {
- VectorClear( relOrigin );
- VectorSubtract( entityPositions.alienBuildablePos[ i ], origin, relOrigin );
-
- if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] > 0 ) )
- CG_DrawBlips( rect, relOrigin, aIabove );
- }
-
- //draw human clients above scanner plane
- for( i = 0; i < entityPositions.numHumanClients; i++ )
- {
- VectorClear( relOrigin );
- VectorSubtract( entityPositions.humanClientPos[ i ], origin, relOrigin );
-
- if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] > 0 ) )
- CG_DrawBlips( rect, relOrigin, hIabove );
- }
-
- //draw alien clients above scanner plane
- for( i = 0; i < entityPositions.numAlienClients; i++ )
- {
- VectorClear( relOrigin );
- VectorSubtract( entityPositions.alienClientPos[ i ], origin, relOrigin );
-
- if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] > 0 ) )
- CG_DrawBlips( rect, relOrigin, aIabove );
- }
-}
diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c
deleted file mode 100644
index 71fbaac9..00000000
--- a/src/cgame/cg_servercmds.c
+++ /dev/null
@@ -1,1130 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_servercmds.c -- reliably sequenced text commands sent by the server
-// these are processed at snapshot transition time, so there will definately
-// be a valid snapshot this frame
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-/*
-=================
-CG_ParseScores
-
-=================
-*/
-static void CG_ParseScores( void )
-{
- int i;
-
- cg.numScores = atoi( CG_Argv( 1 ) );
-
- if( cg.numScores > MAX_CLIENTS )
- cg.numScores = MAX_CLIENTS;
-
- cg.teamScores[ 0 ] = atoi( CG_Argv( 2 ) );
- cg.teamScores[ 1 ] = atoi( CG_Argv( 3 ) );
-
- memset( cg.scores, 0, sizeof( cg.scores ) );
-
- if( cg_debugRandom.integer )
- CG_Printf( "cg.numScores: %d\n", cg.numScores );
-
- for( i = 0; i < cg.numScores; i++ )
- {
- //
- cg.scores[ i ].client = atoi( CG_Argv( i * 6 + 4 ) );
- cg.scores[ i ].score = atoi( CG_Argv( i * 6 + 5 ) );
- cg.scores[ i ].ping = atoi( CG_Argv( i * 6 + 6 ) );
- cg.scores[ i ].time = atoi( CG_Argv( i * 6 + 7 ) );
- cg.scores[ i ].weapon = atoi( CG_Argv( i * 6 + 8 ) );
- cg.scores[ i ].upgrade = atoi( CG_Argv( i * 6 + 9 ) );
-
- if( cg.scores[ i ].client < 0 || cg.scores[ i ].client >= MAX_CLIENTS )
- cg.scores[ i ].client = 0;
-
- cgs.clientinfo[ cg.scores[ i ].client ].score = cg.scores[ i ].score;
- cgs.clientinfo[ cg.scores[ i ].client ].powerups = 0;
-
- cg.scores[ i ].team = cgs.clientinfo[ cg.scores[ i ].client ].team;
- }
-}
-
-/*
-=================
-CG_ParseTeamInfo
-
-=================
-*/
-static void CG_ParseTeamInfo( void )
-{
- int i;
- int client;
-
- numSortedTeamPlayers = atoi( CG_Argv( 1 ) );
-
- for( i = 0; i < numSortedTeamPlayers; i++ )
- {
- client = atoi( CG_Argv( i * 6 + 2 ) );
-
- sortedTeamPlayers[ i ] = client;
-
- cgs.clientinfo[ client ].location = atoi( CG_Argv( i * 6 + 3 ) );
- cgs.clientinfo[ client ].health = atoi( CG_Argv( i * 6 + 4 ) );
- cgs.clientinfo[ client ].armor = atoi( CG_Argv( i * 6 + 5 ) );
- cgs.clientinfo[ client ].curWeapon = atoi( CG_Argv( i * 6 + 6 ) );
- cgs.clientinfo[ client ].powerups = atoi( CG_Argv( i * 6 + 7 ) );
- }
-}
-
-
-/*
-================
-CG_ParseServerinfo
-
-This is called explicitly when the gamestate is first received,
-and whenever the server updates any serverinfo flagged cvars
-================
-*/
-void CG_ParseServerinfo( void )
-{
- const char *info;
- char *mapname;
-
- info = CG_ConfigString( CS_SERVERINFO );
- cgs.dmflags = atoi( Info_ValueForKey( info, "dmflags" ) );
- cgs.teamflags = atoi( Info_ValueForKey( info, "teamflags" ) );
- cgs.timelimit = atoi( Info_ValueForKey( info, "timelimit" ) );
- cgs.maxclients = atoi( Info_ValueForKey( info, "sv_maxclients" ) );
- mapname = Info_ValueForKey( info, "mapname" );
- Com_sprintf( cgs.mapname, sizeof( cgs.mapname ), "maps/%s.bsp", mapname );
-}
-
-/*
-==================
-CG_ParseWarmup
-==================
-*/
-static void CG_ParseWarmup( void )
-{
- const char *info;
- int warmup;
-
- info = CG_ConfigString( CS_WARMUP );
-
- warmup = atoi( info );
- cg.warmupCount = -1;
-
- if( warmup == 0 && cg.warmup )
- {
- }
-
- cg.warmup = warmup;
-}
-
-/*
-================
-CG_SetConfigValues
-
-Called on load to set the initial values from configure strings
-================
-*/
-void CG_SetConfigValues( void )
-{
- cgs.scores1 = atoi( CG_ConfigString( CS_SCORES1 ) );
- cgs.scores2 = atoi( CG_ConfigString( CS_SCORES2 ) );
-
- sscanf( CG_ConfigString( CS_BUILDPOINTS ),
- "%d %d %d %d %d", &cgs.alienBuildPoints,
- &cgs.alienBuildPointsTotal,
- &cgs.humanBuildPoints,
- &cgs.humanBuildPointsTotal,
- &cgs.humanBuildPointsPowered );
-
- sscanf( CG_ConfigString( CS_STAGES ), "%d %d %d %d %d %d", &cgs.alienStage, &cgs.humanStage,
- &cgs.alienKills, &cgs.humanKills, &cgs.alienNextStageThreshold, &cgs.humanNextStageThreshold );
- sscanf( CG_ConfigString( CS_SPAWNS ), "%d %d", &cgs.numAlienSpawns, &cgs.numHumanSpawns );
-
- cgs.levelStartTime = atoi( CG_ConfigString( CS_LEVEL_START_TIME ) );
- cg.warmup = atoi( CG_ConfigString( CS_WARMUP ) );
-}
-
-
-/*
-=====================
-CG_ShaderStateChanged
-=====================
-*/
-void CG_ShaderStateChanged( void )
-{
- char originalShader[ MAX_QPATH ];
- char newShader[ MAX_QPATH ];
- char timeOffset[ 16 ];
- const char *o;
- char *n, *t;
-
- o = CG_ConfigString( CS_SHADERSTATE );
-
- while( o && *o )
- {
- n = strstr( o, "=" );
-
- if( n && *n )
- {
- strncpy( originalShader, o, n - o );
- originalShader[ n - o ] = 0;
- n++;
- t = strstr( n, ":" );
-
- if( t && *t )
- {
- strncpy( newShader, n, t - n );
- newShader[ t - n ] = 0;
- }
- else
- break;
-
- t++;
- o = strstr( t, "@" );
-
- if( o )
- {
- strncpy( timeOffset, t, o - t );
- timeOffset[ o - t ] = 0;
- o++;
- trap_R_RemapShader( originalShader, newShader, timeOffset );
- }
- }
- else
- break;
- }
-}
-
-/*
-================
-CG_AnnounceAlienStageTransistion
-================
-*/
-static void CG_AnnounceAlienStageTransistion( stage_t from, stage_t to )
-{
- if( cg.predictedPlayerState.stats[ STAT_PTEAM ] != PTE_ALIENS )
- return;
-
- trap_S_StartLocalSound( cgs.media.alienStageTransition, CHAN_ANNOUNCER );
- CG_CenterPrint( "We have evolved!", 200, GIANTCHAR_WIDTH * 4 );
-}
-
-/*
-================
-CG_AnnounceHumanStageTransistion
-================
-*/
-static void CG_AnnounceHumanStageTransistion( stage_t from, stage_t to )
-{
- if( cg.predictedPlayerState.stats[ STAT_PTEAM ] != PTE_HUMANS )
- return;
-
- trap_S_StartLocalSound( cgs.media.humanStageTransition, CHAN_ANNOUNCER );
- CG_CenterPrint( "Reinforcements have arrived!", 200, GIANTCHAR_WIDTH * 4 );
-}
-
-/*
-================
-CG_ConfigStringModified
-
-================
-*/
-static void CG_ConfigStringModified( void )
-{
- const char *str;
- int num;
-
- num = atoi( CG_Argv( 1 ) );
-
- // get the gamestate from the client system, which will have the
- // new configstring already integrated
- trap_GetGameState( &cgs.gameState );
-
- // look up the individual string that was modified
- str = CG_ConfigString( num );
-
- // do something with it if necessary
- if( num == CS_MUSIC )
- CG_StartMusic( );
- else if( num == CS_SERVERINFO )
- CG_ParseServerinfo( );
- else if( num == CS_WARMUP )
- CG_ParseWarmup( );
- else if( num == CS_SCORES1 )
- cgs.scores1 = atoi( str );
- else if( num == CS_SCORES2 )
- cgs.scores2 = atoi( str );
- else if( num == CS_BUILDPOINTS )
- sscanf( str, "%d %d %d %d %d", &cgs.alienBuildPoints,
- &cgs.alienBuildPointsTotal,
- &cgs.humanBuildPoints,
- &cgs.humanBuildPointsTotal,
- &cgs.humanBuildPointsPowered );
- else if( num == CS_STAGES )
- {
- stage_t oldAlienStage = cgs.alienStage;
- stage_t oldHumanStage = cgs.humanStage;
-
- sscanf( str, "%d %d %d %d %d %d",
- &cgs.alienStage, &cgs.humanStage,
- &cgs.alienKills, &cgs.humanKills,
- &cgs.alienNextStageThreshold, &cgs.humanNextStageThreshold );
-
- if( cgs.alienStage != oldAlienStage )
- CG_AnnounceAlienStageTransistion( oldAlienStage, cgs.alienStage );
-
- if( cgs.humanStage != oldHumanStage )
- CG_AnnounceHumanStageTransistion( oldHumanStage, cgs.humanStage );
- }
- else if( num == CS_SPAWNS )
- sscanf( str, "%d %d", &cgs.numAlienSpawns, &cgs.numHumanSpawns );
- else if( num == CS_LEVEL_START_TIME )
- cgs.levelStartTime = atoi( str );
- else if( num == CS_VOTE_TIME )
- {
- cgs.voteTime = atoi( str );
- cgs.voteModified = qtrue;
-
- if( cgs.voteTime )
- trap_Cvar_Set( "ui_voteActive", "1" );
- else
- trap_Cvar_Set( "ui_voteActive", "0" );
- }
- else if( num == CS_VOTE_YES )
- {
- cgs.voteYes = atoi( str );
- cgs.voteModified = qtrue;
- }
- else if( num == CS_VOTE_NO )
- {
- cgs.voteNo = atoi( str );
- cgs.voteModified = qtrue;
- }
- else if( num == CS_VOTE_STRING )
- Q_strncpyz( cgs.voteString, str, sizeof( cgs.voteString ) );
- else if( num >= CS_TEAMVOTE_TIME && num <= CS_TEAMVOTE_TIME + 1 )
- {
- int cs_offset = num - CS_TEAMVOTE_TIME;
-
- cgs.teamVoteTime[ cs_offset ] = atoi( str );
- cgs.teamVoteModified[ cs_offset ] = qtrue;
-
- if( cs_offset == 0 )
- {
- if( cgs.teamVoteTime[ cs_offset ] )
- trap_Cvar_Set( "ui_humanTeamVoteActive", "1" );
- else
- trap_Cvar_Set( "ui_humanTeamVoteActive", "0" );
- }
- else if( cs_offset == 1 )
- {
- if( cgs.teamVoteTime[ cs_offset ] )
- trap_Cvar_Set( "ui_alienTeamVoteActive", "1" );
- else
- trap_Cvar_Set( "ui_alienTeamVoteActive", "0" );
- }
- }
- else if( num >= CS_TEAMVOTE_YES && num <= CS_TEAMVOTE_YES + 1 )
- {
- cgs.teamVoteYes[ num - CS_TEAMVOTE_YES ] = atoi( str );
- cgs.teamVoteModified[ num - CS_TEAMVOTE_YES ] = qtrue;
- }
- else if( num >= CS_TEAMVOTE_NO && num <= CS_TEAMVOTE_NO + 1 )
- {
- cgs.teamVoteNo[ num - CS_TEAMVOTE_NO ] = atoi( str );
- cgs.teamVoteModified[ num - CS_TEAMVOTE_NO ] = qtrue;
- }
- else if( num >= CS_TEAMVOTE_STRING && num <= CS_TEAMVOTE_STRING + 1 )
- Q_strncpyz( cgs.teamVoteString[ num - CS_TEAMVOTE_STRING ], str, sizeof( cgs.teamVoteString ) );
- else if( num == CS_INTERMISSION )
- cg.intermissionStarted = atoi( str );
- else if( num >= CS_MODELS && num < CS_MODELS+MAX_MODELS )
- cgs.gameModels[ num - CS_MODELS ] = trap_R_RegisterModel( str );
- else if( num >= CS_SHADERS && num < CS_SHADERS+MAX_SHADERS )
- cgs.gameShaders[ num - CS_SHADERS ] = trap_R_RegisterShader( str );
- else if( num >= CS_PARTICLE_SYSTEMS && num < CS_PARTICLE_SYSTEMS+MAX_GAME_PARTICLE_SYSTEMS )
- cgs.gameParticleSystems[ num - CS_PARTICLE_SYSTEMS ] = CG_RegisterParticleSystem( (char *)str );
- else if( num >= CS_SOUNDS && num < CS_SOUNDS+MAX_SOUNDS )
- {
- if( str[ 0 ] != '*' )
- { // player specific sounds don't register here
- cgs.gameSounds[ num - CS_SOUNDS ] = trap_S_RegisterSound( str, qfalse );
- }
- }
- else if( num >= CS_PLAYERS && num < CS_PLAYERS+MAX_CLIENTS )
- {
- CG_NewClientInfo( num - CS_PLAYERS );
- CG_BuildSpectatorString( );
- }
- else if( num == CS_FLAGSTATUS )
- {
- }
- else if( num == CS_SHADERSTATE )
- {
- CG_ShaderStateChanged( );
- }
-}
-
-
-/*
-=======================
-CG_AddToTeamChat
-
-=======================
-*/
-static void CG_AddToTeamChat( const char *str )
-{
- int len;
- char *p, *ls;
- int lastcolor;
- int chatHeight;
-
- if( cg_teamChatHeight.integer < TEAMCHAT_HEIGHT )
- chatHeight = cg_teamChatHeight.integer;
- else
- chatHeight = TEAMCHAT_HEIGHT;
-
- if( chatHeight <= 0 || cg_teamChatTime.integer <= 0 )
- {
- // team chat disabled, dump into normal chat
- cgs.teamChatPos = cgs.teamLastChatPos = 0;
- return;
- }
-
- len = 0;
-
- p = cgs.teamChatMsgs[cgs.teamChatPos % chatHeight];
- *p = 0;
-
- lastcolor = '7';
-
- ls = NULL;
- while( *str )
- {
- if( len > TEAMCHAT_WIDTH - 1 )
- {
- if( ls )
- {
- str -= ( p - ls );
- str++;
- p -= ( p - ls );
- }
-
- *p = 0;
-
- cgs.teamChatMsgTimes[ cgs.teamChatPos % chatHeight ] = cg.time;
-
- cgs.teamChatPos++;
- p = cgs.teamChatMsgs[ cgs.teamChatPos % chatHeight ];
- *p = 0;
- *p++ = Q_COLOR_ESCAPE;
- *p++ = lastcolor;
- len = 0;
- ls = NULL;
- }
-
- if( Q_IsColorString( str ) )
- {
- *p++ = *str++;
- lastcolor = *str;
- *p++ = *str++;
- continue;
- }
-
- if( *str == ' ' )
- ls = p;
-
- *p++ = *str++;
- len++;
- }
- *p = 0;
-
- cgs.teamChatMsgTimes[ cgs.teamChatPos % chatHeight ] = cg.time;
- cgs.teamChatPos++;
-
- if( cgs.teamChatPos - cgs.teamLastChatPos > chatHeight )
- cgs.teamLastChatPos = cgs.teamChatPos - chatHeight;
-}
-
-
-
-/*
-===============
-CG_MapRestart
-
-The server has issued a map_restart, so the next snapshot
-is completely new and should not be interpolated to.
-
-A tournement restart will clear everything, but doesn't
-require a reload of all the media
-===============
-*/
-static void CG_MapRestart( void )
-{
- if( cg_showmiss.integer )
- CG_Printf( "CG_MapRestart\n" );
-
- CG_InitMarkPolys( );
-
- // make sure the "3 frags left" warnings play again
- cg.fraglimitWarnings = 0;
-
- cg.timelimitWarnings = 0;
-
- cg.intermissionStarted = qfalse;
-
- cgs.voteTime = 0;
-
- cg.mapRestart = qtrue;
-
- CG_StartMusic( );
-
- trap_S_ClearLoopingSounds( qtrue );
-
- // we really should clear more parts of cg here and stop sounds
-
- // play the "fight" sound if this is a restart without warmup
- if( cg.warmup == 0 )
- CG_CenterPrint( "FIGHT!", 120, GIANTCHAR_WIDTH * 2 );
-
- trap_Cvar_Set( "cg_thirdPerson", "0" );
-}
-
-/*
-=================
-CG_RemoveChatEscapeChar
-=================
-*/
-static void CG_RemoveChatEscapeChar( char *text )
-{
- int i, l;
-
- l = 0;
- for( i = 0; text[ i ]; i++ )
- {
- if( text[ i ] == '\x19' )
- continue;
-
- text[ l++ ] = text[ i ];
- }
-
- text[ l ] = '\0';
-}
-
-/*
-===============
-CG_SetUIVars
-
-Set some cvars used by the UI
-===============
-*/
-static void CG_SetUIVars( void )
-{
- int i;
- char carriageCvar[ MAX_TOKEN_CHARS ];
-
- *carriageCvar = 0;
-
- //determine what the player is carrying
- for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
- {
- if( BG_InventoryContainsWeapon( i, cg.snap->ps.stats ) &&
- BG_FindPurchasableForWeapon( i ) )
- strcat( carriageCvar, va( "W%d ", i ) );
- }
- for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
- {
- if( BG_InventoryContainsUpgrade( i, cg.snap->ps.stats ) &&
- BG_FindPurchasableForUpgrade( i ) )
- strcat( carriageCvar, va( "U%d ", i ) );
- }
- strcat( carriageCvar, "$" );
-
- trap_Cvar_Set( "ui_carriage", carriageCvar );
-
- trap_Cvar_Set( "ui_stages", va( "%d %d", cgs.alienStage, cgs.humanStage ) );
-}
-
-
-/*
-==============
-CG_Menu
-==============
-*/
-void CG_Menu( int menu )
-{
- CG_SetUIVars( );
-
- switch( menu )
- {
- case MN_TEAM: trap_SendConsoleCommand( "menu tremulous_teamselect\n" ); break;
- case MN_A_CLASS: trap_SendConsoleCommand( "menu tremulous_alienclass\n" ); break;
- case MN_H_SPAWN: trap_SendConsoleCommand( "menu tremulous_humanitem\n" ); break;
- case MN_A_BUILD: trap_SendConsoleCommand( "menu tremulous_alienbuild\n" ); break;
- case MN_H_BUILD: trap_SendConsoleCommand( "menu tremulous_humanbuild\n" ); break;
- case MN_H_ARMOURY: trap_SendConsoleCommand( "menu tremulous_humanarmoury\n" ); break;
-
- case MN_A_TEAMFULL:
- trap_Cvar_Set( "ui_dialog", "The alien team has too many players. Please wait until "
- "slots become available or join the human team." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- break;
-
- case MN_H_TEAMFULL:
- trap_Cvar_Set( "ui_dialog", "The human team has too many players. Please wait until "
- "slots become available or join the alien team." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- break;
-
- case MN_H_NOROOM:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "There is no room to build here. Move until the buildable turns "
- "translucent green indicating a valid build location." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- }
- else
- CG_Printf( "There is no room to build here\n" );
-
- break;
-
- case MN_H_NOPOWER:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "There is no power remaining. Free up power by destroying existing "
- "buildable objects." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- }
- else
- CG_Printf( "There is no power remaining\n" );
-
- break;
-
- case MN_H_NOTPOWERED:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "This buildable is not powered. Build a Reactor and/or Repeater in "
- "order to power it." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- }
- else
- CG_Printf( "This buildable is not powered\n" );
-
- break;
-
- case MN_H_NORMAL:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "Cannot build on this surface. The surface is too steep or unsuitable "
- "to build on. Please choose another site for this structure." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- }
- else
- CG_Printf( "Cannot build on this surface\n" );
-
- break;
-
- case MN_H_REACTOR:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "There can only be one Reactor. Destroy the existing one if you "
- "wish to move it." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- }
- else
- CG_Printf( "There can only be one Reactor\n" );
-
- break;
-
- case MN_H_REPEATER:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "There is no power here. If available, a Repeater may be used to "
- "transmit power to this location." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- }
- else
- CG_Printf( "There is no power here\n" );
-
- break;
-
- case MN_H_NODCC:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "There is no Defense Computer. A Defense Computer is needed to build "
- "this." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- }
- else
- CG_Printf( "There is no Defense Computer\n" );
-
- break;
-
- case MN_H_TNODEWARN:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "WARNING: This Telenode will not be powered. Build near a power "
- "structure to prevent seeing this message again." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- }
- else
- CG_Printf( "This Telenode will not be powered\n" );
-
- break;
-
- case MN_H_RPTWARN:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "WARNING: This Repeater will not be powered as there is no parent "
- "Reactor providing power. Build a Reactor." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- }
- else
- CG_Printf( "This Repeater will not be powered\n" );
-
- break;
-
- case MN_H_RPTWARN2:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "This area already has power. A Repeater is not required here." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- }
- else
- CG_Printf( "This area already has power\n" );
-
- break;
-
- case MN_H_NOSLOTS:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "You have no room to carry this. Please sell any conflicting "
- "upgrades before purchasing this item." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- }
- else
- CG_Printf( "You have no room to carry this\n" );
-
- break;
-
- case MN_H_NOFUNDS:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "Insufficient funds. You do not have enough credits to perform this "
- "action." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- }
- else
- CG_Printf( "Insufficient funds\n" );
-
- break;
-
- case MN_H_ITEMHELD:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "You already hold this item. It is not possible to carry multiple items "
- "of the same type." );
- trap_SendConsoleCommand( "menu tremulous_human_dialog\n" );
- }
- else
- CG_Printf( "You already hold this item\n" );
-
- break;
-
-
- //===============================
-
-
- case MN_A_NOROOM:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "There is no room to build here. Move until the structure turns "
- "translucent green indicating a valid build location." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "There is no room to build here\n" );
-
- break;
-
- case MN_A_NOCREEP:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "There is no creep here. You must build near existing Eggs or "
- "the Overmind. Alien structures will not support themselves." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "There is no creep here\n" );
-
- break;
-
- case MN_A_NOOVMND:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "There is no Overmind. An Overmind must be built to control "
- "the structure you tried to place" );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "There is no Overmind\n" );
-
- break;
-
- case MN_A_OVERMIND:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "There can only be one Overmind. Destroy the existing one if you "
- "wish to move it." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "There can only be one Overmind\n" );
-
- break;
-
- case MN_A_HOVEL:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "There can only be one Hovel. Destroy the existing one if you "
- "wish to move it." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "There can only be one Hovel\n" );
-
- break;
-
- case MN_A_NOASSERT:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "The Overmind cannot control any more structures. Destroy existing "
- "structures to build more." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "The Overmind cannot control any more structures\n" );
-
- break;
-
- case MN_A_SPWNWARN:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "WARNING: This spawn will not be controlled by an Overmind. "
- "Build an Overmind to prevent seeing this message again." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "This spawn will not be controlled by an Overmind\n" );
-
- break;
-
- case MN_A_NORMAL:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "Cannot build on this surface. This surface is too steep or unsuitable "
- "to build on. Please choose another site for this structure." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "Cannot build on this surface\n" );
-
- break;
-
- case MN_A_NOEROOM:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "There is no room to evolve here. Move away from walls or other "
- "nearby objects and try again." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "There is no room to evolve here\n" );
-
- break;
-
- case MN_A_TOOCLOSE:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "This location is too close to the enemy to evolve. "
- "Move away until you are no longer aware of the enemy's "
- "presence and try again." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "This location is too close to the enemy to evolve\n" );
-
- break;
-
- case MN_A_NOOVMND_EVOLVE:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "There is no Overmind. An Overmind must be built to allow "
- "you to upgrade." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "There is no Overmind\n" );
-
- break;
-
- case MN_A_HOVEL_OCCUPIED:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "This Hovel is occupied by another builder. Please find or build "
- "another." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "This Hovel is occupied by another builder\n" );
-
- break;
-
- case MN_A_HOVEL_BLOCKED:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "The exit to this Hovel is currently blocked. Please wait until it "
- "becomes clear then try again." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "The exit to this Hovel is currently blocked\n" );
-
- break;
-
- case MN_A_HOVEL_EXIT:
- if( !cg_disableWarningDialogs.integer )
- {
- trap_Cvar_Set( "ui_dialog", "The exit to this Hovel would always be blocked. Please choose "
- "a more suitable location." );
- trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" );
- }
- else
- CG_Printf( "The exit to this Hovel would always be blocked\n" );
-
- break;
-
- case MN_A_INFEST:
- trap_Cvar_Set( "ui_currentClass", va( "%d %d", cg.snap->ps.stats[ STAT_PCLASS ],
- cg.snap->ps.persistant[ PERS_CREDIT ] ) );
- trap_SendConsoleCommand( "menu tremulous_alienupgrade\n" );
- break;
-
- default:
- Com_Printf( "cgame: debug: no such menu %d\n", menu );
- }
-}
-
-/*
-=================
-CG_ServerCommand
-
-The string has been tokenized and can be retrieved with
-Cmd_Argc() / Cmd_Argv()
-=================
-*/
-static void CG_ServerCommand( void )
-{
- const char *cmd;
- char text[ MAX_SAY_TEXT ];
-
- cmd = CG_Argv( 0 );
-
- if( !cmd[ 0 ] )
- {
- // server claimed the command
- return;
- }
-
- if( !strcmp( cmd, "cp" ) )
- {
- CG_CenterPrint( CG_Argv( 1 ), SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH );
- return;
- }
-
- if( !strcmp( cmd, "cs" ) )
- {
- CG_ConfigStringModified( );
- return;
- }
-
- if( !strcmp( cmd, "print" ) )
- {
- CG_Printf( "%s", CG_Argv( 1 ) );
- return;
- }
-
- if( !strcmp( cmd, "chat" ) )
- {
- if( !cg_teamChatsOnly.integer )
- {
- trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
- Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT );
- CG_RemoveChatEscapeChar( text );
- CG_Printf( "%s\n", text );
- }
-
- return;
- }
-
- if( !strcmp( cmd, "tchat" ) )
- {
- trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
- Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT );
- CG_RemoveChatEscapeChar( text );
- CG_AddToTeamChat( text );
- CG_Printf( "%s\n", text );
- return;
- }
-
- if( !strcmp( cmd, "scores" ) )
- {
- CG_ParseScores( );
- return;
- }
-
- if( !strcmp( cmd, "tinfo" ) )
- {
- CG_ParseTeamInfo( );
- return;
- }
-
- if( !strcmp( cmd, "map_restart" ) )
- {
- CG_MapRestart( );
- return;
- }
-
- if( Q_stricmp( cmd, "remapShader" ) == 0 )
- {
- if( trap_Argc( ) == 4 )
- trap_R_RemapShader( CG_Argv( 1 ), CG_Argv( 2 ), CG_Argv( 3 ) );
- }
-
- // clientLevelShot is sent before taking a special screenshot for
- // the menu system during development
- if( !strcmp( cmd, "clientLevelShot" ) )
- {
- cg.levelShot = qtrue;
- return;
- }
-
- //enable G_Printfs from the server to appear in the TA console
- if( !strcmp( cmd, "gprintf" ) )
- {
- if( trap_Argc( ) == 2 )
- CG_TAUIConsole( CG_Argv( 1 ) );
-
- return;
- }
-
- //the server has triggered a menu
- if( !strcmp( cmd, "servermenu" ) )
- {
- if( trap_Argc( ) == 2 && !cg.demoPlayback )
- CG_Menu( atoi( CG_Argv( 1 ) ) );
-
- return;
- }
-
- //the server thinks this client should close all menus
- if( !strcmp( cmd, "serverclosemenus" ) )
- {
- trap_SendConsoleCommand( "closemenus\n" );
- return;
- }
-
- //poison cloud effect needs to be reliable
- if( !strcmp( cmd, "poisoncloud" ) )
- {
- cg.poisonedTime = cg.time;
-
- if( CG_IsParticleSystemValid( &cg.poisonCloudPS ) )
- {
- cg.poisonCloudPS = CG_SpawnNewParticleSystem( cgs.media.poisonCloudPS );
- CG_SetAttachmentCent( &cg.poisonCloudPS->attachment, &cg.predictedPlayerEntity );
- CG_AttachToCent( &cg.poisonCloudPS->attachment );
- }
-
- return;
- }
-
- if( !strcmp( cmd, "weaponswitch" ) )
- {
- CG_Printf( "client weaponswitch\n" );
- if( trap_Argc( ) == 2 )
- {
- cg.weaponSelect = atoi( CG_Argv( 1 ) );
- cg.weaponSelectTime = cg.time;
- }
-
- return;
- }
-
- // server requests a ptrc
- if( !strcmp( cmd, "ptrcrequest" ) )
- {
- int code = CG_ReadPTRCode( );
-
- trap_SendClientCommand( va( "ptrcverify %d", code ) );
- return;
- }
-
- // server issues a ptrc
- if( !strcmp( cmd, "ptrcissue" ) )
- {
- if( trap_Argc( ) == 2 )
- {
- int code = atoi( CG_Argv( 1 ) );
-
- CG_WritePTRCode( code );
- }
-
- return;
- }
-
- // reply to ptrcverify
- if( !strcmp( cmd, "ptrcconfirm" ) )
- {
- trap_SendConsoleCommand( "menu ptrc_popmenu\n" );
-
- return;
- }
-
- CG_Printf( "Unknown client game command: %s\n", cmd );
-}
-
-
-/*
-====================
-CG_ExecuteNewServerCommands
-
-Execute all of the server commands that were received along
-with this this snapshot.
-====================
-*/
-void CG_ExecuteNewServerCommands( int latestSequence )
-{
- while( cgs.serverCommandSequence < latestSequence )
- {
- if( trap_GetServerCommand( ++cgs.serverCommandSequence ) )
- CG_ServerCommand( );
- }
-}
diff --git a/src/cgame/cg_snapshot.c b/src/cgame/cg_snapshot.c
deleted file mode 100644
index 4a5722ae..00000000
--- a/src/cgame/cg_snapshot.c
+++ /dev/null
@@ -1,402 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_snapshot.c -- things that happen on snapshot transition,
-// not necessarily every single rendered frame
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-/*
-==================
-CG_ResetEntity
-==================
-*/
-static void CG_ResetEntity( centity_t *cent )
-{
- // if the previous snapshot this entity was updated in is at least
- // an event window back in time then we can reset the previous event
- if( cent->snapShotTime < cg.time - EVENT_VALID_MSEC )
- cent->previousEvent = 0;
-
- cent->trailTime = cg.snap->serverTime;
-
- VectorCopy( cent->currentState.origin, cent->lerpOrigin );
- VectorCopy( cent->currentState.angles, cent->lerpAngles );
-
- if( cent->currentState.eType == ET_PLAYER )
- CG_ResetPlayerEntity( cent );
-}
-
-/*
-===============
-CG_TransitionEntity
-
-cent->nextState is moved to cent->currentState and events are fired
-===============
-*/
-static void CG_TransitionEntity( centity_t *cent )
-{
- cent->currentState = cent->nextState;
- cent->currentValid = qtrue;
-
- // reset if the entity wasn't in the last frame or was teleported
- if( !cent->interpolate )
- CG_ResetEntity( cent );
-
- // clear the next state. if will be set by the next CG_SetNextSnap
- cent->interpolate = qfalse;
-
- // check for events
- CG_CheckEvents( cent );
-}
-
-
-/*
-==================
-CG_SetInitialSnapshot
-
-This will only happen on the very first snapshot, or
-on tourney restarts. All other times will use
-CG_TransitionSnapshot instead.
-
-FIXME: Also called by map_restart?
-==================
-*/
-void CG_SetInitialSnapshot( snapshot_t *snap )
-{
- int i;
- centity_t *cent;
- entityState_t *state;
-
- cg.snap = snap;
-
- BG_PlayerStateToEntityState( &snap->ps, &cg_entities[ snap->ps.clientNum ].currentState, qfalse );
-
- // sort out solid entities
- CG_BuildSolidList( );
-
- CG_ExecuteNewServerCommands( snap->serverCommandSequence );
-
- // set our local weapon selection pointer to
- // what the server has indicated the current weapon is
- CG_Respawn( );
-
- for( i = 0; i < cg.snap->numEntities; i++ )
- {
- state = &cg.snap->entities[ i ];
- cent = &cg_entities[ state->number ];
-
- memcpy( &cent->currentState, state, sizeof( entityState_t ) );
- //cent->currentState = *state;
- cent->interpolate = qfalse;
- cent->currentValid = qtrue;
-
- CG_ResetEntity( cent );
-
- // check for events
- CG_CheckEvents( cent );
- }
-}
-
-
-/*
-===================
-CG_TransitionSnapshot
-
-The transition point from snap to nextSnap has passed
-===================
-*/
-static void CG_TransitionSnapshot( void )
-{
- centity_t *cent;
- snapshot_t *oldFrame;
- int i;
-
- if( !cg.snap )
- CG_Error( "CG_TransitionSnapshot: NULL cg.snap" );
-
- if( !cg.nextSnap )
- CG_Error( "CG_TransitionSnapshot: NULL cg.nextSnap" );
-
- // execute any server string commands before transitioning entities
- CG_ExecuteNewServerCommands( cg.nextSnap->serverCommandSequence );
-
- // if we had a map_restart, set everthing with initial
- if( !cg.snap ) { } //TA: ?
-
- // clear the currentValid flag for all entities in the existing snapshot
- for( i = 0; i < cg.snap->numEntities; i++ )
- {
- cent = &cg_entities[ cg.snap->entities[ i ].number ];
- cent->currentValid = qfalse;
- }
-
- // move nextSnap to snap and do the transitions
- oldFrame = cg.snap;
- cg.snap = cg.nextSnap;
-
- BG_PlayerStateToEntityState( &cg.snap->ps, &cg_entities[ cg.snap->ps.clientNum ].currentState, qfalse );
- cg_entities[ cg.snap->ps.clientNum ].interpolate = qfalse;
-
- for( i = 0; i < cg.snap->numEntities; i++ )
- {
- cent = &cg_entities[ cg.snap->entities[ i ].number ];
- CG_TransitionEntity( cent );
-
- // remember time of snapshot this entity was last updated in
- cent->snapShotTime = cg.snap->serverTime;
- }
-
- cg.nextSnap = NULL;
-
- // check for playerstate transition events
- if( oldFrame )
- {
- playerState_t *ops, *ps;
-
- ops = &oldFrame->ps;
- ps = &cg.snap->ps;
- // teleporting checks are irrespective of prediction
- if( ( ps->eFlags ^ ops->eFlags ) & EF_TELEPORT_BIT )
- cg.thisFrameTeleport = qtrue; // will be cleared by prediction code
-
- // if we are not doing client side movement prediction for any
- // reason, then the client events and view changes will be issued now
- if( cg.demoPlayback || ( cg.snap->ps.pm_flags & PMF_FOLLOW ) ||
- cg_nopredict.integer || cg_synchronousClients.integer )
- CG_TransitionPlayerState( ps, ops );
- }
-}
-
-
-/*
-===================
-CG_SetNextSnap
-
-A new snapshot has just been read in from the client system.
-===================
-*/
-static void CG_SetNextSnap( snapshot_t *snap )
-{
- int num;
- entityState_t *es;
- centity_t *cent;
-
- cg.nextSnap = snap;
-
- BG_PlayerStateToEntityState( &snap->ps, &cg_entities[ snap->ps.clientNum ].nextState, qfalse );
- cg_entities[ cg.snap->ps.clientNum ].interpolate = qtrue;
-
- // check for extrapolation errors
- for( num = 0 ; num < snap->numEntities ; num++ )
- {
- es = &snap->entities[ num ];
- cent = &cg_entities[ es->number ];
-
- memcpy( &cent->nextState, es, sizeof( entityState_t ) );
- //cent->nextState = *es;
-
- // if this frame is a teleport, or the entity wasn't in the
- // previous frame, don't interpolate
- if( !cent->currentValid || ( ( cent->currentState.eFlags ^ es->eFlags ) & EF_TELEPORT_BIT ) )
- cent->interpolate = qfalse;
- else
- cent->interpolate = qtrue;
- }
-
- // if the next frame is a teleport for the playerstate, we
- // can't interpolate during demos
- if( cg.snap && ( ( snap->ps.eFlags ^ cg.snap->ps.eFlags ) & EF_TELEPORT_BIT ) )
- cg.nextFrameTeleport = qtrue;
- else
- cg.nextFrameTeleport = qfalse;
-
- // if changing follow mode, don't interpolate
- if( cg.nextSnap->ps.clientNum != cg.snap->ps.clientNum )
- cg.nextFrameTeleport = qtrue;
-
- // if changing server restarts, don't interpolate
- if( ( cg.nextSnap->snapFlags ^ cg.snap->snapFlags ) & SNAPFLAG_SERVERCOUNT )
- cg.nextFrameTeleport = qtrue;
-
- // sort out solid entities
- CG_BuildSolidList( );
-}
-
-
-/*
-========================
-CG_ReadNextSnapshot
-
-This is the only place new snapshots are requested
-This may increment cgs.processedSnapshotNum multiple
-times if the client system fails to return a
-valid snapshot.
-========================
-*/
-static snapshot_t *CG_ReadNextSnapshot( void )
-{
- qboolean r;
- snapshot_t *dest;
-
- if( cg.latestSnapshotNum > cgs.processedSnapshotNum + 1000 )
- {
- CG_Printf( "WARNING: CG_ReadNextSnapshot: way out of range, %i > %i",
- cg.latestSnapshotNum, cgs.processedSnapshotNum );
- }
-
- while( cgs.processedSnapshotNum < cg.latestSnapshotNum )
- {
- // decide which of the two slots to load it into
- if( cg.snap == &cg.activeSnapshots[ 0 ] )
- dest = &cg.activeSnapshots[ 1 ];
- else
- dest = &cg.activeSnapshots[ 0 ];
-
- // try to read the snapshot from the client system
- cgs.processedSnapshotNum++;
- r = trap_GetSnapshot( cgs.processedSnapshotNum, dest );
-
- // FIXME: why would trap_GetSnapshot return a snapshot with the same server time
- if( cg.snap && r && dest->serverTime == cg.snap->serverTime )
- {
- //continue;
- }
-
- // if it succeeded, return
- if( r )
- {
- CG_AddLagometerSnapshotInfo( dest );
- return dest;
- }
-
- // a GetSnapshot will return failure if the snapshot
- // never arrived, or is so old that its entities
- // have been shoved off the end of the circular
- // buffer in the client system.
-
- // record as a dropped packet
- CG_AddLagometerSnapshotInfo( NULL );
-
- // If there are additional snapshots, continue trying to
- // read them.
- }
-
- // nothing left to read
- return NULL;
-}
-
-
-/*
-============
-CG_ProcessSnapshots
-
-We are trying to set up a renderable view, so determine
-what the simulated time is, and try to get snapshots
-both before and after that time if available.
-
-If we don't have a valid cg.snap after exiting this function,
-then a 3D game view cannot be rendered. This should only happen
-right after the initial connection. After cg.snap has been valid
-once, it will never turn invalid.
-
-Even if cg.snap is valid, cg.nextSnap may not be, if the snapshot
-hasn't arrived yet (it becomes an extrapolating situation instead
-of an interpolating one)
-
-============
-*/
-void CG_ProcessSnapshots( void )
-{
- snapshot_t *snap;
- int n;
-
- // see what the latest snapshot the client system has is
- trap_GetCurrentSnapshotNumber( &n, &cg.latestSnapshotTime );
-
- if( n != cg.latestSnapshotNum )
- {
- if( n < cg.latestSnapshotNum )
- {
- // this should never happen
- CG_Error( "CG_ProcessSnapshots: n < cg.latestSnapshotNum" );
- }
-
- cg.latestSnapshotNum = n;
- }
-
- // If we have yet to receive a snapshot, check for it.
- // Once we have gotten the first snapshot, cg.snap will
- // always have valid data for the rest of the game
- while( !cg.snap )
- {
- snap = CG_ReadNextSnapshot( );
-
- if( !snap )
- {
- // we can't continue until we get a snapshot
- return;
- }
-
- // set our weapon selection to what
- // the playerstate is currently using
- if( !( snap->snapFlags & SNAPFLAG_NOT_ACTIVE ) )
- CG_SetInitialSnapshot( snap );
- }
-
- // loop until we either have a valid nextSnap with a serverTime
- // greater than cg.time to interpolate towards, or we run
- // out of available snapshots
- do
- {
- // if we don't have a nextframe, try and read a new one in
- if( !cg.nextSnap )
- {
- snap = CG_ReadNextSnapshot( );
-
- // if we still don't have a nextframe, we will just have to
- // extrapolate
- if( !snap )
- break;
-
- CG_SetNextSnap( snap );
-
- // if time went backwards, we have a level restart
- if( cg.nextSnap->serverTime < cg.snap->serverTime )
- CG_Error( "CG_ProcessSnapshots: Server time went backwards" );
- }
-
- // if our time is < nextFrame's, we have a nice interpolating state
- if( cg.time >= cg.snap->serverTime && cg.time < cg.nextSnap->serverTime )
- break;
-
- // we have passed the transition from nextFrame to frame
- CG_TransitionSnapshot( );
- } while( 1 );
-
- // assert our valid conditions upon exiting
- if( cg.snap == NULL )
- CG_Error( "CG_ProcessSnapshots: cg.snap == NULL" );
-
- if( cg.time < cg.snap->serverTime )
- {
- // this can happen right after a vid_restart
- cg.time = cg.snap->serverTime;
- }
-
- if( cg.nextSnap != NULL && cg.nextSnap->serverTime <= cg.time )
- CG_Error( "CG_ProcessSnapshots: cg.nextSnap->serverTime <= cg.time" );
-}
-
diff --git a/src/cgame/cg_syscalls.asm b/src/cgame/cg_syscalls.asm
deleted file mode 100644
index 9da1dade..00000000
--- a/src/cgame/cg_syscalls.asm
+++ /dev/null
@@ -1,105 +0,0 @@
-code
-
-equ trap_Print -1
-equ trap_Error -2
-equ trap_Milliseconds -3
-equ trap_Cvar_Register -4
-equ trap_Cvar_Update -5
-equ trap_Cvar_Set -6
-equ trap_Cvar_VariableStringBuffer -7
-equ trap_Argc -8
-equ trap_Argv -9
-equ trap_Args -10
-equ trap_FS_FOpenFile -11
-equ trap_FS_Read -12
-equ trap_FS_Write -13
-equ trap_FS_FCloseFile -14
-equ trap_SendConsoleCommand -15
-equ trap_AddCommand -16
-equ trap_SendClientCommand -17
-equ trap_UpdateScreen -18
-equ trap_CM_LoadMap -19
-equ trap_CM_NumInlineModels -20
-equ trap_CM_InlineModel -21
-equ trap_CM_LoadModel -22
-equ trap_CM_TempBoxModel -23
-equ trap_CM_PointContents -24
-equ trap_CM_TransformedPointContents -25
-equ trap_CM_BoxTrace -26
-equ trap_CM_TransformedBoxTrace -27
-equ trap_CM_MarkFragments -28
-equ trap_S_StartSound -29
-equ trap_S_StartLocalSound -30
-equ trap_S_ClearLoopingSounds -31
-equ trap_S_AddLoopingSound -32
-equ trap_S_UpdateEntityPosition -33
-equ trap_S_Respatialize -34
-equ trap_S_RegisterSound -35
-equ trap_S_StartBackgroundTrack -36
-equ trap_R_LoadWorldMap -37
-equ trap_R_RegisterModel -38
-equ trap_R_RegisterSkin -39
-equ trap_R_RegisterShader -40
-equ trap_R_ClearScene -41
-equ trap_R_AddRefEntityToScene -42
-equ trap_R_AddPolyToScene -43
-equ trap_R_AddLightToScene -44
-equ trap_R_RenderScene -45
-equ trap_R_SetColor -46
-equ trap_R_DrawStretchPic -47
-equ trap_R_ModelBounds -48
-equ trap_R_LerpTag -49
-equ trap_GetGlconfig -50
-equ trap_GetGameState -51
-equ trap_GetCurrentSnapshotNumber -52
-equ trap_GetSnapshot -53
-equ trap_GetServerCommand -54
-equ trap_GetCurrentCmdNumber -55
-equ trap_GetUserCmd -56
-equ trap_SetUserCmdValue -57
-equ trap_R_RegisterShaderNoMip -58
-equ trap_MemoryRemaining -59
-equ trap_R_RegisterFont -60
-equ trap_Key_IsDown -61
-equ trap_Key_GetCatcher -62
-equ trap_Key_SetCatcher -63
-equ trap_Key_GetKey -64
-equ trap_PC_AddGlobalDefine -65
-equ trap_PC_LoadSource -66
-equ trap_PC_FreeSource -67
-equ trap_PC_ReadToken -68
-equ trap_PC_SourceFileAndLine -69
-equ trap_S_StopBackgroundTrack -70
-equ trap_RealTime -71
-equ trap_SnapVector -72
-equ trap_RemoveCommand -73
-equ trap_R_LightForPoint -74
-equ trap_CIN_PlayCinematic -75
-equ trap_CIN_StopCinematic -76
-equ trap_CIN_RunCinematic -77
-equ trap_CIN_DrawCinematic -78
-equ trap_CIN_SetExtents -79
-equ trap_R_RemapShader -80
-equ trap_S_AddRealLoopingSound -81
-equ trap_S_StopLoopingSound -82
-equ trap_CM_TempCapsuleModel -83
-equ trap_CM_CapsuleTrace -84
-equ trap_CM_TransformedCapsuleTrace -85
-equ trap_R_AddAdditiveLightToScene -86
-equ trap_GetEntityToken -87
-equ trap_R_AddPolysToScene -88
-equ trap_R_inPVS -89
-equ trap_FS_Seek -90
-
-equ memset -101
-equ memcpy -102
-equ strncpy -103
-equ sin -104
-equ cos -105
-equ atan2 -106
-equ sqrt -107
-equ floor -108
-equ ceil -109
-equ testPrintInt -110
-equ testPrintFloat -111
-
diff --git a/src/cgame/cg_syscalls.c b/src/cgame/cg_syscalls.c
deleted file mode 100644
index 3e8c5849..00000000
--- a/src/cgame/cg_syscalls.c
+++ /dev/null
@@ -1,507 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_syscalls.c -- this file is only included when building a dll
-// cg_syscalls.asm is included instead when building a qvm
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-static long (QDECL *syscall)( long arg, ... ) = (long (QDECL *)( long, ...))-1;
-
-
-void dllEntry( long (QDECL *syscallptr)( long arg,... ) )
-{
- syscall = syscallptr;
-}
-
-
-int PASSFLOAT( float x )
-{
- float floatTemp;
- floatTemp = x;
- return *(int *)&floatTemp;
-}
-
-void trap_Print( const char *fmt )
-{
- syscall( CG_PRINT, fmt );
-}
-
-void trap_Error( const char *fmt )
-{
- syscall( CG_ERROR, fmt );
-}
-
-int trap_Milliseconds( void )
-{
- return syscall( CG_MILLISECONDS );
-}
-
-void trap_Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags )
-{
- syscall( CG_CVAR_REGISTER, vmCvar, varName, defaultValue, flags );
-}
-
-void trap_Cvar_Update( vmCvar_t *vmCvar )
-{
- syscall( CG_CVAR_UPDATE, vmCvar );
-}
-
-void trap_Cvar_Set( const char *var_name, const char *value )
-{
- syscall( CG_CVAR_SET, var_name, value );
-}
-
-void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize )
-{
- syscall( CG_CVAR_VARIABLESTRINGBUFFER, var_name, buffer, bufsize );
-}
-
-int trap_Argc( void )
-{
- return syscall( CG_ARGC );
-}
-
-void trap_Argv( int n, char *buffer, int bufferLength )
-{
- syscall( CG_ARGV, n, buffer, bufferLength );
-}
-
-void trap_Args( char *buffer, int bufferLength )
-{
- syscall( CG_ARGS, buffer, bufferLength );
-}
-
-int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode )
-{
- return syscall( CG_FS_FOPENFILE, qpath, f, mode );
-}
-
-void trap_FS_Read( void *buffer, int len, fileHandle_t f )
-{
- syscall( CG_FS_READ, buffer, len, f );
-}
-
-void trap_FS_Write( const void *buffer, int len, fileHandle_t f )
-{
- syscall( CG_FS_WRITE, buffer, len, f );
-}
-
-void trap_FS_FCloseFile( fileHandle_t f )
-{
- syscall( CG_FS_FCLOSEFILE, f );
-}
-
-void trap_FS_Seek( fileHandle_t f, long offset, fsOrigin_t origin )
-{
- syscall( CG_FS_SEEK, f, offset, origin );
-}
-
-void trap_SendConsoleCommand( const char *text )
-{
- syscall( CG_SENDCONSOLECOMMAND, text );
-}
-
-void trap_AddCommand( const char *cmdName )
-{
- syscall( CG_ADDCOMMAND, cmdName );
-}
-
-void trap_RemoveCommand( const char *cmdName )
-{
- syscall( CG_REMOVECOMMAND, cmdName );
-}
-
-void trap_SendClientCommand( const char *s )
-{
- syscall( CG_SENDCLIENTCOMMAND, s );
-}
-
-void trap_UpdateScreen( void )
-{
- syscall( CG_UPDATESCREEN );
-}
-
-void trap_CM_LoadMap( const char *mapname )
-{
- syscall( CG_CM_LOADMAP, mapname );
-}
-
-int trap_CM_NumInlineModels( void )
-{
- return syscall( CG_CM_NUMINLINEMODELS );
-}
-
-clipHandle_t trap_CM_InlineModel( int index )
-{
- return syscall( CG_CM_INLINEMODEL, index );
-}
-
-clipHandle_t trap_CM_TempBoxModel( const vec3_t mins, const vec3_t maxs )
-{
- return syscall( CG_CM_TEMPBOXMODEL, mins, maxs );
-}
-
-clipHandle_t trap_CM_TempCapsuleModel( const vec3_t mins, const vec3_t maxs )
-{
- return syscall( CG_CM_TEMPCAPSULEMODEL, mins, maxs );
-}
-
-int trap_CM_PointContents( const vec3_t p, clipHandle_t model )
-{
- return syscall( CG_CM_POINTCONTENTS, p, model );
-}
-
-int trap_CM_TransformedPointContents( const vec3_t p, clipHandle_t model, const vec3_t origin,
- const vec3_t angles )
-{
- return syscall( CG_CM_TRANSFORMEDPOINTCONTENTS, p, model, origin, angles );
-}
-
-void trap_CM_BoxTrace( trace_t *results, const vec3_t start, const vec3_t end,
- const vec3_t mins, const vec3_t maxs,
- clipHandle_t model, int brushmask )
-{
- syscall( CG_CM_BOXTRACE, results, start, end, mins, maxs, model, brushmask );
-}
-
-void trap_CM_CapsuleTrace( trace_t *results, const vec3_t start, const vec3_t end,
- const vec3_t mins, const vec3_t maxs,
- clipHandle_t model, int brushmask )
-{
- syscall( CG_CM_CAPSULETRACE, results, start, end, mins, maxs, model, brushmask );
-}
-
-void trap_CM_TransformedBoxTrace( trace_t *results, const vec3_t start, const vec3_t end,
- const vec3_t mins, const vec3_t maxs,
- clipHandle_t model, int brushmask,
- const vec3_t origin, const vec3_t angles )
-{
- syscall( CG_CM_TRANSFORMEDBOXTRACE, results, start, end, mins, maxs, model, brushmask, origin, angles );
-}
-
-void trap_CM_TransformedCapsuleTrace( trace_t *results, const vec3_t start, const vec3_t end,
- const vec3_t mins, const vec3_t maxs,
- clipHandle_t model, int brushmask,
- const vec3_t origin, const vec3_t angles )
-{
- syscall( CG_CM_TRANSFORMEDCAPSULETRACE, results, start, end, mins, maxs, model, brushmask, origin, angles );
-}
-
-int trap_CM_MarkFragments( int numPoints, const vec3_t *points,
- const vec3_t projection,
- int maxPoints, vec3_t pointBuffer,
- int maxFragments, markFragment_t *fragmentBuffer )
-{
- return syscall( CG_CM_MARKFRAGMENTS, numPoints, points, projection, maxPoints,
- pointBuffer, maxFragments, fragmentBuffer );
-}
-
-void trap_S_StartSound( vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfx )
-{
- syscall( CG_S_STARTSOUND, origin, entityNum, entchannel, sfx );
-}
-
-void trap_S_StartLocalSound( sfxHandle_t sfx, int channelNum )
-{
- syscall( CG_S_STARTLOCALSOUND, sfx, channelNum );
-}
-
-void trap_S_ClearLoopingSounds( qboolean killall )
-{
- syscall( CG_S_CLEARLOOPINGSOUNDS, killall );
-}
-
-void trap_S_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx )
-{
- syscall( CG_S_ADDLOOPINGSOUND, entityNum, origin, velocity, sfx );
-}
-
-void trap_S_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx )
-{
- syscall( CG_S_ADDREALLOOPINGSOUND, entityNum, origin, velocity, sfx );
-}
-
-void trap_S_StopLoopingSound( int entityNum )
-{
- syscall( CG_S_STOPLOOPINGSOUND, entityNum );
-}
-
-void trap_S_UpdateEntityPosition( int entityNum, const vec3_t origin )
-{
- syscall( CG_S_UPDATEENTITYPOSITION, entityNum, origin );
-}
-
-void trap_S_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater )
-{
- syscall( CG_S_RESPATIALIZE, entityNum, origin, axis, inwater );
-}
-
-sfxHandle_t trap_S_RegisterSound( const char *sample, qboolean compressed )
-{
- return syscall( CG_S_REGISTERSOUND, sample, compressed );
-}
-
-void trap_S_StartBackgroundTrack( const char *intro, const char *loop )
-{
- syscall( CG_S_STARTBACKGROUNDTRACK, intro, loop );
-}
-
-void trap_R_LoadWorldMap( const char *mapname )
-{
- syscall( CG_R_LOADWORLDMAP, mapname );
-}
-
-qhandle_t trap_R_RegisterModel( const char *name )
-{
- return syscall( CG_R_REGISTERMODEL, name );
-}
-
-qhandle_t trap_R_RegisterSkin( const char *name )
-{
- return syscall( CG_R_REGISTERSKIN, name );
-}
-
-qhandle_t trap_R_RegisterShader( const char *name )
-{
- return syscall( CG_R_REGISTERSHADER, name );
-}
-
-qhandle_t trap_R_RegisterShaderNoMip( const char *name )
-{
- return syscall( CG_R_REGISTERSHADERNOMIP, name );
-}
-
-void trap_R_RegisterFont( const char *fontName, int pointSize, fontInfo_t *font )
-{
- syscall(CG_R_REGISTERFONT, fontName, pointSize, font );
-}
-
-void trap_R_ClearScene( void )
-{
- syscall( CG_R_CLEARSCENE );
-}
-
-void trap_R_AddRefEntityToScene( const refEntity_t *re )
-{
- syscall( CG_R_ADDREFENTITYTOSCENE, re );
-}
-
-void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts )
-{
- syscall( CG_R_ADDPOLYTOSCENE, hShader, numVerts, verts );
-}
-
-void trap_R_AddPolysToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts, int num )
-{
- syscall( CG_R_ADDPOLYSTOSCENE, hShader, numVerts, verts, num );
-}
-
-int trap_R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir )
-{
- return syscall( CG_R_LIGHTFORPOINT, point, ambientLight, directedLight, lightDir );
-}
-
-void trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b )
-{
- syscall( CG_R_ADDLIGHTTOSCENE, org, PASSFLOAT(intensity), PASSFLOAT(r), PASSFLOAT(g), PASSFLOAT(b) );
-}
-
-void trap_R_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, float g, float b )
-{
- syscall( CG_R_ADDADDITIVELIGHTTOSCENE, org, PASSFLOAT(intensity), PASSFLOAT(r), PASSFLOAT(g), PASSFLOAT(b) );
-}
-
-void trap_R_RenderScene( const refdef_t *fd )
-{
- syscall( CG_R_RENDERSCENE, fd );
-}
-
-void trap_R_SetColor( const float *rgba )
-{
- syscall( CG_R_SETCOLOR, rgba );
-}
-
-void trap_R_DrawStretchPic( float x, float y, float w, float h,
- float s1, float t1, float s2, float t2, qhandle_t hShader )
-{
- syscall( CG_R_DRAWSTRETCHPIC, PASSFLOAT(x), PASSFLOAT(y), PASSFLOAT(w), PASSFLOAT(h),
- PASSFLOAT(s1), PASSFLOAT(t1), PASSFLOAT(s2), PASSFLOAT(t2), hShader );
-}
-
-void trap_R_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs ) {
- syscall( CG_R_MODELBOUNDS, model, mins, maxs );
-}
-
-int trap_R_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame,
- float frac, const char *tagName )
-{
- return syscall( CG_R_LERPTAG, tag, mod, startFrame, endFrame, PASSFLOAT(frac), tagName );
-}
-
-void trap_R_RemapShader( const char *oldShader, const char *newShader, const char *timeOffset )
-{
- syscall( CG_R_REMAP_SHADER, oldShader, newShader, timeOffset );
-}
-
-void trap_GetGlconfig( glconfig_t *glconfig )
-{
- syscall( CG_GETGLCONFIG, glconfig );
-}
-
-void trap_GetGameState( gameState_t *gamestate )
-{
- syscall( CG_GETGAMESTATE, gamestate );
-}
-
-void trap_GetCurrentSnapshotNumber( int *snapshotNumber, int *serverTime )
-{
- syscall( CG_GETCURRENTSNAPSHOTNUMBER, snapshotNumber, serverTime );
-}
-
-qboolean trap_GetSnapshot( int snapshotNumber, snapshot_t *snapshot )
-{
- return syscall( CG_GETSNAPSHOT, snapshotNumber, snapshot );
-}
-
-qboolean trap_GetServerCommand( int serverCommandNumber )
-{
- return syscall( CG_GETSERVERCOMMAND, serverCommandNumber );
-}
-
-int trap_GetCurrentCmdNumber( void )
-{
- return syscall( CG_GETCURRENTCMDNUMBER );
-}
-
-qboolean trap_GetUserCmd( int cmdNumber, usercmd_t *ucmd )
-{
- return syscall( CG_GETUSERCMD, cmdNumber, ucmd );
-}
-
-void trap_SetUserCmdValue( int stateValue, float sensitivityScale )
-{
- syscall( CG_SETUSERCMDVALUE, stateValue, PASSFLOAT( sensitivityScale ) );
-}
-
-void testPrintInt( char *string, int i )
-{
- syscall( CG_TESTPRINTINT, string, i );
-}
-
-void testPrintFloat( char *string, float f )
-{
- syscall( CG_TESTPRINTFLOAT, string, PASSFLOAT(f) );
-}
-
-int trap_MemoryRemaining( void )
-{
- return syscall( CG_MEMORY_REMAINING );
-}
-
-qboolean trap_Key_IsDown( int keynum )
-{
- return syscall( CG_KEY_ISDOWN, keynum );
-}
-
-int trap_Key_GetCatcher( void )
-{
- return syscall( CG_KEY_GETCATCHER );
-}
-
-void trap_Key_SetCatcher( int catcher )
-{
- syscall( CG_KEY_SETCATCHER, catcher );
-}
-
-int trap_Key_GetKey( const char *binding )
-{
- return syscall( CG_KEY_GETKEY, binding );
-}
-
-int trap_PC_AddGlobalDefine( char *define )
-{
- return syscall( CG_PC_ADD_GLOBAL_DEFINE, define );
-}
-
-int trap_PC_LoadSource( const char *filename )
-{
- return syscall( CG_PC_LOAD_SOURCE, filename );
-}
-
-int trap_PC_FreeSource( int handle )
-{
- return syscall( CG_PC_FREE_SOURCE, handle );
-}
-
-int trap_PC_ReadToken( int handle, pc_token_t *pc_token )
-{
- return syscall( CG_PC_READ_TOKEN, handle, pc_token );
-}
-
-int trap_PC_SourceFileAndLine( int handle, char *filename, int *line )
-{
- return syscall( CG_PC_SOURCE_FILE_AND_LINE, handle, filename, line );
-}
-
-void trap_S_StopBackgroundTrack( void )
-{
- syscall( CG_S_STOPBACKGROUNDTRACK );
-}
-
-int trap_RealTime(qtime_t *qtime)
-{
- return syscall( CG_REAL_TIME, qtime );
-}
-
-void trap_SnapVector( float *v )
-{
- syscall( CG_SNAPVECTOR, v );
-}
-
-// this returns a handle. arg0 is the name in the format "idlogo.roq", set arg1 to NULL, alteredstates to qfalse (do not alter gamestate)
-int trap_CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits )
-{
- return syscall(CG_CIN_PLAYCINEMATIC, arg0, xpos, ypos, width, height, bits);
-}
-
-// stops playing the cinematic and ends it. should always return FMV_EOF
-// cinematics must be stopped in reverse order of when they are started
-e_status trap_CIN_StopCinematic( int handle )
-{
- return syscall(CG_CIN_STOPCINEMATIC, handle);
-}
-
-
-// will run a frame of the cinematic but will not draw it. Will return FMV_EOF if the end of the cinematic has been reached.
-e_status trap_CIN_RunCinematic( int handle )
-{
- return syscall(CG_CIN_RUNCINEMATIC, handle);
-}
-
-
-// draws the current frame
-void trap_CIN_DrawCinematic( int handle )
-{
- syscall(CG_CIN_DRAWCINEMATIC, handle);
-}
-
-
-// allows you to resize the animation dynamically
-void trap_CIN_SetExtents( int handle, int x, int y, int w, int h )
-{
- syscall(CG_CIN_SETEXTENTS, handle, x, y, w, h);
-}
-
diff --git a/src/cgame/cg_trails.c b/src/cgame/cg_trails.c
deleted file mode 100644
index 3ef19f00..00000000
--- a/src/cgame/cg_trails.c
+++ /dev/null
@@ -1,1489 +0,0 @@
-// cg_trails.c -- the trail system
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-static baseTrailSystem_t baseTrailSystems[ MAX_BASETRAIL_SYSTEMS ];
-static baseTrailBeam_t baseTrailBeams[ MAX_BASETRAIL_BEAMS ];
-static int numBaseTrailSystems = 0;
-static int numBaseTrailBeams = 0;
-
-static trailSystem_t trailSystems[ MAX_TRAIL_SYSTEMS ];
-static trailBeam_t trailBeams[ MAX_TRAIL_BEAMS ];
-
-/*
-===============
-CG_CalculateBeamNodeProperties
-
-Fills in trailBeamNode_t.textureCoord
-===============
-*/
-static void CG_CalculateBeamNodeProperties( trailBeam_t *tb )
-{
- trailBeamNode_t *i = NULL;
- trailSystem_t *ts;
- baseTrailBeam_t *btb;
- float nodeDistances[ MAX_TRAIL_BEAM_NODES ];
- float totalDistance = 0.0f, position = 0.0f;
- int j, numNodes = 0;
- float TCRange, widthRange, alphaRange;
- vec3_t colorRange;
- float fadeAlpha = 1.0f;
-
- if( !tb || !tb->nodes )
- return;
-
- ts = tb->parent;
- btb = tb->class;
-
- if( ts->destroyTime > 0 && btb->fadeOutTime )
- {
- fadeAlpha -= ( cg.time - ts->destroyTime ) / btb->fadeOutTime;
-
- if( fadeAlpha < 0.0f )
- fadeAlpha = 0.0f;
- }
-
- TCRange = tb->class->backTextureCoord -
- tb->class->frontTextureCoord;
- widthRange = tb->class->backWidth -
- tb->class->frontWidth;
- alphaRange = tb->class->backAlpha -
- tb->class->frontAlpha;
- VectorSubtract( tb->class->backColor,
- tb->class->frontColor, colorRange );
-
- for( i = tb->nodes; i && i->next; i = i->next )
- {
- nodeDistances[ numNodes++ ] =
- Distance( i->position, i->next->position );
- }
-
- for( j = 0; j < numNodes; j++ )
- totalDistance += nodeDistances[ j ];
-
- for( j = 0, i = tb->nodes; i; i = i->next, j++ )
- {
- if( tb->class->textureType == TBTT_STRETCH )
- {
- i->textureCoord = tb->class->frontTextureCoord +
- ( ( position / totalDistance ) * TCRange );
- }
- else if( tb->class->textureType == TBTT_REPEAT )
- {
- if( tb->class->clampToBack )
- i->textureCoord = ( totalDistance - position ) /
- tb->class->repeatLength;
- else
- i->textureCoord = position / tb->class->repeatLength;
- }
-
- i->halfWidth = ( tb->class->frontWidth +
- ( ( position / totalDistance ) * widthRange ) ) / 2.0f;
- i->alpha = (byte)( (float)0xFF * ( tb->class->frontAlpha +
- ( ( position / totalDistance ) * alphaRange ) ) * fadeAlpha );
- VectorMA( tb->class->frontColor, ( position / totalDistance ),
- colorRange, i->color );
-
- position += nodeDistances[ j ];
- }
-}
-
-/*
-===============
-CG_LightVertex
-
-Lights a particular vertex
-===============
-*/
-static void CG_LightVertex( vec3_t point, byte alpha, byte *rgba )
-{
- int i;
- vec3_t alight, dlight, lightdir;
-
- trap_R_LightForPoint( point, alight, dlight, lightdir );
- for( i = 0; i <= 2; i++ )
- rgba[ i ] = (int)alight[ i ];
-
- rgba[ 3 ] = alpha;
-}
-
-/*
-===============
-CG_RenderBeam
-
-Renders a beam
-===============
-*/
-static void CG_RenderBeam( trailBeam_t *tb )
-{
- trailBeamNode_t *i = NULL;
- trailBeamNode_t *prev = NULL;
- trailBeamNode_t *next = NULL;
- vec3_t up;
- polyVert_t verts[ ( MAX_TRAIL_BEAM_NODES - 1 ) * 4 ];
- int numVerts = 0;
- baseTrailBeam_t *btb;
- trailSystem_t *ts;
- baseTrailSystem_t *bts;
-
- if( !tb || !tb->nodes )
- return;
-
- btb = tb->class;
- ts = tb->parent;
- bts = ts->class;
-
- if( bts->thirdPersonOnly &&
- ( CG_AttachmentCentNum( &ts->frontAttachment ) == cg.snap->ps.clientNum ||
- CG_AttachmentCentNum( &ts->backAttachment ) == cg.snap->ps.clientNum ) &&
- !cg.renderingThirdPerson )
- return;
-
- CG_CalculateBeamNodeProperties( tb );
-
- i = tb->nodes;
-
- do
- {
- prev = i->prev;
- next = i->next;
-
- if( prev && next )
- {
- //this node has two neighbours
- GetPerpendicularViewVector( cg.refdef.vieworg, next->position, prev->position, up );
- }
- else if( !prev && next )
- {
- //this is the front
- GetPerpendicularViewVector( cg.refdef.vieworg, next->position, i->position, up );
- }
- else if( prev && !next )
- {
- //this is the back
- GetPerpendicularViewVector( cg.refdef.vieworg, i->position, prev->position, up );
- }
- else
- break;
-
- if( prev )
- {
- VectorMA( i->position, i->halfWidth, up, verts[ numVerts ].xyz );
- verts[ numVerts ].st[ 0 ] = i->textureCoord;
- verts[ numVerts ].st[ 1 ] = 1.0f;
-
- if( btb->realLight )
- CG_LightVertex( verts[ numVerts ].xyz, i->alpha, verts[ numVerts ].modulate );
- else
- {
- VectorCopy( i->color, verts[ numVerts ].modulate );
- verts[ numVerts ].modulate[ 3 ] = i->alpha;
- }
-
- numVerts++;
-
- VectorMA( i->position, -i->halfWidth, up, verts[ numVerts ].xyz );
- verts[ numVerts ].st[ 0 ] = i->textureCoord;
- verts[ numVerts ].st[ 1 ] = 0.0f;
-
- if( btb->realLight )
- CG_LightVertex( verts[ numVerts ].xyz, i->alpha, verts[ numVerts ].modulate );
- else
- {
- VectorCopy( i->color, verts[ numVerts ].modulate );
- verts[ numVerts ].modulate[ 3 ] = i->alpha;
- }
-
- numVerts++;
- }
-
- if( next )
- {
- VectorMA( i->position, -i->halfWidth, up, verts[ numVerts ].xyz );
- verts[ numVerts ].st[ 0 ] = i->textureCoord;
- verts[ numVerts ].st[ 1 ] = 0.0f;
-
- if( btb->realLight )
- CG_LightVertex( verts[ numVerts ].xyz, i->alpha, verts[ numVerts ].modulate );
- else
- {
- VectorCopy( i->color, verts[ numVerts ].modulate );
- verts[ numVerts ].modulate[ 3 ] = i->alpha;
- }
-
- numVerts++;
-
- VectorMA( i->position, i->halfWidth, up, verts[ numVerts ].xyz );
- verts[ numVerts ].st[ 0 ] = i->textureCoord;
- verts[ numVerts ].st[ 1 ] = 1.0f;
-
- if( btb->realLight )
- CG_LightVertex( verts[ numVerts ].xyz, i->alpha, verts[ numVerts ].modulate );
- else
- {
- VectorCopy( i->color, verts[ numVerts ].modulate );
- verts[ numVerts ].modulate[ 3 ] = i->alpha;
- }
-
- numVerts++;
- }
-
- i = i->next;
- } while( i );
-
- trap_R_AddPolysToScene( tb->class->shader, 4, &verts[ 0 ], numVerts / 4 );
-}
-
-/*
-===============
-CG_AllocateBeamNode
-
-Allocates a trailBeamNode_t from a trailBeam_t's nodePool
-===============
-*/
-static trailBeamNode_t *CG_AllocateBeamNode( trailBeam_t *tb )
-{
- baseTrailBeam_t *btb = tb->class;
- int i;
- trailBeamNode_t *tbn;
-
- for( i = 0; i < MAX_TRAIL_BEAM_NODES; i++ )
- {
- tbn = &tb->nodePool[ i ];
- if( !tbn->used )
- {
- tbn->timeLeft = btb->segmentTime;
- tbn->prev = NULL;
- tbn->next = NULL;
- tbn->used = qtrue;
- return tbn;
- }
- }
-
- // no space left
- return NULL;
-}
-
-/*
-===============
-CG_DestroyBeamNode
-
-Removes a node from a beam
-Returns the new head
-===============
-*/
-static trailBeamNode_t *CG_DestroyBeamNode( trailBeamNode_t *tbn )
-{
- trailBeamNode_t *newHead = NULL;
-
- if( tbn->prev )
- {
- if( tbn->next )
- {
- // node is in the middle
- tbn->prev->next = tbn->next;
- tbn->next->prev = tbn->prev;
- }
- else // node is at the back
- tbn->prev->next = NULL;
-
- // find the new head (shouldn't have changed)
- newHead = tbn->prev;
-
- while( newHead->prev )
- newHead = newHead->prev;
- }
- else if( tbn->next )
- {
- //node is at the front
- tbn->next->prev = NULL;
- newHead = tbn->next;
- }
-
- tbn->prev = NULL;
- tbn->next = NULL;
- tbn->used = qfalse;
-
- return newHead;
-}
-
-/*
-===============
-CG_FindLastBeamNode
-
-Returns the last beam node in a beam
-===============
-*/
-static trailBeamNode_t *CG_FindLastBeamNode( trailBeam_t *tb )
-{
- trailBeamNode_t *i = tb->nodes;
-
- while( i && i->next )
- i = i->next;
-
- return i;
-}
-
-/*
-===============
-CG_CountBeamNodes
-
-Returns the number of nodes in a beam
-===============
-*/
-static int CG_CountBeamNodes( trailBeam_t *tb )
-{
- trailBeamNode_t *i = tb->nodes;
- int numNodes = 0;
-
- while( i )
- {
- numNodes++;
- i = i->next;
- }
-
- return numNodes;
-}
-
-/*
-===============
-CG_PrependBeamNode
-
-Prepend a new beam node to the front of a beam
-Returns the new node
-===============
-*/
-static trailBeamNode_t *CG_PrependBeamNode( trailBeam_t *tb )
-{
- trailBeamNode_t *i;
-
- if( tb->nodes )
- {
- // prepend another node
- i = CG_AllocateBeamNode( tb );
-
- if( i )
- {
- i->next = tb->nodes;
- tb->nodes->prev = i;
- tb->nodes = i;
- }
- }
- else //add first node
- {
- i = CG_AllocateBeamNode( tb );
-
- if( i )
- tb->nodes = i;
- }
-
- return i;
-}
-
-/*
-===============
-CG_AppendBeamNode
-
-Append a new beam node to the back of a beam
-Returns the new node
-===============
-*/
-static trailBeamNode_t *CG_AppendBeamNode( trailBeam_t *tb )
-{
- trailBeamNode_t *last, *i;
-
- if( tb->nodes )
- {
- // append another node
- last = CG_FindLastBeamNode( tb );
- i = CG_AllocateBeamNode( tb );
-
- if( i )
- {
- last->next = i;
- i->prev = last;
- i->next = NULL;
- }
- }
- else //add first node
- {
- i = CG_AllocateBeamNode( tb );
-
- if( i )
- tb->nodes = i;
- }
-
- return i;
-}
-
-/*
-===============
-CG_ApplyJitters
-===============
-*/
-static void CG_ApplyJitters( trailBeam_t *tb )
-{
- trailBeamNode_t *i = NULL;
- int j;
- baseTrailBeam_t *btb;
- trailSystem_t *ts;
- trailBeamNode_t *start;
- trailBeamNode_t *end;
-
- if( !tb || !tb->nodes )
- return;
-
- btb = tb->class;
- ts = tb->parent;
-
- for( j = 0; j < btb->numJitters; j++ )
- {
- if( tb->nextJitterTimes[ j ] <= cg.time )
- {
- for( i = tb->nodes; i; i = i->next )
- {
- i->jitters[ j ][ 0 ] = ( crandom( ) * btb->jitters[ j ].magnitude );
- i->jitters[ j ][ 1 ] = ( crandom( ) * btb->jitters[ j ].magnitude );
- }
-
- tb->nextJitterTimes[ j ] = cg.time + btb->jitters[ j ].period;
- }
- }
-
- start = tb->nodes;
- end = CG_FindLastBeamNode( tb );
-
- if( !btb->jitterAttachments )
- {
- if( CG_Attached( &ts->frontAttachment ) && start->next )
- start = start->next;
-
- if( CG_Attached( &ts->backAttachment ) && end->prev )
- end = end->prev;
- }
-
- for( i = start; i; i = i->next )
- {
- vec3_t forward, right, up;
- trailBeamNode_t *prev;
- trailBeamNode_t *next;
- float upJitter = 0.0f, rightJitter = 0.0f;
-
- prev = i->prev;
- next = i->next;
-
- if( prev && next )
- {
- //this node has two neighbours
- GetPerpendicularViewVector( cg.refdef.vieworg, next->position, prev->position, up );
- VectorSubtract( next->position, prev->position, forward );
- }
- else if( !prev && next )
- {
- //this is the front
- GetPerpendicularViewVector( cg.refdef.vieworg, next->position, i->position, up );
- VectorSubtract( next->position, i->position, forward );
- }
- else if( prev && !next )
- {
- //this is the back
- GetPerpendicularViewVector( cg.refdef.vieworg, i->position, prev->position, up );
- VectorSubtract( i->position, prev->position, forward );
- }
-
- VectorNormalize( forward );
- CrossProduct( forward, up, right );
- VectorNormalize( right );
-
- for( j = 0; j < btb->numJitters; j++ )
- {
- upJitter += i->jitters[ j ][ 0 ];
- rightJitter += i->jitters[ j ][ 1 ];
- }
-
- VectorMA( i->position, upJitter, up, i->position );
- VectorMA( i->position, rightJitter, right, i->position );
-
- if( i == end )
- break;
- }
-}
-
-/*
-===============
-CG_UpdateBeam
-
-Updates a beam
-===============
-*/
-static void CG_UpdateBeam( trailBeam_t *tb )
-{
- baseTrailBeam_t *btb;
- trailSystem_t *ts;
- trailBeamNode_t *i;
- int deltaTime;
- int nodesToAdd;
- int j;
- int numNodes;
-
- if( !tb )
- return;
-
- btb = tb->class;
- ts = tb->parent;
-
- deltaTime = cg.time - tb->lastEvalTime;
- tb->lastEvalTime = cg.time;
-
- // first make sure this beam has enough nodes
- if( ts->destroyTime <= 0 )
- {
- nodesToAdd = btb->numSegments - CG_CountBeamNodes( tb ) + 1;
-
- while( nodesToAdd-- )
- {
- i = CG_AppendBeamNode( tb );
-
- if( !tb->nodes->next && CG_Attached( &ts->frontAttachment ) )
- {
- // this is the first node to be added
- if( !CG_AttachmentPoint( &ts->frontAttachment, i->refPosition ) )
- CG_DestroyTrailSystem( &ts );
- }
- else
- VectorCopy( i->prev->refPosition, i->refPosition );
- }
- }
-
- numNodes = CG_CountBeamNodes( tb );
-
- for( i = tb->nodes; i; i = i->next )
- VectorCopy( i->refPosition, i->position );
-
- if( CG_Attached( &ts->frontAttachment ) && CG_Attached( &ts->backAttachment ) )
- {
- // beam between two attachments
- vec3_t dir, front, back;
-
- if( ts->destroyTime > 0 && ( cg.time - ts->destroyTime ) >= btb->fadeOutTime )
- {
- tb->valid = qfalse;
- return;
- }
-
- if( !CG_AttachmentPoint( &ts->frontAttachment, front ) )
- CG_DestroyTrailSystem( &ts );
-
- if( !CG_AttachmentPoint( &ts->backAttachment, back ) )
- CG_DestroyTrailSystem( &ts );
-
- VectorSubtract( back, front, dir );
-
- for( j = 0, i = tb->nodes; i; i = i->next, j++ )
- {
- float scale = (float)j / (float)( numNodes - 1 );
-
- VectorMA( front, scale, dir, i->position );
- }
- }
- else if( CG_Attached( &ts->frontAttachment ) )
- {
- // beam from one attachment
-
- // cull the trail tail
- i = CG_FindLastBeamNode( tb );
-
- if( i && i->timeLeft >= 0 )
- {
- i->timeLeft -= deltaTime;
-
- if( i->timeLeft < 0 )
- {
- tb->nodes = CG_DestroyBeamNode( i );
-
- if( !tb->nodes )
- {
- tb->valid = qfalse;
- return;
- }
-
- // if the ts has been destroyed, stop creating new nodes
- if( ts->destroyTime <= 0 )
- CG_PrependBeamNode( tb );
- }
- else if( i->timeLeft >= 0 && i->prev )
- {
- vec3_t dir;
- float length;
-
- VectorSubtract( i->refPosition, i->prev->refPosition, dir );
- length = VectorNormalize( dir ) *
- ( (float)i->timeLeft / (float)tb->class->segmentTime );
-
- VectorMA( i->prev->refPosition, length, dir, i->position );
- }
- }
-
- if( tb->nodes )
- {
- if( !CG_AttachmentPoint( &ts->frontAttachment, tb->nodes->refPosition ) )
- CG_DestroyTrailSystem( &ts );
-
- VectorCopy( tb->nodes->refPosition, tb->nodes->position );
- }
- }
-
- CG_ApplyJitters( tb );
-}
-
-/*
-===============
-CG_ParseTrailBeamColor
-===============
-*/
-static qboolean CG_ParseTrailBeamColor( byte *c, char **text_p )
-{
- char *token;
- int i;
-
- for( i = 0; i <= 2; i++ )
- {
- token = COM_Parse( text_p );
-
- if( !Q_stricmp( token, "" ) )
- return qfalse;
-
- c[ i ] = (int)( (float)0xFF * atof_neg( token, qfalse ) );
- }
-
- return qtrue;
-}
-
-/*
-===============
-CG_ParseTrailBeam
-
-Parse a trail beam
-===============
-*/
-static qboolean CG_ParseTrailBeam( baseTrailBeam_t *btb, char **text_p )
-{
- char *token;
-
- // read optional parameters
- while( 1 )
- {
- token = COM_Parse( text_p );
-
- if( !Q_stricmp( token, "" ) )
- return qfalse;
-
- if( !Q_stricmp( token, "segments" ) )
- {
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- btb->numSegments = atoi_neg( token, qfalse );
-
- if( btb->numSegments >= MAX_TRAIL_BEAM_NODES )
- {
- btb->numSegments = MAX_TRAIL_BEAM_NODES - 1;
- CG_Printf( S_COLOR_YELLOW "WARNING: too many segments in trail beam\n" );
- }
- continue;
- }
- else if( !Q_stricmp( token, "width" ) )
- {
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- btb->frontWidth = atof_neg( token, qfalse );
-
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- if( !Q_stricmp( token, "-" ) )
- btb->backWidth = btb->frontWidth;
- else
- btb->backWidth = atof_neg( token, qfalse );
- continue;
- }
- else if( !Q_stricmp( token, "alpha" ) )
- {
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- btb->frontAlpha = atof_neg( token, qfalse );
-
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- if( !Q_stricmp( token, "-" ) )
- btb->backAlpha = btb->frontAlpha;
- else
- btb->backAlpha = atof_neg( token, qfalse );
- continue;
- }
- else if( !Q_stricmp( token, "color" ) )
- {
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- if( !Q_stricmp( token, "{" ) )
- {
- if( !CG_ParseTrailBeamColor( btb->frontColor, text_p ) )
- break;
-
- token = COM_Parse( text_p );
- if( Q_stricmp( token, "}" ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: missing '}'\n" );
- break;
- }
-
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- if( !Q_stricmp( token, "-" ) )
- {
- btb->backColor[ 0 ] = btb->frontColor[ 0 ];
- btb->backColor[ 1 ] = btb->frontColor[ 1 ];
- btb->backColor[ 2 ] = btb->frontColor[ 2 ];
- }
- else if( !Q_stricmp( token, "{" ) )
- {
- if( !CG_ParseTrailBeamColor( btb->backColor, text_p ) )
- break;
-
- token = COM_Parse( text_p );
- if( Q_stricmp( token, "}" ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: missing '}'\n" );
- break;
- }
- }
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: missing '{'\n" );
- break;
- }
- }
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: missing '{'\n" );
- break;
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "segmentTime" ) )
- {
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- btb->segmentTime = atoi_neg( token, qfalse );
- continue;
- }
- else if( !Q_stricmp( token, "fadeOutTime" ) )
- {
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- btb->fadeOutTime = atoi_neg( token, qfalse );
- continue;
- }
- else if( !Q_stricmp( token, "shader" ) )
- {
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- Q_strncpyz( btb->shaderName, token, MAX_QPATH );
-
- continue;
- }
- else if( !Q_stricmp( token, "textureType" ) )
- {
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- if( !Q_stricmp( token, "stretch" ) )
- {
- btb->textureType = TBTT_STRETCH;
-
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- btb->frontTextureCoord = atof_neg( token, qfalse );
-
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- btb->backTextureCoord = atof_neg( token, qfalse );
- }
- else if( !Q_stricmp( token, "repeat" ) )
- {
- btb->textureType = TBTT_REPEAT;
-
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- if( !Q_stricmp( token, "front" ) )
- btb->clampToBack = qfalse;
- else if( !Q_stricmp( token, "back" ) )
- btb->clampToBack = qtrue;
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: unknown textureType clamp \"%s\"\n", token );
- break;
- }
-
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- btb->repeatLength = atof_neg( token, qfalse );
- }
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: unknown textureType \"%s\"\n", token );
- break;
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "realLight" ) )
- {
- btb->realLight = qtrue;
-
- continue;
- }
- else if( !Q_stricmp( token, "jitter" ) )
- {
- if( btb->numJitters == MAX_TRAIL_BEAM_JITTERS )
- {
- CG_Printf( S_COLOR_RED "ERROR: too many jitters\n", token );
- break;
- }
-
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- btb->jitters[ btb->numJitters ].magnitude = atof_neg( token, qfalse );
-
- token = COM_Parse( text_p );
- if( !Q_stricmp( token, "" ) )
- break;
-
- btb->jitters[ btb->numJitters ].period = atoi_neg( token, qfalse );
-
- btb->numJitters++;
-
- continue;
- }
- else if( !Q_stricmp( token, "jitterAttachments" ) )
- {
- btb->jitterAttachments = qtrue;
-
- continue;
- }
- else if( !Q_stricmp( token, "}" ) )
- return qtrue; //reached the end of this trail beam
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: unknown token '%s' in trail beam\n", token );
- return qfalse;
- }
- }
-
- return qfalse;
-}
-
-/*
-===============
-CG_InitialiseBaseTrailBeam
-===============
-*/
-static void CG_InitialiseBaseTrailBeam( baseTrailBeam_t *btb )
-{
- memset( btb, 0, sizeof( baseTrailBeam_t ) );
-
- btb->numSegments = 1;
- btb->frontWidth = btb->backWidth = 1.0f;
- btb->frontAlpha = btb->backAlpha = 1.0f;
- memset( btb->frontColor, 0xFF, sizeof( btb->frontColor ) );
- memset( btb->backColor, 0xFF, sizeof( btb->backColor ) );
-
- btb->segmentTime = 100;
-
- btb->textureType = TBTT_STRETCH;
- btb->frontTextureCoord = 0.0f;
- btb->backTextureCoord = 1.0f;
-}
-
-/*
-===============
-CG_ParseTrailSystem
-
-Parse a trail system section
-===============
-*/
-static qboolean CG_ParseTrailSystem( baseTrailSystem_t *bts, char **text_p, const char *name )
-{
- char *token;
-
- // read optional parameters
- while( 1 )
- {
- token = COM_Parse( text_p );
-
- if( !Q_stricmp( token, "" ) )
- return qfalse;
-
- if( !Q_stricmp( token, "{" ) )
- {
- CG_InitialiseBaseTrailBeam( &baseTrailBeams[ numBaseTrailBeams ] );
-
- if( !CG_ParseTrailBeam( &baseTrailBeams[ numBaseTrailBeams ], text_p ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: failed to parse trail beam\n" );
- return qfalse;
- }
-
- if( bts->numBeams == MAX_BEAMS_PER_SYSTEM )
- {
- CG_Printf( S_COLOR_RED "ERROR: trail system has > %d beams\n", MAX_BEAMS_PER_SYSTEM );
- return qfalse;
- }
- else if( numBaseTrailBeams == MAX_BASETRAIL_BEAMS )
- {
- CG_Printf( S_COLOR_RED "ERROR: maximum number of trail beams (%d) reached\n",
- MAX_BASETRAIL_BEAMS );
- return qfalse;
- }
- else
- {
- //start parsing beams again
- bts->beams[ bts->numBeams ] = &baseTrailBeams[ numBaseTrailBeams ];
- bts->numBeams++;
- numBaseTrailBeams++;
- }
- continue;
- }
- else if( !Q_stricmp( token, "thirdPersonOnly" ) )
- bts->thirdPersonOnly = qtrue;
- else if( !Q_stricmp( token, "beam" ) ) //acceptable text
- continue;
- else if( !Q_stricmp( token, "}" ) )
- {
- if( cg_debugTrails.integer >= 1 )
- CG_Printf( "Parsed trail system %s\n", name );
-
- return qtrue; //reached the end of this trail system
- }
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: unknown token '%s' in trail system %s\n", token, bts->name );
- return qfalse;
- }
- }
-
- return qfalse;
-}
-
-/*
-===============
-CG_ParseTrailFile
-
-Load the trail systems from a trail file
-===============
-*/
-static qboolean CG_ParseTrailFile( const char *fileName )
-{
- char *text_p;
- int i;
- int len;
- char *token;
- char text[ 32000 ];
- char tsName[ MAX_QPATH ];
- qboolean tsNameSet = qfalse;
- fileHandle_t f;
-
- // load the file
- len = trap_FS_FOpenFile( fileName, &f, FS_READ );
- if( len <= 0 )
- return qfalse;
-
- if( len >= sizeof( text ) - 1 )
- {
- CG_Printf( S_COLOR_RED "ERROR: trail file %s too long\n", fileName );
- return qfalse;
- }
-
- trap_FS_Read( text, len, f );
- text[ len ] = 0;
- trap_FS_FCloseFile( f );
-
- // parse the text
- text_p = text;
-
- // read optional parameters
- while( 1 )
- {
- token = COM_Parse( &text_p );
-
- if( !Q_stricmp( token, "" ) )
- break;
-
- if( !Q_stricmp( token, "{" ) )
- {
- if( tsNameSet )
- {
- //check for name space clashes
- for( i = 0; i < numBaseTrailSystems; i++ )
- {
- if( !Q_stricmp( baseTrailSystems[ i ].name, tsName ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: a trail system is already named %s\n", tsName );
- return qfalse;
- }
- }
-
- Q_strncpyz( baseTrailSystems[ numBaseTrailSystems ].name, tsName, MAX_QPATH );
-
- if( !CG_ParseTrailSystem( &baseTrailSystems[ numBaseTrailSystems ], &text_p, tsName ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: %s: failed to parse trail system %s\n", fileName, tsName );
- return qfalse;
- }
-
- //start parsing trail systems again
- tsNameSet = qfalse;
-
- if( numBaseTrailSystems == MAX_BASETRAIL_SYSTEMS )
- {
- CG_Printf( S_COLOR_RED "ERROR: maximum number of trail systems (%d) reached\n",
- MAX_BASETRAIL_SYSTEMS );
- return qfalse;
- }
- else
- numBaseTrailSystems++;
-
- continue;
- }
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: unamed trail system\n" );
- return qfalse;
- }
- }
-
- if( !tsNameSet )
- {
- Q_strncpyz( tsName, token, sizeof( tsName ) );
- tsNameSet = qtrue;
- }
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: trail system already named\n" );
- return qfalse;
- }
- }
-
- return qtrue;
-}
-
-/*
-===============
-CG_LoadTrailSystems
-
-Load trail system templates
-===============
-*/
-void CG_LoadTrailSystems( void )
-{
- int i;
- /*const char *s[ MAX_TRAIL_FILES ];*/
-
- //clear out the old
- numBaseTrailSystems = 0;
- numBaseTrailBeams = 0;
-
- for( i = 0; i < MAX_BASETRAIL_SYSTEMS; i++ )
- {
- baseTrailSystem_t *bts = &baseTrailSystems[ i ];
- memset( bts, 0, sizeof( baseTrailSystem_t ) );
- }
-
- for( i = 0; i < MAX_BASETRAIL_BEAMS; i++ )
- {
- baseTrailBeam_t *btb = &baseTrailBeams[ i ];
- memset( btb, 0, sizeof( baseTrailBeam_t ) );
- }
-
- //and bring in the new
-/* for( i = 0; i < MAX_TRAIL_FILES; i++ )
- {
- s[ i ] = CG_ConfigString( CS_TRAIL_FILES + i );
-
- if( strlen( s[ i ] ) > 0 )
- {
- CG_Printf( "...loading '%s'\n", s[ i ] );
- CG_ParseTrailFile( s[ i ] );
- }
- else
- break;
- }*/
- CG_Printf( "trail.trail: %d\n", CG_ParseTrailFile( "scripts/trail.trail" ) );
-}
-
-/*
-===============
-CG_RegisterTrailSystem
-
-Load the media that a trail system needs
-===============
-*/
-qhandle_t CG_RegisterTrailSystem( char *name )
-{
- int i, j;
- baseTrailSystem_t *bts;
- baseTrailBeam_t *btb;
-
- for( i = 0; i < MAX_BASETRAIL_SYSTEMS; i++ )
- {
- bts = &baseTrailSystems[ i ];
-
- if( !Q_stricmp( bts->name, name ) )
- {
- //already registered
- if( bts->registered )
- return i + 1;
-
- for( j = 0; j < bts->numBeams; j++ )
- {
- btb = bts->beams[ j ];
-
- btb->shader = trap_R_RegisterShader( btb->shaderName );
- }
-
- if( cg_debugTrails.integer >= 1 )
- CG_Printf( "Registered trail system %s\n", name );
-
- bts->registered = qtrue;
-
- //avoid returning 0
- return i + 1;
- }
- }
-
- CG_Printf( S_COLOR_RED "ERROR: failed to register trail system %s\n", name );
- return 0;
-}
-
-
-/*
-===============
-CG_SpawnNewTrailBeam
-
-Allocate a new trail beam
-===============
-*/
-static trailBeam_t *CG_SpawnNewTrailBeam( baseTrailBeam_t *btb,
- trailSystem_t *parent )
-{
- int i;
- trailBeam_t *tb = NULL;
- trailSystem_t *ts = parent;
-
- for( i = 0; i < MAX_TRAIL_BEAMS; i++ )
- {
- tb = &trailBeams[ i ];
-
- if( !tb->valid )
- {
- memset( tb, 0, sizeof( trailBeam_t ) );
-
- //found a free slot
- tb->class = btb;
- tb->parent = ts;
-
- tb->valid = qtrue;
-
- if( cg_debugTrails.integer >= 1 )
- CG_Printf( "TB %s created\n", ts->class->name );
-
- break;
- }
- }
-
- return tb;
-}
-
-
-/*
-===============
-CG_SpawnNewTrailSystem
-
-Spawns a new trail system
-===============
-*/
-trailSystem_t *CG_SpawnNewTrailSystem( qhandle_t psHandle )
-{
- int i, j;
- trailSystem_t *ts = NULL;
- baseTrailSystem_t *bts = &baseTrailSystems[ psHandle - 1 ];
-
- if( !bts->registered )
- {
- CG_Printf( S_COLOR_RED "ERROR: a trail system has not been registered yet\n" );
- return NULL;
- }
-
- for( i = 0; i < MAX_TRAIL_SYSTEMS; i++ )
- {
- ts = &trailSystems[ i ];
-
- if( !ts->valid )
- {
- memset( ts, 0, sizeof( trailSystem_t ) );
-
- //found a free slot
- ts->class = bts;
-
- ts->valid = qtrue;
- ts->destroyTime = -1;
-
- for( j = 0; j < bts->numBeams; j++ )
- CG_SpawnNewTrailBeam( bts->beams[ j ], ts );
-
- if( cg_debugTrails.integer >= 1 )
- CG_Printf( "TS %s created\n", bts->name );
-
- break;
- }
- }
-
- return ts;
-}
-
-/*
-===============
-CG_DestroyTrailSystem
-
-Destroy a trail system
-===============
-*/
-void CG_DestroyTrailSystem( trailSystem_t **ts )
-{
- (*ts)->destroyTime = cg.time;
-
- if( CG_Attached( &(*ts)->frontAttachment ) &&
- !CG_Attached( &(*ts)->backAttachment ) )
- {
- vec3_t v;
-
- // attach the trail head to a static point
- CG_AttachmentPoint( &(*ts)->frontAttachment, v );
- CG_SetAttachmentPoint( &(*ts)->frontAttachment, v );
- CG_AttachToPoint( &(*ts)->frontAttachment );
-
- (*ts)->frontAttachment.centValid = qfalse; // a bit naughty
- }
-
- ts = NULL;
-}
-
-/*
-===============
-CG_IsTrailSystemValid
-
-Test a trail system for validity
-===============
-*/
-qboolean CG_IsTrailSystemValid( trailSystem_t **ts )
-{
- if( *ts == NULL || ( *ts && !(*ts)->valid ) )
- {
- if( *ts && !(*ts)->valid )
- *ts = NULL;
-
- return qfalse;
- }
-
- return qtrue;
-}
-
-/*
-===============
-CG_GarbageCollectTrailSystems
-
-Destroy inactive trail systems
-===============
-*/
-static void CG_GarbageCollectTrailSystems( void )
-{
- int i, j, count;
- trailSystem_t *ts;
- trailBeam_t *tb;
- int centNum;
-
- for( i = 0; i < MAX_TRAIL_SYSTEMS; i++ )
- {
- ts = &trailSystems[ i ];
- count = 0;
-
- //don't bother checking already invalid systems
- if( !ts->valid )
- continue;
-
- for( j = 0; j < MAX_TRAIL_BEAMS; j++ )
- {
- tb = &trailBeams[ j ];
-
- if( tb->valid && tb->parent == ts )
- count++;
- }
-
- if( !count )
- ts->valid = qfalse;
-
- //check systems where the parent cent has left the PVS
- //( local player entity is always valid )
- if( ( centNum = CG_AttachmentCentNum( &ts->frontAttachment ) ) >= 0 &&
- centNum != cg.snap->ps.clientNum )
- {
- trailSystem_t *tempTS = ts;
-
- if( !cg_entities[ centNum ].valid )
- CG_DestroyTrailSystem( &tempTS );
- }
-
- if( ( centNum = CG_AttachmentCentNum( &ts->backAttachment ) ) >= 0 &&
- centNum != cg.snap->ps.clientNum )
- {
- trailSystem_t *tempTS = ts;
-
- if( !cg_entities[ centNum ].valid )
- CG_DestroyTrailSystem( &tempTS );
- }
-
- if( cg_debugTrails.integer >= 1 && !ts->valid )
- CG_Printf( "TS %s garbage collected\n", ts->class->name );
- }
-}
-
-/*
-===============
-CG_AddTrails
-
-Add trails to the scene
-===============
-*/
-void CG_AddTrails( void )
-{
- int i;
- trailBeam_t *tb;
- int numTS = 0, numTB = 0;
-
- //remove expired trail systems
- CG_GarbageCollectTrailSystems( );
-
- for( i = 0; i < MAX_TRAIL_BEAMS; i++ )
- {
- tb = &trailBeams[ i ];
-
- if( tb->valid )
- {
- CG_UpdateBeam( tb );
- CG_RenderBeam( tb );
- }
- }
-
- if( cg_debugTrails.integer >= 2 )
- {
- for( i = 0; i < MAX_TRAIL_SYSTEMS; i++ )
- if( trailSystems[ i ].valid )
- numTS++;
-
- for( i = 0; i < MAX_TRAIL_BEAMS; i++ )
- if( trailBeams[ i ].valid )
- numTB++;
-
- CG_Printf( "TS: %d TB: %d\n", numTS, numTB );
- }
-}
-
-static trailSystem_t *testTS;
-static qhandle_t testTSHandle;
-
-/*
-===============
-CG_DestroyTestTS_f
-
-Destroy the test a trail system
-===============
-*/
-void CG_DestroyTestTS_f( void )
-{
- if( CG_IsTrailSystemValid( &testTS ) )
- CG_DestroyTrailSystem( &testTS );
-}
-
-/*
-===============
-CG_TestTS_f
-
-Test a trail system
-===============
-*/
-void CG_TestTS_f( void )
-{
- char tsName[ MAX_QPATH ];
-
- if( trap_Argc( ) < 2 )
- return;
-
- Q_strncpyz( tsName, CG_Argv( 1 ), MAX_QPATH );
- testTSHandle = CG_RegisterTrailSystem( tsName );
-
- if( testTSHandle )
- {
- CG_DestroyTestTS_f( );
-
- testTS = CG_SpawnNewTrailSystem( testTSHandle );
-
- if( CG_IsTrailSystemValid( &testTS ) )
- {
- CG_SetAttachmentCent( &testTS->frontAttachment, &cg_entities[ 0 ] );
- CG_AttachToCent( &testTS->frontAttachment );
- }
- }
-}
diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c
deleted file mode 100644
index 324646c9..00000000
--- a/src/cgame/cg_view.c
+++ /dev/null
@@ -1,1330 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_view.c -- setup all the parameters (position, angle, etc)
-// for a 3D rendering
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-
-/*
-=============================================================================
-
- MODEL TESTING
-
-The viewthing and gun positioning tools from Q2 have been integrated and
-enhanced into a single model testing facility.
-
-Model viewing can begin with either "testmodel <modelname>" or "testgun <modelname>".
-
-The names must be the full pathname after the basedir, like
-"models/weapons/v_launch/tris.md3" or "players/male/tris.md3"
-
-Testmodel will create a fake entity 100 units in front of the current view
-position, directly facing the viewer. It will remain immobile, so you can
-move around it to view it from different angles.
-
-Testgun will cause the model to follow the player around and supress the real
-view weapon model. The default frame 0 of most guns is completely off screen,
-so you will probably have to cycle a couple frames to see it.
-
-"nextframe", "prevframe", "nextskin", and "prevskin" commands will change the
-frame or skin of the testmodel. These are bound to F5, F6, F7, and F8 in
-q3default.cfg.
-
-If a gun is being tested, the "gun_x", "gun_y", and "gun_z" variables will let
-you adjust the positioning.
-
-Note that none of the model testing features update while the game is paused, so
-it may be convenient to test with deathmatch set to 1 so that bringing down the
-console doesn't pause the game.
-
-=============================================================================
-*/
-
-/*
-=================
-CG_TestModel_f
-
-Creates an entity in front of the current position, which
-can then be moved around
-=================
-*/
-void CG_TestModel_f( void )
-{
- vec3_t angles;
-
- memset( &cg.testModelEntity, 0, sizeof( cg.testModelEntity ) );
- memset( &cg.testModelBarrelEntity, 0, sizeof( cg.testModelBarrelEntity ) );
-
- if( trap_Argc( ) < 2 )
- return;
-
- Q_strncpyz( cg.testModelName, CG_Argv( 1 ), MAX_QPATH );
- cg.testModelEntity.hModel = trap_R_RegisterModel( cg.testModelName );
-
- Q_strncpyz( cg.testModelBarrelName, CG_Argv( 1 ), MAX_QPATH );
- cg.testModelBarrelName[ strlen( cg.testModelBarrelName ) - 4 ] = '\0';
- Q_strcat( cg.testModelBarrelName, MAX_QPATH, "_barrel.md3" );
- cg.testModelBarrelEntity.hModel = trap_R_RegisterModel( cg.testModelBarrelName );
-
- if( trap_Argc( ) == 3 )
- {
- cg.testModelEntity.backlerp = atof( CG_Argv( 2 ) );
- cg.testModelEntity.frame = 1;
- cg.testModelEntity.oldframe = 0;
- }
-
- if( !cg.testModelEntity.hModel )
- {
- CG_Printf( "Can't register model\n" );
- return;
- }
-
- VectorMA( cg.refdef.vieworg, 100, cg.refdef.viewaxis[ 0 ], cg.testModelEntity.origin );
-
- angles[ PITCH ] = 0;
- angles[ YAW ] = 180 + cg.refdefViewAngles[ 1 ];
- angles[ ROLL ] = 0;
-
- AnglesToAxis( angles, cg.testModelEntity.axis );
- cg.testGun = qfalse;
-
- if( cg.testModelBarrelEntity.hModel )
- {
- angles[ YAW ] = 0;
- angles[ PITCH ] = 0;
- angles[ ROLL ] = 0;
- AnglesToAxis( angles, cg.testModelBarrelEntity.axis );
- }
-}
-
-/*
-=================
-CG_TestGun_f
-
-Replaces the current view weapon with the given model
-=================
-*/
-void CG_TestGun_f( void )
-{
- CG_TestModel_f( );
- cg.testGun = qtrue;
- cg.testModelEntity.renderfx = RF_MINLIGHT | RF_DEPTHHACK | RF_FIRST_PERSON;
-}
-
-
-void CG_TestModelNextFrame_f( void )
-{
- cg.testModelEntity.frame++;
- CG_Printf( "frame %i\n", cg.testModelEntity.frame );
-}
-
-void CG_TestModelPrevFrame_f( void )
-{
- cg.testModelEntity.frame--;
-
- if( cg.testModelEntity.frame < 0 )
- cg.testModelEntity.frame = 0;
-
- CG_Printf( "frame %i\n", cg.testModelEntity.frame );
-}
-
-void CG_TestModelNextSkin_f( void )
-{
- cg.testModelEntity.skinNum++;
- CG_Printf( "skin %i\n", cg.testModelEntity.skinNum );
-}
-
-void CG_TestModelPrevSkin_f( void )
-{
- cg.testModelEntity.skinNum--;
-
- if( cg.testModelEntity.skinNum < 0 )
- cg.testModelEntity.skinNum = 0;
-
- CG_Printf( "skin %i\n", cg.testModelEntity.skinNum );
-}
-
-static void CG_AddTestModel( void )
-{
- int i;
-
- // re-register the model, because the level may have changed
- cg.testModelEntity.hModel = trap_R_RegisterModel( cg.testModelName );
- cg.testModelBarrelEntity.hModel = trap_R_RegisterModel( cg.testModelBarrelName );
-
- if( !cg.testModelEntity.hModel )
- {
- CG_Printf( "Can't register model\n" );
- return;
- }
-
- // if testing a gun, set the origin reletive to the view origin
- if( cg.testGun )
- {
- VectorCopy( cg.refdef.vieworg, cg.testModelEntity.origin );
- VectorCopy( cg.refdef.viewaxis[ 0 ], cg.testModelEntity.axis[ 0 ] );
- VectorCopy( cg.refdef.viewaxis[ 1 ], cg.testModelEntity.axis[ 1 ] );
- VectorCopy( cg.refdef.viewaxis[ 2 ], cg.testModelEntity.axis[ 2 ] );
-
- // allow the position to be adjusted
- for( i = 0; i < 3; i++ )
- {
- cg.testModelEntity.origin[ i ] += cg.refdef.viewaxis[ 0 ][ i ] * cg_gun_x.value;
- cg.testModelEntity.origin[ i ] += cg.refdef.viewaxis[ 1 ][ i ] * cg_gun_y.value;
- cg.testModelEntity.origin[ i ] += cg.refdef.viewaxis[ 2 ][ i ] * cg_gun_z.value;
- }
- }
-
- trap_R_AddRefEntityToScene( &cg.testModelEntity );
-
- if( cg.testModelBarrelEntity.hModel )
- {
- CG_PositionEntityOnTag( &cg.testModelBarrelEntity, &cg.testModelEntity,
- cg.testModelEntity.hModel, "tag_barrel" );
-
- trap_R_AddRefEntityToScene( &cg.testModelBarrelEntity );
- }
-}
-
-
-
-//============================================================================
-
-
-/*
-=================
-CG_CalcVrect
-
-Sets the coordinates of the rendered window
-=================
-*/
-static void CG_CalcVrect( void )
-{
- int size;
-
- // the intermission should allways be full screen
- if( cg.snap->ps.pm_type == PM_INTERMISSION )
- size = 100;
- else
- {
- // bound normal viewsize
- if( cg_viewsize.integer < 30 )
- {
- trap_Cvar_Set( "cg_viewsize", "30" );
- size = 30;
- }
- else if( cg_viewsize.integer > 100 )
- {
- trap_Cvar_Set( "cg_viewsize","100" );
- size = 100;
- }
- else
- size = cg_viewsize.integer;
- }
-
- cg.refdef.width = cgs.glconfig.vidWidth * size / 100;
- cg.refdef.width &= ~1;
-
- cg.refdef.height = cgs.glconfig.vidHeight * size / 100;
- cg.refdef.height &= ~1;
-
- cg.refdef.x = ( cgs.glconfig.vidWidth - cg.refdef.width ) / 2;
- cg.refdef.y = ( cgs.glconfig.vidHeight - cg.refdef.height ) / 2;
-}
-
-//==============================================================================
-
-
-/*
-===============
-CG_OffsetThirdPersonView
-
-===============
-*/
-#define FOCUS_DISTANCE 512
-static void CG_OffsetThirdPersonView( void )
-{
- vec3_t forward, right, up;
- vec3_t view;
- vec3_t focusAngles;
- trace_t trace;
- static vec3_t mins = { -8, -8, -8 };
- static vec3_t maxs = { 8, 8, 8 };
- vec3_t focusPoint;
- float focusDist;
- float forwardScale, sideScale;
- vec3_t surfNormal;
-
- if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_WALLCLIMBING )
- {
- if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING )
- VectorSet( surfNormal, 0.0f, 0.0f, -1.0f );
- else
- VectorCopy( cg.predictedPlayerState.grapplePoint, surfNormal );
- }
- else
- VectorSet( surfNormal, 0.0f, 0.0f, 1.0f );
-
- VectorMA( cg.refdef.vieworg, cg.predictedPlayerState.viewheight, surfNormal, cg.refdef.vieworg );
-
- VectorCopy( cg.refdefViewAngles, focusAngles );
-
- // if dead, look at killer
- if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 )
- {
- focusAngles[ YAW ] = cg.predictedPlayerState.stats[ STAT_VIEWLOCK ];
- cg.refdefViewAngles[ YAW ] = cg.predictedPlayerState.stats[ STAT_VIEWLOCK ];
- }
-
- //if ( focusAngles[PITCH] > 45 ) {
- // focusAngles[PITCH] = 45; // don't go too far overhead
- //}
- AngleVectors( focusAngles, forward, NULL, NULL );
-
- VectorMA( cg.refdef.vieworg, FOCUS_DISTANCE, forward, focusPoint );
-
- VectorCopy( cg.refdef.vieworg, view );
-
- VectorMA( view, 12, surfNormal, view );
-
- //cg.refdefViewAngles[PITCH] *= 0.5;
-
- AngleVectors( cg.refdefViewAngles, forward, right, up );
-
- forwardScale = cos( cg_thirdPersonAngle.value / 180 * M_PI );
- sideScale = sin( cg_thirdPersonAngle.value / 180 * M_PI );
- VectorMA( view, -cg_thirdPersonRange.value * forwardScale, forward, view );
- VectorMA( view, -cg_thirdPersonRange.value * sideScale, right, view );
-
- // trace a ray from the origin to the viewpoint to make sure the view isn't
- // in a solid block. Use an 8 by 8 block to prevent the view from near clipping anything
-
- if( !cg_cameraMode.integer )
- {
- CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.predictedPlayerState.clientNum, MASK_SOLID );
-
- if( trace.fraction != 1.0 )
- {
- VectorCopy( trace.endpos, view );
- view[ 2 ] += ( 1.0 - trace.fraction ) * 32;
- // try another trace to this position, because a tunnel may have the ceiling
- // close enogh that this is poking out
-
- CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.predictedPlayerState.clientNum, MASK_SOLID );
- VectorCopy( trace.endpos, view );
- }
- }
-
- VectorCopy( view, cg.refdef.vieworg );
-
- // select pitch to look at focus point from vieword
- VectorSubtract( focusPoint, cg.refdef.vieworg, focusPoint );
- focusDist = sqrt( focusPoint[ 0 ] * focusPoint[ 0 ] + focusPoint[ 1 ] * focusPoint[ 1 ] );
- if ( focusDist < 1 ) {
- focusDist = 1; // should never happen
- }
- cg.refdefViewAngles[ PITCH ] = -180 / M_PI * atan2( focusPoint[ 2 ], focusDist );
- cg.refdefViewAngles[ YAW ] -= cg_thirdPersonAngle.value;
-}
-
-
-// this causes a compiler bug on mac MrC compiler
-static void CG_StepOffset( void )
-{
- float steptime;
- int timeDelta;
- vec3_t normal;
- playerState_t *ps = &cg.predictedPlayerState;
-
- if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING )
- {
- if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING )
- VectorSet( normal, 0.0f, 0.0f, -1.0f );
- else
- VectorCopy( ps->grapplePoint, normal );
- }
- else
- VectorSet( normal, 0.0f, 0.0f, 1.0f );
-
- steptime = BG_FindSteptimeForClass( ps->stats[ STAT_PCLASS ] );
-
- // smooth out stair climbing
- timeDelta = cg.time - cg.stepTime;
- if( timeDelta < steptime )
- {
- float stepChange = cg.stepChange
- * (steptime - timeDelta) / steptime;
-
- if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING )
- VectorMA( cg.refdef.vieworg, -stepChange, normal, cg.refdef.vieworg );
- else
- cg.refdef.vieworg[ 2 ] -= stepChange;
- }
-}
-
-#define PCLOUD_ROLL_AMPLITUDE 25.0f
-#define PCLOUD_ROLL_FREQUENCY 0.4f
-#define PCLOUD_ZOOM_AMPLITUDE 15
-#define PCLOUD_ZOOM_FREQUENCY 0.7f
-
-
-/*
-===============
-CG_OffsetFirstPersonView
-
-===============
-*/
-static void CG_OffsetFirstPersonView( void )
-{
- float *origin;
- float *angles;
- float bob;
- float ratio;
- float delta;
- float speed;
- float f;
- vec3_t predictedVelocity;
- int timeDelta;
- float bob2;
- vec3_t normal, baseOrigin;
- playerState_t *ps = &cg.predictedPlayerState;
-
- if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING )
- {
- if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING )
- VectorSet( normal, 0.0f, 0.0f, -1.0f );
- else
- VectorCopy( ps->grapplePoint, normal );
- }
- else
- VectorSet( normal, 0.0f, 0.0f, 1.0f );
-
-
- if( cg.snap->ps.pm_type == PM_INTERMISSION )
- return;
-
- origin = cg.refdef.vieworg;
- angles = cg.refdefViewAngles;
-
- VectorCopy( origin, baseOrigin );
-
- // if dead, fix the angle and don't add any kick
- if( cg.snap->ps.stats[ STAT_HEALTH ] <= 0 )
- {
- angles[ ROLL ] = 40;
- angles[ PITCH ] = -15;
- angles[ YAW ] = cg.snap->ps.stats[ STAT_VIEWLOCK ];
- origin[ 2 ] += cg.predictedPlayerState.viewheight;
- return;
- }
-
- // add angles based on weapon kick
- VectorAdd( angles, cg.kick_angles, angles );
-
- // add angles based on damage kick
- if( cg.damageTime )
- {
- ratio = cg.time - cg.damageTime;
- if( ratio < DAMAGE_DEFLECT_TIME )
- {
- ratio /= DAMAGE_DEFLECT_TIME;
- angles[ PITCH ] += ratio * cg.v_dmg_pitch;
- angles[ ROLL ] += ratio * cg.v_dmg_roll;
- }
- else
- {
- ratio = 1.0 - ( ratio - DAMAGE_DEFLECT_TIME ) / DAMAGE_RETURN_TIME;
- if( ratio > 0 )
- {
- angles[ PITCH ] += ratio * cg.v_dmg_pitch;
- angles[ ROLL ] += ratio * cg.v_dmg_roll;
- }
- }
- }
-
- // add pitch based on fall kick
-#if 0
- ratio = ( cg.time - cg.landTime) / FALL_TIME;
- if (ratio < 0)
- ratio = 0;
- angles[PITCH] += ratio * cg.fall_value;
-#endif
-
- // add angles based on velocity
- VectorCopy( cg.predictedPlayerState.velocity, predictedVelocity );
-
- delta = DotProduct( predictedVelocity, cg.refdef.viewaxis[ 0 ] );
- angles[ PITCH ] += delta * cg_runpitch.value;
-
- delta = DotProduct( predictedVelocity, cg.refdef.viewaxis[ 1 ] );
- angles[ ROLL ] -= delta * cg_runroll.value;
-
- // add angles based on bob
- //TA: bob amount is class dependant
-
- if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
- bob2 = 0.0f;
- else
- bob2 = BG_FindBobForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] );
-
-
-#define LEVEL4_FEEDBACK 10.0f
-
- //give a charging player some feedback
- if( ps->weapon == WP_ALEVEL4 )
- {
- if( ps->stats[ STAT_MISC ] > 0 )
- {
- float fraction = (float)ps->stats[ STAT_MISC ] / (float)LEVEL4_CHARGE_TIME;
-
- if( fraction > 1.0f )
- fraction = 1.0f;
-
- bob2 *= ( 1.0f + fraction * LEVEL4_FEEDBACK );
- }
- }
-
- if( bob2 != 0.0f )
- {
- // make sure the bob is visible even at low speeds
- speed = cg.xyspeed > 200 ? cg.xyspeed : 200;
-
- delta = cg.bobfracsin * ( bob2 ) * speed;
- if( cg.predictedPlayerState.pm_flags & PMF_DUCKED )
- delta *= 3; // crouching
-
- angles[ PITCH ] += delta;
- delta = cg.bobfracsin * ( bob2 ) * speed;
- if( cg.predictedPlayerState.pm_flags & PMF_DUCKED )
- delta *= 3; // crouching accentuates roll
-
- if( cg.bobcycle & 1 )
- delta = -delta;
-
- angles[ ROLL ] += delta;
- }
-
-#define LEVEL3_FEEDBACK 20.0f
-
- //provide some feedback for pouncing
- if( cg.predictedPlayerState.weapon == WP_ALEVEL3 ||
- cg.predictedPlayerState.weapon == WP_ALEVEL3_UPG )
- {
- if( cg.predictedPlayerState.stats[ STAT_MISC ] > 0 )
- {
- float fraction1, fraction2;
- vec3_t forward;
-
- AngleVectors( angles, forward, NULL, NULL );
- VectorNormalize( forward );
-
- fraction1 = (float)( cg.time - cg.weapon2Time ) / (float)LEVEL3_POUNCE_CHARGE_TIME;
-
- if( fraction1 > 1.0f )
- fraction1 = 1.0f;
-
- fraction2 = -sin( fraction1 * M_PI / 2 );
-
- VectorMA( origin, LEVEL3_FEEDBACK * fraction2, forward, origin );
- }
- }
-
-#define STRUGGLE_DIST 5.0f
-#define STRUGGLE_TIME 250
-
- //allow the player to struggle a little whilst grabbed
- if( cg.predictedPlayerState.pm_type == PM_GRABBED )
- {
- vec3_t forward, right, up;
- usercmd_t cmd;
- int cmdNum;
- float fFraction, rFraction, uFraction;
- float fFraction2, rFraction2, uFraction2;
-
- cmdNum = trap_GetCurrentCmdNumber();
- trap_GetUserCmd( cmdNum, &cmd );
-
- AngleVectors( angles, forward, right, up );
-
- fFraction = (float)( cg.time - cg.forwardMoveTime ) / STRUGGLE_TIME;
- rFraction = (float)( cg.time - cg.rightMoveTime ) / STRUGGLE_TIME;
- uFraction = (float)( cg.time - cg.upMoveTime ) / STRUGGLE_TIME;
-
- if( fFraction > 1.0f )
- fFraction = 1.0f;
- if( rFraction > 1.0f )
- rFraction = 1.0f;
- if( uFraction > 1.0f )
- uFraction = 1.0f;
-
- fFraction2 = -sin( fFraction * M_PI / 2 );
- rFraction2 = -sin( rFraction * M_PI / 2 );
- uFraction2 = -sin( uFraction * M_PI / 2 );
-
- if( cmd.forwardmove > 0 )
- VectorMA( origin, STRUGGLE_DIST * fFraction, forward, origin );
- else if( cmd.forwardmove < 0 )
- VectorMA( origin, -STRUGGLE_DIST * fFraction, forward, origin );
- else
- cg.forwardMoveTime = cg.time;
-
- if( cmd.rightmove > 0 )
- VectorMA( origin, STRUGGLE_DIST * rFraction, right, origin );
- else if( cmd.rightmove < 0 )
- VectorMA( origin, -STRUGGLE_DIST * rFraction, right, origin );
- else
- cg.rightMoveTime = cg.time;
-
- if( cmd.upmove > 0 )
- VectorMA( origin, STRUGGLE_DIST * uFraction, up, origin );
- else if( cmd.upmove < 0 )
- VectorMA( origin, -STRUGGLE_DIST * uFraction, up, origin );
- else
- cg.upMoveTime = cg.time;
- }
-
- if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_POISONCLOUDED &&
- !( cg.snap->ps.pm_flags & PMF_FOLLOW ) )
- {
- float fraction = sin( ( (float)cg.time / 1000.0f ) * M_PI * 2 * PCLOUD_ROLL_FREQUENCY );
- float pitchFraction = sin( ( (float)cg.time / 1000.0f ) * M_PI * 5 * PCLOUD_ROLL_FREQUENCY );
-
- fraction *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)LEVEL1_PCLOUD_TIME );
- pitchFraction *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)LEVEL1_PCLOUD_TIME );
-
- angles[ ROLL ] += fraction * PCLOUD_ROLL_AMPLITUDE;
- angles[ YAW ] += fraction * PCLOUD_ROLL_AMPLITUDE;
- angles[ PITCH ] += pitchFraction * PCLOUD_ROLL_AMPLITUDE / 2.0f;
- }
-
- //TA: this *feels* more realisitic for humans
- if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS )
- {
- angles[PITCH] += cg.bobfracsin * bob2 * 0.5;
-
- //TA: heavy breathing effects //FIXME: sound
- if( cg.predictedPlayerState.stats[ STAT_STAMINA ] < 0 )
- {
- float deltaBreath = (float)(
- cg.predictedPlayerState.stats[ STAT_STAMINA ] < 0 ?
- -cg.predictedPlayerState.stats[ STAT_STAMINA ] :
- cg.predictedPlayerState.stats[ STAT_STAMINA ] ) / 200.0;
- float deltaAngle = cos( (float)cg.time/150.0 ) * deltaBreath;
-
- deltaAngle += ( deltaAngle < 0 ? -deltaAngle : deltaAngle ) * 0.5;
-
- angles[ PITCH ] -= deltaAngle;
- }
- }
-
-//===================================
-
- // add view height
- //TA: when wall climbing the viewheight is not straight up
- if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_WALLCLIMBING )
- VectorMA( origin, ps->viewheight, normal, origin );
- else
- origin[ 2 ] += cg.predictedPlayerState.viewheight;
-
- // smooth out duck height changes
- timeDelta = cg.time - cg.duckTime;
- if( timeDelta < DUCK_TIME)
- {
- cg.refdef.vieworg[ 2 ] -= cg.duckChange
- * ( DUCK_TIME - timeDelta ) / DUCK_TIME;
- }
-
- // add bob height
- bob = cg.bobfracsin * cg.xyspeed * bob2;
-
- if( bob > 6 )
- bob = 6;
-
- //TA: likewise for bob
- if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_WALLCLIMBING )
- VectorMA( origin, bob, normal, origin );
- else
- origin[ 2 ] += bob;
-
-
- // add fall height
- delta = cg.time - cg.landTime;
-
- if( delta < LAND_DEFLECT_TIME )
- {
- f = delta / LAND_DEFLECT_TIME;
- cg.refdef.vieworg[ 2 ] += cg.landChange * f;
- }
- else if( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME )
- {
- delta -= LAND_DEFLECT_TIME;
- f = 1.0 - ( delta / LAND_RETURN_TIME );
- cg.refdef.vieworg[ 2 ] += cg.landChange * f;
- }
-
- // add step offset
- CG_StepOffset( );
-
- // add kick offset
-
- VectorAdd (origin, cg.kick_origin, origin);
-}
-
-//======================================================================
-
-void CG_ZoomDown_f( void )
-{
- if( cg.zoomed )
- return;
-
- cg.zoomed = qtrue;
- cg.zoomTime = cg.time;
-}
-
-void CG_ZoomUp_f( void )
-{
- if( !cg.zoomed )
- return;
-
- cg.zoomed = qfalse;
- cg.zoomTime = cg.time;
-}
-
-
-/*
-====================
-CG_CalcFov
-
-Fixed fov at intermissions, otherwise account for fov variable and zooms.
-====================
-*/
-#define WAVE_AMPLITUDE 1
-#define WAVE_FREQUENCY 0.4
-
-#define FOVWARPTIME 400.0
-
-static int CG_CalcFov( void )
-{
- float x;
- float phase;
- float v;
- int contents;
- float fov_x, fov_y;
- float zoomFov;
- float f;
- int inwater;
- int attribFov;
-
- if( cg.predictedPlayerState.pm_type == PM_INTERMISSION ||
- ( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) )
- {
- // if in intermission, use a fixed value
- fov_x = 90;
- }
- else
- {
- //TA: don't lock the fov globally - we need to be able to change it
- attribFov = BG_FindFovForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] );
- fov_x = attribFov;
-
- if ( fov_x < 1 )
- fov_x = 1;
- else if ( fov_x > 160 )
- fov_x = 160;
-
- if( cg.spawnTime > ( cg.time - FOVWARPTIME ) &&
- BG_ClassHasAbility( cg.predictedPlayerState.stats[ STAT_PCLASS ], SCA_FOVWARPS ) )
- {
- float temp, temp2;
-
- temp = (float)( cg.time - cg.spawnTime ) / FOVWARPTIME;
- temp2 = ( 180 - fov_x ) * temp;
-
- //Com_Printf( "%f %f\n", temp*100, temp2*100 );
-
- fov_x = 180 - temp2;
- }
-
- // account for zooms
- zoomFov = BG_FindZoomFovForWeapon( cg.predictedPlayerState.weapon );
- if ( zoomFov < 1 )
- zoomFov = 1;
- else if ( zoomFov > attribFov )
- zoomFov = attribFov;
-
- //TA: only do all the zoom stuff if the client CAN zoom
- if( BG_WeaponCanZoom( cg.predictedPlayerState.weapon ) )
- {
- if ( cg.zoomed )
- {
- f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
-
- if ( f > 1.0 )
- fov_x = zoomFov;
- else
- fov_x = fov_x + f * ( zoomFov - fov_x );
- }
- else
- {
- f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
-
- if ( f > 1.0 )
- fov_x = fov_x;
- else
- fov_x = zoomFov + f * ( fov_x - zoomFov );
- }
- }
- }
-
- x = cg.refdef.width / tan( fov_x / 360 * M_PI );
- fov_y = atan2( cg.refdef.height, x );
- fov_y = fov_y * 360 / M_PI;
-
- // warp if underwater
- contents = CG_PointContents( cg.refdef.vieworg, -1 );
-
- if( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) )
- {
- phase = cg.time / 1000.0 * WAVE_FREQUENCY * M_PI * 2;
- v = WAVE_AMPLITUDE * sin( phase );
- fov_x += v;
- fov_y -= v;
- inwater = qtrue;
- }
- else
- inwater = qfalse;
-
- if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_POISONCLOUDED &&
- cg.predictedPlayerState.stats[ STAT_HEALTH ] > 0 &&
- !( cg.snap->ps.pm_flags & PMF_FOLLOW ) )
- {
- phase = cg.time / 1000.0 * PCLOUD_ZOOM_FREQUENCY * M_PI * 2;
- v = PCLOUD_ZOOM_AMPLITUDE * sin( phase );
- v *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)LEVEL1_PCLOUD_TIME );
- fov_x += v;
- fov_y += v;
- }
-
-
- // set it
- cg.refdef.fov_x = fov_x;
- cg.refdef.fov_y = fov_y;
-
- if( !cg.zoomed )
- cg.zoomSensitivity = 1;
- else
- cg.zoomSensitivity = cg.refdef.fov_y / 75.0;
-
- return inwater;
-}
-
-
-
-#define NORMAL_HEIGHT 64.0f
-#define NORMAL_WIDTH 6.0f
-
-/*
-===============
-CG_DrawSurfNormal
-
-Draws a vector against
-the surface player is looking at
-===============
-*/
-static void CG_DrawSurfNormal( void )
-{
- trace_t tr;
- vec3_t end, temp;
- polyVert_t normal[ 4 ];
- vec4_t color = { 0.0f, 255.0f, 0.0f, 128.0f };
-
- VectorMA( cg.refdef.vieworg, 8192, cg.refdef.viewaxis[ 0 ], end );
-
- CG_Trace( &tr, cg.refdef.vieworg, NULL, NULL, end, cg.predictedPlayerState.clientNum, MASK_SOLID );
-
- VectorCopy( tr.endpos, normal[ 0 ].xyz );
- normal[ 0 ].st[ 0 ] = 0;
- normal[ 0 ].st[ 1 ] = 0;
- Vector4Copy( color, normal[ 0 ].modulate );
-
- VectorMA( tr.endpos, NORMAL_WIDTH, cg.refdef.viewaxis[ 1 ], temp );
- VectorCopy( temp, normal[ 1 ].xyz);
- normal[ 1 ].st[ 0 ] = 0;
- normal[ 1 ].st[ 1 ] = 1;
- Vector4Copy( color, normal[ 1 ].modulate );
-
- VectorMA( tr.endpos, NORMAL_HEIGHT, tr.plane.normal, temp );
- VectorMA( temp, NORMAL_WIDTH, cg.refdef.viewaxis[ 1 ], temp );
- VectorCopy( temp, normal[ 2 ].xyz );
- normal[ 2 ].st[ 0 ] = 1;
- normal[ 2 ].st[ 1 ] = 1;
- Vector4Copy( color, normal[ 2 ].modulate );
-
- VectorMA( tr.endpos, NORMAL_HEIGHT, tr.plane.normal, temp );
- VectorCopy( temp, normal[ 3 ].xyz );
- normal[ 3 ].st[ 0 ] = 1;
- normal[ 3 ].st[ 1 ] = 0;
- Vector4Copy( color, normal[ 3 ].modulate );
-
- trap_R_AddPolyToScene( cgs.media.outlineShader, 4, normal );
-}
-
-/*
-===============
-CG_addSmoothOp
-===============
-*/
-void CG_addSmoothOp( vec3_t rotAxis, float rotAngle, float timeMod )
-{
- int i;
-
- //iterate through smooth array
- for( i = 0; i < MAXSMOOTHS; i++ )
- {
- //found an unused index in the smooth array
- if( cg.sList[ i ].time + cg_wwSmoothTime.integer < cg.time )
- {
- //copy to array and stop
- VectorCopy( rotAxis, cg.sList[ i ].rotAxis );
- cg.sList[ i ].rotAngle = rotAngle;
- cg.sList[ i ].time = cg.time;
- cg.sList[ i ].timeMod = timeMod;
- return;
- }
- }
-
- //no free indices in the smooth array
-}
-
-/*
-===============
-CG_smoothWWTransitions
-===============
-*/
-static void CG_smoothWWTransitions( playerState_t *ps, const vec3_t in, vec3_t out )
-{
- vec3_t surfNormal, rotAxis, temp;
- vec3_t refNormal = { 0.0f, 0.0f, 1.0f };
- vec3_t ceilingNormal = { 0.0f, 0.0f, -1.0f };
- int i;
- float stLocal, sFraction, rotAngle;
- float smoothTime, timeMod;
- qboolean performed = qfalse;
- vec3_t inAxis[ 3 ], lastAxis[ 3 ], outAxis[ 3 ];
-
- if( cg.snap->ps.pm_flags & PMF_FOLLOW )
- {
- VectorCopy( in, out );
- return;
- }
-
- //set surfNormal
- if( !( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) )
- VectorCopy( ps->grapplePoint, surfNormal );
- else
- VectorCopy( ceilingNormal, surfNormal );
-
- AnglesToAxis( in, inAxis );
-
- //if we are moving from one surface to another smooth the transition
- if( !VectorCompare( surfNormal, cg.lastNormal ) )
- {
- //if we moving from the ceiling to the floor special case
- //( x product of colinear vectors is undefined)
- if( VectorCompare( ceilingNormal, cg.lastNormal ) &&
- VectorCompare( refNormal, surfNormal ) )
- {
- AngleVectors( in, temp, NULL, NULL );
- ProjectPointOnPlane( rotAxis, temp, refNormal );
- VectorNormalize( rotAxis );
- rotAngle = 180.0f;
- timeMod = 1.5f;
- }
- else
- {
- AnglesToAxis( cg.lastVangles, lastAxis );
- rotAngle = DotProduct( inAxis[ 0 ], lastAxis[ 0 ] ) +
- DotProduct( inAxis[ 1 ], lastAxis[ 1 ] ) +
- DotProduct( inAxis[ 2 ], lastAxis[ 2 ] );
-
- rotAngle = RAD2DEG( acos( ( rotAngle - 1.0f ) / 2.0f ) );
-
- CrossProduct( lastAxis[ 0 ], inAxis[ 0 ], temp );
- VectorCopy( temp, rotAxis );
- CrossProduct( lastAxis[ 1 ], inAxis[ 1 ], temp );
- VectorAdd( rotAxis, temp, rotAxis );
- CrossProduct( lastAxis[ 2 ], inAxis[ 2 ], temp );
- VectorAdd( rotAxis, temp, rotAxis );
-
- VectorNormalize( rotAxis );
-
- timeMod = 1.0f;
- }
-
- //add the op
- CG_addSmoothOp( rotAxis, rotAngle, timeMod );
- }
-
- //iterate through ops
- for( i = MAXSMOOTHS - 1; i >= 0; i-- )
- {
- smoothTime = (int)( cg_wwSmoothTime.integer * cg.sList[ i ].timeMod );
-
- //if this op has time remaining, perform it
- if( cg.time < cg.sList[ i ].time + smoothTime )
- {
- stLocal = 1.0f - ( ( ( cg.sList[ i ].time + smoothTime ) - cg.time ) / smoothTime );
- sFraction = -( cos( stLocal * M_PI ) + 1.0f ) / 2.0f;
-
- RotatePointAroundVector( outAxis[ 0 ], cg.sList[ i ].rotAxis,
- inAxis[ 0 ], sFraction * cg.sList[ i ].rotAngle );
- RotatePointAroundVector( outAxis[ 1 ], cg.sList[ i ].rotAxis,
- inAxis[ 1 ], sFraction * cg.sList[ i ].rotAngle );
- RotatePointAroundVector( outAxis[ 2 ], cg.sList[ i ].rotAxis,
- inAxis[ 2 ], sFraction * cg.sList[ i ].rotAngle );
-
- AxisCopy( outAxis, inAxis );
- performed = qtrue;
- }
- }
-
- //if we performed any ops then return the smoothed angles
- //otherwise simply return the in angles
- if( performed )
- AxisToAngles( outAxis, out );
- else
- VectorCopy( in, out );
-
- //copy the current normal to the lastNormal
- VectorCopy( in, cg.lastVangles );
- VectorCopy( surfNormal, cg.lastNormal );
-}
-
-/*
-===============
-CG_smoothWJTransitions
-===============
-*/
-static void CG_smoothWJTransitions( playerState_t *ps, const vec3_t in, vec3_t out )
-{
- int i;
- float stLocal, sFraction;
- qboolean performed = qfalse;
- vec3_t inAxis[ 3 ], outAxis[ 3 ];
-
- if( cg.snap->ps.pm_flags & PMF_FOLLOW )
- {
- VectorCopy( in, out );
- return;
- }
-
- AnglesToAxis( in, inAxis );
-
- //iterate through ops
- for( i = MAXSMOOTHS - 1; i >= 0; i-- )
- {
- //if this op has time remaining, perform it
- if( cg.time < cg.sList[ i ].time + cg_wwSmoothTime.integer )
- {
- stLocal = ( ( cg.sList[ i ].time + cg_wwSmoothTime.integer ) - cg.time ) / cg_wwSmoothTime.integer;
- sFraction = 1.0f - ( ( cos( stLocal * M_PI * 2.0f ) + 1.0f ) / 2.0f );
-
- RotatePointAroundVector( outAxis[ 0 ], cg.sList[ i ].rotAxis,
- inAxis[ 0 ], sFraction * cg.sList[ i ].rotAngle );
- RotatePointAroundVector( outAxis[ 1 ], cg.sList[ i ].rotAxis,
- inAxis[ 1 ], sFraction * cg.sList[ i ].rotAngle );
- RotatePointAroundVector( outAxis[ 2 ], cg.sList[ i ].rotAxis,
- inAxis[ 2 ], sFraction * cg.sList[ i ].rotAngle );
-
- AxisCopy( outAxis, inAxis );
- performed = qtrue;
- }
- }
-
- //if we performed any ops then return the smoothed angles
- //otherwise simply return the in angles
- if( performed )
- AxisToAngles( outAxis, out );
- else
- VectorCopy( in, out );
-}
-
-
-/*
-===============
-CG_CalcViewValues
-
-Sets cg.refdef view values
-===============
-*/
-static int CG_CalcViewValues( void )
-{
- playerState_t *ps;
-
- memset( &cg.refdef, 0, sizeof( cg.refdef ) );
-
- // calculate size of 3D view
- CG_CalcVrect( );
-
- ps = &cg.predictedPlayerState;
-
- // intermission view
- if( ps->pm_type == PM_INTERMISSION )
- {
- VectorCopy( ps->origin, cg.refdef.vieworg );
- VectorCopy( ps->viewangles, cg.refdefViewAngles );
- AnglesToAxis( cg.refdefViewAngles, cg.refdef.viewaxis );
-
- return CG_CalcFov( );
- }
-
- cg.bobcycle = ( ps->bobCycle & 128 ) >> 7;
- cg.bobfracsin = fabs( sin( ( ps->bobCycle & 127 ) / 127.0 * M_PI ) );
- cg.xyspeed = sqrt( ps->velocity[ 0 ] * ps->velocity[ 0 ] +
- ps->velocity[ 1 ] * ps->velocity[ 1 ] );
-
- VectorCopy( ps->origin, cg.refdef.vieworg );
-
- if( BG_ClassHasAbility( ps->stats[ STAT_PCLASS ], SCA_WALLCLIMBER ) )
- CG_smoothWWTransitions( ps, ps->viewangles, cg.refdefViewAngles );
- else if( BG_ClassHasAbility( ps->stats[ STAT_PCLASS ], SCA_WALLJUMPER ) )
- CG_smoothWJTransitions( ps, ps->viewangles, cg.refdefViewAngles );
- else
- VectorCopy( ps->viewangles, cg.refdefViewAngles );
-
- //clumsy logic, but it needs to be this way round because the CS propogation
- //delay screws things up otherwise
- if( !BG_ClassHasAbility( ps->stats[ STAT_PCLASS ], SCA_WALLJUMPER ) )
- {
- if( !( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) )
- VectorSet( cg.lastNormal, 0.0f, 0.0f, 1.0f );
- }
-
- // add error decay
- if( cg_errorDecay.value > 0 )
- {
- int t;
- float f;
-
- t = cg.time - cg.predictedErrorTime;
- f = ( cg_errorDecay.value - t ) / cg_errorDecay.value;
-
- if( f > 0 && f < 1 )
- VectorMA( cg.refdef.vieworg, f, cg.predictedError, cg.refdef.vieworg );
- else
- cg.predictedErrorTime = 0;
- }
-
- //shut off the poison cloud effect if it's still on the go
- if( cg.snap->ps.stats[ STAT_HEALTH ] <= 0 )
- {
- if( CG_IsParticleSystemValid( &cg.poisonCloudPS ) )
- CG_DestroyParticleSystem( &cg.poisonCloudPS );
- }
-
- if( cg.renderingThirdPerson )
- {
- // back away from character
- CG_OffsetThirdPersonView( );
- }
- else
- {
- // offset for local bobbing and kicks
- CG_OffsetFirstPersonView( );
- }
-
- // position eye reletive to origin
- AnglesToAxis( cg.refdefViewAngles, cg.refdef.viewaxis );
-
- if( cg.hyperspace )
- cg.refdef.rdflags |= RDF_NOWORLDMODEL | RDF_HYPERSPACE;
-
- //draw the surface normal looking at
- if( cg_drawSurfNormal.integer )
- CG_DrawSurfNormal( );
-
- // field of view
- return CG_CalcFov( );
-}
-
-/*
-=====================
-CG_AddBufferedSound
-=====================
-*/
-void CG_AddBufferedSound( sfxHandle_t sfx )
-{
- if( !sfx )
- return;
-
- cg.soundBuffer[ cg.soundBufferIn ] = sfx;
- cg.soundBufferIn = ( cg.soundBufferIn + 1 ) % MAX_SOUNDBUFFER;
-
- if( cg.soundBufferIn == cg.soundBufferOut )
- cg.soundBufferOut++;
-}
-
-/*
-=====================
-CG_PlayBufferedSounds
-=====================
-*/
-static void CG_PlayBufferedSounds( void )
-{
- if( cg.soundTime < cg.time )
- {
- if( cg.soundBufferOut != cg.soundBufferIn && cg.soundBuffer[ cg.soundBufferOut ] )
- {
- trap_S_StartLocalSound( cg.soundBuffer[ cg.soundBufferOut ], CHAN_ANNOUNCER );
- cg.soundBuffer[ cg.soundBufferOut ] = 0;
- cg.soundBufferOut = ( cg.soundBufferOut + 1 ) % MAX_SOUNDBUFFER;
- cg.soundTime = cg.time + 750;
- }
- }
-}
-
-//=========================================================================
-
-/*
-=================
-CG_DrawActiveFrame
-
-Generates and draws a game scene and status information at the given time.
-=================
-*/
-void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback )
-{
- int inwater;
-
- cg.time = serverTime;
- cg.demoPlayback = demoPlayback;
-
- // update cvars
- CG_UpdateCvars( );
-
- // if we are only updating the screen as a loading
- // pacifier, don't even try to read snapshots
- if( cg.infoScreenText[ 0 ] != 0 )
- {
- CG_DrawLoadingScreen( );
- return;
- }
-
- // any looped sounds will be respecified as entities
- // are added to the render list
- trap_S_ClearLoopingSounds( qfalse );
-
- // clear all the render lists
- trap_R_ClearScene( );
-
- // set up cg.snap and possibly cg.nextSnap
- CG_ProcessSnapshots( );
-
- // if we haven't received any snapshots yet, all
- // we can draw is the information screen
- if( !cg.snap || ( cg.snap->snapFlags & SNAPFLAG_NOT_ACTIVE ) )
- {
- CG_DrawLoadingScreen( );
- return;
- }
-
- // let the client system know what our weapon and zoom settings are
- trap_SetUserCmdValue( cg.weaponSelect, cg.zoomSensitivity );
-
- // this counter will be bumped for every valid scene we generate
- cg.clientFrame++;
-
- // update cg.predictedPlayerState
- CG_PredictPlayerState( );
-
- // decide on third person view
- cg.renderingThirdPerson = cg_thirdPerson.integer || ( cg.snap->ps.stats[ STAT_HEALTH ] <= 0 );
-
- // build cg.refdef
- inwater = CG_CalcViewValues( );
-
- // build the render lists
- if( !cg.hyperspace )
- {
- CG_AddPacketEntities( ); // after calcViewValues, so predicted player state is correct
- CG_AddMarks( );
- }
-
- CG_AddViewWeapon( &cg.predictedPlayerState );
-
- //after CG_AddViewWeapon
- if( !cg.hyperspace )
- {
- CG_AddParticles( );
- CG_AddTrails( );
- }
-
- // add buffered sounds
- CG_PlayBufferedSounds( );
-
- // finish up the rest of the refdef
- if( cg.testModelEntity.hModel )
- CG_AddTestModel( );
-
- cg.refdef.time = cg.time;
- memcpy( cg.refdef.areamask, cg.snap->areamask, sizeof( cg.refdef.areamask ) );
-
- //remove expired console lines
- if( cg.consoleLines[ 0 ].time + cg_consoleLatency.integer < cg.time && cg_consoleLatency.integer > 0 )
- CG_RemoveConsoleLine( );
-
- // update audio positions
- trap_S_Respatialize( cg.snap->ps.clientNum, cg.refdef.vieworg, cg.refdef.viewaxis, inwater );
-
- // make sure the lagometerSample and frame timing isn't done twice when in stereo
- if( stereoView != STEREO_RIGHT )
- {
- cg.frametime = cg.time - cg.oldTime;
-
- if( cg.frametime < 0 )
- cg.frametime = 0;
-
- cg.oldTime = cg.time;
- CG_AddLagometerFrameInfo( );
- }
-
- if( cg_timescale.value != cg_timescaleFadeEnd.value )
- {
- if( cg_timescale.value < cg_timescaleFadeEnd.value )
- {
- cg_timescale.value += cg_timescaleFadeSpeed.value * ( (float)cg.frametime ) / 1000;
- if( cg_timescale.value > cg_timescaleFadeEnd.value )
- cg_timescale.value = cg_timescaleFadeEnd.value;
- }
- else
- {
- cg_timescale.value -= cg_timescaleFadeSpeed.value * ( (float)cg.frametime ) / 1000;
- if( cg_timescale.value < cg_timescaleFadeEnd.value )
- cg_timescale.value = cg_timescaleFadeEnd.value;
- }
-
- if( cg_timescaleFadeSpeed.value )
- trap_Cvar_Set( "timescale", va( "%f", cg_timescale.value ) );
- }
-
- // actually issue the rendering calls
- CG_DrawActive( stereoView );
-
- if( cg_stats.integer )
- CG_Printf( "cg.clientFrame:%i\n", cg.clientFrame );
-}
-
diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c
deleted file mode 100644
index 7297c518..00000000
--- a/src/cgame/cg_weapons.c
+++ /dev/null
@@ -1,1810 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-// cg_weapons.c -- events and effects dealing with weapons
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "cg_local.h"
-
-/*
-=================
-CG_RegisterUpgrade
-
-The server says this item is used on this level
-=================
-*/
-void CG_RegisterUpgrade( int upgradeNum )
-{
- upgradeInfo_t *upgradeInfo;
- char *icon;
-
- upgradeInfo = &cg_upgrades[ upgradeNum ];
-
- if( upgradeNum == 0 )
- return;
-
- if( upgradeInfo->registered )
- return;
-
- memset( upgradeInfo, 0, sizeof( *upgradeInfo ) );
- upgradeInfo->registered = qtrue;
-
- if( !BG_FindNameForUpgrade( upgradeNum ) )
- CG_Error( "Couldn't find upgrade %i", upgradeNum );
-
- upgradeInfo->humanName = BG_FindHumanNameForUpgrade( upgradeNum );
-
- //la la la la la, i'm not listening!
- if( upgradeNum == UP_GRENADE )
- upgradeInfo->upgradeIcon = cg_weapons[ WP_GRENADE ].weaponIcon;
- else if( ( icon = BG_FindIconForUpgrade( upgradeNum ) ) )
- upgradeInfo->upgradeIcon = trap_R_RegisterShader( icon );
-}
-
-/*
-===============
-CG_InitUpgrades
-
-Precaches upgrades
-===============
-*/
-void CG_InitUpgrades( void )
-{
- int i;
-
- memset( cg_upgrades, 0, sizeof( cg_upgrades ) );
-
- for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
- CG_RegisterUpgrade( i );
-}
-
-
-/*
-===============
-CG_ParseWeaponModeSection
-
-Parse a weapon mode section
-===============
-*/
-static qboolean CG_ParseWeaponModeSection( weaponInfoMode_t *wim, char **text_p )
-{
- char *token;
- int i;
-
- // read optional parameters
- while( 1 )
- {
- token = COM_Parse( text_p );
-
- if( !token )
- break;
-
- if( !Q_stricmp( token, "" ) )
- return qfalse;
-
- if( !Q_stricmp( token, "missileModel" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->missileModel = trap_R_RegisterModel( token );
-
- if( !wim->missileModel )
- CG_Printf( S_COLOR_RED "ERROR: missile model not found %s\n", token );
-
- continue;
- }
- else if( !Q_stricmp( token, "missileSprite" ) )
- {
- int size = 0;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- size = atoi( token );
-
- if( size < 0 )
- size = 0;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->missileSprite = trap_R_RegisterShader( token );
- wim->missileSpriteSize = size;
- wim->usesSpriteMissle = qtrue;
-
- if( !wim->missileSprite )
- CG_Printf( S_COLOR_RED "ERROR: missile sprite not found %s\n", token );
-
- continue;
- }
- else if( !Q_stricmp( token, "missileRotates" ) )
- {
- wim->missileRotates = qtrue;
-
- continue;
- }
- else if( !Q_stricmp( token, "missileAnimates" ) )
- {
- wim->missileAnimates = qtrue;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->missileAnimStartFrame = atoi( token );
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->missileAnimNumFrames = atoi( token );
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->missileAnimFrameRate = atoi( token );
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->missileAnimLooping = atoi( token );
-
- continue;
- }
- else if( !Q_stricmp( token, "missileParticleSystem" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->missileParticleSystem = CG_RegisterParticleSystem( token );
-
- if( !wim->missileParticleSystem )
- CG_Printf( S_COLOR_RED "ERROR: missile particle system not found %s\n", token );
-
- continue;
- }
- else if( !Q_stricmp( token, "missileTrailSystem" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->missileTrailSystem = CG_RegisterTrailSystem( token );
-
- if( !wim->missileTrailSystem )
- CG_Printf( S_COLOR_RED "ERROR: missile trail system not found %s\n", token );
-
- continue;
- }
- else if( !Q_stricmp( token, "muzzleParticleSystem" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->muzzleParticleSystem = CG_RegisterParticleSystem( token );
-
- if( !wim->muzzleParticleSystem )
- CG_Printf( S_COLOR_RED "ERROR: muzzle particle system not found %s\n", token );
-
- continue;
- }
- else if( !Q_stricmp( token, "impactParticleSystem" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->impactParticleSystem = CG_RegisterParticleSystem( token );
-
- if( !wim->impactParticleSystem )
- CG_Printf( S_COLOR_RED "ERROR: impact particle system not found %s\n", token );
-
- continue;
- }
- else if( !Q_stricmp( token, "impactMark" ) )
- {
- int size = 0;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- size = atoi( token );
-
- if( size < 0 )
- size = 0;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->impactMark = trap_R_RegisterShader( token );
- wim->impactMarkSize = size;
-
- if( !wim->impactMark )
- CG_Printf( S_COLOR_RED "ERROR: impact mark shader not found %s\n", token );
-
- continue;
- }
- else if( !Q_stricmp( token, "impactSound" ) )
- {
- int index = 0;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- index = atoi( token );
-
- if( index < 0 )
- index = 0;
- else if( index > 3 )
- index = 3;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->impactSound[ index ] = trap_S_RegisterSound( token, qfalse );
-
- continue;
- }
- else if( !Q_stricmp( token, "impactFleshSound" ) )
- {
- int index = 0;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- index = atoi( token );
-
- if( index < 0 )
- index = 0;
- else if( index > 3 )
- index = 3;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->impactFleshSound[ index ] = trap_S_RegisterSound( token, qfalse );
-
- continue;
- }
- else if( !Q_stricmp( token, "alwaysImpact" ) )
- {
- wim->alwaysImpact = qtrue;
-
- continue;
- }
- else if( !Q_stricmp( token, "flashDLightColor" ) )
- {
- for( i = 0 ; i < 3 ; i++ )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->flashDlightColor[ i ] = atof( token );
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "continuousFlash" ) )
- {
- wim->continuousFlash = qtrue;
-
- continue;
- }
- else if( !Q_stricmp( token, "missileDlightColor" ) )
- {
- for( i = 0 ; i < 3 ; i++ )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->missileDlightColor[ i ] = atof( token );
- }
-
- continue;
- }
- else if( !Q_stricmp( token, "missileDlight" ) )
- {
- int size = 0;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- size = atoi( token );
-
- if( size < 0 )
- size = 0;
-
- wim->missileDlight = size;
-
- continue;
- }
- else if( !Q_stricmp( token, "firingSound" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->firingSound = trap_S_RegisterSound( token, qfalse );
-
- continue;
- }
- else if( !Q_stricmp( token, "missileSound" ) )
- {
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->missileSound = trap_S_RegisterSound( token, qfalse );
-
- continue;
- }
- else if( !Q_stricmp( token, "flashSound" ) )
- {
- int index = 0;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- index = atoi( token );
-
- if( index < 0 )
- index = 0;
- else if( index > 3 )
- index = 3;
-
- token = COM_Parse( text_p );
- if( !token )
- break;
-
- wim->flashSound[ index ] = trap_S_RegisterSound( token, qfalse );
-
- continue;
- }
- else if( !Q_stricmp( token, "}" ) )
- return qtrue; //reached the end of this weapon section
- else
- {
- CG_Printf( S_COLOR_RED "ERROR: unknown token '%s' in weapon section\n", token );
- return qfalse;
- }
- }
-
- return qfalse;
-}
-
-
-/*
-======================
-CG_ParseWeaponFile
-
-Parses a configuration file describing a weapon
-======================
-*/
-static qboolean CG_ParseWeaponFile( const char *filename, weaponInfo_t *wi )
-{
- char *text_p;
- int len;
- char *token;
- char text[ 20000 ];
- fileHandle_t f;
- weaponMode_t weaponMode = WPM_NONE;
-
- // load the file
- len = trap_FS_FOpenFile( filename, &f, FS_READ );
- if( len <= 0 )
- return qfalse;
-
- if( len >= sizeof( text ) - 1 )
- {
- CG_Printf( "File %s too long\n", filename );
- return qfalse;
- }
-
- trap_FS_Read( text, len, f );
- text[ len ] = 0;
- trap_FS_FCloseFile( f );
-
- // parse the text
- text_p = text;
-
- // read optional parameters
- while( 1 )
- {
- token = COM_Parse( &text_p );
-
- if( !token )
- break;
-
- if( !Q_stricmp( token, "" ) )
- break;
-
- if( !Q_stricmp( token, "{" ) )
- {
- if( weaponMode == WPM_NONE )
- {
- CG_Printf( S_COLOR_RED "ERROR: weapon mode section started without a declaration\n" );
- return qfalse;
- }
- else if( !CG_ParseWeaponModeSection( &wi->wim[ weaponMode ], &text_p ) )
- {
- CG_Printf( S_COLOR_RED "ERROR: failed to parse weapon mode section\n" );
- return qfalse;
- }
-
- //start parsing ejectors again
- weaponMode = WPM_NONE;
-
- continue;
- }
- else if( !Q_stricmp( token, "primary" ) )
- {
- weaponMode = WPM_PRIMARY;
- continue;
- }
- else if( !Q_stricmp( token, "secondary" ) )
- {
- weaponMode = WPM_SECONDARY;
- continue;
- }
- else if( !Q_stricmp( token, "tertiary" ) )
- {
- weaponMode = WPM_TERTIARY;
- continue;
- }
- else if( !Q_stricmp( token, "weaponModel" ) )
- {
- char path[ MAX_QPATH ];
-
- token = COM_Parse( &text_p );
- if( !token )
- break;
-
- wi->weaponModel = trap_R_RegisterModel( token );
-
- if( !wi->weaponModel )
- CG_Printf( S_COLOR_RED "ERROR: weapon model not found %s\n", token );
-
- strcpy( path, token );
- COM_StripExtension( path, path );
- strcat( path, "_flash.md3" );
- wi->flashModel = trap_R_RegisterModel( path );
-
- strcpy( path, token );
- COM_StripExtension( path, path );
- strcat( path, "_barrel.md3" );
- wi->barrelModel = trap_R_RegisterModel( path );
-
- strcpy( path, token );
- COM_StripExtension( path, path );
- strcat( path, "_hand.md3" );
- wi->handsModel = trap_R_RegisterModel( path );
-
- if( !wi->handsModel )
- wi->handsModel = trap_R_RegisterModel( "models/weapons2/shotgun/shotgun_hand.md3" );
-
- continue;
- }
- else if( !Q_stricmp( token, "idleSound" ) )
- {
- token = COM_Parse( &text_p );
- if( !token )
- break;
-
- wi->readySound = trap_S_RegisterSound( token, qfalse );
-
- continue;
- }
- else if( !Q_stricmp( token, "icon" ) )
- {
- token = COM_Parse( &text_p );
- if( !token )
- break;
-
- wi->weaponIcon = wi->ammoIcon = trap_R_RegisterShader( token );
-
- if( !wi->weaponIcon )
- CG_Printf( S_COLOR_RED "ERROR: weapon icon not found %s\n", token );
-
- continue;
- }
- else if( !Q_stricmp( token, "crosshair" ) )
- {
- int size = 0;
-
- token = COM_Parse( &text_p );
- if( !token )
- break;
-
- size = atoi( token );
-
- if( size < 0 )
- size = 0;
-
- token = COM_Parse( &text_p );
- if( !token )
- break;
-
- wi->crossHair = trap_R_RegisterShader( token );
- wi->crossHairSize = size;
-
- if( !wi->crossHair )
- CG_Printf( S_COLOR_RED "ERROR: weapon crosshair not found %s\n", token );
-
- continue;
- }
- else if( !Q_stricmp( token, "disableIn3rdPerson" ) )
- {
- wi->disableIn3rdPerson = qtrue;
-
- continue;
- }
-
- Com_Printf( S_COLOR_RED "ERROR: unknown token '%s'\n", token );
- return qfalse;
- }
-
- return qtrue;
-}
-
-/*
-=================
-CG_RegisterWeapon
-=================
-*/
-void CG_RegisterWeapon( int weaponNum )
-{
- weaponInfo_t *weaponInfo;
- char path[ MAX_QPATH ];
- vec3_t mins, maxs;
- int i;
-
- weaponInfo = &cg_weapons[ weaponNum ];
-
- if( weaponNum == 0 )
- return;
-
- if( weaponInfo->registered )
- return;
-
- memset( weaponInfo, 0, sizeof( *weaponInfo ) );
- weaponInfo->registered = qtrue;
-
- if( !BG_FindNameForWeapon( weaponNum ) )
- CG_Error( "Couldn't find weapon %i", weaponNum );
-
- Com_sprintf( path, MAX_QPATH, "models/weapons/%s/weapon.cfg", BG_FindNameForWeapon( weaponNum ) );
-
- weaponInfo->humanName = BG_FindHumanNameForWeapon( weaponNum );
-
- if( !CG_ParseWeaponFile( path, weaponInfo ) )
- Com_Printf( S_COLOR_RED "ERROR: failed to parse %s\n", path );
-
- // calc midpoint for rotation
- trap_R_ModelBounds( weaponInfo->weaponModel, mins, maxs );
- for( i = 0 ; i < 3 ; i++ )
- weaponInfo->weaponMidpoint[ i ] = mins[ i ] + 0.5 * ( maxs[ i ] - mins[ i ] );
-
- //FIXME:
- for( i = WPM_NONE + 1; i < WPM_NUM_WEAPONMODES; i++ )
- weaponInfo->wim[ i ].loopFireSound = qfalse;
-}
-
-/*
-===============
-CG_InitWeapons
-
-Precaches weapons
-===============
-*/
-void CG_InitWeapons( void )
-{
- int i;
-
- memset( cg_weapons, 0, sizeof( cg_weapons ) );
-
- for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
- CG_RegisterWeapon( i );
-
- cgs.media.level2ZapTS = CG_RegisterTrailSystem( "models/weapons/lev2zap/lightning" );
-}
-
-
-/*
-========================================================================================
-
-VIEW WEAPON
-
-========================================================================================
-*/
-
-/*
-=================
-CG_MapTorsoToWeaponFrame
-
-=================
-*/
-static int CG_MapTorsoToWeaponFrame( clientInfo_t *ci, int frame )
-{
-
- // change weapon
- if( frame >= ci->animations[ TORSO_DROP ].firstFrame &&
- frame < ci->animations[ TORSO_DROP ].firstFrame + 9 )
- return frame - ci->animations[ TORSO_DROP ].firstFrame + 6;
-
- // stand attack
- if( frame >= ci->animations[ TORSO_ATTACK ].firstFrame &&
- frame < ci->animations[ TORSO_ATTACK ].firstFrame + 6 )
- return 1 + frame - ci->animations[ TORSO_ATTACK ].firstFrame;
-
- // stand attack 2
- if( frame >= ci->animations[ TORSO_ATTACK2 ].firstFrame &&
- frame < ci->animations[ TORSO_ATTACK2 ].firstFrame + 6 )
- return 1 + frame - ci->animations[ TORSO_ATTACK2 ].firstFrame;
-
- return 0;
-}
-
-
-/*
-==============
-CG_CalculateWeaponPosition
-==============
-*/
-static void CG_CalculateWeaponPosition( vec3_t origin, vec3_t angles )
-{
- float scale;
- int delta;
- float fracsin;
- float bob;
-
- VectorCopy( cg.refdef.vieworg, origin );
- VectorCopy( cg.refdefViewAngles, angles );
-
- // on odd legs, invert some angles
- if( cg.bobcycle & 1 )
- scale = -cg.xyspeed;
- else
- scale = cg.xyspeed;
-
- // gun angles from bobbing
- //TA: bob amount is class dependant
- bob = BG_FindBobForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] );
-
- if( bob != 0 )
- {
- angles[ ROLL ] += scale * cg.bobfracsin * 0.005;
- angles[ YAW ] += scale * cg.bobfracsin * 0.01;
- angles[ PITCH ] += cg.xyspeed * cg.bobfracsin * 0.005;
- }
-
- // drop the weapon when landing
- if( !BG_ClassHasAbility( cg.predictedPlayerState.stats[ STAT_PCLASS ], SCA_NOWEAPONDRIFT ) )
- {
- delta = cg.time - cg.landTime;
- if( delta < LAND_DEFLECT_TIME )
- origin[ 2 ] += cg.landChange*0.25 * delta / LAND_DEFLECT_TIME;
- else if( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME )
- origin[ 2 ] += cg.landChange*0.25 *
- ( LAND_DEFLECT_TIME + LAND_RETURN_TIME - delta ) / LAND_RETURN_TIME;
-
- // idle drift
- scale = cg.xyspeed + 40;
- fracsin = sin( cg.time * 0.001 );
- angles[ ROLL ] += scale * fracsin * 0.01;
- angles[ YAW ] += scale * fracsin * 0.01;
- angles[ PITCH ] += scale * fracsin * 0.01;
- }
-}
-
-
-/*
-======================
-CG_MachinegunSpinAngle
-======================
-*/
-#define SPIN_SPEED 0.9
-#define COAST_TIME 1000
-static float CG_MachinegunSpinAngle( centity_t *cent )
-{
- int delta;
- float angle;
- float speed;
-
- delta = cg.time - cent->pe.barrelTime;
- if( cent->pe.barrelSpinning )
- angle = cent->pe.barrelAngle + delta * SPIN_SPEED;
- else
- {
- if( delta > COAST_TIME )
- delta = COAST_TIME;
-
- speed = 0.5 * ( SPIN_SPEED + (float)( COAST_TIME - delta ) / COAST_TIME );
- angle = cent->pe.barrelAngle + delta * speed;
- }
-
- if( cent->pe.barrelSpinning == !( cent->currentState.eFlags & EF_FIRING ) )
- {
- cent->pe.barrelTime = cg.time;
- cent->pe.barrelAngle = AngleMod( angle );
- cent->pe.barrelSpinning = !!( cent->currentState.eFlags & EF_FIRING );
- //TA: um?
- }
-
- return angle;
-}
-
-
-/*
-=============
-CG_AddPlayerWeapon
-
-Used for both the view weapon (ps is valid) and the world modelother character models (ps is NULL)
-The main player will have this called for BOTH cases, so effects like light and
-sound should only be done on the world model case.
-=============
-*/
-void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent )
-{
- refEntity_t gun;
- refEntity_t barrel;
- refEntity_t flash;
- vec3_t angles;
- weapon_t weaponNum;
- weaponMode_t weaponMode;
- weaponInfo_t *weapon;
- qboolean noGunModel;
- qboolean firing;
-
- weaponNum = cent->currentState.weapon;
- weaponMode = cent->currentState.generic1;
-
- if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES )
- weaponMode = WPM_PRIMARY;
-
- if( ( ( cent->currentState.eFlags & EF_FIRING ) && weaponMode == WPM_PRIMARY ) ||
- ( ( cent->currentState.eFlags & EF_FIRING2 ) && weaponMode == WPM_SECONDARY ) ||
- ( ( cent->currentState.eFlags & EF_FIRING3 ) && weaponMode == WPM_TERTIARY ) )
- firing = qtrue;
- else
- firing = qfalse;
-
- CG_RegisterWeapon( weaponNum );
- weapon = &cg_weapons[ weaponNum ];
-
- // add the weapon
- memset( &gun, 0, sizeof( gun ) );
- VectorCopy( parent->lightingOrigin, gun.lightingOrigin );
- gun.shadowPlane = parent->shadowPlane;
- gun.renderfx = parent->renderfx;
-
- // set custom shading for railgun refire rate
- if( ps )
- {
- gun.shaderRGBA[ 0 ] = 255;
- gun.shaderRGBA[ 1 ] = 255;
- gun.shaderRGBA[ 2 ] = 255;
- gun.shaderRGBA[ 3 ] = 255;
-
- //set weapon[1/2]Time when respective buttons change state
- if( cg.weapon1Firing != ( cg.predictedPlayerState.eFlags & EF_FIRING ) )
- {
- cg.weapon1Time = cg.time;
- cg.weapon1Firing = ( cg.predictedPlayerState.eFlags & EF_FIRING );
- }
-
- if( cg.weapon2Firing != ( cg.predictedPlayerState.eFlags & EF_FIRING2 ) )
- {
- cg.weapon2Time = cg.time;
- cg.weapon2Firing = ( cg.predictedPlayerState.eFlags & EF_FIRING2 );
- }
-
- if( cg.weapon3Firing != ( cg.predictedPlayerState.eFlags & EF_FIRING3 ) )
- {
- cg.weapon3Time = cg.time;
- cg.weapon3Firing = ( cg.predictedPlayerState.eFlags & EF_FIRING3 );
- }
- }
-
- gun.hModel = weapon->weaponModel;
-
- noGunModel = ( ( !ps || cg.renderingThirdPerson ) && weapon->disableIn3rdPerson ) || !gun.hModel;
-
- if( !ps )
- {
- // add weapon ready sound
- if( firing && weapon->wim[ weaponMode ].firingSound )
- {
- trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin,
- weapon->wim[ weaponMode ].firingSound );
- }
- else if( weapon->readySound )
- trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, weapon->readySound );
- }
-
- if( !noGunModel )
- {
- CG_PositionEntityOnTag( &gun, parent, parent->hModel, "tag_weapon" );
-
- trap_R_AddRefEntityToScene( &gun );
-
- // add the spinning barrel
- if( weapon->barrelModel )
- {
- memset( &barrel, 0, sizeof( barrel ) );
- VectorCopy( parent->lightingOrigin, barrel.lightingOrigin );
- barrel.shadowPlane = parent->shadowPlane;
- barrel.renderfx = parent->renderfx;
-
- barrel.hModel = weapon->barrelModel;
- angles[ YAW ] = 0;
- angles[ PITCH ] = 0;
- angles[ ROLL ] = CG_MachinegunSpinAngle( cent );
- AnglesToAxis( angles, barrel.axis );
-
- CG_PositionRotatedEntityOnTag( &barrel, &gun, weapon->weaponModel, "tag_barrel" );
-
- trap_R_AddRefEntityToScene( &barrel );
- }
- }
-
- if( CG_IsParticleSystemValid( &cent->muzzlePS ) )
- {
- if( ps || cg.renderingThirdPerson ||
- cent->currentState.number != cg.predictedPlayerState.clientNum )
- {
- if( noGunModel )
- CG_SetAttachmentTag( &cent->muzzlePS->attachment, *parent, parent->hModel, "tag_weapon" );
- else
- CG_SetAttachmentTag( &cent->muzzlePS->attachment, gun, weapon->weaponModel, "tag_flash" );
- }
-
- //if the PS is infinite disable it when not firing
- if( !firing && CG_IsParticleSystemInfinite( cent->muzzlePS ) )
- CG_DestroyParticleSystem( &cent->muzzlePS );
- }
-
- // add the flash
- if( !weapon->wim[ weaponMode ].continuousFlash || !firing )
- {
- // impulse flash
- if( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME )
- return;
- }
-
- memset( &flash, 0, sizeof( flash ) );
- VectorCopy( parent->lightingOrigin, flash.lightingOrigin );
- flash.shadowPlane = parent->shadowPlane;
- flash.renderfx = parent->renderfx;
-
- flash.hModel = weapon->flashModel;
- if( flash.hModel )
- {
- angles[ YAW ] = 0;
- angles[ PITCH ] = 0;
- angles[ ROLL ] = crandom( ) * 10;
- AnglesToAxis( angles, flash.axis );
-
- if( noGunModel )
- CG_PositionRotatedEntityOnTag( &flash, parent, parent->hModel, "tag_weapon" );
- else
- CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash" );
-
- trap_R_AddRefEntityToScene( &flash );
- }
-
- if( ps || cg.renderingThirdPerson ||
- cent->currentState.number != cg.predictedPlayerState.clientNum )
- {
- if( weapon->wim[ weaponMode ].muzzleParticleSystem && cent->muzzlePsTrigger )
- {
- cent->muzzlePS = CG_SpawnNewParticleSystem( weapon->wim[ weaponMode ].muzzleParticleSystem );
-
- if( CG_IsParticleSystemValid( &cent->muzzlePS ) )
- {
- if( noGunModel )
- CG_SetAttachmentTag( &cent->muzzlePS->attachment, *parent, parent->hModel, "tag_weapon" );
- else
- CG_SetAttachmentTag( &cent->muzzlePS->attachment, gun, weapon->weaponModel, "tag_flash" );
-
- CG_SetAttachmentCent( &cent->muzzlePS->attachment, cent );
- CG_AttachToTag( &cent->muzzlePS->attachment );
- }
-
- cent->muzzlePsTrigger = qfalse;
- }
-
- // make a dlight for the flash
- if( weapon->wim[ weaponMode ].flashDlightColor[ 0 ] ||
- weapon->wim[ weaponMode ].flashDlightColor[ 1 ] ||
- weapon->wim[ weaponMode ].flashDlightColor[ 2 ] )
- {
- trap_R_AddLightToScene( flash.origin, 300 + ( rand( ) & 31 ),
- weapon->wim[ weaponMode ].flashDlightColor[ 0 ],
- weapon->wim[ weaponMode ].flashDlightColor[ 1 ],
- weapon->wim[ weaponMode ].flashDlightColor[ 2 ] );
- }
- }
-}
-
-/*
-==============
-CG_AddViewWeapon
-
-Add the weapon, and flash for the player's view
-==============
-*/
-void CG_AddViewWeapon( playerState_t *ps )
-{
- refEntity_t hand;
- centity_t *cent;
- clientInfo_t *ci;
- float fovOffset;
- vec3_t angles;
- weaponInfo_t *wi;
- weapon_t weapon = ps->weapon;
- weaponMode_t weaponMode = ps->generic1;
-
- if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES )
- weaponMode = WPM_PRIMARY;
-
- CG_RegisterWeapon( weapon );
- wi = &cg_weapons[ weapon ];
- cent = &cg.predictedPlayerEntity; // &cg_entities[cg.snap->ps.clientNum];
-
- if( ( ps->persistant[PERS_TEAM] == TEAM_SPECTATOR ) ||
- ( ps->stats[ STAT_STATE ] & SS_INFESTING ) ||
- ( ps->stats[ STAT_STATE ] & SS_HOVELING ) )
- return;
-
- //TA: no weapon carried - can't draw it
- if( weapon == WP_NONE )
- return;
-
- if( ps->pm_type == PM_INTERMISSION )
- return;
-
- //TA: draw a prospective buildable infront of the player
- if( ( ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) > BA_NONE )
- CG_GhostBuildable( ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT );
-
- if( weapon == WP_LUCIFER_CANNON && ps->stats[ STAT_MISC ] > 0 )
- {
- if( ps->stats[ STAT_MISC ] > ( LCANNON_TOTAL_CHARGE - ( LCANNON_TOTAL_CHARGE / 3 ) ) )
- trap_S_AddLoopingSound( ps->clientNum, ps->origin, vec3_origin, cgs.media.lCannonWarningSound );
- }
-
- // no gun if in third person view
- if( cg.renderingThirdPerson )
- return;
-
- // allow the gun to be completely removed
- if( !cg_drawGun.integer )
- {
- vec3_t origin;
-
- VectorCopy( cg.refdef.vieworg, origin );
- VectorMA( origin, -8, cg.refdef.viewaxis[ 2 ], origin );
-
- if( cent->muzzlePS )
- CG_SetAttachmentPoint( &cent->muzzlePS->attachment, origin );
-
- //check for particle systems
- if( wi->wim[ weaponMode ].muzzleParticleSystem && cent->muzzlePsTrigger )
- {
- cent->muzzlePS = CG_SpawnNewParticleSystem( wi->wim[ weaponMode ].muzzleParticleSystem );
-
- if( CG_IsParticleSystemValid( &cent->muzzlePS ) )
- {
- CG_SetAttachmentPoint( &cent->muzzlePS->attachment, origin );
- CG_SetAttachmentCent( &cent->muzzlePS->attachment, cent );
- CG_AttachToPoint( &cent->muzzlePS->attachment );
- }
- cent->muzzlePsTrigger = qfalse;
- }
-
- return;
- }
-
- // don't draw if testing a gun model
- if( cg.testGun )
- return;
-
- // drop gun lower at higher fov
- //if ( cg_fov.integer > 90 ) {
- //TA: the client side variable isn't used ( shouldn't iD have done this anyway? )
- if( cg.refdef.fov_y > 90 )
- fovOffset = -0.4 * ( cg.refdef.fov_y - 90 );
- else
- fovOffset = 0;
-
- memset( &hand, 0, sizeof( hand ) );
-
- // set up gun position
- CG_CalculateWeaponPosition( hand.origin, angles );
-
- VectorMA( hand.origin, cg_gun_x.value, cg.refdef.viewaxis[ 0 ], hand.origin );
- VectorMA( hand.origin, cg_gun_y.value, cg.refdef.viewaxis[ 1 ], hand.origin );
- VectorMA( hand.origin, ( cg_gun_z.value + fovOffset ), cg.refdef.viewaxis[ 2 ], hand.origin );
-
- if( weapon == WP_LUCIFER_CANNON && ps->stats[ STAT_MISC ] > 0 )
- {
- float fraction = (float)ps->stats[ STAT_MISC ] / (float)LCANNON_TOTAL_CHARGE;
-
- VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 0 ], hand.origin );
- VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 1 ], hand.origin );
- }
-
- AnglesToAxis( angles, hand.axis );
-
- // map torso animations to weapon animations
- if( cg_gun_frame.integer )
- {
- // development tool
- hand.frame = hand.oldframe = cg_gun_frame.integer;
- hand.backlerp = 0;
- }
- else
- {
- // get clientinfo for animation map
- ci = &cgs.clientinfo[ cent->currentState.clientNum ];
- hand.frame = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.frame );
- hand.oldframe = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.oldFrame );
- hand.backlerp = cent->pe.torso.backlerp;
- }
-
- hand.hModel = wi->handsModel;
- hand.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT;
-
- // add everything onto the hand
- CG_AddPlayerWeapon( &hand, ps, &cg.predictedPlayerEntity );
-}
-
-/*
-==============================================================================
-
-WEAPON SELECTION
-
-==============================================================================
-*/
-
-/*
-===============
-CG_WeaponSelectable
-===============
-*/
-static qboolean CG_WeaponSelectable( weapon_t weapon )
-{
- //int ammo, clips;
- //
- //BG_UnpackAmmoArray( i, cg.snap->ps.ammo, cg.snap->ps.powerups, &ammo, &clips );
- //
- //TA: this is a pain in the ass
- //if( !ammo && !clips && !BG_FindInfinteAmmoForWeapon( i ) )
- // return qfalse;
-
- if( !BG_InventoryContainsWeapon( weapon, cg.snap->ps.stats ) )
- return qfalse;
-
- return qtrue;
-}
-
-
-/*
-===============
-CG_UpgradeSelectable
-===============
-*/
-static qboolean CG_UpgradeSelectable( upgrade_t upgrade )
-{
- if( !BG_InventoryContainsUpgrade( upgrade, cg.snap->ps.stats ) )
- return qfalse;
-
- return qtrue;
-}
-
-
-#define ICON_BORDER 4
-
-/*
-===================
-CG_DrawItemSelect
-===================
-*/
-void CG_DrawItemSelect( rectDef_t *rect, vec4_t color )
-{
- int i;
- int x = rect->x;
- int y = rect->y;
- int width = rect->w;
- int height = rect->h;
- int iconsize;
- int items[ 64 ];
- int numItems = 0, selectedItem = 0;
- int length;
- int selectWindow;
- qboolean vertical;
- centity_t *cent;
- playerState_t *ps;
-
- cent = &cg_entities[ cg.snap->ps.clientNum ];
- ps = &cg.snap->ps;
-
- // don't display if dead
- if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 )
- return;
-
- if( !( cg.snap->ps.pm_flags & PMF_FOLLOW ) )
- {
- // first make sure that whatever it selected is actually selectable
- if( cg.weaponSelect <= 32 && !CG_WeaponSelectable( cg.weaponSelect ) )
- CG_NextWeapon_f( );
- else if( cg.weaponSelect > 32 && !CG_UpgradeSelectable( cg.weaponSelect ) )
- CG_NextWeapon_f( );
- }
-
- // showing weapon select clears pickup item display, but not the blend blob
- cg.itemPickupTime = 0;
-
- if( height > width )
- {
- vertical = qtrue;
- iconsize = width;
- length = height / width;
- }
- else if( height <= width )
- {
- vertical = qfalse;
- iconsize = height;
- length = width / height;
- }
-
- selectWindow = length / 2;
-
- for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
- {
- if( !BG_InventoryContainsWeapon( i, cg.snap->ps.stats ) )
- continue;
-
- if( i == cg.weaponSelect )
- selectedItem = numItems;
-
- CG_RegisterWeapon( i );
- items[ numItems ] = i;
- numItems++;
- }
-
- for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
- {
- if( !BG_InventoryContainsUpgrade( i, cg.snap->ps.stats ) )
- continue;
-
- if( i == cg.weaponSelect - 32 )
- selectedItem = numItems;
-
- CG_RegisterUpgrade( i );
- items[ numItems ] = i + 32;
- numItems++;
- }
-
- for( i = 0; i < length; i++ )
- {
- int displacement = i - selectWindow;
- int item = displacement + selectedItem;
-
- if( ( item >= 0 ) && ( item < numItems ) )
- {
- trap_R_SetColor( color );
-
- if( items[ item ] <= 32 )
- CG_DrawPic( x, y, iconsize, iconsize, cg_weapons[ items[ item ] ].weaponIcon );
- else if( items[ item ] > 32 )
- CG_DrawPic( x, y, iconsize, iconsize, cg_upgrades[ items[ item ] - 32 ].upgradeIcon );
-
- trap_R_SetColor( NULL );
-
-/* if( displacement == 0 )
- CG_DrawPic( x, y, iconsize, iconsize, cgs.media.selectShader );*/
- }
-
- if( vertical )
- y += iconsize;
- else
- x += iconsize;
- }
-}
-
-
-/*
-===================
-CG_DrawItemSelectText
-===================
-*/
-void CG_DrawItemSelectText( rectDef_t *rect, float scale, int textStyle )
-{
- int x, w;
- char *name;
- float *color;
-
- color = CG_FadeColor( cg.weaponSelectTime, WEAPON_SELECT_TIME );
- if( !color )
- return;
-
- trap_R_SetColor( color );
-
- // draw the selected name
- if( cg.weaponSelect <= 32 )
- {
- if( cg_weapons[ cg.weaponSelect ].registered &&
- BG_InventoryContainsWeapon( cg.weaponSelect, cg.snap->ps.stats ) )
- {
- if( ( name = cg_weapons[ cg.weaponSelect ].humanName ) )
- {
- w = CG_Text_Width( name, scale, 0 );
- x = rect->x + rect->w / 2;
- CG_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle );
- }
- }
- }
- else if( cg.weaponSelect > 32 )
- {
- if( cg_upgrades[ cg.weaponSelect - 32 ].registered &&
- BG_InventoryContainsUpgrade( cg.weaponSelect - 32, cg.snap->ps.stats ) )
- {
- if( ( name = cg_upgrades[ cg.weaponSelect - 32 ].humanName ) )
- {
- w = CG_Text_Width( name, scale, 0 );
- x = rect->x + rect->w / 2;
- CG_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle );
- }
- }
- }
-
- trap_R_SetColor( NULL );
-}
-
-
-/*
-===============
-CG_NextWeapon_f
-===============
-*/
-void CG_NextWeapon_f( void )
-{
- int i;
- int original;
-
- if( !cg.snap )
- return;
-
- if( cg.snap->ps.pm_flags & PMF_FOLLOW )
- {
- trap_SendClientCommand( "followprev\n" );
- return;
- }
-
- cg.weaponSelectTime = cg.time;
- original = cg.weaponSelect;
-
- for( i = 0; i < 64; i++ )
- {
- cg.weaponSelect++;
- if( cg.weaponSelect == 64 )
- cg.weaponSelect = 0;
-
- if( cg.weaponSelect <= 32 )
- {
- if( CG_WeaponSelectable( cg.weaponSelect ) )
- break;
- }
- else if( cg.weaponSelect > 32 )
- {
- if( CG_UpgradeSelectable( cg.weaponSelect - 32 ) )
- break;
- }
- }
-
- if( i == 64 )
- cg.weaponSelect = original;
-}
-
-/*
-===============
-CG_PrevWeapon_f
-===============
-*/
-void CG_PrevWeapon_f( void )
-{
- int i;
- int original;
-
- if( !cg.snap )
- return;
-
- if( cg.snap->ps.pm_flags & PMF_FOLLOW )
- {
- trap_SendClientCommand( "follownext\n" );
- return;
- }
-
- cg.weaponSelectTime = cg.time;
- original = cg.weaponSelect;
-
- for( i = 0; i < 64; i++ )
- {
- cg.weaponSelect--;
- if( cg.weaponSelect == -1 )
- cg.weaponSelect = 63;
-
- if( cg.weaponSelect <= 32 )
- {
- if( CG_WeaponSelectable( cg.weaponSelect ) )
- break;
- }
- else if( cg.weaponSelect > 32 )
- {
- if( CG_UpgradeSelectable( cg.weaponSelect - 32 ) )
- break;
- }
- }
-
- if( i == 64 )
- cg.weaponSelect = original;
-}
-
-/*
-===============
-CG_Weapon_f
-===============
-*/
-void CG_Weapon_f( void )
-{
- int num;
-
- if( !cg.snap )
- return;
-
- if( cg.snap->ps.pm_flags & PMF_FOLLOW )
- return;
-
- num = atoi( CG_Argv( 1 ) );
-
- if( num < 1 || num > 31 )
- return;
-
- cg.weaponSelectTime = cg.time;
-
- if( !BG_InventoryContainsWeapon( num, cg.snap->ps.stats ) )
- return; // don't have the weapon
-
- cg.weaponSelect = num;
-}
-
-
-/*
-===================================================================================================
-
-WEAPON EVENTS
-
-===================================================================================================
-*/
-
-/*
-================
-CG_FireWeapon
-
-Caused by an EV_FIRE_WEAPON event
-================
-*/
-void CG_FireWeapon( centity_t *cent, weaponMode_t weaponMode )
-{
- entityState_t *es;
- int c;
- weaponInfo_t *wi;
- weapon_t weaponNum;
-
- es = &cent->currentState;
-
- weaponNum = es->weapon;
-
- if( weaponNum == WP_NONE )
- return;
-
- if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES )
- weaponMode = WPM_PRIMARY;
-
- if( weaponNum >= WP_NUM_WEAPONS )
- {
- CG_Error( "CG_FireWeapon: ent->weapon >= WP_NUM_WEAPONS" );
- return;
- }
-
- wi = &cg_weapons[ weaponNum ];
-
- // mark the entity as muzzle flashing, so when it is added it will
- // append the flash to the weapon model
- cent->muzzleFlashTime = cg.time;
-
- if( wi->wim[ weaponMode ].muzzleParticleSystem )
- {
- if( !CG_IsParticleSystemValid( &cent->muzzlePS ) ||
- !CG_IsParticleSystemInfinite( cent->muzzlePS ) )
- cent->muzzlePsTrigger = qtrue;
- }
-
- // play a sound
- for( c = 0; c < 4; c++ )
- {
- if( !wi->wim[ weaponMode ].flashSound[ c ] )
- break;
- }
-
- if( c > 0 )
- {
- c = rand( ) % c;
- if( wi->wim[ weaponMode ].flashSound[ c ] )
- trap_S_StartSound( NULL, es->number, CHAN_WEAPON, wi->wim[ weaponMode ].flashSound[ c ] );
- }
-}
-
-
-/*
-=================
-CG_MissileHitWall
-
-Caused by an EV_MISSILE_MISS event, or directly by local bullet tracing
-=================
-*/
-void CG_MissileHitWall( weapon_t weaponNum, weaponMode_t weaponMode, int clientNum,
- vec3_t origin, vec3_t dir, impactSound_t soundType )
-{
- qhandle_t mark = 0;
- qhandle_t ps = 0;
- int c;
- float radius = 1.0f;
- weaponInfo_t *weapon = &cg_weapons[ weaponNum ];
-
- if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES )
- weaponMode = WPM_PRIMARY;
-
- mark = weapon->wim[ weaponMode ].impactMark;
- radius = weapon->wim[ weaponMode ].impactMarkSize;
- ps = weapon->wim[ weaponMode ].impactParticleSystem;
-
- if( soundType == IMPACTSOUND_FLESH )
- {
- //flesh sound
- for( c = 0; c < 4; c++ )
- {
- if( !weapon->wim[ weaponMode ].impactFleshSound[ c ] )
- break;
- }
-
- if( c > 0 )
- {
- c = rand( ) % c;
- if( weapon->wim[ weaponMode ].impactFleshSound[ c ] )
- trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weapon->wim[ weaponMode ].impactFleshSound[ c ] );
- }
- }
- else
- {
- //normal sound
- for( c = 0; c < 4; c++ )
- {
- if( !weapon->wim[ weaponMode ].impactSound[ c ] )
- break;
- }
-
- if( c > 0 )
- {
- c = rand( ) % c;
- if( weapon->wim[ weaponMode ].impactSound[ c ] )
- trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weapon->wim[ weaponMode ].impactSound[ c ] );
- }
- }
-
- //create impact particle system
- if( ps )
- {
- particleSystem_t *partSystem = CG_SpawnNewParticleSystem( ps );
-
- if( CG_IsParticleSystemValid( &partSystem ) )
- {
- CG_SetAttachmentPoint( &partSystem->attachment, origin );
- CG_SetParticleSystemNormal( partSystem, dir );
- CG_AttachToPoint( &partSystem->attachment );
- }
- }
-
- //
- // impact mark
- //
- if( radius > 0.0f )
- CG_ImpactMark( mark, origin, dir, random( ) * 360, 1, 1, 1, 1, qfalse, radius, qfalse );
-}
-
-
-/*
-=================
-CG_MissileHitPlayer
-=================
-*/
-void CG_MissileHitPlayer( weapon_t weaponNum, weaponMode_t weaponMode,
- vec3_t origin, vec3_t dir, int entityNum )
-{
- vec3_t normal;
- weaponInfo_t *weapon = &cg_weapons[ weaponNum ];
-
- VectorCopy( dir, normal );
- VectorInverse( normal );
-
- CG_Bleed( origin, normal, entityNum );
-
- if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES )
- weaponMode = WPM_PRIMARY;
-
- if( weapon->wim[ weaponMode ].alwaysImpact )
- CG_MissileHitWall( weaponNum, weaponMode, 0, origin, dir, IMPACTSOUND_FLESH );
-}
-
-
-/*
-============================================================================
-
-BULLETS
-
-============================================================================
-*/
-
-
-/*
-===============
-CG_Tracer
-===============
-*/
-void CG_Tracer( vec3_t source, vec3_t dest )
-{
- vec3_t forward, right;
- polyVert_t verts[ 4 ];
- vec3_t line;
- float len, begin, end;
- vec3_t start, finish;
- vec3_t midpoint;
-
- // tracer
- VectorSubtract( dest, source, forward );
- len = VectorNormalize( forward );
-
- // start at least a little ways from the muzzle
- if( len < 100 )
- return;
-
- begin = 50 + random( ) * ( len - 60 );
- end = begin + cg_tracerLength.value;
- if( end > len )
- end = len;
-
- VectorMA( source, begin, forward, start );
- VectorMA( source, end, forward, finish );
-
- line[ 0 ] = DotProduct( forward, cg.refdef.viewaxis[ 1 ] );
- line[ 1 ] = DotProduct( forward, cg.refdef.viewaxis[ 2 ] );
-
- VectorScale( cg.refdef.viewaxis[ 1 ], line[ 1 ], right );
- VectorMA( right, -line[ 0 ], cg.refdef.viewaxis[ 2 ], right );
- VectorNormalize( right );
-
- VectorMA( finish, cg_tracerWidth.value, right, verts[ 0 ].xyz );
- verts[ 0 ].st[ 0 ] = 0;
- verts[ 0 ].st[ 1 ] = 1;
- verts[ 0 ].modulate[ 0 ] = 255;
- verts[ 0 ].modulate[ 1 ] = 255;
- verts[ 0 ].modulate[ 2 ] = 255;
- verts[ 0 ].modulate[ 3 ] = 255;
-
- VectorMA( finish, -cg_tracerWidth.value, right, verts[ 1 ].xyz );
- verts[ 1 ].st[ 0 ] = 1;
- verts[ 1 ].st[ 1 ] = 0;
- verts[ 1 ].modulate[ 0 ] = 255;
- verts[ 1 ].modulate[ 1 ] = 255;
- verts[ 1 ].modulate[ 2 ] = 255;
- verts[ 1 ].modulate[ 3 ] = 255;
-
- VectorMA( start, -cg_tracerWidth.value, right, 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;
-
- VectorMA( start, cg_tracerWidth.value, right, verts[ 3 ].xyz );
- verts[ 3 ].st[ 0 ] = 0;
- 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;
-
- trap_R_AddPolyToScene( cgs.media.tracerShader, 4, verts );
-
- midpoint[ 0 ] = ( start[ 0 ] + finish[ 0 ] ) * 0.5;
- midpoint[ 1 ] = ( start[ 1 ] + finish[ 1 ] ) * 0.5;
- midpoint[ 2 ] = ( start[ 2 ] + finish[ 2 ] ) * 0.5;
-
- // add the tracer sound
- trap_S_StartSound( midpoint, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.tracerSound );
-}
-
-
-/*
-======================
-CG_CalcMuzzlePoint
-======================
-*/
-static qboolean CG_CalcMuzzlePoint( int entityNum, vec3_t muzzle )
-{
- vec3_t forward;
- centity_t *cent;
- int anim;
-
- if( entityNum == cg.snap->ps.clientNum )
- {
- VectorCopy( cg.snap->ps.origin, muzzle );
- muzzle[ 2 ] += cg.snap->ps.viewheight;
- AngleVectors( cg.snap->ps.viewangles, forward, NULL, NULL );
- VectorMA( muzzle, 14, forward, muzzle );
- return qtrue;
- }
-
- cent = &cg_entities[entityNum];
-
- if( !cent->currentValid )
- return qfalse;
-
- VectorCopy( cent->currentState.pos.trBase, muzzle );
-
- AngleVectors( cent->currentState.apos.trBase, forward, NULL, NULL );
- anim = cent->currentState.legsAnim & ~ANIM_TOGGLEBIT;
-
- if( anim == LEGS_WALKCR || anim == LEGS_IDLECR )
- muzzle[ 2 ] += CROUCH_VIEWHEIGHT;
- else
- muzzle[ 2 ] += DEFAULT_VIEWHEIGHT;
-
- VectorMA( muzzle, 14, forward, muzzle );
-
- return qtrue;
-
-}
-
-
-/*
-======================
-CG_Bullet
-
-Renders bullet effects.
-======================
-*/
-void CG_Bullet( vec3_t end, int sourceEntityNum, vec3_t normal, qboolean flesh, int fleshEntityNum )
-{
- vec3_t start;
-
- // if the shooter is currently valid, calc a source point and possibly
- // do trail effects
- if( sourceEntityNum >= 0 && cg_tracerChance.value > 0 )
- {
- if( CG_CalcMuzzlePoint( sourceEntityNum, start ) )
- {
- // draw a tracer
- if( random( ) < cg_tracerChance.value )
- CG_Tracer( start, end );
- }
- }
-
- // impact splash and mark
- if( flesh )
- CG_Bleed( end, normal, fleshEntityNum );
- else
- CG_MissileHitWall( WP_MACHINEGUN, WPM_PRIMARY, 0, end, normal, IMPACTSOUND_DEFAULT );
-}
-
-/*
-============================================================================
-
-SHOTGUN TRACING
-
-============================================================================
-*/
-
-/*
-================
-CG_ShotgunPattern
-
-Perform the same traces the server did to locate the
-hit splashes
-================
-*/
-static void CG_ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, int otherEntNum )
-{
- int i;
- float r, u;
- vec3_t end;
- vec3_t forward, right, up;
- trace_t tr;
-
- // derive the right and up vectors from the forward vector, because
- // the client won't have any other information
- VectorNormalize2( origin2, forward );
- PerpendicularVector( right, forward );
- CrossProduct( forward, right, up );
-
- // generate the "random" spread pattern
- for( i = 0; i < SHOTGUN_PELLETS; i++ )
- {
- r = Q_crandom( &seed ) * SHOTGUN_SPREAD * 16;
- u = Q_crandom( &seed ) * SHOTGUN_SPREAD * 16;
- VectorMA( origin, 8192 * 16, forward, end );
- VectorMA( end, r, right, end );
- VectorMA( end, u, up, end );
-
- CG_Trace( &tr, origin, NULL, NULL, end, otherEntNum, MASK_SHOT );
-
- if( !( tr.surfaceFlags & SURF_NOIMPACT ) )
- {
- if( cg_entities[ tr.entityNum ].currentState.eType == ET_PLAYER )
- CG_MissileHitPlayer( WP_SHOTGUN, WPM_PRIMARY, tr.endpos, tr.plane.normal, tr.entityNum );
- else if( tr.surfaceFlags & SURF_METALSTEPS )
- CG_MissileHitWall( WP_SHOTGUN, WPM_PRIMARY, 0, tr.endpos, tr.plane.normal, IMPACTSOUND_METAL );
- else
- CG_MissileHitWall( WP_SHOTGUN, WPM_PRIMARY, 0, tr.endpos, tr.plane.normal, IMPACTSOUND_DEFAULT );
- }
- }
-}
-
-/*
-==============
-CG_ShotgunFire
-==============
-*/
-void CG_ShotgunFire( entityState_t *es )
-{
- vec3_t v;
-
- VectorSubtract( es->origin2, es->pos.trBase, v );
- VectorNormalize( v );
- VectorScale( v, 32, v );
- VectorAdd( es->pos.trBase, v, v );
-
- CG_ShotgunPattern( es->pos.trBase, es->origin2, es->eventParm, es->otherEntityNum );
-}
-
diff --git a/src/cgame/tr_types.h b/src/cgame/tr_types.h
deleted file mode 100644
index 26240a2f..00000000
--- a/src/cgame/tr_types.h
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright (C) 1999-2000 Id Software, Inc.
-//
-
-/*
- * Portions Copyright (C) 2000-2001 Tim Angus
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the OSML - Open Source Modification License v1.0 as
- * described in the file COPYING which is distributed with this source
- * code.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef __TR_TYPES_H
-#define __TR_TYPES_H
-
-
-#define MAX_DLIGHTS 32 // can't be increased, because bit flags are used on surfaces
-#define MAX_ENTITIES 1023 // can't be increased without changing drawsurf bit packing
-
-// renderfx flags
-#define RF_MINLIGHT 1 // allways have some light (viewmodel, some items)
-#define RF_THIRD_PERSON 2 // don't draw through eyes, only mirrors (player bodies, chat sprites)
-#define RF_FIRST_PERSON 4 // only draw through eyes (view weapon, damage blood blob)
-#define RF_DEPTHHACK 8 // for view weapon Z crunching
-#define RF_NOSHADOW 64 // don't add stencil shadows
-
-#define RF_LIGHTING_ORIGIN 128 // use refEntity->lightingOrigin instead of refEntity->origin
- // for lighting. This allows entities to sink into the floor
- // with their origin going solid, and allows all parts of a
- // player to get the same lighting
-#define RF_SHADOW_PLANE 256 // use refEntity->shadowPlane
-#define RF_WRAP_FRAMES 512 // mod the model frames by the maxframes to allow continuous
- // animation without needing to know the frame count
-
-// refdef flags
-#define RDF_NOWORLDMODEL 1 // used for player configuration screen
-#define RDF_HYPERSPACE 4 // teleportation effect
-
-typedef struct
-{
- vec3_t xyz;
- float st[ 2 ];
- byte modulate[ 4 ];
-} polyVert_t;
-
-typedef struct poly_s
-{
- qhandle_t hShader;
- int numVerts;
- polyVert_t *verts;
-} poly_t;
-
-typedef enum
-{
- RT_MODEL,
- RT_POLY,
- RT_SPRITE,
- RT_BEAM,
- RT_RAIL_CORE,
- RT_RAIL_RINGS,
- RT_LIGHTNING,
- RT_PORTALSURFACE, // doesn't draw anything, just info for portals
-
- RT_MAX_REF_ENTITY_TYPE
-} refEntityType_t;
-
-typedef struct
-{
- refEntityType_t reType;
- int renderfx;
-
- qhandle_t hModel; // opaque type outside refresh
-
- // most recent data
- vec3_t lightingOrigin; // so multi-part models can be lit identically (RF_LIGHTING_ORIGIN)
- float shadowPlane; // projection shadows go here, stencils go slightly lower
-
- vec3_t axis[ 3 ]; // rotation vectors
- qboolean nonNormalizedAxes; // axis are not normalized, i.e. they have scale
- float origin[ 3 ]; // also used as MODEL_BEAM's "from"
- int frame; // also used as MODEL_BEAM's diameter
-
- // previous data for frame interpolation
- float oldorigin[ 3 ]; // also used as MODEL_BEAM's "to"
- int oldframe;
- float backlerp; // 0.0 = current, 1.0 = old
-
- // texturing
- int skinNum; // inline skin index
- qhandle_t customSkin; // NULL for default skin
- qhandle_t customShader; // use one image for the entire thing
-
- // misc
- byte shaderRGBA[ 4 ]; // colors used by rgbgen entity shaders
- float shaderTexCoord[ 2 ];// texture coordinates used by tcMod entity modifiers
- float shaderTime; // subtracted from refdef time to control effect start times
-
- // extra sprite information
- float radius;
- float rotation;
-} refEntity_t;
-
-
-#define MAX_RENDER_STRINGS 8
-#define MAX_RENDER_STRING_LENGTH 32
-
-typedef struct
-{
- int x, y, width, height;
- float fov_x, fov_y;
- vec3_t vieworg;
- vec3_t viewaxis[ 3 ]; // transformation matrix
-
- // time in milliseconds for shader effects and other time dependent rendering issues
- int time;
-
- int rdflags; // RDF_NOWORLDMODEL, etc
-
- // 1 bits will prevent the associated area from rendering at all
- byte areamask[ MAX_MAP_AREA_BYTES ];
-
- // text messages for deform text shaders
- char text[ MAX_RENDER_STRINGS ][ MAX_RENDER_STRING_LENGTH ];
-} refdef_t;
-
-
-typedef enum
-{
- STEREO_CENTER,
- STEREO_LEFT,
- STEREO_RIGHT
-} stereoFrame_t;
-
-
-/*
-** glconfig_t
-**
-** Contains variables specific to the OpenGL configuration
-** being run right now. These are constant once the OpenGL
-** subsystem is initialized.
-*/
-typedef enum
-{
- TC_NONE,
- TC_S3TC
-} textureCompression_t;
-
-typedef enum
-{
- GLDRV_ICD, // driver is integrated with window system
- // WARNING: there are tests that check for
- // > GLDRV_ICD for minidriverness, so this
- // should always be the lowest value in this
- // enum set
- GLDRV_STANDALONE, // driver is a non-3Dfx standalone driver
- GLDRV_VOODOO // driver is a 3Dfx standalone driver
-} glDriverType_t;
-
-typedef enum
-{
- GLHW_GENERIC, // where everthing works the way it should
- GLHW_3DFX_2D3D, // Voodoo Banshee or Voodoo3, relevant since if this is
- // the hardware type then there can NOT exist a secondary
- // display adapter
- GLHW_RIVA128, // where you can't interpolate alpha
- GLHW_RAGEPRO, // where you can't modulate alpha on alpha textures
- GLHW_PERMEDIA2 // where you don't have src*dst
-} glHardwareType_t;
-
-typedef struct
-{
- char renderer_string[ MAX_STRING_CHARS ];
- char vendor_string[ MAX_STRING_CHARS ];
- char version_string[ MAX_STRING_CHARS ];
- char extensions_string[ BIG_INFO_STRING ];
-
- int maxTextureSize; // queried from GL
- int maxActiveTextures; // multitexture ability
-
- int colorBits, depthBits, stencilBits;
-
- glDriverType_t driverType;
- glHardwareType_t hardwareType;
-
- qboolean deviceSupportsGamma;
- textureCompression_t textureCompression;
- qboolean textureEnvAddAvailable;
-
- int vidWidth, vidHeight;
-
- // aspect is the screen's physical width / height, which may be different
- // than scrWidth / scrHeight if the pixels are non-square
- // normal screens should be 4/3, but wide aspect monitors may be 16/9
- float windowAspect;
-
- int displayFrequency;
-
- // synonymous with "does rendering consume the entire screen?", therefore
- // a Voodoo or Voodoo2 will have this set to TRUE, as will a Win32 ICD that
- // used CDS.
- qboolean isFullscreen;
- qboolean stereoEnabled;
- qboolean smpActive; // dual processor
-} glconfig_t;
-
-
-#if !defined _WIN32
-
-#define _3DFX_DRIVER_NAME "libMesaVoodooGL.so"
-// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=524
-#define OPENGL_DRIVER_NAME "libGL.so.1"
-
-#else
-
-#define _3DFX_DRIVER_NAME "3dfxvgl"
-#define OPENGL_DRIVER_NAME "opengl32"
-
-#endif // !defined _WIN32
-
-
-#endif // __TR_TYPES_H