
Spoiler: tl;drFor a long time I've been bugged by the odd fact that (in ZDoom) certain sounds [wiki=Classes:Sorcerer2]D'Sparil[/wiki] and [wiki=Classes:Sorcerer1]his serpent[/wiki] make play on the entire map while others do not. But my ancient memory tells me he did in fact play all sounds (except pain) on the entire map. Specifically dsparil/attack and dsparil/active (and */sight when called through A_Look) always play on the entire map while the other dsparil/* sounds don't.
Instead of testing whether my memory was to be trusted by trying to play Heretic in DOSBox, I've decided to look at Heretic's source code and previous ZDoom revisions.
In Heretic's source code's P_ENEMY.C we have this:
Code: Select all
//----------------------------------------------------------------------------
//
// D'Sparil Sound Routines
//
//----------------------------------------------------------------------------
void A_SorZap(mobj_t *actor) {S_StartSound(NULL, sfx_sorzap);}
void A_SorRise(mobj_t *actor) {S_StartSound(NULL, sfx_sorrise);}
void A_SorDSph(mobj_t *actor) {S_StartSound(NULL, sfx_sordsph);}
void A_SorDExp(mobj_t *actor) {S_StartSound(NULL, sfx_sordexp);}
void A_SorDBon(mobj_t *actor) {S_StartSound(NULL, sfx_sordbon);}
void A_SorSightSnd(mobj_t *actor) {S_StartSound(NULL, sfx_sorsit);}
While S_StartSound(*insert actor here*, *insert sound here*) is kind of like ZDoom's S_Sound (self/*insert actor here*, *insert channel here*, *insert sound here*, 1, ATTN_NORM) (I came to this conclusion by comparing Heretic's A_Look in P_ENEMY.C with ZDoom's)
Looking back at previous revisions, trying the find the point when all Heretic actors were converted to DECORATE, I stumbled upon r1077(from 2008; 5 years ago).
At the bottom of r1077's a_dsparil.cpp we have this:
Code: Select all
//----------------------------------------------------------------------------
//
// D'Sparil Sound Routines
//
//----------------------------------------------------------------------------
void A_SorZap (AActor *actor) {S_Sound (actor, CHAN_BODY, "dsparil/zap", 1, ATTN_NONE);}
void A_SorRise (AActor *actor) {S_Sound (actor, CHAN_BODY, "dsparil/rise", 1, ATTN_NONE);}
void A_SorDSph (AActor *actor) {S_Sound (actor, CHAN_BODY, "dsparil/scream", 1, ATTN_NONE);}
void A_SorDExp (AActor *actor) {S_Sound (actor, CHAN_BODY, "dsparil/explode", 1, ATTN_NONE);}
void A_SorDBon (AActor *actor) {S_Sound (actor, CHAN_BODY, "dsparil/bones", 1, ATTN_NONE);}
void A_SorSightSnd (AActor *actor) {S_Sound (actor, CHAN_BODY, "dsparil/sight", 1, ATTN_NONE);}
All of these were converted into generic code pointers with each (respectively) looking like this:
Code: Select all
A_PlaySoundEx("dsparil/zap", "body")
A_PlaySoundEx("dsparil/rise", "Body")
A_PlaySoundEx("dsparil/scream", "Body")
A_PlaySoundEx("dsparil/explode", "Body")
A_PlaySoundEx("dsparil/bones", "Body")
A_PlaySoundEx("dsparil/sight", "Body")
Code: Select all
action native A_PlaySoundEx(sound whattoplay, coerce name slot, bool looping = false, int attenuation = 0);
thingdef_codeptr.cpp: (In the present, of course)
Code: Select all
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PlaySoundEx)
{
ACTION_PARAM_START(4);
ACTION_PARAM_SOUND(soundid, 0);
ACTION_PARAM_NAME(channel, 1);
ACTION_PARAM_BOOL(looping, 2);
ACTION_PARAM_INT(attenuation_raw, 3);
float attenuation;
switch (attenuation_raw)
{
case -1: attenuation = ATTN_STATIC; break; // drop off rapidly
default:
case 0: attenuation = ATTN_NORM; break; // normal
case 1:
case 2: attenuation = ATTN_NONE; break; // full volume
}
if (channel < NAME_Auto || channel > NAME_SoundSlot7)
{
channel = NAME_Auto;
}
if (!looping)
{
S_Sound (self, int(channel) - NAME_Auto, soundid, 1, attenuation);
}
else
{
if (!S_IsActorPlayingSomething (self, int(channel) - NAME_Auto, soundid))
{
S_Sound (self, (int(channel) - NAME_Auto) | CHAN_LOOP, soundid, 1, attenuation);
}
}
}
My proposed fix would be either this:
Code: Select all
A_PlaySoundEx("dsparil/zap", "body", false, 1)
A_PlaySoundEx("dsparil/rise", "Body", false, 1)
A_PlaySoundEx("dsparil/scream", "Body", false, 1)
A_PlaySoundEx("dsparil/explode", "Body", false, 1)
A_PlaySoundEx("dsparil/bones", "Body", false, 1)
A_PlaySoundEx("dsparil/sight", "Body", false, 1)
Code: Select all
A_PlaySound("dsparil/zap", CHAN_BODY, 1.0, false, ATTN_NONE)
A_PlaySound("dsparil/rise", CHAN_BODY, 1.0, false, ATTN_NONE)
A_PlaySound("dsparil/scream", CHAN_BODY, 1.0, false, ATTN_NONE)
A_PlaySound("dsparil/explode", CHAN_BODY, 1.0, false, ATTN_NONE)
A_PlaySound("dsparil/bones", CHAN_BODY, 1.0, false, ATTN_NONE)
A_PlaySound("dsparil/sight", CHAN_BODY, 1.0, false, ATTN_NONE)