From 006540640be840f7569f12a29edee7e1be7456be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= Date: Tue, 10 Nov 2020 22:12:00 +0200 Subject: [PATCH] Heretic: Dynamic ambient sound sequences In addition to the built-in sequences, this allows defining additional ones and also dynamically overriding the built-in sequences. --- .../apps/plugins/heretic/include/p_spec.h | 2 + doomsday/apps/plugins/heretic/src/h_main.cpp | 2 +- doomsday/apps/plugins/heretic/src/p_spec.cpp | 72 ++++++++++++++++--- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/doomsday/apps/plugins/heretic/include/p_spec.h b/doomsday/apps/plugins/heretic/include/p_spec.h index d3dd085b0f..1905597bfd 100644 --- a/doomsday/apps/plugins/heretic/include/p_spec.h +++ b/doomsday/apps/plugins/heretic/include/p_spec.h @@ -61,6 +61,8 @@ void P_SpawnAllSpecialThinkers(void); void P_InitAmbientSound(void); +void P_DefineAmbientSfx(int sequence, const int *seq, size_t count); + /** * Called by spawnMapThing during @ref P_SetupMap() */ diff --git a/doomsday/apps/plugins/heretic/src/h_main.cpp b/doomsday/apps/plugins/heretic/src/h_main.cpp index 741035d6d2..600a8ea12c 100644 --- a/doomsday/apps/plugins/heretic/src/h_main.cpp +++ b/doomsday/apps/plugins/heretic/src/h_main.cpp @@ -26,7 +26,7 @@ #include #include #include -#include > +#include #include "d_netsv.h" #include "g_defs.h" #include "gamesession.h" diff --git a/doomsday/apps/plugins/heretic/src/p_spec.cpp b/doomsday/apps/plugins/heretic/src/p_spec.cpp index f7f9ae977d..1b9b55b92f 100644 --- a/doomsday/apps/plugins/heretic/src/p_spec.cpp +++ b/doomsday/apps/plugins/heretic/src/p_spec.cpp @@ -40,6 +40,9 @@ #include "p_user.h" #include "player.h" +#include +#include + #define MAX_AMBIENT_SFX 8 ///< Per level enum afxcmd_t @@ -59,6 +62,7 @@ ThinkerT LavaInflictor; static const int *LevelAmbientSfx[MAX_AMBIENT_SFX]; static const int *AmbSfxPtr; +static int AmbSfxCurrentSeq; // corresponds to AmbSfxPtr static int AmbSfxCount; static int AmbSfxTics; static int AmbSfxVolume; @@ -197,6 +201,10 @@ static const int *AmbientSfx[] = { AmbSndSeq10 // FastFootsteps }; +static constexpr int NUM_BUILTIN_AMBIENT_SFX = int(sizeof(AmbientSfx) / sizeof(AmbientSfx[0])); + +static std::map> AmbDynamicSndSeq; + dd_bool P_ActivateLine(Line *ld, mobj_t *mo, int side, int actType) { // Clients do not activate lines. @@ -857,19 +865,67 @@ void P_PlayerInWindSector(player_t *player) void P_InitAmbientSound() { - AmbSfxCount = 0; - AmbSfxVolume = 0; - AmbSfxTics = 10 * TICSPERSEC; - AmbSfxPtr = AmbSndSeqInit; + AmbSfxCount = 0; + AmbSfxVolume = 0; + AmbSfxTics = 10 * TICSPERSEC; + AmbSfxPtr = AmbSndSeqInit; + AmbSfxCurrentSeq = -1; +} + +static const int *ambientSeqPtr(int sequence) +{ + if (AmbDynamicSndSeq.find(sequence) != AmbDynamicSndSeq.end()) + { + return AmbDynamicSndSeq[sequence].data(); + } + else if (sequence < NUM_BUILTIN_AMBIENT_SFX) + { + return AmbientSfx[sequence]; + } + return nullptr; +} + +void P_DefineAmbientSfx(int sequence, const int *seq, size_t count) +{ + const int *oldSeq = ambientSeqPtr(sequence); // Becomes obsolete. + + AmbDynamicSndSeq[sequence] = {seq, seq + count}; + + // If this is a previously existing sequence, it may need to be reset if active in the level. + if (oldSeq) + { + for (auto &ptr : LevelAmbientSfx) + { + if (ptr == oldSeq) + { + ptr = ambientSeqPtr(sequence); + } + } + } + + // Restart if this was the current sequence. + if (AmbSfxCurrentSeq == sequence) + { + AmbSfxPtr = ambientSeqPtr(sequence); + } } void P_AddAmbientSfx(int sequence) { - if(AmbSfxCount == MAX_AMBIENT_SFX) + if (AmbSfxCount == MAX_AMBIENT_SFX) + { + LOG_MAP_ERROR("Too many ambient sound sequences per level (max: %d)") << MAX_AMBIENT_SFX; + return; + } + + if (const int *seqPtr = ambientSeqPtr(sequence)) + { + LevelAmbientSfx[AmbSfxCount++] = seqPtr; + } + else { - Con_Error("Too many ambient sound sequences"); + LOG_MAP_WARNING("Ambient sound sequence %d does not exist") << sequence; } - LevelAmbientSfx[AmbSfxCount++] = AmbientSfx[sequence]; } void P_AmbientSound() @@ -923,7 +979,7 @@ void P_AmbientSound() case afxcmd_end: AmbSfxTics = 6 * TICSPERSEC + P_Random(); - AmbSfxPtr = LevelAmbientSfx[P_Random() % AmbSfxCount]; + AmbSfxPtr = LevelAmbientSfx[AmbSfxCurrentSeq = P_Random() % AmbSfxCount]; return; default: