1 /****************************************************************/
2 /* code copyright 1995-1996 Andrew Johnson - ALL RIGHTS RESERVED*/
3 /* ajohnson@eecs.uic.edu */
4 /* */
5 /* Electronic Visualization Lab (M/C 154) */
6 /* University of Illinois at Chicago */
7 /* 851 South Morgan St. Room 1120 SEO */
8 /* Chicago, IL 60607-7053 */
9 /* */
10 /* (312) 996-3002 (312) 413-7585 FAX */
11 /***********************************************************************/
12 /* audio.c v 1.4 */
13 /* audio routines for battalion */
14 /* since audio is so machine dependant there is separate code for the */
15 /* various implementations ... */
16 /***********************************************************************/
17
18 #include "battalion.h"
19 #include <sys/stat.h>
20
21 extern int noSound;
22 int soundOn;
23 int musicOn;
24 extern int showframes;
25 extern struct monsterInfo Googelon;
26
27 /***************/
28 /* music stuff */
29 /***************/
30
31 int playingTankFire, playingHeloRocket, playingTankMaser;
32 int playingExplosion, playingSlag, playingTech;
33
34 int musicCount, deadCount;
35
36 #ifdef SGIAUDIO
37
38 struct sound * allSounds;
39 struct aSound oneSound[MAXSOUNDS];
40
41 #endif
42 #ifdef SUNAUDIO
43
44 char *audio_buffer[MAXSOUNDS];
45 int buffer_counter[MAXSOUNDS];
46 char *audio_dev = "/dev/audio";
47 int audiofd;
48 Audio_hdr file_hdr;
49
50 int playingBeam, playingMusic;
51
52 #endif
53
54 #ifdef MACVERSION
55
56 int playingBeam, playingCrash, playingMusic, maserOn;
57
58 Boolean idleFlag;
59
60 Handle beamSound, boomSound, crashSound, monsterbeamSound,
61 rocketSound, slagSound, tankSound, techSound, musicSound;
62
63 long musicRefNum, monsterbeamRefNum, maserbeamRefNum;
64 SndChannelPtr musicChan, monsterbeamChan, maserbeamChan;
65
66 #endif
67
68 #ifdef LINUXAUDIO
69
70 #include "soundIt.h"
71 #define NUM_SAMPLES 12
72 #define SAMPLE_RATE 11000
73 #define NUM_CHANNELS 8
74
75 Sample snd[NUM_SAMPLES];
76 char *audio_dev = "/dev/dsp";
77 int audiofd;
78 int playingBeam, playingMusic;
79
80 #endif
81
82 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
83 /* small sound routines to avoid having to use external variables*/
84
85 #ifdef LINUXAUDIO
86
killSounds(void)87 void killSounds( void )
88 {
89 Snd_restore();
90 }
91
92 #endif
93
94 #ifdef MACVERSION
setSoundVolume(long vol)95 void setSoundVolume(long vol)
96 {
97 SetDefaultOutputVolume(vol);
98 }
99 #endif
100
turnSoundOff()101 void turnSoundOff()
102 {
103 soundOn = 0;
104 }
105
turnSoundOn()106 void turnSoundOn()
107 {
108 soundOn = 1;
109 }
110
toggleSound()111 void toggleSound()
112 {
113 soundOn = !soundOn;
114 }
115
getSoundOn()116 int getSoundOn()
117 {
118 return(soundOn);
119 }
120
turnMusicOff()121 void turnMusicOff()
122 {
123 musicOn = 0;
124 }
125
turnMusicOn()126 void turnMusicOn()
127 {
128 musicOn = 1;
129 }
130
toggleMusic()131 void toggleMusic()
132 {
133 musicOn = !musicOn;
134 }
135
getMusicOn()136 int getMusicOn()
137 {
138 return(musicOn);
139 }
140
141 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
142
checkSound(char * dataPath)143 void checkSound(char * dataPath)
144 {
145 char * garbage;
146
147 #ifdef SGIAUDIO
148 long pvbuf[4];
149
150 ALseterrorhandler(0);
151
152 pvbuf[0] = AL_OUTPUT_COUNT;
153 pvbuf[2] = AL_MONITOR_CTL;
154
155 if (ALgetparams(AL_DEFAULT_DEVICE, pvbuf, 4) < 0)
156 {
157 noSound = 1;
158 soundOn = 0;
159 musicOn = 0;
160 }
161
162 if (!noSound)
163 {
164 /******************************************/
165 /* load all the sound effects into memory */
166 /******************************************/
167
168 InitAudio("SOUNDS/beam.aiff", dataPath, 0);
169 InitAudio("SOUNDS/boom.aiff", dataPath, 1);
170 InitAudio("SOUNDS/crash.aiff", dataPath, 2);
171 InitAudio("SOUNDS/monsterbeam.aiff", dataPath, 3);
172 InitAudio("SOUNDS/rocket.aiff", dataPath, 4);
173 InitAudio("SOUNDS/slag.aiff", dataPath, 5);
174 InitAudio("SOUNDS/tank.aiff", dataPath, 6);
175 InitAudio("SOUNDS/tech.aiff", dataPath, 7);
176
177 /*********************************************/
178 /* load all the background music into memory */
179 /*********************************************/
180
181 InitAudio("MUSIC/1.aiff", dataPath, 10);
182 InitAudio("MUSIC/2.aiff", dataPath, 11);
183 InitAudio("MUSIC/3.aiff", dataPath, 12);
184 InitAudio("MUSIC/4.aiff", dataPath, 13);
185 InitAudio("MUSIC/5.aiff", dataPath, 14);
186
187 InitAudio("MUSIC/d1.aiff", dataPath, 15);
188 InitAudio("MUSIC/d2.aiff", dataPath, 16);
189 InitAudio("MUSIC/d3.aiff", dataPath, 17);
190 InitAudio("MUSIC/d4.aiff", dataPath, 18);
191 InitAudio("MUSIC/d5.aiff", dataPath, 19);
192
193 }
194 #else
195 # ifdef SUNAUDIO
196 /* Solaris audio support */
197
198 noSound = 1;
199 soundOn = 0;
200 musicOn = 0;
201 {
202 /* Check if audio device is available and writable */
203 struct stat st;
204
205 if (stat(audio_dev, &st) >= 0) {
206 audiofd = open(audio_dev, O_WRONLY);
207 if (audiofd >= 0) {
208 noSound = 0;
209 close(audiofd);
210 }
211 }
212 }
213
214 if (!noSound) {
215 /* Load all sound effects into memory */
216 InitAudio("SOUNDS/beam.au", dataPath, 0);
217 InitAudio("SOUNDS/boom.au", dataPath, 1);
218 InitAudio("SOUNDS/crash.au", dataPath, 2);
219 InitAudio("SOUNDS/monsterbeam.au", dataPath, 3);
220 InitAudio("SOUNDS/rocket.au", dataPath, 4);
221 InitAudio("SOUNDS/slag.au", dataPath, 5);
222 InitAudio("SOUNDS/tank.au", dataPath, 6);
223 InitAudio("SOUNDS/tech.au", dataPath, 7);
224
225 /* Load all background music into memory */
226 InitAudio("MUSIC/1.au", dataPath, 10);
227 InitAudio("MUSIC/2.au", dataPath, 11);
228 InitAudio("MUSIC/3.au", dataPath, 12);
229 InitAudio("MUSIC/4.au", dataPath, 13);
230 InitAudio("MUSIC/5.au", dataPath, 14);
231
232 InitAudio("MUSIC/d1.au", dataPath, 15);
233 InitAudio("MUSIC/d2.au", dataPath, 16);
234 InitAudio("MUSIC/d3.au", dataPath, 17);
235 InitAudio("MUSIC/d4.au", dataPath, 18);
236 InitAudio("MUSIC/d5.au", dataPath, 19);
237 }
238 #else
239 #ifdef MACVERSION
240
241 SndCommand testCommand;
242
243 beamSound = GetResource( 'snd ', 1000 );
244 boomSound = GetResource( 'snd ', 1001 );
245 crashSound = GetResource( 'snd ', 1002 );
246 monsterbeamSound = GetResource( 'snd ', 1003 );
247 rocketSound = GetResource( 'snd ', 1004 );
248 slagSound = GetResource( 'snd ', 1005 );
249 tankSound = GetResource( 'snd ', 1006 );
250 techSound = GetResource( 'snd ', 1007 );
251 musicSound = GetResource( 'snd ', 1010 );
252
253 noSound = 0;
254 soundOn = 0;
255 musicOn = 0;
256
257 /* using the SoundHelper code to do asynch audio */
258
259 SHInitSoundHelper(&idleFlag, 8);
260
261 SHPlayByHandle(musicSound, -1, &musicRefNum);
262 SHPlayPause(musicRefNum);
263 SHPlayByHandle(beamSound, -1, &maserbeamRefNum);
264 SHPlayPause(maserbeamRefNum);
265 SHPlayByHandle(monsterbeamSound, -1, &monsterbeamRefNum);
266 SHPlayPause(monsterbeamRefNum);
267
268
269 # else
270 #ifdef LINUXAUDIO
271 /* Linux audio support */
272
273 noSound = 1;
274 soundOn = 0;
275 musicOn = 0;
276 {
277 /* Check if audio device is available and writable */
278 struct stat st;
279
280 if (stat(audio_dev, &st) >= 0) {
281 audiofd = open(audio_dev, O_WRONLY);
282 if (audiofd >= 0) {
283 noSound = 0;
284 close(audiofd);
285 }
286 }
287 }
288
289 if (!noSound) {
290 /* Load all sound effects into memory */
291 Snd_loadRawSample("SOUNDS/beam.raw", &snd[0]);
292 Snd_loadRawSample("SOUNDS/boom.raw", &snd[1]);
293 Snd_loadRawSample("SOUNDS/crash.raw",&snd[2]);
294 Snd_loadRawSample("SOUNDS/monsterbeam.raw",&snd[3]);
295 Snd_loadRawSample("SOUNDS/rocket.raw",&snd[4]);
296 Snd_loadRawSample("SOUNDS/slag.raw",&snd[5]);
297 Snd_loadRawSample("SOUNDS/tank.raw",&snd[6]);
298 Snd_loadRawSample("SOUNDS/tech.raw",&snd[7]);
299
300 /* Load all background music into memory */
301
302 Snd_loadRawSample("MUSIC/1.raw",&snd[10]);
303 Snd_loadRawSample("MUSIC/2.raw",&snd[11]);
304 /* Snd_loadRawSample("MUSIC/3.au",&snd[12]);
305 Snd_loadRawSample("MUSIC/4.au",&snd[13]);
306 Snd_loadRawSample("MUSIC/5.au",&snd[14]);
307
308 Snd_loadRawSample("MUSIC/d1.au",&snd[15]);
309 Snd_loadRawSample("MUSIC/d2.au",&snd[16]);
310 Snd_loadRawSample("MUSIC/d3.au",&snd[17]);
311 Snd_loadRawSample("MUSIC/d4.au",&snd[18]);
312 Snd_loadRawSample("MUSIC/d5.au",&snd[19]);
313 */
314 if (Snd_init( NUM_SAMPLES, snd, SAMPLE_RATE, NUM_CHANNELS, audio_dev )==EXIT_FAILURE){
315 printf("Can't init soundIt library. yech..\n");
316 exit(0);
317 }
318 }
319 #else
320
321 /* Other than SGI or Solaris or Macintosh*/
322 noSound = 1;
323 soundOn = 0;
324 musicOn = 0;
325
326 #endif
327 #endif
328 #endif
329 #endif
330
331 garbage = dataPath; /* to avoid compiler warning */
332 }
333
334 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
335
336 #ifdef MACVERSION
337
processIdleAppSounds(void)338 void processIdleAppSounds(void)
339 {
340 if (idleFlag)
341 {
342 SHIdle();
343 }
344 }
345 #endif
346
347 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
348 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
349 /* initialize sound list to empty */
350 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
351
initSounds()352 void initSounds()
353 {
354 #ifdef SGIAUDIO
355
356 register int i;
357
358 allSounds = NULL;
359 allSounds = (struct sound *) calloc(1, sizeof(struct sound));
360 allSounds->next = NULL;
361
362 musicCount = 0;
363 deadCount = 0;
364
365 playingTankFire = playingHeloRocket = playingTankMaser = 0;
366 playingExplosion = playingSlag = playingTech = 0;
367
368 for (i=0; i<MAXSOUNDS; i++)
369 {
370 oneSound[i].samplesPerFrame = 0;
371 oneSound[i].numberSamples = 0;
372 oneSound[i].samplesPerBuffer = 0;
373 oneSound[i].audioRate = 0;
374 oneSound[i].sampleBuffer = NULL;
375 }
376
377 #endif
378 # ifdef SUNAUDIO
379
380 int n;
381
382 musicCount = 0;
383 deadCount = 0;
384
385 playingTankFire = playingHeloRocket = playingTankMaser = 0;
386 playingExplosion = playingSlag = playingTech = 0;
387 playingBeam = playingMusic = 0;
388
389 /* Mark audio buffers as empty */
390
391 for (n = 0; n < MAXSOUNDS; n++)
392 audio_buffer[n] = NULL;
393
394 # endif
395
396 #ifdef MACVERSION
397
398 musicCount = 0;
399 deadCount = 0;
400
401 playingTankFire = playingHeloRocket = playingTankMaser = 0;
402 playingExplosion = playingSlag = playingTech = 0;
403 playingBeam = playingMusic = maserOn = 0;
404 playingCrash = 0;
405
406
407 #endif
408 #ifdef LINUXAUDIO
409
410 int n;
411
412 musicCount = 0;
413 deadCount = 0;
414
415 playingTankFire = playingHeloRocket = playingTankMaser = 0;
416 playingExplosion = playingSlag = playingTech = 0;
417 playingBeam = playingMusic = 0;
418
419 /* Mark audio buffers as empty */
420
421 // for (n = 0; n < MAXSOUNDS; n++)
422 // audio_buffer[n] = NULL;
423
424 #endif
425
426 }
427
428 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
429 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
430 /* clear all completed sounds from the sound list */
431 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
432
flushSounds()433 void flushSounds()
434 {
435 #ifdef SGIAUDIO
436
437 struct sound *s, *t;
438
439 playingHeloRocket = playingTech = playingTankMaser = playingSlag = 0;
440
441 playingExplosion--;
442 if (playingExplosion < 0)
443 playingExplosion = 0;
444
445 playingTankFire--;
446 if (playingTankFire < 0)
447 playingTankFire = 0;
448
449 s = allSounds;
450 while(s->next != NULL)
451 {
452 if(ALgetfilled(s->next->audio_port) <= 0)
453 {
454 ALcloseport(s->next->audio_port);
455 t = s->next;
456 s->next = s->next->next;
457 free(t);
458 }
459 else
460 s = s->next;
461 }
462 #endif
463 # ifdef SUNAUDIO
464
465 playingHeloRocket = playingTech = playingTankMaser = playingSlag = 0;
466
467 playingExplosion--;
468 if (playingExplosion < 0)
469 playingExplosion = 0;
470
471 playingTankFire--;
472 if (playingTankFire < 0)
473 playingTankFire = 0;
474
475 playingBeam--;
476 if (playingBeam < 0)
477 playingBeam = 0;
478
479 playingMusic--;
480 if (playingMusic < 0)
481 playingMusic = 0;
482
483 # endif
484
485 #ifdef MACVERSION
486
487 processIdleAppSounds();
488
489 playingTankMaser = playingSlag = 0;
490
491 playingHeloRocket--;
492 if (playingHeloRocket < 0)
493 playingHeloRocket = 0;
494
495 playingCrash--;
496 if (playingCrash < 0)
497 playingCrash = 0;
498
499 playingExplosion--;
500 if (playingExplosion < 0)
501 playingExplosion = 0;
502
503 playingTech--;
504 if (playingTech < 0)
505 playingTech = 0;
506
507 playingTankFire--;
508 if (playingTankFire < 0)
509 playingTankFire = 0;
510 #endif
511
512 #ifdef LINUXAUDIO
513
514 playingHeloRocket = playingTech = playingTankMaser = playingSlag = 0;
515
516 playingExplosion--;
517 if (playingExplosion < 0)
518 playingExplosion = 0;
519
520 playingTankFire--;
521 if (playingTankFire < 0)
522 playingTankFire = 0;
523
524 playingBeam--;
525 if (playingBeam < 0)
526 playingBeam = 0;
527
528 playingMusic--;
529 if (playingMusic < 0)
530 playingMusic = 0;
531
532 #endif
533
534 }
535
536
537
538 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
539 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
540 /* clear all sounds of a given type from the sound list */
541 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
542
soundKiller(int soundType)543 void soundKiller(int soundType)
544 {
545 int garbage;
546
547 #ifdef SGIAUDIO
548
549 struct sound * s, *t;
550
551 s = allSounds;
552
553 while(s->next != NULL)
554 {
555 if (s->next->type == soundType)
556 {
557 ALcloseport(s->next->audio_port);
558 t = s->next;
559 s->next = s->next->next;
560 free(t);
561 }
562 else
563 s = s->next;
564 }
565 #endif
566
567 #ifdef MACVERSION
568
569 /* stop the sound */
570
571 switch (soundType) {
572 case MUSIC:
573 /*if (playingMusic)*/
574 {
575 /* SHPlayStop(musicRefNum);*/
576 SHPlayPause(musicRefNum);
577 playingMusic = 0;
578 }
579 break;
580 case MONSTERBEAM:
581 /*if (playingBeam)*/
582 {
583 /*SHPlayStop(monsterbeamRefNum);*/
584 SHPlayPause(monsterbeamRefNum);
585 playingBeam = 0;
586 }
587 break;
588
589 case TANKMASER:
590 /* if (maserOn)*/
591 {
592 /*SHPlayStop(maserbeamRefNum);*/
593 SHPlayPause(maserbeamRefNum);
594 maserOn = 0;
595 }
596 break;
597
598 }
599 #endif
600
601 #ifdef LINUXAUDIO
602 /*
603 printf("callkill %d... ", soundType);
604 if (soundType == MUSIC) {
605 Snd_effect( 10, -1 );
606 Snd_effect( 11, -1 );
607 }
608 */
609 #endif
610
611 garbage = soundType; /* to avoid compiler warning */
612 }
613
614 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
615 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
616 /* process a request for a specific sound */
617 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
618
doSound(int theSound)619 void doSound(int theSound)
620 {
621 int garbage;
622
623 #ifdef SGIAUDIO
624
625 static int deadMusic[MAXDEADMUSIC] = {15, 16, 17, 18, 19};
626
627 static int theMusic[MAXMUSIC] = {10, 11, 12, 13, 14};
628
629
630 struct sound * s, *t;
631 int soundDelay;
632
633 if (!noSound)
634 {
635 soundDelay = showframes;
636
637 if (soundDelay <= 1)
638 soundDelay = 1;
639
640 if (soundDelay > 30)
641 soundDelay = 30;
642
643 if (((theSound == MUSIC) && musicOn) || ((theSound != MUSIC) && soundOn))
644 {
645 t = NULL;
646
647 switch (theSound){
648 case MUSIC: s = allSounds->next;
649 while ((s != NULL) && (t == NULL))
650 if (s->type == MUSIC)
651 t = s;
652 else
653 s = s->next;
654
655 if (Googelon.monsterIsDead)
656 {
657 musicCount = 0;
658 if ((t != NULL) && (deadCount < MAXDEADMUSIC))
659 {
660 if ((ALgetfilled(t->audio_port)+oneSound[deadMusic[deadCount]].numberSamples < 2*oneSound[10].samplesPerBuffer) && (deadCount < 3))
661 {
662 ALwritesamps(t->audio_port,
663 oneSound[deadMusic[deadCount]].sampleBuffer,
664 oneSound[deadMusic[deadCount]].numberSamples);
665 deadCount = deadCount+1;
666 }
667 }
668 else if (deadCount < MAXDEADMUSIC)
669 {
670 OutAudio(deadMusic[deadCount]);
671 deadCount = deadCount+1;
672 }
673 }
674 else
675 {
676 deadCount = 0;
677 if (t != NULL)
678 {
679 if(ALgetfilled(t->audio_port)+oneSound[theMusic[musicCount]].numberSamples < 2*oneSound[10].samplesPerBuffer)
680 {
681 ALwritesamps(t->audio_port,
682 oneSound[theMusic[musicCount]].sampleBuffer,
683 oneSound[theMusic[musicCount]].numberSamples);
684 musicCount = (musicCount+1) % MAXMUSIC;
685 }
686 }
687 else
688 {
689 OutAudio(theMusic[musicCount]);
690 musicCount = (musicCount+1) % MAXMUSIC;
691 }
692
693 }
694 break;
695
696 case TANKFIRE: if (!playingTankFire)
697 {
698 OutAudio(6);
699 playingTankFire = soundDelay / 5;
700 if (playingTankFire < 2)
701 playingTankFire = 2;
702 }
703 break;
704
705 case HELOROCKET: if (!playingHeloRocket)
706 {
707 OutAudio(4);
708 playingHeloRocket = 1;
709 }
710 break;
711
712 case TANKMASER: s = allSounds->next;
713 while ((s != NULL) && (t == NULL))
714 if (s->type == TANKMASER)
715 t = s;
716 else
717 s = s->next;
718 if (t != NULL)
719 {
720 if(ALgetfilled(t->audio_port) <= oneSound[0].samplesPerBuffer)
721 ALwritesamps(t->audio_port,
722 oneSound[0].sampleBuffer,
723 oneSound[0].numberSamples);
724 }
725 else
726 OutAudio(0);
727 break;
728
729 case EXPLOSION: if (!playingExplosion)
730 {
731 OutAudio(1);
732 playingExplosion = soundDelay / 5;
733 if (playingExplosion < 2)
734 playingExplosion = 2;
735 }
736 break;
737
738 case MONSTERBEAM: s = allSounds->next;
739 while ((s != NULL) && (t == NULL))
740 if (s->type == MONSTERBEAM)
741 t = s;
742 else
743 s = s->next;
744 if (t != NULL)
745 {
746 if(ALgetfilled(t->audio_port) <= oneSound[3].samplesPerBuffer)
747 ALwritesamps(t->audio_port,
748 oneSound[3].sampleBuffer,
749 oneSound[3].numberSamples);
750 }
751 else
752 OutAudio(3);
753 break;
754
755 case SLAG: if (!playingSlag)
756 {
757 OutAudio(5);
758 playingSlag = 1;
759 }
760 break;
761
762 case CRASH: OutAudio(2);
763 break;
764
765 case TECHSHOOT: if (!playingTech)
766 {
767 OutAudio(7);
768 playingTech = 1;
769 }
770 break;
771 }
772 }
773 }
774
775 #endif
776 # ifdef SUNAUDIO
777
778 static int deadMusic[MAXDEADMUSIC] = {15, 16, 17, 18, 19};
779
780 static int theMusic[MAXMUSIC] = {10, 11, 12, 13, 14};
781
782 int soundDelay;
783
784 if (!noSound) {
785 soundDelay = showframes;
786
787 if (soundDelay <= 1)
788 soundDelay = 1;
789
790 if (soundDelay > 30)
791 soundDelay = 30;
792
793 if (((theSound == MUSIC) && musicOn) ||
794 ((theSound != MUSIC) && soundOn)) {
795
796 switch (theSound) {
797 case MUSIC:
798 if (!playingMusic) {
799 OutAudio(theMusic[musicCount]);
800 musicCount = (musicCount+1) % MAXMUSIC;
801
802 /* each music sample is 5 secs long */
803 playingMusic = soundDelay * 5; ;
804 }
805 break;
806
807 case TANKFIRE:
808 if (!playingTankFire) {
809 OutAudio(6);
810 playingTankFire = soundDelay / 5;
811 if (playingTankFire < 2)
812 playingTankFire = 2;
813 }
814 break;
815
816 case HELOROCKET:
817 if (!playingHeloRocket) {
818 OutAudio(4);
819 playingHeloRocket = 1;
820 }
821 break;
822
823 case TANKMASER:
824 OutAudio(0);
825 break;
826
827 case EXPLOSION:
828 if (!playingExplosion) {
829 OutAudio(1);
830 playingExplosion = soundDelay / 5;
831 if (playingExplosion < 2)
832 playingExplosion = 2;
833 }
834 break;
835
836 case MONSTERBEAM:
837 if (!playingBeam) {
838 OutAudio(3);
839 playingBeam = 5 /*soundDelay / 5*/;
840 }
841 break;
842
843 case SLAG:
844 if (!playingSlag) {
845 OutAudio(5);
846 playingSlag = 1;
847 }
848 break;
849
850 case CRASH:
851 OutAudio(2);
852 break;
853
854 case TECHSHOOT:
855 if (!playingTech) {
856 OutAudio(7);
857 playingTech = 1;
858 }
859 break;
860 }
861 }
862 }
863
864 #endif
865 #ifdef LINUXAUDIO
866
867 static int deadMusic[MAXDEADMUSIC] = {15, 16};
868
869 static int theMusic[MAXMUSIC] = {10, 11};
870
871 int soundDelay;
872
873 // printf("doSound -> %d\n", theSound);
874
875 if (!noSound) {
876 soundDelay = showframes;
877
878 if (soundDelay <= 1)
879 soundDelay = 1;
880
881 if (soundDelay > 30)
882 soundDelay = 30;
883
884 if (((theSound == MUSIC) && musicOn) ||
885 ((theSound != MUSIC) && soundOn)) {
886
887 switch (theSound) {
888 case MUSIC:
889 if (!playingMusic) {
890 OutAudio(theMusic[musicCount]);
891 musicCount = (musicCount+1) % MAXMUSIC;
892 //printf("Music start\n");
893 /* each music sample is 5 secs long */
894 playingMusic = soundDelay * 20; ;
895 }
896 break;
897
898 case TANKFIRE:
899 if (!playingTankFire) {
900 OutAudio(6);
901 playingTankFire = soundDelay / 5;
902 if (playingTankFire < 2)
903 playingTankFire = 2;
904 }
905 break;
906
907 case HELOROCKET:
908 if (!playingHeloRocket) {
909 OutAudio(4);
910 playingHeloRocket = 1;
911 }
912 break;
913
914 case TANKMASER:
915 OutAudio(0);
916 break;
917
918 case EXPLOSION:
919 if (!playingExplosion) {
920 OutAudio(1);
921 playingExplosion = soundDelay / 5;
922 if (playingExplosion < 2)
923 playingExplosion = 2;
924 }
925 break;
926
927 case MONSTERBEAM:
928 if (!playingBeam) {
929 OutAudio(3);
930 playingBeam = 5 /*soundDelay / 5*/;
931 }
932 break;
933
934 case SLAG:
935 if (!playingSlag) {
936 OutAudio(5);
937 playingSlag = 1;
938 }
939 break;
940
941 case CRASH:
942 OutAudio(2);
943 break;
944
945 case TECHSHOOT:
946 if (!playingTech) {
947 OutAudio(7);
948 playingTech = 1;
949 }
950 break;
951 }
952 }
953 }
954
955 #endif
956
957 /*------------------------ Mac Specific code --------------------*/
958
959 #ifdef MACVERSION
960 int soundDelay;
961
962 if (!noSound)
963 {
964 soundDelay = showframes;
965
966 if (soundDelay <= 1)
967 soundDelay = 1;
968
969 if (soundDelay > 30)
970 soundDelay = 30;
971
972 if (((theSound == MUSIC) && musicOn) || ((theSound != MUSIC) && soundOn))
973 {
974 switch (theSound){
975 case MUSIC: if (!playingMusic)
976 {
977 /*SHPlayByHandle(musicSound, &musicRefNum);*/
978 SHPlayContinue(musicRefNum);
979 playingMusic = 1;
980 }
981 break;
982
983 case TANKFIRE:if (!playingTankFire)
984 { /* different from sun version */
985 SHPlayByHandle(tankSound, 1, nil);
986
987 playingTankFire = soundDelay / 5;
988 if (playingTankFire < 3)
989 playingTankFire = 3;
990 }
991 break;
992
993 case HELOROCKET:
994 if (!playingHeloRocket)
995 { /* different from sun version */
996 SHPlayByHandle(rocketSound, 1, nil);
997
998 playingHeloRocket = soundDelay / 5;
999 if (playingHeloRocket < 3)
1000 playingHeloRocket = 3;
1001
1002 }
1003 break;
1004
1005
1006 case TANKMASER:
1007 if (!maserOn)
1008 {
1009 /*SHPlayByHandle(beamSound, &maserbeamRefNum);*/
1010 SHPlayContinue(maserbeamRefNum);
1011
1012 maserOn = 1;
1013 }
1014 break;
1015
1016 case EXPLOSION:
1017 if (!playingExplosion)
1018 { /* different from sun version */
1019 SHPlayByHandle(boomSound, 1, nil);
1020
1021 playingExplosion = soundDelay / 5;
1022 if (playingExplosion < 3)
1023 playingExplosion = 3;
1024 }
1025 break;
1026
1027 case MONSTERBEAM:
1028 if (!playingBeam)
1029 {
1030 /*SHPlayByHandle(monsterbeamSound, &monsterbeamRefNum);*/
1031 SHPlayContinue(monsterbeamRefNum);
1032
1033 playingBeam = 1;
1034 }
1035 break;
1036
1037 case SLAG:
1038 if (!playingSlag) {
1039 SHPlayByHandle(slagSound, 1, nil);
1040
1041 playingSlag = 1;
1042 }
1043 break;
1044
1045 case CRASH:
1046 if (!playingCrash)
1047 {
1048 SHPlayByHandle(crashSound, 1, nil);
1049
1050 playingCrash = 2;
1051 }
1052 break;
1053
1054 case TECHSHOOT:
1055 if (!playingTech)
1056 { /* different from sun version */
1057 SHPlayByHandle(techSound, 1, nil);
1058
1059 playingTech = 2;
1060 }
1061 break;
1062 }
1063 }
1064 }
1065 #endif
1066 garbage = theSound;
1067 }
1068
1069
1070
1071 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1072 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1073 /* output a particular sound */
1074 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1075
1076
OutAudio(int sCounter)1077 void OutAudio(int sCounter)
1078 {
1079 int garbage;
1080
1081 #ifdef SGIAUDIO
1082
1083 ALconfig audioPortConfig;
1084 long pvbuf[4];
1085 long outputRate;
1086 struct sound * s;
1087
1088 pvbuf[0] = AL_OUTPUT_RATE;
1089 ALgetparams(AL_DEFAULT_DEVICE, pvbuf, 2);
1090
1091 if (pvbuf[1] > 0)
1092 outputRate = pvbuf[1];
1093 else
1094 outputRate = AL_RATE_UNDEFINED;
1095
1096 pvbuf[0] = AL_OUTPUT_COUNT;
1097 pvbuf[2] = AL_MONITOR_CTL;
1098 ALgetparams(AL_DEFAULT_DEVICE, pvbuf, 4);
1099
1100 if ((outputRate != oneSound[sCounter].audioRate) || ((pvbuf[1] == 0) && (pvbuf[3] == AL_MONITOR_OFF)))
1101 {
1102 outputRate = oneSound[sCounter].audioRate;
1103 pvbuf[0] = AL_OUTPUT_RATE;
1104 pvbuf[1] = outputRate;
1105 ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2);
1106 }
1107
1108 audioPortConfig = ALnewconfig();
1109 ALsetwidth(audioPortConfig, AL_SAMPLE_16);
1110 ALsetchannels(audioPortConfig, oneSound[sCounter].samplesPerFrame);
1111
1112 switch(sCounter){
1113 case 1:
1114 case 2:
1115 case 4:
1116 case 5:
1117 case 6:
1118 case 7: ALsetqueuesize(audioPortConfig, oneSound[sCounter].samplesPerBuffer);
1119 break;
1120 case 0:
1121 case 3: ALsetqueuesize(audioPortConfig, 2*oneSound[sCounter].samplesPerBuffer);
1122 break;
1123 default: ALsetqueuesize(audioPortConfig, 3*oneSound[sCounter].samplesPerBuffer);
1124 break;
1125 }
1126
1127 s = (struct sound *) calloc(1, sizeof(struct sound));
1128
1129 if (s != NULL)
1130 {
1131 if (sCounter == 3)
1132 s->type = MONSTERBEAM;
1133 else if (sCounter == 0)
1134 s->type = TANKMASER;
1135 else if (sCounter >= 10)
1136 s->type = MUSIC;
1137 else
1138 s->type = -1;
1139
1140 s->next = allSounds->next;
1141 allSounds->next = s;
1142
1143 s->audio_port = ALopenport("battalion", "w", audioPortConfig);
1144 if (s->audio_port == 0)
1145 {
1146 showError("too many simultaneous sounds");
1147 allSounds->next = s->next;
1148 free(s);
1149 }
1150 else
1151 ALwritesamps(s->audio_port, oneSound[sCounter].sampleBuffer, oneSound[sCounter].numberSamples);
1152 }
1153
1154 #endif
1155 # ifdef SUNAUDIO
1156
1157 static int first = 1;
1158
1159 /* Check if a valid buffer and buffer contains a sample */
1160
1161 if (sCounter < 0 || sCounter >= MAXSOUNDS ||
1162 audio_buffer[sCounter] == NULL)
1163 return;
1164
1165 if (first) {
1166 first = 0;
1167
1168 /* Open audio device */
1169
1170 audiofd = open(audio_dev, O_WRONLY /*| O_NDELAY | O_NONBLOCK*/);
1171 if (audiofd < 0)
1172 return;
1173 }
1174
1175 audio_flush_play(audiofd);
1176
1177 if (write(audiofd, audio_buffer[sCounter], buffer_counter[sCounter]) < 0)
1178 fprintf(stderr, "audio_play: buffer %d failed\n", sCounter);
1179
1180
1181 # endif
1182 #ifdef LINUXAUDIO
1183
1184 static int first = 1;
1185
1186 /* Check if a valid buffer and buffer contains a sample */
1187
1188 // printf("Sound N --> %d \n", sCounter);
1189
1190 if (sCounter < 0 || sCounter >= NUM_SAMPLES) return;
1191
1192
1193 Snd_effect( sCounter, sCounter );
1194
1195 # endif
1196
1197 garbage = sCounter; /* to avoid compiler warning */
1198 }
1199
1200 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1201 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1202 /* load a particular sound into memory */
1203 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1204
1205
InitAudio(char * fileName,char * dataPath,int sCounter)1206 void InitAudio(char * fileName, char * dataPath, int sCounter)
1207 {
1208 char * garbName, * garbPath;
1209 int garbCount;
1210
1211 #ifdef SGIAUDIO
1212
1213 /* IRIX 6 compilers want these next two to be integers
1214 * while IRIS 5 compilers want them to be long ... sheesh */
1215
1216 int bitsPerSample;
1217 int garbage;
1218
1219 long framesPerBuffer;
1220 long framesRead;
1221 FILE * sndtest;
1222 AFfilehandle audioFile;
1223 char textBuffer[80];
1224 char fullPath[MAXPATH];
1225
1226
1227 bitsPerSample = 0;
1228 framesPerBuffer = 0;
1229 garbage = 0;
1230 framesRead = 0;
1231
1232 strcpy(fullPath, dataPath);
1233 strcat(fullPath, fileName);
1234
1235 sndtest = fopen(fullPath, "rb");
1236 if (sndtest == NULL)
1237 {
1238 sprintf(textBuffer, "Could not load %s", fullPath);
1239 showError(textBuffer);
1240 }
1241 else
1242 {
1243 fclose(sndtest);
1244
1245 audioFile = AFopenfile(fullPath, "r", AF_NULL_FILESETUP);
1246
1247 oneSound[sCounter].samplesPerFrame = AFgetchannels(audioFile, AF_DEFAULT_TRACK);
1248
1249 AFgetsampfmt(audioFile, AF_DEFAULT_TRACK, &garbage, &bitsPerSample);
1250
1251 oneSound[sCounter].audioRate = (long) (AFgetrate(audioFile, AF_DEFAULT_TRACK));
1252
1253 if (bitsPerSample != 16)
1254 {
1255 sprintf(textBuffer, "incorrect sound format for %s - should be 16-bits", fileName);
1256 showError(textBuffer);
1257 }
1258
1259 framesPerBuffer = AFgetframecnt(audioFile, AF_DEFAULT_TRACK);
1260
1261 oneSound[sCounter].samplesPerBuffer = framesPerBuffer * oneSound[sCounter].samplesPerFrame;
1262
1263 oneSound[sCounter].sampleBuffer = (short *) calloc((unsigned) oneSound[sCounter].samplesPerBuffer, sizeof(short));
1264
1265 AFseekframe(audioFile, AF_DEFAULT_TRACK, 0);
1266
1267 framesRead = AFreadframes(audioFile, AF_DEFAULT_TRACK, oneSound[sCounter].sampleBuffer, framesPerBuffer);
1268
1269 AFclosefile(audioFile);
1270
1271 oneSound[sCounter].numberSamples = framesRead * oneSound[sCounter].samplesPerFrame;
1272 }
1273
1274 #endif
1275 # ifdef SUNAUDIO
1276
1277 int error;
1278 int count;
1279 char audioFile[MAXPATH];
1280
1281 strcpy(audioFile, dataPath);
1282 strcat(audioFile, fileName);
1283
1284 if ((audiofd = open(audioFile, O_RDONLY, 0)) < 0) {
1285 fprintf(stderr, "audio_load: cannot open %s\n", audioFile);
1286 exit(1);
1287 }
1288
1289 error = audio_read_filehdr(audiofd, &file_hdr, (char *)NULL, 0);
1290
1291 if (error != AUDIO_SUCCESS) {
1292 fprintf(stderr, "audio_load: %s is not a valid audio file\n",
1293 audioFile);
1294 exit(-1);
1295 }
1296
1297 if (audio_buffer[sCounter]) {
1298 free(audio_buffer[sCounter]);
1299 audio_buffer[sCounter] = NULL;
1300 }
1301
1302 audio_buffer[sCounter] = (char *)malloc(file_hdr.data_size);
1303
1304 if ((count = read(audiofd, audio_buffer[sCounter],
1305 file_hdr.data_size)) < 0) {
1306 fprintf(stderr, "audio_load: error reading\n");
1307 close(audiofd);
1308 }
1309
1310 buffer_counter[sCounter] = count;
1311 close(audiofd);
1312
1313 # endif
1314
1315 #ifdef LINUXAUDIO
1316
1317 #endif
1318
1319 garbName = fileName;
1320 garbPath = dataPath;
1321 garbCount = sCounter;
1322
1323 }
1324