📄 s_sound.c
字号:
first_saw = (first_saw + 1) % 10; for (n=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]) n++; } 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); } } } I_UpdateSound(); // 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);}voidS_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.//intS_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 #.//intS_getChannel( void* origin, sfxinfo_t* sfxinfo ){ // channel number to use int cnum; channel_t* c; // Find an open channel for (cnum=0 ; cnum<numChannels ; cnum++) { if (!channels[cnum].sfxinfo) break; else if (origin && channels[cnum].origin == origin) { S_StopChannel(cnum); break; } } // None available if (cnum == numChannels) { // Look for lower priority for (cnum=0 ; cnum<numChannels ; 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -