예제 #1
0
/*
   ===============
   RotatePointAroundVector

   This is not implemented very well...
   ===============
 */
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point,
							  float degrees ) {
	float m[3][3];
	float im[3][3];
	float zrot[3][3];
	float tmpmat[3][3];
	float rot[3][3];
	int i;
	vec3_t vr, vup, vf;
	float rad;

	vf[0] = dir[0];
	vf[1] = dir[1];
	vf[2] = dir[2];

	PerpendicularVector( vr, dir );
	CrossProduct( vr, vf, vup );

	m[0][0] = vr[0];
	m[1][0] = vr[1];
	m[2][0] = vr[2];

	m[0][1] = vup[0];
	m[1][1] = vup[1];
	m[2][1] = vup[2];

	m[0][2] = vf[0];
	m[1][2] = vf[1];
	m[2][2] = vf[2];

	memcpy( im, m, sizeof( im ) );

	im[0][1] = m[1][0];
	im[0][2] = m[2][0];
	im[1][0] = m[0][1];
	im[1][2] = m[2][1];
	im[2][0] = m[0][2];
	im[2][1] = m[1][2];

	memset( zrot, 0, sizeof( zrot ) );
	zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F;

	rad = (float)DEG2RAD( degrees );
	zrot[0][0] = (vec_t)cos( rad );
	zrot[0][1] = (vec_t)sin( rad );
	zrot[1][0] = (vec_t)-sin( rad );
	zrot[1][1] = (vec_t)cos( rad );

	MatrixMultiply( m, zrot, tmpmat );
	MatrixMultiply( tmpmat, im, rot );

	for ( i = 0; i < 3; i++ ) {
		dst[i] = rot[i][0] * point[0] + rot[i][1] * point[1] + rot[i][2] * point[2];
	}
}
예제 #2
0
void RotatePointAroundVector( vec3_t &dst, const vec3_t &dir, const vec3_t &point, float degrees )
{
	float	m[3][3];
	float	im[3][3];
	float	zrot[3][3];
	float	tmpmat[3][3];
	float	rot[3][3];
	int	i;
	vec3_t vr, vup, vf;

	vf[0] = dir[0];
	vf[1] = dir[1];
	vf[2] = dir[2];

	PerpendicularVector( vr, dir );
	//CrossProduct( vr, vf, vup );
	vup = CrossProduct( vr, vf );

	m[0][0] = vr[0];
	m[1][0] = vr[1];
	m[2][0] = vr[2];

	m[0][1] = vup[0];
	m[1][1] = vup[1];
	m[2][1] = vup[2];

	m[0][2] = vf[0];
	m[1][2] = vf[1];
	m[2][2] = vf[2];

	memcpy( im, m, sizeof( im ) );

	im[0][1] = m[1][0];
	im[0][2] = m[2][0];
	im[1][0] = m[0][1];
	im[1][2] = m[2][1];
	im[2][0] = m[0][2];
	im[2][1] = m[1][2];

	memset( zrot, 0, sizeof( zrot ) );
	zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F;

	zrot[0][0] = cos( DEG2RAD( degrees ) );
	zrot[0][1] = sin( DEG2RAD( degrees ) );
	zrot[1][0] = -sin( DEG2RAD( degrees ) );
	zrot[1][1] = cos( DEG2RAD( degrees ) );

	R_ConcatRotations( m, zrot, tmpmat );
	R_ConcatRotations( tmpmat, im, rot );

	for ( i = 0; i < 3; i++ )
	{
		dst[i] = rot[i][0] * point[0] + rot[i][1] * point[1] + rot[i][2] * point[2];
	}
}
예제 #3
0
파일: mathlib.c 프로젝트: kevlund/ufoai
/**
 * @brief Rotate a point around a given vector
 * @param[in] dir The vector around which to rotate
 * @param[in] point The point to be rotated
 * @param[in] degrees How many degrees to rotate the point by
 * @param[out] dst The point after rotation
 * @note Warning: @c dst must be different from @c point (otherwise the result has no meaning)
 * @pre @c dir must be normalized
 */
