- continued refactoring on sound code.

The game independent part of the code has been mostly isolated.
This commit is contained in:
Christoph Oelckers 2019-12-08 21:22:53 +01:00
parent fd181f469d
commit b9582cc98e
22 changed files with 1545 additions and 1331 deletions

View file

@ -208,9 +208,7 @@ extern bool ParsingKeyConf, UnsafeExecutionContext;
void ResetButtonTriggers (); // Call ResetTriggers for all buttons
void ResetButtonStates (); // Same as above, but also clear bDown
extern unsigned int MakeKey (const char *s);
extern unsigned int MakeKey (const char *s, size_t len);
extern unsigned int SuperFastHash (const char *data, size_t len);
#include "superfasthash.h"
void execLogfile(const char *fn, bool append = false);

View file

@ -364,7 +364,7 @@ static FSoundID T_FindSound(const char * name)
}
int id = S_AddSound(name, buffer);
S_HashSounds();
soundEngine->HashSounds();
return FSoundID(id);
}

View file

@ -4387,11 +4387,11 @@ int DLevelScript::GetActorProperty (int tid, int property)
return 0;
}
case APROP_SeeSound: return GlobalACSStrings.AddString(actor->SeeSound);
case APROP_AttackSound: return GlobalACSStrings.AddString(actor->AttackSound);
case APROP_PainSound: return GlobalACSStrings.AddString(actor->PainSound);
case APROP_DeathSound: return GlobalACSStrings.AddString(actor->DeathSound);
case APROP_ActiveSound: return GlobalACSStrings.AddString(actor->ActiveSound);
case APROP_SeeSound: return GlobalACSStrings.AddString(S_GetSoundName(actor->SeeSound));
case APROP_AttackSound: return GlobalACSStrings.AddString(S_GetSoundName(actor->AttackSound));
case APROP_PainSound: return GlobalACSStrings.AddString(S_GetSoundName(actor->PainSound));
case APROP_DeathSound: return GlobalACSStrings.AddString(S_GetSoundName(actor->DeathSound));
case APROP_ActiveSound: return GlobalACSStrings.AddString(S_GetSoundName(actor->ActiveSound));
case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies());
case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag());
case APROP_StencilColor:return actor->fillcolor;
@ -4464,11 +4464,11 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value)
// Strings are covered by GetActorProperty, but they're fairly
// heavy-duty, so make the check here.
case APROP_SeeSound: string = actor->SeeSound; break;
case APROP_AttackSound: string = actor->AttackSound; break;
case APROP_PainSound: string = actor->PainSound; break;
case APROP_DeathSound: string = actor->DeathSound; break;
case APROP_ActiveSound: string = actor->ActiveSound; break;
case APROP_SeeSound: string = S_GetSoundName(actor->SeeSound); break;
case APROP_AttackSound: string = S_GetSoundName(actor->AttackSound); break;
case APROP_PainSound: string = S_GetSoundName(actor->PainSound); break;
case APROP_DeathSound: string = S_GetSoundName(actor->DeathSound); break;
case APROP_ActiveSound: string = S_GetSoundName(actor->ActiveSound); break;
case APROP_Species: string = actor->GetSpecies(); break;
case APROP_NameTag: string = actor->GetTag(); break;
case APROP_DamageType: string = actor->DamageType; break;
@ -5265,7 +5265,7 @@ int DLevelScript::SwapActorTeleFog(AActor *activator, int tid)
}
else if (rettype == TypeSound)
{
retval = GlobalACSStrings.AddString(FSoundID(retval));
retval = GlobalACSStrings.AddString(S_GetSoundName(FSoundID(retval)));
}
}
else if (rettype == TypeFloat64)

View file

