mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-10 23:02:03 +00:00
- added serialization of playing sounds.
For ambient sounds that can be cleanly restarted a new 'transient' flag was added so that these do not get written out. Tested on SW so far, other games yet to do.
This commit is contained in:
parent
da6c7ddab5
commit
69e018d0c4
6 changed files with 141 additions and 10 deletions
|
@ -50,6 +50,7 @@
|
|||
#include "serializer.h"
|
||||
#include "version.h"
|
||||
#include "z_music.h"
|
||||
#include "s_soundinternal.h"
|
||||
|
||||
static CompositeSavegameWriter savewriter;
|
||||
static FResourceFile *savereader;
|
||||
|
@ -70,6 +71,7 @@ static void SerializeSession(FSerializer& arc)
|
|||
SECRET_Serialize(arc);
|
||||
Mus_Serialize(arc);
|
||||
quoteMgr.Serialize(arc);
|
||||
S_SerializeSounds(arc);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
#include "filesystem.h"
|
||||
#include "cmdlib.h"
|
||||
#include "gamecontrol.h"
|
||||
#include "serializer.h"
|
||||
#include "build.h"
|
||||
|
||||
|
||||
enum
|
||||
|
@ -280,7 +282,7 @@ TArray<FSoundChan*> SoundEngine::AllActiveChannels()
|
|||
// If the sound is forgettable, this is as good a time as
|
||||
// any to forget about it. And if it's a UI sound, it shouldn't
|
||||
// be stored in the savegame.
|
||||
if (!(chan->ChanFlags & (CHANF_FORGETTABLE | CHANF_UI)))
|
||||
if (!(chan->ChanFlags & (CHANF_FORGETTABLE | CHANF_UI | CHANF_TRANSIENT)))
|
||||
{
|
||||
chans.Push(chan);
|
||||
}
|
||||
|
@ -1764,3 +1766,105 @@ int S_LookupSound(const char* fn)
|
|||
}
|
||||
return fileSystem.FindFile(fn);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Although saving the sound system's state is supposed to be an engine
|
||||
// feature, the specifics cannot be set up there, this needs to be on the client side.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static FSerializer& Serialize(FSerializer& arc, const char* key, FSoundChan& chan, FSoundChan* def)
|
||||
{
|
||||
if (arc.BeginObject(key))
|
||||
{
|
||||
arc("sourcetype", chan.SourceType)
|
||||
("soundid", chan.SoundID)
|
||||
("orgid", chan.OrgID)
|
||||
("volume", chan.Volume)
|
||||
("distancescale", chan.DistanceScale)
|
||||
("pitch", chan.Pitch)
|
||||
("chanflags", chan.ChanFlags)
|
||||
("entchannel", chan.EntChannel)
|
||||
("priority", chan.Priority)
|
||||
("nearlimit", chan.NearLimit)
|
||||
("starttime", chan.StartTime)
|
||||
("rolloftype", chan.Rolloff.RolloffType)
|
||||
("rolloffmin", chan.Rolloff.MinDistance)
|
||||
("rolloffmax", chan.Rolloff.MaxDistance)
|
||||
("limitrange", chan.LimitRange)
|
||||
.Array("point", chan.Point, 3);
|
||||
|
||||
int SourceIndex = 0;
|
||||
if (arc.isWriting())
|
||||
{
|
||||
if (chan.SourceType == SOURCE_Actor) SourceIndex = int((spritetype*)(chan.Source) - sprite);
|
||||
else SourceIndex = soundEngine->SoundSourceIndex(&chan);
|
||||
}
|
||||
arc("Source", SourceIndex);
|
||||
if (arc.isReading())
|
||||
{
|
||||
if (chan.SourceType == SOURCE_Actor) chan.Source = &sprite[SourceIndex];
|
||||
else soundEngine->SetSource(&chan, SourceIndex);
|
||||
}
|
||||
arc.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_SerializeSounds
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_SerializeSounds(FSerializer& arc)
|
||||
{
|
||||
FSoundChan* chan;
|
||||
|
||||
GSnd->Sync(true);
|
||||
|
||||
if (arc.isWriting())
|
||||
{
|
||||
// Count channels and accumulate them so we can store them in
|
||||
// reverse order. That way, they will be in the same order when
|
||||
// reloaded later as they are now.
|
||||
TArray<FSoundChan*> chans = soundEngine->AllActiveChannels();
|
||||
|
||||
if (chans.Size() > 0 && arc.BeginArray("sounds"))
|
||||
{
|
||||
for (unsigned int i = chans.Size(); i-- != 0; )
|
||||
{
|
||||
// Replace start time with sample position.
|
||||
uint64_t start = chans[i]->StartTime;
|
||||
chans[i]->StartTime = GSnd ? GSnd->GetPosition(chans[i]) : 0;
|
||||
arc(nullptr, *chans[i]);
|
||||
chans[i]->StartTime = start;
|
||||
}
|
||||
arc.EndArray();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int count;
|
||||
|
||||
soundEngine->StopAllChannels();
|
||||
if (arc.BeginArray("sounds"))
|
||||
{
|
||||
count = arc.ArraySize();
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
{
|
||||
chan = (FSoundChan*)soundEngine->GetChannel(nullptr);
|
||||
arc(nullptr, *chan);
|
||||
// Sounds always start out evicted when restored from a save.
|
||||
chan->ChanFlags |= CHANF_EVICTED | CHANF_ABSTIME;
|
||||
}
|
||||
arc.EndArray();
|
||||
}
|
||||
// totalclock runs on 120 fps, we need to allow a small delay here.
|
||||
soundEngine->SetRestartTime((int)totalclock + 6);
|
||||
}
|
||||
GSnd->Sync(false);
|
||||
GSnd->UpdateSounds();
|
||||
}
|
||||
|
||||
|
|
|
@ -275,6 +275,10 @@ public:
|
|||
}
|
||||
void EvictAllChannels();
|
||||
|
||||
// For handling special sound types. Source types None, Unattached and Actor never get here.
|
||||
virtual int SoundSourceIndex(FSoundChan* chan) { return 0; }
|
||||
virtual void SetSource(FSoundChan* chan, int index) {}
|
||||
|
||||
void StopChannel(FSoundChan* chan);
|
||||
sfxinfo_t* LoadSound(sfxinfo_t* sfx);
|
||||
|
||||
|
@ -451,3 +455,5 @@ inline int S_FindSound(const char* name)
|
|||
}
|
||||
|
||||
int S_LookupSound(const char* fn);
|
||||
class FSerializer;
|
||||
void S_SerializeSounds(FSerializer& arc);
|
||||
|
|
|
@ -258,7 +258,7 @@ void BendAmbientSound(void)
|
|||
{
|
||||
soundEngine->EnumerateChannels([](FSoundChan* chan)
|
||||
{
|
||||
if (chan->SourceType == SOURCE_Ambient)
|
||||
if (chan->SourceType == SOURCE_Ambient && chan->Source == &amb)
|
||||
{
|
||||
soundEngine->SetPitch(chan, (nDronePitch + 11800) / 11025.f);
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ void StartSwirly(int nActiveSound)
|
|||
nVolume = 220;
|
||||
|
||||
soundEngine->StopSound(SOURCE_Swirly, &swirly, -1);
|
||||
soundEngine->StartSound(SOURCE_Swirly, &swirly, nullptr, CHAN_BODY, 0, StaticSound[kSoundMana1]+1, nVolume / 255.f, ATTN_NONE, nullptr, nPitch / 11025.f);
|
||||
soundEngine->StartSound(SOURCE_Swirly, &swirly, nullptr, CHAN_BODY, CHANF_TRANSIENT, StaticSound[kSoundMana1]+1, nVolume / 255.f, ATTN_NONE, nullptr, nPitch / 11025.f);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -396,7 +396,7 @@ void SoundBigEntrance(void)
|
|||
short nPitch = i * 512 - 1200;
|
||||
//pASound->snd_pitch = nPitch;
|
||||
soundEngine->StopSound(SOURCE_EXBoss, &fakesources[i], -1);
|
||||
soundEngine->StartSound(SOURCE_EXBoss, &fakesources[i], nullptr, CHAN_BODY, 0, StaticSound[kSoundTorchOn]+1, 200 / 255.f, ATTN_NONE, nullptr, nPitch / 11025.f);
|
||||
soundEngine->StartSound(SOURCE_EXBoss, &fakesources[i], nullptr, CHAN_BODY, CHANF_TRANSIENT, StaticSound[kSoundTorchOn]+1, 200 / 255.f, ATTN_NONE, nullptr, nPitch / 11025.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -611,7 +611,7 @@ void CheckAmbience(short nSector)
|
|||
{
|
||||
vec3_t v = { pWall->x, pWall->y, sector[nSector2].floorz };
|
||||
amb = GetSoundPos(&v);
|
||||
soundEngine->StartSound(SOURCE_Ambient, &amb, nullptr, CHAN_BODY, CHANF_NONE, SectSound[nSector] + 1, 1.f, ATTN_NORM);
|
||||
soundEngine->StartSound(SOURCE_Ambient, &amb, nullptr, CHAN_BODY, CHANF_TRANSIENT, SectSound[nSector] + 1, 1.f, ATTN_NORM);
|
||||
return;
|
||||
}
|
||||
soundEngine->EnumerateChannels([=](FSoundChan* chan)
|
||||
|
@ -685,7 +685,7 @@ void UpdateCreepySounds()
|
|||
|
||||
GetSpriteSoundPitch(&nVolume, &nPitch);
|
||||
soundEngine->StopSound(SOURCE_Ambient, &creepy, CHAN_BODY);
|
||||
soundEngine->StartSound(SOURCE_Ambient, &creepy, nullptr, CHAN_BODY, CHANF_NONE, vsi + 1, nVolume / 255.f, ATTN_NONE, nullptr, (11025 + nPitch) / 11025.f);
|
||||
soundEngine->StartSound(SOURCE_Ambient, &creepy, nullptr, CHAN_BODY, CHANF_TRANSIENT, vsi + 1, nVolume / 255.f, ATTN_NONE, nullptr, (11025 + nPitch) / 11025.f);
|
||||
}
|
||||
}
|
||||
nCreepyTimer = kCreepyCount;
|
||||
|
|
|
@ -1009,16 +1009,18 @@ void InitLevelGlobals2(void)
|
|||
void
|
||||
InitLevel(void)
|
||||
{
|
||||
if (LoadGameOutsideMoveLoop)
|
||||
{
|
||||
InitLevelGlobals();
|
||||
return;
|
||||
}
|
||||
|
||||
static int DemoNumber = 0;
|
||||
|
||||
Terminate3DSounds();
|
||||
|
||||
// A few IMPORTANT GLOBAL RESETS
|
||||
InitLevelGlobals();
|
||||
if (LoadGameOutsideMoveLoop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DemoMode)
|
||||
Mus_Stop();
|
||||
|
|
|
@ -431,6 +431,23 @@ public:
|
|||
S_Rolloff.MinDistance = 0; // These are the default values, SW uses a few different rolloff settings.
|
||||
S_Rolloff.MaxDistance = 1187;
|
||||
}
|
||||
|
||||
int SoundSourceIndex(FSoundChan* chan) override
|
||||
{
|
||||
if (chan->SourceType == SOURCE_Player) return int(PLAYERp(chan->Source) - Player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetSource(FSoundChan* chan, int index) override
|
||||
{
|
||||
if (chan->SourceType == SOURCE_Player)
|
||||
{
|
||||
if (index < 0 || index >= MAX_SW_PLAYERS_REG) index = 0;
|
||||
chan->Source = &Player[index];
|
||||
}
|
||||
else chan->Source = nullptr;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
|
Loading…
Reference in a new issue