[Add] Sound should be fully positional now.

This commit is contained in:
Allanis 2013-10-02 01:17:01 +01:00
parent cc34292293
commit 5bf8a0b689
2 changed files with 44 additions and 16 deletions

View File

@ -188,22 +188,27 @@ int sound_get(char* name) {
* *
* @brief Play the sound in the first available channel. * @brief Play the sound in the first available channel.
* @param sound Sound to play. * @param sound Sound to play.
* @return 0 on success. * @return Voice identifier on success..
*/ */
int sound_play(int sound) { int sound_play(int sound) {
int channel; alVoice* v;
if(sound_disabled) return 0; if(sound_disabled) return 0;
if((sound < 0) || (sound > sound_nlist)) if((sound < 0) || (sound > sound_nlist))
return -1; return -1;
channel = Mix_PlayChannel(-1, sound_list[sound].buffer, 0); v = voice_new();
if(channel < 0) v->channel = Mix_PlayChannel(-1, sound_list[sound].buffer, 0);
if(v->channel < 0)
WARN("Unable to play sound: %s", Mix_GetError()); WARN("Unable to play sound: %s", Mix_GetError());
return 0; v->state = VOICE_PLAYING;
v->id = ++voice_genid;
voice_add(v);
return v->id;
} }
/** /**
@ -311,15 +316,23 @@ int sound_update(void) {
if((v->state == VOICE_STOPPED) || (v->state == VOICE_DESTROY)) { if((v->state == VOICE_STOPPED) || (v->state == VOICE_DESTROY)) {
/* Remove from active list. */ /* Remove from active list. */
tv = v->prev; tv = v->prev;
if(tv == NULL) if(tv == NULL) {
voice_active = v->next; voice_active = v->next;
else if(voice_active != NULL)
voice_active->prev = NULL;
} else {
tv->next = v->next; tv->next = v->next;
if(tv->next != NULL)
tv->next->prev = tv;
}
/* Add to free pool. */ /* Add to free pool. */
v->next = voice_pool; v->next = voice_pool;
v->prev = NULL;
voice_pool = v; voice_pool = v;
v->channel = 0; v->channel = 0;
if(v->next != NULL)
v->next->prev = v;
/* Avoid loop blockage. */ /* Avoid loop blockage. */
v = (tv != NULL) ? tv->next : voice_active; v = (tv != NULL) ? tv->next : voice_active;
@ -604,7 +617,7 @@ static alVoice* voice_new(void) {
} }
/* First free voice. */ /* First free voice. */
v = voice_pool; v = voice_pool; /* We do not touch the next nor prev, it's still in the pool. */
return v; return v;
} }
@ -618,10 +631,12 @@ static alVoice* voice_new(void) {
static int voice_add(alVoice* v) { static int voice_add(alVoice* v) {
alVoice* tv; alVoice* tv;
/* Set previous to point to next. */ /* Remove from pool. */
if(v->prev != NULL) { if(v->prev != NULL) {
tv = v->prev; tv = v->prev;
tv->next = v->next; tv->next = v->next;
if(tv->next != NULL)
voice_pool->prev = NULL;
} else { /* Set pool to be the next. */ } else { /* Set pool to be the next. */
voice_pool = v->next; voice_pool = v->next;
} }
@ -630,6 +645,9 @@ static int voice_add(alVoice* v) {
tv = voice_active; tv = voice_active;
voice_active = v; voice_active = v;
v->next = tv; v->next = tv;
v->prev = NULL;
if(tv != NULL)
tv->prev = v;
return 0; return 0;
} }

View File

@ -46,6 +46,7 @@ typedef struct Weapon_ {
unsigned int target; /* Target to hit. Only used by seeking stuff. */ unsigned int target; /* Target to hit. Only used by seeking stuff. */
const Outfit* outfit; /* Related outfit that fired. */ const Outfit* outfit; /* Related outfit that fired. */
int voice; /**< Weapons voice. */
double lockon; /* Some weapons have a lockon delay. */ double lockon; /* Some weapons have a lockon delay. */
double timer; /* Mainly used to see when the weapon was fired. */ double timer; /* Mainly used to see when the weapon was fired. */
@ -312,9 +313,6 @@ static void weapons_updateLayer(const double dt, const WeaponLayer layer) {
case OUTFIT_TYPE_TURRET_BEAM: case OUTFIT_TYPE_TURRET_BEAM:
wlayer[i]->timer -= dt; wlayer[i]->timer -= dt;
if(wlayer[i]->timer < 0.) { if(wlayer[i]->timer < 0.) {
sound_playPos(w->outfit->u.bem.sound_off,
w->solid->pos.x,
w->solid->pos.y);
weapon_destroy(wlayer[i],layer); weapon_destroy(wlayer[i],layer);
continue; continue;
} }
@ -494,7 +492,11 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
/* Smart weapons also get to think their next move. */ /* Smart weapons also get to think their next move. */
if(weapon_isSmart(w)) (*w->think)(w,dt); if(weapon_isSmart(w)) (*w->think)(w,dt);
/* Update the solid position. */
(*w->solid->update)(w->solid, dt); (*w->solid->update)(w->solid, dt);
/* Update the sound. */
sound_updatePos(w->voice, w->solid->pos.x, w->solid->pos.y);
} }
/** /**
@ -627,7 +629,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir)); vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
w->timer += outfit->u.blt.range/outfit->u.blt.speed; w->timer += outfit->u.blt.range/outfit->u.blt.speed;
w->solid = solid_create(mass, rdir, pos, &v); w->solid = solid_create(mass, rdir, pos, &v);
sound_playPos(w->outfit->u.blt.sound, w->voice = sound_playPos(w->outfit->u.blt.sound,
w->solid->pos.x + w->solid->vel.x, w->solid->pos.x + w->solid->vel.x,
w->solid->pos.y + w->solid->vel.y); w->solid->pos.y + w->solid->vel.y);
break; break;
@ -646,7 +648,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
w->solid = solid_create(mass, rdir, pos, NULL); w->solid = solid_create(mass, rdir, pos, NULL);
w->think = think_beam; w->think = think_beam;
w->timer = outfit->u.bem.duration; w->timer = outfit->u.bem.duration;
sound_playPos(w->outfit->u.bem.sound, w->voice = sound_playPos(w->outfit->u.bem.sound,
w->solid->pos.x + vel->x, w->solid->pos.x + vel->x,
w->solid->pos.y + vel->y); w->solid->pos.y + vel->y);
break; break;
@ -670,7 +672,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
w->think = think_seeker; w->think = think_seeker;
else if(outfit->type == OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO) else if(outfit->type == OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO)
w->think = think_smart;*/ w->think = think_smart;*/
sound_playPos(w->outfit->u.amm.sound, w->voice = sound_playPos(w->outfit->u.amm.sound,
w->solid->pos.x + w->solid->vel.x, w->solid->pos.x + w->solid->vel.x,
w->solid->pos.y + w->solid->vel.y); w->solid->pos.y + w->solid->vel.y);
break; break;
@ -683,7 +685,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
vect_pset(&w->solid->force, w->outfit->u.amm.thrust, dir); vect_pset(&w->solid->force, w->outfit->u.amm.thrust, dir);
w->think = NULL; /* No AI. */ w->think = NULL; /* No AI. */
sound_playPos(w->outfit->u.amm.sound, w->voice = sound_playPos(w->outfit->u.amm.sound,
w->solid->pos.x + w->solid->vel.x, w->solid->pos.x + w->solid->vel.x,
w->solid->pos.y + w->solid->vel.y); w->solid->pos.y + w->solid->vel.y);
break; break;
@ -870,6 +872,14 @@ static void weapon_destroy(Weapon* w, WeaponLayer layer) {
pilot_target->lockons--; pilot_target->lockons--;
} }
/* Stop playing sound if beam weapon. */
if(outfit_isBeam(w->outfit)) {
sound_stop(w->voice);
sound_playPos(w->outfit->u.bem.sound_off,
w->solid->pos.x,
w->solid->pos.y);
}
switch(layer) { switch(layer) {
case WEAPON_LAYER_BG: case WEAPON_LAYER_BG:
wlayer = wbackLayer; wlayer = wbackLayer;