shithub: rott

Download patch

ref: 14fe6d1445b3679340a400c2c0ee1d32638ad22e
author: levesqu8 <levesqu8@msu.edu>
date: Thu Aug 17 21:38:40 EDT 2017

Everything from 6/2017 to now. First commit.

--- /dev/null
+++ b/README.txt
@@ -1,0 +1,56 @@
+Based off of the icculus Rise of the Triad source port (can be found here: https://icculus.org/rott/)
+
+This source port of Rise of the Triad features the following:
+
+New gameplay options including the following
+	Blitzguards being outfitted with anything from the missile arsenal!
+	You can now pick up ammo from dropped missile weapons!
+	A special respawning enemy game mode called ZomROTT, where you have to gib your enemies to keep them from coming back!
+	Toggalable Auto Aim
+	Auto Aim for Missile Weapons
+	...and more
+
+Top Bar of the status bar isn't off to the side anymore!
+
+And all of the improvements made in the icculus source port...
+
+
+
+
+To run the game you'll need the following things:
+
+SDL.dll (https://www.libsdl.org/download-1.2.php)
+
+SDL_mixer.dll (https://www.libsdl.org/projects/SDL_mixer/release-1.2.html)
+
+And Either:
+
+DARKWAR.RTC
+DARKWAR.RTL
+DARKWAR.WAD
+DEMO1_3.DMO
+DEMO2_3.DMO
+DEMO3_3.DMO
+DEMO4_3.DMO
+REMOTE1.RTS
+
+Or
+
+HUNTBGIN.RTC
+HUNTBGIN.RTL
+HUNTBGIN.WAD
+DEMO1_3.DMO
+DEMO2_3.DMO
+DEMO3_3.DMO
+DEMO4_3.DMO
+REMOTE1.RTS
+
+Place all those files in the same directory as rott.exe.
+
+
+BUILDING:
+
+To build the project, you'll need the SDL1.2 development libraries (https://www.libsdl.org/download-1.2.php) 
+as well as the SDL_mixer developement libaries (https://www.libsdl.org/projects/SDL_mixer/release-1.2.html, under Binary).
+
+I used MinGW with gcc to build the project.
--- /dev/null
+++ b/rott/LICENSE.DOC
@@ -1,0 +1,56 @@
+"Rise of the Triad: Dark War"
+Copyright 1994/1995 Apogee Software, Ltd.
+P.O. Box 496389, Garland, TX 75049, TEL: 214-271-2137 ("Apogee")
+
+BY COPYING OR USING THIS PROGRAM, YOU INDICATE YOUR AGREEMENT TO
+THE FOLLOWING TERMS, WHICH ARE THE ONLY ONES BY WHICH APOGEE
+PERMITS COPYING OR USE.  THIS PROGRAM IS NOT SHAREWARE. 
+DISTRIBUTING IT WITHOUT APOGEE'S PERMISSION IS ILLEGAL.
+
+[1] OWNERSHIP.  Except to the extent expressly licensed by us,
+we have and reserve the exclusive copyright, trade secret and
+other rights to the Program, and the right to use the Trademarks
+"Apogee", the Apogee "comet", "Rise of the Triad", and "Dark War"
+in connection with it.
+
+[2] USE AND COPIES. You may use the Program only for your own
+purposes "just like a book".  This permits use by any number of
+people on any number of machines to use it so long as -- just
+like a book -- there is NO POSSIBILITY that more than one copy
+will be used at a time.  You have no right to copy this Program
+except for legal backups.
+
+[3] LIMITED WARRANTY AND LIMITATION OF REMEDIES
+
+If this Program (including any related written material)
+contained a physical defect, you may receive a replacement if
+you return it within 90 days of receiving it from Apogee.  Aside
+from this, IT IS PROVIDED "AS-IS", AND NO WARRANTIES OF ANY KIND
+(INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR
+A PARTICULAR PURPOSE), EXPRESS OR IMPLIED, ARE MADE AS TO IT OR
+ANY MEDIUM IT MAY BE ON.  OUR ENTIRE LIABILITY AND YOUR
+EXCLUSIVE REMEDY IS SUCH REPLACEMENT, AND UNDER NO CIRCUMSTANCES
+WILL WE PROVIDE ANY OTHER REMEDY FOR DIRECT, INDIRECT, SPECIAL,
+CONSEQUENTIAL, PUNITIVE, INCIDENTAL OR OTHER DAMAGES ARISING
+FROM IT, INCLUDING SUCH FROM NEGLIGENCE, STRICT LIABILITY, OR
+BREACH OF WARRANTY OR CONTRACT, EVEN AFTER NOTICE OF THE
+POSSIBILITY OF SUCH DAMAGES.  Some states do not allow the
+exclusion or limitation of implied warranties or liability for
+incidental or consequential damages, so this may not apply to
+buyers of the Program.  This gives you specific legal rights,
+and you may also have other rights which vary from state to
+state.
+
+[4] MISCELLANY
+
+ [A] With respect to every matter arising under this, you
+consent to the exclusive jurisdiction and venue of the state and
+federal courts sitting in Dallas, Texas and to service by
+certified mail, return receipt requested, or as otherwise
+permitted by law.
+
+ [B] You will not modify, reverse compile, disassemble, or
+reverse engineer the Program, or use or disclose any of our
+secret information that it contains.
+
+[V.07.15.94]
--- /dev/null
+++ b/rott/Makefile
@@ -1,0 +1,102 @@
+# Determine which version to build
+# Make sure only one of the following is set to 1 at once
+# Triple 0 will build the commercial/registered version
+
+SHAREWARE   ?= 1
+SUPERROTT   ?= 0
+SITELICENSE ?= 0
+
+CPPFLAGS += -DSHAREWARE=$(SHAREWARE)
+CPPFLAGS += -DSUPERROTT=$(SUPERROTT)
+CPPFLAGS += -DSITELICENSE=$(SITELICENSE)
+
+ROTT ?= rott
+
+# Regular build flags and rules
+
+CC ?= gcc
+
+CFLAGS ?= -g -O2
+CFLAGS += -Wall -Wno-unused
+CFLAGS += $(shell sdl-config --cflags)
+CFLAGS += $(EXTRACFLAGS)
+
+CPPFLAGS += -DUSE_SDL=1
+CPPFLAGS += -DPLATFORM_UNIX=1
+CPPFLAGS += $(EXTRACPPFLAGS)
+
+LDFLAGS += $(EXTRALDFLAGS)
+
+LDLIBS += $(shell sdl-config --libs)
+LDLIBS += -lSDL_mixer
+LDLIBS += $(EXTRALDLIBS)
+
+OBJS :=
+OBJS += cin_actr.o
+OBJS += cin_efct.o
+OBJS += cin_evnt.o
+OBJS += cin_glob.o
+OBJS += cin_main.o
+OBJS += cin_util.o
+OBJS += dosutil.o
+OBJS += engine.o
+OBJS += isr.o
+OBJS += modexlib.o
+OBJS += rt_actor.o
+OBJS += rt_battl.o
+OBJS += rt_build.o
+OBJS += rt_cfg.o
+OBJS += rt_crc.o
+OBJS += rt_com.o
+OBJS += rt_debug.o
+OBJS += rt_dmand.o
+OBJS += rt_door.o
+OBJS += rt_draw.o
+OBJS += rt_floor.o
+OBJS += rt_game.o
+OBJS += rt_in.o
+OBJS += rt_main.o
+OBJS += rt_map.o
+OBJS += rt_menu.o
+OBJS += rt_msg.o
+OBJS += rt_net.o
+OBJS += rt_playr.o
+OBJS += rt_rand.o
+OBJS += rt_scale.o
+OBJS += rt_sound.o
+OBJS += rt_spbal.o
+OBJS += rt_sqrt.o
+OBJS += rt_stat.o
+OBJS += rt_state.o
+OBJS += rt_str.o
+OBJS += rt_swift.o
+OBJS += rt_ted.o
+OBJS += rt_util.o
+OBJS += rt_view.o
+OBJS += rt_vid.o
+OBJS += rt_err.o
+OBJS += scriplib.o
+OBJS += w_wad.o
+OBJS += watcom.o
+OBJS += z_zone.o
+OBJS += byteordr.o
+OBJS += dukemusc.o
+OBJS += winrott.o
+
+AUDIOLIB := audiolib/audiolib.a
+
+all: $(ROTT)
+
+$(ROTT): $(OBJS) $(AUDIOLIB)
+	$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(OBJS): develop.h
+
+$(AUDIOLIB):
+	$(MAKE) -C audiolib
+
+tidy: 
+	$(RM) $(OBJS) $(ROTT) $(ROTT).exe
+
+clean: tidy
+	$(MAKE) -C audiolib $@
\ No newline at end of file
binary files /dev/null b/rott/SDL.dll differ
binary files /dev/null b/rott/SDL_mixer.dll differ
--- /dev/null
+++ b/rott/WinRott.h
@@ -1,0 +1,58 @@
+
+
+// winrott.h
+
+
+//husk at rette i winrott.c
+
+extern int iGLOBAL_SCREENWIDTH;//bna val 800
+extern int iGLOBAL_SCREENHEIGHT;//bna val 600
+
+//extern int topBarCenterOffsetX;
+
+extern int iGLOBAL_SCREENBWIDE ;
+extern int iG_SCREENWIDTH;// default screen width in bytes
+
+extern int iGLOBAL_HEALTH_X;
+extern int iGLOBAL_HEALTH_Y;
+extern int iGLOBAL_AMMO_X;
+extern int iGLOBAL_AMMO_Y;
+
+extern int iGLOBAL_FOCALWIDTH;
+extern double dGLOBAL_FPFOCALWIDTH;
+
+void EnableScreenStretch(void);
+void DisableScreenStretch(void);
+
+/*
+double dYZANGLELIMIT;
+
+#define FOCALWIDTH 160//160
+#define FPFOCALWIDTH 160.0//160.0
+
+
+
+#define MAXSCREENHEIGHT    480//600//     200*2
+#define MAXSCREENWIDTH     640//800//     320*2
+#define SCREENBWIDE        640*(96/320)//800*(96/320)//     96*2
+#define MAXVIEWWIDTH       640//     320*2
+#define SCREENWIDTH        640*(96/320)//800*(96/320)//     96*2              // default screen width in bytes
+
+
+#define MAXSCREENHEIGHT    600
+#define MAXSCREENWIDTH     800
+#define SCREENBWIDE        800*(96/320)
+#define MAXVIEWWIDTH       800
+#define SCREENWIDTH        800*(96/320)// default screen width in bytes
+
+*/
+//#define VIEWWIDTH               MAXSCREENWIDTH//320*2             // size of view window
+//#define VIEWHEIGHT              MAXSCREENHEIGHT//200*2
+//#define MAXSCANLINES            MAXSCREENHEIGHT//200*2             // size of ylookup table
+
+
+
+
+
+
+
--- /dev/null
+++ b/rott/_engine.h
@@ -1,0 +1,27 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _engine_private
+#define _engine_private
+
+#define NOTSAMETILE(x1,x2)     ( (posts[(x1)].posttype!=posts[(x2)].posttype) || \
+                                 (posts[(x1)].offset!=posts[(x2)].offset))
+#define SGN(x)                 (x>0 ? 1 : -1)
+
+#endif
--- /dev/null
+++ b/rott/_isr.h
@@ -1,0 +1,32 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//    ISR Constants
+//
+//***************************************************************************
+
+#ifndef _isr_private
+#define _isr_private
+
+#define TIMERINT                0x08
+#define KEYBOARDINT             0x09
+
+#endif
--- /dev/null
+++ b/rott/_rt_acto.h
@@ -1,0 +1,296 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_actor_private
+#define _rt_actor_private
+
+#define MAXGIBS            600
+#define HAAPT              24
+#define VAAPT              24
+#define GODHAPT            1024
+#define GODVAPT            1024
+#define MAXDELTAYZSHOOT    (((5*FINEANGLES)/360))
+#define MAXDELTAYZSEE      (((15*FINEANGLES)/360))
+#define MAXSHOOTOFFSET     (((15*FINEANGLES)/360))
+#define MAXSHOOTSHIFT      (1)
+#define MAXDAMAGE          (64)
+#define MAXYZANGLE         (((30*FINEANGLES)/360))
+#define SMOKEWALLOFFSET    (0x800)
+#define MZADJUST           0x30000;
+#define MAXSTEPHEIGHT      24
+#define SIGN(x)            ((x)>=0)?(1):(-1)
+#define MAXRAIN            128
+#define SG_PSTAT      0x4000
+#define SG_PSTATE     0x2000
+#define EXPLOSION_DAMAGE   50
+#define LOWFALLCLIPZ       (maxheight - 96)
+#define HIGHFALLCLIPZ      -5
+#define LOWRISECLIPZ       (nominalheight)
+#define HIGHRISECLIPZ      64
+#define NORMALGIBSPEED     0x2f00
+
+#define FL_PLEADING        0x400
+#define FL_EYEBALL         0x400
+#define FL_UNDEAD          0x8000
+
+#define NME_DRUNKTYPE       0x01
+#define NME_HEATSEEKINGTYPE 0x02
+
+#define NUMSTATES 11
+
+enum {
+    STAND,
+    PATH,
+    COLLIDE1,
+    COLLIDE2,
+    CHASE,
+    USE,
+    AIM,
+    DIE,
+    FIRE,
+    WAIT,
+    CRUSH
+};
+
+#define SHOTMOM                0x200l
+#define NEXT                   1
+#define PREV                   0
+#define ANGLEMOVE              0x2b000l
+#define PAINTIME               5l
+#define LOOKAHEAD              (20 << 16)
+#define DRAINTIME              70l
+#define EXPLOSION_IMPULSE      0x2600l
+#define ZEROMOM                ob->momentumx = ob->momentumy = 0
+#define NOMOM                  ((!ob->momentumx) && (!ob->momentumy))
+#define WHICHACTOR             (ob->obclass-lowguardobj)
+#define SPDPATROL              0x600l
+//#define ENEMYRUNSPEED          (3*SPDPATROL)
+#define ENEMYRUNSPEED          (0xc00)
+#define ENEMYFASTRUNSPEED      (5*SPDPATROL)
+#define ENEMYINSANESPEED       (7*SPDPATROL)
+#define MAXMOVE                0x2000l
+#define PROJECTILESIZE         0x6000l
+#define DEADFRICTION           0x6000l
+#define ROLLMOMENTUM           0x920l
+#define PROJSIZE               0x4000l
+#define PILLARMOM              0x800l
+#define HALFGLOBAL1            (TILEGLOBAL/2)
+#define TOUCHDIST              0xb000l
+#define STANDDIST              0x5000l
+#define SNAKERAD               0x4000l
+#define MINSIGHT               0x18000l
+#define HBM                    -2
+#define SNEAKY                 -3
+#define GIBVALUE               -3
+#define DISKMOMZ               4
+
+//=========================== macros =============================
+
+#define M_ISWALL(x)           ((x->which == WALL) || (x->which == PWALL) || (x->which == MWALL))
+#define M_DISTOK(p1,p2,d)     (abs((p1)-(p2)) <= d)
+#define M_NONS(x)             ((x->obclass == wallfireobj) || (x->obclass == pillarobj))
+#define M_CHOOSETIME(x)       ((int)(TILEGLOBAL/((x->speed))))
+#define M_DIST(x1,x2,y1,y2)   (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))
+#define M_S(x)                (UPDATE_STATES[x][ob->obclass-lowguardobj])
+#define Fix(a)                (a &= (FINEANGLES - 1))
+
+
+#define STOPACTOR(ob)                   \
+   {                                    \
+   ob->momentumx = ob->momentumy = 0;   \
+   ob->dirchoosetime = 0;               \
+   }
+
+
+#define M_CHECKDIR(ob,tdir)             \
+   {                                    \
+   ob->dir = tdir;                      \
+   ParseMomentum(ob,dirangle8[tdir]);   \
+   ActorMovement(ob);                   \
+   if (ob->momentumx || ob->momentumy)  \
+      return;                           \
+   }                                    \
+
+
+#define M_CHECKTURN(x,ndir)                             \
+   {                                                    \
+   if (ndir == olddir)                                  \
+      ZEROMOM;                                          \
+   ParseMomentum(x,dirangle8[ndir]);                    \
+   ActorMovement(x);                                    \
+   if (!NOMOM)                                          \
+      {                                                 \
+      if (ndir != olddir)                               \
+         {                                              \
+         next = dirorder[olddir][NEXT];                 \
+         prev = dirorder[olddir][PREV];                 \
+         x->temp1 = ndir;                               \
+         if (dirdiff[ndir][next] < dirdiff[ndir][prev]) \
+            NewState(x,&s_kristleft);                   \
+         else                                           \
+            NewState(x,&s_kristright);                  \
+         }                                              \
+      return;                                           \
+      }                                                 \
+   }                                                    \
+
+#define M_CheckDoor(ob)                          \
+   {                                             \
+   door = ob->door_to_open;                      \
+   if (door != -1)                               \
+      {                                          \
+      if ((ob->obclass > shurikenobj) &&         \
+          (ob->obclass != collectorobj)          \
+         )                                       \
+         Error("you got it !!!");                \
+      LinkedOpenDoor(door);                      \
+      if (doorobjlist[door]->action != dr_open)  \
+         return;                                 \
+      ob->door_to_open = -1;                     \
+      }                                          \
+   }                                             \
+
+#define M_CheckBossSounds(ob)                                 \
+   {                                                          \
+   if ((ob->obclass >= b_darianobj) &&                        \
+       (ob->obclass <= b_darksnakeobj) &&                     \
+       (ob->flags & FL_ATTACKMODE)  &&                        \
+       (ob->obclass != b_robobossobj) &&                      \
+       (!(ob->flags & FL_DYING))                              \
+      )                                                       \
+      {                                                       \
+      if (MISCVARS->SOUNDTIME)                                \
+         MISCVARS->SOUNDTIME --;                              \
+      else                                                    \
+         {                                                    \
+         MISCVARS->SOUNDTIME = 5*VBLCOUNTER;                  \
+         if (GameRandomNumber("boss sound check",0)<160)      \
+            {                                                 \
+            int rand,sound;                                   \
+                                                              \
+            rand = GameRandomNumber("boss sounds",0);         \
+            sound = BAS[ob->obclass].operate;                 \
+            if (rand < 160)                                   \
+               sound ++;                                      \
+            if (rand < 80)                                    \
+               sound ++;                                      \
+                                                              \
+            SD_PlaySoundRTP(sound,ob->x,ob->y);               \
+            }                                                 \
+         }                                                    \
+      if (MISCVARS->REDTIME)                                  \
+         {                                                    \
+         MISCVARS->REDTIME --;                                \
+         MISCVARS->redindex = ((MISCVARS->REDTIME >> 1) & 15);\
+         }                                                    \
+      }                                                       \
+   }
+
+
+
+
+#define SET_DEATH_SHAPEOFFSET(ob)                     \
+   {                                                  \
+   ob->flags |= FL_ALTERNATE;                         \
+   ob->shapeoffset += deathshapeoffset[ob->obclass];  \
+   }
+
+
+#define RESET_DEATH_SHAPEOFFSET(ob)                   \
+   {                                                  \
+   ob->flags &= ~FL_ALTERNATE;                        \
+   ob->shapeoffset -= deathshapeoffset[ob->obclass];  \
+   }
+
+#define LOW_VIOLENCE_DEATH_SHOULD_BE_SET(ob)          \
+     ((gamestate.violence < vl_high) &&               \
+      (ob->obclass >= lowguardobj) &&                 \
+      (ob->obclass <= triadenforcerobj) &&            \
+      (!(ob->flags & FL_ALTERNATE))                   \
+     )                                                \
+
+#define LOW_VIOLENCE_DEATH_IS_SET(ob)   (ob->flags & FL_ALTERNATE)
+
+#define LOW_VIOLENCE_PAIN_SHOULD_BE_SET  LOW_VIOLENCE_DEATH_SHOULD_BE_SET
+
+#define LOW_VIOLENCE_PAIN_IS_SET  LOW_VIOLENCE_DEATH_IS_SET
+
+#define SET_PAIN_SHAPEOFFSET  SET_DEATH_SHAPEOFFSET
+
+#define RESET_PAIN_SHAPEOFFSET  RESET_DEATH_SHAPEOFFSET
+
+
+// default = actor
+
+typedef struct  sat
+{   int          x,y,z;
+    unsigned     flags;
+    int          hitpoints;
+    int          targetx,targety;
+    int          angle;
+    int          yzangle;
+    int          speed;
+    int          momentumx,momentumy,momentumz;
+    int          temp1,temp2,temp3;
+    int          whateverindex,targetindex;
+
+    short        ticcount;
+    short        shapeoffset;
+    short        stateindex;
+    short        dirchoosetime;
+
+    byte         areanumber;
+    byte         obclass;
+    signed char  door_to_open;
+    signed char  dir;
+
+} saved_actor_type;
+
+
+typedef struct
+{   thingtype which;
+    byte tilex,tiley;
+    fixed x,y,z;
+} tpoint;
+
+
+//========================== Function Prototypes ==============================
+
+void     MissileMovement(objtype*);
+boolean  MissileTryMove(objtype*,int,int,int);
+void     T_DarkSnakeChase(objtype*);
+void     HeatSeek(objtype*);
+boolean  CheckDoor(objtype *ob,doorobj_t*,int,int);
+boolean  NextToDoor(objtype*ob);
+void     MissileHit (objtype *ob,void*);
+int      Near(objtype*,void*,int);
+void     FirstSighting(objtype*);
+void     SelectOrobotChaseDir(objtype*);
+void     SelectPathDir(objtype*);
+void     SelectChaseDir(objtype*);
+void     SelectRoboChaseDir(objtype*);
+void     SelectDodgeDir(objtype*);
+void     SelectRollDir (objtype*);
+void     SelectTouchDir(objtype*);
+void     SelectMineDir(objtype*);
+boolean  WallCheck(int,int);
+boolean  NMEspincheck(objtype*);
+void     TurnActorIntoSprite(objtype*ob);
+void     ActivateEnemy(objtype*);
+#endif
--- /dev/null
+++ b/rott/_rt_buil.h
@@ -1,0 +1,48 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_build_private
+#define _rt_build_private
+
+#define MAX(x,y)               ((x>y) ? (x) : (y))
+#define MAXPLANES 10
+
+// Should be 10 with titles
+#define MENUOFFY     (10)
+#define MENUBACKNAME ("plane")
+#define MENUTITLEY 10
+#define TEXTUREW     (288)
+#define TEXTUREWIDTH ((TEXTUREW*1024)-1)
+#define TEXTUREHEIGHT (158)
+#define NORMALVIEW   (0x40400L)
+#define NORMALHEIGHTDIVISOR   (156000000)
+#define NORMALWIDTHMULTIPLIER (241)
+#define FLIPTIME     20//60
+
+
+typedef struct
+{
+    int   x1, y1;
+    int   x2, y2;
+    int   texturewidth;
+    int   texture;
+    int   origheight;
+} plane_t;
+
+#endif
--- /dev/null
+++ b/rott/_rt_com.h
@@ -1,0 +1,53 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_com_private
+#define _rt_com_private
+
+
+#define SYNCPACKETSIZE 32
+
+#define SYNC_PHASE0 6
+#define SYNC_PHASE1 0
+#define SYNC_PHASE2 1
+#define SYNC_PHASE3 2
+#define SYNC_PHASE4 3
+#define SYNC_PHASE5 4
+#define SYNC_MEMO   99
+#define NUMSYNCPHASES 5
+
+#define SYNCTIME    15
+
+typedef struct
+{
+    byte type;
+    int  phase;
+    int  clocktime;
+    int  delta;
+    byte data[SYNCPACKETSIZE];
+} syncpackettype;
+
+typedef struct
+{
+    int  sendtime;
+    int  deltatime;
+    syncpackettype pkt;
+} synctype;
+
+#endif
--- /dev/null
+++ b/rott/_rt_dman.h
@@ -1,0 +1,29 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_dmand_private
+#define _rt_dmand_private
+
+#define RECORDINGSAMPLERATE 7000
+#define RECORDINGBUFFERSIZE 16384
+#define PLAYBACKBUFFERSIZE 16384
+#define PLAYBACKDELTASIZE  256
+
+#endif
+
--- /dev/null
+++ b/rott/_rt_door.h
@@ -1,0 +1,48 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_door_private
+#define _rt_door_private
+
+#define OPENTICS	165
+
+typedef struct tp
+{
+    signed char actionindex;
+    signed char swapactionindex;
+    int         whichobj;
+    byte        tictime;
+    byte        ticcount;
+    byte        triggered;
+    byte        complete;
+    byte        done;
+} saved_touch_type;
+
+
+#define NUMTOUCHPLATEACTIONS 8
+
+#define FL_TACT 0x4000
+#define FL_TSTAT 0x8000
+
+#define PUSHWALLSPEED 10
+
+#define AMW_NUMFRAMES 9
+#define AMW_TICCOUNT  3
+
+#endif
--- /dev/null
+++ b/rott/_rt_draw.h
@@ -1,0 +1,74 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_draw_private
+#define _rt_draw_private
+
+#include "develop.h"
+
+#define MINZ                            0x2700
+#define MAXBOB                          0x9000
+
+#define GOLOWER  0x38000
+#define GOHIGHER 0x20000
+
+#define MAXVISIBLEDOORS 30
+
+#define DHEIGHTFRACTION 8
+
+#define MINZ                            0x2700
+#define MAXDRAWNTICS                    40
+
+#define W_CHANGE  (WEAPONUPTICS || WEAPONDOWNTICS)
+
+#if (SHAREWARE == 0)
+#define NUMWEAPGRAPHICS 16
+#else
+#define NUMWEAPGRAPHICS 9
+#endif
+
+#define HFRACTION (6+HEIGHTFRACTION)
+
+#define FIXEDTRANSLEVEL (30)
+
+typedef struct
+{
+    int x;
+    int y;
+    int angle;
+    int scale;
+    int dx;
+    int dy;
+    int dangle;
+    int dscale;
+    int phase;
+    int time;
+    int pausetime;
+    int pausex;
+    int pausey;
+} screensaver_t;
+
+void  DrawPlayerWeapon(void);
+boolean TransformPlane (int x1, int y1, int x2, int y2, visobj_t * plane);
+int   CalcRotate (objtype *ob);
+void  DrawScaleds (void);
+void  FixOfs (void);
+void SetSpriteLightLevel (int x, int y, visobj_t * sprite, int dir, int fullbright);
+
+#endif
--- /dev/null
+++ b/rott/_rt_floo.h
@@ -1,0 +1,28 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_floor_private
+#define _rt_floor_private
+
+//#define	MAXVIEWHEIGHT MAXSCREENHEIGHT
+#define MAXSKYSEGS    2048
+#define MAXSKYDATA    8
+#define MINSKYHEIGHT  148
+
+#endif
--- /dev/null
+++ b/rott/_rt_game.h
@@ -1,0 +1,165 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_game_private
+#define _rt_game_private
+
+//******************************************************************************
+//
+// Private header for RT_GAME.C
+//
+//******************************************************************************
+
+
+//******************************************************************************
+//
+// TYPEDEFS
+//
+//******************************************************************************
+
+typedef struct {
+    char str[10];
+    int length;
+} STR;
+
+//******************************************************************************
+//
+// DEFINES
+//
+//******************************************************************************
+
+#define MENUSHADELEVEL  105
+
+#define KILLS_X      0
+#define KILLS_Y      176
+#define KILLS_WIDTH  32
+#define KILLS_HEIGHT 24
+#define KILLS_OFFSET 14
+#define KILLS_NAME_Y ( KILLS_Y + 16 )
+#define MAXKILLBOXES 10
+#define PLAYERS_Y      ( 107 + ( gamestate.teamplay ? 0 : 4 ) )
+#define PLAYERS_NAME_Y ( PLAYERS_Y + 16 )
+#define PLAYERS_TEAM_Y ( PLAYERS_Y + 24 )
+
+#define LEADER_X      0
+#define LEADER_Y      0
+#define LEADER_NUM_X  61
+#define LEADER_NUM_Y  ( LEADER_Y )
+#define LEADER_NAME_X ( LEADER_X + 3 )
+#define LEADER_NAME_Y ( LEADER_Y + 2 )
+#define LEADER_WIDTH  88
+#define LEADER_HEIGHT 16
+/* bna++
+#define HEALTH_X  20
+#define HEALTH_Y  185
+
+#define AMMO_X    300
+#define AMMO_Y    184
+*/
+//--------------------
+#define HEALTH_X  20*2
+#define HEALTH_Y  (185*2)+16
+
+#define AMMO_X    300*2
+#define AMMO_Y    (184*2)+16
+//--------------------
+
+#define SCORE_X   4
+#define SCORE_Y   0
+
+/*
+#define KEY1_X    152
+#define KEY2_X    160
+#define KEY3_X    168
+#define KEY4_X    176
+#define KEY_Y     0
+
+#define POWER_X   184
+#define POWER_Y   0
+
+#define ARMOR_X   200
+#define ARMOR_Y   0
+
+#define MEN_X     216
+#define MEN_Y     0
+*/
+//--------------------
+#define KEY1_X    152
+#define KEY2_X    160
+#define KEY3_X    168
+#define KEY4_X    176
+#define KEY_Y     0
+
+#define POWER_X   (184)
+#define POWER_Y   0
+
+#define ARMOR_X   200
+#define ARMOR_Y   0
+
+#define MEN_X     216
+#define MEN_Y     0
+//--------------------
+#define HOUR_X    7
+#define MIN_X     26
+#define SEC_X     45
+#define TIME_Y    0
+
+#define GAMETIME_X 88
+#define GAMETIME_Y 0
+
+#define TALLYTIME_X 130
+#define TALLYTIME_Y 8
+
+#define LIVES_X   288
+#define LIVES_Y   0
+
+#define TRIAD_X   308
+#define TRIAD_Y   6
+
+#define POWERUP1X 184
+#define POWERUP2X 200
+#define POWERUPY  0
+
+#define EXTRAPOINTS        50000
+#define ADRENALINEBONUS    5
+
+#define STR_SAVECHT1 "Your Save Game file is,"
+#define STR_SAVECHT2 "shall we say, \"corrupted\"."
+#define STR_SAVECHT3 "But I'll let you go on and"
+#define STR_SAVECHT4 "play anyway...."
+
+#define MAXSAVEDGAMESIZE 120000
+
+#if (SHAREWARE == 0)
+#define WEAPON_IS_MAGICAL(x) (((x) == wp_dog) || ((x) == wp_godhand))
+#else
+#define WEAPON_IS_MAGICAL(x) ((x) == wp_godhand)
+#endif
+
+//******************************************************************************
+//
+// PROTOTYPES
+//
+//******************************************************************************
+
+void DrawMPPic (int xpos, int ypos, int width, int height, int heightmod, byte *src, boolean bufferofsonly);
+void DrawHighScores (void);
+void GM_MemToScreen (byte *source, int width, int height, int x, int y);
+
+#endif
--- /dev/null
+++ b/rott/_rt_in.h
@@ -1,0 +1,61 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//****************************************************************************
+//
+// Private header for RT_IN.C
+//
+//****************************************************************************
+
+#ifndef _rt_in_private
+#define _rt_in_private
+
+
+//****************************************************************************
+//
+// TYPEDEFS
+//
+//****************************************************************************
+
+
+//****************************************************************************
+//
+// DEFINES
+//
+//****************************************************************************
+
+#define  KeyInt         9  // The keyboard ISR number
+#define  MReset         0
+#define  MButtons       3
+#define  MDelta         11
+#define  MouseInt       0x33
+#define  JoyScaleMax    32768
+#define  JoyScaleShift  8
+#define  MaxJoyValue    5000
+
+void Mouse (int x);
+
+#if defined(__WATCOMC__)
+#pragma aux Mouse =  \
+   "int  33h"        \
+   parm [EAX]        \
+   modify [EAX]
+#endif
+
+#endif
--- /dev/null
+++ b/rott/_rt_main.h
@@ -1,0 +1,74 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_main_private
+#define _rt_main_private
+
+#include "develop.h"
+
+void GameLoop (void);
+void PlayLoop (void);
+void PollKeyboard(void);
+void FixColorMap( void );
+
+#define QUITTIMEINTERVAL ((35*6)-5)
+boolean CheckForQuickLoad ( void );
+
+#if SAVE_SCREEN
+
+void WriteLBMfile (char *filename, byte *data, int width, int height);
+void GetFileName (boolean saveLBM);
+void DrawRottTitle ( void );
+
+void WritePCX (char * file, byte * source);
+int PutBytes (unsigned char *ptr, unsigned int bytes);
+
+typedef struct
+{
+    unsigned short w,h;
+    short          x,y;
+    unsigned char  nPlanes;
+    unsigned char  masking;
+    unsigned char  compression;
+    unsigned char  pad1;
+    unsigned short transparentColor;
+    unsigned char  xAspect,yAspect;
+    short          pageWidth,pageHeight;
+} bmhd_t;
+
+
+typedef struct {
+    unsigned char manufacturer;
+    unsigned char version;
+    unsigned char encoding;
+    unsigned char bitsperpixel;
+    unsigned short int  xmin, ymin, xmax, ymax;
+    unsigned short int  hres, vres;
+    unsigned char colormap[16][3];
+    unsigned char reserved;
+    unsigned char nplanes;
+    unsigned short int  bytesperline;
+} PCX_HEADER;
+
+#define GAP_SIZE  (128 - sizeof (PCX_HEADER))
+
+
+#endif
+
+#endif
--- /dev/null
+++ b/rott/_rt_map.h
@@ -1,0 +1,44 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_map_private
+#define _rt_map_private
+
+#if defined(__WATCOM__)
+#pragma aux FastFill =  \
+        "rep stosb"       \
+        parm    [edi] [eax] [ecx] \
+        modify exact [ecx]
+#endif
+void FastFill(byte * buf, int color, int count);
+
+
+#define MAP_PLAYERCOLOR 4
+#define MAP_MWALLCOLOR 13
+#define MAP_PWALLCOLOR 8
+#define MAP_AWALLCOLOR 9
+#define MAP_WALLCOLOR 7
+#define MAP_DOORCOLOR 3
+#define MAP_SPRITECOLOR 2
+#define MAP_ACTORCOLOR 15
+#define MAP_SKYCOLOR 11
+
+#define FULLMAP_SCALE 5
+
+#endif
--- /dev/null
+++ b/rott/_rt_menu.h
@@ -1,0 +1,369 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_menu_private
+#define _rt_menu_private
+
+//******************************************************************************
+//
+// Private Header for RT_MENU.C
+//
+//******************************************************************************
+
+#include "rt_in.h"
+
+//
+// Specific Menu defines
+//
+
+#define BORDCOLOR       0x29
+#define BORD2COLOR      0x23
+#define DEACTIVE        0x2b
+#define BKGDCOLOR       0x2d
+#define STRIPE          0x2c
+
+
+#define SENSITIVE       60
+#define CENTER          SENSITIVE*2
+
+
+#define MENU_X          32
+#define MENU_Y          16
+#define MENU_W          235
+#define MENU_H          14*9+4
+
+
+#define LSM_X           180      //32
+#define LSM_Y           16
+#define LSM_W           80       //176
+#define LSM_H           10*14+8
+
+#define LSA_X           96
+#define LSA_Y           80
+#define LSA_W           130
+#define LSA_H           42
+
+
+#define SM_X            32
+#define SM_Y            52
+#define SM_W            252
+#define SM_H            35
+
+#define SM_Y1           20
+#define SM_H1           4*14-9
+#define SM_Y2           SM_Y1+5*14
+#define SM_H2           4*14-9
+#define SM_Y3           SM_Y2+5*14
+#define SM_H3           3*14-9
+
+
+#define CTL_X           19
+#define CTL_Y           32
+#define CTL_W           284
+#define CTL_H           105
+
+
+#define CST_X           20
+#define CST_Y           43
+#define CST_START       60
+#define CST_SPC         60
+
+
+#define TUF_X           0
+#define TUF_Y           32
+
+
+#define HLP_X           34
+#define HLP_Y           63
+#define HLP_W           264
+#define HLP_H           51
+
+
+#define MU_X            32
+#define MU_Y            22
+#define MU_W            252
+#define MU_H            118
+
+
+#define FX_X            32
+#define FX_Y            16
+#define FX_W            252
+#define FX_H            130
+
+
+#define MP_X            55//32
+#define MP_Y            60
+#define MP_W            252
+#define MP_H            35
+
+
+#define X1_X            55
+#define X1_Y            25
+#define X1_W            252
+
+#define X2_X            55
+#define X2_Y            65
+#define X2_W            252
+#define X2_H            35
+
+#define X3_X            55
+#define X3_Y            65
+#define X3_W            252
+#define X3_H            35
+
+#define LEVSEL_X            32
+#define LEVSEL_Y            22
+#define LEVSEL_W            252
+#define LEVSEL_H            118
+#define MAXCUSTOM       12
+
+#define STARTITEM       newgame
+
+//
+// General defines
+//
+#define CP_SemiActive      4
+#define CP_Highlight       5
+
+#define OUTOFRANGE         100
+#define ESCPRESSED         -1
+#define PAGEUP             -2
+#define PAGEDOWN           -3
+#define NOTAVAILABLECOLOR  7
+#define NEXTPAGECOLOR      16
+#define NORMALCOLOR        21
+#define DIMMEDCOLOR        24
+#define ACTIVECOLOR        241
+#define HIGHLIGHTCOLOR     1
+
+#define MouseInt 0x33
+#define GAMESVD      "There's already a game\n" \
+                     "saved at this position.\n"\
+                     "Overwrite?"
+#define COLOR        235
+
+#define CUSTOMX      76
+
+#define NUMSAVEGAMES 14
+
+#define PWORDX 58
+#define PWORDY 46
+//#define PBOXX  68
+#define PBOXX  ( ( 288 - PBOXW ) / 2 )
+#define PBOXY  71
+#define PBOXW  115
+#define PSTRW  110
+#define PBOXH  12
+
+
+#define QUICKSAVEBACKUP ("rottgamf.rot")
+//******************************************************************************
+//
+// ENUMS
+//
+//******************************************************************************
+
+typedef struct
+{
+    int allowed[4];
+} CustomCtrls;
+
+// FOR INPUT TYPES
+enum {MOUSE, JOYSTICK, KEYBOARDBTNS, KEYBOARDMOVE, SPECIAL1, SPECIAL2};
+
+
+//******************************************************************************
+//
+// GLOBALS
+//
+//******************************************************************************
+
+static byte *ScanNames[] =    // Scan code names with single chars
+{
+    "?","?","1","2","3","4","5","6","7","8","9","0","-","+","?","?",
+    "Q","W","E","R","T","Y","U","I","O","P","[","]","|","?","A","S",
+    "D","F","G","H","J","K","L",";","\"","?","?","?","Z","X","C","V",
+    "B","N","M",",",".","/","?","?","?","?","?","?","?","?","?","?",
+    "?","?","?","?","?","?","?","?","\xf","?","-","\x15","5","\x11","+","?",
+    "\x13","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
+    "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
+    "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"
+};
+
+
+static byte ExtScanCodes[] = // Scan codes with >1 char names
+{
+    1,    0xe,  0xf,  0x1d, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
+    0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x57, 0x58, 0x46, 0x1c, 0x36,
+    0x37, 0x38, 0x47, 0x49, 0x4f, 0x51, 0x52, 0x53, 0x45, 0x48,
+    0x50, 0x4b, 0x4d, 0x00
+};
+
+static byte *ExtScanNames[] = // Names corresponding to ExtScanCodes
+{
+    "Esc","BkSp","Tab","Ctrl","Space","CapLk","F1","F2","F3","F4",
+    "F5","F6","F7","F8","F9","F10","F11","F12","SclLk","Enter","Shift",
+    "PrtSc","Alt","Home","PgUp","End","PgDn","Ins","Del","NumLk","Up",
+    "Down","Left","Right",""
+};
+
+
+//******************************************************************************
+//
+// PROTOTYPES
+//
+//******************************************************************************
+
+void MouseSensitivity (void);
+void DoThreshold (void);
+byte * IN_GetScanName (ScanCode scan);
+void DisplayInfo (int which);
+
+void PrintLSEntry (int w);
+
+void DrawHalfStep (int x, int y);
+
+void DrawCtlScreen (void);
+void DrawCtlButtons (void);
+void DrawSoundMenu (void);
+void DrawCustomScreen (void);
+void DrawLoadSaveScreen (int loadsave);
+void DrawLoadSaveScreenAlt (int loadsave);
+void DrawMusicMenu (void);
+void DrawNewGame (void);
+void DrawNewGameDiff (int w);
+void DrawNewPlayerDiff (int w);
+void DrawFXMenu (void);
+void DrawFXButtons (void);
+void DrawCustomJoystick (void);
+void DrawCustomMouse (void);
+void DrawCustomSpecial (void);
+void DrawCustomMenu (void);
+void DrawPlayerMenu (void);
+
+void DoMainMenu (void);
+
+boolean CP_DisplayMsg (char *s, int number);
+void CP_EndGame (void);
+int CP_SaveGame (void);
+void CP_Control (void);
+void CP_Sound (void);
+void CP_ChangeView (void);
+void CP_DoubleClickSpeed( void );
+void CP_ErrorMsg( char *title, char *error, int font );
+void CP_Quit (int which);
+void CP_NewGame (void);
+void CP_Music (void);
+void CP_FX (void);
+void CP_MCports (void);
+void CP_FXMenu (void);
+void CP_Custom (void);
+void CP_Keyboard (void);
+void CP_Mouse (void);
+void CP_Joystick (void);
+void CP_Special (void);
+void CP_OrderInfo( void );
+
+void DefineMouseBtns1 (void);
+void DefineMouseBtns2 (void);
+void DefineKeyBtns1 (void);
+void DefineKeyBtns2 (void);
+void DefineKeyMove1 (void);
+void DefineKeyMove2 (void);
+void DefineJoyBtns1 (void);
+void DefineJoyBtns2 (void);
+void DefineSpecialBtns1 (void);
+void DefineSpecialBtns2 (void);
+
+void DrawSTMenuBuf (int x, int y, int w, int h, boolean up);
+
+void MusicVolume (void);
+void FXVolume (void);
+
+void DefineKey( void );
+void DefineJoyBtn( void );
+void DefineMouseBtn( void );
+
+void DrawControlMenu (void);
+void CP_ControlMenu (void);
+void DrawOptionsMenu (void);
+void DrawExtOptionsMenu (void);
+void CP_ExtOptionsMenu (void);
+void CP_OptionsMenu (void);
+void DrawOptionsButtons (void);
+void DrawExtOptionsButtons (void);
+void MenuFlipSpeed (void);
+void DrawDetailMenu (void);
+void CP_DetailMenu (void);
+void DrawBattleMenu (void);
+void CP_BattleMenu (void);
+void MCERROR (void);
+
+void DrawKeyboardMenu (void);
+void CP_KeyboardMenu (void);
+boolean SliderMenu( int *number, int upperbound, int lowerbound, int erasex,
+                    int erasey, int erasew, int numadjust, char *blockname,
+                    void (*routine) (int w), char *title, char *left, char *right );
+
+void DrawF1Help (void);
+void CP_F1Help (void);
+void CP_ScreenSize( void );
+
+void CP_ViolenceMenu (void);
+void DrawViolenceLevelMenu (void);
+void DrawViolenceLevelPWord (void);
+
+void DrawViolenceLevel (void);
+void CP_ViolenceLevel (void);
+
+void DrawPWMenu (void);
+void CP_PWMenu (void);
+
+void DrawBattleModes (void);
+void CP_BattleModes (void);
+
+void DrawBattleOptions (void);
+void CP_BattleOptions (void);
+
+void DrawGravityMenu (void);
+void CP_GravityOptions (void);
+void DrawSpeedMenu (void);
+void CP_SpeedOptions (void);
+void DrawAmmoPerWeaponMenu (void);
+void CP_AmmoPerWeaponOptions (void);
+void DrawHitPointsMenu (void);
+void CP_HitPointsOptions (void);
+void DrawSpawnControlMenu (void);
+void DrawSpawnControlButtons (void);
+void CP_SpawnControlOptions (void);
+void DrawLightLevelMenu (void);
+void CP_LightLevelOptions (void);
+void DrawPointGoalMenu (void);
+void CP_PointGoalOptions (void);
+void DrawDangerMenu (void);
+void CP_DangerOptions (void);
+void DrawTimeLimitMenu (void);
+void CP_TimeLimitOptions (void);
+void PrintBattleOption( boolean inmenu, int x, int y, char *text );
+
+void CP_OnePlayerWarningMessage( void );
+
+void DrawMultiPageCustomMenu( char *title, void ( *redrawfunc )( void ) );
+
+#endif
--- /dev/null
+++ b/rott/_rt_msg.h
@@ -1,0 +1,25 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_msg_private
+#define _rt_msg_private
+
+#define MESSAGETIME (35*6)
+
+#endif
--- /dev/null
+++ b/rott/_rt_net.h
@@ -1,0 +1,122 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_net_private
+#define _rt_net_private
+
+#define DEMOBUFFSIZE 50000
+
+#define FASTSPEED (0xB000)
+
+#define SETUPTIME     15
+
+#define PlayerCommand(player,command)    \
+        (PlayerCmds[(player)]->Commands[(command)])
+
+#define ClientCommand(player,command)    \
+        (ClientCmds[(player)]->Commands[(command)])
+
+#define LocalCommand(command)    \
+        (LocalCmds->Commands[(command)])
+
+#define ServerCommand(command)    \
+        (ServerCmds->Commands[(command)])
+
+#define CommandAddress(time)    \
+        (((time)-controlupdatestartedtime) & (MAXCMDS-1))
+
+#define NextLocalCommand()    \
+        (LocalCommand(CommandAddress(controlupdatetime)))
+
+#define NextServerCommand()    \
+        (ServerCommand(CommandAddress(serverupdatetime)))
+
+#define ClientTimeCommand(which,whichtime)    \
+        (ClientCmds[(which)]->Commands[(CommandAddress((whichtime)))])
+
+#define ServerCommandStatus(whichtime)    \
+        (CommandState[0]->CommandStates[(CommandAddress((whichtime)))])
+
+#define ServerCommandNumberStatus(command)    \
+        (CommandState[0]->CommandStates[(command)])
+
+#define ClientCommandStatus(which, whichtime)    \
+        (CommandState[(which+1)]->CommandStates[(CommandAddress((whichtime)))])
+
+#define ClientCommandNumberStatus(which, command)    \
+        (CommandState[(which+1)]->CommandStates[(command)])
+
+/*
+#define PacketAddress(time)    \
+        ((time) & (MAXCMDS-1))
+*/
+
+#define PacketAddress(time)    \
+        (time)
+
+
+#define NETWORKTIMEOUT  (VBLCOUNTER/3)
+#define MODEMTIMEOUT    (VBLCOUNTER/2)
+#define SERVERTIMEOUT    (VBLCOUNTER<<3)
+
+#define MAXPOLLTICS 3
+
+
+typedef enum {
+    scfp_nodata,
+    scfp_gameready,
+    scfp_data,
+    scfp_done
+} setupcheckforpacketstate;
+
+typedef enum {
+    cs_ready,
+    cs_notarrived,
+    cs_fixing
+} en_CommandStatus;
+
+typedef enum {
+    player_ingame,
+    player_quitgame,
+    player_leftgame
+} en_playerstatus;
+
+void PreparePacket (MoveType * pkt);
+int  GetPacketSize (void * pkt);
+void SendPacket (void * pkt, int dest);
+void GetRemotePacket (int from, int delay);
+void ResendLocalPackets  (int time, int dest, int numpackets);
+void ResendServerPackets (int time, int dest, int numpackets);
+void ResendPacket (void * pkt, int dest);
+void AddClientDelta (void * pkt, int src);
+void FixupPacket (void * pkt, int src);
+void ProcessPacket (void * pkt, int src);
+void AddServerPacket(void * pkt, int src);
+void AddClientPacket (void * pkt, int src);
+void AddPacket (void * pkt, int src);
+void RequestPacket (int time, int dest, int numpackets);
+boolean AllPlayersReady ( void );
+boolean AreClientsReady ( void );
+boolean IsServerCommandReady ( int time );
+void UpdatePlayerObj ( int player );
+void AddServerSubPacket(COM_ServerHeaderType * serverpkt);
+void AddSubPacket (void * pkt, int src);
+
+
+#endif
--- /dev/null
+++ b/rott/_rt_play.h
@@ -1,0 +1,125 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_playr_private
+#define _rt_playr_private
+
+#include "watcom.h"
+//double dTopYZANGLELIMIT; in winrott.c
+#define TopYZANGLELIMIT  (44*FINEANGLES/360)//bna added
+#define YZANGLELIMIT  (80*FINEANGLES/360)//bna--(30*FINEANGLES/360)
+/*
+//bna++ had to limit this or the sky would fuck up
+#define TopYZANGLELIMIT  (6*FINEANGLES/360)//bna added
+#define YZANGLELIMIT  (40*FINEANGLES/360)//bna--(30*FINEANGLES/360)
+//partly fixed you can now se up but not down very much see rt_playr.c TopYZANGLELIMIT
+*/
+
+
+#define YZTILTSPEED   20*4//*2 = bna added
+#define SNAPBACKSPEED 10*15//*2 = bna added
+#define YZHORIZONSPEED 4*5//*2 = bna added
+#define HORIZONYZOFFSET (FINEANGLES/4)
+#define SetPlayerHorizon(ps,hlevel)    \
+    {                                  \
+    if ((hlevel)>YZANGLELIMIT)           \
+       (ps)->horizon=HORIZONYZOFFSET+YZANGLELIMIT;\
+    else if ((hlevel)<-YZANGLELIMIT)     \
+       (ps)->horizon=HORIZONYZOFFSET-YZANGLELIMIT;\
+    else                                  \
+       (ps)->horizon=HORIZONYZOFFSET+(hlevel);\
+	 }
+
+#define StartWeaponChange \
+{\
+ SD_PlaySoundRTP(SD_SELECTWPNSND,ob->x,ob->y);\
+ pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;\
+ if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )\
+	 DrawBarAmmo (false);            \
+}
+
+
+#define BULLETHOLEOFFSET 0x700
+
+#define M_DIST(x1,x2,y1,y2)   (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))
+
+#define W_CHANGE(x)   ((x->weapondowntics) || (x->weaponuptics))
+#define NOMOM         ((!ob->momentumx) && (!ob->momentumy))
+#define DISTOK(p1,p2,d)    (abs((p1)-(p2)) <= d)
+#define Fix(a)        (a &= (FINEANGLES-1))
+#define REMOTEPKTSIZE    (sizeof(MoveType))
+#define BJRUNSPEED   2048
+#define BJJUMPSPEED  680
+#define PROJECTILESIZE 0xc000l
+
+#define MOVESCALE       150l
+#define BACKMOVESCALE   100l
+#define EXTRAPOINTS     40000
+#define JETPACKTHRUST (64)
+
+#define RUNMOVE      0xa00
+#define BASEMOVE     0x600
+#define ANGLEMOVE    0x100000
+
+#define SGN(x)                 (x>0 ? 1 : -1)
+#define NETMOM    (BASEMOVE+0x10000)
+
+#define DISTANCE(x1,x2,y1,y2)   (FixedMulShift((x1-x2),(x1-x2),16)+FixedMulShift((y1-y2),(y1-y2),16))
+
+#define TILTLIMIT     95
+#define PLAYERSTEPTIME 0xf000
+
+#define HITWALLSPEED  0x2800
+#define GODVIEWANGLE  FINEANGLES/150
+#define GODOFFSET     10
+#define DOGOFFSET     46
+#define KESTICS       70
+#define BBTIME        105
+
+#define KEYBOARDNORMALTURNAMOUNT (0x160000)
+//#define KEYBOARDPREAMBLETURNAMOUNT (0xe0000)
+#define KEYBOARDPREAMBLETURNAMOUNT (0xa0000)
+#define TURBOTURNTIME      (5)
+#define TURBOTURNAMOUNT    (0x1e000)
+#define TURNAROUNDSPEED   ((ANG180<<16)/15)
+
+#define VR_INPUT_SERVICE (0x30)
+#define VR_FEEDBACK_SERVICE (0x31)
+
+#define VR_RUNBUTTON         (0)
+#define VR_STRAFELEFTBUTTON  (1)
+#define VR_STRAFERIGHTBUTTON (2)
+#define VR_ATTACKBUTTON      (3)
+#define VR_LOOKUPBUTTON      (4)
+#define VR_LOOKDOWNBUTTON    (5)
+#define VR_SWAPWEAPONBUTTON  (6)
+#define VR_USEBUTTON         (7)
+#define VR_HORIZONUPBUTTON   (8)
+#define VR_HORIZONDOWNBUTTON (9)
+#define VR_MAPBUTTON         (10)
+#define VR_PISTOLBUTTON      (11)
+#define VR_DUALPISTOLBUTTON  (12)
+#define VR_MP40BUTTON        (13)
+#define VR_MISSILEWEAPONBUTTON (14)
+#define VR_RECORDBUTTON      (15)
+
+#define STEPADJUST 3
+void BatAttack(objtype*ob);
+void  T_DogLick (objtype *ob);
+#endif
--- /dev/null
+++ b/rott/_rt_rand.h
@@ -1,0 +1,291 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_rand_private
+#define _rt_rand_private
+
+//****************************************************************************
+//
+// Private header for RT_RAND.C
+//
+//****************************************************************************
+
+#define SIZE_OF_RANDOM_TABLE   2048
+
+static const unsigned char RandomTable[ SIZE_OF_RANDOM_TABLE ] =
+{
+    107,   65,  179,   81,  212,    1,   34,  230,
+    167,  142,   82,   27,   62,   88,  140,  119,
+    222,  252,  254,  160,   26,   33,   30,  234,
+    162,  216,  126,   42,   20,  108,  245,  150,
+    167,  145,  215,  226,  153,  184,  251,  141,
+    116,  225,  201,  114,  111,   92,  223,  185,
+    199,  160,  244,  190,  113,   77,  217,  239,
+    15,  239,  129,  243,   21,  242,  202,  183,
+    49,  151,   38,   38,  147,  179,  234,  130,
+    138,  110,  228,  118,   93,   81,  253,   98,
+    246,   44,   75,  161,  189,   86,   85,  204,
+    169,   95,  199,  178,  186,  123,  200,  250,
+    118,  242,   86,   48,    7,  205,   71,  132,
+    185,  214,  192,   68,  191,  236,  175,  197,
+    199,  177,  163,   57,  220,  139,  133,  182,
+    91,  196,  246,   29,  177,   82,  184,  226,
+    209,  151,  206,  250,  195,  119,  193,  235,
+    144,  146,   58,   61,  245,   83,  204,  214,
+    249,  164,  212,  172,   90,  199,  242,  182,
+    228,  159,  127,   37,  209,  165,   89,  122,
+    87,  254,  222,   43,  148,  205,  155,  230,
+    74,  127,  238,  181,  154,  170,  232,   47,
+    105,   31,   96,  166,  208,    5,  201,   73,
+    244,   67,   55,  168,   84,  221,  251,   85,
+    44,  198,    8,   35,  229,  122,  229,   80,
+    137,   28,  202,  135,  211,   69,  100,  250,
+    224,  156,   75,  128,  176,   53,  207,  157,
+    241,  216,  210,  124,  163,  248,  223,  174,
+    241,  235,   97,  120,   25,    3,  218,  102,
+    143,  187,  202,  116,  209,  253,  227,  151,
+    203,  254,  223,   65,  146,  255,  231,  237,
+    162,  187,  194,   90,  198,   81,  219,   94,
+    70,  158,  106,  175,   81,  239,  181,   79,
+    62,  184,   21,   30,   98,  245,  233,    8,
+    57,   54,  133,   95,   43,  125,  161,  109,
+    167,  130,   32,   46,   72,    3,   42,   34,
+    147,  139,   19,  122,   49,   23,  253,  192,
+    231,  116,  165,    8,   15,   16,  223,  140,
+    29,  136,    2,  114,  248,  219,  214,  168,
+    36,  241,  210,   63,  230,   42,  197,  100,
+    134,  159,  179,  149,   17,   96,  152,   45,
+    93,  151,   26,  202,   35,   58,  189,  220,
+    74,  173,  250,   76,   57,   52,   55,   14,
+    205,   80,  213,  190,   14,  108,   60,   89,
+    236,   41,   53,   59,  249,  237,   88,  217,
+    129,  252,  169,  123,   87,   23,   91,   79,
+    36,  164,   89,   24,  102,  111,  104,  115,
+    116,  221,  212,   82,  166,   16,  244,   18,
+    68,   73,   64,  194,   82,  115,  121,  216,
+    133,   47,   85,  124,  242,  144,    1,   65,
+    0,   75,   91,   83,  137,  183,  132,   15,
+    66,  227,   67,   98,  186,  100,  208,  150,
+    74,   61,   69,  130,  120,   56,   39,   21,
+    44,  166,  180,  145,   97,  101,   68,   19,
+    243,  162,  222,  228,    9,  160,  185,   10,
+    168,   64,  109,  198,  113,   75,   48,   52,
+    119,  163,  176,  201,   12,  246,   20,   92,
+    31,  175,   33,    4,   70,  169,  218,   86,
+    240,  127,    7,   38,  102,   94,  112,   90,
+    114,   63,  139,  119,   45,    5,  183,  224,
+    155,   13,  141,   90,   93,  177,  118,   67,
+    211,  117,   58,  158,  135,   83,  236,  194,
+    72,   59,  131,   40,  196,  232,  247,  132,
+    18,   73,   37,  207,   50,  187,   32,  174,
+    13,   34,  135,   39,   46,  192,   51,  203,
+    216,    3,  188,   99,  245,  112,   61,  206,
+    127,  118,  136,  186,  153,  148,  140,  106,
+    55,  201,   19,    9,   27,   97,   84,   24,
+    48,  227,  108,  202,    5,  190,    6,  235,
+    160,  146,  123,  222,  212,  147,   27,   28,
+    50,  226,  200,  221,  180,  244,   34,  146,
+    41,  104,   37,  217,   10,  238,   52,  198,
+    4,   29,  126,   16,   45,  124,   64,   25,
+    40,   20,  138,  225,   71,  247,  128,   62,
+    62,  178,   31,  251,  197,  215,  226,  193,
+    28,   25,   82,   15,   21,   43,   30,   86,
+    50,   99,  199,  191,   80,  171,  250,    4,
+    149,   61,  163,  128,  143,   95,   76,   56,
+    14,  109,   54,   84,  137,   43,   77,  255,
+    204,  151,  129,    8,   20,   26,  193,   38,
+    205,  125,  203,   22,   78,   47,  101,   37,
+    121,  113,  141,   36,   33,   23,  131,   55,
+    78,   96,  123,  228,   69,  213,   51,  147,
+    195,  195,   85,   54,  225,   65,  143,   13,
+    152,   60,  110,   29,  146,  179,  164,   17,
+    96,   67,  156,    7,    3,   92,   26,  104,
+    157,  220,  211,  154,  103,    2,  174,  136,
+    83,  229,   18,  116,   66,   87,    0,   74,
+    98,   58,   75,  162,  254,  177,   89,  173,
+    169,  107,   12,   90,   71,  193,   53,  255,
+    138,    2,  233,  163,   11,  138,  183,  209,
+    119,  210,  249,  112,  113,   30,  185,  180,
+    11,  171,  164,   77,    5,   99,   35,  218,
+    11,  159,  221,  148,  170,  137,  129,  188,
+    231,  172,  191,  135,  176,   33,  189,   68,
+    190,  152,    7,  220,  246,  203,  181,   63,
+    199,   91,  251,  208,  217,   39,  170,  111,
+    182,  209,  216,  247,  240,  165,  153,  118,
+    238,  233,  204,   12,  126,  105,  168,  234,
+    38,  184,  132,  110,  145,  227,  165,   92,
+    241,   24,  251,  231,  213,  126,  240,  214,
+    31,   11,  223,   46,    0,   35,  218,  242,
+    211,  191,   48,  110,  253,   94,  161,  139,
+    42,  148,  198,  246,  239,  107,   57,    5,
+    117,  252,    9,   12,   73,   77,   58,  167,
+    6,  142,   32,   34,   72,   31,  243,  170,
+    0,   93,  182,   56,  254,  158,  250,   23,
+    77,   81,   45,   69,  142,  237,  225,   44,
+    232,  142,  209,  115,   61,   38,  224,   70,
+    53,   82,   10,  229,  214,  224,  101,   42,
+    100,  121,  133,   85,   67,  150,  116,   91,
+    79,   79,  235,   22,    1,  244,   16,  101,
+    88,   25,   43,  242,   53,  106,  128,   40,
+    18,    2,  196,   22,   47,   96,  130,  249,
+    49,  117,  178,  171,  132,  189,   95,   66,
+    153,  200,   71,   71,  215,  113,  102,  131,
+    172,  235,  192,  204,  107,  127,   60,   52,
+    254,   84,   20,   27,  107,   44,   72,  149,
+    230,   87,   64,  144,  140,  186,  154,   49,
+    76,  156,  162,  219,    9,  146,   41,   80,
+    59,  142,  147,  184,  115,  158,  103,  140,
+    8,  234,  157,   17,  112,   22,  163,  187,
+    47,  178,  207,   63,  125,  202,  156,   30,
+    97,  193,  171,  173,  204,   28,    4,  195,
+    109,  211,  105,  103,  179,  221,  203,  138,
+    139,  172,   14,   44,  119,  150,  185,  180,
+    205,  255,  152,   94,  205,  173,   40,  134,
+    13,   65,  194,  196,   68,  124,   26,  134,
+    85,  228,   50,  216,  159,  254,  237,  206,
+    103,   69,   90,  187,  182,  183,    2,  114,
+    3,  201,    1,  129,  212,  232,   81,   33,
+    56,  182,  133,  176,   19,    6,  144,   84,
+    145,   24,  243,  234,   35,   25,   89,  150,
+    54,  143,  207,  104,  248,  102,   41,  253,
+    46,   44,  197,  208,  200,   52,  219,  238,
+    223,  241,   60,  230,  196,   42,   88,   51,
+    170,   25,   40,  114,   39,   45,   57,   29,
+    186,   54,   36,  167,   51,  249,  194,  108,
+    250,  199,   67,  212,  123,  151,   92,   32,
+    46,   12,  248,  165,  223,   24,  143,  189,
+    120,   57,   38,  222,  169,   17,  188,   27,
+    209,  176,  215,  108,  177,   96,   50,  154,
+    41,   15,   32,  181,   99,  120,   73,  225,
+    49,  200,   43,  177,   72,  202,   97,   92,
+    240,  110,  252,   21,   28,  192,   70,  128,
+    85,   60,  127,   63,  235,  100,  155,   65,
+    241,  119,   34,   80,   75,  117,  148,  102,
+    15,   90,  121,  206,  104,  164,  132,   98,
+    36,  108,  214,    0,   84,   94,  107,  154,
+    14,   26,   23,   93,  195,  224,  162,  171,
+    245,   76,  125,  158,  120,   66,   80,  130,
+    183,  120,  179,  118,   31,  176,  106,  184,
+    164,  111,   59,  253,  118,   62,  114,  215,
+    156,  161,  127,  210,  112,  122,  204,   86,
+    29,   69,  187,  218,  233,   47,  188,   91,
+    105,  153,  236,  116,  135,   19,   83,  175,
+    88,  166,  156,  238,  245,  227,  248,  161,
+    10,  180,   22,  230,  157,  205,    6,   37,
+    3,  234,  155,   49,  239,  229,  122,  223,
+    234,  206,   82,  135,  190,   77,  130,  197,
+    144,  226,  123,  181,  143,  208,  169,    8,
+    1,  174,   97,  177,  232,  201,  210,  193,
+    192,   62,  211,   28,  252,   19,  189,  229,
+    191,  246,    7,  202,   35,   20,   28,   30,
+    70,  221,   55,  159,  237,   10,   15,  134,
+    124,  103,   73,  172,   26,  201,   13,  117,
+    35,  131,  136,   66,   33,  245,  159,  207,
+    225,  147,   18,  248,  126,  131,   33,  153,
+    101,   60,  186,  216,  250,   11,   30,   50,
+    57,   58,  151,  178,  181,  227,  128,  253,
+    10,    5,  224,   48,  160,   34,    7,  111,
+    124,   27,  160,   75,  137,   17,   53,   39,
+    243,  236,   39,   81,  217,  122,   79,   32,
+    13,  115,  191,  167,  137,   87,  228,   91,
+    86,   78,   18,   22,   40,   76,   94,  129,
+    119,   87,   63,  197,  203,   21,  218,  185,
+    166,   49,  161,  213,   38,  111,  209,  154,
+    43,  152,  134,  132,    4,  133,  108,   83,
+    145,   41,   97,   74,  251,  173,   42,  213,
+    46,  118,   73,   68,   21,  244,  106,  158,
+    11,   90,  252,  140,   44,  157,  194,   66,
+    229,   58,  215,  251,  144,  125,  146,  172,
+    165,  136,  105,  102,  173,   95,  150,  169,
+    78,  230,  111,  160,  196,  112,  120,  231,
+    168,  152,  149,  174,  128,  232,  194,  122,
+    3,   74,  231,  105,   12,  239,  180,  239,
+    89,  235,   95,  157,  149,  187,    6,  203,
+    188,   71,  110,    8,  126,  242,  188,  249,
+    71,  123,  162,   93,   59,   65,   16,  222,
+    192,   24,   27,  142,  168,  114,   89,  220,
+    226,  182,  207,   94,  195,  207,  174,  228,
+    142,  130,  115,  175,  154,  106,  206,   48,
+    185,  147,  155,  224,  239,   64,   88,   83,
+    54,  247,  113,  248,  137,   96,    5,  110,
+    240,   51,    1,  208,  166,  200,  233,  167,
+    230,   14,   20,  198,   36,   13,    0,  220,
+    165,  104,   85,  122,    1,  255,  212,  161,
+    190,   37,   86,  226,  195,  105,   78,  244,
+    236,  168,   48,  211,  121,  216,   25,  144,
+    16,  237,    7,   75,   12,   99,   56,  109,
+    218,   87,   35,  204,  155,   61,  191,   41,
+    61,   57,  121,  236,   62,   22,  187,   95,
+    92,   69,  210,  163,  205,  214,   34,   84,
+    73,  184,  109,  124,  231,  103,  217,  241,
+    77,  175,  183,  232,  198,  164,   14,  125,
+    103,  197,  249,  241,  176,   59,   48,   50,
+    25,  222,  134,  199,  252,  196,   23,   19,
+    78,    0,   59,  120,   91,  121,  117,  228,
+    52,   68,  113,  127,  141,   67,   65,  130,
+    132,  243,  160,  138,  138,  116,   10,   98,
+    170,   70,  246,  206,  219,   28,   94,  226,
+    29,   58,  255,   31,  141,   82,  134,  152,
+    251,   84,   52,   23,  154,  139,   74,   55,
+    47,  198,  167,  162,    4,   16,  220,   53,
+    37,  158,  135,  136,  190,   86,  151,  178,
+    238,  161,   88,  171,  148,  169,  137,  212,
+    181,  146,  189,   70,   49,   79,  142,  131,
+    195,  126,  149,  156,   93,   55,  164,  174,
+    87,  243,   66,   92,  207,    9,  126,  123,
+    40,   51,  133,  143,    9,   55,  193,  173,
+    56,   64,  210,  159,    6,  178,  145,  153,
+    115,  215,  185,  238,  101,  210,   98,  157,
+    95,  171,  235,  217,  240,  232,  107,   53,
+    54,  211,  111,  236,  100,   37,  147,   64,
+    60,  215,  174,  136,  128,   98,   79,  234,
+    145,   76,  197,  165,  191,  141,  114,  109,
+    148,  214,   93,   12,  163,  125,  222,   96,
+    71,  220,    8,  225,  200,   14,  139,  166,
+    155,    9,  237,    9,  172,    6,  229,  179,
+    247,   76,   24,  213,   26,  248,   56,  247,
+    106,  221,   63,   20,  206,  231,  168,  196,
+    208,   36,   31,  175,  178,  255,  124,  156,
+    129,  186,   45,  201,    7,  112,  189,   68,
+    225,   64,  150,   74,    2,  218,   62,  159,
+    4,   11,  213,   40,   23,   15,   67,   52,
+    182,  203,  246,  194,   72,   33,   89,  104,
+    16,  131,   60,  150,  243,   21,   59,  175,
+    219,  149,   56,  224,   32,  105,  153,   99,
+    80,  148,  107,   99,  108,   43,  106,   41,
+    32,  244,    4,  186,  253,   27,  233,  104,
+    245,    5,    2,  252,  170,    2,  101,   39,
+    17,  166,  221,   11,  227,  129,  103,   45,
+    144,   79,   17,  139,   70,  237,  176,    6,
+    76,  134,   54,   30,   69,   13,  100,  149,
+    141,  227,  255,   22,  179,   61,   88,   97,
+    121,   29,   24,   77,  170,  190,  242,  109,
+    152,   47,   81,  140,   45,   46,  249,   78,
+    180,  143,  102,   19,  208,  177,   72,   72,
+    247,   51,  115,    3,  141,  117,   39,  188,
+    180,  171,   83,    1,    0,   51,  100,  112,
+    172,   18,  219,  136,  155,  125,  200,  131,
+    157,  217,   78,   63,  213,  238,  193,  173,
+    145,   46,  101,  158,   42,  140,  110,   66,
+    183,  181,  233,  188,   10,  133,   36,  135,
+    17,  254,  138,  233,  117,  240,  184,   80,
+    113,   18,   99,  219,  240,   50,  192,  247
+};
+
+#endif
--- /dev/null
+++ b/rott/_rt_scal.h
@@ -1,0 +1,25 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_scale_private
+#define _rt_scale_private
+
+#define PLAYERHEIGHT (260<<HEIGHTFRACTION)
+
+#endif
--- /dev/null
+++ b/rott/_rt_soun.h
@@ -1,0 +1,114 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_sound_private
+#define _rt_sound_private
+
+#define SOUNDTYPES 2
+
+typedef struct
+{
+    int     snds[SOUNDTYPES];
+    byte    flags;
+    byte    priority;
+    byte    count;
+    int     prevhandle;
+    int     prevdistance;
+} sound_t;
+
+#define SD_OVERWRITE  0x01
+#define SD_WRITE      0x02
+#define SD_LOOP       0x04
+#define SD_PITCHSHIFTOFF 0x08
+#define SD_PLAYONCE      0x10
+
+enum {
+    sd_prio0=17,
+    sd_prio1=16,
+    sd_prio2=15,
+    sd_prio3=14,
+    sd_prio4=13,
+    sd_prio5=12,
+    sd_prio6=11,
+    sd_prio7=10,
+    sd_prio8=9,
+    sd_prio9=8,
+    sd_prio10=7,
+    sd_prio11=6,
+    sd_prio12=5,
+    sd_prio13=4,
+    sd_prio14=3,
+    sd_prio15=2,
+    sd_prio16=1
+} ;
+
+#define SD_PRIOSECRET sd_prio1
+#define SD_PRIOREMOTE sd_prio1
+#define SD_PRIOPHURT  sd_prio1
+#define SD_PRIOGAME   sd_prio2
+#define SD_PRIOBOSS   sd_prio2
+#define SD_PRIOGODDOG sd_prio2
+#define SD_PRIOEXPL   sd_prio3
+#define SD_PRIOASNEAK sd_prio3
+#define SD_PRIOADEATH sd_prio3
+#define SD_PRIOPMISS  sd_prio4
+#define SD_PRIOPGUNS  sd_prio5
+#define SD_PRIOAFIRE  sd_prio6
+#define SD_PRIOPMP40  sd_prio7
+#define SD_PRIOAHURT  sd_prio8
+#define SD_PRIOGLASS  sd_prio9
+#define SD_PRIOPSNDS  sd_prio11
+#define SD_PRIOPCAUSD sd_prio12
+#define SD_PRIOAGREET sd_prio13
+#define SD_PRIOENVRON sd_prio14
+#define SD_PRIOQUIT   sd_prio15
+#define SD_PRIOMENU   sd_prio16
+
+#define SD_DISTANCESHIFT 12
+
+#define USEADLIB 255
+
+#define SD_RANDOMSHIFT 1
+
+#define PitchOffset()  ((RandomNumber("Pitch Offset",0)-128)>>SD_RANDOMSHIFT)
+
+#define SoundOffset(x) (sounds[x].snds[soundtype])
+
+#define GUSMIDIINIFILE ("gusmidi.ini")
+
+
+typedef enum {
+    loop_yes,
+    loop_no
+} looptypes;
+
+
+typedef struct
+{
+    byte    loopflag;
+    byte    songtype;
+    char    lumpname[9];
+    char    songname[40];
+} song_t;
+
+int SD_PlayIt ( int sndnum, int angle, int distance, int pitch );
+boolean SD_SoundOkay ( int sndnum );
+
+#endif
+
--- /dev/null
+++ b/rott/_rt_spba.h
@@ -1,0 +1,27 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_spba_private
+#define _rt_spba_private
+
+#define SGN(x)                 (x>0 ? 1 : -1)
+
+#define NUMSPACEBALLBUTTONS 6
+
+#endif
--- /dev/null
+++ b/rott/_rt_stat.h
@@ -1,0 +1,58 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_stat_private
+#define _rt_stat_private
+
+void        AddStatic(statobj_t*);
+void        AddAnimStatic(statobj_t*);
+void        PreCacheStaticSounds(int);
+
+#define SOLIDCOLORTICTIME   1
+#define SOLIDCOLORINCREMENT 1
+#define MAXFIRECOLOR      248
+#define INITIALFIRECOLOR  246
+#define IsLight(x,y)          ( (x>=0) && (x<=127) && (y>=0) && (y<=127) &&   \
+										  (sprites[x][y]) && (sprites[x][y]->flags & FL_LIGHT) )
+
+typedef struct
+{
+    int  tictime,
+         numanims;
+    char firstlump[9];
+} awallinfo_t;
+
+
+typedef struct sas
+{
+    int          x,y,z;
+    int          flags;
+    signed char  ticcount;
+    int          hitpoints;
+    short int    shapenum;
+    signed char  ammo;
+    signed char  count;
+    signed char  itemnumber;
+    short int    areanumber;
+    short int    whichstat;
+    byte         numanims;
+    int          linked_to;
+} saved_stat_type;
+
+#endif
--- /dev/null
+++ b/rott/_rt_str.h
@@ -1,0 +1,44 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//******************************************************************************
+//
+// Private header for RT_STR.C
+//
+//******************************************************************************
+
+#ifndef _rt_str_private
+#define _rt_str_private
+
+//******************************************************************************
+//
+// PROTOTYPES
+//
+//******************************************************************************
+
+void VWB_DrawPropString  (const char *string);
+void VW_MeasurePropString (const char *string, int *width, int *height );
+
+//void (*USL_MeasureString)(const char *, int *, int *, font_t *) = VW_MeasurePropString,
+//     (*USL_DrawString)(const char *) = VWB_DrawPropString;
+void (*USL_MeasureString)(const char *, int *, int *, font_t *) = (void (*)(const char *, int *, int *, font_t *))VW_MeasurePropString,
+(*USL_DrawString)(const char *) = VWB_DrawPropString;
+
+
+#endif
--- /dev/null
+++ b/rott/_rt_swft.h
@@ -1,0 +1,109 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_swift_private
+#define _rt_swift_private
+
+#ifdef DOS
+//****************************************************************************
+//
+// Private header for RT_SWIFT.C.
+//
+//****************************************************************************
+
+
+
+//****************************************************************************
+//
+// DEFINES
+//
+//****************************************************************************
+
+#define DPMI_INT     0x31
+#define MOUSE_INT    0x33
+#define DOSMEMSIZE   64                // enough for any SWIFT structure
+
+//
+// device type codes, returned in deviceType field (SWIFT_StaticData)
+//
+#define SWIFT_DEV_NONE		0
+#define SWIFT_DEV_CYBERMAN	1
+
+//
+// Dynamic device data
+//
+#define SDD_EXTERNAL_POWER_CONNECTED	1
+#define SDD_EXTERNAL_POWER_TOO_HIGH	   2
+
+#define AX(r) ((r).x.eax)
+#define BX(r) ((r).x.ebx)
+#define CX(r) ((r).x.ecx)
+#define DX(r) ((r).x.edx)
+#define SI(r) ((r).x.esi)
+#define DI(r) ((r).x.edi)
+
+
+//****************************************************************************
+//
+// TYPEDEFS
+//
+//****************************************************************************
+
+// Active flag:
+static int fActive;                       //  TRUE after successful init
+//  and before termination
+static int nAttached = SWIFT_DEV_NONE;    // type of SWIFT device
+
+union REGS regs;
+struct SREGS sregs;
+
+short selector;                           // selector of DOS memory block
+short segment;                            // segment of DOS memory block
+void far *pdosmem;                        // pointer to DOS memory block
+
+// DPMI real mode interrupt structure
+static struct rminfo
+{
+    long di;
+    long si;
+    long bp;
+    long reserved_by_system;
+    long bx;
+    long dx;
+    long cx;
+    long ax;
+    short flags;
+    short es, ds, fs, gs, ip, cs, sp, ss;
+} RMI;
+
+
+//****************************************************************************
+//
+// PROTOTYPES
+//
+//****************************************************************************
+
+void MouseInt (struct rminfo *prmi);
+static void far *allocDOS (unsigned nbytes, short *pseg, short *psel);
+static void freeDOS (short sel);
+
+#endif
+
+#endif
+
--- /dev/null
+++ b/rott/_rt_ted.h
@@ -1,0 +1,90 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_ted_private
+#define _rt_ted_private
+
+#define  MAXPRECACHE    3500
+
+#include "rt_actor.h"
+#include "develop.h"
+
+#define SHAREWARE_TAG     0x4d4b
+#define REGISTERED_TAG    0x4344
+#define RTL_VERSION       ( 0x0101 )
+#define COMMBAT_SIGNATURE ( "RTC" )
+#define NORMAL_SIGNATURE  ( "RTL" )
+#define RTL_HEADER_OFFSET 8
+
+typedef struct
+{
+    int  lump;
+    int  cachelevel;
+    int  type; // To make precaching possible on big endian machines
+} cachetype;
+
+//========================================
+
+typedef struct
+{
+    short   RLEWtag;
+    int             headeroffsets[100];
+    byte            tileinfo[1];
+} mapfiletype;
+
+
+typedef struct
+{
+    int   planestart[3];
+    word  planelength[3];
+    word  width,height;
+    char            name[16];
+} maptype;
+
+#define ActorIsPushWall(xx,yy)   ((actorat[xx][yy])&&(((objtype *)actorat[xx][yy])->which==PWALL) )
+#define ActorIsWall(xx,yy)   ((actorat[xx][yy])&&(((objtype *)actorat[xx][yy])->which==WALL) )
+#define ActorIsSpring(xx,yy)   ((actorat[xx][yy])&&(((objtype *)actorat[xx][yy])->obclass==springobj) )
+#define StaticUndefined(xx,yy)   ((sprites[xx][yy])&&(((statobj_t *)sprites[xx][yy])->z<-64) )
+
+#define  PRECACHEASTRINGX 141
+#define  PRECACHEASTRINGY 8
+
+#define  PRECACHEESTRINGX 16
+#define  PRECACHEESTRINGY 8
+
+#define  PRECACHESTRINGX 16
+#define  PRECACHESTRINGY 144
+
+#define  PRECACHEBARX 28
+#define  PRECACHEBARY 178
+
+#define  PRECACHELED1X 9
+#define  PRECACHELED1Y 8
+
+#define  PRECACHELED2X 9
+#define  PRECACHELED2Y 12
+
+#define  MAXLEDS 57
+
+#define  MAXSILLYSTRINGS 32
+
+
+
+
+#endif
--- /dev/null
+++ b/rott/_rt_util.h
@@ -1,0 +1,47 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_util_private
+#define _rt_util_private
+
+#ifdef DOS
+#define PEL_WRITE_ADR   0x3c8
+#define PEL_READ_ADR    0x3c7
+#define PEL_DATA        0x3c9
+#define PEL_MASK        0x3c6
+#endif
+
+#define ERRORROW        2
+#define ERRORCOL        11
+
+#define ERRORFILE       ("rotterr.txt")
+#define SOFTERRORFILE   ("error.txt")
+#define DEBUGFILE       ("rott.dbg")
+#define MAPDEBUGFILE    ("mapinfo.txt")
+
+#define SGN(x)          ((x>0) ? (1) : ((x==0) ? (0) : (-1)))
+
+#define SLASHES         ('\\')
+#define MAXCHARS        8
+
+#define WeightR  3
+#define WeightG  5
+#define WeightB  2
+
+#endif
--- /dev/null
+++ b/rott/_rt_vid.h
@@ -1,0 +1,45 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_vid_private
+#define _rt_vid_private
+
+//******************************************************************************
+//
+// Private header for RT_VID.C
+//
+//******************************************************************************
+
+
+//******************************************************************************
+//
+// DEFINES
+//
+//******************************************************************************
+
+#define PIXTOBLOCK         4
+
+#define VW_Hlin(x,z,y,c)   VL_Hlin(x,y,(z)-(x)+1,c)
+#define VW_Vlin(y,z,x,c)   VL_Vlin(x,y,(z)-(y)+1,c)
+
+#define VW_THlin(x,z,y,up)    VL_THlin(x,y,(z)-(x)+1, up)
+#define VW_TVlin(y,z,x,up)    VL_TVlin(x,y,(z)-(y)+1, up)
+
+
+#endif
--- /dev/null
+++ b/rott/_w_wad.h
@@ -1,0 +1,76 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _w_wad_private
+#define _w_wad_private
+
+#include "develop.h"
+
+#define CHECKPERIOD 20
+
+
+#if ( SHAREWARE == 1 )
+
+#if ( DELUXE == 1)
+#define WADCHECKSUM (54748)
+#elif ( LOWCOST == 1)
+#define WADCHECKSUM (12185)
+#else
+#ifdef DOS
+#define WADCHECKSUM (45677)
+#else
+#define WADCHECKSUM (20567)
+#endif
+#endif
+
+#else
+
+#define WADCHECKSUM (24222)
+
+#endif
+
+//===============
+//   TYPES
+//===============
+
+
+typedef struct
+{
+    char            name[8];
+    int             handle,position,size;
+    int             byteswapped;
+} lumpinfo_t;
+
+
+typedef struct
+{
+    char            identification[4];              // should be IWAD
+    int             numlumps;
+    int             infotableofs;
+} wadinfo_t;
+
+
+typedef struct
+{
+    int             filepos;
+    int             size;
+    char            name[8];
+} filelump_t;
+
+#endif
--- /dev/null
+++ b/rott/_z_zone.h
@@ -1,0 +1,57 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _z_zone_private
+#define _z_zone_private
+
+#include "develop.h"
+
+#define MINFRAGMENT     64
+#define DPMI_INT  0x31
+#define MAXMEMORYSIZE   9000000
+
+#define LEVELZONESIZE   250000
+
+// memory storage data types
+
+#define MEMORYPRETAG   (0x1a2b3c4d)
+#define MEMORYPOSTTAG  (0x9f8e7d6b)
+
+typedef struct memblock_s
+{
+#if (MEMORYCORRUPTIONTEST==1)
+    int     pretag;
+#endif
+    int     size;   // including the header and possibly tiny fragments
+    void    **user; // NULL if a free block
+    int     tag;    // purgelevel
+    struct memblock_s   *next, *prev;
+#if (MEMORYCORRUPTIONTEST==1)
+    int     posttag;
+#endif
+} memblock_t;
+
+typedef struct
+{
+    int     size;          // total bytes malloced, including header
+    memblock_t  blocklist; // start / end cap for linked list
+    memblock_t  *rover;
+} memzone_t;
+
+#endif
--- /dev/null
+++ b/rott/audiolib/Makefile
@@ -1,0 +1,31 @@
+AUDIOLIB ?= audiolib.a
+
+AR ?= ar
+CC ?= gcc
+RANLIB ?= ranlib
+
+ARFLAGS ?= rcT
+
+CFLAGS ?= -g -O2
+CFLAGS += -Wall
+CFLAGS += $(shell sdl-config --cflags)
+
+OBJS :=
+OBJS += fx_man.o
+OBJS += dsl.o
+OBJS += ll_man.o
+OBJS += multivoc.o
+OBJS += mv_mix.o
+OBJS += mvreverb.o
+OBJS += nodpmi.o
+OBJS += pitch.o
+OBJS += user.o
+OBJS += usrhooks.o
+
+$(AUDIOLIB): $(OBJS)
+	$(RM) $@
+	$(AR) $(ARFLAGS) $@ $^
+	$(RANLIB) $@
+
+clean:
+	$(RM) $(AUDIOLIB) $(OBJS)
--- /dev/null
+++ b/rott/audiolib/Makefile.am
@@ -1,0 +1,13 @@
+noinst_LIBRARIES = libaudiolib.a
+libaudiolib_a_SOURCES = \
+	dsl.c \
+	fx_man.c \
+	ll_man.c \
+	multivoc.c \
+	mv_mix.c \
+	mvreverb.c \
+	nodpmi.c \
+	pitch.c \
+	user.c \
+	usrhooks.c
+libaudiolib_a_CFLAGS = @SDL_CFLAGS@
--- /dev/null
+++ b/rott/audiolib/Makefile_old
@@ -1,0 +1,30 @@
+AUDIOLIB ?= audiolib.a
+
+AR ?= ar
+CC ?= gcc
+RANLIB ?= ranlib
+
+ARFLAGS ?= rcT
+CFLAGS ?= -g -O2
+CFLAGS += -Wall
+CFLAGS += $(shell sdl-config --cflags)
+
+OBJS :=
+OBJS += fx_man.o
+OBJS += dsl.o
+OBJS += ll_man.o
+OBJS += multivoc.o
+OBJS += mv_mix.o
+OBJS += mvreverb.o
+OBJS += nodpmi.o
+OBJS += pitch.o
+OBJS += user.o
+OBJS += usrhooks.o
+
+$(AUDIOLIB): $(OBJS)
+	$(RM) $@
+	$(AR) $(ARFLAGS) $@ $^
+	$(RANLIB) $@
+
+clean:
+	$(RM) $(AUDIOLIB) $(OBJS)
--- /dev/null
+++ b/rott/audiolib/_al_midi.h
@@ -1,0 +1,174 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef ___AL_MIDI_H
+#define ___AL_MIDI_H
+
+#define NO_ADLIB_DETECTION    "NOAL"
+
+#define STEREO_DETUNE 5
+
+#define lobyte( num )   ( ( unsigned )*( ( char * )&( num ) ) )
+#define hibyte( num )   ( ( unsigned )*( ( ( char * )&( num ) ) + 1 ) )
+
+#define AL_VoiceNotFound -1
+
+#define  alFreqH     0xb0
+#define  alEffects   0xbd
+
+/* Number of slots for the voices on the chip */
+#define NumChipSlots 18
+
+#define NUM_VOICES      9
+#define NUM_CHANNELS    16
+
+#define NOTE_ON         0x2000  /* Used to turn note on or toggle note */
+#define NOTE_OFF        0x0000
+
+#define MAX_VELOCITY   0x7f
+#define MAX_OCTAVE     7
+#define MAX_NOTE       ( MAX_OCTAVE * 12 + 11 )
+#define FINETUNE_MAX   31
+#define FINETUNE_RANGE ( FINETUNE_MAX + 1 )
+
+#define PITCHBEND_CENTER 1638400
+
+#define note_off             0x80
+#define note_on              0x90
+#define poly_aftertouch      0xa0
+#define control_change       0xb0
+#define program_chng         0xc0
+#define channel_aftertouch   0xd0
+#define pitch_wheel          0xe0
+
+#define MIDI_VOLUME          7
+#define MIDI_PAN             10
+#define MIDI_DETUNE          94
+#define MIDI_ALL_NOTES_OFF   0x7B
+#define MIDI_RESET_ALL_CONTROLLERS 0x79
+#define MIDI_RPN_MSB               100
+#define MIDI_RPN_LSB               101
+#define MIDI_DATAENTRY_MSB         6
+#define MIDI_DATAENTRY_LSB         38
+#define MIDI_PITCHBEND_RPN         0
+
+enum cromatic_scale
+   {
+   C       = 0x157,
+   C_SHARP = 0x16B,
+   D_FLAT  = 0x16B,
+   D       = 0x181,
+   D_SHARP = 0x198,
+   E_FLAT  = 0x198,
+   E       = 0x1B0,
+   F_FLAT  = 0x1B0,
+   E_SHARP = 0x1CA,
+   F       = 0x1CA,
+   F_SHARP = 0x1E5,
+   G_FLAT  = 0x1E5,
+   G       = 0x202,
+   G_SHARP = 0x220,
+   A_FLAT  = 0x220,
+   A       = 0x241,
+   A_SHARP = 0x263,
+   B_FLAT  = 0x263,
+   B       = 0x287,
+   C_FLAT  = 0x287,
+   B_SHARP = 0x2AE,
+   };
+
+/* Definition of octave information to be ORed onto F-Number */
+
+enum octaves
+   {
+   OCTAVE_0 = 0x0000,
+   OCTAVE_1 = 0x0400,
+   OCTAVE_2 = 0x0800,
+   OCTAVE_3 = 0x0C00,
+   OCTAVE_4 = 0x1000,
+   OCTAVE_5 = 0x1400,
+   OCTAVE_6 = 0x1800,
+   OCTAVE_7 = 0x1C00
+   };
+
+typedef struct VOICE
+   {
+   struct VOICE *next;
+   struct VOICE *prev;
+
+   unsigned num;
+   unsigned key;
+   unsigned velocity;
+   unsigned channel;
+   unsigned pitchleft;
+   unsigned pitchright;
+   int      timbre;
+   int      port;
+   unsigned status;
+   } VOICE;
+
+typedef struct
+   {
+   VOICE *start;
+   VOICE *end;
+   } VOICELIST;
+
+typedef struct
+   {
+   VOICELIST Voices;
+   int       Timbre;
+   int       Pitchbend;
+   int       KeyOffset;
+   unsigned  KeyDetune;
+   unsigned  Volume;
+   unsigned  EffectiveVolume;
+   int       Pan;
+   int       Detune;
+   unsigned  RPN;
+   short     PitchBendRange;
+   short     PitchBendSemiTones;
+   short     PitchBendHundreds;
+   } CHANNEL;
+
+typedef struct
+   {
+   unsigned char SAVEK[ 2 ];
+   unsigned char Level[ 2 ];
+   unsigned char Env1[ 2 ];
+   unsigned char Env2[ 2 ];
+   unsigned char Wave[ 2 ];
+   unsigned char Feedback;
+   signed   char Transpose;
+   signed   char Velocity;
+   } TIMBRE;
+
+extern TIMBRE ADLIB_TimbreBank[ 256 ];
+
+static void AL_ResetVoices( void );
+static void AL_CalcPitchInfo( void );
+static void AL_SetVoiceTimbre( int voice );
+static void AL_SetVoiceVolume( int voice );
+static int  AL_AllocVoice( void );
+static int  AL_GetVoice( int channel, int key );
+static void AL_SetVoicePitch( int voice );
+static void AL_SetChannelVolume( int channel, int volume );
+static void AL_SetChannelPan( int channel, int pan );
+static void AL_SetChannelDetune( int channel, int detune );
+
+#endif
--- /dev/null
+++ b/rott/audiolib/_blaster.h
@@ -1,0 +1,133 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: _BLASTER.H
+
+   author: James R. Dose
+   date:   February 4, 1994
+
+   Private header for for BLASTER.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef ___BLASTER_H
+#define ___BLASTER_H
+
+#define VALID   ( 1 == 1 )
+#define INVALID ( !VALID )
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+#define YES ( 1 == 1 )
+#define NO  ( !YES )
+
+#define lobyte( num )   ( ( int )*( ( char * )&( num ) ) )
+#define hibyte( num )   ( ( int )*( ( ( char * )&( num ) ) + 1 ) )
+
+#define BLASTER_MixerAddressPort  0x04
+#define BLASTER_MixerDataPort     0x05
+#define BLASTER_ResetPort         0x06
+#define BLASTER_ReadPort          0x0A
+#define BLASTER_WritePort         0x0C
+#define BLASTER_DataAvailablePort 0x0E
+#define BLASTER_Ready             0xAA
+#define BLASTER_16BitDMAAck       0x0F
+
+#define MIXER_DSP4xxISR_Ack       0x82
+#define MIXER_DSP4xxISR_Enable    0x83
+#define MIXER_MPU401_INT          0x4
+#define MIXER_16BITDMA_INT        0x2
+#define MIXER_8BITDMA_INT         0x1
+#define MIXER_DisableMPU401Interrupts 0xB
+#define MIXER_SBProOutputSetting  0x0E
+#define MIXER_SBProStereoFlag     0x02
+#define MIXER_SBProVoice          0x04
+#define MIXER_SBProMidi           0x26
+#define MIXER_SB16VoiceLeft       0x32
+#define MIXER_SB16VoiceRight      0x33
+#define MIXER_SB16MidiLeft        0x34
+#define MIXER_SB16MidiRight       0x35
+
+#define DSP_Version1xx            0x0100
+#define DSP_Version2xx            0x0200
+#define DSP_Version201            0x0201
+#define DSP_Version3xx            0x0300
+#define DSP_Version4xx            0x0400
+#define DSP_SB16Version           DSP_Version4xx
+
+#define DSP_MaxNormalRate         22000
+#define DSP_MaxHighSpeedRate      44000
+
+#define DSP_8BitAutoInitRecord        0x2c
+#define DSP_8BitHighSpeedAutoInitRecord 0x98
+#define DSP_Old8BitADC                0x24
+#define DSP_8BitAutoInitMode          0x1c
+#define DSP_8BitHighSpeedAutoInitMode 0x90
+#define DSP_SetBlockLength            0x48
+#define DSP_Old8BitDAC                0x14
+#define DSP_16BitDAC                  0xB6
+#define DSP_8BitDAC                   0xC6
+#define DSP_8BitADC                   0xCe
+#define DSP_SetTimeConstant           0x40
+#define DSP_Set_DA_Rate               0x41
+#define DSP_Set_AD_Rate               0x42
+#define DSP_Halt8bitTransfer          0xd0
+#define DSP_Continue8bitTransfer      0xd4
+#define DSP_Halt16bitTransfer         0xd5
+#define DSP_Continue16bitTransfer     0xd6
+#define DSP_SpeakerOn                 0xd1
+#define DSP_SpeakerOff                0xd3
+#define DSP_GetVersion                0xE1
+#define DSP_Reset                     0xFFFF
+
+#define DSP_SignedBit                 0x10
+#define DSP_StereoBit                 0x20
+
+#define DSP_UnsignedMonoData      0x00
+#define DSP_SignedMonoData        ( DSP_SignedBit )
+#define DSP_UnsignedStereoData    ( DSP_StereoBit )
+#define DSP_SignedStereoData      ( DSP_SignedBit | DSP_StereoBit )
+
+#define BlasterEnv_Address    'A'
+#define BlasterEnv_Interrupt  'I'
+#define BlasterEnv_8bitDma    'D'
+#define BlasterEnv_16bitDma   'H'
+#define BlasterEnv_Type       'T'
+#define BlasterEnv_Midi       'P'
+#define BlasterEnv_EmuAddress 'E'
+
+#define CalcTimeConstant( rate, samplesize ) \
+   ( ( 65536L - ( 256000000L / ( ( samplesize ) * ( rate ) ) ) ) >> 8 )
+
+#define CalcSamplingRate( tc ) \
+   ( 256000000L / ( 65536L - ( tc << 8 ) ) )
+
+typedef struct
+   {
+   int IsSupported;
+   int HasMixer;
+   int MaxMixMode;
+   int MinSamplingRate;
+   int MaxSamplingRate;
+   } CARD_CAPABILITY;
+
+#endif
--- /dev/null
+++ b/rott/audiolib/_guswave.h
@@ -1,0 +1,164 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   file:   _GUSWAVE.H
+
+   author: James R. Dose
+   date:   March 23, 1994
+
+   Private header for GUSWAVE.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef ___GUSWAVE_H
+#define ___GUSWAVE_H
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+#define LOADDS _loadds
+
+#define VOC_8BIT            0x0
+#define VOC_CT4_ADPCM       0x1
+#define VOC_CT3_ADPCM       0x2
+#define VOC_CT2_ADPCM       0x3
+#define VOC_16BIT           0x4
+#define VOC_ALAW            0x6
+#define VOC_MULAW           0x7
+#define VOC_CREATIVE_ADPCM  0x200
+
+#define MAX_BLOCK_LENGTH 0x8000
+
+#define GF1BSIZE   896L   /* size of buffer per wav on GUS */
+//#define GF1BSIZE   512L   /* size of buffer per wav on GUS */
+
+//#define VOICES     8      /* maximum amount of concurrent wav files */
+#define VOICES     2      /* maximum amount of concurrent wav files */
+#define MAX_VOICES 32     /* This should always be 32 */
+#define MAX_VOLUME 4095
+#define BUFFER     2048U  /* size of DMA buffer for patch loading */
+
+typedef enum
+   {
+   Raw,
+   VOC,
+   DemandFeed,
+   WAV
+   } wavedata;
+
+typedef enum
+   {
+   NoMoreData,
+   KeepPlaying,
+   SoundDone
+   } playbackstatus;
+
+
+typedef volatile struct VoiceNode
+   {
+   struct VoiceNode *next;
+   struct VoiceNode *prev;
+
+   wavedata      wavetype;
+   int           bits;
+   playbackstatus ( *GetSound )( struct VoiceNode *voice );
+
+   int num;
+
+   unsigned long  mem;           /* location in ultrasound memory */
+   int            Active;        /* this instance in use */
+   int            GF1voice;      /* handle to active voice */
+
+   char          *NextBlock;
+   char          *LoopStart;
+   char          *LoopEnd;
+   unsigned       LoopCount;
+   unsigned long  LoopSize;
+   unsigned long  BlockLength;
+
+   unsigned long  PitchScale;
+
+   unsigned char *sound;
+   unsigned long  length;
+   unsigned long  SamplingRate;
+   unsigned long  RateScale;
+   int            Playing;
+
+   int    handle;
+   int    priority;
+
+   void          ( *DemandFeed )( char **ptr, unsigned long *length );
+
+   unsigned long callbackval;
+
+   int    Volume;
+   int    Pan;
+   }
+VoiceNode;
+
+typedef struct
+   {
+   VoiceNode *start;
+   VoiceNode *end;
+   }
+voicelist;
+
+typedef volatile struct voicestatus
+   {
+   VoiceNode *Voice;
+   int playing;
+   }
+voicestatus;
+
+typedef struct
+   {
+   char          RIFF[ 4 ];
+   unsigned long file_size;
+   char          WAVE[ 4 ];
+   char          fmt[ 4 ];
+   unsigned long format_size;
+   } riff_header;
+
+typedef struct
+   {
+   unsigned short wFormatTag;
+   unsigned short nChannels;
+   unsigned long  nSamplesPerSec;
+   unsigned long  nAvgBytesPerSec;
+   unsigned short nBlockAlign;
+   unsigned short nBitsPerSample;
+   } format_header;
+
+typedef struct
+   {
+   unsigned char DATA[ 4 ];
+   unsigned long size;
+   } data_header;
+
+playbackstatus GUSWAVE_GetNextVOCBlock( VoiceNode *voice );
+VoiceNode *GUSWAVE_GetVoice( int handle );
+
+int GUSWAVE_Play( VoiceNode *voice, int angle, int volume, int channels );
+
+VoiceNode *GUSWAVE_AllocVoice( int priority );
+static int GUSWAVE_InitVoices( void );
+
+#endif
--- /dev/null
+++ b/rott/audiolib/_midi.h
@@ -1,0 +1,290 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: _MIDI.H
+
+   author: James R. Dose
+   date:   May 25, 1994
+
+   Private header for MIDI.C.  Midi song file playback routines.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef ___MIDI_H
+#define ___MIDI_H
+
+#define RELATIVE_BEAT( measure, beat, tick ) \
+   ( ( tick ) + ( ( beat ) << 9 ) + ( ( measure ) << 16 ) )
+
+//Bobby Prince thinks this may be 100
+//#define GENMIDI_DefaultVolume 100
+#define GENMIDI_DefaultVolume 90
+
+#define MAX_FORMAT            1
+
+#define NUM_MIDI_CHANNELS     16
+
+#define TIME_PRECISION        16
+
+#define MIDI_HEADER_SIGNATURE 0x6468544d    // "MThd"
+#define MIDI_TRACK_SIGNATURE  0x6b72544d    // "MTrk"
+
+#define MIDI_VOLUME                7
+#define MIDI_PAN                   10
+#define MIDI_DETUNE                94
+#define MIDI_RHYTHM_CHANNEL        9
+#define MIDI_RPN_MSB               100
+#define MIDI_RPN_LSB               101
+#define MIDI_DATAENTRY_MSB         6
+#define MIDI_DATAENTRY_LSB         38
+#define MIDI_PITCHBEND_MSB         0
+#define MIDI_PITCHBEND_LSB         0
+#define MIDI_RUNNING_STATUS        0x80
+#define MIDI_NOTE_OFF              0x8
+#define MIDI_NOTE_ON               0x9
+#define MIDI_POLY_AFTER_TCH        0xA
+#define MIDI_CONTROL_CHANGE        0xB
+#define MIDI_PROGRAM_CHANGE        0xC
+#define MIDI_AFTER_TOUCH           0xD
+#define MIDI_PITCH_BEND            0xE
+#define MIDI_SPECIAL               0xF
+#define MIDI_SYSEX                 0xF0
+#define MIDI_SYSEX_CONTINUE        0xF7
+#define MIDI_META_EVENT            0xFF
+#define MIDI_END_OF_TRACK          0x2F
+#define MIDI_TEMPO_CHANGE          0x51
+#define MIDI_TIME_SIGNATURE        0x58
+#define MIDI_RESET_ALL_CONTROLLERS 0x79
+#define MIDI_ALL_NOTES_OFF         0x7b
+#define MIDI_MONO_MODE_ON          0x7E
+#define MIDI_SYSTEM_RESET          0xFF
+
+#define GET_NEXT_EVENT( track, data ) \
+   ( data ) = *( track )->pos; \
+   ( track )->pos += 1
+
+#define GET_MIDI_CHANNEL( event )       ( ( event ) & 0xf )
+#define GET_MIDI_COMMAND( event )       ( ( event ) >> 4 )
+
+#define EMIDI_INFINITE          -1
+#define EMIDI_END_LOOP_VALUE    127
+#define EMIDI_ALL_CARDS         127
+#define EMIDI_INCLUDE_TRACK     110
+#define EMIDI_EXCLUDE_TRACK     111
+#define EMIDI_PROGRAM_CHANGE    112
+#define EMIDI_VOLUME_CHANGE     113
+#define EMIDI_CONTEXT_START     114
+#define EMIDI_CONTEXT_END       115
+#define EMIDI_LOOP_START        116
+#define EMIDI_LOOP_END          117
+#define EMIDI_SONG_LOOP_START   118
+#define EMIDI_SONG_LOOP_END     119
+
+#define EMIDI_GeneralMIDI       0
+#define EMIDI_SoundCanvas       1
+#define EMIDI_AWE32             2
+#define EMIDI_WaveBlaster       3
+#define EMIDI_SoundBlaster      4
+#define EMIDI_ProAudio          5
+#define EMIDI_SoundMan16        6
+#define EMIDI_Adlib             7
+#define EMIDI_Soundscape        8
+#define EMIDI_Ultrasound        9
+
+#define EMIDI_AffectsCurrentCard( c, type ) \
+   ( ( ( c ) == EMIDI_ALL_CARDS ) || ( ( c ) == ( type ) ) )
+
+
+#define EMIDI_NUM_CONTEXTS      7
+typedef struct
+   {
+   unsigned char *pos;
+   unsigned char *loopstart;
+   short          loopcount;
+   short          RunningStatus;
+   unsigned       time;
+   long           FPSecondsPerTick;
+   short          tick;
+   short          beat;
+   short          measure;
+   short          BeatsPerMeasure;
+   short          TicksPerBeat;
+   short          TimeBase;
+   long           delay;
+   short          active;
+   } songcontext;
+
+typedef struct
+   {
+   unsigned char *start;
+   unsigned char *pos;
+
+   long           delay;
+   short          active;
+   short          RunningStatus;
+
+   short          currentcontext;
+   songcontext    context[ EMIDI_NUM_CONTEXTS ];
+
+   char           EMIDI_IncludeTrack;
+   char           EMIDI_ProgramChange;
+   char           EMIDI_VolumeChange;
+   } track;
+
+static long _MIDI_ReadNumber( void *from, size_t size );
+static long _MIDI_ReadDelta( track *ptr );
+static void _MIDI_ResetTracks( void );
+static void _MIDI_AdvanceTick( void );
+static void _MIDI_MetaEvent( track *Track );
+static void _MIDI_SysEx( track *Track );
+static int  _MIDI_InterpretControllerInfo( track *Track, int TimeSet,
+   int channel, int c1, int c2 );
+//static
+   void _MIDI_ServiceRoutine( task *Task );
+static int  _MIDI_SendControlChange( int channel, int c1, int c2 );
+static void _MIDI_SetChannelVolume( int channel, int volume );
+static void _MIDI_SendChannelVolumes( void );
+static int  _MIDI_ProcessNextTick( void );
+static void _MIDI_InitEMIDI( void );
+
+/*
+               if ( c1 == EMIDI_LOOP_START )
+                  {
+                  if ( c2 == 0 )
+                     {
+                     Track->context[ 0 ].loopcount = EMIDI_INFINITE;
+                     }
+                  else
+                     {
+                     Track->context[ 0 ].loopcount = c2;
+                     }
+
+                  Track->context[ 0 ].pos              = Track->pos;
+                  Track->context[ 0 ].loopstart        = Track->pos;
+                  Track->context[ 0 ].RunningStatus    = Track->RunningStatus;
+                  Track->context[ 0 ].time             = _MIDI_Time;
+                  Track->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick;
+                  Track->context[ 0 ].tick             = _MIDI_Tick;
+                  Track->context[ 0 ].beat             = _MIDI_Beat;
+                  Track->context[ 0 ].measure          = _MIDI_Measure;
+                  Track->context[ 0 ].BeatsPerMeasure  = _MIDI_BeatsPerMeasure;
+                  Track->context[ 0 ].TicksPerBeat     = _MIDI_TicksPerBeat;
+                  Track->context[ 0 ].TimeBase         = _MIDI_TimeBase;
+                  break;
+                  }
+
+               if ( ( c1 == EMIDI_LOOP_END ) &&
+                  ( c2 == EMIDI_END_LOOP_VALUE ) )
+                  {
+                  if ( ( Track->context[ 0 ].loopstart != NULL ) &&
+                     ( Track->context[ 0 ].loopcount != 0 ) )
+                     {
+                     if ( Track->context[ 0 ].loopcount != EMIDI_INFINITE )
+                        {
+                        Track->context[ 0 ].loopcount--;
+                        }
+
+                     Track->pos           = Track->context[ 0 ].loopstart;
+                     Track->RunningStatus = Track->context[ 0 ].RunningStatus;
+
+                     if ( !TimeSet )
+                        {
+                        _MIDI_Time             = Track->context[ 0 ].time;
+                        _MIDI_FPSecondsPerTick = Track->context[ 0 ].FPSecondsPerTick;
+                        _MIDI_Tick             = Track->context[ 0 ].tick;
+                        _MIDI_Beat             = Track->context[ 0 ].beat;
+                        _MIDI_Measure          = Track->context[ 0 ].measure;
+                        _MIDI_BeatsPerMeasure  = Track->context[ 0 ].BeatsPerMeasure;
+                        _MIDI_TicksPerBeat     = Track->context[ 0 ].TicksPerBeat;
+                        _MIDI_TimeBase         = Track->context[ 0 ].TimeBase;
+                        TimeSet = TRUE;
+                        }
+                     }
+                  break;
+                  }
+
+               if ( c1 == MIDI_MONO_MODE_ON )
+                  {
+                  Track->pos++;
+                  }
+
+               if ( ( c1 == MIDI_VOLUME ) && ( !Track->EMIDI_VolumeChange ) )
+                  {
+                  _MIDI_SetChannelVolume( channel, c2 );
+                  break;
+                  }
+               else if ( ( c1 == EMIDI_VOLUME_CHANGE ) &&
+                  ( Track->EMIDI_VolumeChange ) )
+                  {
+                  _MIDI_SetChannelVolume( channel, c2 );
+                  break;
+                  }
+
+               if ( ( c1 == EMIDI_PROGRAM_CHANGE ) &&
+                  ( Track->EMIDI_ProgramChange ) )
+                  {
+                  _MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c2 & 0x7f ] );
+                  break;
+                  }
+
+               if ( c1 == EMIDI_CONTEXT_START )
+                  {
+                  break;
+                  }
+
+               if ( c1 == EMIDI_CONTEXT_END )
+                  {
+                  if ( ( Track->currentcontext != _MIDI_Context ) ||
+                     ( Track->context[ _MIDI_Context ].pos == NULL )
+                     {
+                     break;
+                     }
+
+                  Track->currentcontext = _MIDI_Context;
+                  Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart;
+                  Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount;
+                  Track->pos           = Track->context[ _MIDI_Context ].pos;
+                  Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus;
+
+                  if ( TimeSet )
+                     {
+                     break;
+                     }
+
+                  _MIDI_Time             = Track->context[ _MIDI_Context ].time;
+                  _MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick;
+                  _MIDI_Tick             = Track->context[ _MIDI_Context ].tick;
+                  _MIDI_Beat             = Track->context[ _MIDI_Context ].beat;
+                  _MIDI_Measure          = Track->context[ _MIDI_Context ].measure;
+                  _MIDI_BeatsPerMeasure  = Track->context[ _MIDI_Context ].BeatsPerMeasure;
+                  _MIDI_TicksPerBeat     = Track->context[ _MIDI_Context ].TicksPerBeat;
+                  _MIDI_TimeBase         = Track->context[ _MIDI_Context ].TimeBase;
+                  TimeSet = TRUE;
+                  break;
+                  }
+
+               if ( _MIDI_Funcs->ControlChange )
+                  {
+                  _MIDI_Funcs->ControlChange( channel, c1, c2 );
+                  }
+ */
+
+#endif
--- /dev/null
+++ b/rott/audiolib/_multivc.h
@@ -1,0 +1,286 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   file:   _MULTIVC.H
+
+   author: James R. Dose
+   date:   December 20, 1993
+
+   Private header for MULTIVOC.C
+
+   (c) Copyright 1993 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef ___MULTIVC_H
+#define ___MULTIVC_H
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+#define VOC_8BIT            0x0
+#define VOC_CT4_ADPCM       0x1
+#define VOC_CT3_ADPCM       0x2
+#define VOC_CT2_ADPCM       0x3
+#define VOC_16BIT           0x4
+#define VOC_ALAW            0x6
+#define VOC_MULAW           0x7
+#define VOC_CREATIVE_ADPCM  0x200
+
+#define T_SIXTEENBIT_STEREO 0
+#define T_8BITS       1
+#define T_MONO        2
+#define T_16BITSOURCE 4
+#define T_LEFTQUIET   8
+#define T_RIGHTQUIET  16
+#define T_DEFAULT     T_SIXTEENBIT_STEREO
+
+#define MV_MaxPanPosition  31
+#define MV_NumPanPositions ( MV_MaxPanPosition + 1 )
+#define MV_MaxTotalVolume  255
+//#define MV_MaxVolume       63
+#define MV_NumVoices       8
+
+#define MIX_VOLUME( volume ) \
+   ( ( max( 0, min( ( volume ), 255 ) ) * ( MV_MaxVolume + 1 ) ) >> 8 )
+//   ( ( max( 0, min( ( volume ), 255 ) ) ) >> 2 )
+
+//#define SILENCE_16BIT     0x80008000
+#define SILENCE_16BIT     0
+#define SILENCE_8BIT      0x80808080
+//#define SILENCE_16BIT_PAS 0
+
+#define MixBufferSize     256
+
+#define NumberOfBuffers   16
+#define TotalBufferSize   ( MixBufferSize * NumberOfBuffers )
+
+#define PI                3.1415926536
+
+typedef enum
+   {
+   Raw,
+   VOC,
+   DemandFeed,
+   WAV
+   } wavedata;
+
+typedef enum
+   {
+   NoMoreData,
+   KeepPlaying
+   } playbackstatus;
+
+
+typedef struct VoiceNode
+   {
+   struct VoiceNode *next;
+   struct VoiceNode *prev;
+
+   wavedata      wavetype;
+   char          bits;
+
+   playbackstatus ( *GetSound )( struct VoiceNode *voice );
+
+   void ( *mix )( unsigned long position, unsigned long rate,
+      const char *start, unsigned long length );
+
+   char         *NextBlock;
+   char         *LoopStart;
+   char         *LoopEnd;
+   unsigned      LoopCount;
+   unsigned long LoopSize;
+   unsigned long BlockLength;
+
+   unsigned long PitchScale;
+   unsigned long FixedPointBufferSize;
+
+   char         *sound;
+   unsigned long length;
+   unsigned long SamplingRate;
+   unsigned long RateScale;
+   unsigned long position;
+   int           Playing;
+
+   int           handle;
+   int           priority;
+
+   void          ( *DemandFeed )( char **ptr, unsigned long *length );
+
+   short        *LeftVolume;
+   short        *RightVolume;
+
+   unsigned long callbackval;
+
+   } VoiceNode;
+
+typedef struct
+   {
+   VoiceNode *start;
+   VoiceNode *end;
+   } VList;
+
+typedef struct
+   {
+   unsigned char left;
+   unsigned char right;
+   } Pan;
+
+typedef signed short MONO16;
+typedef signed char  MONO8;
+
+typedef struct
+   {
+   MONO16 left;
+   MONO16 right;
+//   unsigned short left;
+//   unsigned short right;
+   } STEREO16;
+
+typedef struct
+   {
+   MONO16 left;
+   MONO16 right;
+   } SIGNEDSTEREO16;
+
+typedef struct
+   {
+//   MONO8 left;
+//   MONO8 right;
+   char left;
+   char right;
+   } STEREO8;
+
+typedef struct
+   {
+   char          RIFF[ 4 ];
+   unsigned long file_size;
+   char          WAVE[ 4 ];
+   char          fmt[ 4 ];
+   unsigned long format_size;
+   } riff_header;
+
+typedef struct
+   {
+   unsigned short wFormatTag;
+   unsigned short nChannels;
+   unsigned long  nSamplesPerSec;
+   unsigned long  nAvgBytesPerSec;
+   unsigned short nBlockAlign;
+   unsigned short nBitsPerSample;
+   } format_header;
+
+typedef struct
+   {
+   unsigned char DATA[ 4 ];
+   unsigned long size;
+   } data_header;
+
+typedef MONO8  VOLUME8[ 256 ];
+typedef MONO16 VOLUME16[ 256 ];
+
+typedef char HARSH_CLIP_TABLE_8[ MV_NumVoices * 256 ];
+
+static void MV_Mix( VoiceNode *voice, int buffer );
+static void MV_PlayVoice( VoiceNode *voice );
+static void MV_StopVoice( VoiceNode *voice );
+static void MV_ServiceVoc( void );
+
+static playbackstatus MV_GetNextVOCBlock( VoiceNode *voice );
+static playbackstatus MV_GetNextDemandFeedBlock( VoiceNode *voice );
+static playbackstatus MV_GetNextRawBlock( VoiceNode *voice );
+static playbackstatus MV_GetNextWAVBlock( VoiceNode *voice );
+
+static void       MV_ServiceRecord( void );
+static VoiceNode *MV_GetVoice( int handle );
+static VoiceNode *MV_AllocVoice( int priority );
+
+static short     *MV_GetVolumeTable( int vol );
+
+static void       MV_SetVoiceMixMode( VoiceNode *voice );
+
+static void       MV_SetVoicePitch( VoiceNode *voice, unsigned long rate, int pitchoffset );
+static void       MV_CalcVolume( int MaxLevel );
+static void       MV_CalcPanTable( void );
+
+#ifdef PLAT_DOS
+#define ATR_INDEX               0x3c0
+#define STATUS_REGISTER_1       0x3da
+
+#define SetBorderColor(color) \
+   { \
+   inp  (STATUS_REGISTER_1); \
+   outp (ATR_INDEX,0x31);    \
+   outp (ATR_INDEX,color);   \
+   }
+#endif
+
+void ClearBuffer_DW( void *ptr, unsigned data, int length );
+
+#ifdef PLAT_DOS
+#pragma aux ClearBuffer_DW = \
+   "cld",                    \
+   "push   es",              \
+   "push   ds",              \
+   "pop    es",              \
+   "rep    stosd",           \
+   "pop    es",              \
+parm [ edi ] [ eax ] [ ecx ] modify exact [ ecx edi ];
+#endif
+
+void MV_Mix8BitMono( unsigned long position, unsigned long rate,
+   const char *start, unsigned long length );
+
+void MV_Mix8BitStereo( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length );
+
+void MV_Mix16BitMono( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length );
+
+void MV_Mix16BitStereo( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length );
+
+void MV_Mix16BitMono16( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length );
+
+void MV_Mix8BitMono16( unsigned long position, unsigned long rate,
+   const char *start, unsigned long length );
+
+void MV_Mix8BitStereo16( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length );
+
+void MV_Mix16BitStereo16( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length );
+
+void MV_16BitReverb( const char *src, char *dest, const VOLUME16 *volume, int count );
+
+void MV_8BitReverb( const signed char *src, signed char *dest, const VOLUME16 *volume, int count );
+
+void MV_16BitReverbFast( const char *src, char *dest, int count, int shift );
+
+void MV_8BitReverbFast( const signed char *src, signed char *dest, int count, int shift );
+
+#ifdef PLAT_DOS
+#pragma aux MV_16BitReverb parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
+#pragma aux MV_8BitReverb parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
+#pragma aux MV_16BitReverbFast parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
+#pragma aux MV_8BitReverbFast parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
+#endif
+
+#endif
--- /dev/null
+++ b/rott/audiolib/_pas16.h
@@ -1,0 +1,250 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: _PAS16.H
+
+   author: James R. Dose
+   date:   March 27, 1994
+
+   Private header for for PAS16.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef ___PAS16_H
+#define ___PAS16_H
+
+#define TRUE    ( 1 == 1 )
+#define FALSE   ( !TRUE )
+
+#define VALID   ( 1 == 1 )
+#define INVALID ( !VALID )
+
+#define lobyte( num )   ( ( int )*( ( char * )&( num ) ) )
+#define hibyte( num )   ( ( int )*( ( ( char * )&( num ) ) + 1 ) )
+
+#define STEREO      1
+#define SIXTEEN_BIT 2
+
+#define MONO_8BIT    0
+#define STEREO_8BIT  ( STEREO )
+#define MONO_16BIT   ( SIXTEEN_BIT )
+#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
+
+#define PAS_MaxMixMode        STEREO_16BIT
+
+#define MONO_8BIT_SAMPLE_SIZE    1
+#define MONO_16BIT_SAMPLE_SIZE   2
+#define STEREO_8BIT_SAMPLE_SIZE  ( 2 * MONO_8BIT_SAMPLE_SIZE )
+#define STEREO_16BIT_SAMPLE_SIZE ( 2 * MONO_16BIT_SAMPLE_SIZE )
+
+#define PAS_RevisionBits        0xe0
+
+#define AudioFilterControl      0xb8a
+#define InterruptControl        0xb8b
+#define InterruptStatus         0xb89
+#define PCMDataRegister         0xf88
+#define CrossChannelControl     0xf8a
+#define SampleRateTimer         0x1388
+#define SampleBufferCount       0x1389
+#define LocalSpeakerTimerCount  0x138a
+#define LocalTimerControl       0x138b
+#define SampleSizeConfiguration 0x8389
+
+#define AudioMuteFlag             0x20
+#define SampleRateTimerGateFlag   0x40
+#define SampleBufferCountGateFlag 0x80
+
+#define SampleRateInterruptFlag   0x04
+#define SampleBufferInterruptFlag 0x08
+
+#define PAS_SampleSizeMask     0xf3
+#define PAS_SignedSampleMask   0xe3
+#define PAS_16BitSampleFlag    0x04
+#define PAS_UnsignedSampleFlag 0x10
+//bSC2msbinv   equ   00010000b   ;; invert MSB from standard method
+
+#define PAS_OverSamplingMask 0xfc
+
+#define PAS_1xOverSampling  0x00
+#define PAS_2xOverSampling  0x01
+#define PAS_4xOverSampling  0x03
+
+#define PAS_StereoFlag      0x20
+
+#define PAS_AudioMuteFlag  0x20
+
+#define DEFAULT_BASE ( 0x0388 ^ 0x388 ) /* default base I/O address */
+#define ALT_BASE_1   ( 0x0384 ^ 0x388 ) /* first alternate address  */
+#define ALT_BASE_2   ( 0x038C ^ 0x388 ) /* second alternate address */
+#define ALT_BASE_3   ( 0x0288 ^ 0x388 ) /* third alternate address  */
+
+#define PAS_DMAEnable          0x80
+#define PAS_ChannelConnectMask 0x0f
+#define PAS_PCMStartDAC        0xD0
+#define PAS_PCMStartADC        0xC0
+#define PAS_PCMStopMask        0x3f
+
+#define RECORD   0
+#define PLAYBACK 1
+
+#define SelectSampleRateTimer   0x36   // 00110110b
+#define SelectSampleBufferCount 0x74   // 01110100b
+
+#define CalcTimeInterval( rate ) \
+   ( 1193180UL / ( rate ) )
+
+#define CalcSamplingRate( interval ) \
+   ( 1193180UL / ( interval ) )
+
+#define MV_Signature                 0x4d56
+#define MV_SoundInt                  0x2f
+#define MV_CheckForDriver            0xbc00
+#define MV_GetVersion                0xbc01
+#define MV_GetPointerToStateTable    0xbc02
+#define MV_GetPointerToFunctionTable 0xbc03
+#define MV_GetDmaIrqInt              0xbc04
+#define MV_SendCommandStructure      0xbc05
+#define MV_GetDriverMessage          0xbc06
+#define MV_SetHotkeyScanCodes        0xbc0a
+#define MV_GetPathToDriver           0xbc0b
+
+#define OUTPUTMIXER     0x00         /* output mixer H/W select */
+#define INPUTMIXER      0x40         /* input mixer select      */
+#define DEFMIXER        -1           /* use last mixer selected   */
+
+/* left channel values */
+
+#define L_FM            0x01
+#define L_IMIXER        0x02
+#define L_EXT           0x03
+#define L_INT           0x04
+#define L_MIC           0x05
+#define L_PCM           0x06
+#define L_SPEAKER       0x07
+#define L_FREE          0x00
+#define L_SBDAC         0x00
+
+/* right channel values */
+
+#define R_FM            0x08
+#define R_IMIXER        0x09
+#define R_EXT           0x0A
+#define R_INT           0x0B
+#define R_MIC           0x0C
+#define R_PCM           0x0D
+#define R_SPEAKER       0x0E
+#define R_FREE          0x0F
+#define R_SBDAC         0x0F
+
+typedef struct
+   {
+   unsigned char  sysspkrtmr;   /*   42 System Speaker Timer Address */
+   unsigned char  systmrctlr;   /*   43 System Timer Control         */
+   unsigned char  sysspkrreg;   /*   61 System Speaker Register      */
+   unsigned char  joystick;     /*  201 Joystick Register            */
+   unsigned char  lfmaddr;      /*  388 Left  FM Synth Address       */
+   unsigned char  lfmdata;      /*  389 Left  FM Synth Data          */
+   unsigned char  rfmaddr;      /*  38A Right FM Synth Address       */
+   unsigned char  rfmdata;      /*  38B Right FM Synth Data          */
+   unsigned char  dfmaddr;      /*  788 Dual  FM Synth Address       */
+   unsigned char  dfmdata;      /*  789 Dual  FM Synth Data          */
+   unsigned char  RESRVD1[1];   /*      reserved                     */
+   unsigned char  paudiomixr;   /*  78B Paralllel Audio Mixer Control*/
+   unsigned char  audiomixr;    /*  B88 Audio Mixer Control          */
+   unsigned char  intrctlrst;   /*  B89 Interrupt Status             */
+   unsigned char  audiofilt;    /*  B8A Audio Filter Control         */
+   unsigned char  intrctlr;     /*  B8B Interrupt Control            */
+   unsigned char  pcmdata;      /*  F88 PCM Data I/O Register        */
+   unsigned char  RESRVD2;      /*      reserved                     */
+   unsigned char  crosschannel; /*  F8A Cross Channel                */
+   unsigned char  RESRVD3;      /*      reserved                     */
+   unsigned short samplerate;   /* 1388 Sample Rate Timer            */
+   unsigned short samplecnt;    /* 1389 Sample Count Register        */
+   unsigned short spkrtmr;      /* 138A Shadow Speaker Timer Count   */
+   unsigned char  tmrctlr;      /* 138B Shadow Speaker Timer Control */
+   unsigned char  mdirqvect;    /* 1788 MIDI IRQ Vector Register     */
+   unsigned char  mdsysctlr;    /* 1789 MIDI System Control Register */
+   unsigned char  mdsysstat;    /* 178A MIDI IRQ Status Register     */
+   unsigned char  mdirqclr;     /* 178B MIDI IRQ Clear Register      */
+   unsigned char  mdgroup1;     /* 1B88 MIDI Group #1 Register       */
+   unsigned char  mdgroup2;     /* 1B89 MIDI Group #2 Register       */
+   unsigned char  mdgroup3;     /* 1B8A MIDI Group #3 Register       */
+   unsigned char  mdgroup4;     /* 1B8B MIDI Group #4 Register       */
+   } MVState;
+
+typedef struct
+   {
+   unsigned long SetMixer;
+   unsigned long SetVolume;
+   unsigned long SetFilter;
+   unsigned long SetCrossChannel;
+   unsigned long GetMixer;
+   unsigned long GetVolume;
+   unsigned long GetFilter;
+   unsigned long GetCrossChannel;
+   unsigned long ReadSound;
+   unsigned long FMSplit;
+   } MVFunc;
+
+int     PAS_CheckForDriver( void );
+MVState *PAS_GetStateTable( void );
+MVFunc  *PAS_GetFunctionTable( void );
+int     PAS_GetCardSettings( void );
+void    PAS_EnableInterrupt( void );
+void    PAS_DisableInterrupt( void );
+void    interrupt far PAS_ServiceInterrupt( void );
+//void    interrupt PAS_ServiceInterrupt( void );
+void    PAS_Write( int Register, int Data );
+int     PAS_Read( int Register );
+void    PAS_SetSampleRateTimer( void );
+void    PAS_SetSampleBufferCount( void );
+int     PAS_SetupDMABuffer( char *BufferPtr, int BufferSize, int mode );
+int     PAS_GetFilterSetting( int rate );
+void    PAS_BeginTransfer( int mode );
+int     PAS_TestAddress( int address );
+int     PAS_FindCard( void );
+int     PAS_CallMVFunction( unsigned long function, int ebx, int ecx, int edx );
+void    PAS_SaveState( void );
+void    PAS_RestoreState( void );
+
+
+#pragma aux PAS_TestAddress = \
+   "mov   dx, 0b8bh", \
+   "xor    dx, ax", \
+   "in    al, dx", \
+   "cmp   al, 0ffh", \
+   "je    TestExit", \
+   "mov   ah, al", \
+   "xor   al, 0e0h", \
+   "out   dx, al", \
+   "jmp   TestDelay1", \
+   "TestDelay1:", \
+   "jmp   TestDelay2", \
+   "TestDelay2:", \
+   "in    al, dx", \
+   "xchg  al, ah", \
+   "out   dx, al", \
+   "sub   al, ah", \
+   "TestExit:", \
+   "and   eax, 0ffh" \
+   parm [ eax ] modify exact [ eax dx ];
+
+#endif
--- /dev/null
+++ b/rott/audiolib/_sndscap.h
@@ -1,0 +1,136 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: _SNDSCAP.H
+
+   author: James R. Dose
+   date:   October 26, 1994
+
+   Private header for SNDSCAPE.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef ___SNDSCAP_H
+#define ___SNDSCAP_H
+
+#define VALID   ( 1 == 1 )
+#define INVALID ( !VALID )
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+#define lobyte( num )   ( ( int )*( ( char * )&( num ) ) )
+#define hibyte( num )   ( ( int )*( ( ( char * )&( num ) ) + 1 ) )
+
+#define STEREO      1
+#define SIXTEEN_BIT 2
+
+#define MONO_8BIT    0
+#define STEREO_8BIT  ( STEREO )
+#define MONO_16BIT   ( SIXTEEN_BIT )
+#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
+
+#define SOUNDSCAPE_MaxMixMode        STEREO_16BIT
+
+#define MONO_8BIT_SAMPLE_SIZE    1
+#define MONO_16BIT_SAMPLE_SIZE   2
+#define STEREO_8BIT_SAMPLE_SIZE  ( 2 * MONO_8BIT_SAMPLE_SIZE )
+#define STEREO_16BIT_SAMPLE_SIZE ( 2 * MONO_16BIT_SAMPLE_SIZE )
+
+#define SOUNDSCAPE_DefaultSampleRate 11000
+#define SOUNDSCAPE_DefaultMixMode    MONO_8BIT
+#define SOUNDSCAPE_MaxIrq            15
+
+/* Ensoniq gate-array chip defines ... */
+#define ODIE            0       /* ODIE gate array */
+#define OPUS            1       /* OPUS gate array */
+#define MMIC            2       /* MiMIC gate array */
+
+/* relevant direct register defines - offsets from base address */
+#define GA_HOSTCSTAT    2       /* host port ctrl/stat reg */
+#define GA_HOSTDATA     3       /* host port data reg */
+#define GA_REGADDR      4       /* indirect address reg */
+#define GA_REGDATA      5       /* indirect data reg */
+#define SB_IACK      0x22e /* SoundBlaster IACK register */
+
+/* relevant indirect register defines */
+#define GA_DMACHB       3       /* DMA chan B assign reg */
+#define GA_INTCFG       4       /* interrupt configuration reg */
+#define GA_DMACFG       5       /* DMA config reg */
+#define GA_CDCFG        6       /* CD-ROM (AD-1848) config reg */
+#define GA_HMCTL  9  /* host master control reg */
+#define GA_CHIPSEL      10      /* programmable external chip select */
+
+/* AD-1848 chip defines ... */
+/* relevant direct register defines */
+#define AD_REGADDR      0       /* indirect address reg */
+#define AD_REGDATA      1       /* indirect data reg */
+#define AD_STATUS       2       /* status register */
+#define AD_OFFSET       8       /* for some boards, a fixed BasePort offset */
+
+/* relevant indirect register defines */
+#define AD_LEFTOUT      6       /* left DAC output control reg */
+#define AD_RIGHTOUT     7       /* right DAC output control reg */
+#define AD_FORMAT       8       /* clock and data format reg */
+#define AD_CONFIG       9       /* interface config register */
+#define AD_PINCTRL      10      /* external pin control reg */
+#define AD_UCOUNT       14      /* upper count reg */
+#define AD_LCOUNT       15      /* lower count reg */
+
+/* some firmware command and communication defines */
+#define SET_CTL      0x88  /* set a control value */
+#define GET_CTL      0x89  /* get a control value */
+#define SET_REV      0xb0  /* set synth reverb */
+#define SYNTH_VOL 0x04  /* Synth Vol control number */
+#define RXRDY     0x01  /* Receive-Ready bit mask */
+#define TXRDY     0x02  /* Transmit-Ready bit mask */
+
+/* some miscellaneous defines ... soundscape reg values, sytem int regs, ... */
+#define INTCONT1        0x20    /* Interrupt Controller 1 control register */
+#define INTCONT2        0xa0    /* Interrupt Controller 2 control register */
+#define INTMASK1        0x21    /* Interrupt Controller 1 mask register */
+#define INTMASK2        0xa1    /* Interrupt Controller 2 mask register */
+#define VECTBASE1       0x08    /* vector base for XT interrupts */
+#define VECTBASE2       0x70    /* vector base for AT extended interrupts */
+#define EOI             0x20    /* End Of Interrupt command */
+#define AUTO_OUT        0x58    /* DMA controller mode */
+
+static void SOUNDSCAPE_EnableInterrupt( void );
+static void SOUNDSCAPE_DisableInterrupt( void );
+static void __interrupt __far SOUNDSCAPE_ServiceInterrupt( void );
+static int  ga_read( int rnum );
+static void ga_write( int rnum, int value );
+static int  ad_read( int rnum );
+static void ad_write( int rnum, int value );
+static void tdelay( void );
+static void pcm_format( void );
+static int  SOUNDSCAPE_SetupDMABuffer( char *BufferPtr, int BufferSize, int mode );
+static int  SOUNDSCAPE_BeginPlayback( int length );
+static void SOUNDSCAPE_LockEnd( void );
+static void SOUNDSCAPE_UnlockMemory( void );
+static int  SOUNDSCAPE_LockMemory( void );
+static unsigned short allocateTimerStack( unsigned short size );
+static void deallocateTimerStack( unsigned short selector );
+static int  parse( char *val, char *str, FILE *p1 );
+static int  SOUNDSCAPE_FindCard( void );
+static int  SOUNDSCAPE_Setup( void );
+
+#endif
--- /dev/null
+++ b/rott/audiolib/adlibfx.c
@@ -1,0 +1,552 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: ADLIBFX.C
+
+   author: James R. Dose
+   date:   April 1, 1994
+
+   Low level routines to support Adlib sound effects created by Muse.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <dos.h>
+#include <stdlib.h>
+#include <conio.h>
+#include "dpmi.h"
+#include "task_man.h"
+#include "interrup.h"
+#include "al_midi.h"
+#include "adlibfx.h"
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+static void ADLIBFX_SendOutput( int reg, int data );
+static void ADLIBFX_Service( task *Task );
+
+static long     ADLIBFX_LengthLeft;
+static int      ADLIBFX_Block;
+static ALSound *ADLIBFX_Sound = NULL;
+static char    *ADLIBFX_SoundPtr = NULL;
+static int      ADLIBFX_Priority;
+static unsigned long ADLIBFX_CallBackVal;
+static void     ( *ADLIBFX_CallBackFunc )( unsigned long ) = NULL;
+static int      ADLIBFX_SoundVolume;
+static int      ADLIBFX_TotalVolume = ADLIBFX_MaxVolume;
+static task    *ADLIBFX_ServiceTask = NULL;
+static int      ADLIBFX_VoiceHandle = ADLIBFX_MinVoiceHandle;
+
+int ADLIBFX_Installed = FALSE;
+
+int ADLIBFX_ErrorCode = ADLIBFX_Ok;
+
+#define ADLIBFX_SetErrorCode( status ) \
+   ADLIBFX_ErrorCode   = ( status );
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *ADLIBFX_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case ADLIBFX_Warning :
+      case ADLIBFX_Error :
+         ErrorString = ADLIBFX_ErrorString( ADLIBFX_ErrorCode );
+         break;
+
+      case ADLIBFX_Ok :
+         ErrorString = "Adlib FX ok.";
+         break;
+
+      case ADLIBFX_NoVoices :
+         ErrorString = "No free voices available in Adlib FX.";
+         break;
+
+      case ADLIBFX_VoiceNotFound :
+         ErrorString = "No voice with matching handle found.";
+         break;
+
+      case ADLIBFX_DPMI_Error :
+         ErrorString = "DPMI Error in AdlibFX.";
+         break;
+
+      default :
+         ErrorString = "Unknown Adlib FX error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define ADLIBFX_LockStart ADLIBFX_SendOutput
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_SendOutput
+
+   Writes a byte of data to the specified register on the Adlib card.
+---------------------------------------------------------------------*/
+
+static void ADLIBFX_SendOutput
+   (
+   int reg,
+   int data
+   )
+
+   {
+   int i;
+   int adlib_port = 0x388;
+   unsigned flags;
+
+   flags = DisableInterrupts();
+
+   outp( adlib_port, reg );
+
+   for( i = 6; i ; i-- )
+      {
+      inp( adlib_port );
+      }
+
+   outp( adlib_port + 1, data );
+
+   for( i = 35; i ; i-- )
+      {
+      inp( adlib_port );
+      }
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_Stop
+
+   Halts playback of the currently playing sound effect.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_Stop
+   (
+   int handle
+   )
+
+   {
+   unsigned flags;
+
+   if ( ( handle != ADLIBFX_VoiceHandle ) || ( ADLIBFX_Sound == NULL ) )
+      {
+      ADLIBFX_SetErrorCode( ADLIBFX_VoiceNotFound );
+      return( ADLIBFX_Warning );
+      }
+
+   flags = DisableInterrupts();
+
+   ADLIBFX_SendOutput( 0xb0, 0 );
+
+   ADLIBFX_Sound      = NULL;
+   ADLIBFX_SoundPtr   = NULL;
+   ADLIBFX_LengthLeft = 0;
+   ADLIBFX_Priority   = 0;
+
+   RestoreInterrupts( flags );
+
+   if ( ADLIBFX_CallBackFunc )
+      {
+      ADLIBFX_CallBackFunc( ADLIBFX_CallBackVal );
+      }
+
+   return( ADLIBFX_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_Service
+
+   Task Manager routine to perform the playback of a sound effect.
+---------------------------------------------------------------------*/
+
+static void ADLIBFX_Service
+   (
+   task *Task
+   )
+
+   {
+   int value;
+
+   if ( ADLIBFX_SoundPtr )
+      {
+      value = *ADLIBFX_SoundPtr++;
+      if ( value != 0 )
+         {
+         ADLIBFX_SendOutput( 0xa0, value );
+         ADLIBFX_SendOutput( 0xb0, ADLIBFX_Block );
+         }
+      else
+         {
+         ADLIBFX_SendOutput( 0xb0, 0 );
+         }
+
+      ADLIBFX_LengthLeft--;
+      if ( ADLIBFX_LengthLeft <= 0 )
+         {
+         ADLIBFX_Stop( ADLIBFX_VoiceHandle );
+         }
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_SetVolume
+
+   Sets the volume of the currently playing sound effect.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_SetVolume
+   (
+   int handle,
+   int volume
+   )
+
+   {
+   unsigned flags;
+   int      carrierlevel;
+
+   flags = DisableInterrupts();
+   if ( ( handle != ADLIBFX_VoiceHandle ) || ( ADLIBFX_Sound == NULL ) )
+      {
+      RestoreInterrupts( flags );
+      ADLIBFX_SetErrorCode( ADLIBFX_VoiceNotFound );
+      return( ADLIBFX_Warning );
+      }
+
+   volume  = min( volume, ADLIBFX_MaxVolume );
+   volume  = max( volume, 0 );
+   ADLIBFX_SoundVolume = volume;
+
+   volume *= ADLIBFX_TotalVolume;
+   volume /= ADLIBFX_MaxVolume;
+
+   carrierlevel  = ADLIBFX_Sound->cScale & 0x3f;
+   carrierlevel ^= 0x3f;
+   carrierlevel *= ( volume / 2 ) + 0x80;
+   carrierlevel /= ADLIBFX_MaxVolume;
+   carrierlevel ^= 0x3f;
+   carrierlevel |= ADLIBFX_Sound->cScale & 0xc0;
+
+   ADLIBFX_SendOutput( 0x43, carrierlevel );
+
+   RestoreInterrupts( flags );
+   return( ADLIBFX_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_SetTotalVolume
+
+   Sets the total volume of the sound effect.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_SetTotalVolume
+   (
+   int volume
+   )
+
+   {
+   volume = max( volume, 0 );
+   volume = min( volume, ADLIBFX_MaxVolume );
+
+   ADLIBFX_TotalVolume = volume;
+   ADLIBFX_SetVolume( ADLIBFX_VoiceHandle, ADLIBFX_SoundVolume );
+
+   return( ADLIBFX_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_GetTotalVolume
+
+   Returns the total volume of the sound effect.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_GetTotalVolume
+   (
+   void
+   )
+
+   {
+   return( ADLIBFX_TotalVolume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_VoiceAvailable
+
+   Checks if a voice can be play at the specified priority.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_VoiceAvailable
+   (
+   int priority
+   )
+
+   {
+   if ( priority < ADLIBFX_Priority )
+      {
+      return( FALSE );
+      }
+
+   return( TRUE );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_Play
+
+   Starts playback of a Muse sound effect.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_Play
+   (
+   ALSound *sound,
+   int volume,
+   int priority,
+   unsigned long callbackval
+   )
+
+   {
+   unsigned flags;
+   int      carrierlevel;
+
+   if ( priority < ADLIBFX_Priority )
+      {
+      ADLIBFX_SetErrorCode( ADLIBFX_NoVoices );
+      return( ADLIBFX_Warning );
+      }
+
+   ADLIBFX_Stop( ADLIBFX_VoiceHandle );
+
+   ADLIBFX_VoiceHandle++;
+   if ( ADLIBFX_VoiceHandle < ADLIBFX_MinVoiceHandle )
+      {
+      ADLIBFX_VoiceHandle = ADLIBFX_MinVoiceHandle;
+      }
+
+   flags = DisableInterrupts();
+
+   ADLIBFX_LengthLeft  = sound->length;
+   ADLIBFX_Priority    = priority;
+   ADLIBFX_Sound       = sound;
+   ADLIBFX_SoundPtr    = &sound->data;
+   ADLIBFX_CallBackVal = callbackval;
+
+   ADLIBFX_Block = ( ( sound->block & 7 ) << 2 ) | 0x20;
+
+   volume = min( volume, ADLIBFX_MaxVolume );
+   volume = max( volume, 0 );
+   ADLIBFX_SoundVolume = volume;
+
+   volume *= ADLIBFX_TotalVolume;
+   volume /= ADLIBFX_MaxVolume;
+
+   carrierlevel  = sound->cScale & 0x3f;
+   carrierlevel ^= 0x3f;
+   carrierlevel *= ( volume / 2 ) + 0x80;
+   carrierlevel /= ADLIBFX_MaxVolume;
+   carrierlevel ^= 0x3f;
+   carrierlevel |= sound->cScale & 0xc0;
+
+   ADLIBFX_SendOutput( 0x20, sound->mChar );
+   ADLIBFX_SendOutput( 0x40, sound->mScale );
+   ADLIBFX_SendOutput( 0x60, sound->mAttack );
+   ADLIBFX_SendOutput( 0x80, sound->mSus );
+   ADLIBFX_SendOutput( 0xe0, sound->mWave );
+
+   ADLIBFX_SendOutput( 0x23, sound->cChar );
+   ADLIBFX_SendOutput( 0x43, carrierlevel );
+   ADLIBFX_SendOutput( 0x63, sound->cAttack );
+   ADLIBFX_SendOutput( 0x83, sound->cSus );
+   ADLIBFX_SendOutput( 0xe3, sound->cWave );
+
+   ADLIBFX_SendOutput( 0xc0, 0 );
+
+   RestoreInterrupts( flags );
+
+   return( ADLIBFX_VoiceHandle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_SoundPlaying
+
+   Checks if a sound effect is currently playing.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_SoundPlaying
+   (
+   int handle
+   )
+
+   {
+   int status;
+
+   status = FALSE;
+   if ( ( handle == ADLIBFX_VoiceHandle ) && ( ADLIBFX_LengthLeft > 0 ) )
+      {
+      status = TRUE;
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void ADLIBFX_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_SetCallBack
+
+   Set the function to call when a voice stops.
+---------------------------------------------------------------------*/
+
+void ADLIBFX_SetCallBack
+   (
+   void ( *function )( unsigned long )
+   )
+
+   {
+   ADLIBFX_CallBackFunc = function;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_Init
+
+   Initializes the sound effect engine.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_Init
+   (
+   void
+   )
+
+   {
+   int status;
+
+   if ( ADLIBFX_Installed )
+      {
+      ADLIBFX_Shutdown();
+      }
+
+   status  = DPMI_LockMemoryRegion( ADLIBFX_LockStart, ADLIBFX_LockEnd );
+   status |= DPMI_Lock( ADLIBFX_VoiceHandle );
+   status |= DPMI_Lock( ADLIBFX_Sound );
+   status |= DPMI_Lock( ADLIBFX_ErrorCode );
+   status |= DPMI_Lock( ADLIBFX_SoundPtr );
+   status |= DPMI_Lock( ADLIBFX_LengthLeft );
+   status |= DPMI_Lock( ADLIBFX_Priority );
+   status |= DPMI_Lock( ADLIBFX_CallBackFunc );
+   status |= DPMI_Lock( ADLIBFX_Block );
+
+   if ( status != DPMI_Ok )
+      {
+      ADLIBFX_SetErrorCode( ADLIBFX_DPMI_Error );
+      return( ADLIBFX_Error );
+      }
+
+//JIM
+//   AL_ReserveVoice( 0 );
+   ADLIBFX_Stop( ADLIBFX_VoiceHandle );
+   ADLIBFX_ServiceTask = TS_ScheduleTask( &ADLIBFX_Service, 140, 2, NULL );
+   TS_Dispatch();
+   ADLIBFX_Installed = TRUE;
+   ADLIBFX_CallBackFunc = NULL;
+
+   ADLIBFX_SetErrorCode( ADLIBFX_Ok );
+   return( ADLIBFX_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_Shutdown
+
+   Ends the use of the sound effect engine.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_Shutdown
+   (
+   void
+   )
+
+   {
+   if ( ADLIBFX_Installed )
+      {
+      ADLIBFX_Stop( ADLIBFX_VoiceHandle );
+      TS_Terminate( ADLIBFX_ServiceTask );
+      ADLIBFX_ServiceTask = NULL;
+//JIM
+//      AL_ReleaseVoice( 0 );
+      ADLIBFX_Installed = FALSE;
+
+      DPMI_UnlockMemoryRegion( ADLIBFX_LockStart, ADLIBFX_LockEnd );
+      DPMI_Unlock( ADLIBFX_VoiceHandle );
+      DPMI_Unlock( ADLIBFX_Sound );
+      DPMI_Unlock( ADLIBFX_ErrorCode );
+      DPMI_Unlock( ADLIBFX_SoundPtr );
+      DPMI_Unlock( ADLIBFX_LengthLeft );
+      DPMI_Unlock( ADLIBFX_Priority );
+      DPMI_Unlock( ADLIBFX_CallBackFunc );
+      DPMI_Unlock( ADLIBFX_Block );
+      }
+
+   ADLIBFX_SetErrorCode( ADLIBFX_Ok );
+   return( ADLIBFX_Ok );
+   }
--- /dev/null
+++ b/rott/audiolib/adlibfx.h
@@ -1,0 +1,80 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: ADLIBFX.H
+
+   author: James R. Dose
+   date:   April 1, 1994
+
+   Public header for ADLIBFX.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __ADLIBFX_H
+#define __ADLIBFX_H
+
+enum ADLIBFX_Errors
+   {
+   ADLIBFX_Warning = -2,
+   ADLIBFX_Error   = -1,
+   ADLIBFX_Ok      = 0,
+   ADLIBFX_NoVoices,
+   ADLIBFX_VoiceNotFound,
+   ADLIBFX_DPMI_Error
+   };
+
+typedef	struct
+   {
+   unsigned long  length;
+   short int      priority;
+   char           mChar, cChar;
+   char           mScale, cScale;
+   char           mAttack, cAttack;
+   char           mSus, cSus;
+   char           mWave, cWave;
+   char           nConn;
+   char           voice;
+   char           mode;
+   char           unused[ 3 ];
+   char           block;
+   char           data[];
+   } ALSound;
+
+#define ADLIBFX_MaxVolume      255
+#define ADLIBFX_MinVoiceHandle 1
+
+char *ADLIBFX_ErrorString( int ErrorNumber );
+int   ADLIBFX_Stop( int handle );
+int   ADLIBFX_SetVolume( int handle, int volume );
+int   ADLIBFX_SetTotalVolume( int volume );
+int   ADLIBFX_GetTotalVolume( void );
+int   ADLIBFX_VoiceAvailable( int priority );
+int   ADLIBFX_Play( ALSound *sound, int volume, int priority, unsigned long callbackval );
+int   ADLIBFX_SoundPlaying( int handle );
+void  ADLIBFX_SetCallBack( void ( *function )( unsigned long ) );
+int   ADLIBFX_Init( void );
+int   ADLIBFX_Shutdown( void );
+   #pragma aux ADLIBFX_Shutdown frame;
+void  PCFX_UnlockMemory( void );
+   #pragma aux ADLIBFX_UnlockMemory frame;
+int   PCFX_LockMemory( void );
+
+#endif
--- /dev/null
+++ b/rott/audiolib/al_midi.c
@@ -1,0 +1,1510 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: AL_MIDI.C
+
+   author: James R. Dose
+   date:   April 1, 1994
+
+   Low level routines to support General MIDI music on Adlib compatible
+   cards.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <conio.h>
+#include <dos.h>
+#include <stddef.h>
+#include <stdlib.h>
+//#include <math.h>
+#include "dpmi.h"
+#include "interrup.h"
+#include "sndcards.h"
+#include "blaster.h"
+#include "user.h"
+#include "al_midi.h"
+#include "_al_midi.h"
+#include "ll_man.h"
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+static unsigned OctavePitch[ MAX_OCTAVE + 1 ] =
+   {
+   OCTAVE_0, OCTAVE_1, OCTAVE_2, OCTAVE_3,
+   OCTAVE_4, OCTAVE_5, OCTAVE_6, OCTAVE_7,
+   };
+
+static unsigned NoteMod12[ MAX_NOTE + 1 ];
+static unsigned NoteDiv12[ MAX_NOTE + 1 ];
+
+// Pitch table
+
+//static unsigned NotePitch[ FINETUNE_MAX + 1 ][ 12 ] =
+//   {
+//      { C, C_SHARP, D, D_SHARP, E, F, F_SHARP, G, G_SHARP, A, A_SHARP, B },
+//   };
+
+static unsigned NotePitch[ FINETUNE_MAX + 1 ][ 12 ] =
+   {
+      { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x241, 0x263, 0x287 },
+      { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x242, 0x264, 0x288 },
+      { 0x158, 0x16c, 0x182, 0x199, 0x1b1, 0x1cb, 0x1e6, 0x203, 0x221, 0x243, 0x265, 0x289 },
+      { 0x158, 0x16c, 0x183, 0x19a, 0x1b2, 0x1cc, 0x1e7, 0x204, 0x222, 0x244, 0x266, 0x28a },
+      { 0x159, 0x16d, 0x183, 0x19a, 0x1b3, 0x1cd, 0x1e8, 0x205, 0x223, 0x245, 0x267, 0x28b },
+      { 0x15a, 0x16e, 0x184, 0x19b, 0x1b3, 0x1ce, 0x1e9, 0x206, 0x224, 0x246, 0x268, 0x28c },
+      { 0x15a, 0x16e, 0x185, 0x19c, 0x1b4, 0x1ce, 0x1ea, 0x207, 0x225, 0x247, 0x269, 0x28e },
+      { 0x15b, 0x16f, 0x185, 0x19d, 0x1b5, 0x1cf, 0x1eb, 0x208, 0x226, 0x248, 0x26a, 0x28f },
+      { 0x15b, 0x170, 0x186, 0x19d, 0x1b6, 0x1d0, 0x1ec, 0x209, 0x227, 0x249, 0x26b, 0x290 },
+      { 0x15c, 0x170, 0x187, 0x19e, 0x1b7, 0x1d1, 0x1ec, 0x20a, 0x228, 0x24a, 0x26d, 0x291 },
+      { 0x15d, 0x171, 0x188, 0x19f, 0x1b7, 0x1d2, 0x1ed, 0x20b, 0x229, 0x24b, 0x26e, 0x292 },
+      { 0x15d, 0x172, 0x188, 0x1a0, 0x1b8, 0x1d3, 0x1ee, 0x20c, 0x22a, 0x24c, 0x26f, 0x293 },
+      { 0x15e, 0x172, 0x189, 0x1a0, 0x1b9, 0x1d4, 0x1ef, 0x20d, 0x22b, 0x24d, 0x270, 0x295 },
+      { 0x15f, 0x173, 0x18a, 0x1a1, 0x1ba, 0x1d4, 0x1f0, 0x20e, 0x22c, 0x24e, 0x271, 0x296 },
+      { 0x15f, 0x174, 0x18a, 0x1a2, 0x1bb, 0x1d5, 0x1f1, 0x20f, 0x22d, 0x24f, 0x272, 0x297 },
+      { 0x160, 0x174, 0x18b, 0x1a3, 0x1bb, 0x1d6, 0x1f2, 0x210, 0x22e, 0x250, 0x273, 0x298 },
+      { 0x161, 0x175, 0x18c, 0x1a3, 0x1bc, 0x1d7, 0x1f3, 0x211, 0x22f, 0x251, 0x274, 0x299 },
+      { 0x161, 0x176, 0x18c, 0x1a4, 0x1bd, 0x1d8, 0x1f4, 0x212, 0x230, 0x252, 0x276, 0x29b },
+      { 0x162, 0x176, 0x18d, 0x1a5, 0x1be, 0x1d9, 0x1f5, 0x212, 0x231, 0x254, 0x277, 0x29c },
+      { 0x162, 0x177, 0x18e, 0x1a6, 0x1bf, 0x1d9, 0x1f5, 0x213, 0x232, 0x255, 0x278, 0x29d },
+      { 0x163, 0x178, 0x18f, 0x1a6, 0x1bf, 0x1da, 0x1f6, 0x214, 0x233, 0x256, 0x279, 0x29e },
+      { 0x164, 0x179, 0x18f, 0x1a7, 0x1c0, 0x1db, 0x1f7, 0x215, 0x235, 0x257, 0x27a, 0x29f },
+      { 0x164, 0x179, 0x190, 0x1a8, 0x1c1, 0x1dc, 0x1f8, 0x216, 0x236, 0x258, 0x27b, 0x2a1 },
+      { 0x165, 0x17a, 0x191, 0x1a9, 0x1c2, 0x1dd, 0x1f9, 0x217, 0x237, 0x259, 0x27c, 0x2a2 },
+      { 0x166, 0x17b, 0x192, 0x1aa, 0x1c3, 0x1de, 0x1fa, 0x218, 0x238, 0x25a, 0x27e, 0x2a3 },
+      { 0x166, 0x17b, 0x192, 0x1aa, 0x1c3, 0x1df, 0x1fb, 0x219, 0x239, 0x25b, 0x27f, 0x2a4 },
+      { 0x167, 0x17c, 0x193, 0x1ab, 0x1c4, 0x1e0, 0x1fc, 0x21a, 0x23a, 0x25c, 0x280, 0x2a6 },
+      { 0x168, 0x17d, 0x194, 0x1ac, 0x1c5, 0x1e0, 0x1fd, 0x21b, 0x23b, 0x25d, 0x281, 0x2a7 },
+      { 0x168, 0x17d, 0x194, 0x1ad, 0x1c6, 0x1e1, 0x1fe, 0x21c, 0x23c, 0x25e, 0x282, 0x2a8 },
+      { 0x169, 0x17e, 0x195, 0x1ad, 0x1c7, 0x1e2, 0x1ff, 0x21d, 0x23d, 0x260, 0x283, 0x2a9 },
+      { 0x16a, 0x17f, 0x196, 0x1ae, 0x1c8, 0x1e3, 0x1ff, 0x21e, 0x23e, 0x261, 0x284, 0x2ab },
+      { 0x16a, 0x17f, 0x197, 0x1af, 0x1c8, 0x1e4, 0x200, 0x21f, 0x23f, 0x262, 0x286, 0x2ac }
+   };
+
+// Slot numbers as a function of the voice and the operator.
+// ( melodic only)
+
+static int slotVoice[ NUM_VOICES ][ 2 ] =
+   {
+      { 0, 3 },    // voice 0
+      { 1, 4 },    // 1
+      { 2, 5 },    // 2
+      { 6, 9 },    // 3
+      { 7, 10 },   // 4
+      { 8, 11 },   // 5
+      { 12, 15 },  // 6
+      { 13, 16 },  // 7
+      { 14, 17 },  // 8
+   };
+
+static int VoiceLevel[ NumChipSlots ][ 2 ];
+static int VoiceKsl[ NumChipSlots ][ 2 ];
+
+// This table gives the offset of each slot within the chip.
+// offset = fn( slot)
+
+static char offsetSlot[ NumChipSlots ] =
+   {
+    0,  1,  2,  3,  4,  5,
+    8,  9, 10, 11, 12, 13,
+   16, 17, 18, 19, 20, 21
+   };
+
+static int VoiceReserved[ NUM_VOICES * 2 ] =
+   {
+   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
+   };
+
+static VOICE     Voice[ NUM_VOICES * 2 ];
+static VOICELIST Voice_Pool;
+
+static CHANNEL   Channel[ NUM_CHANNELS ];
+
+static int AL_LeftPort   = 0x388;
+static int AL_RightPort  = 0x388;
+static int AL_Stereo     = FALSE;
+static int AL_SendStereo = FALSE;
+static int AL_OPL3       = FALSE;
+static int AL_MaxMidiChannel = 16;
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define AL_LockStart AL_SendOutputToPort
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SendOutputToPort
+
+   Sends data to the Adlib using a specified port.
+---------------------------------------------------------------------*/
+
+void AL_SendOutputToPort
+   (
+   int  port,
+   int  reg,
+   int  data
+   )
+
+   {
+   int delay;
+
+   outp( port, reg );
+
+   for( delay = 6; delay > 0 ; delay-- )
+//   for( delay = 2; delay > 0 ; delay-- )
+      {
+      inp( port );
+      }
+
+   outp( port + 1, data );
+
+//   for( delay = 35; delay > 0 ; delay-- )
+   for( delay = 27; delay > 0 ; delay-- )
+//   for( delay = 2; delay > 0 ; delay-- )
+      {
+      inp( port );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SendOutput
+
+   Sends data to the Adlib.
+---------------------------------------------------------------------*/
+
+void AL_SendOutput
+   (
+   int  voice,
+   int  reg,
+   int  data
+   )
+
+   {
+   int port;
+
+   if ( AL_SendStereo )
+      {
+      AL_SendOutputToPort( AL_LeftPort, reg, data );
+      AL_SendOutputToPort( AL_RightPort, reg, data );
+      }
+   else
+      {
+      port = ( voice == 0 ) ? AL_RightPort : AL_LeftPort;
+      AL_SendOutputToPort( port, reg, data );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetVoiceTimbre
+
+   Programs the specified voice's timbre.
+---------------------------------------------------------------------*/
+
+static void AL_SetVoiceTimbre
+   (
+   int voice
+   )
+
+   {
+   int    off;
+   int    slot;
+   int    port;
+   int    voc;
+   int    patch;
+   int    channel;
+   TIMBRE *timbre;
+
+   channel = Voice[ voice ].channel;
+
+   if ( channel == 9 )
+      {
+      patch = Voice[ voice ].key + 128;
+      }
+   else
+      {
+      patch = Channel[ channel ].Timbre;
+      }
+
+   if ( Voice[ voice ].timbre == patch )
+      {
+      return;
+      }
+
+   Voice[ voice ].timbre = patch;
+   timbre = &ADLIB_TimbreBank[ patch ];
+
+   port = Voice[ voice ].port;
+   voc  = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;
+   slot = slotVoice[ voc ][ 0 ];
+   off  = offsetSlot[ slot ];
+
+   VoiceLevel[ slot ][ port ] = 63 - ( timbre->Level[ 0 ] & 0x3f );
+   VoiceKsl[ slot ][ port ]   = timbre->Level[ 0 ] & 0xc0;
+
+   AL_SendOutput( port, 0xA0 + voc, 0 );
+   AL_SendOutput( port, 0xB0 + voc, 0 );
+
+   // Let voice clear the release
+   AL_SendOutput( port, 0x80 + off, 0xff );
+
+   AL_SendOutput( port, 0x60 + off, timbre->Env1[ 0 ] );
+   AL_SendOutput( port, 0x80 + off, timbre->Env2[ 0 ] );
+   AL_SendOutput( port, 0x20 + off, timbre->SAVEK[ 0 ] );
+   AL_SendOutput( port, 0xE0 + off, timbre->Wave[ 0 ] );
+
+   AL_SendOutput( port, 0x40 + off, timbre->Level[ 0 ] );
+   slot = slotVoice[ voc ][ 1 ];
+
+   if ( AL_SendStereo )
+      {
+      AL_SendOutputToPort( AL_LeftPort, 0xC0 + voice,
+         ( timbre->Feedback & 0x0f ) | 0x20 );
+      AL_SendOutputToPort( AL_RightPort, 0xC0 + voice,
+         ( timbre->Feedback & 0x0f ) | 0x10 );
+      }
+   else
+      {
+      if ( AL_OPL3 )
+         {
+         AL_SendOutput( port, 0xC0 + voc, ( timbre->Feedback & 0x0f ) |
+            0x30 );
+         }
+      else
+         {
+         AL_SendOutputToPort( ADLIB_PORT, 0xC0 + voice, timbre->Feedback );
+         }
+      }
+
+   off = offsetSlot[ slot ];
+
+   VoiceLevel[ slot ][ port ] = 63 - ( timbre->Level[ 1 ] & 0x3f );
+   VoiceKsl[ slot ][ port ]   = timbre->Level[ 1 ] & 0xc0;
+   AL_SendOutput( port, 0x40 + off, 63 );
+
+   // Let voice clear the release
+   AL_SendOutput( port, 0x80 + off, 0xff );
+
+   AL_SendOutput( port, 0x60 + off, timbre->Env1[ 1 ] );
+   AL_SendOutput( port, 0x80 + off, timbre->Env2[ 1 ] );
+   AL_SendOutput( port, 0x20 + off, timbre->SAVEK[ 1 ] );
+   AL_SendOutput( port, 0xE0 + off, timbre->Wave[ 1 ] );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetVoiceVolume
+
+   Sets the volume of the specified voice.
+---------------------------------------------------------------------*/
+
+static void AL_SetVoiceVolume
+   (
+   int voice
+   )
+
+   {
+   int channel;
+   int velocity;
+   int slot;
+   int port;
+   int voc;
+   unsigned long t1;
+   unsigned long t2;
+   unsigned long volume;
+   TIMBRE *timbre;
+
+   channel = Voice[ voice ].channel;
+
+   timbre = &ADLIB_TimbreBank[ Voice[ voice ].timbre ];
+
+   velocity = Voice[ voice ].velocity + timbre->Velocity;
+   velocity = min( velocity, MAX_VELOCITY );
+
+   voc  = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;
+   slot = slotVoice[ voc ][ 1 ];
+   port = Voice[ voice ].port;
+
+   // amplitude
+   t1  = ( unsigned )VoiceLevel[ slot ][ port ];
+   t1 *= ( velocity + 0x80 );
+   t1  = ( Channel[ channel ].Volume * t1 ) >> 15;
+
+   if ( !AL_SendStereo )
+      {
+      volume  = t1 ^ 63;
+      volume |= ( unsigned )VoiceKsl[ slot ][ port ];
+
+      AL_SendOutput( port, 0x40 + offsetSlot[ slot ], volume );
+
+      // Check if this timbre is Additive
+      if ( timbre->Feedback & 0x01 )
+         {
+         slot = slotVoice[ voc ][ 0 ];
+
+         // amplitude
+         t2  = ( unsigned )VoiceLevel[ slot ][ port ];
+         t2 *= ( velocity + 0x80 );
+         t2  = ( Channel[ channel ].Volume * t1 ) >> 15;
+
+         volume  = t2 ^ 63;
+         volume |= ( unsigned )VoiceKsl[ slot ][ port ];
+
+         AL_SendOutput( port, 0x40 + offsetSlot[ slot ], volume );
+         }
+      }
+   else
+      {
+      // Set left channel volume
+      volume = t1;
+      if ( Channel[ channel ].Pan < 64 )
+         {
+         volume *= Channel[ channel ].Pan;
+         volume >>= 6;
+         }
+
+      volume ^= 63;
+      volume |= ( unsigned )VoiceKsl[ slot ][ port ];
+
+      AL_SendOutputToPort( AL_LeftPort, 0x40 + offsetSlot[ slot ], volume );
+
+      // Set right channel volume
+      volume = t1;
+      if ( Channel[ channel ].Pan > 64 )
+         {
+         volume *= 127 - Channel[ channel ].Pan;
+         volume >>= 6;
+         }
+
+      volume ^= 63;
+      volume |= ( unsigned )VoiceKsl[ slot ][ port ];
+
+      AL_SendOutputToPort( AL_RightPort, 0x40 + offsetSlot[ slot ], volume );
+
+      // Check if this timbre is Additive
+      if ( timbre->Feedback & 0x01 )
+         {
+         // amplitude
+         t2  = ( unsigned )VoiceLevel[ slot ][ port ];
+         t2 *= ( velocity + 0x80 );
+         t2  = ( Channel[ channel ].Volume * t1 ) >> 15;
+
+         slot = slotVoice[ voc ][ 0 ];
+
+         // Set left channel volume
+         volume = t2;
+         if ( Channel[ channel ].Pan < 64 )
+            {
+            volume *= Channel[ channel ].Pan;
+            volume >>= 6;
+            }
+
+         volume ^= 63;
+         volume |= ( unsigned )VoiceKsl[ slot ][ port ];
+
+         AL_SendOutputToPort( AL_LeftPort, 0x40 + offsetSlot[ slot ], volume );
+
+         // Set right channel volume
+         volume = t2;
+         if ( Channel[ channel ].Pan > 64 )
+            {
+            volume *= 127 - Channel[ channel ].Pan;
+            volume >>= 6;
+            }
+
+         volume ^= 63;
+         volume |= ( unsigned )VoiceKsl[ slot ][ port ];
+
+         AL_SendOutputToPort( AL_RightPort, 0x40 + offsetSlot[ slot ], volume );
+         }
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_AllocVoice
+
+   Retrieves a free voice from the voice pool.
+---------------------------------------------------------------------*/
+
+static int AL_AllocVoice
+   (
+   void
+   )
+
+   {
+   int voice;
+
+   if ( Voice_Pool.start )
+      {
+      voice = Voice_Pool.start->num;
+      LL_Remove( VOICE, &Voice_Pool, &Voice[ voice ] );
+      return( voice );
+      }
+
+   return( AL_VoiceNotFound );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_GetVoice
+
+   Determines which voice is associated with a specified note and
+   MIDI channel.
+---------------------------------------------------------------------*/
+
+static int AL_GetVoice
+   (
+   int channel,
+   int key
+   )
+
+   {
+   VOICE *voice;
+
+   voice = Channel[ channel ].Voices.start;
+
+   while( voice != NULL )
+      {
+      if ( voice->key == key )
+         {
+         return( voice->num );
+         }
+      voice = voice->next;
+      }
+
+   return( AL_VoiceNotFound );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetVoicePitch
+
+   Programs the pitch of the specified voice.
+---------------------------------------------------------------------*/
+
+static void AL_SetVoicePitch
+   (
+   int voice
+   )
+
+   {
+   int note;
+   int channel;
+   int patch;
+   int detune;
+   int ScaleNote;
+   int Octave;
+   int pitch;
+   int port;
+   int voc;
+
+   port = Voice[ voice ].port;
+   voc  = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;
+   channel = Voice[ voice ].channel;
+
+   if ( channel == 9 )
+      {
+      patch = Voice[ voice ].key + 128;
+      note  = ADLIB_TimbreBank[ patch ].Transpose;
+      }
+   else
+      {
+      patch = Channel[ channel ].Timbre;
+      note  = Voice[ voice ].key + ADLIB_TimbreBank[ patch ].Transpose;
+      }
+
+   note += Channel[ channel ].KeyOffset - 12;
+   if ( note > MAX_NOTE )
+      {
+      note = MAX_NOTE;
+      }
+   if ( note < 0 )
+      {
+      note = 0;
+      }
+
+   detune = Channel[ channel ].KeyDetune;
+
+   ScaleNote = NoteMod12[ note ];
+   Octave    = NoteDiv12[ note ];
+
+   pitch = OctavePitch[ Octave ] | NotePitch[ detune ][ ScaleNote ];
+
+   Voice[ voice ].pitchleft = pitch;
+
+   pitch |= Voice[ voice ].status;
+
+   if ( !AL_SendStereo )
+      {
+      AL_SendOutput( port, 0xA0 + voc, pitch );
+      AL_SendOutput( port, 0xB0 + voc, pitch >> 8 );
+      }
+   else
+      {
+      AL_SendOutputToPort( AL_LeftPort, 0xA0 + voice, pitch );
+      AL_SendOutputToPort( AL_LeftPort, 0xB0 + voice, pitch >> 8 );
+
+      if ( channel != 9 )
+         {
+         detune += STEREO_DETUNE;
+         }
+
+      if ( detune > FINETUNE_MAX )
+         {
+         detune -= FINETUNE_RANGE;
+         if ( note < MAX_NOTE )
+            {
+            note++;
+            ScaleNote = NoteMod12[ note ];
+            Octave    = NoteDiv12[ note ];
+            }
+         }
+
+      pitch = OctavePitch[ Octave ] | NotePitch[ detune ][ ScaleNote ];
+
+      Voice[ voice ].pitchright = pitch;
+
+      pitch |= Voice[ voice ].status;
+
+      AL_SendOutputToPort( AL_RightPort, 0xA0 + voice, pitch );
+      AL_SendOutputToPort( AL_RightPort, 0xB0 + voice, pitch >> 8 );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetChannelVolume
+
+   Sets the volume of the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+static void AL_SetChannelVolume
+   (
+   int channel,
+   int volume
+   )
+
+   {
+   VOICE *voice;
+
+   volume = max( 0, volume );
+   volume = min( volume, AL_MaxVolume );
+   Channel[ channel ].Volume = volume;
+
+   voice = Channel[ channel ].Voices.start;
+   while( voice != NULL )
+      {
+      AL_SetVoiceVolume( voice->num );
+      voice = voice->next;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetChannelPan
+
+   Sets the pan position of the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+static void AL_SetChannelPan
+   (
+   int channel,
+   int pan
+   )
+
+   {
+   // Don't pan drum sounds
+   if ( channel != 9 )
+      {
+      Channel[ channel ].Pan = pan;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetChannelDetune
+
+   Sets the stereo voice detune of the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+static void AL_SetChannelDetune
+   (
+   int channel,
+   int detune
+   )
+
+   {
+   Channel[ channel ].Detune = detune;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_ResetVoices
+
+   Sets all voice info to the default state.
+---------------------------------------------------------------------*/
+
+static void AL_ResetVoices
+   (
+   void
+   )
+
+   {
+   int index;
+   int numvoices;
+
+   Voice_Pool.start = NULL;
+   Voice_Pool.end = NULL;
+
+   numvoices = NUM_VOICES;
+   if ( ( AL_OPL3 ) && ( !AL_Stereo ) )
+      {
+      numvoices = NUM_VOICES * 2;
+      }
+   for( index = 0; index < numvoices; index++ )
+      {
+      if ( VoiceReserved[ index ] == FALSE )
+         {
+         Voice[ index ].num = index;
+         Voice[ index ].key = 0;
+         Voice[ index ].velocity = 0;
+         Voice[ index ].channel = -1;
+         Voice[ index ].timbre = -1;
+         Voice[ index ].port = ( index < NUM_VOICES ) ? 0 : 1;
+         Voice[ index ].status = NOTE_OFF;
+         LL_AddToTail( VOICE, &Voice_Pool, &Voice[ index ] );
+         }
+      }
+
+   for( index = 0; index < NUM_CHANNELS; index++ )
+      {
+      Channel[ index ].Voices.start    = NULL;
+      Channel[ index ].Voices.end      = NULL;
+      Channel[ index ].Timbre          = 0;
+      Channel[ index ].Pitchbend       = 0;
+      Channel[ index ].KeyOffset       = 0;
+      Channel[ index ].KeyDetune       = 0;
+      Channel[ index ].Volume          = AL_DefaultChannelVolume;
+      Channel[ index ].Pan             = 64;
+      Channel[ index ].RPN             = 0;
+      Channel[ index ].PitchBendRange     = AL_DefaultPitchBendRange;
+      Channel[ index ].PitchBendSemiTones = AL_DefaultPitchBendRange / 100;
+      Channel[ index ].PitchBendHundreds  = AL_DefaultPitchBendRange % 100;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_CalcPitchInfo
+
+   Calculates the pitch table.
+---------------------------------------------------------------------*/
+
+static void AL_CalcPitchInfo
+   (
+   void
+   )
+
+   {
+   int    note;
+//   int    finetune;
+//   double detune;
+
+   for( note = 0; note <= MAX_NOTE; note++ )
+      {
+      NoteMod12[ note ] = note % 12;
+      NoteDiv12[ note ] = note / 12;
+      }
+
+//   for( finetune = 1; finetune <= FINETUNE_MAX; finetune++ )
+//      {
+//      detune = pow( 2, ( double )finetune / ( 12.0 * FINETUNE_RANGE ) );
+//      for( note = 0; note < 12; note++ )
+//         {
+//         NotePitch[ finetune ][ note ] = ( ( double )NotePitch[ 0 ][ note ] * detune );
+//         }
+//      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_FlushCard
+
+   Sets all voices to a known (quiet) state.
+---------------------------------------------------------------------*/
+
+void AL_FlushCard
+   (
+   int port
+   )
+
+   {
+   int i;
+   unsigned slot1;
+   unsigned slot2;
+
+   for( i = 0 ; i < NUM_VOICES; i++ )
+      {
+      if ( VoiceReserved[ i ] == FALSE )
+         {
+         slot1 = offsetSlot[ slotVoice[ i ][ 0 ] ];
+         slot2 = offsetSlot[ slotVoice[ i ][ 1 ] ];
+
+         AL_SendOutputToPort( port, 0xA0 + i, 0 );
+         AL_SendOutputToPort( port, 0xB0 + i, 0 );
+
+         AL_SendOutputToPort( port, 0xE0 + slot1, 0 );
+         AL_SendOutputToPort( port, 0xE0 + slot2, 0 );
+
+         // Set the envelope to be fast and quiet
+         AL_SendOutputToPort( port, 0x60 + slot1, 0xff );
+         AL_SendOutputToPort( port, 0x60 + slot2, 0xff );
+         AL_SendOutputToPort( port, 0x80 + slot1, 0xff );
+         AL_SendOutputToPort( port, 0x80 + slot2, 0xff );
+
+         // Maximum attenuation
+         AL_SendOutputToPort( port, 0x40 + slot1, 0xff );
+         AL_SendOutputToPort( port, 0x40 + slot2, 0xff );
+         }
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_StereoOn
+
+   Sets the card send info in stereo.
+---------------------------------------------------------------------*/
+
+void AL_StereoOn
+   (
+   void
+   )
+
+   {
+   if ( ( AL_Stereo ) && ( !AL_SendStereo ) )
+      {
+      AL_SendStereo = TRUE;
+      if ( AL_OPL3 )
+         {
+         // Set card to OPL3 operation
+         AL_SendOutputToPort( AL_RightPort, 0x5, 1 );
+         }
+      }
+   else if ( AL_OPL3 )
+      {
+      // Set card to OPL3 operation
+      AL_SendOutputToPort( AL_RightPort, 0x5, 1 );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_StereoOff
+
+   Sets the card send info in mono.
+---------------------------------------------------------------------*/
+
+void AL_StereoOff
+   (
+   void
+   )
+
+   {
+   if ( ( AL_Stereo ) && ( AL_SendStereo ) )
+      {
+      AL_SendStereo = FALSE;
+      if ( AL_OPL3 )
+         {
+         // Set card back to OPL2 operation
+         AL_SendOutputToPort( AL_RightPort, 0x5, 0 );
+         }
+      }
+   else if ( AL_OPL3 )
+      {
+      // Set card back to OPL2 operation
+      AL_SendOutputToPort( AL_RightPort, 0x5, 0 );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_Reset
+
+   Sets the card to a known (quiet) state.
+---------------------------------------------------------------------*/
+
+void AL_Reset
+   (
+   void
+   )
+
+   {
+   AL_SendOutputToPort( ADLIB_PORT, 1, 0x20 );
+   AL_SendOutputToPort( ADLIB_PORT, 0x08, 0 );
+
+   // Set the values: AM Depth, VIB depth & Rhythm
+   AL_SendOutputToPort( ADLIB_PORT, 0xBD, 0 );
+
+   AL_StereoOn();
+
+   if ( ( AL_SendStereo ) || ( AL_OPL3 ) )
+      {
+      AL_FlushCard( AL_LeftPort );
+      AL_FlushCard( AL_RightPort );
+      }
+   else
+      {
+      AL_FlushCard( ADLIB_PORT );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_ReserveVoice
+
+   Marks a voice as being not available for use.  This allows the
+   driver to use the rest of the card while another driver uses the
+   reserved voice.
+---------------------------------------------------------------------*/
+
+int AL_ReserveVoice
+   (
+   int voice
+   )
+
+   {
+   unsigned flags;
+
+   if ( ( voice < 0 ) || ( voice >= NUM_VOICES ) )
+      {
+      return( AL_Error );
+      }
+
+   if ( VoiceReserved[ voice ] )
+      {
+      return( AL_Warning );
+      }
+
+   flags = DisableInterrupts();
+
+   if ( Voice[ voice ].status == NOTE_ON )
+      {
+      AL_NoteOff( Voice[ voice ].channel, Voice[ voice ].key, 0 );
+      }
+
+   VoiceReserved[ voice ] = TRUE;
+   LL_Remove( VOICE, &Voice_Pool, &Voice[ voice ] );
+
+   RestoreInterrupts( flags );
+   return( AL_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_ReleaseVoice
+
+   Marks a previously reserved voice as being free to use.
+---------------------------------------------------------------------*/
+
+int AL_ReleaseVoice
+   (
+   int voice
+   )
+
+   {
+   unsigned flags;
+
+   if ( ( voice < 0 ) || ( voice >= NUM_VOICES ) )
+      {
+      return( AL_Error );
+      }
+
+   if ( !VoiceReserved[ voice ] )
+      {
+      return( AL_Warning );
+      }
+
+   flags = DisableInterrupts();
+
+   VoiceReserved[ voice ] = FALSE;
+   LL_AddToTail( VOICE, &Voice_Pool, &Voice[ voice ] );
+
+   RestoreInterrupts( flags );
+   return( AL_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_NoteOff
+
+   Turns off a note on the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+void AL_NoteOff
+   (
+   int channel,
+   int key,
+   int velocity
+   )
+
+   {
+   int voice;
+   int port;
+   int voc;
+
+   // We only play channels 1 through 10
+   if ( channel > AL_MaxMidiChannel )
+      {
+      return;
+      }
+
+   voice = AL_GetVoice( channel, key );
+
+   if ( voice == AL_VoiceNotFound )
+      {
+      return;
+      }
+
+   Voice[ voice ].status = NOTE_OFF;
+
+   port = Voice[ voice ].port;
+   voc  = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;
+
+   if ( AL_SendStereo )
+      {
+      AL_SendOutputToPort( AL_LeftPort, 0xB0 + voice,
+         hibyte( Voice[ voice ].pitchleft ) );
+      AL_SendOutputToPort( AL_RightPort, 0xB0 + voice,
+         hibyte( Voice[ voice ].pitchright ) );
+      }
+   else
+      {
+      AL_SendOutput( port, 0xB0 + voc, hibyte( Voice[ voice ].pitchleft ) );
+      }
+
+   LL_Remove( VOICE, &Channel[ channel ].Voices, &Voice[ voice ] );
+   LL_AddToTail( VOICE, &Voice_Pool, &Voice[ voice ] );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_NoteOn
+
+   Plays a note on the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+void AL_NoteOn
+   (
+   int channel,
+   int key,
+   int velocity
+   )
+
+   {
+   int voice;
+
+   // We only play channels 1 through 10
+   if ( channel > AL_MaxMidiChannel )
+      {
+      return;
+      }
+
+   if ( velocity == 0 )
+      {
+      AL_NoteOff( channel, key, velocity );
+      return;
+      }
+
+   voice = AL_AllocVoice();
+
+   if ( voice == AL_VoiceNotFound )
+      {
+      if ( Channel[ 9 ].Voices.start )
+         {
+         AL_NoteOff( 9, Channel[ 9 ].Voices.start->key, 0 );
+         voice = AL_AllocVoice();
+         }
+      if ( voice == AL_VoiceNotFound )
+         {
+         return;
+         }
+      }
+
+   Voice[ voice ].key      = key;
+   Voice[ voice ].channel  = channel;
+   Voice[ voice ].velocity = velocity;
+   Voice[ voice ].status   = NOTE_ON;
+
+   LL_AddToTail( VOICE, &Channel[ channel ].Voices, &Voice[ voice ] );
+
+   AL_SetVoiceTimbre( voice );
+   AL_SetVoiceVolume( voice );
+   AL_SetVoicePitch( voice );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_AllNotesOff
+
+   Turns off all currently playing voices.
+---------------------------------------------------------------------*/
+
+void AL_AllNotesOff
+   (
+   int channel
+   )
+
+   {
+   while( Channel[ channel ].Voices.start != NULL )
+      {
+      AL_NoteOff( channel, Channel[ channel ].Voices.start->key, 0 );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_ControlChange
+
+   Sets the value of a controller on the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+void AL_ControlChange
+   (
+   int channel,
+   int type,
+   int data
+   )
+
+   {
+   // We only play channels 1 through 10
+   if ( channel > AL_MaxMidiChannel )
+      {
+      return;
+      }
+
+   switch( type )
+      {
+      case MIDI_VOLUME :
+         AL_SetChannelVolume( channel, data );
+         break;
+
+      case MIDI_PAN :
+         AL_SetChannelPan( channel, data );
+         break;
+
+      case MIDI_DETUNE :
+         AL_SetChannelDetune( channel, data );
+         break;
+
+      case MIDI_ALL_NOTES_OFF :
+         AL_AllNotesOff( channel );
+         break;
+
+      case MIDI_RESET_ALL_CONTROLLERS :
+         AL_ResetVoices();
+         AL_SetChannelVolume( channel, AL_DefaultChannelVolume );
+         AL_SetChannelPan( channel, 64 );
+         AL_SetChannelDetune( channel, 0 );
+         break;
+
+      case MIDI_RPN_MSB :
+         Channel[ channel ].RPN &= 0x00FF;
+         Channel[ channel ].RPN |= ( data & 0xFF ) << 8;
+         break;
+
+      case MIDI_RPN_LSB :
+         Channel[ channel ].RPN &= 0xFF00;
+         Channel[ channel ].RPN |= data & 0xFF;
+         break;
+
+      case MIDI_DATAENTRY_MSB :
+         if ( Channel[ channel ].RPN == MIDI_PITCHBEND_RPN )
+            {
+            Channel[ channel ].PitchBendSemiTones = data;
+            Channel[ channel ].PitchBendRange     =
+               Channel[ channel ].PitchBendSemiTones * 100 +
+               Channel[ channel ].PitchBendHundreds;
+            }
+         break;
+
+      case MIDI_DATAENTRY_LSB :
+         if ( Channel[ channel ].RPN == MIDI_PITCHBEND_RPN )
+            {
+            Channel[ channel ].PitchBendHundreds = data;
+            Channel[ channel ].PitchBendRange    =
+               Channel[ channel ].PitchBendSemiTones * 100 +
+               Channel[ channel ].PitchBendHundreds;
+            }
+         break;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_ProgramChange
+
+   Selects the instrument to use on the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+void AL_ProgramChange
+   (
+   int channel,
+   int patch
+   )
+
+   {
+   // We only play channels 1 through 10
+   if ( channel > AL_MaxMidiChannel )
+      {
+      return;
+      }
+
+   Channel[ channel ].Timbre  = patch;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetPitchBend
+
+   Sets the pitch bend amount on the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+void AL_SetPitchBend
+   (
+   int channel,
+   int lsb,
+   int msb
+   )
+
+   {
+   int            pitchbend;
+   unsigned long  TotalBend;
+   VOICE         *voice;
+
+   // We only play channels 1 through 10
+   if ( channel > AL_MaxMidiChannel )
+      {
+      return;
+      }
+
+   pitchbend = lsb + ( msb << 8 );
+   Channel[ channel ].Pitchbend = pitchbend;
+
+   TotalBend  = pitchbend * Channel[ channel ].PitchBendRange;
+   TotalBend /= ( PITCHBEND_CENTER / FINETUNE_RANGE );
+
+   Channel[ channel ].KeyOffset  = ( int )( TotalBend / FINETUNE_RANGE );
+   Channel[ channel ].KeyOffset -= Channel[ channel ].PitchBendSemiTones;
+
+   Channel[ channel ].KeyDetune = ( unsigned )( TotalBend % FINETUNE_RANGE );
+
+   voice = Channel[ channel ].Voices.start;
+   while( voice != NULL )
+      {
+      AL_SetVoicePitch( voice->num );
+      voice = voice->next;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_DetectFM
+
+   Determines if an Adlib compatible card is installed in the machine.
+---------------------------------------------------------------------*/
+
+int AL_DetectFM
+   (
+   void
+   )
+
+   {
+   int status1;
+   int status2;
+   int i;
+
+   if ( USER_CheckParameter( NO_ADLIB_DETECTION ) )
+      {
+      return( FALSE );
+      }
+
+   AL_SendOutputToPort( ADLIB_PORT, 4, 0x60 );   // Reset T1 & T2
+   AL_SendOutputToPort( ADLIB_PORT, 4, 0x80 );   // Reset IRQ
+
+   status1 = inp( ADLIB_PORT );
+
+   AL_SendOutputToPort( ADLIB_PORT, 2, 0xff );   // Set timer 1
+   AL_SendOutputToPort( ADLIB_PORT, 4, 0x21 );   // Start timer 1
+
+   for( i = 100; i > 0; i-- )
+      {
+      inp( ADLIB_PORT );
+      }
+
+   status2 = inp( ADLIB_PORT );
+
+   AL_SendOutputToPort( ADLIB_PORT, 4, 0x60 );
+   AL_SendOutputToPort( ADLIB_PORT, 4, 0x80 );
+
+   return( ( ( status1 & 0xe0 ) == 0x00 ) && ( ( status2 & 0xe0 ) == 0xc0 ) );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void AL_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_Shutdown
+
+   Ends use of the sound card and resets it to a quiet state.
+---------------------------------------------------------------------*/
+
+void AL_Shutdown
+   (
+   void
+   )
+
+   {
+   AL_StereoOff();
+
+   AL_OPL3 = FALSE;
+   AL_ResetVoices();
+   AL_Reset();
+
+   DPMI_UnlockMemoryRegion( AL_LockStart, AL_LockEnd );
+   DPMI_Unlock( slotVoice );
+   DPMI_Unlock( VoiceLevel );
+   DPMI_Unlock( VoiceKsl );
+   DPMI_Unlock( offsetSlot );
+   DPMI_Unlock( NotePitch );
+   DPMI_Unlock( OctavePitch );
+   DPMI_Unlock( NoteMod12 );
+   DPMI_Unlock( NoteDiv12 );
+   DPMI_Unlock( VoiceReserved );
+   DPMI_Unlock( Voice );
+   DPMI_Unlock( Voice_Pool );
+   DPMI_Unlock( Channel );
+   DPMI_Unlock( AL_LeftPort );
+   DPMI_Unlock( AL_RightPort );
+   DPMI_Unlock( AL_Stereo );
+   DPMI_Unlock( AL_SendStereo );
+   DPMI_Unlock( AL_OPL3 );
+   DPMI_Unlock( AL_MaxMidiChannel );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetMaxMidiChannel
+
+   Sets the maximum MIDI channel that FM cards respond to.
+---------------------------------------------------------------------*/
+
+void AL_SetMaxMidiChannel
+   (
+   int channel
+   )
+
+   {
+   AL_MaxMidiChannel = channel - 1;
+   }
+
+/*---------------------------------------------------------------------
+   Function: AL_Init
+
+   Begins use of the sound card.
+---------------------------------------------------------------------*/
+
+int AL_Init
+   (
+   int soundcard
+   )
+
+   {
+   BLASTER_CONFIG Blaster;
+   int status;
+
+   status  = DPMI_LockMemoryRegion( AL_LockStart, AL_LockEnd );
+   status |= DPMI_Lock( slotVoice );
+   status |= DPMI_Lock( VoiceLevel );
+   status |= DPMI_Lock( VoiceKsl );
+   status |= DPMI_Lock( offsetSlot );
+   status |= DPMI_Lock( NotePitch );
+   status |= DPMI_Lock( OctavePitch );
+   status |= DPMI_Lock( NoteMod12 );
+   status |= DPMI_Lock( NoteDiv12 );
+   status |= DPMI_Lock( VoiceReserved );
+   status |= DPMI_Lock( Voice );
+   status |= DPMI_Lock( Voice_Pool );
+   status |= DPMI_Lock( Channel );
+   status |= DPMI_Lock( AL_LeftPort );
+   status |= DPMI_Lock( AL_RightPort );
+   status |= DPMI_Lock( AL_Stereo );
+   status |= DPMI_Lock( AL_SendStereo );
+   status |= DPMI_Lock( AL_OPL3 );
+   status |= DPMI_Lock( AL_MaxMidiChannel );
+
+   if ( status != DPMI_Ok )
+      {
+      return( AL_Error );
+      }
+
+   AL_Stereo = FALSE;
+   AL_OPL3   = FALSE;
+   AL_LeftPort = 0x388;
+   AL_RightPort = 0x388;
+
+   switch( soundcard )
+      {
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         AL_OPL3 = TRUE;
+         AL_LeftPort = 0x388;
+         AL_RightPort = 0x38A;
+         break;
+
+      case SoundBlaster :
+         status = BLASTER_GetCardSettings( &Blaster );
+         if ( status != BLASTER_Ok )
+            {
+            status = BLASTER_GetEnv( &Blaster );
+            if ( status != BLASTER_Ok )
+               {
+               break;
+               }
+            }
+
+         switch( Blaster.Type )
+            {
+            case SBPro2 :
+            case SB16 :
+               AL_OPL3 = TRUE;
+               AL_LeftPort  = Blaster.Address;
+               AL_RightPort = Blaster.Address + 2;
+               break;
+            }
+         break;
+      }
+// Temporarally commented out for ROTT.
+// Stereo FM seems to take too long on some computers and
+// causes the mouse driver to miss interrupts.
+
+/*
+   switch( soundcard )
+      {
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         AL_OPL3 = TRUE;
+         AL_Stereo = TRUE;
+         AL_LeftPort  = 0x388;
+         AL_RightPort = 0x38A;
+         break;
+
+      case SoundBlaster :
+         status = BLASTER_GetCardSettings( &Blaster );
+         if ( status != BLASTER_Ok )
+            {
+            status = BLASTER_GetEnv( &Blaster );
+            if ( status != BLASTER_Ok )
+               {
+               break;
+               }
+            }
+
+         switch( Blaster.Type )
+            {
+            case SBPro2 :
+            case SB16 :
+               AL_OPL3 = TRUE;
+               AL_Stereo = TRUE;
+               AL_LeftPort  = Blaster.Address;
+               AL_RightPort = Blaster.Address + 2;
+               break;
+
+            case SBPro :
+               AL_Stereo = TRUE;
+               AL_LeftPort  = Blaster.Address;
+               AL_RightPort = Blaster.Address + 2;
+               break;
+            }
+         break;
+      }
+*/
+
+   AL_CalcPitchInfo();
+   AL_Reset();
+   AL_ResetVoices();
+
+   return( AL_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_RegisterTimbreBank
+
+   Copies user supplied timbres over the default timbre bank.
+---------------------------------------------------------------------*/
+
+void AL_RegisterTimbreBank
+   (
+   unsigned char *timbres
+   )
+
+   {
+   int i;
+
+   for( i = 0; i < 256; i++ )
+      {
+      ADLIB_TimbreBank[ i ].SAVEK[ 0 ] = *( timbres++ );
+      ADLIB_TimbreBank[ i ].SAVEK[ 1 ] = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Level[ 0 ] = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Level[ 1 ] = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Env1[ 0 ]  = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Env1[ 1 ]  = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Env2[ 0 ]  = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Env2[ 1 ]  = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Wave[ 0 ]  = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Wave[ 1 ]  = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Feedback   = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Transpose  = *( signed char * )( timbres++ );
+      ADLIB_TimbreBank[ i ].Velocity   = *( signed char * )( timbres++ );
+      }
+   }
--- /dev/null
+++ b/rott/audiolib/al_midi.h
@@ -1,0 +1,58 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef __AL_MIDI_H
+#define __AL_MIDI_H
+
+enum AL_Errors
+   {
+   AL_Warning  = -2,
+   AL_Error    = -1,
+   AL_Ok       = 0,
+   };
+
+#define AL_MaxVolume             127
+#define AL_DefaultChannelVolume  90
+//#define AL_DefaultPitchBendRange 2
+#define AL_DefaultPitchBendRange 200
+
+#define ADLIB_PORT 0x388
+
+void AL_SendOutputToPort( int port, int reg, int data );
+void AL_SendOutput( int  voice, int reg, int data );
+void AL_StereoOn( void );
+void AL_StereoOff( void );
+int  AL_ReserveVoice( int voice );
+int  AL_ReleaseVoice( int voice );
+void AL_Shutdown( void );
+int  AL_Init( int soundcard );
+void AL_SetMaxMidiChannel( int channel );
+void AL_Reset( void );
+void AL_NoteOff( int channel, int key, int velocity );
+void AL_NoteOn( int channel, int key, int vel );
+//Turned off to test if it works with Watcom 10a
+//   #pragma aux AL_NoteOn frame;
+void AL_AllNotesOff( int channel );
+void AL_ControlChange( int channel, int type, int data );
+void AL_ProgramChange( int channel, int patch );
+void AL_SetPitchBend( int channel, int lsb, int msb );
+int  AL_DetectFM( void );
+void AL_RegisterTimbreBank( unsigned char *timbres );
+
+#endif
--- /dev/null
+++ b/rott/audiolib/assert.h
@@ -1,0 +1,45 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef    __ASSERT_H
+
+    #define    __ASSERT_H
+
+    #ifdef NDEBUG
+
+        #define ASSERT(f)
+
+    #else
+
+        #pragma aux _Assert aborts;          /* _Assert will not return */
+        extern void _Assert( char *strFile, unsigned  uLine ); /*prototype */
+
+        #define ASSERT(f)          \
+            if (f)                 \
+                ;                  \
+            else                   \
+                _Assert( __FILE__, __LINE__ )
+
+    #endif
+
+#else
+
+    #error Multiple definition of ASSERT()
+
+#endif
binary files /dev/null b/rott/audiolib/audiolib.a differ
--- /dev/null
+++ b/rott/audiolib/awe32.c
@@ -1,0 +1,540 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: AWE32.C
+
+   author: James R. Dose
+   date:   August 23, 1994
+
+   Cover functions for calling the AWE32 low-level library.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <conio.h>
+#include <string.h>
+#include "dpmi.h"
+#include "blaster.h"
+#include "ctaweapi.h"
+#include "awe32.h"
+
+#define _inp    inp
+#define _outp   outp
+
+/*  DSP defines  */
+#define MPU_ACK_OK          0xfe
+#define MPU_RESET_CMD       0xff
+#define MPU_ENTER_UART      0x3f
+
+static WORD wSBCBaseAddx;            /* Sound Blaster base address */
+static WORD wEMUBaseAddx;            /* EMU8000 subsystem base address */
+static WORD wMpuBaseAddx;            /* MPU401 base address */
+
+static unsigned short NoteFlags[ 128 ];
+
+/*  macros  */
+#define SBCPort( x )  ( ( x ) + wSBCBaseAddx )
+#define MPUPort( x )  ( ( x ) + wMpuBaseAddx )
+
+static SOUND_PACKET spSound =
+   {
+   0
+   };
+
+static LONG lBankSizes[ MAXBANKS ] =
+   {
+   0
+   };
+
+unsigned SetES( void );
+#pragma aux SetES = \
+        "xor eax, eax" \
+        "mov ax, es" \
+        "mov bx, ds" \
+        "mov es, bx" \
+        modify [ eax ebx ];
+
+void RestoreES( unsigned num );
+#pragma aux RestoreES = \
+        "mov  es, ax" \
+        parm [ eax ];
+
+int AWE32_ErrorCode = AWE32_Ok;
+
+#define AWE32_SetErrorCode( status ) \
+   AWE32_ErrorCode = ( status );
+
+
+/*---------------------------------------------------------------------
+   Function: AWE32_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *AWE32_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case AWE32_Warning :
+      case AWE32_Error :
+         ErrorString = AWE32_ErrorString( AWE32_ErrorCode );
+         break;
+
+      case AWE32_Ok :
+         ErrorString = "AWE32 ok.";
+         break;
+
+      case AWE32_SoundBlasterError :
+         ErrorString = BLASTER_ErrorString( BLASTER_Error );
+         break;
+
+      case AWE32_NotDetected :
+         ErrorString = "Could not detect AWE32.";
+         break;
+
+      case AWE32_UnableToInitialize :
+         ErrorString = "Unable to initialize AWE32.";
+
+      case AWE32_MPU401Error :
+         ErrorString = "MPU-401 initialization failed in AWE32.";
+         break;
+
+      case AWE32_DPMI_Error :
+         ErrorString = "DPMI Error in AWE32.";
+         break;
+
+      default :
+         ErrorString = "Unknown AWE32 error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define AWE32_LockStart AWE32_NoteOff
+
+
+void AWE32_NoteOff
+   (
+   int channel,
+   int key,
+   int velocity
+   )
+
+   {
+   unsigned temp;
+
+   temp = SetES();
+   awe32NoteOff( channel, key, velocity );
+   RestoreES( temp );
+   NoteFlags[ key ] ^= ( 1 << channel );
+   }
+
+void AWE32_NoteOn
+   (
+   int channel,
+   int key,
+   int velocity
+   )
+
+   {
+   unsigned temp;
+
+   temp = SetES();
+   awe32NoteOn( channel, key, velocity );
+   RestoreES( temp );
+   NoteFlags[ key ] |= ( 1 << channel );
+   }
+
+void AWE32_PolyAftertouch
+   (
+   int channel,
+   int key,
+   int pressure
+   )
+
+   {
+   unsigned temp;
+
+   temp = SetES();
+   awe32PolyKeyPressure( channel, key, pressure );
+   RestoreES( temp );
+   }
+
+void AWE32_ChannelAftertouch
+   (
+   int channel,
+   int pressure
+   )
+
+   {
+   unsigned temp;
+
+   temp = SetES();
+   awe32ChannelPressure( channel, pressure );
+   RestoreES( temp );
+   }
+
+void AWE32_ControlChange
+   (
+   int channel,
+   int number,
+   int value
+   )
+
+   {
+   unsigned temp;
+   int i;
+   unsigned channelmask;
+
+   temp = SetES();
+
+   if ( number == 0x7b )
+      {
+      channelmask = 1 << channel;
+      for( i = 0; i < 128; i++ )
+         {
+         if ( NoteFlags[ i ] & channelmask )
+            {
+            awe32NoteOff( channel, i, 0 );
+            NoteFlags[ i ] ^= channelmask;
+            }
+         }
+      }
+   else
+      {
+      awe32Controller( channel, number, value );
+      }
+   RestoreES( temp );
+   }
+
+void AWE32_ProgramChange
+   (
+   int channel,
+   int program
+   )
+
+   {
+   unsigned temp;
+
+   temp = SetES();
+   awe32ProgramChange( channel, program );
+   RestoreES( temp );
+   }
+
+void AWE32_PitchBend
+   (
+   int channel,
+   int lsb,
+   int msb
+   )
+
+   {
+   unsigned temp;
+
+   temp = SetES();
+   awe32PitchBend( channel, lsb, msb );
+   RestoreES( temp );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AWE32_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void AWE32_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*
+static int InitMPU
+   (
+   void
+   )
+
+   {
+   volatile DWORD dwCount;
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
+   _outp(MPUPort(1), MPU_RESET_CMD);
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
+   _inp(MPUPort(0));
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
+   _outp(MPUPort(1), MPU_RESET_CMD);
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
+   _inp(MPUPort(0));
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
+   _outp(MPUPort(1), MPU_ENTER_UART);
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
+   if (!dwCount) return TRUE;
+   if (_inp(MPUPort(0)) != MPU_ACK_OK) return TRUE;
+
+   // mask MPU-401 interrupt
+   _outp(SBCPort(0x4), 0x83);
+   _outp(SBCPort(0x5), _inp(SBCPort(0x5)) & ~0x04);
+
+   return FALSE;
+   }
+*/
+
+/*������������������������������������������������������������������������͸*/
+/*� ShutdownMPU                                                    �*/
+/*� Cleans up Sound Blaster to normal state.                               �*/
+/*������������������������������������������������������������������������;*/
+
+static void ShutdownMPU
+   (
+   void
+   )
+
+   {
+   volatile DWORD dwCount;
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
+   _outp(MPUPort(1), MPU_RESET_CMD);
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   _inp(MPUPort(0));
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
+   _outp(MPUPort(1), MPU_RESET_CMD);
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   _inp(MPUPort(0));
+   }
+
+
+/*������������������������������������������������������������������������͸*/
+/*� LoadSBK                                                                �*/
+/*������������������������������������������������������������������������;*/
+
+static void LoadSBK
+   (
+   void
+   )
+
+   {
+   /* use embeded preset objects */
+   spSound.bank_no = 0;            /* load as Bank 0 */
+   spSound.total_banks = 1;        /* use 1 bank first */
+   lBankSizes[ 0 ] = 0;            /* ram is not needed */
+
+   spSound.banksizes = lBankSizes;
+   awe32DefineBankSizes( &spSound );
+   awe32SoundPad.SPad1 = awe32SPad1Obj;
+   awe32SoundPad.SPad2 = awe32SPad2Obj;
+   awe32SoundPad.SPad3 = awe32SPad3Obj;
+   awe32SoundPad.SPad4 = awe32SPad4Obj;
+   awe32SoundPad.SPad5 = awe32SPad5Obj;
+   awe32SoundPad.SPad6 = awe32SPad6Obj;
+   awe32SoundPad.SPad7 = awe32SPad7Obj;
+   }
+
+
+int AWE32_Init
+   (
+   void
+   )
+
+   {
+   int status;
+   BLASTER_CONFIG Blaster;
+
+   wSBCBaseAddx = 0x220;
+   wEMUBaseAddx = 0x620;
+   wMpuBaseAddx = 0x330;
+
+   status = BLASTER_GetCardSettings( &Blaster );
+   if ( status != BLASTER_Ok )
+      {
+      status = BLASTER_GetEnv( &Blaster );
+      if ( status != BLASTER_Ok )
+         {
+         AWE32_SetErrorCode( AWE32_SoundBlasterError );
+         return( AWE32_Error );
+         }
+      }
+
+   wSBCBaseAddx = Blaster.Address;
+   if ( wSBCBaseAddx == UNDEFINED )
+      {
+      wSBCBaseAddx = 0x220;
+      }
+
+   wMpuBaseAddx = Blaster.Midi;
+   if ( wMpuBaseAddx == UNDEFINED )
+      {
+      wMpuBaseAddx = 0x330;
+      }
+
+   wEMUBaseAddx = Blaster.Emu;
+   if ( wEMUBaseAddx <= 0 )
+      {
+      wEMUBaseAddx = wSBCBaseAddx + 0x400;
+      }
+
+   status = awe32Detect( wEMUBaseAddx );
+   if ( status )
+      {
+      AWE32_SetErrorCode( AWE32_NotDetected );
+      return( AWE32_Error );
+      }
+
+   status = awe32InitHardware();
+   if ( status )
+      {
+      AWE32_SetErrorCode( AWE32_UnableToInitialize );
+      return( AWE32_Error );
+      }
+
+
+   status = awe32InitMIDI();
+   if ( status )
+      {
+      AWE32_Shutdown();
+      AWE32_SetErrorCode( AWE32_MPU401Error )
+      return( AWE32_Error );
+      }
+
+/*
+    status = InitMPU();
+   if ( status )
+      {
+      ShutdownMPU();
+      status = InitMPU();
+      if ( status )
+         {
+         ShutdownMPU();
+         status = InitMPU();
+         if ( status )
+            {
+            AWE32_Shutdown();
+            AWE32_SetErrorCode( AWE32_MPU401Error )
+            return( AWE32_Error );
+            }
+         }
+      }
+*/
+   status  = DPMI_LockMemoryRegion( AWE32_LockStart, AWE32_LockEnd );
+   status |= DPMI_Lock( wSBCBaseAddx );
+   status |= DPMI_Lock( wEMUBaseAddx );
+   status |= DPMI_Lock( wMpuBaseAddx );
+   status |= DPMI_Lock( spSound );
+   status |= DPMI_Lock( lBankSizes );
+   status |= DPMI_LockMemory( NoteFlags, sizeof( NoteFlags ) );
+
+   // Lock awe32 library
+   status  = DPMI_LockMemoryRegion( __midieng_code, __midieng_ecode );
+   status  = DPMI_LockMemoryRegion( __midieng_code(), __midieng_ecode() );
+   status  = DPMI_LockMemoryRegion( __nrpn_code, __nrpn_ecode );
+   status  = DPMI_LockMemoryRegion( __nrpn_code(), __nrpn_ecode() );
+   status  = DPMI_LockMemoryRegion( &__midivar_data, &__midivar_edata );
+   status  = DPMI_LockMemoryRegion( &__nrpnvar_data, &__nrpnvar_edata );
+   status  = DPMI_LockMemoryRegion( &__embed_data, &__embed_edata );
+
+   if ( status != DPMI_Ok )
+      {
+      ShutdownMPU();
+      awe32Terminate();
+      AWE32_SetErrorCode( AWE32_DPMI_Error );
+      return( AWE32_Error );
+      }
+
+   // Set the number of voices to use to 32
+   awe32NumG = 32;
+
+   awe32TotalPatchRam(&spSound);
+
+   LoadSBK();
+   awe32InitMIDI();
+   awe32InitNRPN();
+
+   memset( NoteFlags, 0, sizeof( NoteFlags ) );
+
+   return( AWE32_Ok );
+   }
+
+void AWE32_Shutdown
+   (
+   void
+   )
+
+   {
+   ShutdownMPU();
+   awe32Terminate();
+
+   DPMI_UnlockMemoryRegion( AWE32_LockStart, AWE32_LockEnd );
+   DPMI_Unlock( wSBCBaseAddx );
+   DPMI_Unlock( wEMUBaseAddx );
+   DPMI_Unlock( wMpuBaseAddx );
+   DPMI_Unlock( spSound );
+   DPMI_Unlock( lBankSizes );
+   DPMI_UnlockMemory( NoteFlags, sizeof( NoteFlags ) );
+
+   // Unlock awe32 library
+   DPMI_UnlockMemoryRegion( __midieng_code, __midieng_ecode );
+   DPMI_UnlockMemoryRegion( __midieng_code(), __midieng_ecode() );
+   DPMI_UnlockMemoryRegion( __nrpn_code, __nrpn_ecode );
+   DPMI_UnlockMemoryRegion( __nrpn_code(), __nrpn_ecode() );
+   DPMI_UnlockMemoryRegion( &__midivar_data, &__midivar_edata );
+   DPMI_UnlockMemoryRegion( &__nrpnvar_data, &__nrpnvar_edata );
+   DPMI_UnlockMemoryRegion( &__embed_data, &__embed_edata );
+   }
--- /dev/null
+++ b/rott/audiolib/awe32.h
@@ -1,0 +1,58 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: AWE32.H
+
+   author: James R. Dose
+   date:   August 23, 1994
+
+   Public header for AWE32.C  Cover functions for calling the
+   AWE32 low-level library.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __AWE32_H
+#define __AWE32_H
+
+enum AWE32_ERRORS
+   {
+   AWE32_Warning = -2,
+   AWE32_Error = -1,
+   AWE32_Ok = 0,
+   AWE32_SoundBlasterError,
+   AWE32_NotDetected,
+   AWE32_UnableToInitialize,
+   AWE32_MPU401Error,
+   AWE32_DPMI_Error
+   };
+
+char *AWE32_ErrorString( int ErrorNumber );
+int  AWE32_Init( void );
+void AWE32_Shutdown( void );
+void AWE32_NoteOff( int channel, int key, int velocity );
+void AWE32_NoteOn( int channel, int key, int velocity );
+void AWE32_PolyAftertouch( int channel, int key, int pressure );
+void AWE32_ChannelAftertouch( int channel, int pressure );
+void AWE32_ControlChange( int channel, int number, int value );
+void AWE32_ProgramChange( int channel, int program );
+void AWE32_PitchBend( int channel, int lsb, int msb );
+
+#endif
--- /dev/null
+++ b/rott/audiolib/blaster.c
@@ -1,0 +1,2330 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: BLASTER.C
+
+   author: James R. Dose
+   date:   February 4, 1994
+
+   Low level routines to support Sound Blaster, Sound Blaster Pro,
+   Sound Blaster 16, and compatible sound cards.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <dos.h>
+#include <conio.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "dpmi.h"
+#include "dma.h"
+#include "irq.h"
+#include "blaster.h"
+#include "_blaster.h"
+
+#define USESTACK
+
+const int BLASTER_Interrupts[ BLASTER_MaxIrq + 1 ]  =
+   {
+   INVALID, INVALID,     0xa,     0xb,
+   INVALID,     0xd, INVALID,     0xf,
+   INVALID, INVALID,    0x72,    0x73,
+      0x74, INVALID, INVALID,    0x77
+   };
+
+const int BLASTER_SampleSize[ BLASTER_MaxMixMode + 1 ] =
+   {
+   MONO_8BIT_SAMPLE_SIZE,  STEREO_8BIT_SAMPLE_SIZE,
+   MONO_16BIT_SAMPLE_SIZE, STEREO_16BIT_SAMPLE_SIZE
+   };
+
+const CARD_CAPABILITY BLASTER_CardConfig[ BLASTER_MaxCardType + 1 ] =
+   {
+      { FALSE, INVALID,      INVALID, INVALID, INVALID }, // Unsupported
+      {  TRUE,      NO,    MONO_8BIT,    4000,   23000 }, // SB 1.0
+      {  TRUE,     YES,  STEREO_8BIT,    4000,   44100 }, // SBPro
+      {  TRUE,      NO,    MONO_8BIT,    4000,   23000 }, // SB 2.xx
+      {  TRUE,     YES,  STEREO_8BIT,    4000,   44100 }, // SBPro 2
+      { FALSE, INVALID,      INVALID, INVALID, INVALID }, // Unsupported
+      {  TRUE,     YES, STEREO_16BIT,    5000,   44100 }, // SB16
+   };
+
+CARD_CAPABILITY BLASTER_Card;
+
+static void    ( __interrupt __far *BLASTER_OldInt )( void );
+
+BLASTER_CONFIG BLASTER_Config =
+   {
+   UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED
+   };
+
+static int BLASTER_Installed = FALSE;
+
+int BLASTER_Version;
+
+static char   *BLASTER_DMABuffer;
+static char   *BLASTER_DMABufferEnd;
+static char   *BLASTER_CurrentDMABuffer;
+static int     BLASTER_TotalDMABufferSize;
+
+static int      BLASTER_TransferLength   = 0;
+static int      BLASTER_MixMode          = BLASTER_DefaultMixMode;
+static int      BLASTER_SamplePacketSize = MONO_16BIT_SAMPLE_SIZE;
+static unsigned BLASTER_SampleRate       = BLASTER_DefaultSampleRate;
+
+static unsigned BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+
+volatile int   BLASTER_SoundPlaying;
+volatile int   BLASTER_SoundRecording;
+
+void ( *BLASTER_CallBack )( void );
+
+static int  BLASTER_IntController1Mask;
+static int  BLASTER_IntController2Mask;
+
+static int BLASTER_MixerAddress = UNDEFINED;
+static int BLASTER_MixerType    = 0;
+static int BLASTER_OriginalMidiVolumeLeft   = 255;
+static int BLASTER_OriginalMidiVolumeRight  = 255;
+static int BLASTER_OriginalVoiceVolumeLeft  = 255;
+static int BLASTER_OriginalVoiceVolumeRight = 255;
+
+static int BLASTER_WaveBlasterState = 0x0F;
+
+// adequate stack size
+#define kStackSize 2048
+
+static unsigned short StackSelector = NULL;
+static unsigned long  StackPointer;
+
+static unsigned short oldStackSelector;
+static unsigned long  oldStackPointer;
+
+// This is defined because we can't create local variables in a
+// function that switches stacks.
+static int GlobalStatus;
+
+// These declarations are necessary to use the inline assembly pragmas.
+
+extern void GetStack(unsigned short *selptr,unsigned long *stackptr);
+extern void SetStack(unsigned short selector,unsigned long stackptr);
+
+// This function will get the current stack selector and pointer and save
+// them off.
+#pragma aux GetStack =  \
+   "mov  [edi],esp"     \
+   "mov  ax,ss"         \
+   "mov  [esi],ax"      \
+   parm [esi] [edi]     \
+   modify [eax esi edi];
+
+// This function will set the stack selector and pointer to the specified
+// values.
+#pragma aux SetStack =  \
+   "mov  ss,ax"         \
+   "mov  esp,edx"       \
+   parm [ax] [edx]      \
+   modify [eax edx];
+
+int BLASTER_DMAChannel;
+
+int BLASTER_ErrorCode = BLASTER_Ok;
+
+#define BLASTER_SetErrorCode( status ) \
+   BLASTER_ErrorCode   = ( status );
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *BLASTER_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case BLASTER_Warning :
+      case BLASTER_Error :
+         ErrorString = BLASTER_ErrorString( BLASTER_ErrorCode );
+         break;
+
+      case BLASTER_Ok :
+         ErrorString = "Sound Blaster ok.";
+         break;
+
+      case BLASTER_EnvNotFound :
+         ErrorString = "BLASTER environment variable not set.";
+         break;
+
+      case BLASTER_AddrNotSet :
+         ErrorString = "Sound Blaster address not set.";
+         break;
+
+      case BLASTER_DMANotSet :
+         ErrorString = "Sound Blaster 8-bit DMA channel not set.";
+         break;
+
+      case BLASTER_DMA16NotSet :
+         ErrorString = "Sound Blaster 16-bit DMA channel not set.";
+         break;
+
+      case BLASTER_InvalidParameter :
+         ErrorString = "Invalid parameter in BLASTER environment variable.";
+         break;
+
+      case BLASTER_CardNotReady :
+         ErrorString = "Sound Blaster not responding on selected port.";
+         break;
+
+      case BLASTER_NoSoundPlaying :
+         ErrorString = "No sound playing on Sound Blaster.";
+         break;
+
+      case BLASTER_InvalidIrq :
+         ErrorString = "Invalid Sound Blaster Irq.";
+         break;
+
+      case BLASTER_UnableToSetIrq :
+         ErrorString = "Unable to set Sound Blaster IRQ.  Try selecting an IRQ of 7 or below.";
+         break;
+
+      case BLASTER_DmaError :
+         ErrorString = DMA_ErrorString( DMA_Error );
+         break;
+
+      case BLASTER_NoMixer :
+         ErrorString = "Mixer not available on selected Sound Blaster card.";
+         break;
+
+      case BLASTER_DPMI_Error :
+         ErrorString = "DPMI Error in Blaster.";
+         break;
+
+      case BLASTER_OutOfMemory :
+         ErrorString = "Out of conventional memory in Blaster.";
+         break;
+
+      default :
+         ErrorString = "Unknown Sound Blaster error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define BLASTER_LockStart BLASTER_EnableInterrupt
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_EnableInterrupt
+
+   Enables the triggering of the sound card interrupt.
+---------------------------------------------------------------------*/
+
+void BLASTER_EnableInterrupt
+   (
+   void
+   )
+
+   {
+   int Irq;
+   int mask;
+
+   // Unmask system interrupt
+   Irq  = BLASTER_Config.Interrupt;
+   if ( Irq < 8 )
+      {
+      mask = inp( 0x21 ) & ~( 1 << Irq );
+      outp( 0x21, mask  );
+      }
+   else
+      {
+      mask = inp( 0xA1 ) & ~( 1 << ( Irq - 8 ) );
+      outp( 0xA1, mask  );
+
+      mask = inp( 0x21 ) & ~( 1 << 2 );
+      outp( 0x21, mask  );
+      }
+
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DisableInterrupt
+
+   Disables the triggering of the sound card interrupt.
+---------------------------------------------------------------------*/
+
+void BLASTER_DisableInterrupt
+   (
+   void
+   )
+
+   {
+   int Irq;
+   int mask;
+
+   // Restore interrupt mask
+   Irq  = BLASTER_Config.Interrupt;
+   if ( Irq < 8 )
+      {
+      mask  = inp( 0x21 ) & ~( 1 << Irq );
+      mask |= BLASTER_IntController1Mask & ( 1 << Irq );
+      outp( 0x21, mask  );
+      }
+   else
+      {
+      mask  = inp( 0x21 ) & ~( 1 << 2 );
+      mask |= BLASTER_IntController1Mask & ( 1 << 2 );
+      outp( 0x21, mask  );
+
+      mask  = inp( 0xA1 ) & ~( 1 << ( Irq - 8 ) );
+      mask |= BLASTER_IntController2Mask & ( 1 << ( Irq - 8 ) );
+      outp( 0xA1, mask  );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_ServiceInterrupt
+
+   Handles interrupt generated by sound card at the end of a voice
+   transfer.  Calls the user supplied callback function.
+---------------------------------------------------------------------*/
+
+void __interrupt __far BLASTER_ServiceInterrupt
+   (
+   void
+   )
+
+   {
+   #ifdef USESTACK
+   // save stack
+   GetStack( &oldStackSelector, &oldStackPointer );
+
+   // set our stack
+   SetStack( StackSelector, StackPointer );
+   #endif
+
+   // Acknowledge interrupt
+   // Check if this is this an SB16 or newer
+   if ( BLASTER_Version >= DSP_Version4xx )
+      {
+      outp( BLASTER_Config.Address + BLASTER_MixerAddressPort,
+         MIXER_DSP4xxISR_Ack );
+
+      GlobalStatus = inp( BLASTER_Config.Address + BLASTER_MixerDataPort );
+
+      // Check if a 16-bit DMA interrupt occurred
+      if ( GlobalStatus & MIXER_16BITDMA_INT )
+         {
+         // Acknowledge 16-bit transfer interrupt
+         inp( BLASTER_Config.Address + BLASTER_16BitDMAAck );
+         }
+      else if ( GlobalStatus & MIXER_8BITDMA_INT )
+         {
+         inp( BLASTER_Config.Address + BLASTER_DataAvailablePort );
+         }
+      else
+         {
+         #ifdef USESTACK
+         // restore stack
+         SetStack( oldStackSelector, oldStackPointer );
+         #endif
+
+         // Wasn't our interrupt.  Call the old one.
+         _chain_intr( BLASTER_OldInt );
+         }
+      }
+   else
+      {
+      // Older card - can't detect if an interrupt occurred.
+      inp( BLASTER_Config.Address + BLASTER_DataAvailablePort );
+      }
+
+   // Keep track of current buffer
+   BLASTER_CurrentDMABuffer += BLASTER_TransferLength;
+
+   if ( BLASTER_CurrentDMABuffer >= BLASTER_DMABufferEnd )
+      {
+      BLASTER_CurrentDMABuffer = BLASTER_DMABuffer;
+      }
+
+   // Continue playback on cards without autoinit mode
+   if ( BLASTER_Version < DSP_Version2xx )
+      {
+      if ( BLASTER_SoundPlaying )
+         {
+         BLASTER_DSP1xx_BeginPlayback( BLASTER_TransferLength );
+         }
+
+      if ( BLASTER_SoundRecording )
+         {
+         BLASTER_DSP1xx_BeginRecord( BLASTER_TransferLength );
+         }
+      }
+
+   // Call the caller's callback function
+   if ( BLASTER_CallBack != NULL )
+      {
+      BLASTER_CallBack();
+      }
+
+   #ifdef USESTACK
+   // restore stack
+   SetStack( oldStackSelector, oldStackPointer );
+   #endif
+
+   // send EOI to Interrupt Controller
+   if ( BLASTER_Config.Interrupt > 7 )
+      {
+      outp( 0xA0, 0x20 );
+      }
+
+   outp( 0x20, 0x20 );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_WriteDSP
+
+   Writes a byte of data to the sound card's DSP.
+---------------------------------------------------------------------*/
+
+int BLASTER_WriteDSP
+   (
+   unsigned data
+   )
+
+   {
+   int      port;
+   unsigned count;
+   int      status;
+
+   port = BLASTER_Config.Address + BLASTER_WritePort;
+
+   status = BLASTER_Error;
+
+   count = 0xFFFF;
+
+   do
+      {
+      if ( ( inp( port ) & 0x80 ) == 0 )
+         {
+         outp( port, data );
+         status = BLASTER_Ok;
+         break;
+         }
+
+      count--;
+      }
+   while( count > 0 );
+
+   if ( status != BLASTER_Ok )
+      {
+      BLASTER_SetErrorCode( BLASTER_CardNotReady );
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_ReadDSP
+
+   Reads a byte of data from the sound card's DSP.
+---------------------------------------------------------------------*/
+
+int BLASTER_ReadDSP
+   (
+   void
+   )
+
+   {
+   int      port;
+   unsigned count;
+   int      status;
+
+   port = BLASTER_Config.Address + BLASTER_DataAvailablePort;
+
+   status = BLASTER_Error;
+
+   count = 0xFFFF;
+
+   do
+      {
+      if ( inp( port ) & 0x80 )
+         {
+         status = inp( BLASTER_Config.Address + BLASTER_ReadPort );
+         break;
+         }
+
+      count--;
+      }
+   while( count > 0 );
+
+   if ( status == BLASTER_Error )
+      {
+      BLASTER_SetErrorCode( BLASTER_CardNotReady );
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_ResetDSP
+
+   Sends a reset command to the sound card's Digital Signal Processor
+   (DSP), causing it to perform an initialization.
+---------------------------------------------------------------------*/
+
+int BLASTER_ResetDSP
+   (
+   void
+   )
+
+   {
+   volatile int count;
+   int port;
+   int status;
+
+   port = BLASTER_Config.Address + BLASTER_ResetPort;
+
+   status = BLASTER_CardNotReady;
+
+   outp( port, 1 );
+
+/* What the hell am I doing here?
+   count = 100;
+
+   do
+      {
+      if ( inp( port ) == 255 )
+         {
+         break;
+         }
+
+      count--;
+      }
+   while( count > 0 );
+*/
+
+   count = 0x100;
+   do
+      {
+      count--;
+      }
+   while( count > 0 );
+
+   outp( port, 0 );
+
+   count = 100;
+
+   do
+      {
+      if ( BLASTER_ReadDSP() == BLASTER_Ready )
+         {
+         status = BLASTER_Ok;
+         break;
+         }
+
+      count--;
+      }
+   while( count > 0 );
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetDSPVersion
+
+   Returns the version number of the sound card's DSP.
+---------------------------------------------------------------------*/
+
+int BLASTER_GetDSPVersion
+   (
+   void
+   )
+
+   {
+   int MajorVersion;
+   int MinorVersion;
+   int version;
+
+   BLASTER_WriteDSP( DSP_GetVersion );
+
+   MajorVersion   = BLASTER_ReadDSP();
+   MinorVersion   = BLASTER_ReadDSP();
+
+   if ( ( MajorVersion == BLASTER_Error ) ||
+      ( MinorVersion == BLASTER_Error ) )
+      {
+      BLASTER_SetErrorCode( BLASTER_CardNotReady );
+      return( BLASTER_Error );
+      }
+
+   version = ( MajorVersion << 8 ) + MinorVersion;
+
+   if ( version >= DSP_Version4xx )
+      {
+      BLASTER_Card.IsSupported     = TRUE;
+      BLASTER_Card.HasMixer        = YES;
+      BLASTER_Card.MaxMixMode      = STEREO_16BIT;
+      BLASTER_Card.MinSamplingRate = 5000;
+      BLASTER_Card.MaxSamplingRate = 44100;
+      BLASTER_MixerType = SB16;
+      }
+   else if ( version >= DSP_Version3xx )
+      {
+      BLASTER_Card.IsSupported     = TRUE;
+      BLASTER_Card.HasMixer        = YES;
+      BLASTER_Card.MaxMixMode      = STEREO_8BIT;
+      BLASTER_Card.MinSamplingRate = 4000;
+      BLASTER_Card.MaxSamplingRate = 44100;
+      BLASTER_MixerType = SBPro;
+      }
+   else if ( version >= DSP_Version2xx )
+      {
+      BLASTER_Card.IsSupported     = TRUE;
+      BLASTER_Card.HasMixer        = NO;
+      BLASTER_Card.MaxMixMode      = MONO_8BIT;
+      BLASTER_Card.MinSamplingRate = 4000;
+      BLASTER_Card.MaxSamplingRate = 23000;
+      BLASTER_MixerType = 0;
+      }
+   else
+      {
+      // DSP_Version1xx
+      BLASTER_Card.IsSupported     = TRUE;
+      BLASTER_Card.HasMixer        = NO;
+      BLASTER_Card.MaxMixMode      = MONO_8BIT;
+      BLASTER_Card.MinSamplingRate = 4000;
+      BLASTER_Card.MaxSamplingRate = 23000;
+      BLASTER_MixerType = 0;
+      }
+
+   return( version );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SpeakerOn
+
+   Enables output from the DAC.
+---------------------------------------------------------------------*/
+
+void BLASTER_SpeakerOn
+   (
+   void
+   )
+
+   {
+   BLASTER_WriteDSP( DSP_SpeakerOn );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SpeakerOff
+
+   Disables output from the DAC.
+---------------------------------------------------------------------*/
+
+void BLASTER_SpeakerOff
+   (
+   void
+   )
+
+   {
+   BLASTER_WriteDSP( DSP_SpeakerOff );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetPlaybackRate
+
+   Sets the rate at which the digitized sound will be played in
+   hertz.
+---------------------------------------------------------------------*/
+
+void BLASTER_SetPlaybackRate
+   (
+   unsigned rate
+   )
+
+   {
+   int LoByte;
+   int HiByte;
+
+   if ( BLASTER_Version < DSP_Version4xx )
+      {
+      int  timeconstant;
+      long ActualRate;
+
+      // Send sampling rate as time constant for older Sound
+      // Blaster compatible cards.
+
+      ActualRate = rate * BLASTER_SamplePacketSize;
+      if ( ActualRate < BLASTER_Card.MinSamplingRate )
+         {
+         rate = BLASTER_Card.MinSamplingRate / BLASTER_SamplePacketSize;
+         }
+
+      if ( ActualRate > BLASTER_Card.MaxSamplingRate )
+         {
+         rate = BLASTER_Card.MaxSamplingRate / BLASTER_SamplePacketSize;
+         }
+
+      timeconstant = ( int )CalcTimeConstant( rate, BLASTER_SamplePacketSize );
+
+      // Keep track of what the actual rate is
+      BLASTER_SampleRate  = ( unsigned )CalcSamplingRate( timeconstant );
+      BLASTER_SampleRate /= BLASTER_SamplePacketSize;
+
+      BLASTER_WriteDSP( DSP_SetTimeConstant );
+      BLASTER_WriteDSP( timeconstant );
+      }
+   else
+      {
+      // Send literal sampling rate for cards with DSP version
+      // 4.xx (Sound Blaster 16)
+
+      BLASTER_SampleRate = rate;
+
+      if ( BLASTER_SampleRate < BLASTER_Card.MinSamplingRate )
+         {
+         BLASTER_SampleRate = BLASTER_Card.MinSamplingRate;
+         }
+
+      if ( BLASTER_SampleRate > BLASTER_Card.MaxSamplingRate )
+         {
+         BLASTER_SampleRate = BLASTER_Card.MaxSamplingRate;
+         }
+
+      HiByte = hibyte( BLASTER_SampleRate );
+      LoByte = lobyte( BLASTER_SampleRate );
+
+      // Set playback rate
+      BLASTER_WriteDSP( DSP_Set_DA_Rate );
+      BLASTER_WriteDSP( HiByte );
+      BLASTER_WriteDSP( LoByte );
+
+      // Set recording rate
+      BLASTER_WriteDSP( DSP_Set_AD_Rate );
+      BLASTER_WriteDSP( HiByte );
+      BLASTER_WriteDSP( LoByte );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetPlaybackRate
+
+   Returns the rate at which the digitized sound will be played in
+   hertz.
+---------------------------------------------------------------------*/
+
+unsigned BLASTER_GetPlaybackRate
+   (
+   void
+   )
+
+   {
+   return( BLASTER_SampleRate );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetMixMode
+
+   Sets the sound card to play samples in mono or stereo.
+---------------------------------------------------------------------*/
+
+int BLASTER_SetMixMode
+   (
+   int mode
+   )
+
+   {
+   int   port;
+   int   data;
+   int   CardType;
+
+   CardType = BLASTER_Config.Type;
+
+   mode &= BLASTER_MaxMixMode;
+
+   if ( !( BLASTER_Card.MaxMixMode & STEREO ) )
+      {
+      mode &= ~STEREO;
+      }
+
+   if ( !( BLASTER_Card.MaxMixMode & SIXTEEN_BIT ) )
+      {
+      mode &= ~SIXTEEN_BIT;
+      }
+
+   BLASTER_MixMode = mode;
+   BLASTER_SamplePacketSize = BLASTER_SampleSize[ mode ];
+
+   // For the Sound Blaster Pro, we have to set the mixer chip
+   // to play mono or stereo samples.
+
+   if ( ( CardType == SBPro ) || ( CardType == SBPro2 ) )
+      {
+      port = BLASTER_Config.Address + BLASTER_MixerAddressPort;
+      outp( port, MIXER_SBProOutputSetting );
+
+      port = BLASTER_Config.Address + BLASTER_MixerDataPort;
+
+      // Get current mode
+      data = inp( port );
+
+      // set stereo mode bit
+      if ( mode & STEREO )
+         {
+         data |= MIXER_SBProStereoFlag;
+         }
+      else
+         {
+         data &= ~MIXER_SBProStereoFlag;
+         }
+
+      // set the mode
+      outp( port, data );
+
+      BLASTER_SetPlaybackRate( BLASTER_SampleRate );
+      }
+
+   return( mode );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_StopPlayback
+
+   Ends the DMA transfer of digitized sound to the sound card.
+---------------------------------------------------------------------*/
+
+void BLASTER_StopPlayback
+   (
+   void
+   )
+
+   {
+   int DmaChannel;
+
+   // Don't allow anymore interrupts
+   BLASTER_DisableInterrupt();
+
+   if ( BLASTER_HaltTransferCommand == DSP_Reset )
+      {
+      BLASTER_ResetDSP();
+      }
+   else
+      {
+      BLASTER_WriteDSP( BLASTER_HaltTransferCommand );
+      }
+
+   // Disable the DMA channel
+   if ( BLASTER_MixMode & SIXTEEN_BIT )
+      {
+      DmaChannel = BLASTER_Config.Dma16;
+      }
+   else
+      {
+      DmaChannel = BLASTER_Config.Dma8;
+      }
+   DMA_EndTransfer( DmaChannel );
+
+   // Turn off speaker
+   BLASTER_SpeakerOff();
+
+   BLASTER_SoundPlaying = FALSE;
+   BLASTER_SoundRecording = FALSE;
+
+   BLASTER_DMABuffer = NULL;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetupDMABuffer
+
+   Programs the DMAC for sound transfer.
+---------------------------------------------------------------------*/
+
+int BLASTER_SetupDMABuffer
+   (
+   char *BufferPtr,
+   int   BufferSize,
+   int   mode
+   )
+
+   {
+   int DmaChannel;
+   int DmaStatus;
+   int errorcode;
+
+   if ( BLASTER_MixMode & SIXTEEN_BIT )
+      {
+      DmaChannel = BLASTER_Config.Dma16;
+      errorcode  = BLASTER_DMA16NotSet;
+      }
+   else
+      {
+      DmaChannel = BLASTER_Config.Dma8;
+      errorcode  = BLASTER_DMANotSet;
+      }
+
+   if ( DmaChannel == UNDEFINED )
+      {
+      BLASTER_SetErrorCode( errorcode );
+      return( BLASTER_Error );
+      }
+
+   DmaStatus = DMA_SetupTransfer( DmaChannel, BufferPtr, BufferSize, mode );
+   if ( DmaStatus == DMA_Error )
+      {
+      BLASTER_SetErrorCode( BLASTER_DmaError );
+      return( BLASTER_Error );
+      }
+
+   BLASTER_DMAChannel = DmaChannel;
+
+   BLASTER_DMABuffer          = BufferPtr;
+   BLASTER_CurrentDMABuffer   = BufferPtr;
+   BLASTER_TotalDMABufferSize = BufferSize;
+   BLASTER_DMABufferEnd       = BufferPtr + BufferSize;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetCurrentPos
+
+   Returns the offset within the current sound being played.
+---------------------------------------------------------------------*/
+
+int BLASTER_GetCurrentPos
+   (
+   void
+   )
+
+   {
+   char *CurrentAddr;
+   int   DmaChannel;
+   int   offset;
+
+   if ( !BLASTER_SoundPlaying )
+      {
+      BLASTER_SetErrorCode( BLASTER_NoSoundPlaying );
+      return( BLASTER_Error );
+      }
+
+   if ( BLASTER_MixMode & SIXTEEN_BIT )
+      {
+      DmaChannel = BLASTER_Config.Dma16;
+      }
+   else
+      {
+      DmaChannel = BLASTER_Config.Dma8;
+      }
+
+   if ( DmaChannel == UNDEFINED )
+      {
+      BLASTER_SetErrorCode( BLASTER_DMANotSet );
+      return( BLASTER_Error );
+      }
+
+   CurrentAddr = DMA_GetCurrentPos( DmaChannel );
+
+   offset = ( int )( ( ( unsigned long )CurrentAddr ) -
+      ( ( unsigned long )BLASTER_CurrentDMABuffer ) );
+
+   if ( BLASTER_MixMode & SIXTEEN_BIT )
+      {
+      offset >>= 1;
+      }
+
+   if ( BLASTER_MixMode & STEREO )
+      {
+      offset >>= 1;
+      }
+
+   return( offset );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DSP1xx_BeginPlayback
+
+   Starts playback of digitized sound on cards compatible with DSP
+   version 1.xx.
+---------------------------------------------------------------------*/
+
+int BLASTER_DSP1xx_BeginPlayback
+   (
+   int length
+   )
+
+   {
+   int SampleLength;
+   int LoByte;
+   int HiByte;
+
+   SampleLength = length - 1;
+   HiByte = hibyte( SampleLength );
+   LoByte = lobyte( SampleLength );
+
+   // Program DSP to play sound
+   BLASTER_WriteDSP( DSP_Old8BitDAC );
+   BLASTER_WriteDSP( LoByte );
+   BLASTER_WriteDSP( HiByte );
+
+   BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+
+   BLASTER_SoundPlaying = TRUE;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DSP2xx_BeginPlayback
+
+   Starts playback of digitized sound on cards compatible with DSP
+   version 2.xx.
+---------------------------------------------------------------------*/
+
+int BLASTER_DSP2xx_BeginPlayback
+   (
+   int length
+   )
+
+   {
+   int SampleLength;
+   int LoByte;
+   int HiByte;
+
+   SampleLength = length - 1;
+   HiByte = hibyte( SampleLength );
+   LoByte = lobyte( SampleLength );
+
+   BLASTER_WriteDSP( DSP_SetBlockLength );
+   BLASTER_WriteDSP( LoByte );
+   BLASTER_WriteDSP( HiByte );
+
+   if ( ( BLASTER_Version >= DSP_Version201 ) && ( DSP_MaxNormalRate <
+      ( BLASTER_SampleRate * BLASTER_SamplePacketSize ) ) )
+      {
+      BLASTER_WriteDSP( DSP_8BitHighSpeedAutoInitMode );
+      BLASTER_HaltTransferCommand = DSP_Reset;
+      }
+   else
+      {
+      BLASTER_WriteDSP( DSP_8BitAutoInitMode );
+      BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+      }
+
+   BLASTER_SoundPlaying = TRUE;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DSP4xx_BeginPlayback
+
+   Starts playback of digitized sound on cards compatible with DSP
+   version 4.xx, such as the Sound Blaster 16.
+---------------------------------------------------------------------*/
+
+int BLASTER_DSP4xx_BeginPlayback
+   (
+   int length
+   )
+
+   {
+   int TransferCommand;
+   int TransferMode;
+   int SampleLength;
+   int LoByte;
+   int HiByte;
+
+   if ( BLASTER_MixMode & SIXTEEN_BIT )
+      {
+      TransferCommand = DSP_16BitDAC;
+      SampleLength = ( length / 2 ) - 1;
+      BLASTER_HaltTransferCommand = DSP_Halt16bitTransfer;
+      if ( BLASTER_MixMode & STEREO )
+         {
+         TransferMode = DSP_SignedStereoData;
+         }
+      else
+         {
+         TransferMode = DSP_SignedMonoData;
+         }
+      }
+   else
+      {
+      TransferCommand = DSP_8BitDAC;
+      SampleLength = length - 1;
+      BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+      if ( BLASTER_MixMode & STEREO )
+         {
+         TransferMode = DSP_UnsignedStereoData;
+         }
+      else
+         {
+         TransferMode = DSP_UnsignedMonoData;
+         }
+      }
+
+   HiByte = hibyte( SampleLength );
+   LoByte = lobyte( SampleLength );
+
+   // Program DSP to play sound
+   BLASTER_WriteDSP( TransferCommand );
+   BLASTER_WriteDSP( TransferMode );
+   BLASTER_WriteDSP( LoByte );
+   BLASTER_WriteDSP( HiByte );
+
+   BLASTER_SoundPlaying = TRUE;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_BeginBufferedPlayback
+
+   Begins multibuffered playback of digitized sound on the sound card.
+---------------------------------------------------------------------*/
+
+int BLASTER_BeginBufferedPlayback
+   (
+   char    *BufferStart,
+   int      BufferSize,
+   int      NumDivisions,
+   unsigned SampleRate,
+   int      MixMode,
+   void  ( *CallBackFunc )( void )
+   )
+
+   {
+   int DmaStatus;
+   int TransferLength;
+
+//JIM
+//   if ( BLASTER_SoundPlaying || BLASTER_SoundRecording )
+      {
+      BLASTER_StopPlayback();
+      }
+
+   BLASTER_SetMixMode( MixMode );
+
+   DmaStatus = BLASTER_SetupDMABuffer( BufferStart, BufferSize, DMA_AutoInitRead );
+   if ( DmaStatus == BLASTER_Error )
+      {
+      return( BLASTER_Error );
+      }
+
+   BLASTER_SetPlaybackRate( SampleRate );
+
+   BLASTER_SetCallBack( CallBackFunc );
+
+   BLASTER_EnableInterrupt();
+
+   // Turn on speaker
+   BLASTER_SpeakerOn();
+
+   TransferLength = BufferSize / NumDivisions;
+   BLASTER_TransferLength = TransferLength;
+
+   //  Program the sound card to start the transfer.
+   if ( BLASTER_Version < DSP_Version2xx )
+      {
+      BLASTER_DSP1xx_BeginPlayback( TransferLength );
+      }
+   else if ( BLASTER_Version < DSP_Version4xx )
+      {
+      BLASTER_DSP2xx_BeginPlayback( TransferLength );
+      }
+   else
+      {
+      BLASTER_DSP4xx_BeginPlayback( TransferLength );
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DSP4xx_BeginRecord
+
+   Starts recording of digitized sound on cards compatible with DSP
+   version 4.xx, such as the Sound Blaster 16.
+---------------------------------------------------------------------*/
+
+int BLASTER_DSP4xx_BeginRecord
+   (
+   int length
+   )
+
+   {
+   int TransferCommand;
+   int TransferMode;
+   int SampleLength;
+   int LoByte;
+   int HiByte;
+
+   TransferCommand = DSP_8BitADC;
+   SampleLength = length - 1;
+   BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+
+   TransferMode = DSP_UnsignedMonoData;
+
+   HiByte = hibyte( SampleLength );
+   LoByte = lobyte( SampleLength );
+
+   // Program DSP to play sound
+   BLASTER_WriteDSP( TransferCommand );
+   BLASTER_WriteDSP( TransferMode );
+   BLASTER_WriteDSP( LoByte );
+   BLASTER_WriteDSP( HiByte );
+
+   BLASTER_SoundRecording = TRUE;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DSP2xx_BeginRecord
+
+   Starts recording of digitized sound on cards compatible with DSP
+   version 2.xx.
+---------------------------------------------------------------------*/
+
+int BLASTER_DSP2xx_BeginRecord
+   (
+   int length
+   )
+
+   {
+   int SampleLength;
+   int LoByte;
+   int HiByte;
+
+   SampleLength = length - 1;
+   HiByte = hibyte( SampleLength );
+   LoByte = lobyte( SampleLength );
+
+   BLASTER_WriteDSP( DSP_SetBlockLength );
+   BLASTER_WriteDSP( LoByte );
+   BLASTER_WriteDSP( HiByte );
+
+   if ( ( BLASTER_Version >= DSP_Version201 ) && ( DSP_MaxNormalRate <
+      ( BLASTER_SampleRate * BLASTER_SamplePacketSize ) ) )
+      {
+      BLASTER_WriteDSP( DSP_8BitHighSpeedAutoInitRecord );
+      BLASTER_HaltTransferCommand = DSP_Reset;
+      }
+   else
+      {
+      BLASTER_WriteDSP( DSP_8BitAutoInitRecord );
+      BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+      }
+
+   BLASTER_SoundRecording = TRUE;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DSP1xx_BeginRecord
+
+   Starts recording of digitized sound on cards compatible with DSP
+   version 1.xx.
+---------------------------------------------------------------------*/
+
+int BLASTER_DSP1xx_BeginRecord
+   (
+   int length
+   )
+
+   {
+   int SampleLength;
+   int LoByte;
+   int HiByte;
+
+   SampleLength = length - 1;
+   HiByte = hibyte( SampleLength );
+   LoByte = lobyte( SampleLength );
+
+   // Program DSP to play sound
+   BLASTER_WriteDSP( DSP_Old8BitADC );
+   BLASTER_WriteDSP( LoByte );
+   BLASTER_WriteDSP( HiByte );
+
+   BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+
+   BLASTER_SoundRecording = TRUE;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_BeginBufferedRecord
+
+   Begins multibuffered recording of digitized sound on the sound card.
+---------------------------------------------------------------------*/
+
+int BLASTER_BeginBufferedRecord
+   (
+   char    *BufferStart,
+   int      BufferSize,
+   int      NumDivisions,
+   unsigned SampleRate,
+   int      MixMode,
+   void  ( *CallBackFunc )( void )
+   )
+
+   {
+   int DmaStatus;
+   int TransferLength;
+
+//JIM
+//   if ( BLASTER_SoundPlaying || BLASTER_SoundRecording )
+      {
+      BLASTER_StopPlayback();
+      }
+
+   BLASTER_SetMixMode( MixMode );
+
+   DmaStatus = BLASTER_SetupDMABuffer( BufferStart, BufferSize, DMA_AutoInitWrite );
+   if ( DmaStatus == BLASTER_Error )
+      {
+      return( BLASTER_Error );
+      }
+
+   BLASTER_SetPlaybackRate( SampleRate );
+
+   BLASTER_SetCallBack( CallBackFunc );
+
+   BLASTER_EnableInterrupt();
+
+   // Turn off speaker
+   BLASTER_SpeakerOff();
+
+   TransferLength = BufferSize / NumDivisions;
+   BLASTER_TransferLength = TransferLength;
+
+   //  Program the sound card to start the transfer.
+   if ( BLASTER_Version < DSP_Version2xx )
+      {
+      BLASTER_DSP1xx_BeginRecord( TransferLength );
+      }
+   else if ( BLASTER_Version < DSP_Version4xx )
+      {
+      BLASTER_DSP2xx_BeginRecord( TransferLength );
+      }
+   else
+      {
+      BLASTER_DSP4xx_BeginRecord( TransferLength );
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_WriteMixer
+
+   Writes a byte of data to the Sound Blaster's mixer chip.
+---------------------------------------------------------------------*/
+
+void BLASTER_WriteMixer
+   (
+   int reg,
+   int data
+   )
+
+   {
+   outp( BLASTER_MixerAddress + BLASTER_MixerAddressPort, reg );
+   outp( BLASTER_MixerAddress + BLASTER_MixerDataPort, data );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_ReadMixer
+
+   Reads a byte of data from the Sound Blaster's mixer chip.
+---------------------------------------------------------------------*/
+
+int BLASTER_ReadMixer
+   (
+   int reg
+   )
+
+   {
+   int data;
+
+   outp( BLASTER_MixerAddress + BLASTER_MixerAddressPort, reg );
+   data = inp( BLASTER_MixerAddress + BLASTER_MixerDataPort );
+   return( data );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetVoiceVolume
+
+   Reads the average volume of the digitized sound channel from the
+   Sound Blaster's mixer chip.
+---------------------------------------------------------------------*/
+
+int BLASTER_GetVoiceVolume
+   (
+   void
+   )
+
+   {
+   int volume;
+   int left;
+   int right;
+
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         left   = BLASTER_ReadMixer( MIXER_SBProVoice );
+         right  = ( left & 0x0f ) << 4;
+         left  &= 0xf0;
+         volume = ( left + right ) / 2;
+         break;
+
+      case SB16 :
+         left  = BLASTER_ReadMixer( MIXER_SB16VoiceLeft );
+         right = BLASTER_ReadMixer( MIXER_SB16VoiceRight );
+         volume = ( left + right ) / 2;
+         break;
+
+      default :
+         BLASTER_SetErrorCode( BLASTER_NoMixer );
+         volume = BLASTER_Error;
+      }
+
+   return( volume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetVoiceVolume
+
+   Sets the volume of the digitized sound channel on the Sound
+   Blaster's mixer chip.
+---------------------------------------------------------------------*/
+
+int BLASTER_SetVoiceVolume
+   (
+   int volume
+   )
+
+   {
+   int data;
+   int status;
+
+   volume = min( 255, volume );
+   volume = max( 0, volume );
+
+   status = BLASTER_Ok;
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         data = ( volume & 0xf0 ) + ( volume >> 4 );
+         BLASTER_WriteMixer( MIXER_SBProVoice, data );
+         break;
+
+      case SB16 :
+         BLASTER_WriteMixer( MIXER_SB16VoiceLeft, volume & 0xf8 );
+         BLASTER_WriteMixer( MIXER_SB16VoiceRight, volume & 0xf8 );
+         break;
+
+      default :
+         BLASTER_SetErrorCode( BLASTER_NoMixer );
+         status = BLASTER_Error;
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetMidiVolume
+
+   Reads the average volume of the Midi sound channel from the
+   Sound Blaster's mixer chip.
+---------------------------------------------------------------------*/
+
+int BLASTER_GetMidiVolume
+   (
+   void
+   )
+
+   {
+   int volume;
+   int left;
+   int right;
+
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         left   = BLASTER_ReadMixer( MIXER_SBProMidi );
+         right  = ( left & 0x0f ) << 4;
+         left  &= 0xf0;
+         volume = ( left + right ) / 2;
+         break;
+
+      case SB16 :
+         left  = BLASTER_ReadMixer( MIXER_SB16MidiLeft );
+         right = BLASTER_ReadMixer( MIXER_SB16MidiRight );
+         volume = ( left + right ) / 2;
+         break;
+
+      default :
+         BLASTER_SetErrorCode( BLASTER_NoMixer );
+         volume = BLASTER_Error;
+      }
+
+   return( volume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetMidiVolume
+
+   Sets the volume of the Midi sound channel on the Sound
+   Blaster's mixer chip.
+---------------------------------------------------------------------*/
+
+int BLASTER_SetMidiVolume
+   (
+   int volume
+   )
+
+   {
+   int data;
+   int status;
+
+   volume = min( 255, volume );
+   volume = max( 0, volume );
+
+   status = BLASTER_Ok;
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         data = ( volume & 0xf0 ) + ( volume >> 4 );
+         BLASTER_WriteMixer( MIXER_SBProMidi, data );
+         break;
+
+      case SB16 :
+         BLASTER_WriteMixer( MIXER_SB16MidiLeft, volume & 0xf8 );
+         BLASTER_WriteMixer( MIXER_SB16MidiRight, volume & 0xf8 );
+         break;
+
+      default :
+         BLASTER_SetErrorCode( BLASTER_NoMixer );
+         status = BLASTER_Error;
+      }
+
+   return( status );
+   }
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_CardHasMixer
+
+   Checks if the selected Sound Blaster card has a mixer.
+---------------------------------------------------------------------*/
+
+int BLASTER_CardHasMixer
+   (
+   void
+   )
+
+   {
+   return( BLASTER_Card.HasMixer );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SaveVoiceVolume
+
+   Saves the user's voice mixer settings.
+---------------------------------------------------------------------*/
+
+void BLASTER_SaveVoiceVolume
+   (
+   void
+   )
+
+   {
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         BLASTER_OriginalVoiceVolumeLeft =
+            BLASTER_ReadMixer( MIXER_SBProVoice );
+         break;
+
+      case SB16 :
+         BLASTER_OriginalVoiceVolumeLeft =
+            BLASTER_ReadMixer( MIXER_SB16VoiceLeft );
+         BLASTER_OriginalVoiceVolumeRight =
+            BLASTER_ReadMixer( MIXER_SB16VoiceRight );
+         break;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_RestoreVoiceVolume
+
+   Restores the user's voice mixer settings.
+---------------------------------------------------------------------*/
+
+void BLASTER_RestoreVoiceVolume
+   (
+   void
+   )
+
+   {
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         BLASTER_WriteMixer( MIXER_SBProVoice,
+            BLASTER_OriginalVoiceVolumeLeft );
+         break;
+
+      case SB16 :
+         BLASTER_WriteMixer( MIXER_SB16VoiceLeft,
+            BLASTER_OriginalVoiceVolumeLeft );
+         BLASTER_WriteMixer( MIXER_SB16VoiceRight,
+            BLASTER_OriginalVoiceVolumeRight );
+         break;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SaveMidiVolume
+
+   Saves the user's FM mixer settings.
+---------------------------------------------------------------------*/
+
+void BLASTER_SaveMidiVolume
+   (
+   void
+   )
+
+   {
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         BLASTER_OriginalMidiVolumeLeft =
+            BLASTER_ReadMixer( MIXER_SBProMidi );
+         break;
+
+      case SB16 :
+         BLASTER_OriginalMidiVolumeLeft =
+            BLASTER_ReadMixer( MIXER_SB16MidiLeft );
+         BLASTER_OriginalMidiVolumeRight =
+            BLASTER_ReadMixer( MIXER_SB16MidiRight );
+         break;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_RestoreMidiVolume
+
+   Restores the user's FM mixer settings.
+---------------------------------------------------------------------*/
+
+void BLASTER_RestoreMidiVolume
+   (
+   void
+   )
+
+   {
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         BLASTER_WriteMixer( MIXER_SBProMidi,
+            BLASTER_OriginalMidiVolumeLeft );
+         break;
+
+      case SB16 :
+         BLASTER_WriteMixer( MIXER_SB16MidiLeft,
+            BLASTER_OriginalMidiVolumeLeft );
+         BLASTER_WriteMixer( MIXER_SB16MidiRight,
+            BLASTER_OriginalMidiVolumeRight );
+         break;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetEnv
+
+   Retrieves the BLASTER environment settings and returns them to
+   the caller.
+---------------------------------------------------------------------*/
+
+int BLASTER_GetEnv
+   (
+   BLASTER_CONFIG *Config
+   )
+
+   {
+   char *Blaster;
+   char parameter;
+
+   Config->Address   = UNDEFINED;
+   Config->Type      = UNDEFINED;
+   Config->Interrupt = UNDEFINED;
+   Config->Dma8      = UNDEFINED;
+   Config->Dma16     = UNDEFINED;
+   Config->Midi      = UNDEFINED;
+   Config->Emu       = UNDEFINED;
+
+   Blaster = getenv( "BLASTER" );
+   if ( Blaster == NULL )
+      {
+      BLASTER_SetErrorCode( BLASTER_EnvNotFound );
+      return( BLASTER_Error );
+      }
+
+   while( *Blaster != 0 )
+      {
+      if ( *Blaster == ' ' )
+         {
+         Blaster++;
+         continue;
+         }
+
+      parameter = toupper( *Blaster );
+      Blaster++;
+
+      if ( !isxdigit( *Blaster ) )
+         {
+         BLASTER_SetErrorCode( BLASTER_InvalidParameter );
+         return( BLASTER_Error );
+         }
+
+      switch( parameter )
+         {
+         case BlasterEnv_Address :
+            sscanf( Blaster, "%x", &Config->Address );
+            break;
+         case BlasterEnv_Interrupt :
+            sscanf( Blaster, "%d", &Config->Interrupt );
+            break;
+         case BlasterEnv_8bitDma :
+            sscanf( Blaster, "%d", &Config->Dma8 );
+            break;
+         case BlasterEnv_Type :
+            sscanf( Blaster, "%d", &Config->Type );
+            break;
+         case BlasterEnv_16bitDma :
+            sscanf( Blaster, "%d", &Config->Dma16 );
+            break;
+         case BlasterEnv_Midi :
+            sscanf( Blaster, "%x", &Config->Midi );
+            break;
+         case BlasterEnv_EmuAddress :
+            sscanf( Blaster, "%x", &Config->Emu );
+            break;
+         default  :
+            // Skip the offending data
+            // sscanf( Blaster, "%*s" );
+            break;
+         }
+
+      while( isxdigit( *Blaster ) )
+         {
+         Blaster++;
+         }
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetCardSettings
+
+   Sets up the sound card's parameters.
+---------------------------------------------------------------------*/
+
+int BLASTER_SetCardSettings
+   (
+   BLASTER_CONFIG Config
+   )
+
+   {
+   if ( BLASTER_Installed )
+      {
+      BLASTER_Shutdown();
+      }
+
+   BLASTER_Config.Address   = Config.Address;
+   BLASTER_Config.Type      = Config.Type;
+   BLASTER_Config.Interrupt = Config.Interrupt;
+   BLASTER_Config.Dma8      = Config.Dma8;
+   BLASTER_Config.Dma16     = Config.Dma16;
+   BLASTER_Config.Midi      = Config.Midi;
+   BLASTER_Config.Emu       = Config.Emu;
+   BLASTER_MixerAddress     = Config.Address;
+   BLASTER_MixerType        = Config.Type;
+
+   if ( BLASTER_Config.Emu == UNDEFINED )
+      {
+      BLASTER_Config.Emu = BLASTER_Config.Address + 0x400;
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetCardSettings
+
+   Sets up the sound card's parameters.
+---------------------------------------------------------------------*/
+
+int BLASTER_GetCardSettings
+   (
+   BLASTER_CONFIG *Config
+   )
+
+   {
+   if ( BLASTER_Config.Address == UNDEFINED )
+      {
+      return( BLASTER_Warning );
+      }
+   else
+      {
+      Config->Address   = BLASTER_Config.Address;
+      Config->Type      = BLASTER_Config.Type;
+      Config->Interrupt = BLASTER_Config.Interrupt;
+      Config->Dma8      = BLASTER_Config.Dma8;
+      Config->Dma16     = BLASTER_Config.Dma16;
+      Config->Midi      = BLASTER_Config.Midi;
+      Config->Emu       = BLASTER_Config.Emu;
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetCardInfo
+
+   Returns the maximum number of bits that can represent a sample
+   (8 or 16) and the number of channels (1 for mono, 2 for stereo).
+---------------------------------------------------------------------*/
+
+int BLASTER_GetCardInfo
+   (
+   int *MaxSampleBits,
+   int *MaxChannels
+   )
+
+   {
+   if ( BLASTER_Card.MaxMixMode & STEREO )
+      {
+      *MaxChannels = 2;
+      }
+   else
+      {
+      *MaxChannels = 1;
+      }
+
+   if ( BLASTER_Card.MaxMixMode & SIXTEEN_BIT )
+      {
+      *MaxSampleBits = 16;
+      }
+   else
+      {
+      *MaxSampleBits = 8;
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetCallBack
+
+   Specifies the user function to call at the end of a sound transfer.
+---------------------------------------------------------------------*/
+
+void BLASTER_SetCallBack
+   (
+   void ( *func )( void )
+   )
+
+   {
+   BLASTER_CallBack = func;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void BLASTER_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_UnlockMemory
+
+   Unlocks all neccessary data.
+---------------------------------------------------------------------*/
+
+void BLASTER_UnlockMemory
+   (
+   void
+   )
+
+   {
+   DPMI_UnlockMemoryRegion( BLASTER_LockStart, BLASTER_LockEnd );
+   DPMI_UnlockMemory( ( void * )&BLASTER_Interrupts[ 0 ],
+      sizeof( BLASTER_Interrupts ) );
+   DPMI_UnlockMemory( ( void * )&BLASTER_SampleSize[ 0 ],
+      sizeof( BLASTER_SampleSize ) );
+   DPMI_Unlock( BLASTER_Card );
+   DPMI_Unlock( BLASTER_OldInt );
+   DPMI_Unlock( BLASTER_Config );
+   DPMI_Unlock( BLASTER_Installed );
+   DPMI_Unlock( BLASTER_Version );
+   DPMI_Unlock( BLASTER_DMABuffer );
+   DPMI_Unlock( BLASTER_DMABufferEnd );
+   DPMI_Unlock( BLASTER_CurrentDMABuffer );
+   DPMI_Unlock( BLASTER_TotalDMABufferSize );
+   DPMI_Unlock( BLASTER_TransferLength );
+   DPMI_Unlock( BLASTER_MixMode );
+   DPMI_Unlock( BLASTER_SamplePacketSize );
+   DPMI_Unlock( BLASTER_SampleRate );
+   DPMI_Unlock( BLASTER_HaltTransferCommand );
+   DPMI_Unlock( ( int )BLASTER_SoundPlaying );
+   DPMI_Unlock( ( int )BLASTER_SoundRecording );
+   DPMI_Unlock( BLASTER_CallBack );
+   DPMI_Unlock( BLASTER_IntController1Mask );
+   DPMI_Unlock( BLASTER_IntController2Mask );
+   DPMI_Unlock( BLASTER_MixerAddress );
+   DPMI_Unlock( BLASTER_MixerType );
+   DPMI_Unlock( BLASTER_OriginalMidiVolumeLeft );
+   DPMI_Unlock( BLASTER_OriginalMidiVolumeRight );
+   DPMI_Unlock( BLASTER_OriginalVoiceVolumeLeft );
+   DPMI_Unlock( BLASTER_OriginalVoiceVolumeRight );
+   DPMI_Unlock( GlobalStatus );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_LockMemory
+
+   Locks all neccessary data.
+---------------------------------------------------------------------*/
+
+int BLASTER_LockMemory
+   (
+   void
+   )
+
+   {
+   int status;
+
+   status  = DPMI_LockMemoryRegion( BLASTER_LockStart, BLASTER_LockEnd );
+   status |= DPMI_LockMemory( ( void * )&BLASTER_Interrupts[ 0 ],
+      sizeof( BLASTER_Interrupts ) );
+   status |= DPMI_LockMemory( ( void * )&BLASTER_SampleSize[ 0 ],
+      sizeof( BLASTER_SampleSize ) );
+   status |= DPMI_Lock( BLASTER_Card );
+   status |= DPMI_Lock( BLASTER_OldInt );
+   status |= DPMI_Lock( BLASTER_Config );
+   status |= DPMI_Lock( BLASTER_Installed );
+   status |= DPMI_Lock( BLASTER_Version );
+   status |= DPMI_Lock( BLASTER_DMABuffer );
+   status |= DPMI_Lock( BLASTER_DMABufferEnd );
+   status |= DPMI_Lock( BLASTER_CurrentDMABuffer );
+   status |= DPMI_Lock( BLASTER_TotalDMABufferSize );
+   status |= DPMI_Lock( BLASTER_TransferLength );
+   status |= DPMI_Lock( BLASTER_MixMode );
+   status |= DPMI_Lock( BLASTER_SamplePacketSize );
+   status |= DPMI_Lock( BLASTER_SampleRate );
+   status |= DPMI_Lock( BLASTER_HaltTransferCommand );
+   status |= DPMI_Lock( ( ( int )BLASTER_SoundPlaying ) );
+   status |= DPMI_Lock( ( ( int )BLASTER_SoundRecording ) );
+   status |= DPMI_Lock( BLASTER_CallBack );
+   status |= DPMI_Lock( BLASTER_IntController1Mask );
+   status |= DPMI_Lock( BLASTER_IntController2Mask );
+   status |= DPMI_Lock( BLASTER_MixerAddress );
+   status |= DPMI_Lock( BLASTER_MixerType );
+   status |= DPMI_Lock( BLASTER_OriginalMidiVolumeLeft );
+   status |= DPMI_Lock( BLASTER_OriginalMidiVolumeRight );
+   status |= DPMI_Lock( BLASTER_OriginalVoiceVolumeLeft );
+   status |= DPMI_Lock( BLASTER_OriginalVoiceVolumeRight );
+   status |= DPMI_Lock( GlobalStatus );
+
+   if ( status != DPMI_Ok )
+      {
+      BLASTER_UnlockMemory();
+      BLASTER_SetErrorCode( BLASTER_DPMI_Error );
+      return( BLASTER_Error );
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: allocateTimerStack
+
+   Allocate a block of memory from conventional (low) memory and return
+   the selector (which can go directly into a segment register) of the
+   memory block or 0 if an error occured.
+---------------------------------------------------------------------*/
+
+static unsigned short allocateTimerStack
+   (
+   unsigned short size
+   )
+
+   {
+   union REGS regs;
+
+   // clear all registers
+   memset( &regs, 0, sizeof( regs ) );
+
+   // DPMI allocate conventional memory
+   regs.w.ax = 0x100;
+
+   // size in paragraphs
+   regs.w.bx = ( size + 15 ) / 16;
+
+   int386( 0x31, &regs, &regs );
+   if (!regs.w.cflag)
+      {
+      // DPMI call returns selector in dx
+      // (ax contains real mode segment
+      // which is ignored here)
+
+      return( regs.w.dx );
+      }
+
+   // Couldn't allocate memory.
+   return( NULL );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: deallocateTimerStack
+
+   Deallocate a block of conventional (low) memory given a selector to
+   it.  Assumes the block was allocated with DPMI function 0x100.
+---------------------------------------------------------------------*/
+
+static void deallocateTimerStack
+   (
+   unsigned short selector
+   )
+
+   {
+   union REGS regs;
+
+   if ( selector != NULL )
+      {
+      // clear all registers
+      memset( &regs, 0, sizeof( regs ) );
+
+      regs.w.ax = 0x101;
+      regs.w.dx = selector;
+      int386( 0x31, &regs, &regs );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetupWaveBlaster
+
+   Allows the WaveBlaster to play music while the Sound Blaster 16
+   plays digital sound.
+---------------------------------------------------------------------*/
+
+void BLASTER_SetupWaveBlaster
+   (
+   void
+   )
+
+   {
+
+   if ( BLASTER_MixerType == SB16 )
+      {
+      // Disable MPU401 interrupts.  If they are not disabled,
+      // the SB16 will not produce sound or music.
+      BLASTER_WaveBlasterState = BLASTER_ReadMixer( MIXER_DSP4xxISR_Enable );
+      BLASTER_WriteMixer( MIXER_DSP4xxISR_Enable, MIXER_DisableMPU401Interrupts );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_ShutdownWaveBlaster
+
+   Restores WaveBlaster mixer to original state.
+---------------------------------------------------------------------*/
+
+void BLASTER_ShutdownWaveBlaster
+   (
+   void
+   )
+
+   {
+   if ( BLASTER_MixerType == SB16 )
+      {
+      // Restore the state of MPU401 interrupts.  If they are not disabled,
+      // the SB16 will not produce sound or music.
+      BLASTER_WriteMixer( MIXER_DSP4xxISR_Enable, BLASTER_WaveBlasterState );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_Init
+
+   Initializes the sound card and prepares the module to play
+   digitized sounds.
+---------------------------------------------------------------------*/
+
+int BLASTER_Init
+   (
+   void
+   )
+
+   {
+   int Irq;
+   int Interrupt;
+   int status;
+
+   if ( BLASTER_Installed )
+      {
+      BLASTER_Shutdown();
+      }
+
+   if ( BLASTER_Config.Address == UNDEFINED )
+      {
+      BLASTER_SetErrorCode( BLASTER_AddrNotSet );
+      return( BLASTER_Error );
+      }
+
+   // Save the interrupt masks
+   BLASTER_IntController1Mask = inp( 0x21 );
+   BLASTER_IntController2Mask = inp( 0xA1 );
+
+   status = BLASTER_ResetDSP();
+   if ( status == BLASTER_Ok )
+      {
+      BLASTER_SaveVoiceVolume();
+
+      BLASTER_SoundPlaying = FALSE;
+
+      BLASTER_SetCallBack( NULL );
+
+      BLASTER_DMABuffer = NULL;
+
+      BLASTER_Version = BLASTER_GetDSPVersion();
+
+      BLASTER_SetPlaybackRate( BLASTER_DefaultSampleRate );
+      BLASTER_SetMixMode( BLASTER_DefaultMixMode );
+
+      if ( BLASTER_Config.Dma16 != UNDEFINED )
+         {
+         status = DMA_VerifyChannel( BLASTER_Config.Dma16 );
+         if ( status == DMA_Error )
+            {
+            BLASTER_SetErrorCode( BLASTER_DmaError );
+            return( BLASTER_Error );
+            }
+         }
+
+      if ( BLASTER_Config.Dma8 != UNDEFINED )
+         {
+         status = DMA_VerifyChannel( BLASTER_Config.Dma8 );
+         if ( status == DMA_Error )
+            {
+            BLASTER_SetErrorCode( BLASTER_DmaError );
+            return( BLASTER_Error );
+            }
+         }
+
+      // Install our interrupt handler
+      Irq = BLASTER_Config.Interrupt;
+      if ( !VALID_IRQ( Irq ) )
+         {
+         BLASTER_SetErrorCode( BLASTER_InvalidIrq );
+         return( BLASTER_Error );
+         }
+
+      Interrupt = BLASTER_Interrupts[ Irq ];
+      if ( Interrupt == INVALID )
+         {
+         BLASTER_SetErrorCode( BLASTER_InvalidIrq );
+         return( BLASTER_Error );
+         }
+
+      status = BLASTER_LockMemory();
+      if ( status != BLASTER_Ok )
+         {
+         BLASTER_UnlockMemory();
+         return( status );
+         }
+
+      StackSelector = allocateTimerStack( kStackSize );
+      if ( StackSelector == NULL )
+         {
+         BLASTER_UnlockMemory();
+         BLASTER_SetErrorCode( BLASTER_OutOfMemory );
+         return( BLASTER_Error );
+         }
+
+      // Leave a little room at top of stack just for the hell of it...
+      StackPointer = kStackSize - sizeof( long );
+
+      BLASTER_OldInt = _dos_getvect( Interrupt );
+      if ( Irq < 8 )
+         {
+         _dos_setvect( Interrupt, BLASTER_ServiceInterrupt );
+         }
+      else
+         {
+         status = IRQ_SetVector( Interrupt, BLASTER_ServiceInterrupt );
+         if ( status != IRQ_Ok )
+            {
+            BLASTER_UnlockMemory();
+            deallocateTimerStack( StackSelector );
+            StackSelector = NULL;
+            BLASTER_SetErrorCode( BLASTER_UnableToSetIrq );
+            return( BLASTER_Error );
+            }
+         }
+
+      BLASTER_Installed = TRUE;
+      status = BLASTER_Ok;
+      }
+
+   BLASTER_SetErrorCode( status );
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_Shutdown
+
+   Ends transfer of sound data to the sound card and restores the
+   system resources used by the card.
+---------------------------------------------------------------------*/
+
+void BLASTER_Shutdown
+   (
+   void
+   )
+
+   {
+   int Irq;
+   int Interrupt;
+
+   // Halt the DMA transfer
+   BLASTER_StopPlayback();
+
+   BLASTER_RestoreVoiceVolume();
+
+   // Reset the DSP
+   BLASTER_ResetDSP();
+
+   // Restore the original interrupt
+   Irq = BLASTER_Config.Interrupt;
+   Interrupt = BLASTER_Interrupts[ Irq ];
+   if ( Irq >= 8 )
+      {
+      IRQ_RestoreVector( Interrupt );
+      }
+   _dos_setvect( Interrupt, BLASTER_OldInt );
+
+   BLASTER_SoundPlaying = FALSE;
+
+   BLASTER_DMABuffer = NULL;
+
+   BLASTER_SetCallBack( NULL );
+
+   BLASTER_UnlockMemory();
+
+   deallocateTimerStack( StackSelector );
+   StackSelector = NULL;
+
+   BLASTER_Installed = FALSE;
+   }
--- /dev/null
+++ b/rott/audiolib/blaster.h
@@ -1,0 +1,148 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: BLASTER.H
+
+   author: James R. Dose
+   date:   February 4, 1994
+
+   Public header for BLASTER.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __BLASTER_H
+#define __BLASTER_H
+
+typedef struct
+   {
+   unsigned Address;
+   unsigned Type;
+   unsigned Interrupt;
+   unsigned Dma8;
+   unsigned Dma16;
+   unsigned Midi;
+   unsigned Emu;
+   } BLASTER_CONFIG;
+
+extern BLASTER_CONFIG BLASTER_Config;
+extern int BLASTER_DMAChannel;
+
+#define UNDEFINED -1
+
+enum BLASTER_ERRORS
+   {
+   BLASTER_Warning = -2,
+   BLASTER_Error = -1,
+   BLASTER_Ok = 0,
+   BLASTER_EnvNotFound,
+   BLASTER_AddrNotSet,
+   BLASTER_DMANotSet,
+   BLASTER_DMA16NotSet,
+   BLASTER_InvalidParameter,
+   BLASTER_CardNotReady,
+   BLASTER_NoSoundPlaying,
+   BLASTER_InvalidIrq,
+   BLASTER_UnableToSetIrq,
+   BLASTER_DmaError,
+   BLASTER_NoMixer,
+   BLASTER_DPMI_Error,
+   BLASTER_OutOfMemory
+   };
+
+enum BLASTER_Types
+   {
+   SB     = 1,
+   SBPro  = 2,
+   SB20   = 3,
+   SBPro2 = 4,
+   SB16   = 6
+   };
+
+#define BLASTER_MinCardType    SB
+#define BLASTER_MaxCardType    SB16
+
+#define STEREO      1
+#define SIXTEEN_BIT 2
+
+#define MONO_8BIT    0
+#define STEREO_8BIT  ( STEREO )
+#define MONO_16BIT   ( SIXTEEN_BIT )
+#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
+
+#define BLASTER_MaxMixMode        STEREO_16BIT
+
+#define MONO_8BIT_SAMPLE_SIZE    1
+#define MONO_16BIT_SAMPLE_SIZE   2
+#define STEREO_8BIT_SAMPLE_SIZE  ( 2 * MONO_8BIT_SAMPLE_SIZE )
+#define STEREO_16BIT_SAMPLE_SIZE ( 2 * MONO_16BIT_SAMPLE_SIZE )
+
+#define BLASTER_DefaultSampleRate 11000
+#define BLASTER_DefaultMixMode    MONO_8BIT
+#define BLASTER_MaxIrq            15
+
+char *BLASTER_ErrorString( int ErrorNumber );
+void  BLASTER_EnableInterrupt( void );
+void  BLASTER_DisableInterrupt( void );
+int   BLASTER_WriteDSP( unsigned data );
+int   BLASTER_ReadDSP( void );
+int   BLASTER_ResetDSP( void );
+int   BLASTER_GetDSPVersion( void );
+void  BLASTER_SpeakerOn( void );
+void  BLASTER_SpeakerOff( void );
+void  BLASTER_SetPlaybackRate( unsigned rate );
+unsigned BLASTER_GetPlaybackRate( void );
+int   BLASTER_SetMixMode( int mode );
+void  BLASTER_StopPlayback( void );
+int   BLASTER_SetupDMABuffer( char *BufferPtr, int BufferSize, int mode );
+int   BLASTER_GetCurrentPos( void );
+int   BLASTER_DSP1xx_BeginPlayback( int length );
+int   BLASTER_DSP2xx_BeginPlayback( int length );
+int   BLASTER_DSP4xx_BeginPlayback( int length );
+int   BLASTER_BeginBufferedRecord( char *BufferStart, int BufferSize,
+          int NumDivisions, unsigned SampleRate, int MixMode,
+          void ( *CallBackFunc )( void ) );
+int   BLASTER_BeginBufferedPlayback( char *BufferStart,
+         int BufferSize, int NumDivisions, unsigned SampleRate,
+         int MixMode, void ( *CallBackFunc )( void ) );
+void  BLASTER_WriteMixer( int reg, int data );
+int   BLASTER_ReadMixer( int reg );
+int   BLASTER_GetVoiceVolume( void );
+int   BLASTER_SetVoiceVolume( int volume );
+int   BLASTER_GetMidiVolume( void );
+int   BLASTER_SetMidiVolume( int volume );
+int   BLASTER_CardHasMixer( void );
+void  BLASTER_SaveVoiceVolume( void );
+void  BLASTER_RestoreVoiceVolume( void );
+void  BLASTER_SaveMidiVolume( void );
+void  BLASTER_RestoreMidiVolume( void );
+int   BLASTER_GetEnv( BLASTER_CONFIG *Config );
+int   BLASTER_SetCardSettings( BLASTER_CONFIG Config );
+int   BLASTER_GetCardSettings( BLASTER_CONFIG *Config );
+int   BLASTER_GetCardInfo( int *MaxSampleBits, int *MaxChannels );
+void  BLASTER_SetCallBack( void ( *func )( void ) );
+void  BLASTER_SetupWaveBlaster( void );
+void  BLASTER_ShutdownWaveBlaster( void );
+int   BLASTER_Init( void );
+void  BLASTER_Shutdown( void );
+void  BLASTER_UnlockMemory( void );
+int   BLASTER_LockMemory( void );
+
+#endif
--- /dev/null
+++ b/rott/audiolib/ctaweapi.h
@@ -1,0 +1,352 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/****************************************************************************\
+*                                                                            *
+* CTAWEAPI.H SB AWE32 DOS API header                                         *
+*                                                                            *
+* (C) Copyright Creative Technology Ltd. 1992-94. All rights reserved        *
+* worldwide.                                                                 *
+*                                                                            *
+* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY      *
+* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE        *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR      *
+* PURPOSE.                                                                   *
+*                                                                            *
+* You have a royalty-free right to use, modify, reproduce and                *
+* distribute the Sample Files (and/or any modified version) in               *
+* any way you find useful, provided that you agree to                        *
+* the Creative's Software Licensing Aggreement and you also agree that       *
+* Creative has no warranty obligations or liability for any Sample Files.    *
+*                                                                            *
+\****************************************************************************/
+
+/****************************************************************************\
+*      File name       : CTAWEAPI.H                                          *
+*                                                                            *
+*      Programmer      : Creative SB AWE32 Team                              *
+*                        Creative Technology Ltd, 1994. All rights reserved. *
+*                                                                            *
+*      Version         : 2.0b                                                *
+*                                                                            *
+\****************************************************************************/
+
+#ifndef _CTAWEAPI
+#define _CTAWEAPI
+
+
+#define MAXBANKS            64      /* maximum number of banks */
+#define MAXNRPN             32      /* maximum number of NRPN */
+
+
+#if defined(__FLAT__) || defined(__HIGHC__) || defined(DOS386)
+#define PACKETSIZE      8192        /* packet size for 32bit libraries */
+#else
+#define PACKETSIZE      512         /* packet size for real mode libraries */
+#endif
+
+
+#if defined(__FLAT__)
+    #define NEAR
+    #define FAR
+#endif
+
+
+#if defined(__SC__)
+    #pragma pack(1)
+    #if defined(DOS386)
+        #define NEAR
+        #define FAR
+    #endif
+#endif
+
+
+#if defined(__WATCOMC__)
+    #pragma pack(1)
+#endif
+
+
+#if defined(__HIGHC__)
+    #define NEAR
+    #define FAR
+    #define PASCAL  _DCC((_DEFAULT_CALLING_CONVENTION|_CALLEE_POPS_STACK) & \
+                         ~ (_REVERSE_PARMS|_OVERLOADED))
+    #pragma Push_align_members(1)
+    #pragma Global_aliasing_convention("_%r")
+#endif
+
+
+typedef int                     BOOL;
+#define FALSE                   0
+#define TRUE                    1
+
+typedef unsigned char		BYTE;
+typedef unsigned short		WORD;
+typedef unsigned long		DWORD;
+
+typedef short int               SHORT;
+typedef unsigned int		UINT;
+typedef signed long 		LONG;
+
+#ifndef FAR
+#define FAR                     __far
+#endif
+
+#ifndef HUGE
+#define HUGE                    __huge
+#endif
+
+#ifndef PASCAL
+#define PASCAL                  __pascal
+#endif
+
+typedef void FAR*               LPVOID;
+typedef BYTE FAR*               LPBYTE;
+typedef WORD FAR*               LPWORD;
+typedef DWORD FAR*              LPDWORD;
+
+#define LOBYTE(w)