void RotatePointAroundVector (vec3_t dst, const vec3_t dir, const vec3_t point, float degrees)
{
	float m[3][3];
	float im[3][3];
	float zrot[3][3];
	float tmpmat[3][3];
	float rot[3][3];
	int i;
	vec3_t vr, vup, vf;

	vf[0] = dir[0];
	vf[1] = dir[1];
	vf[2] = dir[2];

	PerpendicularVector(vr, dir);
	CrossProduct(vr, vf, vup);

	m[0][0] = vr[0];
	m[1][0] = vr[1];
	m[2][0] = vr[2];

	m[0][1] = vup[0];
	m[1][1] = vup[1];
	m[2][1] = vup[2];

	m[0][2] = vf[0];
	m[1][2] = vf[1];
	m[2][2] = vf[2];

	memcpy(im, m, sizeof(im));

	im[0][1] = m[1][0];
	im[0][2] = m[2][0];
	im[1][0] = m[0][1];
	im[1][2] = m[2][1];
	im[2][0] = m[0][2];
	im[2][1] = m[1][2];

	OBJZERO(zrot);

	/* now prepare the rotation matrix */
	zrot[0][0] = cos(degrees * torad);
	zrot[0][1] = sin(degrees * torad);
	zrot[1][0] = -sin(degrees * torad);
	zrot[1][1] = cos(degrees * torad);
	zrot[2][2] = 1.0F;

	R_ConcatRotations(m, zrot, tmpmat);
	R_ConcatRotations(tmpmat, im, rot);

	for (i = 0; i < 3; i++) {
		dst[i] = DotProduct(rot[i], point);
	}
}
예제 #4
0
파일: vector.c 프로젝트: Oppen/Wolf3DRedux
/*
-----------------------------------------------------------------------------
 Function: RotatePointAroundVector -Rotate a point around a vector.

 Parameters: dst -[out] Point after rotation.
			 dir -[in] vector.
			 point -[in] Point.
			 degrees -[in] Degrees of rotation.

 Returns: Nothing.

 Notes: 
-----------------------------------------------------------------------------
*/
PUBLIC void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees ) 
{
	mat3_t	m;
	mat3_t	im;
	mat3_t	zrot;
	mat3_t	tmpmat;
	mat3_t	rot;
	vec3_t  vr, vup, vf;
	float	rad;

	vf[0] = dir[0];
	vf[1] = dir[1];
	vf[2] = dir[2];

	PerpendicularVector( vr, dir );
	vectorCrossProduct( vr, vf, vup );

	m[0] = vr[0];
	m[3] = vr[1];
	m[6] = vr[2];

	m[1] = vup[0];
	m[4] = vup[1];
	m[7] = vup[2];

	m[2] = vf[0];
	m[5] = vf[1];
	m[8] = vf[2];

	memcpy( im, m, sizeof( im ) );

	im[1] = m[3];
	im[2] = m[6];
	im[3] = m[1];
	im[5] = m[7];
	im[6] = m[2];
	im[7] = m[5];

	memset( zrot, 0, sizeof( zrot ) );
	zrot[0] = zrot[4] = zrot[8] = 1.0F;

	rad = DEG2RAD( degrees );
	zrot[0] = (float)cos( rad );
	zrot[1] = (float)sin( rad );
	zrot[3] = (float)-sin( rad );
	zrot[4] = (float)cos( rad );

	Matrix3x3Multiply( m, zrot, tmpmat );
	Matrix3x3Multiply( tmpmat, im, rot );

	dst[0] = rot[0] * point[0] + rot[1] * point[1] + rot[2] * point[2];
	dst[1] = rot[3] * point[0] + rot[4] * point[1] + rot[5] * point[2];
	dst[2] = rot[6] * point[0] + rot[7] * point[1] + rot[8] * point[2];	
}
예제 #5
0
static int vector_Perpendicular(lua_State * L)
{
	vec_t          *dst;
	vec_t          *src;

	dst = lua_getvector(L, 1);
	src = lua_getvector(L, 2);

	PerpendicularVector(dst, src);

	return 1;
}
예제 #6
0
/*
========================
GetSurfaceOrientations
========================
*/
void R_GetSurfaceOrientations( cplane_t *plane,  orientation_t *surface, orientation_t *camera )
{
	VectorCopy( plane->normal, surface->axis[0] );
	PerpendicularVector( surface->axis[1], surface->axis[0] );
	CrossProduct( surface->axis[0], surface->axis[1], surface->axis[2] );

	VectorScale( plane->normal, plane->dist, surface->origin );
	VectorCopy( surface->origin, camera->origin );
	VectorSubtract( vec3_origin, surface->axis[0], camera->axis[0] );
	VectorCopy( surface->axis[1], camera->axis[1] );
	VectorCopy( surface->axis[2], camera->axis[2] );

}
예제 #7
0
void RotatePointAroundVector( Coord *dst, Coord dir, Coord point, float degrees )
{
  float	m[3][3];
  float	im[3][3];
  float	zrot[3][3];
  float	tmpmat[3][3];
  float	rot[3][3];
  Coord vr, vup, vf;

  vf.x = dir.x;
  vf.y = dir.y;
  vf.z = dir.z;

  PerpendicularVector( &vr, dir );
  CrossProduct( vr, vf, &vup );
  m[0][0] = vr.x;
  m[1][0] = vr.y;
  m[2][0] = vr.z;

  m[0][1] = vup.x;
  m[1][1] = vup.y;
  m[2][1] = vup.z;

  m[0][2] = vf.x;
  m[1][2] = vf.y;
  m[2][2] = vf.z;

  memcpy( im, m, sizeof( im ) );

  im[0][1] = m[1][0];
  im[0][2] = m[2][0];
  im[1][0] = m[0][1];
  im[1][2] = m[2][1];
  im[2][0] = m[0][2];
  im[2][1] = m[1][2];

  memset( zrot, 0, sizeof( zrot ) );
  zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F;

  zrot[0][0] = cos( ( degrees*DEGTORAD ) );
  zrot[0][1] = sin( ( degrees*DEGTORAD ) );
  zrot[1][0] = -sin( ( degrees*DEGTORAD ) );
  zrot[1][1] = cos( ( degrees*DEGTORAD ) );

  R_ConcatRotations( m, zrot, tmpmat );
  R_ConcatRotations( tmpmat, im, rot );

  dst->x = rot[0][0] * point.x + rot[0][1] * point.y + rot[0][2] * point.z;
  dst->y = rot[1][0] * point.x + rot[1][1] * point.y + rot[1][2] * point.z;
  dst->z = rot[2][0] * point.x + rot[2][1] * point.y + rot[2][2] * point.z;
}
예제 #8
0
void CG_EffectMark(qhandle_t markShader, const vec3_t origin, const vec3_t dir, float alpha, float radius)
{
	// 'quick' version of the CG_ImpactMark function

	vec3_t axis[3], originalPoints[4];
	float texCoordScale;
	byte colors[4];
	int i;
	polyVert_t *v, verts[4];

	if (!cg_addMarks.integer) {
		return;
	}

	if (radius <= 0) {
		CG_Error("CG_EffectMark called with <= 0 radius");
	}
	// create the texture axis
	VectorNormalize2(dir, axis[0]);
	PerpendicularVector(axis[1], axis[0]);
	VectorSet(axis[2], 1, 0, 0);	// This is _wrong_, but the function is for water anyway (i.e. usually flat)
	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];
	}

	colors[0] = 127;
	colors[1] = 127;
	colors[2] = 127;
	colors[3] = alpha * 255;

	for (i = 0, v = verts; i < 4; i++, v++) {
		vec3_t delta;

		VectorCopy(originalPoints[i], 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;
	}

	trap_R_AddPolyToScene(markShader, 4, verts);
}
예제 #9
0
// This is not implemented very well...
void RotatePointAroundVector( vector3 *dst, const vector3 *dir, const vector3 *point, float degrees ) {
	vector3 m[3], im[3], zrot[3], tmpmat[3], rot[3];
	vector3 vr, vup, vf;
	int	i;
	float	rad;

	vf.x = dir->x;
	vf.y = dir->y;
	vf.z = dir->z;

	PerpendicularVector( &vr, dir );
	CrossProduct( &vr, &vf, &vup );

	m[0].x = vr.x;
	m[1].x = vr.y;
	m[2].x = vr.z;

	m[0].y = vup.x;
	m[1].y = vup.y;
	m[2].y = vup.z;

	m[0].z = vf.x;
	m[1].z = vf.y;
	m[2].z = vf.z;

	memcpy( im, m, sizeof(im) );

	im[0].y = m[1].x;
	im[0].z = m[2].x;
	im[1].x = m[0].y;
	im[1].z = m[2].y;
	im[2].x = m[0].z;
	im[2].y = m[1].z;

	memset( zrot, 0, sizeof(zrot) );
	zrot[0].x = zrot[1].y = zrot[2].z = 1.0f;

	rad = DEG2RAD( degrees );
	zrot[0].x =  cosf( rad );
	zrot[0].y =  sinf( rad );
	zrot[1].x = -sinf( rad );
	zrot[1].y =  cosf( rad );

	MatrixMultiply( m, zrot, tmpmat );
	MatrixMultiply( tmpmat, im, rot );

	for ( i = 0; i < 3; i++ ) {
		dst->raw[i] = DotProduct( &rot[i], point );
	}
}
예제 #10
0
qboolean fire_weaponDir(gentity_t *self, vec3_t start, vec3_t dir, int weaponnum, float quadFactor, int handSide)
{
	vec3_t right, up;

	if (weaponnum <= 0 || weaponnum >= BG_NumWeapons()) {
		return qfalse;
	}

	// Get up and right from dir (which is "forward")
	PerpendicularVector( up, dir );
	CrossProduct( up, dir, right );

	return fire_projectile(self, start, dir, right, up, bg_weaponinfo[weaponnum].projnum,
		quadFactor, bg_weaponinfo[weaponnum].mod, bg_weaponinfo[weaponnum].splashMod, handSide);
}
예제 #11
0
// this should match CG_ShotgunPattern
void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent ) {
	int			i, n, c;
	float		r, u, d;
	vec3_t		end;
	vec3_t		forward, right, up;
	qboolean	hitClient = qfalse;

	// 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 );
	n = DEFAULT_SHOTGUN_COUNT;
	d = DEFAULT_SHOTGUN_SPREAD / 2;
	c = 3;
	while (n > 0) {
		float stepSize = (2 * M_PI) / c;
		float step;
		for (step = -M_PI; step < M_PI && n > 0; step += stepSize) {
			r = cos(step) * d;
			u = sin(step) * d;
			VectorMA( origin, 8192, forward, end);
			VectorMA (end, r, right, end);
			VectorMA (end, u, up, end);
			if( ShotgunPellet( origin, end, ent ) && !hitClient ) {
				hitClient = qtrue;
				ent->client->accuracy_hits++;
			}
			n--;
		}
		d += DEFAULT_SHOTGUN_SPREAD / 2;
		c += 4;
	}
	/*
	// generate the "random" spread pattern
	for ( i = 0 ; i < DEFAULT_SHOTGUN_COUNT ; i++ ) {
		r = Q_crandom( &seed ) * DEFAULT_SHOTGUN_SPREAD;  // CPM
		u = Q_crandom( &seed ) * DEFAULT_SHOTGUN_SPREAD;  // CPM
		VectorMA( origin, 8192, forward, end);
		VectorMA (end, r, right, end);
		VectorMA (end, u, up, end);
		if( ShotgunPellet( origin, end, ent ) && !hitClient ) {
			hitClient = qtrue;
			ent->client->accuracy_hits++;
		}
	}
	*/
}
예제 #12
0
void RotateAroundDirection( vector3 axis[3], float yaw ) {

	// create an arbitrary axis[1]
	PerpendicularVector( &axis[1], &axis[0] );

	// rotate it around axis[0] by yaw
	if ( yaw ) {
		vector3	temp;

		VectorCopy( &axis[1], &temp );
		RotatePointAroundVector( &axis[1], &axis[0], &temp, yaw );
	}

	// cross to get axis[2]
	CrossProduct( &axis[0], &axis[1], &axis[2] );
}
예제 #13
0
// this should match CG_ShotgunPattern
void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent ) {
	int			i;
	float		r, u;
	vec3_t		end;
	vec3_t		forward, right, up;
	qboolean	hitClient = qfalse;

//unlagged - attack prediction #2
	// use this for testing
	/*
	if ( g_unlagged.integer )
		Com_Printf( "Server seed: %d\n", seed );
		*/
//-unlagged - attack prediction #2

	// 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 );

//unlagged - backward reconciliation #2
	// backward-reconcile the other clients
	if ( g_unlagged.integer )
		G_DoTimeShiftFor( ent );
//-unlagged - backward reconciliation #2

	// generate the "random" spread pattern
	for ( i = 0 ; i < DEFAULT_SHOTGUN_COUNT ; i++ ) {
		r = Q_crandom( &seed ) * DEFAULT_SHOTGUN_SPREAD * 16;
		u = Q_crandom( &seed ) * DEFAULT_SHOTGUN_SPREAD * 16;
		VectorMA( origin, 8192 * 16, forward, end);
		VectorMA (end, r, right, end);
		VectorMA (end, u, up, end);
		if( ShotgunPellet( origin, end, ent ) && !hitClient ) {
			hitClient = qtrue;
			ent->client->accuracy_hits++;
		}
	}

//unlagged - backward reconciliation #2
	// put them back
	if ( g_unlagged.integer )
		G_UndoTimeShiftFor( ent );
//-unlagged - backward reconciliation #2
}
예제 #14
0
파일: g_misc.c 프로젝트: otty/cake3
void Use_Shooter(gentity_t * ent, gentity_t * other, gentity_t * activator)
{
	vec3_t          dir;
	float           deg;
	vec3_t          up, right;

	// see if we have a target
	if(ent->enemy)
	{
		VectorSubtract(ent->enemy->r.currentOrigin, ent->s.origin, dir);
		VectorNormalize(dir);
	}
	else
	{
		VectorCopy(ent->movedir, dir);
	}

	// randomize a bit
	PerpendicularVector(up, dir);
	CrossProduct(up, dir, right);

	deg = crandom() * ent->random;
	VectorMA(dir, deg, up, dir);

	deg = crandom() * ent->random;
	VectorMA(dir, deg, right, dir);

	VectorNormalize(dir);

	switch (ent->s.weapon)
	{
		case WP_GRENADE_LAUNCHER:
			fire_grenade(ent, ent->s.origin, dir);
			break;
		case WP_ROCKET_LAUNCHER:
			fire_rocket(ent, ent->s.origin, dir);
			break;
		case WP_PLASMAGUN:
			fire_plasma(ent, ent->s.origin, dir);
			break;
	}

	G_AddEvent(ent, EV_FIRE_WEAPON, 0);
}
예제 #15
0
/*
** RB_DrawSun
*/
void RB_DrawSun( float scale, shader_t *shader ) {
	float		size;
	float		dist;
	vec3_t		origin, vec1, vec2;

	if ( !backEnd.skyRenderedThisView ) {
		return;
	}

	//qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );
	//qglTranslatef (backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2]);
	{
		// FIXME: this could be a lot cleaner
		mat4_t translation, modelview;

		Mat4Translation( backEnd.viewParms.or.origin, translation );
		Mat4Multiply( backEnd.viewParms.world.modelMatrix, translation, modelview );
		GL_SetModelviewMatrix( modelview );
	}

	dist = 	backEnd.viewParms.zFar / 1.75;		// div sqrt(3)
	size = dist * scale;

	VectorScale( tr.sunDirection, dist, origin );
	PerpendicularVector( vec1, tr.sunDirection );
	CrossProduct( tr.sunDirection, vec1, vec2 );

	VectorScale( vec1, size, vec1 );
	VectorScale( vec2, size, vec2 );

	// farthest depth range
	qglDepthRange( 1.0, 1.0 );

	RB_BeginSurface( shader, 0, 0 );

	RB_AddQuadStamp(origin, vec1, vec2, colorWhite);

	RB_EndSurface();

	// back to normal depth range
	qglDepthRange( 0.0, 1.0 );
}
예제 #16
0
/*
================
Keep this in sync with ShotgunPattern in CGAME!
================
*/
static void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *self )
{
	int       i;
	float     r, u, a;
	vec3_t    end;
	vec3_t    forward, right, up;
	trace_t   tr;
	gentity_t *traceEnt;

	// 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 ) * M_PI;
		a = Q_random( &seed ) * SHOTGUN_SPREAD * 16;

		u = sin( r ) * a;
		r = cos( r ) * a;

		VectorMA( origin, SHOTGUN_RANGE, forward, end );
		VectorMA( end, r, right, end );
		VectorMA( end, u, up, end );

		trap_Trace( &tr, origin, NULL, NULL, end, self->s.number, MASK_SHOT );
		traceEnt = &g_entities[ tr.entityNum ];

		// do the damage
		if ( !( tr.surfaceFlags & SURF_NOIMPACT ) )
		{
			if ( traceEnt->takedamage )
			{
				G_Damage( traceEnt, self, self, forward, tr.endpos, SHOTGUN_DMG, 0, MOD_SHOTGUN );
			}
		}
	}
}
예제 #17
0
bool HoldableItemExplosive::findPlaceToSet( Vector &newOrigin, Vector &newAngles )
{
	Player *player;
	trace_t viewTrace;
	Vector forward;
	Vector left;
	Vector up;
	float axis[3][3];
	vec3_t newAnglesVec;

	if ( !_owner || !_owner->isSubclassOf( Player ) )
		return false;

	player = (Player *)_owner;
		
	memset( &viewTrace, 0, sizeof(trace_t) );

	player->GetViewTrace( viewTrace, MASK_SHOT, 16.0f * 7.0f );

	if ( ( viewTrace.fraction < 1.0f ) && ( viewTrace.ent && viewTrace.entityNum == ENTITYNUM_WORLD ) )
	{
		newOrigin = viewTrace.endpos;

		up = viewTrace.plane.normal;
		PerpendicularVector( forward, viewTrace.plane.normal );
		left.CrossProduct( up, forward );

		forward.copyTo( axis[ AXIS_FORWARD_VECTOR ] );
		left.copyTo( axis[ AXIS_RIGHT_VECTOR ] );
		up.copyTo( axis[ AXIS_UP_VECTOR ] );

		AxisToAngles( axis, newAnglesVec );

		newAngles = newAnglesVec;

		return true;
	}

	return false;
}
예제 #18
0
void CG_ExplosionsDust( vec3_t pos, vec3_t dir, float radius )
{
	const int count = 32; /* Number of sprites used to create the circle */
	lentity_t *le;
	struct shader_s *shader = CG_MediaShader( cgs.media.shaderSmokePuff3 );

	vec3_t dir_per1;
	vec3_t dir_per2;
	vec3_t dir_temp = { 0.0f, 0.0f, 0.0f };
	int i;
	float angle;

	if( CG_PointContents( pos ) & MASK_WATER )
		return; // no smoke under water :)

	PerpendicularVector( dir_per2, dir );
	CrossProduct( dir, dir_per2, dir_per1 );

	//VectorScale( dir_per1, VectorNormalize( dir_per1 ), dir_per1 );
	//VectorScale( dir_per2, VectorNormalize( dir_per2 ), dir_per2 );

	// make a circle out of the specified number (int count) of sprites
	for( i = 0; i < count; i++ )
	{
		angle = (float)( 6.2831f / count * i );
		VectorSet( dir_temp, 0.0f, 0.0f, 0.0f );
		VectorMA( dir_temp, sin( angle ), dir_per1, dir_temp );
		VectorMA( dir_temp, cos( angle ), dir_per2, dir_temp );
		//VectorScale(dir_temp, VectorNormalize(dir_temp),dir_temp );
		VectorScale( dir_temp, crandom()*8 + radius + 16.0f, dir_temp );
		// make the sprite smaller & alpha'd
		le = CG_AllocSprite( LE_ALPHA_FADE, pos, 10, 10,
			1.0f, 1.0f, 1.0f, 1.0f,
			0, 0, 0, 0,
			shader );
		VectorCopy( dir_temp, le->velocity );
	}       
}
예제 #19
0
/*
================
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_entities[ tr.entityNum ].currentState.eType == ET_BUILDABLE )
        CG_MissileHitEntity( WP_SHOTGUN, WPM_PRIMARY, tr.endpos, tr.plane.normal, tr.entityNum, 0 );
      else if( tr.surfaceFlags & SURF_METALSTEPS )
        CG_MissileHitWall( WP_SHOTGUN, WPM_PRIMARY, 0, tr.endpos, tr.plane.normal, IMPACTSOUND_METAL, 0 );
      else
        CG_MissileHitWall( WP_SHOTGUN, WPM_PRIMARY, 0, tr.endpos, tr.plane.normal, IMPACTSOUND_DEFAULT, 0 );
    }
  }
}
예제 #20
0
// this should match CG_ShotgunPattern
void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent ) {
	int			i;
	float		r, u;
	vec3_t		end;
	vec3_t		forward, right, up;
	int			oldScore;
	qboolean	hitClient = qfalse;
	/* LQ3A */
	int			spread;

	// 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 );

	oldScore = ent->client->ps.persistant[PERS_SCORE];

	/* LQ3A */
	spread = (g_damageBulletSpread.integer > 0) ? g_damageBulletSpread.integer : 0;

	// generate the "random" spread pattern
	for ( i = 0 ; i < DEFAULT_SHOTGUN_COUNT ; i++ ) {

		/* LQ3A */
		r = Q_crandom( &seed ) * spread * 16;
		u = Q_crandom( &seed ) * spread * 16;

		VectorMA( origin, 8192 * 16, forward, end);
		VectorMA (end, r, right, end);
		VectorMA (end, u, up, end);
		if( ShotgunPellet( origin, end, ent ) && !hitClient ) {
			hitClient = qtrue;
			ent->client->accuracy_hits++;
		}
	}
}
예제 #21
0
파일: tr_sky.cpp 프로젝트: Jsoucek/q3ce
/*
** RB_DrawSun
*/
void RB_DrawSun( void ) {
	bfixed		size;
	bfixed		dist;
	bvec3_t		origin;
	avec3_t		vec1, vec2;
	bvec3_t		bvec1, bvec2;
	bvec3_t		temp;

	if ( !backEnd.skyRenderedThisView ) {
		return;
	}
	if ( !r_drawSun->integer ) {
		return;
	}
	glLoadMatrixX( backEnd.viewParms.world.modelMatrix );
	glTranslateX ( REINTERPRET_GFIXED(backEnd.viewParms._or.origin[0]), 
				   REINTERPRET_GFIXED(backEnd.viewParms._or.origin[1]), 
				   REINTERPRET_GFIXED(backEnd.viewParms._or.origin[2]));

	dist = 	backEnd.viewParms.zFar / BFIXED(1,75);		// div sqrt(3)
	size = dist * BFIXED(0,4);

	FIXED_VEC3SCALE_R( tr.sunDirection, dist, origin );
	PerpendicularVector( vec1, tr.sunDirection );
	CrossProduct( tr.sunDirection, vec1, vec2 );

	FIXED_VEC3SCALE_R( vec1, size, bvec1 );
	FIXED_VEC3SCALE_R( vec2, size, bvec2 );

	// farthest depth range
	glDepthRangeX( GFIXED_1, GFIXED_1 );

	// FIXME: use quad stamp
	RB_BeginSurface( tr.sunShader, tess.fogNum );
		VectorCopy( origin, temp );
		VectorSubtract( temp, bvec1, temp );
		VectorSubtract( temp, bvec2, temp );
		VectorCopy( temp, tess.xyz[tess.numVertexes] );
		tess.texCoords[tess.numVertexes][0][0] = GFIXED_0;
		tess.texCoords[tess.numVertexes][0][1] = GFIXED_0;
		tess.vertexColors[tess.numVertexes][0] = 255;
		tess.vertexColors[tess.numVertexes][1] = 255;
		tess.vertexColors[tess.numVertexes][2] = 255;
		tess.numVertexes++;

		VectorCopy( origin, temp );
		VectorAdd( temp, bvec1, temp );
		VectorSubtract( temp, bvec2, temp );
		VectorCopy( temp, tess.xyz[tess.numVertexes] );
		tess.texCoords[tess.numVertexes][0][0] = GFIXED_0;
		tess.texCoords[tess.numVertexes][0][1] = GFIXED_1;
		tess.vertexColors[tess.numVertexes][0] = 255;
		tess.vertexColors[tess.numVertexes][1] = 255;
		tess.vertexColors[tess.numVertexes][2] = 255;
		tess.numVertexes++;

		VectorCopy( origin, temp );
		VectorAdd( temp, bvec1, temp );
		VectorAdd( temp, bvec2, temp );
		VectorCopy( temp, tess.xyz[tess.numVertexes] );
		tess.texCoords[tess.numVertexes][0][0] = GFIXED_1;
		tess.texCoords[tess.numVertexes][0][1] = GFIXED_1;
		tess.vertexColors[tess.numVertexes][0] = 255;
		tess.vertexColors[tess.numVertexes][1] = 255;
		tess.vertexColors[tess.numVertexes][2] = 255;
		tess.numVertexes++;

		VectorCopy( origin, temp );
		VectorSubtract( temp, bvec1, temp );
		VectorAdd( temp, bvec2, temp );
		VectorCopy( temp, tess.xyz[tess.numVertexes] );
		tess.texCoords[tess.numVertexes][0][0] = GFIXED_1;
		tess.texCoords[tess.numVertexes][0][1] = GFIXED_0;
		tess.vertexColors[tess.numVertexes][0] = 255;
		tess.vertexColors[tess.numVertexes][1] = 255;
		tess.vertexColors[tess.numVertexes][2] = 255;
		tess.numVertexes++;

		tess.indexes[tess.numIndexes++] = 0;
		tess.indexes[tess.numIndexes++] = 1;
		tess.indexes[tess.numIndexes++] = 2;
		tess.indexes[tess.numIndexes++] = 0;
		tess.indexes[tess.numIndexes++] = 2;
		tess.indexes[tess.numIndexes++] = 3;

	RB_EndSurface();

	// back to normal depth range
	glDepthRangeX( GFIXED_0, GFIXED_1);
}
예제 #22
0
파일: cl_ui.cpp 프로젝트: entdark/jaMME
/*
====================
CL_UISystemCalls

The ui module is making a system call
====================
*/
intptr_t CL_UISystemCalls(intptr_t *args) {
	switch(args[0]) {
	//rww - alright, DO NOT EVER add a GAME/CGAME/UI generic call without adding a trap to match, and
	//all of these traps must be shared and have cases in sv_game, cl_cgame, and cl_ui. They must also
	//all be in the same order, and start at 100.
	case TRAP_MEMSET:
		Com_Memset(VMA(1), args[2], args[3]);
		return 0;
	case TRAP_MEMCPY:
		Com_Memcpy(VMA(1), VMA(2), args[3]);
		return 0;
	case TRAP_STRNCPY:
		return (intptr_t)strncpy((char *)VMA(1), (const char *)VMA(2), args[3]);
	case TRAP_SIN:
		return FloatAsInt(sin(VMF(1)));
	case TRAP_COS:
		return FloatAsInt(cos(VMF(1)));
	case TRAP_ATAN2:
		return FloatAsInt(atan2(VMF(1), VMF(2)));
	case TRAP_SQRT:
		return FloatAsInt(sqrt(VMF(1)));
	case TRAP_MATRIXMULTIPLY:
		MatrixMultiply((vec3_t *)VMA(1), (vec3_t *)VMA(2), (vec3_t *)VMA(3));
		return 0;
	case TRAP_ANGLEVECTORS:
		AngleVectors((const float *)VMA(1), (float *)VMA(2), (float *)VMA(3), (float *)VMA(4));
		return 0;
	case TRAP_PERPENDICULARVECTOR:
		PerpendicularVector((float *)VMA(1), (const float *)VMA(2));
		return 0;
	case TRAP_FLOOR:
		return FloatAsInt(floor(VMF(1)));
	case TRAP_CEIL:
		return FloatAsInt(ceil(VMF(1)));
	case TRAP_TESTPRINTINT:
		return 0;
	case TRAP_TESTPRINTFLOAT:
		return 0;
	case TRAP_ACOS:
		return FloatAsInt(Q_acos(VMF(1)));
	case TRAP_ASIN:
		return FloatAsInt(Q_asin(VMF(1)));
	case UI_ERROR:
		Com_Error( ERR_DROP, "%s", VMA(1) );
		return 0;

	case UI_PRINT:
		Com_Printf( "%s", VMA(1) );
		return 0;

	case UI_MILLISECONDS:
		return Sys_Milliseconds();

	case UI_CVAR_REGISTER:
		Cvar_Register( (vmCvar_t *)VMA(1), (const char *)VMA(2), (const char *)VMA(3), args[4] ); 
		return 0;

	case UI_CVAR_UPDATE:
		Cvar_Update( (vmCvar_t *)VMA(1) );
		return 0;

	case UI_CVAR_SET:
		Cvar_Set( (const char *)VMA(1), (const char *)VMA(2) );
		return 0;

	case UI_CVAR_VARIABLEVALUE:
		return FloatAsInt( Cvar_VariableValue( (const char *)VMA(1) ) );

	case UI_CVAR_VARIABLESTRINGBUFFER:
		Cvar_VariableStringBuffer( (const char *)VMA(1), (char *)VMA(2), args[3] );
		return 0;

	case UI_CVAR_SETVALUE:
		Cvar_SetValue( (const char *)VMA(1), VMF(2) );
		return 0;

	case UI_CVAR_RESET:
		Cvar_Reset( (const char *)VMA(1) );
		return 0;

	case UI_CVAR_CREATE:
		Cvar_Get( (const char *)VMA(1), (const char *)VMA(2), args[3] );
		return 0;

	case UI_CVAR_INFOSTRINGBUFFER:
		Cvar_InfoStringBuffer( args[1], (char *)VMA(2), args[3] );
		return 0;

	case UI_ARGC:
		return Cmd_Argc();

	case UI_ARGV:
		Cmd_ArgvBuffer( args[1], (char *)VMA(2), args[3] );
		return 0;

	case UI_CMD_EXECUTETEXT:
		Cbuf_ExecuteText( args[1], (const char *)VMA(2) );
		return 0;

	case UI_FS_FOPENFILE:
		return FS_FOpenFileByMode( (const char *)VMA(1), (int *)VMA(2), (fsMode_t)args[3] );

	case UI_FS_READ:
		FS_Read2( VMA(1), args[2], args[3] );
		return 0;

	case UI_FS_WRITE:
		FS_Write( VMA(1), args[2], args[3] );
		return 0;

	case UI_FS_FCLOSEFILE:
		FS_FCloseFile( args[1] );
		return 0;

	case UI_FS_GETFILELIST:
		return FS_GetFileList( (const char *)VMA(1), (const char *)VMA(2), (char *)VMA(3), args[4] );

	case UI_R_REGISTERMODEL:
		return re.RegisterModel( (const char *)VMA(1) );

	case UI_R_REGISTERSKIN:
		return re.RegisterSkin( (const char *)VMA(1) );

	case UI_R_REGISTERSHADERNOMIP:
		return re.RegisterShaderNoMip( (const char *)VMA(1) );

	case UI_R_SHADERNAMEFROMINDEX:
		{
			char *gameMem = (char *)VMA(1);
			const char *retMem = re.ShaderNameFromIndex(args[2]);
			if (retMem)
			{
				strcpy(gameMem, retMem);
			}
			else
			{
				gameMem[0] = 0;
			}
		}
		return 0;

	case UI_R_CLEARSCENE:
		re.ClearScene();
		return 0;

	case UI_R_ADDREFENTITYTOSCENE:
		re.AddRefEntityToScene( (const refEntity_t *)VMA(1) );
		return 0;

	case UI_R_ADDPOLYTOSCENE:
		re.AddPolyToScene( args[1], args[2], (const polyVert_t *)VMA(3), 1 );
		return 0;

	case UI_R_ADDLIGHTTOSCENE:
#ifdef VV_LIGHTING
		VVLightMan.RE_AddLightToScene( (const float *)VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
#else
		re.AddLightToScene( (const float *)VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
#endif
		return 0;

	case UI_R_RENDERSCENE:
		re.RenderScene( (const refdef_t *)VMA(1) );
		return 0;

	case UI_R_SETCOLOR:
		re.SetColor( (const float *)VMA(1) );
		return 0;

	case UI_R_DRAWSTRETCHPIC:
		re.DrawStretchPic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9] );
		return 0;

  case UI_R_MODELBOUNDS:
		re.ModelBounds( args[1], (float *)VMA(2), (float *)VMA(3) );
		return 0;

	case UI_UPDATESCREEN:
		SCR_UpdateScreen();
		return 0;

	case UI_CM_LERPTAG:
		re.LerpTag( (orientation_t *)VMA(1), args[2], args[3], args[4], VMF(5), (const char *)VMA(6) );
		return 0;

	case UI_S_REGISTERSOUND:
		return S_RegisterSound( (const char *)VMA(1) );

	case UI_S_STARTLOCALSOUND:
		S_StartLocalSound( args[1], args[2] );
		return 0;

	case UI_KEY_KEYNUMTOSTRINGBUF:
		Key_KeynumToStringBuf( args[1], (char *)VMA(2), args[3] );
		return 0;

	case UI_KEY_GETBINDINGBUF:
		Key_GetBindingBuf( args[1], (char *)VMA(2), args[3] );
		return 0;

	case UI_KEY_SETBINDING:
		Key_SetBinding( args[1], (const char *)VMA(2) );
		return 0;

	case UI_KEY_ISDOWN:
		return Key_IsDown( args[1] );

	case UI_KEY_GETOVERSTRIKEMODE:
		return Key_GetOverstrikeMode();

	case UI_KEY_SETOVERSTRIKEMODE:
		Key_SetOverstrikeMode( (qboolean)args[1] );
		return 0;

	case UI_KEY_CLEARSTATES:
		Key_ClearStates();
		return 0;

	case UI_KEY_GETCATCHER:
		return Key_GetCatcher();

	case UI_KEY_SETCATCHER:
		// Don't allow the ui module to close the console
		Key_SetCatcher( args[1] | ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) );
		return 0;

	case UI_GETCLIPBOARDDATA:
		GetClipboardData( (char *)VMA(1), args[2] );
		return 0;

	case UI_GETCLIENTSTATE:
		GetClientState( (uiClientState_t *)VMA(1) );
		return 0;		

	case UI_GETGLCONFIG:
		CL_GetGlconfig( (glconfig_t *)VMA(1) );
		return 0;

	case UI_GETCONFIGSTRING:
		return GetConfigString( args[1], (char *)VMA(2), args[3] );

	case UI_LAN_LOADCACHEDSERVERS:
		LAN_LoadCachedServers();
		return 0;

	case UI_LAN_SAVECACHEDSERVERS:
		LAN_SaveServersToCache();
		return 0;

	case UI_LAN_ADDSERVER:
		return LAN_AddServer(args[1], (const char *)VMA(2), (const char *)VMA(3));

	case UI_LAN_REMOVESERVER:
		LAN_RemoveServer(args[1], (const char *)VMA(2));
		return 0;

	case UI_LAN_GETPINGQUEUECOUNT:
		return LAN_GetPingQueueCount();

	case UI_LAN_CLEARPING:
		LAN_ClearPing( args[1] );
		return 0;

	case UI_LAN_GETPING:
		LAN_GetPing( args[1], (char *)VMA(2), args[3], (int *)VMA(4) );
		return 0;

	case UI_LAN_GETPINGINFO:
		LAN_GetPingInfo( args[1], (char *)VMA(2), args[3] );
		return 0;

	case UI_LAN_GETSERVERCOUNT:
		return LAN_GetServerCount(args[1]);

	case UI_LAN_GETSERVERADDRESSSTRING:
		LAN_GetServerAddressString( args[1], args[2], (char *)VMA(3), args[4] );
		return 0;

	case UI_LAN_GETSERVERINFO:
		LAN_GetServerInfo( args[1], args[2], (char *)VMA(3), args[4] );
		return 0;

	case UI_LAN_GETSERVERPING:
		return LAN_GetServerPing( args[1], args[2] );

	case UI_LAN_MARKSERVERVISIBLE:
		LAN_MarkServerVisible( args[1], args[2], (qboolean)args[3] );
		return 0;

	case UI_LAN_SERVERISVISIBLE:
		return LAN_ServerIsVisible( args[1], args[2] );

	case UI_LAN_UPDATEVISIBLEPINGS:
		return LAN_UpdateVisiblePings( args[1] );

	case UI_LAN_RESETPINGS:
		LAN_ResetPings( args[1] );
		return 0;

	case UI_LAN_SERVERSTATUS:
		return LAN_GetServerStatus( (char *)VMA(1), (char *)VMA(2), args[3] );

	case UI_LAN_COMPARESERVERS:
		return LAN_CompareServers( args[1], args[2], args[3], args[4], args[5] );

	case UI_MEMORY_REMAINING:
		return Hunk_MemoryRemaining();

	case UI_R_REGISTERFONT:
		return re.RegisterFont( (const char *)VMA(1) );

	case UI_R_FONT_STRLENPIXELS:
		return re.Font_StrLenPixels( (const char *)VMA(1), args[2], VMF(3) );

	case UI_R_FONT_STRLENCHARS:
		return re.Font_StrLenChars( (const char *)VMA(1) );

	case UI_R_FONT_STRHEIGHTPIXELS:
		return re.Font_HeightPixels( args[1], VMF(2) );

	case UI_R_FONT_DRAWSTRING:
#ifdef __ANDROID__
		re.Font_DrawString( VMF(1), VMF(2), (const char *)VMA(3), (const float *) VMA(4), args[5], args[6], VMF(7) );
#else
		{float ox, oy;
		if (cls.mmeState >= MME_STATE_DEFAULT) {
			ox = VMF(1); oy = VMF(2);
		} else {
			ox = args[1]; oy = args[2];
		}
		re.Font_DrawString( ox, oy, (const char *)VMA(3), (const float *) VMA(4), args[5], args[6], VMF(7) );}
		return 0;
#endif
	case UI_LANGUAGE_ISASIAN:
		return re.Language_IsAsian();

	case UI_LANGUAGE_USESSPACES:
		return re.Language_UsesSpaces();

	case UI_ANYLANGUAGE_READCHARFROMSTRING:
		return re.AnyLanguage_ReadCharFromString( (const char *)VMA(1), (int *) VMA(2), (qboolean *) VMA(3) );

	case UI_PC_ADD_GLOBAL_DEFINE:
		return botlib_export->PC_AddGlobalDefine( (char *)VMA(1) );
	case UI_PC_LOAD_SOURCE:
		return botlib_export->PC_LoadSourceHandle( (const char *)VMA(1) );
	case UI_PC_FREE_SOURCE:
		return botlib_export->PC_FreeSourceHandle( args[1] );
	case UI_PC_READ_TOKEN:
		return botlib_export->PC_ReadTokenHandle( args[1], (struct pc_token_s *)VMA(2) );
	case UI_PC_SOURCE_FILE_AND_LINE:
		return botlib_export->PC_SourceFileAndLine( args[1], (char *)VMA(2), (int *)VMA(3) );
	case UI_PC_LOAD_GLOBAL_DEFINES:
		return botlib_export->PC_LoadGlobalDefines ( (char *)VMA(1) );
	case UI_PC_REMOVE_ALL_GLOBAL_DEFINES:
		botlib_export->PC_RemoveAllGlobalDefines ( );
		return 0;

	case UI_S_STOPBACKGROUNDTRACK:
		S_StopBackgroundTrack();
		return 0;
	case UI_S_STARTBACKGROUNDTRACK:
		S_StartBackgroundTrack( (const char *)VMA(1), (const char *)VMA(2), qfalse);
		return 0;

	case UI_REAL_TIME:
		return Com_RealTime( (struct qtime_s *)VMA(1) );

	case UI_CIN_PLAYCINEMATIC:
	  Com_DPrintf("UI_CIN_PlayCinematic\n");
	  return CIN_PlayCinematic((const char *)VMA(1), args[2], args[3], args[4], args[5], args[6]);

	case UI_CIN_STOPCINEMATIC:
	  return CIN_StopCinematic(args[1]);

	case UI_CIN_RUNCINEMATIC:
	  return CIN_RunCinematic(args[1]);

	case UI_CIN_DRAWCINEMATIC:
	  CIN_DrawCinematic(args[1]);
	  return 0;

	case UI_CIN_SETEXTENTS:
	  CIN_SetExtents(args[1], args[2], args[3], args[4], args[5]);
	  return 0;

	case UI_R_REMAP_SHADER:
		re.RemapShader( (const char *)VMA(1), (const char *)VMA(2), (const char *)VMA(3) );
		return 0;

	case UI_SP_GETNUMLANGUAGES:
		return SE_GetNumLanguages();

	case UI_SP_GETLANGUAGENAME:
		char *languageName,*holdName;

		holdName = ((char *)VMA(2));
		languageName = (char *) SE_GetLanguageName((const intptr_t)VMA(1));
		Q_strncpyz( holdName, languageName,128 );
		return 0;

	case UI_SP_GETSTRINGTEXTSTRING:
		const char* text;

		assert(VMA(1));
		assert(VMA(2));
		text = SE_GetString((const char *) VMA(1));
		Q_strncpyz( (char *) VMA(2), text, args[3] );
		return qtrue;

/*
Ghoul2 Insert Start
*/
/*
Ghoul2 Insert Start
*/
		
	case UI_G2_LISTSURFACES:
		re.G2API_ListSurfaces( (CGhoul2Info *) args[1] );
		return 0;

	case UI_G2_LISTBONES:
		re.G2API_ListBones( (CGhoul2Info *) args[1], args[2]);
		return 0;

	case UI_G2_HAVEWEGHOULMODELS:
		return re.G2API_HaveWeGhoul2Models(((CGhoul2Info_v *)args[1]) );

	case UI_G2_SETMODELS:
		re.G2API_SetGhoul2ModelIndexes(((CGhoul2Info_v *)args[1]),(qhandle_t *)VMA(2),(qhandle_t *)VMA(3));
		return 0;

	case UI_G2_GETBOLT:
		return re.G2API_GetBoltMatrix(((CGhoul2Info_v *)args[1]), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9));

	case UI_G2_GETBOLT_NOREC:
		re.G2API_BoltMatrixReconstruction( qfalse );//gG2_GBMNoReconstruct = qtrue;
		return re.G2API_GetBoltMatrix(((CGhoul2Info_v *)args[1]), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9));

	case UI_G2_GETBOLT_NOREC_NOROT:
		//RAZFIXME: cgame reconstructs bolt matrix, why is this different?
		re.G2API_BoltMatrixReconstruction( qfalse );//gG2_GBMNoReconstruct = qtrue;
		re.G2API_BoltMatrixSPMethod( qtrue );//gG2_GBMUseSPMethod = qtrue;
		return re.G2API_GetBoltMatrix(((CGhoul2Info_v *)args[1]), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9));

	case UI_G2_INITGHOUL2MODEL:
