예제 #1
0
/*
* source_setup
*/
static void source_setup( src_t *src, sfx_t *sfx, int priority, int entNum, int channel, float fvol, float attenuation )
{
	ALuint buffer;

	// Mark the SFX as used, and grab the raw AL buffer
	S_UseBuffer( sfx );
	buffer = S_GetALBuffer( sfx );

	clamp_low( attenuation, 0.0f );

	src->lastUse = trap_Milliseconds();
	src->sfx = sfx;
	src->priority = priority;
	src->entNum = entNum;
	src->channel = channel;
	src->fvol = fvol;
	src->attenuation = attenuation;
	src->isActive = qtrue;
	src->isLocked = qfalse;
	src->isLooping = qfalse;
	src->isTracking = qfalse;
	VectorClear( src->origin );
	VectorClear( src->velocity );

	qalSourcefv( src->source, AL_POSITION, vec3_origin );
	qalSourcefv( src->source, AL_VELOCITY, vec3_origin );
	qalSourcef( src->source, AL_GAIN, fvol * s_volume->value );
	qalSourcei( src->source, AL_SOURCE_RELATIVE, AL_FALSE );
	qalSourcei( src->source, AL_LOOPING, AL_FALSE );
	qalSourcei( src->source, AL_BUFFER, buffer );

	qalSourcef( src->source, AL_REFERENCE_DISTANCE, s_attenuation_refdistance );
	qalSourcef( src->source, AL_MAX_DISTANCE, s_attenuation_maxdistance );
	qalSourcef( src->source, AL_ROLLOFF_FACTOR, attenuation );
}
/*
=================
S_AL_SrcSetup
=================
*/
static void S_AL_SrcSetup(srcHandle_t src, sfxHandle_t sfx, alSrcPriority_t priority,
		int entity, int channel, qboolean local)
{
	ALuint buffer;
	src_t *curSource;

	// Mark the SFX as used, and grab the raw AL buffer
	S_AL_BufferUse(sfx);
	buffer = S_AL_BufferGet(sfx);

	// Set up src struct
	curSource = &srcList[src];
	
	curSource->lastUsedTime = Sys_Milliseconds();
	curSource->sfx = sfx;
	curSource->priority = priority;
	curSource->entity = entity;
	curSource->channel = channel;
	curSource->isActive = qtrue;
	curSource->isLocked = qfalse;
	curSource->isLooping = qfalse;
	curSource->isTracking = qfalse;
	curSource->curGain = s_alGain->value * s_volume->value;
	curSource->scaleGain = curSource->curGain;
	curSource->local = local;

	// Set up OpenAL source
	qalSourcei(curSource->alSource, AL_BUFFER, buffer);
	qalSourcef(curSource->alSource, AL_PITCH, 1.0f);
	qalSourcef(curSource->alSource, AL_GAIN, curSource->curGain);
	qalSourcefv(curSource->alSource, AL_POSITION, vec3_origin);
	qalSourcefv(curSource->alSource, AL_VELOCITY, vec3_origin);
	qalSourcei(curSource->alSource, AL_LOOPING, AL_FALSE);
	qalSourcef(curSource->alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value);

	if(local)
	{
		qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_TRUE);
		qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, 0.0f);
	}
	else
	{
		qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_FALSE);
		qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
	}
}
예제 #3
0
/*
* source_spatialize
*/
static void source_spatialize( src_t *src )
{
	if( !src->attenuation )
	{
		qalSourcei( src->source, AL_SOURCE_RELATIVE, AL_TRUE );
		// this was set at source_setup, no need to redo every frame
		//qalSourcefv( src->source, AL_POSITION, vec3_origin );
		//qalSourcefv( src->source, AL_VELOCITY, vec3_origin );
		return;
	}

	if( src->isTracking )
		trap_GetEntitySpatilization( src->entNum, src->origin, src->velocity );

	qalSourcei( src->source, AL_SOURCE_RELATIVE, AL_FALSE );
	qalSourcefv( src->source, AL_POSITION, src->origin );
	qalSourcefv( src->source, AL_VELOCITY, src->velocity );
}
/*
=================
S_AL_StartSound

Play a one-shot sound effect
=================
*/
static
void S_AL_StartSound( vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx )
{
	vec3_t sorigin;
	srcHandle_t src;

	if(S_AL_CheckInput(origin ? 0 : entnum, sfx))
		return;

	// Try to grab a source
	src = S_AL_SrcAlloc(SRCPRI_ONESHOT, entnum, entchannel);
	if(src == -1)
		return;

	// Set up the effect
	if( origin == NULL )
	{
		if( S_AL_HearingThroughEntity( entnum ) )
		{
			// Where the entity is the local player, play a local sound
			S_AL_SrcSetup( src, sfx, SRCPRI_ONESHOT, entnum, entchannel, qtrue );
			VectorClear( sorigin );
		}
		else
		{
			S_AL_SrcSetup( src, sfx, SRCPRI_ONESHOT, entnum, entchannel, qfalse );
			VectorCopy( entityList[ entnum ].origin, sorigin );
		}
		srcList[ src ].isTracking = qtrue;
	}
	else
	{
		S_AL_SrcSetup( src, sfx, SRCPRI_ONESHOT, entnum, entchannel, qfalse );
		VectorCopy( origin, sorigin );
	}

	S_AL_SanitiseVector( sorigin );
	qalSourcefv( srcList[ src ].alSource, AL_POSITION, sorigin );
	S_AL_ScaleGain(&srcList[src], sorigin);

	// Start it playing
	qalSourcePlay(srcList[src].alSource);
}
/*
=================
S_AL_SrcUpdate

Update state (move things around, manage sources, and so on)
=================
*/
static
void S_AL_SrcUpdate( void )
{
	int i;
	int entityNum;
	ALint state;
	src_t *curSource;	

	for(i = 0; i < srcCount; i++)
	{
		entityNum = srcList[i].entity;
		curSource = &srcList[i];

		if(curSource->isLocked)
			continue;

		if(!curSource->isActive)
			continue;

		// Update source parameters
		if((s_alGain->modified)||(s_volume->modified))
			curSource->curGain = s_alGain->value * s_volume->value;
		if((s_alRolloff->modified)&&(!curSource->local))
			qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
		if(s_alMinDistance->modified)
			qalSourcef(curSource->alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value);

		if(curSource->isLooping)
		{
			sentity_t *sent = &entityList[ entityNum ];

			// If a looping effect hasn't been touched this frame, kill it
			if(sent->loopAddedThisFrame)
			{
				// The sound has changed without an intervening removal
				if(curSource->isActive && !sent->startLoopingSound &&
						curSource->sfx != sent->loopSfx)
				{
					qalSourceStop(curSource->alSource);
					qalSourcei(curSource->alSource, AL_BUFFER, 0);
					sent->startLoopingSound = qtrue;
				}

				// The sound hasn't been started yet
				if(sent->startLoopingSound)
				{
					S_AL_SrcSetup(i, sent->loopSfx, sent->loopPriority,
							entityNum, -1, curSource->local);
					curSource->isLooping = qtrue;
					qalSourcei(curSource->alSource, AL_LOOPING, AL_TRUE);
					qalSourcePlay(curSource->alSource);

					sent->startLoopingSound = qfalse;
				}

				// Update locality
				if(curSource->local)
				{
					qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_TRUE);
					qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, 0.0f);
				}
				else
				{
					qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_FALSE);
					qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
				}
			}
			else
				S_AL_SrcKill( i );

			continue;
		}

		// Check if it's done, and flag it
		qalGetSourcei(curSource->alSource, AL_SOURCE_STATE, &state);
		if(state == AL_STOPPED)
		{
			S_AL_SrcKill(i);
			continue;
		}

		// Query relativity of source, don't move if it's true
		qalGetSourcei(curSource->alSource, AL_SOURCE_RELATIVE, &state);

		// See if it needs to be moved
		if(curSource->isTracking && !state)
		{
			qalSourcefv(curSource->alSource, AL_POSITION, entityList[entityNum].origin);
 			S_AL_ScaleGain(curSource, entityList[entityNum].origin);
		}
	}
}
/*
=================
S_AL_SrcLoop
=================
*/
static void S_AL_SrcLoop( alSrcPriority_t priority, sfxHandle_t sfx,
		const vec3_t origin, const vec3_t velocity, int entityNum )
{
	int				src;
	sentity_t	*sent = &entityList[ entityNum ];
	src_t		*curSource;

	// Do we need to allocate a new source for this entity
	if( !sent->srcAllocated )
	{
		// Try to get a channel
		src = S_AL_SrcAlloc( priority, entityNum, -1 );
		if( src == -1 )
		{
			Com_DPrintf( S_COLOR_YELLOW "WARNING: Failed to allocate source "
					"for loop sfx %d on entity %d\n", sfx, entityNum );
			return;
		}

		sent->startLoopingSound = qtrue;
	}
	else
		src = sent->srcIndex;

	sent->srcAllocated = qtrue;
	sent->srcIndex = src;

	sent->loopPriority = priority;
	sent->loopSfx = sfx;

	// If this is not set then the looping sound is removed
	sent->loopAddedThisFrame = qtrue;

	curSource = &srcList[src];

	// UGH
	// These lines should be called via S_AL_SrcSetup, but we
	// can't call that yet as it buffers sfxes that may change
	// with subsequent calls to S_AL_SrcLoop
	curSource->entity = entityNum;
	curSource->isLooping = qtrue;
	curSource->isActive = qtrue;

	if( S_AL_HearingThroughEntity( entityNum ) )
	{
		curSource->local = qtrue;

		qalSourcefv( curSource->alSource, AL_POSITION, vec3_origin );
		qalSourcefv( curSource->alSource, AL_VELOCITY, vec3_origin );
	}
	else
	{
		curSource->local = qfalse;

		qalSourcefv( curSource->alSource, AL_POSITION, (ALfloat *)sent->origin );
		qalSourcefv( curSource->alSource, AL_VELOCITY, (ALfloat *)velocity );
		
	}

	S_AL_ScaleGain(curSource, sent->origin);
}