mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-09-22 03:12:00 -04:00
Sound tweaks (#2215)
* Remove unused idnum tracking * Seamlessly pause and resume sounds Side effect: No more chainsaw "rev up" sound when pausing game. * Update listener before updating sound sources Make sure the sound sources are fed the latest listener data. This shouldn't matter with the call to I_DeferSoundUpdates, but just in case. * Skip unnecessary listener calculations No need to constantly update the listener when the menu is open (single player only), the game is paused, or no game is being played. * Fix initial mobj->oldz when spawning mobj mobj->oldz should be set after mobj->z is initialized. See Crispy Doom. * Improve doppler effect for listener Uses the correct velocity calculation. * Improve doppler effect for sources Uses the correct velocity calculation. * Adjust doppler effect scaling range With the changes made to the velocity calculations, the doppler effect thermo should be linear (0.0 to 2.0, 0.2 steps). * Defer doppler effect thermo action Resetting the OpenAL 3D sound module is slow. * Use a standard map units to meters conversion factor 16 map units per foot or 0.01905 meters per map unit (https://www.doomworld.com/idgames/docs/editing/metrics). Same as the speedometer widget. * Misc. sound refactoring * Use parameters structure for sound functions * Improve sound curve Sound attenuation over distance is now more gradual when using the OpenAL 3D sound module. Previously, there was a more pronounced drop off near the sound distance limit. This uses a different roll-off factor, so the air absorption factor has been adjusted to preserve the same effect as before. * Reduce PC speaker square wave amplitude It was way too loud in comparison to the other sound modules.
This commit is contained in:
parent
4681e5aeb2
commit
4fcf30323d
19
src/g_game.c
19
src/g_game.c
@ -1321,9 +1321,15 @@ boolean G_Responder(event_t* ev)
|
||||
if (M_InputActivated(input_pause))
|
||||
{
|
||||
if (paused ^= 2)
|
||||
{
|
||||
S_PauseSound();
|
||||
S_PauseMusic();
|
||||
}
|
||||
else
|
||||
{
|
||||
S_ResumeSound();
|
||||
S_ResumeMusic();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1343,7 +1349,6 @@ boolean G_Responder(event_t* ev)
|
||||
((ev->type == ev_keydown) ||
|
||||
(ev->type == ev_mouseb_down) ||
|
||||
(ev->type == ev_joyb_down)) ?
|
||||
(!menuactive ? S_StartSound(NULL,sfx_swtchn) : true),
|
||||
MN_StartControlPanel(), true : false;
|
||||
}
|
||||
|
||||
@ -2992,9 +2997,15 @@ void G_Ticker(void)
|
||||
|
||||
case BTS_PAUSE:
|
||||
if ((paused ^= 1))
|
||||
S_PauseSound();
|
||||
{
|
||||
S_PauseSound();
|
||||
S_PauseMusic();
|
||||
}
|
||||
else
|
||||
S_ResumeSound();
|
||||
{
|
||||
S_ResumeSound();
|
||||
S_ResumeMusic();
|
||||
}
|
||||
break;
|
||||
|
||||
case BTS_SAVEGAME:
|
||||
@ -3892,7 +3903,7 @@ void G_InitNew(skill_t skill, int episode, int map)
|
||||
if (paused)
|
||||
{
|
||||
paused = false;
|
||||
S_ResumeSound();
|
||||
S_ResumeMusic();
|
||||
}
|
||||
|
||||
if (skill > sk_nightmare)
|
||||
|
128
src/i_3dsound.c
128
src/i_3dsound.c
@ -45,7 +45,7 @@ typedef struct oal_source_params_s
|
||||
{
|
||||
ALfloat position[3];
|
||||
ALfloat velocity[3];
|
||||
boolean use_3d;
|
||||
boolean positional;
|
||||
boolean point_source;
|
||||
fixed_t z;
|
||||
} oal_source_params_t;
|
||||
@ -86,11 +86,14 @@ static void CalcListenerParams(const mobj_t *listener,
|
||||
lis->position[1] = FIXED_TO_ALFLOAT(player->viewz);
|
||||
lis->position[2] = FIXED_TO_ALFLOAT(-listener->y);
|
||||
|
||||
if (oal_use_doppler)
|
||||
if (oal_use_doppler && listener->interp == true)
|
||||
{
|
||||
lis->velocity[0] = FIXED_TO_ALFLOAT(listener->momx) * TICRATE;
|
||||
lis->velocity[1] = FIXED_TO_ALFLOAT(listener->momz) * TICRATE;
|
||||
lis->velocity[2] = FIXED_TO_ALFLOAT(-listener->momy) * TICRATE;
|
||||
lis->velocity[0] =
|
||||
FIXED_TO_ALFLOAT(listener->x - listener->oldx) * TICRATE;
|
||||
lis->velocity[1] =
|
||||
FIXED_TO_ALFLOAT(listener->z - listener->oldz) * TICRATE;
|
||||
lis->velocity[2] =
|
||||
FIXED_TO_ALFLOAT(listener->oldy - listener->y) * TICRATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -137,12 +140,14 @@ static void CalcSourceParams(const mobj_t *source, oal_source_params_t *src)
|
||||
src->position[1] = FIXED_TO_ALFLOAT(src->z);
|
||||
src->position[2] = FIXED_TO_ALFLOAT(-source->y);
|
||||
|
||||
// Doppler effect only applies to monsters and projectiles.
|
||||
if (oal_use_doppler && src->point_source)
|
||||
// Doppler effect only applies to projectiles and other players.
|
||||
if (oal_use_doppler && src->point_source && source->interp == true
|
||||
&& (source->flags & (MF_MISSILE | MF_SKULLFLY)
|
||||
|| source->type == MT_PLAYER))
|
||||
{
|
||||
src->velocity[0] = FIXED_TO_ALFLOAT(source->momx) * TICRATE;
|
||||
src->velocity[1] = FIXED_TO_ALFLOAT(source->momz) * TICRATE;
|
||||
src->velocity[2] = FIXED_TO_ALFLOAT(-source->momy) * TICRATE;
|
||||
src->velocity[0] = FIXED_TO_ALFLOAT(source->x - source->oldx) * TICRATE;
|
||||
src->velocity[1] = FIXED_TO_ALFLOAT(source->z - source->oldz) * TICRATE;
|
||||
src->velocity[2] = FIXED_TO_ALFLOAT(source->oldy - source->y) * TICRATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -152,11 +157,11 @@ static void CalcSourceParams(const mobj_t *source, oal_source_params_t *src)
|
||||
}
|
||||
}
|
||||
|
||||
static void CalcHypotenuse(fixed_t adx, fixed_t ady, fixed_t *dist)
|
||||
static void CalcHypotenuse(int adx, int ady, int *dist)
|
||||
{
|
||||
if (ady > adx)
|
||||
{
|
||||
const fixed_t temp = adx;
|
||||
const int temp = adx;
|
||||
adx = ady;
|
||||
ady = temp;
|
||||
}
|
||||
@ -174,24 +179,22 @@ static void CalcHypotenuse(fixed_t adx, fixed_t ady, fixed_t *dist)
|
||||
}
|
||||
|
||||
static void CalcDistance(const mobj_t *listener, const mobj_t *source,
|
||||
oal_source_params_t *src, fixed_t *dist)
|
||||
oal_source_params_t *src, int *dist)
|
||||
{
|
||||
const fixed_t adx =
|
||||
abs((listener->x >> FRACBITS) - (source->x >> FRACBITS));
|
||||
const fixed_t ady =
|
||||
abs((listener->y >> FRACBITS) - (source->y >> FRACBITS));
|
||||
fixed_t distxy;
|
||||
const int adx = abs((listener->x >> FRACBITS) - (source->x >> FRACBITS));
|
||||
const int ady = abs((listener->y >> FRACBITS) - (source->y >> FRACBITS));
|
||||
int distxy;
|
||||
|
||||
CalcHypotenuse(adx, ady, &distxy);
|
||||
|
||||
// Treat monsters and projectiles as point sources.
|
||||
// Treat monsters, projectiles, and other players as point sources.
|
||||
src->point_source =
|
||||
(source->thinker.function.p1 != (actionf_p1)P_DegenMobjThinker
|
||||
&& source->info && source->actualheight);
|
||||
|
||||
if (src->point_source)
|
||||
{
|
||||
fixed_t adz;
|
||||
int adz;
|
||||
// Vertical distance is from player's view to middle of source's sprite.
|
||||
src->z = source->z + (source->actualheight >> 1);
|
||||
adz = abs((listener->player->viewz >> FRACBITS) - (src->z >> FRACBITS));
|
||||
@ -206,104 +209,79 @@ static void CalcDistance(const mobj_t *listener, const mobj_t *source,
|
||||
}
|
||||
}
|
||||
|
||||
static boolean CalcVolumePriority(fixed_t dist, int *vol, int *pri)
|
||||
static boolean CalcVolumePriority(int dist, sfxparams_t *params)
|
||||
{
|
||||
int pri_volume;
|
||||
|
||||
if (dist == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (dist >= (S_CLIPPING_DIST >> FRACBITS))
|
||||
else if (dist >= S_CLIPPING_DIST)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (dist <= (S_CLOSE_DIST >> FRACBITS))
|
||||
{
|
||||
pri_volume = *vol;
|
||||
}
|
||||
else if (dist > S_ATTENUATOR)
|
||||
else if (dist > S_CLOSE_DIST)
|
||||
{
|
||||
// OpenAL inverse distance model never reaches zero volume. Gradually
|
||||
// ramp down the volume as the distance approaches the limit.
|
||||
pri_volume = *vol * ((S_CLIPPING_DIST >> FRACBITS) - dist)
|
||||
/ (S_CLOSE_DIST >> FRACBITS);
|
||||
*vol = pri_volume;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Range where OpenAL inverse distance model applies. Calculate volume
|
||||
// for priority bookkeeping but let OpenAL handle the real volume.
|
||||
// Simplify formula for OAL_ROLLOFF_FACTOR = 1:
|
||||
pri_volume = *vol * (S_CLOSE_DIST >> FRACBITS) / dist;
|
||||
params->volume =
|
||||
params->volume * (S_CLIPPING_DIST - dist) / S_ATTENUATOR;
|
||||
}
|
||||
|
||||
// Decrease priority with volume attenuation.
|
||||
*pri += (127 - pri_volume);
|
||||
params->priority += (127 - params->volume);
|
||||
|
||||
if (*pri > 255)
|
||||
if (params->priority > 255)
|
||||
{
|
||||
*pri = 255;
|
||||
params->priority = 255;
|
||||
}
|
||||
|
||||
return (pri_volume > 0);
|
||||
}
|
||||
|
||||
static boolean ScaleVolume(int chanvol, int *vol)
|
||||
{
|
||||
*vol = (snd_SfxVolume * chanvol) / 15;
|
||||
|
||||
if (*vol < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (*vol > 127)
|
||||
{
|
||||
*vol = 127;
|
||||
}
|
||||
|
||||
return true;
|
||||
return (params->volume > 0);
|
||||
}
|
||||
|
||||
static boolean I_3D_AdjustSoundParams(const mobj_t *listener,
|
||||
const mobj_t *source, int chanvol,
|
||||
int *vol, int *sep, int *pri)
|
||||
const mobj_t *source, sfxparams_t *params)
|
||||
{
|
||||
fixed_t dist;
|
||||
int dist;
|
||||
|
||||
if (!ScaleVolume(chanvol, vol))
|
||||
params->volume = snd_SfxVolume * params->volume_scale / 15;
|
||||
|
||||
if (params->volume < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (params->volume > 127)
|
||||
{
|
||||
params->volume = 127;
|
||||
}
|
||||
|
||||
if (!source || source == players[displayplayer].mo || !listener
|
||||
|| !listener->player)
|
||||
{
|
||||
src.use_3d = false;
|
||||
src.positional = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
CalcDistance(listener, source, &src, &dist);
|
||||
|
||||
if (!CalcVolumePriority(dist, vol, pri))
|
||||
if (!CalcVolumePriority(dist, params))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
src.use_3d = true;
|
||||
src.positional = true;
|
||||
CalcSourceParams(source, &src);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void I_3D_UpdateSoundParams(int channel, int volume, int separation)
|
||||
static void I_3D_UpdateSoundParams(int channel, const sfxparams_t *params)
|
||||
{
|
||||
if (src.use_3d)
|
||||
if (src.positional)
|
||||
{
|
||||
I_OAL_UpdateSourceParams(channel, src.position, src.velocity);
|
||||
}
|
||||
|
||||
I_OAL_SetVolume(channel, volume);
|
||||
I_OAL_SetVolume(channel, params->volume);
|
||||
}
|
||||
|
||||
static void I_3D_UpdateListenerParams(const mobj_t *listener)
|
||||
@ -315,13 +293,20 @@ static void I_3D_UpdateListenerParams(const mobj_t *listener)
|
||||
return;
|
||||
}
|
||||
|
||||
// Only update when listener is moving.
|
||||
if ((menuactive && !netgame && !demoplayback) || paused
|
||||
|| gamestate != GS_LEVEL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CalcListenerParams(listener, &lis);
|
||||
I_OAL_UpdateListenerParams(lis.position, lis.velocity, lis.orientation);
|
||||
}
|
||||
|
||||
static boolean I_3D_StartSound(int channel, sfxinfo_t *sfx, float pitch)
|
||||
{
|
||||
if (src.use_3d)
|
||||
if (src.positional)
|
||||
{
|
||||
I_OAL_ResetSource3D(channel, src.point_source);
|
||||
}
|
||||
@ -354,7 +339,10 @@ const sound_module_t sound_3d_module =
|
||||
I_3D_UpdateListenerParams,
|
||||
I_3D_StartSound,
|
||||
I_OAL_StopSound,
|
||||
I_OAL_PauseSound,
|
||||
I_OAL_ResumeSound,
|
||||
I_OAL_SoundIsPlaying,
|
||||
I_OAL_SoundIsPaused,
|
||||
I_OAL_ShutdownSound,
|
||||
I_OAL_ShutdownModule,
|
||||
I_OAL_DeferUpdates,
|
||||
|
@ -28,30 +28,31 @@
|
||||
#include "m_fixed.h"
|
||||
#include "p_mobj.h"
|
||||
#include "r_main.h"
|
||||
#include "sounds.h"
|
||||
#include "tables.h"
|
||||
|
||||
static boolean force_flip_pan;
|
||||
|
||||
static boolean I_MBF_AdjustSoundParams(const mobj_t *listener,
|
||||
const mobj_t *source, int chanvol,
|
||||
int *vol, int *sep, int *pri)
|
||||
const mobj_t *source,
|
||||
sfxparams_t *params)
|
||||
{
|
||||
fixed_t adx, ady, dist;
|
||||
int adx, ady, dist;
|
||||
angle_t angle;
|
||||
|
||||
// haleyjd 05/29/06: allow per-channel volume scaling
|
||||
*vol = (snd_SfxVolume * chanvol) / 15;
|
||||
params->volume = snd_SfxVolume * params->volume_scale / 15;
|
||||
|
||||
if (*vol < 1)
|
||||
if (params->volume < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (*vol > 127)
|
||||
else if (params->volume > 127)
|
||||
{
|
||||
*vol = 127;
|
||||
params->volume = 127;
|
||||
}
|
||||
|
||||
*sep = NORM_SEP;
|
||||
params->separation = NORM_SEP;
|
||||
|
||||
if (!source || source == players[displayplayer].mo)
|
||||
{
|
||||
@ -75,20 +76,28 @@ static boolean I_MBF_AdjustSoundParams(const mobj_t *listener,
|
||||
|
||||
if (ady > adx)
|
||||
{
|
||||
dist = adx, adx = ady, ady = dist;
|
||||
const int temp = adx;
|
||||
adx = ady;
|
||||
ady = temp;
|
||||
}
|
||||
|
||||
dist = adx ? FixedDiv(
|
||||
adx, finesine[(tantoangle[FixedDiv(ady, adx) >> DBITS] + ANG90)
|
||||
>> ANGLETOFINESHIFT])
|
||||
: 0;
|
||||
if (adx)
|
||||
{
|
||||
const int slope = FixedDiv(ady, adx) >> DBITS;
|
||||
const int angle = tantoangle[slope] >> ANGLETOFINESHIFT;
|
||||
dist = FixedDiv(adx, finecosine[angle]);
|
||||
}
|
||||
else
|
||||
{
|
||||
dist = 0;
|
||||
}
|
||||
|
||||
if (!dist) // killough 11/98: handle zero-distance as special case
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (dist > S_CLIPPING_DIST >> FRACBITS)
|
||||
if (dist >= S_CLIPPING_DIST)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -107,35 +116,38 @@ static boolean I_MBF_AdjustSoundParams(const mobj_t *listener,
|
||||
angle >>= ANGLETOFINESHIFT;
|
||||
|
||||
// stereo separation
|
||||
*sep = NORM_SEP - FixedMul(S_STEREO_SWING >> FRACBITS, finesine[angle]);
|
||||
params->separation -= FixedMul(S_STEREO_SWING, finesine[angle]);
|
||||
}
|
||||
|
||||
// volume calculation
|
||||
if (dist > S_CLOSE_DIST >> FRACBITS)
|
||||
if (dist > S_CLOSE_DIST)
|
||||
{
|
||||
*vol = *vol * ((S_CLIPPING_DIST >> FRACBITS) - dist) / S_ATTENUATOR;
|
||||
params->volume =
|
||||
params->volume * (S_CLIPPING_DIST - dist) / S_ATTENUATOR;
|
||||
}
|
||||
|
||||
// haleyjd 09/27/06: decrease priority with volume attenuation
|
||||
*pri = *pri + (127 - *vol);
|
||||
params->priority += (127 - params->volume);
|
||||
|
||||
if (*pri > 255) // cap to 255
|
||||
if (params->priority > 255) // cap to 255
|
||||
{
|
||||
*pri = 255;
|
||||
params->priority = 255;
|
||||
}
|
||||
|
||||
return (*vol > 0);
|
||||
return (params->volume > 0);
|
||||
}
|
||||
|
||||
void I_MBF_UpdateSoundParams(int channel, int volume, int separation)
|
||||
static void I_MBF_UpdateSoundParams(int channel, const sfxparams_t *params)
|
||||
{
|
||||
int separation = params->separation;
|
||||
|
||||
// SoM 7/1/02: forceFlipPan accounted for here
|
||||
if (force_flip_pan)
|
||||
{
|
||||
separation = 254 - separation;
|
||||
}
|
||||
|
||||
I_OAL_SetVolume(channel, volume);
|
||||
I_OAL_SetVolume(channel, params->volume);
|
||||
I_OAL_SetPan(channel, separation);
|
||||
}
|
||||
|
||||
@ -165,7 +177,10 @@ const sound_module_t sound_mbf_module =
|
||||
NULL,
|
||||
I_OAL_StartSound,
|
||||
I_OAL_StopSound,
|
||||
I_OAL_PauseSound,
|
||||
I_OAL_ResumeSound,
|
||||
I_OAL_SoundIsPlaying,
|
||||
I_OAL_SoundIsPaused,
|
||||
I_OAL_ShutdownSound,
|
||||
I_OAL_ShutdownModule,
|
||||
I_OAL_DeferUpdates,
|
||||
|
@ -39,10 +39,10 @@
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
#define OAL_ROLLOFF_FACTOR 1
|
||||
#define OAL_ROLLOFF_FACTOR 0.5f
|
||||
#define OAL_SPEED_OF_SOUND 343.3f
|
||||
// 128 map units per 3 meters (https://doomwiki.org/wiki/Map_unit).
|
||||
#define OAL_MAP_UNITS_PER_METER (128.0f / 3.0f)
|
||||
// 16 mu/ft (https://www.doomworld.com/idgames/docs/editing/metrics)
|
||||
#define OAL_METERS_PER_MAP_UNIT 0.01905f
|
||||
#define OAL_SOURCE_RADIUS 32.0f
|
||||
#define OAL_DEFAULT_PITCH 1.0f
|
||||
|
||||
@ -248,8 +248,7 @@ void I_OAL_ResetSource2D(int channel)
|
||||
|
||||
alSource3f(oal->sources[channel], AL_POSITION, 0.0f, 0.0f, 0.0f);
|
||||
alSource3f(oal->sources[channel], AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
alSourcei(oal->sources[channel], AL_ROLLOFF_FACTOR, 0);
|
||||
alSourcef(oal->sources[channel], AL_ROLLOFF_FACTOR, 0.0f);
|
||||
alSourcei(oal->sources[channel], AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
}
|
||||
|
||||
@ -272,7 +271,7 @@ void I_OAL_ResetSource3D(int channel, boolean point_source)
|
||||
point_source ? 0.0f : OAL_SOURCE_RADIUS);
|
||||
}
|
||||
|
||||
alSourcei(oal->sources[channel], AL_ROLLOFF_FACTOR, OAL_ROLLOFF_FACTOR);
|
||||
alSourcef(oal->sources[channel], AL_ROLLOFF_FACTOR, OAL_ROLLOFF_FACTOR);
|
||||
alSourcei(oal->sources[channel], AL_SOURCE_RELATIVE, AL_FALSE);
|
||||
}
|
||||
|
||||
@ -337,8 +336,8 @@ static void UpdateUserSoundSettings(void)
|
||||
|
||||
if (oal_snd_module == SND_MODULE_3D)
|
||||
{
|
||||
oal->absorption = (ALfloat)snd_absorption / 2.0f;
|
||||
alDopplerFactor((ALfloat)snd_doppler * snd_doppler / 100.0f);
|
||||
oal->absorption = (ALfloat)snd_absorption;
|
||||
alDopplerFactor((ALfloat)snd_doppler / 5.0f);
|
||||
oal_use_doppler = (snd_doppler > 0);
|
||||
}
|
||||
else
|
||||
@ -359,9 +358,8 @@ static void ResetParams(void)
|
||||
{
|
||||
I_OAL_ResetSource2D(i);
|
||||
alSource3i(oal->sources[i], AL_DIRECTION, 0, 0, 0);
|
||||
alSourcei(oal->sources[i], AL_MAX_DISTANCE, S_ATTENUATOR);
|
||||
alSourcei(oal->sources[i], AL_REFERENCE_DISTANCE,
|
||||
S_CLOSE_DIST >> FRACBITS);
|
||||
alSourcei(oal->sources[i], AL_REFERENCE_DISTANCE, S_CLOSE_DIST);
|
||||
alSourcei(oal->sources[i], AL_MAX_DISTANCE, S_CLIPPING_DIST);
|
||||
}
|
||||
// Spatialization is required even for 2D panning emulation.
|
||||
if (oal->SOFT_source_spatialize)
|
||||
@ -378,12 +376,12 @@ static void ResetParams(void)
|
||||
alListeneriv(AL_ORIENTATION, default_orientation);
|
||||
if (oal->EXT_EFX)
|
||||
{
|
||||
alListenerf(AL_METERS_PER_UNIT, 1.0f / OAL_MAP_UNITS_PER_METER);
|
||||
alListenerf(AL_METERS_PER_UNIT, OAL_METERS_PER_MAP_UNIT);
|
||||
}
|
||||
|
||||
// Context state parameters.
|
||||
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); // OpenAL 1.1 Specs, 3.4.2.
|
||||
alSpeedOfSound(OAL_SPEED_OF_SOUND * OAL_MAP_UNITS_PER_METER);
|
||||
alSpeedOfSound(OAL_SPEED_OF_SOUND / OAL_METERS_PER_MAP_UNIT);
|
||||
|
||||
UpdateUserSoundSettings();
|
||||
}
|
||||
@ -735,6 +733,33 @@ void I_OAL_StopSound(int channel)
|
||||
alSourceStop(oal->sources[channel]);
|
||||
}
|
||||
|
||||
void I_OAL_PauseSound(int channel)
|
||||
{
|
||||
if (!oal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
alSourcePause(oal->sources[channel]);
|
||||
}
|
||||
|
||||
void I_OAL_ResumeSound(int channel)
|
||||
{
|
||||
ALint state;
|
||||
|
||||
if (!oal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
alGetSourcei(oal->sources[channel], AL_SOURCE_STATE, &state);
|
||||
|
||||
if (state == AL_PAUSED)
|
||||
{
|
||||
alSourcePlay(oal->sources[channel]);
|
||||
}
|
||||
}
|
||||
|
||||
boolean I_OAL_SoundIsPlaying(int channel)
|
||||
{
|
||||
ALint state;
|
||||
@ -749,6 +774,20 @@ boolean I_OAL_SoundIsPlaying(int channel)
|
||||
return (state == AL_PLAYING);
|
||||
}
|
||||
|
||||
boolean I_OAL_SoundIsPaused(int channel)
|
||||
{
|
||||
ALint state;
|
||||
|
||||
if (!oal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
alGetSourcei(oal->sources[channel], AL_SOURCE_STATE, &state);
|
||||
|
||||
return (state == AL_PAUSED);
|
||||
}
|
||||
|
||||
void I_OAL_SetVolume(int channel, int volume)
|
||||
{
|
||||
if (!oal)
|
||||
|
@ -62,8 +62,14 @@ boolean I_OAL_StartSound(int channel, struct sfxinfo_s *sfx, float pitch);
|
||||
|
||||
void I_OAL_StopSound(int channel);
|
||||
|
||||
void I_OAL_PauseSound(int channel);
|
||||
|
||||
void I_OAL_ResumeSound(int channel);
|
||||
|
||||
boolean I_OAL_SoundIsPlaying(int channel);
|
||||
|
||||
boolean I_OAL_SoundIsPaused(int channel);
|
||||
|
||||
void I_OAL_SetVolume(int channel, int volume);
|
||||
|
||||
void I_OAL_SetPan(int channel, int separation);
|
||||
|
@ -38,7 +38,7 @@ static LPALBUFFERCALLBACKSOFT alBufferCallbackSOFT;
|
||||
static ALuint callback_buffer;
|
||||
static ALuint callback_source;
|
||||
|
||||
#define SQUARE_WAVE_AMP 0x2000
|
||||
#define SQUARE_WAVE_AMP 0x1000 // Chocolate Doom: 0x2000
|
||||
|
||||
static SDL_mutex *sound_lock;
|
||||
static int mixing_freq;
|
||||
@ -381,10 +381,11 @@ static boolean I_PCS_CacheSound(sfxinfo_t *sfx)
|
||||
}
|
||||
|
||||
static boolean I_PCS_AdjustSoundParams(const mobj_t *listener,
|
||||
const mobj_t *source, int chanvol,
|
||||
int *vol, int *sep, int *pri)
|
||||
const mobj_t *source,
|
||||
sfxparams_t *params)
|
||||
{
|
||||
fixed_t adx, ady, approx_dist;
|
||||
fixed_t adx, ady;
|
||||
int approx_dist;
|
||||
|
||||
if (!source || source == players[displayplayer].mo)
|
||||
{
|
||||
@ -403,9 +404,9 @@ static boolean I_PCS_AdjustSoundParams(const mobj_t *listener,
|
||||
ady = abs(listener->y - source->y);
|
||||
|
||||
// From _GG1_ p.428. Appox. eucledian distance fast.
|
||||
approx_dist = adx + ady - ((adx < ady ? adx : ady) >> 1);
|
||||
approx_dist = (adx + ady - ((adx < ady ? adx : ady) >> 1)) >> FRACBITS;
|
||||
|
||||
if (approx_dist > S_CLIPPING_DIST)
|
||||
if (approx_dist >= S_CLIPPING_DIST)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -413,19 +414,19 @@ static boolean I_PCS_AdjustSoundParams(const mobj_t *listener,
|
||||
// volume calculation
|
||||
if (approx_dist < S_CLOSE_DIST)
|
||||
{
|
||||
*vol = snd_SfxVolume;
|
||||
params->volume = snd_SfxVolume;
|
||||
}
|
||||
else
|
||||
{
|
||||
// distance effect
|
||||
*vol = (snd_SfxVolume * ((S_CLIPPING_DIST - approx_dist) >> FRACBITS))
|
||||
/ S_ATTENUATOR;
|
||||
params->volume =
|
||||
snd_SfxVolume * (S_CLIPPING_DIST - approx_dist) / S_ATTENUATOR;
|
||||
}
|
||||
|
||||
return (*vol > 0);
|
||||
return (params->volume > 0);
|
||||
}
|
||||
|
||||
static void I_PCS_UpdateSoundParams(int channel, int volume, int separation)
|
||||
static void I_PCS_UpdateSoundParams(int channel, const sfxparams_t *params)
|
||||
{
|
||||
// adjust PC Speaker volume
|
||||
alSourcef(callback_source, AL_GAIN, (float)snd_SfxVolume / 15);
|
||||
@ -502,7 +503,10 @@ const sound_module_t sound_pcs_module =
|
||||
NULL,
|
||||
I_PCS_StartSound,
|
||||
I_PCS_StopSound,
|
||||
NULL,
|
||||
NULL,
|
||||
I_PCS_SoundIsPlaying,
|
||||
NULL,
|
||||
I_PCS_ShutdownSound,
|
||||
I_PCS_ShutdownModule,
|
||||
I_OAL_DeferUpdates,
|
||||
|
@ -78,8 +78,6 @@ typedef struct
|
||||
sfxinfo_t *sfx;
|
||||
|
||||
boolean enabled;
|
||||
// haleyjd 06/16/08: unique id number
|
||||
int idnum;
|
||||
} channel_info_t;
|
||||
|
||||
static channel_info_t channelinfo[MAX_CHANNELS];
|
||||
@ -123,14 +121,14 @@ static void StopChannel(int channel)
|
||||
// Returns false if no sound should be played.
|
||||
//
|
||||
boolean I_AdjustSoundParams(const mobj_t *listener, const mobj_t *source,
|
||||
int chanvol, int *vol, int *sep, int *pri)
|
||||
sfxparams_t *params)
|
||||
{
|
||||
if (!snd_init)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return sound_module->AdjustSoundParams(listener, source, chanvol, vol, sep, pri);
|
||||
return sound_module->AdjustSoundParams(listener, source, params);
|
||||
}
|
||||
|
||||
//
|
||||
@ -139,7 +137,7 @@ boolean I_AdjustSoundParams(const mobj_t *listener, const mobj_t *source,
|
||||
// Changes sound parameters in response to stereo panning and relative location
|
||||
// change.
|
||||
//
|
||||
void I_UpdateSoundParams(int channel, int volume, int separation)
|
||||
void I_UpdateSoundParams(int channel, const sfxparams_t *params)
|
||||
{
|
||||
if (!snd_init)
|
||||
{
|
||||
@ -153,7 +151,7 @@ void I_UpdateSoundParams(int channel, int volume, int separation)
|
||||
}
|
||||
#endif
|
||||
|
||||
sound_module->UpdateSoundParams(channel, volume, separation);
|
||||
sound_module->UpdateSoundParams(channel, params);
|
||||
}
|
||||
|
||||
void I_UpdateListenerParams(const mobj_t *listener)
|
||||
@ -262,9 +260,8 @@ int I_GetSfxLumpNum(sfxinfo_t *sfx)
|
||||
// active sounds, which is maintained as a given number
|
||||
// of internal channels. Returns a free channel.
|
||||
//
|
||||
int I_StartSound(sfxinfo_t *sfx, int vol, int sep, int pitch)
|
||||
int I_StartSound(sfxinfo_t *sfx, const sfxparams_t *params, int pitch)
|
||||
{
|
||||
static unsigned int id = 0;
|
||||
int channel;
|
||||
|
||||
if (!snd_init)
|
||||
@ -297,9 +294,8 @@ int I_StartSound(sfxinfo_t *sfx, int vol, int sep, int pitch)
|
||||
|
||||
channelinfo[channel].sfx = sfx;
|
||||
channelinfo[channel].enabled = true;
|
||||
channelinfo[channel].idnum = id++; // give the sound a unique id
|
||||
|
||||
I_UpdateSoundParams(channel, vol, sep);
|
||||
I_UpdateSoundParams(channel, params);
|
||||
|
||||
float step = (pitch == NORM_PITCH) ? 1.0f : steptable[pitch];
|
||||
|
||||
@ -336,6 +332,46 @@ void I_StopSound(int channel)
|
||||
StopChannel(channel);
|
||||
}
|
||||
|
||||
void I_PauseSound(int channel)
|
||||
{
|
||||
if (!snd_init || !sound_module->PauseSound)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (channel < 0 || channel >= MAX_CHANNELS)
|
||||
{
|
||||
I_Error("I_PauseSound: channel out of range");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (channelinfo[channel].enabled)
|
||||
{
|
||||
sound_module->PauseSound(channel);
|
||||
}
|
||||
}
|
||||
|
||||
void I_ResumeSound(int channel)
|
||||
{
|
||||
if (!snd_init || !sound_module->ResumeSound)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (channel < 0 || channel >= MAX_CHANNELS)
|
||||
{
|
||||
I_Error("I_ResumeSound: channel out of range");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (channelinfo[channel].enabled)
|
||||
{
|
||||
sound_module->ResumeSound(channel);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// I_SoundIsPlaying
|
||||
//
|
||||
@ -358,29 +394,21 @@ boolean I_SoundIsPlaying(int channel)
|
||||
return sound_module->SoundIsPlaying(channel);
|
||||
}
|
||||
|
||||
//
|
||||
// I_SoundID
|
||||
//
|
||||
// haleyjd: returns the unique id number assigned to a specific instance
|
||||
// of a sound playing on a given channel. This is required to make sure
|
||||
// that the higher-level sound code doesn't start updating sounds that have
|
||||
// been displaced without it noticing.
|
||||
//
|
||||
int I_SoundID(int channel)
|
||||
boolean I_SoundIsPaused(int channel)
|
||||
{
|
||||
if (!snd_init)
|
||||
if (!snd_init || !sound_module->SoundIsPaused)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (channel < 0 || channel >= MAX_CHANNELS)
|
||||
{
|
||||
I_Error("I_SoundID: channel out of range\n");
|
||||
I_Error("I_SoundIsPaused: channel out of range");
|
||||
}
|
||||
#endif
|
||||
|
||||
return channelinfo[channel].idnum;
|
||||
return sound_module->SoundIsPaused(channel);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
// when to clip out sounds
|
||||
// Does not fit the large outdoor areas.
|
||||
#define S_CLIPPING_DIST (1200 << FRACBITS)
|
||||
#define S_CLIPPING_DIST 1200
|
||||
|
||||
// Distance to origin when sounds should be maxed out.
|
||||
// This should relate to movement clipping resolution
|
||||
@ -39,9 +39,9 @@
|
||||
// killough 12/98: restore original
|
||||
// #define S_CLOSE_DIST (160<<FRACBITS)
|
||||
|
||||
#define S_CLOSE_DIST (200 << FRACBITS)
|
||||
#define S_CLOSE_DIST 200
|
||||
|
||||
#define S_ATTENUATOR ((S_CLIPPING_DIST - S_CLOSE_DIST) >> FRACBITS)
|
||||
#define S_ATTENUATOR (S_CLIPPING_DIST - S_CLOSE_DIST)
|
||||
|
||||
// Adjustable by menu.
|
||||
// [FG] moved here from i_sound.c
|
||||
@ -50,7 +50,7 @@
|
||||
#define NORM_PITCH 128
|
||||
#define NORM_PRIORITY 64
|
||||
#define NORM_SEP 128
|
||||
#define S_STEREO_SWING (96 << FRACBITS)
|
||||
#define S_STEREO_SWING 96
|
||||
|
||||
#define SND_SAMPLERATE 44100
|
||||
|
||||
@ -65,8 +65,8 @@ void I_ShutdownSound(void);
|
||||
//
|
||||
|
||||
struct mobj_s;
|
||||
|
||||
struct sfxinfo_s;
|
||||
struct sfxparams_s;
|
||||
|
||||
typedef struct sound_module_s
|
||||
{
|
||||
@ -75,13 +75,16 @@ typedef struct sound_module_s
|
||||
boolean (*AllowReinitSound)(void);
|
||||
boolean (*CacheSound)(struct sfxinfo_s *sfx);
|
||||
boolean (*AdjustSoundParams)(const struct mobj_s *listener,
|
||||
const struct mobj_s *source, int chanvol,
|
||||
int *vol, int *sep, int *pri);
|
||||
void (*UpdateSoundParams)(int channel, int vol, int sep);
|
||||
const struct mobj_s *source,
|
||||
struct sfxparams_s *params);
|
||||
void (*UpdateSoundParams)(int channel, const struct sfxparams_s *params);
|
||||
void (*UpdateListenerParams)(const struct mobj_s *listener);
|
||||
boolean (*StartSound)(int channel, struct sfxinfo_s *sfx, float pitch);
|
||||
void (*StopSound)(int channel);
|
||||
void (*PauseSound)(int channel);
|
||||
void (*ResumeSound)(int channel);
|
||||
boolean (*SoundIsPlaying)(int channel);
|
||||
boolean (*SoundIsPaused)(int channel);
|
||||
void (*ShutdownSound)(void);
|
||||
void (*ShutdownModule)(void);
|
||||
void (*DeferUpdates)(void);
|
||||
@ -113,32 +116,34 @@ void I_SetChannels(void);
|
||||
int I_GetSfxLumpNum(struct sfxinfo_s *sfxinfo);
|
||||
|
||||
// Starts a sound in a particular sound channel.
|
||||
int I_StartSound(struct sfxinfo_s *sound, int vol, int sep, int pitch);
|
||||
int I_StartSound(struct sfxinfo_s *sound, const struct sfxparams_s *params,
|
||||
int pitch);
|
||||
|
||||
// Stops a sound channel.
|
||||
void I_StopSound(int handle);
|
||||
|
||||
void I_PauseSound(int handle);
|
||||
void I_ResumeSound(int handle);
|
||||
|
||||
// Called by S_*() functions
|
||||
// to see if a channel is still playing.
|
||||
// Returns 0 if no longer playing, 1 if playing.
|
||||
boolean I_SoundIsPlaying(int handle);
|
||||
boolean I_SoundIsPaused(int handle);
|
||||
|
||||
// Outputs adjusted volume, separation, and priority from the sound module.
|
||||
// Returns false if no sound should be played.
|
||||
boolean I_AdjustSoundParams(const struct mobj_s *listener,
|
||||
const struct mobj_s *source, int chanvol, int *vol,
|
||||
int *sep, int *pri);
|
||||
const struct mobj_s *source,
|
||||
struct sfxparams_s *params);
|
||||
|
||||
// Updates the volume, separation,
|
||||
// and pitch of a sound channel.
|
||||
void I_UpdateSoundParams(int handle, int vol, int sep);
|
||||
void I_UpdateSoundParams(int handle, const struct sfxparams_s *params);
|
||||
void I_UpdateListenerParams(const struct mobj_s *listener);
|
||||
void I_DeferSoundUpdates(void);
|
||||
void I_ProcessSoundUpdates(void);
|
||||
|
||||
// haleyjds
|
||||
int I_SoundID(int handle);
|
||||
|
||||
//
|
||||
// MUSIC I/O
|
||||
//
|
||||
|
@ -253,6 +253,22 @@ static void M_ExtHelpNextScreen(int choice);
|
||||
static void M_ExtHelp(int choice);
|
||||
static void M_DrawExtHelp(void);
|
||||
|
||||
static void M_PauseSound(void)
|
||||
{
|
||||
if (!paused && gamestate == GS_LEVEL && !demoplayback && !netgame)
|
||||
{
|
||||
S_PauseSound();
|
||||
}
|
||||
}
|
||||
|
||||
static void M_ResumeSound(void)
|
||||
{
|
||||
if (!paused && gamestate == GS_LEVEL && !demoplayback && !netgame)
|
||||
{
|
||||
S_ResumeSound();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SetNextMenu
|
||||
//
|
||||
@ -1700,12 +1716,14 @@ static void M_QuickLoad(void)
|
||||
{
|
||||
if (netgame && !demoplayback) // killough 5/26/98: add !demoplayback
|
||||
{
|
||||
M_StartSound(sfx_swtchn);
|
||||
M_StartMessage(s_QLOADNET, NULL, false); // Ty 03/27/98 - externalized
|
||||
return;
|
||||
}
|
||||
|
||||
if (demorecording) // killough 5/26/98: exclude during demo recordings
|
||||
{
|
||||
M_StartSound(sfx_swtchn);
|
||||
M_StartMessage("you can't quickload\n"
|
||||
"while recording a demo!\n\n" PRESSKEY,
|
||||
NULL, false); // killough 5/26/98: not externalized
|
||||
@ -1746,6 +1764,7 @@ static void M_EndGameResponse(int ch)
|
||||
quickSaveSlot = -1;
|
||||
|
||||
currentMenu->lastOn = itemOn;
|
||||
S_StopChannels();
|
||||
MN_ClearMenus();
|
||||
D_StartTitle();
|
||||
}
|
||||
@ -2168,6 +2187,7 @@ void MN_ClearMenus(void)
|
||||
|
||||
I_SetSensorEventState(false);
|
||||
G_ClearInput();
|
||||
M_ResumeSound();
|
||||
}
|
||||
|
||||
static boolean MenuBack(void)
|
||||
@ -2437,19 +2457,15 @@ boolean M_ShortcutResponder(const event_t *ev)
|
||||
if (M_InputActivated(input_help)) // Help key
|
||||
{
|
||||
MN_StartControlPanel();
|
||||
|
||||
currentMenu = &HelpDef; // killough 10/98: new help screen
|
||||
|
||||
currentMenu->prevMenu = NULL;
|
||||
itemOn = 0;
|
||||
M_StartSound(sfx_swtchn);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (M_InputActivated(input_savegame)) // Save Game
|
||||
{
|
||||
MN_StartControlPanel();
|
||||
M_StartSound(sfx_swtchn);
|
||||
M_SaveGame(0);
|
||||
return true;
|
||||
}
|
||||
@ -2457,7 +2473,6 @@ boolean M_ShortcutResponder(const event_t *ev)
|
||||
if (M_InputActivated(input_loadgame)) // Load Game
|
||||
{
|
||||
MN_StartControlPanel();
|
||||
M_StartSound(sfx_swtchn);
|
||||
M_LoadGame(0);
|
||||
return true;
|
||||
}
|
||||
@ -2467,19 +2482,18 @@ boolean M_ShortcutResponder(const event_t *ev)
|
||||
MN_StartControlPanel();
|
||||
currentMenu = &SoundDef;
|
||||
itemOn = currentMenu->lastOn;
|
||||
M_StartSound(sfx_swtchn);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (M_InputActivated(input_quicksave)) // Quicksave
|
||||
{
|
||||
M_StartSound(sfx_swtchn);
|
||||
M_QuickSave();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (M_InputActivated(input_endgame)) // End game
|
||||
{
|
||||
M_PauseSound();
|
||||
M_StartSound(sfx_swtchn);
|
||||
M_EndGame(0);
|
||||
return true;
|
||||
@ -2494,13 +2508,13 @@ boolean M_ShortcutResponder(const event_t *ev)
|
||||
|
||||
if (M_InputActivated(input_quickload)) // Quickload
|
||||
{
|
||||
M_StartSound(sfx_swtchn);
|
||||
M_QuickLoad();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (M_InputActivated(input_quit)) // Quit DOOM
|
||||
{
|
||||
M_PauseSound();
|
||||
M_StartSound(sfx_swtchn);
|
||||
M_QuitDOOM(0);
|
||||
return true;
|
||||
@ -3088,6 +3102,7 @@ boolean M_Responder(event_t *ev)
|
||||
I_SetSensorEventState(false);
|
||||
G_ClearInput();
|
||||
menuactive = false;
|
||||
M_ResumeSound();
|
||||
M_StartSound(sfx_swtchx);
|
||||
return true;
|
||||
}
|
||||
@ -3117,7 +3132,6 @@ boolean M_Responder(event_t *ev)
|
||||
{
|
||||
I_ShowMouseCursor(menu_input != pad_mode);
|
||||
MN_StartControlPanel();
|
||||
M_StartSound(sfx_swtchn);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -3372,6 +3386,9 @@ void MN_StartControlPanel(void)
|
||||
|
||||
I_SetSensorEventState(true);
|
||||
G_ClearInput();
|
||||
|
||||
M_PauseSound();
|
||||
M_StartSound(sfx_swtchn);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2588,7 +2588,7 @@ static setup_menu_t sfx_settings1[] = {
|
||||
|
||||
MI_GAP,
|
||||
|
||||
{"Doppler Effect", S_THERMO, CNTR_X, M_THRM_SPC, {"snd_doppler"},
|
||||
{"Doppler Effect", S_THERMO | S_ACTION, CNTR_X, M_THRM_SPC, {"snd_doppler"},
|
||||
.strings_id = str_percent, .action = SetSoundModule},
|
||||
|
||||
MI_END
|
||||
|
18
src/p_mobj.c
18
src/p_mobj.c
@ -870,15 +870,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||
// NULL head of sector list // phares 3/13/98
|
||||
mobj->touching_sectorlist = NULL;
|
||||
|
||||
// [AM] Do not interpolate on spawn.
|
||||
mobj->interp = false;
|
||||
|
||||
// [AM] Just in case interpolation is attempted...
|
||||
mobj->oldx = mobj->x;
|
||||
mobj->oldy = mobj->y;
|
||||
mobj->oldz = mobj->z;
|
||||
mobj->oldangle = mobj->angle;
|
||||
|
||||
// set subsector and/or block links
|
||||
|
||||
P_SetThingPosition(mobj);
|
||||
@ -890,6 +881,15 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||
mobj->z = z == ONFLOORZ ? mobj->floorz : z == ONCEILINGZ ?
|
||||
mobj->ceilingz - mobj->height : z;
|
||||
|
||||
// [AM] Do not interpolate on spawn.
|
||||
mobj->interp = false;
|
||||
|
||||
// [AM] Just in case interpolation is attempted...
|
||||
mobj->oldx = mobj->x;
|
||||
mobj->oldy = mobj->y;
|
||||
mobj->oldz = mobj->z;
|
||||
mobj->oldangle = mobj->angle;
|
||||
|
||||
mobj->thinker.function.p1 = (actionf_p1)P_MobjThinker;
|
||||
mobj->above_thing = mobj->below_thing = 0; // phares
|
||||
|
||||
|
113
src/s_sound.c
113
src/s_sound.c
@ -46,12 +46,11 @@ typedef struct channel_s
|
||||
{
|
||||
sfxinfo_t *sfxinfo; // sound information (if null, channel avail.)
|
||||
const mobj_t *origin; // origin of sound
|
||||
int volume; // volume scale value for effect -- haleyjd 05/29/06
|
||||
int volume_scale; // volume scale value for effect -- haleyjd 05/29/06
|
||||
int handle; // handle of the sound being played
|
||||
int o_priority; // haleyjd 09/27/06: stored priority value
|
||||
int priority; // current priority value
|
||||
int singularity; // haleyjd 09/27/06: stored singularity value
|
||||
int idnum; // haleyjd 09/30/06: unique id num for sound event
|
||||
} channel_t;
|
||||
|
||||
// the set of channels available
|
||||
@ -129,9 +128,9 @@ void S_StopChannels(void)
|
||||
// haleyjd: added priority scaling
|
||||
//
|
||||
static int S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source,
|
||||
int chanvol, int *vol, int *sep, int *pri)
|
||||
sfxparams_t *params)
|
||||
{
|
||||
return I_AdjustSoundParams(listener, source, chanvol, vol, sep, pri);
|
||||
return I_AdjustSoundParams(listener, source, params);
|
||||
}
|
||||
|
||||
//
|
||||
@ -141,8 +140,7 @@ static int S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source,
|
||||
// haleyjd 09/27/06: fixed priority/singularity bugs
|
||||
// Note that a higher priority number means lower priority!
|
||||
//
|
||||
static int S_getChannel(const mobj_t *origin, sfxinfo_t *sfxinfo, int priority,
|
||||
int singularity)
|
||||
static int S_getChannel(const mobj_t *origin, int priority, int singularity)
|
||||
{
|
||||
// channel number to use
|
||||
int cnum;
|
||||
@ -213,9 +211,8 @@ static int S_getChannel(const mobj_t *origin, sfxinfo_t *sfxinfo, int priority,
|
||||
static void StartSound(const mobj_t *origin, int sfx_id,
|
||||
pitchrange_t pitch_range, rumble_type_t rumble_type)
|
||||
{
|
||||
int sep, pitch, o_priority, priority, singularity, cnum, handle;
|
||||
int volumeScale = 127;
|
||||
int volume = snd_SfxVolume;
|
||||
int pitch, o_priority, singularity, cnum, handle;
|
||||
sfxparams_t params;
|
||||
sfxinfo_t *sfx;
|
||||
|
||||
// jff 1/22/98 return if sound is not enabled
|
||||
@ -242,17 +239,17 @@ static void StartSound(const mobj_t *origin, int sfx_id,
|
||||
|
||||
// Initialize sound parameters
|
||||
pitch = NORM_PITCH;
|
||||
params.volume_scale = 127;
|
||||
|
||||
// haleyjd: modified so that priority value is always used
|
||||
// haleyjd: also modified to get and store proper singularity value
|
||||
o_priority = priority = sfx->priority;
|
||||
o_priority = params.priority = sfx->priority;
|
||||
singularity = sfx->singularity;
|
||||
|
||||
// Check to see if it is audible, modify the params
|
||||
// killough 3/7/98, 4/25/98: code rearranged slightly
|
||||
|
||||
if (!S_AdjustSoundParams(players[displayplayer].mo, origin, volumeScale,
|
||||
&volume, &sep, &priority))
|
||||
if (!S_AdjustSoundParams(players[displayplayer].mo, origin, ¶ms))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -281,7 +278,7 @@ static void StartSound(const mobj_t *origin, int sfx_id,
|
||||
}
|
||||
|
||||
// try to find a channel
|
||||
if ((cnum = S_getChannel(origin, sfx, priority, singularity)) < 0)
|
||||
if ((cnum = S_getChannel(origin, params.priority, singularity)) < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -294,7 +291,6 @@ static void StartSound(const mobj_t *origin, int sfx_id,
|
||||
#endif
|
||||
|
||||
channels[cnum].sfxinfo = sfx;
|
||||
channels[cnum].origin = origin;
|
||||
|
||||
while (sfx->link)
|
||||
{
|
||||
@ -302,20 +298,19 @@ static void StartSound(const mobj_t *origin, int sfx_id,
|
||||
}
|
||||
|
||||
// Assigns the handle to one of the channels in the mix/output buffer.
|
||||
handle = I_StartSound(sfx, volume, sep, pitch);
|
||||
handle = I_StartSound(sfx, ¶ms, pitch);
|
||||
|
||||
// haleyjd: check to see if the sound was started
|
||||
if (handle >= 0)
|
||||
{
|
||||
channels[cnum].handle = handle;
|
||||
|
||||
// haleyjd 05/29/06: record volume scale value
|
||||
// haleyjd 09/27/06: store priority and singularity values (!!!)
|
||||
channels[cnum].volume = volumeScale;
|
||||
channels[cnum].o_priority = o_priority; // original priority
|
||||
channels[cnum].priority = priority; // scaled priority
|
||||
channels[cnum].origin = origin;
|
||||
channels[cnum].handle = handle;
|
||||
channels[cnum].volume_scale = params.volume_scale;
|
||||
channels[cnum].o_priority = o_priority; // original priority
|
||||
channels[cnum].priority = params.priority; // scaled priority
|
||||
channels[cnum].singularity = singularity;
|
||||
channels[cnum].idnum = I_SoundID(handle); // unique instance id
|
||||
|
||||
if (rumble_type != RUMBLE_NONE)
|
||||
{
|
||||
@ -505,11 +500,51 @@ void S_UnlinkSound(mobj_t *origin)
|
||||
}
|
||||
}
|
||||
|
||||
void S_PauseSound(void)
|
||||
{
|
||||
if (nosfxparm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
I_DeferSoundUpdates();
|
||||
|
||||
for (int cnum = 0; cnum < snd_channels; cnum++)
|
||||
{
|
||||
if (channels[cnum].sfxinfo)
|
||||
{
|
||||
I_PauseSound(channels[cnum].handle);
|
||||
}
|
||||
}
|
||||
|
||||
I_ProcessSoundUpdates();
|
||||
}
|
||||
|
||||
void S_ResumeSound(void)
|
||||
{
|
||||
if (nosfxparm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
I_DeferSoundUpdates();
|
||||
|
||||
for (int cnum = 0; cnum < snd_channels; cnum++)
|
||||
{
|
||||
if (channels[cnum].sfxinfo)
|
||||
{
|
||||
I_ResumeSound(channels[cnum].handle);
|
||||
}
|
||||
}
|
||||
|
||||
I_ProcessSoundUpdates();
|
||||
}
|
||||
|
||||
//
|
||||
// Stop and resume music, during game PAUSE.
|
||||
//
|
||||
|
||||
void S_PauseSound(void)
|
||||
void S_PauseMusic(void)
|
||||
{
|
||||
if (mus_playing && !mus_paused)
|
||||
{
|
||||
@ -518,7 +553,7 @@ void S_PauseSound(void)
|
||||
}
|
||||
}
|
||||
|
||||
void S_ResumeSound(void)
|
||||
void S_ResumeMusic(void)
|
||||
{
|
||||
if (mus_playing && mus_paused)
|
||||
{
|
||||
@ -554,56 +589,48 @@ void S_UpdateSounds(const mobj_t *listener)
|
||||
}
|
||||
|
||||
I_DeferSoundUpdates();
|
||||
I_UpdateListenerParams(listener);
|
||||
|
||||
for (cnum = 0; cnum < snd_channels; ++cnum)
|
||||
{
|
||||
channel_t *c = &channels[cnum];
|
||||
sfxinfo_t *sfx = c->sfxinfo;
|
||||
|
||||
// haleyjd: has this software channel lost its hardware channel?
|
||||
if (c->idnum != I_SoundID(c->handle))
|
||||
{
|
||||
// clear the channel and keep going
|
||||
memset(c, 0, sizeof(channel_t));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sfx)
|
||||
{
|
||||
if (I_SoundIsPlaying(c->handle))
|
||||
{
|
||||
// initialize parameters
|
||||
int volume = snd_SfxVolume;
|
||||
int sep = NORM_SEP;
|
||||
int pri = c->o_priority; // haleyjd 09/27/06: priority
|
||||
|
||||
// check non-local sounds for distance clipping
|
||||
// or modify their params
|
||||
|
||||
if (c->origin && listener != c->origin) // killough 3/20/98
|
||||
{
|
||||
if (!S_AdjustSoundParams(listener, c->origin, c->volume,
|
||||
&volume, &sep, &pri))
|
||||
// initialize parameters
|
||||
sfxparams_t params;
|
||||
params.volume_scale = c->volume_scale;
|
||||
params.priority = c->o_priority; // haleyjd 09/27/06: priority
|
||||
|
||||
if (S_AdjustSoundParams(listener, c->origin, ¶ms))
|
||||
{
|
||||
S_StopChannel(cnum);
|
||||
I_UpdateSoundParams(c->handle, ¶ms);
|
||||
c->priority = params.priority; // haleyjd
|
||||
}
|
||||
else
|
||||
{
|
||||
I_UpdateSoundParams(c->handle, volume, sep);
|
||||
c->priority = pri; // haleyjd
|
||||
S_StopChannel(cnum);
|
||||
}
|
||||
}
|
||||
|
||||
I_UpdateRumbleParams(listener, c->origin, c->handle);
|
||||
}
|
||||
else // if channel is allocated but sound has stopped, free it
|
||||
else if (!I_SoundIsPaused(c->handle))
|
||||
{
|
||||
// if channel is allocated but sound has stopped, free it
|
||||
S_StopChannel(cnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
I_UpdateListenerParams(listener);
|
||||
I_ProcessSoundUpdates();
|
||||
I_UpdateRumble();
|
||||
}
|
||||
|
@ -102,10 +102,13 @@ void S_ChangeMusInfoMusic(int lumpnum, int looping);
|
||||
// Stops the music fer sure.
|
||||
void S_StopMusic(void);
|
||||
|
||||
// Stop and resume music, during game PAUSE.
|
||||
void S_PauseSound(void);
|
||||
void S_ResumeSound(void);
|
||||
|
||||
// Stop and resume music, during game PAUSE.
|
||||
void S_PauseMusic(void);
|
||||
void S_ResumeMusic(void);
|
||||
|
||||
void S_RestartMusic(void);
|
||||
|
||||
//
|
||||
|
@ -23,6 +23,14 @@
|
||||
|
||||
#include "doomtype.h"
|
||||
|
||||
typedef struct sfxparams_s
|
||||
{
|
||||
int volume_scale;
|
||||
int volume;
|
||||
int separation;
|
||||
int priority;
|
||||
} sfxparams_t;
|
||||
|
||||
//
|
||||
// SoundFX struct.
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user