]> 4ch.mooo.com Git - 16.git/commitdiff
i want to test it before i mess with the variable pushing to gvar
authorsparky4 <sparky4@cock.li>
Thu, 14 Sep 2017 17:21:15 +0000 (12:21 -0500)
committersparky4 <sparky4@cock.li>
Thu, 14 Sep 2017 17:21:15 +0000 (12:21 -0500)
makefile
src/imfplay.c
src/lib/16_sd.c
src/lib/16_sd.h
src/lib/16_snd.c [new file with mode: 0755]
src/lib/16_snd.h [new file with mode: 0755]
src/lib/id_sd.c [deleted file]
src/lib/id_sd.h [deleted file]
src/sdtest.c [new file with mode: 0755]
src/sountest.c
src/vgmtest.c

index b66d08cecb954c7d510fe36e7fe2e61d71d498f4..528cb6ed4d88348df13b9ab63d333288d7559ff8 100755 (executable)
--- a/makefile
+++ b/makefile
@@ -145,7 +145,7 @@ LIBFLAGS=$(WLIBQ) -b -n
 VGMSNDOBJ = vgmSnd.$(OBJ)
 OLDLIBOBJS=bitmap.$(OBJ) 16render.$(OBJ)
 GFXLIBOBJS = 16_vl.$(OBJ) 16_vl_1.$(OBJ) 16_vl_2.$(OBJ) 16_vlpal.$(OBJ) 16text.$(OBJ) scroll16.$(OBJ) 16_spri.$(OBJ)
-16LIBOBJS = 16_mm.$(OBJ) 16_pm.$(OBJ) 16_ca.$(OBJ) 16_tail.$(OBJ) 16_head.$(OBJ) 16_enti.$(OBJ) 16_dbg.$(OBJ) 16_in.$(OBJ) kitten.$(OBJ) 16_hc.$(OBJ) 16_wcpu.$(OBJ) 16_timer.$(OBJ) jsmn.$(OBJ) 16_map.$(OBJ) 16_sd.$(OBJ) 16_tail_.$(OBJ) 16_dbg_1.$(OBJ)
+16LIBOBJS = 16_mm.$(OBJ) 16_pm.$(OBJ) 16_ca.$(OBJ) 16_tail.$(OBJ) 16_head.$(OBJ) 16_enti.$(OBJ) 16_dbg.$(OBJ) 16_in.$(OBJ) kitten.$(OBJ) 16_hc.$(OBJ) 16_wcpu.$(OBJ) 16_timer.$(OBJ) jsmn.$(OBJ) 16_map.$(OBJ) 16_sd.$(OBJ) 16_snd.$(OBJ) 16_tail_.$(OBJ) 16_dbg_1.$(OBJ)
 DOSLIBOBJ = adlib.$(OBJ) 8254.$(OBJ) 8259.$(OBJ) dos.$(OBJ) cpu.$(OBJ)
 !ifeq DEBUGSERIAL 1
 DOSLIBOBJ += 8250.$(OBJ)
@@ -202,6 +202,8 @@ TESTEXEC = &
        exmmtest.exe &
        vgmtest.exe &
        sountest.exe &
+       imfplay.exe &
+       sdtest.exe &
        xcroll.exe &
        0croll.exe &
        1croll.exe &
@@ -210,7 +212,6 @@ TESTEXEC = &
        tesuto.exe &
        0tesuto.exe &
        maptest.exe &
-       imfplay.exe &
        vrldbg.exe
 #zcroll.exe &
 TESTEXEC2 = &
@@ -261,7 +262,7 @@ ALLEXEC = &
        $(TESTEXEC2) &
        $(TESTEXEC3)
 
-all: $(EXEC)   id_sd.$(OBJ)
+all: $(EXEC)
 testexec: $(EXEC) $(TESTEXEC2)
 
 #
@@ -294,6 +295,7 @@ fontgfx.exe:        fontgfx.$(OBJ) gfx.lib $(DOSLIB)
 inputest.exe:   inputest.$(OBJ) $(16LIB) $(DOSLIB) gfx.lib
 sountest.exe:  sountest.$(OBJ) $(16LIB) $(DOSLIB) gfx.lib
 imfplay.exe:           imfplay.$(OBJ) $(16LIB) $(DOSLIB) gfx.lib
+sdtest.exe:    sdtest.$(OBJ) $(16LIB) $(DOSLIB) gfx.lib
 vrldbg.exe:            vrldbg.$(OBJ) #gfx.lib $(DOSLIB)
 pcxtest.exe:   pcxtest.$(OBJ) gfx.lib $(DOSLIB) $(16LIB)
 vrstest.exe:   vrstest.$(OBJ) $(16LIB) gfx.lib $(DOSLIB)
@@ -342,7 +344,8 @@ fonttest.$(OBJ):$(SRC)/fonttest.c
 fontgfx.$(OBJ):$(SRC)/fontgfx.c
 inputest.$(OBJ):$(SRC)/inputest.c
 #inntest.$(OBJ):$(SRC)/inntest.c
-sountest.$(OBJ): $(SRC)/sountest.c
+sountest.$(OBJ):       $(SRC)/sountest.c
+sdtest.$(OBJ): $(SRC)/sdtest.c
 imfplay.$(OBJ): $(SRC)/imfplay.c
 vrldbg.$(OBJ): $(SRC)/vrldbg.c
 #miditest.$(OBJ): $(SRC)/miditest.c
@@ -423,8 +426,8 @@ mapread.$(OBJ):     $(SRCLIB)/mapread.c     $(SRCLIB)/mapread.h
 16_tail.$(OBJ):        $(SRCLIB)/16_tail.c     $(SRCLIB)/16_tail.h
 16_tail_.$(OBJ):       $(SRCLIB)/16_tail_.c    $(SRCLIB)/16_tail.h
 16_hc.$(OBJ):  $(SRCLIB)/16_hc.c       $(SRCLIB)/16_hc.h
+16_snd.$(OBJ): $(SRCLIB)/16_snd.c      $(SRCLIB)/16_snd.h
 16_sd.$(OBJ):  $(SRCLIB)/16_sd.c       $(SRCLIB)/16_sd.h
-id_sd.$(OBJ):  $(SRCLIB)/id_sd.c       $(SRCLIB)/id_sd.h
 jsmn.$(OBJ):   $(JSMNLIB)/jsmn.c       $(JSMNLIB)/jsmn.h
 kitten.$(OBJ): $(NYANLIB)/kitten.c     $(NYANLIB)/kitten.h
 vgmSnd.$(OBJ): $(VGMSNDLIB)/vgmSnd.c   $(VGMSNDLIB)/vgmSnd.h
index 563ab8546b1895875bc6d83a69f497f93fff6e2d..67ed43956607840affb3a3d1849783d7b48fd69f 100755 (executable)
@@ -19,7 +19,7 @@
 #include "src/lib/16_mm.h"
 #include "src/lib/16_hc.h"
 #include "src/lib/16_dbg.h"
-#include "src/lib/16_sd.h"
+#include "src/lib/16_snd.h"
 
 extern struct glob_game_vars   *ggvv;
 
index 1cdd5627811a092c41566bcc9d5fc4e5c8e85f0e..76e78e68cdb280a789ae04e4a508a0cf57eac204 100755 (executable)
  *\r
  */\r
 \r
+//\r
+//     ID Engine\r
+//     ID_SD.c - Sound Manager for Wolfenstein 3D\r
+//     v1.2w\r
+//     By Jason Blochowiak\r
+//     Open Watcom port by sparky4\r
+//\r
+\r
+//\r
+//     This module handles dealing with generating sound on the appropriate\r
+//             hardware\r
+//\r
+//     Depends on: User Mgr (for parm checking)\r
+//\r
+//     Globals:\r
+//             For User Mgr:\r
+//                     SoundSourcePresent - Sound Source thingie present?\r
+//                     SoundBlasterPresent - SoundBlaster card present?\r
+//                     AdLibPresent - AdLib card present?\r
+//                     SoundMode - What device is used for sound effects\r
+//                             (Use SM_SetSoundMode() to set)\r
+//                     MusicMode - What device is used for music\r
+//                             (Use SM_SetMusicMode() to set)\r
+//                     DigiMode - What device is used for digitized sound effects\r
+//                             (Use SM_SetDigiDevice() to set)\r
+//\r
+//             For Cache Mgr:\r
+//                     NeedsDigitized - load digitized sounds?\r
+//                     NeedsMusic - load music?\r
+//\r
+\r
+#pragma hdrstop                // Wierdo thing with MUSE\r
+\r
+#include <dos.h>\r
+\r
+#ifndef        _MUSE_      // Will be defined in ID_Types.h\r
 #include "src/lib/16_sd.h"\r
+#else\r
+#include "src/lib/16_head.h"\r
+#endif\r
+#pragma        hdrstop\r
+#pragma        warn    -pia\r
+\r
+#define        SDL_SoundFinished()     {SoundNumber = SoundPriority = 0;}\r
+\r
+// Macros for AdLib stuff\r
+#define        selreg(n)       outportb(alFMAddr,n)\r
+#define        writereg(n)     outportb(alFMData,n)\r
+#define        readstat()      inportb(alFMStatus)\r
+\r
+//#define SD_USECATA3DSETTIMERSPEED\r
+\r
+//     Imports from ID_SD_A.ASM\r
+/*extern*/     void                    SDL_SetDS(void);\r
+/*extern*/     void interrupt  SDL_t0ExtremeAsmService(void);//,\r
+//                                     SDL_t0FastAsmService(void),\r
+//                                     SDL_t0SlowAsmService(void);\r
+       void                    SDL_IndicatePC(boolean on),\r
+                                       SDL_DigitizedDoneInIRQ();\r
+\r
+//     Global variables\r
+       boolean         AdLibPresent,\r
+                               NeedsDigitized,NeedsMusic,\r
+                               SoundPositioned;\r
+       SDMode          SoundMode;\r
+       SMMode          MusicMode;\r
+       SDSMode         DigiMode;\r
+       dword   TimeCount;\r
+       word            HackCount;\r
+       word            *SoundTable;    // Really * _seg *SoundTable, but that don't work\r
+       boolean         ssIsTandy;\r
+       int                     DigiMap[LASTSOUND];\r
+\r
+//     Internal variables\r
+static boolean                 SD_Started;\r
+               boolean                 nextsoundpos;\r
+               word/*boolean_+*/                       TimerDone;\r
+               word                    TimerVal,TimerDelay10,TimerDelay25,TimerDelay100;\r
+               dword           TimerDivisor,TimerCount;\r
+static char                    *ParmStrings[] =\r
+                                               {\r
+                                                       "noal",\r
+                                                       nil\r
+                                               };\r
+static void                    (*SoundUserHook)(void);\r
+               soundnames              SoundNumber,DigiNumber;\r
+               word                    SoundPriority,DigiPriority;\r
+               int                             LeftPosition,RightPosition;\r
+               void interrupt  (*t0OldService)(void);\r
+               long                    LocalTime;\r
+               word                    TimerRate;\r
+\r
+               word                    NumDigi,DigiLeft,DigiPage;\r
+               word                    _seg *DigiList;\r
+               word                    DigiLastStart,DigiLastEnd;\r
+               boolean                 DigiPlaying;\r
+static boolean                 DigiMissed,DigiLastSegment;\r
+static memptr                  DigiNextAddr;\r
+static word                    DigiNextLen;\r
+\r
+//     PC Sound variables\r
+               volatile byte   pcLastSample,far *pcSound;\r
+               dword           pcLengthLeft;\r
+               word                    pcSoundLookup[255];\r
+\r
+//     AdLib variables\r
+               boolean                 alNoCheck;\r
+               byte                    far *alSound;\r
+               word                    alBlock;\r
+               dword           alLengthLeft;\r
+               dword           alTimeCount;\r
+               Instrument              alZeroInst;\r
+\r
+// This table maps channel numbers to carrier and modulator op cells\r
+static byte                    carriers[9] =  { 3, 4, 5,11,12,13,19,20,21},\r
+                                               modifiers[9] = { 0, 1, 2, 8, 9,10,16,17,18},\r
+// This table maps percussive voice numbers to op cells\r
+                                               pcarriers[5] = {19,0xff,0xff,0xff,0xff},\r
+                                               pmodifiers[5] = {16,17,18,20,21};\r
 \r
-static void interrupt  (*t0OldService)(void);\r
+//     Sequencer variables\r
+               boolean                 sqActive;\r
+static word                    alFXReg;\r
+static ActiveTrack             *tracks[sqMaxTracks];//,\r
+//--                                           mytracks[sqMaxTracks];\r
+//--static     word                    sqMode,sqFadeStep;\r
+               word                    far *sqHack,far *sqHackPtr,sqHackLen,sqHackSeqLen;\r
+               long                    sqHackTime;\r
 \r