#ifdef _FULL_G2_LEAK_CHECKING
		g_G2AllocServer = 0;
#endif
		return	re.G2API_InitGhoul2Model((CGhoul2Info_v **)VMA(1), (const char *)VMA(2), args[3], (qhandle_t) args[4],
									  (qhandle_t) args[5], args[6], args[7]);


	case UI_G2_COLLISIONDETECT:
	case UI_G2_COLLISIONDETECTCACHE:
		return 0; //not supported for ui

	case UI_G2_ANGLEOVERRIDE:
		return re.G2API_SetBoneAngles(((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3), (float *)VMA(4), args[5],
							 (const Eorientations) args[6], (const Eorientations) args[7], (const Eorientations) args[8],
							 (qhandle_t *)VMA(9), args[10], args[11] );
	
	case UI_G2_CLEANMODELS:
#ifdef _FULL_G2_LEAK_CHECKING
		g_G2AllocServer = 0;
#endif
		re.G2API_CleanGhoul2Models((CGhoul2Info_v **)VMA(1));
	//	re.G2API_CleanGhoul2Models((CGhoul2Info_v **)args[1]);
		return 0;

	case UI_G2_PLAYANIM:
		return re.G2API_SetBoneAnim(((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3), args[4], args[5],
								args[6], VMF(7), args[8], VMF(9), args[10]);

	case UI_G2_GETBONEANIM:
		{
			CGhoul2Info_v &g2 = *((CGhoul2Info_v *)args[1]);
			int modelIndex = args[10];
			return re.G2API_GetBoneAnim(&g2[modelIndex], (const char*)VMA(2), args[3], (float *)VMA(4), (int *)VMA(5),
								(int *)VMA(6), (int *)VMA(7), (float *)VMA(8), (int *)VMA(9));
		}

	case UI_G2_GETBONEFRAME:
		{ //rwwFIXMEFIXME: Just make a G2API_GetBoneFrame func too. This is dirty.
			CGhoul2Info_v &g2 = *((CGhoul2Info_v *)args[1]);
			int modelIndex = args[6];
			int iDontCare1 = 0, iDontCare2 = 0, iDontCare3 = 0;
			float fDontCare1 = 0;
			return re.G2API_GetBoneAnim(&g2[modelIndex], (const char*)VMA(2), args[3], (float *)VMA(4), &iDontCare1,
								&iDontCare2, &iDontCare3, &fDontCare1, (int *)VMA(5));
		}

	case UI_G2_GETGLANAME:
		//	return (int)G2API_GetGLAName(*((CGhoul2Info_v *)VMA(1)), args[2]);
		{
			char *point = ((char *)VMA(3));
			char *local;
			local = re.G2API_GetGLAName(((CGhoul2Info_v *)args[1]), args[2]);
			if (local)
			{
				strcpy(point, local);
			}
		}
		return 0;

	case UI_G2_COPYGHOUL2INSTANCE:
		return (int)re.G2API_CopyGhoul2Instance(((CGhoul2Info_v *)args[1]), ((CGhoul2Info_v *)args[2]), args[3]);

	case UI_G2_COPYSPECIFICGHOUL2MODEL:
		re.G2API_CopySpecificG2Model(((CGhoul2Info_v *)args[1]), args[2], ((CGhoul2Info_v *)args[3]), args[4]);
		return 0;

	case UI_G2_DUPLICATEGHOUL2INSTANCE:
#ifdef _FULL_G2_LEAK_CHECKING
		g_G2AllocServer = 0;
#endif
		re.G2API_DuplicateGhoul2Instance(((CGhoul2Info_v *)args[1]), (CGhoul2Info_v **)VMA(2));
		return 0;

	case UI_G2_HASGHOUL2MODELONINDEX:
		return (int)re.G2API_HasGhoul2ModelOnIndex((CGhoul2Info_v **)VMA(1), args[2]);
		//return (int)G2API_HasGhoul2ModelOnIndex((CGhoul2Info_v **)args[1], args[2]);

	case UI_G2_REMOVEGHOUL2MODEL:
#ifdef _FULL_G2_LEAK_CHECKING
		g_G2AllocServer = 0;
#endif
		return (int)re.G2API_RemoveGhoul2Model((CGhoul2Info_v **)VMA(1), args[2]);
		//return (int)G2API_RemoveGhoul2Model((CGhoul2Info_v **)args[1], args[2]);

	case UI_G2_ADDBOLT:
		return re.G2API_AddBolt(((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3));

//	case UI_G2_REMOVEBOLT:
//		return G2API_RemoveBolt(*((CGhoul2Info_v *)VMA(1)), args[2]);

	case UI_G2_SETBOLTON:
		re.G2API_SetBoltInfo(((CGhoul2Info_v *)args[1]), args[2], args[3]);
		return 0;

#ifdef _SOF2	
	case UI_G2_ADDSKINGORE:
		re.G2API_AddSkinGore(*((CGhoul2Info_v *)args[1]),*(SSkinGoreData *)VMA(2));
		return 0;
#endif // _SOF2
/*
Ghoul2 Insert End
*/
	case UI_G2_SETROOTSURFACE:
		return re.G2API_SetRootSurface(((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3));

	case UI_G2_SETSURFACEONOFF:
		return re.G2API_SetSurfaceOnOff(((CGhoul2Info_v *)args[1]), (const char *)VMA(2), /*(const int)VMA(3)*/args[3]);

	case UI_G2_SETNEWORIGIN:
		return re.G2API_SetNewOrigin(((CGhoul2Info_v *)args[1]), /*(const int)VMA(2)*/args[2]);

	case UI_G2_GETTIME:
		return re.G2API_GetTime(0);

	case UI_G2_SETTIME:
		re.G2API_SetTime(args[1], args[2]);
		return 0;

	case UI_G2_SETRAGDOLL:
		return 0; //not supported for ui
		break;
	case UI_G2_ANIMATEG2MODELS:
		return 0; //not supported for ui
		break;

	case UI_G2_SETBONEIKSTATE:
		return re.G2API_SetBoneIKState(*((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3), args[4], (sharedSetBoneIKStateParams_t *)VMA(5));
	case UI_G2_IKMOVE:
		return re.G2API_IKMove(*((CGhoul2Info_v *)args[1]), args[2], (sharedIKMoveParams_t *)VMA(3));

	case UI_G2_GETSURFACENAME:
		{ //Since returning a pointer in such a way to a VM seems to cause MASSIVE FAILURE<tm>, we will shove data into the pointer the vm passes instead
			char *point = ((char *)VMA(4));
			char *local;
			int modelindex = args[3];
			CGhoul2Info_v &g2 = *((CGhoul2Info_v *)args[1]);
			local = re.G2API_GetSurfaceName(&g2[modelindex], args[2]);
			if (local)
			{
				strcpy(point, local);
			}
		}
		return 0;
	case UI_G2_SETSKIN:
		{
			CGhoul2Info_v &g2 = *((CGhoul2Info_v *)args[1]);
			int modelIndex = args[2];
			return re.G2API_SetSkin(&g2[modelIndex], args[3], args[4]);
		}
	case UI_G2_ATTACHG2MODEL:
		{
			CGhoul2Info_v *g2From = ((CGhoul2Info_v *)args[1]);
			CGhoul2Info_v *g2To = ((CGhoul2Info_v *)args[3]);
			
			return re.G2API_AttachG2Model(g2From, args[2], g2To, args[4], args[5]);
		}
/*
Ghoul2 Insert End
*/
	case UI_MME_FONTRATIOFIX:
		re.FontRatioFix(VMF(1));
        return 0; 
	case UI_MME_EDITINGFIELD:
		cls.uiEditingField = (qboolean)args[1];
        return 0;	
	default:
		Com_Error( ERR_DROP, "Bad UI system trap: %ld", (long int) args[0] );

	}

	return 0;
}
예제 #23
0
/*
** RB_DrawSun
*/
void RB_DrawSun( void ) {
    float		size;
    float		dist;
    vec3_t		origin, vec1, vec2;
    vec3_t		temp;

    if ( !backEnd.skyRenderedThisView ) {
        return;
    }
    if ( !r_drawSun->integer ) {
        return;
    }
    qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );
    qglTranslatef (backEnd.viewParms.ori.origin[0], backEnd.viewParms.ori.origin[1], backEnd.viewParms.ori.origin[2]);

    dist = 	backEnd.viewParms.zFar / 1.75;		// div sqrt(3)
    size = dist * 0.4;

    VectorScale( tr.sunDirection, dist, origin );
    PerpendicularVector( vec1, tr.sunDirection );
    CrossProduct( tr.sunDirection, vec1, vec2 );

    VectorScale( vec1, size, vec1 );
    VectorScale( vec2, size, vec2 );

    // farthest depth range
    qglDepthRange( 1.0, 1.0 );

    // FIXME: use quad stamp
    RB_BeginSurface( tr.sunShader, tess.fogNum );
    VectorCopy( origin, temp );
    VectorSubtract( temp, vec1, temp );
    VectorSubtract( temp, vec2, temp );
    VectorCopy( temp, tess.xyz[tess.numVertexes] );
    tess.texCoords[tess.numVertexes][0][0] = 0;
    tess.texCoords[tess.numVertexes][0][1] = 0;
    tess.vertexColors[tess.numVertexes][0] = 255;
    tess.vertexColors[tess.numVertexes][1] = 255;
    tess.vertexColors[tess.numVertexes][2] = 255;
    tess.numVertexes++;

    VectorCopy( origin, temp );
    VectorAdd( temp, vec1, temp );
    VectorSubtract( temp, vec2, temp );
    VectorCopy( temp, tess.xyz[tess.numVertexes] );
    tess.texCoords[tess.numVertexes][0][0] = 0;
    tess.texCoords[tess.numVertexes][0][1] = 1;
    tess.vertexColors[tess.numVertexes][0] = 255;
    tess.vertexColors[tess.numVertexes][1] = 255;
    tess.vertexColors[tess.numVertexes][2] = 255;
    tess.numVertexes++;

    VectorCopy( origin, temp );
    VectorAdd( temp, vec1, temp );
    VectorAdd( temp, vec2, temp );
    VectorCopy( temp, tess.xyz[tess.numVertexes] );
    tess.texCoords[tess.numVertexes][0][0] = 1;
    tess.texCoords[tess.numVertexes][0][1] = 1;
    tess.vertexColors[tess.numVertexes][0] = 255;
    tess.vertexColors[tess.numVertexes][1] = 255;
    tess.vertexColors[tess.numVertexes][2] = 255;
    tess.numVertexes++;

    VectorCopy( origin, temp );
    VectorSubtract( temp, vec1, temp );
    VectorAdd( temp, vec2, temp );
    VectorCopy( temp, tess.xyz[tess.numVertexes] );
    tess.texCoords[tess.numVertexes][0][0] = 1;
    tess.texCoords[tess.numVertexes][0][1] = 0;
    tess.vertexColors[tess.numVertexes][0] = 255;
    tess.vertexColors[tess.numVertexes][1] = 255;
    tess.vertexColors[tess.numVertexes][2] = 255;
    tess.numVertexes++;

    tess.indexes[tess.numIndexes++] = 0;
    tess.indexes[tess.numIndexes++] = 1;
    tess.indexes[tess.numIndexes++] = 2;
    tess.indexes[tess.numIndexes++] = 0;
    tess.indexes[tess.numIndexes++] = 2;
    tess.indexes[tess.numIndexes++] = 3;

    RB_EndSurface();

    // back to normal depth range
    qglDepthRange( 0.0, 1.0 );
}
예제 #24
0
/*
=================
R_GetPortalOrientation

entityNum is the entity that the portal surface is a part of, which may
be moving and rotating.

Returns qtrue if it should be mirrored
=================
*/
qboolean R_GetPortalOrientations( drawSurf_t *drawSurf, int entityNum,
							 orientation_t *surface, orientation_t *camera,
							 vec3_t pvsOrigin, qboolean *mirror ) {
	int			i;
	cplane_t	originalPlane, plane;
	trRefEntity_t	*e;
	float		d;
	vec3_t		transformed;

	// create plane axis for the portal we are seeing
	R_PlaneForSurface( drawSurf->surface, &originalPlane );

	// rotate the plane if necessary
	if ( entityNum != REFENTITYNUM_WORLD ) {
		tr.currentEntityNum = entityNum;
		tr.currentEntity = &tr.refdef.entities[entityNum];

		// get the orientation of the entity
		R_RotateForEntity( tr.currentEntity, &tr.viewParms, &tr.ori );

		// rotate the plane, but keep the non-rotated version for matching
		// against the portalSurface entities
		R_LocalNormalToWorld( originalPlane.normal, plane.normal );
		plane.dist = originalPlane.dist + DotProduct( plane.normal, tr.ori.origin );

		// translate the original plane
		originalPlane.dist = originalPlane.dist + DotProduct( originalPlane.normal, tr.ori.origin );
	} else {
		plane = originalPlane;
	}

	VectorCopy( plane.normal, surface->axis[0] );
	PerpendicularVector( surface->axis[1], surface->axis[0] );
	CrossProduct( surface->axis[0], surface->axis[1], surface->axis[2] );

	// locate the portal entity closest to this plane.
	// origin will be the origin of the portal, origin2 will be
	// the origin of the camera
	for ( i = 0 ; i < tr.refdef.num_entities ; i++ ) {
		e = &tr.refdef.entities[i];
		if ( e->e.reType != RT_PORTALSURFACE ) {
			continue;
		}

		d = DotProduct( e->e.origin, originalPlane.normal ) - originalPlane.dist;
		if ( d > 64 || d < -64) {
			continue;
		}

		// get the pvsOrigin from the entity
		VectorCopy( e->e.oldorigin, pvsOrigin );

		// if the entity is just a mirror, don't use as a camera point
		if ( e->e.oldorigin[0] == e->e.origin[0] &&
			e->e.oldorigin[1] == e->e.origin[1] &&
			e->e.oldorigin[2] == e->e.origin[2] ) {
			VectorScale( plane.normal, plane.dist, surface->origin );
			VectorCopy( surface->origin, camera->origin );
			VectorSubtract( vec3_origin, surface->axis[0], camera->axis[0] );
			VectorCopy( surface->axis[1], camera->axis[1] );
			VectorCopy( surface->axis[2], camera->axis[2] );

			*mirror = qtrue;
			return qtrue;
		}

		// project the origin onto the surface plane to get
		// an origin point we can rotate around
		d = DotProduct( e->e.origin, plane.normal ) - plane.dist;
		VectorMA( e->e.origin, -d, surface->axis[0], surface->origin );

		// now get the camera origin and orientation
		VectorCopy( e->e.oldorigin, camera->origin );
		AxisCopy( e->e.axis, camera->axis );
		VectorSubtract( vec3_origin, camera->axis[0], camera->axis[0] );
		VectorSubtract( vec3_origin, camera->axis[1], camera->axis[1] );

		// optionally rotate
		if ( e->e.oldframe ) {
			// if a speed is specified
			if ( e->e.frame ) {
				// continuous rotate
				d = (tr.refdef.time/1000.0f) * e->e.frame;
				VectorCopy( camera->axis[1], transformed );
				RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
				CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
			} else {
				// bobbing rotate, with skinNum being the rotation offset
				d = sin( tr.refdef.time * 0.003f );
				d = e->e.skinNum + d * 4;
				VectorCopy( camera->axis[1], transformed );
				RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
				CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
			}
		}
		else if ( e->e.skinNum ) {
			d = e->e.skinNum;
			VectorCopy( camera->axis[1], transformed );
			RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
			CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
		}
		*mirror = qfalse;
		return qtrue;
	}

	// if we didn't locate a portal entity, don't render anything.
	// We don't want to just treat it as a mirror, because without a
	// portal entity the server won't have communicated a proper entity set
	// in the snapshot

	// unfortunately, with local movement prediction it is easily possible
	// to see a surface before the server has communicated the matching
	// portal surface entity, so we don't want to print anything here...

	//ri->Printf( PRINT_ALL, "Portal surface without a portal entity\n" );

	return qfalse;
}
예제 #25
0
/*
** RB_DrawSun
*/
void RB_DrawSun( void )
{
#if 0
	float    size;
	float    dist;
	vec3_t   origin, vec1, vec2;
	vec3_t   temp;
	matrix_t transformMatrix;
	matrix_t modelViewMatrix;

	if ( !backEnd.skyRenderedThisView )
	{
		return;
	}

	if ( !r_drawSun->integer )
	{
		return;
	}

	GL_PushMatrix();

	GL_BindProgram( &tr.genericShader );

	// set uniforms
	GLSL_SetUniform_TCGen_Environment( &tr.genericShader,  qfalse );
	GLSL_SetUniform_InverseVertexColor( &tr.genericShader,  qfalse );

	if ( glConfig2.vboVertexSkinningAvailable )
	{
		GLSL_SetUniform_VertexSkinning( &tr.genericShader, qfalse );
	}

	GLSL_SetUniform_DeformGen( &tr.genericShader, DGEN_NONE );
	GLSL_SetUniform_AlphaTest( &tr.genericShader, -1.0 );

	MatrixSetupTranslation( transformMatrix, backEnd.viewParms.orientation.origin[ 0 ], backEnd.viewParms.orientation.origin[ 1 ],
	                        backEnd.viewParms.orientation.origin[ 2 ] );
	MatrixMultiply( backEnd.viewParms.world.viewMatrix, transformMatrix, modelViewMatrix );

	GL_LoadProjectionMatrix( backEnd.viewParms.projectionMatrix );
	GL_LoadModelViewMatrix( modelViewMatrix );

	GLSL_SetUniform_ModelMatrix( &tr.genericShader, backEnd.orientation.transformMatrix );
	GLSL_SetUniform_ModelViewProjectionMatrix( &tr.genericShader, glState.modelViewProjectionMatrix[ glState.stackIndex ] );

	GLSL_SetUniform_PortalClipping( &tr.genericShader, backEnd.viewParms.isPortal );

	if ( backEnd.viewParms.isPortal )
	{
		float plane[ 4 ];

		// clipping plane in world space
		plane[ 0 ] = backEnd.viewParms.portalPlane.normal[ 0 ];
		plane[ 1 ] = backEnd.viewParms.portalPlane.normal[ 1 ];
		plane[ 2 ] = backEnd.viewParms.portalPlane.normal[ 2 ];
		plane[ 3 ] = backEnd.viewParms.portalPlane.dist;

		GLSL_SetUniform_PortalPlane( &tr.genericShader, plane );
	}

	dist = backEnd.viewParms.skyFar / 1.75; // div sqrt(3)
	size = dist * 0.4;

	VectorScale( tr.sunDirection, dist, origin );
	PerpendicularVector( vec1, tr.sunDirection );
	CrossProduct( tr.sunDirection, vec1, vec2 );

	VectorScale( vec1, size, vec1 );
	VectorScale( vec2, size, vec2 );

	// farthest depth range
	glDepthRange( 1.0, 1.0 );

	// FIXME: use quad stamp
	Tess_Begin( Tess_StageIteratorGeneric, tr.sunShader, NULL, tess.skipTangentSpaces, qfalse, -1, tess.fogNum );
	VectorCopy( origin, temp );
	VectorSubtract( temp, vec1, temp );
	VectorSubtract( temp, vec2, temp );
	VectorCopy( temp, tess.xyz[ tess.numVertexes ] );
	tess.xyz[ tess.numVertexes ][ 3 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 0 ] = 0;
	tess.texCoords[ tess.numVertexes ][ 1 ] = 0;
	tess.texCoords[ tess.numVertexes ][ 2 ] = 0;
	tess.texCoords[ tess.numVertexes ][ 3 ] = 1;
	tess.colors[ tess.numVertexes ][ 0 ] = 1;
	tess.colors[ tess.numVertexes ][ 1 ] = 1;
	tess.colors[ tess.numVertexes ][ 2 ] = 1;
	tess.numVertexes++;

	VectorCopy( origin, temp );
	VectorAdd( temp, vec1, temp );
	VectorSubtract( temp, vec2, temp );
	VectorCopy( temp, tess.xyz[ tess.numVertexes ] );
	tess.xyz[ tess.numVertexes ][ 3 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 0 ] = 0;
	tess.texCoords[ tess.numVertexes ][ 1 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 2 ] = 0;
	tess.texCoords[ tess.numVertexes ][ 3 ] = 1;
	tess.colors[ tess.numVertexes ][ 0 ] = 1;
	tess.colors[ tess.numVertexes ][ 1 ] = 1;
	tess.colors[ tess.numVertexes ][ 2 ] = 1;
	tess.numVertexes++;

	VectorCopy( origin, temp );
	VectorAdd( temp, vec1, temp );
	VectorAdd( temp, vec2, temp );
	VectorCopy( temp, tess.xyz[ tess.numVertexes ] );
	tess.xyz[ tess.numVertexes ][ 3 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 0 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 1 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 2 ] = 0;
	tess.texCoords[ tess.numVertexes ][ 3 ] = 1;
	tess.colors[ tess.numVertexes ][ 0 ] = 1;
	tess.colors[ tess.numVertexes ][ 1 ] = 1;
	tess.colors[ tess.numVertexes ][ 2 ] = 1;
	tess.numVertexes++;

	VectorCopy( origin, temp );
	VectorSubtract( temp, vec1, temp );
	VectorAdd( temp, vec2, temp );
	VectorCopy( temp, tess.xyz[ tess.numVertexes ] );
	tess.xyz[ tess.numVertexes ][ 3 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 0 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 1 ] = 0;
	tess.texCoords[ tess.numVertexes ][ 2 ] = 0;
	tess.texCoords[ tess.numVertexes ][ 3 ] = 1;
	tess.colors[ tess.numVertexes ][ 0 ] = 1;
	tess.colors[ tess.numVertexes ][ 1 ] = 1;
	tess.colors[ tess.numVertexes ][ 2 ] = 1;
	tess.numVertexes++;

	tess.indexes[ tess.numIndexes++ ] = 0;
	tess.indexes[ tess.numIndexes++ ] = 1;
	tess.indexes[ tess.numIndexes++ ] = 2;
	tess.indexes[ tess.numIndexes++ ] = 0;
	tess.indexes[ tess.numIndexes++ ] = 2;
	tess.indexes[ tess.numIndexes++ ] = 3;

	Tess_End();

	// back to standard depth range
	glDepthRange( 0.0, 1.0 );

	GL_PopMatrix();
#endif
}
예제 #26
0
/*
====================
SV_GameSystemCalls

The module is making a system call
====================
*/
intptr_t SV_GameSystemCalls(intptr_t * args) {
	switch (args[0]) {
		case G_PRINT:
			Com_Printf("%s", (char *)VMA(1));
			return 0;
		case G_ERROR:
			Com_Error(ERR_DROP, "%s", (char *)VMA(1));
			return 0;
		case G_MILLISECONDS:
			return Sys_Milliseconds();
		case G_CVAR_REGISTER:
			Cvar_Register((vmCvar_t*)VMA(1), (char*)VMA(2), (char*)VMA(3), args[4]);
			return 0;
		case G_CVAR_UPDATE:
			Cvar_Update((vmCvar_t*)VMA(1));
			return 0;
		case G_CVAR_SET:
			Cvar_Set((const char *)VMA(1), (const char *)VMA(2));
			return 0;
		case G_CVAR_VARIABLE_INTEGER_VALUE:
			return Cvar_VariableIntegerValue((const char *)VMA(1));
		case G_CVAR_VARIABLE_STRING_BUFFER:
			Cvar_VariableStringBuffer((char *)VMA(1), (char*)VMA(2), args[3]);
			return 0;
		case G_CVAR_LATCHEDVARIABLESTRINGBUFFER:
			Cvar_LatchedVariableStringBuffer((char *)VMA(1), (char*)VMA(2), args[3]);
			return 0;
		case G_ARGC:
			return Cmd_Argc();
		case G_ARGV:
			Cmd_ArgvBuffer(args[1], (char*)VMA(2), args[3]);
			return 0;
		case G_SEND_CONSOLE_COMMAND:
			Cbuf_ExecuteText(args[1], (char *)VMA(2));
			return 0;
		case G_FS_FOPEN_FILE:
			return FS_FOpenFileByMode((char *)VMA(1), (fileHandle_t*)VMA(2), (fsMode_t)args[3]);
		case G_FS_READ:
			FS_Read2(VMA(1), args[2], args[3]);
			return 0;
		case G_FS_WRITE:
			return FS_Write(VMA(1), args[2], args[3]);
		case G_FS_RENAME:
			FS_Rename((char *)VMA(1), (char *)VMA(2));
			return 0;
		case G_FS_FCLOSE_FILE:
			FS_FCloseFile(args[1]);
			return 0;
		case G_FS_GETFILELIST:
			return FS_GetFileList((char *)VMA(1), (char *)VMA(2), (char*)VMA(3), args[4]);
		case G_LOCATE_GAME_DATA:
			SV_LocateGameData((sharedEntity_t*)VMA(1), args[2], args[3], (playerState_t*)VMA(4), args[5]);
			return 0;
		case G_DROP_CLIENT:
			SV_GameDropClient(args[1], (char*)VMA(2), args[3]);
			return 0;
		case G_SEND_SERVER_COMMAND:
			SV_GameSendServerCommand(args[1], (char*)VMA(2));
			return 0;
		case G_LINKENTITY:
			SV_LinkEntity((sharedEntity_t*)VMA(1));
			return 0;
		case G_UNLINKENTITY:
			SV_UnlinkEntity((sharedEntity_t*)VMA(1));
			return 0;
		case G_ENTITIES_IN_BOX:
			return SV_AreaEntities((float*)VMA(1), (float*)VMA(2), (int*)VMA(3), args[4]);
		case G_ENTITY_CONTACT:
			return SV_EntityContact((float*)VMA(1), (float*)VMA(2), (sharedEntity_t*)VMA(3), TT_AABB);
		case G_ENTITY_CONTACTCAPSULE:
			return SV_EntityContact((float*)VMA(1), (float*)VMA(2), (sharedEntity_t*)VMA(3), TT_CAPSULE);
		case G_TRACE:
			SV_Trace((trace_t*)VMA(1), (float*)VMA(2), (float*)VMA(3), (float*)VMA(4), (float*)VMA(5), args[6], args[7], TT_AABB);
			return 0;
		case G_TRACECAPSULE:
			SV_Trace((trace_t*)VMA(1), (float*)VMA(2), (float*)VMA(3), (float*)VMA(4), (float*)VMA(5), args[6], args[7], TT_CAPSULE);
			return 0;
		case G_POINT_CONTENTS:
			return SV_PointContents((float*)VMA(1), args[2]);
		case G_SET_BRUSH_MODEL:
			SV_SetBrushModel((sharedEntity_t*)VMA(1), (char*)VMA(2));
			return 0;
		case G_IN_PVS:
			return SV_inPVS((float*)VMA(1), (float*)VMA(2));
		case G_IN_PVS_IGNORE_PORTALS:
			return SV_inPVSIgnorePortals((float*)VMA(1), (float*)VMA(2));
		case G_SET_CONFIGSTRING:
			SV_SetConfigstring(args[1], (char*)VMA(2));
			return 0;
		case G_GET_CONFIGSTRING:
			SV_GetConfigstring(args[1], (char*)VMA(2), args[3]);
			return 0;
		case G_SET_CONFIGSTRING_RESTRICTIONS:
			SV_SetConfigstringRestrictions( args[1], (clientList_t*)VMA(2) );
			return 0;
		case G_SET_USERINFO:
			SV_SetUserinfo(args[1], (char*)VMA(2));
			return 0;
		case G_GET_USERINFO:
			SV_GetUserinfo(args[1], (char*)VMA(2), args[3]);
			return 0;
		case G_GET_SERVERINFO:
			SV_GetServerinfo((char*)VMA(1), args[2]);
			return 0;
		case G_ADJUST_AREA_PORTAL_STATE:
			SV_AdjustAreaPortalState((sharedEntity_t*)VMA(1),(bool)args[2]);
			return 0;
		case G_AREAS_CONNECTED:
			return CM_AreasConnected(args[1], args[2]);
		case G_UPDATE_SHARED_CONFIG:
			SV_UpdateSharedConfig( args[1], (char*)VMA(2) );
			return 0;
		case G_BOT_ALLOCATE_CLIENT:
			return SV_BotAllocateClient(args[1]);
		case G_BOT_FREE_CLIENT:
			SV_BotFreeClient(args[1]);
			return 0;
		case G_GET_USERCMD:
			SV_GetUsercmd(args[1], (usercmd_t*)VMA(2));
			return 0;
		case G_GET_ENTITY_TOKEN: {
			const char     *s;

			s = COM_Parse(&sv.entityParsePoint);
			Q_strncpyz((char*)VMA(1), s, args[2]);
			if(!sv.entityParsePoint && !s[0]) {
				return false;
			} else {
				return true;
			}
		}
		case G_DEBUG_POLYGON_CREATE:
			return BotImport_DebugPolygonCreate(args[1], args[2], (vec3_t*)VMA(3));
		case G_DEBUG_POLYGON_DELETE:
			BotImport_DebugPolygonDelete(args[1]);
			return 0;
		case G_REAL_TIME:
			return Com_RealTime((qtime_t*)VMA(1));
		case G_SNAPVECTOR:
			Q_SnapVector((float*)VMA(1));
			return 0;
		case G_SEND_GAMESTAT:
			SV_MasterGameStat( (char*)VMA(1) );
			return 0;
		case G_ADDCOMMAND:
			Cmd_AddCommand( (char*)VMA(1), NULL, (char*)VMA(3) );
			return 0;
		case G_REMOVECOMMAND:
			Cmd_RemoveCommand( (char*)VMA(1) );
			return 0;
		case G_GETTAG:
			return SV_GetTag(args[1], args[2], (char*)VMA(3), (orientation_t*)VMA(4));
		case G_REGISTERTAG:
			return SV_LoadTag((char*)VMA(1));
		case G_REGISTERSOUND:
			return S_RegisterSound((char*)VMA(1), (bool)args[2]);
		case G_GET_SOUND_LENGTH:
			return S_GetSoundLength(args[1]);
		case G_PARSE_ADD_GLOBAL_DEFINE:
			return Parse_AddGlobalDefine( (char*)VMA(1) );
		case G_PARSE_LOAD_SOURCE:
			return Parse_LoadSourceHandle( (char*)VMA(1) );
		case G_PARSE_FREE_SOURCE:
			return Parse_FreeSourceHandle( args[1] );
		case G_PARSE_READ_TOKEN:
			return Parse_ReadTokenHandle( args[1], (pc_token_t*)VMA(2) );
		case G_PARSE_SOURCE_FILE_AND_LINE:
			return Parse_SourceFileAndLine( args[1], (char*)VMA(2), (int*)VMA(3) );
		case BOTLIB_SETUP:
			return SV_BotLibSetup();
		case BOTLIB_SHUTDOWN:
			return SV_BotLibShutdown();
		case BOTLIB_LIBVAR_SET:
			return botlib_export->BotLibVarSet((char*)VMA(1), (char*)VMA(2));
		case BOTLIB_LIBVAR_GET:
			return botlib_export->BotLibVarGet((char*)VMA(1), (char*)VMA(2), args[3]);
		case BOTLIB_PC_ADD_GLOBAL_DEFINE:
			return Parse_AddGlobalDefine( (char*)VMA(1) );
		case BOTLIB_PC_LOAD_SOURCE:
			return Parse_LoadSourceHandle((char*)VMA(1));
		case BOTLIB_PC_FREE_SOURCE:
			return Parse_FreeSourceHandle(args[1]);
		case BOTLIB_PC_READ_TOKEN:
			return Parse_ReadTokenHandle(args[1], (pc_token_t*)VMA(2));
		case BOTLIB_PC_SOURCE_FILE_AND_LINE:
			return Parse_SourceFileAndLine(args[1], (char*)VMA(2), (int*)VMA(3));
		case BOTLIB_PC_UNREAD_TOKEN:
			Parse_UnreadLastTokenHandle(args[1]);
			return 0;
		case BOTLIB_START_FRAME:
			return botlib_export->BotLibStartFrame(VMF(1));
		case BOTLIB_LOAD_MAP:
			return botlib_export->BotLibLoadMap((char*)VMA(1));
		case BOTLIB_UPDATENTITY:
			return botlib_export->BotLibUpdateEntity(args[1], (bot_entitystate_t*)VMA(2));
		case BOTLIB_TEST:
			return botlib_export->Test( args[1], (char*)VMA(2), (float*)VMA(3), (float*)VMA(4) );
		case BOTLIB_GET_SNAPSHOT_ENTITY:
			return SV_BotGetSnapshotEntity(args[1], args[2]);
		case BOTLIB_GET_CONSOLE_MESSAGE:
			return SV_BotGetConsoleMessage(args[1], (char*)VMA(2), args[3]);
		case BOTLIB_USER_COMMAND:
			SV_ClientThink(&svs.clients[args[1]], (usercmd_t*)VMA(2));
			return 0;
		case BOTLIB_AAS_ENTITY_INFO:
			botlib_export->aas.AAS_EntityInfo(args[1], (aas_entityinfo_s*)VMA(2));
			return 0;
		case BOTLIB_AAS_INITIALIZED:
			return botlib_export->aas.AAS_Initialized();
		case BOTLIB_AAS_PRESENCE_TYPE_BOUNDING_BOX:
			botlib_export->aas.AAS_PresenceTypeBoundingBox( args[1], (float*)VMA(2), (float*)VMA(3) );
			return 0;
		case BOTLIB_AAS_TIME:
			return FloatAsInt(botlib_export->aas.AAS_Time());
		case BOTLIB_AAS_SETCURRENTWORLD:
			botlib_export->aas.AAS_SetCurrentWorld(args[1]);
			return 0;
		case BOTLIB_AAS_POINT_AREA_NUM:
			return botlib_export->aas.AAS_PointAreaNum( (float*)VMA(1) );
		case BOTLIB_AAS_TRACE_AREAS:
			return botlib_export->aas.AAS_TraceAreas( (float*)VMA(1), (float*)VMA(2), (int*)VMA(3), (vec3_t*)VMA(4), args[5] );
		case BOTLIB_AAS_BBOX_AREAS:
			return botlib_export->aas.AAS_BBoxAreas( (float*)VMA(1), (float*)VMA(2), (int*)VMA(3), args[4] );
		case BOTLIB_AAS_AREA_CENTER:
			botlib_export->aas.AAS_AreaCenter(args[1], (float*)VMA(2));
			return 0;
		case BOTLIB_AAS_AREA_WAYPOINT:
			return botlib_export->aas.AAS_AreaWaypoint(args[1], (float*)VMA(2));
		case BOTLIB_AAS_POINT_CONTENTS:
			return botlib_export->aas.AAS_PointContents((float*)VMA(1));
		case BOTLIB_AAS_NEXT_BSP_ENTITY:
			return botlib_export->aas.AAS_NextBSPEntity(args[1]);
		case BOTLIB_AAS_VALUE_FOR_BSP_EPAIR_KEY:
			return botlib_export->aas.AAS_ValueForBSPEpairKey(args[1], (char*)VMA(2), (char*)VMA(3), args[4]);
		case BOTLIB_AAS_VECTOR_FOR_BSP_EPAIR_KEY:
			return botlib_export->aas.AAS_VectorForBSPEpairKey(args[1], (char*)VMA(2), (float*)VMA(3));
		case BOTLIB_AAS_FLOAT_FOR_BSP_EPAIR_KEY:
			return botlib_export->aas.AAS_FloatForBSPEpairKey(args[1], (char*)VMA(2), (float*)VMA(3));
		case BOTLIB_AAS_INT_FOR_BSP_EPAIR_KEY:
			return botlib_export->aas.AAS_IntForBSPEpairKey(args[1], (char*)VMA(2), (int*)VMA(3));
		case BOTLIB_AAS_AREA_REACHABILITY:
			return botlib_export->aas.AAS_AreaReachability(args[1]);
		case BOTLIB_AAS_AREA_LADDER:
			return botlib_export->aas.AAS_AreaLadder(args[1]);
		case BOTLIB_AAS_AREA_TRAVEL_TIME_TO_GOAL_AREA:
			return botlib_export->aas.AAS_AreaTravelTimeToGoalArea(args[1], (float*)VMA(2), args[3], args[4]);
		case BOTLIB_AAS_SWIMMING:
			return botlib_export->aas.AAS_Swimming((float*)VMA(1));
		case BOTLIB_AAS_PREDICT_CLIENT_MOVEMENT:
			return botlib_export->aas.AAS_PredictClientMovement((aas_clientmove_s*)VMA(1), args[2], (float*)VMA(3), args[4], args[5], (float*)VMA(6), (float*)VMA(7), args[8], args[9], VMF(10), args[11], args[12], args[13]);
		case BOTLIB_AAS_RT_SHOWROUTE:
			botlib_export->aas.AAS_RT_ShowRoute((float*)VMA(1), args[2], args[3]);
			return 0;
		case BOTLIB_AAS_NEARESTHIDEAREA:
			return botlib_export->aas.AAS_NearestHideArea(args[1], (float*)VMA(2), args[3], args[4], (float*)VMA(5), args[6], args[7], VMF(8), (float*)VMA(9));
		case BOTLIB_AAS_LISTAREASINRANGE:
			return botlib_export->aas.AAS_ListAreasInRange((float*)VMA(1), args[2], VMF(3), args[4], (vec3_t*)VMA(5), args[6]);
		case BOTLIB_AAS_AVOIDDANGERAREA:
			return botlib_export->aas.AAS_AvoidDangerArea((float*)VMA(1), args[2], (float*)VMA(3), args[4], VMF(5), args[6]);
		case BOTLIB_AAS_RETREAT:
			return botlib_export->aas.AAS_Retreat((int*)VMA(1), args[2], (float*)VMA(3), args[4], (float*)VMA(5), args[6], VMF(7), VMF(8), args[9]);
		case BOTLIB_AAS_ALTROUTEGOALS:
			return botlib_export->aas.AAS_AlternativeRouteGoals((float*)VMA(1), (float*)VMA(2), args[3], (aas_altroutegoal_t*)VMA(4), args[5], args[6]);
		case BOTLIB_AAS_SETAASBLOCKINGENTITY:
			botlib_export->aas.AAS_SetAASBlockingEntity((float*)VMA(1), (float*)VMA(2), args[3]);
			return 0;
		case BOTLIB_AAS_RECORDTEAMDEATHAREA:
			botlib_export->aas.AAS_RecordTeamDeathArea((float*)VMA(1), args[2], args[3], args[4], args[5]);
			return 0;
		case BOTLIB_EA_SAY:
			botlib_export->ea.EA_Say(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_SAY_TEAM:
			botlib_export->ea.EA_SayTeam(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_USE_ITEM:
			botlib_export->ea.EA_UseItem(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_DROP_ITEM:
			botlib_export->ea.EA_DropItem(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_USE_INV:
			botlib_export->ea.EA_UseInv(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_DROP_INV:
			botlib_export->ea.EA_DropInv(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_GESTURE:
			botlib_export->ea.EA_Gesture(args[1]);
			return 0;
		case BOTLIB_EA_COMMAND:
			botlib_export->ea.EA_Command(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_SELECT_WEAPON:
			botlib_export->ea.EA_SelectWeapon(args[1], args[2]);
			return 0;
		case BOTLIB_EA_TALK:
			botlib_export->ea.EA_Talk(args[1]);
			return 0;
		case BOTLIB_EA_ATTACK:
			botlib_export->ea.EA_Attack(args[1]);
			return 0;
		case BOTLIB_EA_RELOAD:
			botlib_export->ea.EA_Reload(args[1]);
			return 0;
		case BOTLIB_EA_USE:
			botlib_export->ea.EA_Use(args[1]);
			return 0;
		case BOTLIB_EA_RESPAWN:
			botlib_export->ea.EA_Respawn(args[1]);
			return 0;
		case BOTLIB_EA_JUMP:
			botlib_export->ea.EA_Jump(args[1]);
			return 0;
		case BOTLIB_EA_DELAYED_JUMP:
			botlib_export->ea.EA_DelayedJump(args[1]);
			return 0;
		case BOTLIB_EA_CROUCH:
			botlib_export->ea.EA_Crouch(args[1]);
			return 0;
		case BOTLIB_EA_WALK:
			botlib_export->ea.EA_Walk(args[1]);
			return 0;
		case BOTLIB_EA_MOVE_UP:
			botlib_export->ea.EA_MoveUp(args[1]);
			return 0;
		case BOTLIB_EA_MOVE_DOWN:
			botlib_export->ea.EA_MoveDown(args[1]);
			return 0;
		case BOTLIB_EA_MOVE_FORWARD:
			botlib_export->ea.EA_MoveForward(args[1]);
			return 0;
		case BOTLIB_EA_MOVE_BACK:
			botlib_export->ea.EA_MoveBack(args[1]);
			return 0;
		case BOTLIB_EA_MOVE_LEFT:
			botlib_export->ea.EA_MoveLeft(args[1]);
			return 0;
		case BOTLIB_EA_MOVE_RIGHT:
			botlib_export->ea.EA_MoveRight(args[1]);
			return 0;
		case BOTLIB_EA_MOVE:
			botlib_export->ea.EA_Move(args[1], (float*)VMA(2), VMF(3));
			return 0;
		case BOTLIB_EA_VIEW:
			botlib_export->ea.EA_View(args[1], (float*)VMA(2));
			return 0;
		case BOTLIB_EA_PRONE:
			botlib_export->ea.EA_Prone(args[1]);
			return 0;
		case BOTLIB_EA_END_REGULAR:
			botlib_export->ea.EA_EndRegular(args[1], VMF(2));
			return 0;
		case BOTLIB_EA_GET_INPUT:
			botlib_export->ea.EA_GetInput(args[1], VMF(2), (bot_input_t*)VMA(3));
			return 0;
		case BOTLIB_EA_RESET_INPUT:
			botlib_export->ea.EA_ResetInput(args[1], (bot_input_t*)VMA(2));
			return 0;
		case BOTLIB_AI_LOAD_CHARACTER:
			return botlib_export->ai.BotLoadCharacter((char*)VMA(1), args[2]);
		case BOTLIB_AI_FREE_CHARACTER:
			botlib_export->ai.BotFreeCharacter(args[1]);
			return 0;
		case BOTLIB_AI_CHARACTERISTIC_FLOAT:
			return FloatAsInt(botlib_export->ai.Characteristic_Float(args[1], args[2]));
		case BOTLIB_AI_CHARACTERISTIC_BFLOAT:
			return FloatAsInt(botlib_export->ai.Characteristic_BFloat(args[1], args[2], VMF(3), VMF(4)));
		case BOTLIB_AI_CHARACTERISTIC_INTEGER:
			return botlib_export->ai.Characteristic_Integer(args[1], args[2]);
		case BOTLIB_AI_CHARACTERISTIC_BINTEGER:
			return botlib_export->ai.Characteristic_BInteger(args[1], args[2], args[3], args[4]);
		case BOTLIB_AI_CHARACTERISTIC_STRING:
			botlib_export->ai.Characteristic_String(args[1], args[2], (char*)VMA(3), args[4]);
			return 0;
		case BOTLIB_AI_ALLOC_CHAT_STATE:
			return botlib_export->ai.BotAllocChatState();
		case BOTLIB_AI_FREE_CHAT_STATE:
			botlib_export->ai.BotFreeChatState(args[1]);
			return 0;
		case BOTLIB_AI_QUEUE_CONSOLE_MESSAGE:
			botlib_export->ai.BotQueueConsoleMessage(args[1], args[2], (char*)VMA(3));
			return 0;
		case BOTLIB_AI_REMOVE_CONSOLE_MESSAGE:
			botlib_export->ai.BotRemoveConsoleMessage(args[1], args[2]);
			return 0;
		case BOTLIB_AI_NEXT_CONSOLE_MESSAGE:
			return botlib_export->ai.BotNextConsoleMessage(args[1], (bot_consolemessage_s*)VMA(2));
		case BOTLIB_AI_NUM_CONSOLE_MESSAGE:
			return botlib_export->ai.BotNumConsoleMessages(args[1]);
		case BOTLIB_AI_INITIAL_CHAT:
			botlib_export->ai.BotInitialChat(args[1], (char*)VMA(2), args[3], (char*)VMA(4), (char*)VMA(5), (char*)VMA(6), (char*)VMA(7), (char*)VMA(8), (char*)VMA(9), (char*)VMA(10), (char*)VMA(11));
			return 0;
		case BOTLIB_AI_NUM_INITIAL_CHATS:
			return botlib_export->ai.BotNumInitialChats(args[1], (char*)VMA(2));
		case BOTLIB_AI_REPLY_CHAT:
			return botlib_export->ai.BotReplyChat(args[1], (char*)VMA(2), args[3], args[4], (char*)VMA(5), (char*)VMA(6), (char*)VMA(7), (char*)VMA(8), (char*)VMA(9), (char*)VMA(10), (char*)VMA(11), (char*)VMA(12));
		case BOTLIB_AI_CHAT_LENGTH:
			return botlib_export->ai.BotChatLength(args[1]);
		case BOTLIB_AI_ENTER_CHAT:
			botlib_export->ai.BotEnterChat(args[1], args[2], args[3]);
			return 0;
		case BOTLIB_AI_GET_CHAT_MESSAGE:
			botlib_export->ai.BotGetChatMessage(args[1], (char*)VMA(2), args[3]);
			return 0;
		case BOTLIB_AI_STRING_CONTAINS:
			return botlib_export->ai.StringContains((char*)VMA(1), (char*)VMA(2), args[3]);
		case BOTLIB_AI_FIND_MATCH:
			return botlib_export->ai.BotFindMatch((char*)VMA(1), (bot_match_s*)VMA(2), args[3]);
		case BOTLIB_AI_MATCH_VARIABLE:
			botlib_export->ai.BotMatchVariable((bot_match_s*)VMA(1), args[2], (char*)VMA(3), args[4]);
			return 0;
		case BOTLIB_AI_UNIFY_WHITE_SPACES:
			botlib_export->ai.UnifyWhiteSpaces((char*)VMA(1));
			return 0;
		case BOTLIB_AI_REPLACE_SYNONYMS:
			botlib_export->ai.BotReplaceSynonyms((char*)VMA(1), args[2]);
			return 0;
		case BOTLIB_AI_LOAD_CHAT_FILE:
			return botlib_export->ai.BotLoadChatFile(args[1], (char*)VMA(2), (char*)VMA(3));
		case BOTLIB_AI_SET_CHAT_GENDER:
			botlib_export->ai.BotSetChatGender(args[1], args[2]);
			return 0;
		case BOTLIB_AI_SET_CHAT_NAME:
			botlib_export->ai.BotSetChatName(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_AI_RESET_GOAL_STATE:
			botlib_export->ai.BotResetGoalState(args[1]);
			return 0;
		case BOTLIB_AI_RESET_AVOID_GOALS:
			botlib_export->ai.BotResetAvoidGoals(args[1]);
			return 0;
		case BOTLIB_AI_REMOVE_FROM_AVOID_GOALS:
			botlib_export->ai.BotRemoveFromAvoidGoals(args[1], args[2]);
			return 0;
		case BOTLIB_AI_PUSH_GOAL:
			botlib_export->ai.BotPushGoal(args[1], (bot_goal_s*)VMA(2));
			return 0;
		case BOTLIB_AI_POP_GOAL:
			botlib_export->ai.BotPopGoal(args[1]);
			return 0;
		case BOTLIB_AI_EMPTY_GOAL_STACK:
			botlib_export->ai.BotEmptyGoalStack(args[1]);
			return 0;
		case BOTLIB_AI_DUMP_AVOID_GOALS:
			botlib_export->ai.BotDumpAvoidGoals(args[1]);
			return 0;
		case BOTLIB_AI_DUMP_GOAL_STACK:
			botlib_export->ai.BotDumpGoalStack(args[1]);
			return 0;
		case BOTLIB_AI_GOAL_NAME:
			botlib_export->ai.BotGoalName(args[1], (char*)VMA(2), args[3]);
			return 0;
		case BOTLIB_AI_GET_TOP_GOAL:
			return botlib_export->ai.BotGetTopGoal(args[1], (bot_goal_s*)VMA(2));
		case BOTLIB_AI_GET_SECOND_GOAL:
			return botlib_export->ai.BotGetSecondGoal(args[1], (bot_goal_s*)VMA(2));
		case BOTLIB_AI_CHOOSE_LTG_ITEM:
			return botlib_export->ai.BotChooseLTGItem(args[1], (float*)VMA(2), (int*)VMA(3), args[4]);
		case BOTLIB_AI_CHOOSE_NBG_ITEM:
			return botlib_export->ai.BotChooseNBGItem(args[1], (float*)VMA(2), (int*)VMA(3), args[4], (bot_goal_s*)VMA(5), VMF(6));
		case BOTLIB_AI_TOUCHING_GOAL:
			return botlib_export->ai.BotTouchingGoal((float*)VMA(1), (bot_goal_s*)VMA(2));
		case BOTLIB_AI_ITEM_GOAL_IN_VIS_BUT_NOT_VISIBLE:
			return botlib_export->ai.BotItemGoalInVisButNotVisible(args[1], (float*)VMA(2), (float*)VMA(3), (bot_goal_s*)VMA(4));
		case BOTLIB_AI_GET_LEVEL_ITEM_GOAL:
			return botlib_export->ai.BotGetLevelItemGoal(args[1], (char*)VMA(2), (bot_goal_s*)VMA(3));
		case BOTLIB_AI_GET_NEXT_CAMP_SPOT_GOAL:
			return botlib_export->ai.BotGetNextCampSpotGoal(args[1], (bot_goal_s*)VMA(2));
		case BOTLIB_AI_GET_MAP_LOCATION_GOAL:
			return botlib_export->ai.BotGetMapLocationGoal((char*)VMA(1), (bot_goal_s*)VMA(2));
		case BOTLIB_AI_AVOID_GOAL_TIME:
			return FloatAsInt(botlib_export->ai.BotAvoidGoalTime(args[1], args[2]));
		case BOTLIB_AI_INIT_LEVEL_ITEMS:
			botlib_export->ai.BotInitLevelItems();
			return 0;
		case BOTLIB_AI_UPDATE_ENTITY_ITEMS:
			botlib_export->ai.BotUpdateEntityItems();
			return 0;
		case BOTLIB_AI_LOAD_ITEM_WEIGHTS:
			return botlib_export->ai.BotLoadItemWeights(args[1], (char*)VMA(2));
		case BOTLIB_AI_FREE_ITEM_WEIGHTS:
			botlib_export->ai.BotFreeItemWeights(args[1]);
			return 0;
		case BOTLIB_AI_INTERBREED_GOAL_FUZZY_LOGIC:
			botlib_export->ai.BotInterbreedGoalFuzzyLogic(args[1], args[2], args[3]);
			return 0;
		case BOTLIB_AI_SAVE_GOAL_FUZZY_LOGIC:
			botlib_export->ai.BotSaveGoalFuzzyLogic(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_AI_MUTATE_GOAL_FUZZY_LOGIC:
			botlib_export->ai.BotMutateGoalFuzzyLogic(args[1], VMF(2));
			return 0;
		case BOTLIB_AI_ALLOC_GOAL_STATE:
			return botlib_export->ai.BotAllocGoalState(args[1]);
		case BOTLIB_AI_FREE_GOAL_STATE:
			botlib_export->ai.BotFreeGoalState(args[1]);
			return 0;
		case BOTLIB_AI_RESET_MOVE_STATE:
			botlib_export->ai.BotResetMoveState(args[1]);
			return 0;
		case BOTLIB_AI_MOVE_TO_GOAL:
			botlib_export->ai.BotMoveToGoal((bot_moveresult_s*)VMA(1), args[2], (bot_goal_s*)VMA(3), args[4]);
			return 0;
		case BOTLIB_AI_MOVE_IN_DIRECTION:
			return botlib_export->ai.BotMoveInDirection(args[1], (float*)VMA(2), VMF(3), args[4]);
		case BOTLIB_AI_RESET_AVOID_REACH:
			botlib_export->ai.BotResetAvoidReach(args[1]);
			return 0;
		case BOTLIB_AI_RESET_LAST_AVOID_REACH:
			botlib_export->ai.BotResetLastAvoidReach(args[1]);
			return 0;
		case BOTLIB_AI_REACHABILITY_AREA:
			return botlib_export->ai.BotReachabilityArea((float*)VMA(1), args[2]);
		case BOTLIB_AI_MOVEMENT_VIEW_TARGET:
			return botlib_export->ai.BotMovementViewTarget(args[1], (bot_goal_s*)VMA(2), args[3], VMF(4), (float*)VMA(5));
		case BOTLIB_AI_PREDICT_VISIBLE_POSITION:
			return botlib_export->ai.BotPredictVisiblePosition((float*)VMA(1), args[2], (bot_goal_s*)VMA(3), args[4], (vec_t*)VMA(5));
		case BOTLIB_AI_ALLOC_MOVE_STATE:
			return botlib_export->ai.BotAllocMoveState();
		case BOTLIB_AI_FREE_MOVE_STATE:
			botlib_export->ai.BotFreeMoveState(args[1]);
			return 0;
		case BOTLIB_AI_INIT_MOVE_STATE:
			botlib_export->ai.BotInitMoveState(args[1], (bot_initmove_s*)VMA(2));
			return 0;
		case BOTLIB_AI_INIT_AVOID_REACH:
			botlib_export->ai.BotInitAvoidReach(args[1]);
			return 0;
		case BOTLIB_AI_CHOOSE_BEST_FIGHT_WEAPON:
			return botlib_export->ai.BotChooseBestFightWeapon(args[1], (int*)VMA(2));
		case BOTLIB_AI_GET_WEAPON_INFO:
			botlib_export->ai.BotGetWeaponInfo(args[1], args[2], (weaponinfo_s*)VMA(3));
			return 0;
		case BOTLIB_AI_LOAD_WEAPON_WEIGHTS:
			return botlib_export->ai.BotLoadWeaponWeights(args[1], (char*)VMA(2));
		case BOTLIB_AI_ALLOC_WEAPON_STATE:
			return botlib_export->ai.BotAllocWeaponState();
		case BOTLIB_AI_FREE_WEAPON_STATE:
			botlib_export->ai.BotFreeWeaponState(args[1]);
			return 0;
		case BOTLIB_AI_RESET_WEAPON_STATE:
			botlib_export->ai.BotResetWeaponState(args[1]);
			return 0;
		case BOTLIB_AI_GENETIC_PARENTS_AND_CHILD_SELECTION:
			return botlib_export->ai.GeneticParentsAndChildSelection(args[1], (float*)VMA(2), (int*)VMA(3), (int*)VMA(4), (int*)VMA(5));
		case G_ADD_PHYSICS_ENTITY:
#ifdef USE_PHYSICS
			CMod_PhysicsAddEntity((sharedEntity_t*)VMA(1));
#endif
			return 0;
		case G_ADD_PHYSICS_STATIC:
#ifdef USE_PHYSICS
			CMod_PhysicsAddStatic((sharedEntity_t*)VMA(1));
#endif
			return 0;
		case TRAP_MEMSET:
			memset(VMA(1), args[2], args[3]);
			return 0;
		case TRAP_MEMCPY:
			memcpy(VMA(1), VMA(2), args[3]);
			return 0;
		case TRAP_STRNCPY:
			return (intptr_t)strncpy( (char*)VMA( 1 ), (char*)VMA( 2 ), args[3] );
		case TRAP_SIN:
			return FloatAsInt(sin(VMF(1)));
		case TRAP_COS:
			return FloatAsInt(cos(VMF(1)));
		case TRAP_ATAN2:
			return FloatAsInt(atan2(VMF(1), VMF(2)));
		case TRAP_SQRT:
			return FloatAsInt(sqrt(VMF(1)));
		case TRAP_MATRIXMULTIPLY:
			AxisMultiply((vec3_t*)VMA(1), (vec3_t*)VMA(2), (vec3_t*)VMA(3));
			return 0;
		case TRAP_ANGLEVECTORS:
			AngleVectors((vec_t*)VMA(1), (vec_t*)VMA(2), (vec_t*)VMA(3), (vec_t*)VMA(4));
			return 0;
		case TRAP_PERPENDICULARVECTOR:
			PerpendicularVector((vec_t*)VMA(1), (vec_t*)VMA(2));
			return 0;
		case TRAP_FLOOR:
			return FloatAsInt(floor(VMF(1)));
		case TRAP_CEIL:
			return FloatAsInt(ceil(VMF(1)));
		case G_SENDMESSAGE:
			SV_SendBinaryMessage(args[1], (char*)VMA(2), args[3]);
			return 0;
		case G_MESSAGESTATUS:
			return SV_BinaryMessageStatus(args[1]);
#if defined(ET_MYSQL)
        case G_SQL_RUNQUERY:
                return OW_RunQuery( (char*)VMA(1) );
        case G_SQL_FINISHQUERY:
                OW_FinishQuery( args[1] );
                return 0;
        case G_SQL_NEXTROW:
                return OW_NextRow( args[1] );
        case G_SQL_ROWCOUNT:
                return OW_RowCount( args[1] );
        case G_SQL_GETFIELDBYID:
                OW_GetFieldByID( args[1], args[2], (char*)VMA(3), args[4]  );
                return 0;
        case G_SQL_GETFIELDBYNAME:
                OW_GetFieldByName( args[1], (char*)VMA(2), (char*)VMA(3), args[4] );
                return 0;
        case G_SQL_GETFIELDBYID_INT:
                return OW_GetFieldByID_int( args[1], args[2] );
        case G_SQL_GETFIELDBYNAME_INT:
                return OW_GetFieldByName_int( args[1], (char*)VMA(2) );
        case G_SQL_FIELDCOUNT:
                return OW_FieldCount( args[1] );
        case G_SQL_CLEANSTRING:
                OW_CleanString( (char*)VMA(1), (char*)VMA(2), args[3] );
                return 0;
#endif
		case G_RSA_GENMSG:
			return SV_RSAGenMsg( (char*)VMA(1), (char*)VMA(2), (char*)VMA(3) );
		default:
			Com_Error( ERR_DROP, "Bad game system trap: %ld", (long int) args[0] );
	}
	return -1;
}
예제 #27
0
void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir,
                    float orientation, float red, float green, float blue, float alpha,
                    bool alphaFade, float radius, bool 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( temporary )
	{
		if( CG_CullPointAndRadius( origin, M_SQRT2 * radius ) )
		{
			return;
		}
	}

	if ( radius <= 0 )
	{
		Com_Error(errorParm_t::ERR_DROP,  "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, ( const vec3_t * ) 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 persistently
		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 persistently
		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++;
	}
}
예제 #28
0
void RE_AddDecalToScene( qhandle_t decalShader, const vec3_t origin, const vec3_t dir, float orientation, float red, float green, float blue, float alpha, qboolean alphaFade, float radius, qboolean temporary )
{
    matrix3_t		axis;
    float			texCoordScale;
    vec3_t			originalPoints[4];
    byte			colors[4];
    int				i, j;
    int				numFragments;
    markFragment_t	markFragments[MAX_DECAL_FRAGMENTS], *mf;
    vec3_t			markPoints[MAX_DECAL_POINTS];
    vec3_t			projection;

    assert(decalShader);

    if ( r_markcount->integer <= 0 && !temporary )
        return;

    if ( radius <= 0 )
        Com_Error( ERR_FATAL, "RE_AddDecalToScene:  called with <= 0 radius" );

    // 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 = R_MarkFragments( 4, (const vec3_t*)originalPoints,
                                    projection, MAX_DECAL_POINTS, markPoints[0],
                                    MAX_DECAL_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_DECAL_POLY];
        decalPoly_t	*decal;

        // we have an upper limit on the complexity of polygons
        // that we store persistantly
        if ( mf->numPoints > MAX_VERTS_ON_DECAL_POLY )
            mf->numPoints = MAX_VERTS_ON_DECAL_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;

            for ( int k=0; k<4; k++ )
                v->modulate[k] = colors[k];
        }

        // if it is a temporary (shadow) mark, add it immediately and forget about it
        if ( temporary )
        {
            RE_AddPolyToScene( decalShader, mf->numPoints, verts, 1 );
            continue;
        }

        // otherwise save it persistantly
        decal = RE_AllocDecal( DECALPOLY_TYPE_NORMAL );
        decal->time = tr.refdef.time;
        decal->shader = decalShader;
        decal->poly.numVerts = mf->numPoints;
        decal->color[0] = red;
        decal->color[1] = green;
        decal->color[2] = blue;
        decal->color[3] = alpha;
        memcpy( decal->verts, verts, mf->numPoints * sizeof( verts[0] ) );
    }
}
예제 #29
0
파일: cg_marks.c 프로젝트: Razish/QtZ
// 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.
void CG_ImpactMark( qhandle_t markShader, const vector3 *origin, const vector3 *dir, float orientation, float red, float green, float blue, float alpha, qboolean alphaFade, float radius, qboolean temporary ) {
	matrix3			axis;
	float			texCoordScale;
	vector3			originalPoints[4];
	byte			colors[4];
	int				i, j, numFragments;
	markFragment_t	markFragments[MAX_MARK_FRAGMENTS] = {0}, *mf;
	vector3			markPoints[MAX_MARK_POINTS] = {0};
	vector3			projection;

	if ( !cg_marks->boolean ) {
		return;
	}

	if ( radius <= 0 ) {
		trap->Error( ERR_DROP, "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.5f * 1.0f / radius;

	// create the full polygon
	for ( i = 0 ; i < 3 ; i++ ) {
		originalPoints[0].data[i] = origin->data[i] - radius * axis[1].data[i] - radius * axis[2].data[i];
		originalPoints[1].data[i] = origin->data[i] + radius * axis[1].data[i] - radius * axis[2].data[i];
		originalPoints[2].data[i] = origin->data[i] + radius * axis[1].data[i] + radius * axis[2].data[i];
		originalPoints[3].data[i] = origin->data[i] - radius * axis[1].data[i] + radius * axis[2].data[i];
	}

	// get the fragments
	VectorScale( dir, -20, &projection );
	numFragments = trap->R_MarkFragments( 4, originalPoints, &projection, MAX_MARK_POINTS, &markPoints[0], MAX_MARK_FRAGMENTS, markFragments );

	colors[0] = (byte)(red * 255);
	colors[1] = (byte)(green * 255);
	colors[2] = (byte)(blue * 255);
	colors[3] = (byte)(alpha * 255);

	for ( i = 0, mf = markFragments ; i < numFragments ; i++, mf++ ) {
		polyVert_t	*v;
		polyVert_t	verts[MAX_VERTS_ON_POLY] = {0};
		markPoly_t	*mark;

		// we have an upper limit on the complexity of polygons
		// that we store persistently
		if ( mf->numPoints > MAX_VERTS_ON_POLY ) {
			mf->numPoints = MAX_VERTS_ON_POLY;
		}
		for ( j = 0, v = verts ; j < mf->numPoints ; j++, v++ ) {
			vector3 delta;

			VectorCopy( &markPoints[mf->firstPoint + j], &v->xyz );

			VectorSubtract( &v->xyz, origin, &delta );
			v->st.x = 0.5f + DotProduct( &delta, &axis[1] ) * texCoordScale;
			v->st.y = 0.5f + DotProduct( &delta, &axis[2] ) * texCoordScale;
			{
				int k;
				for ( k=0; k<4; k++ )
					v->modulate[k] = colors[k];
			}
		}

		// if it is a temporary (shadow) mark, add it immediately and forget about it
		if ( temporary ) {
			trap->R_AddPolysToScene( markShader, mf->numPoints, verts, 1 );
			continue;
		}

		// otherwise save it persistently
		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++;
	}
}
예제 #30
0
/*
* CG_AddFragmentedDecal
*/
void CG_AddFragmentedDecal( vec3_t origin, vec3_t dir, float orient, float radius,
							float r, float g, float b, float a, struct shader_s *shader ) {
	int i, j, c;
	vec3_t axis[3];
	byte_vec4_t color;
	fragment_t *fr, fragments[MAX_TEMPDECAL_FRAGMENTS];
	int numfragments;
	poly_t poly;
	vec4_t verts[MAX_BLOBSHADOW_VERTS];
	static vec4_t t_verts[MAX_TEMPDECAL_VERTS * MAX_TEMPDECALS];
	static vec4_t t_norms[MAX_TEMPDECAL_VERTS * MAX_TEMPDECALS];
	static vec2_t t_stcoords[MAX_TEMPDECAL_VERTS * MAX_TEMPDECALS];
	static byte_vec4_t t_colors[MAX_TEMPDECAL_VERTS * MAX_TEMPDECALS];

	if( radius <= 0 || VectorCompare( dir, vec3_origin ) ) {
		return; // invalid

	}

	// calculate orientation matrix
	VectorNormalize2( dir, axis[0] );
	PerpendicularVector( axis[1], axis[0] );
	RotatePointAroundVector( axis[2], axis[0], axis[1], orient );
	CrossProduct( axis[0], axis[2], axis[1] );

	numfragments = trap_R_GetClippedFragments( origin, radius, axis, // clip it
											   MAX_BLOBSHADOW_VERTS, verts, MAX_TEMPDECAL_FRAGMENTS, fragments );

	// no valid fragments
	if( !numfragments ) {
		return;
	}

	// clamp and scale colors
	if( r < 0 ) {
		r = 0;
	} else if( r > 1 ) {
		r = 255;
	} else {
		r *= 255;
	}
	if( g < 0 ) {
		g = 0;
	} else if( g > 1 ) {
		g = 255;
	} else {
		g *= 255;
	}
	if( b < 0 ) {
		b = 0;
	} else if( b > 1 ) {
		b = 255;
	} else {
		b *= 255;
	}
	if( a < 0 ) {
		a = 0;
	} else if( a > 1 ) {
		a = 255;
	} else {
		a *= 255;
	}

	color[0] = ( uint8_t )( r );
	color[1] = ( uint8_t )( g );
	color[2] = ( uint8_t )( b );
	color[3] = ( uint8_t )( a );
	c = *( int * )color;

	radius = 0.5f / radius;
	VectorScale( axis[1], radius, axis[1] );
	VectorScale( axis[2], radius, axis[2] );

	memset( &poly, 0, sizeof( poly ) );

	for( i = 0, fr = fragments; i < numfragments; i++, fr++ ) {
		if( fr->numverts <= 0 ) {
			continue;
		}
		if( cg_numDecalVerts + (unsigned)fr->numverts > sizeof( t_verts ) / sizeof( t_verts[0] ) ) {
			return;
		}

		poly.shader = shader;
		poly.verts = &t_verts[cg_numDecalVerts];
		poly.normals = &t_norms[cg_numDecalVerts];
		poly.stcoords = &t_stcoords[cg_numDecalVerts];
		poly.colors = &t_colors[cg_numDecalVerts];
		poly.numverts = fr->numverts;
		poly.fognum = fr->fognum;
		cg_numDecalVerts += (unsigned)fr->numverts;

		for( j = 0; j < fr->numverts; j++ ) {
			vec3_t v;

			Vector4Copy( verts[fr->firstvert + j], poly.verts[j] );
			VectorCopy( axis[0], poly.normals[j] ); poly.normals[j][3] = 0;
			VectorSubtract( poly.verts[j], origin, v );
			poly.stcoords[j][0] = DotProduct( v, axis[1] ) + 0.5f;
			poly.stcoords[j][1] = DotProduct( v, axis[2] ) + 0.5f;
			*( int * )poly.colors[j] = c;
		}

		trap_R_AddPolyToScene( &poly );
	}
}