mirror of
https://github.com/DrBeef/Raze.git
synced 2025-01-31 21:20:39 +00:00
- use backend pitch features for Duke instead of replicating them on the game side.
This commit is contained in:
parent
8859712a7b
commit
f1c3a6548f
3 changed files with 41 additions and 66 deletions
|
@ -60,7 +60,7 @@ enum SICommands
|
|||
SI_Limit,
|
||||
SI_Singular,
|
||||
SI_PitchSet,
|
||||
SI_DukePitchRange,
|
||||
SI_PitchSetDuke,
|
||||
SI_DukeFlags,
|
||||
};
|
||||
|
||||
|
@ -93,7 +93,7 @@ static const char *SICommandStrings[] =
|
|||
"$limit",
|
||||
"$singular",
|
||||
"$pitchset",
|
||||
"$dukepitchrange",
|
||||
"$pitchsetduke",
|
||||
"$dukeflags",
|
||||
NULL
|
||||
};
|
||||
|
@ -315,6 +315,26 @@ static void S_AddSNDINFO (int lump)
|
|||
}
|
||||
break;
|
||||
|
||||
case SI_PitchSetDuke: {
|
||||
// $pitchset <logical name> <pitch amount as float> [range maximum]
|
||||
// Same as above, but uses Duke's value range of 1200 units per octave.
|
||||
FSoundID sfx;
|
||||
|
||||
sc.MustGetString();
|
||||
sfx = soundEngine->FindSoundTentative(sc.String);
|
||||
sc.MustGetFloat();
|
||||
auto sfxp = soundEngine->GetWritableSfx(sfx);
|
||||
sfxp->DefPitch = (float)pow(2, sc.Float / 1200.);
|
||||
if (sc.CheckFloat())
|
||||
{
|
||||
sfxp->DefPitchMax = (float)pow(2, sc.Float / 1200.);
|
||||
}
|
||||
else
|
||||
{
|
||||
sfxp->DefPitchMax = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SI_ConReserve: {
|
||||
// $conreserve <logical name> <resource id>
|
||||
|
@ -328,34 +348,6 @@ 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 the current game and will be ignored");
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case SI_DukeFlags: {
|
||||
static const char* dukeflags[] = { "LOOP", "MSFX", "TALK", "GLOBAL", nullptr};
|
||||
|
||||
|
|
|
@ -174,19 +174,6 @@ void S_CacheAllSounds(void)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static inline int S_GetPitch(FSoundID soundid)
|
||||
{
|
||||
auto const* snd = soundEngine->GetUserData(soundid);
|
||||
if (!snd) return 0;
|
||||
int const range = abs(snd[kPitchEnd] - snd[kPitchStart]);
|
||||
return (range == 0) ? snd[kPitchStart] : min(snd[kPitchStart], snd[kPitchEnd]) + rand() % range;
|
||||
}
|
||||
|
||||
float S_ConvertPitch(int lpitch)
|
||||
{
|
||||
return powf(2, lpitch / 1200.f); // I hope I got this right that ASS uses a linear scale where 1200 is a full octave.
|
||||
}
|
||||
|
||||
int S_GetUserFlags(FSoundID soundid)
|
||||
{
|
||||
if (!soundEngine->isValidSoundId(soundid)) return 0;
|
||||
|
@ -234,9 +221,6 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit
|
|||
// Set everything to 0 to have default handling.
|
||||
sfx->UserData.Resize(kMaxUserData);
|
||||
auto& sndinf = sfx->UserData;
|
||||
sndinf[kPitchStart] = 0;
|
||||
sndinf[kPitchEnd] = 0;
|
||||
sndinf[kPriority] = 0; // Raze's sound engine does not use this.
|
||||
sndinf[kVolAdjust] = 0;
|
||||
sndinf[kWorldTourMapping] = 0;
|
||||
sndinf[kFlags] = 0;
|
||||
|
@ -261,13 +245,14 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit
|
|||
fn.Substitute(".ogg", ".voc");
|
||||
sfx->lumpnum = S_LookupSound(fn);
|
||||
}
|
||||
sndinf[kPitchStart] = clamp<int>(minpitch, INT16_MIN, INT16_MAX);
|
||||
sndinf[kPitchEnd] = clamp<int>(maxpitch, INT16_MIN, INT16_MAX);
|
||||
sndinf[kPriority] = priority & 255;
|
||||
if (minpitch != 0 || maxpitch != 0)
|
||||
{
|
||||
sfx->DefPitch = (float)pow(2, clamp<int>(minpitch, INT16_MIN, INT16_MAX) / 1200.);
|
||||
sfx->DefPitchMax = (float)pow(2, clamp<int>(maxpitch, INT16_MIN, INT16_MAX) / 1200.);
|
||||
}
|
||||
sndinf[kVolAdjust] = clamp<int>(distance, INT16_MIN, INT16_MAX);
|
||||
sndinf[kWorldTourMapping] = 0;
|
||||
sfx->Volume = volume;
|
||||
//sfx->NearLimit = index == TELEPORTER + 1? 6 : 0; // the teleporter sound cannot be unlimited due to how it gets used.
|
||||
sfx->bTentative = false;
|
||||
return 0;
|
||||
}
|
||||
|
@ -499,25 +484,20 @@ int S_PlaySound3D(FSoundID soundid, DDukeActor* actor, const DVector3& pos, int
|
|||
|
||||
S_GetCamera(&campos, nullptr, &camsect);
|
||||
GetPositionInfo(actor, soundid, camsect, campos, pos, &sndist, &sndpos);
|
||||
int pitch = S_GetPitch(soundid);
|
||||
|
||||
auto sfx = soundEngine->GetSfx(soundid);
|
||||
bool explosion = ((userflags & (SF_GLOBAL | SF_DTAG)) == (SF_GLOBAL | SF_DTAG)) ||
|
||||
((sfx->ResourceId == PIPEBOMB_EXPLODE || sfx->ResourceId == LASERTRIP_EXPLODE || sfx->ResourceId == RPG_EXPLODE));
|
||||
|
||||
bool underwater = ps[screenpeek].insector() && ps[screenpeek].cursector->lotag == ST_2_UNDERWATER;
|
||||
if (explosion)
|
||||
{
|
||||
if (underwater)
|
||||
pitch -= 1024;
|
||||
}
|
||||
else
|
||||
float pitch = 0;
|
||||
if (!explosion)
|
||||
{
|
||||
if (sndist > 32767 && !issoundcontroller(actor) && (userflags & (SF_LOOP | SF_MSFX)) == 0)
|
||||
return -1;
|
||||
|
||||
if (underwater && (userflags & SF_TALK) == 0)
|
||||
pitch = -768;
|
||||
pitch = 0.64f;
|
||||
}
|
||||
|
||||
bool is_playing = soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundid);
|
||||
|
@ -541,8 +521,16 @@ int S_PlaySound3D(FSoundID soundid, DDukeActor* actor, const DVector3& pos, int
|
|||
if (userflags & SF_LOOP) flags |= CHANF_LOOP;
|
||||
float vol = attenuation == ATTN_NONE ? 0.8f : 1.f;
|
||||
if (currentCommentarySound != NO_SOUND) vol *= 0.25f;
|
||||
auto chan = soundEngine->StartSound(SOURCE_Actor, actor, &sndpos, CHAN_AUTO, flags, soundid, vol, attenuation, nullptr, S_ConvertPitch(pitch));
|
||||
if (chan) chan->UserData = (currentCommentarySound != NO_SOUND);
|
||||
auto chan = soundEngine->StartSound(SOURCE_Actor, actor, &sndpos, CHAN_AUTO, flags, soundid, vol, attenuation, nullptr, pitch);
|
||||
if (chan)
|
||||
{
|
||||
if (explosion && underwater)
|
||||
{
|
||||
pitch = chan->Pitch? chan->Pitch * (0.55 / 128) : 0.55; // todo: fix pitch storage in backend.
|
||||
soundEngine->SetPitch(chan, pitch);
|
||||
}
|
||||
chan->UserData = (currentCommentarySound != NO_SOUND);
|
||||
}
|
||||
return chan ? 0 : -1;
|
||||
}
|
||||
|
||||
|
@ -562,11 +550,9 @@ int S_PlaySound(FSoundID soundid, int channel, EChanFlags flags, float vol)
|
|||
if ((!(snd_speech & 1) && (userflags & SF_TALK)))
|
||||
return -1;
|
||||
|
||||
int const pitch = S_GetPitch(soundid);
|
||||
|
||||
if (userflags & SF_LOOP) flags |= CHANF_LOOP;
|
||||
if (currentCommentarySound != NO_SOUND) vol *= 0.25f;
|
||||
auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, soundid, vol, ATTN_NONE, nullptr, S_ConvertPitch(pitch));
|
||||
auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, soundid, vol, ATTN_NONE, nullptr);
|
||||
if (chan) chan->UserData = (currentCommentarySound != NO_SOUND);
|
||||
return chan ? 0 : -1;
|
||||
}
|
||||
|
|
|
@ -26,10 +26,7 @@ enum {
|
|||
|
||||
enum esound_t
|
||||
{
|
||||
kPitchStart,
|
||||
kPitchEnd,
|
||||
kVolAdjust,
|
||||
kPriority,
|
||||
kFlags,
|
||||
kWorldTourMapping,
|
||||
kMaxUserData
|
||||
|
|
Loading…
Reference in a new issue