-void opl2out(word reg, word data)\r
+//     Internal routines\r
+               void                    SDL_DigitizedDone(void);\r
+\r
+//Assembly functions\r
+boolean                alNoIRQ;\r
+\r
+int count_time=0;\r
+int count_fx=0;\r
+int extreme=0;\r
+\r
+void SDL_turnOnPCSpeaker(word timerval)\r
 {\r
-       __asm\r
-       {\r
-               mov     ax,reg\r
-               mov     dx,word ptr [ADLIB_FM_ADDRESS]\r
-               or      ah,ah\r
-               jz      @@1\r
-               add     dx,2\r
-@@1:    out     dx,al\r
-               mov     cx,6\r
-@@2:    in      al,dx\r
-               loop    @@2\r
-               inc     dl\r
-               mov     ax,data\r
-               out     dx,al\r
-               dec     dl\r
-               mov     cx,36\r
-@@3:    in      al,dx\r
-               loop    @@3\r
+       __asm {\r
+               mov     bx,timerval\r
+               mov     al,0b6h\r
+               out     43h,al\r
+               mov     al,bl\r
+               out     42h,al\r
+               mov     al,bh\r
+               out     42h,al\r
+               in      al,61h\r
+               or      al,3\r
+               out     61h,al\r
+       }\r
+}\r
+\r
+void SDL_turnOffPCSpeaker()\r
+{\r
+       __asm {\r
+               in      al,61h\r
+               and     al,0fch\r
+               out     61h,al\r
+       }\r
+}\r
+\r
+void SDL_setPCSpeaker(byte val)\r
+{\r
+       __asm {\r
+               mov     al,val\r
+               in      al,61h\r
+               and     al,0fch\r
+               or      al,ah\r
+               out     61h,al\r
        }\r
 }\r
 \r
-void opl3out(word reg, word data)\r
+void SDL_DoFX()\r
 {\r
-       __asm\r
+       if(pcSound)\r
        {\r
-               mov     ax,reg\r
-               mov     dx,word ptr [ADLIB_FM_ADDRESS]\r
-               or      ah,ah\r
-               jz      @@1\r
-               add     dx,2\r
-@@1:    out     dx,al\r
-               inc     dl\r
-               mov     ax,data\r
-               out     dx,al\r
-               dec     dl\r
-               mov     cx,26\r
-@@2:    in      al,dx\r
-               loop    @@2\r
+               if(*pcSound!=pcLastSample)\r
+               {\r
+                       pcLastSample=*pcSound;\r
+\r
+                       if(pcLastSample)\r
+                               SDL_turnOnPCSpeaker(pcLastSample*60);\r
+                       else\r
+                               SDL_turnOffPCSpeaker();\r
+               }\r
+               pcSound++;\r
+               pcLengthLeft--;\r
+               if(!pcLengthLeft)\r
+               {\r
+                       pcSound=0;\r
+                       SoundNumber=(soundnames)0;\r
+                       SoundPriority=0;\r
+                       SDL_turnOffPCSpeaker();\r
+               }\r
+       }\r
+\r
+       if(alSound && !alNoIRQ)\r
+       {\r
+               if(*alSound)\r
+               {\r
+                       alOut/*InIRQ*/(alFreqL,*alSound);\r
+                       alOut/*InIRQ*/(alFreqH,alBlock);\r
+               }\r
+               else alOut/*InIRQ*/(alFreqH,0);\r
+               alSound++;\r
+               alLengthLeft--;\r
+               if(!alLengthLeft)\r
+               {\r
+                       alSound=0;\r
+                       SoundNumber=(soundnames)0;\r
+                       SoundPriority=0;\r
+                       alOut/*InIRQ*/(alFreqH,0);\r
+               }\r
        }\r
+\r
 }\r
 \r
-void opl3exp(word data)\r
+void SDL_DoFast()\r
 {\r
-       __asm\r
+       count_fx++;\r
+       if(count_fx>=5)\r
        {\r
-               mov     ax,data\r
-               mov     dx,word ptr [ADLIB_FM_ADDRESS]\r
-               add     dx,2\r
-               out     dx,al\r
-               mov     cx,6\r
-@@1:    in      al,dx\r
-               loop    @@1\r
-               inc     dl\r
-               mov     al,ah\r
-               out     dx,al\r
-               mov     cx,36\r
-@@2:    in      al,dx\r
-               loop    @@2\r
-       }\r
-}\r
-\r
-/* Function: FMResest *******************************************************\r
-*\r
-*     Description:        quick and dirty sound card reset (zeros all\r
-*                         registers).\r
-*\r
-*/\r
-void FMReset(void/*int percusiveMode*/)\r
-{\r
-       int i;\r
-\r
-       /* zero all registers */\r
-       for(i = MIN_REGISTER; i < MAX_REGISTER+1; i++) opl2out(i, 0);\r
-\r
-       /* allow FM chips to control the waveform of each operator */\r
-       opl2out(0x01, 0x20);\r
-\r
-       /* set rhythm enabled (6 melodic voices, 5 percussive) */\r
-       opl2out(0xBD, 0x20);\r
-\r
-       //FMSetPercusiveMode(percusiveMode);\r
-} /* End of FMReset */\r
-\r
-/* Function: FMKeyOff *******************************************************\r
-*\r
-*     Parameters:        voice - which voice to turn off.\r
-*\r
-*     Description:        turns off the specified voice.\r
-*\r
-*/\r
-void FMKeyOff(int voice)\r
-{\r
-       int regNum;\r
-\r
-       /* turn voice off */\r
-       regNum = 0xB0 + voice % 11;//NUMVOICE;\r
-       opl2out(regNum, 0x0E);\r
-} /* End of FMKeyOff */\r
-\r
-/* Function: FMKeyOn *******************************************************\r
-*\r
-*     Parameters:        voice - which voice to turn on.\r
-*                         freq - its frequency (note).\r
-*                         octave - its octave.\r
-*\r
-*     Description:        turns on a voice of specfied frequency and\r
-*                         octave.\r
-*\r
-*/\r
-void FMKeyOn(int voice, int freq, int octave)\r
-{\r
-       int regNum, tmp;\r
-\r
-       regNum = 0xA0 + voice % 11;//NUMVOICE;\r
-       opl2out(regNum, freq & 0xff);\r
-       regNum = 0xB0 + voice % 11;//NUMVOICE;\r
-       tmp = (freq >> 8) | (octave << 2) | 0x20;\r
-       opl2out(regNum, tmp);\r
-} /* End of FMKeyOn */\r
-\r
-/* Function: FMSetVoice *****************************************************\r
-*\r
-*     Parameters:        voiceNum - which voice to set.\r
-*                         ins - instrument to set voice.\r
-*\r
-*     Description:        sets the instrument of a voice.\r
-*\r
-*/\r
-void FMSetVoice(int voiceNum, FMInstrument *ins){\r
-       int opCellNum, cellOffset;\r
-\r
-       voiceNum %= 11;//NUMVOICE;\r
-       cellOffset = voiceNum % 3 + ((voiceNum / 3) << 3);\r
-\r
-       /* set sound characteristic */\r
-       opCellNum = 0x20 + (char)cellOffset;\r
-       opl2out(opCellNum, ins->SoundCharacteristic[0]);\r
-       opCellNum += 3;\r
-       opl2out(opCellNum, ins->SoundCharacteristic[1]);\r
-\r
-       /* set level/output */\r
-       opCellNum = 0x40 + (char)cellOffset;\r
-       opl2out(opCellNum, ins->Level[0]);\r
-       opCellNum += 3;\r
-       opl2out(opCellNum, ins->Level[1]);\r
-\r
-       /* set Attack/Decay */\r
-       opCellNum = 0x60 + (char)cellOffset;\r
-       opl2out(opCellNum, ins->AttackDecay[0]);\r
-       opCellNum += 3;\r
-       opl2out(opCellNum, ins->AttackDecay[1]);\r
-\r
-       /* set Sustain/Release */\r
-       opCellNum = 0x80 + (char)cellOffset;\r
-       opl2out(opCellNum, ins->SustainRelease[0]);\r
-       opCellNum += 3;\r
-       opl2out(opCellNum, ins->SustainRelease[1]);\r
-\r
-       /* set Wave Select */\r
-       opCellNum = 0xE0 + (char)cellOffset;\r
-       opl2out(opCellNum, ins->WaveSelect[0]);\r
-       opCellNum += 3;\r
-       opl2out(opCellNum, ins->WaveSelect[1]);\r
-\r
-       /* set Feedback/Selectivity */\r
-       opCellNum = (byte)0xC0 + (byte)voiceNum;\r
-       opl2out(opCellNum, ins->Feedback);\r
-} /* End of FMSetVoice */\r
-\r
-\r
-//newer sd\r
-\r
-\r
-struct glob_game_vars  *ggvv;\r
-// WARNING: subroutine call in interrupt handler. make sure you compile with -zu flag for large/compact memory models\r
-void interrupt SDL_irq0()\r
-{\r
-       ggvv->ca.sd.irq0_ticks++;\r
-       if ((ggvv->ca.sd.irq0_cnt += ggvv->ca.sd.irq0_add) >= ggvv->ca.sd.irq0_max) {\r
-               ggvv->ca.sd.irq0_cnt -= ggvv->ca.sd.irq0_max;\r
+               count_fx=0;\r
+\r
+               SDL_DoFX();\r
+\r
+               count_time++;\r
+               if(count_time>=2)\r
+               {\r
+                       TimeCount++;\r
+                       count_time=0;\r
+               }\r
+       }\r
+\r
+       if(sqActive && !alNoIRQ)\r
+       {\r
+               if(sqHackLen)\r
+               {\r
+                       do\r
+                       {\r
+                               if(sqHackTime>alTimeCount) break;\r
+                               sqHackTime=alTimeCount+*(sqHackPtr+1);\r
+                               alOut/*InIRQ*/(*(byte *)sqHackPtr,*(((byte *)sqHackPtr)+1));\r
+                               sqHackPtr+=2;\r
+                               sqHackLen-=4;\r
+                       }\r
+                       while(sqHackLen);\r
+               }\r
+               alTimeCount++;\r
+               if(!sqHackLen)\r
+               {\r
+                       sqHackPtr=sqHack;\r
+                       sqHackLen=sqHackSeqLen;\r
+                       alTimeCount=0;\r
+                       sqHackTime=0;\r
+               }\r
+       }\r
+\r
+//SS   if(ssSample)\r
+//SS   {\r
+//SS           if(!(inp(ssStatus)&0x40))\r
+//SS           {\r
+//SS                   outp(ssData,*ssSample++);\r
+//SS                   outp(ssControl,ssOff);\r
+//SS                   __asm push ax\r
+//SS                   __asm pop ax\r
+//SS                   outp(ssControl,ssOn);\r
+//SS                   __asm push ax\r
+//SS                   __asm pop ax\r
+//SS                   ssLengthLeft--;\r
+//SS                   if(!ssLengthLeft)\r
+//SS                   {\r
+//SS                           ssSample=0;\r
+//SS                           SDL_DigitizedDoneInIRQ();\r
+//SS                   }\r
+//SS           }\r
+//SS   }\r
+\r
+       TimerCount+=TimerDivisor;\r
+       if(*((word *)&TimerCount+1))\r
+       {\r
+               *((word *)&TimerCount+1)=0;\r
                t0OldService();\r
        }\r
-       else {\r
-               p8259_OCW2(0,P8259_OCW2_NON_SPECIFIC_EOI);\r
+       else\r
+       {\r
+               outp(0x20,0x20);\r
        }\r
 }\r
 \r
-void SD_Initimf(global_game_variables_t *gvar)\r
+// Timer 0 ISR for 700Hz interrupts\r
+void interrupt SDL_t0FastAsmService(void)\r
 {\r
-       if (!init_adlib()) {\r
-               printf("Cannot init library\n");\r
-               return;\r
+       SDL_DoFast();\r
+}\r
+\r
+// Timer 0 ISR for 140Hz interrupts\r
+void interrupt SDL_t0SlowAsmService(void)\r
+{\r
+       count_time++;\r
+       if(count_time>=2)\r
+       {\r
+               TimeCount++;\r
+               count_time=0;\r
        }\r
-       if (!probe_8254()) { /* we need the timer to keep time with the music */\r
-               printf("8254 timer not found\n");\r
-               return;\r
+\r
+       SDL_DoFX();\r
+\r
+       TimerCount+=TimerDivisor;\r
+       if(*((word *)&TimerCount+1))\r
+       {\r
+               *((word *)&TimerCount+1)=0;\r
+               t0OldService();\r
        }\r
+       else\r
+               outp(0x20,0x20);\r
+}\r
+\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_SetTimer0() - Sets system timer 0 to the specified speed\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+#pragma        argsused\r
+static void\r
+SDL_SetTimer0(word speed)\r
+{\r
+#ifndef TPROF  // If using Borland's profiling, don't screw with the timer\r
+asm    pushf\r
+asm    cli\r
 \r
-       gvar->ca.sd.imf_delay_countdown=0;\r
-       gvar->ca.sd.imf_music=\r
-       gvar->ca.sd.imf_play_ptr=\r
-       gvar->ca.sd.imf_music_end=NULL;\r
+       outportb(0x43,0x36);                            // Change timer 0\r
+       outportb(0x40,speed);\r
+       outportb(0x40,speed >> 8);\r
+       // Kludge to handle special case for digitized PC sounds\r
+       if (TimerDivisor == (1192030 / (TickBase * 100)))\r
+               TimerDivisor = (1192030 / (TickBase * 10));\r
+       else\r
+               TimerDivisor = speed;\r
 \r
-       SD_adlib_shut_up();\r
-       shutdown_adlib_opl3(); // NTS: Apparently the music won't play otherwise\r
+asm    popf\r
+#else\r
+       TimerDivisor = 0x10000;\r
+#endif\r
 }\r
 \r
-void SD_imf_reset_music(global_game_variables_t *gvar)\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_SetIntsPerSec() - Uses SDL_SetTimer0() to set the number of\r
+//             interrupts generated by system timer 0 per second\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+SDL_SetIntsPerSec(word ints)\r
 {\r
-       gvar->ca.sd.imf_music = gvar->ca.sd.imf_play_ptr = gvar->ca.sd.imf_music_end = NULL;\r
-       gvar->ca.sd.imf_delay_countdown = 0;\r
+       TimerRate = ints;\r
+       SDL_SetTimer0(1192030 / ints);\r
 }\r
 \r
-void SD_StartupTimer(global_game_variables_t *gvar)\r
+#ifndef SD_USECATA3DSETTIMERSPEED\r
+static void\r
+SDL_SetTimerSpeed(void)\r
 {\r
-       gvar->ca.sd.irq0_ticks=\r
-       gvar->ca.sd.irq0_cnt = 0;\r
-       gvar->ca.sd.irq0_add = 182;\r
-       gvar->ca.sd.irq0_max = 1000; /* about 18.2Hz */\r
-       gvar->ca.sd.tickrate = 700;\r
+       word    rate;\r
+       void interrupt  (*isr)(void);\r
+\r
+       if ((DigiMode == sds_PC) && DigiPlaying)\r
+       {\r
+               rate = TickBase * 100;\r
+               isr = SDL_t0ExtremeAsmService;\r
+       }\r
+       else if\r
+       (\r
+               (MusicMode == smm_AdLib)\r
+       ||      ((DigiMode == sds_SoundSource) && DigiPlaying)\r
+       )\r
+       {\r
+               rate = TickBase * 10;\r
+               isr = SDL_t0FastAsmService;\r
+       }\r
+       else\r
+       {\r
+               rate = TickBase * 2;\r
+               isr = SDL_t0SlowAsmService;\r
+       }\r
 \r
-       write_8254_system_timer(T8254_REF_CLOCK_HZ / gvar->ca.sd.tickrate);\r
-       t0OldService = _dos_getvect(8); /*IRQ0*/\r
-       _dos_setvect(8,SDL_irq0);\r
+       if (rate != TimerRate)\r
+       {\r
+               setvect(8,isr);\r
+               SDL_SetIntsPerSec(rate);\r
+               TimerRate = rate;\r
+       }\r
+}\r
+#else\r
+static void\r
+SDL_SetTimerSpeed(void)\r
+{\r
+       word    rate;\r
 \r
-       _cli();\r
-       gvar->ca.sd.irq0_ticks = gvar->ca.sd.ptick = 0;\r
-       _sti();\r
+       if (MusicMode == smm_AdLib)\r
+               rate = TickBase * 8;\r
+       else\r
+               rate = TickBase * 2;\r
+       SDL_SetIntsPerSec(rate);\r
 }\r
+#endif\r
 \r
-void SD_ShutdownTimer()\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_TimingService() - Used by SDL_InitDelay() to determine a timing\r
+//             value for the current system that we're running on\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+//static void interrupt\r
+void interrupt\r
+SDL_TimingService(void)\r
 {\r
-       _dos_setvect(8,t0OldService);\r
+       //TimerVal = _CX;\r
+       __asm {\r
+               mov TimerVal,cx\r
+       }\r
+       TimerDone = 1;\r
+\r
+       outportb(0x20,0x20);                            // Ack interrupt\r
 }\r
+#ifdef SD_USECATA3DSETTIMERSPEED\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_InitDelay() - Sets up TimerDelay's for SDL_Delay()\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+SDL_InitDelay(void)\r
+{\r
+       int             i;\r
+       word    timer;\r
+\r
+       setvect(8,SDL_TimingService);           // Set to my timer 0 ISR\r
+\r
+       SDL_SetIntsPerSec(1000);                        // Time 1ms\r
+\r
+       for (i = 0,timer = 0;i < 10;i++)        // Do timing test 10 times\r
+       {\r
+               __asm {\r
+                       xor             dx,dx                                   // Zero DX\r
+                       mov             cx,0xffff                               // Put starting value in CX\r
+                       mov             [TimerDone],cx                  // TimerDone = false - 1\r
+#ifdef __BORLANDC__\r
+               }\r
+#endif\r
+startloop:\r
+#ifdef __BORLANDC__\r
+               __asm {\r
+#endif\r
+                       or              [TimerDone],0\r
+                       jnz             startloop                               // Make sure we're at the start\r
+#ifdef __BORLANDC__\r
+               }\r
+#endif\r
+loop_:\r
+#ifdef __BORLANDC__\r
+               __asm {\r
+#endif\r
+                       test    [TimerDone],1                   // See if TimerDone flag got hit\r
+                       jnz             done                                    // Yep - drop out of the loop\r
+                       loop    loop_\r
+#ifdef __BORLANDC__\r
+               }\r
+#endif\r
+done:\r
+#ifdef __WATCOMC__\r
+       }\r
+#endif\r
+\r
+               if (0xffff - TimerVal > timer)\r
+                       timer = 0xffff - TimerVal;\r
+       }\r
+       timer += timer / 2;                                     // Use some slop\r
+       TimerDelay10 =  timer / (1000 / 10);\r
+       TimerDelay25 =  timer / (1000 / 25);\r
+       TimerDelay100 = timer / (1000 / 100);\r
+\r
+       SDL_SetTimer0(0);                                       // Reset timer 0\r
 \r
-void SD_imf_free_music(global_game_variables_t *gvar)\r
+       setvect(8,t0OldService);                        // Set back to old ISR\r
+}\r
+#endif\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_Delay() - Delays the specified amount of time\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+SDL_Delay(word delay)\r
 {\r
-#ifndef SD_USESCAMMPM\r
-       if (gvar->ca.sd.imf_music) free(gvar->ca.sd.imf_music);\r
+       if (!delay)\r
+               return;\r
+\r
+       __asm {\r
+               mov             cx,[delay]\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+loop_:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               test    [TimerDone],0   // Useless code - just for timing equivilency\r
+               jnz             done\r
+               loop    loop_\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+done:\r
+#ifdef __WATCOMC__\r
+       }\r
+#endif\r
+}\r
+\r
+//\r
+//     PC Sound code\r
+//\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_PCPlaySample() - Plays the specified sample on the PC speaker\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+#ifdef _MUSE_\r
+void\r
 #else\r
-       MM_FreePtr(MEMPTRCONV gvar->ca.audiosegs[0], gvar);     //TODO make behave like id engine\r
+static void\r
 #endif\r
-       SD_imf_reset_music(gvar);\r
+SDL_PCPlaySample(byte huge *data,dword len)\r
+{\r
+asm    pushf\r
+asm    cli\r
+\r
+       SDL_IndicatePC(true);\r
+\r
+       pcLengthLeft = len;\r
+       pcSound = (volatile byte far *)data;\r
+\r
+asm    popf\r
 }\r
 \r
-int SD_imf_load_music(const char *path, global_game_variables_t *gvar)\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_PCStopSample() - Stops a sample playing on the PC speaker\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+#ifdef _MUSE_\r
+void\r
+#else\r
+static void\r
+#endif\r
+SDL_PCStopSample(void)\r
 {\r
-       unsigned long len;\r
-       unsigned char buf[8];\r
-       int fd;\r
+asm    pushf\r
+asm    cli\r
 \r
-#ifndef SD_USESCAMMPM\r
-       SD_imf_free_music(gvar);\r
+       /*(long)*/pcSound = 0;\r
+\r
+       SDL_IndicatePC(false);\r
+\r
+asm    in      al,0x61                 // Turn the speaker off\r
+asm    and     al,0xfd                 // ~2\r
+asm    out     0x61,al\r
+\r
+asm    popf\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_PCPlaySound() - Plays the specified sound on the PC speaker\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+#ifdef _MUSE_\r
+void\r
 #else\r
-       SD_imf_reset_music(gvar);\r
+static void\r
 #endif\r
+SDL_PCPlaySound(PCSound far *sound)\r
+{\r
+asm    pushf\r
+asm    cli\r
 \r
-       fd = open(path,O_RDONLY|O_BINARY);\r
-       if (fd < 0) return 0;\r
+       pcLastSample = -1;\r
+       pcLengthLeft = sound->common.length;\r
+       pcSound = sound->data;\r
 \r
-       len = lseek(fd,0,SEEK_END);\r
-       lseek(fd,0,SEEK_SET);\r
-       read(fd,buf,2);\r
-       if (buf[0] != 0 || buf[1] != 0) // type 1 IMF\r
-               len = *((uint16_t*)buf);\r
-       else\r
-               lseek(fd,0,SEEK_SET);\r
+asm    popf\r
+}\r
 \r
-       if (len == 0 || len > 65535UL) {\r
-               close(fd);\r
-               return 0;\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_PCStopSound() - Stops the current sound playing on the PC Speaker\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+#ifdef _MUSE_\r
+void\r
+#else\r
+static void\r
+#endif\r
+SDL_PCStopSound(void)\r
+{\r
+asm    pushf\r
+asm    cli\r
+\r
+       /*(long)*/pcSound = 0;\r
+\r
+asm    in      al,0x61                 // Turn the speaker off\r
+asm    and     al,0xfd                 // ~2\r
+asm    out     0x61,al\r
+\r
+asm    popf\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_PCService() - Handles playing the next sample in a PC sound\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+SDL_PCService(void)\r
+{\r
+       byte    s;\r
+       word    t;\r
+\r
+       if (pcSound)\r
+       {\r
+               s = *pcSound++;\r
+               if (s != pcLastSample)\r
+               {\r
+               asm     pushf\r
+               asm     cli\r
+\r
+                       pcLastSample = s;\r
+                       if (s)                                  // We have a frequency!\r
+                       {\r
+                               t = pcSoundLookup[s];\r
+                       asm     mov     bx,[t]\r
+\r
+                       asm     mov     al,0xb6                 // Write to channel 2 (speaker) timer\r
+                       asm     out     43h,al\r
+                       asm     mov     al,bl\r
+                       asm     out     42h,al                  // Low byte\r
+                       asm     mov     al,bh\r
+                       asm     out     42h,al                  // High byte\r
+\r
+                       asm     in      al,0x61                 // Turn the speaker & gate on\r
+                       asm     or      al,3\r
+                       asm     out     0x61,al\r
+                       }\r
+                       else                                    // Time for some silence\r
+                       {\r
+                       asm     in      al,0x61                 // Turn the speaker & gate off\r
+                       asm     and     al,0xfc                 // ~3\r
+                       asm     out     0x61,al\r
+                       }\r
+\r
+               asm     popf\r
+               }\r
+\r
+               if (!(--pcLengthLeft))\r
+               {\r
+                       SDL_PCStopSound();\r
+                       SDL_SoundFinished();\r
+               }\r
        }\r
-       len -= len & 3;\r
+}\r
 \r
-#ifndef SD_USESCAMMPM\r
-       gvar->ca.sd.imf_music = malloc(len);\r
-#else\r
-       MM_GetPtr(MEMPTRCONV gvar->ca.audiosegs[0],len, gvar);\r
-       gvar->ca.sd.imf_music = (struct imf_entry *)gvar->ca.audiosegs[0];\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_ShutPC() - Turns off the pc speaker\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+SDL_ShutPC(void)\r
+{\r
+asm    pushf\r
+asm    cli\r
+\r
+       pcSound = 0;\r
+\r
+asm    in      al,0x61                 // Turn the speaker & gate off\r
+asm    and     al,0xfc                 // ~3\r
+asm    out     0x61,al\r
+\r
+asm    popf\r
+}\r
+\r
+//\r
+//     Stuff for digitized sounds\r
+//\r
+memptr\r
+SDL_LoadDigiSegment(word page, global_game_variables_t *gvar)\r
+{\r
+       memptr  addr;\r
+\r
+#if 0  // for debugging\r
+asm    mov     dx,STATUS_REGISTER_1\r
+asm    in      al,dx\r
+asm    mov     dx,ATR_INDEX\r
+asm    mov     al,ATR_OVERSCAN\r
+asm    out     dx,al\r
+asm    mov     al,10   // bright green\r
+asm    out     dx,al\r
+#endif\r
+\r
+       addr = PM_GetSoundPage(page);\r
+       PM_SetPageLock(gvar->pm.fi.PMSoundStart + page,pml_Locked, gvar);\r
+\r
+#if 0  // for debugging\r
+asm    mov     dx,STATUS_REGISTER_1\r
+asm    in      al,dx\r
+asm    mov     dx,ATR_INDEX\r
+asm    mov     al,ATR_OVERSCAN\r
+asm    out     dx,al\r
+asm    mov     al,3    // blue\r
+asm    out     dx,al\r
+asm    mov     al,0x20 // normal\r
+asm    out     dx,al\r
 #endif\r
-       if (gvar->ca.sd.imf_music == NULL) {\r
-               close(fd);\r
-               return 0;\r
+\r
+       return(addr);\r
+}\r
+\r
+void\r
+SDL_PlayDigiSegment(memptr addr,word len)\r
+{\r
+       switch (DigiMode)\r
+       {\r
+       case sds_PC:\r
+       SDL_PCPlaySample(addr,len);\r
+               break;\r
+//SS   case sds_SoundSource:\r
+//SS           SDL_SSPlaySample(addr,len);\r
+//SS           break;\r
+//SB   case sds_SoundBlaster:\r
+//SB           SDL_SBPlaySample(addr,len);\r
+//SB           break;\r
+       }\r
+}\r
+\r
+void\r
+SD_StopDigitized(global_game_variables_t *gvar)\r
+{\r
+       int     i;\r
+\r
+asm    pushf\r
+asm    cli\r
+\r
+       DigiLeft = 0;\r
+       DigiNextAddr = nil;\r
+       DigiNextLen = 0;\r
+       DigiMissed = false;\r
+       DigiPlaying = false;\r
+       DigiNumber = DigiPriority = 0;\r
+       SoundPositioned = false;\r
+       if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
+               SDL_SoundFinished();\r
+\r
+       switch (DigiMode)\r
+       {\r
+       case sds_PC:\r
+               SDL_PCStopSample();\r
+               break;\r
+//SS   case sds_SoundSource:\r
+//SS           SDL_SSStopSample();\r
+//SS           break;\r
+//SB   case sds_SoundBlaster:\r
+//SB           SDL_SBStopSample();\r
+//SB           break;\r
+       }\r
+\r
+asm    popf\r
+\r
+       for (i = DigiLastStart;i < DigiLastEnd;i++)\r
+               PM_SetPageLock(i + gvar->pm.fi.PMSoundStart,pml_Unlocked, gvar);\r
+       DigiLastStart = 1;\r
+       DigiLastEnd = 0;\r
+}\r
+\r
+void\r
+SD_Poll(global_game_variables_t *gvar)\r
+{\r
+       if (DigiLeft && !DigiNextAddr)\r
+       {\r
+               DigiNextLen = (DigiLeft >= PMPageSize)? PMPageSize : (DigiLeft % PMPageSize);\r
+               DigiLeft -= DigiNextLen;\r
+               if (!DigiLeft)\r
+                       DigiLastSegment = true;\r
+               DigiNextAddr = SDL_LoadDigiSegment(DigiPage++, gvar);\r
+       }\r
+       if (DigiMissed && DigiNextAddr)\r
+       {\r
+               SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen);\r
+               DigiNextAddr = nil;\r
+               DigiMissed = false;\r
+               if (DigiLastSegment)\r
+               {\r
+                       DigiPlaying = false;\r
+                       DigiLastSegment = false;\r
+               }\r
+       }\r
+       SDL_SetTimerSpeed();\r
+}\r
+\r
+void\r
+SD_SetPosition(int leftpos,int rightpos, global_game_variables_t *gvar)\r
+{\r
+       if\r
+       (\r
+               (leftpos < 0)\r
+       ||      (leftpos > 15)\r
+       ||      (rightpos < 0)\r
+       ||      (rightpos > 15)\r
+       ||      ((leftpos == 15) && (rightpos == 15))\r
+       )\r
+               Quit(gvar, "SD_SetPosition: Illegal position");\r
+\r
+       switch (DigiMode)\r
+       {\r
+//SB   case sds_SoundBlaster:\r
+//SB           SDL_PositionSBP(leftpos,rightpos);\r
+//SB           break;\r
        }\r
-       read(fd,gvar->ca.sd.imf_music,len);\r
-       close(fd);\r
+}\r
+\r
+void\r
+SD_PlayDigitized(word which,int leftpos,int rightpos, global_game_variables_t *gvar)\r
+{\r
+       word    len;\r
+       memptr  addr;\r
 \r
-       gvar->ca.sd.imf_play_ptr = gvar->ca.sd.imf_music;\r
-       gvar->ca.sd.imf_music_end = gvar->ca.sd.imf_music + (len >> 2UL);\r
-       return 1;\r
+       if (!DigiMode)\r
+               return;\r
+\r
+       SD_StopDigitized(gvar);\r
+       if (which >= NumDigi)\r
+               Quit(gvar, "SD_PlayDigitized: bad sound number");\r
+\r
+       SD_SetPosition(leftpos,rightpos, gvar);\r
+\r
+       DigiPage = DigiList[(which * 2) + 0];\r
+       DigiLeft = DigiList[(which * 2) + 1];\r
+\r
+       DigiLastStart = DigiPage;\r
+       DigiLastEnd = DigiPage + ((DigiLeft + (PMPageSize - 1)) / PMPageSize);\r
+\r
+       len = (DigiLeft >= PMPageSize)? PMPageSize : (DigiLeft % PMPageSize);\r
+       addr = SDL_LoadDigiSegment(DigiPage++, gvar);\r
+\r
+       DigiPlaying = true;\r
+       DigiLastSegment = false;\r
+\r
+       SDL_PlayDigiSegment(addr,len);\r
+       DigiLeft -= len;\r
+       if (!DigiLeft)\r
+               DigiLastSegment = true;\r
+\r
+       SD_Poll(gvar);\r
 }\r
 \r
-void SD_imf_tick(global_game_variables_t *gvar)\r
+void\r
+SDL_DigitizedDone(void)\r
 {\r
-       if (gvar->ca.sd.imf_delay_countdown == 0) {\r
-               do {\r
-                       adlib_write(gvar->ca.sd.imf_play_ptr->reg,gvar->ca.sd.imf_play_ptr->data);\r
-                       gvar->ca.sd.imf_delay_countdown = gvar->ca.sd.imf_play_ptr->delay;\r
-                       gvar->ca.sd.imf_play_ptr++;\r
-                       if (gvar->ca.sd.imf_play_ptr == gvar->ca.sd.imf_music_end)\r
+       if (DigiNextAddr)\r
+       {\r
+               SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen);\r
+               DigiNextAddr = nil;\r
+               DigiMissed = false;\r
+       }\r
+       else\r
+       {\r
+               if (DigiLastSegment)\r
+               {\r
+                       DigiPlaying = false;\r
+                       DigiLastSegment = false;\r
+                       if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
                        {\r
-//                             printf("replay\n");\r
-                               gvar->ca.sd.imf_play_ptr = gvar->ca.sd.imf_music;\r
+                               SDL_SoundFinished();\r
                        }\r
-               } while (gvar->ca.sd.imf_delay_countdown == 0);\r
+                       else\r
+                               DigiNumber = DigiPriority = 0;\r
+                       SoundPositioned = false;\r
+               }\r
+               else\r
+                       DigiMissed = true;\r
+       }\r
+}\r
+\r
+void\r
+SD_SetDigiDevice(SDSMode mode, global_game_variables_t *gvar)\r
+{\r
+       boolean devicenotpresent;\r
+\r
+       if (mode == DigiMode)\r
+               return;\r
+\r
+       SD_StopDigitized(gvar);\r
+\r
+       devicenotpresent = false;\r
+//SBSS switch (mode)\r
+//SBSS {\r
+//SB   case sds_SoundBlaster:\r
+//SB           if (!SoundBlasterPresent)\r
+//SB           {\r
+//SB                   if (SoundSourcePresent)\r
+//SB                           mode = sds_SoundSource;\r
+//SB                   else\r
+//SB                           devicenotpresent = true;\r
+//SB           }\r
+//SB           break;\r
+//SS   case sds_SoundSource:\r
+//SS           if (!SoundSourcePresent)\r
+//SS                   devicenotpresent = true;\r
+//SS           break;\r
+//SBSS }\r
+\r
+       if (!devicenotpresent)\r
+       {\r
+//SS           if (DigiMode == sds_SoundSource)\r
+//SS                   SDL_ShutSS();\r
+\r
+               DigiMode = mode;\r
+\r
+//SS           if (mode == sds_SoundSource)\r
+//SS                   SDL_StartSS();\r
+\r
+               SDL_SetTimerSpeed();\r
        }\r
-       else {\r
-               gvar->ca.sd.imf_delay_countdown--;\r
+}\r
+\r
+void\r
+SDL_SetupDigi(global_game_variables_t *gvar)\r
+{\r
+       memptr  list;\r
+       word    far *p,\r
+                       pg;\r
+       int             i;\r
+\r
+       PM_UnlockMainMem(gvar);\r
+       MM_GetPtr(&list,PMPageSize, gvar);\r
+       PM_CheckMainMem(gvar);\r
+       p = (word far *)MK_FP(PM_GetPage(gvar->pm.fi.ChunksInFile - 1, gvar),0);\r
+       _fmemcpy((void far *)list,(void far *)p,PMPageSize);\r
+       pg = gvar->pm.fi.PMSoundStart;\r
+       for (i = 0;i < PMPageSize / (sizeof(word) * 2);i++,p += 2)\r
+       {\r
+               if (pg >= gvar->pm.fi.ChunksInFile - 1)\r
+                       break;\r
+               pg += (p[1] + (PMPageSize - 1)) / PMPageSize;\r
        }\r
+       PM_UnlockMainMem(gvar);\r
+       MM_GetPtr(MEMPTRCONV DigiList,i * sizeof(word) * 2, gvar);\r
+       _fmemcpy((void far *)DigiList,(void far *)list,i * sizeof(word) * 2);\r
+       MM_FreePtr(&list, gvar);\r
+       NumDigi = i;\r
+\r
+       for (i = 0;i < LASTSOUND;i++)\r
+               DigiMap[i] = -1;\r
 }\r
 \r
-void SD_adlib_shut_up() {\r
-       int i;\r
+//     AdLib Code\r
 \r
-       memset(adlib_fm,0,sizeof(adlib_fm));\r
-       memset(&adlib_reg_bd,0,sizeof(adlib_reg_bd));\r
-       for (i=0;i < adlib_fm_voices;i++) {\r
-               struct adlib_fm_operator *f;\r
-               f = &adlib_fm[i].mod;\r
-               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;\r
-               f = &adlib_fm[i].car;\r
-               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     alOut(n,b) - Puts b in AdLib card register n\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+alOut(byte n,byte b)\r
+{\r
+asm    pushf\r
+asm    cli\r
+\r
+asm    mov             dx,0x388\r
+asm    mov             al,[n]\r
+asm    out             dx,al\r
+#if 0\r
+       SDL_Delay(TimerDelay10);\r
+#else\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+#endif\r
+\r
+asm    mov             dx,0x389\r
+asm    mov             al,[b]\r
+asm    out             dx,al\r
+\r
+asm    popf\r
+\r
+#if 0\r
+       SDL_Delay(TimerDelay25);\r
+#else\r
+asm    mov     dx,0x388\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+asm    in      al, dx\r
+#endif\r
+}\r
+\r
+//#if 0\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_SetInstrument() - Puts an instrument into a generator\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+//static void\r
+void\r
+SDL_SetInstrument(int track,int which,Instrument far *inst,boolean percussive)\r
+{\r
+       byte            c,m;\r
+\r
+       if (percussive)\r
+       {\r
+               c = pcarriers[which];\r
+               m = pmodifiers[which];\r
+       }\r
+       else\r
+       {\r
+               c = carriers[which];\r
+               m = modifiers[which];\r
        }\r
 \r
-       for (i=0;i < adlib_fm_voices;i++) {\r
-               struct adlib_fm_operator *f;\r
+       tracks[track - 1]->inst = *inst;\r
+       tracks[track - 1]->percussive = percussive;\r
 \r
-               f = &adlib_fm[i].mod;\r
-               f->mod_multiple = 1;\r
-               f->total_level = 63 - 16;\r
-               f->attack_rate = 15;\r
-               f->decay_rate = 4;\r
-               f->sustain_level = 0;\r
-               f->release_rate = 8;\r
-               f->f_number = 400;\r
-               f->sustain = 1;\r
-               f->octave = 4;\r
-               f->key_on = 0;\r
+       alOut(m + alChar,inst->mChar);\r
+       alOut(m + alScale,inst->mScale);\r
+       alOut(m + alAttack,inst->mAttack);\r
+       alOut(m + alSus,inst->mSus);\r
+       alOut(m + alWave,inst->mWave);\r
 \r
-               f = &adlib_fm[i].car;\r
-               f->mod_multiple = 1;\r
-               f->total_level = 63 - 16;\r
-               f->attack_rate = 15;\r
-               f->decay_rate = 4;\r
-               f->sustain_level = 0;\r
-               f->release_rate = 8;\r
-               f->f_number = 0;\r
-               f->sustain = 1;\r
-               f->octave = 0;\r
-               f->key_on = 0;\r
+       // Most percussive instruments only use one cell\r
+       if (c != 0xff)\r
+       {\r
+               alOut(c + alChar,inst->cChar);\r
+               alOut(c + alScale,inst->cScale);\r
+               alOut(c + alAttack,inst->cAttack);\r
+               alOut(c + alSus,inst->cSus);\r
+               alOut(c + alWave,inst->cWave);\r
        }\r
 \r
-       adlib_apply_all();\r
+       alOut(which + alFeedCon,inst->nConn);   // DEBUG - I think this is right\r
+}\r
+//#endif\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_ALStopSound() - Turns off any sound effects playing through the\r
+//             AdLib card\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+#ifdef _MUSE_\r
+void\r
+#else\r
+static void\r
+#endif\r
+SDL_ALStopSound(void)\r
+{\r
+asm    pushf\r
+asm    cli\r
+\r
+       /*(long)*/alSound = 0;\r
+       alOut(alFreqH + 0,0);\r
+\r
+asm    popf\r
 }\r
+\r
+static void\r
+SDL_AlSetFXInst(Instrument far *inst)\r
+{\r
+       byte            c,m;\r
+\r
+       m = modifiers[0];\r
+       c = carriers[0];\r
+       alOut(m + alChar,inst->mChar);\r
+       alOut(m + alScale,inst->mScale);\r
+       alOut(m + alAttack,inst->mAttack);\r
+       alOut(m + alSus,inst->mSus);\r
+       alOut(m + alWave,inst->mWave);\r
+       alOut(c + alChar,inst->cChar);\r
+       alOut(c + alScale,inst->cScale);\r
+       alOut(c + alAttack,inst->cAttack);\r
+       alOut(c + alSus,inst->cSus);\r
+       alOut(c + alWave,inst->cWave);\r
+\r
+       // Note: Switch commenting on these lines for old MUSE compatibility\r
+//     alOut(alFeedCon,inst->nConn);\r
+       alOut(alFeedCon,0);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_ALPlaySound() - Plays the specified sound on the AdLib card\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+#ifdef _MUSE_\r
+void\r
+#else\r
+static void\r
+#endif\r
+SDL_ALPlaySound(AdLibSound far *sound, global_game_variables_t *gvar)\r
+{\r
+       Instrument      __far *inst;\r
+       byte            huge *data;\r
+\r
+       SDL_ALStopSound();\r
+\r
+asm    pushf\r
+asm    cli\r
+\r
+       alLengthLeft = sound->common.length;\r
+       data = sound->data;\r
+       data++;\r
+       data--;\r
+       alSound = (byte far *)data;\r
+       alBlock = ((sound->block & 7) << 2) | 0x20;\r
+       inst = &sound->inst;\r
+\r
+       if (!(inst->mSus | inst->cSus))\r
+       {\r
+       asm     popf\r
+               Quit(gvar, "SDL_ALPlaySound() - Bad instrument");\r
+       }\r
+\r
+       SDL_AlSetFXInst(&alZeroInst);   // DEBUG\r
+       SDL_AlSetFXInst(inst);\r
+\r
+asm    popf\r
+}\r
+\r
+//#if 0\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_ALSoundService() - Plays the next sample out through the AdLib card\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+//static void\r
+void\r
+SDL_ALSoundService(void)\r
+{\r
+       byte    s;\r
+\r
+       if (alSound)\r
+       {\r
+               s = *alSound++;\r
+               if (!s)\r
+                       alOut(alFreqH + 0,0);\r
+               else\r
+               {\r
+                       alOut(alFreqL + 0,s);\r
+                       alOut(alFreqH + 0,alBlock);\r
+               }\r
+\r
+               if (!(--alLengthLeft))\r
+               {\r
+                       /*(long)*/alSound = 0;\r
+                       alOut(alFreqH + 0,0);\r
+                       SDL_SoundFinished();\r
+               }\r
+       }\r
+}\r
+//#endif\r
+\r
+#if 0\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_SelectMeasure() - sets up sequencing variables for a given track\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+SDL_SelectMeasure(ActiveTrack *track)\r
+{\r
+       track->seq = track->moods[track->mood];\r
+       track->nextevent = 0;\r
+}\r
+#endif\r
+\r
+//#if 0\r
+void\r
+SDL_ALService(void)\r
+{\r
+       byte    a,v;\r
+       word    w;\r
+\r
+       a=v=0;\r
+\r
+       if (!sqActive)\r
+               return;\r
+\r
+       while (sqHackLen && (sqHackTime <= alTimeCount))\r
+       {\r
+               w = *sqHackPtr++;\r
+               sqHackTime = alTimeCount + *sqHackPtr++;\r
+       asm     mov     dx,[w]\r
+       asm     mov     [a],dl\r
+       asm     mov     [v],dh\r
+               alOut(a,v);\r
+               sqHackLen -= 4;\r
+       }\r
+       alTimeCount++;\r
+       if (!sqHackLen)\r
+       {\r
+               sqHackPtr = (word far *)sqHack;\r
+               sqHackLen = sqHackSeqLen;\r
+               alTimeCount = sqHackTime = 0;\r
+       }\r
+}\r
+//#endif\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_ShutAL() - Shuts down the AdLib card for sound effects\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+SDL_ShutAL(void)\r
+{\r
+asm    pushf\r
+asm    cli\r
+\r
+       alOut(alEffects,0);\r
+       alOut(alFreqH + 0,0);\r
+       SDL_AlSetFXInst(&alZeroInst);\r
+       alSound = 0;\r
+\r
+asm    popf\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_CleanAL() - Totally shuts down the AdLib card\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+SDL_CleanAL(void)\r
+{\r
+       int     i;\r
+\r
+asm    pushf\r
+asm    cli\r
+\r
+       alOut(alEffects,0);\r
+       for (i = 1;i < 0xf5;i++)\r
+               alOut(i,0);\r
+\r
+asm    popf\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_StartAL() - Starts up the AdLib card for sound effects\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+SDL_StartAL(void)\r
+{\r
+       alFXReg = 0;\r
+       alOut(alEffects,alFXReg);\r
+       SDL_AlSetFXInst(&alZeroInst);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_DetectAdLib() - Determines if there's an AdLib (or SoundBlaster\r
+//             emulating an AdLib) present\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static boolean\r
+SDL_DetectAdLib(void)\r
+{\r
+       byte    status1,status2;\r
+       int             i;\r
+\r
+       alOut(4,0x60);  // Reset T1 & T2\r
+       alOut(4,0x80);  // Reset IRQ\r
+       status1 = readstat();\r
+       alOut(2,0xff);  // Set timer 1\r
+       alOut(4,0x21);  // Start timer 1\r
+       SDL_Delay(TimerDelay100);\r
+\r
+#if 0\r
+       __asm {\r
+               mov     dx,0x388\r
+               mov     cx,100\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+usecloop:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+       in      al,dx\r
+       loop usecloop\r
+       }\r
+#endif\r
+\r
+       status2 = readstat();\r
+       alOut(4,0x60);\r
+       alOut(4,0x80);\r
+\r
+       if (((status1 & 0xe0) == 0x00) && ((status2 & 0xe0) == 0xc0))\r
+       {\r
+               for (i = 1;i <= 0xf5;i++)       // Zero all the registers\r
+                       alOut(i,0);\r
+\r
+               alOut(1,0x20);  // Set WSE=1\r
+               alOut(8,0);             // Set CSM=0 & SEL=0\r
+\r
+               return(true);\r
+       }\r
+       else\r
+               return(false);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_t0Service() - My timer 0 ISR which handles the different timings and\r
+//             dispatches to whatever other routines are appropriate\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+//static void interrupt\r
+void interrupt\r
+SDL_t0Service(void)\r
+{\r
+static word    count = 1;\r
+       boolean myackflag = 0;\r
+\r
+//00#if 0      // for debugging\r
+asm    mov     dx,STATUS_REGISTER_1\r
+asm    in      al,dx\r
+asm    mov     dx,ATR_INDEX\r
+asm    mov     al,ATR_OVERSCAN\r
+asm    out     dx,al\r
+asm    mov     al,4    // red\r
+asm    out     dx,al\r
+//00#endif\r
+\r
+       HackCount++;\r
+\r
+       if ((MusicMode == smm_AdLib) || (DigiMode == sds_SoundSource))\r
+       {\r
+               SDL_ALService();\r
+//SS           SDL_SSService();\r
+//             if (!(++count & 7))\r
+               if (!(++count % 10))\r
+               {\r
+                       LocalTime++;\r
+                       TimeCount++;\r
+                       if (SoundUserHook)\r
+                               SoundUserHook();\r
+               }\r
+//             if (!(count & 3))\r
+               if (!(count % 5))\r
+               {\r
+                       switch (SoundMode)\r
+                       {\r
+                       case sdm_PC:\r
+                               SDL_PCService();\r
+                               break;\r
+                       case sdm_AdLib:\r
+                               SDL_ALSoundService();\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+       else\r
+       {\r
+               if (!(++count & 1))\r
+               {\r
+                       LocalTime++;\r
+                       TimeCount++;\r
+                       if (SoundUserHook)\r
+                               SoundUserHook();\r
+               }\r
+               switch (SoundMode)\r
+               {\r
+               case sdm_PC:\r
+                       SDL_PCService();\r
+                       break;\r
+               case sdm_AdLib:\r
+                       SDL_ALSoundService();\r
+                       break;\r
+               }\r
+       }\r
+\r
+       __asm {\r
+               mov     ax,[WORD PTR TimerCount]\r
+               add     ax,[WORD PTR TimerDivisor]\r
+               mov     [WORD PTR TimerCount],ax\r
+               jnc     myack\r
+               jmp end1\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+myack:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               mov     myackflag,1\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+end1:\r
+#ifdef __WATCOMC__\r
+       }\r
+#endif\r
+       if(!myackflag)\r
+               t0OldService();                 // If we overflow a word, time to call old int handler\r
+       else\r
+               outportb(0x20,0x20);    // Ack the interrupt\r
+\r
+//00#if 0      // for debugging\r
+asm    mov     dx,STATUS_REGISTER_1\r
+asm    in      al,dx\r
+asm    mov     dx,ATR_INDEX\r
+asm    mov     al,ATR_OVERSCAN\r
+asm    out     dx,al\r
+asm    mov     al,3    // blue\r
+asm    out     dx,al\r
+asm    mov     al,0x20 // normal\r
+asm    out     dx,al\r
+//00#endif\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_ShutDevice() - turns off whatever device was being used for sound fx\r
+//\r
+////////////////////////////////////////////////////////////////////////////\r
+static void\r
+SDL_ShutDevice(void)\r
+{\r
+       switch (SoundMode)\r
+       {\r
+       case sdm_PC:\r
+               SDL_ShutPC();\r
+               break;\r
+       case sdm_AdLib:\r
+               SDL_ShutAL();\r
+               break;\r
+       }\r
+       SoundMode = sdm_Off;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_CleanDevice() - totally shuts down all sound devices\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+SDL_CleanDevice(void)\r
+{\r
+       if ((SoundMode == sdm_AdLib) || (MusicMode == smm_AdLib))\r
+               SDL_CleanAL();\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SDL_StartDevice() - turns on whatever device is to be used for sound fx\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+SDL_StartDevice(void)\r
+{\r
+       switch (SoundMode)\r
+       {\r
+       case sdm_AdLib:\r
+               SDL_StartAL();\r
+               break;\r
+       }\r
+       SoundNumber = SoundPriority = 0;\r
+}\r
+#if 0\r
+static void\r
+SDL_SetTimerSpeed(void)\r
+{\r
+       word    rate;\r
+\r
+       if (MusicMode == smm_AdLib)\r
+               rate = TickBase * 8;\r
+       else\r
+               rate = TickBase * 2;\r
+       SDL_SetIntsPerSec(rate);\r
+}\r
+#endif\r
+//     Public routines\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_SetSoundMode() - Sets which sound hardware to use for sound effects\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+boolean\r
+SD_SetSoundMode(SDMode mode, global_game_variables_t *gvar)\r
+{\r
+       boolean result = false;\r
+       word    tableoffset;\r
+\r
+       SD_StopSound(gvar);\r
+\r
+#ifndef        _MUSE_\r
+       if ((mode == sdm_AdLib) && !AdLibPresent)\r
+               mode = sdm_PC;\r
+\r
+       switch (mode)\r
+       {\r
+       case sdm_Off:\r
+               NeedsDigitized = false;\r
+               result = true;\r
+               break;\r
+       case sdm_PC:\r
+               tableoffset = STARTPCSOUNDS;\r
+               NeedsDigitized = false;\r
+               result = true;\r
+               break;\r
+       case sdm_AdLib:\r
+               if (AdLibPresent)\r
+               {\r
+                       tableoffset = STARTADLIBSOUNDS;\r
+                       NeedsDigitized = false;\r
+                       result = true;\r
+               }\r
+               break;\r
+       }\r
+#else\r
+       result = true;\r
+#endif\r
+\r
+       if (result && (mode != SoundMode))\r
+       {\r
+               SDL_ShutDevice();\r
+               SoundMode = mode;\r
+#ifndef        _MUSE_\r
+               SoundTable = (word *)(&gvar->ca.audiosegs[tableoffset]);\r
+#endif\r
+               SDL_StartDevice();\r
+       }\r
+\r
+       SDL_SetTimerSpeed();\r
+\r
+       return(result);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_SetMusicMode() - sets the device to use for background music\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+boolean\r
+SD_SetMusicMode(SMMode mode)\r
+{\r
+       boolean result = false;\r
+\r
+       SD_FadeOutMusic();\r
+       while (SD_MusicPlaying())\r
+               ;\r
+\r
+       switch (mode)\r
+       {\r
+       case smm_Off:\r
+               NeedsMusic = false;\r
+               result = true;\r
+               break;\r
+       case smm_AdLib:\r
+               if (AdLibPresent)\r
+               {\r
+                       NeedsMusic = true;\r
+                       result = true;\r
+               }\r
+               break;\r
+       }\r
+\r
+       if (result)\r
+               MusicMode = mode;\r
+\r
+       SDL_SetTimerSpeed();\r
+\r
+       return(result);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_Startup() - starts up the Sound Mgr\r
+//             Detects all additional sound hardware and installs my ISR\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+SD_Startup(global_game_variables_t *gvar)\r
+{\r
+       int     i;\r
+\r
+       if (SD_Started)\r
+               return;\r
+#ifndef SD_USECATA3DSETTIMERSPEED\r
+       SDL_SetDS();\r
+#endif\r
+       ssIsTandy = false;\r
+//SS   ssNoCheck = false;\r
+       alNoCheck = false;\r
+//SB   sbNoCheck = false;\r
+//SB   sbNoProCheck = false;\r
+#ifndef        _MUSE_\r
+       for (i = 1;i < _argc;i++)\r
+       {\r
+               switch (US_CheckParm(_argv[i],ParmStrings))\r
+               {\r
+               case 0:                                         // No AdLib detection\r
+                       alNoCheck = true;\r
+                       break;\r
+//SB           case 1:                                         // No SoundBlaster detection\r
+//SB                   sbNoCheck = true;\r
+//SB                   break;\r
+//SB           case 2:                                         // No SoundBlaster Pro detection\r
+//SB                   sbNoProCheck = true;\r
+//SB                   break;\r
+//SS           case 3:\r
+//SS                   ssNoCheck = true;               // No Sound Source detection\r
+//SS                   break;\r
+               case 4:                                         // Tandy Sound Source handling\r
+                       ssIsTandy = true;\r
+                       break;\r
+//SS           case 5:                                         // Sound Source present at LPT1\r
+//SS                   ssPort = 1;\r
+//SS                   ssNoCheck = SoundSourcePresent = true;\r
+//SS                   break;\r
+//SS           case 6:                     // Sound Source present at LPT2\r
+//SS                   ssPort = 2;\r
+//SS                   ssNoCheck = SoundSourcePresent = true;\r
+//SS                   break;\r
+//SS           case 7:                     // Sound Source present at LPT3\r
+//SS                   ssPort = 3;\r
+//SS                   ssNoCheck = SoundSourcePresent = true;\r
+//SS                   break;\r
+               }\r
+       }\r
+#endif\r
+\r
+       SoundUserHook = 0;\r
+\r
+       t0OldService = getvect(8);      // Get old timer 0 ISR\r
+#ifdef SD_USECATA3DSETTIMERSPEED\r
+       SDL_InitDelay();                        // SDL_InitDelay() uses t0OldService\r
+\r
+       setvect(8,SDL_t0Service);       // Set to my timer 0 ISR\r
+#endif\r
+       LocalTime = TimeCount = alTimeCount = 0;\r
+\r
+       SD_SetSoundMode(sdm_Off, gvar);\r
+       SD_SetMusicMode(smm_Off);\r
+\r
+//SS   if (!ssNoCheck)\r
+//SS           SoundSourcePresent = SDL_DetectSoundSource();\r
+\r
+       if (!alNoCheck)\r
+       {\r
+               AdLibPresent = SDL_DetectAdLib();\r
+//SB           if (AdLibPresent) && !sbNoCheck)\r
+//SB           {\r
+//SB                   int port = -1;\r
+//SB                   char *env = getenv("BLASTER");\r
+//SB                   if (env)\r
+//SB                   {\r
+//SB                           long temp;\r
+//SB                           while (*env)\r
+//SB                           {\r
+//SB                                   while (isspace(*env))\r
+//SB                                           env++;\r
+//SB\r
+//SB                                   switch (toupper(*env))\r
+//SB                                   {\r
+//SB                                   case 'A':\r
+//SB                                           temp = strtol(env + 1,&env,16);\r
+//SB                                           if\r
+//SB                                           (\r
+//SB                                                   (temp >= 0x210)\r
+//SB                                           &&      (temp <= 0x260)\r
+//SB                                           &&      (!(temp & 0x00f))\r
+//SB                                           )\r
+//SB                                                   port = (temp - 0x200) >> 4;\r
+//SB                                           else\r
+//SB                                                   Quit(gvar, "SD_Startup: Unsupported address value in BLASTER");\r
+//SB                                           break;\r
+//SB                                   case 'I':\r
+//SB                                           temp = strtol(env + 1,&env,10);\r
+//SB                                           if\r
+//SB                                           (\r
+//SB                                                   (temp >= 0)\r
+//SB                                           &&      (temp <= 10)\r
+//SB                                           &&      (sbIntVectors[temp] != -1)\r
+//SB                                           )\r
+//SB                                           {\r
+//SB                                                   sbInterrupt = temp;\r
+//SB                                                   sbIntVec = sbIntVectors[sbInterrupt];\r
+//SB                                           }\r
+//SB                                           else\r
+//SB                                                   Quit(gvar, "SD_Startup: Unsupported interrupt value in BLASTER");\r
+//SB                                           break;\r
+//SB                                   case 'D':\r
+//SB                                           temp = strtol(env + 1,&env,10);\r
+//SB                                           if ((temp == 0) || (temp == 1) || (temp == 3))\r
+//SB                                                   SDL_SBSetDMA(temp);\r
+//SB                                           else\r
+//SB                                                   Quit(gvar, "SD_Startup: Unsupported DMA value in BLASTER");\r
+//SB                                           break;\r
+//SB                                   default:\r
+//SB                                           while (isspace(*env))\r
+//SB                                                   env++;\r
+//SB                                           while (*env && !isspace(*env))\r
+//SB                                                   env++;\r
+//SB                                           break;\r
+//SB                                   }\r
+//SB                           }\r
+//SB                   }\r
+//SB                   SoundBlasterPresent = SDL_DetectSoundBlaster(port);\r
+//SB           }\r
+       }\r
+\r
+       for (i = 0;i < 255;i++)\r
+               pcSoundLookup[i] = i * 60;\r
+\r
+//SB   if (SoundBlasterPresent)\r
+//SB           SDL_StartSB();\r
+\r
+       SDL_SetupDigi(gvar);\r
+\r
+       SD_Started = true;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_Default() - Sets up the default behaviour for the Sound Mgr whether\r
+//             the config file was present or not.\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+SD_Default(boolean gotit,SDMode sd,SMMode sm, global_game_variables_t *gvar)\r
+{\r
+       boolean gotsd,gotsm;\r
+\r
+       gotsd = gotsm = gotit;\r
+\r
+       if (gotsd)      // Make sure requested sound hardware is available\r
+       {\r
+               switch (sd)\r
+               {\r
+               case sdm_AdLib:\r
+                       gotsd = AdLibPresent;\r
+                       break;\r
+               }\r
+       }\r
+       if (!gotsd)\r
+       {\r
+               if (AdLibPresent)\r
+                       sd = sdm_AdLib;\r
+               else\r
+                       sd = sdm_PC;\r
+       }\r
+       if (sd != SoundMode)\r
+               SD_SetSoundMode(sd, gvar);\r
+\r
+\r
+       if (gotsm)      // Make sure requested music hardware is available\r
+       {\r
+               switch (sm)\r
+               {\r
+               case sdm_AdLib:\r
+                       gotsm = AdLibPresent;\r
+                       break;\r
+               }\r
+       }\r
+       if (!gotsm)\r
+       {\r
+               if (AdLibPresent)\r
+                       sm = smm_AdLib;\r
+       }\r
+       if (sm != MusicMode)\r
+               SD_SetMusicMode(sm);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_Shutdown() - shuts down the Sound Mgr\r
+//             Removes sound ISR and turns off whatever sound hardware was active\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+SD_Shutdown(global_game_variables_t *gvar)\r
+{\r
+       if (!SD_Started)\r
+               return;\r
+\r
+       SD_MusicOff();\r
+       SD_StopSound(gvar);\r
+       SDL_ShutDevice();\r
+       SDL_CleanDevice();\r
+\r
+//SB   if (SoundBlasterPresent)\r
+//SB           SDL_ShutSB();\r
+\r
+//SS   if (SoundSourcePresent)\r
+//SS           SDL_ShutSS();\r
+\r
+       asm     pushf\r
+       asm     cli\r
+\r
+       SDL_SetTimer0(0);\r
+\r
+       setvect(8,t0OldService);\r
+\r
+       asm     popf\r
+\r
+       SD_Started = false;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_SetUserHook() - sets the routine that the Sound Mgr calls every 1/70th\r
+//             of a second from its timer 0 ISR\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+SD_SetUserHook(void (* hook)(void))\r
+{\r
+       SoundUserHook = hook;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_PositionSound() - Sets up a stereo imaging location for the next\r
+//             sound to be played. Each channel ranges from 0 to 15.\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+SD_PositionSound(int leftvol,int rightvol)\r
+{\r
+       LeftPosition = leftvol;\r
+       RightPosition = rightvol;\r
+       nextsoundpos = true;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_PlaySound() - plays the specified sound on the appropriate hardware\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+boolean\r
+SD_PlaySound(soundnames sound, global_game_variables_t *gvar)\r
+{\r
+       boolean         ispos;\r
+       SoundCommon     far *s;\r
+       int     lp,rp;\r
+\r
+       lp = LeftPosition;\r
+       rp = RightPosition;\r
+       LeftPosition = 0;\r
+       RightPosition = 0;\r
+\r
+       ispos = nextsoundpos;\r
+       nextsoundpos = false;\r
+\r
+       if (sound == -1)\r
+               return(false);\r
+\r
+       s = MK_FP(SoundTable[sound],0);\r
+       if ((SoundMode != sdm_Off) && !s)\r
+               Quit(gvar, "SD_PlaySound() - Uncached sound");\r
+\r
+       if ((DigiMode != sds_Off) && (DigiMap[sound] != -1))\r
+       {\r
+               if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
+               {\r
+                       if (s->priority < SoundPriority)\r
+                               return(false);\r
+\r
+                       SDL_PCStopSound();\r
+\r
+                       SD_PlayDigitized(DigiMap[sound],lp,rp, gvar);\r
+                       SoundPositioned = ispos;\r
+                       SoundNumber = sound;\r
+                       SoundPriority = s->priority;\r
+               }\r
+               else\r
+               {\r
+               asm     pushf\r
+               asm     cli\r
+                       if (DigiPriority && !DigiNumber)\r
+                       {\r
+                       asm     popf\r
+                               Quit(gvar, "SD_PlaySound: Priority without a sound");\r
+                       }\r
+               asm     popf\r
+\r
+                       if (s->priority < DigiPriority)\r
+                               return(false);\r
+\r
+                       SD_PlayDigitized(DigiMap[sound],lp,rp, gvar);\r
+                       SoundPositioned = ispos;\r
+                       DigiNumber = sound;\r
+                       DigiPriority = s->priority;\r
+               }\r
+\r
+               return(true);\r
+       }\r
+\r
+       if (SoundMode == sdm_Off)\r
+               return(false);\r
+       if (!s->length)\r
+               Quit(gvar, "SD_PlaySound() - Zero length sound");\r
+       if (s->priority < SoundPriority)\r
+               return(false);\r
+\r
+       switch (SoundMode)\r
+       {\r
+       case sdm_PC:\r
+               SDL_PCPlaySound((void far *)s);\r
+               break;\r
+       case sdm_AdLib:\r
+               SDL_ALPlaySound((void far *)s, gvar);\r
+               break;\r
+       }\r
+\r
+       SoundNumber = sound;\r
+       SoundPriority = s->priority;\r
+\r
+       return(false);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_SoundPlaying() - returns the sound number that's playing, or 0 if\r
+//             no sound is playing\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+word\r
+SD_SoundPlaying(void)\r
+{\r
+       boolean result = false;\r
+\r
+       switch (SoundMode)\r
+       {\r
+       case sdm_PC:\r
+               result = pcSound? true : false;\r
+               break;\r
+       case sdm_AdLib:\r
+               result = alSound? true : false;\r
+               break;\r
+       }\r
+\r
+       if (result)\r
+               return(SoundNumber);\r
+       else\r
+               return(false);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_StopSound() - if a sound is playing, stops it\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+SD_StopSound(global_game_variables_t *gvar)\r
+{\r
+       if (DigiPlaying)\r
+               SD_StopDigitized(gvar);\r
+\r
+       switch (SoundMode)\r
+       {\r
+       case sdm_PC:\r
+               SDL_PCStopSound();\r
+               break;\r
+       case sdm_AdLib:\r
+               SDL_ALStopSound();\r
+               break;\r
+       }\r
+\r
+       SoundPositioned = false;\r
+\r
+       SDL_SoundFinished();\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_WaitSoundDone() - waits until the current sound is done playing\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+SD_WaitSoundDone(void)\r
+{\r
+       while (SD_SoundPlaying())\r
+               ;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_MusicOn() - turns on the sequencer\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+SD_MusicOn(void)\r
+{\r
+       sqActive = true;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_MusicOff() - turns off the sequencer and any playing notes\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+SD_MusicOff(void)\r
+{\r
+       word    i;\r
+\r
+\r
+       switch (MusicMode)\r
+       {\r
+       case smm_AdLib:\r
+               alFXReg = 0;\r
+               alOut(alEffects,0);\r
+               for (i = 0;i < sqMaxTracks;i++)\r
+                       alOut(alFreqH + i + 1,0);\r
+               break;\r
+       }\r
+       sqActive = false;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_StartMusic() - starts playing the music pointed to\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+SD_StartMusic(MusicGroup far *music)\r
+{\r
+       SD_MusicOff();\r
+asm    pushf\r
+asm    cli\r
+\r
+       if (MusicMode == smm_AdLib)\r
+       {\r
+               sqHackPtr = sqHack = music->values;\r
+               sqHackSeqLen = sqHackLen = music->length;\r
+               sqHackTime = 0;\r
+               alTimeCount = 0;\r
+               SD_MusicOn();\r
+       }\r
+\r
+asm    popf\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_FadeOutMusic() - starts fading out the music. Call SD_MusicPlaying()\r
+//             to see if the fadeout is complete\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+SD_FadeOutMusic(void)\r
+{\r
+       switch (MusicMode)\r
+       {\r
+       case smm_AdLib:\r
+               // DEBUG - quick hack to turn the music off\r
+               SD_MusicOff();\r
+               break;\r
+       }\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     SD_MusicPlaying() - returns true if music is currently playing, false if\r
+//             not\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+boolean\r
+SD_MusicPlaying(void)\r
+{\r
+       boolean result;\r
+\r
+       switch (MusicMode)\r
+       {\r
+       case smm_AdLib:\r
+               result = false;\r
+               // DEBUG - not written\r
+               break;\r
+       default:\r
+               result = false;\r
+       }\r
+\r
+       return(result);\r
+}\r
+\r
+//#if 0\r
+//\r
+// SD ASS!\r
+//\r
+\r
+//variables for these assembly functions\r
+volatile boolean pcindicate;\r
+volatile unsigned/*boolean*/ MyDS;\r
+\r
+void SDL_SetDS()\r
+{\r
+       __asm {\r
+               mov     ax,ds\r
+               mov     [cs:MyDS],ds\r
+               ret\r
+       }\r
+}\r
+\r
+//\r
+\r
+// Timer 0 ISR for 7000Hz interrupts\r
+void interrupt SDL_t0ExtremeAsmService(void)\r
+{\r
+       if(pcindicate)\r
+       {\r
+               if(pcSound)\r
+               {\r
+                       SDL_setPCSpeaker(((*pcSound++)&0x80)>>6);\r
+                       pcLengthLeft--;\r
+                       if(!pcLengthLeft)\r
+                       {\r
+                               pcSound=0;\r
+                               SDL_turnOffPCSpeaker();\r
+                               SDL_DigitizedDoneInIRQ();\r
+                       }\r
+               }\r
+       }\r
+       extreme++;\r
+       if(extreme>=10)\r
+       {\r
+               extreme=0;\r
+               SDL_DoFast();\r
+       }\r
+       else\r
+               outp(0x20,0x20);\r
+}\r
+\r
+//\r
+\r
+void SDL_IndicatePC(boolean ind)\r
+{\r
+       pcindicate=ind;\r
+}\r
+\r
+void\r
+SDL_DigitizedDoneInIRQ(void)\r
+{\r
+       if (DigiNextAddr)\r
+       {\r
+               SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen/*,true*/);\r
+               DigiNextAddr = nil;\r
+               DigiMissed = false;\r
+       }\r
+       else\r
+       {\r
+               if (DigiLastSegment)\r
+               {\r
+                       DigiPlaying = false;\r
+                       DigiLastSegment = false;\r
+                       if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
+                       {\r
+                               SDL_SoundFinished();\r
+                       }\r
+                       else\r
+                       {\r
+                               DigiNumber = (soundnames) 0;\r
+                               DigiPriority = 0;\r
+                       }\r
+                       SoundPositioned = false;\r
+               }\r
+               else\r
+                       DigiMissed = true;\r
+       }\r
+}\r
+\r
+#if 0\r
+// Inside an interrupt handler interrupts should already be disabled\r
+// so don't disable them again and cause V86 exceptions which cost\r
+// aprox. 300 processor tics!\r
+\r
+//static\r
+void alOutInIRQ(byte n,byte b)\r
+{\r
+       __asm {\r
+               mov     dx,0x388\r
+               mov     al,[n]\r
+               out     dx,al\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               inc     dx\r
+               mov     al,[b]\r
+               out     dx,al\r
+\r
+               dec     dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+               in      al,dx\r
+       }\r
+}\r
+#endif\r
index 858ed74cfd40dc252c0e12457f53266df0d70f74..12558e66bb45d3e76e6063c63aa6abb6ddf635d7 100755 (executable)
  *\r
  */\r
 \r
-#ifndef __16_SD_H_\r
-#define __16_SD_H_\r
+//\r
+//     ID Engine\r
+//     ID_SD.h - Sound Manager Header\r
+//     Version for Wolfenstein\r
+//     By Jason Blochowiak\r
+//     Open Watcom port by sparky4\r
+//\r
+\r
+#ifndef        __16_SD__\r
+#define        __16_SD__\r
 \r
 #include "src/lib/16_head.h"\r
-#include "src/lib/16_tail.h"\r
-#include <hw/8254/8254.h>              /* 8254 timer */\r
-#include <hw/adlib/adlib.h>\r
-#include <hw/vga/vga.h>\r
-#include <hw/dos/dos.h>\r
-#include <hw/8259/8259.h>\r
-\r
-#define SD_USESCAMMPM\r
-\r
-#define MIN_REGISTER                   0x01\r
-#define MAX_REGISTER                   0xF5\r
-#define ADLIB_FM_ADDRESS       0x388   /* adlib address/status register */\r
-#define ADLIB_FM_DATA          0x389   /* adlib data register           */\r
-\r
-/*\r
-* FM Instrument definition for .SBI files - SoundBlaster instrument\r
-* - these are the important parts - we will skip the header, but since\r
-*   I am not sure where it starts and ends so I have had to guess.\r
-*   However it SEEMS! to work. Each array has two values, one for\r
-*   each operator.\r
-*/\r
-typedef struct{\r
-       byte SoundCharacteristic[2];    /* modulator frequency multiple...  */\r
-       byte Level[2];                  /* modulator frequency level...     */\r
-       byte AttackDecay[2];            /* modulator attack/decay...        */\r
-       byte SustainRelease[2];         /* modulator sustain/release...     */\r
-       byte WaveSelect[2];             /* output waveform distortion       */\r
-       byte Feedback;                  /* feedback algorithm and strength  */\r
-} FMInstrument;\r
-\r
-void opl2out(word reg, word data);\r
-void opl3out(word reg, word data);\r
-void opl3exp(word data);\r
-\r
-void FMReset(void/*int percusiveMode*/);\r
-void FMKeyOff(int voice);\r
-void FMKeyOn(int voice, int freq, int octave);\r
-void FMSetVoice(int voiceNum, FMInstrument *ins);\r
-\r
-void SD_Initimf(global_game_variables_t *gvar);\r
-void SD_imf_reset_music(global_game_variables_t *gvar);\r
-void   SD_StartupTimer(global_game_variables_t *gvar),\r
-               SD_ShutdownTimer();\r
-void SD_imf_free_music(global_game_variables_t *gvar);\r
-int SD_imf_load_music(const char *path, global_game_variables_t *gvar);\r
-void interrupt SD_irq0(void);\r
-void SD_imf_tick(global_game_variables_t *gvar);\r
-void SD_adlib_shut_up();\r
-\r
-#endif /*__16_SND_H_*/\r
+#include "src/lib/16_pm.h"\r
+\r
+void   alOut(byte n,byte b);\r
+\r
+#ifdef __DEBUG__\r
+#define        __DEBUG_SoundMgr__\r
+#endif\r
+\r
+#define        TickBase        70              // 70Hz per tick - used as a base for timer 0\r
+\r
+typedef        enum    {\r
+                                       sdm_Off,\r
+                                       sdm_PC,sdm_AdLib,\r
+                               }       SDMode;\r
+typedef        enum    {\r
+                                       smm_Off,smm_AdLib\r
+                               }       SMMode;\r
+typedef        enum    {\r
+                                       sds_Off,sds_PC,sds_SoundSource,sds_SoundBlaster\r
+                               }       SDSMode;\r
+typedef        struct\r
+               {\r
+                       dword   length;\r
+                       word            priority;\r
+               } SoundCommon;\r
+\r
+//     PC Sound stuff\r
+#define        pcTimer         0x42\r
+#define        pcTAccess       0x43\r
+#define        pcSpeaker       0x61\r
+\r
+#define        pcSpkBits       3\r
+\r
+typedef        struct\r
+               {\r
+                       SoundCommon     common;\r
+                       byte            data[1];\r
+               } PCSound;\r
+\r
+//     Registers for the Sound Blaster card - needs to be offset by n0 (0x10,0x20,0x30,0x40,0x50,0x60)\r
+#define        sbReset         0x206   // W\r
+#define        sbFMStatus      0x208   // R\r
+#define        sbFMAddr        0x208   // W\r
+#define        sbFMData        0x209   // W\r
+#define        sbReadData      0x20a   // R\r
+#define        sbWriteCmd      0x20c   // W\r
+#define        sbWriteData     0x20c   // W\r
+#define        sbWriteStat     0x20c   // R\r
+#define        sbDataAvail     0x20e   // R\r
+\r
+//     Registers for the Sound Blaster Pro card - needs to be offset by n0 (0x20 or 0x40)\r
+#define        sbpLFMStatus    0x200   // R\r
+#define        sbpLFMAddr              0x200   // W\r
+#define        sbpLFMData              0x201   // W\r
+#define        sbpRFMStatus    0x202   // R\r
+#define        sbpRFMAddr              0x202   // W\r
+#define        sbpRFMData              0x203   // W\r
+#define        sbpMixerAddr    0x204   // W\r
+#define        sbpMixerData    0x205   // RW\r
+#define        sbpCDData               0x210   // R\r
+#define        sbpCDCommand    0x210   // W\r
+#define        sbpCDStatus             0x211   // R\r
+#define        sbpCDReset              0x212   // W\r
+\r
+//     SBPro Mixer addresses\r
+#define        sbpmReset               0x00\r
+#define        sbpmVoiceVol    0x04\r
+#define        sbpmMicMix              0x0a\r
+#define        sbpmFilterADC   0x0c\r
+#define        sbpmControl             0x0e\r
+#define        sbpmMasterVol   0x22\r
+#define        sbpmFMVol               0x26\r
+#define        sbpmCDVol               0x28\r
+#define        sbpmLineVol             0x2e\r
+\r
+typedef        struct\r
+               {\r
+                       SoundCommon     common;\r
+                       word            hertz;\r
+                       byte            bits,\r
+                                               reference,\r
+                                               data[1];\r
+               } SampledSound;\r
+\r
+//     Registers for the AdLib card\r
+#define        alFMStatus      0x388   // R\r
+#define        alFMAddr        0x388   // W\r
+#define        alFMData        0x389   // W\r
+\r
+//     Register addresses\r
+// Operator stuff\r
+#define        alChar          0x20\r
+#define        alScale         0x40\r
+#define        alAttack        0x60\r
+#define        alSus           0x80\r
+#define        alWave          0xe0\r
+// Channel stuff\r
+#define        alFreqL         0xa0\r
+#define        alFreqH         0xb0\r
+#define        alFeedCon       0xc0\r
+// Global stuff\r
+#define        alEffects       0xbd\r
+\r
+typedef        struct\r
+               {\r
+                       byte    mChar,cChar,\r
+                                       mScale,cScale,\r
+                                       mAttack,cAttack,\r
+                                       mSus,cSus,\r
+                                       mWave,cWave,\r
+                                       nConn,\r
+\r
+                                       // These are only for Muse - these bytes are really unused\r
+                                       voice,\r
+                                       mode,\r
+                                       unused[3];\r
+               } Instrument;\r
+\r
+typedef        struct\r
+               {\r
+                       SoundCommon     common;\r
+                       Instrument      inst;\r
+                       byte            block,\r
+                                               data[1];\r
+               } AdLibSound;\r
+\r
+//\r
+//     Sequencing stuff\r
+//\r
+#define        sqMaxTracks     10\r
+#define        sqMaxMoods      1       // DEBUG\r
+\r
+#define        sev_Null                0       // Does nothing\r
+#define        sev_NoteOff             1       // Turns a note off\r
+#define        sev_NoteOn              2       // Turns a note on\r
+#define        sev_NotePitch   3       // Sets the pitch of a currently playing note\r
+#define        sev_NewInst             4       // Installs a new instrument\r
+#define        sev_NewPerc             5       // Installs a new percussive instrument\r
+#define        sev_PercOn              6       // Turns a percussive note on\r
+#define        sev_PercOff             7       // Turns a percussive note off\r
+#define        sev_SeqEnd              -1      // Terminates a sequence\r
+\r
+//     Flags for MusicGroup.flags\r
+#define        sf_Melodic              0\r
+#define        sf_Percussive   1\r
+\r
+#if 1\r
+typedef        struct\r
+               {\r
+                       word    length,\r
+                                       values[1];\r
+               } MusicGroup;\r
+#else\r
+typedef        struct\r
+               {\r
+                       word    flags,\r
+                                       count,\r
+                                       offsets[1];\r
+               } MusicGroup;\r
+#endif\r
+\r
+typedef        struct\r
+               {\r
+                       /* This part needs to be set up by the user */\r
+                       word        mood,far *moods[sqMaxMoods];\r
+\r
+                       /* The rest is set up by the code */\r
+                       Instrument      inst;\r
+                       boolean         percussive;\r
+                       word            far *seq;\r
+                       dword   nextevent;\r
+               } ActiveTrack;\r
+\r
+#define        sqmode_Normal           0\r
+#define        sqmode_FadeIn           1\r
+#define        sqmode_FadeOut          2\r
+\r
+#define        sqMaxFade               64      // DEBUG\r
+\r
+\r
+// Global variables\r
+extern boolean         AdLibPresent,\r
+                                       SoundSourcePresent,\r
+                                       SoundBlasterPresent,\r
+                                       NeedsMusic,                                     // For Caching Mgr\r
+                                       SoundPositioned;\r
+extern SDMode          SoundMode;\r
+extern SDSMode         DigiMode;\r
+extern SMMode          MusicMode;\r
+extern boolean         DigiPlaying;\r
+extern int                     DigiMap[];\r
+extern dword   TimeCount;                                      // Global time in ticks\r
+\r
+// Function prototypes\r
+extern void    SD_Startup(global_game_variables_t *gvar),\r
+                               SD_Shutdown(global_game_variables_t *gvar),\r
+                               SD_Default(boolean gotit,SDMode sd,SMMode sm, global_game_variables_t *gvar),\r
+\r
+                               SD_PositionSound(int leftvol,int rightvol);\r
+extern boolean SD_PlaySound(soundnames sound, global_game_variables_t *gvar);\r
+extern void    SD_SetPosition(int leftvol,int rightvol, global_game_variables_t *gvar),\r
+                               SD_StopSound(global_game_variables_t *gvar),\r
+                               SD_WaitSoundDone(void),\r
+\r
+                               SD_StartMusic(MusicGroup far *music),\r
+                               SD_MusicOn(void),\r
+                               SD_MusicOff(void),\r
+                               SD_FadeOutMusic(void),\r
+\r
+                               SD_SetUserHook(void (*hook)(void));\r
+extern boolean SD_MusicPlaying(void),\r
+                               SD_SetSoundMode(SDMode mode, global_game_variables_t *gvar),\r
+                               SD_SetMusicMode(SMMode mode);\r
+extern word    SD_SoundPlaying(void);\r
+\r
+extern void    SD_SetDigiDevice(SDSMode, global_game_variables_t *gvar),\r
+                               SD_PlayDigitized(word which,int leftpos,int rightpos, global_game_variables_t *gvar),\r
+                               SD_StopDigitized(global_game_variables_t *gvar),\r
+                               SD_Poll(global_game_variables_t *gvar);\r
+\r
+#ifdef _MUSE_  // MUSE Goes directly to the lower level routines\r
+extern void    SDL_PCPlaySound(PCSound far *sound, global_game_variables_t *gvar),\r
+                               SDL_PCStopSound(void),\r
+                               SDL_ALPlaySound(AdLibSound far *sound),\r
+                               SDL_ALStopSound(void);\r
+#endif\r
+\r
+#endif\r
+\r
diff --git a/src/lib/16_snd.c b/src/lib/16_snd.c
new file mode 100755 (executable)
index 0000000..8d6e0d2
--- /dev/null
@@ -0,0 +1,382 @@
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2017 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#include "src/lib/16_snd.h"\r
+\r
+static void interrupt  (*t0OldService)(void);\r
+\r
+void opl2out(word reg, word data)\r
+{\r
+       __asm\r
+       {\r
+               mov     ax,reg\r
+               mov     dx,word ptr [ADLIB_FM_ADDRESS]\r
+               or      ah,ah\r
+               jz      @@1\r
+               add     dx,2\r
+@@1:    out     dx,al\r
+               mov     cx,6\r
+@@2:    in      al,dx\r
+               loop    @@2\r
+               inc     dl\r
+               mov     ax,data\r
+               out     dx,al\r
+               dec     dl\r
+               mov     cx,36\r
+@@3:    in      al,dx\r
+               loop    @@3\r
+       }\r
+}\r
+\r
+void opl3out(word reg, word data)\r
+{\r
+       __asm\r
+       {\r
+               mov     ax,reg\r
+               mov     dx,word ptr [ADLIB_FM_ADDRESS]\r
+               or      ah,ah\r
+               jz      @@1\r
+               add     dx,2\r
+@@1:    out     dx,al\r
+               inc     dl\r
+               mov     ax,data\r
+               out     dx,al\r
+               dec     dl\r
+               mov     cx,26\r
+@@2:    in      al,dx\r
+               loop    @@2\r
+       }\r
+}\r
+\r
+void opl3exp(word data)\r
+{\r
+       __asm\r
+       {\r
+               mov     ax,data\r
+               mov     dx,word ptr [ADLIB_FM_ADDRESS]\r
+               add     dx,2\r
+               out     dx,al\r
+               mov     cx,6\r
+@@1:    in      al,dx\r
+               loop    @@1\r
+               inc     dl\r
+               mov     al,ah\r
+               out     dx,al\r
+               mov     cx,36\r
+@@2:    in      al,dx\r
+               loop    @@2\r
+       }\r
+}\r
+\r
+/* Function: FMResest *******************************************************\r
+*\r
+*     Description:        quick and dirty sound card reset (zeros all\r
+*                         registers).\r
+*\r
+*/\r
+void FMReset(void/*int percusiveMode*/)\r
+{\r
+       int i;\r
+\r
+       /* zero all registers */\r
+       for(i = MIN_REGISTER; i < MAX_REGISTER+1; i++) opl2out(i, 0);\r
+\r
+       /* allow FM chips to control the waveform of each operator */\r
+       opl2out(0x01, 0x20);\r
+\r
+       /* set rhythm enabled (6 melodic voices, 5 percussive) */\r
+       opl2out(0xBD, 0x20);\r
+\r
+       //FMSetPercusiveMode(percusiveMode);\r
+} /* End of FMReset */\r
+\r
+/* Function: FMKeyOff *******************************************************\r
+*\r
+*     Parameters:        voice - which voice to turn off.\r
+*\r
+*     Description:        turns off the specified voice.\r
+*\r
+*/\r
+void FMKeyOff(int voice)\r
+{\r
+       int regNum;\r
+\r
+       /* turn voice off */\r
+       regNum = 0xB0 + voice % 11;//NUMVOICE;\r
+       opl2out(regNum, 0x0E);\r
+} /* End of FMKeyOff */\r
+\r
+/* Function: FMKeyOn *******************************************************\r
+*\r
+*     Parameters:        voice - which voice to turn on.\r
+*                         freq - its frequency (note).\r
+*                         octave - its octave.\r
+*\r
+*     Description:        turns on a voice of specfied frequency and\r
+*                         octave.\r
+*\r
+*/\r
+void FMKeyOn(int voice, int freq, int octave)\r
+{\r
+       int regNum, tmp;\r
+\r
+       regNum = 0xA0 + voice % 11;//NUMVOICE;\r
+       opl2out(regNum, freq & 0xff);\r
+       regNum = 0xB0 + voice % 11;//NUMVOICE;\r
+       tmp = (freq >> 8) | (octave << 2) | 0x20;\r
+       opl2out(regNum, tmp);\r
+} /* End of FMKeyOn */\r
+\r
+/* Function: FMSetVoice *****************************************************\r
+*\r
+*     Parameters:        voiceNum - which voice to set.\r
+*                         ins - instrument to set voice.\r
+*\r
+*     Description:        sets the instrument of a voice.\r
+*\r
+*/\r
+void FMSetVoice(int voiceNum, FMInstrument *ins){\r
+       int opCellNum, cellOffset;\r
+\r
+       voiceNum %= 11;//NUMVOICE;\r
+       cellOffset = voiceNum % 3 + ((voiceNum / 3) << 3);\r
+\r
+       /* set sound characteristic */\r
+       opCellNum = 0x20 + (char)cellOffset;\r
+       opl2out(opCellNum, ins->SoundCharacteristic[0]);\r
+       opCellNum += 3;\r
+       opl2out(opCellNum, ins->SoundCharacteristic[1]);\r
+\r
+       /* set level/output */\r
+       opCellNum = 0x40 + (char)cellOffset;\r
+       opl2out(opCellNum, ins->Level[0]);\r
+       opCellNum += 3;\r
+       opl2out(opCellNum, ins->Level[1]);\r
+\r
+       /* set Attack/Decay */\r
+       opCellNum = 0x60 + (char)cellOffset;\r
+       opl2out(opCellNum, ins->AttackDecay[0]);\r
+       opCellNum += 3;\r
+       opl2out(opCellNum, ins->AttackDecay[1]);\r
+\r
+       /* set Sustain/Release */\r
+       opCellNum = 0x80 + (char)cellOffset;\r
+       opl2out(opCellNum, ins->SustainRelease[0]);\r
+       opCellNum += 3;\r
+       opl2out(opCellNum, ins->SustainRelease[1]);\r
+\r
+       /* set Wave Select */\r
+       opCellNum = 0xE0 + (char)cellOffset;\r
+       opl2out(opCellNum, ins->WaveSelect[0]);\r
+       opCellNum += 3;\r
+       opl2out(opCellNum, ins->WaveSelect[1]);\r
+\r
+       /* set Feedback/Selectivity */\r
+       opCellNum = (byte)0xC0 + (byte)voiceNum;\r
+       opl2out(opCellNum, ins->Feedback);\r
+} /* End of FMSetVoice */\r
+\r
+\r
+//newer sd\r
+\r
+\r
+struct glob_game_vars  *ggvv;\r
+// WARNING: subroutine call in interrupt handler. make sure you compile with -zu flag for large/compact memory models\r
+void interrupt SDL_irq0()\r
+{\r
+       ggvv->ca.sd.irq0_ticks++;\r
+       if ((ggvv->ca.sd.irq0_cnt += ggvv->ca.sd.irq0_add) >= ggvv->ca.sd.irq0_max) {\r
+               ggvv->ca.sd.irq0_cnt -= ggvv->ca.sd.irq0_max;\r
+               t0OldService();\r
+       }\r
+       else {\r
+               p8259_OCW2(0,P8259_OCW2_NON_SPECIFIC_EOI);\r
+       }\r
+}\r
+\r
+void SD_Initimf(global_game_variables_t *gvar)\r
+{\r
+       if (!init_adlib()) {\r
+               printf("Cannot init library\n");\r
+               return;\r
+       }\r
+       if (!probe_8254()) { /* we need the timer to keep time with the music */\r
+               printf("8254 timer not found\n");\r
+               return;\r
+       }\r
+\r
+       gvar->ca.sd.imf_delay_countdown=0;\r
+       gvar->ca.sd.imf_music=\r
+       gvar->ca.sd.imf_play_ptr=\r
+       gvar->ca.sd.imf_music_end=NULL;\r
+\r
+       SD_adlib_shut_up();\r
+       shutdown_adlib_opl3(); // NTS: Apparently the music won't play otherwise\r
+}\r
+\r
+void SD_imf_reset_music(global_game_variables_t *gvar)\r
+{\r
+       gvar->ca.sd.imf_music = gvar->ca.sd.imf_play_ptr = gvar->ca.sd.imf_music_end = NULL;\r
+       gvar->ca.sd.imf_delay_countdown = 0;\r
+}\r
+\r
+void SD_StartupTimer(global_game_variables_t *gvar)\r
+{\r
+       gvar->ca.sd.irq0_ticks=\r
+       gvar->ca.sd.irq0_cnt = 0;\r
+       gvar->ca.sd.irq0_add = 182;\r
+       gvar->ca.sd.irq0_max = 1000; /* about 18.2Hz */\r
+       gvar->ca.sd.tickrate = 700;\r
+\r
+       write_8254_system_timer(T8254_REF_CLOCK_HZ / gvar->ca.sd.tickrate);\r
+       t0OldService = _dos_getvect(8); /*IRQ0*/\r
+       _dos_setvect(8,SDL_irq0);\r
+\r
+       _cli();\r
+       gvar->ca.sd.irq0_ticks = gvar->ca.sd.ptick = 0;\r
+       _sti();\r
+}\r
+\r
+void SD_ShutdownTimer()\r
+{\r
+       _dos_setvect(8,t0OldService);\r
+}\r
+\r
+void SD_imf_free_music(global_game_variables_t *gvar)\r
+{\r
+#ifndef SD_USESCAMMPM\r
+       if (gvar->ca.sd.imf_music) free(gvar->ca.sd.imf_music);\r
+#else\r
+       MM_FreePtr(MEMPTRCONV gvar->ca.audiosegs[0], gvar);     //TODO make behave like id engine\r
+#endif\r
+       SD_imf_reset_music(gvar);\r
+}\r
+\r
+int SD_imf_load_music(const char *path, global_game_variables_t *gvar)\r
+{\r
+       unsigned long len;\r
+       unsigned char buf[8];\r
+       int fd;\r
+\r
+#ifndef SD_USESCAMMPM\r
+       SD_imf_free_music(gvar);\r
+#else\r
+       SD_imf_reset_music(gvar);\r
+#endif\r
+\r
+       fd = open(path,O_RDONLY|O_BINARY);\r
+       if (fd < 0) return 0;\r
+\r
+       len = lseek(fd,0,SEEK_END);\r
+       lseek(fd,0,SEEK_SET);\r
+       read(fd,buf,2);\r
+       if (buf[0] != 0 || buf[1] != 0) // type 1 IMF\r
+               len = *((uint16_t*)buf);\r
+       else\r
+               lseek(fd,0,SEEK_SET);\r
+\r
+       if (len == 0 || len > 65535UL) {\r
+               close(fd);\r
+               return 0;\r
+       }\r
+       len -= len & 3;\r
+\r
+#ifndef SD_USESCAMMPM\r
+       gvar->ca.sd.imf_music = malloc(len);\r
+#else\r
+       MM_GetPtr(MEMPTRCONV gvar->ca.audiosegs[0],len, gvar);\r
+       gvar->ca.sd.imf_music = (struct imf_entry *)gvar->ca.audiosegs[0];\r
+#endif\r
+       if (gvar->ca.sd.imf_music == NULL) {\r
+               close(fd);\r
+               return 0;\r
+       }\r
+       read(fd,gvar->ca.sd.imf_music,len);\r
+       close(fd);\r
+\r
+       gvar->ca.sd.imf_play_ptr = gvar->ca.sd.imf_music;\r
+       gvar->ca.sd.imf_music_end = gvar->ca.sd.imf_music + (len >> 2UL);\r
+       return 1;\r
+}\r
+\r
+void SD_imf_tick(global_game_variables_t *gvar)\r
+{\r
+       if (gvar->ca.sd.imf_delay_countdown == 0) {\r
+               do {\r
+                       adlib_write(gvar->ca.sd.imf_play_ptr->reg,gvar->ca.sd.imf_play_ptr->data);\r
+                       gvar->ca.sd.imf_delay_countdown = gvar->ca.sd.imf_play_ptr->delay;\r
+                       gvar->ca.sd.imf_play_ptr++;\r
+                       if (gvar->ca.sd.imf_play_ptr == gvar->ca.sd.imf_music_end)\r
+                       {\r
+//                             printf("replay\n");\r
+                               gvar->ca.sd.imf_play_ptr = gvar->ca.sd.imf_music;\r
+                       }\r
+               } while (gvar->ca.sd.imf_delay_countdown == 0);\r
+       }\r
+       else {\r
+               gvar->ca.sd.imf_delay_countdown--;\r
+       }\r
+}\r
+\r
+void SD_adlib_shut_up() {\r
+       int i;\r
+\r
+       memset(adlib_fm,0,sizeof(adlib_fm));\r
+       memset(&adlib_reg_bd,0,sizeof(adlib_reg_bd));\r
+       for (i=0;i < adlib_fm_voices;i++) {\r
+               struct adlib_fm_operator *f;\r
+               f = &adlib_fm[i].mod;\r
+               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;\r
+               f = &adlib_fm[i].car;\r
+               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;\r
+       }\r
+\r
+       for (i=0;i < adlib_fm_voices;i++) {\r
+               struct adlib_fm_operator *f;\r
+\r
+               f = &adlib_fm[i].mod;\r
+               f->mod_multiple = 1;\r
+               f->total_level = 63 - 16;\r
+               f->attack_rate = 15;\r
+               f->decay_rate = 4;\r
+               f->sustain_level = 0;\r
+               f->release_rate = 8;\r
+               f->f_number = 400;\r
+               f->sustain = 1;\r
+               f->octave = 4;\r
+               f->key_on = 0;\r
+\r
+               f = &adlib_fm[i].car;\r
+               f->mod_multiple = 1;\r
+               f->total_level = 63 - 16;\r
+               f->attack_rate = 15;\r
+               f->decay_rate = 4;\r
+               f->sustain_level = 0;\r
+               f->release_rate = 8;\r
+               f->f_number = 0;\r
+               f->sustain = 1;\r
+               f->octave = 0;\r
+               f->key_on = 0;\r
+       }\r
+\r
+       adlib_apply_all();\r
+}\r
diff --git a/src/lib/16_snd.h b/src/lib/16_snd.h
new file mode 100755 (executable)
index 0000000..858ed74
--- /dev/null
@@ -0,0 +1,76 @@
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2017 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#ifndef __16_SD_H_\r
+#define __16_SD_H_\r
+\r
+#include "src/lib/16_head.h"\r
+#include "src/lib/16_tail.h"\r
+#include <hw/8254/8254.h>              /* 8254 timer */\r
+#include <hw/adlib/adlib.h>\r
+#include <hw/vga/vga.h>\r
+#include <hw/dos/dos.h>\r
+#include <hw/8259/8259.h>\r
+\r
+#define SD_USESCAMMPM\r
+\r
+#define MIN_REGISTER                   0x01\r
+#define MAX_REGISTER                   0xF5\r
+#define ADLIB_FM_ADDRESS       0x388   /* adlib address/status register */\r
+#define ADLIB_FM_DATA          0x389   /* adlib data register           */\r
+\r
+/*\r
+* FM Instrument definition for .SBI files - SoundBlaster instrument\r
+* - these are the important parts - we will skip the header, but since\r
+*   I am not sure where it starts and ends so I have had to guess.\r
+*   However it SEEMS! to work. Each array has two values, one for\r
+*   each operator.\r
+*/\r
+typedef struct{\r
+       byte SoundCharacteristic[2];    /* modulator frequency multiple...  */\r
+       byte Level[2];                  /* modulator frequency level...     */\r
+       byte AttackDecay[2];            /* modulator attack/decay...        */\r
+       byte SustainRelease[2];         /* modulator sustain/release...     */\r
+       byte WaveSelect[2];             /* output waveform distortion       */\r
+       byte Feedback;                  /* feedback algorithm and strength  */\r
+} FMInstrument;\r
+\r
+void opl2out(word reg, word data);\r
+void opl3out(word reg, word data);\r
+void opl3exp(word data);\r
+\r
+void FMReset(void/*int percusiveMode*/);\r
+void FMKeyOff(int voice);\r
+void FMKeyOn(int voice, int freq, int octave);\r
+void FMSetVoice(int voiceNum, FMInstrument *ins);\r
+\r
+void SD_Initimf(global_game_variables_t *gvar);\r
+void SD_imf_reset_music(global_game_variables_t *gvar);\r
+void   SD_StartupTimer(global_game_variables_t *gvar),\r
+               SD_ShutdownTimer();\r
+void SD_imf_free_music(global_game_variables_t *gvar);\r
+int SD_imf_load_music(const char *path, global_game_variables_t *gvar);\r
+void interrupt SD_irq0(void);\r
+void SD_imf_tick(global_game_variables_t *gvar);\r
+void SD_adlib_shut_up();\r
+\r
+#endif /*__16_SND_H_*/\r
diff --git a/src/lib/id_sd.c b/src/lib/id_sd.c
deleted file mode 100755 (executable)
index 2e8788b..0000000
+++ /dev/null
@@ -1,2311 +0,0 @@
-/* Project 16 Source Code~\r
- * Copyright (C) 2012-2017 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
- *\r
- * This file is part of Project 16.\r
- *\r
- * Project 16 is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 3 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * Project 16 is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
- * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
- * Fifth Floor, Boston, MA 02110-1301 USA.\r
- *\r
- */\r
-\r
-//\r
-//     ID Engine\r
-//     ID_SD.c - Sound Manager for Wolfenstein 3D\r
-//     v1.2w\r
-//     By Jason Blochowiak\r
-//     Open Watcom port by sparky4\r
-//\r
-\r
-//\r
-//     This module handles dealing with generating sound on the appropriate\r
-//             hardware\r
-//\r
-//     Depends on: User Mgr (for parm checking)\r
-//\r
-//     Globals:\r
-//             For User Mgr:\r
-//                     SoundSourcePresent - Sound Source thingie present?\r
-//                     SoundBlasterPresent - SoundBlaster card present?\r
-//                     AdLibPresent - AdLib card present?\r
-//                     SoundMode - What device is used for sound effects\r
-//                             (Use SM_SetSoundMode() to set)\r
-//                     MusicMode - What device is used for music\r
-//                             (Use SM_SetMusicMode() to set)\r
-//                     DigiMode - What device is used for digitized sound effects\r
-//                             (Use SM_SetDigiDevice() to set)\r
-//\r
-//             For Cache Mgr:\r
-//                     NeedsDigitized - load digitized sounds?\r
-//                     NeedsMusic - load music?\r
-//\r
-\r
-#pragma hdrstop                // Wierdo thing with MUSE\r
-\r
-#include <dos.h>\r
-\r
-#ifndef        _MUSE_      // Will be defined in ID_Types.h\r
-#include "src/lib/id_sd.h"\r
-#else\r
-#include "src/lib/16_head.h"\r
-#endif\r
-#pragma        hdrstop\r
-#pragma        warn    -pia\r
-\r
-#define        SDL_SoundFinished()     {SoundNumber = SoundPriority = 0;}\r
-\r
-// Macros for AdLib stuff\r
-#define        selreg(n)       outportb(alFMAddr,n)\r
-#define        writereg(n)     outportb(alFMData,n)\r
-#define        readstat()      inportb(alFMStatus)\r
-\r
-//#define SD_USECATA3DSETTIMERSPEED\r
-\r
-//     Imports from ID_SD_A.ASM\r
-/*extern*/     void                    SDL_SetDS(void);\r
-/*extern*/     void interrupt  SDL_t0ExtremeAsmService(void);//,\r
-//                                     SDL_t0FastAsmService(void),\r
-//                                     SDL_t0SlowAsmService(void);\r
-       void                    SDL_IndicatePC(boolean on),\r
-                                       SDL_DigitizedDoneInIRQ();\r
-\r
-//     Global variables\r
-       boolean         AdLibPresent,\r
-                               NeedsDigitized,NeedsMusic,\r
-                               SoundPositioned;\r
-       SDMode          SoundMode;\r
-       SMMode          MusicMode;\r
-       SDSMode         DigiMode;\r
-       dword   TimeCount;\r
-       word            HackCount;\r
-       word            *SoundTable;    // Really * _seg *SoundTable, but that don't work\r
-       boolean         ssIsTandy;\r
-       int                     DigiMap[LASTSOUND];\r
-\r
-//     Internal variables\r
-static boolean                 SD_Started;\r
-               boolean                 nextsoundpos;\r
-               word/*boolean_+*/                       TimerDone;\r
-               word                    TimerVal,TimerDelay10,TimerDelay25,TimerDelay100;\r
-               dword           TimerDivisor,TimerCount;\r
-static char                    *ParmStrings[] =\r
-                                               {\r
-                                                       "noal",\r
-                                                       nil\r
-                                               };\r
-static void                    (*SoundUserHook)(void);\r
-               soundnames              SoundNumber,DigiNumber;\r
-               word                    SoundPriority,DigiPriority;\r
-               int                             LeftPosition,RightPosition;\r
-               void interrupt  (*t0OldService)(void);\r
-               long                    LocalTime;\r
-               word                    TimerRate;\r
-\r
-               word                    NumDigi,DigiLeft,DigiPage;\r
-               word                    _seg *DigiList;\r
-               word                    DigiLastStart,DigiLastEnd;\r
-               boolean                 DigiPlaying;\r
-static boolean                 DigiMissed,DigiLastSegment;\r
-static memptr                  DigiNextAddr;\r
-static word                    DigiNextLen;\r
-\r
-//     PC Sound variables\r
-               volatile byte   pcLastSample,far *pcSound;\r
-               dword           pcLengthLeft;\r
-               word                    pcSoundLookup[255];\r
-\r
-//     AdLib variables\r
-               boolean                 alNoCheck;\r
-               byte                    far *alSound;\r
-               word                    alBlock;\r
-               dword           alLengthLeft;\r
-               dword           alTimeCount;\r
-               Instrument              alZeroInst;\r
-\r
-// This table maps channel numbers to carrier and modulator op cells\r
-static byte                    carriers[9] =  { 3, 4, 5,11,12,13,19,20,21},\r
-                                               modifiers[9] = { 0, 1, 2, 8, 9,10,16,17,18},\r
-// This table maps percussive voice numbers to op cells\r
-                                               pcarriers[5] = {19,0xff,0xff,0xff,0xff},\r
-                                               pmodifiers[5] = {16,17,18,20,21};\r
-\r
-//     Sequencer variables\r
-               boolean                 sqActive;\r
-static word                    alFXReg;\r
-static ActiveTrack             *tracks[sqMaxTracks];//,\r
-//--                                           mytracks[sqMaxTracks];\r
-//--static     word                    sqMode,sqFadeStep;\r
-               word                    far *sqHack,far *sqHackPtr,sqHackLen,sqHackSeqLen;\r
-               long                    sqHackTime;\r
-\r
-//     Internal routines\r
-               void                    SDL_DigitizedDone(void);\r
-\r
-//Assembly functions\r
-boolean                alNoIRQ;\r
-\r
-int count_time=0;\r
-int count_fx=0;\r
-int extreme=0;\r
-\r
-void SDL_turnOnPCSpeaker(word timerval)\r
-{\r
-       __asm {\r
-               mov     bx,timerval\r
-               mov     al,0b6h\r
-               out     43h,al\r
-               mov     al,bl\r
-               out     42h,al\r
-               mov     al,bh\r
-               out     42h,al\r
-               in      al,61h\r
-               or      al,3\r
-               out     61h,al\r
-       }\r
-}\r
-\r
-void SDL_turnOffPCSpeaker()\r
-{\r
-       __asm {\r
-               in      al,61h\r
-               and     al,0fch\r
-               out     61h,al\r
-       }\r
-}\r
-\r
-void SDL_setPCSpeaker(byte val)\r
-{\r
-       __asm {\r
-               mov     al,val\r
-               in      al,61h\r
-               and     al,0fch\r
-               or      al,ah\r
-               out     61h,al\r
-       }\r
-}\r
-\r
-void SDL_DoFX()\r
-{\r
-       if(pcSound)\r
-       {\r
-               if(*pcSound!=pcLastSample)\r
-               {\r
-                       pcLastSample=*pcSound;\r
-\r
-                       if(pcLastSample)\r
-                               SDL_turnOnPCSpeaker(pcLastSample*60);\r
-                       else\r
-                               SDL_turnOffPCSpeaker();\r
-               }\r
-               pcSound++;\r
-               pcLengthLeft--;\r
-               if(!pcLengthLeft)\r
-               {\r
-                       pcSound=0;\r
-                       SoundNumber=(soundnames)0;\r
-                       SoundPriority=0;\r
-                       SDL_turnOffPCSpeaker();\r
-               }\r
-       }\r
-\r
-       if(alSound && !alNoIRQ)\r
-       {\r
-               if(*alSound)\r
-               {\r
-                       alOut/*InIRQ*/(alFreqL,*alSound);\r
-                       alOut/*InIRQ*/(alFreqH,alBlock);\r
-               }\r
-               else alOut/*InIRQ*/(alFreqH,0);\r
-               alSound++;\r
-               alLengthLeft--;\r
-               if(!alLengthLeft)\r
-               {\r
-                       alSound=0;\r
-                       SoundNumber=(soundnames)0;\r
-                       SoundPriority=0;\r
-                       alOut/*InIRQ*/(alFreqH,0);\r
-               }\r
-       }\r
-\r
-}\r
-\r
-void SDL_DoFast()\r
-{\r
-       count_fx++;\r
-       if(count_fx>=5)\r
-       {\r
-               count_fx=0;\r
-\r
-               SDL_DoFX();\r
-\r
-               count_time++;\r
-               if(count_time>=2)\r
-               {\r
-                       TimeCount++;\r
-                       count_time=0;\r
-               }\r
-       }\r
-\r
-       if(sqActive && !alNoIRQ)\r
-       {\r
-               if(sqHackLen)\r
-               {\r
-                       do\r
-                       {\r
-                               if(sqHackTime>alTimeCount) break;\r
-                               sqHackTime=alTimeCount+*(sqHackPtr+1);\r
-                               alOut/*InIRQ*/(*(byte *)sqHackPtr,*(((byte *)sqHackPtr)+1));\r
-                               sqHackPtr+=2;\r
-                               sqHackLen-=4;\r
-                       }\r
-                       while(sqHackLen);\r
-               }\r
-               alTimeCount++;\r
-               if(!sqHackLen)\r
-               {\r
-                       sqHackPtr=sqHack;\r
-                       sqHackLen=sqHackSeqLen;\r
-                       alTimeCount=0;\r
-                       sqHackTime=0;\r
-               }\r
-       }\r
-\r
-//SS   if(ssSample)\r
-//SS   {\r
-//SS           if(!(inp(ssStatus)&0x40))\r
-//SS           {\r
-//SS                   outp(ssData,*ssSample++);\r
-//SS                   outp(ssControl,ssOff);\r
-//SS                   __asm push ax\r
-//SS                   __asm pop ax\r
-//SS                   outp(ssControl,ssOn);\r
-//SS                   __asm push ax\r
-//SS                   __asm pop ax\r
-//SS                   ssLengthLeft--;\r
-//SS                   if(!ssLengthLeft)\r
-//SS                   {\r
-//SS                           ssSample=0;\r
-//SS                           SDL_DigitizedDoneInIRQ();\r
-//SS                   }\r
-//SS           }\r
-//SS   }\r
-\r
-       TimerCount+=TimerDivisor;\r
-       if(*((word *)&TimerCount+1))\r
-       {\r
-               *((word *)&TimerCount+1)=0;\r
-               t0OldService();\r
-       }\r
-       else\r
-       {\r
-               outp(0x20,0x20);\r
-       }\r
-}\r
-\r
-// Timer 0 ISR for 700Hz interrupts\r
-void interrupt SDL_t0FastAsmService(void)\r
-{\r
-       SDL_DoFast();\r
-}\r
-\r
-// Timer 0 ISR for 140Hz interrupts\r
-void interrupt SDL_t0SlowAsmService(void)\r
-{\r
-       count_time++;\r
-       if(count_time>=2)\r
-       {\r
-               TimeCount++;\r
-               count_time=0;\r
-       }\r
-\r
-       SDL_DoFX();\r
-\r
-       TimerCount+=TimerDivisor;\r
-       if(*((word *)&TimerCount+1))\r
-       {\r
-               *((word *)&TimerCount+1)=0;\r
-               t0OldService();\r
-       }\r
-       else\r
-               outp(0x20,0x20);\r
-}\r
-\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_SetTimer0() - Sets system timer 0 to the specified speed\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-#pragma        argsused\r
-static void\r
-SDL_SetTimer0(word speed)\r
-{\r
-#ifndef TPROF  // If using Borland's profiling, don't screw with the timer\r
-asm    pushf\r
-asm    cli\r
-\r
-       outportb(0x43,0x36);                            // Change timer 0\r
-       outportb(0x40,speed);\r
-       outportb(0x40,speed >> 8);\r
-       // Kludge to handle special case for digitized PC sounds\r
-       if (TimerDivisor == (1192030 / (TickBase * 100)))\r
-               TimerDivisor = (1192030 / (TickBase * 10));\r
-       else\r
-               TimerDivisor = speed;\r
-\r
-asm    popf\r
-#else\r
-       TimerDivisor = 0x10000;\r
-#endif\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_SetIntsPerSec() - Uses SDL_SetTimer0() to set the number of\r
-//             interrupts generated by system timer 0 per second\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_SetIntsPerSec(word ints)\r
-{\r
-       TimerRate = ints;\r
-       SDL_SetTimer0(1192030 / ints);\r
-}\r
-\r
-#ifndef SD_USECATA3DSETTIMERSPEED\r
-static void\r
-SDL_SetTimerSpeed(void)\r
-{\r
-       word    rate;\r
-       void interrupt  (*isr)(void);\r
-\r
-       if ((DigiMode == sds_PC) && DigiPlaying)\r
-       {\r
-               rate = TickBase * 100;\r
-               isr = SDL_t0ExtremeAsmService;\r
-       }\r
-       else if\r
-       (\r
-               (MusicMode == smm_AdLib)\r
-       ||      ((DigiMode == sds_SoundSource) && DigiPlaying)\r
-       )\r
-       {\r
-               rate = TickBase * 10;\r
-               isr = SDL_t0FastAsmService;\r
-       }\r
-       else\r
-       {\r
-               rate = TickBase * 2;\r
-               isr = SDL_t0SlowAsmService;\r
-       }\r
-\r
-       if (rate != TimerRate)\r
-       {\r
-               setvect(8,isr);\r
-               SDL_SetIntsPerSec(rate);\r
-               TimerRate = rate;\r
-       }\r
-}\r
-#else\r
-static void\r
-SDL_SetTimerSpeed(void)\r
-{\r
-       word    rate;\r
-\r
-       if (MusicMode == smm_AdLib)\r
-               rate = TickBase * 8;\r
-       else\r
-               rate = TickBase * 2;\r
-       SDL_SetIntsPerSec(rate);\r
-}\r
-#endif\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_TimingService() - Used by SDL_InitDelay() to determine a timing\r
-//             value for the current system that we're running on\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-//static void interrupt\r
-void interrupt\r
-SDL_TimingService(void)\r
-{\r
-       //TimerVal = _CX;\r
-       __asm {\r
-               mov TimerVal,cx\r
-       }\r
-       TimerDone = 1;\r
-\r
-       outportb(0x20,0x20);                            // Ack interrupt\r
-}\r
-#ifdef SD_USECATA3DSETTIMERSPEED\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_InitDelay() - Sets up TimerDelay's for SDL_Delay()\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_InitDelay(void)\r
-{\r
-       int             i;\r
-       word    timer;\r
-\r
-       setvect(8,SDL_TimingService);           // Set to my timer 0 ISR\r
-\r
-       SDL_SetIntsPerSec(1000);                        // Time 1ms\r
-\r
-       for (i = 0,timer = 0;i < 10;i++)        // Do timing test 10 times\r
-       {\r
-               __asm {\r
-                       xor             dx,dx                                   // Zero DX\r
-                       mov             cx,0xffff                               // Put starting value in CX\r
-                       mov             [TimerDone],cx                  // TimerDone = false - 1\r
-#ifdef __BORLANDC__\r
-               }\r
-#endif\r
-startloop:\r
-#ifdef __BORLANDC__\r
-               __asm {\r
-#endif\r
-                       or              [TimerDone],0\r
-                       jnz             startloop                               // Make sure we're at the start\r
-#ifdef __BORLANDC__\r
-               }\r
-#endif\r
-loop_:\r
-#ifdef __BORLANDC__\r
-               __asm {\r
-#endif\r
-                       test    [TimerDone],1                   // See if TimerDone flag got hit\r
-                       jnz             done                                    // Yep - drop out of the loop\r
-                       loop    loop_\r
-#ifdef __BORLANDC__\r
-               }\r
-#endif\r
-done:\r
-#ifdef __WATCOMC__\r
-       }\r
-#endif\r
-\r
-               if (0xffff - TimerVal > timer)\r
-                       timer = 0xffff - TimerVal;\r
-       }\r
-       timer += timer / 2;                                     // Use some slop\r
-       TimerDelay10 =  timer / (1000 / 10);\r
-       TimerDelay25 =  timer / (1000 / 25);\r
-       TimerDelay100 = timer / (1000 / 100);\r
-\r
-       SDL_SetTimer0(0);                                       // Reset timer 0\r
-\r
-       setvect(8,t0OldService);                        // Set back to old ISR\r
-}\r
-#endif\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_Delay() - Delays the specified amount of time\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_Delay(word delay)\r
-{\r
-       if (!delay)\r
-               return;\r
-\r
-       __asm {\r
-               mov             cx,[delay]\r
-#ifdef __BORLANDC__\r
-       }\r
-#endif\r
-loop_:\r
-#ifdef __BORLANDC__\r
-       __asm {\r
-#endif\r
-               test    [TimerDone],0   // Useless code - just for timing equivilency\r
-               jnz             done\r
-               loop    loop_\r
-#ifdef __BORLANDC__\r
-       }\r
-#endif\r
-done:\r
-#ifdef __WATCOMC__\r
-       }\r
-#endif\r
-}\r
-\r
-//\r
-//     PC Sound code\r
-//\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_PCPlaySample() - Plays the specified sample on the PC speaker\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-#ifdef _MUSE_\r
-void\r
-#else\r
-static void\r
-#endif\r
-SDL_PCPlaySample(byte huge *data,dword len)\r
-{\r
-asm    pushf\r
-asm    cli\r
-\r
-       SDL_IndicatePC(true);\r
-\r
-       pcLengthLeft = len;\r
-       pcSound = (volatile byte far *)data;\r
-\r
-asm    popf\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_PCStopSample() - Stops a sample playing on the PC speaker\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-#ifdef _MUSE_\r
-void\r
-#else\r
-static void\r
-#endif\r
-SDL_PCStopSample(void)\r
-{\r
-asm    pushf\r
-asm    cli\r
-\r
-       /*(long)*/pcSound = 0;\r
-\r
-       SDL_IndicatePC(false);\r
-\r
-asm    in      al,0x61                 // Turn the speaker off\r
-asm    and     al,0xfd                 // ~2\r
-asm    out     0x61,al\r
-\r
-asm    popf\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_PCPlaySound() - Plays the specified sound on the PC speaker\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-#ifdef _MUSE_\r
-void\r
-#else\r
-static void\r
-#endif\r
-SDL_PCPlaySound(PCSound far *sound)\r
-{\r
-asm    pushf\r
-asm    cli\r
-\r
-       pcLastSample = -1;\r
-       pcLengthLeft = sound->common.length;\r
-       pcSound = sound->data;\r
-\r
-asm    popf\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_PCStopSound() - Stops the current sound playing on the PC Speaker\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-#ifdef _MUSE_\r
-void\r
-#else\r
-static void\r
-#endif\r
-SDL_PCStopSound(void)\r
-{\r
-asm    pushf\r
-asm    cli\r
-\r
-       /*(long)*/pcSound = 0;\r
-\r
-asm    in      al,0x61                 // Turn the speaker off\r
-asm    and     al,0xfd                 // ~2\r
-asm    out     0x61,al\r
-\r
-asm    popf\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_PCService() - Handles playing the next sample in a PC sound\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_PCService(void)\r
-{\r
-       byte    s;\r
-       word    t;\r
-\r
-       if (pcSound)\r
-       {\r
-               s = *pcSound++;\r
-               if (s != pcLastSample)\r
-               {\r
-               asm     pushf\r
-               asm     cli\r
-\r
-                       pcLastSample = s;\r
-                       if (s)                                  // We have a frequency!\r
-                       {\r
-                               t = pcSoundLookup[s];\r
-                       asm     mov     bx,[t]\r
-\r
-                       asm     mov     al,0xb6                 // Write to channel 2 (speaker) timer\r
-                       asm     out     43h,al\r
-                       asm     mov     al,bl\r
-                       asm     out     42h,al                  // Low byte\r
-                       asm     mov     al,bh\r
-                       asm     out     42h,al                  // High byte\r
-\r
-                       asm     in      al,0x61                 // Turn the speaker & gate on\r
-                       asm     or      al,3\r
-                       asm     out     0x61,al\r
-                       }\r
-                       else                                    // Time for some silence\r
-                       {\r
-                       asm     in      al,0x61                 // Turn the speaker & gate off\r
-                       asm     and     al,0xfc                 // ~3\r
-                       asm     out     0x61,al\r
-                       }\r
-\r
-               asm     popf\r
-               }\r
-\r
-               if (!(--pcLengthLeft))\r
-               {\r
-                       SDL_PCStopSound();\r
-                       SDL_SoundFinished();\r
-               }\r
-       }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_ShutPC() - Turns off the pc speaker\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_ShutPC(void)\r
-{\r
-asm    pushf\r
-asm    cli\r
-\r
-       pcSound = 0;\r
-\r
-asm    in      al,0x61                 // Turn the speaker & gate off\r
-asm    and     al,0xfc                 // ~3\r
-asm    out     0x61,al\r
-\r
-asm    popf\r
-}\r
-\r
-//\r
-//     Stuff for digitized sounds\r
-//\r
-memptr\r
-SDL_LoadDigiSegment(word page, global_game_variables_t *gvar)\r
-{\r
-       memptr  addr;\r
-\r
-#if 0  // for debugging\r
-asm    mov     dx,STATUS_REGISTER_1\r
-asm    in      al,dx\r
-asm    mov     dx,ATR_INDEX\r
-asm    mov     al,ATR_OVERSCAN\r
-asm    out     dx,al\r
-asm    mov     al,10   // bright green\r
-asm    out     dx,al\r
-#endif\r
-\r
-       addr = PM_GetSoundPage(page);\r
-       PM_SetPageLock(gvar->pm.fi.PMSoundStart + page,pml_Locked, gvar);\r
-\r
-#if 0  // for debugging\r
-asm    mov     dx,STATUS_REGISTER_1\r
-asm    in      al,dx\r
-asm    mov     dx,ATR_INDEX\r
-asm    mov     al,ATR_OVERSCAN\r
-asm    out     dx,al\r
-asm    mov     al,3    // blue\r
-asm    out     dx,al\r
-asm    mov     al,0x20 // normal\r
-asm    out     dx,al\r
-#endif\r
-\r
-       return(addr);\r
-}\r
-\r
-void\r
-SDL_PlayDigiSegment(memptr addr,word len)\r
-{\r
-       switch (DigiMode)\r
-       {\r
-       case sds_PC:\r
-       SDL_PCPlaySample(addr,len);\r
-               break;\r
-//SS   case sds_SoundSource:\r
-//SS           SDL_SSPlaySample(addr,len);\r
-//SS           break;\r
-//SB   case sds_SoundBlaster:\r
-//SB           SDL_SBPlaySample(addr,len);\r
-//SB           break;\r
-       }\r
-}\r
-\r
-void\r
-SD_StopDigitized(global_game_variables_t *gvar)\r
-{\r
-       int     i;\r
-\r
-asm    pushf\r
-asm    cli\r
-\r
-       DigiLeft = 0;\r
-       DigiNextAddr = nil;\r
-       DigiNextLen = 0;\r
-       DigiMissed = false;\r
-       DigiPlaying = false;\r
-       DigiNumber = DigiPriority = 0;\r
-       SoundPositioned = false;\r
-       if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
-               SDL_SoundFinished();\r
-\r
-       switch (DigiMode)\r
-       {\r
-       case sds_PC:\r
-               SDL_PCStopSample();\r
-               break;\r
-//SS   case sds_SoundSource:\r
-//SS           SDL_SSStopSample();\r
-//SS           break;\r
-//SB   case sds_SoundBlaster:\r
-//SB           SDL_SBStopSample();\r
-//SB           break;\r
-       }\r
-\r
-asm    popf\r
-\r
-       for (i = DigiLastStart;i < DigiLastEnd;i++)\r
-               PM_SetPageLock(i + gvar->pm.fi.PMSoundStart,pml_Unlocked, gvar);\r
-       DigiLastStart = 1;\r
-       DigiLastEnd = 0;\r
-}\r
-\r
-void\r
-SD_Poll(global_game_variables_t *gvar)\r
-{\r
-       if (DigiLeft && !DigiNextAddr)\r
-       {\r
-               DigiNextLen = (DigiLeft >= PMPageSize)? PMPageSize : (DigiLeft % PMPageSize);\r
-               DigiLeft -= DigiNextLen;\r
-               if (!DigiLeft)\r
-                       DigiLastSegment = true;\r
-               DigiNextAddr = SDL_LoadDigiSegment(DigiPage++, gvar);\r
-       }\r
-       if (DigiMissed && DigiNextAddr)\r
-       {\r
-               SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen);\r
-               DigiNextAddr = nil;\r
-               DigiMissed = false;\r
-               if (DigiLastSegment)\r
-               {\r
-                       DigiPlaying = false;\r
-                       DigiLastSegment = false;\r
-               }\r
-       }\r
-       SDL_SetTimerSpeed();\r
-}\r
-\r
-void\r
-SD_SetPosition(int leftpos,int rightpos, global_game_variables_t *gvar)\r
-{\r
-       if\r
-       (\r
-               (leftpos < 0)\r
-       ||      (leftpos > 15)\r
-       ||      (rightpos < 0)\r
-       ||      (rightpos > 15)\r
-       ||      ((leftpos == 15) && (rightpos == 15))\r
-       )\r
-               Quit(gvar, "SD_SetPosition: Illegal position");\r
-\r
-       switch (DigiMode)\r
-       {\r
-//SB   case sds_SoundBlaster:\r
-//SB           SDL_PositionSBP(leftpos,rightpos);\r
-//SB           break;\r
-       }\r
-}\r
-\r
-void\r
-SD_PlayDigitized(word which,int leftpos,int rightpos, global_game_variables_t *gvar)\r
-{\r
-       word    len;\r
-       memptr  addr;\r
-\r
-       if (!DigiMode)\r
-               return;\r
-\r
-       SD_StopDigitized(gvar);\r
-       if (which >= NumDigi)\r
-               Quit(gvar, "SD_PlayDigitized: bad sound number");\r
-\r
-       SD_SetPosition(leftpos,rightpos, gvar);\r
-\r
-       DigiPage = DigiList[(which * 2) + 0];\r
-       DigiLeft = DigiList[(which * 2) + 1];\r
-\r
-       DigiLastStart = DigiPage;\r
-       DigiLastEnd = DigiPage + ((DigiLeft + (PMPageSize - 1)) / PMPageSize);\r
-\r
-       len = (DigiLeft >= PMPageSize)? PMPageSize : (DigiLeft % PMPageSize);\r
-       addr = SDL_LoadDigiSegment(DigiPage++, gvar);\r
-\r
-       DigiPlaying = true;\r
-       DigiLastSegment = false;\r
-\r
-       SDL_PlayDigiSegment(addr,len);\r
-       DigiLeft -= len;\r
-       if (!DigiLeft)\r
-               DigiLastSegment = true;\r
-\r
-       SD_Poll(gvar);\r
-}\r
-\r
-void\r
-SDL_DigitizedDone(void)\r
-{\r
-       if (DigiNextAddr)\r
-       {\r
-               SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen);\r
-               DigiNextAddr = nil;\r
-               DigiMissed = false;\r
-       }\r
-       else\r
-       {\r
-               if (DigiLastSegment)\r
-               {\r
-                       DigiPlaying = false;\r
-                       DigiLastSegment = false;\r
-                       if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
-                       {\r
-                               SDL_SoundFinished();\r
-                       }\r
-                       else\r
-                               DigiNumber = DigiPriority = 0;\r
-                       SoundPositioned = false;\r
-               }\r
-               else\r
-                       DigiMissed = true;\r
-       }\r
-}\r
-\r
-void\r
-SD_SetDigiDevice(SDSMode mode, global_game_variables_t *gvar)\r
-{\r
-       boolean devicenotpresent;\r
-\r
-       if (mode == DigiMode)\r
-               return;\r
-\r
-       SD_StopDigitized(gvar);\r
-\r
-       devicenotpresent = false;\r
-       switch (mode)\r
-       {\r
-       case sds_SoundBlaster:\r
-               if (!SoundBlasterPresent)\r
-               {\r
-                       if (SoundSourcePresent)\r
-                               mode = sds_SoundSource;\r
-                       else\r
-                               devicenotpresent = true;\r
-               }\r
-               break;\r
-       case sds_SoundSource:\r
-               if (!SoundSourcePresent)\r
-                       devicenotpresent = true;\r
-               break;\r
-       }\r
-\r
-       if (!devicenotpresent)\r
-       {\r
-//SS           if (DigiMode == sds_SoundSource)\r
-//SS                   SDL_ShutSS();\r
-\r
-               DigiMode = mode;\r
-\r
-//SS           if (mode == sds_SoundSource)\r
-//SS                   SDL_StartSS();\r
-\r
-               SDL_SetTimerSpeed();\r
-       }\r
-}\r
-\r
-void\r
-SDL_SetupDigi(global_game_variables_t *gvar)\r
-{\r
-       memptr  list;\r
-       word    far *p,\r
-                       pg;\r
-       int             i;\r
-\r
-       PM_UnlockMainMem(gvar);\r
-       MM_GetPtr(&list,PMPageSize, gvar);\r
-       PM_CheckMainMem(gvar);\r
-       p = (word far *)MK_FP(PM_GetPage(gvar->pm.fi.ChunksInFile - 1, gvar),0);\r
-       _fmemcpy((void far *)list,(void far *)p,PMPageSize);\r
-       pg = gvar->pm.fi.PMSoundStart;\r
-       for (i = 0;i < PMPageSize / (sizeof(word) * 2);i++,p += 2)\r
-       {\r
-               if (pg >= gvar->pm.fi.ChunksInFile - 1)\r
-                       break;\r
-               pg += (p[1] + (PMPageSize - 1)) / PMPageSize;\r
-       }\r
-       PM_UnlockMainMem(gvar);\r
-       MM_GetPtr(MEMPTRCONV DigiList,i * sizeof(word) * 2, gvar);\r
-       _fmemcpy((void far *)DigiList,(void far *)list,i * sizeof(word) * 2);\r
-       MM_FreePtr(&list, gvar);\r
-       NumDigi = i;\r
-\r
-       for (i = 0;i < LASTSOUND;i++)\r
-               DigiMap[i] = -1;\r
-}\r
-\r
-//     AdLib Code\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     alOut(n,b) - Puts b in AdLib card register n\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-alOut(byte n,byte b)\r
-{\r
-asm    pushf\r
-asm    cli\r
-\r
-asm    mov             dx,0x388\r
-asm    mov             al,[n]\r
-asm    out             dx,al\r
-#if 0\r
-       SDL_Delay(TimerDelay10);\r
-#else\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-#endif\r
-\r
-asm    mov             dx,0x389\r
-asm    mov             al,[b]\r
-asm    out             dx,al\r
-\r
-asm    popf\r
-\r
-#if 0\r
-       SDL_Delay(TimerDelay25);\r
-#else\r
-asm    mov     dx,0x388\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-asm    in      al, dx\r
-#endif\r
-}\r
-\r
-//#if 0\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_SetInstrument() - Puts an instrument into a generator\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-//static void\r
-void\r
-SDL_SetInstrument(int track,int which,Instrument far *inst,boolean percussive)\r
-{\r
-       byte            c,m;\r
-\r
-       if (percussive)\r
-       {\r
-               c = pcarriers[which];\r
-               m = pmodifiers[which];\r
-       }\r
-       else\r
-       {\r
-               c = carriers[which];\r
-               m = modifiers[which];\r
-       }\r
-\r
-       tracks[track - 1]->inst = *inst;\r
-       tracks[track - 1]->percussive = percussive;\r
-\r
-       alOut(m + alChar,inst->mChar);\r
-       alOut(m + alScale,inst->mScale);\r
-       alOut(m + alAttack,inst->mAttack);\r
-       alOut(m + alSus,inst->mSus);\r
-       alOut(m + alWave,inst->mWave);\r
-\r
-       // Most percussive instruments only use one cell\r
-       if (c != 0xff)\r
-       {\r
-               alOut(c + alChar,inst->cChar);\r
-               alOut(c + alScale,inst->cScale);\r
-               alOut(c + alAttack,inst->cAttack);\r
-               alOut(c + alSus,inst->cSus);\r
-               alOut(c + alWave,inst->cWave);\r
-       }\r
-\r
-       alOut(which + alFeedCon,inst->nConn);   // DEBUG - I think this is right\r
-}\r
-//#endif\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_ALStopSound() - Turns off any sound effects playing through the\r
-//             AdLib card\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-#ifdef _MUSE_\r
-void\r
-#else\r
-static void\r
-#endif\r
-SDL_ALStopSound(void)\r
-{\r
-asm    pushf\r
-asm    cli\r
-\r
-       /*(long)*/alSound = 0;\r
-       alOut(alFreqH + 0,0);\r
-\r
-asm    popf\r
-}\r
-\r
-static void\r
-SDL_AlSetFXInst(Instrument far *inst)\r
-{\r
-       byte            c,m;\r
-\r
-       m = modifiers[0];\r
-       c = carriers[0];\r
-       alOut(m + alChar,inst->mChar);\r
-       alOut(m + alScale,inst->mScale);\r
-       alOut(m + alAttack,inst->mAttack);\r
-       alOut(m + alSus,inst->mSus);\r
-       alOut(m + alWave,inst->mWave);\r
-       alOut(c + alChar,inst->cChar);\r
-       alOut(c + alScale,inst->cScale);\r
-       alOut(c + alAttack,inst->cAttack);\r
-       alOut(c + alSus,inst->cSus);\r
-       alOut(c + alWave,inst->cWave);\r
-\r
-       // Note: Switch commenting on these lines for old MUSE compatibility\r
-//     alOut(alFeedCon,inst->nConn);\r
-       alOut(alFeedCon,0);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_ALPlaySound() - Plays the specified sound on the AdLib card\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-#ifdef _MUSE_\r
-void\r
-#else\r
-static void\r
-#endif\r
-SDL_ALPlaySound(AdLibSound far *sound, global_game_variables_t *gvar)\r
-{\r
-       Instrument      __far *inst;\r
-       byte            huge *data;\r
-\r
-       SDL_ALStopSound();\r
-\r
-asm    pushf\r
-asm    cli\r
-\r
-       alLengthLeft = sound->common.length;\r
-       data = sound->data;\r
-       data++;\r
-       data--;\r
-       alSound = (byte far *)data;\r
-       alBlock = ((sound->block & 7) << 2) | 0x20;\r
-       inst = &sound->inst;\r
-\r
-       if (!(inst->mSus | inst->cSus))\r
-       {\r
-       asm     popf\r
-               Quit(gvar, "SDL_ALPlaySound() - Bad instrument");\r
-       }\r
-\r
-       SDL_AlSetFXInst(&alZeroInst);   // DEBUG\r
-       SDL_AlSetFXInst(inst);\r
-\r
-asm    popf\r
-}\r
-\r
-//#if 0\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_ALSoundService() - Plays the next sample out through the AdLib card\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-//static void\r
-void\r
-SDL_ALSoundService(void)\r
-{\r
-       byte    s;\r
-\r
-       if (alSound)\r
-       {\r
-               s = *alSound++;\r
-               if (!s)\r
-                       alOut(alFreqH + 0,0);\r
-               else\r
-               {\r
-                       alOut(alFreqL + 0,s);\r
-                       alOut(alFreqH + 0,alBlock);\r
-               }\r
-\r
-               if (!(--alLengthLeft))\r
-               {\r
-                       /*(long)*/alSound = 0;\r
-                       alOut(alFreqH + 0,0);\r
-                       SDL_SoundFinished();\r
-               }\r
-       }\r
-}\r
-//#endif\r
-\r
-#if 0\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_SelectMeasure() - sets up sequencing variables for a given track\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SDL_SelectMeasure(ActiveTrack *track)\r
-{\r
-       track->seq = track->moods[track->mood];\r
-       track->nextevent = 0;\r
-}\r
-#endif\r
-\r
-//#if 0\r
-void\r
-SDL_ALService(void)\r
-{\r
-       byte    a,v;\r
-       word    w;\r
-\r
-       a=v=0;\r
-\r
-       if (!sqActive)\r
-               return;\r
-\r
-       while (sqHackLen && (sqHackTime <= alTimeCount))\r
-       {\r
-               w = *sqHackPtr++;\r
-               sqHackTime = alTimeCount + *sqHackPtr++;\r
-       asm     mov     dx,[w]\r
-       asm     mov     [a],dl\r
-       asm     mov     [v],dh\r
-               alOut(a,v);\r
-               sqHackLen -= 4;\r
-       }\r
-       alTimeCount++;\r
-       if (!sqHackLen)\r
-       {\r
-               sqHackPtr = (word far *)sqHack;\r
-               sqHackLen = sqHackSeqLen;\r
-               alTimeCount = sqHackTime = 0;\r
-       }\r
-}\r
-//#endif\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_ShutAL() - Shuts down the AdLib card for sound effects\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_ShutAL(void)\r
-{\r
-asm    pushf\r
-asm    cli\r
-\r
-       alOut(alEffects,0);\r
-       alOut(alFreqH + 0,0);\r
-       SDL_AlSetFXInst(&alZeroInst);\r
-       alSound = 0;\r
-\r
-asm    popf\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_CleanAL() - Totally shuts down the AdLib card\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_CleanAL(void)\r
-{\r
-       int     i;\r
-\r
-asm    pushf\r
-asm    cli\r
-\r
-       alOut(alEffects,0);\r
-       for (i = 1;i < 0xf5;i++)\r
-               alOut(i,0);\r
-\r
-asm    popf\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_StartAL() - Starts up the AdLib card for sound effects\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_StartAL(void)\r
-{\r
-       alFXReg = 0;\r
-       alOut(alEffects,alFXReg);\r
-       SDL_AlSetFXInst(&alZeroInst);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_DetectAdLib() - Determines if there's an AdLib (or SoundBlaster\r
-//             emulating an AdLib) present\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-SDL_DetectAdLib(void)\r
-{\r
-       byte    status1,status2;\r
-       int             i;\r
-\r
-       alOut(4,0x60);  // Reset T1 & T2\r
-       alOut(4,0x80);  // Reset IRQ\r
-       status1 = readstat();\r
-       alOut(2,0xff);  // Set timer 1\r
-       alOut(4,0x21);  // Start timer 1\r
-       SDL_Delay(TimerDelay100);\r
-\r
-#if 0\r
-       __asm {\r
-               mov     dx,0x388\r
-               mov     cx,100\r
-#ifdef __BORLANDC__\r
-       }\r
-#endif\r
-usecloop:\r
-#ifdef __BORLANDC__\r
-       __asm {\r
-#endif\r
-       in      al,dx\r
-       loop usecloop\r
-       }\r
-#endif\r
-\r
-       status2 = readstat();\r
-       alOut(4,0x60);\r
-       alOut(4,0x80);\r
-\r
-       if (((status1 & 0xe0) == 0x00) && ((status2 & 0xe0) == 0xc0))\r
-       {\r
-               for (i = 1;i <= 0xf5;i++)       // Zero all the registers\r
-                       alOut(i,0);\r
-\r
-               alOut(1,0x20);  // Set WSE=1\r
-               alOut(8,0);             // Set CSM=0 & SEL=0\r
-\r
-               return(true);\r
-       }\r
-       else\r
-               return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_t0Service() - My timer 0 ISR which handles the different timings and\r
-//             dispatches to whatever other routines are appropriate\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-//static void interrupt\r
-void interrupt\r
-SDL_t0Service(void)\r
-{\r
-static word    count = 1;\r
-       boolean myackflag = 0;\r
-\r
-//00#if 0      // for debugging\r
-asm    mov     dx,STATUS_REGISTER_1\r
-asm    in      al,dx\r
-asm    mov     dx,ATR_INDEX\r
-asm    mov     al,ATR_OVERSCAN\r
-asm    out     dx,al\r
-asm    mov     al,4    // red\r
-asm    out     dx,al\r
-//00#endif\r
-\r
-       HackCount++;\r
-\r
-       if ((MusicMode == smm_AdLib) || (DigiMode == sds_SoundSource))\r
-       {\r
-               SDL_ALService();\r
-//SS           SDL_SSService();\r
-//             if (!(++count & 7))\r
-               if (!(++count % 10))\r
-               {\r
-                       LocalTime++;\r
-                       TimeCount++;\r
-                       if (SoundUserHook)\r
-                               SoundUserHook();\r
-               }\r
-//             if (!(count & 3))\r
-               if (!(count % 5))\r
-               {\r
-                       switch (SoundMode)\r
-                       {\r
-                       case sdm_PC:\r
-                               SDL_PCService();\r
-                               break;\r
-                       case sdm_AdLib:\r
-                               SDL_ALSoundService();\r
-                               break;\r
-                       }\r
-               }\r
-       }\r
-       else\r
-       {\r
-               if (!(++count & 1))\r
-               {\r
-                       LocalTime++;\r
-                       TimeCount++;\r
-                       if (SoundUserHook)\r
-                               SoundUserHook();\r
-               }\r
-               switch (SoundMode)\r
-               {\r
-               case sdm_PC:\r
-                       SDL_PCService();\r
-                       break;\r
-               case sdm_AdLib:\r
-                       SDL_ALSoundService();\r
-                       break;\r
-               }\r
-       }\r
-\r
-       __asm {\r
-               mov     ax,[WORD PTR TimerCount]\r
-               add     ax,[WORD PTR TimerDivisor]\r
-               mov     [WORD PTR TimerCount],ax\r
-               jnc     myack\r
-               jmp end1\r
-#ifdef __BORLANDC__\r
-       }\r
-#endif\r
-myack:\r
-#ifdef __BORLANDC__\r
-       __asm {\r
-#endif\r
-               mov     myackflag,1\r
-#ifdef __BORLANDC__\r
-       }\r
-#endif\r
-end1:\r
-#ifdef __WATCOMC__\r
-       }\r
-#endif\r
-       if(!myackflag)\r
-               t0OldService();                 // If we overflow a word, time to call old int handler\r
-       else\r
-               outportb(0x20,0x20);    // Ack the interrupt\r
-\r
-//00#if 0      // for debugging\r
-asm    mov     dx,STATUS_REGISTER_1\r
-asm    in      al,dx\r
-asm    mov     dx,ATR_INDEX\r
-asm    mov     al,ATR_OVERSCAN\r
-asm    out     dx,al\r
-asm    mov     al,3    // blue\r
-asm    out     dx,al\r
-asm    mov     al,0x20 // normal\r
-asm    out     dx,al\r
-//00#endif\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_ShutDevice() - turns off whatever device was being used for sound fx\r
-//\r
-////////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_ShutDevice(void)\r
-{\r
-       switch (SoundMode)\r
-       {\r
-       case sdm_PC:\r
-               SDL_ShutPC();\r
-               break;\r
-       case sdm_AdLib:\r
-               SDL_ShutAL();\r
-               break;\r
-       }\r
-       SoundMode = sdm_Off;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_CleanDevice() - totally shuts down all sound devices\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_CleanDevice(void)\r
-{\r
-       if ((SoundMode == sdm_AdLib) || (MusicMode == smm_AdLib))\r
-               SDL_CleanAL();\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SDL_StartDevice() - turns on whatever device is to be used for sound fx\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_StartDevice(void)\r
-{\r
-       switch (SoundMode)\r
-       {\r
-       case sdm_AdLib:\r
-               SDL_StartAL();\r
-               break;\r
-       }\r
-       SoundNumber = SoundPriority = 0;\r
-}\r
-#if 0\r
-static void\r
-SDL_SetTimerSpeed(void)\r
-{\r
-       word    rate;\r
-\r
-       if (MusicMode == smm_AdLib)\r
-               rate = TickBase * 8;\r
-       else\r
-               rate = TickBase * 2;\r
-       SDL_SetIntsPerSec(rate);\r
-}\r
-#endif\r
-//     Public routines\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_SetSoundMode() - Sets which sound hardware to use for sound effects\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-boolean\r
-SD_SetSoundMode(SDMode mode, global_game_variables_t *gvar)\r
-{\r
-       boolean result = false;\r
-       word    tableoffset;\r
-\r
-       SD_StopSound(gvar);\r
-\r
-#ifndef        _MUSE_\r
-       if ((mode == sdm_AdLib) && !AdLibPresent)\r
-               mode = sdm_PC;\r
-\r
-       switch (mode)\r
-       {\r
-       case sdm_Off:\r
-               NeedsDigitized = false;\r
-               result = true;\r
-               break;\r
-       case sdm_PC:\r
-               tableoffset = STARTPCSOUNDS;\r
-               NeedsDigitized = false;\r
-               result = true;\r
-               break;\r
-       case sdm_AdLib:\r
-               if (AdLibPresent)\r
-               {\r
-                       tableoffset = STARTADLIBSOUNDS;\r
-                       NeedsDigitized = false;\r
-                       result = true;\r
-               }\r
-               break;\r
-       }\r
-#else\r
-       result = true;\r
-#endif\r
-\r
-       if (result && (mode != SoundMode))\r
-       {\r
-               SDL_ShutDevice();\r
-               SoundMode = mode;\r
-#ifndef        _MUSE_\r
-               SoundTable = (word *)(&gvar->ca.audiosegs[tableoffset]);\r
-#endif\r
-               SDL_StartDevice();\r
-       }\r
-\r
-       SDL_SetTimerSpeed();\r
-\r
-       return(result);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_SetMusicMode() - sets the device to use for background music\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-boolean\r
-SD_SetMusicMode(SMMode mode)\r
-{\r
-       boolean result = false;\r
-\r
-       SD_FadeOutMusic();\r
-       while (SD_MusicPlaying())\r
-               ;\r
-\r
-       switch (mode)\r
-       {\r
-       case smm_Off:\r
-               NeedsMusic = false;\r
-               result = true;\r
-               break;\r
-       case smm_AdLib:\r
-               if (AdLibPresent)\r
-               {\r
-                       NeedsMusic = true;\r
-                       result = true;\r
-               }\r
-               break;\r
-       }\r
-\r
-       if (result)\r
-               MusicMode = mode;\r
-\r
-       SDL_SetTimerSpeed();\r
-\r
-       return(result);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_Startup() - starts up the Sound Mgr\r
-//             Detects all additional sound hardware and installs my ISR\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SD_Startup(global_game_variables_t *gvar)\r
-{\r
-       int     i;\r
-\r
-       if (SD_Started)\r
-               return;\r
-#ifndef SD_USECATA3DSETTIMERSPEED\r
-       SDL_SetDS();\r
-#endif\r
-       ssIsTandy = false;\r
-//SS   ssNoCheck = false;\r
-       alNoCheck = false;\r
-//SB   sbNoCheck = false;\r
-//SB   sbNoProCheck = false;\r
-#ifndef        _MUSE_\r
-       for (i = 1;i < _argc;i++)\r
-       {\r
-               switch (US_CheckParm(_argv[i],ParmStrings))\r
-               {\r
-               case 0:                                         // No AdLib detection\r
-                       alNoCheck = true;\r
-                       break;\r
-//SB           case 1:                                         // No SoundBlaster detection\r
-//SB                   sbNoCheck = true;\r
-//SB                   break;\r
-//SB           case 2:                                         // No SoundBlaster Pro detection\r
-//SB                   sbNoProCheck = true;\r
-//SB                   break;\r
-//SS           case 3:\r
-//SS                   ssNoCheck = true;               // No Sound Source detection\r
-//SS                   break;\r
-               case 4:                                         // Tandy Sound Source handling\r
-                       ssIsTandy = true;\r
-                       break;\r
-//SS           case 5:                                         // Sound Source present at LPT1\r
-//SS                   ssPort = 1;\r
-//SS                   ssNoCheck = SoundSourcePresent = true;\r
-//SS                   break;\r
-//SS           case 6:                     // Sound Source present at LPT2\r
-//SS                   ssPort = 2;\r
-//SS                   ssNoCheck = SoundSourcePresent = true;\r
-//SS                   break;\r
-//SS           case 7:                     // Sound Source present at LPT3\r
-//SS                   ssPort = 3;\r
-//SS                   ssNoCheck = SoundSourcePresent = true;\r
-//SS                   break;\r
-               }\r
-       }\r
-#endif\r
-\r
-       SoundUserHook = 0;\r
-\r
-       t0OldService = getvect(8);      // Get old timer 0 ISR\r
-#ifdef SD_USECATA3DSETTIMERSPEED\r
-       SDL_InitDelay();                        // SDL_InitDelay() uses t0OldService\r
-\r
-       setvect(8,SDL_t0Service);       // Set to my timer 0 ISR\r
-#endif\r
-       LocalTime = TimeCount = alTimeCount = 0;\r
-\r
-       SD_SetSoundMode(sdm_Off, gvar);\r
-       SD_SetMusicMode(smm_Off);\r
-\r
-//SS   if (!ssNoCheck)\r
-//SS           SoundSourcePresent = SDL_DetectSoundSource();\r
-\r
-       if (!alNoCheck)\r
-       {\r
-               AdLibPresent = SDL_DetectAdLib();\r
-//SB           if (AdLibPresent) && !sbNoCheck)\r
-//SB           {\r
-//SB                   int port = -1;\r
-//SB                   char *env = getenv("BLASTER");\r
-//SB                   if (env)\r
-//SB                   {\r
-//SB                           long temp;\r
-//SB                           while (*env)\r
-//SB                           {\r
-//SB                                   while (isspace(*env))\r
-//SB                                           env++;\r
-//SB\r
-//SB                                   switch (toupper(*env))\r
-//SB                                   {\r
-//SB                                   case 'A':\r
-//SB                                           temp = strtol(env + 1,&env,16);\r
-//SB                                           if\r
-//SB                                           (\r
-//SB                                                   (temp >= 0x210)\r
-//SB                                           &&      (temp <= 0x260)\r
-//SB                                           &&      (!(temp & 0x00f))\r
-//SB                                           )\r
-//SB                                                   port = (temp - 0x200) >> 4;\r
-//SB                                           else\r
-//SB                                                   Quit(gvar, "SD_Startup: Unsupported address value in BLASTER");\r
-//SB                                           break;\r
-//SB                                   case 'I':\r
-//SB                                           temp = strtol(env + 1,&env,10);\r
-//SB                                           if\r
-//SB                                           (\r
-//SB                                                   (temp >= 0)\r
-//SB                                           &&      (temp <= 10)\r
-//SB                                           &&      (sbIntVectors[temp] != -1)\r
-//SB                                           )\r
-//SB                                           {\r
-//SB                                                   sbInterrupt = temp;\r
-//SB                                                   sbIntVec = sbIntVectors[sbInterrupt];\r
-//SB                                           }\r
-//SB                                           else\r
-//SB                                                   Quit(gvar, "SD_Startup: Unsupported interrupt value in BLASTER");\r
-//SB                                           break;\r
-//SB                                   case 'D':\r
-//SB                                           temp = strtol(env + 1,&env,10);\r
-//SB                                           if ((temp == 0) || (temp == 1) || (temp == 3))\r
-//SB                                                   SDL_SBSetDMA(temp);\r
-//SB                                           else\r
-//SB                                                   Quit(gvar, "SD_Startup: Unsupported DMA value in BLASTER");\r
-//SB                                           break;\r
-//SB                                   default:\r
-//SB                                           while (isspace(*env))\r
-//SB                                                   env++;\r
-//SB                                           while (*env && !isspace(*env))\r
-//SB                                                   env++;\r
-//SB                                           break;\r
-//SB                                   }\r
-//SB                           }\r
-//SB                   }\r
-//SB                   SoundBlasterPresent = SDL_DetectSoundBlaster(port);\r
-//SB           }\r
-       }\r
-\r
-       for (i = 0;i < 255;i++)\r
-               pcSoundLookup[i] = i * 60;\r
-\r
-//SB   if (SoundBlasterPresent)\r
-//SB           SDL_StartSB();\r
-\r
-       SDL_SetupDigi(gvar);\r
-\r
-       SD_Started = true;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_Default() - Sets up the default behaviour for the Sound Mgr whether\r
-//             the config file was present or not.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SD_Default(boolean gotit,SDMode sd,SMMode sm, global_game_variables_t *gvar)\r
-{\r
-       boolean gotsd,gotsm;\r
-\r
-       gotsd = gotsm = gotit;\r
-\r
-       if (gotsd)      // Make sure requested sound hardware is available\r
-       {\r
-               switch (sd)\r
-               {\r
-               case sdm_AdLib:\r
-                       gotsd = AdLibPresent;\r
-                       break;\r
-               }\r
-       }\r
-       if (!gotsd)\r
-       {\r
-               if (AdLibPresent)\r
-                       sd = sdm_AdLib;\r
-               else\r
-                       sd = sdm_PC;\r
-       }\r
-       if (sd != SoundMode)\r
-               SD_SetSoundMode(sd, gvar);\r
-\r
-\r
-       if (gotsm)      // Make sure requested music hardware is available\r
-       {\r
-               switch (sm)\r
-               {\r
-               case sdm_AdLib:\r
-                       gotsm = AdLibPresent;\r
-                       break;\r
-               }\r
-       }\r
-       if (!gotsm)\r
-       {\r
-               if (AdLibPresent)\r
-                       sm = smm_AdLib;\r
-       }\r
-       if (sm != MusicMode)\r
-               SD_SetMusicMode(sm);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_Shutdown() - shuts down the Sound Mgr\r
-//             Removes sound ISR and turns off whatever sound hardware was active\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SD_Shutdown(global_game_variables_t *gvar)\r
-{\r
-       if (!SD_Started)\r
-               return;\r
-\r
-       SD_MusicOff();\r
-       SD_StopSound(gvar);\r
-       SDL_ShutDevice();\r
-       SDL_CleanDevice();\r
-\r
-//SB   if (SoundBlasterPresent)\r
-//SB           SDL_ShutSB();\r
-\r
-//SS   if (SoundSourcePresent)\r
-//SS           SDL_ShutSS();\r
-\r
-       asm     pushf\r
-       asm     cli\r
-\r
-       SDL_SetTimer0(0);\r
-\r
-       setvect(8,t0OldService);\r
-\r
-       asm     popf\r
-\r
-       SD_Started = false;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_SetUserHook() - sets the routine that the Sound Mgr calls every 1/70th\r
-//             of a second from its timer 0 ISR\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SD_SetUserHook(void (* hook)(void))\r
-{\r
-       SoundUserHook = hook;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_PositionSound() - Sets up a stereo imaging location for the next\r
-//             sound to be played. Each channel ranges from 0 to 15.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SD_PositionSound(int leftvol,int rightvol)\r
-{\r
-       LeftPosition = leftvol;\r
-       RightPosition = rightvol;\r
-       nextsoundpos = true;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_PlaySound() - plays the specified sound on the appropriate hardware\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-boolean\r
-SD_PlaySound(soundnames sound, global_game_variables_t *gvar)\r
-{\r
-       boolean         ispos;\r
-       SoundCommon     far *s;\r
-       int     lp,rp;\r
-\r
-       lp = LeftPosition;\r
-       rp = RightPosition;\r
-       LeftPosition = 0;\r
-       RightPosition = 0;\r
-\r
-       ispos = nextsoundpos;\r
-       nextsoundpos = false;\r
-\r
-       if (sound == -1)\r
-               return(false);\r
-\r
-       s = MK_FP(SoundTable[sound],0);\r
-       if ((SoundMode != sdm_Off) && !s)\r
-               Quit(gvar, "SD_PlaySound() - Uncached sound");\r
-\r
-       if ((DigiMode != sds_Off) && (DigiMap[sound] != -1))\r
-       {\r
-               if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
-               {\r
-                       if (s->priority < SoundPriority)\r
-                               return(false);\r
-\r
-                       SDL_PCStopSound();\r
-\r
-                       SD_PlayDigitized(DigiMap[sound],lp,rp, gvar);\r
-                       SoundPositioned = ispos;\r
-                       SoundNumber = sound;\r
-                       SoundPriority = s->priority;\r
-               }\r
-               else\r
-               {\r
-               asm     pushf\r
-               asm     cli\r
-                       if (DigiPriority && !DigiNumber)\r
-                       {\r
-                       asm     popf\r
-                               Quit(gvar, "SD_PlaySound: Priority without a sound");\r
-                       }\r
-               asm     popf\r
-\r
-                       if (s->priority < DigiPriority)\r
-                               return(false);\r
-\r
-                       SD_PlayDigitized(DigiMap[sound],lp,rp, gvar);\r
-                       SoundPositioned = ispos;\r
-                       DigiNumber = sound;\r
-                       DigiPriority = s->priority;\r
-               }\r
-\r
-               return(true);\r
-       }\r
-\r
-       if (SoundMode == sdm_Off)\r
-               return(false);\r
-       if (!s->length)\r
-               Quit(gvar, "SD_PlaySound() - Zero length sound");\r
-       if (s->priority < SoundPriority)\r
-               return(false);\r
-\r
-       switch (SoundMode)\r
-       {\r
-       case sdm_PC:\r
-               SDL_PCPlaySound((void far *)s);\r
-               break;\r
-       case sdm_AdLib:\r
-               SDL_ALPlaySound((void far *)s, gvar);\r
-               break;\r
-       }\r
-\r
-       SoundNumber = sound;\r
-       SoundPriority = s->priority;\r
-\r
-       return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_SoundPlaying() - returns the sound number that's playing, or 0 if\r
-//             no sound is playing\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-word\r
-SD_SoundPlaying(void)\r
-{\r
-       boolean result = false;\r
-\r
-       switch (SoundMode)\r
-       {\r
-       case sdm_PC:\r
-               result = pcSound? true : false;\r
-               break;\r
-       case sdm_AdLib:\r
-               result = alSound? true : false;\r
-               break;\r
-       }\r
-\r
-       if (result)\r
-               return(SoundNumber);\r
-       else\r
-               return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_StopSound() - if a sound is playing, stops it\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SD_StopSound(global_game_variables_t *gvar)\r
-{\r
-       if (DigiPlaying)\r
-               SD_StopDigitized(gvar);\r
-\r
-       switch (SoundMode)\r
-       {\r
-       case sdm_PC:\r
-               SDL_PCStopSound();\r
-               break;\r
-       case sdm_AdLib:\r
-               SDL_ALStopSound();\r
-               break;\r
-       }\r
-\r
-       SoundPositioned = false;\r
-\r
-       SDL_SoundFinished();\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_WaitSoundDone() - waits until the current sound is done playing\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SD_WaitSoundDone(void)\r
-{\r
-       while (SD_SoundPlaying())\r
-               ;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_MusicOn() - turns on the sequencer\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SD_MusicOn(void)\r
-{\r
-       sqActive = true;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_MusicOff() - turns off the sequencer and any playing notes\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SD_MusicOff(void)\r
-{\r
-       word    i;\r
-\r
-\r
-       switch (MusicMode)\r
-       {\r
-       case smm_AdLib:\r
-               alFXReg = 0;\r
-               alOut(alEffects,0);\r
-               for (i = 0;i < sqMaxTracks;i++)\r
-                       alOut(alFreqH + i + 1,0);\r
-               break;\r
-       }\r
-       sqActive = false;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_StartMusic() - starts playing the music pointed to\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SD_StartMusic(MusicGroup far *music)\r
-{\r
-       SD_MusicOff();\r
-asm    pushf\r
-asm    cli\r
-\r
-       if (MusicMode == smm_AdLib)\r
-       {\r
-               sqHackPtr = sqHack = music->values;\r
-               sqHackSeqLen = sqHackLen = music->length;\r
-               sqHackTime = 0;\r
-               alTimeCount = 0;\r
-               SD_MusicOn();\r
-       }\r
-\r
-asm    popf\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_FadeOutMusic() - starts fading out the music. Call SD_MusicPlaying()\r
-//             to see if the fadeout is complete\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SD_FadeOutMusic(void)\r
-{\r
-       switch (MusicMode)\r
-       {\r
-       case smm_AdLib:\r
-               // DEBUG - quick hack to turn the music off\r
-               SD_MusicOff();\r
-               break;\r
-       }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-//     SD_MusicPlaying() - returns true if music is currently playing, false if\r
-//             not\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-boolean\r
-SD_MusicPlaying(void)\r
-{\r
-       boolean result;\r
-\r
-       switch (MusicMode)\r
-       {\r
-       case smm_AdLib:\r
-               result = false;\r
-               // DEBUG - not written\r
-               break;\r
-       default:\r
-               result = false;\r
-       }\r
-\r
-       return(result);\r
-}\r
-\r
-//#if 0\r
-//\r
-// SD ASS!\r
-//\r
-\r
-//variables for these assembly functions\r
-volatile boolean pcindicate;\r
-volatile unsigned/*boolean*/ MyDS;\r
-\r
-void SDL_SetDS()\r
-{\r
-       __asm {\r
-               mov     ax,ds\r
-               mov     [cs:MyDS],ds\r
-               ret\r
-       }\r
-}\r
-\r
-//\r
-\r
-// Timer 0 ISR for 7000Hz interrupts\r
-void interrupt SDL_t0ExtremeAsmService(void)\r
-{\r
-       if(pcindicate)\r
-       {\r
-               if(pcSound)\r
-               {\r
-                       SDL_setPCSpeaker(((*pcSound++)&0x80)>>6);\r
-                       pcLengthLeft--;\r
-                       if(!pcLengthLeft)\r
-                       {\r
-                               pcSound=0;\r
-                               SDL_turnOffPCSpeaker();\r
-                               SDL_DigitizedDoneInIRQ();\r
-                       }\r
-               }\r
-       }\r
-       extreme++;\r
-       if(extreme>=10)\r
-       {\r
-               extreme=0;\r
-               SDL_DoFast();\r
-       }\r
-       else\r
-               outp(0x20,0x20);\r
-}\r
-\r
-//\r
-\r
-void SDL_IndicatePC(boolean ind)\r
-{\r
-       pcindicate=ind;\r
-}\r
-\r
-void\r
-SDL_DigitizedDoneInIRQ(void)\r
-{\r
-       if (DigiNextAddr)\r
-       {\r
-               SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen/*,true*/);\r
-               DigiNextAddr = nil;\r
-               DigiMissed = false;\r
-       }\r
-       else\r
-       {\r
-               if (DigiLastSegment)\r
-               {\r
-                       DigiPlaying = false;\r
-                       DigiLastSegment = false;\r
-                       if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
-                       {\r
-                               SDL_SoundFinished();\r
-                       }\r
-                       else\r
-                       {\r
-                               DigiNumber = (soundnames) 0;\r
-                               DigiPriority = 0;\r
-                       }\r
-                       SoundPositioned = false;\r
-               }\r
-               else\r
-                       DigiMissed = true;\r
-       }\r
-}\r
-\r
-#if 0\r
-// Inside an interrupt handler interrupts should already be disabled\r
-// so don't disable them again and cause V86 exceptions which cost\r
-// aprox. 300 processor tics!\r
-\r
-//static\r
-void alOutInIRQ(byte n,byte b)\r
-{\r
-       __asm {\r
-               mov     dx,0x388\r
-               mov     al,[n]\r
-               out     dx,al\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               inc     dx\r
-               mov     al,[b]\r
-               out     dx,al\r
-\r
-               dec     dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-               in      al,dx\r
-       }\r
-}\r
-#endif\r
diff --git a/src/lib/id_sd.h b/src/lib/id_sd.h
deleted file mode 100755 (executable)
index 12558e6..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/* Project 16 Source Code~\r
- * Copyright (C) 2012-2017 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
- *\r
- * This file is part of Project 16.\r
- *\r
- * Project 16 is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 3 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * Project 16 is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
- * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
- * Fifth Floor, Boston, MA 02110-1301 USA.\r
- *\r
- */\r
-\r
-//\r
-//     ID Engine\r
-//     ID_SD.h - Sound Manager Header\r
-//     Version for Wolfenstein\r
-//     By Jason Blochowiak\r
-//     Open Watcom port by sparky4\r
-//\r
-\r
-#ifndef        __16_SD__\r
-#define        __16_SD__\r
-\r
-#include "src/lib/16_head.h"\r
-#include "src/lib/16_pm.h"\r
-\r
-void   alOut(byte n,byte b);\r
-\r
-#ifdef __DEBUG__\r
-#define        __DEBUG_SoundMgr__\r
-#endif\r
-\r
-#define        TickBase        70              // 70Hz per tick - used as a base for timer 0\r
-\r
-typedef        enum    {\r
-                                       sdm_Off,\r
-                                       sdm_PC,sdm_AdLib,\r
-                               }       SDMode;\r
-typedef        enum    {\r
-                                       smm_Off,smm_AdLib\r
-                               }       SMMode;\r
-typedef        enum    {\r
-                                       sds_Off,sds_PC,sds_SoundSource,sds_SoundBlaster\r
-                               }       SDSMode;\r
-typedef        struct\r
-               {\r
-                       dword   length;\r
-                       word            priority;\r
-               } SoundCommon;\r
-\r
-//     PC Sound stuff\r
-#define        pcTimer         0x42\r
-#define        pcTAccess       0x43\r
-#define        pcSpeaker       0x61\r
-\r
-#define        pcSpkBits       3\r
-\r
-typedef        struct\r
-               {\r
-                       SoundCommon     common;\r
-                       byte            data[1];\r
-               } PCSound;\r
-\r
-//     Registers for the Sound Blaster card - needs to be offset by n0 (0x10,0x20,0x30,0x40,0x50,0x60)\r
-#define        sbReset         0x206   // W\r
-#define        sbFMStatus      0x208   // R\r
-#define        sbFMAddr        0x208   // W\r
-#define        sbFMData        0x209   // W\r
-#define        sbReadData      0x20a   // R\r
-#define        sbWriteCmd      0x20c   // W\r
-#define        sbWriteData     0x20c   // W\r
-#define        sbWriteStat     0x20c   // R\r
-#define        sbDataAvail     0x20e   // R\r
-\r
-//     Registers for the Sound Blaster Pro card - needs to be offset by n0 (0x20 or 0x40)\r
-#define        sbpLFMStatus    0x200   // R\r
-#define        sbpLFMAddr              0x200   // W\r
-#define        sbpLFMData              0x201   // W\r
-#define        sbpRFMStatus    0x202   // R\r
-#define        sbpRFMAddr              0x202   // W\r
-#define        sbpRFMData              0x203   // W\r
-#define        sbpMixerAddr    0x204   // W\r
-#define        sbpMixerData    0x205   // RW\r
-#define        sbpCDData               0x210   // R\r
-#define        sbpCDCommand    0x210   // W\r
-#define        sbpCDStatus             0x211   // R\r
-#define        sbpCDReset              0x212   // W\r
-\r
-//     SBPro Mixer addresses\r
-#define        sbpmReset               0x00\r
-#define        sbpmVoiceVol    0x04\r
-#define        sbpmMicMix              0x0a\r
-#define        sbpmFilterADC   0x0c\r
-#define        sbpmControl             0x0e\r
-#define        sbpmMasterVol   0x22\r
-#define        sbpmFMVol               0x26\r
-#define        sbpmCDVol               0x28\r
-#define        sbpmLineVol             0x2e\r
-\r
-typedef        struct\r
-               {\r
-                       SoundCommon     common;\r
-                       word            hertz;\r
-                       byte            bits,\r
-                                               reference,\r
-                                               data[1];\r
-               } SampledSound;\r
-\r
-//     Registers for the AdLib card\r
-#define        alFMStatus      0x388   // R\r
-#define        alFMAddr        0x388   // W\r
-#define        alFMData        0x389   // W\r
-\r
-//     Register addresses\r
-// Operator stuff\r
-#define        alChar          0x20\r
-#define        alScale         0x40\r
-#define        alAttack        0x60\r
-#define        alSus           0x80\r
-#define        alWave          0xe0\r
-// Channel stuff\r
-#define        alFreqL         0xa0\r
-#define        alFreqH         0xb0\r
-#define        alFeedCon       0xc0\r
-// Global stuff\r
-#define        alEffects       0xbd\r
-\r
-typedef        struct\r
-               {\r
-                       byte    mChar,cChar,\r
-                                       mScale,cScale,\r
-                                       mAttack,cAttack,\r
-                                       mSus,cSus,\r
-                                       mWave,cWave,\r
-                                       nConn,\r
-\r
-                                       // These are only for Muse - these bytes are really unused\r
-                                       voice,\r
-                                       mode,\r
-                                       unused[3];\r
-               } Instrument;\r
-\r
-typedef        struct\r
-               {\r
-                       SoundCommon     common;\r
-                       Instrument      inst;\r
-                       byte            block,\r
-                                               data[1];\r
-               } AdLibSound;\r
-\r
-//\r
-//     Sequencing stuff\r
-//\r
-#define        sqMaxTracks     10\r
-#define        sqMaxMoods      1       // DEBUG\r
-\r
-#define        sev_Null                0       // Does nothing\r
-#define        sev_NoteOff             1       // Turns a note off\r
-#define        sev_NoteOn              2       // Turns a note on\r
-#define        sev_NotePitch   3       // Sets the pitch of a currently playing note\r
-#define        sev_NewInst             4       // Installs a new instrument\r
-#define        sev_NewPerc             5       // Installs a new percussive instrument\r
-#define        sev_PercOn              6       // Turns a percussive note on\r
-#define        sev_PercOff             7       // Turns a percussive note off\r
-#define        sev_SeqEnd              -1      // Terminates a sequence\r
-\r
-//     Flags for MusicGroup.flags\r
-#define        sf_Melodic              0\r
-#define        sf_Percussive   1\r
-\r
-#if 1\r
-typedef        struct\r
-               {\r
-                       word    length,\r
-                                       values[1];\r
-               } MusicGroup;\r
-#else\r
-typedef        struct\r
-               {\r
-                       word    flags,\r
-                                       count,\r
-                                       offsets[1];\r
-               } MusicGroup;\r
-#endif\r
-\r
-typedef        struct\r
-               {\r
-                       /* This part needs to be set up by the user */\r
-                       word        mood,far *moods[sqMaxMoods];\r
-\r
-                       /* The rest is set up by the code */\r
-                       Instrument      inst;\r
-                       boolean         percussive;\r
-                       word            far *seq;\r
-                       dword   nextevent;\r
-               } ActiveTrack;\r
-\r
-#define        sqmode_Normal           0\r
-#define        sqmode_FadeIn           1\r
-#define        sqmode_FadeOut          2\r
-\r
-#define        sqMaxFade               64      // DEBUG\r
-\r
-\r
-// Global variables\r
-extern boolean         AdLibPresent,\r
-                                       SoundSourcePresent,\r
-                                       SoundBlasterPresent,\r
-                                       NeedsMusic,                                     // For Caching Mgr\r
-                                       SoundPositioned;\r
-extern SDMode          SoundMode;\r
-extern SDSMode         DigiMode;\r
-extern SMMode          MusicMode;\r
-extern boolean         DigiPlaying;\r
-extern int                     DigiMap[];\r
-extern dword   TimeCount;                                      // Global time in ticks\r
-\r
-// Function prototypes\r
-extern void    SD_Startup(global_game_variables_t *gvar),\r
-                               SD_Shutdown(global_game_variables_t *gvar),\r
-                               SD_Default(boolean gotit,SDMode sd,SMMode sm, global_game_variables_t *gvar),\r
-\r
-                               SD_PositionSound(int leftvol,int rightvol);\r
-extern boolean SD_PlaySound(soundnames sound, global_game_variables_t *gvar);\r
-extern void    SD_SetPosition(int leftvol,int rightvol, global_game_variables_t *gvar),\r
-                               SD_StopSound(global_game_variables_t *gvar),\r
-                               SD_WaitSoundDone(void),\r
-\r
-                               SD_StartMusic(MusicGroup far *music),\r
-                               SD_MusicOn(void),\r
-                               SD_MusicOff(void),\r
-                               SD_FadeOutMusic(void),\r
-\r
-                               SD_SetUserHook(void (*hook)(void));\r
-extern boolean SD_MusicPlaying(void),\r
-                               SD_SetSoundMode(SDMode mode, global_game_variables_t *gvar),\r
-                               SD_SetMusicMode(SMMode mode);\r
-extern word    SD_SoundPlaying(void);\r
-\r
-extern void    SD_SetDigiDevice(SDSMode, global_game_variables_t *gvar),\r
-                               SD_PlayDigitized(word which,int leftpos,int rightpos, global_game_variables_t *gvar),\r
-                               SD_StopDigitized(global_game_variables_t *gvar),\r
-                               SD_Poll(global_game_variables_t *gvar);\r
-\r
-#ifdef _MUSE_  // MUSE Goes directly to the lower level routines\r
-extern void    SDL_PCPlaySound(PCSound far *sound, global_game_variables_t *gvar),\r
-                               SDL_PCStopSound(void),\r
-                               SDL_ALPlaySound(AdLibSound far *sound),\r
-                               SDL_ALStopSound(void);\r
-#endif\r
-\r
-#endif\r
-\r
diff --git a/src/sdtest.c b/src/sdtest.c
new file mode 100755 (executable)
index 0000000..fd26485
--- /dev/null
@@ -0,0 +1,30 @@
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2017 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#include "src/lib/16_sd.h"\r
+\r
+void main()\r
+{\r
+       /*static */global_game_variables_t gvar;\r
+       SD_Startup(&gvar);\r
+       SD_Shutdown(&gvar);\r
+}\r
index 3ef0114f687af66617a2ec41b657bc69271c0b63..47848ceb5f953fd6a65451bfb09eaf534c9996a7 100755 (executable)
@@ -23,7 +23,7 @@
 #include <stdio.h>\r
 \r
 #include "src/lib/16_in.h"\r
-#include "src/lib/16_sd.h"\r
+#include "src/lib/16_snd.h"\r
 //#include <hw/8254/8254.h>            /* 8254 timer */\r
 //#include <hw/adlib/adlib.h>\r
 \r
index 7d13975a7a77912f8e899a16a3ebdf265de4f318..dcd541412bfea42a0acc9f554bc57cdd3e410475 100755 (executable)
@@ -24,7 +24,7 @@
  */\r
 \r
 #include "src/lib/vgmsnd/vgmSnd.h"\r
-#include "src/lib/16_sd.h"\r
+#include "src/lib/16_snd.h"\r
 //#include "src/lib/doslib/adlib.h"\r
 #include "src/lib/16_tail.h"\r
 #include "src/lib/16_pm.h"\r