diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index 65c8be757..2e2892ee9 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -96,7 +96,7 @@ CUSTOM_CVARD(Int, cl_crosshairscale, 50, CVAR_ARCHIVE, "changes the size of the CUSTOM_CVARD(Int, cl_autoaim, 1, CVAR_ARCHIVE|CVAR_USERINFO, "enable/disable weapon autoaim") { - if (self < 0 || self > (playing_blood? 2 : 3)) self = 1; // The Shadow Warrior backend only has a bool for this. + if (self < 0 || self > ((g_gameType & GAMEFLAG_BLOOD)? 2 : 3)) self = 1; // The Shadow Warrior backend only has a bool for this. //UpdatePlayerFromMenu(); todo: networking (only operational in EDuke32 frontend anyway.) }; @@ -104,7 +104,7 @@ CUSTOM_CVARD(Int, cl_weaponswitch, 3, CVAR_ARCHIVE|CVAR_USERINFO, "enable/disabl { if (self < 0) self = 0; - if (self > 3 && playing_blood) self = 3; + if (self > 3 && (g_gameType & GAMEFLAG_BLOOD)) self = 3; if (self > 7) self = 7; //UpdatePlayerFromMenu(); todo: networking (only operational in EDuke32 frontend anyway.) } diff --git a/source/common/sound/backend/i_soundinternal.h b/source/common/sound/backend/i_soundinternal.h index 08dd311a2..a2bdf81e2 100644 --- a/source/common/sound/backend/i_soundinternal.h +++ b/source/common/sound/backend/i_soundinternal.h @@ -28,7 +28,7 @@ enum EChanFlag CHANF_FORGETTABLE = 4, // internal: Forget channel data when sound stops. CHANF_JUSTSTARTED = 512, // internal: Sound has not been updated yet. CHANF_ABSTIME = 1024, // internal: Start time is absolute and does not depend on current time. - CHANF_VIRTUAL = 2048, // internal: Channel is currently virtual + CHANF_VIRTUAL = 2048, // Channel only plays on demand but won't get deleted automatically. CHANF_NOSTOP = 4096, // only for A_PlaySound. Does not start if channel is playing something. CHANF_OVERLAP = 8192, // [MK] Does not stop any sounds in the channel and instead plays over them. }; diff --git a/source/common/sound/s_sound.cpp b/source/common/sound/s_sound.cpp index c9b011d40..c7ca5f9c1 100644 --- a/source/common/sound/s_sound.cpp +++ b/source/common/sound/s_sound.cpp @@ -479,7 +479,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, // If the sound is blocked and not looped, return now. If the sound // is blocked and looped, pretend to play it so that it can // eventually play for real. - if ((chanflags & (CHANF_EVICTED | CHANF_LOOP)) == CHANF_EVICTED) + if ((chanflags & (CHANF_EVICTED | CHANF_LOOP | CHANF_VIRTUAL)) == CHANF_EVICTED) { return NULL; } @@ -550,7 +550,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, // sound is paused and a non-looped sound is being started. // Such a sound would play right after unpausing which wouldn't sound right. - if (!(chanflags & CHANF_LOOP) && !(chanflags & (CHANF_UI|CHANF_NOPAUSE)) && SoundPaused) + if (!(chanflags & (CHANF_LOOP|CHANF_VIRTUAL)) && !(chanflags & (CHANF_UI|CHANF_NOPAUSE)) && SoundPaused) { return NULL; } @@ -587,7 +587,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, chan = (FSoundChan*)GSnd->StartSound (sfx->data, float(volume), pitch, startflags, NULL); } } - if (chan == NULL && (chanflags & CHANF_LOOP)) + if (chan == NULL && (chanflags & CHANF_LOOP|CHANF_VIRTUAL)) { chan = (FSoundChan*)GetChannel(NULL); GSnd->MarkStartTime(chan); @@ -1014,7 +1014,7 @@ void SoundEngine::RelinkSound (int sourcetype, const void *from, const void *to, { chan->Source = to; } - else if (!(chan->ChanFlags & CHANF_LOOP) && optpos) + else if (!(chan->ChanFlags & (CHANF_LOOP|CHANF_VIRTUAL)) && optpos) { chan->Source = NULL; chan->SourceType = SOURCE_Unattached; @@ -1154,7 +1154,7 @@ bool SoundEngine::IsSourcePlayingSomething (int sourcetype, const void *actor, i { for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan) { - if (chan->SourceType == sourcetype && chan->Source == actor) + if (chan->SourceType == sourcetype && (sourcetype == SOURCE_None || sourcetype == SOURCE_Unattached || chan->Source == actor)) { if (channel == 0 || chan->EntChannel == channel) { @@ -1217,7 +1217,7 @@ void SoundEngine::RestoreEvictedChannel(FSoundChan *chan) if (chan->ChanFlags & CHANF_EVICTED) { RestartChannel(chan); - if (!(chan->ChanFlags & CHANF_LOOP)) + if (!(chan->ChanFlags & (CHANF_LOOP|CHANF_VIRTUAL))) { if (chan->ChanFlags & CHANF_EVICTED) { // Still evicted and not looping? Forget about it. @@ -1229,7 +1229,7 @@ void SoundEngine::RestoreEvictedChannel(FSoundChan *chan) } } } - else if (chan->SysChannel == NULL && (chan->ChanFlags & (CHANF_FORGETTABLE | CHANF_LOOP)) == CHANF_FORGETTABLE) + else if (chan->SysChannel == NULL && (chan->ChanFlags & (CHANF_FORGETTABLE | CHANF_LOOP | CHANF_VIRTUAL)) == CHANF_FORGETTABLE) { ReturnChannel(chan); } @@ -1345,7 +1345,7 @@ void SoundEngine::ChannelEnded(FISoundChannel *ichan) { evicted = false; } - else if (schan->ChanFlags & (CHANF_LOOP | CHANF_EVICTED)) + else if (schan->ChanFlags & (CHANF_LOOP | CHANF_VIRTUAL | CHANF_EVICTED)) { evicted = true; } diff --git a/source/common/sound/s_soundinternal.h b/source/common/sound/s_soundinternal.h index c16451aa6..0941ea768 100644 --- a/source/common/sound/s_soundinternal.h +++ b/source/common/sound/s_soundinternal.h @@ -168,13 +168,14 @@ struct FSoundChan : public FISoundChannel FSoundID OrgID; // Sound ID of sound used to start this channel. float Volume; int16_t Pitch; // Pitch variation. - uint8_t EntChannel; // Actor's sound channel. + int32_t EntChannel; // Actor's sound channel. int8_t Priority; int16_t NearLimit; uint8_t SourceType; float LimitRange; const void *Source; float Point[3]; // Sound is not attached to any source. + int UserData; // One word of data for user-specific data }; diff --git a/source/sw/src/d_menu.cpp b/source/sw/src/d_menu.cpp index 5fbe45dab..79834fc65 100644 --- a/source/sw/src/d_menu.cpp +++ b/source/sw/src/d_menu.cpp @@ -52,6 +52,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "colormap.h" #include "config.h" #include "menu/menu.h" +#include "sound/s_soundinternal.h" +#include "sounds.h" #include "../../glbackend/glbackend.h" @@ -237,17 +239,20 @@ void GameInterface::StartGame(FGameStartup& gs) //InitNewGame(); if (Skill == 0) - handle = PlaySound(DIGI_TAUNTAI3, v3df_none); + PlaySound(DIGI_TAUNTAI3, v3df_none, CHAN_VOICE); else if (Skill == 1) - handle = PlaySound(DIGI_NOFEAR, v3df_none); + PlaySound(DIGI_NOFEAR, v3df_none, CHAN_VOICE); else if (Skill == 2) - handle = PlaySound(DIGI_WHOWANTSWANG, v3df_none); + PlaySound(DIGI_WHOWANTSWANG, v3df_none, CHAN_VOICE); else if (Skill == 3) - handle = PlaySound(DIGI_NOPAIN, v3df_none); + PlaySound(DIGI_NOPAIN, v3df_none, CHAN_VOICE); if (handle > FX_Ok) - while (FX_SoundActive(handle)) - handleevents(); + while (soundEngine->IsSourcePlayingSomething(SOURCE_None, nullptr, CHAN_VOICE)) + { + DoUpdateSounds(); + handleevents(); + } } FSavegameInfo GameInterface::GetSaveSig() diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 489b073eb..90c341a5c 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -98,6 +98,7 @@ Things required to make savegames work: #include "statistics.h" #include "gstrings.h" #include "mapinfo.h" +#include "sound/s_soundinternal.h" //#include "crc32.h" @@ -1309,7 +1310,6 @@ TerminateLevel(void) memset(Track, 0, sizeof(Track)); StopSound(); - Terminate3DSounds(); // Kill the 3d sounds linked list // Clear all anims and any memory associated with them // Clear before killing sprites - save a little time @@ -1604,19 +1604,24 @@ void CreditsLevel(void) videoNextPage(); // Lo Wang feel like singing! - handle = PlaySound(DIGI_JG95012, v3df_none); - - if (handle > 0) - while (FX_SoundActive(handle)) ; + PlaySound(DIGI_JG95012, v3df_none, CHAN_VOICE); + while (soundEngine->IsSourcePlayingSomething(SOURCE_None, nullptr, CHAN_VOICE)) + { + DoUpdateSounds(); + handleevents(); + } // try 14 then 2 then quit if (!PlaySong(nullptr, ThemeSongs[5], ThemeTrack[5], true)) { if (!PlaySong(nullptr, nullptr, 2, true)) { - handle = PlaySound(DIGI_NOLIKEMUSIC, v3df_none); - if (handle > 0) - while (FX_SoundActive(handle)) handleevents(); + PlaySound(DIGI_NOLIKEMUSIC, v3df_none, CHAN_VOICE); + while (soundEngine->IsSourcePlayingSomething(SOURCE_None, nullptr, CHAN_VOICE)) + { + DoUpdateSounds(); + handleevents(); + } return; } } @@ -2255,7 +2260,6 @@ void BonusScreen(PLAYERp pp) } StopSound(); - Terminate3DSounds(); } void EndGameSequence(void) @@ -2471,7 +2475,6 @@ void StatScreen(PLAYERp mpp) } StopSound(); - Terminate3DSounds(); } void GameIntro(void) diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 3de794794..2ee384cc3 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -1210,7 +1210,6 @@ struct PLAYERstruct unsigned char WpnShotgunLastShell; // Number of last shell fired unsigned char WpnRailType; // Normal Rail Gun or EMP Burst Mode SWBOOL Bloody; // Is player gooey from the slaughter? - int nukevochandle; // Stuff for the Nuke SWBOOL InitingNuke; SWBOOL TestNukeInit; SWBOOL NukeInitialized; // Nuke already has counted down @@ -2067,30 +2066,48 @@ short ActorFindTrack(short SpriteNum, int8_t player_dir, int track_type, short * SECT_USERp GetSectUser(short sectnum); +// Some sounds were checked by storing handles in static local variables. +// Problems with this design: +// 1. The variables were unmaintained and could refer to handles that had been reused already. +// 2. No proper sound ownership tracking. +// 3. In some cases items that were supposed to use the same check referred to different handle variables. +// In short: I was very broken. This is a list of all sound items used this way, now each one gets a dedicated channel +// so that proper checks can be performed and sound ownership be tracked. + +enum +{ + CHAN_ToiletFart = 1000, + CHAN_AnimeMad = 1001, + CHAN_AnimeSing = 1002, + CHAN_CoyHandle = 1003, + CHAN_RipHeart = 1004, +}; + short SoundDist(int x, int y, int z, int basedist); short SoundAngle(int x, int y); //void PlaySound(int num, short angle, short vol); -int _PlaySound(int num, SPRITEp sprite, PLAYERp player, vec3_t *pos, Voc3D_Flags flags); -inline int PlaySound(int num, SPRITEp sprite, Voc3D_Flags flags) +int _PlaySound(int num, SPRITEp sprite, PLAYERp player, vec3_t *pos, Voc3D_Flags flags, int channel); +inline void PlaySound(int num, SPRITEp sprite, Voc3D_Flags flags, int channel = 8) { - return _PlaySound(num, sprite, nullptr, nullptr, flags); + _PlaySound(num, sprite, nullptr, nullptr, flags, channel); } -inline int PlaySound(int num, PLAYERp player, Voc3D_Flags flags) +inline void PlaySound(int num, PLAYERp player, Voc3D_Flags flags, int channel = 8) { - return _PlaySound(num, nullptr, player, nullptr, flags); + _PlaySound(num, nullptr, player, nullptr, flags, channel); } -inline int PlaySound(int num, Voc3D_Flags flags) +inline void PlaySound(int num, Voc3D_Flags flags, int channel = 8) { - return _PlaySound(num, nullptr, nullptr, nullptr, flags); + _PlaySound(num, nullptr, nullptr, nullptr, flags, channel); } -inline int PlaySound(int num, vec3_t *pos, Voc3D_Flags flags) +inline void PlaySound(int num, vec3_t *pos, Voc3D_Flags flags, int channel = 8) { - return _PlaySound(num, nullptr, nullptr, pos, flags); + _PlaySound(num, nullptr, nullptr, pos, flags, channel); } int _PlayerSound(int num, PLAYERp pp); inline int PlayerSound(int num, int flags, PLAYERp pp) { return _PlayerSound(num, pp); } void StopPlayerSound(PLAYERp pp); +bool SoundValidAndActive(SPRITEp spr, int channel); ANIMATOR DoActorBeginJump,DoActorJump,DoActorBeginFall,DoActorFall,DoActorDeathMove; diff --git a/source/sw/src/jsector.cpp b/source/sw/src/jsector.cpp index a440b5ba9..65d8793ce 100644 --- a/source/sw/src/jsector.cpp +++ b/source/sw/src/jsector.cpp @@ -83,7 +83,6 @@ void SpawnWallSound(short sndnum, short i) short SpriteNum; vec3_t mid; SPRITEp sp; - int handle; SpriteNum = COVERinsertsprite(0, STAT_DEFAULT); if (SpriteNum < 0) @@ -99,9 +98,7 @@ void SpawnWallSound(short sndnum, short i) setspritez(SpriteNum, &mid); sp = &sprite[SpriteNum]; - handle = PlaySound(sndnum, sp, v3df_dontpan | v3df_doppler); - if (handle != -1) - Set3DSoundOwner(SpriteNum); + PlaySound(sndnum, sp, v3df_dontpan | v3df_doppler); } short @@ -179,7 +176,6 @@ JS_SpriteSetup(void) short SpriteNum = 0, NextSprite, ndx; USERp u; short i, num; - int handle; TRAVERSE_SPRITE_STAT(headspritestat[0], SpriteNum, NextSprite) @@ -250,21 +246,15 @@ JS_SpriteSetup(void) case 2720: case 3143: case 3157: - handle = PlaySound(DIGI_FIRE1, sp, v3df_follow|v3df_dontpan|v3df_doppler); - if (handle != -1) - Set3DSoundOwner(SpriteNum); + PlaySound(DIGI_FIRE1, sp, v3df_follow|v3df_dontpan|v3df_doppler); break; case 795: case 880: - handle = PlaySound(DIGI_WATERFLOW1, sp, v3df_follow|v3df_dontpan|v3df_doppler); - if (handle != -1) - Set3DSoundOwner(SpriteNum); + PlaySound(DIGI_WATERFLOW1, sp, v3df_follow|v3df_dontpan|v3df_doppler); break; case 460: // Wind Chimes - handle = PlaySound(79, sp, v3df_ambient | v3df_init + PlaySound(79, sp, v3df_ambient | v3df_init | v3df_doppler | v3df_follow); - if (handle != -1) - Set3DSoundOwner(SpriteNum); break; } diff --git a/source/sw/src/miscactr.cpp b/source/sw/src/miscactr.cpp index 86f47f723..016e4715d 100644 --- a/source/sw/src/miscactr.cpp +++ b/source/sw/src/miscactr.cpp @@ -168,32 +168,29 @@ int DoToiletGirl(short SpriteNum) { if (RANDOM_RANGE(1000) > 980) { - static int handle; short choose_snd; choose_snd = RANDOM_P2(1024<<4)>>4; - if (!FX_SoundValidAndActive(handle)) + if (!SoundValidAndActive(sp, CHAN_ToiletFart)) { if (choose_snd > 750) - handle = PlaySound(DIGI_TOILETGIRLFART1, sp, v3df_dontpan); + PlaySound(DIGI_TOILETGIRLFART1, sp, v3df_dontpan, CHAN_ToiletFart); else if (choose_snd > 350) - handle = PlaySound(DIGI_TOILETGIRLFART2, sp, v3df_dontpan); + PlaySound(DIGI_TOILETGIRLFART2, sp, v3df_dontpan, CHAN_ToiletFart); else - handle = PlaySound(DIGI_TOILETGIRLFART3, sp, v3df_dontpan); + PlaySound(DIGI_TOILETGIRLFART3, sp, v3df_dontpan, CHAN_ToiletFart); } } } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { - static int madhandle; - - if (!FX_SoundValidAndActive(madhandle)) + if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { if (RANDOM_RANGE(1000<<8)>>8 > 500) - madhandle = PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan); + PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan, CHAN_AnimeMad); else - madhandle = PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan); + PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(SpriteNum,s_ToiletGirlUzi); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); @@ -233,14 +230,12 @@ int NullToiletGirl(short SpriteNum) } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { - static int madhandle; - - if (!FX_SoundValidAndActive(madhandle)) + if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { if (RANDOM_RANGE(1000<<8)>>8 > 500) - madhandle = PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan); + PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan, CHAN_AnimeMad); else - madhandle = PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan); + PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(SpriteNum,s_ToiletGirlUzi); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); @@ -406,7 +401,6 @@ int DoWashGirl(short SpriteNum) USERp u = User[SpriteNum]; SPRITEp sp = User[SpriteNum]->SpriteP; short rnd_range = 0; - static int handle=0; SWBOOL ICanSee = FALSE; DoActorPickClosePlayer(SpriteNum); @@ -414,14 +408,12 @@ int DoWashGirl(short SpriteNum) if (RANDOM_RANGE(1000) > 980 && u->ShellNum <= 0) { - static int handle; - - if (!FX_SoundValidAndActive(handle)) + if (!SoundValidAndActive(sp, CHAN_AnimeSing)) { if (RANDOM_P2(1024<<4)>>4 > 500) - handle = PlaySound(DIGI_ANIMESING1, sp, v3df_dontpan); + PlaySound(DIGI_ANIMESING1, sp, v3df_dontpan, CHAN_AnimeSing); else - handle = PlaySound(DIGI_ANIMESING2, sp, v3df_dontpan); + PlaySound(DIGI_ANIMESING2, sp, v3df_dontpan, CHAN_AnimeSing); } ChangeState(SpriteNum,s_WashGirlStandScrub); @@ -444,14 +436,12 @@ int DoWashGirl(short SpriteNum) } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { - static int madhandle; - - if (!FX_SoundValidAndActive(madhandle)) + if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { if (RANDOM_RANGE(1000<<8)>>8 > 500) - madhandle = PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan); + PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan, CHAN_AnimeMad); else - madhandle = PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan); + PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(SpriteNum,s_WashGirlUzi); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); @@ -488,14 +478,12 @@ int NullWashGirl(short SpriteNum) } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { - static int madhandle; - - if (!FX_SoundValidAndActive(madhandle)) + if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { if (RANDOM_RANGE(1000<<8)>>8 > 500) - madhandle = PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan); + PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan, CHAN_AnimeMad); else - madhandle = PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan); + PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(SpriteNum,s_WashGirlUzi); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); @@ -1303,21 +1291,19 @@ int DoCarGirl(short SpriteNum) { if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { - static int madhandle; - - if (!FX_SoundValidAndActive(madhandle)) + if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RANDOM_RANGE(1000); if (choose > 750) - madhandle = PlaySound(DIGI_LANI049, sp, v3df_dontpan); + PlaySound(DIGI_LANI049, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 500) - madhandle = PlaySound(DIGI_LANI051, sp, v3df_dontpan); + PlaySound(DIGI_LANI051, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) - madhandle = PlaySound(DIGI_LANI052, sp, v3df_dontpan); + PlaySound(DIGI_LANI052, sp, v3df_dontpan, CHAN_AnimeMad); else - madhandle = PlaySound(DIGI_LANI054, sp, v3df_dontpan); + PlaySound(DIGI_LANI054, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(SpriteNum,s_CarGirlUzi); u->WaitTics = SEC(3)+SEC(RANDOM_RANGE(2<<8)>>8); @@ -1358,21 +1344,19 @@ int NullCarGirl(short SpriteNum) } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { - static int madhandle; - - if (!FX_SoundValidAndActive(madhandle)) + if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RANDOM_RANGE(1000); if (choose > 750) - madhandle = PlaySound(DIGI_LANI049, sp, v3df_dontpan); + PlaySound(DIGI_LANI049, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 500) - madhandle = PlaySound(DIGI_LANI051, sp, v3df_dontpan); + PlaySound(DIGI_LANI051, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) - madhandle = PlaySound(DIGI_LANI052, sp, v3df_dontpan); + PlaySound(DIGI_LANI052, sp, v3df_dontpan, CHAN_AnimeMad); else - madhandle = PlaySound(DIGI_LANI054, sp, v3df_dontpan); + PlaySound(DIGI_LANI054, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(SpriteNum,s_CarGirlUzi); u->WaitTics = SEC(3)+SEC(RANDOM_RANGE(2<<8)>>8); @@ -1530,21 +1514,19 @@ int DoMechanicGirl(short SpriteNum) { if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { - static int madhandle; - - if (!FX_SoundValidAndActive(madhandle)) + if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RANDOM_RANGE(1000); if (choose > 750) - madhandle = PlaySound(DIGI_LANI073, sp, v3df_dontpan); + PlaySound(DIGI_LANI073, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 500) - madhandle = PlaySound(DIGI_LANI075, sp, v3df_dontpan); + PlaySound(DIGI_LANI075, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) - madhandle = PlaySound(DIGI_LANI077, sp, v3df_dontpan); + PlaySound(DIGI_LANI077, sp, v3df_dontpan, CHAN_AnimeMad); else - madhandle = PlaySound(DIGI_LANI079, sp, v3df_dontpan); + PlaySound(DIGI_LANI079, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(SpriteNum,s_MechanicGirlDrill); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(2<<8)>>8); @@ -1585,21 +1567,19 @@ int NullMechanicGirl(short SpriteNum) } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { - static int madhandle; - - if (!FX_SoundValidAndActive(madhandle)) + if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RANDOM_RANGE(1000); if (choose > 750) - madhandle = PlaySound(DIGI_LANI073, sp, v3df_dontpan); + PlaySound(DIGI_LANI073, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 500) - madhandle = PlaySound(DIGI_LANI075, sp, v3df_dontpan); + PlaySound(DIGI_LANI075, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) - madhandle = PlaySound(DIGI_LANI077, sp, v3df_dontpan); + PlaySound(DIGI_LANI077, sp, v3df_dontpan, CHAN_AnimeMad); else - madhandle = PlaySound(DIGI_LANI079, sp, v3df_dontpan); + PlaySound(DIGI_LANI079, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(SpriteNum,s_MechanicGirlDrill); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(2<<8)>>8); @@ -1758,9 +1738,7 @@ int DoSailorGirl(short SpriteNum) { if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { - static int madhandle; - - if (!FX_SoundValidAndActive(madhandle)) + if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RANDOM_RANGE(1000); @@ -1769,14 +1747,14 @@ int DoSailorGirl(short SpriteNum) { ActorCoughItem(SpriteNum); alreadythrew++; - madhandle = PlaySound(DIGI_LANI060, sp, v3df_dontpan); + PlaySound(DIGI_LANI060, sp, v3df_dontpan, CHAN_AnimeMad); } else if (choose > 500) - madhandle = PlaySound(DIGI_LANI063, sp, v3df_dontpan); + PlaySound(DIGI_LANI063, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) - madhandle = PlaySound(DIGI_LANI065, sp, v3df_dontpan); + PlaySound(DIGI_LANI065, sp, v3df_dontpan, CHAN_AnimeMad); else - madhandle = PlaySound(DIGI_LANI066, sp, v3df_dontpan); + PlaySound(DIGI_LANI066, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(SpriteNum,s_SailorGirlThrow); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); @@ -1818,9 +1796,7 @@ int NullSailorGirl(short SpriteNum) } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { - static int madhandle; - - if (!FX_SoundValidAndActive(madhandle)) + if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RANDOM_RANGE(1000); @@ -1829,14 +1805,14 @@ int NullSailorGirl(short SpriteNum) { ActorCoughItem(SpriteNum); alreadythrew++; - madhandle = PlaySound(DIGI_LANI060, sp, v3df_dontpan); + PlaySound(DIGI_LANI060, sp, v3df_dontpan, CHAN_AnimeMad); } else if (choose > 500) - madhandle = PlaySound(DIGI_LANI063, sp, v3df_dontpan); + PlaySound(DIGI_LANI063, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) - madhandle = PlaySound(DIGI_LANI065, sp, v3df_dontpan); + PlaySound(DIGI_LANI065, sp, v3df_dontpan, CHAN_AnimeMad); else - madhandle = PlaySound(DIGI_LANI066, sp, v3df_dontpan); + PlaySound(DIGI_LANI066, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(SpriteNum,s_SailorGirlThrow); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); @@ -1968,7 +1944,6 @@ int DoPruneGirl(short SpriteNum) USERp u = User[SpriteNum]; SPRITEp sp = User[SpriteNum]->SpriteP; short rnd_range = 0; - static int madhandle, coyhandle; SWBOOL ICanSee = FALSE; DoActorPickClosePlayer(SpriteNum); @@ -1978,19 +1953,19 @@ int DoPruneGirl(short SpriteNum) { if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { - if (!FX_SoundValidAndActive(madhandle)) + if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = STD_RANDOM_RANGE(1000); if (choose > 750) - madhandle = PlaySound(DIGI_LANI089, sp, v3df_dontpan); + PlaySound(DIGI_LANI089, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 500) - madhandle = PlaySound(DIGI_LANI091, sp, v3df_dontpan); + PlaySound(DIGI_LANI091, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) - madhandle = PlaySound(DIGI_LANI093, sp, v3df_dontpan); + PlaySound(DIGI_LANI093, sp, v3df_dontpan, CHAN_AnimeMad); else - madhandle = PlaySound(DIGI_LANI095, sp, v3df_dontpan); + PlaySound(DIGI_LANI095, sp, v3df_dontpan, CHAN_AnimeMad); } u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); u->FlagOwner = 0; @@ -1998,19 +1973,19 @@ int DoPruneGirl(short SpriteNum) } else { - if (!FX_SoundValidAndActive(coyhandle)) + if (!SoundValidAndActive(sp, CHAN_CoyHandle)) { short choose; choose = STD_RANDOM_RANGE(1000); if (choose > 990) - coyhandle = PlaySound(DIGI_PRUNECACKLE, sp, v3df_dontpan); + PlaySound(DIGI_PRUNECACKLE, sp, v3df_dontpan, CHAN_CoyHandle); else if (choose > 985) - coyhandle = PlaySound(DIGI_PRUNECACKLE2, sp, v3df_dontpan); + PlaySound(DIGI_PRUNECACKLE2, sp, v3df_dontpan, CHAN_CoyHandle); else if (choose > 980) - coyhandle = PlaySound(DIGI_PRUNECACKLE3, sp, v3df_dontpan); + PlaySound(DIGI_PRUNECACKLE3, sp, v3df_dontpan, CHAN_CoyHandle); else if (choose > 975) - coyhandle = PlaySound(DIGI_LANI091, sp, v3df_dontpan); + PlaySound(DIGI_LANI091, sp, v3df_dontpan, CHAN_CoyHandle); } } @@ -2047,21 +2022,19 @@ int NullPruneGirl(short SpriteNum) } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { - static int madhandle; - - if (!FX_SoundValidAndActive(madhandle)) + if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RANDOM_RANGE(1000); if (choose > 750) - madhandle = PlaySound(DIGI_LANI089, sp, v3df_dontpan); + PlaySound(DIGI_LANI089, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 500) - madhandle = PlaySound(DIGI_LANI091, sp, v3df_dontpan); + PlaySound(DIGI_LANI091, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) - madhandle = PlaySound(DIGI_LANI093, sp, v3df_dontpan); + PlaySound(DIGI_LANI093, sp, v3df_dontpan, CHAN_AnimeMad); else - madhandle = PlaySound(DIGI_LANI095, sp, v3df_dontpan); + PlaySound(DIGI_LANI095, sp, v3df_dontpan, CHAN_AnimeMad); } u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); u->FlagOwner = 0; diff --git a/source/sw/src/ninja.cpp b/source/sw/src/ninja.cpp index 5a711fc44..22a2938db 100644 --- a/source/sw/src/ninja.cpp +++ b/source/sw/src/ninja.cpp @@ -2258,7 +2258,6 @@ PlayerDeathReset(PLAYERp pp) pp->Bloody = FALSE; pp->TestNukeInit = FALSE; pp->InitingNuke = FALSE; - pp->nukevochandle = 0; pp->NukeInitialized = FALSE; pp->BunnyMode = FALSE; @@ -2348,7 +2347,6 @@ PlayerGameReset(PLAYERp pp) pp->Bloody = FALSE; pp->TestNukeInit = FALSE; pp->InitingNuke = FALSE; - pp->nukevochandle = 0; pp->NukeInitialized = FALSE; pp->BunnyMode = FALSE; pp->SecretsFound = 0; diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index bc308300e..699f7f553 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -46,6 +46,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "fx_man.h" #include "menu/menu.h" #include "swcvar.h" +#include "sound/s_soundinternal.h" BEGIN_SW_NS @@ -996,11 +997,7 @@ int WeaponOperate(PLAYERp pp) if (pp->WpnRocketType != 2 || pp->CurWpn != pp->Wpn[WPN_MICRO]) { pp->InitingNuke = FALSE; - if (pp->nukevochandle > 0) - { - FX_StopSound(pp->nukevochandle); - pp->nukevochandle = 0; - } + soundEngine->StopSound(SOURCE_Player, pp, CHAN_WEAPON); } return 0; @@ -3694,8 +3691,6 @@ PANEL_STATE ps_RetractRail[] = //#define RAIL_XOFF (160+60) #define RAIL_XOFF (160+6) -static int railvochandle=0; - void InitWeaponRail(PLAYERp pp) { @@ -3740,7 +3735,7 @@ InitWeaponRail(PLAYERp pp) pSetState(psp, psp->PresentState); PlaySound(DIGI_RAIL_UP, pp, v3df_follow); - railvochandle = PlaySound(DIGI_RAILREADY, pp, v3df_follow|v3df_dontpan); + PlaySound(DIGI_RAILREADY, pp, v3df_follow|v3df_dontpan); Set3DSoundOwner(psp->PlayerP->PlayerSprite); FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); @@ -5007,8 +5002,7 @@ pMicroStandBy(PANEL_SPRITEp psp) PLAYERp pp = psp->PlayerP; pMicroOverlays(psp); - pp->nukevochandle = - PlaySound(DIGI_NUKESTDBY, psp->PlayerP, v3df_follow|v3df_dontpan); + PlaySound(DIGI_NUKESTDBY, pp, v3df_follow|v3df_dontpan, CHAN_WEAPON); } void @@ -5016,8 +5010,7 @@ pMicroCount(PANEL_SPRITEp psp) { PLAYERp pp = psp->PlayerP; - pp->nukevochandle = - PlaySound(DIGI_NUKECDOWN, pp, v3df_follow|v3df_dontpan); + PlaySound(DIGI_NUKECDOWN, pp, v3df_follow|v3df_dontpan, CHAN_WEAPON); } void @@ -5025,8 +5018,7 @@ pMicroReady(PANEL_SPRITEp psp) { PLAYERp pp = psp->PlayerP; - pp->nukevochandle = - PlaySound(DIGI_NUKEREADY, pp, v3df_follow|v3df_dontpan); + PlaySound(DIGI_NUKEREADY, pp, v3df_follow|v3df_dontpan, CHAN_WEAPON); pp->NukeInitialized = TRUE; } diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index 65911f530..d4d881632 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -8069,8 +8069,8 @@ domovethings(void) MultiPlayLimits(); - if (MoveSkip8 == 0) // 8=5x 4=10x, 2=20x, 0=40x per second - DoUpdateSounds3D(); + //if (MoveSkip8 == 0) // 8=5x 4=10x, 2=20x, 0=40x per second + DoUpdateSounds(); CorrectPrediction(movefifoplc - 1); diff --git a/source/sw/src/ripper2.cpp b/source/sw/src/ripper2.cpp index 57708c100..11699f604 100644 --- a/source/sw/src/ripper2.cpp +++ b/source/sw/src/ripper2.cpp @@ -1246,12 +1246,11 @@ int DoRipper2StandHeart(short SpriteNum) { SPRITEp sp = &sprite[SpriteNum]; USERp u = User[SpriteNum]; - static int riphearthandle; NullRipper2(SpriteNum); - if (!FX_SoundValidAndActive(riphearthandle)) - riphearthandle = PlaySound(DIGI_RIPPER2HEARTOUT, sp, v3df_none); + if (!SoundValidAndActive(sp, CHAN_RipHeart)) + PlaySound(DIGI_RIPPER2HEARTOUT, sp, v3df_none, CHAN_RipHeart); if ((u->WaitTics -= ACTORMOVETICS) <= 0) NewStateGroup(SpriteNum, sg_Ripper2Run); diff --git a/source/sw/src/save.cpp b/source/sw/src/save.cpp index 2a9ab55ec..b59811e6c 100644 --- a/source/sw/src/save.cpp +++ b/source/sw/src/save.cpp @@ -748,8 +748,6 @@ bool GameInterface::LoadGame(FSaveGameNode* sv) TerminateLevel(); Terminate3DSounds(); - Terminate3DSounds(); - MREAD(&Level,sizeof(Level),1,fil); MREAD(&Skill,sizeof(Skill),1,fil); diff --git a/source/sw/src/sector.cpp b/source/sw/src/sector.cpp index 833ccf04d..f6e0d58f8 100644 --- a/source/sw/src/sector.cpp +++ b/source/sw/src/sector.cpp @@ -1242,7 +1242,6 @@ DoSoundSpotMatch(short match, short sound_num, short sound_type) if (TEST_BOOL2(sp)) flags = v3df_follow|v3df_nolookup|v3df_init; - //flags = v3df_follow|v3df_ambient|v3df_nolookup; // play once and only once if (TEST_BOOL1(sp)) diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp index 33811db9f..3fbca7eb4 100644 --- a/source/sw/src/sounds.cpp +++ b/source/sw/src/sounds.cpp @@ -60,6 +60,10 @@ BEGIN_SW_NS enum EChanExFlags { CHANEXF_AMBIENT = 0x40000000, + CHANEXF_NODOPPLER = 0x20000000, + CHANEXF_DONTPAN = 0x10000000, + CHANEXF_INTERMIT = 0x08000000, + }; // Parentally locked sounds list @@ -118,9 +122,6 @@ void InitFX(void) newsfx.name = entry.name; newsfx.lumpnum = lump; newsfx.NearLimit = 6; - newsfx.UserData.Resize(sizeof(void*)); - auto p = (VOC_INFOp *)newsfx.UserData.Data(); - *p = &entry; // store a link to the static data. } } soundEngine->HashSounds(); @@ -133,10 +134,90 @@ void InitFX(void) //========================================================================== // -// +// Sound Distance Calculation // //========================================================================== +enum +{ + MAXLEVLDIST = 19000, // The higher the number, the further away you can hear sound + DECAY_CONST = 4000 +}; + +short SoundDist(int x, int y, int z, int basedist) +{ + double tx, ty, tz; + double sqrdist, retval; + extern short screenpeek; + + tx = fabs(Player[screenpeek].posx - x); + ty = fabs(Player[screenpeek].posy - y); + tz = fabs((Player[screenpeek].posz - z) >> 4); + + // Use the Pythagreon Theorem to compute the magnitude of a 3D vector + sqrdist = fabs(tx * tx + ty * ty + tz * tz); + retval = sqrt(sqrdist); + + if (basedist < 0) // if basedist is negative + { + double decayshift = 2; + int decay = labs(basedist) / DECAY_CONST; + + for (int i = 0; i < decay; i++) + decayshift *= 2; + + if (fabs(double(basedist) / decayshift) >= retval) + retval = 0; + else + retval *= decay; + } + else + { + if (basedist > retval) + retval = 0; + else + retval -= basedist; + } + + retval = retval * 256 / MAXLEVLDIST; + + if (retval < 0) retval = 0; + if (retval > 255) retval = 255; + + return retval; +} + +//========================================================================== +// +// Calculate rolloff info. +// +//========================================================================== + +FRolloffInfo GetRolloff(int basedist) +{ + FRolloffInfo info; + + if (basedist < 0) // if basedist is negative + { + double decayshift = 2; + int decay = labs(basedist) / DECAY_CONST; + + for (int i = 0; i < decay; i++) + decayshift *= 2; + + info.RolloffType = ROLLOFF_Doom; + info.MinDistance = (float)(-basedist / decayshift / 16.); + info.MaxDistance = MAXLEVLDIST / 16.f / decay; + } + else + { + info.RolloffType = ROLLOFF_Doom; + info.MinDistance = basedist / 16.f; + info.MaxDistance = info.MinDistance + MAXLEVLDIST / 16.f; + } + return info; +} + @@ -151,35 +232,6 @@ void DumpSounds(void); SWBOOL Use_SoundSpriteNum = FALSE; int16_t SoundSpriteNum = -1; // Always set this back to -1 for proper validity checking! -SWBOOL FxInitialized = FALSE; - -void SoundCallBack(unsigned int num); - -#define MUSIC_ID -65536 - -#define NUM_SAMPLES 10 - -int music; -int soundfx; -int num_voices; - -int NumSounds = 0; - -int angle; -int distance; -int voice; - -int loopflag; - -extern SWBOOL DemoMode; - -SWBOOL OpenSound(VOC_INFOp vp, FileReader &handle, int *length); -int ReadSound(FileReader & handle, VOC_INFOp vp, int length); - - -// -// Routine called when a sound is finished playing -// //////////////////////////////////////////////////////////////////////////// // Play a sound @@ -250,7 +302,7 @@ typedef struct } TVOC_INFO, * TVOC_INFOp; void -DoUpdateSounds3D(void) +DoUpdateSounds(void) { VOC3D_INFOp p; SWBOOL looping; @@ -262,8 +314,7 @@ DoUpdateSounds3D(void) TVOC_INFO TmpVocArray[32]; int i; - if (M_Active()) return; - + // Zero out the temporary array // Zero out the temporary array //memset(&TmpVocArray[0],0,sizeof(TmpVocArray)); for (i = 0; i < 32; i++) @@ -500,222 +551,8 @@ DoUpdateSounds3D(void) } -void -StopFX(void) -{ - FX_StopAllSounds_(); -} +/* -void -StopSound(void) -{ - StopFX(); - Mus_Stop(); -} - -// -// Sound Distance Calculation -// - -#define MAXLEVLDIST 19000 // The higher the number, the further away you can hear sound - -short SoundDist(int x, int y, int z, int basedist) -{ - double tx, ty, tz; - double sqrdist,retval; - double decay,decayshift; - extern short screenpeek; - -#define DECAY_CONST 4000 - - - tx = fabs(Player[screenpeek].posx - x); - ty = fabs(Player[screenpeek].posy - y); - tz = fabs((Player[screenpeek].posz - z) >> 4); - - // Use the Pythagreon Theorem to compute the magnitude of a 3D vector - sqrdist = fabs(tx*tx + ty*ty + tz*tz); - retval = sqrt(sqrdist); - - if (basedist < 0) // if basedist is negative - { - short i; - - decayshift=2; - decay = labs(basedist) / DECAY_CONST; - - for (i=0; i= retval) - retval = 0; - else - retval *= decay; - } - else - { - if (basedist > retval) - retval = 0; - else - retval -= basedist; - } - - retval = retval * 256 / MAXLEVLDIST; - - if (retval < 0) retval = 0; - if (retval > 255) retval = 255; - - return retval; -} - -// -// Angle calcuations - may need to be checked to make sure they are right -// - -short SoundAngle(int x, int y) -{ - extern short screenpeek; - - short angle, delta_angle; - - angle = getangle(x - Player[screenpeek].posx, y - Player[screenpeek].posy); - - delta_angle = GetDeltaAngle(angle, Player[screenpeek].pang); - - // convert a delta_angle to a real angle if negative - if (delta_angle < 0) - delta_angle = NORM_ANGLE((1024 + delta_angle) + 1024); - - // convert 2048 degree angle to 128 degree angle - return delta_angle >> 4; -} - -//////////////////////////////////////////////////////////////////////////// -// Play a sound -//////////////////////////////////////////////////////////////////////////// - -#define SOUND_UNIT MAXLEVLDIST/255 -// NOTE: If v3df_follow == 1, x,y,z are considered literal coordinates -int _PlaySound(int num, SPRITEp sp, PLAYERp pp, vec3_t *pos, Voc3D_Flags flags) -{ - VOC_INFOp vp; - VOC3D_INFOp v3p; - int pitch = 0; - short angle, sound_dist; - int tx, ty, tz; - uint8_t priority; - - // Weed out parental lock sounds if PLock is active - if (adult_lockout || Global_PLock) - { - unsigned i; - - for (i=0; i= DIGI_MAX) - return -1; - - if (TEST(flags,v3df_ambient) && !TEST(flags,v3df_nolookup)) // Look for invalid ambient numbers - { - if (!snd_ambience) return -1; - if (num < 0 || num > MAX_AMBIENT_SOUNDS) - { - sprintf(ds,"Invalid or out of range ambient sound number %d\n",num); - PutStringInfo(Player+screenpeek, ds); - return -1; - } - v3p->maxtics = STD_RANDOM_RANGE(ambarray[num].maxtics); - - // If the ambient flag is set, do a name conversion to point to actual - // digital sound entry. - flags |= ambarray[num].ambient_flags; // Add to flags if any - num = ambarray[num].diginame; - if (num < 0 || num >= DIGI_MAX) - { - return -1; - } - } - - //auto chan = soundEngine->StartSound() - - - v3p->num = num; - v3p->priority = 0; - v3p->FX_Ok = FALSE; // Hasn't played yet - // Reset voice - voice = -1; - - // Assign voc to voc pointer - vp = &voc[num]; - if (M_Active() && sp == nullptr && pp == nullptr) // Menus sound outdo everything - priority = 100; - else - priority = vp->priority; - v3p->vp = vp; - - // Assign voc info to 3d struct for future reference - /* - v3p->x = x; - v3p->y = y; - v3p->z = z; - v3p->fx = *x; - v3p->fy = *y; - v3p->fz = *z; - */ - v3p->flags = flags; - - /* - if (flags & v3df_follow) - { - tx = *x; - ty = *y; - if (!z) - tz = 0; // Some sound calls don't have a z - // value - else - tz = *z; - } - else - { - // Don't use pointers to coordinate values. - tx = v3p->fx; - ty = v3p->fy; - tz = v3p->fz; - } - */ - - // Special case stuff for sounds being played in a level - /* - if (*x==0 && *y==0 && *z==0) - tx = ty = tz = 0; - */ - - if ((vp->voc_flags & vf_loop) && Use_SoundSpriteNum && SoundSpriteNum >= 0 && sp) - { - tx=sp->x; - ty=sp->y; - tz=sp->z; - } - - // Calculate sound angle - if (flags & v3df_dontpan) // If true, don't do panning - angle = 0; - else - angle = SoundAngle(tx, ty); - - // Calculate sound distance - if (tx == 0 && ty == 0 && tz == 0) - sound_dist = 255; // Special case for menus sounds,etc. - else - sound_dist = SoundDist(tx, ty, tz, vp->voc_distance); - - v3p->doplr_delta = sound_dist; // Save of distance for doppler - // effect // Can the ambient sound see the player? If not, tone it down some. if ((vp->voc_flags & vf_loop) && Use_SoundSpriteNum && SoundSpriteNum >= 0) @@ -733,88 +570,148 @@ int _PlaySound(int num, SPRITEp sp, PLAYERp pp, vec3_t *pos, Voc3D_Flags flags) if (num == DIGI_WHIPME) sound_dist = 255; } } +*/ - // Assign ambient priorities based on distance - if (snd_ambience && TEST(flags, v3df_ambient)) + + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +float S_ConvertPitch(int lpitch) +{ + return pow(2, lpitch / 1200.); +} + +//========================================================================== +// +// Play a sound +// +//========================================================================== + +int _PlaySound(int num, SPRITEp sp, PLAYERp pp, vec3_t *pos, Voc3D_Flags flags, int channel) +{ + VOC_INFOp vp; + VOC3D_INFOp v3p; + int pitch = 0; + short angle, sound_dist; + int tx, ty, tz; + uint8_t priority; + int maxtics = 0; + EChanFlags cflags = channel == 8 ?CHANF_OVERLAP : CHANF_NONE; // for the default channel we do not want to have sounds stopping each other. + + // Weed out parental lock sounds if PLock is active + if (adult_lockout || Global_PLock) { - v3p->priority = v3p->vp->priority - (sound_dist / 26); - priority = v3p->priority; + unsigned i; + + for (i=0; iflags = v3df_kill; - v3p->handle = -1; - v3p->dist = 0; - v3p->deleted = TRUE; // Sound init failed, remove it! + if (Prediction || !SoundEnabled()) return -1; - }*/ - if (sound_dist < 5) - angle = 0; - - // Check for pitch bending - if (vp->pitch_lo > vp->pitch_hi) - ASSERT(vp->pitch_lo <= vp->pitch_hi); - - if (vp->pitch_hi == vp->pitch_lo) - pitch = vp->pitch_lo; - else if (vp->pitch_hi != vp->pitch_lo) - pitch = vp->pitch_lo + (STD_RANDOM_RANGE(vp->pitch_hi - vp->pitch_lo)); - - // Request playback and play it as a looping sound if flag is set. - if (vp->voc_flags & vf_loop) + if (TEST(flags,v3df_ambient) && !TEST(flags,v3df_nolookup)) // Look for invalid ambient numbers { - short loopvol=0; - - if ((loopvol = 255-sound_dist) <= 0) - loopvol = 0; - - if (sound_dist < 255 || (flags & v3df_init)) + // Ambient sounds need special treatment + if (!snd_ambience) return -1; + if (num < 0 || num > MAX_AMBIENT_SOUNDS) { - voice = FX_Play((char *)vp->data, vp->datalen, 0, 0, - pitch, loopvol, loopvol, loopvol, priority, 1.f, num); // [JM] Should probably utilize floating point volume. !CHECKME! + sprintf(ds,"Invalid or out of range ambient sound number %d\n",num); + PutStringInfo(Player+screenpeek, ds); + return -1; } - else - voice = -1; + maxtics = STD_RANDOM_RANGE(ambarray[num].maxtics); + // If the ambient flag is set, do a name conversion to point to actual + // digital sound entry. + flags |= ambarray[num].ambient_flags; // Add to flags if any + num = ambarray[num].diginame; + cflags |= EChanFlags::FromInt(CHANEXF_AMBIENT); // flag the sound as being an ambient sound. } - else - //if(!flags & v3df_init) // If not initing sound, play it - if (tx==0 && ty==0 && tz==0) // It's a non-inlevel sound + //else { - voice = FX_Play((char *)vp->data, vp->datalen, -1, -1, pitch, 255, 255, 255, priority, 1.f, num); // [JM] And here !CHECKME! - } - else // It's a 3d sound - { - if (sound_dist < 255) + if (!soundEngine->isValidSoundId(num)) { - voice = FX_Play3D((char *)vp->data, vp->datalen, FX_ONESHOT, pitch, angle, sound_dist, priority, 1.f, num); // [JM] And here !CHECKME! + return -1; + } + + vp = &voc[num]; + int sourcetype = SOURCE_None; + void* source = nullptr; + // If the sound is not supposd to be positioned, it may not be linked to the launching actor. + if (!(flags & v3df_follow)) + { + if (sp && !pos) + { + pos = &sp->pos; + sp = nullptr; + } + else if (pp && !pos) + { + pos = (vec3_t*)&pp->posx; + pp = nullptr; + } + } + + if (pos != nullptr) + { + sourcetype = SOURCE_Unattached; + } + else if (sp != nullptr) + { + source = sp; + sourcetype = SOURCE_Actor; + } + else if (pp != nullptr) + { + source = pp; + sourcetype = SOURCE_Player; + } + // Otherwise it's an unpositioned sound. + + if (!(flags & v3df_doppler)) + { + cflags |= EChanFlags::FromInt(CHANEXF_NODOPPLER); // this must ensure that CalcPosVel always zeros the velocity. + } + if (flags & v3df_dontpan) + { + cflags |= EChanFlags::FromInt(CHANEXF_DONTPAN); // beware of hackery to emulate this. + } + if (flags & v3df_init) + { + cflags |= CHANF_VIRTUAL; // don't start right away but keep the channel around until explicitly deleted. + } + if (vp->voc_flags & vf_loop) + { + cflags |= CHANF_LOOP; // with the new sound engine these can just be started and don't have to be stopped ever. + } + + if (vp->pitch_hi <= vp->pitch_lo) + pitch = vp->pitch_lo; + else if (vp->pitch_hi != vp->pitch_lo) + pitch = vp->pitch_lo + (STD_RANDOM_RANGE(vp->pitch_hi - vp->pitch_lo)); + + float fpitch = S_ConvertPitch(pitch); + + auto rolloff = GetRolloff(vp->voc_distance); + auto spos = GetSoundPos(pos); + auto chan = soundEngine->StartSound(sourcetype, source, &spos, CHAN_BODY, cflags, num, 1.f, ATTN_NORM, &rolloff, fpitch); + if (chan) + { + if (flags & v3df_intermit) + { + chan->ChanFlags |= CHANF_VIRTUAL | EChanFlags::FromInt(CHANEXF_INTERMIT); // for intermittent sounds this must be set after starting the sound so that it actually plays. + } + chan->UserData = maxtics; // counter for intermittent delay. } - else - voice = -1; } - // If sound played, update our counter - if (voice > FX_Ok) - { - //vp->playing++; - v3p->FX_Ok = TRUE; - } - else - { - vp->lock--; - } - - // Assign voc info to 3d struct for future reference - v3p->handle = voice; // Save the current voc handle in struct - v3p->dist = sound_dist; - v3p->tics = 0; // Reset tics - if (flags & v3df_init) - v3p->flags ^= v3df_init; // Turn init off now - - return voice; + return 1; } //========================================================================== @@ -1012,6 +909,11 @@ void StopPlayerSound(PLAYERp pp) soundEngine->StopSound(SOURCE_Player, pp, CHAN_VOICE); } +bool SoundValidAndActive(SPRITEp spr, int channel) +{ + return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, spr, channel); +} + /* ============================================================================ @@ -1123,5 +1025,11 @@ SWBOOL PlaySong(const char* mapname, const char* song_file_name, int cdaudio_tra return Mus_Play(nullptr, song_file_name, true); } +void StopSound(void) +{ + soundEngine->StopAllChannels(); + Mus_Stop(); +} + END_SW_NS diff --git a/source/sw/src/sounds.h b/source/sw/src/sounds.h index 77b15abfd..7927287be 100644 --- a/source/sw/src/sounds.h +++ b/source/sw/src/sounds.h @@ -73,7 +73,7 @@ typedef struct ambientstruct AMB_INFO, *AMB_INFOp; extern VOC3D_INFOp voc3dstart; extern VOC3D_INFOp voc3dend; -void DoUpdateSounds3D(void); +void DoUpdateSounds(void); void Terminate3DSounds(void); void Set3DSoundOwner(short spritenum); diff --git a/source/sw/src/zilla.cpp b/source/sw/src/zilla.cpp index 5683532be..4c628e752 100644 --- a/source/sw/src/zilla.cpp +++ b/source/sw/src/zilla.cpp @@ -719,23 +719,22 @@ int DoZillaMove(short SpriteNum) SPRITEp sp = &sprite[SpriteNum]; USERp u = User[SpriteNum]; short choose; - static int handle; //if (TEST(u->Flags,SPR_SLIDING)) //DoActorSlide(SpriteNum); // Random Zilla taunts - if (!FX_SoundValidAndActive(handle)) + if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { choose = STD_RANDOM_RANGE(1000); if (choose > 990) - handle = PlaySound(DIGI_Z16004, sp, v3df_none); + PlaySound(DIGI_Z16004, sp, v3df_none, CHAN_AnimeMad); else if (choose > 985) - handle = PlaySound(DIGI_Z16004, sp, v3df_none); + PlaySound(DIGI_Z16004, sp, v3df_none, CHAN_AnimeMad); else if (choose > 980) - handle = PlaySound(DIGI_Z16004, sp, v3df_none); + PlaySound(DIGI_Z16004, sp, v3df_none, CHAN_AnimeMad); else if (choose > 975) - handle = PlaySound(DIGI_Z16004, sp, v3df_none); + PlaySound(DIGI_Z16004, sp, v3df_none, CHAN_AnimeMad); }