/* Catacomb 3-D Source Code * Copyright (C) 1993-2014 Flat Rock Software * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // // ID Engine // ID_SD.c - Sound Manager // v1.1d1 // By Jason Blochowiak // // // This module handles dealing with generating sound on the appropriate // hardware // // Depends on: User Mgr (for parm checking) // // Globals: // For User Mgr: // SoundSourcePresent - Sound Source thingie present? // SoundBlasterPresent - SoundBlaster card present? // AdLibPresent - AdLib card present? // SoundMode - What device is used for sound effects // (Use SM_SetSoundMode() to set) // MusicMode - What device is used for music // (Use SM_SetMusicMode() to set) // For Cache Mgr: // NeedsDigitized - load digitized sounds? // NeedsMusic - load music? // #pragma hdrstop // Wierdo thing with MUSE #include #ifdef _MUSE_ // Will be defined in ID_Types.h #include "ID_SD.h" #else #include "ID_HEADS.H" #endif #pragma hdrstop #pragma warn -pia #define SDL_SoundFinished() {SoundNumber = SoundPriority = 0;} // Macros for AdLib stuff #define selreg(n) outportb(alFMAddr,n) #define writereg(n) outportb(alFMData,n) #define readstat() inportb(alFMStatus) // Global variables boolean SoundSourcePresent,SoundBlasterPresent,AdLibPresent, NeedsDigitized,NeedsMusic; SDMode SoundMode; SMMode MusicMode; dword TimeCount; word HackCount; word *SoundTable; // Really * _seg *SoundTable, but that don't work boolean ssIsTandy; word ssPort = 2; // Internal variables static boolean SD_Started; boolean TimerDone; word TimerVal,TimerDelay10,TimerDelay25,TimerDelay100; dword TimerDivisor,TimerCount; static char *ParmStrings[] = { "noal", nil }; static void (*SoundUserHook)(void); word SoundNumber,SoundPriority; void interrupt (*t0OldService)(void); // word t0CountTable[] = {8,8,8,8,40,40}; long LocalTime; // PC Sound variables volatile byte pcLastSample,far *pcSound; dword pcLengthLeft; word pcSoundLookup[255]; // AdLib variables boolean alNoCheck; byte far *alSound; word alBlock; dword alLengthLeft; dword alTimeCount; Instrument alZeroInst; // This table maps channel numbers to carrier and modulator op cells static byte carriers[9] = { 3, 4, 5,11,12,13,19,20,21}, modifiers[9] = { 0, 1, 2, 8, 9,10,16,17,18}, // This table maps percussive voice numbers to op cells pcarriers[5] = {19,0xff,0xff,0xff,0xff}, pmodifiers[5] = {16,17,18,20,21}; // Sequencer variables boolean sqActive; static word alFXReg; static ActiveTrack *tracks[sqMaxTracks], mytracks[sqMaxTracks]; static word sqMode,sqFadeStep; word far *sqHack,far *sqHackPtr,sqHackLen,sqHackSeqLen; long sqHackTime; // Internal routines /////////////////////////////////////////////////////////////////////////// // // SDL_SetTimer0() - Sets system timer 0 to the specified speed // /////////////////////////////////////////////////////////////////////////// #pragma argsused static void SDL_SetTimer0(word speed) { #ifndef TPROF // If using Borland's profiling, don't screw with the timer outportb(0x43,0x36); // Change timer 0 outportb(0x40,speed); outportb(0x40,speed >> 8); TimerDivisor = speed; #else TimerDivisor = 0x10000; #endif } /////////////////////////////////////////////////////////////////////////// // // SDL_SetIntsPerSec() - Uses SDL_SetTimer0() to set the number of // interrupts generated by system timer 0 per second // /////////////////////////////////////////////////////////////////////////// static void SDL_SetIntsPerSec(word ints) { SDL_SetTimer0(1192030 / ints); } /////////////////////////////////////////////////////////////////////////// // // SDL_TimingService() - Used by SDL_InitDelay() to determine a timing // value for the current system that we're running on // /////////////////////////////////////////////////////////////////////////// static void interrupt SDL_TimingService(void) { TimerVal = _CX; TimerDone++; outportb(0x20,0x20); // Ack interrupt } /////////////////////////////////////////////////////////////////////////// // // SDL_InitDelay() - Sets up TimerDelay's for SDL_Delay() // /////////////////////////////////////////////////////////////////////////// static void SDL_InitDelay(void) { int i; word timer; setvect(8,SDL_TimingService); // Set to my timer 0 ISR SDL_SetIntsPerSec(1000); // Time 1ms for (i = 0,timer = 0;i < 10;i++) // Do timing test 10 times { asm xor dx,dx // Zero DX asm mov cx,0xffff // Put starting value in CX asm mov [TimerDone],cx // TimerDone = false - 1 startloop: asm or [TimerDone],0 asm jnz startloop // Make sure we're at the start loop: asm test [TimerDone],1 // See if TimerDone flag got hit asm jnz done // Yep - drop out of the loop asm loop loop done: if (0xffff - TimerVal > timer) timer = 0xffff - TimerVal; } timer += timer / 2; // Use some slop TimerDelay10 = timer / (1000 / 10); TimerDelay25 = timer / (1000 / 25); TimerDelay100 = timer / (1000 / 100); SDL_SetTimer0(0); // Reset timer 0 setvect(8,t0OldService); // Set back to old ISR } /////////////////////////////////////////////////////////////////////////// // // SDL_Delay() - Delays the specified amount of time // /////////////////////////////////////////////////////////////////////////// static void SDL_Delay(word delay) { if (!delay) return; asm mov cx,[delay] loop: asm test [TimerDone],0 // Useless code - just for timing equivilency asm jnz done asm loop loop done:; } // // PC Sound code // /////////////////////////////////////////////////////////////////////////// // // SDL_PCPlaySound() - Plays the specified sound on the PC speaker // /////////////////////////////////////////////////////////////////////////// #ifdef _MUSE_ void #else static void #endif SDL_PCPlaySound(PCSound far *sound) { asm pushf asm cli pcLastSample = -1; pcLengthLeft = sound->common.length; pcSound = sound->data; asm popf } /////////////////////////////////////////////////////////////////////////// // // SDL_PCStopSound() - Stops the current sound playing on the PC Speaker // /////////////////////////////////////////////////////////////////////////// #ifdef _MUSE_ void #else static void #endif SDL_PCStopSound(void) { asm pushf asm cli (long)pcSound = 0; asm in al,0x61 // Turn the speaker off asm and al,0xfd // ~2 asm out 0x61,al asm popf } /////////////////////////////////////////////////////////////////////////// // // SDL_PCService() - Handles playing the next sample in a PC sound // /////////////////////////////////////////////////////////////////////////// static void SDL_PCService(void) { byte s; word t; if (pcSound) { s = *pcSound++; if (s != pcLastSample) { asm pushf asm cli pcLastSample = s; if (s) // We have a frequency! { t = pcSoundLookup[s]; asm mov bx,[t] asm mov al,0xb6 // Write to channel 2 (speaker) timer asm out 43h,al asm mov al,bl asm out 42h,al // Low byte asm mov al,bh asm out 42h,al // High byte asm in al,0x61 // Turn the speaker & gate on asm or al,3 asm out 0x61,al } else // Time for some silence { asm in al,0x61 // Turn the speaker & gate off asm and al,0xfc // ~3 asm out 0x61,al } asm popf } if (!(--pcLengthLeft)) { SDL_PCStopSound(); SDL_SoundFinished(); } } } /////////////////////////////////////////////////////////////////////////// // // SDL_ShutPC() - Turns off the pc speaker // /////////////////////////////////////////////////////////////////////////// static void SDL_ShutPC(void) { asm pushf asm cli pcSound = 0; asm in al,0x61 // Turn the speaker & gate off asm and al,0xfc // ~3 asm out 0x61,al asm popf } // AdLib Code /////////////////////////////////////////////////////////////////////////// // // alOut(n,b) - Puts b in AdLib card register n // /////////////////////////////////////////////////////////////////////////// void alOut(byte n,byte b) { asm pushf asm cli asm mov dx,0x388 asm mov al,[n] asm out dx,al #if 0 SDL_Delay(TimerDelay10); #else asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx #endif asm mov dx,0x389 asm mov al,[b] asm out dx,al asm popf #if 0 SDL_Delay(TimerDelay25); #else asm mov dx,0x388 asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx asm in al, dx #endif } #if 0 /////////////////////////////////////////////////////////////////////////// // // SDL_SetInstrument() - Puts an instrument into a generator // /////////////////////////////////////////////////////////////////////////// static void SDL_SetInstrument(int track,int which,Instrument far *inst,boolean percussive) { byte c,m; if (percussive) { c = pcarriers[which]; m = pmodifiers[which]; } else { c = carriers[which]; m = modifiers[which]; } tracks[track - 1]->inst = *inst; tracks[track - 1]->percussive = percussive; alOut(m + alChar,inst->mChar); alOut(m + alScale,inst->mScale); alOut(m + alAttack,inst->mAttack); alOut(m + alSus,inst->mSus); alOut(m + alWave,inst->mWave); // Most percussive instruments only use one cell if (c != 0xff) { alOut(c + alChar,inst->cChar); alOut(c + alScale,inst->cScale); alOut(c + alAttack,inst->cAttack); alOut(c + alSus,inst->cSus); alOut(c + alWave,inst->cWave); } alOut(which + alFeedCon,inst->nConn); // DEBUG - I think this is right } #endif /////////////////////////////////////////////////////////////////////////// // // SDL_ALStopSound() - Turns off any sound effects playing through the // AdLib card // /////////////////////////////////////////////////////////////////////////// #ifdef _MUSE_ void #else static void #endif SDL_ALStopSound(void) { asm pushf asm cli (long)alSound = 0; alOut(alFreqH + 0,0); asm popf } static void SDL_AlSetFXInst(Instrument far *inst) { byte c,m; m = modifiers[0]; c = carriers[0]; alOut(m + alChar,inst->mChar); alOut(m + alScale,inst->mScale); alOut(m + alAttack,inst->mAttack); alOut(m + alSus,inst->mSus); alOut(m + alWave,inst->mWave); alOut(c + alChar,inst->cChar); alOut(c + alScale,inst->cScale); alOut(c + alAttack,inst->cAttack); alOut(c + alSus,inst->cSus); alOut(c + alWave,inst->cWave); // DEBUG!!! - I just put this in // alOut(alFeedCon,inst->nConn); } /////////////////////////////////////////////////////////////////////////// // // SDL_ALPlaySound() - Plays the specified sound on the AdLib card // /////////////////////////////////////////////////////////////////////////// #ifdef _MUSE_ void #else static void #endif SDL_ALPlaySound(AdLibSound far *sound) { Instrument far *inst; SDL_ALStopSound(); asm pushf asm cli alLengthLeft = sound->common.length; alSound = sound->data; alBlock = ((sound->block & 7) << 2) | 0x20; inst = &sound->inst; if (!(inst->mSus | inst->cSus)) { asm popf Quit("SDL_ALPlaySound() - Bad instrument"); } SDL_AlSetFXInst(inst); asm popf } /////////////////////////////////////////////////////////////////////////// // // SDL_ALSoundService() - Plays the next sample out through the AdLib card // /////////////////////////////////////////////////////////////////////////// static void SDL_ALSoundService(void) { byte s; if (alSound) { s = *alSound++; if (!s) alOut(alFreqH + 0,0); else { alOut(alFreqL + 0,s); alOut(alFreqH + 0,alBlock); } if (!(--alLengthLeft)) { (long)alSound = 0; alOut(alFreqH + 0,0); SDL_SoundFinished(); } } } #if 0 /////////////////////////////////////////////////////////////////////////// // // SDL_SelectMeasure() - sets up sequencing variables for a given track // /////////////////////////////////////////////////////////////////////////// static void SDL_SelectMeasure(ActiveTrack *track) { track->seq = track->moods[track->mood]; track->nextevent = 0; } #endif static void SDL_ALService(void) { byte a,v; word w; if (!sqActive) return; while (sqHackLen && (sqHackTime <= alTimeCount)) { w = *sqHackPtr++; sqHackTime = alTimeCount + *sqHackPtr++; asm mov dx,[w] asm mov [a],dl asm mov [v],dh alOut(a,v); sqHackLen -= 4; } alTimeCount++; if (!sqHackLen) { sqHackPtr = (word far *)sqHack; sqHackLen = sqHackSeqLen; alTimeCount = sqHackTime = 0; } } /////////////////////////////////////////////////////////////////////////// // // SDL_ShutAL() - Shuts down the AdLib card for sound effects // /////////////////////////////////////////////////////////////////////////// static void SDL_ShutAL(void) { asm pushf asm cli alOut(alEffects,0); alOut(alFreqH + 0,0); SDL_AlSetFXInst(&alZeroInst); alSound = 0; asm popf } /////////////////////////////////////////////////////////////////////////// // // SDL_CleanAL() - Totally shuts down the AdLib card // /////////////////////////////////////////////////////////////////////////// static void SDL_CleanAL(void) { int i; asm pushf asm cli alOut(alEffects,0); for (i = 1;i < 0xf5;i++) alOut(i,0); asm popf } /////////////////////////////////////////////////////////////////////////// // // SDL_StartAL() - Starts up the AdLib card for sound effects // /////////////////////////////////////////////////////////////////////////// static void SDL_StartAL(void) { alFXReg = 0; alOut(alEffects,alFXReg); SDL_AlSetFXInst(&alZeroInst); } /////////////////////////////////////////////////////////////////////////// // // SDL_DetectAdLib() - Determines if there's an AdLib (or SoundBlaster // emulating an AdLib) present // /////////////////////////////////////////////////////////////////////////// static boolean SDL_DetectAdLib(void) { byte status1,status2; int i; alOut(4,0x60); // Reset T1 & T2 alOut(4,0x80); // Reset IRQ status1 = readstat(); alOut(2,0xff); // Set timer 1 alOut(4,0x21); // Start timer 1 SDL_Delay(TimerDelay100); status2 = readstat(); alOut(4,0x60); alOut(4,0x80); if (((status1 & 0xe0) == 0x00) && ((status2 & 0xe0) == 0xc0)) { for (i = 1;i <= 0xf5;i++) // Zero all the registers alOut(i,0); alOut(1,0x20); // Set WSE=1 alOut(8,0); // Set CSM=0 & SEL=0 return(true); } else return(false); } /////////////////////////////////////////////////////////////////////////// // // SDL_t0Service() - My timer 0 ISR which handles the different timings and // dispatches to whatever other routines are appropriate // /////////////////////////////////////////////////////////////////////////// static void interrupt SDL_t0Service(void) { static word count = 1; #if 0 // for debugging asm mov dx,STATUS_REGISTER_1 asm in al,dx asm mov dx,ATR_INDEX asm mov al,ATR_OVERSCAN asm out dx,al asm mov al,4 // red asm out dx,al #endif HackCount++; if (MusicMode == smm_AdLib) { SDL_ALService(); if (!(++count & 7)) { LocalTime++; TimeCount++; if (SoundUserHook) SoundUserHook(); } if (!(count & 3)) { switch (SoundMode) { case sdm_PC: SDL_PCService(); break; case sdm_AdLib: SDL_ALSoundService(); break; } } } else { if (!(++count & 1)) { LocalTime++; TimeCount++; if (SoundUserHook) SoundUserHook(); } switch (SoundMode) { case sdm_PC: SDL_PCService(); break; case sdm_AdLib: SDL_ALSoundService(); break; } } asm mov ax,[WORD PTR TimerCount] asm add ax,[WORD PTR TimerDivisor] asm mov [WORD PTR TimerCount],ax asm jnc myack t0OldService(); // If we overflow a word, time to call old int handler asm jmp olddone myack:; outportb(0x20,0x20); // Ack the interrupt olddone:; #if 0 // for debugging asm mov dx,STATUS_REGISTER_1 asm in al,dx asm mov dx,ATR_INDEX asm mov al,ATR_OVERSCAN asm out dx,al asm mov al,3 // blue asm out dx,al asm mov al,0x20 // normal asm out dx,al #endif } //////////////////////////////////////////////////////////////////////////// // // SDL_ShutDevice() - turns off whatever device was being used for sound fx // //////////////////////////////////////////////////////////////////////////// static void SDL_ShutDevice(void) { switch (SoundMode) { case sdm_PC: SDL_ShutPC(); break; case sdm_AdLib: SDL_ShutAL(); break; } SoundMode = sdm_Off; } /////////////////////////////////////////////////////////////////////////// // // SDL_CleanDevice() - totally shuts down all sound devices // /////////////////////////////////////////////////////////////////////////// static void SDL_CleanDevice(void) { if ((SoundMode == sdm_AdLib) || (MusicMode == smm_AdLib)) SDL_CleanAL(); } /////////////////////////////////////////////////////////////////////////// // // SDL_StartDevice() - turns on whatever device is to be used for sound fx // /////////////////////////////////////////////////////////////////////////// static void SDL_StartDevice(void) { switch (SoundMode) { case sdm_AdLib: SDL_StartAL(); break; } SoundNumber = SoundPriority = 0; } static void SDL_SetTimerSpeed(void) { word rate; if (MusicMode == smm_AdLib) rate = TickBase * 8; else rate = TickBase * 2; SDL_SetIntsPerSec(rate); } // Public routines /////////////////////////////////////////////////////////////////////////// // // SD_SetSoundMode() - Sets which sound hardware to use for sound effects // /////////////////////////////////////////////////////////////////////////// boolean SD_SetSoundMode(SDMode mode) { boolean result; word tableoffset; SD_StopSound(); #ifndef _MUSE_ switch (mode) { case sdm_Off: NeedsDigitized = false; result = true; break; case sdm_PC: tableoffset = STARTPCSOUNDS; NeedsDigitized = false; result = true; break; case sdm_AdLib: if (AdLibPresent) { tableoffset = STARTADLIBSOUNDS; NeedsDigitized = false; result = true; } break; default: result = false; break; } #endif if (result && (mode != SoundMode)) { SDL_ShutDevice(); SoundMode = mode; #ifndef _MUSE_ SoundTable = (word *)(&audiosegs[tableoffset]); #endif SDL_StartDevice(); } SDL_SetTimerSpeed(); return(result); } /////////////////////////////////////////////////////////////////////////// // // SD_SetMusicMode() - sets the device to use for background music // /////////////////////////////////////////////////////////////////////////// boolean SD_SetMusicMode(SMMode mode) { boolean result; SD_FadeOutMusic(); while (SD_MusicPlaying()) ; switch (mode) { case smm_Off: NeedsMusic = false; result = true; break; case smm_AdLib: if (AdLibPresent) { NeedsMusic = true; result = true; } break; default: result = false; break; } if (result) MusicMode = mode; SDL_SetTimerSpeed(); return(result); } /////////////////////////////////////////////////////////////////////////// // // SD_Startup() - starts up the Sound Mgr // Detects all additional sound hardware and installs my ISR // /////////////////////////////////////////////////////////////////////////// void SD_Startup(void) { int i; if (SD_Started) return; ssIsTandy = false; alNoCheck = false; #ifndef _MUSE_ for (i = 1;i < _argc;i++) { switch (US_CheckParm(_argv[i],ParmStrings)) { case 0: // No AdLib detection alNoCheck = true; break; } } #endif SoundUserHook = 0; t0OldService = getvect(8); // Get old timer 0 ISR SDL_InitDelay(); // SDL_InitDelay() uses t0OldService setvect(8,SDL_t0Service); // Set to my timer 0 ISR LocalTime = TimeCount = alTimeCount = 0; SD_SetSoundMode(sdm_Off); SD_SetMusicMode(smm_Off); if (!alNoCheck) AdLibPresent = SDL_DetectAdLib(); for (i = 0;i < 255;i++) pcSoundLookup[i] = i * 60; SD_Started = true; } /////////////////////////////////////////////////////////////////////////// // // SD_Default() - Sets up the default behaviour for the Sound Mgr whether // the config file was present or not. // /////////////////////////////////////////////////////////////////////////// void SD_Default(boolean gotit,SDMode sd,SMMode sm) { boolean gotsd,gotsm; gotsd = gotsm = gotit; if (gotsd) // Make sure requested sound hardware is available { switch (sd) { case sdm_AdLib: gotsd = AdLibPresent; break; } } if (!gotsd) { if (AdLibPresent) sd = sdm_AdLib; else sd = sdm_PC; } if (sd != SoundMode) SD_SetSoundMode(sd); if (gotsm) // Make sure requested music hardware is available { switch (sm) { case sdm_AdLib: gotsm = AdLibPresent; break; } } if (!gotsm) { if (AdLibPresent) sm = smm_AdLib; } if (sm != MusicMode) SD_SetMusicMode(sm); } /////////////////////////////////////////////////////////////////////////// // // SD_Shutdown() - shuts down the Sound Mgr // Removes sound ISR and turns off whatever sound hardware was active // /////////////////////////////////////////////////////////////////////////// void SD_Shutdown(void) { if (!SD_Started) return; SD_MusicOff(); SDL_ShutDevice(); SDL_CleanDevice(); asm pushf asm cli SDL_SetTimer0(0); setvect(8,t0OldService); asm popf SD_Started = false; } /////////////////////////////////////////////////////////////////////////// // // SD_SetUserHook() - sets the routine that the Sound Mgr calls every 1/70th // of a second from its timer 0 ISR // /////////////////////////////////////////////////////////////////////////// void SD_SetUserHook(void (* hook)(void)) { SoundUserHook = hook; } /////////////////////////////////////////////////////////////////////////// // // SD_PlaySound() - plays the specified sound on the appropriate hardware // /////////////////////////////////////////////////////////////////////////// void SD_PlaySound(soundnames sound) { SoundCommon far *s; if ((SoundMode == sdm_Off) || (sound == -1)) return; s = MK_FP(SoundTable[sound],0); if (!s) Quit("SD_PlaySound() - Uncached sound"); if (!s->length) Quit("SD_PlaySound() - Zero length sound"); if (s->priority < SoundPriority) return; switch (SoundMode) { case sdm_PC: SDL_PCPlaySound((void far *)s); break; case sdm_AdLib: SDL_ALPlaySound((void far *)s); break; } SoundNumber = sound; SoundPriority = s->priority; } /////////////////////////////////////////////////////////////////////////// // // SD_SoundPlaying() - returns the sound number that's playing, or 0 if // no sound is playing // /////////////////////////////////////////////////////////////////////////// word SD_SoundPlaying(void) { boolean result = false; switch (SoundMode) { case sdm_PC: result = pcSound? true : false; break; case sdm_AdLib: result = alSound? true : false; break; } if (result) return(SoundNumber); else return(false); } /////////////////////////////////////////////////////////////////////////// // // SD_StopSound() - if a sound is playing, stops it // /////////////////////////////////////////////////////////////////////////// void SD_StopSound(void) { switch (SoundMode) { case sdm_PC: SDL_PCStopSound(); break; case sdm_AdLib: SDL_ALStopSound(); break; } SDL_SoundFinished(); } /////////////////////////////////////////////////////////////////////////// // // SD_WaitSoundDone() - waits until the current sound is done playing // /////////////////////////////////////////////////////////////////////////// void SD_WaitSoundDone(void) { while (SD_SoundPlaying()) ; } /////////////////////////////////////////////////////////////////////////// // // SD_MusicOn() - turns on the sequencer // /////////////////////////////////////////////////////////////////////////// void SD_MusicOn(void) { sqActive = true; } /////////////////////////////////////////////////////////////////////////// // // SD_MusicOff() - turns off the sequencer and any playing notes // /////////////////////////////////////////////////////////////////////////// void SD_MusicOff(void) { word i; switch (MusicMode) { case smm_AdLib: alFXReg = 0; alOut(alEffects,0); for (i = 0;i < sqMaxTracks;i++) alOut(alFreqH + i + 1,0); break; } sqActive = false; } /////////////////////////////////////////////////////////////////////////// // // SD_StartMusic() - starts playing the music pointed to // /////////////////////////////////////////////////////////////////////////// void SD_StartMusic(MusicGroup far *music) { SD_MusicOff(); asm pushf asm cli if (MusicMode == smm_AdLib) { sqHackPtr = sqHack = music->values; sqHackSeqLen = sqHackLen = music->length; sqHackTime = 0; alTimeCount = 0; SD_MusicOn(); } asm popf } /////////////////////////////////////////////////////////////////////////// // // SD_FadeOutMusic() - starts fading out the music. Call SD_MusicPlaying() // to see if the fadeout is complete // /////////////////////////////////////////////////////////////////////////// void SD_FadeOutMusic(void) { switch (MusicMode) { case smm_AdLib: // DEBUG - quick hack to turn the music off SD_MusicOff(); break; } } /////////////////////////////////////////////////////////////////////////// // // SD_MusicPlaying() - returns true if music is currently playing, false if // not // /////////////////////////////////////////////////////////////////////////// boolean SD_MusicPlaying(void) { boolean result; switch (MusicMode) { case smm_AdLib: result = false; // DEBUG - not written break; default: result = false; } return(result); }