@ -731,7 +731,7 @@ void R_InitSkins (void)
}
else
{
int sndref = S_FindSoundNoHash (key);
int sndref = soundEngine->FindSoundNoHash (key);
if (sndref != 0)
{
S_AddPlayerSound (Skins[i].Name, Skins[i].gender, sndref, lump, true);
@ -911,7 +911,7 @@ void R_InitSkins (void)
if (Skins.Size() > PlayerClasses.Size ())
{ // The sound table may have changed, so rehash it.
S_HashSounds ();
soundEngine->HashSounds ();
S_ShrinkPlayerSoundLists ();
}
}

View file

@ -1243,7 +1243,7 @@ FxExpression *FxStringCast::Resolve(FCompileContext &ctx)
if (basex->isConstant())
{
ExpVal constval = static_cast<FxConstant *>(basex)->GetValue();
FxExpression *x = new FxConstant(S_sfx[constval.GetInt()].name, ScriptPosition);
FxExpression *x = new FxConstant(S_GetSoundName(constval.GetInt()), ScriptPosition);
delete this;
return x;
}

View file

@ -1184,7 +1184,7 @@ PSound::PSound()
void PSound::WriteValue(FSerializer &ar, const char *key,const void *addr) const
{
const char *cptr = *(const FSoundID *)addr;
const char *cptr = S_GetSoundName(*(const FSoundID *)addr);
ar.StringPtr(key, cptr);
}

View file

@ -51,7 +51,7 @@ static void CastN2S(FString *a, int b) { FName name = FName(ENamedName(b)); *a =
static int CastS2Co(FString *b) { return V_GetColor(nullptr, *b); }
static void CastCo2S(FString *a, int b) { PalEntry c(b); a->Format("%02x %02x %02x", c.r, c.g, c.b); }
static int CastS2So(FString *b) { return FSoundID(*b); }
static void CastSo2S(FString *a, int b) { *a = S_sfx[b].name; }
static void CastSo2S(FString* a, int b) { *a = S_GetSoundName(b); }
static void CastSID2S(FString *a, unsigned int b) { *a = (b >= sprites.Size()) ? "TNT1" : sprites[b].name; }
static void CastTID2S(FString *a, int b) { auto tex = TexMan.GetTexture(*(FTextureID*)&b); *a = (tex == nullptr) ? "(null)" : tex->GetName().GetChars(); }

View file

@ -1837,7 +1837,7 @@ static void DoCast(const VMRegisters &reg, const VMFrame *f, int a, int b, int c
case CAST_So2S:
ASSERTS(a); ASSERTD(b);
reg.s[a] = S_sfx[reg.d[b]].name;
reg.s[a] = S_GetSoundName(reg.d[b]);
break;
case CAST_SID2S:

View file

@ -1663,7 +1663,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundI
if (!arc.w->inObject() || def == nullptr || sid != *def)
{
arc.WriteKey(key);
const char *sn = (const char*)sid;
const char *sn = S_GetSoundName(sid);
if (sn != nullptr) arc.w->String(sn);
else arc.w->Null();
}

View file

@ -35,8 +35,6 @@
#include <stdio.h>
#include <stdlib.h>
#include "doomtype.h"
#include "oalsound.h"
#include "i_module.h"
@ -52,6 +50,7 @@
#include "s_music.h"
#include "zmusic/zmusic.h"
EXTERN_CVAR (Float, snd_sfxvolume)
EXTERN_CVAR (Float, snd_musicvolume)
CVAR (Int, snd_samplerate, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
@ -300,8 +299,8 @@ void I_InitSound ()
void I_CloseSound ()
{
// Free all loaded samples
S_UnloadAllSounds();
// Free all loaded samples. Beware that the sound engine may already have been deleted.
if (soundEngine) soundEngine->UnloadAllSounds();
delete GSnd;
GSnd = NULL;

View file

@ -174,11 +174,7 @@ extern bool nosfx;
extern bool nosound;
void I_InitSound ();
void S_ChannelEnded(FISoundChannel *schan);
void S_ChannelVirtualChanged(FISoundChannel *schan, bool is_virtual);
float S_GetRolloff(FRolloffInfo *rolloff, float distance, bool logarithmic);
FISoundChannel *S_GetChannel(void *syschan);
void I_CloseSound();
extern ReverbContainer *DefaultEnvironments[26];

View file

@ -122,4 +122,5 @@ class SoundStream;
#endif

View file

@ -544,22 +544,7 @@ static size_t GetChannelCount(ChannelConfig chans)
static float GetRolloff(const FRolloffInfo *rolloff, float distance)
{
if(distance <= rolloff->MinDistance)
return 1.f;
// Logarithmic rolloff has no max distance where it goes silent.
if(rolloff->RolloffType == ROLLOFF_Log)
return rolloff->MinDistance /
(rolloff->MinDistance + rolloff->RolloffFactor*(distance-rolloff->MinDistance));
if(distance >= rolloff->MaxDistance)
return 0.f;
float volume = (rolloff->MaxDistance - distance) / (rolloff->MaxDistance - rolloff->MinDistance);
if(rolloff->RolloffType == ROLLOFF_Linear)
return volume;
if(rolloff->RolloffType == ROLLOFF_Custom && S_SoundCurve.Size() > 0)
return S_SoundCurve[int(S_SoundCurve.Size() * (1.f - volume))] / 127.f;
return (powf(10.f, volume) - 1.f) / 9.f;
return soundEngine->GetRolloff(rolloff, distance);
}
ALCdevice *OpenALSoundRenderer::InitDevice()
@ -983,7 +968,7 @@ void OpenALSoundRenderer::SetSfxVolume(float volume)
{
SfxVolume = volume;
FSoundChan *schan = Channels;
FSoundChan *schan = soundEngine->GetChannels();
while(schan)
{
if(schan->SysChannel != NULL)
@ -1359,7 +1344,7 @@ void OpenALSoundRenderer::UnloadSound(SoundHandle sfx)
return;
ALuint buffer = GET_PTRID(sfx.data);
FSoundChan *schan = Channels;
FSoundChan *schan = soundEngine->GetChannels();
while(schan)
{
if(schan->SysChannel)
@ -1495,7 +1480,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
FreeSfx.Pop();
FISoundChannel *chan = reuse_chan;
if(!chan) chan = S_GetChannel(MAKE_PTRID(source));
if(!chan) chan = soundEngine->GetChannel(MAKE_PTRID(source));
else chan->SysChannel = MAKE_PTRID(source);
chan->Rolloff.RolloffType = ROLLOFF_Log;
@ -1706,7 +1691,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
FreeSfx.Pop();
FISoundChannel *chan = reuse_chan;
if(!chan) chan = S_GetChannel(MAKE_PTRID(source));
if(!chan) chan = soundEngine->GetChannel(MAKE_PTRID(source));
else chan->SysChannel = MAKE_PTRID(source);
chan->Rolloff = *rolloff;
@ -1765,7 +1750,7 @@ void OpenALSoundRenderer::StopChannel(FISoundChannel *chan)
ALuint source = GET_PTRID(chan->SysChannel);
// Release first, so it can be properly marked as evicted if it's being killed
S_ChannelEnded(chan);
soundEngine->ChannelEnded(chan);
ALint state = AL_INITIAL;
alGetSourcei(source, AL_SOURCE_STATE, &state);
@ -1789,7 +1774,7 @@ void OpenALSoundRenderer::ForceStopChannel(FISoundChannel *chan)
ALuint source = GET_PTRID(chan->SysChannel);
if(!source) return;
S_ChannelEnded(chan);
soundEngine->ChannelEnded(chan);
FreeSource(source);
}
@ -2009,7 +1994,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
alFilterf(EnvFilters[1], AL_LOWPASS_GAINHF, 1.f);
// Apply the updated filters on the sources
FSoundChan *schan = Channels;
FSoundChan *schan = soundEngine->GetChannels();
while (schan)
{
ALuint source = GET_PTRID(schan->SysChannel);
@ -2022,7 +2007,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
}
}
FSoundChan *schan = Channels;
FSoundChan *schan = soundEngine->GetChannels();
while (schan)
{
ALuint source = GET_PTRID(schan->SysChannel);
@ -2047,7 +2032,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
alFilterf(EnvFilters[1], AL_LOWPASS_GAIN, 1.f);
alFilterf(EnvFilters[1], AL_LOWPASS_GAINHF, 1.f);
FSoundChan *schan = Channels;
FSoundChan *schan = soundEngine->GetChannels();
while (schan)
{
ALuint source = GET_PTRID(schan->SysChannel);
@ -2060,7 +2045,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
}
}
FSoundChan *schan = Channels;
FSoundChan *schan = soundEngine->GetChannels();
while (schan)
{
ALuint source = GET_PTRID(schan->SysChannel);
@ -2236,7 +2221,7 @@ void OpenALSoundRenderer::PurgeStoppedSources()
if(state == AL_INITIAL || state == AL_PLAYING || state == AL_PAUSED)
continue;
FSoundChan *schan = Channels;
FSoundChan *schan = soundEngine->GetChannels();
while(schan)
{
if(schan->SysChannel != NULL && src == GET_PTRID(schan->SysChannel))
@ -2358,7 +2343,7 @@ void OpenALSoundRenderer::LoadReverb(const ReverbContainer *env)
FSoundChan *OpenALSoundRenderer::FindLowestChannel()
{
FSoundChan *schan = Channels;
FSoundChan *schan = soundEngine->GetChannels();
FSoundChan *lowest = NULL;
while(schan)
{

View file

@ -61,12 +61,6 @@
// TYPES -------------------------------------------------------------------
struct FRandomSoundList
{
TArray<uint32_t> Choices;
uint32_t Owner = 0;
};
struct FPlayerClassLookup
{
FString Name;
@ -200,11 +194,9 @@ static int S_AddSound (const char *logicalname, int lumpnum, FScanner *sc=NULL);
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
extern int sfx_empty;
// PUBLIC DATA DEFINITIONS -------------------------------------------------
TArray<sfxinfo_t> S_sfx (128);
//TArray<sfxinfo_t> S_sfx (128);
TMap<int, FString> HexenMusic;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
@ -239,7 +231,6 @@ static const char *SICommandStrings[] =
NULL
};
static TArray<FRandomSoundList> S_rnd;
static FMusicVolume *MusicVolumes;
static TArray<FSavedPlayerSoundInfo> SavedPlayerSounds;
@ -255,8 +246,6 @@ static int DefPlayerClass;
static uint8_t CurrentPitchMask;
static FRandom pr_randsound ("RandSound");
// CODE --------------------------------------------------------------------
//==========================================================================
@ -281,36 +270,6 @@ float S_GetMusicVolume (const char *music)
return 1.f;
}
//==========================================================================
//
// S_HashSounds
//
// Fills in the next and index fields of S_sfx to form a working hash table.
//==========================================================================
void S_HashSounds ()
{
unsigned int i;
unsigned int j;
unsigned int size;
S_sfx.ShrinkToFit ();
size = S_sfx.Size ();
// Mark all buckets as empty
for (i = 0; i < size; i++)
S_sfx[i].index = 0;
// Now set up the chains
for (i = 1; i < size; i++)
{
j = MakeKey (S_sfx[i].name) % size;
S_sfx[i].next = S_sfx[j].index;
S_sfx[j].index = i;
}
}
//==========================================================================
//
// S_CheckIntegrity
@ -320,6 +279,7 @@ void S_HashSounds ()
static bool S_CheckSound(sfxinfo_t *startsfx, sfxinfo_t *sfx, TArray<sfxinfo_t *> &chain)
{
auto &S_sfx = soundEngine->GetSounds();
sfxinfo_t *me = sfx;
bool success = true;
unsigned siz = chain.Size();
@ -339,7 +299,7 @@ static bool S_CheckSound(sfxinfo_t *startsfx, sfxinfo_t *sfx, TArray<sfxinfo_t *
if (me->bRandomHeader)
{
const FRandomSoundList *list = &S_rnd[me->link];
const FRandomSoundList* list = soundEngine->ResolveRandomSound(me);
for (unsigned i = 0; i < list->Choices.Size(); ++i)
{
auto rsfx = &S_sfx[list->Choices[i]];
@ -385,6 +345,7 @@ void S_CheckIntegrity()
TArray<sfxinfo_t *> chain;
TArray<bool> broken;
auto &S_sfx = soundEngine->GetSounds();
broken.Resize(S_sfx.Size());
memset(&broken[0], 0, sizeof(bool)*S_sfx.Size());
for (unsigned i = 0; i < S_sfx.Size(); i++)
@ -404,34 +365,18 @@ void S_CheckIntegrity()
}
}
//==========================================================================
//
// S_PickReplacement
//
// Picks a replacement sound from the associated random list. If this sound
// is not the head of a random list, then the sound passed is returned.
//==========================================================================
int S_PickReplacement(int refid)
{
while (S_sfx[refid].bRandomHeader)
{
const FRandomSoundList *list = &S_rnd[S_sfx[refid].link];
refid = list->Choices[pr_randsound(list->Choices.Size())];
}
return refid;
}
//==========================================================================
//
// S_GetSoundMSLength
//
// Returns duration of sound
// This cannot be made a sound engine function due to the player sounds.
//
//==========================================================================
unsigned int S_GetMSLength(FSoundID sound)
{
auto &S_sfx = soundEngine->GetSounds();
if ((unsigned int)sound >= S_sfx.Size())
{
return 0;
@ -453,7 +398,7 @@ unsigned int S_GetMSLength(FSoundID sound)
// I think the longest one makes more sense.
int length = 0;
const FRandomSoundList *list = &S_rnd[sfx->link];
const FRandomSoundList* list = soundEngine->ResolveRandomSound(sfx);
for (auto &me : list->Choices)
{
@ -469,7 +414,7 @@ unsigned int S_GetMSLength(FSoundID sound)
}
}
sfx = S_LoadSound(sfx);
sfx = soundEngine->LoadSound(sfx, nullptr);
if (sfx != NULL) return GSnd->GetMSLength(sfx->data);
else return 0;
}
@ -481,157 +426,6 @@ DEFINE_ACTION_FUNCTION(DObject,S_GetLength)
ACTION_RETURN_FLOAT(S_GetMSLength(sound_id)/1000.0);
}
//==========================================================================
//
// S_CacheRandomSound
//
// Loads all sounds a random sound might play.
//
//==========================================================================
void S_CacheRandomSound (sfxinfo_t *sfx)
{
if (sfx->bRandomHeader)
{
const FRandomSoundList *list = &S_rnd[sfx->link];
for (unsigned i = 0; i < list->Choices.Size(); ++i)
{
sfx = &S_sfx[list->Choices[i]];
sfx->bUsed = true;
S_CacheSound (&S_sfx[list->Choices[i]]);
}
}
}
//==========================================================================
//
// S_FindSound
//
// Given a logical name, find the sound's index in S_sfx.
//==========================================================================
int S_FindSound (const char *logicalname)
{
int i;
if (logicalname != NULL)
{
i = S_sfx[MakeKey (logicalname) % S_sfx.Size ()].index;
while ((i != 0) && stricmp (S_sfx[i].name, logicalname))
i = S_sfx[i].next;
return i;
}
else
{
return 0;
}
}
//==========================================================================
//
// S_FindSoundNoHash
//
// Given a logical name, find the sound's index in S_sfx without
// using the hash table.
//==========================================================================
int S_FindSoundNoHash (const char *logicalname)
{
unsigned int i;
for (i = 1; i < S_sfx.Size (); i++)
{
if (stricmp (S_sfx[i].name, logicalname) == 0)
{
return i;
}
}
return 0;
}
//==========================================================================
//
// S_FindSoundByLump
//
// Given a sound lump, find the sound's index in S_sfx.
//==========================================================================
int S_FindSoundByLump (int lump)
{
if (lump != -1)
{
unsigned int i;
for (i = 1; i < S_sfx.Size (); i++)
if (S_sfx[i].lumpnum == lump)
return i;
}
return 0;
}
//==========================================================================
//
// S_AddSoundLump
//
// Adds a new sound mapping to S_sfx.
//==========================================================================
int S_AddSoundLump (const char *logicalname, int lump)
{
sfxinfo_t newsfx;
newsfx.data.Clear();
newsfx.data3d.Clear();
newsfx.name = logicalname;
newsfx.lumpnum = lump;
newsfx.next = 0;
newsfx.index = 0;
newsfx.Volume = 1;
newsfx.Attenuation = 1;
newsfx.PitchMask = CurrentPitchMask;
newsfx.NearLimit = 2;
newsfx.LimitRange = 256*256;
newsfx.bRandomHeader = false;
newsfx.bPlayerReserve = false;
newsfx.bLoadRAW = false;
newsfx.bPlayerCompat = false;
newsfx.b16bit = false;
newsfx.bUsed = false;
newsfx.bSingular = false;
newsfx.bTentative = false;
newsfx.bPlayerSilent = false;
newsfx.RawRate = 0;
newsfx.link = sfxinfo_t::NO_LINK;
newsfx.Rolloff.RolloffType = ROLLOFF_Doom;
newsfx.Rolloff.MinDistance = 0;
newsfx.Rolloff.MaxDistance = 0;
newsfx.LoopStart = -1;
return (int)S_sfx.Push (newsfx);
}
//==========================================================================
//
// S_FindSoundTentative
//
// Given a logical name, find the sound's index in S_sfx without
// using the hash table. If it does not exist, a new sound without
// an associated lump is created.
//==========================================================================
int S_FindSoundTentative (const char *name)
{
int id = S_FindSoundNoHash (name);
if (id == 0)
{
id = S_AddSoundLump (name, -1);
S_sfx[id].bTentative = true;
}
return id;
}
//==========================================================================
//
// S_AddSound
@ -648,9 +442,10 @@ int S_AddSound (const char *logicalname, const char *lumpname, FScanner *sc)
static int S_AddSound (const char *logicalname, int lumpnum, FScanner *sc)
{
auto &S_sfx = soundEngine->GetSounds();
int sfxid;
sfxid = S_FindSoundNoHash (logicalname);
sfxid = soundEngine->FindSoundNoHash (logicalname);
if (sfxid > 0)
{ // If the sound has already been defined, change the old definition
@ -674,7 +469,7 @@ static int S_AddSound (const char *logicalname, int lumpnum, FScanner *sc)
}
if (sfx->bRandomHeader)
{
FRandomSoundList *rnd = &S_rnd[sfx->link];
FRandomSoundList* rnd = soundEngine->ResolveRandomSound(sfx);
rnd->Choices.Reset();
rnd->Owner = 0;
}
@ -691,7 +486,7 @@ static int S_AddSound (const char *logicalname, int lumpnum, FScanner *sc)
}
else
{ // Otherwise, create a new definition.
sfxid = S_AddSoundLump (logicalname, lumpnum);
sfxid = soundEngine->AddSoundLump (logicalname, lumpnum, CurrentPitchMask);
}
return sfxid;
@ -719,6 +514,7 @@ int S_AddPlayerSound (const char *pclass, int gender, int refid,
int S_AddPlayerSound (const char *pclass, int gender, int refid, int lumpnum, bool fromskin)
{
auto &S_sfx = soundEngine->GetSounds();
FString fakename;
int id;
@ -728,7 +524,7 @@ int S_AddPlayerSound (const char *pclass, int gender, int refid, int lumpnum, bo
fakename += '"';
fakename += S_sfx[refid].name;
id = S_AddSoundLump (fakename, lumpnum);
id = soundEngine->AddSoundLump (fakename, lumpnum, CurrentPitchMask);
int classnum = S_AddPlayerClass (pclass);
int soundlist = S_AddPlayerGender (classnum, gender);
@ -752,6 +548,7 @@ int S_AddPlayerSoundExisting (const char *pclass, int gender, int refid,
int classnum = S_AddPlayerClass (pclass);
int soundlist = S_AddPlayerGender (classnum, gender);
auto &S_sfx = soundEngine->GetSounds();
PlayerSounds[soundlist].AddSound (S_sfx[refid].link, aliasto);
if (fromskin) S_SavePlayerSound(pclass, gender, refid, aliasto, true);
@ -928,7 +725,7 @@ void FPlayerSoundHashTable::MarkUsed()
{
for (Entry *probe = Buckets[i]; probe != NULL; probe = probe->Next)
{
S_sfx[probe->SfxID].bUsed = true;
soundEngine->MarkUsed(probe->SfxID);
}
}
}
@ -944,8 +741,9 @@ void FPlayerSoundHashTable::MarkUsed()
void S_ClearSoundData()
{
S_StopAllChannels();
S_UnloadAllSounds();
soundEngine->StopAllChannels();
soundEngine->UnloadAllSounds();
auto &S_sfx = soundEngine->GetSounds();
S_sfx.Clear();
Ambients.Clear();
while (MusicVolumes != NULL)
@ -954,7 +752,7 @@ void S_ClearSoundData()
MusicVolumes = me->Next;
M_Free(me);
}
S_rnd.Clear();
soundEngine->ClearRandoms();
NumPlayerReserves = 0;
PlayerClassesIsSorted = false;
@ -977,6 +775,7 @@ void S_ClearSoundData()
void S_ParseSndInfo (bool redefine)
{
auto &S_sfx = soundEngine->GetSounds();
int lump;
if (!redefine) SavedPlayerSounds.Clear(); // clear skin sounds only for initial parsing.
@ -1005,13 +804,7 @@ void S_ParseSndInfo (bool redefine)
}
}
S_RestorePlayerSounds();
S_HashSounds ();
S_sfx.ShrinkToFit ();
if (S_rnd.Size() > 0)
{
S_rnd.ShrinkToFit ();
}
soundEngine->HashSounds ();
S_ShrinkPlayerSoundLists ();
@ -1028,13 +821,7 @@ void S_ParseSndInfo (bool redefine)
void S_AddLocalSndInfo(int lump)
{
S_AddSNDINFO(lump);
S_HashSounds ();
S_sfx.ShrinkToFit ();
if (S_rnd.Size() > 0)
{
S_rnd.ShrinkToFit ();
}
soundEngine->HashSounds ();
S_ShrinkPlayerSoundLists ();
S_CheckIntegrity();
@ -1050,6 +837,7 @@ void S_AddLocalSndInfo(int lump)
static void S_AddSNDINFO (int lump)
{
auto &S_sfx = soundEngine->GetSounds();
bool skipToEndIf;
TArray<uint32_t> list;
@ -1087,7 +875,7 @@ static void S_AddSNDINFO (int lump)
ambient->sound = 0;
sc.MustGetString ();
ambient->sound = FSoundID(S_FindSoundTentative(sc.String));
ambient->sound = FSoundID(soundEngine->FindSoundTentative(sc.String));
ambient->attenuation = 0;
sc.MustGetString ();
@ -1205,7 +993,7 @@ static void S_AddSNDINFO (int lump)
int gender, refid, targid;
S_ParsePlayerSoundCommon (sc, pclass, gender, refid);
targid = S_FindSoundNoHash (sc.String);
targid = soundEngine->FindSoundNoHash (sc.String);
if (!S_sfx[targid].bPlayerReserve)
{
sc.ScriptError ("%s is not a player sound", sc.String);
@ -1235,7 +1023,7 @@ static void S_AddSNDINFO (int lump)
int soundnum;
S_ParsePlayerSoundCommon (sc, pclass, gender, refid);
soundnum = S_FindSoundTentative (sc.String);
soundnum = soundEngine->FindSoundTentative (sc.String);
S_AddPlayerSoundExisting (pclass, gender, refid, soundnum);
}
break;
@ -1251,7 +1039,7 @@ static void S_AddSNDINFO (int lump)
{
sfxfrom = S_sfx[sfxfrom].link;
}
S_sfx[sfxfrom].link = S_FindSoundTentative (sc.String);
S_sfx[sfxfrom].link = soundEngine->FindSoundTentative (sc.String);
S_sfx[sfxfrom].NearLimit = -1; // Aliases must use the original sound's limit.
}
break;
@ -1261,7 +1049,7 @@ static void S_AddSNDINFO (int lump)
int sfx;
sc.MustGetString ();
sfx = S_FindSoundTentative (sc.String);
sfx = soundEngine->FindSoundTentative (sc.String);
sc.MustGetNumber ();
S_sfx[sfx].NearLimit = MIN(MAX(sc.Number, 0), 255);
if (sc.CheckFloat())
@ -1276,7 +1064,7 @@ static void S_AddSNDINFO (int lump)
int sfx;
sc.MustGetString ();
sfx = S_FindSoundTentative (sc.String);
sfx = soundEngine->FindSoundTentative (sc.String);
S_sfx[sfx].bSingular = true;
}
break;
@ -1286,7 +1074,7 @@ static void S_AddSNDINFO (int lump)
int sfx;
sc.MustGetString ();
sfx = S_FindSoundTentative (sc.String);
sfx = soundEngine->FindSoundTentative (sc.String);
sc.MustGetNumber ();
S_sfx[sfx].PitchMask = (1 << clamp (sc.Number, 0, 7)) - 1;
}
@ -1303,7 +1091,7 @@ static void S_AddSNDINFO (int lump)
int sfx;
sc.MustGetString();
sfx = S_FindSoundTentative(sc.String);
sfx = soundEngine->FindSoundTentative(sc.String);
sc.MustGetFloat();
S_sfx[sfx].Volume = (float)sc.Float;
}
@ -1314,7 +1102,7 @@ static void S_AddSNDINFO (int lump)
int sfx;
sc.MustGetString();
sfx = S_FindSoundTentative(sc.String);
sfx = soundEngine->FindSoundTentative(sc.String);
sc.MustGetFloat();
S_sfx[sfx].Attenuation = (float)sc.Float;
}
@ -1331,11 +1119,11 @@ static void S_AddSNDINFO (int lump)
if (sc.Compare("*"))
{
sfx = -1;
rolloff = &S_Rolloff;
rolloff = &soundEngine->GlobalRolloff();
}
else
{
sfx = S_FindSoundTentative(sc.String);
sfx = soundEngine->FindSoundTentative(sc.String);
rolloff = &S_sfx[sfx].Rolloff;
}
type = ROLLOFF_Doom;
@ -1376,7 +1164,7 @@ static void S_AddSNDINFO (int lump)
sc.MustGetStringName ("{");
while (sc.GetString () && !sc.Compare ("}"))
{
uint32_t sfxto = S_FindSoundTentative (sc.String);
uint32_t sfxto = soundEngine->FindSoundTentative (sc.String);
if (sfxto == random.Owner)
{
Printf("Definition of random sound '%s' refers to itself recursively.\n", sc.String);
@ -1391,13 +1179,7 @@ static void S_AddSNDINFO (int lump)
}
else if (list.Size() > 1)
{ // Only add non-empty random lists
auto index = S_rnd.Reserve(1);
auto &random = S_rnd.Last();
random.Choices = std::move(list);
random.Owner = Owner;
S_sfx[Owner].link = index;
S_sfx[Owner].bRandomHeader = true;
S_sfx[Owner].NearLimit = -1;
soundEngine->AddRandomSound(Owner, list);
}
}
break;
@ -1513,6 +1295,7 @@ static void S_AddBloodSFX (int lumpnum)
if (rawlump != -1)
{
auto &S_sfx = soundEngine->GetSounds();
const char *name = Wads.GetLumpFullName(lumpnum);
sfxnum = S_AddSound(name, rawlump);
if (sfx->Format < 5 || sfx->Format > 12)
@ -1572,7 +1355,8 @@ static void S_ParsePlayerSoundCommon (FScanner &sc, FString &pclass, int &gender
sc.MustGetString ();
gender = D_GenderToInt (sc.String);
sc.MustGetString ();
refid = S_FindSoundNoHash (sc.String);
refid = soundEngine->FindSoundNoHash (sc.String);
auto &S_sfx = soundEngine->GetSounds();
if (refid != 0 && !S_sfx[refid].bPlayerReserve && !S_sfx[refid].bTentative)
{
sc.ScriptError ("%s has already been used for a non-player sound.", sc.String);
@ -1734,6 +1518,7 @@ int S_LookupPlayerSound (const char *pclass, int gender, const char *name)
int S_LookupPlayerSound (const char *pclass, int gender, FSoundID refid)
{
auto &S_sfx = soundEngine->GetSounds();
if (!S_sfx[refid].bPlayerReserve)
{ // Not a player sound, so just return this sound
return refid;
@ -1744,6 +1529,7 @@ int S_LookupPlayerSound (const char *pclass, int gender, FSoundID refid)
static int S_LookupPlayerSound (int classidx, int gender, FSoundID refid)
{
auto &S_sfx = soundEngine->GetSounds();
int ingender = gender;
if (classidx == -1)
@ -1847,6 +1633,7 @@ bool S_AreSoundsEquivalent (AActor *actor, int id1, int id2)
{
sfxinfo_t *sfx;
auto &S_sfx = soundEngine->GetSounds();
if (id1 == id2)
{
return true;
@ -1998,52 +1785,6 @@ void S_MarkPlayerSounds (AActor *player)
}
}
//==========================================================================
//
// CCMD soundlist
//
//==========================================================================
CCMD (soundlist)
{
char lumpname[9];
unsigned int i;
lumpname[8] = 0;
for (i = 0; i < S_sfx.Size (); i++)
{
const sfxinfo_t *sfx = &S_sfx[i];
if (sfx->bRandomHeader)
{
Printf ("%3d. %s -> #%d {", i, sfx->name.GetChars(), sfx->link);
const FRandomSoundList *list = &S_rnd[sfx->link];
for (auto &me : list->Choices)
{
Printf (" %s ", S_sfx[me].name.GetChars());
}
Printf ("}\n");
}
else if (sfx->bPlayerReserve)
{
Printf ("%3d. %s <<player sound %d>>\n", i, sfx->name.GetChars(), sfx->link);
}
else if (S_sfx[i].lumpnum != -1)
{
Wads.GetLumpName (lumpname, sfx->lumpnum);
Printf ("%3d. %s (%s)\n", i, sfx->name.GetChars(), lumpname);
}
else if (S_sfx[i].link != sfxinfo_t::NO_LINK)
{
Printf ("%3d. %s -> %s\n", i, sfx->name.GetChars(), S_sfx[sfx->link].name.GetChars());
}
else
{
Printf ("%3d. %s **not present**\n", i, sfx->name.GetChars());
}
Printf(" PitchMask = %d\n", sfx->PitchMask);
}
}
//==========================================================================
//
// CCMD soundlinks
@ -2052,6 +1793,7 @@ CCMD (soundlist)
CCMD (soundlinks)
{
auto &S_sfx = soundEngine->GetSounds();
unsigned int i;
for (i = 0; i < S_sfx.Size (); i++)
@ -2075,6 +1817,7 @@ CCMD (soundlinks)
CCMD (playersounds)
{
auto &S_sfx = soundEngine->GetSounds();
const char *reserveNames[256];
unsigned int i;
int j, k, l;
@ -2119,7 +1862,7 @@ DEFINE_ACTION_FUNCTION(AAmbientSound, MarkAmbientSounds)
FAmbientSound *ambient = Ambients.CheckKey(self->args[0]);
if (ambient != NULL)
{
ambient->sound.MarkUsed();
soundEngine->MarkUsed(ambient->sound);
}
return 0;
}
@ -2251,13 +1994,12 @@ DEFINE_ACTION_FUNCTION(AAmbientSound, Activate)
{
if ((amb->type & 3) == 0 && amb->periodmin == 0)
{
int sndnum = S_FindSound(amb->sound);
if (sndnum == 0)
if (amb->sound == 0)
{
self->Destroy ();
return 0;
}
amb->periodmin = ::Scale(S_GetMSLength(sndnum), TICRATE, 1000);
amb->periodmin = ::Scale(S_GetMSLength(amb->sound), TICRATE, 1000);
}
self->special1 = 0;
@ -2343,7 +2085,7 @@ DEFINE_ACTION_FUNCTION(DObject, MarkSound)
{
PARAM_PROLOGUE;
PARAM_SOUND(sound_id);
sound_id.MarkUsed();
soundEngine->MarkUsed(sound_id);
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -3,8 +3,22 @@
// Information about one playing sound.
struct sector_t;
struct FPolyObj;
struct FLevelLocals;
void S_Init();
void S_InitData();
void S_Start();
void S_Shutdown();
void S_UpdateSounds(AActor* listenactor);
void S_SetSoundPaused(int state);
void S_PrecacheLevel(FLevelLocals* l);
// Start sound for thing at <ent>
void S_Sound(int channel, FSoundID sfxid, float volume, float attenuation);
void S_SoundPitch(int channel, FSoundID sfxid, float volume, float attenuation, float pitch);
void S_Sound (AActor *ent, int channel, FSoundID sfxid, float volume, float attenuation);
void S_SoundMinMaxDist (AActor *ent, int channel, FSoundID sfxid, float volume, float mindist, float maxdist);
@ -44,4 +58,32 @@ void S_SerializeSounds(FSerializer &arc);
void A_PlaySound(AActor *self, int soundid, int channel, double volume, int looping, double attenuation, int local, double pitch);
static void S_SetListener(AActor *listenactor);
void S_SoundReset();
void S_SoundReset();
void S_ResumeSound(bool state);
void S_PauseSound(bool state1, bool state);
void S_NoiseDebug();
inline void S_StopSound(int chan)
{
soundEngine->StopSound(chan);
}
inline void S_StopAllChannels()
{
soundEngine->StopAllChannels();
}
inline const char* S_GetSoundName(FSoundID id)
{
return soundEngine->GetSoundName(id);
}
inline int S_FindSound(const char* logicalname)
{
return soundEngine->FindSound(logicalname);
}
inline int S_FindSoundByResID(int rid)
{
return soundEngine->FindSoundByResID(rid);
}

View file

@ -1433,13 +1433,13 @@ void SN_MarkPrecacheSounds(int sequence, seqtype_t type)
{
FSoundSequence *seq = Sequences[sequence];
seq->StopSound.MarkUsed();
soundEngine->MarkUsed(seq->StopSound);
for (int i = 0; GetCommand(seq->Script[i]) != SS_CMD_END; ++i)
{
int cmd = GetCommand(seq->Script[i]);
if (cmd == SS_CMD_PLAY || cmd == SS_CMD_PLAYREPEAT || cmd == SS_CMD_PLAYLOOP)
{
FSoundID(GetData(seq->Script[i])).MarkUsed();
soundEngine->MarkUsed(GetData(seq->Script[i]));
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -28,7 +28,6 @@
#ifndef __S_SOUND__
#define __S_SOUND__
#include "doomtype.h"
#include "i_soundinternal.h"
class AActor;
@ -37,58 +36,36 @@ class FSerializer;
struct FLevelLocals;
#include "s_soundinternal.h"
#include "s_doomsound.h"
// Per level startup code.
// Kills playing sounds at start of level and starts new music.
//
void S_Start ();
// Called after a level is loaded. Ensures that most sounds are loaded.
void S_PrecacheLevel (FLevelLocals *l);
// Start sound for thing at <ent>
void S_Sound (int channel, FSoundID sfxid, float volume, float attenuation);
void S_SoundPitch (int channel, FSoundID sfxid, float volume, float attenuation, float pitch);
struct FSoundLoadBuffer;
int S_PickReplacement (int refid);
void S_CacheRandomSound (sfxinfo_t *sfx);
// Stop sound for all channels
void S_StopAllChannels (void);
void S_SetPitch(FSoundChan *chan, float dpitch);
void S_RestoreEvictedChannels();
// [RH] S_sfx "maintenance" routines
void S_ClearSoundData();
void S_ParseSndInfo (bool redefine);
void S_HashSounds ();
int S_FindSoundNoHash (const char *logicalname);
bool S_AreSoundsEquivalent (AActor *actor, int id1, int id2);
bool S_AreSoundsEquivalent (AActor *actor, const char *name1, const char *name2);
int S_LookupPlayerSound (const char *playerclass, int gender, const char *logicalname);
int S_LookupPlayerSound (const char *playerclass, int gender, FSoundID refid);
int S_FindSkinnedSound (AActor *actor, FSoundID refid);
int S_FindSkinnedSoundEx (AActor *actor, const char *logicalname, const char *extendedname);
int S_FindSoundByLump (int lump);
int S_AddSound (const char *logicalname, const char *lumpname, FScanner *sc=NULL); // Add sound by lumpname
int S_AddSoundLump (const char *logicalname, int lump); // Add sound by lump index
int S_AddPlayerSound (const char *playerclass, const int gender, int refid, const char *lumpname);
int S_AddPlayerSound (const char *playerclass, const int gender, int refid, int lumpnum, bool fromskin=false);
int S_AddPlayerSoundExisting (const char *playerclass, const int gender, int refid, int aliasto, bool fromskin=false);
void S_MarkPlayerSounds (AActor *player);
void S_ShrinkPlayerSoundLists ();
void S_UnloadSound (sfxinfo_t *sfx);
sfxinfo_t *S_LoadSound(sfxinfo_t *sfx, FSoundLoadBuffer *pBuffer = nullptr);
unsigned int S_GetMSLength(FSoundID sound);
// [RH] Prints sound debug info to the screen.
// Modelled after Hexen's noise cheat.
void S_NoiseDebug ();
#include "s_doomsound.h"
#endif

View file

@ -1,7 +1,14 @@
#pragma once
#include "i_soundinternal.h"
#include "i_sound.h"
struct FRandomSoundList
{
TArray<uint32_t> Choices;
uint32_t Owner = 0;
};
extern int sfx_empty;
//
// SoundFX struct.
@ -21,19 +28,20 @@ struct sfxinfo_t
unsigned int next, index; // [RH] For hashing
float Volume;
uint8_t ResourceId; // Resource ID as implemented by Blood. Not used by Doom but added for completeness.
int ResourceId; // Resource ID as implemented by Blood. Not used by Doom but added for completeness.
uint8_t PitchMask;
int16_t NearLimit; // 0 means unlimited
float LimitRange; // Range for sound limiting (squared for faster computations)
unsigned bRandomHeader:1;
unsigned bPlayerReserve:1;
unsigned bLoadRAW:1;
unsigned bPlayerCompat:1;
unsigned b16bit:1;
unsigned bUsed:1;
unsigned bSingular:1;
unsigned bTentative:1;
unsigned bPlayerReserve : 1;
unsigned bPlayerCompat : 1;
unsigned bPlayerSilent:1; // This player sound is intentionally silent.
int RawRate; // Sample rate to use when bLoadRAW is true
@ -61,9 +69,6 @@ enum
int S_FindSound(const char *logicalname);
int S_FindSoundByResID(int snd_id);
// the complete set of sound effects
extern TArray<sfxinfo_t> S_sfx;
// An index into the S_sfx[] array.
class FSoundID
{
@ -110,18 +115,6 @@ public:
{
return ID;
}
operator FString() const
{
return ID ? S_sfx[ID].name : "";
}
operator const char *() const
{
return ID ? S_sfx[ID].name.GetChars() : NULL;
}
void MarkUsed() const
{
S_sfx[ID].MarkUsed();
}
private:
int ID;
protected:
@ -136,13 +129,8 @@ public:
using FSoundID::operator=;
};
extern FRolloffInfo S_Rolloff;
extern TArray<uint8_t> S_SoundCurve;
class AActor;
struct sector_t;
struct FPolyObj;
struct FSoundChan : public FISoundChannel
{
FSoundChan *NextChan; // Next channel in this list.
@ -163,25 +151,6 @@ struct FSoundChan : public FISoundChannel
};
};
extern FSoundChan *Channels;
void S_ReturnChannel(FSoundChan *chan);
void S_EvictAllChannels();
void S_StopChannel(FSoundChan *chan);
void S_LinkChannel(FSoundChan *chan, FSoundChan **head);
void S_UnlinkChannel(FSoundChan *chan);
// Initializes sound stuff, including volume
// Sets channels, SFX and music volume,
// allocates channel buffer, sets S_sfx lookup.
//
void S_Init ();
void S_InitData ();
void S_Shutdown ();
// Loads a sound, including any random sounds it might reference.
void S_CacheSound (sfxinfo_t *sfx);
// sound channels
// channel 0 never willingly overrides
@ -237,9 +206,6 @@ enum
#define ATTN_IDLE 1.001f
#define ATTN_STATIC 3.f // diminish very rapidly with distance
// Checks if a copy of this sound is already playing.
bool S_CheckSingular (int sound_id);
enum // This cannot be remain as this, but for now it has to suffice.
{
SOURCE_None, // Sound is always on top of the listener.
@ -250,31 +216,6 @@ enum // This cannot be remain as this, but for now it has to suffice.
};
//
// Updates music & sounds
//
void S_UpdateSounds (int time);
FSoundChan* S_StartSound(int sourcetype, const void* source,
const FVector3* pt, int channel, FSoundID sound_id, float volume, float attenuation, FRolloffInfo* rolloff = nullptr, float spitch = 0.0f);
// Stops an origin-less sound from playing from this channel.
void S_StopSound(int channel);
void S_StopSound(int sourcetype, const void* actor, int channel);
void S_RelinkSound(int sourcetype, const void* from, const void* to, const FVector3* optpos);
void S_ChangeSoundVolume(int sourcetype, const void *source, int channel, double dvolume);
void S_ChangeSoundPitch(int sourcetype, const void *source, int channel, double pitch);
bool S_IsSourcePlayingSomething (int sourcetype, const void *actor, int channel, int sound_id);
// Stop and resume music, during game PAUSE.
void S_PauseSound (bool notmusic, bool notsfx);
void S_ResumeSound (bool notsfx);
void S_SetSoundPaused (int state);
bool S_GetSoundPlayingInfo(int sourcetype, const void* source, int sound_id);
void S_UnloadAllSounds();
void S_Reset();
extern ReverbContainer *Environments;
extern ReverbContainer *DefaultEnvironments[26];
@ -285,3 +226,163 @@ ReverbContainer *S_FindEnvironment (const char *name);
ReverbContainer *S_FindEnvironment (int id);
void S_AddEnvironment (ReverbContainer *settings);
class SoundEngine
{
protected:
bool SoundPaused = false; // whether sound is paused
int RestartEvictionsAt = 0; // do not restart evicted channels before this time
SoundListener listener{};
FSoundChan* Channels = nullptr;
FSoundChan* FreeChannels = nullptr;
// the complete set of sound effects
TArray<sfxinfo_t> S_sfx;
FRolloffInfo S_Rolloff;
TArray<uint8_t> S_SoundCurve;
TMap<int, int> ResIdMap;
TArray<FRandomSoundList> S_rnd;
private:
void LoadSound3D(sfxinfo_t* sfx, FSoundLoadBuffer* pBuffer);
void LinkChannel(FSoundChan* chan, FSoundChan** head);
void UnlinkChannel(FSoundChan* chan);
void ReturnChannel(FSoundChan* chan);
void RestartChannel(FSoundChan* chan);
void RestoreEvictedChannel(FSoundChan* chan);
bool IsChannelUsed(int sourcetype, const void* actor, int channel, int* seen);
// This is the actual sound positioning logic which needs to be provided by the client.
virtual void CalcPosVel(int type, const void* source, const float pt[3], int channel, int chanflags, FVector3* pos, FVector3* vel) = 0;
// This can be overridden by the clent to provide some diagnostics. The default lets everything pass.
virtual bool ValidatePosVel(int sourcetype, const void* source, const FVector3& pos, const FVector3& vel) { return true; }
bool ValidatePosVel(const FSoundChan* const chan, const FVector3& pos, const FVector3& vel);
// Checks if a copy of this sound is already playing.
bool CheckSingular(int sound_id);
bool CheckSoundLimit(sfxinfo_t* sfx, const FVector3& pos, int near_limit, float limit_range, int sourcetype, const void* actor, int channel);
virtual TArray<uint8_t> ReadSound(int lumpnum) = 0;
public:
virtual ~SoundEngine() = default;
void EvictAllChannels();
void StopChannel(FSoundChan* chan);
sfxinfo_t* LoadSound(sfxinfo_t* sfx, FSoundLoadBuffer* pBuffer);
// Initializes sound stuff, including volume
// Sets channels, SFX and music volume,
// allocates channel buffer, sets S_sfx lookup.
//
void Init(TArray<uint8_t> &sndcurve);
void InitData();
void Shutdown();
void StopAllChannels(void);
void SetPitch(FSoundChan* chan, float dpitch);
FSoundChan* GetChannel(void* syschan);
void RestoreEvictedChannels();
void CalcPosVel(FSoundChan* chan, FVector3* pos, FVector3* vel);
// Loads a sound, including any random sounds it might reference.
void CacheSound(sfxinfo_t* sfx);
void CacheSound(int sfx) { CacheSound(&S_sfx[sfx]); }
void UnloadSound(sfxinfo_t* sfx);
void UpdateSounds(int time);
FSoundChan* StartSound(int sourcetype, const void* source,
const FVector3* pt, int channel, FSoundID sound_id, float volume, float attenuation, FRolloffInfo* rolloff = nullptr, float spitch = 0.0f);
// Stops an origin-less sound from playing from this channel.
void StopSound(int channel);
void StopSound(int sourcetype, const void* actor, int channel);
void RelinkSound(int sourcetype, const void* from, const void* to, const FVector3* optpos);
void ChangeSoundVolume(int sourcetype, const void* source, int channel, double dvolume);
void ChangeSoundPitch(int sourcetype, const void* source, int channel, double pitch);
bool IsSourcePlayingSomething(int sourcetype, const void* actor, int channel, int sound_id);
// Stop and resume music, during game PAUSE.
bool GetSoundPlayingInfo(int sourcetype, const void* source, int sound_id);
void UnloadAllSounds();
void Reset();
void MarkUsed(int num);
void CacheMarkedSounds();
TArray<FSoundChan*> AllActiveChannels();
void MarkAllUnused()
{
for (auto & s: S_sfx) s.bUsed = false;
}
bool isListener(const void* object) const
{
return object && listener.ListenerObject == object;
}
bool isPlayerReserve(int snd_id)
{
return S_sfx[snd_id].bPlayerReserve; // Later this needs to be abstracted out of the engine itself. Right now that cannot be done.
}
void SetListener(SoundListener& l)
{
listener = l;
}
void SetRestartTime(int time)
{
RestartEvictionsAt = time;
}
void SetPaused(bool on)
{
SoundPaused = on;
}
FSoundChan* GetChannels()
{
return Channels;
}
const char *GetSoundName(FSoundID id)
{
return id == 0 ? "" : S_sfx[id].name;
}
TArray<sfxinfo_t> &GetSounds() //Thio should only be used for constructing the sound list or for diagnostics code prinring information about the sound list.
{
return S_sfx;
}
FRolloffInfo& GlobalRolloff() // like GetSounds this is meant for sound list generators, not for gaining cheap access to the sound engine's innards.
{
return S_Rolloff;
}
FRandomSoundList *ResolveRandomSound(sfxinfo_t* sfx)
{
return &S_rnd[sfx->link];
}
void ClearRandoms()
{
S_rnd.Clear();
}
void ChannelVirtualChanged(FISoundChannel* ichan, bool is_virtual);
FString ListSoundChannels();
// Allow this to be overridden for special needs.
virtual float GetRolloff(const FRolloffInfo* rolloff, float distance);
virtual void ChannelEnded(FISoundChannel* ichan); // allows the client to do bookkeeping on the sound.
// Lookup utilities.
int FindSound(const char* logicalname);
int FindSoundByResID(int rid);
int FindSoundNoHash(const char* logicalname);
int FindSoundByLump(int lump);
int AddSoundLump(const char* logicalname, int lump, int CurrentPitchMask, int resid = -1);
int FindSoundTentative(const char* name);
void CacheRandomSound(sfxinfo_t* sfx);
unsigned int GetMSLength(FSoundID sound);
int PickReplacement(int refid);
void HashSounds();
void AddRandomSound(int Owner, TArray<uint32_t> list);
};
extern SoundEngine* soundEngine;

View file

@ -0,0 +1,5 @@
#pragma once
extern unsigned int MakeKey (const char *s);
extern unsigned int MakeKey (const char *s, size_t len);
extern unsigned int SuperFastHash (const char *data, size_t len);

View file

@ -436,6 +436,8 @@ class Actor : Thinker native
MarkSound(BounceSound);
MarkSound(WallBounceSound);
MarkSound(CrushPainSound);
MarkSound(HowlSound);
MarkSound(MeleeSound);
}
bool IsPointerEqual(int ptr_select1, int ptr_select2)