From ab9d7c3be48e087d3761bb4688a656ea220d74d2 Mon Sep 17 00:00:00 2001 From: Dino Bollinger Date: Mon, 26 Sep 2022 10:30:28 +0200 Subject: [PATCH 1/2] Duke3D: Remove the SF_ONEINST_INTERNAL sound flag This flag was set for all sounds that were declared with the SF_LOOP flag, and it prevented multiple SF_LOOP sounds of the same type from playing at the same time. It appears that this was needed for effects such as SE 0, which runs A_CallSound() at the end of the sector movement. Because of the flag, this call is aborted, as the original moving sound is already playing. If this wasn't the case, it would continuously play a sound after activation. The game now instead checks if a looping sound is emitted from an effector or activator sprite, and aborts the call if it is already playing. This achieves the same effect without preventing the same ambient sound from overlapping with itself in other situations. --- source/duke3d/src/sounds.cpp | 13 +++++++------ source/duke3d/src/sounds_common.h | 1 - source/duke3d/src/sounds_mapster32.cpp | 9 ++++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/source/duke3d/src/sounds.cpp b/source/duke3d/src/sounds.cpp index 22982a948..0ea0fe910 100644 --- a/source/duke3d/src/sounds.cpp +++ b/source/duke3d/src/sounds.cpp @@ -599,13 +599,11 @@ int32_t S_DefineSound(int sndidx, const char *name, int minpitch, int maxpitch, snd->minpitch = clamp(minpitch, INT16_MIN, INT16_MAX); snd->maxpitch = clamp(maxpitch, INT16_MIN, INT16_MAX); snd->priority = priority & 0xFF; - snd->flags = type & ~SF_ONEINST_INTERNAL; + snd->flags = type; snd->distOffset = clamp(distance, INT16_MIN, INT16_MAX); snd->volume = volume * fix16_one; snd->voices = &nullvoice; - if (snd->flags & SF_LOOP) - snd->flags |= SF_ONEINST_INTERNAL; return 0; } @@ -917,9 +915,12 @@ int S_PlaySound3D(int num, int spriteNum, const vec3_t& pos) int const repeatp = (snd->flags & SF_LOOP); - if ((snd->flags & (SF_LOOP|SF_ONEINST_INTERNAL)) == (SF_LOOP|SF_ONEINST_INTERNAL) && snd->playing) - return -1; - + // this replaces the previous SF_ONEINST_INTERNAL flag + // do not overlap looping sounds of same type if it originates from a hardcoded effector/activator sprite + if (snd->playing && (snd->flags & SF_LOOP) && (PN(spriteNum) == SECTOREFFECTOR || PN(spriteNum) == ACTIVATOR + || PN(spriteNum) == ACTIVATORLOCKED || PN(spriteNum) == MASTERSWITCH)) + return -1; + #ifdef CACHING_DOESNT_SUCK if (++g_soundlocks[sndNum] < CACHE1D_LOCKED) g_soundlocks[sndNum] = CACHE1D_LOCKED; diff --git a/source/duke3d/src/sounds_common.h b/source/duke3d/src/sounds_common.h index 5c0dae7ff..9cf5ab059 100644 --- a/source/duke3d/src/sounds_common.h +++ b/source/duke3d/src/sounds_common.h @@ -30,7 +30,6 @@ enum { SF_TALK = 4, SF_ADULT = 8, SF_GLOBAL = 16, - SF_ONEINST_INTERNAL = 32, SF_DTAG = 128, }; diff --git a/source/duke3d/src/sounds_mapster32.cpp b/source/duke3d/src/sounds_mapster32.cpp index 4eff2aa6e..e98232896 100644 --- a/source/duke3d/src/sounds_mapster32.cpp +++ b/source/duke3d/src/sounds_mapster32.cpp @@ -186,13 +186,10 @@ int32_t S_DefineSound(int sndidx, const char * filename, const char * definednam snd.ps = clamp(minpitch, INT16_MIN, INT16_MAX); snd.pe = clamp(maxpitch, INT16_MIN, INT16_MAX); snd.pr = priority & 0xFF; - snd.m = type & ~SF_ONEINST_INTERNAL; + snd.m = type; snd.vo = clamp(distance, INT16_MIN, INT16_MAX); snd.volume = volume * fix16_one; - if (snd.m & SF_LOOP) - snd.m |= SF_ONEINST_INTERNAL; - return 0; } @@ -311,9 +308,11 @@ int32_t S_PlaySound3D(int32_t const num, int32_t i, const vec3_t *pos) if (snd.m & SF_LOOP) { +#if 0 + // prevent multiple looping sounds of same type from playing at the same time if (snd.num > 0) return -1; - +#endif voice = FX_Play(snd.ptr, snd.soundsiz, 0, -1, pitch, sndist>>6, sndist>>6, 0, snd.pr, snd.volume, num); } -- GitLab From 9f07afeb834fdf124209b4b13e74a21e0e3ed954 Mon Sep 17 00:00:00 2001 From: Dino Bollinger Date: Mon, 26 Sep 2022 13:58:44 +0200 Subject: [PATCH 2/2] Mapster32: Fix sound handling problems Now supports more than 1 concurrent sound of the same type being played, and properly resets the ambient sound bitmap when all sounds are reset. --- source/duke3d/src/astub.cpp | 9 +++-- source/duke3d/src/sounds_mapster32.cpp | 50 ++++++++++++++------------ 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/source/duke3d/src/astub.cpp b/source/duke3d/src/astub.cpp index 0c2bf9198..74fc5a45e 100644 --- a/source/duke3d/src/astub.cpp +++ b/source/duke3d/src/astub.cpp @@ -1806,6 +1806,8 @@ static int32_t sort_sounds(int32_t how) return 0; } +uint8_t g_ambiencePlaying[(MAXSPRITES+7)>>3]; + static void SoundDisplay(void) { if (g_numsounds <= 0) return; @@ -1983,6 +1985,7 @@ static void SoundDisplay(void) overridepm16y = -1; + Bmemset(g_ambiencePlaying, 0, (MAXSPRITES+7)>>3); FX_StopAllSounds(); S_ClearSoundLocks(); @@ -1994,8 +1997,6 @@ static void SoundDisplay(void) int32_t AmbienceToggle = 1; int32_t ParentalLock = 0; -uint8_t g_ambiencePlaying[(MAXSPRITES+7)>>3]; - #define testbit(bitarray, i) (bitarray[(i)>>3] & pow2char[(i)&7]) #define setbit(bitarray, i) bitarray[(i)>>3] |= pow2char[(i)&7] #define clearbit(bitarray, i) bitarray[(i)>>3] &= ~pow2char[(i)&7] @@ -2039,6 +2040,7 @@ static void M32_MoveFX(void) if (s->picnum == MUSICANDSFX && j != i && sprite[j].lotag < 999 && testbit(g_ambiencePlaying, j) && dist(&sprite[j],&pos) > x) { + clearbit(g_ambiencePlaying, j); S_StopEnvSound(sprite[j].lotag,j); break; } @@ -2739,6 +2741,7 @@ static int32_t editorGetTile(int32_t idInitialTile) int32_t noTilesMarked=1; int32_t mark_lastk = -1; + Bmemset(g_ambiencePlaying, 0, (MAXSPRITES+7)>>3); FX_StopAllSounds(); S_ClearSoundLocks(); @@ -4627,6 +4630,7 @@ static void Keys3d(void) message("Ambience sounds: %s",AmbienceToggle?"enabled":"disabled"); if (!AmbienceToggle) { + Bmemset(g_ambiencePlaying, 0, (MAXSPRITES+7)>>3); FX_StopAllSounds(); S_ClearSoundLocks(); } @@ -11058,6 +11062,7 @@ void ExtCheckKeys(void) corruptchecktimer = (int32_t) totalclock + 120*autocorruptcheck; } + Bmemset(g_ambiencePlaying, 0, (MAXSPRITES+7)>>3); FX_StopAllSounds(); S_ClearSoundLocks(); } diff --git a/source/duke3d/src/sounds_mapster32.cpp b/source/duke3d/src/sounds_mapster32.cpp index e98232896..7720797ce 100644 --- a/source/duke3d/src/sounds_mapster32.cpp +++ b/source/duke3d/src/sounds_mapster32.cpp @@ -510,39 +510,43 @@ void S_Update(void) void S_Callback(intptr_t num) { - int32_t i,j,k; - - k = g_sounds[num].num; - - if (k > 0) + int32_t& sndcnt = g_sounds[num].num; + if (sndcnt > 0) { - if ((g_sounds[num].m & SF_GLOBAL) == 0) - for (j=0; j>3]; + for (int idx = 0; idx < sndcnt;) { - i = g_sounds[num].SoundOwner[j].ow; - if (i < 0) - continue; - - if (sprite[i].picnum == MUSICANDSFX && sector[sprite[i].sectnum].lotag < 3 && sprite[i].lotag < 999) + int32_t spriteNum = g_sounds[num].SoundOwner[idx].ow; + if (spriteNum < 0 || spriteNum >= MAXSPRITES || !bitmap_test(g_ambiencePlaying, spriteNum)) { - extern uint8_t g_ambiencePlaying[(MAXSPRITES+7)>>3]; - - g_ambiencePlaying[i>>3] &= ~pow2char[i&7]; - - if (j < k-1) + if (idx != --sndcnt) { - g_sounds[num].SoundOwner[j].voice = g_sounds[num].SoundOwner[k-1].voice; - g_sounds[num].SoundOwner[j].ow = g_sounds[num].SoundOwner[k-1].ow; + g_sounds[num].SoundOwner[idx].voice = g_sounds[num].SoundOwner[sndcnt].voice; + g_sounds[num].SoundOwner[idx].ow = g_sounds[num].SoundOwner[sndcnt].ow; } - break; + g_sounds[num].SoundOwner[sndcnt].ow = -1; } + else idx++; } + } + } - g_sounds[num].num--; - g_sounds[num].SoundOwner[k-1].ow = -1; + // sanity check, restore k to 0 if something went wrong + if (sndcnt < 0) + { + LOG_F(WARNING, "Negative number of active sounds %d for soundnum %ld detected! This shouldn't be happening!", sndcnt, num); + sndcnt = 0; } - g_sounds[num].lock--; + // only release sound lock if none are playing + if (sndcnt == 0) + g_sounds[num].lock--; } void S_ClearSoundLocks(void) -- GitLab