diff --git a/source/common/audio/sound/s_sound.cpp b/source/common/audio/sound/s_sound.cpp index 51396a378c8..618e6d6303f 100644 --- a/source/common/audio/sound/s_sound.cpp +++ b/source/common/audio/sound/s_sound.cpp @@ -1510,6 +1510,27 @@ FSoundID SoundEngine::FindSoundNoHash(const char* logicalname) return NO_SOUND; } +//========================================================================== +// +// S_FindSoundByResIDNoHash +// +// same with resource IDs. +//========================================================================== + +FSoundID SoundEngine::FindSoundByResIDNoHash(int resid) +{ + unsigned int i; + + for (i = 1; i < S_sfx.Size(); i++) + { + if (S_sfx[i].ResourceId == resid) + { + return FSoundID::fromInt(i); + } + } + return NO_SOUND; +} + //========================================================================== // // S_FindSoundByLump @@ -1550,8 +1571,6 @@ FSoundID SoundEngine::AddSoundLump(const char* logicalname, int lump, int Curren newsfx.ResourceId = resid; newsfx.bTentative = false; auto id = FSoundID::fromInt(S_sfx.Size() - 1); - - if (resid >= 0) ResIdMap[resid] = id; return id; } @@ -1565,12 +1584,12 @@ FSoundID SoundEngine::AddSoundLump(const char* logicalname, int lump, int Curren // an associated lump is created. //========================================================================== -FSoundID SoundEngine::FindSoundTentative(const char* name) +FSoundID SoundEngine::FindSoundTentative(const char* name, int nearlimit) { auto id = FindSoundNoHash(name); if (id == NO_SOUND) { - id = AddSoundLump(name, -1, 0); + id = AddSoundLump(name, -1, 0, -1, nearlimit); S_sfx[id.index()].bTentative = true; } return id; @@ -1694,9 +1713,9 @@ void SoundEngine::HashSounds() S_sfx[i].next = S_sfx[j].index; S_sfx[j].index = i; - if (S_sfx[j].ResourceId != -1) + if (S_sfx[i].ResourceId != -1) { - ResIdMap.Insert(S_sfx[j].ResourceId, FSoundID::fromInt(i)); + ResIdMap.Insert(S_sfx[i].ResourceId, FSoundID::fromInt(i)); } } S_rnd.ShrinkToFit(); diff --git a/source/common/audio/sound/s_soundinternal.h b/source/common/audio/sound/s_soundinternal.h index 95faa99c93f..4eeb4e10457 100644 --- a/source/common/audio/sound/s_soundinternal.h +++ b/source/common/audio/sound/s_soundinternal.h @@ -390,18 +390,15 @@ class SoundEngine FSoundID FindSound(const char* logicalname); FSoundID FindSoundByResID(int rid); FSoundID FindSoundNoHash(const char* logicalname); + FSoundID FindSoundByResIDNoHash(int rid); FSoundID FindSoundByLump(int lump); virtual FSoundID AddSoundLump(const char* logicalname, int lump, int CurrentPitchMask, int resid = -1, int nearlimit = 2); - FSoundID FindSoundTentative(const char* name); + FSoundID FindSoundTentative(const char* name, int nearlimit = 2); void CacheRandomSound(sfxinfo_t* sfx); unsigned int GetMSLength(FSoundID sound); FSoundID PickReplacement(FSoundID refid); void HashSounds(); void AddRandomSound(FSoundID Owner, TArray list); - void RemoveResourceID(int id) - { - ResIdMap.Remove(id); - } TArray& GetSounds() //We still need this for a short time... { diff --git a/source/core/music/s_advsound.cpp b/source/core/music/s_advsound.cpp index 1e65d4f960a..95d62a6e4c4 100644 --- a/source/core/music/s_advsound.cpp +++ b/source/core/music/s_advsound.cpp @@ -54,7 +54,9 @@ enum SICommands SI_MidiDevice, SI_MusicAlias, SI_ConReserve, - SI_Alias + SI_Alias, + SI_Limit, + SI_Singular }; @@ -83,77 +85,59 @@ static const char *SICommandStrings[] = "$musicalias", "$conreserve", "$alias", + "$limit", + "$singular", NULL }; - +static const int DEFAULT_LIMIT = 6; // CODE -------------------------------------------------------------------- //========================================================================== // -// S_ReserveSoundSlot +// S_AddSound // -// Reserves an empty sound slot and assigns it a resource ID and a name -// +// If logical name is already in S_sfx, updates it to use the new sound +// lump. Otherwise, adds the new mapping by using S_AddSoundLump(). //========================================================================== -FSoundID S_ReserveSoundSlot(const char* logicalname, int slotnum, int limit = 6) +static FSoundID S_AddSound(const char* logicalname, int lumpnum, FScanner* sc) { - auto& S_sfx = soundEngine->GetSounds(); - - auto sfxid = soundEngine->FindSoundNoHash(logicalname); + FSoundID sfxid = soundEngine->FindSoundNoHash(logicalname); - if (soundEngine->isValidSoundId(sfxid)) + if (sfxid.isvalid()) { // If the sound has already been defined, change the old definition - sfxinfo_t* sfx = soundEngine->GetWritableSfx(sfxid); + auto sfx = soundEngine->GetWritableSfx(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 = NO_SOUND; } - sfx->ResourceId = slotnum; - sfx->lumpnum = sfx_empty; + sfx->lumpnum = lumpnum; sfx->bRandomHeader = false; sfx->link = sfxinfo_t::NO_LINK; - sfx->bTentative = true; + sfx->bTentative = false; if (sfx->NearLimit == -1) { - sfx->NearLimit = 2; + sfx->NearLimit = 6; sfx->LimitRange = 256 * 256; } //sfx->PitchMask = CurrentPitchMask; } else { // Otherwise, create a new definition. - sfxid = soundEngine->AddSoundLump(logicalname, sfx_empty, 0, slotnum, limit); + sfxid = soundEngine->AddSoundLump(logicalname, lumpnum, 0); } return sfxid; } -//========================================================================== -// -// S_ParseSndInfo -// -// Parses all loaded SNDINFO lumps. -// Also registers Blood SFX files and Strife's voices. -//========================================================================== - -void S_ParseSndInfo () +FSoundID S_AddSound(const char* logicalname, const char* lumpname, FScanner* sc) { - int lump, lastlump = 0; - - while ((lump = fileSystem.FindLumpFullName("engine/mussetting.txt", &lastlump)) >= 0) - { - S_AddSNDINFO (lump); - } + int lump = fileSystem.CheckNumForFullName(lumpname, true, ns_sounds); + return S_AddSound(logicalname, lump, sc); } //========================================================================== @@ -168,6 +152,7 @@ static void S_AddSNDINFO (int lump) { bool skipToEndIf; TArray list; + int wantassigns = -1; FScanner sc(lump); skipToEndIf = false; @@ -262,24 +247,105 @@ static void S_AddSNDINFO (int lump) } break; + case SI_Alias: { + // $alias + FSoundID sfxfrom; + + sc.MustGetString (); + sfxfrom = S_AddSound (sc.String, -1, &sc); + sc.MustGetString (); + auto sfx = soundEngine->GetWritableSfx(sfxfrom); + sfx->link = soundEngine->FindSoundTentative (sc.String); + sfx->NearLimit = -1; // Aliases must use the original sound's limit. (Can be changed later) + } + break; + + case SI_Limit: { + // $limit [] + FSoundID sfxfrom; + + sc.MustGetString (); + sfxfrom = soundEngine->FindSoundTentative (sc.String); + sc.MustGetNumber (); + auto sfx = soundEngine->GetWritableSfx(sfxfrom); + sfx->NearLimit = min(max(sc.Number, 0), 255); + if (sc.CheckFloat()) + { + sfx->LimitRange = float(sc.Float * sc.Float); + } + } + break; + + case SI_Singular: { + // $singular + FSoundID sfx; + + sc.MustGetString (); + sfx = soundEngine->FindSoundTentative (sc.String, DEFAULT_LIMIT); + auto sfxp = soundEngine->GetWritableSfx(sfx); + sfxp->bSingular = true; + } + break; + + case SI_ConReserve: { - sc.MustGetNumber(); - int num = sc.Number; - sc.MustGetStringName("="); + // $conreserve + // Assigns a resource ID to the given sound. sc.MustGetString(); - FString name = sc.String; - int limit = 6; - if (sc.CheckString(",")) + FSoundID sfx = soundEngine->FindSoundTentative(sc.String, DEFAULT_LIMIT); + auto sfxp = soundEngine->GetWritableSfx(sfx); + + sc.MustGetNumber(); + sfxp->ResourceId = sc.Number; + break; + } + + default: + { // Got a logical sound mapping + FString name (sc.String); + if (wantassigns == -1) { - sc.MustGetNumber(); - limit = sc.Number; + wantassigns = sc.CheckString("="); } - S_ReserveSoundSlot(name, num, limit); - } + else if (wantassigns) + { + sc.MustGetStringName("="); + } + + sc.MustGetString (); + S_AddSound (name, sc.String, &sc); } + } } } } +//========================================================================== +// +// S_ParseSndInfo +// +// Parses all loaded SNDINFO lumps. +// +//========================================================================== + +void S_ParseSndInfo() +{ + int lump; + + soundEngine->Clear(); + MusicAliases.Clear(); + MidiDevices.Clear(); + MusicVolumes.Clear(); + + S_AddSound("{ no sound }", "DSEMPTY", nullptr); // Sound 0 is no sound at all + + int lastlump = 0; + while ((lump = fileSystem.FindLump("SNDINFO", &lastlump, false)) != -1) + { + S_AddSNDINFO(lump); + } + soundEngine->HashSounds(); +} + diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index 501298ef8cb..a72f11d1cd2 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -201,20 +201,50 @@ int S_GetUserFlags(FSoundID soundid) int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpitch, int priority, int type, int distance, float volume) { - FSoundID s_index = soundEngine->FindSoundByResID(index); - sfxinfo_t* sfx; + FSoundID s_index = soundEngine->FindSoundByResIDNoHash(index); // cannot use the hash while editing. if (!s_index.isvalid()) { // If the slot isn't defined, give it a meaningful name containing the index. - sfx = soundEngine->AllocateSound(); - sfx->name.Format("ConSound@%04d", index); - sfx->ResourceId = index; + s_index = soundEngine->FindSoundTentative(FStringf("ConSound@%04d", index)); } - else sfx = soundEngine->GetWritableSfx(s_index); + auto sfx = soundEngine->GetWritableSfx(s_index); + // Check if we are allowed to override this sound. + // If it is still tentative, it's ok. Otherwise check if SF_CONDEFINED is set, This means it was defined by CON and may be overwritten. + // If the sound was defined by other means we leave it alone, but set the flags to defaults, if they are not present. + + bool settable = sfx->bTentative; + + if (!settable) + { + if (sfx->UserData.Size() >= kMaxUserData) + { + auto& sndinf = sfx->UserData; + settable = !!(sndinf[kFlags] & SF_CONDEFINED); + } + } + if (!settable) + { + if (sfx->UserData.Size() < kMaxUserData) + { + // sound is defined but has no userdata. + // This means it was defined through SNDINFO without setting extended properties and should not be overwritten. + // Set everything to 0 to have default handling. + sfx->UserData.Resize(kMaxUserData); + auto& sndinf = sfx->UserData; + sndinf[kPitchStart] = 0; + sndinf[kPitchEnd] = 0; + sndinf[kPriority] = 0; // Raze's sound engine does not use this. + sndinf[kVolAdjust] = 0; + sndinf[kWorldTourMapping] = 0; + sndinf[kFlags] = 0; + } + } + + sfx->ResourceId = index; sfx->UserData.Resize(kMaxUserData); - auto sndinf = sfx->UserData.Data(); - sndinf[kFlags] = type & ~SF_ONEINST_INTERNAL; + auto& sndinf = sfx->UserData; + sndinf[kFlags] = (type & ~SF_ONEINST_INTERNAL) | SF_CONDEFINED; if (sndinf[kFlags] & SF_LOOP) sndinf[kFlags] |= SF_ONEINST_INTERNAL; @@ -239,7 +269,6 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit sfx->Volume = volume; //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; } diff --git a/source/games/duke/src/sounds.h b/source/games/duke/src/sounds.h index 37673b04172..97221920c08 100644 --- a/source/games/duke/src/sounds.h +++ b/source/games/duke/src/sounds.h @@ -19,6 +19,7 @@ enum { SF_ADULT = 8, SF_GLOBAL = 16, SF_ONEINST_INTERNAL = 32, + SF_CONDEFINED = 64, SF_DTAG = 128, }; diff --git a/wadsrc/static/filter/duke/sndinfo.txt b/wadsrc/static/filter/duke/sndinfo.txt index 564431c98c9..3a40c1bc260 100644 --- a/wadsrc/static/filter/duke/sndinfo.txt +++ b/wadsrc/static/filter/duke/sndinfo.txt @@ -68,6 +68,7 @@ $conreserve PLAYER_TIP2 67 $conreserve FLESH_BURNING 68 $conreserve SQUISHED 69 $conreserve TELEPORTER 70 +$limit teleporter 0 $conreserve ELEVATOR_ON 71 $conreserve PLAYER_KILLED3 72 $conreserve ELEVATOR_OFF 73 @@ -225,7 +226,7 @@ $conreserve JIBBED_ACTOR4 225 $conreserve JIBBED_ACTOR5 226 $conreserve JIBBED_ACTOR6 227 $conreserve JIBBED_ACTOR7 228 -$conreserve PLAYER_GOTHEALTHATLOW229 +$conreserve PLAYER_GOTHEALTHATLOW 229 $conreserve BOSSTALKTODUKE 230 $conreserve WAR_AMBIENCE1 231 $conreserve WAR_AMBIENCE2 232 @@ -247,8 +248,8 @@ $conreserve RATTY 247 $conreserve INTO_MENU 248 $conreserve BONUSMUSIC 249 $conreserve PLAYER_BOOBY 250 -$conreserve PLAYER_TALKTOBOSSFALL251 -$conreserve PLAYER_LOOKINTOMIRROR252 +$conreserve PLAYER_TALKTOBOSSFALL 251 +$conreserve PLAYER_LOOKINTOMIRROR 252 $conreserve PIG_ROAM3 253 $conreserve KILLME 254 $conreserve DRON_JETSND 255 @@ -270,9 +271,9 @@ $conreserve PLAYER_KILLED4 270 $conreserve PLAYER_KILLED5 271 $conreserve ALIEN_SWITCH1 272 $conreserve PLAYER_STEPONFECES 273 -$conreserve PLAYER_LONGTERM_PAIN2274 -$conreserve PLAYER_LONGTERM_PAIN3275 -$conreserve PLAYER_LONGTERM_PAIN4276 +$conreserve PLAYER_LONGTERM_PAIN2 274 +$conreserve PLAYER_LONGTERM_PAIN3 275 +$conreserve PLAYER_LONGTERM_PAIN4 276 $conreserve COMPANB2 277 $conreserve KTIT 278 $conreserve HELICOP_IDLE 279 @@ -300,10 +301,10 @@ $conreserve ENDSEQVOL2SND6 300 $conreserve ENDSEQVOL2SND7 301 $conreserve GENERIC_AMBIENCE23 302 $conreserve SOMETHINGFROZE 303 -$conreserve PLAYER_LONGTERM_PAIN5304 -$conreserve PLAYER_LONGTERM_PAIN6305 -$conreserve PLAYER_LONGTERM_PAIN7306 -$conreserve PLAYER_LONGTERM_PAIN8307 +$conreserve PLAYER_LONGTERM_PAIN5 304 +$conreserve PLAYER_LONGTERM_PAIN6 305 +$conreserve PLAYER_LONGTERM_PAIN7 306 +$conreserve PLAYER_LONGTERM_PAIN8 307 $conreserve WIND_REPEAT 308 $conreserve MYENEMY_ROAM 309 $conreserve MYENEMY_HURT 310 @@ -342,7 +343,7 @@ $conreserve BOS4_RECOG 342 $conreserve BOS4_ATTACK 343 $conreserve BOS4_PAIN 344 $conreserve BOS4_DYING 345 -$conreserve NEWBEAST_ATTACKMISS346 +$conreserve NEWBEAST_ATTACKMISS 346 $conreserve VOL4_2 347 $conreserve COOKINGDEEPFRIER 348 $conreserve WHINING_DOG 349 diff --git a/wadsrc/static/filter/redneck/sndinfo.txt b/wadsrc/static/filter/redneck/sndinfo.txt index 98a17e2aedb..74ce8e4b76d 100644 --- a/wadsrc/static/filter/redneck/sndinfo.txt +++ b/wadsrc/static/filter/redneck/sndinfo.txt @@ -74,7 +74,8 @@ $conreserve LN_RODE 66 $conreserve CURTAIN 67 $conreserve FIRE09 68 $conreserve SQUISHED 69 -$conreserve TELEPORT 70 +$conreserve TELEPORTER 70 +$limit TELEPORTER 0 $conreserve GBELEV01 71 $conreserve LN_BNCH 72 $conreserve GBELEV02 73 diff --git a/wadsrc/static/zscript/games/duke/actors/tripbomb.zs b/wadsrc/static/zscript/games/duke/actors/tripbomb.zs index e69e973e424..ad613a9f8a4 100644 --- a/wadsrc/static/zscript/games/duke/actors/tripbomb.zs +++ b/wadsrc/static/zscript/games/duke/actors/tripbomb.zs @@ -53,7 +53,7 @@ class DukeTripBomb : DukeActor self.temp_data[2]--; if (self.temp_data[2] == 8) { - self.PlayActorSound(Dukesnd.LASERTRIP_EXPLODE); + self.PlayActorSound("LASERTRIP_EXPLODE"); for (j = 0; j < 5; j++) self.RandomScrap(); int ex = self.extra; self.hitradius(gs.tripbombblastradius, ex >> 2, ex >> 1, ex - (ex >> 2), ex);