1 #include <stdlib.h>
2 #include <stdarg.h>
3 #include <sys/time.h>
4 #include "h2def.h"
5 #include "r_local.h"
6 #include "p_local.h"    // for P_AproxDistance
7 #include "sounds.h"
8 #include "i_sound.h"
9 #include "soundst.h"
10 #include "st_start.h"
11 
12 #define	DEFAULT_ARCHIVEPATH ""
13 
14 
15 #define stricmp strcasecmp
16 #define PRIORITY_MAX_ADJUST 10
17 #define DIST_ADJUST (MAX_SND_DIST/PRIORITY_MAX_ADJUST)
18 
19 extern void **lumpcache;
20 
21 
22 /*
23 ===============================================================================
24 
25 		MUSIC & SFX API
26 
27 ===============================================================================
28 */
29 
30 extern sfxinfo_t S_sfx[];
31 extern musicinfo_t S_music[];
32 
33 static channel_t SChannel[MAX_CHANNELS];
34 static int RegisteredSong; //the current registered song.
35 static int NextCleanup;
36 static boolean MusicPaused;
37 static int Mus_Song = -1;
38 static int Mus_LumpNum;
39 static void *Mus_SndPtr;
40 static byte *SoundCurve;
41 
42 static boolean UseSndScript;
43 static char ArchivePath[128];
44 
45 extern int snd_MusicDevice;
46 extern int snd_SfxDevice;
47 extern int snd_MaxVolume;
48 extern int snd_MusicVolume;
49 extern int snd_Channels;
50 
51 extern int startepisode;
52 extern int startmap;
53 
54 // int AmbChan;
55 
56 boolean S_StopSoundID(int sound_id, int priority);
57 
58 //==========================================================================
59 //
60 // S_Start
61 //
62 //==========================================================================
63 
S_Start(void)64 void S_Start(void)
65 {
66 	S_StopAllSound();
67 	S_StartSong(gamemap, true);
68 }
69 
70 //==========================================================================
71 //
72 // S_StartSong
73 //
74 //==========================================================================
75 
S_StartSong(int song,boolean loop)76 void S_StartSong(int song, boolean loop)
77 {
78 	char *songLump;
79 	int size=0;
80 	{
81 		if(song == Mus_Song)
82 		{ // don't replay an old song
83 			return;
84 		}
85 		if(RegisteredSong)
86 		{
87 			I_StopSong(RegisteredSong);
88 			I_UnRegisterSong(RegisteredSong);
89 			if(UseSndScript)
90 			{
91 				Z_Free(Mus_SndPtr);
92 			}
93 			else
94 			{
95 				Z_ChangeTag(lumpcache[Mus_LumpNum], PU_CACHE);
96 			}
97 			RegisteredSong = 0;
98 		}
99 		songLump = P_GetMapSongLump(song);
100 		if(!songLump)
101 		{
102 			return;
103 		}
104 		if(UseSndScript)
105 		{
106 			char name[128];
107 			sprintf(name, "%s%s.lmp", ArchivePath, songLump);
108 			M_ReadFile(name, (byte **)&Mus_SndPtr);
109 		}
110 		else
111 		{
112 			Mus_LumpNum = W_GetNumForName(songLump);
113 			size=W_LumpLength(Mus_LumpNum);
114 			Mus_SndPtr = W_CacheLumpNum(Mus_LumpNum, PU_MUSIC);
115 		}
116 		if (size) {
117   		 RegisteredSong = I_RegisterSong(Mus_SndPtr,size);
118 		 I_PlaySong(RegisteredSong, loop); // 'true' denotes endless looping.
119 		 Mus_Song = song;
120 		}
121 	}
122 }
123 
124 //==========================================================================
125 //
126 // S_StartSongName
127 //
128 //==========================================================================
129 
S_StartSongName(char * songLump,boolean loop)130 void S_StartSongName(char *songLump, boolean loop)
131 {
132 	int size=0;
133 	if(!songLump)
134 	{
135 		return;
136 	}
137 
138 	{
139 		if(RegisteredSong)
140 		{
141 			I_StopSong(RegisteredSong);
142 			I_UnRegisterSong(RegisteredSong);
143 			if(UseSndScript)
144 			{
145 				Z_Free(Mus_SndPtr);
146 			}
147 			else
148 			{
149 				Z_ChangeTag(lumpcache[Mus_LumpNum], PU_CACHE);
150 			}
151 			RegisteredSong = 0;
152 		}
153 		if(UseSndScript)
154 		{
155 			char name[128];
156 			sprintf(name, "%s%s.lmp", ArchivePath, songLump);
157 			M_ReadFile(name, (byte **)&Mus_SndPtr);
158 		}
159 		else
160 		{
161 			Mus_LumpNum = W_GetNumForName(songLump);
162 			size=W_LumpLength(Mus_LumpNum);
163 			Mus_SndPtr = W_CacheLumpNum(Mus_LumpNum, PU_MUSIC);
164 		}
165 		RegisteredSong = I_RegisterSong(Mus_SndPtr,size);
166 		I_PlaySong(RegisteredSong, loop); // 'true' denotes endless looping.
167 		Mus_Song = -1;
168 	}
169 }
170 
171 //==========================================================================
172 //
173 // S_GetSoundID
174 //
175 //==========================================================================
176 
S_GetSoundID(char * name)177 int S_GetSoundID(char *name)
178 {
179 	int i;
180 
181 	for(i = 0; i < NUMSFX; i++)
182 	{
183 		if(!strcmp(S_sfx[i].tagName, name))
184 		{
185 			return i;
186 		}
187 	}
188 	return 0;
189 }
190 
191 //==========================================================================
192 //
193 // S_StartSound
194 //
195 //==========================================================================
196 
S_StartSound(mobj_t * origin,int sound_id)197 void S_StartSound(mobj_t *origin, int sound_id)
198 {
199 	S_StartSoundAtVolume(origin, sound_id, 127);
200 }
201 
202 //==========================================================================
203 //
204 // S_StartSoundAtVolume
205 //
206 //==========================================================================
207 #if 0
208 void S_StartSoundAtVolume(mobj_t *origin, int sound_id, int volume)
209 {
210 	int dist, vol;
211 	int i = 0;       /* jim - initialise to avoid gcc warning */
212 	int priority;
213 	int sep;
214 	int angle;
215 	int absx;
216 	int absy;
217 
218 	static int sndcount = 0;
219 	int chan;
220 
221     //printf( "S_StartSoundAtVolume: %d\n", sound_id );
222 
223 	if(sound_id == 0 || snd_MaxVolume == 0)
224 		return;
225 	if(origin == NULL)
226 	{
227 		origin = players[displayplayer].mo;
228 	}
229 	if(volume == 0)
230 	{
231 		return;
232 	}
233 
234     // How does the DOS version work without this check?
235     // players[0].mo does not get set until P_SpawnPlayer. - KR
236 
237     if( origin )
238     {
239         // calculate the distance before other stuff so that we can throw out
240         // sounds that are beyond the hearing range.
241         absx = abs(origin->x-players[displayplayer].mo->x);
242         absy = abs(origin->y-players[displayplayer].mo->y);
243         dist = absx+absy-(absx > absy ? absy>>1 : absx>>1);
244         dist >>= FRACBITS;
245         if(dist >= MAX_SND_DIST)
246         {
247           return; // sound is beyond the hearing range...
248         }
249         if(dist < 0)
250         {
251             dist = 0;
252         }
253         priority = S_sfx[sound_id].priority;
254         priority *= (PRIORITY_MAX_ADJUST-(dist/DIST_ADJUST));
255         if(!S_StopSoundID(sound_id, priority))
256         {
257             return; // other sounds have greater priority
258         }
259         for(i = 0; i<snd_Channels; i++)
260         {
261             if(origin->player)
262             {
263                 i = snd_Channels;
264                 break; // let the player have more than one sound.
265             }
266             if(origin == SChannel[i].mo)
267             { // only allow other mobjs one sound
268                 S_StopSound(SChannel[i].mo);
269                 break;
270             }
271         }
272 	}
273     else
274     {
275         dist = 0;
276         priority = S_sfx[sound_id].priority;
277         if( ! S_StopSoundID( sound_id, priority ) )
278         {
279             return; // other sounds have greater priority
280         }
281     }
282 
283 	if(i >= snd_Channels)
284 	{
285 		for(i = 0; i < snd_Channels; i++)
286 		{
287 			if(SChannel[i].mo == NULL)
288 			{
289 				break;
290 			}
291 		}
292 		if(i >= snd_Channels)
293 		{
294 			// look for a lower priority sound to replace.
295 			sndcount++;
296 			if(sndcount >= snd_Channels)
297 			{
298 				sndcount = 0;
299 			}
300 			for(chan = 0; chan < snd_Channels; chan++)
301 			{
302 				i = (sndcount+chan)%snd_Channels;
303 				if(priority >= SChannel[i].priority)
304 				{
305 					chan = -1; //denote that sound should be replaced.
306 					break;
307 				}
308 			}
309 			if(chan != -1)
310 			{
311 				return; //no free channels.
312 			}
313 			else //replace the lower priority sound.
314 			{
315 				if(SChannel[i].handle)
316 				{
317 					if(I_SoundIsPlaying(SChannel[i].handle))
318 					{
319 						I_StopSound(SChannel[i].handle);
320 					}
321 					if(S_sfx[SChannel[i].sound_id].usefulness > 0)
322 					{
323 						S_sfx[SChannel[i].sound_id].usefulness--;
324 					}
325 				}
326 			}
327 		}
328 	}
329 	if(S_sfx[sound_id].lumpnum == 0)
330 	{
331 		S_sfx[sound_id].lumpnum = I_GetSfxLumpNum(&S_sfx[sound_id]);
332 	}
333 	if(S_sfx[sound_id].snd_ptr == NULL)
334 	{
335 		if(UseSndScript)
336 		{
337 			char name[128];
338 			sprintf(name, "%s%s.lmp", ArchivePath, S_sfx[sound_id].lumpname);
339 			M_ReadFile(name, (byte **)&S_sfx[sound_id].snd_ptr);
340 		}
341 		else
342 		{
343 			S_sfx[sound_id].snd_ptr = W_CacheLumpNum(S_sfx[sound_id].lumpnum,
344 				PU_SOUND);
345 		}
346 	}
347 
348 	vol = (SoundCurve[dist]*(snd_MaxVolume*8)*volume)>>14;
349 	if(origin == players[displayplayer].mo)
350 	{
351 		sep = 128;
352 //              vol = (volume*(snd_MaxVolume+1)*8)>>7;
353 	}
354 	else
355 	{
356 #if 1
357         // KR - SChannel[i].mo = 0 here!
358         if( SChannel[i].mo == NULL )
359         {
360             sep = 128;
361             //printf( " SChannel[i].mo not set\n" );
362         }
363         else
364         {
365 #endif
366 		angle = R_PointToAngle2(players[displayplayer].mo->x,
367 			players[displayplayer].mo->y, SChannel[i].mo->x, SChannel[i].mo->y);
368 		angle = (angle-viewangle)>>24;
369 		sep = angle*2-128;
370 		if(sep < 64)
371 			sep = -sep;
372 		if(sep > 192)
373 			sep = 512-sep;
374 //              vol = SoundCurve[dist];
375 #if 1
376         }
377 #endif
378 	}
379 
380 	if(S_sfx[sound_id].changePitch)
381 	{
382 		SChannel[i].pitch = (byte)(127+(M_Random()&7)-(M_Random()&7));
383 	}
384 	else
385 	{
386 		SChannel[i].pitch = 127;
387 	}
388 	SChannel[i].handle = I_StartSound( sound_id, S_sfx[sound_id].snd_ptr, vol,
389 	                                  sep, SChannel[i].pitch, 0 );
390 	SChannel[i].mo = origin;
391 	SChannel[i].sound_id = sound_id;
392 	SChannel[i].priority = priority;
393 	SChannel[i].volume = volume;
394 	if(S_sfx[sound_id].usefulness < 0)
395 	{
396 		S_sfx[sound_id].usefulness = 1;
397 	}
398 	else
399 	{
400 		S_sfx[sound_id].usefulness++;
401 	}
402 }
403 #endif
404 
S_StartSoundAtVolume(mobj_t * origin,int sound_id,int volume)405 void S_StartSoundAtVolume(mobj_t *origin, int sound_id, int volume)
406 {
407 	int dist, vol;
408 	int i;
409 	int priority;
410 	int sep;
411 	int angle;
412 	int absx;
413 	int absy;
414 
415 	static int sndcount = 0;
416 	int chan;
417 
418 	if(sound_id == 0 || snd_MaxVolume == 0)
419 		return;
420 #if 0
421 	if(origin == NULL)
422 	{
423 // origin = players[displayplayer].mo; bug -- can be uninitialized
424 	}
425 #endif
426 	if(volume == 0)
427 	{
428 		return;
429 	}
430 
431 	// calculate the distance before other stuff so that we can throw out
432 	// sounds that are beyond the hearing range.
433 	if (origin)
434 	{
435 	absx = abs(origin->x-players[displayplayer].mo->x);
436 	absy = abs(origin->y-players[displayplayer].mo->y);
437 	}
438 	else
439 	  absx = absy = 0;
440 	dist = absx+absy-(absx > absy ? absy>>1 : absx>>1);
441 	dist >>= FRACBITS;
442 	if(dist >= MAX_SND_DIST)
443 	{
444 	  return; // sound is beyond the hearing range...
445 	}
446 	if(dist < 0)
447 	{
448 		dist = 0;
449 	}
450 	priority = S_sfx[sound_id].priority;
451 	priority *= (PRIORITY_MAX_ADJUST-(dist/DIST_ADJUST));
452 	if(!S_StopSoundID(sound_id, priority))
453 	{
454 		return; // other sounds have greater priority
455 	}
456 	for(i=0; i<snd_Channels; i++)
457 	{
458 		if(!origin || origin->player)
459 		{
460 			i = snd_Channels;
461 			break; // let the player have more than one sound.
462 		}
463 		if(origin == SChannel[i].mo)
464 		{ // only allow other mobjs one sound
465 			S_StopSound(SChannel[i].mo);
466 			break;
467 		}
468 	}
469 	if(i >= snd_Channels)
470 	{
471 		for(i = 0; i < snd_Channels; i++)
472 		{
473 			if(SChannel[i].mo == NULL)
474 			{
475 				break;
476 			}
477 		}
478 		if(i >= snd_Channels)
479 		{
480 			// look for a lower priority sound to replace.
481 			sndcount++;
482 			if(sndcount >= snd_Channels)
483 			{
484 				sndcount = 0;
485 			}
486 			for(chan = 0; chan < snd_Channels; chan++)
487 			{
488 				i = (sndcount+chan)%snd_Channels;
489 				if(priority >= SChannel[i].priority)
490 				{
491 					chan = -1; //denote that sound should be replaced.
492 					break;
493 				}
494 			}
495 			if(chan != -1)
496 			{
497 				return; //no free channels.
498 			}
499 			else //replace the lower priority sound.
500 			{
501 				if(SChannel[i].handle)
502 				{
503 					if(I_SoundIsPlaying(SChannel[i].handle))
504 					{
505 						I_StopSound(SChannel[i].handle);
506 					}
507 					if(S_sfx[SChannel[i].sound_id].usefulness > 0)
508 					{
509 						S_sfx[SChannel[i].sound_id].usefulness--;
510 					}
511 				}
512 			}
513 		}
514 	}
515 	if(S_sfx[sound_id].lumpnum == 0)
516 	{
517 		S_sfx[sound_id].lumpnum = I_GetSfxLumpNum(&S_sfx[sound_id]);
518 	}
519 	if(S_sfx[sound_id].snd_ptr == NULL)
520 	{
521 		if(UseSndScript)
522 		{
523 			char name[128];
524 			sprintf(name, "%s%s.lmp", ArchivePath, S_sfx[sound_id].lumpname);
525 			M_ReadFile(name, (byte **)&S_sfx[sound_id].snd_ptr);
526 		}
527 		else
528 		{
529 			S_sfx[sound_id].snd_ptr = W_CacheLumpNum(S_sfx[sound_id].lumpnum,
530 				PU_SOUND);
531 		}
532 		#ifdef __WATCOMC__
533 //		  _dpmi_lockregion(S_sfx[sound_id].snd_ptr,
534 //			  lumpinfo[S_sfx[sound_id].lumpnum].size);
535 		#endif
536 	}
537 
538 	vol = (SoundCurve[dist]*(snd_MaxVolume*8)*volume)>>14;
539 	if (!origin || origin == players[displayplayer].mo)
540 	{
541 		sep = 128;
542 //              vol = (volume*(snd_MaxVolume+1)*8)>>7;
543 	}
544 	else
545 	{
546 		angle = R_PointToAngle2(players[displayplayer].mo->x,
547 // bug! 		       players[displayplayer].mo->y, SChannel[i].mo->x, SChannel[i].mo->y);
548 			players[displayplayer].mo->y, origin->x, origin->y);
549 		angle = (angle-viewangle)>>24;
550 		sep = angle*2-128;
551 		if(sep < 64)
552 			sep = -sep;
553 		if(sep > 192)
554 			sep = 512-sep;
555 //              vol = SoundCurve[dist];
556 	}
557 
558 	if(S_sfx[sound_id].changePitch)
559 	{
560 		SChannel[i].pitch = (byte)(127+(M_Random()&7)-(M_Random()&7));
561 	}
562 	else
563 	{
564 		SChannel[i].pitch = 127;
565 	}
566 	SChannel[i].handle = I_StartSound(sound_id, S_sfx[sound_id].snd_ptr, vol,
567 		sep, SChannel[i].pitch, 0);
568 	SChannel[i].mo = origin;
569 	SChannel[i].sound_id = sound_id;
570 	SChannel[i].priority = priority;
571 	SChannel[i].volume = volume;
572 	if(S_sfx[sound_id].usefulness < 0)
573 	{
574 		S_sfx[sound_id].usefulness = 1;
575 	}
576 	else
577 	{
578 		S_sfx[sound_id].usefulness++;
579 	}
580 }
581 //==========================================================================
582 //
583 // S_StopSoundID
584 //
585 //==========================================================================
586 
S_StopSoundID(int sound_id,int priority)587 boolean S_StopSoundID(int sound_id, int priority)
588 {
589 	int i;
590 	int lp; //least priority
591 	int found;
592 
593 	if(S_sfx[sound_id].numchannels == -1)
594 	{
595 		return(true);
596 	}
597 	lp = -1; //denote the argument sound_id
598 	found = 0;
599 	for(i=0; i<snd_Channels; i++)
600 	{
601 		if(SChannel[i].sound_id == sound_id && SChannel[i].mo)
602 		{
603 			found++; //found one.  Now, should we replace it??
604 			if(priority >= SChannel[i].priority)
605 			{ // if we're gonna kill one, then this'll be it
606 				lp = i;
607 				priority = SChannel[i].priority;
608 			}
609 		}
610 	}
611 	if(found < S_sfx[sound_id].numchannels)
612 	{
613 		return(true);
614 	}
615 	else if(lp == -1)
616 	{
617 		return(false); // don't replace any sounds
618 	}
619 	if(SChannel[lp].handle)
620 	{
621 		if(I_SoundIsPlaying(SChannel[lp].handle))
622 		{
623 			I_StopSound(SChannel[lp].handle);
624 		}
625 		if(S_sfx[SChannel[lp].sound_id].usefulness > 0)
626 		{
627 			S_sfx[SChannel[lp].sound_id].usefulness--;
628 		}
629 		SChannel[lp].mo = NULL;
630 	}
631 	return(true);
632 }
633 
634 //==========================================================================
635 //
636 // S_StopSound
637 //
638 //==========================================================================
639 
S_StopSound(mobj_t * origin)640 void S_StopSound(mobj_t *origin)
641 {
642 	int i;
643 
644 	for(i=0;i<snd_Channels;i++)
645 	{
646 		if(SChannel[i].mo == origin)
647 		{
648 			I_StopSound(SChannel[i].handle);
649 			if(S_sfx[SChannel[i].sound_id].usefulness > 0)
650 			{
651 				S_sfx[SChannel[i].sound_id].usefulness--;
652 			}
653 			SChannel[i].handle = 0;
654 			SChannel[i].mo = NULL;
655 		}
656 	}
657 }
658 
659 //==========================================================================
660 //
661 // S_StopAllSound
662 //
663 //==========================================================================
664 
S_StopAllSound(void)665 void S_StopAllSound(void)
666 {
667 	int i;
668 
669 	//stop all sounds
670 	for(i=0; i < snd_Channels; i++)
671 	{
672 		if(SChannel[i].handle)
673 		{
674 			S_StopSound(SChannel[i].mo);
675 		}
676 	}
677 	memset(SChannel, 0, 8*sizeof(channel_t));
678 }
679 
680 //==========================================================================
681 //
682 // S_SoundLink
683 //
684 //==========================================================================
685 
S_SoundLink(mobj_t * oldactor,mobj_t * newactor)686 void S_SoundLink(mobj_t *oldactor, mobj_t *newactor)
687 {
688 	int i;
689 
690 	for(i=0;i<snd_Channels;i++)
691 	{
692 		if(SChannel[i].mo == oldactor)
693 			SChannel[i].mo = newactor;
694 	}
695 }
696 
697 //==========================================================================
698 //
699 // S_PauseSound
700 //
701 //==========================================================================
702 
S_PauseSound(void)703 void S_PauseSound(void)
704 {
705 	{
706 		I_PauseSong(RegisteredSong);
707 	}
708 }
709 
710 //==========================================================================
711 //
712 // S_ResumeSound
713 //
714 //==========================================================================
715 
S_ResumeSound(void)716 void S_ResumeSound(void)
717 {
718 	{
719 		I_ResumeSong(RegisteredSong);
720 	}
721 }
722 
723 //==========================================================================
724 //
725 // S_UpdateSounds
726 //
727 //==========================================================================
728 
S_UpdateSounds(mobj_t * listener)729 void S_UpdateSounds(mobj_t *listener)
730 {
731 	int i, dist, vol;
732 	int angle;
733 	int sep;
734 	int priority;
735 	int absx;
736 	int absy;
737 
738 	if(snd_MaxVolume == 0)
739 	{
740 		return;
741 	}
742 
743 	// Update any Sequences
744 	SN_UpdateActiveSequences();
745 
746 	if(NextCleanup < gametic)
747 	{
748 		if(UseSndScript)
749 		{
750 			for(i = 0; i < NUMSFX; i++)
751 			{
752 				if(S_sfx[i].usefulness == 0 && S_sfx[i].snd_ptr)
753 				{
754 					S_sfx[i].usefulness = -1;
755 				}
756 			}
757 		}
758 		else
759 		{
760 			for(i = 0; i < NUMSFX; i++)
761 			{
762 				if(S_sfx[i].usefulness == 0 && S_sfx[i].snd_ptr)
763 				{
764 					if(lumpcache[S_sfx[i].lumpnum])
765 					{
766 						if(((memblock_t *)((byte*)
767 							(lumpcache[S_sfx[i].lumpnum])-
768 							sizeof(memblock_t)))->id == 0x1d4a11)
769 						{ // taken directly from the Z_ChangeTag macro
770 							Z_ChangeTag2(lumpcache[S_sfx[i].lumpnum],
771 								PU_CACHE);
772 						}
773 					}
774 					S_sfx[i].usefulness = -1;
775 					S_sfx[i].snd_ptr = NULL;
776 				}
777 			}
778 		}
779 		NextCleanup = gametic+35*30; // every 30 seconds
780 	}
781 	for(i=0;i<snd_Channels;i++)
782 	{
783 		if(!SChannel[i].handle || S_sfx[SChannel[i].sound_id].usefulness == -1)
784 		{
785 			continue;
786 		}
787 		if(!I_SoundIsPlaying(SChannel[i].handle))
788 		{
789 			if(S_sfx[SChannel[i].sound_id].usefulness > 0)
790 			{
791 				S_sfx[SChannel[i].sound_id].usefulness--;
792 			}
793 			SChannel[i].handle = 0;
794 			SChannel[i].mo = NULL;
795 			SChannel[i].sound_id = 0;
796 		}
797 		if(SChannel[i].mo == NULL || SChannel[i].sound_id == 0
798 			|| SChannel[i].mo == listener)
799 		{
800 			continue;
801 		}
802 		else
803 		{
804 			absx = abs(SChannel[i].mo->x-listener->x);
805 			absy = abs(SChannel[i].mo->y-listener->y);
806 			dist = absx+absy-(absx > absy ? absy>>1 : absx>>1);
807 			dist >>= FRACBITS;
808 
809 			if(dist >= MAX_SND_DIST)
810 			{
811 				S_StopSound(SChannel[i].mo);
812 				continue;
813 			}
814 			if(dist < 0)
815 			{
816 				dist = 0;
817 			}
818 			//vol = SoundCurve[dist];
819 			vol = (SoundCurve[dist]*(snd_MaxVolume*8)*SChannel[i].volume)>>14;
820 			if(SChannel[i].mo == listener)
821 			{
822 				sep = 128;
823 			}
824 			else
825 			{
826 				angle = R_PointToAngle2(listener->x, listener->y,
827 								SChannel[i].mo->x, SChannel[i].mo->y);
828 				angle = (angle-viewangle)>>24;
829 				sep = angle*2-128;
830 				if(sep < 64)
831 					sep = -sep;
832 				if(sep > 192)
833 					sep = 512-sep;
834 			}
835 			I_UpdateSoundParams(SChannel[i].handle, vol, sep,
836 				SChannel[i].pitch);
837 			priority = S_sfx[SChannel[i].sound_id].priority;
838 			priority *= PRIORITY_MAX_ADJUST-(dist/DIST_ADJUST);
839 			SChannel[i].priority = priority;
840 		}
841 	}
842 }
843 
844 //==========================================================================
845 //
846 // S_Init
847 //
848 //==========================================================================
849 
S_Init(void)850 void S_Init(void)
851 {
852 	SoundCurve = W_CacheLumpName("SNDCURVE", PU_STATIC);
853 //      SoundCurve = Z_Malloc(MAX_SND_DIST, PU_STATIC, NULL);
854 	I_StartupSound();
855 	if(snd_Channels > 8)
856 	{
857 		snd_Channels = 8;
858 	}
859 	I_SetChannels(snd_Channels);
860 	I_SetMusicVolume(snd_MusicVolume);
861 
862 }
863 
864 //==========================================================================
865 //
866 // S_GetChannelInfo
867 //
868 //==========================================================================
869 
S_GetChannelInfo(SoundInfo_t * s)870 void S_GetChannelInfo(SoundInfo_t *s)
871 {
872 	int i;
873 	ChanInfo_t *c;
874 
875 	s->channelCount = snd_Channels;
876 	s->musicVolume = snd_MusicVolume;
877 	s->soundVolume = snd_MaxVolume;
878 	for(i = 0; i < snd_Channels; i++)
879 	{
880 		c = &s->chan[i];
881 		c->id = SChannel[i].sound_id;
882 		c->priority = SChannel[i].priority;
883 		c->name = S_sfx[c->id].lumpname;
884 		c->mo = SChannel[i].mo;
885 		c->distance = (c->mo) ? (P_AproxDistance(c->mo->x-viewx, c->mo->y-viewy)
886 			>>FRACBITS) :0;
887 	}
888 }
889 
890 //==========================================================================
891 //
892 // S_GetSoundPlayingInfo
893 //
894 //==========================================================================
895 
S_GetSoundPlayingInfo(mobj_t * mobj,int sound_id)896 boolean S_GetSoundPlayingInfo(mobj_t *mobj, int sound_id)
897 {
898 	int i;
899 
900 	for(i = 0; i < snd_Channels; i++)
901 	{
902 		if(SChannel[i].sound_id == sound_id && SChannel[i].mo == mobj)
903 		{
904 			if(I_SoundIsPlaying(SChannel[i].handle))
905 			{
906 				return true;
907 			}
908 		}
909 	}
910 	return false;
911 }
912 
913 //==========================================================================
914 //
915 // S_SetMusicVolume
916 //
917 //==========================================================================
918 
S_SetMusicVolume(void)919 void S_SetMusicVolume(void)
920 {
921 	{
922 		I_SetMusicVolume(snd_MusicVolume);
923 	}
924 	if(snd_MusicVolume == 0)
925 	{
926 		I_PauseSong(RegisteredSong);
927 		MusicPaused = true;
928 	}
929 	else if(MusicPaused)
930 	{
931 		I_ResumeSong(RegisteredSong);
932 		MusicPaused = false;
933 	}
934 }
935 
936 //==========================================================================
937 //
938 // S_ShutDown
939 //
940 //==========================================================================
941 
S_ShutDown(void)942 void S_ShutDown(void)
943 {
944 	extern int tsm_ID;
945 	if(tsm_ID != -1)
946 	{
947 		I_StopSong(RegisteredSong);
948 		I_UnRegisterSong(RegisteredSong);
949 		I_ShutdownSound();
950 	}
951 }
952 
953 //==========================================================================
954 //
955 // S_InitScript
956 //
957 //==========================================================================
958 
S_InitScript(void)959 void S_InitScript(void)
960 {
961 	int p;
962 	int i;
963 
964 	strcpy(ArchivePath, DEFAULT_ARCHIVEPATH);
965 	if(!(p = M_CheckParm("-devsnd")))
966 	{
967 		UseSndScript = false;
968 		SC_OpenLump("sndinfo");
969 	}
970 	else
971 	{
972 		UseSndScript = true;
973 		SC_OpenFile(myargv[p+1]);
974 	}
975 	while(SC_GetString())
976 	{
977 		if(*sc_String == '$')
978 		{
979 			if(!stricmp(sc_String, "$ARCHIVEPATH"))
980 			{
981 				SC_MustGetString();
982 				strcpy(ArchivePath, sc_String);
983 			}
984 			else if(!stricmp(sc_String, "$MAP"))
985 			{
986 				SC_MustGetNumber();
987 				SC_MustGetString();
988 				if(sc_Number)
989 				{
990 					P_PutMapSongLump(sc_Number, sc_String);
991 				}
992 			}
993 			continue;
994 		}
995 		else
996 		{
997 			for(i = 0; i < NUMSFX; i++)
998 			{
999 				if(!strcmp(S_sfx[i].tagName, sc_String))
1000 				{
1001 					SC_MustGetString();
1002 					if(*sc_String != '?')
1003 					{
1004 						strcpy(S_sfx[i].lumpname, sc_String);
1005 					}
1006 					else
1007 					{
1008 						strcpy(S_sfx[i].lumpname, "default");
1009 					}
1010 					break;
1011 				}
1012 			}
1013 			if(i == NUMSFX)
1014 			{
1015 				SC_MustGetString();
1016 			}
1017 		}
1018 	}
1019 	SC_Close();
1020 
1021 	for(i = 0; i < NUMSFX; i++)
1022 	{
1023 		if(!strcmp(S_sfx[i].lumpname, ""))
1024 		{
1025 			strcpy(S_sfx[i].lumpname, "default");
1026 		}
1027 	}
1028 }
1029 
1030