1 /*
2 Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20 #include "rt_def.h"
21 #include "rt_sound.h"
22 #include "_rt_soun.h"
23 #include "fx_man.h"
24 #include "music.h"
25 #include "z_zone.h"
26 #include "w_wad.h"
27 #include "rt_main.h"
28 #include "rt_ted.h"
29 #include "rt_menu.h"
30 #include "rt_playr.h"
31 #include "rt_util.h"
32 #include "rt_rand.h"
33 #include "watcom.h"
34 #include <stdio.h>
35 #include <stdlib.h>
36
37 #if PLATFORM_DOS
38 #include <mem.h>
39 #include <io.h>
40 #elif PLATFORM_UNIX
41 #include <unistd.h>
42 #endif
43
44 #include "rt_cfg.h"
45 #include "isr.h"
46 #include "develop.h"
47 #include "rt_net.h"
48
49 #include "rt_str.h"
50
51 #if (SHAREWARE==0)
52 #include "snd_reg.h"
53 #else
54 #include "snd_shar.h"
55 #endif
56 //MED
57 #include "memcheck.h"
58
59 // Local Variables
60
61 static int soundstart;
62 static int soundtype;
63 int SD_Started=false;
64 static boolean PositionStored=false;
65 static int NumBadSounds=0;
66 static int remotestart;
67 static boolean SoundsRemapped = false;
68
69 int musicnums[ 11 ] = {
70 -1, UltraSound, SoundBlaster, SoundMan16, ProAudioSpectrum,
71 Awe32, SoundScape, WaveBlaster, GenMidi, SoundCanvas, Adlib
72 };
73
74 int fxnums[ 11 ] = {
75 -1, UltraSound, SoundBlaster, SoundMan16, ProAudioSpectrum,
76 Awe32, SoundScape, Adlib, SoundSource, TandySoundSource, PC
77 };
78
79 void MU_SetupGUSInitFile( void );
80
MUSIC_GetPosition(void)81 int MUSIC_GetPosition( void ) {
82 songposition pos;
83
84 MUSIC_GetSongPosition( &pos );
85 return pos.milliseconds;
86 }
87
MUSIC_SetPosition(int time)88 void MUSIC_SetPosition( int time ) {
89 MUSIC_SetSongTime( ( unsigned long )time );
90 }
91
92
93 //***************************************************************************
94 //
95 // SoundNumber
96 //
97 //***************************************************************************
98
SoundNumber(int x)99 int SoundNumber ( int x )
100 {
101 if ((x>=SD_REMOTEM1SND) && (x<=SD_REMOTEM10SND))
102 return remotestart + x - SD_REMOTEM1SND;
103 // sounds[x].snds[soundtype]+remotestart;
104 else
105 return sounds[x].snds[soundtype]+soundstart;
106 }
107
108
109 //***************************************************************************
110 //
111 // SD_MakeCacheable - Make a sound that has just finished playing cacheable again
112 //
113 //***************************************************************************
SD_MakeCacheable(unsigned long sndnum)114 void SD_MakeCacheable( unsigned long sndnum )
115 {
116 if (sndnum == (unsigned long) -1)
117 {
118 return;
119 }
120
121 if (sndnum>=MAXSOUNDS)
122 {
123 SoftError ("Illegal sound value in SD_MakeCacheable value=%ld\n",sndnum);
124 return;
125 }
126 sounds[sndnum].count--;
127 if (sounds[sndnum].count>0)
128 return;
129 else
130 W_CacheLumpNum(SoundNumber(sndnum),PU_CACHE, CvtFixme, 1);
131 }
132
133 #if 0
134 //***************************************************************************
135 //
136 // SD_PrintActive
137 //
138 //***************************************************************************
139 void SD_PrintActive ( void )
140 {
141 int i;
142
143 myprintf("Active Sounds\n");
144 for (i=0;i<MAXSOUNDS;i++)
145 {
146 if (sounds[i].count>0)
147 {
148 myprintf("sound active #%ld\n",i);
149 }
150 }
151 }
152 #endif
153
154 //***************************************************************************
155 //
156 // SD_SetupFXCard - Initialize sound Tables and start up sound card
157 //
158 //***************************************************************************
159
SD_SetupFXCard(int * numvoices,int * numbits,int * numchannels)160 int SD_SetupFXCard ( int * numvoices, int * numbits, int * numchannels)
161 {
162 fx_device device;
163 int status;
164 int card;
165
166 if (SD_Started==true)
167 SD_Shutdown();
168
169 if ( ( FXMode < 0 ) || ( FXMode >= 11 ) )
170 {
171 return( 0 );
172 }
173
174 card = fxnums[ FXMode ];
175 if (card==-1) // Check if it is off
176 return (0);
177 if ( ( card == SoundBlaster ) || ( card == Awe32 ) )
178 {
179 extern fx_blaster_config SBSettings;
180
181 status = FX_SetupSoundBlaster( SBSettings, numvoices,
182 numbits, numchannels );
183 }
184 else
185 {
186 status=FX_SetupCard( card, &device );
187 if ( status == FX_Ok )
188 {
189 *numvoices=device.MaxVoices;
190 *numbits=device.MaxSampleBits;
191 *numchannels=device.MaxChannels;
192 }
193 }
194
195 return (status);
196 }
197
198 //***************************************************************************
199 //
200 // SD_Startup - Initialize sound Tables and start up sound card
201 //
202 //***************************************************************************
203
SD_Startup(boolean bombonerror)204 int SD_Startup ( boolean bombonerror )
205 {
206 int status;
207 int card;
208 int voices;
209 int channels;
210 int bits;
211 int i;
212 extern boolean IS8250;
213
214 if (SD_Started==true)
215 SD_Shutdown();
216
217 if ( ( FXMode < 0 ) || ( FXMode >= 11 ) )
218 {
219 return( 0 );
220 }
221 card = fxnums[ FXMode ];
222 if (card==-1) // Check if it is off
223 return (0);
224
225 switch (card)
226 {
227 case UltraSound:
228 case SoundBlaster:
229 case SoundMan16:
230 case ProAudioSpectrum:
231 case Awe32:
232 case SoundSource:
233 case TandySoundSource:
234 case SoundScape:
235 soundstart=W_GetNumForName("digistrt")+1;
236 soundtype=fx_digital;
237 break;
238 case Adlib:
239 soundstart=W_GetNumForName("adstart")+1;
240 soundtype=fx_muse;
241 break;
242 case PC:
243 soundstart=W_GetNumForName("pcstart")+1;
244 soundtype=fx_muse;
245 break;
246 default:
247 Error("FX: Unsupported Card number %d",FXMode);
248 break;
249 }
250
251 if ( soundtype == fx_digital )
252 {
253 if ( SoundsRemapped == false )
254 {
255 for( i = 0; i < SD_LASTSOUND; i++ )
256 {
257 int snd;
258
259 snd = sounds[ i ].snds[ fx_digital ];
260 if ( snd >= 0)
261 {
262 sounds[ i ].snds[ fx_digital ] = W_GetNumForName(
263 W_GetNameForNum( snd + soundstart ) );
264 }
265 }
266 SoundsRemapped = true;
267 }
268 soundstart = 0;
269 }
270
271 voices = NumVoices;
272 channels = NumChannels;
273 bits = NumBits;
274
275 if ( IS8250 )
276 {
277 voices = max( voices, 4 );
278 channels = 1;
279 bits = 8;
280 }
281
282 #ifdef DOS
283 status=FX_Init( card, voices, channels, bits, 11000 );
284 #else
285 status=FX_Init( card, voices, channels, bits, 11025 );
286 #endif
287
288 if (status != FX_Ok)
289 {
290 if (bombonerror)
291 {
292 DeleteSoundFile ();
293 Error( "%s\n", FX_ErrorString( status ) );
294 }
295
296 return (status);
297 }
298
299 if (stereoreversed == true)
300 {
301 FX_SetReverseStereo(!FX_GetReverseStereo());
302 }
303
304 FX_SetCallBack( SD_MakeCacheable );
305
306 remotestart=W_GetNumForName("remostrt")+1;
307
308 SD_Started=true;
309
310 FX_SetVolume (FXvolume);
311
312 return (0);
313 }
314
315 //***************************************************************************
316 //
317 // SD_SoundOkay - checks to see if the sound is okay
318 //
319 //***************************************************************************
320
SD_SoundOkay(int sndnum)321 boolean SD_SoundOkay ( int sndnum )
322 {
323 if (SD_Started==false)
324 return false;
325
326 if (sndnum>=MAXSOUNDS)
327 Error ("Illegal sound number, sound number = %d\n",sndnum);
328
329 if (SoundOffset(sndnum)==-1)
330 return false;
331
332 if ( ( sounds[ sndnum ].flags & SD_PLAYONCE ) &&
333 ( SD_SoundActive( sounds[ sndnum ].prevhandle ) ) )
334 {
335 return false;
336 }
337
338 return true;
339 }
340
341 //***************************************************************************
342 //
343 // SD_PlayIt - Play a pre-setup sound
344 //
345 //***************************************************************************
346
SD_PlayIt(int sndnum,int angle,int distance,int pitch)347 int SD_PlayIt ( int sndnum, int angle, int distance, int pitch )
348 {
349 int voice;
350 byte * snd;
351
352 #if (DEVELOPMENT == 1)
353 #if (SOUNDTEST == 1)
354 SoftError("SOUND =%d \n",sndnum);
355 #endif
356 #endif
357
358 if (!(sounds[sndnum].flags & SD_WRITE))
359 {
360 if (sounds[sndnum].count)
361 {
362 if (distance<=sounds[sndnum].prevdistance)
363 FX_StopSound(sounds[sndnum].prevhandle);
364 else
365 return 0;
366 }
367 }
368
369 if ( !FX_VoiceAvailable( sounds[sndnum].priority ) )
370 {
371 return( 0 );
372 }
373
374 sounds[sndnum].count++;
375
376 snd=W_CacheLumpNum(SoundNumber(sndnum),PU_STATIC, CvtNull, 1);
377
378 #ifdef DOS
379 if ( *snd == 'C' )
380 {
381 voice = FX_PlayVOC3D( snd, pitch, angle, distance,
382 sounds[sndnum].priority, (unsigned long) sndnum );
383 }
384 else
385 {
386 voice = FX_PlayWAV3D( snd, pitch, angle, distance,
387 sounds[sndnum].priority, (unsigned long) sndnum );
388 }
389 #else
390 /*
391 Oh boy. The library used to implement these functions may need a
392 file size. So, let's just hack these in!
393 */
394 if ( *snd == 'C' )
395 {
396 voice = FX_PlayVOC3D_ROTT( snd, W_LumpLength(SoundNumber(sndnum)),
397 pitch, angle, distance,
398 sounds[sndnum].priority, (unsigned long) sndnum );
399 }
400 else
401 {
402 voice = FX_PlayWAV3D_ROTT( snd, W_LumpLength(SoundNumber(sndnum)),
403 pitch, angle, distance,
404 sounds[sndnum].priority, (unsigned long) sndnum );
405 }
406 #endif
407
408 if ( voice < FX_Ok )
409 {
410 #if (DEVELOPMENT == 1)
411 /*
412 if (MV_ErrorCode == MV_InvalidVOCFile)
413 {
414 Error("SD_PlayIt: Invalid VOC File snd=%p sndnum=%ld lump=%ld\n",snd,sndnum,SoundNumber(sndnum));
415 }
416 */
417 NumBadSounds++;
418 SoftError("SD_PlayIt: Error/Warning %s\n",FX_ErrorString( FX_Error ));
419 SoftError("BadSoundNumber %ld time %ld\n",NumBadSounds,GetTicCount());
420 #endif
421 SD_MakeCacheable( sndnum );
422
423 return 0;
424 }
425
426 NumBadSounds=0;
427
428 if (!(sounds[sndnum].flags & SD_WRITE))
429 {
430 sounds[sndnum].prevhandle=voice;
431 sounds[sndnum].prevdistance=distance;
432 }
433 return voice;
434 }
435
436
437 //***************************************************************************
438 //
439 // SD_Play - Play a sample
440 //
441 //***************************************************************************
442
SD_Play(int sndnum)443 int SD_Play ( int sndnum )
444 {
445 int voice;
446 int pitch;
447
448 if ( SD_SoundOkay ( sndnum ) == false )
449 return 0;
450
451 pitch = 0;
452
453 if ( !( sounds[ sndnum ].flags & SD_PITCHSHIFTOFF ) )
454 {
455 pitch = PitchOffset();
456 }
457
458 voice = SD_PlayIt ( sndnum, 0, 0, pitch );
459
460 return voice;
461
462 }
463
464 //***************************************************************************
465 //
466 // SD_Play3D - Play a positioned sample
467 //
468 //***************************************************************************
469
SD_Play3D(int sndnum,int angle,int distance)470 int SD_Play3D ( int sndnum, int angle, int distance )
471 {
472 int voice;
473 int pitch;
474
475 if ( SD_SoundOkay ( sndnum ) == false )
476 return 0;
477
478 pitch = 0;
479 if ( !( sounds[ sndnum ].flags & SD_PITCHSHIFTOFF ) )
480 {
481 pitch = PitchOffset();
482 }
483
484 voice = SD_PlayIt ( sndnum, angle, distance, pitch );
485
486 return voice;
487
488 }
489
490 //***************************************************************************
491 //
492 // SD_PlayPositionedSound - Play a positioned sample
493 //
494 //***************************************************************************
495
SD_PlayPositionedSound(int sndnum,int px,int py,int x,int y)496 int SD_PlayPositionedSound ( int sndnum, int px, int py, int x, int y )
497 {
498 int voice;
499 int angle;
500 int distance;
501 int dx;
502 int dy;
503 int pitch;
504
505 if ( SD_SoundOkay ( sndnum ) == false )
506 return 0;
507
508 dx=(x-px);
509 dy=(py-y);
510
511 distance=FindDistance(dx,dy) >> SD_DISTANCESHIFT;
512
513 if (distance>255)
514 return 0;
515
516 if (distance!=0)
517 {
518 angle = ( atan2_appx(dx,dy) & (FINEANGLES-1) ) >> 6;
519 }
520 else
521 {
522 angle=0;
523 }
524
525 pitch = 0;
526
527 if ( !( sounds[ sndnum ].flags & SD_PITCHSHIFTOFF ) )
528 {
529 pitch = PitchOffset();
530 }
531
532 voice = SD_PlayIt ( sndnum, angle, distance, pitch );
533
534 return voice;
535
536 }
537
538 //***************************************************************************
539 //
540 // SD_PlaySoundRTP - Play a positioned sample relative to the player
541 //
542 //***************************************************************************
543
SD_PlaySoundRTP(int sndnum,int x,int y)544 int SD_PlaySoundRTP ( int sndnum, int x, int y )
545 {
546 int voice;
547 int angle;
548 int distance;
549 int dx;
550 int dy;
551 int pitch;
552
553
554 if ( SD_SoundOkay ( sndnum ) == false )
555 return 0;
556
557 dx=(x-player->x);
558 dy=(player->y-y);
559
560 distance=FindDistance(dx,dy) >> SD_DISTANCESHIFT;
561
562 if (distance>255)
563 return 0;
564
565 if (distance!=0)
566 {
567 angle = ( (player->angle - atan2_appx(dx,dy)) & (FINEANGLES-1) ) >> 6;
568 }
569 else
570 {
571 angle=0;
572 }
573
574 pitch = 0;
575
576 if ( !( sounds[ sndnum ].flags & SD_PITCHSHIFTOFF ) )
577 {
578 pitch = PitchOffset();
579 }
580
581 voice = SD_PlayIt ( sndnum, angle, distance, pitch );
582
583 return voice;
584 }
585
586 //***************************************************************************
587 //
588 // SD_PlayPitchedSound - Play a pitched sample
589 //
590 //***************************************************************************
591
SD_PlayPitchedSound(int sndnum,int volume,int pitch)592 int SD_PlayPitchedSound ( int sndnum, int volume, int pitch )
593 {
594 int voice;
595 int distance;
596
597 if ( SD_SoundOkay ( sndnum ) == false )
598 return 0;
599
600 distance = 255 - volume;
601
602 voice = SD_PlayIt ( sndnum, 0, distance, pitch );
603
604 return voice;
605 }
606
607 //***************************************************************************
608 //
609 // SD_SetSoundPitch - sets the pitch of a sound
610 //
611 //***************************************************************************
612
SD_SetSoundPitch(int sndnum,int pitch)613 void SD_SetSoundPitch ( int sndnum, int pitch )
614 {
615 int status;
616
617 if (SD_Started==false)
618 return;
619
620 if (!FX_SoundActive(sndnum))
621 return;
622
623 status=FX_SetPitch( sndnum, pitch );
624 if (status != FX_Ok)
625 {
626 #if (DEVELOPMENT == 1)
627 SoftError("SD_SetSoundPitch : %s\n",FX_ErrorString( status ));
628 #endif
629 }
630 }
631
632 //***************************************************************************
633 //
634 // SD_PanRTP Sound - pan a positioned sample relative to the player
635 //
636 //***************************************************************************
637
SD_PanRTP(int handle,int x,int y)638 void SD_PanRTP ( int handle, int x, int y )
639 {
640 int angle;
641 int distance;
642 int dx;
643 int dy;
644 int status;
645
646 if (SD_Started==false)
647 return;
648
649 if (!FX_SoundActive(handle))
650 return;
651
652 dx=(x-player->x);
653 dy=(player->y-y);
654
655 distance=FindDistance(dx,dy) >> SD_DISTANCESHIFT;
656
657 if (distance>255)
658 return;
659
660 if (distance!=0)
661 {
662 angle = ( (player->angle - atan2_appx(dx,dy)) & (FINEANGLES-1) ) >> 6;
663 }
664 else
665 {
666 angle = 0;
667 }
668
669 status = FX_Pan3D ( handle, angle, distance );
670
671 if (status != FX_Ok)
672 {
673 #if (DEVELOPMENT == 1)
674 SoftError("SD_PanPositionedSound: %s\n",FX_ErrorString( status ));
675 #endif
676 }
677 }
678
679 //***************************************************************************
680 //
681 // SD_SetPan - set the pan of a sample
682 //
683 //***************************************************************************
684
SD_SetPan(int handle,int vol,int left,int right)685 void SD_SetPan ( int handle, int vol, int left, int right )
686 {
687 int status;
688
689 if (SD_Started==false)
690 return;
691
692 if (!FX_SoundActive(handle))
693 return;
694
695 status=FX_SetPan( handle, vol, left, right );
696
697 if (status != FX_Ok)
698 {
699 #if (DEVELOPMENT == 1)
700 SoftError("SD_SetPan: %s\n",FX_ErrorString( status ));
701 #endif
702 }
703 }
704
705 //***************************************************************************
706 //
707 // SD_PanPositioned Sound - pan a positioned sample
708 //
709 //***************************************************************************
710
SD_PanPositionedSound(int handle,int px,int py,int x,int y)711 void SD_PanPositionedSound ( int handle, int px, int py, int x, int y )
712 {
713 int angle;
714 int distance;
715 int dx;
716 int dy;
717 int status;
718
719 if (SD_Started==false)
720 return;
721
722 if (!FX_SoundActive(handle))
723 return;
724
725 dx=(x-px);
726 dy=(py-y);
727
728 distance=FindDistance(dx,dy) >> SD_DISTANCESHIFT;
729
730 if (distance>255)
731 return;
732
733 if (distance!=0)
734 {
735 angle = ( atan2_appx(dx,dy) & (FINEANGLES-1) ) >> 6;
736 }
737 else
738 {
739 angle = 0;
740 }
741
742 status=FX_Pan3D( handle, angle, distance );
743
744 if (status != FX_Ok)
745 {
746 #if (DEVELOPMENT == 1)
747 SoftError("SD_PanPositionedSound: %s\n",FX_ErrorString( status ));
748 #endif
749 }
750 }
751
752
753 //***************************************************************************
754 //
755 // SD_StopSound - Stop the current sound from playing
756 //
757 //***************************************************************************
758
SD_StopSound(int handle)759 void SD_StopSound ( int handle )
760 {
761 int status;
762
763 if (SD_Started==false)
764 return;
765
766 status=FX_StopSound( handle);
767
768 if (status != FX_Ok)
769 {
770 #if (DEVELOPMENT == 1)
771 SoftError("SD_StopSound: %s\n",FX_ErrorString( status ));
772 #endif
773 }
774 }
775
776 //***************************************************************************
777 //
778 // SD_StopAllSounds - Stop All the sounds currently playing
779 //
780 //***************************************************************************
781
SD_StopAllSounds(void)782 void SD_StopAllSounds ( void )
783 {
784 int status;
785
786 if (SD_Started==false)
787 return;
788
789 status=FX_StopAllSounds();
790
791 if (status != FX_Ok)
792 {
793 #if (DEVELOPMENT == 1)
794 SoftError("SD_StopAllSounds: %s\n",FX_ErrorString( status ));
795 #endif
796 }
797 }
798
799 //***************************************************************************
800 //
801 // SD_SoundActive - See if a sound is active
802 //
803 //***************************************************************************
804
SD_SoundActive(int handle)805 int SD_SoundActive ( int handle )
806 {
807 if (SD_Started==false)
808 {
809 return false;
810 }
811 else
812 {
813 return (FX_SoundActive(handle));
814 }
815 }
816
817 //***************************************************************************
818 //
819 // SD_WaitSound - wait until a sound has finished
820 //
821 //***************************************************************************
SD_WaitSound(int handle)822 void SD_WaitSound ( int handle )
823 {
824 int time;
825
826 IN_ClearKeysDown();
827
828 while (FX_SoundActive(handle)!=0)
829 {
830 time=GetTicCount()+1;
831 while (time>GetTicCount()) {}
832 if ((LastScan) || IN_GetMouseButtons())
833 break;
834 }
835 }
836
837
838 //***************************************************************************
839 //
840 // SD_Shutdown - Shutdown the sound system
841 //
842 //***************************************************************************
843
SD_Shutdown(void)844 void SD_Shutdown (void)
845 {
846 if (SD_Started==false)
847 return;
848
849 FX_Shutdown();
850 SD_Started=false;
851 }
852
853
854 //***************************************************************************
855 //
856 // SD_PreCacheSound - PreCache sound
857 //
858 //***************************************************************************
859
SD_PreCacheSound(int num)860 void SD_PreCacheSound ( int num )
861 {
862 if ( SD_SoundOkay ( num ) == false )
863 return;
864
865 PreCacheLump(SoundNumber(num),PU_CACHESOUNDS+sounds[num].priority);
866 }
867
868 //***************************************************************************
869 //
870 // SD_PreCacheSoundGroup - PreCache sound group
871 //
872 //***************************************************************************
873
SD_PreCacheSoundGroup(int lo,int hi)874 void SD_PreCacheSoundGroup ( int lo, int hi )
875 {
876 int i;
877
878 if (SD_Started==false)
879 return;
880
881 for (i=lo;i<=hi;i++)
882 SD_PreCacheSound(i);
883 }
884
885
886 #if (SHAREWARE == 1)
887 #define MAXSONGS 18
888 static song_t rottsongs[MAXSONGS] = {
889 { loop_no, song_apogee ,"FANFARE2","Apogee Fanfare"},
890 { loop_yes, song_title ,"RISE", "Rise"},
891 { loop_yes, song_menu ,"MMMENU", "MMMenu"},
892 { loop_yes, song_christmas,"DEADLY", "Deadly Gentlemen"},
893 { loop_yes, song_elevator,"GOINGUP", "Going up?"},
894 { loop_yes, song_endlevel,"HOWDIDO", "How'd I do?"},
895 { loop_yes, song_secretmenu,"FISHPOLK","Fish Polka"},
896 { loop_yes, song_gameover,"YOUSUCK", "You Suck"},
897 { loop_yes, song_youwin ,"WATZNEXT","Watz Next?"},
898 { loop_no, song_gason ,"GAZZ!", "Gazz!"},
899 { loop_yes, song_level ,"FASTWAY", "Goin' Down The Fast Way"},
900 { loop_yes, song_level ,"MISTACHE","Mist Ache"},
901 { loop_yes, song_level ,"OWW", "Oww!!!"},
902 { loop_yes, song_level ,"SMOKE", "Smoke And Mirrors"},
903 { loop_yes, song_level ,"SPRAY", "Spray"},
904 { loop_yes, song_level ,"RUNLIKE", "Run Like Smeg"},
905 { loop_yes, song_level ,"SMOOTH", "Havana Smooth"},
906 { loop_yes, song_level ,"CHANT", "Chant"},
907 };
908 #else
909 #define MAXSONGS 34
910 static song_t rottsongs[MAXSONGS] = {
911 { loop_no, song_apogee ,"FANFARE2","Apogee Fanfare"},
912 { loop_yes, song_title ,"RISE", "Rise"},
913 { loop_yes, song_menu ,"MMMENU", "MMMenu"},
914 { loop_yes, song_christmas,"DEADLY", "Deadly Gentlemen"},
915 { loop_yes, song_elevator,"GOINGUP", "Going up?"},
916 { loop_yes, song_secretmenu,"FISHPOLK","Fish Polka"},
917 { loop_yes, song_endlevel,"HOWDIDO", "How'd I do?"},
918 { loop_yes, song_gameover,"YOUSUCK", "You Suck"},
919 { loop_yes, song_cinematic2,"WATZNEXT","Watz Next?"},
920 { loop_no, song_gason ,"GAZZ!", "Gazz!"},
921 { loop_yes, song_level ,"FASTWAY", "Goin' Down The Fast Way"},
922 { loop_yes, song_level ,"MISTACHE","Mist Ache"},
923 { loop_yes, song_level ,"OWW", "Oww!!!"},
924 { loop_yes, song_level ,"SMOKE", "Smoke And Mirrors"},
925 { loop_yes, song_level ,"SPRAY", "Spray"},
926 { loop_yes, song_level ,"RUNLIKE", "Run Like Smeg"},
927 { loop_yes, song_level ,"SMOOTH", "Havana Smooth"},
928 { loop_yes, song_level ,"CHANT", "Chant"},
929 { loop_yes, song_level ,"MEDIEV1A","Funeral of Queen Mary"},
930 { loop_yes, song_level ,"TASKFORC","Task Force"},
931 { loop_yes, song_level ,"KISSOFF", "KISS Off"},
932 { loop_yes, song_level ,"RADAGIO", "Adagio For Strings"},
933 { loop_yes, song_level ,"SHARDS", "Shards"},
934 { loop_yes, song_level ,"STAIRS", "I Choose the Stairs"},
935 { loop_yes, song_level ,"SUCKTHIS","Suck This"},
936 { loop_yes, song_level ,"EXCALIBR","Excalibur"},
937 { loop_yes, song_level ,"CCCOOL", "CCCool"},
938 { loop_yes, song_level ,"WORK_DAY","Work Day"},
939 { loop_yes, song_level ,"WHERIZIT","Where Iz It?"},
940 { loop_no, song_bossdie,"BOSSBLOW", "Boss Blow"},
941 { loop_yes, song_bosssee ,"HELLERO", "Hellero"},
942 { loop_yes, song_cinematic1,"EVINRUDE","Evin Rude"},
943 { loop_yes, song_youwin ,"VICTORY", "Victory!"},
944 { loop_yes, song_dogend ,"HERE_BOY","Here Boy"}
945 };
946 #endif
947
948 static byte * currentsong;
949 static int MU_Started=false;
950 static int lastsongnumber=-1;
951 int storedposition=0;
952
953 //****************************************************************************
954 //
955 // MU_JukeBoxMenu()
956 //
957 //****************************************************************************
958
MU_PlayJukeBoxSong(int which)959 void MU_PlayJukeBoxSong
960 (
961 int which
962 )
963
964 {
965 if ( ( MusicMode > 0 ) && ( MU_Started == true ) )
966 {
967 SetMenuHeader( rottsongs[ which ].songname );
968 MU_PlaySong( which );
969 }
970 }
971
972
973 //****************************************************************************
974 //
975 // MU_JukeBoxMenu()
976 //
977 //****************************************************************************
978
MU_JukeBoxRedraw(void)979 void MU_JukeBoxRedraw
980 (
981 void
982 )
983
984 {
985 if ( ( MusicMode > 0 ) && ( MU_Started == true ) )
986 {
987 SetMenuHeader( rottsongs[ lastsongnumber ].songname );
988 }
989 }
990
991
992 //****************************************************************************
993 //
994 // MU_JukeBoxMenu()
995 //
996 //****************************************************************************
997
MU_JukeBoxMenu(void)998 void MU_JukeBoxMenu
999 (
1000 void
1001 )
1002
1003 {
1004 char *SongNames[ MAXSONGS ];
1005 int i;
1006
1007 for( i = 0; i < MAXSONGS; i++ )
1008 {
1009 SongNames[ i ] = rottsongs[ i ].songname;
1010 }
1011
1012 HandleMultiPageCustomMenu( SongNames, MAXSONGS, lastsongnumber,
1013 "Jukebox", MU_PlayJukeBoxSong, MU_JukeBoxRedraw, false );
1014
1015 if ( rottsongs[ lastsongnumber ].loopflag == loop_no )
1016 {
1017 MU_StartSong(song_level);
1018 }
1019 }
1020
1021 //***************************************************************************
1022 //
1023 // MusicStarted - see if the music is started
1024 //
1025 //***************************************************************************
MusicStarted(void)1026 boolean MusicStarted( void )
1027 {
1028 return MU_Started;
1029 }
1030
1031 //***************************************************************************
1032 //
1033 // MU_Startup - Initialize music stuff
1034 //
1035 //***************************************************************************
1036
MU_Startup(boolean bombonerror)1037 int MU_Startup ( boolean bombonerror )
1038 {
1039 int status;
1040 int card;
1041
1042 if (MU_Started==true)
1043 {
1044 MU_StopSong();
1045 MU_Shutdown();
1046 }
1047 if ( ( MusicMode < 0 ) || ( MusicMode >= 11 ) )
1048 {
1049 return( 0 );
1050 }
1051 card = musicnums[ MusicMode ];
1052 if (card==-1) // Check if it is off
1053 return (0);
1054
1055 if ( ( card == SoundBlaster ) || ( card == Awe32 ) || ( card == WaveBlaster ) )
1056 {
1057 if ( SD_Started == false )
1058 {
1059 extern fx_blaster_config SBSettings;
1060 int numvoices;
1061 int numbits;
1062 int numchannels;
1063
1064 FX_SetupSoundBlaster( SBSettings, &numvoices,
1065 &numbits, &numchannels );
1066 }
1067 }
1068
1069 if (card== UltraSound)
1070 {
1071 MU_SetupGUSInitFile();
1072 }
1073
1074 status=MUSIC_Init( card, MidiAddress );
1075
1076 if (status != MUSIC_Ok) {
1077 if (bombonerror)
1078 {
1079 DeleteSoundFile ();
1080 Error( "%s\n", MUSIC_ErrorString( status ) );
1081 }
1082 else
1083 return (status);
1084 }
1085
1086 currentsong=0;
1087
1088 MU_Started=true;
1089
1090 MU_SetVolume (MUvolume);
1091
1092 return (0);
1093 }
1094
1095 //***************************************************************************
1096 //
1097 // MU_Shutdown - Shutdown the music system
1098 //
1099 //***************************************************************************
1100
MU_Shutdown(void)1101 void MU_Shutdown (void)
1102 {
1103 if (MU_Started==false)
1104 return;
1105 MUSIC_Shutdown();
1106 MU_Started=false;
1107 }
1108 //***************************************************************************
1109 //
1110 // MU_SetupGUSInitFile - initialize GUS stuff
1111 //
1112 //***************************************************************************
1113
MU_SetupGUSInitFile(void)1114 void MU_SetupGUSInitFile( void )
1115 {
1116 char filename[ 128 ];
1117
1118 GetPathFromEnvironment( filename, ApogeePath, GUSMIDIINIFILE );
1119 if (access (filename, F_OK) != 0)
1120 {
1121 int lump;
1122
1123 lump=W_GetNumForName("gusmidi");
1124
1125 SaveFile (filename, W_CacheLumpNum(lump,PU_CACHE, CvtNull, 1), W_LumpLength(lump));
1126 }
1127 }
1128
1129 //***************************************************************************
1130 //
1131 // MU_GetNumForType - returns number of song in rottsongs of specific type
1132 //
1133 //***************************************************************************
MU_GetNumForType(int type)1134 int MU_GetNumForType ( int type )
1135 {
1136 int i;
1137
1138 for (i=0;i<MAXSONGS;i++)
1139 {
1140 if (rottsongs[i].songtype == type)
1141 return i;
1142 }
1143 Error("MU_GetNumForType: could not find song type in list\n");
1144 return -1;
1145 }
1146
1147
1148 //***************************************************************************
1149 //
1150 // MU_PlaySong - Play a specific song number
1151 //
1152 //***************************************************************************
1153
MU_PlaySong(int num)1154 void MU_PlaySong ( int num )
1155 {
1156 int lump;
1157 int size;
1158
1159 if (MU_Started==false)
1160 return;
1161
1162 if (num<0)
1163 return;
1164
1165 if (num>=MAXSONGS)
1166 Error("Song number out of range\n");
1167
1168 MU_StopSong();
1169
1170 lastsongnumber=num;
1171
1172 lump = W_GetNumForName(rottsongs[num].lumpname);
1173 size = W_LumpLength(lump);
1174
1175 currentsong=W_CacheLumpNum(lump,PU_STATIC, CvtFixme, 1);
1176
1177 #ifdef PLATFORM_DOS
1178 if (rottsongs[num].loopflag == loop_yes)
1179 MUSIC_PlaySong(currentsong,size,MUSIC_LoopSong);
1180 else
1181 MUSIC_PlaySong(currentsong,size,MUSIC_PlayOnce);
1182 #else
1183 if (rottsongs[num].loopflag == loop_yes)
1184 MUSIC_PlaySongROTT(currentsong,size,MUSIC_LoopSong);
1185 else
1186 MUSIC_PlaySongROTT(currentsong,size,MUSIC_PlayOnce);
1187 #endif
1188
1189 MU_SetVolume (MUvolume);
1190 }
1191
1192 //***************************************************************************
1193 //
1194 // MU_StopSong - Play a specific song number
1195 //
1196 //***************************************************************************
1197
MU_StopSong(void)1198 void MU_StopSong ( void )
1199 {
1200 if (MU_Started==false)
1201 return;
1202
1203 MUSIC_StopSong ();
1204 if (currentsong)
1205 {
1206 W_CacheLumpName(rottsongs[lastsongnumber].lumpname,PU_CACHE, CvtFixme, 1);
1207 currentsong=0;
1208 }
1209 }
1210
1211 //***************************************************************************
1212 //
1213 // MU_GetSongNumber - get current song number
1214 //
1215 //***************************************************************************
1216
MU_GetSongNumber(void)1217 int MU_GetSongNumber ( void )
1218 {
1219 return lastsongnumber;
1220 }
1221
1222
1223 //***************************************************************************
1224 //
1225 // MU_FadeToSong - Fade to a specific song in a certain time
1226 //
1227 //***************************************************************************
1228
MU_FadeToSong(int num,int time)1229 void MU_FadeToSong ( int num, int time )
1230 {
1231 int t;
1232
1233 if (MU_Started==false)
1234 return;
1235
1236 MU_FadeOut(time>>1);
1237
1238 while (MU_FadeActive())
1239 {
1240 t=GetTicCount();
1241 while (GetTicCount()==t) {}
1242 }
1243
1244 MU_FadeIn (num,time>>1);
1245 }
1246
1247 //***************************************************************************
1248 //
1249 // MU_FadeIn - Fade in
1250 //
1251 //***************************************************************************
1252
MU_FadeIn(int num,int time)1253 void MU_FadeIn ( int num, int time )
1254 {
1255 if (MU_Started==false)
1256 return;
1257
1258 MUSIC_SetVolume(0);
1259 MU_PlaySong ( num );
1260 MUSIC_FadeVolume (MUvolume, time);
1261 }
1262
1263 //***************************************************************************
1264 //
1265 // MU_FadeOut - Fade out
1266 //
1267 //***************************************************************************
1268
MU_FadeOut(int time)1269 void MU_FadeOut ( int time )
1270 {
1271 if (MU_Started==false)
1272 return;
1273 if (!MUSIC_SongPlaying())
1274 {
1275 #if (DEVELOPMENT == 1)
1276 SoftError("Called FadeOut with no song playing\n");
1277 #endif
1278 return;
1279 }
1280 MUSIC_FadeVolume(0,time);
1281 }
1282
1283
1284 //***************************************************************************
1285 //
1286 // MU_StartSong - Start a context sensitive song
1287 //
1288 //***************************************************************************
1289
MU_StartSong(int songtype)1290 void MU_StartSong ( int songtype )
1291 {
1292 int songnum;
1293
1294 if (MU_Started==false)
1295 return;
1296
1297 MU_StopSong();
1298
1299 songnum = MU_GetNumForType ( songtype );
1300 switch (songtype)
1301 {
1302 case song_level:
1303 if (IsChristmas())
1304 {
1305 songnum = MU_GetNumForType ( song_christmas );
1306 }
1307 else
1308 {
1309 songnum += GetSongForLevel ();
1310 }
1311 break;
1312 }
1313 MU_PlaySong (songnum);
1314 }
1315
1316 //***************************************************************************
1317 //
1318 // MU_StoreSongPostition - Save off Song Position
1319 //
1320 //***************************************************************************
1321
MU_StoreSongPosition(void)1322 void MU_StoreSongPosition ( void )
1323 {
1324 if (MU_Started==false)
1325 return;
1326 PositionStored=true;
1327 storedposition=MUSIC_GetPosition();
1328 }
1329
1330 //***************************************************************************
1331 //
1332 // MU_RestoreSongPostition - Save off Song Position
1333 //
1334 //***************************************************************************
1335
MU_RestoreSongPosition(void)1336 void MU_RestoreSongPosition ( void )
1337 {
1338 if (MU_Started==false)
1339 return;
1340 if (PositionStored==false)
1341 return;
1342 PositionStored=false;
1343
1344 MUSIC_SetPosition(storedposition);
1345 }
1346
1347 //***************************************************************************
1348 //
1349 // MU_GetStoredPostition - Get Stored song Position
1350 //
1351 //***************************************************************************
1352
MU_GetStoredPosition(void)1353 int MU_GetStoredPosition ( void )
1354 {
1355 if (PositionStored)
1356 return storedposition;
1357 else
1358 return -1;
1359 }
1360
1361 //***************************************************************************
1362 //
1363 // MU_SetStoredPostition - Get Stored song Position
1364 //
1365 //***************************************************************************
1366
MU_SetStoredPosition(int position)1367 void MU_SetStoredPosition ( int position )
1368 {
1369 if (MU_Started==false)
1370 return;
1371 if (position==-1)
1372 return;
1373 PositionStored=true;
1374 storedposition=position;
1375 }
1376
1377
1378
1379 //***************************************************************************
1380 //
1381 // MU_GetSongPostition - Get Song Position
1382 //
1383 //***************************************************************************
1384
MU_GetSongPosition(void)1385 int MU_GetSongPosition ( void )
1386 {
1387 if (MU_Started==false)
1388 return 0;
1389 return MUSIC_GetPosition();
1390 }
1391
1392 //***************************************************************************
1393 //
1394 // MU_SetSongPostition - Set Song Position
1395 //
1396 //***************************************************************************
1397
MU_SetSongPosition(int position)1398 void MU_SetSongPosition ( int position )
1399 {
1400 if (MU_Started==false)
1401 return;
1402 MUSIC_SetPosition(position);
1403 }
1404
1405 //***************************************************************************
1406 //
1407 // MU_SaveMusic
1408 //
1409 //***************************************************************************
1410
MU_SaveMusic(byte ** buf,int * size)1411 void MU_SaveMusic (byte ** buf, int * size)
1412 {
1413 int unitsize;
1414 byte *ptr;
1415 int vsize;
1416 int i;
1417
1418 //
1419 // Size
1420 //
1421
1422 unitsize=0;
1423
1424 unitsize+=sizeof(i);
1425 unitsize+=sizeof(i);
1426 unitsize+=sizeof(i);
1427
1428
1429 *size = unitsize;
1430 *buf = (byte *) SafeMalloc (*size);
1431
1432 ptr = *buf;
1433
1434 i=MU_GetSongNumber();
1435 if (rottsongs[i].songtype == song_menu)
1436 {
1437 i = MU_GetNumForType ( song_level );
1438 if (IsChristmas())
1439 {
1440 i = MU_GetNumForType ( song_christmas );
1441 }
1442 else
1443 {
1444 i += GetSongForLevel ();
1445 }
1446 vsize=sizeof(i);
1447 memcpy(ptr,&i,vsize);
1448 ptr+=vsize;
1449
1450 i=MU_GetStoredPosition();
1451 vsize=sizeof(i);
1452 memcpy(ptr,&i,vsize);
1453 ptr+=vsize;
1454
1455 i=-1;
1456 vsize=sizeof(i);
1457 memcpy(ptr,&i,vsize);
1458 ptr+=vsize;
1459 }
1460 else
1461 {
1462 vsize=sizeof(i);
1463 memcpy(ptr,&i,vsize);
1464 ptr+=vsize;
1465
1466 i=MU_GetSongPosition();
1467 vsize=sizeof(i);
1468 memcpy(ptr,&i,vsize);
1469 ptr+=vsize;
1470
1471 i=MU_GetStoredPosition();
1472 vsize=sizeof(i);
1473 memcpy(ptr,&i,vsize);
1474 ptr+=vsize;
1475 }
1476 }
1477
1478
1479 //***************************************************************************
1480 //
1481 // MU_LoadMusic
1482 //
1483 //***************************************************************************
1484
MU_LoadMusic(byte * buf,int size)1485 void MU_LoadMusic (byte * buf, int size)
1486 {
1487 int unitsize;
1488 byte *ptr;
1489 int i;
1490 int songnumber;
1491 boolean differentsong=false;
1492 int vsize;
1493
1494 //
1495 // Size
1496 //
1497
1498 unitsize=0;
1499
1500 unitsize+=sizeof(i);
1501 unitsize+=sizeof(i);
1502 unitsize+=sizeof(i);
1503
1504 if (size!=unitsize)
1505 Error("LoadMusic: Different number of parameters\n");
1506
1507 ptr = buf;
1508
1509 vsize=sizeof(songnumber);
1510 memcpy(&songnumber,ptr,vsize);
1511 ptr+=vsize;
1512 if (MU_GetSongNumber () != songnumber)
1513 {
1514 MU_PlaySong(songnumber);
1515 differentsong=true;
1516 }
1517
1518 vsize=sizeof(i);
1519 memcpy(&i,ptr,vsize);
1520 ptr+=vsize;
1521 if (differentsong==true)
1522 {
1523 MU_SetSongPosition(i);
1524 }
1525
1526 vsize=sizeof(i);
1527 memcpy(&i,ptr,vsize);
1528 ptr+=vsize;
1529 MU_SetStoredPosition(i);
1530
1531 // Check if game was saved with NOSOUND
1532
1533 if (MU_GetSongNumber () != songnumber)
1534 {
1535 MU_StartSong ( song_level );
1536 }
1537 }
1538