diff --git a/source/core/music/s_advsound.cpp b/source/core/music/s_advsound.cpp index 4d81608ed..9e5229b61 100644 --- a/source/core/music/s_advsound.cpp +++ b/source/core/music/s_advsound.cpp @@ -60,7 +60,7 @@ enum SICommands SI_Limit, SI_Singular, SI_PitchSet, - SI_DukePitchRange, + SI_PitchSetDuke, SI_DukeFlags, }; @@ -93,7 +93,7 @@ static const char *SICommandStrings[] = "$limit", "$singular", "$pitchset", - "$dukepitchrange", + "$pitchsetduke", "$dukeflags", NULL }; @@ -315,6 +315,26 @@ static void S_AddSNDINFO (int lump) } break; + case SI_PitchSetDuke: { + // $pitchset [range maximum] + // Same as above, but uses Duke's value range of 1200 units per octave. + FSoundID sfx; + + sc.MustGetString(); + sfx = soundEngine->FindSoundTentative(sc.String); + sc.MustGetFloat(); + auto sfxp = soundEngine->GetWritableSfx(sfx); + sfxp->DefPitch = (float)pow(2, sc.Float / 1200.); + if (sc.CheckFloat()) + { + sfxp->DefPitchMax = (float)pow(2, sc.Float / 1200.); + } + else + { + sfxp->DefPitchMax = 0; + } + break; + } case SI_ConReserve: { // $conreserve @@ -328,34 +348,6 @@ static void S_AddSNDINFO (int lump) break; } - case SI_DukePitchRange: { - // dukesound - // Sets a pitch range for the sound. - sc.MustGetString(); - auto sfxid = soundEngine->FindSoundTentative(sc.String, DEFAULT_LIMIT); - sc.MustGetNumber(); - int minpitch = sc.Number; - sc.MustGetNumber(); - int maxpitch = sc.Number; - if (isDukeEngine()) - { - auto sfx = soundEngine->GetWritableSfx(sfxid); - if (sfx->UserData.Size() < Duke3d::kMaxUserData) - { - sfx->UserData.Resize(Duke3d::kMaxUserData); - memset(sfx->UserData.Data(), 0, Duke3d::kMaxUserData * sizeof(int)); - } - sfx->UserData[Duke3d::kPitchStart] = clamp(minpitch, INT16_MIN, INT16_MAX); - sfx->UserData[Duke3d::kPitchEnd] = clamp(maxpitch, INT16_MIN, INT16_MAX); - } - else - { - sc.ScriptMessage("'$dukepitchrange' is not available in the current game and will be ignored"); - } - break; - - } - case SI_DukeFlags: { static const char* dukeflags[] = { "LOOP", "MSFX", "TALK", "GLOBAL", nullptr}; diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index 547148e8f..5e2b7e884 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -174,19 +174,6 @@ void S_CacheAllSounds(void) // //========================================================================== -static inline int S_GetPitch(FSoundID soundid) -{ - 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; -} - -float S_ConvertPitch(int lpitch) -{ - return powf(2, lpitch / 1200.f); // I hope I got this right that ASS uses a linear scale where 1200 is a full octave. -} - int S_GetUserFlags(FSoundID soundid) { if (!soundEngine->isValidSoundId(soundid)) return 0; @@ -234,9 +221,6 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit // 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; @@ -261,13 +245,14 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit fn.Substitute(".ogg", ".voc"); sfx->lumpnum = S_LookupSound(fn); } - sndinf[kPitchStart] = clamp(minpitch, INT16_MIN, INT16_MAX); - sndinf[kPitchEnd] = clamp(maxpitch, INT16_MIN, INT16_MAX); - sndinf[kPriority] = priority & 255; + if (minpitch != 0 || maxpitch != 0) + { + sfx->DefPitch = (float)pow(2, clamp(minpitch, INT16_MIN, INT16_MAX) / 1200.); + sfx->DefPitchMax = (float)pow(2, clamp(maxpitch, INT16_MIN, INT16_MAX) / 1200.); + } 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->bTentative = false; return 0; } @@ -499,25 +484,20 @@ int S_PlaySound3D(FSoundID soundid, DDukeActor* actor, const DVector3& pos, int S_GetCamera(&campos, nullptr, &camsect); GetPositionInfo(actor, soundid, camsect, campos, pos, &sndist, &sndpos); - int pitch = S_GetPitch(soundid); auto sfx = soundEngine->GetSfx(soundid); bool explosion = ((userflags & (SF_GLOBAL | SF_DTAG)) == (SF_GLOBAL | SF_DTAG)) || ((sfx->ResourceId == PIPEBOMB_EXPLODE || sfx->ResourceId == LASERTRIP_EXPLODE || sfx->ResourceId == RPG_EXPLODE)); bool underwater = ps[screenpeek].insector() && ps[screenpeek].cursector->lotag == ST_2_UNDERWATER; - if (explosion) - { - if (underwater) - pitch -= 1024; - } - else + float pitch = 0; + if (!explosion) { if (sndist > 32767 && !issoundcontroller(actor) && (userflags & (SF_LOOP | SF_MSFX)) == 0) return -1; if (underwater && (userflags & SF_TALK) == 0) - pitch = -768; + pitch = 0.64f; } bool is_playing = soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundid); @@ -541,8 +521,16 @@ int S_PlaySound3D(FSoundID soundid, DDukeActor* actor, const DVector3& pos, int if (userflags & SF_LOOP) flags |= CHANF_LOOP; float vol = attenuation == ATTN_NONE ? 0.8f : 1.f; 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); + auto chan = soundEngine->StartSound(SOURCE_Actor, actor, &sndpos, CHAN_AUTO, flags, soundid, vol, attenuation, nullptr, pitch); + if (chan) + { + if (explosion && underwater) + { + pitch = chan->Pitch? chan->Pitch * (0.55 / 128) : 0.55; // todo: fix pitch storage in backend. + soundEngine->SetPitch(chan, pitch); + } + chan->UserData = (currentCommentarySound != NO_SOUND); + } return chan ? 0 : -1; } @@ -562,11 +550,9 @@ int S_PlaySound(FSoundID soundid, int channel, EChanFlags flags, float vol) if ((!(snd_speech & 1) && (userflags & SF_TALK))) return -1; - int const pitch = S_GetPitch(soundid); - if (userflags & SF_LOOP) flags |= CHANF_LOOP; 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)); + auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, soundid, vol, ATTN_NONE, nullptr); if (chan) chan->UserData = (currentCommentarySound != NO_SOUND); return chan ? 0 : -1; } diff --git a/source/games/duke/src/sounds.h b/source/games/duke/src/sounds.h index 97dd482f7..f9c25aaa9 100644 --- a/source/games/duke/src/sounds.h +++ b/source/games/duke/src/sounds.h @@ -26,10 +26,7 @@ enum { enum esound_t { - kPitchStart, - kPitchEnd, kVolAdjust, - kPriority, kFlags, kWorldTourMapping, kMaxUserData