From 7a5c34730bbe27441f4e721d7cdb2c77382e1ef2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 11 Apr 2020 18:29:42 +0200 Subject: [PATCH] - moved game specific data out of the sound backend. In Raze I already had a user data array for that so this gets used here, too, now. Also copied a few other fixes. # Conflicts: # src/sound/s_soundinternal.h --- src/sound/s_advsound.cpp | 32 +++++++++++------------ src/sound/s_doomsound.cpp | 46 ++++++++++++++++++++++++++++++-- src/sound/s_sound.cpp | 30 +++++---------------- src/sound/s_sound.h | 14 ++++++++++ src/sound/s_soundinternal.h | 52 ++++++++++++++++++++----------------- 5 files changed, 108 insertions(+), 66 deletions(-) diff --git a/src/sound/s_advsound.cpp b/src/sound/s_advsound.cpp index 1c48544f1..361313787 100644 --- a/src/sound/s_advsound.cpp +++ b/src/sound/s_advsound.cpp @@ -284,7 +284,7 @@ static bool S_CheckSound(sfxinfo_t *startsfx, sfxinfo_t *sfx, TArraybPlayerReserve) + if (sfx->UserData[0] & SND_PlayerReserve) { return true; } @@ -387,7 +387,7 @@ unsigned int S_GetMSLength(FSoundID sound) // Resolve player sounds, random sounds, and aliases if (sfx->link != sfxinfo_t::NO_LINK) { - if (sfx->bPlayerReserve) + if (sfx->UserData[0] & SND_PlayerReserve) { sfx = &S_sfx[S_FindSkinnedSound (NULL, sound)]; } @@ -451,7 +451,7 @@ static int S_AddSound (const char *logicalname, int lumpnum, FScanner *sc) { // If the sound has already been defined, change the old definition sfxinfo_t *sfx = &S_sfx[sfxid]; - if (sfx->bPlayerReserve) + if (sfx->UserData[0] & SND_PlayerReserve) { if (sc != NULL) { @@ -463,7 +463,7 @@ static int S_AddSound (const char *logicalname, int lumpnum, FScanner *sc) } } // Redefining a player compatibility sound will redefine the target instead. - if (sfx->bPlayerCompat) + if (sfx->UserData[0] & SND_PlayerCompat) { sfx = &S_sfx[sfx->link]; } @@ -980,7 +980,7 @@ static void S_AddSNDINFO (int lump) sfxnum = S_AddPlayerSound (pclass, gender, refid, sc.String); if (0 == stricmp(sc.String, "dsempty")) { - S_sfx[sfxnum].bPlayerSilent = true; + S_sfx[sfxnum].UserData[0] |= SND_PlayerSilent; } } break; @@ -992,7 +992,7 @@ static void S_AddSNDINFO (int lump) S_ParsePlayerSoundCommon (sc, pclass, gender, refid); targid = soundEngine->FindSoundNoHash (sc.String); - if (!S_sfx[targid].bPlayerReserve) + if (!S_sfx[targid].UserData[0] & SND_PlayerReserve) { sc.ScriptError ("%s is not a player sound", sc.String); } @@ -1010,7 +1010,7 @@ static void S_AddSNDINFO (int lump) sfxfrom = S_AddSound (sc.String, -1, &sc); aliasto = S_LookupPlayerSound (pclass, gender, refid); S_sfx[sfxfrom].link = aliasto; - S_sfx[sfxfrom].bPlayerCompat = true; + S_sfx[sfxfrom].UserData[0] |= SND_PlayerCompat; } break; @@ -1033,7 +1033,7 @@ static void S_AddSNDINFO (int lump) sc.MustGetString (); sfxfrom = S_AddSound (sc.String, -1, &sc); sc.MustGetString (); - if (S_sfx[sfxfrom].bPlayerCompat) + if (S_sfx[sfxfrom].UserData[0] & SND_PlayerCompat) { sfxfrom = S_sfx[sfxfrom].link; } @@ -1374,7 +1374,7 @@ static void S_ParsePlayerSoundCommon (FScanner &sc, FString &pclass, int &gender sc.MustGetString (); refid = soundEngine->FindSoundNoHash (sc.String); auto &S_sfx = soundEngine->GetSounds(); - if (refid != 0 && !S_sfx[refid].bPlayerReserve && !S_sfx[refid].bTentative) + if (refid != 0 && !S_sfx[refid].UserData[0] & SND_PlayerReserve && !S_sfx[refid].bTentative) { sc.ScriptError ("%s has already been used for a non-player sound.", sc.String); } @@ -1387,7 +1387,7 @@ static void S_ParsePlayerSoundCommon (FScanner &sc, FString &pclass, int &gender { S_sfx[refid].link = NumPlayerReserves++; S_sfx[refid].bTentative = false; - S_sfx[refid].bPlayerReserve = true; + S_sfx[refid].UserData[0] |= SND_PlayerReserve; } sc.MustGetString (); } @@ -1536,7 +1536,7 @@ int S_LookupPlayerSound (const char *pclass, int gender, const char *name) int S_LookupPlayerSound (const char *pclass, int gender, FSoundID refid) { auto &S_sfx = soundEngine->GetSounds(); - if (!S_sfx[refid].bPlayerReserve) + if (!S_sfx[refid].UserData[0] & SND_PlayerReserve) { // Not a player sound, so just return this sound return refid; } @@ -1582,7 +1582,7 @@ static int S_LookupPlayerSound (int classidx, int gender, FSoundID refid) (sndnum == 0 || ((S_sfx[sndnum].lumpnum == -1 || S_sfx[sndnum].lumpnum == sfx_empty) && S_sfx[sndnum].link == sfxinfo_t::NO_LINK && - !S_sfx[sndnum].bPlayerSilent))) + !(S_sfx[sndnum].UserData[0] & SND_PlayerSilent)))) { // This sound is unavailable. if (ingender != 0) { // Try "male" @@ -1662,7 +1662,7 @@ bool S_AreSoundsEquivalent (AActor *actor, int id1, int id2) // Dereference aliases, but not random or player sounds while ((sfx = &S_sfx[id1])->link != sfxinfo_t::NO_LINK) { - if (sfx->bPlayerReserve) + if (sfx->UserData[0] & SND_PlayerReserve) { id1 = S_FindSkinnedSound (actor, id1); } @@ -1677,7 +1677,7 @@ bool S_AreSoundsEquivalent (AActor *actor, int id1, int id2) } while ((sfx = &S_sfx[id2])->link != sfxinfo_t::NO_LINK) { - if (sfx->bPlayerReserve) + if (sfx->UserData[0] & SND_PlayerReserve) { id2 = S_FindSkinnedSound (actor, id2); } @@ -1819,7 +1819,7 @@ CCMD (soundlinks) if (sfx->link != sfxinfo_t::NO_LINK && !sfx->bRandomHeader && - !sfx->bPlayerReserve) + !(sfx->UserData[0] & SND_PlayerReserve)) { Printf ("%s -> %s\n", sfx->name.GetChars(), S_sfx[sfx->link].name.GetChars()); } @@ -1843,7 +1843,7 @@ CCMD (playersounds) memset (reserveNames, 0, sizeof(reserveNames)); for (i = j = 0; j < NumPlayerReserves && i < S_sfx.Size(); ++i) { - if (S_sfx[i].bPlayerReserve) + if (S_sfx[i].UserData[0] & SND_PlayerReserve) { ++j; reserveNames[S_sfx[i].link] = S_sfx[i].name; diff --git a/src/sound/s_doomsound.cpp b/src/sound/s_doomsound.cpp index 151b64203..142c77e00 100644 --- a/src/sound/s_doomsound.cpp +++ b/src/sound/s_doomsound.cpp @@ -85,6 +85,21 @@ class DoomSoundEngine : public SoundEngine TArray ReadSound(int lumpnum); int PickReplacement(int refid); FSoundID ResolveSound(const void *ent, int type, FSoundID soundid, float &attenuation) override; + void CacheSound(sfxinfo_t* sfx) override; + void StopChannel(FSoundChan* chan) override; + int AddSoundLump(const char* logicalname, int lump, int CurrentPitchMask, int resid = -1, int nearlimit = 2) override + { + auto ndx = SoundEngine::AddSoundLump(logicalname, lump, CurrentPitchMask, resid, nearlimit); + S_sfx[ndx].UserData.Resize(1); + S_sfx[ndx].UserData[0] = 0; + return ndx; + } + bool CheckSoundLimit(sfxinfo_t* sfx, const FVector3& pos, int near_limit, float limit_range, int sourcetype, const void* actor, int channel) override + { + if (sourcetype != SOURCE_Actor) actor = nullptr; //ZDoom did this. + return SoundEngine::CheckSoundLimit(sfx, pos, near_limit, limit_range, sourcetype, actor, channel); + } + public: DoomSoundEngine() = default; @@ -309,6 +324,17 @@ DEFINE_ACTION_FUNCTION(DObject, S_StartSound) } +//========================================================================== +// +// +// +//========================================================================== + +void DoomSoundEngine::CacheSound(sfxinfo_t* sfx) +{ + if (!(sfx->UserData[0] & SND_PlayerReserve)) SoundEngine::CacheSound(sfx); +} + //========================================================================== // // @@ -317,7 +343,8 @@ DEFINE_ACTION_FUNCTION(DObject, S_StartSound) FSoundID DoomSoundEngine::ResolveSound(const void * ent, int type, FSoundID soundid, float &attenuation) { - if (isPlayerReserve(soundid)) + auto sfx = &S_sfx[soundid]; + if (sfx->UserData[0] & SND_PlayerReserve) { AActor *src; if (type != SOURCE_Actor) src = nullptr; @@ -353,6 +380,21 @@ static bool VerifyActorSound(AActor* ent, FSoundID& sound_id, int& channel, ECha return true; } +//========================================================================== +// +// Common checking code for the actor sound functions +// +//========================================================================== + +void DoomSoundEngine::StopChannel(FSoundChan* chan) +{ + if (chan && chan->SysChannel != NULL && !(chan->ChanFlags & CHANF_EVICTED) && chan->SourceType == SOURCE_Actor) + { + chan->Source = NULL; + } + SoundEngine::StopChannel(chan); +} + //========================================================================== // @@ -1239,7 +1281,7 @@ void DoomSoundEngine::PrintSoundList() } Printf("}\n"); } - else if (sfx->bPlayerReserve) + else if (sfx->UserData[0] & SND_PlayerReserve) { Printf("%3d. %s <>\n", i, sfx->name.GetChars(), sfx->link); } diff --git a/src/sound/s_sound.cpp b/src/sound/s_sound.cpp index 244d1b721..bfbb914dd 100644 --- a/src/sound/s_sound.cpp +++ b/src/sound/s_sound.cpp @@ -64,6 +64,7 @@ int sfx_empty = -1; void SoundEngine::Init(TArray &curve) { + StopAllChannels(); // Free all channels for use. while (Channels != NULL) { @@ -158,12 +159,8 @@ void SoundEngine::CacheMarkedSounds() void SoundEngine::CacheSound (sfxinfo_t *sfx) { - if (GSnd) + if (GSnd && !sfx->bTentative) { - if (sfx->bPlayerReserve) - { - return; - } sfxinfo_t *orig = sfx; while (!sfx->bRandomHeader && sfx->link != sfxinfo_t::NO_LINK) { @@ -283,7 +280,7 @@ TArray SoundEngine::AllActiveChannels() // If the sound is forgettable, this is as good a time as // any to forget about it. And if it's a UI sound, it shouldn't // be stored in the savegame. - if (!(chan->ChanFlags & (CHANF_FORGETTABLE | CHANF_UI))) + if (!(chan->ChanFlags & (CHANF_FORGETTABLE | CHANF_UI | CHANF_TRANSIENT))) { chans.Push(chan); } @@ -470,9 +467,8 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, near_limit = 0; } - // If this sound doesn't like playing near itself, don't play it if - // that's what would happen. (Does this really need the SOURCE_Actor restriction?) - if (near_limit > 0 && CheckSoundLimit(sfx, pos, near_limit, limit_range, type, type == SOURCE_Actor? source : nullptr, channel)) + // If this sound doesn't like playing near itself, don't play it if that's what would happen. + if (near_limit > 0 && CheckSoundLimit(sfx, pos, near_limit, limit_range, type, source, channel)) { chanflags |= CHANF_EVICTED; } @@ -580,7 +576,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, GSnd->MarkStartTime(chan); chanflags |= CHANF_EVICTED; } - if (attenuation > 0) + if (attenuation > 0 && type != SOURCE_None) { chanflags |= CHANF_IS3D | CHANF_JUSTSTARTED; } @@ -1428,10 +1424,6 @@ void SoundEngine::StopChannel(FSoundChan *chan) if (!(chan->ChanFlags & CHANF_EVICTED)) { chan->ChanFlags |= CHANF_FORGETTABLE; - if (chan->SourceType == SOURCE_Actor) - { - chan->Source = NULL; - } } GSnd->StopChannel(chan); } @@ -1557,14 +1549,11 @@ int SoundEngine::AddSoundLump(const char* logicalname, int lump, int CurrentPitc newsfx.NearLimit = nearlimit; newsfx.LimitRange = 256 * 256; newsfx.bRandomHeader = false; - newsfx.bPlayerReserve = false; newsfx.bLoadRAW = false; - newsfx.bPlayerCompat = false; newsfx.b16bit = false; newsfx.bUsed = false; newsfx.bSingular = false; newsfx.bTentative = false; - newsfx.bPlayerSilent = false; newsfx.ResourceId = resid; newsfx.RawRate = 0; newsfx.link = sfxinfo_t::NO_LINK; @@ -1577,13 +1566,6 @@ int SoundEngine::AddSoundLump(const char* logicalname, int lump, int CurrentPitc return (int)S_sfx.Size()-1; } -int SoundEngine::AddSfx(sfxinfo_t &sfx) -{ - S_sfx.Push(sfx); - if (sfx.ResourceId >= 0) ResIdMap[sfx.ResourceId] = S_sfx.Size() - 1; - return (int)S_sfx.Size() - 1; -} - //========================================================================== // diff --git a/src/sound/s_sound.h b/src/sound/s_sound.h index e54f1fe7b..653ae0187 100644 --- a/src/sound/s_sound.h +++ b/src/sound/s_sound.h @@ -37,6 +37,20 @@ class FSerializer; #include "s_soundinternal.h" #include "s_doomsound.h" +enum SndUserFlags +{ + SND_PlayerReserve = 1, + SND_PlayerCompat = 2, + SND_PlayerSilent = 4 +}; + +enum // This cannot be remain as this, but for now it has to suffice. +{ + SOURCE_Actor = SOURCE_None+1, // Sound is coming from an actor. + SOURCE_Sector, // Sound is coming from a sector. + SOURCE_Polyobj, // Sound is coming from a polyobject. +}; + // Per level startup code. // Kills playing sounds at start of level and starts new music. // diff --git a/src/sound/s_soundinternal.h b/src/sound/s_soundinternal.h index c327177c8..97539eff9 100644 --- a/src/sound/s_soundinternal.h +++ b/src/sound/s_soundinternal.h @@ -39,9 +39,7 @@ struct sfxinfo_t unsigned bSingular:1; unsigned bTentative:1; - unsigned bPlayerReserve : 1; - unsigned bPlayerCompat : 1; - unsigned bPlayerSilent:1; // This player sound is intentionally silent. + TArray UserData; int RawRate; // Sample rate to use when bLoadRAW is true @@ -174,11 +172,8 @@ struct FSoundChan : public FISoundChannel int8_t Priority; uint8_t SourceType; float LimitRange; - union - { - const void *Source; - float Point[3]; // Sound is not attached to any source. - }; + const void *Source; + float Point[3]; // Sound is not attached to any source. }; @@ -212,14 +207,11 @@ enum EChannel #define ATTN_IDLE 1.001f #define ATTN_STATIC 3.f // diminish very rapidly with distance -enum // This cannot be remain as this, but for now it has to suffice. +enum // The core source types, implementations may extend this list as they see fit. { SOURCE_Any = -1, // Input for check functions meaning 'any source' - SOURCE_None, // Sound is always on top of the listener. - SOURCE_Actor, // Sound is coming from an actor. - SOURCE_Sector, // Sound is coming from a sector. - SOURCE_Polyobj, // Sound is coming from a polyobject. SOURCE_Unattached, // Sound is not attached to any particular emitter. + SOURCE_None, // Sound is always on top of the listener. }; @@ -268,13 +260,16 @@ private: // Checks if a copy of this sound is already playing. bool CheckSingular(int sound_id); - bool CheckSoundLimit(sfxinfo_t* sfx, const FVector3& pos, int near_limit, float limit_range, int sourcetype, const void* actor, int channel); virtual TArray ReadSound(int lumpnum) = 0; protected: + virtual bool CheckSoundLimit(sfxinfo_t* sfx, const FVector3& pos, int near_limit, float limit_range, int sourcetype, const void* actor, int channel); virtual FSoundID ResolveSound(const void *ent, int srctype, FSoundID soundid, float &attenuation); public: - virtual ~SoundEngine() = default; + virtual ~SoundEngine() + { + Shutdown(); + } void EvictAllChannels(); void BlockNewSounds(bool on) @@ -282,7 +277,10 @@ public: blockNewSounds = on; } - void StopChannel(FSoundChan* chan); + virtual int SoundSourceIndex(FSoundChan* chan) { return 0; } + virtual void SetSource(FSoundChan* chan, int index) {} + + virtual void StopChannel(FSoundChan* chan); sfxinfo_t* LoadSound(sfxinfo_t* sfx); // Initializes sound stuff, including volume @@ -303,7 +301,7 @@ public: void CalcPosVel(FSoundChan* chan, FVector3* pos, FVector3* vel); // Loads a sound, including any random sounds it might reference. - void CacheSound(sfxinfo_t* sfx); + virtual void CacheSound(sfxinfo_t* sfx); void CacheSound(int sfx) { CacheSound(&S_sfx[sfx]); } void UnloadSound(sfxinfo_t* sfx); void UnloadSound(int sfx) @@ -344,14 +342,14 @@ public: { return object && listener.ListenerObject == object; } - bool isPlayerReserve(int snd_id) - { - return S_sfx[snd_id].bPlayerReserve; // Later this needs to be abstracted out of the engine itself. Right now that cannot be done. - } void SetListener(SoundListener& l) { listener = l; } + const SoundListener& GetListener() const + { + return listener; + } void SetRestartTime(int time) { RestartEvictionsAt = time; @@ -384,6 +382,10 @@ public: { S_rnd.Clear(); } + int *GetUserData(int snd) + { + return S_sfx[snd].UserData.Data(); + } bool isValidSoundId(int id) { return id > 0 && id < (int)S_sfx.Size() && !S_sfx[id].bTentative && S_sfx[id].lumpnum != sfx_empty; @@ -391,10 +393,13 @@ public: template bool EnumerateChannels(func callback) { - for (FSoundChan* chan = Channels; chan; chan = chan->NextChan) + FSoundChan* chan = Channels; + while (chan) { + auto next = chan->NextChan; int res = callback(chan); if (res) return res > 0; + chan = next; } return false; } @@ -417,8 +422,7 @@ public: int FindSoundByResID(int rid); int FindSoundNoHash(const char* logicalname); int FindSoundByLump(int lump); - int AddSoundLump(const char* logicalname, int lump, int CurrentPitchMask, int resid = -1, int nearlimit = 2); - int AddSfx(sfxinfo_t &sfx); + virtual int AddSoundLump(const char* logicalname, int lump, int CurrentPitchMask, int resid = -1, int nearlimit = 2); int FindSoundTentative(const char* name); void CacheRandomSound(sfxinfo_t* sfx); unsigned int GetMSLength(FSoundID sound);