[jak2] Workaround for sound effects getting dropped (#3660)

Similar to the workaround added in jak 3, if too many sounds are
playing, a sound will be removed. If there are multiple instances of the
same sound being played, those will be removed first. Within that, older
sounds are removed first.

It's not exactly the same as the instance limits of 989snd, but it seems
to work well. It's at least better than what we had before.

Co-authored-by: water111 <awaterford1111445@gmail.com>
This commit is contained in:
water111
2024-09-08 14:47:12 -04:00
committed by GitHub
parent 7053090541
commit a39af394fb
4 changed files with 80 additions and 7 deletions
+73 -2
View File
@@ -7,7 +7,8 @@
s32 gMusicFade = 0;
s32 gSema;
Sound gSounds[64];
constexpr int kNumSounds = 64;
Sound gSounds[kNumSounds];
Vec3w gEarTrans[2];
Vec3w gCamTrans;
s32 gMusicFadeDir = 0;
@@ -15,6 +16,7 @@ Curve gCurves[16];
s32 gCamAngle;
u8 gMirrorMode = 0;
u32 sLastTick = 0;
s64 gAddIndex = 0;
static s32 sqrt_table[256] = {
0, 4096, 5793, 7094, 8192, 9159, 10033, 10837, 11585, 12288, 12953, 13585, 14189,
@@ -56,6 +58,7 @@ static s32 atan_table[257] = {
void ssound_init_globals() {
gMusicFade = 0;
gSema = 0;
gAddIndex = 0;
}
Sound* LookupSound(s32 id) {
@@ -268,9 +271,66 @@ void UpdateVolume(Sound* sound) {
}
}
Sound* AllocateSound() {
void RemoveOldSounds() {
int unique_sounds = 0;
struct Entry {
u32 id;
u32 count;
Sound* info;
};
Entry entries[kNumSounds];
Entry* best_entry = nullptr;
for (auto& sound : gSounds) {
if (sound.id) {
Entry* existing_entry = nullptr;
u32 uid = snd_GetSoundID(sound.sound_handle);
// look for entry:
for (int i = 0; i < unique_sounds; i++) {
if (entries[i].id == uid) {
existing_entry = &entries[i];
break;
}
}
// if none found, create
if (!existing_entry) {
existing_entry = &entries[unique_sounds];
unique_sounds++;
existing_entry->id = uid;
existing_entry->count = 0;
existing_entry->info = &sound;
}
// update
existing_entry->count++;
// pick oldest sound
if (sound.add_index < existing_entry->info->add_index) {
existing_entry->info = &sound;
}
// se if we're best
if (!best_entry) {
best_entry = existing_entry;
} else {
if (best_entry->count < existing_entry->count) {
best_entry = existing_entry;
}
}
}
}
if (best_entry) {
snd_StopSound(best_entry->info->sound_handle);
best_entry->info->id = 0;
}
}
Sound* AllocateSound(bool remove_old_sounds) {
for (auto& s : gSounds) {
if (s.id == 0) {
s.add_index = gAddIndex++;
return &s;
}
}
@@ -278,10 +338,21 @@ Sound* AllocateSound() {
CleanSounds();
for (auto& s : gSounds) {
if (s.id == 0) {
s.add_index = gAddIndex++;
return &s;
}
}
if (remove_old_sounds) {
RemoveOldSounds();
for (auto& s : gSounds) {
if (s.id == 0) {
s.add_index = gAddIndex++;
return &s;
}
}
}
return nullptr;
}
+3 -1
View File
@@ -41,6 +41,8 @@ struct Sound {
s32 auto_time;
SoundParams params;
SoundRecord* bank_entry;
s64 add_index = 0;
};
struct Curve {
@@ -61,7 +63,7 @@ extern u32 sLastTick;
void ssound_init_globals();
Sound* LookupSound(s32 id);
Sound* AllocateSound();
Sound* AllocateSound(bool remove_old_sounds);
s32 GetVolume(Sound* sound);
void UpdateVolume(Sound* sound);
s32 CalculateFalloffVolume(Vec3w* pos, s32 volume, s32 fo_curve, s32 fo_min, s32 fo_max);
+2 -2
View File
@@ -93,7 +93,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) {
if (!PollSema(gSema)) {
if (gMusic) {
if (!gMusicPause && !LookupSound(666)) {
Sound* music = AllocateSound();
Sound* music = AllocateSound(false);
if (music != nullptr) {
gMusicFade = 0;
gMusicFadeDir = 1;
@@ -183,7 +183,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) {
break;
}
sound = AllocateSound();
sound = AllocateSound(false);
if (!sound) {
break;
}
+2 -2
View File
@@ -40,7 +40,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) {
if (!PollSema(gSema)) {
if (gMusic) {
if (!gMusicPause && !LookupSound(666)) {
Sound* music = AllocateSound();
Sound* music = AllocateSound(true);
if (music != nullptr) {
gMusicFade = 0;
gMusicFadeDir = 1;
@@ -117,7 +117,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) {
} else {
// new sound
sound = AllocateSound();
sound = AllocateSound(true);
if (sound == nullptr) {
// no free sounds
break;