Skip to content

Commit

Permalink
tr2/sound: fix sound slot issues
Browse files Browse the repository at this point in the history
This resolves problems when the sound slot list is full but the game
continue to try to play further SFX. The previous result would be that
some sounds would be permanently disabled, or some could start playing
but become untracked.

Resolves #2494.
  • Loading branch information
lahm86 committed Feb 13, 2025
1 parent 7db49f7 commit 5dcda1f
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 32 deletions.
1 change: 1 addition & 0 deletions docs/tr2/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
- fixed teleporting to an item on a ledge sometimes pushing Lara to the room below (#2372)
- fixed the game crashing if a cinematic is triggered but the level contains no cinematic frames (#2413)
- fixed being unable to load a level that contains no sound effect data (#2460)
- fixed issues with sound effects not playing or looping forever in some cases when many other effects are playing (#2494)
- fixed Lara activating triggers one frame too early (#2205, regression from 0.7)
- fixed savegame incompatibility with OG (#2271, regression from 0.8)
- fixed stopwatch showing wrong UI in some circumstances (#2221, regression from 0.8)
Expand Down
58 changes: 26 additions & 32 deletions src/tr2/game/sound.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#include <math.h>

#define MAX_VOLUME 0x8000

typedef enum {
SOUND_MODE_NORMAL = 0,
SOUND_MODE_WAIT = 1,
Expand Down Expand Up @@ -172,7 +174,7 @@ bool Sound_Effect(
}

SAMPLE_INFO *const info = Sound_GetSampleInfo(sample_id);
if (info == nullptr) {
if (info == nullptr || info->number < 0) {
return false;
}

Expand Down Expand Up @@ -222,10 +224,6 @@ bool Sound_Effect(
- SOUND_MAX_PITCH_CHANGE;
}

if (info->number < 0) {
return false;
}

const SOUND_MODE mode = info->flags & SOUND_MODE_MASK;
const int32_t num_samples = (info->flags >> 2) & 0xF;
const int32_t track_id = num_samples == 1
Expand All @@ -240,7 +238,7 @@ bool Sound_Effect(
for (int32_t i = 0; i < SOUND_MAX_SLOTS; i++) {
SOUND_SLOT *const slot = &m_SoundSlots[i];
if (slot->effect_num == sample_id) {
if (Audio_Sample_IsPlaying(i)) {
if (Audio_Sample_IsPlaying(slot->handle)) {
return true;
}
M_ClearSlot(slot);
Expand Down Expand Up @@ -273,49 +271,45 @@ bool Sound_Effect(
break;
}

const bool is_looped = mode == SOUND_MODE_LOOPED;
int32_t handle = M_Play(track_id, volume, pitch, pan, is_looped);
int32_t free_slot = -1;
for (int32_t i = 0; i < SOUND_MAX_SLOTS; i++) {
SOUND_SLOT *const slot = &m_SoundSlots[i];
if (slot->effect_num < 0) {
free_slot = i;
break;
}
}

if (handle == AUDIO_NO_SOUND) {
int32_t min_volume = 0x8000;
int32_t min_slot = -1;
for (int32_t i = 1; i < SOUND_MAX_SLOTS; i++) {
if (free_slot == -1) {
// No slot found - try to find the most silent track, and use this one
int32_t min_volume = MAX_VOLUME;
for (int32_t i = 0; i < SOUND_MAX_SLOTS; i++) {
SOUND_SLOT *const slot = &m_SoundSlots[i];
if (slot->effect_num >= 0 && slot->volume < min_volume) {
min_volume = slot->volume;
min_slot = i;
free_slot = i;
}
}

if (min_slot >= 0 && volume >= min_volume) {
SOUND_SLOT *const slot = &m_SoundSlots[min_slot];
M_CloseSlot(slot);
handle = M_Play(track_id, volume, pitch, pan, is_looped);
if (free_slot == -1) {
// No slot found - give up
return false;
}
}

if (handle == AUDIO_NO_SOUND) {
info->number = -1;
return false;
}

int32_t free_slot = -1;
for (int32_t i = 0; i < SOUND_MAX_SLOTS; i++) {
SOUND_SLOT *const slot = &m_SoundSlots[i];
if (slot->effect_num < 0) {
free_slot = i;
break;
}
}
SOUND_SLOT *const slot = &m_SoundSlots[free_slot];
M_CloseSlot(slot);

if (free_slot != -1) {
SOUND_SLOT *const slot = &m_SoundSlots[free_slot];
const bool is_looped = mode == SOUND_MODE_LOOPED;
const int32_t handle = M_Play(track_id, volume, pitch, pan, is_looped);
if (handle != AUDIO_NO_SOUND) {
slot->volume = volume;
slot->pan = pan;
slot->pitch = pitch;
slot->effect_num = sample_id;
slot->handle = handle;
}

return true;
}

Expand Down

0 comments on commit 5dcda1f

Please sign in to comment.