diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 4c0f72b465..e019fc59d2 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,9 @@ +September 9, 2008 (Changes by Graf Zahl) +- Fixed: FMODSoundRenderer::StartSound3D must set the static variable pointing + to the rolloff information back to NULL when starting the sound fails. +- Fixed: Rolloff information was taken from the sfxinfo that contained the + actual sound data, not the one that was used for starting the sound. + September 7, 2008 (Changes by Graf Zahl) - Fixed: Chex Quest's Super Bootspork was missing the pickup message. - Added missing Strife automap colors for items and non-monsters. diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index c26ac7bfdb..84a9a95422 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -501,10 +501,10 @@ int S_AddSoundLump (const char *logicalname, int lump) newsfx.bUsed = false; newsfx.bSingular = false; newsfx.bTentative = false; - newsfx.RolloffType = ROLLOFF_Doom; newsfx.link = sfxinfo_t::NO_LINK; - newsfx.MinDistance = 0; - newsfx.MaxDistance = 0; + newsfx.Rolloff.RolloffType = ROLLOFF_Doom; + newsfx.Rolloff.MinDistance = 0; + newsfx.Rolloff.MaxDistance = 0; return (int)S_sfx.Push (newsfx); } @@ -1202,7 +1202,7 @@ static void S_AddSNDINFO (int lump) case SI_Rolloff: { // $rolloff *| [linear|log|custom] // Using * for the name makes it the default for sounds that don't specify otherwise. - float *min, *max; + FRolloffInfo *rolloff; int type; int sfx; @@ -1210,14 +1210,12 @@ static void S_AddSNDINFO (int lump) if (sc.Compare("*")) { sfx = -1; - min = &S_MinDistance; - max = &S_MaxDistanceOrRolloffFactor; + rolloff = &S_Rolloff; } else { sfx = S_FindSoundTentative(sc.String); - min = &S_sfx[sfx].MinDistance; - max = &S_sfx[sfx].MaxDistance; + rolloff = &S_sfx[sfx].Rolloff; } type = ROLLOFF_Doom; if (!sc.CheckFloat()) @@ -1225,15 +1223,15 @@ static void S_AddSNDINFO (int lump) sc.MustGetString(); if (sc.Compare("linear")) { - type = ROLLOFF_Linear; + rolloff->RolloffType = ROLLOFF_Linear; } else if (sc.Compare("log")) { - type = ROLLOFF_Log; + rolloff->RolloffType = ROLLOFF_Log; } else if (sc.Compare("custom")) { - type = ROLLOFF_Custom; + rolloff->RolloffType = ROLLOFF_Custom; } else { @@ -1241,17 +1239,9 @@ static void S_AddSNDINFO (int lump) } sc.MustGetFloat(); } - if (sfx < 0) - { - S_RolloffType = type; - } - else - { - S_sfx[sfx].RolloffType = type; - } - *min = sc.Float; + rolloff->MinDistance = sc.Float; sc.MustGetFloat(); - *max = sc.Float; + rolloff->MaxDistance = sc.Float; break; } diff --git a/src/s_sound.cpp b/src/s_sound.cpp index dc627c4b6e..da2877fd10 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -126,9 +126,7 @@ int sfx_empty; FSoundChan *Channels; FSoundChan *FreeChannels; -int S_RolloffType; -float S_MinDistance; -float S_MaxDistanceOrRolloffFactor; +FRolloffInfo S_Rolloff; BYTE *S_SoundCurve; int S_SoundCurveSize; @@ -812,6 +810,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO int pitch; FSoundChan *chan; FVector3 pos, vel; + FRolloffInfo *rolloff; if (sound_id <= 0 || volume <= 0) return NULL; @@ -858,6 +857,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO } sfx = &S_sfx[sound_id]; + rolloff = sfx->Rolloff.MinDistance == 0? &S_Rolloff : &sfx->Rolloff; // Scale volume according to SNDINFO data. volume = MIN(volume * sfx->Volume, 1.f); @@ -1005,7 +1005,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO { SoundListener listener; S_SetListener(listener, players[consoleplayer].camera); - chan = GSnd->StartSound3D (sfx, &listener, volume, attenuation, pitch, basepriority, pos, vel, channel, chanflags, NULL); + chan = GSnd->StartSound3D (sfx, &listener, volume, rolloff, attenuation, pitch, basepriority, pos, vel, channel, chanflags, NULL); } else { @@ -1093,7 +1093,7 @@ void S_RestartSound(FSoundChan *chan) SoundListener listener; S_SetListener(listener, players[consoleplayer].camera); - ochan = GSnd->StartSound3D(sfx, &listener, chan->Volume, chan->DistanceScale, chan->Pitch, + ochan = GSnd->StartSound3D(sfx, &listener, chan->Volume, chan->Rolloff, chan->DistanceScale, chan->Pitch, chan->Priority, pos, vel, chan->EntChannel, chan->ChanFlags, chan); } else diff --git a/src/s_sound.h b/src/s_sound.h index a4c8599622..717247ad69 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -27,6 +27,15 @@ class AActor; class FScanner; +// Default rolloff information. +struct FRolloffInfo +{ + int RolloffType; + float MinDistance; + union { float MaxDistance; float RolloffFactor; }; +}; + + // // SoundFX struct. // @@ -61,8 +70,7 @@ struct sfxinfo_t unsigned int link; enum { NO_LINK = 0xffffffff }; - float MinDistance; - union { float MaxDistance, RolloffFactor; }; + FRolloffInfo Rolloff; }; // Rolloff types @@ -158,10 +166,7 @@ public: FArchive &operator<<(FArchive &arc, FSoundID &sid); -// Default rolloff information. -extern int S_RolloffType; -extern float S_MinDistance; -extern float S_MaxDistanceOrRolloffFactor; +extern FRolloffInfo S_Rolloff; extern BYTE *S_SoundCurve; extern int S_SoundCurveSize; @@ -174,6 +179,7 @@ struct FSoundChan FSoundChan *NextChan; // Next channel in this list. FSoundChan **PrevChan; // Previous channel in this list. sfxinfo_t *SfxInfo; // Sound information. + FRolloffInfo *Rolloff; // Rolloff parameters (do not necessarily come from SfxInfo!) QWORD_UNION StartTime; // Sound start time in DSP clocks. FSoundID SoundID; // Sound ID of playing sound. FSoundID OrgID; // Sound ID of sound used to start this channel. diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 46b0dced29..f1ffdc6563 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -133,7 +133,7 @@ static bool ShowedBanner; // The rolloff callback is called during FMOD::Sound::play, so we need this // global variable to contain the sound info during that time for the // callback. -static sfxinfo_t *GSfxInfo; +static FRolloffInfo *GRolloff; static float GDistScale; // In the below lists, duplicate entries are for user selection. When @@ -1358,7 +1358,7 @@ FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch, freq = 0; } - GSfxInfo = sfx; + GRolloff = NULL; // Do 2D sounds need rolloff? result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx->data, true, &chan); if (FMOD_OK == result) { @@ -1398,7 +1398,8 @@ FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch, CVAR(Float, snd_3dspread, 180, 0) -FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *listener, float vol, float distscale, +FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *listener, float vol, + FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan) { @@ -1424,7 +1425,7 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *liste } // Play it. - GSfxInfo = sfx; + GRolloff = rolloff; GDistScale = distscale; // Experiments indicate that playSound will ignore priorities and always succeed @@ -1478,9 +1479,11 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *liste HandleChannelDelay(chan, reuse_chan, freq); chan->setPaused(false); FSoundChan *schan = CommonChannelSetup(chan, reuse_chan); + schan->Rolloff = rolloff; return schan; } + GRolloff = NULL; DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result); return 0; } @@ -1618,7 +1621,7 @@ FSoundChan *FMODSoundRenderer::CommonChannelSetup(FMOD::Channel *chan, FSoundCha } chan->setUserData(schan); chan->setCallback(FMOD_CHANNEL_CALLBACKTYPE_END, ChannelEndCallback, 0); - GSfxInfo = NULL; + GRolloff = NULL; return schan; } @@ -1906,24 +1909,9 @@ bool FMODSoundRenderer::LoadSound(sfxinfo_t *sfx) FMOD_MODE samplemode; FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), }; FMOD::Sound *sample; - int rolloff; - float mindist, maxdist; samplemode = FMOD_3D | FMOD_OPENMEMORY | FMOD_SOFTWARE; - if (sfx->MaxDistance == 0) - { - mindist = S_MinDistance; - maxdist = S_MaxDistanceOrRolloffFactor; - rolloff = S_RolloffType; - } - else - { - mindist = sfx->MinDistance; - maxdist = sfx->MaxDistance; - rolloff = sfx->RolloffType; - } - sfxdata = NULL; sample = NULL; @@ -2003,11 +1991,6 @@ bool FMODSoundRenderer::LoadSound(sfxinfo_t *sfx) if (sample != NULL) { - if (rolloff == ROLLOFF_Log) - { - maxdist = 10000.f; - } - sample->set3DMinMaxDistance(mindist, maxdist); sample->setUserData(sfx); } } @@ -2138,63 +2121,46 @@ float F_CALLBACK FMODSoundRenderer::RolloffCallback(FMOD_CHANNEL *channel, float { FMOD::Channel *chan = (FMOD::Channel *)channel; FSoundChan *schan; - // Defaults for Doom. - int type = ROLLOFF_Doom; - sfxinfo_t *sfx; - float min; - float max; - float factor; - float volume; + FRolloffInfo *rolloff; - type = S_RolloffType; - factor = S_MaxDistanceOrRolloffFactor; - min = S_MinDistance; - max = S_MaxDistanceOrRolloffFactor; - - if (GSfxInfo != NULL) + if (GRolloff != NULL) { - sfx = GSfxInfo; + rolloff = GRolloff; distance *= GDistScale; } else if (chan->getUserData((void **)&schan) == FMOD_OK && schan != NULL) { - sfx = schan->SfxInfo; + rolloff = schan->Rolloff; distance *= schan->DistanceScale; } else { return 0; } - if (sfx == NULL) + if (rolloff == NULL) { return 0; } - if (sfx->MaxDistance == 0) - { - type = sfx->RolloffType; - factor = sfx->RolloffFactor; - } - chan->get3DMinMaxDistance(&min, &max); - - if (distance <= min) + if (distance <= rolloff->MinDistance) { return 1; } - if (type == ROLLOFF_Log) + if (rolloff->RolloffType == ROLLOFF_Log) { // Logarithmic rolloff has no max distance where it goes silent. - return min / (min + factor * (distance - min)); + return rolloff->MinDistance / (rolloff->MinDistance + rolloff->RolloffFactor * (distance - rolloff->MinDistance)); } - if (distance >= max) + if (distance >= rolloff->MaxDistance) { return 0; } - volume = (max - distance) / (max - min); - if (type == ROLLOFF_Custom && S_SoundCurve != NULL) + + float volume = (rolloff->MaxDistance - distance) / (rolloff->MaxDistance - rolloff->MinDistance); + if (rolloff->RolloffType == ROLLOFF_Custom && S_SoundCurve != NULL) { volume = S_SoundCurve[int(S_SoundCurveSize * (1 - volume))] / 127.f; } - if (type == ROLLOFF_Linear) + if (rolloff->RolloffType == ROLLOFF_Linear) { return volume; } diff --git a/src/sound/fmodsound.h b/src/sound/fmodsound.h index 9922faa867..dc0b528b6a 100644 --- a/src/sound/fmodsound.h +++ b/src/sound/fmodsound.h @@ -26,7 +26,7 @@ public: // Starts a sound. FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan); - FSoundChan *StartSound3D (sfxinfo_t *sfx, SoundListener *listener, float vol, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan); + FSoundChan *StartSound3D (sfxinfo_t *sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan); // Stops a sound channel. void StopSound (FSoundChan *chan); diff --git a/src/sound/i_sound.cpp b/src/sound/i_sound.cpp index 5ea1ae430a..5628b00219 100644 --- a/src/sound/i_sound.cpp +++ b/src/sound/i_sound.cpp @@ -149,7 +149,7 @@ public: { return NULL; } - FSoundChan *StartSound3D (sfxinfo_t *sfx, SoundListener *listener, float vol, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan) + FSoundChan *StartSound3D (sfxinfo_t *sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan) { return NULL; } diff --git a/src/sound/i_sound.h b/src/sound/i_sound.h index 0eae448bcc..2d6308cf80 100644 --- a/src/sound/i_sound.h +++ b/src/sound/i_sound.h @@ -102,7 +102,7 @@ public: // Starts a sound. virtual FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan) = 0; - virtual FSoundChan *StartSound3D (sfxinfo_t *sfx, SoundListener *listener, float vol, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan) = 0; + virtual FSoundChan *StartSound3D (sfxinfo_t *sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan) = 0; // Stops a sound channel. virtual void StopSound (FSoundChan *chan) = 0;