Initial import. master
authorSimon Morgan <sjm@sjm.io>
Sat, 3 Nov 2012 23:11:43 +0000 (23:11 +0000)
committerSimon Morgan <sjm@sjm.io>
Sat, 13 Oct 2018 08:53:33 +0000 (09:53 +0100)
506 files changed:
audiolib/AUDIO.MAK [new file with mode: 0644]
audiolib/AUDIO2.MAK [new file with mode: 0644]
audiolib/AUDIO_WF.LIB [new file with mode: 0644]
audiolib/DOPUBLIC.BAT [new file with mode: 0644]
audiolib/GUS/GUSROTT.INI [new file with mode: 0644]
audiolib/GUS/UCALC.EXE [new file with mode: 0644]
audiolib/GUS/ULTRAMID.INI [new file with mode: 0644]
audiolib/LIB/GF1_OSF.LB2 [new file with mode: 0644]
audiolib/LIB/GF1_OSF.LBK [new file with mode: 0644]
audiolib/LIB/GF1_OSF.LIB [new file with mode: 0644]
audiolib/LIB/PAWE32.LIB [new file with mode: 0644]
audiolib/MAKEDB.BAT [new file with mode: 0644]
audiolib/OBJ/ADLIBFX.OBJ [new file with mode: 0644]
audiolib/OBJ/AL_MIDI.OBJ [new file with mode: 0644]
audiolib/OBJ/AUDIO_WF.LIB [new file with mode: 0644]
audiolib/OBJ/AWE32.OBJ [new file with mode: 0644]
audiolib/OBJ/BLASTER.OBJ [new file with mode: 0644]
audiolib/OBJ/DEBUGIO.OBJ [new file with mode: 0644]
audiolib/OBJ/DMA.OBJ [new file with mode: 0644]
audiolib/OBJ/DPMI.OBJ [new file with mode: 0644]
audiolib/OBJ/FX_MAN.OBJ [new file with mode: 0644]
audiolib/OBJ/GMTIMBRE.OBJ [new file with mode: 0644]
audiolib/OBJ/GUS.OBJ [new file with mode: 0644]
audiolib/OBJ/GUSMIDI.OBJ [new file with mode: 0644]
audiolib/OBJ/GUSWAVE.OBJ [new file with mode: 0644]
audiolib/OBJ/IRQ.OBJ [new file with mode: 0644]
audiolib/OBJ/LL_MAN.OBJ [new file with mode: 0644]
audiolib/OBJ/MIDI.OBJ [new file with mode: 0644]
audiolib/OBJ/MPU401.OBJ [new file with mode: 0644]
audiolib/OBJ/MULTIVOC.OBJ [new file with mode: 0644]
audiolib/OBJ/MUSIC.OBJ [new file with mode: 0644]
audiolib/OBJ/MVREVERB.OBJ [new file with mode: 0644]
audiolib/OBJ/MV_MIX.OBJ [new file with mode: 0644]
audiolib/OBJ/MV_MIX16.OBJ [new file with mode: 0644]
audiolib/OBJ/PAS16.OBJ [new file with mode: 0644]
audiolib/OBJ/PCFX.OBJ [new file with mode: 0644]
audiolib/OBJ/PITCH.OBJ [new file with mode: 0644]
audiolib/OBJ/SNDSCAPE.OBJ [new file with mode: 0644]
audiolib/OBJ/SNDSRC.OBJ [new file with mode: 0644]
audiolib/OBJ/TASK_MAN.OBJ [new file with mode: 0644]
audiolib/OBJ/USER.OBJ [new file with mode: 0644]
audiolib/OBJDB/AL_MIDI.OBJ [new file with mode: 0644]
audiolib/OBJDB/AUDIO_WF.LIB [new file with mode: 0644]
audiolib/OBJDB/AWE32.OBJ [new file with mode: 0644]
audiolib/OBJDB/BLASTER.OBJ [new file with mode: 0644]
audiolib/OBJDB/DEBUGIO.OBJ [new file with mode: 0644]
audiolib/OBJDB/DMA.OBJ [new file with mode: 0644]
audiolib/OBJDB/DPMI.OBJ [new file with mode: 0644]
audiolib/OBJDB/FX_MAN.OBJ [new file with mode: 0644]
audiolib/OBJDB/GMTIMBRE.OBJ [new file with mode: 0644]
audiolib/OBJDB/GUS.OBJ [new file with mode: 0644]
audiolib/OBJDB/GUSMIDI.OBJ [new file with mode: 0644]
audiolib/OBJDB/GUSWAVE.OBJ [new file with mode: 0644]
audiolib/OBJDB/IRQ.OBJ [new file with mode: 0644]
audiolib/OBJDB/LL_MAN.OBJ [new file with mode: 0644]
audiolib/OBJDB/MIDI.OBJ [new file with mode: 0644]
audiolib/OBJDB/MPU401.OBJ [new file with mode: 0644]
audiolib/OBJDB/MULTIVOC.OBJ [new file with mode: 0644]
audiolib/OBJDB/MUSIC.OBJ [new file with mode: 0644]
audiolib/OBJDB/MVREVERB.OBJ [new file with mode: 0644]
audiolib/OBJDB/MV_MIX.OBJ [new file with mode: 0644]
audiolib/OBJDB/MV_MIX16.OBJ [new file with mode: 0644]
audiolib/OBJDB/PAS16.OBJ [new file with mode: 0644]
audiolib/OBJDB/PITCH.OBJ [new file with mode: 0644]
audiolib/OBJDB/SNDSCAPE.OBJ [new file with mode: 0644]
audiolib/OBJDB/SNDSRC.OBJ [new file with mode: 0644]
audiolib/OBJDB/TASK_MAN.OBJ [new file with mode: 0644]
audiolib/OBJDB/USER.OBJ [new file with mode: 0644]
audiolib/PUBLIC/AUDIO_WF.LIB [new file with mode: 0644]
audiolib/PUBLIC/EMIDIAPI.TXT [new file with mode: 0644]
audiolib/PUBLIC/INCLUDE/AUDIO_WF.LIB [new file with mode: 0644]
audiolib/PUBLIC/INCLUDE/FX_MAN.H [new file with mode: 0644]
audiolib/PUBLIC/INCLUDE/MUSIC.H [new file with mode: 0644]
audiolib/PUBLIC/INCLUDE/SNDCARDS.H [new file with mode: 0644]
audiolib/PUBLIC/INCLUDE/TASK_MAN.H [new file with mode: 0644]
audiolib/PUBLIC/INCLUDE/USRHOOKS.C [new file with mode: 0644]
audiolib/PUBLIC/INCLUDE/USRHOOKS.H [new file with mode: 0644]
audiolib/PUBLIC/MIDI.TXT [new file with mode: 0644]
audiolib/PUBLIC/NOTES.TXT [new file with mode: 0644]
audiolib/PUBLIC/PM/GMTIMBRE.TMB [new file with mode: 0644]
audiolib/PUBLIC/PM/MAKEFILE [new file with mode: 0644]
audiolib/PUBLIC/PM/MAKETMB.EXE [new file with mode: 0644]
audiolib/PUBLIC/PM/OBJ/PM.OBJ [new file with mode: 0644]
audiolib/PUBLIC/PM/OBJ/USRHOOKS.OBJ [new file with mode: 0644]
audiolib/PUBLIC/PM/PM.EXE [new file with mode: 0644]
audiolib/PUBLIC/PM/PM.TXT [new file with mode: 0644]
audiolib/PUBLIC/PM/README.TXT [new file with mode: 0644]
audiolib/PUBLIC/PM/SOURCE/PM.C [new file with mode: 0644]
audiolib/PUBLIC/PM/SOURCE/USRHOOKS.C [new file with mode: 0644]
audiolib/PUBLIC/PM/SOURCE/USRHOOKS.H [new file with mode: 0644]
audiolib/PUBLIC/PM/TIMBRES.ZIP [new file with mode: 0644]
audiolib/PUBLIC/PS/BINDPS.BAT [new file with mode: 0644]
audiolib/PUBLIC/PS/MAKEFILE [new file with mode: 0644]
audiolib/PUBLIC/PS/PS.C [new file with mode: 0644]
audiolib/PUBLIC/PS/PS.EXE [new file with mode: 0644]
audiolib/PUBLIC/PS/PS.OBJ [new file with mode: 0644]
audiolib/PUBLIC/PS/USRHOOKS.C [new file with mode: 0644]
audiolib/PUBLIC/PS/USRHOOKS.H [new file with mode: 0644]
audiolib/PUBLIC/PS/USRHOOKS.OBJ [new file with mode: 0644]
audiolib/PUBLIC/TIMER/MAKEFILE [new file with mode: 0644]
audiolib/PUBLIC/TIMER/OBJ/TIMER.OBJ [new file with mode: 0644]
audiolib/PUBLIC/TIMER/OBJ/USRHOOKS.OBJ [new file with mode: 0644]
audiolib/PUBLIC/TIMER/SOURCE/TIMER.C [new file with mode: 0644]
audiolib/PUBLIC/TIMER/SOURCE/USRHOOKS.C [new file with mode: 0644]
audiolib/PUBLIC/TIMER/SOURCE/USRHOOKS.H [new file with mode: 0644]
audiolib/PUBLIC/TIMER/TIMER.EXE [new file with mode: 0644]
audiolib/SOURCE/ADLIBFX.C [new file with mode: 0644]
audiolib/SOURCE/ADLIBFX.H [new file with mode: 0644]
audiolib/SOURCE/AL_MIDI.C [new file with mode: 0644]
audiolib/SOURCE/AL_MIDI.H [new file with mode: 0644]
audiolib/SOURCE/ASSERT.H [new file with mode: 0644]
audiolib/SOURCE/AWE32.C [new file with mode: 0644]
audiolib/SOURCE/AWE32.H [new file with mode: 0644]
audiolib/SOURCE/BLASTER.C [new file with mode: 0644]
audiolib/SOURCE/BLASTER.H [new file with mode: 0644]
audiolib/SOURCE/BLASTOLD.C [new file with mode: 0644]
audiolib/SOURCE/CTAWEAPI.H [new file with mode: 0644]
audiolib/SOURCE/CTAWEAPI.INC [new file with mode: 0644]
audiolib/SOURCE/DEBUGIO.C [new file with mode: 0644]
audiolib/SOURCE/DEBUGIO.H [new file with mode: 0644]
audiolib/SOURCE/DMA.C [new file with mode: 0644]
audiolib/SOURCE/DMA.H [new file with mode: 0644]
audiolib/SOURCE/DPMI.C [new file with mode: 0644]
audiolib/SOURCE/DPMI.H [new file with mode: 0644]
audiolib/SOURCE/FX_MAN.C [new file with mode: 0644]
audiolib/SOURCE/FX_MAN.H [new file with mode: 0644]
audiolib/SOURCE/GMTEMP.C [new file with mode: 0644]
audiolib/SOURCE/GMTIMBRE.C [new file with mode: 0644]
audiolib/SOURCE/GMTMBOLD.C [new file with mode: 0644]
audiolib/SOURCE/GUS.C [new file with mode: 0644]
audiolib/SOURCE/GUSMIDI.C [new file with mode: 0644]
audiolib/SOURCE/GUSMIDI.H [new file with mode: 0644]
audiolib/SOURCE/GUSMIDI2.C [new file with mode: 0644]
audiolib/SOURCE/GUSMIDI2.H [new file with mode: 0644]
audiolib/SOURCE/GUSWAVE.C [new file with mode: 0644]
audiolib/SOURCE/GUSWAVE.H [new file with mode: 0644]
audiolib/SOURCE/INTERRUP.H [new file with mode: 0644]
audiolib/SOURCE/IRQ.C [new file with mode: 0644]
audiolib/SOURCE/IRQ.H [new file with mode: 0644]
audiolib/SOURCE/LEEOLD.C [new file with mode: 0644]
audiolib/SOURCE/LEETIMB1.C [new file with mode: 0644]
audiolib/SOURCE/LEETIMBR.C [new file with mode: 0644]
audiolib/SOURCE/LINKLIST.H [new file with mode: 0644]
audiolib/SOURCE/LL_MAN.C [new file with mode: 0644]
audiolib/SOURCE/LL_MAN.H [new file with mode: 0644]
audiolib/SOURCE/MEMCHECK.H [new file with mode: 0644]
audiolib/SOURCE/MIDI.C [new file with mode: 0644]
audiolib/SOURCE/MIDI.H [new file with mode: 0644]
audiolib/SOURCE/MPU401.C [new file with mode: 0644]
audiolib/SOURCE/MPU401.H [new file with mode: 0644]
audiolib/SOURCE/MULTIVOC.C [new file with mode: 0644]
audiolib/SOURCE/MULTIVOC.H [new file with mode: 0644]
audiolib/SOURCE/MUSIC.C [new file with mode: 0644]
audiolib/SOURCE/MUSIC.H [new file with mode: 0644]
audiolib/SOURCE/MV1.C [new file with mode: 0644]
audiolib/SOURCE/MVREVERB.ASM [new file with mode: 0644]
audiolib/SOURCE/MV_MIX.ASM [new file with mode: 0644]
audiolib/SOURCE/MV_MIX1.ASM [new file with mode: 0644]
audiolib/SOURCE/MV_MIX16.ASM [new file with mode: 0644]
audiolib/SOURCE/MV_MIX2.ASM [new file with mode: 0644]
audiolib/SOURCE/MV_MIX3.ASM [new file with mode: 0644]
audiolib/SOURCE/MV_MIX4.ASM [new file with mode: 0644]
audiolib/SOURCE/MV_MIX5.ASM [new file with mode: 0644]
audiolib/SOURCE/MV_MIX6.ASM [new file with mode: 0644]
audiolib/SOURCE/MYPRINT.C [new file with mode: 0644]
audiolib/SOURCE/MYPRINT.H [new file with mode: 0644]
audiolib/SOURCE/NEWGF1.H [new file with mode: 0644]
audiolib/SOURCE/OLDTIMBR.C [new file with mode: 0644]
audiolib/SOURCE/PAS16.C [new file with mode: 0644]
audiolib/SOURCE/PAS16.H [new file with mode: 0644]
audiolib/SOURCE/PCFX.C [new file with mode: 0644]
audiolib/SOURCE/PCFX.H [new file with mode: 0644]
audiolib/SOURCE/PITCH.C [new file with mode: 0644]
audiolib/SOURCE/PITCH.H [new file with mode: 0644]
audiolib/SOURCE/SNDCARDS.H [new file with mode: 0644]
audiolib/SOURCE/SNDSCAPE.C [new file with mode: 0644]
audiolib/SOURCE/SNDSCAPE.H [new file with mode: 0644]
audiolib/SOURCE/SNDSRC.C [new file with mode: 0644]
audiolib/SOURCE/SNDSRC.H [new file with mode: 0644]
audiolib/SOURCE/STANDARD.H [new file with mode: 0644]
audiolib/SOURCE/TASK_MAN.C [new file with mode: 0644]
audiolib/SOURCE/TASK_MAN.H [new file with mode: 0644]
audiolib/SOURCE/USER.C [new file with mode: 0644]
audiolib/SOURCE/USER.H [new file with mode: 0644]
audiolib/SOURCE/USRHOOKS.C [new file with mode: 0644]
audiolib/SOURCE/USRHOOKS.H [new file with mode: 0644]
audiolib/SOURCE/_AL_MIDI.H [new file with mode: 0644]
audiolib/SOURCE/_BLASTER.H [new file with mode: 0644]
audiolib/SOURCE/_GUSWAVE.H [new file with mode: 0644]
audiolib/SOURCE/_MIDI.H [new file with mode: 0644]
audiolib/SOURCE/_MULTIVC.H [new file with mode: 0644]
audiolib/SOURCE/_PAS16.H [new file with mode: 0644]
audiolib/SOURCE/_SNDSCAP.H [new file with mode: 0644]
audiolib/WMAKE.BAT [new file with mode: 0644]
gpl.txt [new file with mode: 0644]
readme.txt [new file with mode: 0644]
rott/13TODO.TXT [new file with mode: 0644]
rott/AUDIO_WF.LIB [new file with mode: 0644]
rott/CHEATS.TXT [new file with mode: 0644]
rott/CIN_ACTR.C [new file with mode: 0644]
rott/CIN_ACTR.H [new file with mode: 0644]
rott/CIN_ACTR.OBJ [new file with mode: 0644]
rott/CIN_DEF.H [new file with mode: 0644]
rott/CIN_EFCT.C [new file with mode: 0644]
rott/CIN_EFCT.H [new file with mode: 0644]
rott/CIN_EFCT.OBJ [new file with mode: 0644]
rott/CIN_EVNT.C [new file with mode: 0644]
rott/CIN_EVNT.H [new file with mode: 0644]
rott/CIN_EVNT.OBJ [new file with mode: 0644]
rott/CIN_GLOB.C [new file with mode: 0644]
rott/CIN_GLOB.H [new file with mode: 0644]
rott/CIN_GLOB.OBJ [new file with mode: 0644]
rott/CIN_MAIN.C [new file with mode: 0644]
rott/CIN_MAIN.H [new file with mode: 0644]
rott/CIN_MAIN.OBJ [new file with mode: 0644]
rott/CIN_UTIL.C [new file with mode: 0644]
rott/CIN_UTIL.H [new file with mode: 0644]
rott/CIN_UTIL.OBJ [new file with mode: 0644]
rott/CMDLINE.TXT [new file with mode: 0644]
rott/DEVELOP.H [new file with mode: 0644]
rott/ENGINE.C [new file with mode: 0644]
rott/ENGINE.H [new file with mode: 0644]
rott/ENGINE.OBJ [new file with mode: 0644]
rott/FLI_DEF.H [new file with mode: 0644]
rott/FLI_GLOB.H [new file with mode: 0644]
rott/FLI_MAIN.C [new file with mode: 0644]
rott/FLI_MAIN.ERR [new file with mode: 0644]
rott/FLI_MAIN.H [new file with mode: 0644]
rott/FLI_MAIN.OBJ [new file with mode: 0644]
rott/FLI_TYPE.H [new file with mode: 0644]
rott/FLI_UTIL.C [new file with mode: 0644]
rott/FLI_UTIL.ERR [new file with mode: 0644]
rott/FLI_UTIL.H [new file with mode: 0644]
rott/FLI_UTIL.OBJ [new file with mode: 0644]
rott/FX_MAN.H [new file with mode: 0644]
rott/F_SCALE.ASM [new file with mode: 0644]
rott/F_SCALE.H [new file with mode: 0644]
rott/F_SCALE.OBJ [new file with mode: 0644]
rott/GMOVE.H [new file with mode: 0644]
rott/GUSMIDI.INI [new file with mode: 0644]
rott/HACKER.TXT [new file with mode: 0644]
rott/ISR.C [new file with mode: 0644]
rott/ISR.H [new file with mode: 0644]
rott/ISR.OBJ [new file with mode: 0644]
rott/KEYB.H [new file with mode: 0644]
rott/LASRSFT.LBM [new file with mode: 0644]
rott/LASRSFT.PCX [new file with mode: 0644]
rott/LAUNCH.H [new file with mode: 0644]
rott/LOOKUPS.C [new file with mode: 0644]
rott/LUMPY.H [new file with mode: 0644]
rott/MAKEFILE [new file with mode: 0644]
rott/MAPSROT.H [new file with mode: 0644]
rott/MEMCHECK.H [new file with mode: 0644]
rott/MODEM.PCK [new file with mode: 0644]
rott/MODEXLIB.C [new file with mode: 0644]
rott/MODEXLIB.H [new file with mode: 0644]
rott/MODEXLIB.OBJ [new file with mode: 0644]
rott/MOUSE.H [new file with mode: 0644]
rott/MUSIC.H [new file with mode: 0644]
rott/MYPRINT.H [new file with mode: 0644]
rott/PROFILE.H [new file with mode: 0644]
rott/RAND.ASM [new file with mode: 0644]
rott/ROTT.LNK [new file with mode: 0644]
rott/ROTT.MAP [new file with mode: 0644]
rott/ROTT0004.GIF [new file with mode: 0644]
rott/ROTT0012.GIF [new file with mode: 0644]
rott/ROTT0024.GIF [new file with mode: 0644]
rott/ROTTNET.H [new file with mode: 0644]
rott/ROTTSER.H [new file with mode: 0644]
rott/RT_ACTOR.C [new file with mode: 0644]
rott/RT_ACTOR.ERR [new file with mode: 0644]
rott/RT_ACTOR.H [new file with mode: 0644]
rott/RT_ACTOR.OBJ [new file with mode: 0644]
rott/RT_BATTL.C [new file with mode: 0644]
rott/RT_BATTL.H [new file with mode: 0644]
rott/RT_BATTL.OBJ [new file with mode: 0644]
rott/RT_BUILD.C [new file with mode: 0644]
rott/RT_BUILD.H [new file with mode: 0644]
rott/RT_BUILD.OBJ [new file with mode: 0644]
rott/RT_CFG.C [new file with mode: 0644]
rott/RT_CFG.ERR [new file with mode: 0644]
rott/RT_CFG.H [new file with mode: 0644]
rott/RT_CFG.OBJ [new file with mode: 0644]
rott/RT_COM.C [new file with mode: 0644]
rott/RT_COM.H [new file with mode: 0644]
rott/RT_COM.OBJ [new file with mode: 0644]
rott/RT_CRC.C [new file with mode: 0644]
rott/RT_CRC.H [new file with mode: 0644]
rott/RT_CRC.OBJ [new file with mode: 0644]
rott/RT_DEBUG.C [new file with mode: 0644]
rott/RT_DEBUG.H [new file with mode: 0644]
rott/RT_DEBUG.OBJ [new file with mode: 0644]
rott/RT_DEF.H [new file with mode: 0644]
rott/RT_DMAND.C [new file with mode: 0644]
rott/RT_DMAND.H [new file with mode: 0644]
rott/RT_DMAND.OBJ [new file with mode: 0644]
rott/RT_DOOR.C [new file with mode: 0644]
rott/RT_DOOR.H [new file with mode: 0644]
rott/RT_DOOR.OBJ [new file with mode: 0644]
rott/RT_DRAW.C [new file with mode: 0644]
rott/RT_DRAW.H [new file with mode: 0644]
rott/RT_DRAW.OBJ [new file with mode: 0644]
rott/RT_DR_A.ASM [new file with mode: 0644]
rott/RT_DR_A.H [new file with mode: 0644]
rott/RT_DR_A.OBJ [new file with mode: 0644]
rott/RT_ENG.ASM [new file with mode: 0644]
rott/RT_ENG.H [new file with mode: 0644]
rott/RT_ERR.OBJ [new file with mode: 0644]
rott/RT_ERROR.C [new file with mode: 0644]
rott/RT_ERROR.H [new file with mode: 0644]
rott/RT_ERROR.OBJ [new file with mode: 0644]
rott/RT_FC_A.ASM [new file with mode: 0644]
rott/RT_FC_A.H [new file with mode: 0644]
rott/RT_FC_A.OBJ [new file with mode: 0644]
rott/RT_FILM.C [new file with mode: 0644]
rott/RT_FILM.H [new file with mode: 0644]
rott/RT_FLOOR.C [new file with mode: 0644]
rott/RT_FLOOR.H [new file with mode: 0644]
rott/RT_FLOOR.OBJ [new file with mode: 0644]
rott/RT_GAME.C [new file with mode: 0644]
rott/RT_GAME.H [new file with mode: 0644]
rott/RT_GAME.OBJ [new file with mode: 0644]
rott/RT_IN.C [new file with mode: 0644]
rott/RT_IN.ERR [new file with mode: 0644]
rott/RT_IN.H [new file with mode: 0644]
rott/RT_IN.OBJ [new file with mode: 0644]
rott/RT_MAIN.C [new file with mode: 0644]
rott/RT_MAIN.H [new file with mode: 0644]
rott/RT_MAIN.OBJ [new file with mode: 0644]
rott/RT_MAP.C [new file with mode: 0644]
rott/RT_MAP.H [new file with mode: 0644]
rott/RT_MAP.OBJ [new file with mode: 0644]
rott/RT_MENU.C [new file with mode: 0644]
rott/RT_MENU.H [new file with mode: 0644]
rott/RT_MENU.OBJ [new file with mode: 0644]
rott/RT_MSG.C [new file with mode: 0644]
rott/RT_MSG.H [new file with mode: 0644]
rott/RT_MSG.OBJ [new file with mode: 0644]
rott/RT_NET.C [new file with mode: 0644]
rott/RT_NET.H [new file with mode: 0644]
rott/RT_NET.OBJ [new file with mode: 0644]
rott/RT_PLAYR.C [new file with mode: 0644]
rott/RT_PLAYR.H [new file with mode: 0644]
rott/RT_PLAYR.OBJ [new file with mode: 0644]
rott/RT_RAND.C [new file with mode: 0644]
rott/RT_RAND.H [new file with mode: 0644]
rott/RT_RAND.OBJ [new file with mode: 0644]
rott/RT_SCALE.C [new file with mode: 0644]
rott/RT_SCALE.H [new file with mode: 0644]
rott/RT_SCALE.OBJ [new file with mode: 0644]
rott/RT_SC_A.ASM [new file with mode: 0644]
rott/RT_SC_A.H [new file with mode: 0644]
rott/RT_SC_A.OBJ [new file with mode: 0644]
rott/RT_SER.C [new file with mode: 0644]
rott/RT_SER.H [new file with mode: 0644]
rott/RT_SOUND.C [new file with mode: 0644]
rott/RT_SOUND.H [new file with mode: 0644]
rott/RT_SOUND.OBJ [new file with mode: 0644]
rott/RT_SPBAL.C [new file with mode: 0644]
rott/RT_SPBAL.H [new file with mode: 0644]
rott/RT_SPBAL.OBJ [new file with mode: 0644]
rott/RT_SQRT.H [new file with mode: 0644]
rott/RT_STAT.C [new file with mode: 0644]
rott/RT_STAT.H [new file with mode: 0644]
rott/RT_STAT.OBJ [new file with mode: 0644]
rott/RT_STATE.C [new file with mode: 0644]
rott/RT_STATE.OBJ [new file with mode: 0644]
rott/RT_STR.C [new file with mode: 0644]
rott/RT_STR.H [new file with mode: 0644]
rott/RT_STR.OBJ [new file with mode: 0644]
rott/RT_SWIFT.C [new file with mode: 0644]
rott/RT_SWIFT.H [new file with mode: 0644]
rott/RT_SWIFT.OBJ [new file with mode: 0644]
rott/RT_TABLE.H [new file with mode: 0644]
rott/RT_TED.C [new file with mode: 0644]
rott/RT_TED.H [new file with mode: 0644]
rott/RT_TED.OBJ [new file with mode: 0644]
rott/RT_TEXT.C [new file with mode: 0644]
rott/RT_UTIL.C [new file with mode: 0644]
rott/RT_UTIL.H [new file with mode: 0644]
rott/RT_UTIL.OBJ [new file with mode: 0644]
rott/RT_VH_A.ASM [new file with mode: 0644]
rott/RT_VH_A.H [new file with mode: 0644]
rott/RT_VH_A.OBJ [new file with mode: 0644]
rott/RT_VID.C [new file with mode: 0644]
rott/RT_VID.H [new file with mode: 0644]
rott/RT_VID.OBJ [new file with mode: 0644]
rott/RT_VIEW.C [new file with mode: 0644]
rott/RT_VIEW.H [new file with mode: 0644]
rott/RT_VIEW.OBJ [new file with mode: 0644]
rott/R_SCALE.ASM [new file with mode: 0644]
rott/SBCONFIG.C [new file with mode: 0644]
rott/SBCONFIG.H [new file with mode: 0644]
rott/SBCONFIG.OBJ [new file with mode: 0644]
rott/SCRIPLIB.C [new file with mode: 0644]
rott/SCRIPLIB.H [new file with mode: 0644]
rott/SCRIPLIB.OBJ [new file with mode: 0644]
rott/SNDCARDS.H [new file with mode: 0644]
rott/SND_REG.H [new file with mode: 0644]
rott/SND_SHAR.H [new file with mode: 0644]
rott/SPBALL.LIB [new file with mode: 0644]
rott/SPLIB.H [new file with mode: 0644]
rott/SPRITES.H [new file with mode: 0644]
rott/SPW_INT.H [new file with mode: 0644]
rott/STATES.H [new file with mode: 0644]
rott/TASK_MAN.H [new file with mode: 0644]
rott/TEXTURE.ASM [new file with mode: 0644]
rott/TEXTURE.C [new file with mode: 0644]
rott/TEXTURE.H [new file with mode: 0644]
rott/TSR.H [new file with mode: 0644]
rott/USRHOOKS.C [new file with mode: 0644]
rott/USRHOOKS.H [new file with mode: 0644]
rott/USRHOOKS.OBJ [new file with mode: 0644]
rott/VERSION.H [new file with mode: 0644]
rott/VRIO.H [new file with mode: 0644]
rott/WAD.TXT [new file with mode: 0644]
rott/WATCOM.H [new file with mode: 0644]
rott/W_WAD.C [new file with mode: 0644]
rott/W_WAD.H [new file with mode: 0644]
rott/W_WAD.OBJ [new file with mode: 0644]
rott/Z_ZONE.C [new file with mode: 0644]
rott/Z_ZONE.H [new file with mode: 0644]
rott/Z_ZONE.OBJ [new file with mode: 0644]
rott/_ENGINE.H [new file with mode: 0644]
rott/_ISR.H [new file with mode: 0644]
rott/_RT_ACTO.H [new file with mode: 0644]
rott/_RT_BUIL.H [new file with mode: 0644]
rott/_RT_COM.H [new file with mode: 0644]
rott/_RT_DMAN.H [new file with mode: 0644]
rott/_RT_DOOR.H [new file with mode: 0644]
rott/_RT_DRAW.H [new file with mode: 0644]
rott/_RT_FILM.H [new file with mode: 0644]
rott/_RT_FLOO.H [new file with mode: 0644]
rott/_RT_GAME.H [new file with mode: 0644]
rott/_RT_IN.H [new file with mode: 0644]
rott/_RT_MAIN.H [new file with mode: 0644]
rott/_RT_MAP.H [new file with mode: 0644]
rott/_RT_MENU.H [new file with mode: 0644]
rott/_RT_MSG.H [new file with mode: 0644]
rott/_RT_NET.H [new file with mode: 0644]
rott/_RT_PLAY.H [new file with mode: 0644]
rott/_RT_RAND.H [new file with mode: 0644]
rott/_RT_SCAL.H [new file with mode: 0644]
rott/_RT_SER.H [new file with mode: 0644]
rott/_RT_SOUN.H [new file with mode: 0644]
rott/_RT_SPBA.H [new file with mode: 0644]
rott/_RT_STAT.H [new file with mode: 0644]
rott/_RT_STR.H [new file with mode: 0644]
rott/_RT_SWFT.H [new file with mode: 0644]
rott/_RT_TED.H [new file with mode: 0644]
rott/_RT_UTIL.H [new file with mode: 0644]
rott/_RT_VID.H [new file with mode: 0644]
rott/_ST_MENU.H [new file with mode: 0644]
rott/_W_WAD.H [new file with mode: 0644]
rott/_Z_ZONE.H [new file with mode: 0644]
rottcom/README.TXT [new file with mode: 0644]
rottcom/ROTTIPX/GLOBAL.C [new file with mode: 0644]
rottcom/ROTTIPX/GLOBAL.H [new file with mode: 0644]
rottcom/ROTTIPX/IPXNET.C [new file with mode: 0644]
rottcom/ROTTIPX/IPXNET.H [new file with mode: 0644]
rottcom/ROTTIPX/IPXSETUP.C [new file with mode: 0644]
rottcom/ROTTIPX/IPXSETUP.CFG [new file with mode: 0644]
rottcom/ROTTIPX/IPXSETUP.DSK [new file with mode: 0644]
rottcom/ROTTIPX/IPXSETUP.H [new file with mode: 0644]
rottcom/ROTTIPX/ROTTIPX.CFG [new file with mode: 0644]
rottcom/ROTTIPX/ROTTIPX.DSK [new file with mode: 0644]
rottcom/ROTTIPX/ROTTIPX.EXE [new file with mode: 0644]
rottcom/ROTTIPX/ROTTIPX.PRJ [new file with mode: 0644]
rottcom/ROTTIPX/ROTTIPX.TFA [new file with mode: 0644]
rottcom/ROTTNET.C [new file with mode: 0644]
rottcom/ROTTNET.H [new file with mode: 0644]
rottcom/ROTTSER/GLOBAL.C [new file with mode: 0644]
rottcom/ROTTSER/GLOBAL.H [new file with mode: 0644]
rottcom/ROTTSER/KEYB.H [new file with mode: 0644]
rottcom/ROTTSER/PORT.C [new file with mode: 0644]
rottcom/ROTTSER/PORT.H [new file with mode: 0644]
rottcom/ROTTSER/ROTT.ROT [new file with mode: 0644]
rottcom/ROTTSER/ROTTSER.CFG [new file with mode: 0644]
rottcom/ROTTSER/ROTTSER.DSK [new file with mode: 0644]
rottcom/ROTTSER/ROTTSER.EXE [new file with mode: 0644]
rottcom/ROTTSER/ROTTSER.PRJ [new file with mode: 0644]
rottcom/ROTTSER/SCRIPLIB.C [new file with mode: 0644]
rottcom/ROTTSER/SCRIPLIB.H [new file with mode: 0644]
rottcom/ROTTSER/SERCOM.C [new file with mode: 0644]
rottcom/ROTTSER/SERCOM.H [new file with mode: 0644]
rottcom/ROTTSER/SERIAL.H [new file with mode: 0644]
rottcom/ROTTSER/SERMODEM.C [new file with mode: 0644]
rottcom/ROTTSER/SERMODEM.H [new file with mode: 0644]
rottcom/ROTTSER/SERSETUP.C [new file with mode: 0644]
rottcom/ROTTSER/SERSETUP.DSK [new file with mode: 0644]
rottcom/ROTTSER/SERSETUP.H [new file with mode: 0644]
rottcom/ROTTSER/SETUP.DSK [new file with mode: 0644]
rottcom/ROTTSER/SETUP.ROT [new file with mode: 0644]
rottcom/ROTTSER/ST_CFG.C [new file with mode: 0644]
rottcom/ROTTSER/ST_CFG.H [new file with mode: 0644]
rottcom/RT_NET.H [new file with mode: 0644]
rtsmaker/CMDLIB.C [new file with mode: 0644]
rtsmaker/CMDLIB.H [new file with mode: 0644]
rtsmaker/REMOTE.WL [new file with mode: 0644]
rtsmaker/RTSMAKER.C [new file with mode: 0644]
rtsmaker/RTSMAKER.DSK [new file with mode: 0644]
rtsmaker/RTSMAKER.EXE [new file with mode: 0644]
rtsmaker/RTSMAKER.PRJ [new file with mode: 0644]
rtsmaker/SAMPLE.TXT [new file with mode: 0644]
rtsmaker/SCRIPLIB.C [new file with mode: 0644]
rtsmaker/SCRIPLIB.H [new file with mode: 0644]

