- allow setting Duke's relevant sound properties through SNDINFO.

This commit is contained in:
Christoph Oelckers 2023-01-15 11:54:24 +01:00
parent 2c5062255c
commit ad0bff921b
3 changed files with 72 additions and 6 deletions

View file

@ -42,9 +42,11 @@
#include "s_music.h"
#include "sc_man.h"
#include "s_soundinternal.h"
#include "gamecontrol.h"
#include <zmusic.h>
#include "raze_music.h"
#include "games/duke/src/sounds.h"
// MACROS ------------------------------------------------------------------
@ -56,7 +58,9 @@ enum SICommands
SI_ConReserve,
SI_Alias,
SI_Limit,
SI_Singular
SI_Singular,
SI_DukePitchRange,
SI_DukeFlags,
};
@ -87,6 +91,8 @@ static const char *SICommandStrings[] =
"$alias",
"$limit",
"$singular",
"$dukepitchrange",
"$dukeflags",
NULL
};
@ -300,6 +306,67 @@ static void S_AddSNDINFO (int lump)
break;
}
case SI_DukePitchRange: {
// dukesound <logical name> <lower> <upper>
// Sets a pitch range for the sound.
sc.MustGetString();
auto sfxid = soundEngine->FindSoundTentative(sc.String, DEFAULT_LIMIT);
sc.MustGetNumber();
int minpitch = sc.Number;
sc.MustGetNumber();
int maxpitch = sc.Number;
if (isDukeEngine())
{
auto sfx = soundEngine->GetWritableSfx(sfxid);
if (sfx->UserData.Size() < Duke3d::kMaxUserData)
{
sfx->UserData.Resize(Duke3d::kMaxUserData);
memset(sfx->UserData.Data(), 0, Duke3d::kMaxUserData * sizeof(int));
}
sfx->UserData[Duke3d::kPitchStart] = clamp<int>(minpitch, INT16_MIN, INT16_MAX);
sfx->UserData[Duke3d::kPitchEnd] = clamp<int>(maxpitch, INT16_MIN, INT16_MAX);
}
else
{
sc.ScriptMessage("'dukepitchrange' is not available in current game and will be ignored");
}
break;
}
case SI_DukeFlags: {
static const char* dukeflags[] = { "LOOP", "MSFX", "TALK", "GLOBAL", nullptr};
// dukesound <logical name> <flag> <flag> <flag>..
// Sets a pitch range for the sound.
sc.MustGetString();
auto sfxid = soundEngine->FindSoundTentative(sc.String, DEFAULT_LIMIT);
int flags = 0;
while (sc.GetString())
{
int bit = sc.MatchString(dukeflags);
if (bit == -1) break;
flags |= 1 << bit;
}
if (isDukeEngine())
{
auto sfx = soundEngine->GetWritableSfx(sfxid);
if (sfx->UserData.Size() < Duke3d::kMaxUserData)
{
sfx->UserData.Resize(Duke3d::kMaxUserData);
memset(sfx->UserData.Data(), 0, Duke3d::kMaxUserData * sizeof(int));
}
sfx->UserData[Duke3d::kFlags] = flags;
}
else
{
sc.ScriptMessage("'dukeflags' is not available in current game and will be ignored");
}
break;
}
default:
{ // Got a logical sound mapping
FString name (sc.String);

View file

@ -246,9 +246,7 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit
sfx->ResourceId = index;
sfx->UserData.Resize(kMaxUserData);
auto& sndinf = sfx->UserData;
sndinf[kFlags] = (type & ~SF_ONEINST_INTERNAL) | SF_CONDEFINED;
if (sndinf[kFlags] & SF_LOOP)
sndinf[kFlags] |= SF_ONEINST_INTERNAL;
sndinf[kFlags] = (type & SF_CON_MASK) | SF_CONDEFINED;
// Take care of backslashes in sound names. Also double backslashes which occur in World Tour.
FString fn = filename;
@ -528,7 +526,7 @@ int S_PlaySound3D(FSoundID soundid, DDukeActor* actor, const DVector3& pos, int
int const repeatp = (userflags & SF_LOOP);
if (repeatp && (userflags & SF_ONEINST_INTERNAL) && is_playing)
if (repeatp && is_playing)
{
return -1;
}

View file

@ -18,7 +18,7 @@ enum {
SF_TALK = 4,
SF_ADULT = 8,
SF_GLOBAL = 16,
SF_ONEINST_INTERNAL = 32,
SF_CON_MASK = 31,
SF_CONDEFINED = 64,
SF_DTAG = 128,
@ -35,6 +35,7 @@ enum esound_t
kMaxUserData
};
class DDukeActor;
int S_PlaySound(FSoundID num, int channel = CHAN_AUTO, EChanFlags flags = 0, float vol = 0.8f);
int S_PlaySound3D(FSoundID num, DDukeActor* spriteNum, const DVector3& pos, int channel = CHAN_AUTO, EChanFlags flags = 0);
int S_PlayActorSound(FSoundID soundNum, DDukeActor* spriteNum, int channel = CHAN_AUTO, EChanFlags flags = 0);