1 /* Catacomb Armageddon Source Code
\r
2 * Copyright (C) 1993-2014 Flat Rock Software
\r
4 * This program is free software; you can redistribute it and/or modify
\r
5 * it under the terms of the GNU General Public License as published by
\r
6 * the Free Software Foundation; either version 2 of the License, or
\r
7 * (at your option) any later version.
\r
9 * This program is distributed in the hope that it will be useful,
\r
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
12 * GNU General Public License for more details.
\r
14 * You should have received a copy of the GNU General Public License along
\r
15 * with this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
21 // ID_SD.c - Sound Manager
\r
23 // By Jason Blochowiak
\r
27 // This module handles dealing with generating sound on the appropriate
\r
30 // Depends on: User Mgr (for parm checking)
\r
34 // SoundSourcePresent - Sound Source thingie present?
\r
35 // SoundBlasterPresent - SoundBlaster card present?
\r
36 // AdLibPresent - AdLib card present?
\r
37 // SoundMode - What device is used for sound effects
\r
38 // (Use SM_SetSoundMode() to set)
\r
39 // MusicMode - What device is used for music
\r
40 // (Use SM_SetMusicMode() to set)
\r
42 // NeedsDigitized - load digitized sounds?
\r
43 // NeedsMusic - load music?
\r
48 #pragma hdrstop // Wierdo thing with MUSE
\r
52 #ifdef _MUSE_ // Will be defined in ID_Types.h
\r
55 #include "ID_HEADS.H"
\r
60 #define SDL_SoundFinished() {SoundNumber = SoundPriority = 0;}
\r
62 // Macros for AdLib stuff
\r
63 #define selreg(n) outportb(0x388,n)
\r
64 #define writereg(n) outportb(0x389,n)
\r
65 #define readstat() inportb(0x388)
\r
68 boolean SoundSourcePresent,SoundBlasterPresent,AdLibPresent,
\r
69 NeedsDigitized,NeedsMusic;
\r
74 word *SoundTable; // Really * _seg *SoundTable, but that don't work
\r
78 // Internal variables
\r
79 static boolean SD_Started;
\r
80 static boolean TimerDone;
\r
81 static word TimerVal,TimerDelay10,TimerDelay25,TimerDelay100;
\r
82 static longword TimerDivisor,TimerCount;
\r
83 static char *ParmStrings[] =
\r
88 static void (*SoundUserHook)(void);
\r
89 static word SoundNumber,SoundPriority;
\r
90 static void interrupt (*t0OldService)(void);
\r
91 //static word t0CountTable[] = {8,8,8,8,40,40};
\r
92 static long LocalTime;
\r
94 // PC Sound variables
\r
95 static byte pcLastSample,far *pcSound;
\r
96 static longword pcLengthLeft;
\r
97 static word pcSoundLookup[255];
\r
100 static boolean alNoCheck;
\r
101 static byte far *alSound;
\r
102 static word alBlock;
\r
103 static longword alLengthLeft;
\r
104 static longword alTimeCount;
\r
105 static Instrument alZeroInst;
\r
107 // This table maps channel numbers to carrier and modulator op cells
\r
108 static byte carriers[9] = { 3, 4, 5,11,12,13,19,20,21},
\r
109 modifiers[9] = { 0, 1, 2, 8, 9,10,16,17,18},
\r
110 // This table maps percussive voice numbers to op cells
\r
111 pcarriers[5] = {19,0xff,0xff,0xff,0xff},
\r
112 pmodifiers[5] = {16,17,18,20,21};
\r
114 // Sequencer variables
\r
115 static boolean sqActive;
\r
116 static word alFXReg;
\r
117 static ActiveTrack *tracks[sqMaxTracks],
\r
118 mytracks[sqMaxTracks];
\r
119 static word sqMode,sqFadeStep;
\r
120 static word far *sqHack,far *sqHackPtr,sqHackLen,sqHackSeqLen;
\r
121 static long sqHackTime;
\r
123 // Internal routines
\r
125 ///////////////////////////////////////////////////////////////////////////
\r
127 // SDL_SetTimer0() - Sets system timer 0 to the specified speed
\r
129 ///////////////////////////////////////////////////////////////////////////
\r
132 SDL_SetTimer0(word speed)
\r
134 #ifndef TPROF // If using Borland's profiling, don't screw with the timer
\r
135 outportb(0x43,0x36); // Change timer 0
\r
136 outportb(0x40,speed);
\r
137 outportb(0x40,speed >> 8);
\r
138 TimerDivisor = speed;
\r
140 TimerDivisor = 0x10000;
\r
144 ///////////////////////////////////////////////////////////////////////////
\r
146 // SDL_SetIntsPerSec() - Uses SDL_SetTimer0() to set the number of
\r
147 // interrupts generated by system timer 0 per second
\r
149 ///////////////////////////////////////////////////////////////////////////
\r
151 SDL_SetIntsPerSec(word ints)
\r
153 SDL_SetTimer0(1192030 / ints);
\r
156 ///////////////////////////////////////////////////////////////////////////
\r
158 // SDL_TimingService() - Used by SDL_InitDelay() to determine a timing
\r
159 // value for the current system that we're running on
\r
161 ///////////////////////////////////////////////////////////////////////////
\r
162 static void interrupt
\r
163 SDL_TimingService(void)
\r
168 outportb(0x20,0x20); // Ack interrupt
\r
171 ///////////////////////////////////////////////////////////////////////////
\r
173 // SDL_InitDelay() - Sets up TimerDelay's for SDL_Delay()
\r
175 ///////////////////////////////////////////////////////////////////////////
\r
177 SDL_InitDelay(void)
\r
182 setvect(8,SDL_TimingService); // Set to my timer 0 ISR
\r
184 SDL_SetIntsPerSec(1000); // Time 1ms
\r
186 for (i = 0,timer = 0;i < 10;i++) // Do timing test 10 times
\r
188 asm xor dx,dx // Zero DX
\r
189 asm mov cx,0xffff // Put starting value in CX
\r
190 asm mov [TimerDone],cx // TimerDone = false - 1
\r
192 asm or [TimerDone],0
\r
193 asm jnz startloop // Make sure we're at the start
\r
195 asm test [TimerDone],1 // See if TimerDone flag got hit
\r
196 asm jnz done // Yep - drop out of the loop
\r
200 if (0xffff - TimerVal > timer)
\r
201 timer = 0xffff - TimerVal;
\r
203 timer += timer / 2; // Use some slop
\r
204 TimerDelay10 = timer / (1000 / 10);
\r
205 TimerDelay25 = timer / (1000 / 25);
\r
206 TimerDelay100 = timer / (1000 / 100);
\r
208 SDL_SetTimer0(0); // Reset timer 0
\r
210 setvect(8,t0OldService); // Set back to old ISR
\r
213 ///////////////////////////////////////////////////////////////////////////
\r
215 // SDL_Delay() - Delays the specified amount of time
\r
217 ///////////////////////////////////////////////////////////////////////////
\r
219 SDL_Delay(word delay)
\r
226 asm test [TimerDone],0 // Useless code - just for timing equivilency
\r
236 ///////////////////////////////////////////////////////////////////////////
\r
238 // SDL_PCPlaySound() - Plays the specified sound on the PC speaker
\r
240 ///////////////////////////////////////////////////////////////////////////
\r
246 SDL_PCPlaySound(PCSound far *sound)
\r
252 pcLengthLeft = sound->common.length;
\r
253 pcSound = sound->data;
\r
258 ///////////////////////////////////////////////////////////////////////////
\r
260 // SDL_PCStopSound() - Stops the current sound playing on the PC Speaker
\r
262 ///////////////////////////////////////////////////////////////////////////
\r
268 SDL_PCStopSound(void)
\r
275 asm in al,0x61 // Turn the speaker off
\r
276 asm and al,0xfd // ~2
\r
282 ///////////////////////////////////////////////////////////////////////////
\r
284 // SDL_PCService() - Handles playing the next sample in a PC sound
\r
286 ///////////////////////////////////////////////////////////////////////////
\r
288 SDL_PCService(void)
\r
296 if (s != pcLastSample)
\r
302 if (s) // We have a frequency!
\r
304 t = pcSoundLookup[s];
\r
307 asm mov al,0xb6 // Write to channel 2 (speaker) timer
\r
310 asm out 42h,al // Low byte
\r
312 asm out 42h,al // High byte
\r
314 asm in al,0x61 // Turn the speaker & gate on
\r
318 else // Time for some silence
\r
320 asm in al,0x61 // Turn the speaker & gate off
\r
321 asm and al,0xfc // ~3
\r
328 if (!(--pcLengthLeft))
\r
331 SDL_SoundFinished();
\r
336 ///////////////////////////////////////////////////////////////////////////
\r
338 // SDL_ShutPC() - Turns off the pc speaker
\r
340 ///////////////////////////////////////////////////////////////////////////
\r
349 asm in al,0x61 // Turn the speaker & gate off
\r
350 asm and al,0xfc // ~3
\r
358 ///////////////////////////////////////////////////////////////////////////
\r
360 // alOut(n,b) - Puts b in AdLib card register n
\r
362 ///////////////////////////////////////////////////////////////////////////
\r
364 alOut(byte n,byte b)
\r
373 SDL_Delay(TimerDelay10);
\r
390 SDL_Delay(TimerDelay25);
\r
435 ///////////////////////////////////////////////////////////////////////////
\r
437 // SDL_SetInstrument() - Puts an instrument into a generator
\r
439 ///////////////////////////////////////////////////////////////////////////
\r
441 SDL_SetInstrument(int track,int which,Instrument far *inst,boolean percussive)
\r
447 c = pcarriers[which];
\r
448 m = pmodifiers[which];
\r
452 c = carriers[which];
\r
453 m = modifiers[which];
\r
456 tracks[track - 1]->inst = *inst;
\r
457 tracks[track - 1]->percussive = percussive;
\r
459 alOut(m + alChar,inst->mChar);
\r
460 alOut(m + alScale,inst->mScale);
\r
461 alOut(m + alAttack,inst->mAttack);
\r
462 alOut(m + alSus,inst->mSus);
\r
463 alOut(m + alWave,inst->mWave);
\r
465 // Most percussive instruments only use one cell
\r
468 alOut(c + alChar,inst->cChar);
\r
469 alOut(c + alScale,inst->cScale);
\r
470 alOut(c + alAttack,inst->cAttack);
\r
471 alOut(c + alSus,inst->cSus);
\r
472 alOut(c + alWave,inst->cWave);
\r
475 alOut(which + alFeedCon,inst->nConn); // DEBUG - I think this is right
\r
479 ///////////////////////////////////////////////////////////////////////////
\r
481 // SDL_ALStopSound() - Turns off any sound effects playing through the
\r
484 ///////////////////////////////////////////////////////////////////////////
\r
490 SDL_ALStopSound(void)
\r
496 alOut(alFreqH + 0,0);
\r
502 SDL_AlSetFXInst(Instrument far *inst)
\r
508 alOut(m + alChar,inst->mChar);
\r
509 alOut(m + alScale,inst->mScale);
\r
510 alOut(m + alAttack,inst->mAttack);
\r
511 alOut(m + alSus,inst->mSus);
\r
512 alOut(m + alWave,inst->mWave);
\r
513 alOut(c + alChar,inst->cChar);
\r
514 alOut(c + alScale,inst->cScale);
\r
515 alOut(c + alAttack,inst->cAttack);
\r
516 alOut(c + alSus,inst->cSus);
\r
517 alOut(c + alWave,inst->cWave);
\r
518 // DEBUG!!! - I just put this in
\r
519 // alOut(alFeedCon,inst->nConn);
\r
522 ///////////////////////////////////////////////////////////////////////////
\r
524 // SDL_ALPlaySound() - Plays the specified sound on the AdLib card
\r
526 ///////////////////////////////////////////////////////////////////////////
\r
532 SDL_ALPlaySound(AdLibSound far *sound)
\r
534 Instrument far *inst;
\r
541 alLengthLeft = sound->common.length;
\r
542 alSound = sound->data;
\r
543 alBlock = ((sound->block & 7) << 2) | 0x20;
\r
544 inst = &sound->inst;
\r
546 if (!(inst->mSus | inst->cSus))
\r
549 Quit("SDL_ALPlaySound() - Bad instrument");
\r
552 SDL_AlSetFXInst(inst);
\r
557 ///////////////////////////////////////////////////////////////////////////
\r
559 // SDL_ALSoundService() - Plays the next sample out through the AdLib card
\r
561 ///////////////////////////////////////////////////////////////////////////
\r
563 SDL_ALSoundService(void)
\r
571 alOut(alFreqH + 0,0);
\r
574 alOut(alFreqL + 0,s);
\r
575 alOut(alFreqH + 0,alBlock);
\r
578 if (!(--alLengthLeft))
\r
581 alOut(alFreqH + 0,0);
\r
582 SDL_SoundFinished();
\r
588 ///////////////////////////////////////////////////////////////////////////
\r
590 // SDL_SelectMeasure() - sets up sequencing variables for a given track
\r
592 ///////////////////////////////////////////////////////////////////////////
\r
594 SDL_SelectMeasure(ActiveTrack *track)
\r
596 track->seq = track->moods[track->mood];
\r
597 track->nextevent = 0;
\r
602 SDL_ALService(void)
\r
610 while (sqHackLen && (sqHackTime <= alTimeCount))
\r
613 sqHackTime = alTimeCount + *sqHackPtr++;
\r
623 sqHackPtr = (word far *)sqHack;
\r
624 sqHackLen = sqHackSeqLen;
\r
625 alTimeCount = sqHackTime = 0;
\r
629 ///////////////////////////////////////////////////////////////////////////
\r
631 // SDL_ShutAL() - Shuts down the AdLib card for sound effects
\r
633 ///////////////////////////////////////////////////////////////////////////
\r
640 alOut(alEffects,0);
\r
641 alOut(alFreqH + 0,0);
\r
642 SDL_AlSetFXInst(&alZeroInst);
\r
648 ///////////////////////////////////////////////////////////////////////////
\r
650 // SDL_CleanAL() - Totally shuts down the AdLib card
\r
652 ///////////////////////////////////////////////////////////////////////////
\r
661 alOut(alEffects,0);
\r
662 for (i = 1;i < 0xf5;i++)
\r
668 ///////////////////////////////////////////////////////////////////////////
\r
670 // SDL_StartAL() - Starts up the AdLib card for sound effects
\r
672 ///////////////////////////////////////////////////////////////////////////
\r
677 alOut(alEffects,alFXReg);
\r
678 SDL_AlSetFXInst(&alZeroInst);
\r
681 ///////////////////////////////////////////////////////////////////////////
\r
683 // SDL_DetectAdLib() - Determines if there's an AdLib (or SoundBlaster
\r
684 // emulating an AdLib) present
\r
686 ///////////////////////////////////////////////////////////////////////////
\r
688 SDL_DetectAdLib(void)
\r
690 byte status1,status2;
\r
693 alOut(4,0x60); // Reset T1 & T2
\r
694 alOut(4,0x80); // Reset IRQ
\r
695 status1 = readstat();
\r
696 alOut(2,0xff); // Set timer 1
\r
697 alOut(4,0x21); // Start timer 1
\r
698 SDL_Delay(TimerDelay100);
\r
700 status2 = readstat();
\r
704 if (((status1 & 0xe0) == 0x00) && ((status2 & 0xe0) == 0xc0))
\r
706 for (i = 1;i <= 0xf5;i++) // Zero all the registers
\r
709 alOut(1,0x20); // Set WSE=1
\r
710 alOut(8,0); // Set CSM=0 & SEL=0
\r
718 ///////////////////////////////////////////////////////////////////////////
\r
720 // SDL_t0Service() - My timer 0 ISR which handles the different timings and
\r
721 // dispatches to whatever other routines are appropriate
\r
723 ///////////////////////////////////////////////////////////////////////////
\r
724 static void interrupt
\r
725 SDL_t0Service(void)
\r
727 static word count = 1;
\r
729 #if 0 // for debugging
\r
730 asm mov dx,STATUS_REGISTER_1
\r
732 asm mov dx,ATR_INDEX
\r
733 asm mov al,ATR_OVERSCAN
\r
735 asm mov al,4 // red
\r
742 if (MusicMode == smm_AdLib)
\r
745 if (!(++count & 7))
\r
760 SDL_ALSoundService();
\r
768 if (!(++count & 1))
\r
781 SDL_ALSoundService();
\r
786 asm mov ax,[WORD PTR TimerCount]
\r
787 asm add ax,[WORD PTR TimerDivisor]
\r
788 asm mov [WORD PTR TimerCount],ax
\r
790 t0OldService(); // If we overflow a word, time to call old int handler
\r
793 outportb(0x20,0x20); // Ack the interrupt
\r
796 #if 0 // for debugging
\r
797 asm mov dx,STATUS_REGISTER_1
\r
799 asm mov dx,ATR_INDEX
\r
800 asm mov al,ATR_OVERSCAN
\r
802 asm mov al,3 // blue
\r
804 asm mov al,0x20 // normal
\r
809 ////////////////////////////////////////////////////////////////////////////
\r
811 // SDL_ShutDevice() - turns off whatever device was being used for sound fx
\r
813 ////////////////////////////////////////////////////////////////////////////
\r
815 SDL_ShutDevice(void)
\r
826 SoundMode = sdm_Off;
\r
829 ///////////////////////////////////////////////////////////////////////////
\r
831 // SDL_CleanDevice() - totally shuts down all sound devices
\r
833 ///////////////////////////////////////////////////////////////////////////
\r
835 SDL_CleanDevice(void)
\r
837 if ((SoundMode == sdm_AdLib) || (MusicMode == smm_AdLib))
\r
841 ///////////////////////////////////////////////////////////////////////////
\r
843 // SDL_StartDevice() - turns on whatever device is to be used for sound fx
\r
845 ///////////////////////////////////////////////////////////////////////////
\r
847 SDL_StartDevice(void)
\r
855 SoundNumber = SoundPriority = 0;
\r
859 SDL_SetTimerSpeed(void)
\r
864 if (MusicMode == smm_AdLib)
\r
865 rate = TickBase * 8;
\r
868 rate = TickBase * 2;
\r
869 SDL_SetIntsPerSec(rate);
\r
874 ///////////////////////////////////////////////////////////////////////////
\r
876 // SD_SetSoundMode() - Sets which sound hardware to use for sound effects
\r
878 ///////////////////////////////////////////////////////////////////////////
\r
880 SD_SetSoundMode(SDMode mode)
\r
891 NeedsDigitized = false;
\r
895 tableoffset = STARTPCSOUNDS;
\r
896 NeedsDigitized = false;
\r
902 tableoffset = STARTADLIBSOUNDS;
\r
903 NeedsDigitized = false;
\r
913 if (result && (mode != SoundMode))
\r
918 SoundTable = (word *)(&audiosegs[tableoffset]);
\r
923 SDL_SetTimerSpeed();
\r
928 ///////////////////////////////////////////////////////////////////////////
\r
930 // SD_SetMusicMode() - sets the device to use for background music
\r
932 ///////////////////////////////////////////////////////////////////////////
\r
934 SD_SetMusicMode(SMMode mode)
\r
940 while (SD_MusicPlaying())
\r
946 NeedsMusic = false;
\r
964 SDL_SetTimerSpeed();
\r
970 ///////////////////////////////////////////////////////////////////////////
\r
972 // SD_Startup() - starts up the Sound Mgr
\r
973 // Detects all additional sound hardware and installs my ISR
\r
975 ///////////////////////////////////////////////////////////////////////////
\r
987 for (i = 1;i < _argc;i++)
\r
989 switch (US_CheckParm(_argv[i],ParmStrings))
\r
991 case 0: // No AdLib detection
\r
1000 t0OldService = getvect(8); // Get old timer 0 ISR
\r
1002 SDL_InitDelay(); // SDL_InitDelay() uses t0OldService
\r
1004 setvect(8,SDL_t0Service); // Set to my timer 0 ISR
\r
1005 LocalTime = TimeCount = alTimeCount = 0;
\r
1007 SD_SetSoundMode(sdm_Off);
\r
1009 SD_SetMusicMode(smm_Off);
\r
1013 AdLibPresent = SDL_DetectAdLib();
\r
1015 for (i = 0;i < 255;i++)
\r
1016 pcSoundLookup[i] = i * 60;
\r
1018 SD_Started = true;
\r
1021 ///////////////////////////////////////////////////////////////////////////
\r
1023 // SD_Default() - Sets up the default behaviour for the Sound Mgr whether
\r
1024 // the config file was present or not.
\r
1026 ///////////////////////////////////////////////////////////////////////////
\r
1028 SD_Default(boolean gotit,SDMode sd,SMMode sm)
\r
1030 boolean gotsd,gotsm;
\r
1032 gotsd = gotsm = gotit;
\r
1034 if (gotsd) // Make sure requested sound hardware is available
\r
1039 gotsd = AdLibPresent;
\r
1050 if (sd != SoundMode)
\r
1051 SD_SetSoundMode(sd);
\r
1054 if (gotsm) // Make sure requested music hardware is available
\r
1059 gotsm = AdLibPresent;
\r
1069 if (sm != MusicMode)
\r
1070 SD_SetMusicMode(sm);
\r
1074 ///////////////////////////////////////////////////////////////////////////
\r
1076 // SD_Shutdown() - shuts down the Sound Mgr
\r
1077 // Removes sound ISR and turns off whatever sound hardware was active
\r
1079 ///////////////////////////////////////////////////////////////////////////
\r
1090 SDL_CleanDevice();
\r
1097 setvect(8,t0OldService);
\r
1101 SD_Started = false;
\r
1104 ///////////////////////////////////////////////////////////////////////////
\r
1106 // SD_SetUserHook() - sets the routine that the Sound Mgr calls every 1/70th
\r
1107 // of a second from its timer 0 ISR
\r
1109 ///////////////////////////////////////////////////////////////////////////
\r
1111 SD_SetUserHook(void (* hook)(void))
\r
1113 SoundUserHook = hook;
\r
1116 ///////////////////////////////////////////////////////////////////////////
\r
1118 // SD_PlaySound() - plays the specified sound on the appropriate hardware
\r
1120 ///////////////////////////////////////////////////////////////////////////
\r
1122 SD_PlaySound(soundnames sound)
\r
1124 SoundCommon far *s;
\r
1126 if ((SoundMode == sdm_Off) || (sound == -1))
\r
1129 s = MK_FP(SoundTable[sound],0);
\r
1131 Quit("SD_PlaySound() - Uncached sound");
\r
1133 Quit("SD_PlaySound() - Zero length sound");
\r
1134 if (s->priority < SoundPriority)
\r
1137 switch (SoundMode)
\r
1140 SDL_PCPlaySound((void far *)s);
\r
1143 SDL_ALPlaySound((void far *)s);
\r
1147 SoundNumber = sound;
\r
1148 SoundPriority = s->priority;
\r
1151 ///////////////////////////////////////////////////////////////////////////
\r
1153 // SD_SoundPlaying() - returns the sound number that's playing, or 0 if
\r
1154 // no sound is playing
\r
1156 ///////////////////////////////////////////////////////////////////////////
\r
1158 SD_SoundPlaying(void)
\r
1160 boolean result = false;
\r
1162 switch (SoundMode)
\r
1165 result = pcSound? true : false;
\r
1168 result = alSound? true : false;
\r
1173 return(SoundNumber);
\r
1178 ///////////////////////////////////////////////////////////////////////////
\r
1180 // SD_StopSound() - if a sound is playing, stops it
\r
1182 ///////////////////////////////////////////////////////////////////////////
\r
1184 SD_StopSound(void)
\r
1186 switch (SoundMode)
\r
1189 SDL_PCStopSound();
\r
1192 SDL_ALStopSound();
\r
1196 SDL_SoundFinished();
\r
1199 ///////////////////////////////////////////////////////////////////////////
\r
1201 // SD_WaitSoundDone() - waits until the current sound is done playing
\r
1203 ///////////////////////////////////////////////////////////////////////////
\r
1205 SD_WaitSoundDone(void)
\r
1207 while (SD_SoundPlaying())
\r
1211 ///////////////////////////////////////////////////////////////////////////
\r
1213 // SD_MusicOn() - turns on the sequencer
\r
1215 ///////////////////////////////////////////////////////////////////////////
\r
1224 ///////////////////////////////////////////////////////////////////////////
\r
1226 // SD_MusicOff() - turns off the sequencer and any playing notes
\r
1228 ///////////////////////////////////////////////////////////////////////////
\r
1236 switch (MusicMode)
\r
1240 alOut(alEffects,0);
\r
1241 for (i = 0;i < sqMaxTracks;i++)
\r
1242 alOut(alFreqH + i + 1,0);
\r
1249 ///////////////////////////////////////////////////////////////////////////
\r
1251 // SD_StartMusic() - starts playing the music pointed to
\r
1253 ///////////////////////////////////////////////////////////////////////////
\r
1255 SD_StartMusic(MusicGroup far *music)
\r
1262 if (MusicMode == smm_AdLib)
\r
1264 sqHackPtr = sqHack = music->values;
\r
1265 sqHackSeqLen = sqHackLen = music->length;
\r
1275 ///////////////////////////////////////////////////////////////////////////
\r
1277 // SD_FadeOutMusic() - starts fading out the music. Call SD_MusicPlaying()
\r
1278 // to see if the fadeout is complete
\r
1280 ///////////////////////////////////////////////////////////////////////////
\r
1282 SD_FadeOutMusic(void)
\r
1285 switch (MusicMode)
\r
1288 // DEBUG - quick hack to turn the music off
\r
1295 ///////////////////////////////////////////////////////////////////////////
\r
1297 // SD_MusicPlaying() - returns true if music is currently playing, false if
\r
1300 ///////////////////////////////////////////////////////////////////////////
\r
1302 SD_MusicPlaying(void)
\r
1307 switch (MusicMode)
\r
1311 // DEBUG - not written
\r