/* =============== 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]; } }
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]; } }
/** * @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); } }
/* ----------------------------------------------------------------------------- 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]; }
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; }
/* ======================== 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] ); }
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; }
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); }
// 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 ); } }
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); }
// 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++; } } */ }
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] ); }
// 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 }
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); }
/* ** 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 ); }
/* ================ 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 ); } } } }
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; }
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 ); } }
/* ================ 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 ); } } }
// 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++; } } }
/* ** 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); }
/* ==================== 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; }
/* ** 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 ); }
/* ================= 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; }
/* ** 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 }
/* ==================== 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; }
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++; } }
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] ) ); } }
// 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++; } }
/* * 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 ); } }