📄 s_sound.c
字号:
// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------//// $Id: s_sound.c,v 1.2 2003/09/08 22:34:31 jasonk Exp $//// 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: s_sound.c,v $// Revision 1.2 2003/09/08 22:34:31 jasonk// Updated files because this fucker won't build for no fucking good reason.//// Revision 1.1.1.1 2003/09/04 21:08:13 jasonk// Initial import//// Revision 1.1 2000/12/08 21:07:54 jeffw// nxdoom initial entry -- No nxdoom/Makefile so it won't build automatically////// DESCRIPTION: none////-----------------------------------------------------------------------------static const charrcsid[] = "$Id: s_sound.c,v 1.2 2003/09/08 22:34:31 jasonk 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 availablestatic 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_pausedstatic boolean mus_paused; // music currently being playedstatic musicinfo_t* mus_playing=0;// following is set// by the defaults code in M_misc:// number of channels availableint numChannels; static int nextcleanup;//// Internals.//intS_getChannel( void* origin, sfxinfo_t* sfxinfo );intS_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; fprintf( stderr, "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;} voidS_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; /* If no sould has been set, then go ahead and bail */#if !defined(USE_DSP) && !defined(USE_ESOUND) return;#endif // Debug. /*fprintf( stderr, "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) { fprintf( stderr, "S_StartSoundAtVolume: 16bit and not pre-cached - wtf?\n"); // DOS remains, 8bit handling //sfx->data = (void *) W_CacheLumpNum(sfx->lumpnum, PU_MUSIC); // fprintf( stderr, // "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);} voidS_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) fprintf(stderr, "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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -