diff options
Diffstat (limited to 'demos/3rdparty/doom/s_sound.c')
-rw-r--r-- | demos/3rdparty/doom/s_sound.c | 875 |
1 files changed, 0 insertions, 875 deletions
diff --git a/demos/3rdparty/doom/s_sound.c b/demos/3rdparty/doom/s_sound.c deleted file mode 100644 index f995c69e..00000000 --- a/demos/3rdparty/doom/s_sound.c +++ /dev/null @@ -1,875 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// $Id:$ -// -// Copyright (C) 1993-1996 by id Software, Inc. -// -// This source is available for distribution and/or modification -// only under the terms of the DOOM Source Code License as -// published by id Software. All rights reserved. -// -// The source is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License -// for more details. -// -// $Log:$ -// -// DESCRIPTION: none -// -//----------------------------------------------------------------------------- - - -static const char -rcsid[] = "$Id: s_sound.c,v 1.6 1997/02/03 22:45:12 b1 Exp $"; - - - -#include <stdio.h> -#include <stdlib.h> - -#include "i_system.h" -#include "i_sound.h" -#include "sounds.h" -#include "s_sound.h" - -#include "z_zone.h" -#include "m_random.h" -#include "w_wad.h" - -#include "doomdef.h" -#include "p_local.h" - -#include "doomstat.h" - - -// Purpose? -const char snd_prefixen[] -= { 'P', 'P', 'A', 'S', 'S', 'S', 'M', 'M', 'M', 'S', 'S', 'S' }; - -#define S_MAX_VOLUME 127 - -// when to clip out sounds -// Does not fit the large outdoor areas. -#define S_CLIPPING_DIST (1200*0x10000) - -// Distance tp origin when sounds should be maxed out. -// This should relate to movement clipping resolution -// (see BLOCKMAP handling). -// Originally: (200*0x10000). -#define S_CLOSE_DIST (160*0x10000) - - -#define S_ATTENUATOR ((S_CLIPPING_DIST-S_CLOSE_DIST)>>FRACBITS) - -// Adjustable by menu. -#define NORM_VOLUME snd_MaxVolume - -#define NORM_PITCH 128 -#define NORM_PRIORITY 64 -#define NORM_SEP 128 - -#define S_PITCH_PERTURB 1 -#define S_STEREO_SWING (96*0x10000) - -// percent attenuation from front to back -#define S_IFRACVOL 30 - -#define NA 0 -#define S_NUMCHANNELS 2 - - -// Current music/sfx card - index useless -// w/o a reference LUT in a sound module. -extern int snd_MusicDevice; -extern int snd_SfxDevice; -// Config file? Same disclaimer as above. -extern int snd_DesiredMusicDevice; -extern int snd_DesiredSfxDevice; - - - -typedef struct -{ - // sound information (if null, channel avail.) - sfxinfo_t* sfxinfo; - - // origin of sound - void* origin; - - // handle of the sound being played - int handle; - -} channel_t; - - -// the set of channels available -static channel_t* channels; - -// These are not used, but should be (menu). -// Maximum volume of a sound effect. -// Internal default is max out of 0-15. -int snd_SfxVolume = 15; - -// Maximum volume of music. Useless so far. -int snd_MusicVolume = 15; - - - -// whether songs are mus_paused -static boolean mus_paused; - -// music currently being played -static musicinfo_t* mus_playing=0; - -// following is set -// by the defaults code in M_misc: -// number of channels available -int numChannels; - -static int nextcleanup; - - - -// -// Internals. -// -int -S_getChannel -( void* origin, - sfxinfo_t* sfxinfo ); - - -int -S_AdjustSoundParams -( mobj_t* listener, - mobj_t* source, - int* vol, - int* sep, - int* pitch ); - -void S_StopChannel(int cnum); - - - -// -// Initializes sound stuff, including volume -// Sets channels, SFX and music volume, -// allocates channel buffer, sets S_sfx lookup. -// -void S_Init -( int sfxVolume, - int musicVolume ) -{ - int i; - - I_DBGprintf("S_Init: default sfx volume %d\n", sfxVolume); - - // Whatever these did with DMX, these are rather dummies now. - I_SetChannels(); - - S_SetSfxVolume(sfxVolume); - // No music with Linux - another dummy. - S_SetMusicVolume(musicVolume); - - // Allocating the internal channels for mixing - // (the maximum numer of sounds rendered - // simultaneously) within zone memory. - channels = - (channel_t *) Z_Malloc(numChannels*sizeof(channel_t), PU_STATIC, 0); - - // Free all channels for use - for (i=0 ; i<numChannels ; i++) - channels[i].sfxinfo = 0; - - // no sounds are playing, and they are not mus_paused - mus_paused = 0; - - // Note that sounds have not been cached (yet). - for (i=1 ; i<NUMSFX ; i++) - S_sfx[i].lumpnum = S_sfx[i].usefulness = -1; -} - - - - -// -// Per level startup code. -// Kills playing sounds at start of level, -// determines music if any, changes music. -// -void S_Start(void) -{ - int cnum; - int mnum; - - // kill all playing sounds at start of level - // (trust me - a good idea) - for (cnum=0 ; cnum<numChannels ; cnum++) - if (channels[cnum].sfxinfo) - S_StopChannel(cnum); - - // start new music for the level - mus_paused = 0; - - if (gamemode == commercial) - mnum = mus_runnin + gamemap - 1; - else - { - int spmus[]= - { - // Song - Who? - Where? - - mus_e3m4, // American e4m1 - mus_e3m2, // Romero e4m2 - mus_e3m3, // Shawn e4m3 - mus_e1m5, // American e4m4 - mus_e2m7, // Tim e4m5 - mus_e2m4, // Romero e4m6 - mus_e2m6, // J.Anderson e4m7 CHIRON.WAD - mus_e2m5, // Shawn e4m8 - mus_e1m9 // Tim e4m9 - }; - - if (gameepisode < 4) - mnum = mus_e1m1 + (gameepisode-1)*9 + gamemap-1; - else - mnum = spmus[gamemap-1]; - } - - // HACK FOR COMMERCIAL - // if (commercial && mnum > mus_e3m9) - // mnum -= mus_e3m9; - - S_ChangeMusic(mnum, true); - - nextcleanup = 15; -} - - - - - -void -S_StartSoundAtVolume -( void* origin_p, - int sfx_id, - int volume ) -{ - - int rc; - int sep; - int pitch; - int priority; - sfxinfo_t* sfx; - int cnum; - - mobj_t* origin = (mobj_t *) origin_p; - - - // Debug. - /*I_DBGprintf("S_StartSoundAtVolume: playing sound %d (%s)\n", - sfx_id, S_sfx[sfx_id].name );*/ - - // check for bogus sound # - if (sfx_id < 1 || sfx_id > NUMSFX) - I_Error("Bad sfx #: %d", sfx_id); - - sfx = &S_sfx[sfx_id]; - - // Initialize sound parameters - if (sfx->link) - { - pitch = sfx->pitch; - priority = sfx->priority; - volume += sfx->volume; - - if (volume < 1) - return; - - if (volume > snd_SfxVolume) - volume = snd_SfxVolume; - } - else - { - pitch = NORM_PITCH; - priority = NORM_PRIORITY; - } - - - // Check to see if it is audible, - // and if not, modify the params - if (origin && origin != players[consoleplayer].mo) - { - rc = S_AdjustSoundParams(players[consoleplayer].mo, - origin, - &volume, - &sep, - &pitch); - - if ( origin->x == players[consoleplayer].mo->x - && origin->y == players[consoleplayer].mo->y) - { - sep = NORM_SEP; - } - - if (!rc) - return; - } - else - { - sep = NORM_SEP; - } - - // hacks to vary the sfx pitches - if (sfx_id >= sfx_sawup - && sfx_id <= sfx_sawhit) - { - pitch += 8 - (M_Random()&15); - - if (pitch<0) - pitch = 0; - else if (pitch>255) - pitch = 255; - } - else if (sfx_id != sfx_itemup - && sfx_id != sfx_tink) - { - pitch += 16 - (M_Random()&31); - - if (pitch<0) - pitch = 0; - else if (pitch>255) - pitch = 255; - } - - // kill old sound - S_StopSound(origin); - - // try to find a channel - cnum = S_getChannel(origin, sfx); - - if (cnum<0) - return; - - // - // This is supposed to handle the loading/caching. - // For some odd reason, the caching is done nearly - // each time the sound is needed? - // - - // get lumpnum if necessary - if (sfx->lumpnum < 0) - sfx->lumpnum = I_GetSfxLumpNum(sfx); - -#ifndef SNDSRV - // cache data if necessary - if (!sfx->data) - { - I_DBGprintf("S_StartSoundAtVolume: 16bit and not pre-cached - wtf?\n"); - - // DOS remains, 8bit handling - //sfx->data = (void *) W_CacheLumpNum(sfx->lumpnum, PU_MUSIC); - // I_DBGprintf("S_StartSoundAtVolume: loading %d (lump %d) : 0x%x\n", - // sfx_id, sfx->lumpnum, (int)sfx->data ); - - } -#endif - - // increase the usefulness - if (sfx->usefulness++ < 0) - sfx->usefulness = 1; - - // Assigns the handle to one of the channels in the - // mix/output buffer. - channels[cnum].handle = I_StartSound(sfx_id, - /*sfx->data,*/ - volume, - sep, - pitch, - priority); -} - -void -S_StartSound -( void* origin, - int sfx_id ) -{ -#ifdef SAWDEBUG - // if (sfx_id == sfx_sawful) - // sfx_id = sfx_itemup; -#endif - - S_StartSoundAtVolume(origin, sfx_id, snd_SfxVolume); - - - // UNUSED. We had problems, had we not? -#ifdef SAWDEBUG -{ - int i; - int n; - - static mobj_t* last_saw_origins[10] = {1,1,1,1,1,1,1,1,1,1}; - static int first_saw=0; - static int next_saw=0; - - if (sfx_id == sfx_sawidl - || sfx_id == sfx_sawful - || sfx_id == sfx_sawhit) - { - for (i=first_saw;i!=next_saw;i=(i+1)%10) - if (last_saw_origins[i] != origin) - I_DBGprintf("old origin 0x%lx != " - "origin 0x%lx for sfx %d\n", - last_saw_origins[i], - origin, - sfx_id); - - last_saw_origins[next_saw] = origin; - next_saw = (next_saw + 1) % 10; - if (next_saw == first_saw) - 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]) - { - I_DBGprintf("chn: sfxinfo=0x%lx, origin=0x%lx, " - "handle=%d\n", - channels[i].sfxinfo, - channels[i].origin, - channels[i].handle); - } - } - I_DBGprintf("\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) - { - I_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]) - I_DBGprintf("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 ) -{ - // 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; -} - - - - |