diff --git a/source/common/audio/sound/s_soundinternal.h b/source/common/audio/sound/s_soundinternal.h index 57a8372b2..c206ccd7e 100644 --- a/source/common/audio/sound/s_soundinternal.h +++ b/source/common/audio/sound/s_soundinternal.h @@ -398,6 +398,12 @@ public: FSoundID PickReplacement(FSoundID refid); void HashSounds(); void AddRandomSound(FSoundID Owner, TArray list); + + TArray& GetSounds() //We still need this for a short time... + { + return S_sfx; + } + }; diff --git a/source/common/engine/i_interface.h b/source/common/engine/i_interface.h index c391e21dc..48cd2b95d 100644 --- a/source/common/engine/i_interface.h +++ b/source/common/engine/i_interface.h @@ -46,6 +46,7 @@ struct SystemCallbacks void (*LanguageChanged)(const char*); bool (*OkForLocalization)(FTextureID, const char*); FConfigFile* (*GetConfig)(); + bool (*WantEscape)(); }; extern SystemCallbacks sysCallbacks; diff --git a/source/core/raze_sound.cpp b/source/core/raze_sound.cpp index 4adaa2a53..14875222f 100644 --- a/source/core/raze_sound.cpp +++ b/source/core/raze_sound.cpp @@ -124,7 +124,7 @@ FString NoiseDebug(SoundEngine *engine) (chan->ChanFlags & CHANF_LOOP) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, (chan->ChanFlags & CHANF_EVICTED) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, (chan->ChanFlags & CHANF_VIRTUAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, - GSnd->GetAudibility(chan), GSnd->GetPosition(chan), ((int)chan->OrgID)-1, engine->GetSounds()[chan->SoundID].name.GetChars(), chan->Source); + GSnd->GetAudibility(chan), GSnd->GetPosition(chan), ((int)chan->OrgID.index())-1, engine->GetSfx(chan->SoundID)->name.GetChars(), chan->Source); ch++; } out.AppendFormat("%d channels\n", ch); @@ -283,8 +283,8 @@ CCMD(playsound) { if (argv.argc() > 1) { - FSoundID id = argv[1]; - if (id == 0) + FSoundID id = S_FindSound(argv[1]); + if (id == NO_SOUND) { Printf("'%s' is not a sound\n", argv[1]); } @@ -306,7 +306,7 @@ CCMD(playsoundid) if (argv.argc() > 1) { FSoundID id = soundEngine->FindSoundByResID((int)strtol(argv[1], nullptr, 0)); - if (id == 0) + if (id == NO_SOUND) { Printf("'%s' is not a sound\n", argv[1]); } @@ -325,9 +325,9 @@ CCMD(playsoundid) CCMD(listsounds) { - auto& S_sfx = soundEngine->GetSounds(); - for (unsigned i = 0; i < S_sfx.Size(); i++) + for (unsigned i = 0; i < soundEngine->GetNumSounds(); i++) { - Printf("%4d: name = %s, resId = %d, lumpnum = %d\n", i, S_sfx[i].name.GetChars(), S_sfx[i].ResourceId, S_sfx[i].lumpnum); + auto sfx = soundEngine->GetSfx(FSoundID::fromInt(i)); + Printf("%4d: name = %s, resId = %d, lumpnum = %d\n", i, sfx->name.GetChars(), sfx->ResourceId, sfx->lumpnum); } } diff --git a/source/core/rts.cpp b/source/core/rts.cpp index 1754d990f..7756bab1c 100644 --- a/source/core/rts.cpp +++ b/source/core/rts.cpp @@ -57,7 +57,8 @@ struct FileLump struct LumpInfoInternal { - int32_t position, size, sid; + int32_t position, size; + FSoundID sid; }; //============= @@ -97,7 +98,7 @@ bool RTS_IsInitialized() LumpInfo.Resize(numlumps); for(int i = 0; i < numlumps; i++, li++) { - LumpInfo[i] = { LittleLong(li->position), LittleLong(li->size), -1 }; + LumpInfo[i] = { LittleLong(li->position), LittleLong(li->size), INVALID_SOUND }; if (unsigned(LumpInfo[i].position + LumpInfo[i].size) >= RTSFile.Size()) { LumpInfo[i].size = 0; // points to invalid data @@ -142,11 +143,11 @@ void *RTS_GetSound(int lump) return RTSFile.Data() + LumpInfo[lump].position; } -int RTS_GetSoundID(int lump) +FSoundID RTS_GetSoundID(int lump) { - if (!RTS_IsInitialized()) return -1; + if (!RTS_IsInitialized()) return INVALID_SOUND; lump++; - if ((unsigned)lump >= LumpInfo.Size()) return -1; - if (LumpInfo[lump].size <= 0) return -1; + if ((unsigned)lump >= LumpInfo.Size()) return INVALID_SOUND; + if (LumpInfo[lump].size <= 0) return INVALID_SOUND; return LumpInfo[lump].sid; } diff --git a/source/core/rts.h b/source/core/rts.h index 8ef937595..a0520049b 100644 --- a/source/core/rts.h +++ b/source/core/rts.h @@ -1,7 +1,8 @@ #pragma once +#include "s_soundinternal.h" void RTS_Init(const char *filename); bool RTS_IsInitialized(); int RTS_SoundLength(int lump); void *RTS_GetSound(int lump); -int RTS_GetSoundID(int lump); +FSoundID RTS_GetSoundID(int lump); diff --git a/source/core/zcc_compile_raze.cpp b/source/core/zcc_compile_raze.cpp index 9926cf312..1e8406ae1 100644 --- a/source/core/zcc_compile_raze.cpp +++ b/source/core/zcc_compile_raze.cpp @@ -464,7 +464,7 @@ void ZCCRazeCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt * } else if (f->Type == TypeSound) { - *(FSoundID*)addr = GetStringConst(ex, ctx); + *(FSoundID*)addr = S_FindSound(GetStringConst(ex, ctx)); } else if (f->Type == TypeColor && ex->ValueType == TypeString) // colors can also be specified as ints. { diff --git a/source/games/blood/src/aiunicult.cpp b/source/games/blood/src/aiunicult.cpp index 03b5ae704..6a69ca7d5 100644 --- a/source/games/blood/src/aiunicult.cpp +++ b/source/games/blood/src/aiunicult.cpp @@ -1293,7 +1293,7 @@ bool playGenDudeSound(DBloodActor* actor, int mode) int maxRetries = 5; while (maxRetries-- > 0) { int random = Random(rand); - if (!soundEngine->FindSoundByResID(sndId + random)) continue; + if (!soundEngine->FindSoundByResID(sndId + random).isvalid()) continue; sndId = sndId + random; break; } @@ -1302,7 +1302,7 @@ bool playGenDudeSound(DBloodActor* actor, int mode) if (maxRetries <= 0) { int maxSndId = sndId + rand; - while (sndId < maxSndId && !soundEngine->FindSoundByResID(sndId++)); + while (sndId < maxSndId && !soundEngine->FindSoundByResID(sndId++).isvalid()); } // let's check if there same sounds already played by other dudes diff --git a/source/games/blood/src/asound.cpp b/source/games/blood/src/asound.cpp index c68516bbe..1f9302f39 100644 --- a/source/games/blood/src/asound.cpp +++ b/source/games/blood/src/asound.cpp @@ -69,7 +69,7 @@ void ambProcess(PLAYER* pPlayer) AMB_CHANNEL *pChannel = ambChannels; for (int i = 0; i < nAmbChannels; i++, pChannel++) { - if (soundEngine->IsSourcePlayingSomething(SOURCE_Ambient, pChannel, CHAN_BODY, -1)) + if (soundEngine->IsSourcePlayingSomething(SOURCE_Ambient, pChannel, CHAN_BODY)) { if (pChannel->distance > 0) { @@ -102,7 +102,7 @@ void ambKillAll(void) for (int i = 0; i < nAmbChannels; i++, pChannel++) { soundEngine->StopSound(SOURCE_Ambient, pChannel, CHAN_BODY); - pChannel->soundID = 0; + pChannel->soundID = NO_SOUND; } nAmbChannels = 0; } @@ -137,7 +137,7 @@ void ambInit(void) int nSFX = actor->xspr.data3; auto snd = soundEngine->FindSoundByResID(nSFX); - if (!snd) { + if (!snd.isvalid()) { //I_Error("Missing sound #%d used in ambient sound generator %d\n", nSFX); viewSetSystemMessage("Missing sound #%d used in ambient sound generator #%d\n", nSFX, actor->GetIndex()); actPostSprite(actor, kStatDecoration); diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 3d5af8745..cc3b78641 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -8375,7 +8375,8 @@ DBloodActor* aiPatrolSearchTargets(DBloodActor* actor) for (int i = 0; i < kMaxPatrolFoundSounds; i++) { - patrolBonkles[i].snd = patrolBonkles[i].cur = 0; + patrolBonkles[i].snd = NO_SOUND; + patrolBonkles[i].cur = 0; patrolBonkles[i].max = ClipLow((gGameOptions.nDifficulty + 1) >> 1, 1); } @@ -8461,7 +8462,7 @@ DBloodActor* aiPatrolSearchTargets(DBloodActor* actor) if (nsDist > hearDistf) return false; - int sndnum = chan->OrgID; + auto sndnum = chan->OrgID; // N same sounds per single enemy for (int f = 0; f < sndCnt; f++) diff --git a/source/games/blood/src/nnexts.h b/source/games/blood/src/nnexts.h index 0634dd7e4..b28eb8169 100644 --- a/source/games/blood/src/nnexts.h +++ b/source/games/blood/src/nnexts.h @@ -249,7 +249,7 @@ struct TRCONDITION { struct PATROL_FOUND_SOUNDS { - int snd; + FSoundID snd; int max; int cur; diff --git a/source/games/blood/src/seq.cpp b/source/games/blood/src/seq.cpp index 67efe5c9b..5cdc66a6d 100644 --- a/source/games/blood/src/seq.cpp +++ b/source/games/blood/src/seq.cpp @@ -379,7 +379,7 @@ void SEQINST::Update() int sndId = surfSfxMove[surf][Random(2)]; auto snd = soundEngine->FindSoundByResID(sndId); - if (snd > 0) + if (snd.isvalid()) { auto udata = soundEngine->GetUserData(snd); int relVol = udata ? udata[2] : 255; diff --git a/source/games/blood/src/sfx.cpp b/source/games/blood/src/sfx.cpp index 8b4d8e3d2..f458d9497 100644 --- a/source/games/blood/src/sfx.cpp +++ b/source/games/blood/src/sfx.cpp @@ -170,7 +170,7 @@ void sfxPlay3DSound(const DVector3& pos, int soundId, sectortype* pSector) { if (!SoundEnabled() || soundId < 0) return; auto sid = soundEngine->FindSoundByResID(soundId); - if (sid == 0) return; + if (!sid.isvalid()) return; auto svec = GetSoundPos(pos); @@ -196,7 +196,7 @@ void sfxPlay3DSoundCP(DBloodActor* pActor, int soundId, int playchannel, int pla { if (!SoundEnabled() || soundId < 0 || !pActor) return; auto sid = soundEngine->FindSoundByResID(soundId); - if (sid == 0) return; + if (!sid.isvalid()) return; auto svec = GetSoundPos(pActor->spr.pos); diff --git a/source/games/blood/src/sound.cpp b/source/games/blood/src/sound.cpp index a8beb7185..61faa4d22 100644 --- a/source/games/blood/src/sound.cpp +++ b/source/games/blood/src/sound.cpp @@ -74,29 +74,29 @@ static void S_AddBloodSFX(int lumpnum) ByteSwapSFX(sfx); FStringf rawname("%s.raw", sfx->rawName); auto rawlump = fileSystem.FindFile(rawname); - int sfxnum; + FSoundID sfxnum; if (rawlump != -1) { - auto& S_sfx = soundEngine->GetSounds(); sfxnum = soundEngine->AddSoundLump(sfx->rawName, rawlump, 0, fileSystem.GetResourceId(lumpnum), 6); + auto soundfx = soundEngine->GetWritableSfx(sfxnum); if (sfx->format < 5 || sfx->format > 12) { // [0..4] + invalid formats - S_sfx[sfxnum].RawRate = 11025; + soundfx->RawRate = 11025; } else if (sfx->format < 9) { // [5..8] - S_sfx[sfxnum].RawRate = 22050; + soundfx->RawRate = 22050; } else { // [9..12] - S_sfx[sfxnum].RawRate = 44100; + soundfx->RawRate = 44100; } - S_sfx[sfxnum].bLoadRAW = true; - S_sfx[sfxnum].LoopStart = LittleLong(sfx->loopStart); + soundfx->bLoadRAW = true; + soundfx->LoopStart = LittleLong(sfx->loopStart); //S_sfx[sfxnum].Volume = sfx->relVol / 255.f; This cannot be done because this volume setting is optional. - S_sfx[sfxnum].UserData.Resize(3); - int* udata = (int*)S_sfx[sfxnum].UserData.Data(); + soundfx->UserData.Resize(3); + int* udata = (int*)soundfx->UserData.Data(); udata[0] = sfx->pitch; udata[1] = sfx->pitchRange; udata[2] = sfx->relVol; @@ -118,7 +118,7 @@ void sndInit(void) auto type = fileSystem.GetResourceType(i); if (!stricmp(type, "SFX")) { - if (soundEngine->FindSoundByResID(fileSystem.GetResourceId(i)) == 0) + if (soundEngine->FindSoundByResID(fileSystem.GetResourceId(i)) == NO_SOUND) S_AddBloodSFX(i); } else if (!stricmp(type, "WAV") || !stricmp(type, "OGG") || !stricmp(type, "FLAC") || !stricmp(type, "VOC")) @@ -146,14 +146,14 @@ int sndGetRate(int format) bool sndCheckPlaying(unsigned int nSound) { auto snd = soundEngine->FindSoundByResID(nSound); - return snd > 0 ? soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, snd) : false; + return snd.isvalid() ? soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, snd) : false; } void sndStopSample(unsigned int nSound) { auto snd = soundEngine->FindSoundByResID(nSound); - if (snd > 0) + if (snd.isvalid()) { soundEngine->StopSoundID(snd); } @@ -172,7 +172,7 @@ void sndStartSample(const char* pzSound, int nVolume, int nChannel) if (!strlen(pzSound)) return; auto snd = soundEngine->FindSound(pzSound); - if (snd > 0) + if (snd.isvalid()) { soundEngine->StartSound(SOURCE_None, nullptr, nullptr, nChannel + 1, 0, snd, nVolume / 255.f, ATTN_NONE); } @@ -184,7 +184,7 @@ void sndStartSample(unsigned int nSound, int nVolume, int nChannel, bool bLoop, return; if (nChannel >= 7) nChannel = -1; auto snd = soundEngine->FindSoundByResID(nSound); - if (snd > 0) + if (snd.isvalid()) { if (nVolume < 0) { diff --git a/source/games/duke/src/game_misc.cpp b/source/games/duke/src/game_misc.cpp index a85c4d319..a00c9c141 100644 --- a/source/games/duke/src/game_misc.cpp +++ b/source/games/duke/src/game_misc.cpp @@ -349,9 +349,9 @@ int startrts(int lumpNum, int localPlayer) RTS_IsInitialized() && rtsplaying == 0 && (snd_speech & (localPlayer ? 1 : 4))) { auto sid = RTS_GetSoundID(lumpNum - 1); - if (sid != -1) + if (sid.isvalid()) { - S_PlaySound(sid, CHAN_AUTO, CHANF_UI); + S_PlaySound(sid.index() - 1, CHAN_AUTO, CHANF_UI); rtsplaying = 7; return 1; } diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index 3b2bbd7f8..50ed8c411 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -111,8 +111,8 @@ public: if (schan != NULL && schan->SoundID == currentCommentarySound) { - UnloadSound(schan->SoundID); - currentCommentarySound = 0; + UnloadSound(schan->SoundID.index()); + currentCommentarySound = NO_SOUND; if (currentCommentarySprite) currentCommentarySprite->spr.picnum = DEVELOPERCOMMENTARY; I_SetRelativeVolume(1.0f); UnmuteSounds(); @@ -129,9 +129,9 @@ void S_InitSound() static int GetReplacementSound(int soundNum) { - if (wt_forcevoc && isWorldTour() && soundEngine->isValidSoundId(soundNum+1)) + if (wt_forcevoc && isWorldTour() && soundEngine->isValidSoundId(FSoundID::fromInt(soundNum+1))) { - auto const* snd = soundEngine->GetUserData(soundNum + 1); + auto const* snd = soundEngine->GetUserData(FSoundID::fromInt(soundNum + 1)); int sndx = snd[kWorldTourMapping]; if (sndx > 0) soundNum = sndx-1; } @@ -158,12 +158,10 @@ TArray DukeSoundEngine::ReadSound(int lumpnum) void S_CacheAllSounds(void) { - auto& sfx = soundEngine->GetSounds(); - int i = 0; - for(auto &snd : sfx) + for(unsigned i = 0; i < soundEngine->GetNumSounds(); i++) { - soundEngine->CacheSound(&snd); - if (((++i)&31) == 0) + soundEngine->CacheSound(FSoundID::fromInt(i)); + if ((i & 31) == 0) I_GetEvent(); } } @@ -176,7 +174,8 @@ void S_CacheAllSounds(void) static inline int S_GetPitch(int num) { - auto const* snd = soundEngine->GetUserData(num+1); + auto soundid = FSoundID::fromInt(num + 1); + auto const* snd = soundEngine->GetUserData(soundid); if (!snd) return 0; int const range = abs(snd[kPitchEnd] - snd[kPitchStart]); return (range == 0) ? snd[kPitchStart] : min(snd[kPitchStart], snd[kPitchEnd]) + rand() % range; @@ -189,8 +188,9 @@ float S_ConvertPitch(int lpitch) int S_GetUserFlags(int num) { - if (!soundEngine->isValidSoundId(num+1)) return 0; - auto const* snd = soundEngine->GetUserData(num + 1); + auto soundid = FSoundID::fromInt(num + 1); + if (!soundEngine->isValidSoundId(soundid)) return 0; + auto const* snd = soundEngine->GetUserData(soundid); if (!snd) return 0; return snd[kFlags]; } @@ -259,8 +259,9 @@ static int GetPositionInfo(DDukeActor* actor, int soundNum, sectortype* sect, // There's a lot of hackery going on here that could be mapped to rolloff and attenuation parameters. // However, ultimately rolloff would also just reposition the sound source so this can remain as it is. + auto soundid = FSoundID::fromInt(soundNum + 1); int orgsndist = 0, sndist = 0; - auto const* snd = soundEngine->GetUserData(soundNum + 1); + auto const* snd = soundEngine->GetUserData(soundid); int userflags = snd ? snd[kFlags] : 0; int dist_adjust = snd ? snd[kVolAdjust] : 0; @@ -317,7 +318,7 @@ void S_GetCamera(DVector3* c, DAngle* ca, sectortype** cs) if (ud.cameraactor == nullptr) { auto p = &ps[screenpeek]; - if (c) *c = p->pos; + if (c) *c = p->actor->spr.pos; if (cs) *cs = p->cursector; if (ca) *ca = p->angle.ang; } @@ -358,7 +359,7 @@ void DukeSoundEngine::CalcPosVel(int type, const void* source, const float pt[3] auto aactor = (DDukeActor*)source; if (aactor != nullptr) { - GetPositionInfo(aactor, chanSound - 1, camsect, campos, aactor->spr.pos, nullptr, pos); + GetPositionInfo(aactor, chanSound.index() - 1, camsect, campos, aactor->spr.pos, nullptr, pos); /* if (vel) // DN3D does not properly maintain this. { @@ -418,11 +419,13 @@ void GameInterface::UpdateSounds(void) int S_PlaySound3D(int sndnum, DDukeActor* actor, const DVector3& pos, int channel, EChanFlags flags) { + auto soundid = FSoundID::fromInt(sndnum + 1); auto const pl = &ps[myconnectindex]; - if (!soundEngine->isValidSoundId(sndnum+1) || !SoundEnabled() || actor == nullptr || !playrunning() || + if (!soundEngine->isValidSoundId(soundid) || !SoundEnabled() || actor == nullptr || !playrunning() || (pl->timebeforeexit > 0 && pl->timebeforeexit <= REALGAMETICSPERSEC * 3)) return -1; sndnum = GetReplacementSound(sndnum); + soundid = FSoundID::fromInt(sndnum + 1); int userflags = S_GetUserFlags(sndnum); if ((userflags & (SF_DTAG | SF_GLOBAL)) == SF_DTAG) @@ -437,7 +440,7 @@ int S_PlaySound3D(int sndnum, DDukeActor* actor, const DVector3& pos, int channe bool foundone = soundEngine->EnumerateChannels([&](FSoundChan* chan) { auto sid = chan->OrgID; - auto flags = S_GetUserFlags(sid - 1); + auto flags = S_GetUserFlags(sid.index() - 1); return !!(flags & SF_TALK); }); // don't play if any Duke talk sounds are already playing @@ -478,7 +481,7 @@ int S_PlaySound3D(int sndnum, DDukeActor* actor, const DVector3& pos, int channe pitch = -768; } - bool is_playing = soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, sndnum+1); + bool is_playing = soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundid); if (is_playing && !issoundcontroller(actor)) S_StopSound(sndnum, actor); @@ -498,9 +501,9 @@ int S_PlaySound3D(int sndnum, DDukeActor* actor, const DVector3& pos, int channe if (userflags & SF_LOOP) flags |= CHANF_LOOP; float vol = attenuation == ATTN_NONE ? 0.8f : 1.f; - if (currentCommentarySound != 0) vol *= 0.25f; - auto chan = soundEngine->StartSound(SOURCE_Actor, actor, &sndpos, CHAN_AUTO, flags, sndnum+1, vol, attenuation, nullptr, S_ConvertPitch(pitch)); - if (chan) chan->UserData = (currentCommentarySound != 0); + if (currentCommentarySound != NO_SOUND) vol *= 0.25f; + auto chan = soundEngine->StartSound(SOURCE_Actor, actor, &sndpos, CHAN_AUTO, flags, soundid, vol, attenuation, nullptr, S_ConvertPitch(pitch)); + if (chan) chan->UserData = (currentCommentarySound != NO_SOUND); return chan ? 0 : -1; } @@ -512,9 +515,11 @@ int S_PlaySound3D(int sndnum, DDukeActor* actor, const DVector3& pos, int channe int S_PlaySound(int sndnum, int channel, EChanFlags flags, float vol) { - if (!soundEngine->isValidSoundId(sndnum+1) || !SoundEnabled()) return -1; + auto soundid = FSoundID::fromInt(sndnum + 1); + if (!soundEngine->isValidSoundId(soundid) || !SoundEnabled()) return -1; sndnum = GetReplacementSound(sndnum); + soundid = FSoundID::fromInt(sndnum + 1); int userflags = S_GetUserFlags(sndnum); if ((!(snd_speech & 1) && (userflags & SF_TALK))) @@ -523,9 +528,9 @@ int S_PlaySound(int sndnum, int channel, EChanFlags flags, float vol) int const pitch = S_GetPitch(sndnum); if (userflags & SF_LOOP) flags |= CHANF_LOOP; - if (currentCommentarySound != 0) vol *= 0.25f; - auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, sndnum + 1, vol, ATTN_NONE, nullptr, S_ConvertPitch(pitch)); - if (chan) chan->UserData = (currentCommentarySound != 0); + if (currentCommentarySound != NO_SOUND) vol *= 0.25f; + auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, soundid, vol, ATTN_NONE, nullptr, S_ConvertPitch(pitch)); + if (chan) chan->UserData = (currentCommentarySound != NO_SOUND); return chan ? 0 : -1; } @@ -545,11 +550,12 @@ void S_StopSound(int sndNum, DDukeActor* actor, int channel) { sndNum = GetReplacementSound(sndNum); - if (!actor) soundEngine->StopSoundID(sndNum+1); + auto soundid = FSoundID::fromInt(sndNum + 1); + if (!actor) soundEngine->StopSoundID(soundid); else { - if (channel == -1) soundEngine->StopSound(SOURCE_Actor, actor, -1, sndNum + 1); - else soundEngine->StopSound(SOURCE_Actor, actor, channel, -1); + if (channel == -1) soundEngine->StopSound(SOURCE_Actor, actor, -1, soundid); + else soundEngine->StopSound(SOURCE_Actor, actor, channel); // StopSound kills the actor reference so this cannot be delayed until ChannelEnded gets called. At that point the actor may also not be valid anymore. if (S_IsAmbientSFX(actor) && actor->sector()->lotag < 3) // ST_2_UNDERWATER @@ -560,15 +566,16 @@ void S_StopSound(int sndNum, DDukeActor* actor, int channel) void S_ChangeSoundPitch(int soundNum, DDukeActor* actor, int pitchoffset) { soundNum = GetReplacementSound(soundNum); + auto soundid = FSoundID::fromInt(soundNum + 1); double expitch = pow(2, pitchoffset / 1200.); // I hope I got this right that ASS uses a linear scale where 1200 is a full octave. if (!actor) { - soundEngine->ChangeSoundPitch(SOURCE_Unattached, nullptr, CHAN_AUTO, expitch, soundNum+1); + soundEngine->ChangeSoundPitch(SOURCE_Unattached, nullptr, CHAN_AUTO, expitch, soundid); } else { - soundEngine->ChangeSoundPitch(SOURCE_Actor, actor, CHAN_AUTO, expitch, soundNum+1); + soundEngine->ChangeSoundPitch(SOURCE_Actor, actor, CHAN_AUTO, expitch, soundid); } } @@ -581,22 +588,24 @@ void S_ChangeSoundPitch(int soundNum, DDukeActor* actor, int pitchoffset) int S_CheckActorSoundPlaying(DDukeActor* actor, int soundNum, int channel) { soundNum = GetReplacementSound(soundNum); + auto soundid = FSoundID::fromInt(soundNum + 1); - if (actor == nullptr) return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundNum+1); - return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, actor, channel, soundNum+1); + if (actor == nullptr) return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundid); + return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, actor, channel, soundid); } // Check if actor is playing any sound. int S_CheckAnyActorSoundPlaying(DDukeActor* actor) { if (!actor) return false; - return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, actor, CHAN_AUTO, 0); + return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, actor, CHAN_AUTO); } int S_CheckSoundPlaying(int soundNum) { soundNum = GetReplacementSound(soundNum); - return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundNum+1); + auto soundid = FSoundID::fromInt(soundNum + 1); + return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundid); } //========================================================================== @@ -728,10 +737,11 @@ void S_WorldTourMappingsForOldSounds() // This tries to retrieve the original sounds for World Tour's often inferior replacements. // It's really ironic that despite their low quality they often sound a lot better than the new ones. if (!isWorldTour()) return; - auto &s_sfx = soundEngine->GetSounds(); - for(unsigned i = 1; i < s_sfx.Size(); i++) + unsigned maxsnd = soundEngine->GetNumSounds(); + for(unsigned i = 1; i < maxsnd; i++) { - auto fname = s_sfx[i].name; + auto sfx = soundEngine->GetSfx(FSoundID::fromInt(i)); + auto fname = sfx->name; if (!fname.Right(4).CompareNoCase(".ogg")) { // All names here follow the same convention. We must strip the "sound/" folder and replace the extension to get the original VOCs. @@ -741,11 +751,11 @@ void S_WorldTourMappingsForOldSounds() int lump = fileSystem.FindFile(fname); // in this case we absolutely do not want the extended lookup that's optionally performed by S_LookupSound. if (lump >= 0) { - s_sfx.Reserve(1); - s_sfx.Last() = s_sfx[i]; - s_sfx.Last().name = fname; - s_sfx.Last().lumpnum = lump; - s_sfx[i].UserData[kWorldTourMapping] = s_sfx.Size() - 1; + auto newsfx = soundEngine->AllocateSound(); + *newsfx = *sfx; + newsfx->name = fname; + newsfx->lumpnum = lump; + sfx->UserData[kWorldTourMapping] = soundEngine->GetNumSounds() - 1; } } } @@ -805,7 +815,7 @@ void S_ParseDeveloperCommentary() void StopCommentary() { - if (currentCommentarySound > 0) + if (currentCommentarySound.isvalid()) { soundEngine->StopSound(SOURCE_None, nullptr, CHAN_VOICE, currentCommentarySound); } @@ -816,7 +826,7 @@ bool StartCommentary(int tag, DDukeActor* actor) if (wt_commentary && Commentaries.Size() > (unsigned)tag && Commentaries[tag].IsNotEmpty()) { FSoundID id = soundEngine->FindSound(Commentaries[tag]); - if (id == 0) + if (!id.isvalid()) { int lump = fileSystem.FindFile(Commentaries[tag]); if (lump < 0) diff --git a/source/games/duke/src/sounds.h b/source/games/duke/src/sounds.h index 4e9ede57b..b6cd4226a 100644 --- a/source/games/duke/src/sounds.h +++ b/source/games/duke/src/sounds.h @@ -56,7 +56,7 @@ int S_GetUserFlags(int sndnum); inline bool S_IsSoundValid(int num) { - return (!soundEngine->isValidSoundId(num + 1)); + return (!soundEngine->isValidSoundId(FSoundID::fromInt(num + 1))); } diff --git a/source/games/exhumed/src/exhumed.cpp b/source/games/exhumed/src/exhumed.cpp index df51795fb..843e66e64 100644 --- a/source/games/exhumed/src/exhumed.cpp +++ b/source/games/exhumed/src/exhumed.cpp @@ -500,7 +500,7 @@ void GameInterface::Ticker() videoTintBlood(flash * 30, flash * 30, flash * 30); if (EndLevel == 1) { - if (!soundEngine->GetSoundPlayingInfo(SOURCE_None, nullptr, StaticSound[59] + 1)) + if (!soundEngine->GetSoundPlayingInfo(SOURCE_None, nullptr, FSoundID::fromInt(StaticSound[59] + 1))) { videoTintBlood(0, 0, 0); CompleteLevel(NextMap); diff --git a/source/games/exhumed/src/sound.cpp b/source/games/exhumed/src/sound.cpp index e2b412bfa..d05985aec 100644 --- a/source/games/exhumed/src/sound.cpp +++ b/source/games/exhumed/src/sound.cpp @@ -183,8 +183,8 @@ int LoadSound(const char* name) { char nname[9]{}; for (int i = 0; i < 8 && name[i]; i++) nname[i] = name[i]; - int sndid = soundEngine->FindSoundNoHash(nname); - if (sndid > 0) return sndid - 1; + FSoundID sndid = soundEngine->FindSoundNoHash(nname); + if (sndid.isvalid()) return sndid.index() - 1; FStringf filename("%s.voc", nname); auto lump = S_LookupSound(filename); @@ -197,10 +197,10 @@ int LoadSound(const char* name) // This game uses the actual loop point information in the sound data as its only means to check if a sound is looped. loops = true; } - int retval = soundEngine->AddSoundLump(nname, lump, 0, -1, 6); + FSoundID retval = soundEngine->AddSoundLump(nname, lump, 0, -1, 6); soundEngine->CacheSound(retval); - looped[retval-1] = loops; - return retval - 1; + looped[retval.index() - 1] = loops; + return retval.index() - 1; } else if (!isShareware()) // demo tries to load sound files it doesn't have { @@ -285,7 +285,8 @@ void BendAmbientSound(void) void PlayLocalSound(int nSound, int nRate, bool unattached, EChanFlags cflags) { if (!SoundEnabled()) return; - if (nSound < 0 || nSound >= kMaxSounds || !soundEngine->isValidSoundId(nSound + 1)) + auto soundid = FSoundID::fromInt(nSound + 1); + if (!soundEngine->isValidSoundId(soundid)) { Printf("PlayLocalSound: Invalid sound nSound == %i, nRate == %i\n", nSound, nRate); return; @@ -295,13 +296,13 @@ void PlayLocalSound(int nSound, int nRate, bool unattached, EChanFlags cflags) FSoundChan* chan; if (!unattached) { - if (!(cflags & CHANF_UI) && soundEngine->IsSourcePlayingSomething(SOURCE_None, nullptr, CHAN_BODY, nSound + 1)) return; + if (!(cflags & CHANF_UI) && soundEngine->IsSourcePlayingSomething(SOURCE_None, nullptr, CHAN_BODY, soundid)) return; soundEngine->StopSound(SOURCE_None, nullptr, CHAN_BODY); - chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, CHAN_BODY, cflags, nSound + 1, 1.f, ATTN_NONE, nullptr); + chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, CHAN_BODY, cflags, soundid, 1.f, ATTN_NONE, nullptr); } else { - chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, CHAN_VOICE, CHANF_OVERLAP|cflags, nSound + 1, 1.f, ATTN_NONE, nullptr); + chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, CHAN_VOICE, CHANF_OVERLAP|cflags, soundid, 1.f, ATTN_NONE, nullptr); } if (nRate && chan) @@ -359,7 +360,7 @@ void StartSwirly(int nActiveSound) nVolume = 220; soundEngine->StopSound(SOURCE_Swirly, &swirly, -1); - soundEngine->StartSound(SOURCE_Swirly, &swirly, nullptr, CHAN_BODY, CHANF_TRANSIENT, StaticSound[kSoundMana1]+1, nVolume / 255.f, ATTN_NONE, nullptr, nPitch / 11025.f); + soundEngine->StartSound(SOURCE_Swirly, &swirly, nullptr, CHAN_BODY, CHANF_TRANSIENT, FSoundID::fromInt(StaticSound[kSoundMana1]+1), nVolume / 255.f, ATTN_NONE, nullptr, nPitch / 11025.f); } //========================================================================== @@ -410,7 +411,7 @@ void SoundBigEntrance(void) int nPitch = 11025 + (i * 512 - 1200); //pASound->snd_pitch = nPitch; soundEngine->StopSound(SOURCE_EXBoss, &fakesources[i], -1); - soundEngine->StartSound(SOURCE_EXBoss, &fakesources[i], nullptr, CHAN_BODY, CHANF_TRANSIENT, StaticSound[kSoundTorchOn]+1, 200 / 255.f, ATTN_NONE, nullptr, nPitch / 11025.f); + soundEngine->StartSound(SOURCE_EXBoss, &fakesources[i], nullptr, CHAN_BODY, CHANF_TRANSIENT, FSoundID::fromInt(StaticSound[kSoundTorchOn]+1), 200 / 255.f, ATTN_NONE, nullptr, nPitch / 11025.f); } } @@ -551,7 +552,8 @@ void GameInterface::UpdateSounds() void PlayFX2(int nSound, DExhumedActor* pActor, int sectf, EChanFlags chanflags, int sprflags, const DVector3* soundpos) { if (!SoundEnabled()) return; - if ((nSound&0x1ff) >= kMaxSounds || !soundEngine->isValidSoundId((nSound & 0x1ff)+1)) + auto soundid = FSoundID::fromInt(nSound & 0x1ff); + if (!soundEngine->isValidSoundId(soundid)) { Printf("PlayFX2: Invalid sound nSound == %i\n", nSound); return; @@ -595,7 +597,7 @@ void PlayFX2(int nSound, DExhumedActor* pActor, int sectf, EChanFlags chanflags, { if (prio >= chan->UserData) { - if (chan->SoundID == nSound + 1) + if (chan->SoundID == soundid) { if (!allowMultiple && pActor == chan->Source) return 1; @@ -610,7 +612,7 @@ void PlayFX2(int nSound, DExhumedActor* pActor, int sectf, EChanFlags chanflags, } else if (chan->SourceType == SOURCE_Unattached && pActor != nullptr) { - if (chan->SoundID == nSound + 1) + if (chan->SoundID == soundid) { if (vv.X == chan->Point[0] && vv.Y == chan->Point[1] && vv.Z == chan->Point[2]) return 1; @@ -624,11 +626,11 @@ void PlayFX2(int nSound, DExhumedActor* pActor, int sectf, EChanFlags chanflags, FSoundChan* chan = nullptr; if (pActor != nullptr) { - chan = soundEngine->StartSound(SOURCE_Actor, pActor, nullptr, CHAN_BODY, chanflags| CHANF_OVERLAP, nSound+1, nVolume / 255.f,fullvol? 0.5f : ATTN_NORM, nullptr, (11025 + nPitch) / 11025.f); + chan = soundEngine->StartSound(SOURCE_Actor, pActor, nullptr, CHAN_BODY, chanflags| CHANF_OVERLAP, soundid, nVolume / 255.f,fullvol? 0.5f : ATTN_NORM, nullptr, (11025 + nPitch) / 11025.f); } else { - chan = soundEngine->StartSound(SOURCE_Unattached, nullptr, &vv, CHAN_BODY, chanflags | CHANF_OVERLAP, nSound+1, nVolume / 255.f, ATTN_NORM, nullptr, (11025 + nPitch) / 11025.f); + chan = soundEngine->StartSound(SOURCE_Unattached, nullptr, &vv, CHAN_BODY, chanflags | CHANF_OVERLAP, soundid, nVolume / 255.f, ATTN_NORM, nullptr, (11025 + nPitch) / 11025.f); } if (chan) { @@ -669,7 +671,7 @@ void CheckAmbience(sectortype* sect) { DVector3 v = { pWall->pos.X, pWall->pos.Y, pSector2->floorz }; amb = GetSoundPos(v); - soundEngine->StartSound(SOURCE_Ambient, &amb, nullptr, CHAN_BODY, CHANF_TRANSIENT, sect->Sound + 1, 1.f, ATTN_NORM); + soundEngine->StartSound(SOURCE_Ambient, &amb, nullptr, CHAN_BODY, CHANF_TRANSIENT, FSoundID::fromInt(sect->Sound + 1), 1.f, ATTN_NORM); return; } soundEngine->EnumerateChannels([=](FSoundChan* chan) @@ -727,7 +729,9 @@ void UpdateCreepySounds() auto sp = PlayerList[nLocalPlayer].pActor->spr.pos + adder; creepy = GetSoundPos(sp); - if ((vsi & 0x1ff) >= kMaxSounds || !soundEngine->isValidSoundId((vsi & 0x1ff) + 1)) + auto soundid = FSoundID::fromInt(vsi & 0x1ff); + + if (!soundEngine->isValidSoundId(soundid)) { return; } @@ -741,7 +745,7 @@ void UpdateCreepySounds() GetSpriteSoundPitch(&nVolume, &nPitch); soundEngine->StopSound(SOURCE_Ambient, &creepy, CHAN_BODY); - soundEngine->StartSound(SOURCE_Ambient, &creepy, nullptr, CHAN_BODY, CHANF_TRANSIENT, vsi + 1, nVolume / 255.f, ATTN_NONE, nullptr, (11025 + nPitch) / 11025.f); + soundEngine->StartSound(SOURCE_Ambient, &creepy, nullptr, CHAN_BODY, CHANF_TRANSIENT, soundid, nVolume / 255.f, ATTN_NONE, nullptr, (11025 + nPitch) / 11025.f); } } nCreepyTimer = kCreepyCount; @@ -801,7 +805,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Exhumed, StopLocalSound, StopLocalSound) DEFINE_ACTION_FUNCTION(_Exhumed, LocalSoundPlaying) { - ACTION_RETURN_BOOL(soundEngine->IsSourcePlayingSomething(SOURCE_None, nullptr, CHAN_AUTO, -1)); + ACTION_RETURN_BOOL(soundEngine->IsSourcePlayingSomething(SOURCE_None, nullptr, CHAN_AUTO)); } DEFINE_ACTION_FUNCTION(_Exhumed, PlayCDTrack) diff --git a/source/games/sw/src/sounds.cpp b/source/games/sw/src/sounds.cpp index 54fa3a3c7..6a88dc7d6 100644 --- a/source/games/sw/src/sounds.cpp +++ b/source/games/sw/src/sounds.cpp @@ -197,7 +197,7 @@ struct AmbientSound { DSWActor* spot; int ambIndex; - int vocIndex; + FSoundID vocIndex; int ChanFlags; int maxIndex; int curIndex; @@ -250,7 +250,7 @@ void InitAmbient(int num, DSWActor* actor) } return; } - auto vnum = ambarray[num].diginame; + auto vnum = FSoundID::fromInt(ambarray[num].diginame); if (!soundEngine->isValidSoundId(vnum)) { return; // linked sound does not exist. @@ -262,7 +262,7 @@ void InitAmbient(int num, DSWActor* actor) amb->vocIndex = vnum; amb->ChanFlags = CHANF_TRANSIENT; if (ambarray[num].ambient_flags & v3df_dontpan) amb->ChanFlags |= EChanFlags::FromInt(CHANEXF_DONTPAN); - if (voc[vnum].voc_flags & vf_loop) amb->ChanFlags |= CHANF_LOOP; + if (voc[vnum.index()].voc_flags & vf_loop) amb->ChanFlags |= CHANF_LOOP; amb->maxIndex = ambarray[num].maxtics; amb->curIndex = 0; amb->intermit = !!(ambarray[num].ambient_flags & v3df_intermit); @@ -296,7 +296,7 @@ static void RestartAmbient(AmbientSound* amb) { if (!SoundEnabled()) return; - auto& vp = voc[amb->vocIndex]; + auto& vp = voc[amb->vocIndex.index()]; auto rolloff = GetRolloff(vp.voc_distance); int pitch = 0; if (vp.pitch_hi <= vp.pitch_lo) pitch = vp.pitch_lo; @@ -348,7 +348,7 @@ static void DoTimedSound(AmbientSound* amb) int ambid = RandomizeAmbientSpecials(amb->ambIndex); if (ambid != -1) { - amb->vocIndex = ambarray[ambid].diginame; + amb->vocIndex = FSoundID::fromInt(ambarray[ambid].diginame); amb->maxIndex = StdRandomRange(ambarray[ambid].maxtics); } RestartAmbient(amb); @@ -369,9 +369,9 @@ static void UpdateAmbients() for (auto& amb : ambients) { auto spot = amb->spot; - auto sdist = SoundDist(spot->spr.pos, voc[amb->vocIndex].voc_distance); + auto sdist = SoundDist(spot->spr.pos, voc[amb->vocIndex.index()].voc_distance); - if (sdist < 255 && amb->vocIndex == DIGI_WHIPME) + if (sdist < 255 && amb->vocIndex.index() == DIGI_WHIPME) { PLAYER* pp = Player + screenpeek; if (!FAFcansee(spot->spr.pos, spot->sector(), pp->pos, pp->cursector)) @@ -569,7 +569,7 @@ void SWSoundEngine::CalcPosVel(int type, const void* source, const float pt[3], { // For unpanned sounds the volume must be set directly and the position taken from the listener. *pos = campos; - auto sdist = SoundDist(vPos, voc[chanSound].voc_distance); + auto sdist = SoundDist(vPos, voc[chanSound.index()].voc_distance); if (chan) SetVolume(chan, (255 - sdist) * (1 / 255.f)); } @@ -627,7 +627,7 @@ void GameInterface::UpdateSounds(void) int _PlaySound(int num, DSWActor* actor, PLAYER* pp, const DVector3* const ppos, int flags, int channel, EChanFlags cflags) { - if (Prediction || !SoundEnabled() || !soundEngine->isValidSoundId(num)) + if (Prediction || !SoundEnabled() || !soundEngine->isValidSoundId(FSoundID::fromInt(num))) return -1; auto sps = actor; @@ -681,7 +681,7 @@ int _PlaySound(int num, DSWActor* actor, PLAYER* pp, const DVector3* const ppos, auto rolloff = GetRolloff(vp->voc_distance); FVector3 spos = GetSoundPos(pos); - auto chan = soundEngine->StartSound(sourcetype, source, &spos, channel, cflags, num, 1.f, ATTN_NORM, &rolloff, S_ConvertPitch(pitch)); + auto chan = soundEngine->StartSound(sourcetype, source, &spos, channel, cflags, FSoundID::fromInt(num), 1.f, ATTN_NORM, &rolloff, S_ConvertPitch(pitch)); if (chan && sourcetype == SOURCE_Unattached) chan->Source = sps; // needed for sound termination. return 1; } @@ -697,7 +697,7 @@ void PlaySoundRTS(int rts_num) if (SoundEnabled() && RTS_IsInitialized() && snd_speech) { auto sid = RTS_GetSoundID(rts_num - 1); - if (sid != -1) + if (sid.isvalid()) { soundEngine->StartSound(SOURCE_Unattached, nullptr, nullptr, CHAN_VOICE, 0, sid, 0.8f, ATTN_NONE); } @@ -809,7 +809,7 @@ int _PlayerSound(int num, PLAYER* pp) return 0; } - if (num < 0 || num >= DIGI_MAX || !soundEngine->isValidSoundId(num) || !SoundEnabled()) + if (num < 0 || num >= DIGI_MAX || !soundEngine->isValidSoundId(FSoundID::fromInt(num)) || !SoundEnabled()) return 0; if (pp->Flags & (PF_DEAD)) return 0; // You're dead, no talking! @@ -826,7 +826,7 @@ int _PlayerSound(int num, PLAYER* pp) return 0; // The surfacing sound should not block other player speech. - if (soundEngine->IsSourcePlayingSomething(SOURCE_Player, pp, CHAN_VOICE, DIGI_SURFACE)) + if (soundEngine->IsSourcePlayingSomething(SOURCE_Player, pp, CHAN_VOICE, FSoundID::fromInt(DIGI_SURFACE))) { soundEngine->StopSound(SOURCE_Player, pp, CHAN_VOICE); } @@ -834,7 +834,7 @@ int _PlayerSound(int num, PLAYER* pp) // He wasn't talking, but he will be now. if (!soundEngine->IsSourcePlayingSomething(SOURCE_Player, pp, CHAN_VOICE)) { - soundEngine->StartSound(SOURCE_Player, pp, nullptr, CHAN_VOICE, 0, num, 1.f, ATTN_NORM); + soundEngine->StartSound(SOURCE_Player, pp, nullptr, CHAN_VOICE, 0, FSoundID::fromInt(num), 1.f, ATTN_NORM); } return 0; @@ -842,7 +842,7 @@ int _PlayerSound(int num, PLAYER* pp) void StopPlayerSound(PLAYER* pp, int which) { - soundEngine->StopSound(SOURCE_Player, pp, CHAN_VOICE, which); + soundEngine->StopSound(SOURCE_Player, pp, CHAN_VOICE, FSoundID::fromInt(which)); } bool SoundValidAndActive(DSWActor* spr, int channel)