diff --git a/audiolib/AUDIO.MAK b/audiolib/AUDIO.MAK
new file mode 100644 (file)
index 0000000..697acb5
--- /dev/null
@@ -0,0 +1,187 @@
+.OPTIMIZE\r
+\r
+version = production\r
+#version = debugging\r
+\r
+timbre_file       = gmtimbre\r
+#timbre_file       = leetimbr\r
+\r
+prg_dir           = .\r
+obj_debugging     = $(prg_dir)\objdb\r
+obj_production    = $(prg_dir)\obj\r
+obj_dir           = $(obj_$(version))\r
+lib_dir           = $(prg_dir)\lib\r
+output_dir        = $(prg_dir)\r
+main_dir          = $(prg_dir)\source\r
+header_dir        = $(main_dir)\r
+tasm_include_dir  = /i$(main_dir)\r
+\r
+model             = f\r
+compiler          = w\r
+lib_filename      = audio_$(compiler)$(model).lib\r
+lib_name          = $(obj_dir)\$(lib_filename)\r
+final_lib         = $(output_dir)\$(lib_filename)\r
+\r
+.h   :              $(header_dir)\r
+.c   :              $(header_dir)\r
+.asm :              $(header_dir)\r
+.obj :              $(obj_dir)\r
+\r
+offlib_files     = gf1_osf.lib\r
+lib_files         = gf1_osf.lib &\r
+                    pawe32.lib\r
+\r
+#object_files      = &\r
+object_files      = $(timbre_file).obj &\r
+                    al_midi.obj  &\r
+                    awe32.obj    &\r
+                    blaster.obj  &\r
+                    debugio.obj  &\r
+                    dma.obj      &\r
+                    dpmi.obj     &\r
+                    fx_man.obj   &\r
+                    gus.obj      &\r
+                    gusmidi.obj  &\r
+                    guswave.obj  &\r
+                    irq.obj      &\r
+                    ll_man.obj   &\r
+                    midi.obj     &\r
+                    mpu401.obj   &\r
+                    multivoc.obj &\r
+                    mv_mix.obj   &\r
+                    mv_mix16.obj &\r
+                    mvreverb.obj &\r
+                    music.obj    &\r
+                    pas16.obj    &\r
+                    pitch.obj    &\r
+                    sndscape.obj &\r
+                    sndsrc.obj   &\r
+                    task_man.obj &\r
+                    user.obj\r
+\r
+offobject_files      = blaster.obj  &\r
+                    debugio.obj  &\r
+                    dma.obj      &\r
+                    dpmi.obj     &\r
+                    fx_man.obj   &\r
+                    gus.obj      &\r
+                    guswave.obj  &\r
+                    irq.obj      &\r
+                    ll_man.obj   &\r
+                    multivoc.obj &\r
+                    mv_mix.obj   &\r
+                    pas16.obj    &\r
+                    pitch.obj    &\r
+                    sndscape.obj &\r
+                    sndsrc.obj   &\r
+                    task_man.obj &\r
+                    user.obj\r
+\r
+\r
+msg_debugging       = Creating debugging library...\r
+tasm_debugging      = /t  /zi /p  /mx /w2 $(tasm_include_dir)\r
+wcc_debugging       = /zq /w4 /d2 /i=$(header_dir)\r
+wlink_debugging     =\r
+\r
+gus_debugging       = /zq /w4 /d2 /i=$(header_dir)\r
+gusmidi_debugging   = /zq /w4 /d2 /i=$(header_dir)\r
+multivoc_debugging  = /zq /w4 /d1 /omaxne /zp4 /5r /zu /d2 /i=$(header_dir)\r
+pas16_debugging     = /zq /w4 /d1 /omaxnet /zp4 /5r /i=$(header_dir)\r
+task_man_debugging  = /zq /w4 /d1 /omaxnet /zp4 /5r /i=$(header_dir)\r
+midi_debugging      = /zq /w4 /d2 /zu /i=$(header_dir)\r
+al_midi_debugging   = /zq /w4 /d2 /zu /i=$(header_dir)\r
+\r
+msg_production      = Creating production library...\r
+tasm_production     = /t  /zi /p  /mx /w2 $(tasm_include_dir)\r
+#tasm_production     = /m /oi /zi $(tasm_include_dir)\r
+wcc_production      = /zq /w4 /d1 /omaxnet /zp4 /5r /i=$(header_dir)\r
+wlink_production    =\r
+\r
+gus_production      = /zq /w4 /d2 /i=$(header_dir)\r
+gusmidi_production  = /zq /w4 /d2 /i=$(header_dir)\r
+multivoc_production = /zq /w4 /d1 /omaxne /zp4 /5r /zu /i=$(header_dir)\r
+music_production    = /zq /w4 /d1 /omaxne /zp4 /5r /zu /i=$(header_dir)\r
+pas16_production    = /zq /w4 /d1 /omaxnet /zp4 /5r /i=$(header_dir)\r
+task_man_production = /zq /w4 /d1 /omaxnet /zp4 /5r /i=$(header_dir)\r
+midi_production     = /zq /w4 /d1 /omaxnet /zp4 /5r /zu /i=$(header_dir)\r
+al_midi_production  = /zq /w4 /d1 /omaxnet /zp4 /5r /zu /i=$(header_dir)\r
+\r
+$(final_lib) : $(lib_name)\r
+   copy $(lib_name) $(final_lib)\r
+\r
+$(lib_name) : $(object_files) audio.mak\r
+   @echo $(msg_$(version))\r
+   %create temp.lnk\r
+   for %i in ($(object_files)) do %append temp.lnk -+$(obj_dir)\%i\r
+   for %i in ($(lib_files)) do %append temp.lnk -+$(lib_dir)\%i\r
+   wlib $^@ /n /b @temp.lnk\r
+   del temp.lnk\r
+\r
+.asm.obj :\r
+   tasm $(tasm_$(version)) $[* $(obj_dir)\$^&\r
+\r
+.c.obj :\r
+   wcc386 $(wcc_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+\r
+al_midi.obj  : al_midi.c dpmi.h interrupt.h sndcards.h blaster.h user.h al_midi.h _al_midi.h ll_man.h\r
+   wcc386 $(al_midi_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+awe32.obj    : awe32.c dpmi.h blaster.h ctaweapi.h awe32.h\r
+\r
+blaster.obj  : blaster.c dpmi.h dma.h irq.h blaster.h _blaster.h\r
+\r
+debugio.obj  : debugio.c debugio.h\r
+\r
+dma.obj      : dma.c dma.h\r
+\r
+dpmi.obj     : dpmi.c dpmi.h\r
+\r
+fx_man.obj   : fx_man.c ll_man.h sndcards.h multivoc.h blaster.h pas16.h &\r
+   sndscape.h guswave.h sndsrc.h user.h fx_man.h\r
+\r
+$(timbre_file).obj : $(timbre_file).c\r
+\r
+gus.obj      : gus.c usrhooks.h interrupt.h gusmidi.h guswave.h _guswave.h newgf1.h\r
+   wcc386 $(gus_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+gusmidi.obj  : gusmidi.c usrhooks.h interrupt.h gusmidi.h newgf1.h\r
+   wcc386 $(gusmidi_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+guswave.obj  : guswave.c debugio.h interrupt.h ll_man.h pitch.h user.h _guswave.h guswave.h newgf1.h multivoc.h\r
+\r
+irq.obj      : irq.c irq.h\r
+\r
+ll_man.obj   : ll_man.c dpmi.h ll_man.h\r
+\r
+midi.obj     : midi.c interrupt.h dpmi.h standard.h task_man.h ll_man.h usrhooks.h music.h _midi.h midi.h sndcards.h\r
+   wcc386 $(midi_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+mpu401.obj   : mpu401.c dpmi.h user.h mpu401.h\r
+\r
+multivoc.obj : multivoc.c usrhooks.h interrupt.h dpmi.h ll_man.h sndcards.h &\r
+   blaster.h sndscape.h pas16.h sndsrc.h pitch.h multivoc.h _multivc.h dma.h\r
+   wcc386 $(multivoc_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+mv_mix.obj   : mv_mix.asm\r
+mv_mix16.obj : mv_mix16.asm\r
+mvreverb.obj : mvreverb.asm\r
+\r
+music.obj    : music.c ll_man.h task_man.h sndcards.h midi.h al_midi.h pas16.h blaster.h gusmidi.h mpu401.h awe32.h sndscape.h user.h music.h\r
+   wcc386 $(music_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+pas16.obj    : pas16.c dpmi.h dma.h interrupt.h irq.h pas16.h _pas16.h\r
+   wcc386 $(pas16_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+pitch.obj    : pitch.c dpmi.h standard.h pitch.h\r
+\r
+sndscape.obj : sndscape.c interrupt.h dpmi.h dma.h irq.h sndscape.h _sndscap.h\r
+\r
+sndsrc.obj   : sndsrc.c dpmi.h task_man.h sndcards.h user.h sndsrc.h\r
+\r
+task_man.obj : task_man.c dpmi.h interrupt.h linklist.h usrhooks.h task_man.h\r
+   wcc386 $(task_man_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+user.obj     : user.c user.h\r
+\r
+#myprint.obj  : myprint.c myprint.h\r
diff --git a/audiolib/AUDIO2.MAK b/audiolib/AUDIO2.MAK
new file mode 100644 (file)
index 0000000..439e428
--- /dev/null
@@ -0,0 +1,192 @@
+.OPTIMIZE\r
+\r
+version = production\r
+#version = debugging\r
+\r
+timbre_file       = gmtimbre\r
+#timbre_file       = leetimbr\r
+\r
+prg_dir           = .\r
+obj_debugging     = $(prg_dir)\objdb\r
+obj_production    = $(prg_dir)\obj\r
+obj_dir           = $(obj_$(version))\r
+lib_dir           = $(prg_dir)\lib\r
+output_dir        = $(prg_dir)\r
+main_dir          = $(prg_dir)\source\r
+header_dir        = $(main_dir)\r
+tasm_include_dir  = /i$(main_dir)\r
+\r
+model             = f\r
+compiler          = w\r
+lib_filename      = audio_$(compiler)$(model).lib\r
+lib_name          = $(obj_dir)\$(lib_filename)\r
+final_lib         = $(output_dir)\$(lib_filename)\r
+\r
+.h   :              $(header_dir)\r
+.c   :              $(header_dir)\r
+.asm :              $(header_dir)\r
+.obj :              $(obj_dir)\r
+\r
+offlib_files     = gf1_osf.lib\r
+lib_files         = gf1_osf.lib &\r
+                    pawe32.lib\r
+\r
+#object_files      = &\r
+object_files      = $(timbre_file).obj &\r
+                    adlibfx.obj  &\r
+                    al_midi.obj  &\r
+                    awe32.obj    &\r
+                    blaster.obj  &\r
+                    debugio.obj  &\r
+                    dma.obj      &\r
+                    dpmi.obj     &\r
+                    fx_man.obj   &\r
+                    gus.obj      &\r
+                    gusmidi.obj  &\r
+                    guswave.obj  &\r
+                    irq.obj      &\r
+                    ll_man.obj   &\r
+                    midi.obj     &\r
+                    mpu401.obj   &\r
+                    multivoc.obj &\r
+                    mv_mix.obj   &\r
+                    music.obj    &\r
+                    pas16.obj    &\r
+                    pcfx.obj     &\r
+                    pitch.obj    &\r
+                    sndscape.obj &\r
+                    sndsrc.obj   &\r
+                    task_man.obj &\r
+                    user.obj\r
+\r
+offobject_files      = adlibfx.obj  &\r
+                    blaster.obj  &\r
+                    debugio.obj  &\r
+                    dma.obj      &\r
+                    dpmi.obj     &\r
+                    fx_man.obj   &\r
+                    gus.obj      &\r
+                    guswave.obj  &\r
+                    irq.obj      &\r
+                    ll_man.obj   &\r
+                    multivoc.obj &\r
+                    mv_mix.obj   &\r
+                    pas16.obj    &\r
+                    pcfx.obj     &\r
+                    pitch.obj    &\r
+                    sndscape.obj &\r
+                    sndsrc.obj   &\r
+                    task_man.obj &\r
+                    user.obj\r
+\r
+\r
+msg_debugging       = Creating debugging library...\r
+tasm_debugging      = /t  /zi /p  /mx /w2 $(tasm_include_dir)\r
+wcc_debugging       = /zq /w4 /d2 /i=$(header_dir)\r
+wlink_debugging     =\r
+\r
+gus_debugging       = /zq /w4 /d2 /i=$(header_dir)\r
+gusmidi_debugging   = /zq /w4 /d2 /i=$(header_dir)\r
+multivoc_debugging  = /zq /w4 /d1 /omaxne /zp4 /5r /zu /d2 /i=$(header_dir)\r
+pas16_debugging     = /zq /w4 /d1 /omaxnet /zp4 /5r /i=$(header_dir)\r
+task_man_debugging  = /zq /w4 /d1 /omaxnet /zp4 /5r /i=$(header_dir)\r
+midi_debugging      = /zq /w4 /d2 /zu /i=$(header_dir)\r
+al_midi_debugging   = /zq /w4 /d2 /zu /i=$(header_dir)\r
+\r
+msg_production      = Creating production library...\r
+tasm_production     = /t  /zi /p  /mx /w2 $(tasm_include_dir)\r
+wcc_production      = /zq /w4 /d1 /omaxnet /zp4 /5r /i=$(header_dir)\r
+wlink_production    =\r
+\r
+gus_production      = /zq /w4 /d2 /i=$(header_dir)\r
+gusmidi_production  = /zq /w4 /d2 /i=$(header_dir)\r
+multivoc_production = /zq /w4 /d1 /omaxne /zp4 /5r /zu /i=$(header_dir)\r
+pas16_production    = /zq /w4 /d1 /omaxnet /zp4 /5r /i=$(header_dir)\r
+task_man_production = /zq /w4 /d1 /omaxnet /zp4 /5r /i=$(header_dir)\r
+midi_production     = /zq /w4 /d1 /omaxnet /zp4 /5r /zu /i=$(header_dir)\r
+al_midi_production  = /zq /w4 /d1 /omaxnet /zp4 /5r /zu /i=$(header_dir)\r
+\r
+$(final_lib) : $(lib_name)\r
+   copy $(lib_name) $(final_lib)\r
+\r
+$(lib_name) : $(object_files) audio.mak\r
+   echo ******************************************************************\r
+   echo\r
+   echo $(msg_$(version))\r
+   echo\r
+   echo ******************************************************************\r
+   %create temp.lnk\r
+   for %i in ($(object_files)) do %append temp.lnk -+$(obj_dir)\%i\r
+   for %i in ($(lib_files)) do %append temp.lnk -+$(lib_dir)\%i\r
+   wlib $^@ /n /b @temp.lnk\r
+   del temp.lnk\r
+\r
+.asm.obj :\r
+   tasm $(tasm_$(version)) $[* $(obj_dir)\$^&\r
+\r
+.c.obj :\r
+   wcc386 $(wcc_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+\r
+adlibfx.obj  : adlibfx.c dpmi.h task_man.h interrupt.h al_midi.h adlibfx.h\r
+\r
+al_midi.obj  : al_midi.c dpmi.h interrupt.h sndcards.h blaster.h user.h al_midi.h _al_midi.h ll_man.h\r
+   wcc386 $(al_midi_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+awe32.obj    : awe32.c dpmi.h blaster.h ctaweapi.h awe32.h\r
+\r
+blaster.obj  : blaster.c dpmi.h dma.h irq.h blaster.h _blaster.h\r
+\r
+debugio.obj  : debugio.c debugio.h\r
+\r
+dma.obj      : dma.c dma.h\r
+\r
+dpmi.obj     : dpmi.c dpmi.h\r
+\r
+fx_man.obj   : fx_man.c ll_man.h sndcards.h multivoc.h blaster.h pas16.h &\r
+   sndscape.h guswave.h sndsrc.h adlibfx.h pcfx.h user.h fx_man.h\r
+\r
+$(timbre_file).obj : $(timbre_file).c\r
+\r
+gus.obj      : gus.c usrhooks.h interrupt.h gusmidi.h guswave.h _guswave.h newgf1.h\r
+   wcc386 $(gus_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+gusmidi.obj  : gusmidi.c usrhooks.h interrupt.h gusmidi.h newgf1.h\r
+   wcc386 $(gusmidi_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+guswave.obj  : guswave.c debugio.h interrupt.h ll_man.h pitch.h user.h _guswave.h guswave.h newgf1.h multivoc.h\r
+\r
+irq.obj      : irq.c irq.h\r
+\r
+ll_man.obj   : ll_man.c dpmi.h ll_man.h\r
+\r
+midi.obj     : midi.c interrupt.h dpmi.h standard.h task_man.h ll_man.h usrhooks.h _midi.h midi.h\r
+   wcc386 $(midi_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+mpu401.obj   : mpu401.c dpmi.h user.h mpu401.h\r
+\r
+multivoc.obj : multivoc.c usrhooks.h interrupt.h dpmi.h ll_man.h sndcards.h &\r
+   blaster.h sndscape.h pas16.h sndsrc.h pitch.h multivoc.h _multivc.h dma.h\r
+   wcc386 $(multivoc_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+mv_mix.obj   : mv_mix.asm\r
+\r
+music.obj    : music.c ll_man.h task_man.h sndcards.h midi.h al_midi.h pas16.h blaster.h gusmidi.h mpu401.h awe32.h sndscape.h user.h music.h\r
+\r
+pas16.obj    : pas16.c dpmi.h dma.h interrupt.h irq.h pas16.h _pas16.h\r
+   wcc386 $(pas16_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+pcfx.obj     : pcfx.c dpmi.h task_man.h interrupt.h pcfx.h\r
+\r
+pitch.obj    : pitch.c dpmi.h standard.h pitch.h\r
+\r
+sndscape.obj : sndscape.c interrupt.h dpmi.h dma.h irq.h sndscape.h _sndscap.h\r
+\r
+sndsrc.obj   : sndsrc.c dpmi.h task_man.h sndcards.h user.h sndsrc.h\r
+\r
+task_man.obj : task_man.c dpmi.h interrupt.h linklist.h usrhooks.h task_man.h\r
+   wcc386 $(task_man_$(version)) $[* /fo=$(obj_dir)\$^&\r
+\r
+user.obj     : user.c user.h\r
+\r
+#myprint.obj  : myprint.c myprint.h\r
diff --git a/audiolib/AUDIO_WF.LIB b/audiolib/AUDIO_WF.LIB
new file mode 100644 (file)
index 0000000..1e894a5
Binary files /dev/null and b/audiolib/AUDIO_WF.LIB differ
diff --git a/audiolib/DOPUBLIC.BAT b/audiolib/DOPUBLIC.BAT
new file mode 100644 (file)
index 0000000..ed05d7a
--- /dev/null
@@ -0,0 +1,17 @@
+call wmake.bat\r
+copy audio_wf.lib      public\r
+copy notes.txt         public\r
+copy midi.txt          public\r
+copy notes.txt         public\r
+copy audio_wf.lib      public\include\r
+copy source\fx_man.h   public\include\r
+copy source\music.h    public\include\r
+copy source\sndcards.h public\include\r
+copy source\task_man.h public\include\r
+cd public\timer\r
+wmake\r
+cd ..\..\public\ps\r
+wmake\r
+cd ..\..\public\pm\r
+wmake\r
+cd ..\..\r
diff --git a/audiolib/GUS/GUSROTT.INI b/audiolib/GUS/GUSROTT.INI
new file mode 100644 (file)
index 0000000..f761176
--- /dev/null
@@ -0,0 +1,205 @@
+#\r
+#    GUSROTT.INI - Gravis Ultrasound<TM> .INI file for use with\r
+#                  Rise of the Triad<TM> by Apogee Software, Ltd.\r
+#                  Patch data configured by Lee Jackson.\r
+#\r
+#    *** WARNING - DO NOT EDIT OR IN ANY WAY CHANGE THIS FILE!!! ***\r
+#\r
+#    Ultrasound<TM> is a trademark of Advanced Gravis Computer\r
+#    Technology, Ltd.\r
+#\r
+#    Rise of the Triad<TM> is a trademark of Apogee Software, Ltd.\r
+#\r
+#\r
+#Explanation of Columns: Patch #  256K  512K  768K  1024K  Patch Name\r
+#\r
+0, 2, 2, 1, 0, acpiano\r
+1, 2, 2, 1, 1, britepno\r
+2, 128, 128, 128, 128, synpiano\r
+3, 128, 128, 128, 128, honky\r
+4, 2, 2, 4, 4, epiano1\r
+5, 128, 128, 128, 128, epiano2\r
+6, 128, 128, 128, 128, hrpschrd\r
+7, 128, 128, 128, 128, clavinet\r
+8, 128, 128, 128, 128, celeste\r
+9, 128, 128, 128, 128, glocken\r
+10, 128, 128, 128, 128, musicbox\r
+11, 2, 11, 11, 11, vibes\r
+12, 128, 128, 128, 128, marimba\r
+13, 128, 128, 128, 128, xylophon\r
+14, 2, 14, 14, 14, tubebell\r
+15, 128, 128, 128, 128, santur\r
+16, 128, 128, 128, 128, homeorg\r
+17, 20, 17, 17, 17, percorg\r
+18, 128, 128, 128, 128, rockorg\r
+19, 20, 19, 19, 19, church\r
+20, 20, 20, 20, 20, reedorg\r
+21, 2, 21, 21, 21, accordn\r
+22, 128, 128, 128, 128, harmonca\r
+23, 128, 128, 128, 128, concrtna\r
+24, 128, 128, 128, 128, nyguitar\r
+25, 128, 128, 128, 128, acguitar\r
+26, 128, 128, 128, 128, jazzgtr\r
+27, 24, 27, 27, 27, cleangtr\r
+28, 24, 28, 28, 28, mutegtr\r
+29, 29, 29, 29, 29, odguitar\r
+30, 29, 30, 30, 30, distgtr\r
+31, 29, 29, 30, 31, gtrharm\r
+32, 128, 128, 128, 128, acbass\r
+33, 39, 33, 33, 33, fngrbass\r
+34, 39, 33, 34, 34, pickbass\r
+35, 39, 33, 33, 35, fretless\r
+36, 39, 36, 36, 36, slapbas1\r
+37, 39, 36, 36, 37, slapbas2\r
+38, 39, 38, 38, 38, synbass1\r
+39, 39, 38, 38, 39, synbass2\r
+40, 128, 128, 128, 128, violin\r
+41, 128, 128, 128, 128, viola\r
+42, 128, 128, 128, 128, cello\r
+43, 128, 128, 128, 128, contraba\r
+44, 128, 128, 128, 128, tremstr\r
+45, 2, 46, 45, 45, pizzcato\r
+46, 2, 46, 46, 46, harp\r
+47, 47, 47, 47, 47, timpani\r
+48, 51, 51, 48, 48, marcato\r
+49, 128, 128, 128, 128, slowstr\r
+50, 128, 128, 128, 128, synstr1\r
+51, 51, 51, 51, 51, synstr2\r
+52, 52, 52, 52, 52, choir\r
+53, 128, 128, 128, 128, doo\r
+54, 128, 128, 128, 128, voices\r
+55, 128, 128, 128, 128, orchhit\r
+56, 56, 56, 56, 56, trumpet\r
+57, 56, 56, 56, 57, trombone\r
+58, 56, 56, 58, 58, tuba\r
+59, 128, 128, 128, 128, mutetrum\r
+60, 56, 60, 60, 60, frenchrn\r
+61, 56, 61, 61, 61, hitbrass\r
+62, 56, 56, 62, 62, synbras1\r
+63, 56, 56, 62, 62, synbras2\r
+64, 128, 128, 128, 128, sprnosax\r
+65, 65, 65, 65, 65, altosax\r
+66, 65, 65, 65, 66, tenorsax\r
+67, 128, 128, 128, 128, barisax\r
+68, 65, 65, 68, 68, oboe\r
+69, 128, 128, 128, 128, englhorn\r
+70, 128, 128, 128, 128, bassoon\r
+71, 65, 71, 71, 71, clarinet\r
+72, 128, 128, 128, 128, piccolo\r
+73, 73, 73, 73, 73, flute\r
+74, 128, 128, 128, 128, recorder\r
+75, 128, 128, 128, 128, woodflut\r
+76, 128, 128, 128, 128, bottle\r
+77, 128, 128, 128, 128, shakazul\r
+78, 73, 73, 73, 73, whistle\r
+79, 73, 73, 73, 79, ocarina\r
+80, 81, 80, 80, 80, sqrwave\r
+81, 81, 81, 81, 81, sawwave\r
+82, 20, 20, 20, 20, calliope\r
+83, 128, 128, 128, 128, chiflead\r
+84, 128, 128, 128, 128, charang\r
+85, 128, 128, 128, 128, voxlead\r
+86, 52, 52, 29, 29, lead5th\r
+87, 128, 128, 128, 128, basslead\r
+88, 128, 128, 128, 128, fantasia\r
+89, 128, 128, 128, 128, warmpad\r
+90, 128, 128, 128, 128, polysyn\r
+91, 81, 81, 81, 81, ghostie\r
+92, 128, 128, 128, 128, bowglass\r
+93, 52, 52, 52, 103, metalpad\r
+94, 19, 19, 19, 19, halopad\r
+95, 52, 52, 52, 95, sweeper\r
+96, 128, 128, 128, 128, aurora\r
+97, 128, 128, 128, 128, soundtrk\r
+98, 128, 128, 128, 128, crystal\r
+99, 128, 128, 128, 128, atmosphr\r
+100, 128, 128, 128, 128, freshair\r
+101, 128, 128, 128, 128, unicorn\r
+102, 128, 128, 128, 128, echovox\r
+103, 52, 52, 103, 103, startrak\r
+104, 128, 128, 128, 128, sitar\r
+105, 128, 128, 128, 128, banjo\r
+106, 128, 128, 128, 128, shamisen\r
+107, 128, 128, 128, 128, koto\r
+108, 128, 128, 128, 128, kalimba\r
+109, 128, 128, 128, 128, bagpipes\r
+110, 128, 128, 128, 128, fiddle\r
+111, 128, 128, 128, 128, shannai\r
+112, 128, 128, 128, 128, carillon\r
+113, 128, 128, 128, 128, agogo\r
+114, 128, 128, 128, 128, steeldrm\r
+115, 128, 128, 128, 128, woodblk\r
+116, 128, 128, 128, 128, taiko\r
+117, 47, 117, 117, 117, toms\r
+118, 128, 128, 128, 128, syntom\r
+119, 128, 128, 128, 119, revcym\r
+120, 128, 128, 128, 128, fx-fret\r
+121, 128, 128, 128, 128, fx-blow\r
+122, 128, 128, 128, 128, seashore\r
+123, 128, 128, 128, 128, jungle\r
+124, 128, 128, 128, 128, telephon\r
+125, 128, 128, 128, 128, helicptr\r
+126, 128, 128, 128, 128, applause\r
+127, 128, 128, 128, 128, pistol\r
+128, 128, 128, 128, 128, blank\r
+155, 128, 128, 128, 128, highq\r
+156, 128, 128, 128, 128, slap\r
+157, 128, 128, 128, 128, scratch1\r
+158, 128, 128, 128, 128, scratch2\r
+159, 128, 128, 128, 128, sticks\r
+160, 128, 128, 128, 128, sqrclick\r
+161, 128, 128, 128, 128, metclick\r
+162, 128, 128, 128, 128, metbell\r
+163, 164, 164, 163, 163, kick1\r
+164, 164, 164, 164, 164, kick2\r
+165, 165, 165, 165, 165, stickrim\r
+166, 168, 168, 166, 166, snare1\r
+167, 165, 167, 167, 167, claps\r
+168, 168, 168, 168, 168, snare2\r
+169, 175, 171, 169, 169, tomlo2\r
+170, 170, 170, 170, 170, hihatcl\r
+171, 175, 171, 171, 171, tomlo1\r
+172, 172, 172, 172, 172, hihatpd\r
+173, 175, 175, 173, 173, tommid2\r
+174, 174, 174, 174, 174, hihatop\r
+175, 178, 175, 175, 175, tommid1\r
+176, 178, 178, 176, 176, tomhi2\r
+177, 185, 177, 177, 177, cymcrsh1\r
+178, 178, 178, 178, 178, tomhi1\r
+179, 179, 179, 179, 179, cymride1\r
+180, 185, 177, 177, 180, cymchina\r
+181, 179, 179, 179, 181, cymbell\r
+182, 170, 182, 182, 182, tamborin\r
+183, 185, 177, 177, 183, cymsplsh\r
+184, 205, 205, 205, 184, cowbell\r
+185, 185, 177, 177, 185, cymcrsh2\r
+186, 128, 186, 186, 186, vibslap\r
+187, 179, 179, 179, 187, cymride2\r
+188, 128, 128, 128, 128, bongohi\r
+189, 128, 128, 128, 128, bongolo\r
+190, 190, 190, 190, 190, congahi1\r
+191, 190, 191, 191, 191, congahi2\r
+192, 192, 192, 192, 192, congalo\r
+193, 190, 191, 193, 193, timbaleh\r
+194, 192, 192, 194, 194, timbalel\r
+195, 128, 128, 128, 128, agogohi\r
+196, 128, 128, 128, 128, agogolo\r
+197, 170, 170, 170, 210, cabasa\r
+198, 128, 128, 128, 128, maracas\r
+199, 128, 128, 128, 128, whistle1\r
+200, 128, 128, 128, 128, whistle2\r
+201, 128, 201, 201, 201, guiro1\r
+202, 128, 202, 202, 202, guiro2\r
+203, 205, 205, 203, 203, clave\r
+204, 205, 205, 204, 204, woodblk1\r
+205, 205, 205, 205, 205, woodblk2\r
+206, 128, 206, 206, 206, cuica1\r
+207, 128, 128, 128, 128, cuica2\r
+208, 128, 128, 128, 128, triangl1\r
+209, 179, 179, 179, 181, triangl2\r
+210, 170, 170, 170, 210, shaker\r
+211, 170, 182, 182, 182, jingles\r
+212, 128, 128, 128, 128, belltree\r
+213, 128, 128, 128, 128, castinet\r
+214, 128, 128, 128, 128, surdo1\r
+215, 128, 128, 128, 128, surdo2\r
diff --git a/audiolib/GUS/UCALC.EXE b/audiolib/GUS/UCALC.EXE
new file mode 100644 (file)
index 0000000..0758043
Binary files /dev/null and b/audiolib/GUS/UCALC.EXE differ
diff --git a/audiolib/GUS/ULTRAMID.INI b/audiolib/GUS/ULTRAMID.INI
new file mode 100644 (file)
index 0000000..59689bb
--- /dev/null
@@ -0,0 +1,200 @@
+#Purpose: Different size patch libraries for different memory sizes.\r
+#         The libraries are built in such a way as to leave 8K+32bytes\r
+#         after the patches are loaded for digital audio.\r
+#\r
+#Revision History: 06/22/93 - Fixed problem with 512K patch library\r
+#                  07/26/93 - patch names changed in various releases\r
+#\r
+#\r
+#Explanation of Columns: Patch #  256K  512K  768K  1024K  Patch Name\r
+#\r
+0, 2, 1, 1, 1, acpiano\r
+1, 2, 1, 1, 1, britepno\r
+2, 2, 1, 1, 1, synpiano\r
+3, 2, 1, 1, 1, honktonk\r
+4, 2, 1, 1, 4, epiano1\r
+5, 2, 1, 1, 4, epiano2\r
+6, 2, 1, 1, 1, hrpschrd\r
+7, 2, 1, 1, 1, clavinet\r
+8, 12, 12, 12, 12, celeste\r
+9, 12, 12, 12, 12, glocken\r
+10, 12, 12, 12, 12, musicbox\r
+11, 12, 12, 12, 12, vibes\r
+12, 12, 12, 12, 12, marimba\r
+13, 12, 12, 12, 12, xylophon\r
+14, 12, 12, 12, 12, tubebell\r
+15, 12, 12, 12, 12, santur\r
+16, 2, 16, 16, 19, homeorg\r
+17, 2, 16, 16, 19, percorg\r
+18, 2, 16, 16, 19, rockorg\r
+19, 2, 16, 16, 19, church\r
+20, 2, 16, 16, 19, reedorg\r
+21, 2, 16, 16, 19, accordn\r
+22, 2, 16, 16, 19, harmonca\r
+23, 2, 16, 16, 19, concrtna\r
+24, 24, 24, 24, 24, nyguitar\r
+25, 24, 24, 24, 24, acguitar\r
+26, 24, 24, 24, 24, jazzgtr\r
+27, 24, 24, 24, 27, cleangtr\r
+28, 24, 24, 24, 24, mutegtr\r
+29, 29, 29, 29, 29, odguitar\r
+30, 29, 30, 30, 30, distgtr\r
+31, 29, 30, 30, 31, gtrharm\r
+32, 39, 32, 32, 32, acbass\r
+33, 39, 32, 32, 32, fngrbass\r
+34, 39, 32, 32, 34, pickbass\r
+35, 39, 32, 32, 32, fretless\r
+36, 39, 36, 36, 36, slapbas1\r
+37, 39, 36, 36, 36, slapbas2\r
+38, 39, 36, 36, 32, synbass1\r
+39, 39, 36, 36, 32, synbass2\r
+40, 40, 40, 40, 40, violin\r
+41, 40, 40, 40, 40, viola\r
+42, 40, 42, 42, 42, cello\r
+43, 40, 40, 40, 40, contraba\r
+44, 40, 40, 40, 40, marcato\r
+45, 40, 40, 40, 45, pizzcato\r
+46, 24, 24, 46, 46, harp\r
+47, 47, 47, 47, 47, timpani\r
+48, 51, 51, 48, 48, marcato\r
+49, 51, 51, 49, 48, slowstr\r
+50, 51, 51, 48, 48, synstr1\r
+51, 51, 51, 48, 48, synstr2\r
+52, 52, 52, 52, 52, choir\r
+53, 52, 52, 52, 52, doo\r
+54, 52, 52, 52, 54, voices\r
+55, 128, 128, 55, 55, orchhit\r
+56, 56, 56, 56, 56, trumpet\r
+57, 56, 56, 56, 56, trombone\r
+58, 56, 56, 56, 58, tuba\r
+59, 56, 56, 56, 56, mutetrum\r
+60, 56, 56, 56, 56, frenchrn\r
+61, 56, 56, 56, 56, hitbrass\r
+62, 56, 56, 56, 56, synbras1\r
+63, 56, 56, 56, 56, synbras2\r
+64, 66, 66, 64, 64, sprnosax\r
+65, 66, 66, 66, 66, altosax\r
+66, 66, 66, 66, 66, tenorsax\r
+67, 66, 66, 66, 66, barisax\r
+68, 68, 69, 69, 69, oboe\r
+69, 68, 69, 69, 69, englhorn\r
+70, 68, 69, 69, 70, bassoon\r
+71, 68, 69, 69, 71, clarinet\r
+72, 73, 73, 73, 73, piccolo\r
+73, 73, 73, 73, 73, flute\r
+74, 73, 73, 73, 73, recorder\r
+75, 73, 73, 73, 75, woodflut\r
+76, 73, 73, 73, 75, bottle\r
+77, 73, 77, 77, 77, shakazul\r
+78, 73, 73, 73, 73, whistle\r
+79, 73, 73, 73, 73, ocarina\r
+80, 29, 29, 29, 29, sqrwave\r
+81, 29, 29, 29, 29, sawwave\r
+82, 73, 73, 29, 82, calliope\r
+83, 73, 73, 29, 29, chiflead\r
+84, 29, 29, 29, 29, voxlead\r
+85, 52, 52, 29, 85, voxlead\r
+86, 52, 52, 29, 86, lead5th\r
+87, 52, 52, 29, 34, basslead\r
+88, 52, 52, 88, 88, fantasia\r
+89, 52, 52, 29, 89, warmpad\r
+90, 52, 52, 29, 89, polysyn\r
+91, 52, 52, 29, 89, ghostie\r
+92, 52, 52, 29, 89, bowglass\r
+93, 52, 52, 29, 89, metalpad\r
+94, 52, 52, 29, 89, halopad\r
+95, 52, 52, 29, 89, sweeper\r
+96, 52, 52, 96, 89, aurora\r
+97, 52, 52, 52, 89, soundtrk\r
+98, 52, 52, 52, 89, crystal\r
+99, 52, 52, 52, 89, atmosphr\r
+100, 52, 52, 52, 89, freshair\r
+101, 52, 52, 52, 89, unicorn\r
+102, 52, 102, 102, 89, ghostie\r
+103, 52, 102, 102, 89, startrak\r
+104, 24, 102, 102, 104, sitar\r
+105, 24, 105, 105, 105, banjo\r
+106, 24, 105, 105, 105, shamisen\r
+107, 24, 105, 105, 105, koto\r
+108, 115, 115, 115, 115, kalimba\r
+109, 24, 69, 105, 109, bagpipes\r
+110, 24, 42, 42, 42, fiddle\r
+111, 24, 105, 105, 105, shannai\r
+112, 114, 114, 112, 112, carillon\r
+113, 114, 114, 112, 112, agogo\r
+114, 114, 114, 114, 114, steeldrm\r
+115, 115, 115, 115, 115, woodblk\r
+116, 115, 117, 117, 117, taiko\r
+117, 115, 117, 117, 117, toms\r
+118, 115, 117, 117, 117, syntom\r
+119, 128, 128, 128, 128, revcym\r
+120, 128, 128, 128, 128, fx-fret\r
+121, 128, 128, 128, 128, fx-blow\r
+122, 128, 128, 128, 122, seashore\r
+123, 128, 128, 128, 128, jungle\r
+124, 128, 128, 128, 128, telephon\r
+125, 128, 128, 128, 128, helicptr\r
+126, 128, 128, 126, 126, applause\r
+127, 128, 128, 128, 128, ringwhsl\r
+128, 128, 128, 128, 128, blank\r
+155, 128, 128, 128, 128, highq\r
+156, 128, 128, 128, 128, slap\r
+157, 128, 128, 128, 157, scratch1\r
+158, 128, 128, 128, 158, scratch2\r
+159, 159, 159, 159, 159, sticks\r
+160, 128, 128, 128, 160, sqrclick\r
+161, 128, 128, 128, 160, metclick\r
+162, 128, 128, 128, 128, metbell\r
+163, 163, 163, 163, 163, kick1\r
+164, 164, 164, 164, 164, kick2\r
+165, 165, 165, 165, 165, stickrim\r
+166, 166, 166, 166, 166, snare1\r
+167, 167, 167, 167, 167, claps\r
+168, 168, 168, 168, 168, snare2\r
+169, 171, 169, 169, 169, tomlo2\r
+170, 170, 170, 170, 170, hihatcl\r
+171, 171, 171, 171, 171, tomlo1\r
+172, 172, 172, 172, 172, hihatpd\r
+173, 175, 173, 173, 173, tommid2\r
+174, 174, 174, 174, 174, hihatop\r
+175, 175, 175, 175, 175, tommid1\r
+176, 178, 176, 176, 176, tomhi2\r
+177, 181, 177, 177, 177, cymcrsh1\r
+178, 178, 178, 178, 178, tomhi1\r
+179, 181, 177, 177, 177, cymride1\r
+180, 181, 177, 177, 180, cymchina\r
+181, 181, 177, 177, 181, cymbell\r
+182, 182, 182, 182, 182, tamborin\r
+183, 181, 177, 177, 177, cymsplsh\r
+184, 128, 128, 128, 128, cowbell\r
+185, 181, 177, 177, 177, cymcrsh2\r
+186, 128, 128, 128, 128, vibslap\r
+187, 181, 177, 177, 177, cymride2\r
+188, 178, 188, 188, 188, bongohi\r
+189, 175, 189, 189, 189, bongolo\r
+190, 175, 190, 190, 190, congahi1\r
+191, 175, 191, 191, 191, congahi2\r
+192, 171, 191, 191, 192, congalo\r
+193, 128, 128, 128, 193, timbaleh\r
+194, 128, 128, 128, 194, timbalel\r
+195, 128, 128, 128, 195, agogohi\r
+196, 128, 128, 128, 196, agogolo\r
+197, 128, 128, 128, 128, cabasa\r
+198, 128, 198, 198, 198, maracas\r
+199, 128, 128, 128, 128, whistle1\r
+200, 128, 128, 128, 128, whistle2\r
+201, 128, 128, 128, 128, guiro1\r
+202, 128, 128, 128, 128, guiro2\r
+203, 128, 128, 128, 128, clave\r
+204, 128, 204, 204, 204, woodblk1\r
+205, 128, 205, 205, 205, woodblk2\r
+206, 128, 128, 128, 206, cuica1\r
+207, 128, 128, 128, 207, cuica2\r
+208, 128, 128, 128, 208, triangl1\r
+209, 128, 128, 128, 209, triangl2\r
+210, 128, 128, 128, 128, shaker\r
+211, 128, 128, 128, 128, jingles\r
+212, 128, 128, 128, 128, belltree\r
+213, 128, 128, 128, 128, castinet\r
+214, 128, 128, 128, 128, surdo1\r
+215, 128, 128, 128, 128, surdo2\r
diff --git a/audiolib/LIB/GF1_OSF.LB2 b/audiolib/LIB/GF1_OSF.LB2
new file mode 100644 (file)
index 0000000..c14bc30
Binary files /dev/null and b/audiolib/LIB/GF1_OSF.LB2 differ
diff --git a/audiolib/LIB/GF1_OSF.LBK b/audiolib/LIB/GF1_OSF.LBK
new file mode 100644 (file)
index 0000000..d69914e
Binary files /dev/null and b/audiolib/LIB/GF1_OSF.LBK differ
diff --git a/audiolib/LIB/GF1_OSF.LIB b/audiolib/LIB/GF1_OSF.LIB
new file mode 100644 (file)
index 0000000..d69914e
Binary files /dev/null and b/audiolib/LIB/GF1_OSF.LIB differ
diff --git a/audiolib/LIB/PAWE32.LIB b/audiolib/LIB/PAWE32.LIB
new file mode 100644 (file)
index 0000000..b4fc89b
Binary files /dev/null and b/audiolib/LIB/PAWE32.LIB differ
diff --git a/audiolib/MAKEDB.BAT b/audiolib/MAKEDB.BAT
new file mode 100644 (file)
index 0000000..aea497f
--- /dev/null
@@ -0,0 +1,2 @@
+del audio_wf.lib\r
+wmake.exe -f audio.mak "version = debugging" %1 %2 %3 %4 %5
\ No newline at end of file
diff --git a/audiolib/OBJ/ADLIBFX.OBJ b/audiolib/OBJ/ADLIBFX.OBJ
new file mode 100644 (file)
index 0000000..9765df7
Binary files /dev/null and b/audiolib/OBJ/ADLIBFX.OBJ differ
diff --git a/audiolib/OBJ/AL_MIDI.OBJ b/audiolib/OBJ/AL_MIDI.OBJ
new file mode 100644 (file)
index 0000000..69e32ad
Binary files /dev/null and b/audiolib/OBJ/AL_MIDI.OBJ differ
diff --git a/audiolib/OBJ/AUDIO_WF.LIB b/audiolib/OBJ/AUDIO_WF.LIB
new file mode 100644 (file)
index 0000000..918088a
Binary files /dev/null and b/audiolib/OBJ/AUDIO_WF.LIB differ
diff --git a/audiolib/OBJ/AWE32.OBJ b/audiolib/OBJ/AWE32.OBJ
new file mode 100644 (file)
index 0000000..4fc4963
Binary files /dev/null and b/audiolib/OBJ/AWE32.OBJ differ
diff --git a/audiolib/OBJ/BLASTER.OBJ b/audiolib/OBJ/BLASTER.OBJ
new file mode 100644 (file)
index 0000000..e936988
Binary files /dev/null and b/audiolib/OBJ/BLASTER.OBJ differ
diff --git a/audiolib/OBJ/DEBUGIO.OBJ b/audiolib/OBJ/DEBUGIO.OBJ
new file mode 100644 (file)
index 0000000..74d32b2
Binary files /dev/null and b/audiolib/OBJ/DEBUGIO.OBJ differ
diff --git a/audiolib/OBJ/DMA.OBJ b/audiolib/OBJ/DMA.OBJ
new file mode 100644 (file)
index 0000000..d4f4340
Binary files /dev/null and b/audiolib/OBJ/DMA.OBJ differ
diff --git a/audiolib/OBJ/DPMI.OBJ b/audiolib/OBJ/DPMI.OBJ
new file mode 100644 (file)
index 0000000..9f67187
Binary files /dev/null and b/audiolib/OBJ/DPMI.OBJ differ
diff --git a/audiolib/OBJ/FX_MAN.OBJ b/audiolib/OBJ/FX_MAN.OBJ
new file mode 100644 (file)
index 0000000..4a1c440
Binary files /dev/null and b/audiolib/OBJ/FX_MAN.OBJ differ
diff --git a/audiolib/OBJ/GMTIMBRE.OBJ b/audiolib/OBJ/GMTIMBRE.OBJ
new file mode 100644 (file)
index 0000000..49c4ecb
Binary files /dev/null and b/audiolib/OBJ/GMTIMBRE.OBJ differ
diff --git a/audiolib/OBJ/GUS.OBJ b/audiolib/OBJ/GUS.OBJ
new file mode 100644 (file)
index 0000000..9d749e9
Binary files /dev/null and b/audiolib/OBJ/GUS.OBJ differ
diff --git a/audiolib/OBJ/GUSMIDI.OBJ b/audiolib/OBJ/GUSMIDI.OBJ
new file mode 100644 (file)
index 0000000..48f6abf
Binary files /dev/null and b/audiolib/OBJ/GUSMIDI.OBJ differ
diff --git a/audiolib/OBJ/GUSWAVE.OBJ b/audiolib/OBJ/GUSWAVE.OBJ
new file mode 100644 (file)
index 0000000..70e776c
Binary files /dev/null and b/audiolib/OBJ/GUSWAVE.OBJ differ
diff --git a/audiolib/OBJ/IRQ.OBJ b/audiolib/OBJ/IRQ.OBJ
new file mode 100644 (file)
index 0000000..0a34ad8
Binary files /dev/null and b/audiolib/OBJ/IRQ.OBJ differ
diff --git a/audiolib/OBJ/LL_MAN.OBJ b/audiolib/OBJ/LL_MAN.OBJ
new file mode 100644 (file)
index 0000000..ca84a3a
Binary files /dev/null and b/audiolib/OBJ/LL_MAN.OBJ differ
diff --git a/audiolib/OBJ/MIDI.OBJ b/audiolib/OBJ/MIDI.OBJ
new file mode 100644 (file)
index 0000000..cac3b79
Binary files /dev/null and b/audiolib/OBJ/MIDI.OBJ differ
diff --git a/audiolib/OBJ/MPU401.OBJ b/audiolib/OBJ/MPU401.OBJ
new file mode 100644 (file)
index 0000000..5013b17
Binary files /dev/null and b/audiolib/OBJ/MPU401.OBJ differ
diff --git a/audiolib/OBJ/MULTIVOC.OBJ b/audiolib/OBJ/MULTIVOC.OBJ
new file mode 100644 (file)
index 0000000..26047d7
Binary files /dev/null and b/audiolib/OBJ/MULTIVOC.OBJ differ
diff --git a/audiolib/OBJ/MUSIC.OBJ b/audiolib/OBJ/MUSIC.OBJ
new file mode 100644 (file)
index 0000000..f8235b9
Binary files /dev/null and b/audiolib/OBJ/MUSIC.OBJ differ
diff --git a/audiolib/OBJ/MVREVERB.OBJ b/audiolib/OBJ/MVREVERB.OBJ
new file mode 100644 (file)
index 0000000..1e57a43
Binary files /dev/null and b/audiolib/OBJ/MVREVERB.OBJ differ
diff --git a/audiolib/OBJ/MV_MIX.OBJ b/audiolib/OBJ/MV_MIX.OBJ
new file mode 100644 (file)
index 0000000..e6bc36e
Binary files /dev/null and b/audiolib/OBJ/MV_MIX.OBJ differ
diff --git a/audiolib/OBJ/MV_MIX16.OBJ b/audiolib/OBJ/MV_MIX16.OBJ
new file mode 100644 (file)
index 0000000..0bbcd0d
Binary files /dev/null and b/audiolib/OBJ/MV_MIX16.OBJ differ
diff --git a/audiolib/OBJ/PAS16.OBJ b/audiolib/OBJ/PAS16.OBJ
new file mode 100644 (file)
index 0000000..b4052e3
Binary files /dev/null and b/audiolib/OBJ/PAS16.OBJ differ
diff --git a/audiolib/OBJ/PCFX.OBJ b/audiolib/OBJ/PCFX.OBJ
new file mode 100644 (file)
index 0000000..8e9ed27
Binary files /dev/null and b/audiolib/OBJ/PCFX.OBJ differ
diff --git a/audiolib/OBJ/PITCH.OBJ b/audiolib/OBJ/PITCH.OBJ
new file mode 100644 (file)
index 0000000..efd685d
Binary files /dev/null and b/audiolib/OBJ/PITCH.OBJ differ
diff --git a/audiolib/OBJ/SNDSCAPE.OBJ b/audiolib/OBJ/SNDSCAPE.OBJ
new file mode 100644 (file)
index 0000000..29d891b
Binary files /dev/null and b/audiolib/OBJ/SNDSCAPE.OBJ differ
diff --git a/audiolib/OBJ/SNDSRC.OBJ b/audiolib/OBJ/SNDSRC.OBJ
new file mode 100644 (file)
index 0000000..a53a0c5
Binary files /dev/null and b/audiolib/OBJ/SNDSRC.OBJ differ
diff --git a/audiolib/OBJ/TASK_MAN.OBJ b/audiolib/OBJ/TASK_MAN.OBJ
new file mode 100644 (file)
index 0000000..6fc0fa9
Binary files /dev/null and b/audiolib/OBJ/TASK_MAN.OBJ differ
diff --git a/audiolib/OBJ/USER.OBJ b/audiolib/OBJ/USER.OBJ
new file mode 100644 (file)
index 0000000..4ef74a6
Binary files /dev/null and b/audiolib/OBJ/USER.OBJ differ
diff --git a/audiolib/OBJDB/AL_MIDI.OBJ b/audiolib/OBJDB/AL_MIDI.OBJ
new file mode 100644 (file)
index 0000000..1bf3ae9
Binary files /dev/null and b/audiolib/OBJDB/AL_MIDI.OBJ differ
diff --git a/audiolib/OBJDB/AUDIO_WF.LIB b/audiolib/OBJDB/AUDIO_WF.LIB
new file mode 100644 (file)
index 0000000..1e894a5
Binary files /dev/null and b/audiolib/OBJDB/AUDIO_WF.LIB differ
diff --git a/audiolib/OBJDB/AWE32.OBJ b/audiolib/OBJDB/AWE32.OBJ
new file mode 100644 (file)
index 0000000..2c3b1dc
Binary files /dev/null and b/audiolib/OBJDB/AWE32.OBJ differ
diff --git a/audiolib/OBJDB/BLASTER.OBJ b/audiolib/OBJDB/BLASTER.OBJ
new file mode 100644 (file)
index 0000000..f01c34f
Binary files /dev/null and b/audiolib/OBJDB/BLASTER.OBJ differ
diff --git a/audiolib/OBJDB/DEBUGIO.OBJ b/audiolib/OBJDB/DEBUGIO.OBJ
new file mode 100644 (file)
index 0000000..87625dd
Binary files /dev/null and b/audiolib/OBJDB/DEBUGIO.OBJ differ
diff --git a/audiolib/OBJDB/DMA.OBJ b/audiolib/OBJDB/DMA.OBJ
new file mode 100644 (file)
index 0000000..f48b1ef
Binary files /dev/null and b/audiolib/OBJDB/DMA.OBJ differ
diff --git a/audiolib/OBJDB/DPMI.OBJ b/audiolib/OBJDB/DPMI.OBJ
new file mode 100644 (file)
index 0000000..7e43565
Binary files /dev/null and b/audiolib/OBJDB/DPMI.OBJ differ
diff --git a/audiolib/OBJDB/FX_MAN.OBJ b/audiolib/OBJDB/FX_MAN.OBJ
new file mode 100644 (file)
index 0000000..f4065b6
Binary files /dev/null and b/audiolib/OBJDB/FX_MAN.OBJ differ
diff --git a/audiolib/OBJDB/GMTIMBRE.OBJ b/audiolib/OBJDB/GMTIMBRE.OBJ
new file mode 100644 (file)
index 0000000..c72b8c5
Binary files /dev/null and b/audiolib/OBJDB/GMTIMBRE.OBJ differ
diff --git a/audiolib/OBJDB/GUS.OBJ b/audiolib/OBJDB/GUS.OBJ
new file mode 100644 (file)
index 0000000..9d749e9
Binary files /dev/null and b/audiolib/OBJDB/GUS.OBJ differ
diff --git a/audiolib/OBJDB/GUSMIDI.OBJ b/audiolib/OBJDB/GUSMIDI.OBJ
new file mode 100644 (file)
index 0000000..48f6abf
Binary files /dev/null and b/audiolib/OBJDB/GUSMIDI.OBJ differ
diff --git a/audiolib/OBJDB/GUSWAVE.OBJ b/audiolib/OBJDB/GUSWAVE.OBJ
new file mode 100644 (file)
index 0000000..f8f1cac
Binary files /dev/null and b/audiolib/OBJDB/GUSWAVE.OBJ differ
diff --git a/audiolib/OBJDB/IRQ.OBJ b/audiolib/OBJDB/IRQ.OBJ
new file mode 100644 (file)
index 0000000..abd1488
Binary files /dev/null and b/audiolib/OBJDB/IRQ.OBJ differ
diff --git a/audiolib/OBJDB/LL_MAN.OBJ b/audiolib/OBJDB/LL_MAN.OBJ
new file mode 100644 (file)
index 0000000..62412ab
Binary files /dev/null and b/audiolib/OBJDB/LL_MAN.OBJ differ
diff --git a/audiolib/OBJDB/MIDI.OBJ b/audiolib/OBJDB/MIDI.OBJ
new file mode 100644 (file)
index 0000000..fcbe60d
Binary files /dev/null and b/audiolib/OBJDB/MIDI.OBJ differ
diff --git a/audiolib/OBJDB/MPU401.OBJ b/audiolib/OBJDB/MPU401.OBJ
new file mode 100644 (file)
index 0000000..4f45c8c
Binary files /dev/null and b/audiolib/OBJDB/MPU401.OBJ differ
diff --git a/audiolib/OBJDB/MULTIVOC.OBJ b/audiolib/OBJDB/MULTIVOC.OBJ
new file mode 100644 (file)
index 0000000..ca0abac
Binary files /dev/null and b/audiolib/OBJDB/MULTIVOC.OBJ differ
diff --git a/audiolib/OBJDB/MUSIC.OBJ b/audiolib/OBJDB/MUSIC.OBJ
new file mode 100644 (file)
index 0000000..a84cd88
Binary files /dev/null and b/audiolib/OBJDB/MUSIC.OBJ differ
diff --git a/audiolib/OBJDB/MVREVERB.OBJ b/audiolib/OBJDB/MVREVERB.OBJ
new file mode 100644 (file)
index 0000000..9ea6135
Binary files /dev/null and b/audiolib/OBJDB/MVREVERB.OBJ differ
diff --git a/audiolib/OBJDB/MV_MIX.OBJ b/audiolib/OBJDB/MV_MIX.OBJ
new file mode 100644 (file)
index 0000000..e6bc36e
Binary files /dev/null and b/audiolib/OBJDB/MV_MIX.OBJ differ
diff --git a/audiolib/OBJDB/MV_MIX16.OBJ b/audiolib/OBJDB/MV_MIX16.OBJ
new file mode 100644 (file)
index 0000000..0bbcd0d
Binary files /dev/null and b/audiolib/OBJDB/MV_MIX16.OBJ differ
diff --git a/audiolib/OBJDB/PAS16.OBJ b/audiolib/OBJDB/PAS16.OBJ
new file mode 100644 (file)
index 0000000..b4052e3
Binary files /dev/null and b/audiolib/OBJDB/PAS16.OBJ differ
diff --git a/audiolib/OBJDB/PITCH.OBJ b/audiolib/OBJDB/PITCH.OBJ
new file mode 100644 (file)
index 0000000..4dbd0e1
Binary files /dev/null and b/audiolib/OBJDB/PITCH.OBJ differ
diff --git a/audiolib/OBJDB/SNDSCAPE.OBJ b/audiolib/OBJDB/SNDSCAPE.OBJ
new file mode 100644 (file)
index 0000000..bdb2835
Binary files /dev/null and b/audiolib/OBJDB/SNDSCAPE.OBJ differ
diff --git a/audiolib/OBJDB/SNDSRC.OBJ b/audiolib/OBJDB/SNDSRC.OBJ
new file mode 100644 (file)
index 0000000..82e4ec4
Binary files /dev/null and b/audiolib/OBJDB/SNDSRC.OBJ differ
diff --git a/audiolib/OBJDB/TASK_MAN.OBJ b/audiolib/OBJDB/TASK_MAN.OBJ
new file mode 100644 (file)
index 0000000..6fc0fa9
Binary files /dev/null and b/audiolib/OBJDB/TASK_MAN.OBJ differ
diff --git a/audiolib/OBJDB/USER.OBJ b/audiolib/OBJDB/USER.OBJ
new file mode 100644 (file)
index 0000000..34f5328
Binary files /dev/null and b/audiolib/OBJDB/USER.OBJ differ
diff --git a/audiolib/PUBLIC/AUDIO_WF.LIB b/audiolib/PUBLIC/AUDIO_WF.LIB
new file mode 100644 (file)
index 0000000..ed11fc6
Binary files /dev/null and b/audiolib/PUBLIC/AUDIO_WF.LIB differ
diff --git a/audiolib/PUBLIC/EMIDIAPI.TXT b/audiolib/PUBLIC/EMIDIAPI.TXT
new file mode 100644 (file)
index 0000000..8cfe53a
--- /dev/null
@@ -0,0 +1,224 @@
+=============================================================\r
+| Apogee Expanded MIDI (EMIDI) API v1.0                     |\r
+=============================================================\r
+\r
+Specifications created by Lee Jackson and Jim Dos\8a\r
+Support coded by Jim Dos\8a\r
+\r
+\r
+FOR INTERNAL USE ONLY.  ACCESS OR USE WITHOUT EXPRESS WRITTEN\r
+PERMISSION FROM APOGEE SOFTWARE, LTD., 3D REALMS ENTERTAINMENT, OR\r
+ACTION ENTERTAINMENT, INC., IS STRICTLY PROHIBITED.\r
+\r
+\r
+Copyright (c) 1995 Apogee Software Ltd.  All Rights Reserved.\r
+\r
+\r
+=============================================================\r
+| Contents                                                  |\r
+=============================================================\r
+\r
+    I.      Instrument Definitions\r
+    II.     Controller Definitions\r
+    III.    InitBeat Format\r
+\r
+\r
+=============================================================\r
+| I.  Instrument Definitions                                |\r
+=============================================================\r
+\r
+The following instruments are currently defined as valid for data\r
+entry events:\r
+\r
+        0 -     General MIDI\r
+        1 -     Roland Sound Canvas (GM and GS)\r
+        2 -     Sound Blaster AWE32\r
+        3 -     Wave Blaster and Compatibles (SCD-10, etc.)\r
+        4 -     Sound Blaster and Compatibles (OPL-2 and OPL-3)\r
+        5 -     Media Vision Pro Audio series\r
+        6 -     Logitech Sound Man 16\r
+        7 -     Adlib and Compatibles\r
+        8 -     Ensoniq Soundscape\r
+        9 -     Gravis Ultrasound, Ultrasound Max, Ultrasound ACE\r
+        127 -   All (see Controller Definitions)\r
+\r
+\r
+=============================================================\r
+| II.  Controller Definitions                                |\r
+=============================================================\r
+\r
+The following controllers are currently defined as valid:\r
+\r
+110 -   Track Designation\r
+        Required:               Yes\r
+        Multiples allowed:      Yes\r
+        Format:                 110 nn\r
+                                (where nn is a defined instrument)\r
+\r
+Controller 110 determines which instruments will receive data for\r
+this track.  Multiple instances may be used to designate multiple\r
+instruments.  If the track is designated for all instruments,\r
+Instrument 127 may be used.  This instrument may also be used in\r
+conjunction with Controller 111 to exclude a single instrument or\r
+group of instruments.\r
+\r
+\r
+111 -   Track Exclusion\r
+        Required:               No\r
+        Multiples allowed:      Yes\r
+        Format:                 111 nn\r
+                                (where nn is a defined instrument -\r
+                                        instrument 127 is invalid)\r
+\r
+Controller 111 excludes an instrument from receiving the data for\r
+this track.  Multiple instances may be used to exclude multiple\r
+instruments.  Instrument 127 is not valid for this controller.\r
+\r
+\r
+112 -   Program Change\r
+        Required:               No\r
+        Multiples allowed:      Yes\r
+        Format:                 112 nn\r
+                                (where nn is a GM program change)\r
+\r
+Controller 112 is the same as the standard MIDI program change\r
+event.  It may be inserted at any point a program change is\r
+required.  If it does not exist, standard MIDI program change events\r
+will be recognized for this track.  If it does exist, standard MIDI\r
+program change events will not be recognized for this track, and all\r
+program changes for the track must be entered using Controller 112.\r
+\r
+\r
+113 -   Volume\r
+        Required:               No\r
+        Multiples allowed:      Yes\r
+        Format:                 113 nn\r
+                                (where nn is between 0 and 127)\r
+\r
+Controller 113 allows different volumes to be inserted in the same\r
+manner as Controller 7.  It should be used only if\r
+designation/exclusion groups exist on the same MIDI channel.  If\r
+Controller 113 does not exist at the beginning of the track,\r
+Controller 7 events will be recognized.  If Controller 113 does\r
+exist at the beginning of the track, Controller 7 events will be\r
+ignored.\r
+\r
+\r
+116 -   Loop Begin\r
+        Required:               Yes\r
+        Multiples allowed:      Yes (see below)\r
+        Format:                 116 nn\r
+                                (see below for definition)\r
+\r
+Controller 116 indicates the beginning of a sequence to be looped.\r
+Values for this controller are as follows:\r
+\r
+        0 - infinite loop\r
+        1 - loop once\r
+        2 - loop twice\r
+        x - loop x times\r
+\r
+A song should have a Master Start point and a Master End point.  The\r
+start point should occur after the InitBeat (see section III) and\r
+after any introduction you wish to have played only once.  Any\r
+controller information (patch changes, pitch bend info, etc.)\r
+required for the loop should be entered and/or repeated after the\r
+loop's Master Start event (see also Section III, "InitBeat", below).\r
+Likewise, any "reset" events required should be entered either just\r
+after the loop's Master Start event or just before the loop's Master\r
+End event.\r
+\r
+Multiple non-infinite loop start/end pairs (see Controller 117\r
+below) may occur at any point inside the Master Loop.  Only one\r
+infinite loop may be defined per song.  Nested loops are not yet\r
+supported.\r
+\r
+IMPORTANT:  Any event to be included within the loop must fall after\r
+            the Loop Begin point and end before the Loop End point.\r
+            If you are using Cakewalk Pro for Windows, you can\r
+            verify this by looking at the Event List view.\r
+            SIMULTANEOUS TIMES FOR LOOP POINTS AND EVENT DATA DO NOT\r
+            GUARANTEE THAT AN EVENT IS INSIDE THE LOOP.  If in\r
+            doubt, set the event one tick after the Loop Begin or\r
+            have it end one tick before the Loop End.\r
+\r
+\r
+117 -   Loop End\r
+        Required:               Yes\r
+        Multiples allowed:      Yes (see below)\r
+        Format:                 117 127\r
+\r
+Controller 117 indicates the end of a looped segment of a song, or\r
+in the case of a Master Loop, the end of the entire song.  This\r
+controller signals that the Apogee Sound System should immediately\r
+loop back to the nearest non-resolved loop begin event (i.e., the\r
+nearest Controller 116 event that does not have a matching\r
+Controller 117 event).\r
+\r
+Loop End events should not occur at the exact time of a Loop Begin\r
+event.\r
+\r
+Note:  Loop Begin/End pairs only affect the track they are placed\r
+       on.  If an entire song is to be looped through a segment, all\r
+       tracks must contain Loop Begin events and Loop End events\r
+       which occur on the same tick across all tracks.  Be careful\r
+       how you use non-synchronous single track loops - the composer\r
+       is responsible for making sure that everything stays in sync.\r
+\r
+See Controller 116 above for important information regarding\r
+placements of events to be included within loops.\r
+\r
+\r
+=============================================================\r
+| III.  InitBeat Format                                     |\r
+=============================================================\r
+\r
+Each song should begin with an InitBeat.  In terms of standard\r
+musical notation, an example of this would be a single 1/4 measure\r
+where the rest of the song is in 4/4, or a single 1/8 measure when\r
+the rest of the song is in 6/8.  In MIDI terms, this is equivalent\r
+to one full cycle of the current timebase (e.g., for timebase 120, a\r
+single beat, 120 ticks long).  Each track used should have its own\r
+InitBeat.  This beat should not contain any note on/off data, sysex\r
+dump data, Loop Begin/End events (Controllers 116 and/or 117), or\r
+other non-Controller events.  It may, however, contain MetaEvents\r
+such as text, copyrights, markers, program changes (normal or\r
+Controller 112), and the like.\r
+\r
+The InitBeat should contain any needed Controller 110, 111, 112, or\r
+113 events needed to set up each track for the song.  It may also\r
+contain other Controllers (pitch wheel, modulation, RPN/NRPN data,\r
+etc.) as desired.  Keep in mind that you will need to repeat these\r
+controller values at some point within the Master Loop if you change\r
+them at any point in the song (and you rely on the original values\r
+when the song goes back to the Master Start point).\r
+\r
+If no special handling is required for a track (i.e., the track is\r
+to be played by all instruments and no Controller resets/setups are\r
+desired), the InitBeat for that track may be left blank.  It is\r
+advisable, however, to at least insert a single Controller 110 event\r
+with value 127, indicating that the track is to be played by all\r
+instruments.  This is more a matter of personal preference, but it\r
+can come in handy for setting up templates with Cakewalk Pro for\r
+Windows and other programs that support default song templates.\r
+\r
+If none of the tracks in a song require any special handling, all\r
+InitBeats may be left blank.  Do not delete the InitBeat measure -\r
+just leave it blank.\r
+\r
+Controller events may be spread throughout the InitBeat as desired.\r
+You may place them all on a single tick, or on separate ticks.  Some\r
+instruments will behave unpredictably if all events for a track are\r
+placed on the same tick (e.g., the 5-6 events needed to adjust pitch\r
+bend parameters, especially if controllers 100 and 101 are set with\r
+value 0 and then reset with value 127 as recommended by Roland), so\r
+composer discretion is advised.  At this time, simultaneous events\r
+across multiple tracks are not known to cause a problem.\r
+\r
+The InitBeat may be inserted in any way desired.  If you are using\r
+Cakewalk Pro for Windows, it is simplest to make the first measure a\r
+1/4 measure (one beat @ 4 per measure) and then switch the meter to\r
+whatever you want to use for the remainder of the song right at\r
+measure 2.  Meter changes within the song are not affected by this,\r
+of course.\r
+\r
diff --git a/audiolib/PUBLIC/INCLUDE/AUDIO_WF.LIB b/audiolib/PUBLIC/INCLUDE/AUDIO_WF.LIB
new file mode 100644 (file)
index 0000000..ed11fc6
Binary files /dev/null and b/audiolib/PUBLIC/INCLUDE/AUDIO_WF.LIB differ
diff --git a/audiolib/PUBLIC/INCLUDE/FX_MAN.H b/audiolib/PUBLIC/INCLUDE/FX_MAN.H
new file mode 100644 (file)
index 0000000..86cb5dd
--- /dev/null
@@ -0,0 +1,135 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: FX_MAN.H\r
+\r
+   author: James R. Dose\r
+   date:   March 17, 1994\r
+\r
+   Public header for FX_MAN.C\r
+\r
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.\r
+**********************************************************************/\r
+\r
+#ifndef __FX_MAN_H\r
+#define __FX_MAN_H\r
+\r
+#include "sndcards.h"\r
+\r
+typedef struct\r
+   {\r
+   int MaxVoices;\r
+   int MaxSampleBits;\r
+   int MaxChannels;\r
+   } fx_device;\r
+\r
+#define MonoFx   1\r
+#define StereoFx 2\r
+\r
+typedef struct\r
+   {\r
+   unsigned long Address;\r
+   unsigned long Type;\r
+   unsigned long Interrupt;\r
+   unsigned long Dma8;\r
+   unsigned long Dma16;\r
+   unsigned long Midi;\r
+   unsigned long Emu;\r
+   } fx_blaster_config;\r
+\r
+enum FX_ERRORS\r
+   {\r
+   FX_Warning = -2,\r
+   FX_Error = -1,\r
+   FX_Ok = 0,\r
+   FX_ASSVersion,\r
+   FX_BlasterError,\r
+   FX_SoundCardError,\r
+   FX_InvalidCard,\r
+   FX_MultiVocError,\r
+   FX_DPMI_Error\r
+   };\r
+\r
+enum fx_BLASTER_Types\r
+   {\r
+   fx_SB     = 1,\r
+   fx_SBPro  = 2,\r
+   fx_SB20   = 3,\r
+   fx_SBPro2 = 4,\r
+   fx_SB16   = 6\r
+   };\r
+\r
+\r
+char *FX_ErrorString( int ErrorNumber );\r
+int   FX_SetupCard( int SoundCard, fx_device *device );\r
+int   FX_GetBlasterSettings( fx_blaster_config *blaster );\r
+int   FX_SetupSoundBlaster( fx_blaster_config blaster, int *MaxVoices, int *MaxSampleBits, int *MaxChannels );\r
+int   FX_Init( int SoundCard, int numvoices, int numchannels, int samplebits, unsigned mixrate );\r
+int   FX_Shutdown( void );\r
+int   FX_SetCallBack( void ( *function )( unsigned long ) );\r
+void  FX_SetVolume( int volume );\r
+int   FX_GetVolume( void );\r
+\r
+void  FX_SetReverseStereo( int setting );\r
+int   FX_GetReverseStereo( void );\r
+void  FX_SetReverb( int reverb );\r
+void  FX_SetFastReverb( int reverb );\r
+int   FX_GetMaxReverbDelay( void );\r
+int   FX_GetReverbDelay( void );\r
+void  FX_SetReverbDelay( int delay );\r
+\r
+int FX_VoiceAvailable( int priority );\r
+int FX_EndLooping( int handle );\r
+int FX_SetPan( int handle, int vol, int left, int right );\r
+int FX_SetPitch( int handle, int pitchoffset );\r
+int FX_SetFrequency( int handle, int frequency );\r
+\r
+int FX_PlayVOC( char *ptr, int pitchoffset, int vol, int left, int right,\r
+       int priority, unsigned long callbackval );\r
+int FX_PlayLoopedVOC( char *ptr, long loopstart, long loopend,\r
+       int pitchoffset, int vol, int left, int right, int priority,\r
+       unsigned long callbackval );\r
+int FX_PlayWAV( char *ptr, int pitchoffset, int vol, int left, int right,\r
+       int priority, unsigned long callbackval );\r
+int FX_PlayLoopedWAV( char *ptr, long loopstart, long loopend,\r
+       int pitchoffset, int vol, int left, int right, int priority,\r
+       unsigned long callbackval );\r
+int FX_PlayVOC3D( char *ptr, int pitchoffset, int angle, int distance,\r
+       int priority, unsigned long callbackval );\r
+int FX_PlayWAV3D( char *ptr, int pitchoffset, int angle, int distance,\r
+       int priority, unsigned long callbackval );\r
+int FX_PlayRaw( char *ptr, unsigned long length, unsigned rate,\r
+       int pitchoffset, int vol, int left, int right, int priority,\r
+       unsigned long callbackval );\r
+int FX_PlayLoopedRaw( char *ptr, unsigned long length, char *loopstart,\r
+       char *loopend, unsigned rate, int pitchoffset, int vol, int left,\r
+       int right, int priority, unsigned long callbackval );\r
+int FX_Pan3D( int handle, int angle, int distance );\r
+int FX_SoundActive( int handle );\r
+int FX_SoundsPlaying( void );\r
+int FX_StopSound( int handle );\r
+int FX_StopAllSounds( void );\r
+int FX_StartDemandFeedPlayback( void ( *function )( char **ptr, unsigned long *length ),\r
+       int rate, int pitchoffset, int vol, int left, int right,\r
+       int priority, unsigned long callbackval );\r
+int  FX_StartRecording( int MixRate, void ( *function )( char *ptr, int length ) );\r
+void FX_StopRecord( void );\r
+\r
+#endif\r
diff --git a/audiolib/PUBLIC/INCLUDE/MUSIC.H b/audiolib/PUBLIC/INCLUDE/MUSIC.H
new file mode 100644 (file)
index 0000000..d231115
--- /dev/null
@@ -0,0 +1,92 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: MUSIC.H\r
+\r
+   author: James R. Dose\r
+   date:   March 25, 1994\r
+\r
+   Public header for MUSIC.C\r
+\r
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.\r
+**********************************************************************/\r
+\r
+#ifndef __MUSIC_H\r
+#define __MUSIC_H\r
+\r
+#include "sndcards.h"\r
+\r
+extern int MUSIC_ErrorCode;\r
+\r
+enum MUSIC_ERRORS\r
+   {\r
+   MUSIC_Warning = -2,\r
+   MUSIC_Error   = -1,\r
+   MUSIC_Ok      = 0,\r
+   MUSIC_ASSVersion,\r
+   MUSIC_SoundCardError,\r
+   MUSIC_MPU401Error,\r
+   MUSIC_InvalidCard,\r
+   MUSIC_MidiError,\r
+   MUSIC_TaskManError,\r
+   MUSIC_FMNotDetected,\r
+   MUSIC_DPMI_Error\r
+   };\r
+\r
+typedef struct\r
+   {\r
+   unsigned long tickposition;\r
+   unsigned long milliseconds;\r
+   unsigned int  measure;\r
+   unsigned int  beat;\r
+   unsigned int  tick;\r
+   } songposition;\r
+\r
+#define MUSIC_LoopSong ( 1 == 1 )\r
+#define MUSIC_PlayOnce ( !MUSIC_LoopSong )\r
+\r
+char *MUSIC_ErrorString( int ErrorNumber );\r
+int   MUSIC_Init( int SoundCard, int Address );\r
+int   MUSIC_Shutdown( void );\r
+void  MUSIC_SetMaxFMMidiChannel( int channel );\r
+void  MUSIC_SetVolume( int volume );\r
+void  MUSIC_SetMidiChannelVolume( int channel, int volume );\r
+void  MUSIC_ResetMidiChannelVolumes( void );\r
+int   MUSIC_GetVolume( void );\r
+void  MUSIC_SetLoopFlag( int loopflag );\r
+int   MUSIC_SongPlaying( void );\r
+void  MUSIC_Continue( void );\r
+void  MUSIC_Pause( void );\r
+int   MUSIC_StopSong( void );\r
+int   MUSIC_PlaySong( unsigned char *song, int loopflag );\r
+void  MUSIC_SetContext( int context );\r
+int   MUSIC_GetContext( void );\r
+void  MUSIC_SetSongTick( unsigned long PositionInTicks );\r
+void  MUSIC_SetSongTime( unsigned long milliseconds );\r
+void  MUSIC_SetSongPosition( int measure, int beat, int tick );\r
+void  MUSIC_GetSongPosition( songposition *pos );\r
+void  MUSIC_GetSongLength( songposition *pos );\r
+int   MUSIC_FadeVolume( int tovolume, int milliseconds );\r
+int   MUSIC_FadeActive( void );\r
+void  MUSIC_StopFade( void );\r
+void  MUSIC_RerouteMidiChannel( int channel, int cdecl ( *function )( int event, int c1, int c2 ) );\r
+void  MUSIC_RegisterTimbreBank( unsigned char *timbres );\r
+\r
+#endif\r
diff --git a/audiolib/PUBLIC/INCLUDE/SNDCARDS.H b/audiolib/PUBLIC/INCLUDE/SNDCARDS.H
new file mode 100644 (file)
index 0000000..c7aa873
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: SNDCARDS.H\r
+\r
+   author: James R. Dose\r
+   date:   March 31, 1994\r
+\r
+   Contains enumerated type definitions for sound cards.\r
+\r
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.\r
+**********************************************************************/\r
+\r
+#ifndef __SNDCARDS_H\r
+#define __SNDCARDS_H\r
+\r
+#define ASS_VERSION_STRING "1.12"\r
+\r
+typedef enum\r
+   {\r
+//   ASS_NoSound,\r
+   SoundBlaster,\r
+   ProAudioSpectrum,\r
+   SoundMan16,\r
+   Adlib,\r
+   GenMidi,\r
+   SoundCanvas,\r
+   Awe32,\r
+   WaveBlaster,\r
+   SoundScape,\r
+   UltraSound,\r
+   SoundSource,\r
+   TandySoundSource,\r
+   PC,\r
+   NumSoundCards\r
+   } soundcardnames;\r
+\r
+#endif\r
diff --git a/audiolib/PUBLIC/INCLUDE/TASK_MAN.H b/audiolib/PUBLIC/INCLUDE/TASK_MAN.H
new file mode 100644 (file)
index 0000000..b1ba2f5
--- /dev/null
@@ -0,0 +1,68 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: TASK_MAN.C\r
+\r
+   author: James R. Dose\r
+   date:   July 25, 1994\r
+\r
+   Public header for TASK_MAN.C, a low level timer task scheduler.\r
+\r
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.\r
+**********************************************************************/\r
+\r
+#ifndef __TASK_MAN_H\r
+#define __TASK_MAN_H\r
+\r
+enum TASK_ERRORS\r
+   {\r
+   TASK_Warning = -2,\r
+   TASK_Error = -1,\r
+   TASK_Ok = 0\r
+   };\r
+\r
+typedef struct task\r
+{\r
+    struct   task *next;\r
+    struct   task *prev;\r
+    void          ( *TaskService )( struct task * );\r
+    void          *data;\r
+    long          rate;\r
+    volatile long count;\r
+    int           priority;\r
+    int           active;\r
+} task;\r
+\r
+// TS_InInterrupt is TRUE during a taskman interrupt.\r
+// Use this if you have code that may be used both outside\r
+// and within interrupts.\r
+\r
+extern volatile int TS_InInterrupt;\r
+\r
+void    TS_Shutdown( void );\r
+task    *TS_ScheduleTask( void ( *Function )( task * ), int rate,\r
+                          int priority, void *data );\r
+int     TS_Terminate( task *ptr );\r
+void    TS_Dispatch( void );\r
+void    TS_SetTaskRate( task *Task, int rate );\r
+void    TS_UnlockMemory( void );\r
+int     TS_LockMemory( void );\r
+\r
+#endif\r
diff --git a/audiolib/PUBLIC/INCLUDE/USRHOOKS.C b/audiolib/PUBLIC/INCLUDE/USRHOOKS.C
new file mode 100644 (file)
index 0000000..a2058d1
--- /dev/null
@@ -0,0 +1,84 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: USRHOOKS.C\r
+\r
+   author: James R. Dose\r
+   date:   July 26, 1994\r
+\r
+   This module contains cover functions for operations the library\r
+   needs that may be restricted by the calling program.  This code\r
+   is left public for you to modify.\r
+**********************************************************************/\r
+\r
+#include <stdlib.h>\r
+#include "usrhooks.h"\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: USRHOOKS_GetMem\r
+\r
+   Allocates the requested amount of memory and returns a pointer to\r
+   its location, or NULL if an error occurs.  NOTE: pointer is assumed\r
+   to be dword aligned.\r
+---------------------------------------------------------------------*/\r
+\r
+int USRHOOKS_GetMem\r
+   (\r
+   void **ptr,\r
+   unsigned long size\r
+   )\r
+\r
+   {\r
+   void *memory;\r
+\r
+   memory = malloc( size );\r
+   if ( memory == NULL )\r
+      {\r
+      return( USRHOOKS_Error );\r
+      }\r
+\r
+   *ptr = memory;\r
+\r
+   return( USRHOOKS_Ok );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: USRHOOKS_FreeMem\r
+\r
+   Deallocates the memory associated with the specified pointer.\r
+---------------------------------------------------------------------*/\r
+\r
+int USRHOOKS_FreeMem\r
+   (\r
+   void *ptr\r
+   )\r
+\r
+   {\r
+   if ( ptr == NULL )\r
+      {\r
+      return( USRHOOKS_Error );\r
+      }\r
+\r
+   free( ptr );\r
+\r
+   return( USRHOOKS_Ok );\r
+   }\r
diff --git a/audiolib/PUBLIC/INCLUDE/USRHOOKS.H b/audiolib/PUBLIC/INCLUDE/USRHOOKS.H
new file mode 100644 (file)
index 0000000..d030421
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: USRHOOKS.H\r
+\r
+   author: James R. Dose\r
+   date:   July 26, 1994\r
+\r
+   Public header file for USRHOOKS.C.\r
+\r
+   This module contains cover functions for operations the library\r
+   needs that may be restricted by the calling program.  The function\r
+   prototypes in this header should not be modified.\r
+**********************************************************************/\r
+\r
+#ifndef __USRHOOKS_H\r
+#define __USRHOOKS_H\r
+\r
+/*---------------------------------------------------------------------\r
+   Error definitions\r
+---------------------------------------------------------------------*/\r
+\r
+enum USRHOOKS_Errors\r
+   {\r
+   USRHOOKS_Warning = -2,\r
+   USRHOOKS_Error   = -1,\r
+   USRHOOKS_Ok      = 0\r
+   };\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function Prototypes\r
+---------------------------------------------------------------------*/\r
+\r
+int USRHOOKS_GetMem( void **ptr, unsigned long size );\r
+int USRHOOKS_FreeMem( void *ptr );\r
+\r
+#endif\r
diff --git a/audiolib/PUBLIC/MIDI.TXT b/audiolib/PUBLIC/MIDI.TXT
new file mode 100644 (file)
index 0000000..ab70951
--- /dev/null
@@ -0,0 +1,60 @@
+\r
+Apogee Sound System MIDI notes:\r
+-------------------------------\r
+\r
+FM Midi :\r
+\r
+On OPL2 cards 9 voices are available.  OPL3 cards have 18 voices.  Melodic\r
+mode is used for music.  For percussion (channel 10), each key is assigned\r
+a timbre to play at a pitch specified by the patch.  This method was chosen\r
+based on the advice of Bobby Prince, Rob Wallace, George Sanger, and Lee\r
+Jackson, all of whom felt the 11 voice mode was too restricting for\r
+musicians.\r
+\r
+Channels 1-16 are now supported.\r
+\r
+Controllers supported\r
+\r
+6   data entry msb     |\r
+38  data entry lsb     | - Only on Set Pitch Bend Range (RPN 0, 0)\r
+96  data increment     |\r
+97  data decrement     |\r
+7   channel volume\r
+10  pan (balance)\r
+121 reset all controllers\r
+123 all notes off\r
+\r
+\r
+AWE32 :\r
+\r
+All controllers supported by API.\r
+\r
+\r
+Gravis Ultrasound:\r
+\r
+1   modulation wheel\r
+6   data entry msb     |\r
+38  data entry lsb     | - Only on Set Pitch Bend Range (RPN 0, 0)\r
+96  data increment     |\r
+97  data decrement     |\r
+7   channel volume\r
+39  volume lsb ignored\r
+10  pan (balance)\r
+11  channel expression (volume)\r
+43  expression lsb ignored\r
+64  sustain (damper pedal)\r
+100 set registered parameter number\r
+101 set registered parameter number\r
+121 reset all controllers\r
+\r
+120 all sounds off     |\r
+123 all notes off      |\r
+124 omni off           | - Perform all notes off\r
+125 omni on            |\r
+126 mono               |\r
+127 mono               |\r
+\r
+\r
+General MIDI (all other cards):\r
+\r
+All controllers sent.  Support depends on the card.\r
diff --git a/audiolib/PUBLIC/NOTES.TXT b/audiolib/PUBLIC/NOTES.TXT
new file mode 100644 (file)
index 0000000..b577bbc
--- /dev/null
@@ -0,0 +1,1713 @@
+\r
+                             Apogee Sound System\r
+\r
+                                Version 1.09\r
+\r
+                                 by Jim Dos\82\r
+\r
+                                Revision notes\r
+\r
+When your game is in beta, you must fax me your beta reports with sound\r
+problems since I will not see them otherwise.\r
+\r
+Please be sure to include my name in the credits for your program.  I'm\r
+not asking for a design or game programming credit, just credit for the\r
+sound system.  This includes the credits screen, the manual, and the\r
+text files accompanying the game (if the credits for the game are listed\r
+in them).  Thank you.\r
+\r
+NOTE: make sure that you unzipped the zip file using the "-d"\r
+parameter.  This will create some directories that the demo needs.\r
+\r
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r
+³                           Known problems:                                 ³\r
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
+\r
+- GUS may crash on systems with a VMM since the GUS code does not lock\r
+  any of its allocated memory.\r
+\r
+- GUS only supports IRQs below 8.  At higher IRQs, the dos extender seems\r
+  to be too slow.\r
+\r
+- PAS mixer does not have a linear sounding volume change.\r
+\r
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r
+³                             To-do list:                                   ³\r
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
+\r
+- Add support for playback of stereo sounds.  If anyone needs this\r
+  right away, let me know.\r
+- Add permanant debugging code to various modules.\r
+- If an error occurs loading a patch file, GUS code should return\r
+  which file it is.\r
+- Finish this doc file.  Music functions have to be documented using the\r
+  new format.\r
+- Change current limit of one upper IRQ.\r
+- Get upper IRQ's working for GUS code.\r
+- Lock memory in GUS code.\r
+- Test code on OS/2 and Windows\r
+- Lookup table for PAS mixer for more linear volume change.\r
+- MOD music playback.\r
+\r
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r
+³                          Revision History:                                ³\r
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
+\r
+5/14/96\r
+\r
+- Version 1.12\r
+- Fixed a reverb bug where 8-bit fast reverb would round down to -infinity\r
+  instead of 0.  This caused a bit of noise since the mix buffer would\r
+  only reduce down to -1 and 0.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+5/10/96\r
+\r
+- Version 1.11\r
+- added function FX_EndLooping to break a looping sound out of its loop.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+1/16/96\r
+\r
+- Modified Maketmb to chop off bits not relevant to OPL2 cards.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+1/8/96\r
+\r
+- Version 1.09\r
+- ***** IMPORTANT *****\r
+  Any code that is called by the sound system should be compiled with\r
+  the -zu option.  This tells the compiler to assume that SS is not\r
+  equal to DS.  This is required for any code that's called from the\r
+  sound system while it's in an interrupt (I switch to a custom stack\r
+  upon entering the interrupt).  Any function that is used with\r
+  TS_ScheduleTask or FX_SetCallBack should be compiled this way (you may\r
+  want to put them in a separate module.  I recommend doing this for\r
+  USRHOOKS functions as well, in case you free a task from within a timer\r
+  function (MUSIC_FadeVolume does this, so if you use it, USRHOOKS must\r
+  be compiled with -zu).\r
+\r
+- The sound system now uses the ULTRAMID.INI in the current directory if\r
+  it exists, otherwise it uses the one pointed to by the ULTRADIR environment\r
+  variable.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+1/4/96\r
+\r
+- Fixed a bug with fast 8-bit reverb.  Also made a few optimizations to\r
+  it.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+12/18/95\r
+\r
+- Version 1.08\r
+- I'm a dumbass.  I left a "strcat( InstrumentDirectory, name );"\r
+  after locating the ULTRAMID.INI file for the Gravis Ultrasound.  So\r
+  if you  haven't been able to initialize music in a while, you know\r
+  who's to blame. :)\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+12/12/95\r
+\r
+- New utility called PS.  Allows you to test a WAV, VOC, or raw sound\r
+  file from the command line using the sound system.  Check in the\r
+  PS directory for the source code.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+12/8/95\r
+\r
+- Version 1.07\r
+- Added adjustable delay on the reverb.  The following functions allow\r
+  you to manipulate the delay setting.\r
+\r
+  int   FX_GetMaxReverbDelay( void );\r
+  int   FX_GetReverbDelay( void );\r
+  void  FX_SetReverbDelay( int delay );\r
+\r
+  The delay is measured in the number of samples to delay before the\r
+  sound is regenerated.  To calculate the delay in seconds, just do this:\r
+  seconds = delay / mixingrate; (using floats, obviously).  The minimum\r
+  delay is 256 samples.  The maximum depends on whether you're doing\r
+  16 bit or 8 bit, and stereo or mono mixing.  Use FXGetMaxReverbDelay\r
+  to get the maximum (after the FX_Init has been called).  In 8-bit mono,\r
+  the delay is about 1/2 of a second.  The maximum delay is constrained\r
+  by the size of the buffer I allocate to mix the sound in.  If anyone\r
+  wants longer delays, let me know and I can increase the buffer size\r
+  for you (I'd probably make it adjustable by you).\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+12/6/95\r
+\r
+- 18 voice FM music on OPL3 cards.\r
+- FM music is no longer limited to MIDI channels 1 through 10.  For\r
+  backward compatability sake, the function MUSIC_SetMaxFMMidiChannel\r
+  can be used to limit it, but why would anyone want to do that?\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+11/13/95\r
+\r
+- Fixed a bug with Adlib music where the default pitch bend range was\r
+  set too low.  Thanks Peter!\r
+- 1.06a library upload.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+11/7/95\r
+\r
+- 1.06 update.  Time sure flies...\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+8/21/95\r
+\r
+- 1.05 update.\r
+- Full EMIDI support.\r
+- Context sensitive music through EMIDI.\r
+- Added the ability to fastforward to a specific beat/measure or time\r
+  in a song.\r
+- GUSMIDI.INI file no longer required (this may return, we're still debating).\r
+- Probably a few other things that I can't think of right now.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+7/24/95\r
+\r
+- Changed GUS code to use software mixing instead of hardware mixing.\r
+  GUS purists will hate me (if they found out), but it makes a lot more\r
+  sense this way since I only have to maintain one playback method, plus\r
+  it allows GUS owners to hear reverb and gives better control over panning.\r
+  There may be other benefits, but I can't think of them right now.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+5/31/95\r
+\r
+- Playback of 16-bit digitized sound now supported.  Source data must\r
+  be signed data.  Still need to do GUS version, but I'm uploading it for\r
+  Jason Blochowiak.\r
+- Reverb code rewritten in assembly.  Still needs to be fine-tuned.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+5/25/95\r
+\r
+- Using "option eliminate" with the sound library should no longer crash\r
+  the linker.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+5/8/95\r
+\r
+- Added some new functions:\r
+\r
+     void FX_SetReverseStereo( int setting );\r
+     int  FX_GetReverseStereo( void );\r
+     void FX_SetReverb( int reverb );\r
+     void FX_SetFastReverb( int reverb );\r
+\r
+  FX_SetReverseStereo and FX_GetReverseStereo allow you to swap the left\r
+  and right channel volumes for people whose speakers are reversed.  Zero\r
+  is no swap, non-zero swaps channels.\r
+\r
+  FX_SetReverb and FX_SetFastReverb set the amount of echo to mix into\r
+  the sound.  It's a very mechanical sounding echo, kind of like the spring\r
+  reverb on guitar amps.  The effect is much like the echo effects in\r
+  Super Mario World on the SNES.\r
+\r
+  FX_SetReverb accepts values from 0 to 255. 0 means no reverb and 255\r
+  is 100% reverb (sound repeats infinitely).  Values above 96 are probably\r
+  overkill.  Speedwise, reverb costs about as much as one sound effect.\r
+\r
+  FX_SetFastReverb uses a bitwise shift instead of table lookup to scale\r
+  the volume of the echo.  A value of 0 is no echo, 1 is echo at half\r
+  volume (equivalent to 128 with FX_SetReverb), 2 to 1/4 volume\r
+  (equivalent to 64), etc.  If you're not doing dynamic changes in reverb,\r
+  this may be preferable since it's a bit faster.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+4/7/95\r
+\r
+- void MUSIC_RegisterTimbreBank( unsigned char *timbres );\r
+\r
+  Added the function MUSIC_RegisterTimbreBank to allow developers to use\r
+  their own FM timbres on Sound Blaster and Adlib compatibles.  Use the\r
+  supplied utility MAKETMB to create data files using a script and IBK\r
+  files.  The resulting file can be loaded by the program at runtime and\r
+  a pointer to it passed to MUSIC_RegisterTimbreBank.  Afterwards, the\r
+  memory can be deallocated (the audio library copies the supplied timbres\r
+  over the default timbres.\r
+\r
+  If you decide to use your own timbres, I can recommend a good shareware\r
+  program that helps you to create them.  Just give me a call.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+3/17/95\r
+\r
+- Finished looping functions.  Here is how to loop a sample:\r
+\r
+  For a raw sample, use FX_PlayLoopedRaw.  Here is it's definition:\r
+\r
+     int FX_PlayLoopedRaw\r
+        (\r
+        char          *ptr,\r
+        unsigned long  length,\r
+        char          *loopstart,\r
+        char          *loopend,\r
+        unsigned       rate,\r
+        int            pitchoffset,\r
+        int            vol,\r
+        int            left,\r
+        int            right,\r
+        int            priority,\r
+        unsigned long  callbackval\r
+        );\r
+\r
+     ptr is a pointer to the start of the sample.  It can actually be\r
+  later in the sample than the start of the loop.  This is usefull for\r
+  MOD players which may start a sample at an offset into the sound.\r
+\r
+     length is the number of samples to play before the loop begins.  In\r
+  most cases, this will be ( loopend - ptr ).  It may seem strange to be\r
+  able to play past the end of the loop on the first time through the\r
+  sound, but it's the most flexible.\r
+\r
+     loopstart is a pointer to the start of the loop.  The can be before\r
+  or after the start of the sample.\r
+\r
+     loopend is a pointer to the end of the loop.  This points to the last\r
+  sample to play in the loop.\r
+\r
+  For a WAV file, use FX_PlayLoopedWAV.\r
+\r
+     int FX_PlayLoopedWAV\r
+        (\r
+        char *ptr,\r
+        long  loopstart,\r
+        long  loopend,\r
+        int   pitchoffset,\r
+        int   vol,\r
+        int   left,\r
+        int   right,\r
+        int   priority,\r
+        unsigned long callbackval\r
+        );\r
+\r
+     ptr is the start of the WAV file.  WAV files currently do not have\r
+  the flexibility that raw files do, in that the sound must start at the\r
+  beginning of the WAV file.  All looping is based past the beginning of\r
+  the WAV file.  The sound will loop after the sample pointed to by\r
+  loopend.\r
+\r
+     loopstart is the offset (not pointer) of the sample to begin the loop\r
+  on.  This must be a positive value.  Any negative values or values past\r
+  the end of the sound will cause the WAV to only play once.\r
+\r
+     loopend is the offset (not pointer) of the sample to end the loop on\r
+  (the sample will loop after this sample is played).  If the offset is\r
+  past the end of the sample, the loop end will be set to the last sample\r
+  in the file.\r
+\r
+  For a VOC file, use FX_PlayLoopedVOC.\r
+\r
+     int FX_PlayLoopedVOC\r
+        (\r
+        char *ptr,\r
+        long  loopstart,\r
+        long  loopend,\r
+        int   pitchoffset,\r
+        int   vol,\r
+        int   left,\r
+        int   right,\r
+        int   priority,\r
+        unsigned long callbackval\r
+        );\r
+\r
+     ptr is the start of the VOC file.  VOC files currently do not have\r
+  the flexibility that raw files do, in that the sound must start at the\r
+  beginning of the VOC file.  All looping is based past the beginning of\r
+  the VOC file.  Since VOC files can contain multiple blocks of data,\r
+  looping samples will only play the first block of data.\r
+\r
+     loopstart is the offset (not pointer) of the sample to begin the loop\r
+  on.  This must be a positive value.  Any negative values or values past\r
+  the end of the sound will cause the VOC to play normally.\r
+\r
+     loopend is the offset (not pointer) of the sample to end the loop on\r
+  (the sample will loop after this sample is played).  If the offset is\r
+  past the end of the sample, the loop end will be set to the last sample\r
+  in the file.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+3/16/95\r
+\r
+- I have changed the names of the two functions for playing VOCs.  It just\r
+  no longer makes sense to call them PlaySound when there are a variety of\r
+  file formats supported.\r
+\r
+  Here's an updated list of functions that play digitized sound:\r
+\r
+  FX_PlayRaw       : Plays raw sampled data once\r
+  FX_PlayLoopedRaw : Plays raw sampled data with looping\r
+  FX_PlayWAV       : Plays a WAV file once\r
+  FX_PlayLoopedWAV : Plays a WAV file with looping\r
+  FX_PlayVOC3D     : Plays a VOC file once using '3D' panning\r
+  FX_PlayVOC       : Plays a VOC file once\r
+  FX_PlayLoopedVOC : Plays a VOC file with looping\r
+\r
+  I'm thinking about moving the '3D' routines out of the library since\r
+  they are really just panning tables.  This way, users could create their\r
+  own method.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+3/15/95\r
+\r
+- Increased the reported maximum number of voices you can play on some cards\r
+  to 32.  Since all voice tables are dynamically allocated, you could have\r
+  more, but anything beyond 16 is a bit ridiculous.  The Gravis Ultrasound\r
+  is limited to 24 currently, and any voices used for sound fx leaves fewer\r
+  voices for music.  In any case, 8 voices is the recommended maximum, but\r
+  if you have reason to use more, go ahead.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+3/14/95\r
+\r
+- Added special routines optimized to mix only 1 channel into stereo.\r
+  Whenever the volume of the left or the right channel is zero for a\r
+  voice, only one channel is mixed.  This is especially useful if you\r
+  intend to play a sound with the left and right channels' frequencies are\r
+  slightly different.  Peter Freese (from Q Studios, who are developing\r
+  Blood) needs to do this for his Sonic Holography 3D sound library that\r
+  he is developing.\r
+\r
+- Fixed a problem on the Sound Source.  I noticed that pitches were higher\r
+  than normal on the Sound Source, and discovered that it was possible to\r
+  overflow the FIFO buffer without causing the overflow flag to be set.\r
+  Since the Sound Source can only play sound at 7khz, I must poll the\r
+  port to see if it's ready for sound.  The overflow flag sometimes doesn't\r
+  register imediatly, so I changed my routine to write only 14 samples at\r
+  a time to the port.  This causes the pitch to be nearly 7khz.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+3/13/95\r
+\r
+- Increased the resolution of the volume levels that digitized sounds can\r
+  play from 16 to 64.  Since the volumes were passed in as 0 to 255, there\r
+  is no need for users to change any code to take advantage of this.\r
+  Although this requires more memory (in 16bit mode, 32k as opposed to 8k),\r
+  it means smooth volume changes and allows for MOD playback.\r
+\r
+- Added new function for changing pitch: FX_SetFrequency.  This allows you\r
+  to change the rate that a sound is mixed at.  This isn't very usefull for\r
+  VOC playback since the VOC file can override the rate, it is very usefull\r
+  for playback of raw data since you will already know the sampling rate.\r
+  This is also usefull for MOD playback.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+3/10/95\r
+\r
+- Added embedded looping commands for MIDI files.  To loop a specific\r
+  track, use controller 116 on any MIDI channel on that track with a value\r
+  of 0 for infinite, or > 0 for the number of times to loop.  To mark the\r
+  end of a loop, use controller 117 with a value of 127.  NOTE: Currently,\r
+  you must put loop info on all tracks to if you want all of them to loop.\r
+  This may seem like a pain at first, but I thought that it would give\r
+  the musician extra flexibility.  If no one likes this, I'll change it so\r
+  that you only have to do one loop controller.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+3/9/95\r
+\r
+- Added support for .WAV files and raw samples.\r
+- Added two new functions allowing the programmer to control the relative\r
+  volume of each MIDI channel of a song.  Use MUSIC_SetMidiChannelVolume\r
+  to set the volume of a MIDI channel and MUSIC_ResetMidiChannelVolumes\r
+  to restore all channels to full volume.  I do not reset the volumes\r
+  when you play a new song so that you can set the volume of all the\r
+  channels before playing a song.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+2/14/95\r
+\r
+- Found a potential bug where the pitch scaling function could go outside\r
+  of the array bounds given certain pitch offsets.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+2/4/95\r
+\r
+- Stereo FM temporarally commented out for ROTT.  Seems to take too long on\r
+  some computers and causes the mouse driver to miss interrupts.\r
+  Have to contact Creative Labs to find out which chips have fast timings.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+2/3/95\r
+\r
+- Added FX_VoiceAvailable.  Checks if a voice can be played at the\r
+  specified priority.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+1/30/95\r
+\r
+- Version 1.02 uploaded for all current developers.\r
+\r
+- Various initialization routines improved.\r
+\r
+- Now performs checks to see if DMA and IRQ are working.\r
+\r
+- Added the ability to do custom Sound Blaster setup.  Now users can enter\r
+  the DMA, card address, and IRQ.\r
+\r
+- Fixed problem with SB16 and Sound Canvas Daughterboard.  This was\r
+  caused by an undocumented IRQ disable flag in the SB16.\r
+\r
+- GUS initialization no longer bombs if all the patches in GUSMIDI.INI\r
+  could not be loaded.  I was forced to do this due to the problems\r
+  that can be caused by a slight error in the patch list.  Gravis has changed\r
+  the patch sizes over several versions making it difficult to create a patch\r
+  list that works on all cards.  Since the last patches loaded are percussion,\r
+  these are the ones that will be affected.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+1/11/95\r
+\r
+- Additive timbres now respond to volume changes.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+1/7/95\r
+\r
+- Added better error checking and detection for AWE32.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+1/4/95\r
+\r
+- Version 1.01 uploaded for all current developers.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+12/20/94 - Version 1.01\r
+\r
+- Version built for Rise of the Triad.\r
+\r
+- Fixed some problems with MIDI playback on SoundScape.  It was\r
+  missing program changes (instruments).\r
+\r
+- GUS uses GUSMIDI.INI in local directory instead of ULTRAMID.INI.\r
+  This is so that a custom patch list could be included with your\r
+  game.  If you own a GUS, copy the file ULTRAMIDI.INI from your\r
+  ULTRASND\MIDI directory.  I will come up with something more\r
+  convenient in the future.\r
+\r
+- When command line parameter "ASSVER" used, the library returns\r
+  an error when initialized.  The error string will contain the\r
+  version text.  This was done so that your programs could perform\r
+  their normal shutdown procedure before exiting to DOS.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+12/15/94\r
+\r
+- Optimized mixing routines.  50% increase in 8-bit mono and stereo\r
+  playback and 20%-30% increase in 16-bit playback.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+11/28/94\r
+\r
+- Pitch tables are now linked in rather than generated at startup.\r
+  This gets rid of any floating point code.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+11/14/94\r
+\r
+- Added function FX_SoundsPlaying to report the number of voices\r
+  playing.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+11/13/94\r
+\r
+- Fixed problem with SoundScape where it wasn't reporting the MaxBits\r
+  and MaxVoices properly.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+11/6/94 - Version 1.00\r
+\r
+- SoundScape now automatically gets MIDI port address from SNDSCAPE.INI.\r
+\r
+- WaveBlaster now automatically gets MIDI port address from the BLASTER\r
+  environment string.\r
+\r
+- TaskMan now locks the link list manager's memory in case FX_Init\r
+  and MUSIC_Init are not called.\r
+\r
+- All developers must make sure that they ask for the midi port on the\r
+  following cards: GenMidi, and SoundCanvas.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+11/5/94\r
+\r
+- Made the GUSWAVE play voice routine allocate voice with a priority of\r
+  0, which tells gf1_play_digital to not attempt voice stealing.  This\r
+  prevents the music playback from stealing sound fx voices and was\r
+  the source of the bug in Boppin' where voices would be cutoff.\r
+\r
+- VOC decoder now deals with block type 8 properly.  Bug caused it to be\r
+  ignored.\r
+\r
+- GUS set volume function now sets volume of all playing voices.  Before,\r
+  it would only set the volume for new voices.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+10/31/94\r
+\r
+- Now keeping track of version number.  From any game that uses the\r
+  sound system, you can type "ASSVER" to get version number.\r
+\r
+- Added command line parameter "DEBUGGUS" to Gravis Ultrasound GUSWAVE\r
+  to help track down a voice dropout problem.  I'll eventually add similar\r
+  parameters to other modules.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+10/26/94\r
+\r
+- Added native support for the Ensoniq SoundScape.  This card is capable\r
+  of playing 8 and 16 bit stereo or mono data and uses wavetable synthesis\r
+  for music.  Please add this to your config.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+10/23/94\r
+\r
+- Did some optimizing and found that for 16-bit mixing it is slightly\r
+  quicker to use code to do harsh clipping than to use tables.  This\r
+  gets rid of a 64k lookup table I had.  With 8-bit sound, it is quicker\r
+  to use a table, but it only takes up 512 bytes.\r
+\r
+  Here is the various mixing modes in order of fastest to slowest:\r
+      8-bit mono, 16-bit mono, 8-bit stereo, 16-bit stereo.\r
+\r
+  Just for reference, 8-bit mono is only about 40% faster than 16-bit\r
+  stereo.  And considering that at 11khz, mixing is only called about\r
+  10 times a second, it's not an incredible difference.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+10/20/94\r
+\r
+- Fixed the PAS slowdown bug.  DMA channel was not being disabled after\r
+  a PCM transfer.  On some computers with PAS-16s, when the DMA circuitry\r
+  in the PAS was turned off, it left the DRQ line on the DMA in a floating\r
+  state, causing the DMA to do a continuous burst transfer, which would\r
+  slow down the computer.  This would not happen on other cards, since\r
+  their DMA circuitry is always active.\r
+\r
+- Fixed the WaveBlaster bug.  Bug caused by a problem with playing\r
+  WaveBlaster music and Sound Blaster-16 that is completely undocumented\r
+  in Creative Labs' developer kits.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+10/4/94\r
+\r
+- Added several new cards to enum list in SNDCARDS.H.  Unless you use all\r
+  of these, you are not supporting all sound cards----PUT THEM IN!\r
+- AWE32 support for General MIDI.\r
+- Midi callback system for implimenting digital drums and other music-\r
+  synced events.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+9/7/94\r
+\r
+- All interrupt service routines now allocate their own 1024 byte stack\r
+  in case Windows or OS/2 don't leave enough stack space.  This was\r
+  suggested by Steve Lepisto (Accursed Toys) who kindly supplied example\r
+  code.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+9/6/94\r
+\r
+- PC speaker sound fx can now be turned off by setting the volume to 0.\r
+- Turned off panning on the FM rhythm channel.\r
+- Found and fixed another FM panning bug.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+9/2/94\r
+\r
+- Added ability to reroute data from a MIDI channel to a user function.\r
+  Good for digital drums or animation synced to music.\r
+- Fixed a problem on the GUS with instruments that use tremelo.  Only\r
+  showed up when volume was set to 0.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+9/1/94\r
+\r
+- Fixed the high volume notes on GUS.\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+8/26/94\r
+\r
+- Ummm, added revision notes!  What follows is what I've added in the\r
+  past few weeks.\r
+- Locked down memory on all cards except GUS.\r
+- Support for higher IRQ's on PAS and Sound Blaster.  Requires Dos4gw Pro\r
+  version 1.97.\r
+- Internal support for PAS mixer control (using MVSOUND.SYS).  Requires\r
+  Dos4gw Pro version 1.97.\r
+- FM pan position defaulted to full left.  Only noticable if midi file\r
+  didn't set its own pan positions.  Now defaults to center.\r
+- Added stereo panning on FM music.\r
+- Added stereo detuning on FM music.\r
+- Added harsh clipping so that digitized sounds playback at same volume\r
+  no matter how many voices are allocated.  Could distort when many sounds\r
+  are playing, but that's the price you pay.\r
+- Changed panning from sine tables to a linear attenuation ramp as you\r
+  deviate from center.\r
+- GUS can now choose number of voices to use (used to be 8 no matter what).\r
+\r
+\r
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r
+³                            Header files:                                  ³\r
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
+\r
+There are four header files that you'll need: TASK_MAN.H, SNDCARDS.H,\r
+MUSIC.H and FX_MAN.H.  MUSIC.H contains all functions that control music.\r
+FX_MAN.H contains all functions for control of digitized and synthesized\r
+sound.  SNDCARDS.H contains sound card definitions and is brought in by\r
+MUSIC.H and FX_MAN.H.  TASK_MAN.H is a module used for timer management.\r
+\r
+SNDCARDS.H defines the following enumerated type:\r
+\r
+   typedef enum\r
+      {\r
+      SoundBlaster,\r
+      ProAudioSpectrum,\r
+      SoundMan16,\r
+      Adlib,\r
+      GenMidi,             <--- Requires midi port\r
+      SoundCanvas,         <--- Requires midi port\r
+      Awe32,\r
+      WaveBlaster,\r
+      SoundScape,\r
+      UltraSound,\r
+      SoundSource,\r
+      TandySoundSource,\r
+      PC,\r
+      NumSoundCards\r
+      } soundcardnames;\r
+\r
+These are used to select which card to use when initializing the routines.\r
+Do not use hard coded values since the value of these cards may change\r
+in future versions of the library.  NumSoundCards is simply to identify\r
+how many cards are supported (since support for more cards may be added\r
+in the future).\r
+\r
+\r
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r
+³                              Functions:                                   ³\r
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
+\r
+In the functions that follow, TRUE is assumed to be the value returned by\r
+the expression ( 1 == 1 ) and FALSE is assumed to be the value returned\r
+by the expression ( !TRUE ).  Using macros, you could define them this\r
+way:\r
+\r
+   #define TRUE   ( 1 == 1 )\r
+   #define FALSE  ( !TRUE )\r
+\r
+This method is used because it makes no assumptions on the value of the\r
+boolean expressions when they are evaluated by the compiler.\r
+\r
+\r
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r
+³                           Sound Effects:                                  ³\r
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
+\r
+The following cards will be supported for sound effects: SoundBlaster,\r
+ProAudioSpectrum, UltraSound, SoundSource, TandySoundSource, AWE32,\r
+SoundMan16, and the PC speaker.\r
+\r
+Functions that return an error status will return one of the following:\r
+FX_Ok (if the function was successfull), FX_Error (if an error occurred),\r
+or FX_Warning (if a non-critical error occurred).\r
+\r
+The number of the last error or warning is stored in the global variable\r
+FX_ErrorCode.  Whether an error is worth exiting for is up to you.  Check\r
+out the names of the possible errors in the header file.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+FX_ErrorString\r
+\r
+\r
+Synopsis:\r
+\r
+   #include "fx_man.h"\r
+   char *FX_ErrorString( int ErrorNumber );\r
+\r
+Description:\r
+\r
+   The FX_ErrorString function maps the error number contained\r
+   in ErrorNumber to a string describing the error.\r
+\r
+   ErrorNumber can be the number of any error.  If ErrorNumber is\r
+   set to FX_Error or FX_Warning, FX_ErrorString will return the\r
+   string corresponding with the last error that occurred.\r
+\r
+Returns:\r
+\r
+   The FX_ErrorString function returns a pointer to the error message.\r
+   This string of data should not be modified by the program.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+FX_SetupCard\r
+\r
+\r
+Synopsis:\r
+\r
+   #include "fx_man.h"\r
+   int FX_SetupCard( int SoundCard, fx_device *device );\r
+\r
+Description:\r
+\r
+   The FX_SetupCard function is used to detect a sound card and\r
+   get information on what the card can do.\r
+\r
+   SoundCard:\r
+      This is an int passed into the function and corresponds\r
+      to the enumerated list of cards.\r
+\r
+   device:\r
+      This is the address of the data structure to store information\r
+      about the card.\r
+\r
+   Here is the definition of fx_device:\r
+\r
+   typedef struct\r
+      {\r
+      int   MaxVoices;\r
+      int   MaxSampleBits;\r
+      int   MaxChannels;\r
+      } fx_device;\r
+\r
+   MaxVoices:\r
+      This is the recommended maximum number of digitized sound\r
+      that can be played at once.  4 voices is adequate for most games,\r
+      although 8 voices is great for games that have a lot of atmosphere\r
+      sounds (like 3D games).  You should offer an option to select the\r
+      number of voices to use for people with slower machines.\r
+\r
+   MaxSampleBits:\r
+      This will be either 8 or 16, depending on whether you have an\r
+      8-bit or 16-bit sound card.  The routines only support playback\r
+      of 8-bit samples, but can mix them as 16-bit.  This provides better\r
+      quality sound, especially at low volumes, however it is slower since\r
+      you have twice as much data to mix.  You might want to offer this\r
+      as an option to people with slower machines.\r
+\r
+   MaxChannels:\r
+      This will be 1 if you have a mono card and 2 if you have a stereo\r
+      card.  Again, offer this as a choice in case the user has a slow\r
+      machine.  If you are not using the panning capabilities of the\r
+      sound system, choose mono sound since there would be no benefit\r
+      in using stereo.\r
+\r
+Returns:\r
+\r
+   The FX_SetupCard function will return FX_Ok if the sound card was\r
+   detected succesfully, and FX_Error if the card was not found or\r
+   could not be initialized.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+FX_Init\r
+\r
+\r
+Synopsis:\r
+\r
+   #include "fx_man.h"\r
+   int FX_Init( int SoundCard, int numvoices, int mixmode, int samplebits,\r
+      unsigned mixrate );\r
+\r
+Description:\r
+\r
+   The function FX_Init configures the sound engine by selecting the\r
+   sound card, the maximum number of sounds that can play, and whether\r
+   to mix the sound in 8 or 16 bits.\r
+\r
+   SoundCard:\r
+      This is an int passed into the function to select and corresponds\r
+      to the enumerated list of cards.\r
+\r
+   numvoices:\r
+      This is the number of digitized sound that can be played at once.\r
+\r
+   mixmode:\r
+      This is the number of channels to mix the sound into.  1 for mono,\r
+      2 for stereo.\r
+\r
+   samplebits:\r
+      This should be either 8 or 16, depending on whether sound should\r
+      be mixed in 8-bits or 16.\r
+\r
+   mixrate:\r
+      This selects the rate in hertz that sound should be mixed.\r
+\r
+\r
+Example:\r
+\r
+   int       status;\r
+   fx_device device;\r
+\r
+   status = FX_SetupCard( UltraSound, &device );\r
+   if ( status != FX_Ok )\r
+      {\r
+      printf( "%s\n", FX_ErrorString( status ) );\r
+      exit( 1 );\r
+      }\r
+\r
+   status = FX_Init( UltraSound, 8, 2, 16, 11000 );\r
+   if ( status != FX_Ok )\r
+      {\r
+      printf( "%s\n", FX_ErrorString( status ) );\r
+      exit( 1 );\r
+      }\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+FX_Shutdown\r
+\r
+\r
+Synopsis:\r
+\r
+   #include "fx_man.h"\r
+   int FX_Shutdown( void );\r
+\r
+Description:\r
+\r
+   The function FX_Shutdown ends use of the sound card and restores\r
+   any system resources that were used.  This should be called when\r
+   you exit to DOS, or when you change sound devices.\r
+\r
+Returns:\r
+\r
+   The function FX_Shutdown returns FX_Ok if it was succesfull in\r
+   shutting down the sound card and restoring resources.  Otherwise,\r
+   it returns FX_Error or FX_Warning.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+FX_SetCallBack\r
+\r
+\r
+Synopsis:\r
+\r
+   #include "fx_man.h"\r
+   int FX_SetCallBack( void ( *function )( unsigned long ) );\r
+\r
+Description:\r
+\r
+   The function FX_SetCallBack instructs the engine to call the\r
+   user-defined function when sounds stop playing.\r
+\r
+   function:\r
+      This is the function that the engine should call when a sound stops\r
+      playing.  The user-defined function should accept an unsigned long\r
+      as it's parameter.  The value passed to this function is a user-\r
+      defined value identifying the sound that just finished playing and\r
+      may be an actual pointer to a user-defined data structure.\r
+\r
+Returns:\r
+\r
+   FX_SetCallBack returns FX_Error or FX_Warning when the assignment\r
+   failed.  Otherwise it returns FX_Ok.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+FX_SetVolume\r
+\r
+\r
+Synopsis:\r
+   #include "fx_man.h"\r
+   void FX_SetVolume( int volume );\r
+\r
+\r
+Description:\r
+\r
+   The function FX_SetVolume sets the total volume of sound\r
+   effects.\r
+\r
+   volume:\r
+      This is the volume to set the sound fx device to.\r
+      Valid volumes are from 0 to 255.\r
+\r
+Returns:\r
+\r
+   The function FX_SetVolume does not return a value.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+FX_GetVolume\r
+\r
+Synopsis:\r
+\r
+   #include "fx_man.h"\r
+   int FX_GetVolume( void );\r
+\r
+Description:\r
+\r
+   The FX_GetVolume function returns the total volume of the sound fx\r
+   device.\r
+\r
+Returns:\r
+\r
+   If an error occurs, FX_GetVolume returns FX_Warning or FX_Error,\r
+   otherwise it returns the total volume of sound effects.  Valid\r
+   volumes are from 0 to 255.\r
+\r
+\r
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r
+³                           Playing Sounds:                                 ³\r
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
+\r
+FX_PlaySound\r
+\r
+\r
+Synopsis:\r
+\r
+   #include "fx_man.h"\r
+   int FX_PlaySound( char *ptr, int pitchoffset, int vol, int left,\r
+      int right, int priority, unsigned long callbackval );\r
+\r
+Description:\r
+\r
+   The function FX_PlaySound begins playback of digitized sound.\r
+   The sound data must be formated as a valid VOC sound file.\r
+\r
+   ptr:\r
+      This is the address to the VOC format sound data to be played.\r
+\r
+   pitchoffset:\r
+      This is the amount to transpose the pitch of the sound up or down\r
+      measured in 1/100th's of a semitone.  For example, to transpose\r
+      the pitch up one octave use 1200.  To transpose the pitch down\r
+      one octave use -1200.  For no transposition, use 0.\r
+\r
+   vol:\r
+      This is the volume of the sound in mono mode.  Valid values range\r
+      from 0 to 255.  Note: A volume of 0 does not always mean total\r
+      silence.\r
+\r
+   left:\r
+      This is the volume of the sound played through the left speaker in\r
+      stereo mode.  Valid values range is from 0 to 255.  Note: A volume\r
+      of 0 does not always mean total silence.\r
+\r
+   right:\r
+      This is the volume of the sound played through the right speaker\r
+      in stereo mode.  Valid values range from 0 to 255.  Note: A volume\r
+      of 0 does not always mean total silence.\r
+\r
+   priority:\r
+      This sets the order that sounds should be cancelled if a new sound\r
+      is played when no voices are available.  When this occurs, the\r
+      oldest sound with the lowest priority is replaced with the new\r
+      sound.  If the new sound's priority is lower than all the sounds\r
+      playing, then it will not be played.\r
+\r
+   callbackval:\r
+      This is the value that should be sent to the user-defined callback\r
+      function when the sound ends.  See FX_SetCallBack.\r
+\r
+\r
+Returns:\r
+\r
+   If an error occurs, FX_PlaySound returns FX_Error, or FX_Warning.\r
+   Otherwise, it returns a voice handle.  To determine if a return value\r
+   is a voice handle, check to see if it is greater than FX_Ok.  Valid\r
+   voice handles are always greater than FX_Ok.  The most common error\r
+   that can occur is when there are no voices and the new sound's\r
+   priority was too low.\r
+\r
+   The voice handle can be used later to stop the voice from playing or to\r
+   test if the voice is still playing.\r
+\r
+Example:\r
+\r
+   int voicehandle;\r
+\r
+   voicehandle = FX_PlaySound( address, pitchoffset, vol, left, right,\r
+      priority, callbackval );\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+FX_Play3D\r
+\r
+\r
+Synopsis:\r
+\r
+   #include "fx_man.h"\r
+   int FX_Play3D( char *ptr, int pitchoffset, int angle, int distance,\r
+      int priority, unsigned long callbackval );\r
+\r
+Description:\r
+\r
+   The function FX_Play3D begins playback of digitized sound.  The sound\r
+   data must be formated as a valid VOC sound file.\r
+\r
+   ptr:\r
+      This is the address to the VOC sound data to be played.\r
+\r
+   pitchoffset:\r
+      This is the amount to transpose the pitch of the sound up or down\r
+      measured in 1/100th's of a semitone.  For example, to transpose\r
+      the pitch up one octave use 1200.  To transpose the pitch down\r
+      one octave use -1200.  For no transposition, use 0.\r
+\r
+   angle:\r
+      This is the clockwise angle of the sound in relation to the player\r
+      from 0 to 31.  0 is center, 8 is full right, 16 is directly behind\r
+      the listener, and 24 is full left.\r
+\r
+   distance:\r
+      This is the distance of the sound from the player.  Valid values\r
+      range from 0 to 255, with 255 being the furthest from the player\r
+      (note: this does not mean silence on all cards).\r
+\r
+   priority:\r
+      This sets the order that sounds should be cancelled if a new sound\r
+      is played when no voices are available.  When this occurs, the\r
+      oldest sound with the lowest priority is replaced with the new\r
+      sound.  If the new sound's priority is lower than all the sounds\r
+      playing, then it will not be played.\r
+\r
+   callbackval:\r
+      This is the value that should be sent to the user-defined callback\r
+      function when the sound ends.  See FX_SetCallBack.\r
+\r
+\r
+Returns:\r
+\r
+   If an error occurs, FX_Play3D returns FX_Error, or FX_Warning.\r
+   Otherwise, it returns a voice handle.  To determine if a return value\r
+   is a voice handle, check to see if it is greater than FX_Ok.  Valid\r
+   voice handles are always greater than FX_Ok.  The most common error\r
+   that can occur is when there are no voices and the new sound's\r
+   priority was too low.\r
+\r
+   The voice handle can be used later to stop the voice from playing or to\r
+   test if the voice is still playing.\r
+\r
+Example:\r
+\r
+   int voicehandle;\r
+\r
+   voicehandle = FX_Play3D( address, pitchoffset, angle, distance,\r
+      priority, callbackval );\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+FX_SetPan\r
+\r
+\r
+Synopsis:\r
+\r
+   #include "fx_man.h"\r
+   int FX_SetPan( int handle, int vol, int left, int right );\r
+\r
+Description:\r
+\r
+   The function FX_SetPan sets the mono and stereo volumes of a\r
+   currently playing sound.  This can be used for sounds started\r
+   with FX_PlaySound or FX_Play3D.\r
+\r
+   handle:\r
+      This is the voice handle of the sound.  This is the value returned\r
+      by FX_PlaySound and FX_Play3D.\r
+\r
+   vol:\r
+      This is the volume of the sound in mono mode.  Range is from 0 to\r
+      255.  Note: A volume of 0 does not always mean total silence.\r
+\r
+   left:\r
+      This is the volume of the sound played through the left speaker\r
+      in stereo mode.  Range is from 0 to 255.  Note: A volume of 0\r
+      does not always mean total silence.\r
+\r
+   right:\r
+      This is the volume of the sound played through the right speaker\r
+      in stereo mode.  Range is from 0 to 255.  Note: A volume of 0\r
+      does not always mean total silence.\r
+\r
+Returns:\r
+\r
+   If the sound is no longer playing, FX_SetPan will return FX_Warning,\r
+   otherwise, it will return FX_Ok.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+FX_Pan3D\r
+\r
+\r
+Synopsis:\r
+\r
+   #include "fx_man.h"\r
+   int FX_Pan3D( int handle, int angle, int distance );\r
+\r
+Description:\r
+\r
+   The function FX_Pan3D sets the angle and the distance of a\r
+   currently playing sound in relation to the player.  This can\r
+   be used for sounds started with FX_PlaySound or FX_Play3D.\r
+\r
+   handle:\r
+      This is the voice handle of the sound.  This is the value\r
+      returned by FX_PlaySound and FX_Play3D.\r
+\r
+   angle:\r
+      This is the clockwise angle of the sound in relation to the player\r
+      from 0 to 31.  0 is center, 8 is full right, 16 is directly behind\r
+      the listener, and 24 is full left.\r
+\r
+   distance:\r
+      This is the distance of the sound from the player.  Valid values\r
+      range from 0 to 255, with 255 being the furthest from the player\r
+      (note: this does not mean silence on all cards).\r
+\r
+Returns:\r
+\r
+   If the sound is no longer playing, FX_Pan3D will return FX_Warning,\r
+   otherwise, it will return FX_Ok.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+FX_SetPitch\r
+\r
+\r
+Synopsis:\r
+\r
+   #include "fx_man.h"\r
+   int FX_SetPitch( int handle, int pitchoffset );\r
+\r
+Description:\r
+\r
+   The function FX_SetPitch sets the pitch of a currently playing sound.\r
+\r
+   handle:\r
+      This is the voice handle of the sound.  This is the value returned by\r
+      FX_PlaySound and FX_Play3D.\r
+\r
+   pitchoffset:\r
+      This is the amount to transpose the pitch of the sound up or down\r
+      measured in 1/100th's of a semitone.  For example, to transpose\r
+      the pitch up one octave use 1200.  To transpose the pitch down\r
+      one octave use -1200.  For no transposition, use 0.\r
+\r
+Returns:\r
+\r
+   If the sound is no longer playing, FX_SetPitch will return FX_Warning,\r
+   otherwise, it will return FX_Ok.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+FX_SoundActive\r
+\r
+\r
+Synopsis:\r
+\r
+   #include "fx_man.h"\r
+   int FX_SoundActive( int handle );\r
+\r
+Description:\r
+\r
+   The function FX_SoundActive tests if the sound with the specified\r
+   handle is currently playing.\r
+\r
+   handle:\r
+      This is the voice handle of the sound to test.  This is the value\r
+      returned by FX_PlaySound and FX_Play3D.\r
+\r
+Returns:\r
+   FX_SoundActive returns TRUE if the sound is playing, otherwise it\r
+   returns FALSE.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+int FX_StopSound( int handle );\r
+\r
+\r
+FX_StopSound stops playback of the sound with the associated handle.\r
+If the return value is not equal to FX_Ok, the sound was not found.\r
+\r
+handle is the voice handle of the sound.  This is the value returned by\r
+FX_PlaySound and FX_Play3D.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+FX_StopAllSounds\r
+\r
+\r
+Synopsis:\r
+   #include "fx_man.h"\r
+   int FX_StopAllSounds( void );\r
+\r
+Description:\r
+\r
+   The function FX_StopAllSounds halts output of all playing sounds.\r
+\r
+Returns:\r
+\r
+   FX_StopAllSounds returns FX_Warning or FX_Error if an error occured,\r
+   otherwise, it returns FX_Ok.\r
+\r
+\r
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r
+³                           Music Playback:                                 ³\r
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
+\r
+\r
+The following cards are supported for music: SoundBlaster, ProAudioSpectrum,\r
+Adlib, GenMidi, WaveBlaster, UltraSound, SoundMan16, Awe32, and SoundCanvas.\r
+TandSoundSource, SoundSource and PC are not supported.\r
+\r
+Similar error codes are returned for music as for sound effects.  The\r
+codes are MUSIC_Ok, MUSIC_Warning, and MUSIC_Error.  The last error that\r
+occurred is stored in MUSIC_ErrorCode.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+char *MUSIC_ErrorString( int ErrorNumber );\r
+\r
+\r
+Same as FX_ErrorString, except for music.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+int MUSIC_Init( int SoundCard, int Address );\r
+\r
+\r
+MUSIC_Init select and initializes a sound card for music.  If the card\r
+is not detected or some error occured, it returns MUSIC_Error.\r
+\r
+Address is only used for General Midi and Wave Blaster.  It is the\r
+address of the MPU401 interface.  For other cards, just use 0.\r
+\r
+The two most common values are 0x330, and 0x300.  Doom and Raptor\r
+list other values, also.  To be on the safe side, you might want to\r
+support them also.  The other values are: 0x220, 0x230, 0x240, 0x250,\r
+0x300, 0x320, 0x330, 0x332, 0x334, 0x336, 0x340, 0x360.\r
+\r
+Incidently, I recommend doing your config files as text files with the\r
+extension ".INI".  This would allow people to manually enter certain\r
+settings.  I suggest the extension becuase people are familiar with it\r
+from Windows.  Check out the config file in Raptor sometime.\r
+\r
+Example:\r
+\r
+   status = MUSIC_Init( GenMidi, 0x330 );\r
+   if ( status != MUSIC_Ok )\r
+      {\r
+      printf( "Error - %s\n", MUSIC_ErrorString( MUSIC_Error ) );\r
+      exit( 1 );\r
+      }\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+int MUSIC_Shutdown( void );\r
+\r
+\r
+Ends use of the selected music card.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+void MUSIC_SetVolume( int volume );\r
+\r
+\r
+\r
+Sets the total volume of music.  Valid volumes are from 0 to 255.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+int  MUSIC_GetVolume( void );\r
+\r
+\r
+Returns the total volume of music.  Valid volumes are from 0 to 255.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+int MUSIC_PlaySong( unsigned char far *song, int loopflag );\r
+\r
+\r
+MUSIC_PlaySong begins playback of the midi file pointed to by song.\r
+\r
+Set loopflag to MUSIC_PlayOnce to play the song once, or to\r
+MUSIC_LoopSong to play it continuously.  This is usefull for the Apogee\r
+fanfare music.\r
+\r
+Note: with MUSIC_PlayOnce, the song is simply paused at the end.  You\r
+can call MUSIC_Continue to start it again.  Although I stop playing songs\r
+when you call MUSIC_PlaySong again or MUSIC_Shutdown, I recommend you\r
+call MUSIC_StopSong when you are completly done.  I chose to do it this\r
+way becuase MUSIC_StopSong will cut off sound immediatly.  This allows the\r
+sounds to decay on their own before ending.\r
+\r
+Example:\r
+\r
+   status = MUSIC_PlaySong( SongPtr, MUSIC_LoopSong );\r
+   if ( status != MUSIC_Ok )\r
+      {\r
+      printf( "Error - %s\n", MUSIC_ErrorString( MUSIC_Error ) );\r
+      exit( 1 );\r
+      }\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+void MUSIC_SetLoopFlag( int loopflag );\r
+\r
+\r
+MUSIC_SetLoopFlag allows you to change the type of looping after a song\r
+is started.  This way, you can have the song end at the end of the song.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+int MUSIC_StopSong( void );\r
+\r
+\r
+MUSIC_StopSong halts playback of the the current song.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+void MUSIC_Pause( void );\r
+\r
+\r
+MUSIC_Pause temporarily pauses playback of the song.  Use MUSIC_Continue\r
+to let the music continue.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+void MUSIC_Continue( void );\r
+\r
+\r
+MUSIC_Continue allows music to continue playing after a call to MUSIC_Pause\r
+or when the loopflag is set to MUSIC_PlayOnce and the song has finished.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+int MUSIC_SongPlaying( void );\r
+\r
+\r
+MUSIC_SongPlaying tests if a songs is playing.  Calls to MUSIC_StopSong\r
+or MUSIC_Pause will cause this to send back FALSE.\r
+\r
+Example:\r
+\r
+   // Play the fanfare music\r
+   MUSIC_PlaySong( ApogeeFanfare, MUSIC_PlayOnce );\r
+\r
+   // Hang out while it's playing\r
+   while( MUSIC_SongPlaying() )\r
+      {\r
+      // Do nothing, or maybe check for a key.\r
+      }\r
+\r
+   // Stop the song when we're done\r
+   MUSIC_StopSong();\r
+\r
+\r
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r
+³                           Fade Functions:                                 ³\r
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
+\r
+\r
+These functions are provided for you to fade the music in and out.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+int MUSIC_FadeVolume( int tovolume, int milliseconds );\r
+\r
+\r
+MUSIC_FadeVolume causes the volume of a song to gradually change to\r
+the specified volume.\r
+\r
+tovolume is the final volume the music should be at.\r
+\r
+milliseconds is the time, in milliseconds, in which to make the transition.\r
+Note: accuracy is only to 1/100 of a second.\r
+\r
+For example, to have the music fade in at the begining of a level :\r
+\r
+   // First, make sure we start at 0.\r
+   MUSIC_SetVolume( 0 );\r
+\r
+   // Start the song\r
+   MUSIC_PlaySong( Level1Music, MUSIC_LoopSong );\r
+\r
+   // Fade up to the level the user set the music at over a\r
+   // period of 4 seconds.\r
+   MUSIC_FadeVolume( UserSelectedVolumeLevel, 4000 );\r
+\r
+   PlayGame();\r
+\r
+   // At the end of the game or level, fade out over a period of 4 seconds.\r
+   MUSIC_FadeVolume( 0, 4000 );\r
+\r
+   while( MUSIC_FadeActive() )\r
+      {\r
+      // Hang around until fade is done\r
+      }\r
+\r
+   // Stop the song when we're done\r
+   MUSIC_StopSong();\r
+\r
+\r
+Note: Even if you fade the music volume to 0, the music is still playing.\r
+Remember to use MUSIC_StopSong() to end playback.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+void MUSIC_StopFade( void );\r
+\r
+\r
+MUSIC_StopFade is used if you want to stop the fade.  When called, the\r
+volume remains at the volume it had progressed to.  You don't need to\r
+call this function unless you have a reason to.  I use this internally\r
+and left it public in case someone needed it.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+int MUSIC_FadeActive( void );\r
+\r
+\r
+MUSIC_FadeActive returns a flag stating if a fade is in progress.  This\r
+is useful if you want to wait until the music has faded out before doing\r
+something.\r
+\r
+\r
+ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r
+³                           Timer Functions:                                ³\r
+ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
+\r
+\r
+Since my routines depend heavily on the timer, I have to assume I own\r
+it.  To make it easy for you to do timing, I wrote Task_Man to handle\r
+all requests for the timer.\r
+\r
+To use Task_Man, you must include "Task_Man.h".\r
+\r
+Here's an example how to set up a simple counter running at 30 times\r
+per second:\r
+\r
+#include <stdio.h>\r
+#include "task_man.h"\r
+\r
+void TimeFunction( task *Task );\r
+\r
+// Here's our timer function.  It just increments a counter.\r
+void TimeFunction\r
+   (\r
+   task *Task\r
+   )\r
+\r
+   {\r
+   int *Count;\r
+\r
+   Count = Task->data;\r
+   ( *Count )++;\r
+   }\r
+\r
+void main\r
+   (\r
+   void\r
+   )\r
+\r
+   {\r
+   task *TimerTask;\r
+   int  Count;\r
+\r
+   Count = 0;\r
+\r
+   // Schedule our timing task\r
+   TimerTask = TS_ScheduleTask( TimeFunction, 30, 1, &Count );\r
+\r
+   // Make sure we start it\r
+   TS_Dispatch();\r
+\r
+   while( !kbhit() )\r
+      {\r
+      printf( "Count = %d\n", Count );\r
+      }\r
+\r
+   // clear the key that was hit\r
+   getch();\r
+\r
+   // Hey, let's change it so it runs at 1000 times a second!\r
+   TS_SetTaskRate( TimerTask, 1000 );\r
+\r
+   while( !kbhit() )\r
+      {\r
+      printf( "Count = %d\n", Count );\r
+      }\r
+\r
+   // clear the key that was hit\r
+   getch();\r
+\r
+   // Stop the clock before we leave\r
+   TS_Terminate( TimerTask );\r
+   }\r
+\r
+\r
+Try out that program to see how it works.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+task *TS_ScheduleTask( void ( *Function )( task * ), int rate,\r
+                       int priority, void *data );\r
+\r
+\r
+TS_ScheduleTask add your function to the list of routines that use the\r
+timer.  You can it set to any rate you would normally be able to program\r
+the PC's internal timer for.\r
+\r
+rate is the number of times per second your routine should be called.\r
+\r
+priority is used for when tasks occur simultaniously and must be called in\r
+a specific order.\r
+\r
+data allows you to pass variables into your timer.  You could set up\r
+several tasks using one function, but sending in pointers to different\r
+data.  Here's how to use it:\r
+\r
+   int   Data1 = 0;\r
+   int   Data2 = 100;\r
+   task *Timer1;\r
+   task *Timer2;\r
+\r
+   Timer1 = TS_ScheduleTask( Function, 100, 1, &Data1 );\r
+   Timer2 = TS_ScheduleTask( Function, 200, 1, &Data2 );\r
+   TS_Dispatch();\r
+   .\r
+   .\r
+   .\r
+void Function\r
+   (\r
+   task *Task\r
+   )\r
+\r
+   {\r
+   int *data;\r
+\r
+   data = ( int * )Task->data;\r
+   *data++;\r
+   }\r
+\r
+The task * that's passed in can also be used to control your task.\r
+For example, to terminate your task after a certain period of time:\r
+\r
+void Function\r
+   (\r
+   task *Task\r
+   )\r
+\r
+   {\r
+   int *data;\r
+\r
+   data = ( int * )Task->data;\r
+   *data++;\r
+\r
+   // After 100 times, this task commits suicide.\r
+   if ( *data > 100 )\r
+      {\r
+      TS_Terminate( Task );\r
+      }\r
+   }\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+void TS_Dispatch( void );\r
+\r
+\r
+TS_Dispatch starts the timer on all waiting scheduled events.  Several\r
+events may be scheduled before calling TS_Dispatch.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+int TS_Terminate( task *ptr );\r
+\r
+\r
+TS_Terminate ends a task.  Use this when your done with a task.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
+\r
+void TS_SetTaskRate( task *Task, int rate );\r
+\r
+\r
+TS_SetTaskRate allows you to change the rate a task runs at after you've\r
+started it up.\r
+\r
+\r
+ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
diff --git a/audiolib/PUBLIC/PM/GMTIMBRE.TMB b/audiolib/PUBLIC/PM/GMTIMBRE.TMB
new file mode 100644 (file)
index 0000000..748a3dd
Binary files /dev/null and b/audiolib/PUBLIC/PM/GMTIMBRE.TMB differ
diff --git a/audiolib/PUBLIC/PM/MAKEFILE b/audiolib/PUBLIC/PM/MAKEFILE
new file mode 100644 (file)
index 0000000..a839019
--- /dev/null
@@ -0,0 +1,45 @@
+.OPTIMIZE\r
+\r
+lib_dir                  = ..\r
+prg_dir           = .\r
+obj_dir           = $(prg_dir)\obj\r
+main_dir          = $(prg_dir)\source\r
+header_dir        = $(main_dir);$(lib_dir)\INCLUDE\r
+tasm_include_dir  = /i$(main_dir) /i$(lib_dir)\source\r
+\r
+lib_files         = $(lib_dir)\audio_wf.lib\r
+\r
+.h   :              $(header_dir)\r
+.c   :              $(header_dir)\r
+.asm :              $(header_dir)\r
+.obj :              $(obj_dir)\r
+\r
+object_files        = pm.obj usrhooks.obj\r
+\r
+tasm_options        = /zi /p $(tasm_include_dir)\r
+#wcc_options         = /w4 /d2 /i=$(header_dir)\r
+wcc_options         = /w4 /d1 /omaxnet /zp4 /5r /i=$(header_dir)\r
+wlink_options       =\r
+\r
+pm.exe: $(object_files) $(lib_files) makefile\r
+   %create temp.lnk\r
+   %append temp.lnk option quiet\r
+   %append temp.lnk option stack=128k\r
+   %append temp.lnk system dos4g\r
+   %append temp.lnk name $^&\r
+   %append temp.lnk debug all\r
+   %append temp.lnk libfile $(lib_files)\r
+   for %i in ($(object_files)) do %append temp.lnk file $(obj_dir)\%i\r
+   wlink $(wlink_options) @temp.lnk\r
+   #wc2dbg pm.exe\r
+   del temp.lnk\r
+\r
+.asm.obj :\r
+   tasm $(tasm_options) $[* $(obj_dir)\$^&\r
+\r
+.c.obj :\r
+   wcc386 $(wcc_options) $[* /fo=$(obj_dir)\$^&\r
+\r
+pm.obj     : pm.c music.h sndcards.h\r
+\r
+usrhooks.obj : usrhooks.c usrhooks.h\r
diff --git a/audiolib/PUBLIC/PM/MAKETMB.EXE b/audiolib/PUBLIC/PM/MAKETMB.EXE
new file mode 100644 (file)
index 0000000..2be5402
Binary files /dev/null and b/audiolib/PUBLIC/PM/MAKETMB.EXE differ
diff --git a/audiolib/PUBLIC/PM/OBJ/PM.OBJ b/audiolib/PUBLIC/PM/OBJ/PM.OBJ
new file mode 100644 (file)
index 0000000..9c8ebc1
Binary files /dev/null and b/audiolib/PUBLIC/PM/OBJ/PM.OBJ differ
diff --git a/audiolib/PUBLIC/PM/OBJ/USRHOOKS.OBJ b/audiolib/PUBLIC/PM/OBJ/USRHOOKS.OBJ
new file mode 100644 (file)
index 0000000..656746b
Binary files /dev/null and b/audiolib/PUBLIC/PM/OBJ/USRHOOKS.OBJ differ
diff --git a/audiolib/PUBLIC/PM/PM.EXE b/audiolib/PUBLIC/PM/PM.EXE
new file mode 100644 (file)
index 0000000..c4fd81e
Binary files /dev/null and b/audiolib/PUBLIC/PM/PM.EXE differ
diff --git a/audiolib/PUBLIC/PM/PM.TXT b/audiolib/PUBLIC/PM/PM.TXT
new file mode 100644 (file)
index 0000000..abb1556
--- /dev/null
@@ -0,0 +1,37 @@
+PM is a quick and dirty file player for DOS using the Apogee Sound System.\r
+\r
+If you type PM with no arguments you'll get the following information:\r
+\r
+PM Version 1.10 by Jim Dos\82\r
+Usage: PM [ midifile ] CARD=[ card number ] MPU=[ port address in hex ]\r
+          TIMBRE=[ timbre file ]\r
+\r
+   card number =\r
+      0 : General Midi\r
+      1 : Sound Canvas\r
+      2 : Awe 32\r
+      3 : WaveBlaster\r
+      4 : SoundBlaster\r
+      5 : Pro AudioSpectrum\r
+      6 : Sound Man 16\r
+      7 : Adlib\r
+      8 : Ensoniq SoundScape\r
+      9 : Gravis UltraSound\r
+\r
+So, if you want to play FANFARE.MID on a Sound Canvas at port 330h, type:\r
+   PM Fanfare.mid card=1 mpu=330\r
+\r
+The TIMBRE parameter tells PM to use the MAKETMB generated timbre file\r
+specified.  This is useful when you're testing new timbres and want to\r
+see how they sound.\r
+\r
+You can also set an environment variable that has the card settings you\r
+want to use by default and PM will use it.  Just type "SET PM=<card>,<mpu>"\r
+where <card> is the card number and <mpu> is the address of the MIDI card\r
+(if any).  So for a Sound Canvas at port 330h, you would use "SET PM=1,330".\r
+Then you can just type "PM Fanfare.mid" on the command line to play your\r
+song without worrying about the card and mpu parameters.\r
+\r
+If you have any problems or questions, call me at (214)-271-1365 ext. 221.\r
+\r
+Jim Dos\82\r
diff --git a/audiolib/PUBLIC/PM/README.TXT b/audiolib/PUBLIC/PM/README.TXT
new file mode 100644 (file)
index 0000000..5eb58cd
--- /dev/null
@@ -0,0 +1,31 @@
+\r
+Here's a quick explanation of the files included in this zip file:\r
+\r
+  README.TXT : This file\r
+      PM.TXT : A quick explanation of the PM.EXE midi player\r
+      PM.EXE : PM - a command line midi file player\r
+ MAKETMB.EXE : this generates TMB files for use by PM.  Read GMTIMBRE.INI\r
+GMTIMBRE.TMB : A timbre file generated by MAKETMB\r
+GMTIMBRE.INI : An example timbre script for MAKETMB.  Generates GMTIMBRE.TMB\r
+  PERCUS.IBK : General MIDI percussion instruments.  Used by GMTIMBRE.INI\r
+ GENMIDI.IBK : General MIDI percussion instruments.  Used by GMTIMBRE.INI\r
+ TIMBRES.ZIP : A couple sets of instrument banks that can be used as\r
+               source material for fm instruments.\r
+\r
+\r
+MAKETMB is a simple utility to allow developers to develop and use their\r
+own FM instrument banks with the Apogee Sound System.  It can generate\r
+either a data file or source code (ask me if you'd prefer to use this\r
+feature) containing the instruments and usable by the sound system.\r
+\r
+The benefit of having the instruments in a data file is that multiple files\r
+could be made, each with instruments specific to a particular song or set\r
+of songs.  It also allows you to make quick changes to the instruments and\r
+hear them in a song (using PM) very quickly, without having to recompile\r
+the code (very useful for musicians).\r
+\r
+I know I'm terrible at writing documentation, so if these files are a little\r
+vague, give me a call and I'll walk you through it.\r
+\r
+Jim Dosé\82\r
+(214)-271-1365 Ext. 221\r
diff --git a/audiolib/PUBLIC/PM/SOURCE/PM.C b/audiolib/PUBLIC/PM/SOURCE/PM.C
new file mode 100644 (file)
index 0000000..4c8a2ad
--- /dev/null
@@ -0,0 +1,537 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: PM.C\r
+\r
+   author: James R. Dose\r
+   date:   January 16, 1994\r
+\r
+   Simple music player.\r
+\r
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.\r
+**********************************************************************/\r
+\r
+#include <conio.h>\r
+#include <dos.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include "music.h"\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function prototypes\r
+---------------------------------------------------------------------*/\r
+\r
+void  LoadTimbres( char *timbrefile );\r
+char *LoadMidi( char *filename );\r
+char *GetUserText( const char *parameter );\r
+int   CheckUserParm( const char *parameter );\r
+void  DefaultExtension( char *path, char *extension );\r
+void  TurnOffTextCursor( void );\r
+void  TurnOnTextCursor( void );\r
+\r
+#define TRUE  ( 1 == 1 )\r
+#define FALSE ( !TRUE )\r
+\r
+#define NUMCARDS 10\r
+\r
+char *SoundCardNames[] =\r
+   {\r
+   "General Midi", "Sound Canvas", "Awe 32", "WaveBlaster",\r
+   "SoundBlaster", "Pro AudioSpectrum", "Sound Man 16", "Adlib",\r
+   "Ensoniq SoundScape", "Gravis UltraSound"\r
+   };\r
+\r
+int SoundCardNums[] =\r
+   {\r
+   GenMidi, SoundCanvas, Awe32, WaveBlaster,\r
+   SoundBlaster, ProAudioSpectrum, SoundMan16,\r
+   Adlib, SoundScape, UltraSound\r
+   };\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: main\r
+\r
+   Sets up sound cards, calls the demo, and then cleans up.\r
+---------------------------------------------------------------------*/\r
+\r
+void main\r
+   (\r
+   int argc,\r
+   char *argv[]\r
+   )\r
+\r
+   {\r
+   int card;\r
+   int address;\r
+   int status;\r
+   char *SongPtr = NULL;\r
+   char *ptr;\r
+   char  filename[ 128 ];\r
+   char  timbrefile[ 128 ];\r
+   int   gotopos = 0;\r
+   int   measure = 0;\r
+   int   beat = 0;\r
+   int   tick = 0;\r
+   int   time = 0;\r
+\r
+   printf( "\nPM   EMIDI Music Player   Version 1.21  Copyright (c) 1996 by Jim Dose\n" );\r
+\r
+   if ( ( CheckUserParm( "?" ) ) || ( argc < 2 ) )\r
+      {\r
+      int index;\r
+\r
+      printf(\r
+         "Usage: PM [ midifile ] CARD=[ card number ] MPU=[ port address in hex ]\n"\r
+         "          TIMBRE=[ timbre file ] TIME=[minutes:seconds:milliseconds]\n"\r
+         "          POSITION=[measure:beat:tick]\n\n"\r
+         "   card number = \n" );\r
+      for( index = 0; index < NUMCARDS; index++ )\r
+         {\r
+         printf( "      %d : %s\n", index, SoundCardNames[ index ] );\r
+         }\r
+\r
+      printf( "\n" );\r
+      exit( 0 );\r
+      }\r
+\r
+   // Default is GenMidi\r
+   card = 0;\r
+   address = 0x330;\r
+\r
+   ptr = getenv( "PM" );\r
+   if ( ptr != NULL )\r
+      {\r
+      sscanf( ptr, "%d,%x", &card, &address );\r
+      }\r
+\r
+   ptr = GetUserText( "MPU" );\r
+   if ( ptr != NULL )\r
+      {\r
+      sscanf( ptr, "%x", &address );\r
+      }\r
+\r
+   ptr = GetUserText( "TIMBRE" );\r
+   if ( ptr != NULL )\r
+      {\r
+      sscanf( ptr, "%s", timbrefile );\r
+      LoadTimbres( timbrefile );\r
+      }\r
+\r
+   ptr = GetUserText( "POSITION" );\r
+   if ( ptr != NULL )\r
+      {\r
+      gotopos = 1;\r
+      sscanf( ptr, "%d:%d:%d", &measure, &beat, &tick );\r
+      }\r
+\r
+   ptr = GetUserText( "TIME" );\r
+   if ( ptr != NULL )\r
+      {\r
+      int minutes = 0;\r
+      int seconds = 0;\r
+      int milli   = 0;\r
+\r
+      gotopos = 2;\r
+      sscanf( ptr, "%d:%d:%d", &minutes, &seconds, &milli );\r
+      time = minutes * ( 60 * 1000 ) + seconds * 1000 + milli;\r
+      }\r
+\r
+   ptr = GetUserText( "CARD" );\r
+   if ( ptr != NULL )\r
+      {\r
+      sscanf( ptr, "%d", &card );\r
+      }\r
+\r
+   if ( ( card < 0 ) || ( card >= NUMCARDS ) )\r
+      {\r
+      printf( "Value out of range for CARD: %d\n", card );\r
+      }\r
+\r
+   status = MUSIC_Init( SoundCardNums[ card ], address );\r
+   if ( status != MUSIC_Ok )\r
+      {\r
+      printf( "Error - %s\n", MUSIC_ErrorString( status ) );\r
+      exit( 1 );\r
+      }\r
+\r
+   strcpy( filename, argv[ 1 ] );\r
+   DefaultExtension( filename, ".mid" );\r
+\r
+   SongPtr = LoadMidi( filename );\r
+\r
+   MUSIC_SetVolume( 255 );\r
+\r
+   status = MUSIC_PlaySong( SongPtr, MUSIC_LoopSong );\r
+   if ( status != MUSIC_Ok )\r
+      {\r
+      printf( "Error - %s\n", MUSIC_ErrorString( status ) );\r
+      }\r
+   else\r
+      {\r
+      char ch;\r
+      songposition pos;\r
+\r
+      if ( gotopos == 1 )\r
+         {\r
+         MUSIC_SetSongPosition( measure, beat, tick );\r
+         }\r
+      else if ( gotopos == 2 )\r
+         {\r
+         MUSIC_SetSongTime( time );\r
+         }\r
+\r
+      printf( "Playing file '%s'.\n\n", filename );\r
+      printf( "Press F to advance one measure.\n"\r
+              "Press R to rewind one measure.\n"\r
+              "Press G to go to the selected position.\n"\r
+              "Press ESCape to end.\n\n" );\r
+\r
+      MUSIC_GetSongLength( &pos );\r
+      printf( "Song length: time (m:s:ms) = %d:%d:%d, "\r
+         "(measure:beat:tick) = %d:%d:%d\n\n",\r
+         pos.milliseconds / (60*1000),\r
+         ( pos.milliseconds / 1000 ) % 60,\r
+         pos.milliseconds % 1000,\r
+         pos.measure, pos.beat, pos.tick );\r
+      ch = 0;\r
+\r
+      TurnOffTextCursor();\r
+      while( ch != 27 )\r
+         {\r
+         MUSIC_GetSongPosition( &pos );\r
+         printf( "time (m:s:ms) = %d:%d:%d     \t(measure:beat:tick) = %d:%d:%d          \r",\r
+            pos.milliseconds / (60*1000),\r
+            ( pos.milliseconds / 1000 ) % 60,\r
+            pos.milliseconds % 1000,\r
+            pos.measure, pos.beat, pos.tick );\r
+         fflush( stdout );\r
+\r
+         if ( kbhit() )\r
+            {\r
+            ch = getch();\r
+\r
+            if ( ( ch == 'G' ) || ( ch == 'g' ) )\r
+               {\r
+               if ( gotopos == 1 )\r
+                  {\r
+                  MUSIC_SetSongPosition( measure, beat, tick );\r
+                  }\r
+               else\r
+                  {\r
+                  MUSIC_SetSongTime( time );\r
+                  }\r
+\r
+               ch = 0;\r
+               while( kbhit() )\r
+                  {\r
+                  getch();\r
+                  }\r
+               }\r
+            if ( ( ch == 'F' ) || ( ch == 'f' ) )\r
+               {\r
+               MUSIC_SetSongPosition( pos.measure + 1, 1, 0 );\r
+               ch = 0;\r
+               while( kbhit() )\r
+                  {\r
+                  getch();\r
+                  }\r
+               }\r
+            if ( ( ch == 'R' ) || ( ch == 'r' ) )\r
+               {\r
+               MUSIC_SetSongPosition( pos.measure - 1, 1, 0 );\r
+               ch = 0;\r
+               while( kbhit() )\r
+                  {\r
+                  getch();\r
+                  }\r
+               }\r
+            }\r
+         }\r
+\r
+      TurnOnTextCursor();\r
+      MUSIC_StopSong();\r
+      }\r
+\r
+   free( SongPtr );\r
+   MUSIC_Shutdown();\r
+   printf( "\n" );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: LoadTimbres\r
+\r
+   Loads the instruments from disk\r
+---------------------------------------------------------------------*/\r
+\r
+void LoadTimbres\r
+   (\r
+   char *timbrefile\r
+   )\r
+\r
+   {\r
+   FILE   *in;\r
+   long   size;\r
+   char   *TimbrePtr;\r
+\r
+   if ( ( in = fopen( timbrefile, "rb" ) ) == NULL )\r
+      {\r
+      printf( "Cannot open '%s' for read.\n", timbrefile );\r
+      exit( 1 );\r
+      }\r
+\r
+   fseek( in, 0, SEEK_END );\r
+   size = ftell( in );\r
+   fseek( in, 0, SEEK_SET );\r
+\r
+   TimbrePtr = ( char * )malloc( size );\r
+   if ( TimbrePtr == NULL )\r
+      {\r
+      printf( "Out of memory while reading '%s'.\n", timbrefile );\r
+      exit( 1 );\r
+      }\r
+\r
+   if ( fread( TimbrePtr, size, 1, in ) != 1 )\r
+      {\r
+      printf( "Unexpected end of file while reading '%s'.\n", timbrefile );\r
+      exit(1);\r
+      }\r
+\r
+   fclose( in );\r
+\r
+   MUSIC_RegisterTimbreBank( TimbrePtr );\r
+   }\r
+\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: LoadMidi\r
+\r
+   Loads the midi file from disk.\r
+---------------------------------------------------------------------*/\r
+\r
+char *LoadMidi\r
+   (\r
+   char *filename\r
+   )\r
+\r
+   {\r
+   FILE   *in;\r
+   long   size;\r
+   char   *MidiPtr;\r
+\r
+   if ( ( in = fopen( filename, "rb" ) ) == NULL )\r
+      {\r
+      printf( "Cannot open '%s' for read.\n", filename );\r
+      exit( 1 );\r
+      }\r
+\r
+   fseek( in, 0, SEEK_END );\r
+   size = ftell( in );\r
+   fseek( in, 0, SEEK_SET );\r
+\r
+   MidiPtr = ( char * )malloc( size );\r
+   if ( MidiPtr == NULL )\r
+      {\r
+      printf( "Out of memory while reading '%s'.\n", filename );\r
+      exit( 1 );\r
+      }\r
+\r
+   if ( fread( MidiPtr, size, 1, in ) != 1 )\r
+      {\r
+      printf( "Unexpected end of file while reading '%s'.\n", filename );\r
+      exit(1);\r
+      }\r
+\r
+   fclose( in );\r
+\r
+   return( MidiPtr );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: GetUserText\r
+\r
+   Checks if the specified string is present in the command line\r
+   and returns a pointer to the text following it.\r
+---------------------------------------------------------------------*/\r
+\r
+char *GetUserText\r
+   (\r
+   const char *parameter\r
+   )\r
+\r
+   {\r
+   int i;\r
+   int length;\r
+   char *text;\r
+   char *ptr;\r
+\r
+   extern int   _argc;\r
+   extern char **_argv;\r
+\r
+   text = NULL;\r
+   length = strlen( parameter );\r
+   i = 1;\r
+   while( i < _argc )\r
+      {\r
+      ptr = _argv[ i ];\r
+\r
+      if ( ( strnicmp( parameter, ptr, length ) == 0 ) &&\r
+         ( *( ptr + length ) == '=' ) )\r
+         {\r
+         text = ptr + length + 1;\r
+         break;\r
+         }\r
+\r
+      i++;\r
+      }\r
+\r
+   return( text );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: CheckUserParm\r
+\r
+   Checks if the specified string is present in the command line.\r
+---------------------------------------------------------------------*/\r
+\r
+int CheckUserParm\r
+   (\r
+   const char *parameter\r
+   )\r
+\r
+   {\r
+   int i;\r
+   int found;\r
+   char *ptr;\r
+\r
+   extern int   _argc;\r
+   extern char **_argv;\r
+\r
+   found = FALSE;\r
+   i = 1;\r
+   while( i < _argc )\r
+      {\r
+      ptr = _argv[ i ];\r
+\r
+      // Only check parameters preceded by - or /\r
+      if ( ( *ptr == '-' ) || ( *ptr == '/' ) )\r
+         {\r
+         ptr++;\r
+         if ( stricmp( parameter, ptr ) == 0 )\r
+            {\r
+            found = TRUE;\r
+            break;\r
+            }\r
+         }\r
+\r
+      i++;\r
+      }\r
+\r
+   return( found );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: DefaultExtension\r
+\r
+   Checks if the specified filename contains an extension and adds\r
+   one if it doesn't.\r
+---------------------------------------------------------------------*/\r
+\r
+void DefaultExtension\r
+   (\r
+   char *path,\r
+   char *extension\r
+   )\r
+\r
+   {\r
+       char    *src;\r
+\r
+   //\r
+   // if path doesn't have a .EXT, append extension\r
+   // (extension should include the .)\r
+   //\r
+   src = path + strlen( path ) - 1;\r
+\r
+   while( ( *src != '\\' ) && ( src != path ) )\r
+      {\r
+      if ( *src == '.' )\r
+         {\r
+         // it has an extension\r
+         return;\r
+         }\r
+      src--;\r
+      }\r
+\r
+   strcat( path, extension );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: TurnOffTextCursor\r
+\r
+   Turns the cursor off.\r
+---------------------------------------------------------------------*/\r
+\r
+void TurnOffTextCursor\r
+   (\r
+   void\r
+   )\r
+\r
+   {\r
+   union REGS regs;\r
+\r
+   regs.w.ax = 0x0100;\r
+   regs.w.cx = 0x2000;\r
+#ifdef __FLAT__\r
+   int386(0x10,&regs,&regs);\r
+#else\r
+   int86(0x10,&regs,&regs);\r
+#endif\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: TurnOnTextCursor\r
+\r
+   Turns the cursor on.\r
+---------------------------------------------------------------------*/\r
+\r
+void TurnOnTextCursor\r
+   (\r
+   void\r
+   )\r
+\r
+   {\r
+   union REGS regs;\r
+\r
+   regs.w.ax = 0x0100;\r
+   regs.w.cx = 0x0708;\r
+#ifdef __FLAT__\r
+   int386(0x10,&regs,&regs);\r
+#else\r
+   int86(0x10,&regs,&regs);\r
+#endif\r
+   }\r
diff --git a/audiolib/PUBLIC/PM/SOURCE/USRHOOKS.C b/audiolib/PUBLIC/PM/SOURCE/USRHOOKS.C
new file mode 100644 (file)
index 0000000..a2058d1
--- /dev/null
@@ -0,0 +1,84 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: USRHOOKS.C\r
+\r
+   author: James R. Dose\r
+   date:   July 26, 1994\r
+\r
+   This module contains cover functions for operations the library\r
+   needs that may be restricted by the calling program.  This code\r
+   is left public for you to modify.\r
+**********************************************************************/\r
+\r
+#include <stdlib.h>\r
+#include "usrhooks.h"\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: USRHOOKS_GetMem\r
+\r
+   Allocates the requested amount of memory and returns a pointer to\r
+   its location, or NULL if an error occurs.  NOTE: pointer is assumed\r
+   to be dword aligned.\r
+---------------------------------------------------------------------*/\r
+\r
+int USRHOOKS_GetMem\r
+   (\r
+   void **ptr,\r
+   unsigned long size\r
+   )\r
+\r
+   {\r
+   void *memory;\r
+\r
+   memory = malloc( size );\r
+   if ( memory == NULL )\r
+      {\r
+      return( USRHOOKS_Error );\r
+      }\r
+\r
+   *ptr = memory;\r
+\r
+   return( USRHOOKS_Ok );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: USRHOOKS_FreeMem\r
+\r
+   Deallocates the memory associated with the specified pointer.\r
+---------------------------------------------------------------------*/\r
+\r
+int USRHOOKS_FreeMem\r
+   (\r
+   void *ptr\r
+   )\r
+\r
+   {\r
+   if ( ptr == NULL )\r
+      {\r
+      return( USRHOOKS_Error );\r
+      }\r
+\r
+   free( ptr );\r
+\r
+   return( USRHOOKS_Ok );\r
+   }\r
diff --git a/audiolib/PUBLIC/PM/SOURCE/USRHOOKS.H b/audiolib/PUBLIC/PM/SOURCE/USRHOOKS.H
new file mode 100644 (file)
index 0000000..d030421
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: USRHOOKS.H\r
+\r
+   author: James R. Dose\r
+   date:   July 26, 1994\r
+\r
+   Public header file for USRHOOKS.C.\r
+\r
+   This module contains cover functions for operations the library\r
+   needs that may be restricted by the calling program.  The function\r
+   prototypes in this header should not be modified.\r
+**********************************************************************/\r
+\r
+#ifndef __USRHOOKS_H\r
+#define __USRHOOKS_H\r
+\r
+/*---------------------------------------------------------------------\r
+   Error definitions\r
+---------------------------------------------------------------------*/\r
+\r
+enum USRHOOKS_Errors\r
+   {\r
+   USRHOOKS_Warning = -2,\r
+   USRHOOKS_Error   = -1,\r
+   USRHOOKS_Ok      = 0\r
+   };\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function Prototypes\r
+---------------------------------------------------------------------*/\r
+\r
+int USRHOOKS_GetMem( void **ptr, unsigned long size );\r
+int USRHOOKS_FreeMem( void *ptr );\r
+\r
+#endif\r
diff --git a/audiolib/PUBLIC/PM/TIMBRES.ZIP b/audiolib/PUBLIC/PM/TIMBRES.ZIP
new file mode 100644 (file)
index 0000000..b6209bb
Binary files /dev/null and b/audiolib/PUBLIC/PM/TIMBRES.ZIP differ
diff --git a/audiolib/PUBLIC/PS/BINDPS.BAT b/audiolib/PUBLIC/PS/BINDPS.BAT
new file mode 100644 (file)
index 0000000..86dc87b
--- /dev/null
@@ -0,0 +1,3 @@
+ren ps.exe ps2.exe\r
+call bind ps2 ps\r
+del ps2.exe\r
diff --git a/audiolib/PUBLIC/PS/MAKEFILE b/audiolib/PUBLIC/PS/MAKEFILE
new file mode 100644 (file)
index 0000000..02e17fe
--- /dev/null
@@ -0,0 +1,45 @@
+.OPTIMIZE\r
+\r
+lib_dir                  = ..\r
+prg_dir           = .\r
+obj_dir           = $(prg_dir)\\r
+main_dir          = $(prg_dir)\\r
+header_dir        = $(main_dir);$(lib_dir)\INCLUDE\r
+tasm_include_dir  = /i$(main_dir) /i$(lib_dir)\source\r
+\r
+lib_files         = $(lib_dir)\audio_wf.lib\r
+\r
+.h   :              $(header_dir)\r
+.c   :              $(header_dir)\r
+.asm :              $(header_dir)\r
+.obj :              $(obj_dir)\r
+\r
+object_files        = ps.obj usrhooks.obj\r
+\r
+tasm_options        = /zi /p $(tasm_include_dir)\r
+#wcc_options         = /w4 /d2 /i=$(header_dir)\r
+wcc_options         = /w4 /d1 /omaxnet /zp4 /5r /i=$(header_dir)\r
+wlink_options       =\r
+\r
+ps.exe: $(object_files) $(lib_files) makefile\r
+   %create temp.lnk\r
+   %append temp.lnk option quiet\r
+   %append temp.lnk option stack=128k\r
+   %append temp.lnk system dos4g\r
+   %append temp.lnk name $^&\r
+   %append temp.lnk debug all\r
+   %append temp.lnk libfile $(lib_files)\r
+   for %i in ($(object_files)) do %append temp.lnk file $(obj_dir)\%i\r
+   wlink $(wlink_options) @temp.lnk\r
+   #wc2dbg ps.exe\r
+   del temp.lnk\r
+\r
+.asm.obj :\r
+   tasm $(tasm_options) $[* $(obj_dir)\$^&\r
+\r
+.c.obj :\r
+   wcc386 $(wcc_options) $[* /fo=$(obj_dir)\$^&\r
+\r
+ps.obj     : ps.c fx_man.h sndcards.h\r
+\r
+usrhooks.obj : usrhooks.c usrhooks.h\r
diff --git a/audiolib/PUBLIC/PS/PS.C b/audiolib/PUBLIC/PS/PS.C
new file mode 100644 (file)
index 0000000..f77e24e
--- /dev/null
@@ -0,0 +1,410 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: PS.C\r
+\r
+   author: James R. Dose\r
+   date:   December 12, 1995\r
+\r
+   Simple sound player.\r
+\r
+   (c) Copyright 1995 James R. Dose.  All Rights Reserved.\r
+**********************************************************************/\r
+\r
+#include <conio.h>\r
+#include <dos.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include "fx_man.h"\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function prototypes\r
+---------------------------------------------------------------------*/\r
+\r
+char *LoadFile( char *filename, int *length );\r
+char *GetUserText( const char *parameter );\r
+int   CheckUserParm( const char *parameter );\r
+void  DefaultExtension( char *path, char *extension );\r
+\r
+#define TRUE  ( 1 == 1 )\r
+#define FALSE ( !TRUE )\r
+\r
+#define NUMCARDS 8\r
+\r
+char *SoundCardNames[] =\r
+   {\r
+   "Sound Blaster", "Awe 32", "Pro AudioSpectrum",\r
+   "Sound Man 16", "Ensoniq SoundScape", "Gravis UltraSound",\r
+   "Disney SoundSource", "Tandy SoundSource"\r
+   };\r
+\r
+int SoundCardNums[] =\r
+   {\r
+   SoundBlaster, Awe32, ProAudioSpectrum, SoundMan16,\r
+   SoundScape, UltraSound, SoundSource, TandySoundSource\r
+   };\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: main\r
+\r
+   Sets up sound cards, calls the demo, and then cleans up.\r
+---------------------------------------------------------------------*/\r
+\r
+void main\r
+   (\r
+   int argc,\r
+   char *argv[]\r
+   )\r
+\r
+   {\r
+   int card;\r
+   int voices;\r
+   int rate;\r
+   int bits;\r
+   int channels;\r
+   int reverb;\r
+   int status;\r
+   int length;\r
+   int voice;\r
+   fx_device device;\r
+   char *SoundPtr = NULL;\r
+   char *ptr;\r
+   char  filename[ 128 ];\r
+   char ch;\r
+\r
+   printf( "\nPS Version 1.0 by Jim Dose\n" );\r
+\r
+   if ( ( CheckUserParm( "?" ) ) || ( argc < 2 ) )\r
+      {\r
+      int index;\r
+\r
+      printf(\r
+         "Usage: PS [ soundfile ] CARD=[ card # ] VOICES=[ # of voices ]\n"\r
+         "          BITS=[ 8 or 16 ] [MONO/STEREO] RATE=[ mixing rate ]\n"\r
+         "          REVERB=[ reverb amount]\n\n"\r
+         "   sound card # = \n" );\r
+      for( index = 0; index < NUMCARDS; index++ )\r
+         {\r
+         printf( "      %d : %s\n", index, SoundCardNames[ index ] );\r
+         }\r
+\r
+      printf( "\nDefault: PS [ soundfile ] CARD=0 VOICES=4 "\r
+                "BITS=8 MONO RATE=11000\n\n" );\r
+      exit( 0 );\r
+      }\r
+\r
+   // Default is Sound Blaster\r
+   card     = 0;\r
+   voices   = 4;\r
+   bits     = 8;\r
+   channels = 1;\r
+   reverb   = 0;\r
+   rate     = 11000;\r
+\r
+   ptr = GetUserText( "VOICES" );\r
+   if ( ptr != NULL )\r
+      {\r
+      sscanf( ptr, "%d", &voices );\r
+      }\r
+\r
+   ptr = GetUserText( "BITS" );\r
+   if ( ptr != NULL )\r
+      {\r
+      sscanf( ptr, "%d", &bits );\r
+      }\r
+\r
+   ptr = GetUserText( "RATE" );\r
+   if ( ptr != NULL )\r
+      {\r
+      sscanf( ptr, "%d", &rate );\r
+      }\r
+\r
+   ptr = GetUserText( "REVERB" );\r
+   if ( ptr != NULL )\r
+      {\r
+      sscanf( ptr, "%d", &reverb );\r
+      }\r
+\r
+   ptr = GetUserText( "MONO" );\r
+   if ( ptr != NULL )\r
+      {\r
+      channels = 1;\r
+      }\r
+\r
+   ptr = GetUserText( "STEREO" );\r
+   if ( ptr != NULL )\r
+      {\r
+      channels = 2;\r
+      }\r
+\r
+   ptr = GetUserText( "CARD" );\r
+   if ( ptr != NULL )\r
+      {\r
+      sscanf( ptr, "%d", &card );\r
+      }\r
+\r
+   if ( ( card < 0 ) || ( card >= NUMCARDS ) )\r
+      {\r
+      printf( "Value out of range for sound card #: %d\n", card );\r
+      exit( 1 );\r
+      }\r
+\r
+   strcpy( filename, argv[ 1 ] );\r
+   DefaultExtension( filename, ".wav" );\r
+   SoundPtr = LoadFile( filename, &length );\r
+   if ( !SoundPtr )\r
+      {\r
+      strcpy( filename, argv[ 1 ] );\r
+      DefaultExtension( filename, ".voc" );\r
+      SoundPtr = LoadFile( filename, &length );\r
+      if ( !SoundPtr )\r
+         {\r
+         strcpy( filename, argv[ 1 ] );\r
+         SoundPtr = LoadFile( filename, &length );\r
+         if ( !SoundPtr )\r
+            {\r
+            printf( "Cannot open '%s' for read.\n", argv[ 1 ] );\r
+            exit( 1 );\r
+            }\r
+         }\r
+      }\r
+\r
+   status = FX_SetupCard( card, &device );\r
+   if ( status != FX_Ok )\r
+      {\r
+      printf( "%s\n", FX_ErrorString( status ) );\r
+      exit( 1 );\r
+      }\r
+\r
+   status = FX_Init( card, voices, channels, bits, rate );\r
+   if ( status != FX_Ok )\r
+      {\r
+      printf( "%s\n", FX_ErrorString( status ) );\r
+      exit( 1 );\r
+      }\r
+\r
+   FX_SetReverb( reverb );\r
+\r
+   FX_SetVolume( 255 );\r
+\r
+   printf( "Playing file '%s'.\n\n", filename );\r
+   printf( "Press any key to play the sound.\n"\r
+           "Press ESCape to end.\n\n" );\r
+\r
+   ch = 0;\r
+   while( ch != 27 )\r
+      {\r
+      if ( stricmp( &filename[ strlen( filename ) - 3 ], "WAV" ) == 0 )\r
+         {\r
+         voice = FX_PlayWAV( SoundPtr, 0, 255, 255, 255, 0, 0 );\r
+         }\r
+      else if ( stricmp( &filename[ strlen( filename ) - 3 ], "VOC" ) == 0 )\r
+         {\r
+         voice = FX_PlayVOC( SoundPtr, 0, 255, 255, 255, 0, 0 );\r
+         }\r
+      else\r
+         {\r
+         voice = FX_PlayRaw( SoundPtr, length, rate, 0, 255, 255, 255, 0, 0 );\r
+         }\r
+\r
+      if ( voice < FX_Ok )\r
+         {\r
+         printf( "Sound error - %s\n", FX_ErrorString( status ) );\r
+         }\r
+\r
+      ch = getch();\r
+      }\r
+\r
+   FX_StopAllSounds();\r
+   free( SoundPtr );\r
+   FX_Shutdown();\r
+\r
+   printf( "\n" );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: LoadFile\r
+\r
+   Loads a file from disk.\r
+---------------------------------------------------------------------*/\r
+\r
+char *LoadFile\r
+   (\r
+   char *filename,\r
+   int  *length\r
+   )\r
+\r
+   {\r
+   FILE   *in;\r
+   long   size;\r
+   char   *ptr;\r
+\r
+   if ( ( in = fopen( filename, "rb" ) ) == NULL )\r
+      {\r
+      return NULL;\r
+      }\r
+\r
+   fseek( in, 0, SEEK_END );\r
+   size = ftell( in );\r
+   fseek( in, 0, SEEK_SET );\r
+\r
+   ptr = ( char * )malloc( size );\r
+   if ( ptr == NULL )\r
+      {\r
+      printf( "Out of memory while reading '%s'.\n", filename );\r
+      exit( 1 );\r
+      }\r
+\r
+   if ( fread( ptr, size, 1, in ) != 1 )\r
+      {\r
+      printf( "Unexpected end of file while reading '%s'.\n", filename );\r
+      exit(1);\r
+      }\r
+\r
+   fclose( in );\r
+\r
+   *length = size;\r
+\r
+   return( ptr );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: GetUserText\r
+\r
+   Checks if the specified string is present in the command line\r
+   and returns a pointer to the text following it.\r
+---------------------------------------------------------------------*/\r
+\r
+char *GetUserText\r
+   (\r
+   const char *parameter\r
+   )\r
+\r
+   {\r
+   int i;\r
+   int length;\r
+   char *text;\r
+   char *ptr;\r
+\r
+   extern int   _argc;\r
+   extern char **_argv;\r
+\r
+   text = NULL;\r
+   length = strlen( parameter );\r
+   i = 1;\r
+   while( i < _argc )\r
+      {\r
+      ptr = _argv[ i ];\r
+\r
+      if ( ( strnicmp( parameter, ptr, length ) == 0 ) &&\r
+         ( *( ptr + length ) == '=' ) )\r
+         {\r
+         text = ptr + length + 1;\r
+         break;\r
+         }\r
+\r
+      i++;\r
+      }\r
+\r
+   return( text );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: CheckUserParm\r
+\r
+   Checks if the specified string is present in the command line.\r
+---------------------------------------------------------------------*/\r
+\r
+int CheckUserParm\r
+   (\r
+   const char *parameter\r
+   )\r
+\r
+   {\r
+   int i;\r
+   int found;\r
+   char *ptr;\r
+\r
+   extern int   _argc;\r
+   extern char **_argv;\r
+\r
+   found = FALSE;\r
+   i = 1;\r
+   while( i < _argc )\r
+      {\r
+      ptr = _argv[ i ];\r
+\r
+      // Only check parameters preceded by - or /\r
+      if ( ( *ptr == '-' ) || ( *ptr == '/' ) )\r
+         {\r
+         ptr++;\r
+         if ( stricmp( parameter, ptr ) == 0 )\r
+            {\r
+            found = TRUE;\r
+            break;\r
+            }\r
+         }\r
+\r
+      i++;\r
+      }\r
+\r
+   return( found );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: DefaultExtension\r
+\r
+   Checks if the specified filename contains an extension and adds\r
+   one if it doesn't.\r
+---------------------------------------------------------------------*/\r
+\r
+void DefaultExtension\r
+   (\r
+   char *path,\r
+   char *extension\r
+   )\r
+\r
+   {\r
+   char  *src;\r
+\r
+   //\r
+   // if path doesn't have a .EXT, append extension\r
+   // (extension should include the .)\r
+   //\r
+   src = path + strlen( path ) - 1;\r
+\r
+   while( ( *src != '\\' ) && ( src != path ) )\r
+      {\r
+      if ( *src == '.' )\r
+         {\r
+         // it has an extension\r
+         return;\r
+         }\r
+      src--;\r
+      }\r
+\r
+   strcat( path, extension );\r
+   }\r
diff --git a/audiolib/PUBLIC/PS/PS.EXE b/audiolib/PUBLIC/PS/PS.EXE
new file mode 100644 (file)
index 0000000..851f31e
Binary files /dev/null and b/audiolib/PUBLIC/PS/PS.EXE differ
diff --git a/audiolib/PUBLIC/PS/PS.OBJ b/audiolib/PUBLIC/PS/PS.OBJ
new file mode 100644 (file)
index 0000000..9865413
Binary files /dev/null and b/audiolib/PUBLIC/PS/PS.OBJ differ
diff --git a/audiolib/PUBLIC/PS/USRHOOKS.C b/audiolib/PUBLIC/PS/USRHOOKS.C
new file mode 100644 (file)
index 0000000..a2058d1
--- /dev/null
@@ -0,0 +1,84 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: USRHOOKS.C\r
+\r
+   author: James R. Dose\r
+   date:   July 26, 1994\r
+\r
+   This module contains cover functions for operations the library\r
+   needs that may be restricted by the calling program.  This code\r
+   is left public for you to modify.\r
+**********************************************************************/\r
+\r
+#include <stdlib.h>\r
+#include "usrhooks.h"\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: USRHOOKS_GetMem\r
+\r
+   Allocates the requested amount of memory and returns a pointer to\r
+   its location, or NULL if an error occurs.  NOTE: pointer is assumed\r
+   to be dword aligned.\r
+---------------------------------------------------------------------*/\r
+\r
+int USRHOOKS_GetMem\r
+   (\r
+   void **ptr,\r
+   unsigned long size\r
+   )\r
+\r
+   {\r
+   void *memory;\r
+\r
+   memory = malloc( size );\r
+   if ( memory == NULL )\r
+      {\r
+      return( USRHOOKS_Error );\r
+      }\r
+\r
+   *ptr = memory;\r
+\r
+   return( USRHOOKS_Ok );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: USRHOOKS_FreeMem\r
+\r
+   Deallocates the memory associated with the specified pointer.\r
+---------------------------------------------------------------------*/\r
+\r
+int USRHOOKS_FreeMem\r
+   (\r
+   void *ptr\r
+   )\r
+\r
+   {\r
+   if ( ptr == NULL )\r
+      {\r
+      return( USRHOOKS_Error );\r
+      }\r
+\r
+   free( ptr );\r
+\r
+   return( USRHOOKS_Ok );\r
+   }\r
diff --git a/audiolib/PUBLIC/PS/USRHOOKS.H b/audiolib/PUBLIC/PS/USRHOOKS.H
new file mode 100644 (file)
index 0000000..d030421
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: USRHOOKS.H\r
+\r
+   author: James R. Dose\r
+   date:   July 26, 1994\r
+\r
+   Public header file for USRHOOKS.C.\r
+\r
+   This module contains cover functions for operations the library\r
+   needs that may be restricted by the calling program.  The function\r
+   prototypes in this header should not be modified.\r
+**********************************************************************/\r
+\r
+#ifndef __USRHOOKS_H\r
+#define __USRHOOKS_H\r
+\r
+/*---------------------------------------------------------------------\r
+   Error definitions\r
+---------------------------------------------------------------------*/\r
+\r
+enum USRHOOKS_Errors\r
+   {\r
+   USRHOOKS_Warning = -2,\r
+   USRHOOKS_Error   = -1,\r
+   USRHOOKS_Ok      = 0\r
+   };\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function Prototypes\r
+---------------------------------------------------------------------*/\r
+\r
+int USRHOOKS_GetMem( void **ptr, unsigned long size );\r
+int USRHOOKS_FreeMem( void *ptr );\r
+\r
+#endif\r
diff --git a/audiolib/PUBLIC/PS/USRHOOKS.OBJ b/audiolib/PUBLIC/PS/USRHOOKS.OBJ
new file mode 100644 (file)
index 0000000..c11c75c
Binary files /dev/null and b/audiolib/PUBLIC/PS/USRHOOKS.OBJ differ
diff --git a/audiolib/PUBLIC/TIMER/MAKEFILE b/audiolib/PUBLIC/TIMER/MAKEFILE
new file mode 100644 (file)
index 0000000..17a9caa
--- /dev/null
@@ -0,0 +1,45 @@
+.OPTIMIZE\r
+\r
+lib_dir                      = ..\r
+prg_dir           = .\r
+obj_dir           = $(prg_dir)\obj\r
+main_dir          = $(prg_dir)\source\r
+header_dir        = $(main_dir);$(lib_dir)\INCLUDE\r
+tasm_include_dir  = /i$(main_dir) /i$(lib_dir)\source\r
+\r
+lib_files         = $(lib_dir)\audio_wf.lib\r
+\r
+.h   :              $(header_dir)\r
+.c   :              $(header_dir)\r
+.asm :              $(header_dir)\r
+.obj :              $(obj_dir)\r
+\r
+object_files        = timer.obj usrhooks.obj\r
+\r
+tasm_options        = /zi /p $(tasm_include_dir)\r
+#wcc_options         = /w4 /d2 /zm /i=$(header_dir)\r
+wcc_options         = /w4 /d1 /omaxnet /zp4 /5r /zm /i=$(header_dir)\r
+wlink_options       =\r
+\r
+timer.exe: $(object_files) $(lib_files) makefile\r
+   %create temp.lnk\r
+   %append temp.lnk option quiet\r
+   %append temp.lnk option eliminate\r
+   %append temp.lnk system dos4g\r
+   %append temp.lnk name $^&\r
+   %append temp.lnk debug all\r
+   %append temp.lnk libfile $(lib_files)\r
+   for %i in ($(object_files)) do %append temp.lnk file $(obj_dir)\%i\r
+   wlink $(wlink_options) @temp.lnk\r
+   #wc2dbg demo.exe\r
+   del temp.lnk\r
+\r
+.asm.obj :\r
+   tasm $(tasm_options) $[* $(obj_dir)\$^&\r
+\r
+.c.obj :\r
+   wcc386 $(wcc_options) $[* /fo=$(obj_dir)\$^&\r
+\r
+demo.obj     : demo.c task_man.h\r
+\r
+usrhooks.obj : usrhooks.c usrhooks.h\r
diff --git a/audiolib/PUBLIC/TIMER/OBJ/TIMER.OBJ b/audiolib/PUBLIC/TIMER/OBJ/TIMER.OBJ
new file mode 100644 (file)
index 0000000..7088043
Binary files /dev/null and b/audiolib/PUBLIC/TIMER/OBJ/TIMER.OBJ differ
diff --git a/audiolib/PUBLIC/TIMER/OBJ/USRHOOKS.OBJ b/audiolib/PUBLIC/TIMER/OBJ/USRHOOKS.OBJ
new file mode 100644 (file)
index 0000000..8dcc96e
Binary files /dev/null and b/audiolib/PUBLIC/TIMER/OBJ/USRHOOKS.OBJ differ
diff --git a/audiolib/PUBLIC/TIMER/SOURCE/TIMER.C b/audiolib/PUBLIC/TIMER/SOURCE/TIMER.C
new file mode 100644 (file)
index 0000000..8db940c
--- /dev/null
@@ -0,0 +1,149 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: TIMER.C\r
+\r
+   author: James R. Dose\r
+   date:   October 28, 1994\r
+\r
+   Demonstrates how to set up multiple timers with TASK_MAN.\r
+\r
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.\r
+**********************************************************************/\r
+\r
+#include <conio.h>\r
+#include <dos.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include "task_man.h"\r
+\r
+/*---------------------------------------------------------------------\r
+   Function prototypes\r
+---------------------------------------------------------------------*/\r
+\r
+void  TimerFunc( task *Task );\r
+\r
+#define TRUE  ( 1 == 1 )\r
+#define FALSE ( !TRUE )\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: main\r
+---------------------------------------------------------------------*/\r
+\r
+void main\r
+   (\r
+   void\r
+   )\r
+\r
+   {\r
+   task *Task1 = NULL;\r
+   task *Task2 = NULL;\r
+   task *Task3 = NULL;\r
+   int   Timer1;\r
+   int   Timer2;\r
+   int   Timer3;\r
+\r
+   Timer1 = 0;\r
+   Timer2 = 0;\r
+   Timer3 = 0;\r
+\r
+   Task1 = TS_ScheduleTask( &TimerFunc, 60, 1, &Timer1 );\r
+   Task2 = TS_ScheduleTask( &TimerFunc, 129, 1, &Timer2 );\r
+\r
+   printf( "First, Timer 1 is set to 60 ticks per second and Timer 2 is\n"\r
+      "set to 129 ticks per second.\n" );\r
+\r
+   // Start the first two scheduled tasks\r
+   TS_Dispatch();\r
+\r
+   // Wait 5 seconds\r
+   while( Timer1 < 300 )\r
+      {\r
+      printf( "\rTimer 1 = %d\t\tTimer 2 = %d\t\tTimer 3 = %d",\r
+         Timer1, Timer2, Timer3 );\r
+      }\r
+\r
+   printf( "\n\nThen, we start Timer 3 at 849 ticks per second.\n" );\r
+\r
+   // Start the third task\r
+   Task3 = TS_ScheduleTask( &TimerFunc, 849, 1, &Timer3 );\r
+   TS_Dispatch();\r
+\r
+   // Wait 5 seconds\r
+   Timer1 = 0;\r
+   while( Timer1 < 300 )\r
+      {\r
+      printf( "\rTimer 1 = %d\t\tTimer 2 = %d\t\tTimer 3 = %d",\r
+         Timer1, Timer2, Timer3 );\r
+      }\r
+\r
+   printf( "\n\nNow we'll set Timer 2 to run at 1000 ticks per second.\n" );\r
+\r
+   // Change the task's rate\r
+   TS_SetTaskRate( Task2, 1000 );\r
+\r
+   // Wait 5 seconds\r
+   Timer1 = 0;\r
+   while( Timer1 < 300 )\r
+      {\r
+      printf( "\rTimer 1 = %d\t\tTimer 2 = %d\t\tTimer 3 = %d",\r
+         Timer1, Timer2, Timer3 );\r
+      }\r
+\r
+   printf("\n\nAnd finally, we'll halt Timer 2, leaving Timers 1 and 3 to "\r
+      "continue.\n" );\r
+\r
+   // Stop one of the timers\r
+   TS_Terminate( Task2 );\r
+\r
+   // Wait 5 seconds\r
+   Timer1 = 0;\r
+   while( Timer1 < 300 )\r
+      {\r
+      printf( "\rTimer 1 = %d\t\tTimer 2 = %d\t\tTimer 3 = %d",\r
+         Timer1, Timer2, Timer3 );\r
+      }\r
+\r
+   printf( "\n\nAnd now we're done.\n" );\r
+\r
+   // Terminate the other timers.\r
+   TS_Terminate( Task1 );\r
+   TS_Terminate( Task3 );\r
+\r
+   // Shutdown TaskMan.  Failure to do so could be fatal!!!\r
+   TS_Shutdown();\r
+   }\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: TimerFunc\r
+\r
+   A simple timer example.  Simply increments a timer passed in through\r
+   the data pointer.\r
+---------------------------------------------------------------------*/\r
+\r
+void TimerFunc\r
+   (\r
+   task *Task\r
+   )\r
+\r
+   {\r
+   ( *( int * )Task->data )++;\r
+   }\r
diff --git a/audiolib/PUBLIC/TIMER/SOURCE/USRHOOKS.C b/audiolib/PUBLIC/TIMER/SOURCE/USRHOOKS.C
new file mode 100644 (file)
index 0000000..a2058d1
--- /dev/null
@@ -0,0 +1,84 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: USRHOOKS.C\r
+\r
+   author: James R. Dose\r
+   date:   July 26, 1994\r
+\r
+   This module contains cover functions for operations the library\r
+   needs that may be restricted by the calling program.  This code\r
+   is left public for you to modify.\r
+**********************************************************************/\r
+\r
+#include <stdlib.h>\r
+#include "usrhooks.h"\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: USRHOOKS_GetMem\r
+\r
+   Allocates the requested amount of memory and returns a pointer to\r
+   its location, or NULL if an error occurs.  NOTE: pointer is assumed\r
+   to be dword aligned.\r
+---------------------------------------------------------------------*/\r
+\r
+int USRHOOKS_GetMem\r
+   (\r
+   void **ptr,\r
+   unsigned long size\r
+   )\r
+\r
+   {\r
+   void *memory;\r
+\r
+   memory = malloc( size );\r
+   if ( memory == NULL )\r
+      {\r
+      return( USRHOOKS_Error );\r
+      }\r
+\r
+   *ptr = memory;\r
+\r
+   return( USRHOOKS_Ok );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: USRHOOKS_FreeMem\r
+\r
+   Deallocates the memory associated with the specified pointer.\r
+---------------------------------------------------------------------*/\r
+\r
+int USRHOOKS_FreeMem\r
+   (\r
+   void *ptr\r
+   )\r
+\r
+   {\r
+   if ( ptr == NULL )\r
+      {\r
+      return( USRHOOKS_Error );\r
+      }\r
+\r
+   free( ptr );\r
+\r
+   return( USRHOOKS_Ok );\r
+   }\r
diff --git a/audiolib/PUBLIC/TIMER/SOURCE/USRHOOKS.H b/audiolib/PUBLIC/TIMER/SOURCE/USRHOOKS.H
new file mode 100644 (file)
index 0000000..d030421
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: USRHOOKS.H\r
+\r
+   author: James R. Dose\r
+   date:   July 26, 1994\r
+\r
+   Public header file for USRHOOKS.C.\r
+\r
+   This module contains cover functions for operations the library\r
+   needs that may be restricted by the calling program.  The function\r
+   prototypes in this header should not be modified.\r
+**********************************************************************/\r
+\r
+#ifndef __USRHOOKS_H\r
+#define __USRHOOKS_H\r
+\r
+/*---------------------------------------------------------------------\r
+   Error definitions\r
+---------------------------------------------------------------------*/\r
+\r
+enum USRHOOKS_Errors\r
+   {\r
+   USRHOOKS_Warning = -2,\r
+   USRHOOKS_Error   = -1,\r
+   USRHOOKS_Ok      = 0\r
+   };\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function Prototypes\r
+---------------------------------------------------------------------*/\r
+\r
+int USRHOOKS_GetMem( void **ptr, unsigned long size );\r
+int USRHOOKS_FreeMem( void *ptr );\r
+\r
+#endif\r
diff --git a/audiolib/PUBLIC/TIMER/TIMER.EXE b/audiolib/PUBLIC/TIMER/TIMER.EXE
new file mode 100644 (file)
index 0000000..73e6bb8
Binary files /dev/null and b/audiolib/PUBLIC/TIMER/TIMER.EXE differ
diff --git a/audiolib/SOURCE/ADLIBFX.C b/audiolib/SOURCE/ADLIBFX.C
new file mode 100644 (file)
index 0000000..2814cc7
--- /dev/null
@@ -0,0 +1,552 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: ADLIBFX.C\r
+\r
+   author: James R. Dose\r
+   date:   April 1, 1994\r
+\r
+   Low level routines to support Adlib sound effects created by Muse.\r
+\r
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.\r
+**********************************************************************/\r
+\r
+#include <dos.h>\r
+#include <stdlib.h>\r
+#include <conio.h>\r
+#include "dpmi.h"\r
+#include "task_man.h"\r
+#include "interrup.h"\r
+#include "al_midi.h"\r
+#include "adlibfx.h"\r
+\r
+#define TRUE  ( 1 == 1 )\r
+#define FALSE ( !TRUE )\r
+\r
+static void ADLIBFX_SendOutput( int reg, int data );\r
+static void ADLIBFX_Service( task *Task );\r
+\r
+static long     ADLIBFX_LengthLeft;\r
+static int      ADLIBFX_Block;\r
+static ALSound *ADLIBFX_Sound = NULL;\r
+static char    *ADLIBFX_SoundPtr = NULL;\r
+static int      ADLIBFX_Priority;\r
+static unsigned long ADLIBFX_CallBackVal;\r
+static void     ( *ADLIBFX_CallBackFunc )( unsigned long ) = NULL;\r
+static int      ADLIBFX_SoundVolume;\r
+static int      ADLIBFX_TotalVolume = ADLIBFX_MaxVolume;\r
+static task    *ADLIBFX_ServiceTask = NULL;\r
+static int      ADLIBFX_VoiceHandle = ADLIBFX_MinVoiceHandle;\r
+\r
+int ADLIBFX_Installed = FALSE;\r
+\r
+int ADLIBFX_ErrorCode = ADLIBFX_Ok;\r
+\r
+#define ADLIBFX_SetErrorCode( status ) \\r
+   ADLIBFX_ErrorCode   = ( status );\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_ErrorString\r
+\r
+   Returns a pointer to the error message associated with an error\r
+   number.  A -1 returns a pointer the current error.\r
+---------------------------------------------------------------------*/\r
+\r
+char *ADLIBFX_ErrorString\r
+   (\r
+   int ErrorNumber\r
+   )\r
+\r
+   {\r
+   char *ErrorString;\r
+\r
+   switch( ErrorNumber )\r
+      {\r
+      case ADLIBFX_Warning :\r
+      case ADLIBFX_Error :\r
+         ErrorString = ADLIBFX_ErrorString( ADLIBFX_ErrorCode );\r
+         break;\r
+\r
+      case ADLIBFX_Ok :\r
+         ErrorString = "Adlib FX ok.";\r
+         break;\r
+\r
+      case ADLIBFX_NoVoices :\r
+         ErrorString = "No free voices available in Adlib FX.";\r
+         break;\r
+\r
+      case ADLIBFX_VoiceNotFound :\r
+         ErrorString = "No voice with matching handle found.";\r
+         break;\r
+\r
+      case ADLIBFX_DPMI_Error :\r
+         ErrorString = "DPMI Error in AdlibFX.";\r
+         break;\r
+\r
+      default :\r
+         ErrorString = "Unknown Adlib FX error code.";\r
+         break;\r
+      }\r
+\r
+   return( ErrorString );\r
+   }\r
+\r
+\r
+/**********************************************************************\r
+\r
+   Memory locked functions:\r
+\r
+**********************************************************************/\r
+\r
+\r
+#define ADLIBFX_LockStart ADLIBFX_SendOutput\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_SendOutput\r
+\r
+   Writes a byte of data to the specified register on the Adlib card.\r
+---------------------------------------------------------------------*/\r
+\r
+static void ADLIBFX_SendOutput\r
+   (\r
+   int reg,\r
+   int data\r
+   )\r
+\r
+   {\r
+   int i;\r
+   int adlib_port = 0x388;\r
+   unsigned flags;\r
+\r
+   flags = DisableInterrupts();\r
+\r
+   outp( adlib_port, reg );\r
+\r
+   for( i = 6; i ; i-- )\r
+      {\r
+      inp( adlib_port );\r
+      }\r
+\r
+   outp( adlib_port + 1, data );\r
+\r
+   for( i = 35; i ; i-- )\r
+      {\r
+      inp( adlib_port );\r
+      }\r
+\r
+   RestoreInterrupts( flags );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_Stop\r
+\r
+   Halts playback of the currently playing sound effect.\r
+---------------------------------------------------------------------*/\r
+\r
+int ADLIBFX_Stop\r
+   (\r
+   int handle\r
+   )\r
+\r
+   {\r
+   unsigned flags;\r
+\r
+   if ( ( handle != ADLIBFX_VoiceHandle ) || ( ADLIBFX_Sound == NULL ) )\r
+      {\r
+      ADLIBFX_SetErrorCode( ADLIBFX_VoiceNotFound );\r
+      return( ADLIBFX_Warning );\r
+      }\r
+\r
+   flags = DisableInterrupts();\r
+\r
+   ADLIBFX_SendOutput( 0xb0, 0 );\r
+\r
+   ADLIBFX_Sound      = NULL;\r
+   ADLIBFX_SoundPtr   = NULL;\r
+   ADLIBFX_LengthLeft = 0;\r
+   ADLIBFX_Priority   = 0;\r
+\r
+   RestoreInterrupts( flags );\r
+\r
+   if ( ADLIBFX_CallBackFunc )\r
+      {\r
+      ADLIBFX_CallBackFunc( ADLIBFX_CallBackVal );\r
+      }\r
+\r
+   return( ADLIBFX_Ok );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_Service\r
+\r
+   Task Manager routine to perform the playback of a sound effect.\r
+---------------------------------------------------------------------*/\r
+\r
+static void ADLIBFX_Service\r
+   (\r
+   task *Task\r
+   )\r
+\r
+   {\r
+   int value;\r
+\r
+   if ( ADLIBFX_SoundPtr )\r
+      {\r
+      value = *ADLIBFX_SoundPtr++;\r
+      if ( value != 0 )\r
+         {\r
+         ADLIBFX_SendOutput( 0xa0, value );\r
+         ADLIBFX_SendOutput( 0xb0, ADLIBFX_Block );\r
+         }\r
+      else\r
+         {\r
+         ADLIBFX_SendOutput( 0xb0, 0 );\r
+         }\r
+\r
+      ADLIBFX_LengthLeft--;\r
+      if ( ADLIBFX_LengthLeft <= 0 )\r
+         {\r
+         ADLIBFX_Stop( ADLIBFX_VoiceHandle );\r
+         }\r
+      }\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_SetVolume\r
+\r
+   Sets the volume of the currently playing sound effect.\r
+---------------------------------------------------------------------*/\r
+\r
+int ADLIBFX_SetVolume\r
+   (\r
+   int handle,\r
+   int volume\r
+   )\r
+\r
+   {\r
+   unsigned flags;\r
+   int      carrierlevel;\r
+\r
+   flags = DisableInterrupts();\r
+   if ( ( handle != ADLIBFX_VoiceHandle ) || ( ADLIBFX_Sound == NULL ) )\r
+      {\r
+      RestoreInterrupts( flags );\r
+      ADLIBFX_SetErrorCode( ADLIBFX_VoiceNotFound );\r
+      return( ADLIBFX_Warning );\r
+      }\r
+\r
+   volume  = min( volume, ADLIBFX_MaxVolume );\r
+   volume  = max( volume, 0 );\r
+   ADLIBFX_SoundVolume = volume;\r
+\r
+   volume *= ADLIBFX_TotalVolume;\r
+   volume /= ADLIBFX_MaxVolume;\r
+\r
+   carrierlevel  = ADLIBFX_Sound->cScale & 0x3f;\r
+   carrierlevel ^= 0x3f;\r
+   carrierlevel *= ( volume / 2 ) + 0x80;\r
+   carrierlevel /= ADLIBFX_MaxVolume;\r
+   carrierlevel ^= 0x3f;\r
+   carrierlevel |= ADLIBFX_Sound->cScale & 0xc0;\r
+\r
+   ADLIBFX_SendOutput( 0x43, carrierlevel );\r
+\r
+   RestoreInterrupts( flags );\r
+   return( ADLIBFX_Ok );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_SetTotalVolume\r
+\r
+   Sets the total volume of the sound effect.\r
+---------------------------------------------------------------------*/\r
+\r
+int ADLIBFX_SetTotalVolume\r
+   (\r
+   int volume\r
+   )\r
+\r
+   {\r
+   volume = max( volume, 0 );\r
+   volume = min( volume, ADLIBFX_MaxVolume );\r
+\r
+   ADLIBFX_TotalVolume = volume;\r
+   ADLIBFX_SetVolume( ADLIBFX_VoiceHandle, ADLIBFX_SoundVolume );\r
+\r
+   return( ADLIBFX_Ok );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_GetTotalVolume\r
+\r
+   Returns the total volume of the sound effect.\r
+---------------------------------------------------------------------*/\r
+\r
+int ADLIBFX_GetTotalVolume\r
+   (\r
+   void\r
+   )\r
+\r
+   {\r
+   return( ADLIBFX_TotalVolume );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_VoiceAvailable\r
+\r
+   Checks if a voice can be play at the specified priority.\r
+---------------------------------------------------------------------*/\r
+\r
+int ADLIBFX_VoiceAvailable\r
+   (\r
+   int priority\r
+   )\r
+\r
+   {\r
+   if ( priority < ADLIBFX_Priority )\r
+      {\r
+      return( FALSE );\r
+      }\r
+\r
+   return( TRUE );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_Play\r
+\r
+   Starts playback of a Muse sound effect.\r
+---------------------------------------------------------------------*/\r
+\r
+int ADLIBFX_Play\r
+   (\r
+   ALSound *sound,\r
+   int volume,\r
+   int priority,\r
+   unsigned long callbackval\r
+   )\r
+\r
+   {\r
+   unsigned flags;\r
+   int      carrierlevel;\r
+\r
+   if ( priority < ADLIBFX_Priority )\r
+      {\r
+      ADLIBFX_SetErrorCode( ADLIBFX_NoVoices );\r
+      return( ADLIBFX_Warning );\r
+      }\r
+\r
+   ADLIBFX_Stop( ADLIBFX_VoiceHandle );\r
+\r
+   ADLIBFX_VoiceHandle++;\r
+   if ( ADLIBFX_VoiceHandle < ADLIBFX_MinVoiceHandle )\r
+      {\r
+      ADLIBFX_VoiceHandle = ADLIBFX_MinVoiceHandle;\r
+      }\r
+\r
+   flags = DisableInterrupts();\r
+\r
+   ADLIBFX_LengthLeft  = sound->length;\r
+   ADLIBFX_Priority    = priority;\r
+   ADLIBFX_Sound       = sound;\r
+   ADLIBFX_SoundPtr    = &sound->data;\r
+   ADLIBFX_CallBackVal = callbackval;\r
+\r
+   ADLIBFX_Block = ( ( sound->block & 7 ) << 2 ) | 0x20;\r
+\r
+   volume = min( volume, ADLIBFX_MaxVolume );\r
+   volume = max( volume, 0 );\r
+   ADLIBFX_SoundVolume = volume;\r
+\r
+   volume *= ADLIBFX_TotalVolume;\r
+   volume /= ADLIBFX_MaxVolume;\r
+\r
+   carrierlevel  = sound->cScale & 0x3f;\r
+   carrierlevel ^= 0x3f;\r
+   carrierlevel *= ( volume / 2 ) + 0x80;\r
+   carrierlevel /= ADLIBFX_MaxVolume;\r
+   carrierlevel ^= 0x3f;\r
+   carrierlevel |= sound->cScale & 0xc0;\r
+\r
+   ADLIBFX_SendOutput( 0x20, sound->mChar );\r
+   ADLIBFX_SendOutput( 0x40, sound->mScale );\r
+   ADLIBFX_SendOutput( 0x60, sound->mAttack );\r
+   ADLIBFX_SendOutput( 0x80, sound->mSus );\r
+   ADLIBFX_SendOutput( 0xe0, sound->mWave );\r
+\r
+   ADLIBFX_SendOutput( 0x23, sound->cChar );\r
+   ADLIBFX_SendOutput( 0x43, carrierlevel );\r
+   ADLIBFX_SendOutput( 0x63, sound->cAttack );\r
+   ADLIBFX_SendOutput( 0x83, sound->cSus );\r
+   ADLIBFX_SendOutput( 0xe3, sound->cWave );\r
+\r
+   ADLIBFX_SendOutput( 0xc0, 0 );\r
+\r
+   RestoreInterrupts( flags );\r
+\r
+   return( ADLIBFX_VoiceHandle );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_SoundPlaying\r
+\r
+   Checks if a sound effect is currently playing.\r
+---------------------------------------------------------------------*/\r
+\r
+int ADLIBFX_SoundPlaying\r
+   (\r
+   int handle\r
+   )\r
+\r
+   {\r
+   int status;\r
+\r
+   status = FALSE;\r
+   if ( ( handle == ADLIBFX_VoiceHandle ) && ( ADLIBFX_LengthLeft > 0 ) )\r
+      {\r
+      status = TRUE;\r
+      }\r
+\r
+   return( status );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_LockEnd\r
+\r
+   Used for determining the length of the functions to lock in memory.\r
+---------------------------------------------------------------------*/\r
+\r
+static void ADLIBFX_LockEnd\r
+   (\r
+   void\r
+   )\r
+\r
+   {\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_SetCallBack\r
+\r
+   Set the function to call when a voice stops.\r
+---------------------------------------------------------------------*/\r
+\r
+void ADLIBFX_SetCallBack\r
+   (\r
+   void ( *function )( unsigned long )\r
+   )\r
+\r
+   {\r
+   ADLIBFX_CallBackFunc = function;\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_Init\r
+\r
+   Initializes the sound effect engine.\r
+---------------------------------------------------------------------*/\r
+\r
+int ADLIBFX_Init\r
+   (\r
+   void\r
+   )\r
+\r
+   {\r
+   int status;\r
+\r
+   if ( ADLIBFX_Installed )\r
+      {\r
+      ADLIBFX_Shutdown();\r
+      }\r
+\r
+   status  = DPMI_LockMemoryRegion( ADLIBFX_LockStart, ADLIBFX_LockEnd );\r
+   status |= DPMI_Lock( ADLIBFX_VoiceHandle );\r
+   status |= DPMI_Lock( ADLIBFX_Sound );\r
+   status |= DPMI_Lock( ADLIBFX_ErrorCode );\r
+   status |= DPMI_Lock( ADLIBFX_SoundPtr );\r
+   status |= DPMI_Lock( ADLIBFX_LengthLeft );\r
+   status |= DPMI_Lock( ADLIBFX_Priority );\r
+   status |= DPMI_Lock( ADLIBFX_CallBackFunc );\r
+   status |= DPMI_Lock( ADLIBFX_Block );\r
+\r
+   if ( status != DPMI_Ok )\r
+      {\r
+      ADLIBFX_SetErrorCode( ADLIBFX_DPMI_Error );\r
+      return( ADLIBFX_Error );\r
+      }\r
+\r
+//JIM\r
+//   AL_ReserveVoice( 0 );\r
+   ADLIBFX_Stop( ADLIBFX_VoiceHandle );\r
+   ADLIBFX_ServiceTask = TS_ScheduleTask( &ADLIBFX_Service, 140, 2, NULL );\r
+   TS_Dispatch();\r
+   ADLIBFX_Installed = TRUE;\r
+   ADLIBFX_CallBackFunc = NULL;\r
+\r
+   ADLIBFX_SetErrorCode( ADLIBFX_Ok );\r
+   return( ADLIBFX_Ok );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: ADLIBFX_Shutdown\r
+\r
+   Ends the use of the sound effect engine.\r
+---------------------------------------------------------------------*/\r
+\r
+int ADLIBFX_Shutdown\r
+   (\r
+   void\r
+   )\r
+\r
+   {\r
+   if ( ADLIBFX_Installed )\r
+      {\r
+      ADLIBFX_Stop( ADLIBFX_VoiceHandle );\r
+      TS_Terminate( ADLIBFX_ServiceTask );\r
+      ADLIBFX_ServiceTask = NULL;\r
+//JIM\r
+//      AL_ReleaseVoice( 0 );\r
+      ADLIBFX_Installed = FALSE;\r
+\r
+      DPMI_UnlockMemoryRegion( ADLIBFX_LockStart, ADLIBFX_LockEnd );\r
+      DPMI_Unlock( ADLIBFX_VoiceHandle );\r
+      DPMI_Unlock( ADLIBFX_Sound );\r
+      DPMI_Unlock( ADLIBFX_ErrorCode );\r
+      DPMI_Unlock( ADLIBFX_SoundPtr );\r
+      DPMI_Unlock( ADLIBFX_LengthLeft );\r
+      DPMI_Unlock( ADLIBFX_Priority );\r
+      DPMI_Unlock( ADLIBFX_CallBackFunc );\r
+      DPMI_Unlock( ADLIBFX_Block );\r
+      }\r
+\r
+   ADLIBFX_SetErrorCode( ADLIBFX_Ok );\r
+   return( ADLIBFX_Ok );\r
+   }\r
diff --git a/audiolib/SOURCE/ADLIBFX.H b/audiolib/SOURCE/ADLIBFX.H
new file mode 100644 (file)
index 0000000..d68e207
--- /dev/null
@@ -0,0 +1,80 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: ADLIBFX.H\r
+\r
+   author: James R. Dose\r
+   date:   April 1, 1994\r
+\r
+   Public header for ADLIBFX.C\r
+\r
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.\r
+**********************************************************************/\r
+\r
+#ifndef __ADLIBFX_H\r
+#define __ADLIBFX_H\r
+\r
+enum ADLIBFX_Errors\r
+   {\r
+   ADLIBFX_Warning = -2,\r
+   ADLIBFX_Error   = -1,\r
+   ADLIBFX_Ok      = 0,\r
+   ADLIBFX_NoVoices,\r
+   ADLIBFX_VoiceNotFound,\r
+   ADLIBFX_DPMI_Error\r
+   };\r
+\r
+typedef        struct\r
+   {\r
+   unsigned long  length;\r
+   short int      priority;\r
+   char           mChar, cChar;\r
+   char           mScale, cScale;\r
+   char           mAttack, cAttack;\r
+   char           mSus, cSus;\r
+   char           mWave, cWave;\r
+   char           nConn;\r
+   char           voice;\r
+   char           mode;\r
+   char           unused[ 3 ];\r
+   char           block;\r
+   char           data[];\r
+   } ALSound;\r
+\r
+#define ADLIBFX_MaxVolume      255\r
+#define ADLIBFX_MinVoiceHandle 1\r
+\r
+char *ADLIBFX_ErrorString( int ErrorNumber );\r
+int   ADLIBFX_Stop( int handle );\r
+int   ADLIBFX_SetVolume( int handle, int volume );\r
+int   ADLIBFX_SetTotalVolume( int volume );\r
+int   ADLIBFX_GetTotalVolume( void );\r
+int   ADLIBFX_VoiceAvailable( int priority );\r
+int   ADLIBFX_Play( ALSound *sound, int volume, int priority, unsigned long callbackval );\r
+int   ADLIBFX_SoundPlaying( int handle );\r
+void  ADLIBFX_SetCallBack( void ( *function )( unsigned long ) );\r
+int   ADLIBFX_Init( void );\r
+int   ADLIBFX_Shutdown( void );\r
+   #pragma aux ADLIBFX_Shutdown frame;\r
+void  PCFX_UnlockMemory( void );\r
+   #pragma aux ADLIBFX_UnlockMemory frame;\r
+int   PCFX_LockMemory( void );\r
+\r
+#endif\r
diff --git a/audiolib/SOURCE/AL_MIDI.C b/audiolib/SOURCE/AL_MIDI.C
new file mode 100644 (file)
index 0000000..28f9d3d
--- /dev/null
@@ -0,0 +1,1510 @@
+/*\r
+Copyright (C) 1994-1995 Apogee Software, Ltd.\r
+\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+\r
+This program 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.\r
+\r
+See the 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, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+\r
+*/\r
+/**********************************************************************\r
+   module: AL_MIDI.C\r
+\r
+   author: James R. Dose\r
+   date:   April 1, 1994\r
+\r
+   Low level routines to support General MIDI music on Adlib compatible\r
+   cards.\r
+\r
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.\r
+**********************************************************************/\r
+\r
+#include <conio.h>\r
+#include <dos.h>\r
+#include <stddef.h>\r
+#include <stdlib.h>\r
+//#include <math.h>\r
+#include "dpmi.h"\r
+#include "interrup.h"\r
+#include "sndcards.h"\r
+#include "blaster.h"\r
+#include "user.h"\r
+#include "al_midi.h"\r
+#include "_al_midi.h"\r
+#include "ll_man.h"\r
+\r
+#define TRUE  ( 1 == 1 )\r
+#define FALSE ( !TRUE )\r
+\r
+static unsigned OctavePitch[ MAX_OCTAVE + 1 ] =\r
+   {\r
+   OCTAVE_0, OCTAVE_1, OCTAVE_2, OCTAVE_3,\r
+   OCTAVE_4, OCTAVE_5, OCTAVE_6, OCTAVE_7,\r
+   };\r
+\r
+static unsigned NoteMod12[ MAX_NOTE + 1 ];\r
+static unsigned NoteDiv12[ MAX_NOTE + 1 ];\r
+\r
+// Pitch table\r
+\r
+//static unsigned NotePitch[ FINETUNE_MAX + 1 ][ 12 ] =\r
+//   {\r
+//      { C, C_SHARP, D, D_SHARP, E, F, F_SHARP, G, G_SHARP, A, A_SHARP, B },\r
+//   };\r
+\r
+static unsigned NotePitch[ FINETUNE_MAX + 1 ][ 12 ] =\r
+   {\r
+      { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x241, 0x263, 0x287 },\r
+      { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x242, 0x264, 0x288 },\r
+      { 0x158, 0x16c, 0x182, 0x199, 0x1b1, 0x1cb, 0x1e6, 0x203, 0x221, 0x243, 0x265, 0x289 },\r
+      { 0x158, 0x16c, 0x183, 0x19a, 0x1b2, 0x1cc, 0x1e7, 0x204, 0x222, 0x244, 0x266, 0x28a },\r
+      { 0x159, 0x16d, 0x183, 0x19a, 0x1b3, 0x1cd, 0x1e8, 0x205, 0x223, 0x245, 0x267, 0x28b },\r
+      { 0x15a, 0x16e, 0x184, 0x19b, 0x1b3, 0x1ce, 0x1e9, 0x206, 0x224, 0x246, 0x268, 0x28c },\r
+      { 0x15a, 0x16e, 0x185, 0x19c, 0x1b4, 0x1ce, 0x1ea, 0x207, 0x225, 0x247, 0x269, 0x28e },\r
+      { 0x15b, 0x16f, 0x185, 0x19d, 0x1b5, 0x1cf, 0x1eb, 0x208, 0x226, 0x248, 0x26a, 0x28f },\r
+      { 0x15b, 0x170, 0x186, 0x19d, 0x1b6, 0x1d0, 0x1ec, 0x209, 0x227, 0x249, 0x26b, 0x290 },\r
+      { 0x15c, 0x170, 0x187, 0x19e, 0x1b7, 0x1d1, 0x1ec, 0x20a, 0x228, 0x24a, 0x26d, 0x291 },\r
+      { 0x15d, 0x171, 0x188, 0x19f, 0x1b7, 0x1d2, 0x1ed, 0x20b, 0x229, 0x24b, 0x26e, 0x292 },\r
+      { 0x15d, 0x172, 0x188, 0x1a0, 0x1b8, 0x1d3, 0x1ee, 0x20c, 0x22a, 0x24c, 0x26f, 0x293 },\r
+      { 0x15e, 0x172, 0x189, 0x1a0, 0x1b9, 0x1d4, 0x1ef, 0x20d, 0x22b, 0x24d, 0x270, 0x295 },\r
+      { 0x15f, 0x173, 0x18a, 0x1a1, 0x1ba, 0x1d4, 0x1f0, 0x20e, 0x22c, 0x24e, 0x271, 0x296 },\r
+      { 0x15f, 0x174, 0x18a, 0x1a2, 0x1bb, 0x1d5, 0x1f1, 0x20f, 0x22d, 0x24f, 0x272, 0x297 },\r
+      { 0x160, 0x174, 0x18b, 0x1a3, 0x1bb, 0x1d6, 0x1f2, 0x210, 0x22e, 0x250, 0x273, 0x298 },\r
+      { 0x161, 0x175, 0x18c, 0x1a3, 0x1bc, 0x1d7, 0x1f3, 0x211, 0x22f, 0x251, 0x274, 0x299 },\r
+      { 0x161, 0x176, 0x18c, 0x1a4, 0x1bd, 0x1d8, 0x1f4, 0x212, 0x230, 0x252, 0x276, 0x29b },\r
+      { 0x162, 0x176, 0x18d, 0x1a5, 0x1be, 0x1d9, 0x1f5, 0x212, 0x231, 0x254, 0x277, 0x29c },\r
+      { 0x162, 0x177, 0x18e, 0x1a6, 0x1bf, 0x1d9, 0x1f5, 0x213, 0x232, 0x255, 0x278, 0x29d },\r
+      { 0x163, 0x178, 0x18f, 0x1a6, 0x1bf, 0x1da, 0x1f6, 0x214, 0x233, 0x256, 0x279, 0x29e },\r
+      { 0x164, 0x179, 0x18f, 0x1a7, 0x1c0, 0x1db, 0x1f7, 0x215, 0x235, 0x257, 0x27a, 0x29f },\r
+      { 0x164, 0x179, 0x190, 0x1a8, 0x1c1, 0x1dc, 0x1f8, 0x216, 0x236, 0x258, 0x27b, 0x2a1 },\r
+      { 0x165, 0x17a, 0x191, 0x1a9, 0x1c2, 0x1dd, 0x1f9, 0x217, 0x237, 0x259, 0x27c, 0x2a2 },\r
+      { 0x166, 0x17b, 0x192, 0x1aa, 0x1c3, 0x1de, 0x1fa, 0x218, 0x238, 0x25a, 0x27e, 0x2a3 },\r
+      { 0x166, 0x17b, 0x192, 0x1aa, 0x1c3, 0x1df, 0x1fb, 0x219, 0x239, 0x25b, 0x27f, 0x2a4 },\r
+      { 0x167, 0x17c, 0x193, 0x1ab, 0x1c4, 0x1e0, 0x1fc, 0x21a, 0x23a, 0x25c, 0x280, 0x2a6 },\r
+      { 0x168, 0x17d, 0x194, 0x1ac, 0x1c5, 0x1e0, 0x1fd, 0x21b, 0x23b, 0x25d, 0x281, 0x2a7 },\r
+      { 0x168, 0x17d, 0x194, 0x1ad, 0x1c6, 0x1e1, 0x1fe, 0x21c, 0x23c, 0x25e, 0x282, 0x2a8 },\r
+      { 0x169, 0x17e, 0x195, 0x1ad, 0x1c7, 0x1e2, 0x1ff, 0x21d, 0x23d, 0x260, 0x283, 0x2a9 },\r
+      { 0x16a, 0x17f, 0x196, 0x1ae, 0x1c8, 0x1e3, 0x1ff, 0x21e, 0x23e, 0x261, 0x284, 0x2ab },\r
+      { 0x16a, 0x17f, 0x197, 0x1af, 0x1c8, 0x1e4, 0x200, 0x21f, 0x23f, 0x262, 0x286, 0x2ac }\r
+   };\r
+\r
+// Slot numbers as a function of the voice and the operator.\r
+// ( melodic only)\r
+\r
+static int slotVoice[ NUM_VOICES ][ 2 ] =\r
+   {\r
+      { 0, 3 },    // voice 0\r
+      { 1, 4 },    // 1\r
+      { 2, 5 },    // 2\r
+      { 6, 9 },    // 3\r
+      { 7, 10 },   // 4\r
+      { 8, 11 },   // 5\r
+      { 12, 15 },  // 6\r
+      { 13, 16 },  // 7\r
+      { 14, 17 },  // 8\r
+   };\r
+\r
+static int VoiceLevel[ NumChipSlots ][ 2 ];\r
+static int VoiceKsl[ NumChipSlots ][ 2 ];\r
+\r
+// This table gives the offset of each slot within the chip.\r
+// offset = fn( slot)\r
+\r
+static char offsetSlot[ NumChipSlots ] =\r
+   {\r
+    0,  1,  2,  3,  4,  5,\r
+    8,  9, 10, 11, 12, 13,\r
+   16, 17, 18, 19, 20, 21\r
+   };\r
+\r
+static int VoiceReserved[ NUM_VOICES * 2 ] =\r
+   {\r
+   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,\r
+   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE\r
+   };\r
+\r
+static VOICE     Voice[ NUM_VOICES * 2 ];\r
+static VOICELIST Voice_Pool;\r
+\r
+static CHANNEL   Channel[ NUM_CHANNELS ];\r
+\r
+static int AL_LeftPort   = 0x388;\r
+static int AL_RightPort  = 0x388;\r
+static int AL_Stereo     = FALSE;\r
+static int AL_SendStereo = FALSE;\r
+static int AL_OPL3       = FALSE;\r
+static int AL_MaxMidiChannel = 16;\r
+\r
+\r
+/**********************************************************************\r
+\r
+   Memory locked functions:\r
+\r
+**********************************************************************/\r
+\r
+\r
+#define AL_LockStart AL_SendOutputToPort\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: AL_SendOutputToPort\r
+\r
+   Sends data to the Adlib using a specified port.\r
+---------------------------------------------------------------------*/\r
+\r
+void AL_SendOutputToPort\r
+   (\r
+   int  port,\r
+   int  reg,\r
+   int  data\r
+   )\r
+\r
+   {\r
+   int delay;\r
+\r
+   outp( port, reg );\r
+\r
+   for( delay = 6; delay > 0 ; delay-- )\r
+//   for( delay = 2; delay > 0 ; delay-- )\r
+      {\r
+      inp( port );\r
+      }\r
+\r
+   outp( port + 1, data );\r
+\r
+//   for( delay = 35; delay > 0 ; delay-- )\r
+   for( delay = 27; delay > 0 ; delay-- )\r
+//   for( delay = 2; delay > 0 ; delay-- )\r
+      {\r
+      inp( port );\r
+      }\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: AL_SendOutput\r
+\r
+   Sends data to the Adlib.\r
+---------------------------------------------------------------------*/\r
+\r
+void AL_SendOutput\r
+   (\r
+   int  voice,\r
+   int  reg,\r
+   int  data\r
+   )\r
+\r
+   {\r
+   int port;\r
+\r
+   if ( AL_SendStereo )\r
+      {\r
+      AL_SendOutputToPort( AL_LeftPort, reg, data );\r
+      AL_SendOutputToPort( AL_RightPort, reg, data );\r
+      }\r
+   else\r
+      {\r
+      port = ( voice == 0 ) ? AL_RightPort : AL_LeftPort;\r
+      AL_SendOutputToPort( port, reg, data );\r
+      }\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: AL_SetVoiceTimbre\r
+\r
+   Programs the specified voice's timbre.\r
+---------------------------------------------------------------------*/\r
+\r
+static void AL_SetVoiceTimbre\r
+   (\r
+   int voice\r
+   )\r
+\r
+   {\r
+   int    off;\r
+   int    slot;\r
+   int    port;\r
+   int    voc;\r
+   int    patch;\r
+   int    channel;\r
+   TIMBRE *timbre;\r
+\r
+   channel = Voice[ voice ].channel;\r
+\r
+   if ( channel == 9 )\r
+      {\r
+      patch = Voice[ voice ].key + 128;\r
+      }\r
+   else\r
+      {\r
+      patch = Channel[ channel ].Timbre;\r
+      }\r
+\r
+   if ( Voice[ voice ].timbre == patch )\r
+      {\r
+      return;\r
+      }\r
+\r
+   Voice[ voice ].timbre = patch;\r
+   timbre = &ADLIB_TimbreBank[ patch ];\r
+\r
+   port = Voice[ voice ].port;\r
+   voc  = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;\r
+   slot = slotVoice[ voc ][ 0 ];\r
+   off  = offsetSlot[ slot ];\r
+\r
+   VoiceLevel[ slot ][ port ] = 63 - ( timbre->Level[ 0 ] & 0x3f );\r
+   VoiceKsl[ slot ][ port ]   = timbre->Level[ 0 ] & 0xc0;\r
+\r
+   AL_SendOutput( port, 0xA0 + voc, 0 );\r
+   AL_SendOutput( port, 0xB0 + voc, 0 );\r
+\r
+   // Let voice clear the release\r
+   AL_SendOutput( port, 0x80 + off, 0xff );\r
+\r
+   AL_SendOutput( port, 0x60 + off, timbre->Env1[ 0 ] );\r
+   AL_SendOutput( port, 0x80 + off, timbre->Env2[ 0 ] );\r
+   AL_SendOutput( port, 0x20 + off, timbre->SAVEK[ 0 ] );\r
+   AL_SendOutput( port, 0xE0 + off, timbre->Wave[ 0 ] );\r
+\r
+   AL_SendOutput( port, 0x40 + off, timbre->Level[ 0 ] );\r
+   slot = slotVoice[ voc ][ 1 ];\r
+\r
+   if ( AL_SendStereo )\r
+      {\r
+      AL_SendOutputToPort( AL_LeftPort, 0xC0 + voice,\r
+         ( timbre->Feedback & 0x0f ) | 0x20 );\r
+      AL_SendOutputToPort( AL_RightPort, 0xC0 + voice,\r
+         ( timbre->Feedback & 0x0f ) | 0x10 );\r
+      }\r
+   else\r
+      {\r
+      if ( AL_OPL3 )\r
+         {\r
+         AL_SendOutput( port, 0xC0 + voc, ( timbre->Feedback & 0x0f ) |\r
+            0x30 );\r
+         }\r
+      else\r
+         {\r
+         AL_SendOutputToPort( ADLIB_PORT, 0xC0 + voice, timbre->Feedback );\r
+         }\r
+      }\r
+\r
+   off = offsetSlot[ slot ];\r
+\r
+   VoiceLevel[ slot ][ port ] = 63 - ( timbre->Level[ 1 ] & 0x3f );\r
+   VoiceKsl[ slot ][ port ]   = timbre->Level[ 1 ] & 0xc0;\r
+   AL_SendOutput( port, 0x40 + off, 63 );\r
+\r
+   // Let voice clear the release\r
+   AL_SendOutput( port, 0x80 + off, 0xff );\r
+\r
+   AL_SendOutput( port, 0x60 + off, timbre->Env1[ 1 ] );\r
+   AL_SendOutput( port, 0x80 + off, timbre->Env2[ 1 ] );\r
+   AL_SendOutput( port, 0x20 + off, timbre->SAVEK[ 1 ] );\r
+   AL_SendOutput( port, 0xE0 + off, timbre->Wave[ 1 ] );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: AL_SetVoiceVolume\r
+\r
+   Sets the volume of the specified voice.\r
+---------------------------------------------------------------------*/\r
+\r
+static void AL_SetVoiceVolume\r
+   (\r
+   int voice\r
+   )\r
+\r
+   {\r
+   int channel;\r
+   int velocity;\r
+   int slot;\r
+   int port;\r
+   int voc;\r
+   unsigned long t1;\r
+   unsigned long t2;\r
+   unsigned long volume;\r
+   TIMBRE *timbre;\r
+\r
+   channel = Voice[ voice ].channel;\r
+\r
+   timbre = &ADLIB_TimbreBank[ Voice[ voice ].timbre ];\r
+\r
+   velocity = Voice[ voice ].velocity + timbre->Velocity;\r
+   velocity = min( velocity, MAX_VELOCITY );\r
+\r
+   voc  = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;\r
+   slot = slotVoice[ voc ][ 1 ];\r
+   port = Voice[ voice ].port;\r
+\r
+   // amplitude\r
+   t1  = ( unsigned )VoiceLevel[ slot ][ port ];\r
+   t1 *= ( velocity + 0x80 );\r
+   t1  = ( Channel[ channel ].Volume * t1 ) >> 15;\r
+\r
+   if ( !AL_SendStereo )\r
+      {\r
+      volume  = t1 ^ 63;\r
+      volume |= ( unsigned )VoiceKsl[ slot ][ port ];\r
+\r
+      AL_SendOutput( port, 0x40 + offsetSlot[ slot ], volume );\r
+\r
+      // Check if this timbre is Additive\r
+      if ( timbre->Feedback & 0x01 )\r
+         {\r
+         slot = slotVoice[ voc ][ 0 ];\r
+\r
+         // amplitude\r
+         t2  = ( unsigned )VoiceLevel[ slot ][ port ];\r
+         t2 *= ( velocity + 0x80 );\r
+         t2  = ( Channel[ channel ].Volume * t1 ) >> 15;\r
+\r
+         volume  = t2 ^ 63;\r
+         volume |= ( unsigned )VoiceKsl[ slot ][ port ];\r
+\r
+         AL_SendOutput( port, 0x40 + offsetSlot[ slot ], volume );\r
+         }\r
+      }\r
+   else\r
+      {\r
+      // Set left channel volume\r
+      volume = t1;\r
+      if ( Channel[ channel ].Pan < 64 )\r
+         {\r
+         volume *= Channel[ channel ].Pan;\r
+         volume >>= 6;\r
+         }\r
+\r
+      volume ^= 63;\r
+      volume |= ( unsigned )VoiceKsl[ slot ][ port ];\r
+\r
+      AL_SendOutputToPort( AL_LeftPort, 0x40 + offsetSlot[ slot ], volume );\r
+\r
+      // Set right channel volume\r
+      volume = t1;\r
+      if ( Channel[ channel ].Pan > 64 )\r
+         {\r
+         volume *= 127 - Channel[ channel ].Pan;\r
+         volume >>= 6;\r
+         }\r
+\r
+      volume ^= 63;\r
+      volume |= ( unsigned )VoiceKsl[ slot ][ port ];\r
+\r
+      AL_SendOutputToPort( AL_RightPort, 0x40 + offsetSlot[ slot ], volume );\r
+\r
+      // Check if this timbre is Additive\r
+      if ( timbre->Feedback & 0x01 )\r
+         {\r
+         // amplitude\r
+         t2  = ( unsigned )VoiceLevel[ slot ][ port ];\r
+         t2 *= ( velocity + 0x80 );\r
+         t2  = ( Channel[ channel ].Volume * t1 ) >> 15;\r
+\r
+         slot = slotVoice[ voc ][ 0 ];\r
+\r
+         // Set left channel volume\r
+         volume = t2;\r
+         if ( Channel[ channel ].Pan < 64 )\r
+            {\r
+            volume *= Channel[ channel ].Pan;\r
+            volume >>= 6;\r
+            }\r
+\r
+         volume ^= 63;\r
+         volume |= ( unsigned )VoiceKsl[ slot ][ port ];\r
+\r
+         AL_SendOutputToPort( AL_LeftPort, 0x40 + offsetSlot[ slot ], volume );\r
+\r
+         // Set right channel volume\r
+         volume = t2;\r
+         if ( Channel[ channel ].Pan > 64 )\r
+            {\r
+            volume *= 127 - Channel[ channel ].Pan;\r
+            volume >>= 6;\r
+            }\r
+\r
+         volume ^= 63;\r
+         volume |= ( unsigned )VoiceKsl[ slot ][ port ];\r
+\r
+         AL_SendOutputToPort( AL_RightPort, 0x40 + offsetSlot[ slot ], volume );\r
+         }\r
+      }\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: AL_AllocVoice\r
+\r
+   Retrieves a free voice from the voice pool.\r
+---------------------------------------------------------------------*/\r
+\r
+static int AL_AllocVoice\r
+   (\r
+   void\r
+   )\r
+\r
+   {\r
+   int voice;\r
+\r
+   if ( Voice_Pool.start )\r
+      {\r
+      voice = Voice_Pool.start->num;\r
+      LL_Remove( VOICE, &Voice_Pool, &Voice[ voice ] );\r
+      return( voice );\r
+      }\r
+\r
+   return( AL_VoiceNotFound );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: AL_GetVoice\r
+\r
+   Determines which voice is associated with a specified note and\r
+   MIDI channel.\r
+---------------------------------------------------------------------*/\r
+\r
+static int AL_GetVoice\r
+   (\r
+   int channel,\r
+   int key\r
+   )\r
+\r
+   {\r
+   VOICE *voice;\r
+\r
+   voice = Channel[ channel ].Voices.start;\r
+\r
+   while( voice != NULL )\r
+      {\r
+      if ( voice->key == key )\r
+         {\r
+         return( voice->num );\r
+         }\r
+      voice = voice->next;\r
+      }\r
+\r
+   return( AL_VoiceNotFound );\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: AL_SetVoicePitch\r
+\r
+   Programs the pitch of the specified voice.\r
+---------------------------------------------------------------------*/\r
+\r
+static void AL_SetVoicePitch\r
+   (\r
+   int voice\r
+   )\r
+\r
+   {\r
+   int note;\r
+   int channel;\r
+   int patch;\r
+   int detune;\r
+   int ScaleNote;\r
+   int Octave;\r
+   int pitch;\r
+   int port;\r
+   int voc;\r
+\r
+   port = Voice[ voice ].port;\r
+   voc  = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;\r
+   channel = Voice[ voice ].channel;\r
+\r
+   if ( channel == 9 )\r
+      {\r
+      patch = Voice[ voice ].key + 128;\r
+      note  = ADLIB_TimbreBank[ patch ].Transpose;\r
+      }\r
+   else\r
+      {\r
+      patch = Channel[ channel ].Timbre;\r
+      note  = Voice[ voice ].key + ADLIB_TimbreBank[ patch ].Transpose;\r
+      }\r
+\r
+   note += Channel[ channel ].KeyOffset - 12;\r
+   if ( note > MAX_NOTE )\r
+      {\r
+      note = MAX_NOTE;\r
+      }\r
+   if ( note < 0 )\r
+      {\r
+      note = 0;\r
+      }\r
+\r
+   detune = Channel[ channel ].KeyDetune;\r
+\r
+   ScaleNote = NoteMod12[ note ];\r
+   Octave    = NoteDiv12[ note ];\r
+\r
+   pitch = OctavePitch[ Octave ] | NotePitch[ detune ][ ScaleNote ];\r
+\r
+   Voice[ voice ].pitchleft = pitch;\r
+\r
+   pitch |= Voice[ voice ].status;\r
+\r
+   if ( !AL_SendStereo )\r
+      {\r
+      AL_SendOutput( port, 0xA0 + voc, pitch );\r
+      AL_SendOutput( port, 0xB0 + voc, pitch >> 8 );\r
+      }\r
+   else\r
+      {\r
+      AL_SendOutputToPort( AL_LeftPort, 0xA0 + voice, pitch );\r
+      AL_SendOutputToPort( AL_LeftPort, 0xB0 + voice, pitch >> 8 );\r
+\r
+      if ( channel != 9 )\r
+         {\r
+         detune += STEREO_DETUNE;\r
+         }\r
+\r
+      if ( detune > FINETUNE_MAX )\r
+         {\r
+         detune -= FINETUNE_RANGE;\r
+         if ( note < MAX_NOTE )\r
+            {\r
+            note++;\r
+            ScaleNote = NoteMod12[ note ];\r
+            Octave    = NoteDiv12[ note ];\r
+            }\r
+         }\r
+\r
+      pitch = OctavePitch[ Octave ] | NotePitch[ detune ][ ScaleNote ];\r
+\r
+      Voice[ voice ].pitchright = pitch;\r
+\r
+      pitch |= Voice[ voice ].status;\r
+\r
+      AL_SendOutputToPort( AL_RightPort, 0xA0 + voice, pitch );\r
+      AL_SendOutputToPort( AL_RightPort, 0xB0 + voice, pitch >> 8 );\r
+      }\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: AL_SetChannelVolume\r
+\r
+   Sets the volume of the specified MIDI channel.\r
+---------------------------------------------------------------------*/\r
+\r
+static void AL_SetChannelVolume\r
+   (\r
+   int channel,\r
+   int volume\r
+   )\r
+\r
+   {\r
+   VOICE *voice;\r
+\r
+   volume = max( 0, volume );\r
+   volume = min( volume, AL_MaxVolume );\r
+   Channel[ channel ].Volume = volume;\r
+\r
+   voice = Channel[ channel ].Voices.start;\r
+   while( voice != NULL )\r
+      {\r
+      AL_SetVoiceVolume( voice->num );\r
+      voice = voice->next;\r
+      }\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: AL_SetChannelPan\r
+\r
+   Sets the pan position of the specified MIDI channel.\r
+---------------------------------------------------------------------*/\r
+\r
+static void AL_SetChannelPan\r
+   (\r
+   int channel,\r
+   int pan\r
+   )\r
+\r
+   {\r
+   // Don't pan drum sounds\r
+   if ( channel != 9 )\r
+      {\r
+      Channel[ channel ].Pan = pan;\r
+      }\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: AL_SetChannelDetune\r
+\r
+   Sets the stereo voice detune of the specified MIDI channel.\r
+---------------------------------------------------------------------*/\r
+\r
+static void AL_SetChannelDetune\r
+   (\r
+   int channel,\r
+   int detune\r
+   )\r
+\r
+   {\r
+   Channel[ channel ].Detune = detune;\r
+   }\r
+\r
+\r
+/*---------------------------------------------------------------------\r
+   Function: AL_ResetVoices\r
+\r
+   Sets all voice info to the default state.\r
+--------------------------------------------------