summaryrefslogtreecommitdiff
path: root/src/client/snd_openal.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/snd_openal.c')
-rw-r--r--src/client/snd_openal.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/src/client/snd_openal.c b/src/client/snd_openal.c
index e8b0915d..01b965ae 100644
--- a/src/client/snd_openal.c
+++ b/src/client/snd_openal.c
@@ -39,6 +39,7 @@ cvar_t *s_alDopplerSpeed;
cvar_t *s_alMinDistance;
cvar_t *s_alRolloff;
cvar_t *s_alDriver;
+cvar_t *s_alMaxSpeakerDistance;
/*
=================
@@ -469,6 +470,7 @@ typedef struct src_s
static src_t srcList[MAX_SRC];
static int srcCount = 0;
static qboolean alSourcesInitialised = qfalse;
+static vec3_t lastListenerOrigin = { 0.0f, 0.0f, 0.0f };
typedef struct sentity_s
{
@@ -487,6 +489,22 @@ static sentity_t entityList[MAX_GENTITIES];
/*
=================
+S_AL_SanitiseVector
+=================
+*/
+#define S_AL_SanitiseVector(v) _S_AL_SanitiseVector(v,__LINE__)
+static void _S_AL_SanitiseVector( vec3_t v, int line )
+{
+ if( Q_isnan( v[ 0 ] ) || Q_isnan( v[ 1 ] ) || Q_isnan( v[ 2 ] ) )
+ {
+ Com_DPrintf( S_COLOR_YELLOW "WARNING: vector with one or more NaN components "
+ "being passed to OpenAL at %s:%d -- zeroing\n", __FILE__, line );
+ VectorClear( v );
+ }
+}
+
+/*
+=================
S_AL_SrcInit
=================
*/
@@ -762,6 +780,7 @@ S_AL_UpdateEntityPosition
static
void S_AL_UpdateEntityPosition( int entityNum, const vec3_t origin )
{
+ S_AL_SanitiseVector( (vec_t *)origin );
if ( entityNum < 0 || entityNum > MAX_GENTITIES )
Com_Error( ERR_DROP, "S_UpdateEntityPosition: bad entitynum %i", entityNum );
VectorCopy( origin, entityList[entityNum].origin );
@@ -816,6 +835,7 @@ void S_AL_StartSound( vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx
}
else
VectorCopy( origin, sorigin );
+ S_AL_SanitiseVector( sorigin );
qalSourcefv(srcList[src].alSource, AL_POSITION, sorigin);
// Start it playing
@@ -896,7 +916,9 @@ S_AL_AddLoopingSound
static
void S_AL_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx )
{
- S_AL_SrcLoop(SRCPRI_AMBIENT, sfx, origin, velocity, entityNum);
+ S_AL_SanitiseVector( (vec_t *)origin );
+ S_AL_SanitiseVector( (vec_t *)velocity );
+ S_AL_SrcLoop(SRCPRI_ENTITY, sfx, origin, velocity, entityNum);
}
/*
@@ -907,7 +929,17 @@ S_AL_AddRealLoopingSound
static
void S_AL_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx )
{
- S_AL_SrcLoop(SRCPRI_ENTITY, sfx, origin, velocity, entityNum);
+ S_AL_SanitiseVector( (vec_t *)origin );
+ S_AL_SanitiseVector( (vec_t *)velocity );
+
+ // There are certain maps (*cough* Q3:TA mpterra*) that have large quantities
+ // of ET_SPEAKERS in the PVS at any given time. OpenAL can't cope with mixing
+ // large numbers of sounds, so this culls them by distance
+ if( DistanceSquared( origin, lastListenerOrigin ) >
+ s_alMaxSpeakerDistance->value * s_alMaxSpeakerDistance->value )
+ return;
+
+ S_AL_SrcLoop(SRCPRI_AMBIENT, sfx, origin, velocity, entityNum);
}
/*
@@ -1429,12 +1461,18 @@ S_AL_Respatialize
static
void S_AL_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater )
{
+ S_AL_SanitiseVector( (vec_t *)origin );
+ S_AL_SanitiseVector( axis[ 0 ] );
+ S_AL_SanitiseVector( axis[ 1 ] );
+ S_AL_SanitiseVector( axis[ 2 ] );
// Axis[0] = Forward
// Axis[2] = Up
float velocity[] = {0.0f, 0.0f, 0.0f};
float orientation[] = {axis[0][0], axis[0][1], axis[0][2],
axis[2][0], axis[2][1], axis[2][2]};
+ VectorCopy( origin, lastListenerOrigin );
+
// Set OpenAL listener paramaters
qalListenerfv(AL_POSITION, (ALfloat *)origin);
qalListenerfv(AL_VELOCITY, velocity);
@@ -1592,6 +1630,7 @@ qboolean S_AL_Init( soundInterface_t *si )
s_alDopplerSpeed = Cvar_Get( "s_alDopplerSpeed", "2200", CVAR_ARCHIVE );
s_alMinDistance = Cvar_Get( "s_alMinDistance", "120", CVAR_CHEAT );
s_alRolloff = Cvar_Get( "s_alRolloff", "0.8", CVAR_CHEAT );
+ s_alMaxSpeakerDistance = Cvar_Get( "s_alMaxSpeakerDistance", "1024", CVAR_ARCHIVE );
s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE );