diff --git a/source/duke3d/src/astub.cpp b/source/duke3d/src/astub.cpp index 0c2bf91987c85cc2c9af7787aae41fb700280d59..74fc5a45eb08624d1526a1099d27f4c169fd38c1 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.cpp b/source/duke3d/src/sounds.cpp index 22982a94828280574705a18d40b1256578ea82ad..0ea0fe91002ef35d59e512b9da9716ce2f3a4d1e 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 5c0dae7ff6e0a54600de135639b13b6b0238896f..9cf5ab059a7b3dd65dab03d66fa85676963bd2be 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 4eff2aa6e99e07cc5563e01d4a2affd79cecf316..7720797ce62f199e26e0e6e373d82d77e09a31b9 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); } @@ -511,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)