mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 05:51:20 +00:00
- continued refactoring on sound code.
The game independent part of the code has been mostly isolated.
This commit is contained in:
parent
fd181f469d
commit
b9582cc98e
22 changed files with 1545 additions and 1331 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -364,7 +364,7 @@ static FSoundID T_FindSound(const char * name)
|
|||
}
|
||||
|
||||
int id = S_AddSound(name, buffer);
|
||||
S_HashSounds();
|
||||
soundEngine->HashSounds();
|
||||
return FSoundID(id);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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(); }
|
||||
|
||||
|
|
|
@ -1837,7 +1837,7 @@ static void DoCast(const VMRegisters ®, 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:
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -122,4 +122,5 @@ class SoundStream;
|
|||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
@ -45,3 +59,31 @@ 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_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);
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
5
src/utility/superfasthash.h
Normal file
5
src/utility/superfasthash.h
Normal 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);
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue