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