?? s_sound.c
字號(hào):
if (n>1)
{
for (i=0; i<numChannels ; i++)
{
if (channels[i].sfxinfo == &S_sfx[sfx_sawidl]
|| channels[i].sfxinfo == &S_sfx[sfx_sawful]
|| channels[i].sfxinfo == &S_sfx[sfx_sawhit])
{
fprintf(stderr,
"chn: sfxinfo=0x%lx, origin=0x%lx, "
"handle=%d\n",
channels[i].sfxinfo,
channels[i].origin,
channels[i].handle);
}
}
fprintf(stderr, "\n");
}
}
}
#endif
}
void S_StopSound(void *origin)
{
int cnum;
for (cnum=0 ; cnum<numChannels ; cnum++)
{
if (channels[cnum].sfxinfo && channels[cnum].origin == origin)
{
S_StopChannel(cnum);
break;
}
}
}
//
// Stop and resume music, during game PAUSE.
//
void S_PauseSound(void)
{
if (mus_playing && !mus_paused)
{
I_PauseSong(mus_playing->handle);
mus_paused = true;
}
}
void S_ResumeSound(void)
{
if (mus_playing && mus_paused)
{
I_ResumeSong(mus_playing->handle);
mus_paused = false;
}
}
//
// Updates music & sounds
//
void S_UpdateSounds(void* listener_p)
{
int audible;
int cnum;
int volume;
int sep;
int pitch;
sfxinfo_t* sfx;
channel_t* c;
mobj_t* listener = (mobj_t*)listener_p;
// Clean up unused data.
// This is currently not done for 16bit (sounds cached static).
// DOS 8bit remains.
/*if (gametic > nextcleanup)
{
for (i=1 ; i<NUMSFX ; i++)
{
if (S_sfx[i].usefulness < 1
&& S_sfx[i].usefulness > -1)
{
if (--S_sfx[i].usefulness == -1)
{
Z_ChangeTag(S_sfx[i].data, PU_CACHE);
S_sfx[i].data = 0;
}
}
}
nextcleanup = gametic + 15;
}*/
for (cnum=0 ; cnum<numChannels ; cnum++)
{
c = &channels[cnum];
sfx = c->sfxinfo;
if (c->sfxinfo)
{
if (I_SoundIsPlaying(c->handle))
{
// initialize parameters
volume = snd_SfxVolume;
pitch = NORM_PITCH;
sep = NORM_SEP;
if (sfx->link)
{
pitch = sfx->pitch;
volume += sfx->volume;
if (volume < 1)
{
S_StopChannel(cnum);
continue;
}
else if (volume > snd_SfxVolume)
{
volume = snd_SfxVolume;
}
}
// check non-local sounds for distance clipping
// or modify their params
if (c->origin && listener_p != c->origin)
{
audible = S_AdjustSoundParams(listener,
c->origin,
&volume,
&sep,
&pitch);
if (!audible)
{
S_StopChannel(cnum);
}
else
I_UpdateSoundParams(c->handle, volume, sep, pitch);
}
}
else
{
// if channel is allocated but sound has stopped,
// free it
S_StopChannel(cnum);
}
}
}
// kill music if it is a single-play && finished
// if ( mus_playing
// && !I_QrySongPlaying(mus_playing->handle)
// && !mus_paused )
// S_StopMusic();
}
void S_SetMusicVolume(int volume)
{
if (volume < 0 || volume > 127)
{
I_Error("Attempt to set music volume at %d",
volume);
}
I_SetMusicVolume(127);
I_SetMusicVolume(volume);
snd_MusicVolume = volume;
}
void S_SetSfxVolume(int volume)
{
if (volume < 0 || volume > 127)
I_Error("Attempt to set sfx volume at %d", volume);
snd_SfxVolume = volume;
}
//
// Starts some music with the music id found in sounds.h.
//
void S_StartMusic(int m_id)
{
S_ChangeMusic(m_id, false);
}
void
S_ChangeMusic
( int musicnum,
int looping )
{
musicinfo_t* music;
char namebuf[9];
if ( (musicnum <= mus_None)
|| (musicnum >= NUMMUSIC) )
{
I_Error("Bad music number %d", musicnum);
}
else
music = &S_music[musicnum];
if (mus_playing == music)
return;
// shutdown old music
S_StopMusic();
// get lumpnum if neccessary
if (!music->lumpnum)
{
sprintf(namebuf, "d_%s", music->name);
music->lumpnum = W_GetNumForName(namebuf);
}
// load & register it
music->data = (void *) W_CacheLumpNum(music->lumpnum, PU_MUSIC);
music->handle = I_RegisterSong(music->data);
// play it
I_PlaySong(music->handle, looping);
mus_playing = music;
}
void S_StopMusic(void)
{
if (mus_playing)
{
if (mus_paused)
I_ResumeSong(mus_playing->handle);
I_StopSong(mus_playing->handle);
I_UnRegisterSong(mus_playing->handle);
Z_ChangeTag(mus_playing->data, PU_CACHE);
mus_playing->data = 0;
mus_playing = 0;
}
}
void S_StopChannel(int cnum)
{
int i;
channel_t* c = &channels[cnum];
if (c->sfxinfo)
{
// stop the sound playing
if (I_SoundIsPlaying(c->handle))
{
#ifdef SAWDEBUG
if (c->sfxinfo == &S_sfx[sfx_sawful])
fprintf(stderr, "stopped\n");
#endif
I_StopSound(c->handle);
}
// check to see
// if other channels are playing the sound
for (i=0 ; i<numChannels ; i++)
{
if (cnum != i
&& c->sfxinfo == channels[i].sfxinfo)
{
break;
}
}
// degrade usefulness of sound data
c->sfxinfo->usefulness--;
c->sfxinfo = 0;
}
}
//
// Changes volume, stereo-separation, and pitch variables
// from the norm of a sound effect to be played.
// If the sound is not audible, returns a 0.
// Otherwise, modifies parameters and returns 1.
//
int
S_AdjustSoundParams
( mobj_t* listener,
mobj_t* source,
int* vol,
int* sep,
int* pitch )
{
fixed_t approx_dist;
fixed_t adx;
fixed_t ady;
angle_t angle;
// calculate the distance to sound origin
// and clip it if necessary
adx = abs(listener->x - source->x);
ady = abs(listener->y - source->y);
// From _GG1_ p.428. Appox. eucledian distance fast.
approx_dist = adx + ady - ((adx < ady ? adx : ady)>>1);
if (gamemap != 8
&& approx_dist > S_CLIPPING_DIST)
{
return 0;
}
// angle of source to listener
angle = R_PointToAngle2(listener->x,
listener->y,
source->x,
source->y);
if (angle > listener->angle)
angle = angle - listener->angle;
else
angle = angle + (0xffffffff - listener->angle);
angle >>= ANGLETOFINESHIFT;
// stereo separation
*sep = 128 - (FixedMul(S_STEREO_SWING,finesine[angle])>>FRACBITS);
// volume calculation
if (approx_dist < S_CLOSE_DIST)
{
*vol = snd_SfxVolume;
}
else if (gamemap == 8)
{
if (approx_dist > S_CLIPPING_DIST)
approx_dist = S_CLIPPING_DIST;
*vol = 15+ ((snd_SfxVolume-15)
*((S_CLIPPING_DIST - approx_dist)>>FRACBITS))
/ S_ATTENUATOR;
}
else
{
// distance effect
*vol = (snd_SfxVolume
* ((S_CLIPPING_DIST - approx_dist)>>FRACBITS))
/ S_ATTENUATOR;
}
return (*vol > 0);
}
//
// S_getChannel :
// If none available, return -1. Otherwise channel #.
//
int S_getChannel( void *origin, sfxinfo_t *sfxinfo, int sfxid )
{
// channel number to use
int cnum;
channel_t* c;
// Find an open channel
//for (cnum = 0; cnum < numChannels; cnum++)
for (cnum = 0; cnum < NUM_DSBUFFERS; cnum++)
{
if (!channels[cnum].sfxinfo)
break;
else
if (origin && channels[cnum].origin == origin)
{
S_StopChannel(cnum);
break;
}
}
// None available
if (cnum == NUM_DSBUFFERS)
{
// Look for lower priority
for (cnum = NUMSFX; cnum < NUM_DSBUFFERS; cnum++)
if (channels[cnum].sfxinfo->priority >= sfxinfo->priority)
break;
if (cnum == numChannels)
{
// FUCK! No lower priority. Sorry, Charlie.
return -1;
}
else
{
// Otherwise, kick out lower priority.
S_StopChannel(cnum);
}
}
c = &channels[cnum];
// channel is decided to be cnum.
c->sfxinfo = sfxinfo;
c->origin = origin;
return cnum;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -