mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-12 03:00:38 +00:00
Fix issue with explosion sound cutoff in E1L2. This implements functionality to stop playback and free up the voice of a currently playing sound of the same ID when there are already MAXSOUNDINSTANCES (currently 8) of the same sound playing, determined by distance/volume and which sound is oldest.
Initial determination is based purely on distance/volume, and if two qualifying sounds have the same distance/volume the one which started playback first is the one that gets the axe. Feedback from other developers welcome. git-svn-id: https://svn.eduke32.com/eduke32@3065 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
a2ed3682ee
commit
5010b17efe
2 changed files with 61 additions and 20 deletions
|
@ -77,6 +77,7 @@ void S_SoundStartup(void)
|
||||||
g_sounds[i].num = 0;
|
g_sounds[i].num = 0;
|
||||||
g_sounds[i].SoundOwner[j].voice = 0;
|
g_sounds[i].SoundOwner[j].voice = 0;
|
||||||
g_sounds[i].SoundOwner[j].ow = -1;
|
g_sounds[i].SoundOwner[j].ow = -1;
|
||||||
|
g_sounds[i].SoundOwner[j].time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_soundlocks[i] = 199;
|
g_soundlocks[i] = 199;
|
||||||
|
@ -341,6 +342,7 @@ void S_Cleanup(void)
|
||||||
|
|
||||||
g_sounds[num].SoundOwner[j].ow = -1;
|
g_sounds[num].SoundOwner[j].ow = -1;
|
||||||
g_sounds[num].SoundOwner[j].voice = 0;
|
g_sounds[num].SoundOwner[j].voice = 0;
|
||||||
|
g_sounds[num].SoundOwner[j].time = 0;
|
||||||
}
|
}
|
||||||
g_soundlocks[num]--;
|
g_soundlocks[num]--;
|
||||||
}
|
}
|
||||||
|
@ -360,13 +362,19 @@ int32_t S_LoadSound(uint32_t num)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_sounds[num].filename1) fp = kopen4loadfrommod(g_sounds[num].filename1,g_loadFromGroupOnly);
|
if (g_sounds[num].filename1)
|
||||||
if (fp == -1) fp = kopen4loadfrommod(g_sounds[num].filename,g_loadFromGroupOnly);
|
fp = kopen4loadfrommod(g_sounds[num].filename1,g_loadFromGroupOnly);
|
||||||
|
|
||||||
|
if (fp == -1)
|
||||||
|
{
|
||||||
|
fp = kopen4loadfrommod(g_sounds[num].filename,g_loadFromGroupOnly);
|
||||||
|
|
||||||
if (fp == -1)
|
if (fp == -1)
|
||||||
{
|
{
|
||||||
OSD_Printf(OSDTEXT_RED "Sound %s(#%d) not found!\n",g_sounds[num].filename,num);
|
OSD_Printf(OSDTEXT_RED "Sound %s(#%d) not found!\n",g_sounds[num].filename,num);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
g_sounds[num].soundsiz = l = kfilelength(fp);
|
g_sounds[num].soundsiz = l = kfilelength(fp);
|
||||||
|
|
||||||
|
@ -380,31 +388,61 @@ int32_t S_LoadSound(uint32_t num)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int32_t get_sound_pitch(int32_t num)
|
static int32_t S_GetPitch(int32_t num)
|
||||||
{
|
{
|
||||||
int32_t j = klabs(g_sounds[num].pe-g_sounds[num].ps);
|
int32_t j = klabs(g_sounds[num].pe-g_sounds[num].ps);
|
||||||
|
|
||||||
if (j)
|
if (j)
|
||||||
return min(g_sounds[num].ps, g_sounds[num].pe) + rand()%j;
|
return min(g_sounds[num].ps, g_sounds[num].pe) + rand()%j;
|
||||||
else
|
|
||||||
return g_sounds[num].ps;
|
return g_sounds[num].ps;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int32_t find_free_slot(int32_t num)
|
static int32_t S_FindSlot(int32_t num)
|
||||||
{
|
{
|
||||||
int32_t j = 0;
|
int32_t j = 0;
|
||||||
|
|
||||||
while (j < MAXSOUNDINSTANCES && g_sounds[num].SoundOwner[j].voice > 0)
|
while (j < MAXSOUNDINSTANCES && g_sounds[num].SoundOwner[j].voice > 0)
|
||||||
j++;
|
j++;
|
||||||
|
|
||||||
|
if (j == MAXSOUNDINSTANCES)
|
||||||
|
{
|
||||||
|
uint32_t time = totalclock;
|
||||||
|
int32_t i = 0;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
while (j < MAXSOUNDINSTANCES && g_sounds[num].SoundOwner[j].voice > 0)
|
||||||
|
{
|
||||||
|
if (g_sounds[num].SoundOwner[j].time <= time)
|
||||||
|
{
|
||||||
|
time = g_sounds[num].SoundOwner[j].time;
|
||||||
|
i = j;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j != MAXSOUNDINSTANCES)
|
||||||
|
return j;
|
||||||
|
|
||||||
|
if (FX_SoundActive(g_sounds[num].SoundOwner[i].voice))
|
||||||
|
FX_StopSound(g_sounds[num].SoundOwner[i].voice);
|
||||||
|
|
||||||
|
mutex_lock(&s_mutex);
|
||||||
|
dq[dnum++] = (num * MAXSOUNDINSTANCES) + i;
|
||||||
|
mutex_unlock(&s_mutex);
|
||||||
|
S_Cleanup();
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int32_t get_sound_ang(int32_t camang, const vec3_t *cam, const vec3_t *pos)
|
static inline int32_t S_GetAngle(int32_t camang, const vec3_t *cam, const vec3_t *pos)
|
||||||
{
|
{
|
||||||
int32_t sndang = 2048 + camang - getangle(cam->x-pos->x, cam->y-pos->y);
|
int32_t sndang = 2048 + camang - getangle(cam->x-pos->x, cam->y-pos->y);
|
||||||
sndang &= 2047;
|
return sndang & 2047;
|
||||||
return sndang;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t S_CalcDistAndAng(int32_t i, int32_t num, int32_t camsect, int32_t camang,
|
static int32_t S_CalcDistAndAng(int32_t i, int32_t num, int32_t camsect, int32_t camang,
|
||||||
|
@ -420,7 +458,7 @@ static int32_t S_CalcDistAndAng(int32_t i, int32_t num, int32_t camsect, int32_t
|
||||||
goto sound_further_processing;
|
goto sound_further_processing;
|
||||||
}
|
}
|
||||||
|
|
||||||
sndang = get_sound_ang(camang, cam, pos);
|
sndang = S_GetAngle(camang, cam, pos);
|
||||||
|
|
||||||
sndist = FindDistance3D(cam->x-pos->x, cam->y-pos->y, (cam->z-pos->z)>>4);
|
sndist = FindDistance3D(cam->x-pos->x, cam->y-pos->y, (cam->z-pos->z)>>4);
|
||||||
|
|
||||||
|
@ -446,7 +484,7 @@ static int32_t S_CalcDistAndAng(int32_t i, int32_t num, int32_t camsect, int32_t
|
||||||
camang = g_player[1].ps->ang;
|
camang = g_player[1].ps->ang;
|
||||||
|
|
||||||
sndist = sndist2;
|
sndist = sndist2;
|
||||||
sndang = get_sound_ang(camang, cam, pos);
|
sndang = S_GetAngle(camang, cam, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -500,7 +538,7 @@ int32_t S_PlaySound3D(int32_t num, int32_t i, const vec3_t *pos)
|
||||||
ud.config.FXDevice < 0 ||
|
ud.config.FXDevice < 0 ||
|
||||||
((g_sounds[num].m&8) && ud.lockout) ||
|
((g_sounds[num].m&8) && ud.lockout) ||
|
||||||
ud.config.SoundToggle == 0 ||
|
ud.config.SoundToggle == 0 ||
|
||||||
g_sounds[num].num >= MAXSOUNDINSTANCES ||
|
/* g_sounds[num].num >= MAXSOUNDINSTANCES ||*/
|
||||||
(unsigned)i >= MAXSPRITES ||
|
(unsigned)i >= MAXSPRITES ||
|
||||||
FX_VoiceAvailable(g_sounds[num].pr) == 0 ||
|
FX_VoiceAvailable(g_sounds[num].pr) == 0 ||
|
||||||
(myps->timebeforeexit > 0 && myps->timebeforeexit <= GAMETICSPERSEC*3) ||
|
(myps->timebeforeexit > 0 && myps->timebeforeexit <= GAMETICSPERSEC*3) ||
|
||||||
|
@ -547,7 +585,7 @@ int32_t S_PlaySound3D(int32_t num, int32_t i, const vec3_t *pos)
|
||||||
|
|
||||||
explosionp = S_CalcDistAndAng(i, num, cs, ca, &ud.camera, pos, &sndist, &sndang);
|
explosionp = S_CalcDistAndAng(i, num, cs, ca, &ud.camera, pos, &sndist, &sndang);
|
||||||
|
|
||||||
pitch = get_sound_pitch(num);
|
pitch = S_GetPitch(num);
|
||||||
peekps = g_player[screenpeek].ps;
|
peekps = g_player[screenpeek].ps;
|
||||||
|
|
||||||
if (g_fakeMultiMode==2)
|
if (g_fakeMultiMode==2)
|
||||||
|
@ -589,7 +627,7 @@ int32_t S_PlaySound3D(int32_t num, int32_t i, const vec3_t *pos)
|
||||||
else g_soundlocks[num]++;
|
else g_soundlocks[num]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
j = find_free_slot(num);
|
j = S_FindSlot(num);
|
||||||
|
|
||||||
if (j >= MAXSOUNDINSTANCES)
|
if (j >= MAXSOUNDINSTANCES)
|
||||||
{
|
{
|
||||||
|
@ -623,6 +661,7 @@ int32_t S_PlaySound3D(int32_t num, int32_t i, const vec3_t *pos)
|
||||||
g_sounds[num].num++;
|
g_sounds[num].num++;
|
||||||
g_sounds[num].SoundOwner[j].ow = i;
|
g_sounds[num].SoundOwner[j].ow = i;
|
||||||
g_sounds[num].SoundOwner[j].voice = voice;
|
g_sounds[num].SoundOwner[j].voice = voice;
|
||||||
|
g_sounds[num].SoundOwner[j].time = totalclock;
|
||||||
return voice;
|
return voice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,7 +687,7 @@ int32_t S_PlaySound(int32_t num)
|
||||||
if ((g_sounds[num].m&8) && ud.lockout) return -1;
|
if ((g_sounds[num].m&8) && ud.lockout) return -1;
|
||||||
if (FX_VoiceAvailable(g_sounds[num].pr) == 0) return -1;
|
if (FX_VoiceAvailable(g_sounds[num].pr) == 0) return -1;
|
||||||
|
|
||||||
pitch = get_sound_pitch(num);
|
pitch = S_GetPitch(num);
|
||||||
|
|
||||||
if (g_sounds[num].ptr == 0)
|
if (g_sounds[num].ptr == 0)
|
||||||
{
|
{
|
||||||
|
@ -662,7 +701,7 @@ int32_t S_PlaySound(int32_t num)
|
||||||
else g_soundlocks[num]++;
|
else g_soundlocks[num]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
j = find_free_slot(num);
|
j = S_FindSlot(num);
|
||||||
|
|
||||||
if (j >= MAXSOUNDINSTANCES) // no slots available, so let's see if one opens up after multivoc kills a voice
|
if (j >= MAXSOUNDINSTANCES) // no slots available, so let's see if one opens up after multivoc kills a voice
|
||||||
doretry = 1;
|
doretry = 1;
|
||||||
|
@ -682,7 +721,7 @@ int32_t S_PlaySound(int32_t num)
|
||||||
{
|
{
|
||||||
S_Cleanup();
|
S_Cleanup();
|
||||||
|
|
||||||
j = find_free_slot(num);
|
j = S_FindSlot(num);
|
||||||
|
|
||||||
if (j >= MAXSOUNDINSTANCES) // still no slots available
|
if (j >= MAXSOUNDINSTANCES) // still no slots available
|
||||||
{
|
{
|
||||||
|
@ -696,6 +735,7 @@ int32_t S_PlaySound(int32_t num)
|
||||||
g_sounds[num].num++;
|
g_sounds[num].num++;
|
||||||
g_sounds[num].SoundOwner[j].ow = -1;
|
g_sounds[num].SoundOwner[j].ow = -1;
|
||||||
g_sounds[num].SoundOwner[j].voice = voice;
|
g_sounds[num].SoundOwner[j].voice = voice;
|
||||||
|
g_sounds[num].SoundOwner[j].time = totalclock;
|
||||||
return voice;
|
return voice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
int16_t voice;
|
int16_t voice;
|
||||||
int16_t ow;
|
int16_t ow;
|
||||||
|
uint32_t time;
|
||||||
} SOUNDOWNER;
|
} SOUNDOWNER;
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
int32_t length, num, soundsiz; // 12b
|
int32_t length, num, soundsiz; // 12b
|
||||||
char *filename, *ptr, *filename1; // 12b/24b
|
char *filename, *ptr, *filename1; // 12b/24b
|
||||||
SOUNDOWNER SoundOwner[MAXSOUNDINSTANCES]; // 32b
|
SOUNDOWNER SoundOwner[MAXSOUNDINSTANCES]; // 64b
|
||||||
int16_t ps,pe,vo; // 6b
|
int16_t ps,pe,vo; // 6b
|
||||||
char pr,m; // 2b
|
char pr,m; // 2b
|
||||||
} sound_t;
|
} sound_t;
|
||||||
|
|
Loading…
Reference in a new issue