diff --git a/source/core/music/s_advsound.cpp b/source/core/music/s_advsound.cpp index 4103bf4e0ef..69ae064f4af 100644 --- a/source/core/music/s_advsound.cpp +++ b/source/core/music/s_advsound.cpp @@ -41,6 +41,7 @@ #include "v_text.h" #include "s_music.h" #include "sc_man.h" +#include "s_soundinternal.h" #include #include "raze_music.h" @@ -52,6 +53,8 @@ enum SICommands SI_MusicVolume, SI_MidiDevice, SI_MusicAlias, + SI_ConReserve, + SI_Alias }; @@ -78,12 +81,64 @@ static const char *SICommandStrings[] = "$musicvolume", "$mididevice", "$musicalias", + "$conreserve", + "$alias", NULL }; // CODE -------------------------------------------------------------------- +//========================================================================== +// +// S_ReserveSoundSlot +// +// Reserves an empty sound slot and assigns it a resource ID and a name +// +//========================================================================== + +int S_ReserveSoundSlot(const char* logicalname, int slotnum, int limit = 6) +{ + auto& S_sfx = soundEngine->GetSounds(); + int sfxid; + + sfxid = soundEngine->FindSoundNoHash(logicalname); + + if (sfxid > 0 && (unsigned int)sfxid < S_sfx.Size()) + { // If the sound has already been defined, change the old definition + sfxinfo_t* sfx = &S_sfx[sfxid]; + + if (sfx->ResourceId != -1) + { + // If the name was reseved before, delete that mapping. + soundEngine->RemoveResourceID(sfx->ResourceId); + } + if (sfx->bRandomHeader) + { + FRandomSoundList* rnd = soundEngine->ResolveRandomSound(sfx); + rnd->Choices.Reset(); + rnd->Owner = 0; + } + sfx->ResourceId = slotnum; + sfx->lumpnum = sfx_empty; + sfx->bRandomHeader = false; + sfx->link = sfxinfo_t::NO_LINK; + sfx->bTentative = true; + if (sfx->NearLimit == -1) + { + sfx->NearLimit = 2; + sfx->LimitRange = 256 * 256; + } + //sfx->PitchMask = CurrentPitchMask; + } + else + { // Otherwise, create a new definition. + sfxid = soundEngine->AddSoundLump(logicalname, sfx_empty, 0, slotnum, limit); + } + + return sfxid; +} + //========================================================================== // // S_ParseSndInfo @@ -208,7 +263,23 @@ static void S_AddSNDINFO (int lump) } break; + case SI_ConReserve: { + sc.MustGetNumber(); + int num = sc.Number; + sc.MustGetStringName("="); + sc.MustGetString(); + FString name = sc.String; + int limit = 6; + if (sc.CheckString(",")) + { + sc.MustGetNumber(); + limit = sc.Number; + } + S_ReserveSoundSlot(name, num, limit); } + } + + } } } diff --git a/source/core/raze_sound.h b/source/core/raze_sound.h index 9802cea93fe..0c6b7170c96 100644 --- a/source/core/raze_sound.h +++ b/source/core/raze_sound.h @@ -33,6 +33,7 @@ inline void FX_SetReverbDelay(int delay) int S_LookupSound(const char* fn); class FSerializer; void S_SerializeSounds(FSerializer& arc); +int S_ReserveSoundSlot(const char* logicalname, int slotnum, int limit = 6); class RazeSoundEngine : public SoundEngine { diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp index 96fc6615fdc..675ce1f17df 100644 --- a/source/core/savegamehelp.cpp +++ b/source/core/savegamehelp.cpp @@ -102,6 +102,9 @@ static void SerializeGlobals(FSerializer& arc) static void SerializeSession(FSerializer& arc) { + // In Duke we now have reliable sound names. + if (isDukeLike()) arc.SetUniqueSoundNames(); + arc.ReadObjects(false); SerializeMap(arc); SerializeStatistics(arc); diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index 8bfcc71fcae..56815c9e4cb 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -172,7 +172,7 @@ void S_CacheAllSounds(void) // //========================================================================== -static inline int S_GetPitch(int num) +static inline int S_GetPitch(FSoundID num) { auto soundid = FSoundID::fromInt(num + 1); auto const* snd = soundEngine->GetUserData(soundid); @@ -203,13 +203,14 @@ int S_GetUserFlags(int num) int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpitch, int priority, int type, int distance, float volume) { - auto& S_sfx = soundEngine->GetSounds(); - index++; - if (index >= S_sfx.Size()) + int s_index = soundEngine->FindSoundByResID(index); + if (s_index == 0) { - S_sfx.Resize(index + 1); + // If the slot isn't defined, give it a meaningful name containing the index. + s_index = S_ReserveSoundSlot(FStringf("ConSound@%04d", index), index, 6); } - auto sfx = &S_sfx[index]; + + auto sfx = &soundEngine->GetSounds()[s_index]; sfx->UserData.Resize(kMaxUserData); auto sndinf = sfx->UserData.Data(); sndinf[kFlags] = type & ~SF_ONEINST_INTERNAL; @@ -235,7 +236,7 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit sndinf[kVolAdjust] = clamp(distance, INT16_MIN, INT16_MAX); sndinf[kWorldTourMapping] = 0; sfx->Volume = volume; - sfx->NearLimit = index == TELEPORTER + 1? 6 : 0; // the teleporter sound cannot be unlimited due to how it gets used. + //sfx->NearLimit = index == TELEPORTER + 1? 6 : 0; // the teleporter sound cannot be unlimited due to how it gets used. sfx->bTentative = false; sfx->name = std::move(fn); return 0; @@ -253,7 +254,7 @@ inline bool S_IsAmbientSFX(DDukeActor* actor) // //========================================================================== -static int GetPositionInfo(DDukeActor* actor, int soundNum, sectortype* sect, +static int GetPositionInfo(DDukeActor* actor, FSoundID soundID, sectortype* sect, const DVector3 &cam, const DVector3 &pos, int *distPtr, FVector3 *sndPos) { // There's a lot of hackery going on here that could be mapped to rolloff and attenuation parameters.