diff -uNr linux-heretic-0.9.5/Makefile patched-linux-heretic-0.9.5/Makefile
--- linux-heretic-0.9.5/Makefile	Mon Feb 15 12:38:35 1999
+++ patched-linux-heretic-0.9.5/Makefile	Thu Mar 11 13:18:22 1999
@@ -2,6 +2,10 @@
 
 CC = gcc
 
+#
+# For old SVGALIB, comment out -D__NEWVGALIB__
+#
+
 CDEFS.ipx = -DUNIX -DHAVE_USLEEP -DHAVE_MATH_H -DHAVE_VALUES_H -DLINUX_MOUSE \
 	-DIPX_PROTOCOL -DI_GGI_HERETIC -DNEED_SHMGETEVENTBASE \
 	# -DIPX_DEBUG -D__NEWVGALIB__ -DEXTRA_WADS
@@ -27,12 +31,15 @@
 COPT.alpha = -O2 -D__64BIT__ -DHAVE_ALLOCA_H
 
 COPT.FreeBSD = -m486 -O2 -malign-jumps=2 -malign-functions=2 -D__32BIT__
-# _end_
 
+COPT.arm = -O2 -D__32BIT__ -fsigned-char -fomit-frame-pointer \
+		-DHAVE_ALLOCA_H
+# _end_
 
+# If using arm, check Makefiles in sndserv/ and musserv/
 # If you want IPX-netcode compiled, replace $(CDEFS.udp) with $(CDEFS.ipx)
 
-CFLAGS = -Wall -Wstrict-prototypes $(CDEFS.ipx) \
+CFLAGS = -Wall -Wstrict-prototypes $(CDEFS.udp) \
 	 -I. -I.. -I/usr/X11R6/include $(COPT.x86) $(COPT.sound)
 
 ifeq ($(WANT_GSI),yes)
@@ -49,8 +56,11 @@
 SOUND_REFS = soundclient/i_sound.c soundclient/soundst.c soundclient/sounds.c \
 	     m_misc.c
 
-COPT.sound = -D__DOSOUND__ -DSNDSERV -Isoundclient # -D_DEBUGSOUND
+COPT.sound = -D__DOSOUND__ -DSNDSERV -D__DOMUSIC__ -DMUSSERV -Isoundclient # -D_DEBUGSOUND
 X11LIBS = -lXext -lX11
+
+MUSSERV = musserver
+SNDSERV = sndserver
 endif
 
 X_LDFLAGS = -L/usr/X11R6/lib
@@ -83,9 +93,12 @@
 	@echo
 
 clean:	
-	rm -f $(OBJS) xheretic ggiheretic vgaheretic graphics/i_x11.o \
+	rm -f $(OBJS) sndserver musserver xheretic ggiheretic 
+	vgaheretic graphics/i_x11.o \
 	graphics/i_ggi.o graphics/i_vga.o \
 	.depend soundclient/*~ gsisound/*~ sndserv/*~ *~
+	(cd sndserv; $(MAKE) clean; cd ..) || exit 1
+	(cd musserv; $(MAKE) clean; cd ..) || exit 1
 
 depx11:	
 	$(CC) -E -M $(CFLAGS) $(X_LDFLAGS) *.c $(SOUND_REFS) \
@@ -100,21 +113,23 @@
 	graphics/i_vga.c > .depend
 
 
-x11:	depx11 $(OBJS) graphics/i_x11.o
+x11:	depx11 $(OBJS) graphics/i_x11.o $(MUSSERV) $(SNDSERV)
 	$(CC) $(CFLAGS) $(X_LDFLAGS) $(X11LIBS) $(OBJS) \
 	graphics/i_x11.o -o xheretic
 
-ggi:	depggi $(OBJS) graphics/i_ggi.o
+ggi:	depggi $(OBJS) graphics/i_ggi.o $(MUSSERV) $(SNDSERV)
 	$(CC) $(CFLAGS) $(GGILIBS) $(OBJS) \
 	graphics/i_ggi.o -o ggiheretic
 
-vga:	depvga $(OBJS) graphics/i_vga.o
+vga:	depvga $(OBJS) graphics/i_vga.o $(MUSSERV) $(SNDSERV)
 	$(CC) $(CFLAGS) $(VGALIBS) $(OBJS) \
 	graphics/i_vga.o -o vgaheretic
 
 sndserver:
-	(cd sndserv; make sndserver; cd ..)
+	(cd sndserv; $(MAKE) sndserver; cd ..) || exit 1
 
+musserver:
+	(cd musserv; $(MAKE) musserver; cd ..) || exit 1
 
 %.o:	%.c
 	$(CC) $(CFLAGS) -c $< -o $@
diff -uNr linux-heretic-0.9.5/d_net.c patched-linux-heretic-0.9.5/d_net.c
--- linux-heretic-0.9.5/d_net.c	Fri Feb 12 15:10:41 1999
+++ patched-linux-heretic-0.9.5/d_net.c	Thu Mar 11 13:11:12 1999
@@ -266,6 +267,8 @@
 	  strcpy (exitmsg, "PLAYER 1 LEFT THE GAME");
 	  exitmsg[7] += netconsole;
 	  players[consoleplayer].message = exitmsg;
+	  players[consoleplayer].messageTics = MESSAGETICS;
+	  
 	  /*
 	   *			if (demorecording)
 	   *				G_CheckDemoStatus ();
@@ -626,7 +629,7 @@
   netbuffer->numtics = 0;
   for (i=0 ; i<4 ; i++)
     {
-      for (j=1 ; j<doomcom->numnodes ; j++)
+      for (j=0 ; j<doomcom->numnodes ; j++)
 	if (nodeingame[j])
 	  HSendPacket (j, NCMD_EXIT);
       I_WaitVBL (1);
diff -uNr linux-heretic-0.9.5/doomdata.h patched-linux-heretic-0.9.5/doomdata.h
--- linux-heretic-0.9.5/doomdata.h	Wed Jan 13 20:41:39 1999
+++ patched-linux-heretic-0.9.5/doomdata.h	Thu Mar 11 13:11:12 1999
@@ -44,9 +44,9 @@
 {
   short		textureoffset;
   short		rowoffset;
-  char		toptexture[8], bottomtexture[8], midtexture[8];
-  short		sector;				/* on viewer's side */
-} mapsidedef_t;
+  char		toptexture[8] __attribute__ ((packed)), bottomtexture[8] __attribute__ ((packed)), midtexture[8] __attribute__ ((packed));
+  short		sector __attribute__ ((packed));				/* on viewer's side */
+}  __attribute__ ((packed))mapsidedef_t;
 
 typedef struct
 {
@@ -54,7 +54,7 @@
   short		flags;
   short		special, tag;
   short		sidenum[2];			/* sidenum[1] will be -1 if one sided */
-} maplinedef_t;
+}  __attribute__ ((packed))maplinedef_t;
 
 #define	ML_BLOCKING	        1
 #define	ML_BLOCKMONSTERS	2
@@ -79,10 +79,10 @@
 typedef	struct
 {
   short		floorheight, ceilingheight;
-  char		floorpic[8], ceilingpic[8];
-  short		lightlevel;
-  short		special, tag;
-} mapsector_t;
+  char		floorpic[8], ceilingpic[8] __attribute__ ((packed));
+  short		lightlevel __attribute__ ((packed));
+  short		special __attribute__ ((packed)), tag __attribute__ ((packed));
+} __attribute__ ((packed)) mapsector_t;
 
 typedef struct
 {
@@ -112,7 +112,7 @@
   short		x,y,dx,dy;		      /* partition line */
   short		bbox[2][4];		      /* bounding box for each child */
   unsigned short    children[2];	      /* if NF_SUBSECTOR its a subsector */
-} mapnode_t;
+} __attribute__ ((packed)) mapnode_t;
 
 typedef struct
 {
@@ -120,7 +120,7 @@
   short		angle;
   short		type;
   short		options;
-} mapthing_t;
+}__attribute__ ((packed)) mapthing_t;
 
 #define	MTF_EASY		1
 #define	MTF_NORMAL		2
@@ -142,18 +142,18 @@
   short	patch;
   short	stepdir;
   short	colormap;
-} mappatch_t;
+}__attribute__ ((packed)) mappatch_t;
 
 typedef struct
 {
   char		name[8];
-  boolean		masked;	
-  short		width;
-  short		height;
-  void		**columndirectory;	// OBSOLETE
-  short		patchcount;
-  mappatch_t	patches[1];
-} maptexture_t;
+  boolean		masked __attribute__ ((packed));	
+  short		width __attribute__ ((packed));
+  short		height __attribute__ ((packed));
+  void		**columndirectory __attribute__ ((packed));	// OBSOLETE
+  short		patchcount __attribute__ ((packed));
+  mappatch_t	patches[1] __attribute__ ((packed));
+} __attribute__ ((packed)) maptexture_t;
 
 
 /*
@@ -168,9 +168,9 @@
 typedef struct
 {
   byte		topdelta;		/* -1 is the last post in a column */
-  byte		length;
+  byte		length __attribute__ ((packed));
   /* length data bytes follows */
-} post_t;
+} __attribute__ ((packed)) post_t;
 
 /* column_t is a list of 0 or more post_t, (byte)-1 terminated */
 typedef post_t	column_t;
@@ -187,14 +187,14 @@
   short		topoffset;			/* pixels below the origin */
   int		columnofs[8];		        /* only [width] used */
   /* the [0] is &columnofs[width] */
-} patch_t;
+} __attribute__ ((packed)) patch_t;
 
 /* a pic is an unmasked block of pixels */
 typedef struct
 {
-  byte		width,height;
-  byte		data;
-} pic_t;
+  byte		width,height __attribute__ ((packed));
+  byte		data __attribute__ ((packed));
+} __attribute__ ((packed)) pic_t;
 
 
 /*
diff -uNr linux-heretic-0.9.5/doomdef.h patched-linux-heretic-0.9.5/doomdef.h
--- linux-heretic-0.9.5/doomdef.h	Tue Feb  9 07:47:19 1999
+++ patched-linux-heretic-0.9.5/doomdef.h	Thu Mar 11 13:11:12 1999
@@ -165,22 +165,22 @@
 typedef struct
 {
   evtype_t	type;
-  int		data1;		/* keys / mouse/joystick buttons */
-  int		data2;		/* mouse/joystick x move */
-  int		data3;		/* mouse/joystick y move */
-} event_t;
+  int		data1 __attribute__ ((packed));		/* keys / mouse/joystick buttons */
+  int		data2 __attribute__ ((packed));		/* mouse/joystick x move */
+  int		data3 __attribute__ ((packed));		/* mouse/joystick y move */
+} __attribute__ ((packed)) event_t;
 
 typedef struct
 {
   char		forwardmove;	/* *2048 for move */
-  char		sidemove;       /* *2048 for move */
-  short		angleturn;      /* <<16 for angle delta */
-  short		consistancy;	/* checks for net game */
-  byte		chatchar;
-  byte		buttons;
-  byte		lookfly;	/* look/fly up/down/centering */
-  byte		arti;		/* artitype_t to use */
-} ticcmd_t;
+  char		sidemove __attribute__ ((packed));       /* *2048 for move */
+  short		angleturn __attribute__ ((packed));      /* <<16 for angle delta */
+  short		consistancy __attribute__ ((packed));	/* checks for net game */
+  byte		chatchar __attribute__ ((packed));
+  byte		buttons __attribute__ ((packed));
+  byte		lookfly __attribute__ ((packed));	/* look/fly up/down/centering */
+  byte		arti __attribute__ ((packed));		/* artitype_t to use */
+} __attribute__ ((packed)) ticcmd_t;
 
 
 /*
@@ -303,13 +303,13 @@
 typedef struct
 {
   ammotype_t ammo;
-  int upstate;
-  int downstate;
-  int readystate;
-  int atkstate;
-  int holdatkstate;
-  int flashstate;
-} weaponinfo_t;
+  int upstate __attribute__ ((packed));
+  int downstate __attribute__ ((packed));
+  int readystate __attribute__ ((packed));
+  int atkstate __attribute__ ((packed));
+  int holdatkstate __attribute__ ((packed));
+  int flashstate __attribute__ ((packed));
+} __attribute__ ((packed)) weaponinfo_t;
 
 extern weaponinfo_t wpnlev1info[NUMWEAPONS];
 extern weaponinfo_t wpnlev2info[NUMWEAPONS];
@@ -363,7 +363,7 @@
 {
   int type;
   int count;
-} inventory_t;
+} __attribute__ ((packed)) inventory_t;
 
 
 /*
@@ -396,13 +396,13 @@
 typedef struct
 {  
   spritenum_t	        sprite;
-  long			frame;
-  long			tics;
+  long			frame __attribute__ ((packed));
+  long			tics __attribute__ ((packed));
   
-  actionf_t		action;
-  statenum_t		nextstate;
-  long			misc1, misc2;
-} state_t;
+  actionf_t		action __attribute__ ((packed));
+  statenum_t		nextstate __attribute__ ((packed));
+  long			misc1 __attribute__ ((packed)), misc2 __attribute__ ((packed));
+} __attribute__ ((packed)) state_t;
 
 extern state_t	states[NUMSTATES];
 extern char *sprnames[NUMSPRITES];
@@ -413,9 +413,9 @@
 
 typedef struct thinker_s
 {
-  struct		thinker_s	*prev, *next;
-  think_t		function;
-} thinker_t;
+  struct		thinker_s	*prev, *next __attribute__ ((packed));
+  think_t		function __attribute__ ((packed));
+} __attribute__ ((packed)) thinker_t;
 
 struct player_s;
 
@@ -424,52 +424,52 @@
   thinker_t		thinker;       /* thinker links */
   
   /* info for drawing */
-  fixed_t		x,y,z;
-  struct mobj_s	*snext, *sprev;	       /* links in sector (if needed) */
-  angle_t		angle;
-  spritenum_t		sprite;	       /* used to find patch_t and flip value */
-  int			frame;	       /*  might be ord with FF_FULLBRIGHT */
+  fixed_t		x __attribute__ ((packed)),y __attribute__ ((packed)),z __attribute__ ((packed));
+  struct mobj_s	*snext __attribute__ ((packed)), *sprev __attribute__ ((packed));	       /* links in sector (if needed) */
+  angle_t		angle __attribute__ ((packed));
+  spritenum_t		sprite __attribute__ ((packed));	       /* used to find patch_t and flip value */
+  int			frame __attribute__ ((packed));	       /*  might be ord with FF_FULLBRIGHT */
 
   /* interaction info */
-  struct mobj_s	*bnext, *bprev;		/* links in blocks (if needed) */
-  struct subsector_s	*subsector;
-  fixed_t		floorz, ceilingz; /* closest together of contacted secs */
-  fixed_t		radius, height;	  /* for movement checking */
-  fixed_t		momx, momy, momz; /* momentums */
-  
-  int		        validcount;	  /* if == validcount, already checked */
-  
-  mobjtype_t		type;
-  mobjinfo_t		*info;		  /* &mobjinfo[mobj->type] */
-  int			tics;		  /* state tic counter */
-  state_t		*state;
-  int			damage;		  /* For missiles */
-  int			flags;
-  int			flags2;		  /* Heretic flags */
-  int			special1;	  /* Special info */
-  int			special2;	  /* Special info */
-  int		        health;
-  int			movedir;	  /* 0-7 */
-  int		        movecount;	  /* when 0, select a new dir */
-  struct mobj_s *target;		  /* thing being chased/attacked (or NULL) */
+  struct mobj_s	*bnext __attribute__ ((packed)), *bprev __attribute__ ((packed));		/* links in blocks (if needed) */
+  struct subsector_s	*subsector __attribute__ ((packed));
+  fixed_t		floorz __attribute__ ((packed)), ceilingz __attribute__ ((packed)); /* closest together of contacted secs */
+  fixed_t		radius __attribute__ ((packed)), height __attribute__ ((packed));	  /* for movement checking */
+  fixed_t		momx __attribute__ ((packed)), momy __attribute__ ((packed)), momz __attribute__ ((packed)); /* momentums */
+  
+  int		        validcount __attribute__ ((packed));	  /* if == validcount, already checked */
+  
+  mobjtype_t		type __attribute__ ((packed));
+  mobjinfo_t		*info __attribute__ ((packed));		  /* &mobjinfo[mobj->type] */
+  int			tics __attribute__ ((packed));		  /* state tic counter */
+  state_t		*state __attribute__ ((packed));
+  int			damage __attribute__ ((packed));		  /* For missiles */
+  int			flags __attribute__ ((packed));
+  int			flags2 __attribute__ ((packed));		  /* Heretic flags */
+  int			special1 __attribute__ ((packed));	  /* Special info */
+  int			special2 __attribute__ ((packed));	  /* Special info */
+  int		        health __attribute__ ((packed));
+  int			movedir __attribute__ ((packed));
+  int		        movecount __attribute__ ((packed));	  /* when 0, select a new dir */
+  struct mobj_s *target __attribute__ ((packed));		  /* thing being chased/attacked (or NULL) */
   /* also the originator for missiles */
-  int			reactiontime;	  /* if non 0, don't attack yet */
+  int			reactiontime __attribute__ ((packed));	  /* if non 0, don't attack yet */
   /* used by player to freeze a bit after */
   /* teleporting */
-  int			threshold;	  /* if >0, the target will be chased */
+  int			threshold __attribute__ ((packed));	  /* if >0, the target will be chased */
   /* no matter what (even if shot) */
-  struct player_s	*player;	  /* only valid if type == MT_PLAYER */
-  int			lastlook;	  /* player number last looked for */
+  struct player_s	*player __attribute__ ((packed));	  /* only valid if type == MT_PLAYER */
+  int			lastlook __attribute__ ((packed));	  /* player number last looked for */
   
-  mapthing_t		spawnpoint;	  /* for nightmare respawn */
-} mobj_t;
+  mapthing_t		spawnpoint __attribute__ ((packed));	  /* for nightmare respawn */
+} __attribute__ ((packed)) mobj_t;
 
 /* each sector has a degenmobj_t in it's center for sound origin purposes */
 typedef struct
 {
   thinker_t		thinker;	  /* not used for anything */
-  fixed_t		x,y,z;
-} degenmobj_t;
+  fixed_t		x __attribute__ ((packed)),y __attribute__ ((packed)),z __attribute__ ((packed));
+} __attribute__ ((packed)) degenmobj_t;
 
 /* Most damage defined using HITDICE */
 #define HITDICE(a) ((1+(P_Random()&7))*a)
@@ -574,9 +574,9 @@
 typedef struct
 {
   state_t	*state;		/* a NULL state means not active */
-  int		tics;
-  fixed_t	sx, sy;
-} pspdef_t;
+  int		tics __attribute__ ((packed));
+  fixed_t	sx __attribute__ ((packed)), sy __attribute__ ((packed));
+} __attribute__ ((packed)) pspdef_t;
 
 
 
@@ -591,57 +591,57 @@
 typedef struct player_s
 {
   mobj_t *mo;
-  playerstate_t playerstate;
-  ticcmd_t cmd;
+  playerstate_t playerstate __attribute__ ((packed));
+  ticcmd_t cmd __attribute__ ((packed));
   
-  fixed_t		viewz;		   /* focal origin above r.z */
-  fixed_t		viewheight;	   /* base height above floor for viewz */
-  fixed_t		deltaviewheight;   /* squat speed */
-  fixed_t		bob;		   /* bounded/scaled total momentum */
-
-  int			flyheight;
-  int			lookdir;
-  boolean		centering;
-  int			health;		   /* only used between levels, mo->health */
+  fixed_t		viewz __attribute__ ((packed));		   /* focal origin above r.z */
+  fixed_t		viewheight __attribute__ ((packed));	   /* base height above floor for viewz */
+  fixed_t		deltaviewheight __attribute__ ((packed));
+  fixed_t		bob __attribute__ ((packed));		   /* bounded/scaled total momentum */
+
+  int			flyheight __attribute__ ((packed));
+  int			lookdir __attribute__ ((packed));
+  boolean		centering __attribute__ ((packed));
+  int			health __attribute__ ((packed));		   /* only used between levels, mo->health */
   /* is used during levels */
-  int			armorpoints, armortype;	/* armor type is 0-2 */
+  int			armorpoints __attribute__ ((packed)), armortype __attribute__ ((packed));	/* armor type is 0-2 */
   
-  inventory_t	        inventory[NUMINVENTORYSLOTS];
-  artitype_t	        readyArtifact;
-  int			artifactCount;
-  int 		        inventorySlotNum;
-  int			powers[NUMPOWERS];
-  boolean		keys[NUMKEYS];
-  boolean		backpack;
-  signed int		frags[MAXPLAYERS];	  /* kills of other players */
-  weapontype_t	        readyweapon;
-  weapontype_t	        pendingweapon;		  /* wp_nochange if not changing */
-  boolean		weaponowned[NUMWEAPONS];
-  int			ammo[NUMAMMO];
-  int			maxammo[NUMAMMO];
-  int			attackdown, usedown;	  /* true if button down last tic */
-  int			cheats;			  /* bit flags */
-  
-  int			refire;			  /* refired shots are less accurate */
-  
-  int			killcount, 
-                        itemcount, 
-                        secretcount;              /* for intermission */
-  char		        *message;		  /* hint messages */
-  int			messageTics;		  /* counter for showing messages */
-  int			damagecount, bonuscount;  /* for screen flashing */
-  int			flamecount;		  /* for flame thrower duration */
-  mobj_t		*attacker;		  /* who did damage (NULL for floors) */
-  int			extralight;		  /* so gun flashes light up areas */
-  int			fixedcolormap;		  /* can be set to REDCOLORMAP, etc */
-  int			colormap;		  /* 0-3 for which color to draw player */
-  pspdef_t	        psprites[NUMPSPRITES];	  /* view sprites (gun, etc) */
-  boolean		didsecret;		  /* true if secret level has been done */
-  int			chickenTics;		  /* player is a chicken if > 0 */
-  int			chickenPeck;		  /* chicken peck countdown */
-  mobj_t		*rain1;			  /* active rain maker 1 */
-  mobj_t		*rain2;			  /* active rain maker 2 */
-} player_t;
+  inventory_t	        inventory[NUMINVENTORYSLOTS] __attribute__ ((packed));
+  artitype_t	        readyArtifact __attribute__ ((packed));
+  int			artifactCount __attribute__ ((packed));
+  int 		        inventorySlotNum __attribute__ ((packed));
+  int			powers[NUMPOWERS] __attribute__ ((packed));
+  boolean		keys[NUMKEYS] __attribute__ ((packed));
+  boolean		backpack __attribute__ ((packed));
+  signed int		frags[MAXPLAYERS] __attribute__ ((packed));	  /* kills of other players */
+  weapontype_t	        readyweapon __attribute__ ((packed));
+  weapontype_t	        pendingweapon __attribute__ ((packed));		  /* wp_nochange if not changing */
+  boolean		weaponowned[NUMWEAPONS] __attribute__ ((packed));
+  int			ammo[NUMAMMO] __attribute__ ((packed));
+  int			maxammo[NUMAMMO] __attribute__ ((packed));
+  int			attackdown __attribute__ ((packed)), usedown __attribute__ ((packed));	  /* true if button down last tic */
+  int			cheats __attribute__ ((packed));			  /* bit flags */
+  
+  int			refire __attribute__ ((packed));			  /* refired shots are less accurate */
+  
+  int			killcount __attribute__ ((packed)), 
+                        itemcount __attribute__ ((packed)), 
+                        secretcount __attribute__ ((packed));              /* for intermission */
+  char		        *message __attribute__ ((packed));		  /* hint messages */
+  int			messageTics __attribute__ ((packed));		  /* counter for showing messages */
+  int			damagecount __attribute__ ((packed)), bonuscount __attribute__ ((packed));  /* for screen flashing */
+  int			flamecount __attribute__ ((packed));		  /* for flame thrower duration */
+  mobj_t		*attacker __attribute__ ((packed));		  /* who did damage (NULL for floors) */
+  int			extralight __attribute__ ((packed));		  /* so gun flashes light up areas */
+  int			fixedcolormap __attribute__ ((packed));		  /* can be set to REDCOLORMAP, etc */
+  int			colormap __attribute__ ((packed));		  /* 0-3 for which color to draw player */
+  pspdef_t	        psprites[NUMPSPRITES] __attribute__ ((packed));	  /* view sprites (gun, etc) */
+  boolean		didsecret __attribute__ ((packed));		  /* true if secret level has been done */
+  int			chickenTics __attribute__ ((packed));		  /* player is a chicken if > 0 */
+  int			chickenPeck __attribute__ ((packed));		  /* chicken peck countdown */
+  mobj_t		*rain1 __attribute__ ((packed));			  /* active rain maker 1 */
+  mobj_t		*rain2 __attribute__ ((packed));			  /* active rain maker 2 */
+} __attribute__ ((packed)) player_t;
 
 #define CF_NOCLIP		1
 #define	CF_GODMODE		2
@@ -652,41 +652,41 @@
 typedef struct
 {
   unsigned	checksum;	     /* high bit is retransmit request */
-  byte		retransmitfrom;	     /* only valid if NCMD_RETRANSMIT */
-  byte		starttic;
-  byte		player, numtics;
-  ticcmd_t	cmds[BACKUPTICS];
-} doomdata_t;
+  byte		retransmitfrom __attribute__ ((packed));	     /* only valid if NCMD_RETRANSMIT */
+  byte		starttic __attribute__ ((packed));
+  byte		player __attribute__ ((packed)), numtics __attribute__ ((packed));
+  ticcmd_t	cmds[BACKUPTICS] __attribute__ ((packed));
+} __attribute__ ((packed)) doomdata_t;
 
 typedef struct
 {
   long	id;
-  short	intnum;			     /* DOOM executes an int to execute commands */
+  short	intnum __attribute__ ((packed));			     /* DOOM executes an int to execute commands */
   
   /* communication between DOOM and the driver */
-  short	command;		     /* CMD_SEND or CMD_GET */
-  short	remotenode;		     /* dest for send, set by get (-1 = no packet) */
-  short	datalength;		     /* bytes in doomdata to be sent */
+  short	command __attribute__ ((packed));		     /* CMD_SEND or CMD_GET */
+  short	remotenode __attribute__ ((packed));		     /* dest for send, set by get (-1 = no packet) */
+  short	datalength __attribute__ ((packed));		     /* bytes in doomdata to be sent */
 
   /* info common to all nodes */
-  short	numnodes;		     /* console is allways node 0 */
-  short	ticdup;			     /* 1 = no duplication, 2-5 = dup for slow nets */
-  short	extratics;		     /* 1 = send a backup tic in every packet */
-  short	deathmatch;		     /* 1 = deathmatch */
-  short	savegame;		     /* -1 = new game, 0-5 = load savegame */
-  short	episode;		     /* 1-3 */
-  short	map;			     /* 1-9 */
-  short	skill;			     /* 1-5 */
+  short	numnodes __attribute__ ((packed));		     /* console is allways node 0 */
+  short	ticdup __attribute__ ((packed));			     /* 1 = no duplication, 2-5 = dup for slow nets */
+  short	extratics __attribute__ ((packed));		     /* 1 = send a backup tic in every packet */
+  short	deathmatch __attribute__ ((packed));		     /* 1 = deathmatch */
+  short	savegame __attribute__ ((packed));		     /* -1 = new game, 0-5 = load savegame */
+  short	episode __attribute__ ((packed));		     /* 1-3 */
+  short	map __attribute__ ((packed));			     /* 1-9 */
+  short	skill __attribute__ ((packed));			     /* 1-5 */
   
   /* info specific to this node */
-  short	consoleplayer;
-  short	numplayers;
-  short	angleoffset;	             /* 1 = left, 0 = center, -1 = right */
-  short	drone;			     /* 1 = drone */
+  short	consoleplayer __attribute__ ((packed));
+  short	numplayers __attribute__ ((packed));
+  short	angleoffset __attribute__ ((packed));	             /* 1 = left, 0 = center, -1 = right */
+  short	drone __attribute__ ((packed));			     /* 1 = drone */
   
   /* packet data to be sent */
-  doomdata_t	data;
-} doomcom_t;
+  doomdata_t	data __attribute__ ((packed));
+} __attribute__ ((packed)) doomcom_t;
 
 #define	DOOMCOM_ID	0x12345678l
 
@@ -881,11 +881,11 @@
 typedef struct memblock_s
 {
   int                     size;         /* including the header and possibly tiny fragments */
-  void                    **user;       /* NULL if a free block */
-  int                     tag;          /* purgelevel */
-  int                     id;           /* should be ZONEID */
-  struct memblock_s       *next, *prev;
-} memblock_t;
+  void                    **user __attribute__ ((packed));       /* NULL if a free block */
+  int                     tag __attribute__ ((packed));          /* purgelevel */
+  int                     id __attribute__ ((packed));           /* should be ZONEID */
+  struct memblock_s       *next __attribute__ ((packed)), *prev __attribute__ ((packed));
+} __attribute__ ((packed)) memblock_t;
 
 #define Z_ChangeTag(p,t) \
 { \
@@ -902,8 +902,8 @@
 typedef struct
 {
   char		name[8];
-  int		handle,position,size;
-} lumpinfo_t;
+  int		handle __attribute__ ((packed)),position __attribute__ ((packed)),size __attribute__ ((packed));
+} __attribute__ ((packed)) lumpinfo_t;
 
 extern lumpinfo_t *lumpinfo;
 extern	int	numlumps;
diff -uNr linux-heretic-0.9.5/graphics/i_vga.c patched-linux-heretic-0.9.5/graphics/i_vga.c
--- linux-heretic-0.9.5/graphics/i_vga.c	Fri Feb 12 16:26:18 1999
+++ patched-linux-heretic-0.9.5/graphics/i_vga.c	Thu Mar 11 13:12:10 1999
@@ -411,9 +411,9 @@
 	{ MOUSE_BUSMOUSE, "Busmouse" },
 	{ MOUSE_PS2, "PS/2" },
 	{ MOUSE_LOGIMAN, "LogiMan" },
+#ifdef __NEWVGALIB__
 	{ MOUSE_GPM, "GPM emulated" },
 	{ MOUSE_SPACEBALL, "SpaceTec Spaceball" },
-#ifdef __NEWVGALIB__
 	{ MOUSE_INTELLIMOUSE, "Intellimouse" },
 	{ MOUSE_IMPS2, "IMPS/2" },
 	{ MOUSE_NONE, "None" },
diff -uNr linux-heretic-0.9.5/i_udp.c patched-linux-heretic-0.9.5/i_udp.c
--- linux-heretic-0.9.5/i_udp.c	Fri Feb  5 08:29:09 1999
+++ patched-linux-heretic-0.9.5/i_udp.c	Thu Mar 11 13:11:32 1999
@@ -25,6 +25,7 @@
 /*
  * UDP NETWORKING
  */
+boolean server = 0;
 
 static int DOOMPORT = (IPPORT_USERRESERVED +0x1d );
 
@@ -140,6 +141,7 @@
       if (errno != EWOULDBLOCK && errno != ECONNREFUSED)
 	I_Error ("GetPacket: %s",strerror(errno));
       doomcom->remotenode = -1;		/* no packet */
+    //  fromaddress.sin_addr.s_addr = inet_addr("0.0.0.0");
       return;
     }
   
@@ -240,6 +242,22 @@
 	doomcom->consoleplayer = 0;
 	return;
       }
+      
+/*  if (!strcmp(myargv[i+1], "server"))
+    {
+    	doomcom->numnodes = atoi(myargv[i+2])-1;
+    	server = 1;
+    	doomcom->consoleplayer = 0;
+    	
+    	if (doomcom->numnodes >= MAXNETNODES)
+    	{
+    		char buffer[80];
+    		sprintf(buffer, "Bad number of players, maximum %i", MAXNETNODES);
+    		I_Error(buffer);
+    	}
+*/    	
+    		
+    					
     
     /* parse player number and host list */
     doomcom->consoleplayer = myargv[i+1][0]-'1';
diff -uNr linux-heretic-0.9.5/musserv/Makefile patched-linux-heretic-0.9.5/musserv/Makefile
--- linux-heretic-0.9.5/musserv/Makefile	Wed Dec 31 19:00:00 1969
+++ patched-linux-heretic-0.9.5/musserv/Makefile	Thu Mar 11 13:12:18 1999
@@ -0,0 +1,50 @@
+# CPhipps - cph@lxdoom.linuxgames.com
+# New musserver Makefile
+# Modified by Spirilis (hannibal@bitsmart.com)
+# $Id: makefile,v 1.2 1999/01/23 15:25:39 cphipps Exp $
+
+CP = gcc
+CO = co
+# Uncomment the one that you want and comment out the rest.
+# defaults to the AWE32 synth
+DEV_FLAGS= -DDEFAULT_FM_SYNTH
+#DEV_FLAGS= -DDEFAULT_EXT_MIDI
+#DEV_FLAGS=
+# Comment this out if you don't want the musserv binary stripped
+STRIP_MUSSERV=strip musserver
+
+COPT.arm = -fsigned-char
+# Change $(COPT.x86) to $(COPT.arm) for NetWinder
+CFLAGS = -DLINUX -g -O3 -ffast-math $(DEV_FLAGS) $(COPT.x86)
+
+
+all:
+	@echo "Choose one of following actions:"
+	@echo
+	@echo " make musserver  - will build the music server"
+	@echo
+	@echo " make clean      - will clean up object and exec files"
+	@echo
+
+musserver: l_musserver.o l_sequencer.o
+	gcc -o musserver l_musserver.o l_sequencer.o
+	$(STRIP_MUSSERV)
+	cp musserver ..
+
+clean: 
+	rm -rf l_musserver.o l_sequencer.o *~ musserver
+
+#install : musserver
+#	install -o 0 -g 0 -m 755 musserver ..
+#
+#  $Log: makefile,v $
+#  Revision 1.2heretic 1999/02/11 09:45:23  douglasp
+#  Changed makefile for use with heretic
+#
+#  Revision 1.2  1999/01/23 15:25:39  cphipps
+#  Fixed crap first version :/
+#
+#  Revision 1.1  1999/01/23 15:24:05  cphipps
+#  Initial revision
+# 
+# 
diff -uNr linux-heretic-0.9.5/musserv/README patched-linux-heretic-0.9.5/musserv/README
--- linux-heretic-0.9.5/musserv/README	Wed Dec 31 19:00:00 1969
+++ patched-linux-heretic-0.9.5/musserv/README	Thu Mar 11 13:12:18 1999
@@ -0,0 +1,56 @@
+Musserver - modified for LxDoom
+---------
+
+Musserver is a program originally by Michael Heasley, which was written to play back the 
+music for Doom on UNIX systems.
+
+Since the release of the Doom sources it is now possible to modify Doom to communicate 
+with the music server directly, instead of requiring patches or manual intervention.
+
+This update of Musserver is by me, Colin Phipps (cph@lxdoom.linuxgames.com). All of the WAD 
+reading code has been stripped out, and the music code has been put all into a single file, 
+purely for my convenience.
+
+l_sequencer.c is the music generation code, and is almost unchanged from the original 
+musserver - it is just a collection into one file of what used to be many files.
+
+l_musserver.c is a new module by me, which is based on the old musserver code, but now 
+receives all it's data via stdin.
+
+To use this musserver, you need a version of Doom which will feed the right data to 
+musserv. I developed this modified musserver with my own port, LxDoom
+(http://lxdoom.linuxgames.com) in mind - it supports this format.
+
+Running with LxDoom
+-------------------
+
+- Unzip this archive (which you already did, I suppose).
+- If you want to recompile the musserver (e.g. there is (untested) AWE32 support in the
+musserver code which you might try enabling) then do 'rm musserv ; make'
+- Either cp/mv musserv to your LxDoom directory, or symlink it.
+- Make sure that musserv is executable
+
+This makes sure that LxDoom can find and use the musserver.
+
+Then you can run LxDoom; it should find and use musserv.
+
+AWE32 Support
+-------------
+
+To get AWE32 support, recompile the supplied musserver sources with 
+the relevant #define defined. This hasn't been tested for a while though, 
+and I can't test it myself.
+
+Thanks to Spirilis (hannibal@bitsmart.com) for repairing the AWE32 support 
+ni the musserver.
+
+Misc
+----
+
+Thanks to Michael Heasley for this program.
+
+The original docs for Musserver are in the txts/ subdirectory.
+
+Musserver is distributed under the GNU General Public License; for details see 
+txts/COPYING.
+
diff -uNr linux-heretic-0.9.5/musserv/l_musserver.c patched-linux-heretic-0.9.5/musserv/l_musserver.c
--- linux-heretic-0.9.5/musserv/l_musserver.c	Wed Dec 31 19:00:00 1969
+++ patched-linux-heretic-0.9.5/musserv/l_musserver.c	Thu Mar 11 13:12:18 1999
@@ -0,0 +1,350 @@
+// Emacs style mode select   -*- C++ -*- 
+// CPhipps (cph@lxdoom.linuxgames.com)- new music server
+// Many parts were derived from the following file from the original 
+//  musserver program:
+
+/*************************************************************************
+ *  musserver.c
+ *
+ *  Copyright (C) 1995-1997 Michael Heasley (mheasley@hmc.edu)
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *************************************************************************/
+
+// AWE32 fixups by Spirilis (hannibal@bitsmart.com)
+
+//      $Id: l_musserver.c,v 1.11 1999/01/03 13:10:56 cphipps Exp $      
+
+#ifndef lint
+static const char
+ rcsid[] = "$Id: l_musserver.c,v 1.11 1999/01/03 13:10:56 cphipps Exp $";
+#endif				/* lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "l_sequencer.h"
+
+struct new_mus_desc {
+  int loop;
+  unsigned long vol;
+  size_t len;
+};
+
+int returnval, verbose = 1;
+static unsigned int vol;
+int playmus(char *musdata, unsigned int mussize, int play_once);
+void seq_setup(int pref_dev, int dev_type);
+void read_genmidi(const void *genmidibuf);
+void vol_change(int volume);
+void cleanup_midi(void);
+
+void cleanup(int r)
+{
+  exit(r);
+}
+
+void sig_handle(int s)
+{
+  switch (s) {
+  case SIGIO:
+  case SIGURG:
+    returnval = 'S';
+    break;
+  default:
+    exit(-1);
+  }
+}
+
+static int set_file_flag(int desc, unsigned long flag, int on)
+{
+  unsigned int oldflags = fcntl(desc, F_GETFL, 0);
+  /* If reading the flags failed, return error indication now. */
+  if (oldflags == -1)
+    return -1;
+  /* Set just the flag we want to set. */
+  if (on)
+    oldflags |= flag;
+  else
+    oldflags &= ~flag;
+  /* Store modified flag word in the descriptor. */
+  return fcntl(desc, F_SETFL, oldflags);
+}
+
+void saferead(int fd, void *buf, size_t len)
+{
+  register unsigned char *data = buf;
+  // Should be redundant, but seems not to be.
+  
+  while (len > 0) {
+    size_t l = read(fd, data, len);
+    
+    if (l < 0) {
+      fprintf(stderr, "Read error\n");
+      exit(-1);
+    }
+    len -= l;
+    data += l;
+  }
+}
+
+void get_mesg(int wait)
+{
+#if 0
+  struct timeval zerowait =
+  {0, 0};
+  int rc;
+  
+  do {
+    if (!(rc = select(FD_SETSIZE, &scratchset, 0, 0, &zerowait)))
+      if (wait)
+	usleep(1000000);
+  } while (wait && !rc);
+  
+  returnval = rc ? 'S' : 0;
+#else
+  char ch;
+  
+  if (read(STDIN_FILENO, &ch, 1) > 0) {
+    // Message received
+    if (verbose)
+      fprintf(stderr, "Cmd:%c", ch);
+    
+    switch (ch) {
+    case 'V':
+      // Volume change
+      saferead(STDIN_FILENO, &vol, sizeof(vol));
+      vol_change(vol);
+      break;
+    case 'P':
+      // Pause
+      while (read(STDIN_FILENO, &ch, 1) == 0)
+	usleep(1000000);
+      break;
+    default:
+      // Stop playing and drop back to main routine
+      returnval = ch;
+      break;
+    }
+  }
+#endif
+}
+
+void *get_genmidi(int fd)
+{
+  size_t len;
+  void *genmidibuf;
+  
+  saferead(fd, &len, sizeof(size_t));
+  genmidibuf = malloc(len);
+  saferead(fd, genmidibuf, len);
+  
+  return genmidibuf;
+}
+
+void prusage(char **argv)
+{
+#ifdef AWE32_SYNTH_SUPPORT
+  printf("Usage: %s [-a | -f | -e] [-v] [-h]\n", argv[0]);
+  printf("   -a      -- Use AWE32 Synth\n");
+#else
+  printf("Usage: %s [-f | -e] [-v] [-h]\n", argv[0]);
+#endif
+  printf("   -f      -- Use standard FM Synth\n");
+  printf("   -e      -- Use External MIDI device\n");
+  printf("   -v      -- Verbose operation\n");
+  printf("   -h      -- Display this help\n");
+}
+
+int main(int argc, char **argv)
+{
+  char cmdch = 0;
+  int errors = 0;
+  int preferred_dev = FM_SYNTH;
+  int opts;
+#ifdef AWE32_SYNTH_SUPPORT
+  char *optstring = "afevh";
+#else
+  char *optstring = "fevh";
+#endif
+  void *genmidibuf;
+  unsigned int badcmd = 0;
+  
+  signal(SIGPIPE, sig_handle);
+  signal(SIGTERM, sig_handle);
+  signal(SIGHUP, sig_handle);
+  signal(SIGSEGV, sig_handle);
+  
+  verbose = 0;
+  if (argc > 1)
+    if (!strcasecmp(argv[1], "-devparm"))
+      verbose = 1;
+  while ((opts = getopt(argc, argv, optstring)) != EOF) {
+    switch (opts) {
+    case 'f':
+      preferred_dev = FM_SYNTH;
+      break;
+    case 'e':
+      preferred_dev = EXT_MIDI;
+      break;
+#ifdef AWE32_SYNTH_SUPPORT
+    case 'a':
+      preferred_dev = AWE32_SYNTH;
+      break;
+#endif
+    case 'v':
+      verbose = 1;
+      break;
+    case 'h':
+      prusage(argv);
+      exit(0);
+      break;
+    }
+  }
+  
+  seq_setup(preferred_dev, 0);
+  genmidibuf = get_genmidi(STDIN_FILENO);
+  read_genmidi(genmidibuf);
+  
+  if (verbose)
+    fprintf(stderr, "Resetting midi device\n");
+
+  cleanup_midi();
+  seq_setup(preferred_dev, 0);
+  atexit(cleanup_midi);
+  
+  free(genmidibuf);
+  
+  while (1) {
+    int rc = 0;
+    
+    if (!cmdch)
+      while ((rc = read(STDIN_FILENO, &cmdch, 1)) == 0)
+	usleep(100000);	// Doesn't matter if we wait for a while
+                 // Don't wait a whole second so that we respond quickly 
+                 // to a shutdown request - rain
+
+    if (rc < 0)
+      return -1;
+    
+    if (verbose)
+      fprintf(stderr, "Cmd:%c\n", cmdch);
+    
+    switch (cmdch) {
+    case 'V':
+      // Volume change
+      read(0, &vol, sizeof(int));
+      cmdch = 0;
+      break;
+    case 'N':
+      {
+	struct new_mus_desc nm;
+	unsigned char *data;
+	
+	cmdch = 0;	// Make sure command doesn't repeat if we fail
+	
+	returnval = 0;	// Don't return yet
+	
+	usleep(100000);
+	
+	// WARNING: Endianess problems if pipe between different architectures?
+	// Hardly worth worrying about
+	
+	saferead(STDIN_FILENO, &nm, sizeof(nm));
+	data = malloc(nm.len);
+	saferead(STDIN_FILENO, data, nm.len);
+	
+	vol_change(nm.vol);
+	
+	if (verbose)
+	  fprintf(stderr, "Music start: length %u %s\n",
+		  nm.len, nm.loop ? "looping" : "");
+	
+	// Non-blocking IO on stdin
+	set_file_flag(STDIN_FILENO, O_NONBLOCK, 1);
+	
+	cmdch = (char) playmus(data, nm.len, nm.loop ? 0 : 1);
+	
+	// Blocking IO on stdin
+	set_file_flag(STDIN_FILENO, O_NONBLOCK, 0);
+	
+	if (verbose)
+	  fprintf(stderr, "Music ended\n");
+	
+	free(data);
+      }
+    break;
+    case 'Q':
+      cmdch = 0;
+      exit(0);
+    case 'S':
+      cmdch = 0; // cph - prevent stop request causing error message
+      break;
+    default:
+      // cph - better bad command diagnostic
+      if (!badcmd) fprintf(stderr, "musserver: Bad command: ");
+      badcmd += 2;
+      fprintf(stderr, "0x%x", cmdch);
+      if (isascii(cmdch)) fprintf(stderr, "(%c)", cmdch);
+      putc(' ',stderr);
+      cmdch = 0;
+    }
+    if (badcmd) // cph - carriage return after bad command diag
+      if (!(badcmd >>= 1)) putc('\n', stderr);
+  }
+}
+
+// ---------------------------
+// $Log: l_musserver.c,v $
+// Revision 1.11  1999/01/03 13:10:56  cphipps
+// Fix stupid error count exiting
+// Better diagnostics on bad commands
+// Suppress bad or dropped through stop requests causing error messages
+//
+// Revision 1.10  1998/12/20 20:35:36  cphipps
+// Make the default output device FM_SYNTH
+//
+// Revision 1.9  1998/12/02 10:22:29  cphipps
+// Reduce time delay in outer idling loop, so quit requests are noticed quicker
+//
+// Revision 1.8  1998/11/28 12:58:39  cphipps
+// Reformatting slightly
+//
+// Revision 1.7  1998/11/28 12:57:46  cphipps
+// AWE32 support version substituted
+// getopt support added to parse the options
+// These improvements courtesy of Spirilis
+//
+// Revision 1.6  1998/10/31 08:58:02  cphipps
+// Force extra reset on init, so instruments are loaded
+// Set volume when starting song
+//
+// Revision 1.5  1998/10/26 19:45:24  cphipps
+// Receive GENMIDI over the pipe
+//
+// Revision 1.4  1998/10/20 19:32:42  cphipps
+// Fix verboseness, to take parameter from lxdoom.
+// Sleep less long on startup, to give better response
+//
diff -uNr linux-heretic-0.9.5/musserv/l_sequencer.c patched-linux-heretic-0.9.5/musserv/l_sequencer.c
--- linux-heretic-0.9.5/musserv/l_sequencer.c	Wed Dec 31 19:00:00 1969
+++ patched-linux-heretic-0.9.5/musserv/l_sequencer.c	Thu Mar 11 13:12:18 1999
@@ -0,0 +1,802 @@
+// CPhipps - this code was taken from sequencer.c and playmus.c and 
+// musserver.h from the musserver program. The credits from these 
+// sources  are given here. Many thanks to the authors.
+// Note: merged the files into a new file to reduce my RCS overhead.
+// Also remove some IPC code and did some minor edits to accomodate that.
+
+/*      $Id: l_sequencer.c,v 1.6 1998/12/02 10:25:46 cphipps Exp $       */
+
+#ifndef lint
+static const char
+ rcsid[] = "$Id: l_sequencer.c,v 1.6 1998/12/02 10:25:46 cphipps Exp $";
+#endif				/* lint */
+
+
+/************************************************************************
+ *  sequencer.c
+ *
+ *  Copyright (C) 1995-1997 Michael Heasley (mheasley@hmc.edu)
+ *
+ *  Portions Copyright (c) 1997 Takashi Iwai (iwai@dragon.mm.t.u-tokyo.ac.jp)
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *************************************************************************/
+
+/*************************************************************************
+ *  playmus.c
+ *
+ *  Copyright (C) 1995-1996 Michael Heasley (mheasley@hmc.edu)
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *************************************************************************/
+
+/*************************************************************************
+ *  musserver.h
+ *
+ *  Copyright (C) 1995 Michael Heasley (mheasley@hmc.edu)
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *************************************************************************/
+
+// AWE32 fixups done by Spirilis (hannibal@bitsmart.com)
+
+// This was originally inside this file, but it seems that l_musserver.c
+// will need it, so we're taking this portion back out of l_sequencer.c
+#include "l_sequencer.h"
+
+struct mus_header {		/* header of music lump */
+	char id[4];
+	unsigned short music_size;
+	unsigned short header_size;
+	unsigned short channels;
+	unsigned short sec_channels;
+	unsigned short instrnum;
+	unsigned short dummy;
+};
+
+struct opl_instr {
+	unsigned short flags;
+	unsigned char finetune;
+	unsigned char note;
+	sbi_instr_data patchdata;
+};
+
+struct synth_voice {
+	signed int note;
+	signed int channel;
+};
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/soundcard.h>
+
+void get_mesg(int wait);
+
+struct synth_info sinfo[5];
+struct midi_info minfo[5];
+int seqfd;
+int mixfd;
+int use_dev = -1;
+int seq_dev = -1;
+int synth_patches[16];
+int chanvol[16];
+int volscale = 100;
+unsigned int voxdate;
+struct synth_voice *voices;
+struct opl_instr fm_instruments[175];
+struct sbi_instrument fm_sbi[175];
+extern int verbose;
+
+extern void cleanup(int status);
+extern void reset_midi();
+
+struct opl_instr fm_instruments[175];
+struct sbi_instrument fm_sbi[175];
+
+
+SEQ_USE_EXTBUF();
+SEQ_DEFINEBUF(2048);
+
+void fmload(void);
+
+void read_genmidi(const void *genmidibuf)
+{
+	if (strncmp(genmidibuf, "#OPL_II#", 8)) {
+		printf("musserver: couldn't find GENMIDI entry in wadfile, exiting.\n");
+		cleanup(1);
+	}
+	memcpy(&fm_instruments, genmidibuf + 8, sizeof(struct opl_instr) * 175);
+	if (use_dev == FM_SYNTH)
+		fmload();	// Load this data
+
+}
+
+void seqbuf_dump(void)
+{
+	if (_seqbufptr)
+		if (write(seqfd, _seqbuf, _seqbufptr) == -1) {
+			perror("write /dev/sequencer");
+			cleanup(-1);
+		}
+	_seqbufptr = 0;
+}
+
+
+int find_midi(int m_type, int dev_num)
+{
+	int num_midi;
+	int use_midi = -1;
+	int m = 0;
+
+	if (ioctl(seqfd, SNDCTL_SEQ_NRMIDIS, &num_midi) == -1)
+		return 0;
+	for (m = 0; m < num_midi; m++) {
+		minfo[m].device = m;
+		ioctl(seqfd, SNDCTL_MIDI_INFO, &minfo[m]);
+		use_midi = m;
+		if (minfo[m].dev_type == dev_num)
+			break;
+	}
+	if (m_type == NO_SYNTH)
+		return num_midi;
+	else
+		return use_midi;
+}
+
+int find_synth(int s_type, int dev_num)
+{
+	int num = 0;
+	int fm = -1;
+#ifdef AWE32_SYNTH_SUPPORT
+	int awe = -1;
+#endif
+	int s = 0;
+
+	if (ioctl(seqfd, SNDCTL_SEQ_NRSYNTHS, &num) == -1)
+		return 0;
+	else
+		for (s = 0; s < num; s++) {
+			sinfo[s].device = s;
+			ioctl(seqfd, SNDCTL_SYNTH_INFO, &sinfo[s]);
+			if (sinfo[s].synth_type == SYNTH_TYPE_SAMPLE) {
+#ifdef AWE32_SYNTH_SUPPORT
+				if (sinfo[s].synth_subtype == SAMPLE_TYPE_AWE32) {
+					awe = s;
+					if ((dev_num == SYNTH_TYPE_SAMPLE) && (s_type == AWE32_SYNTH))
+						break;
+				}
+#endif
+			} else {
+				fm = s;
+				if ((sinfo[s].synth_type == dev_num) && (s_type == FM_SYNTH))
+					break;
+			}
+		}
+	switch (s_type) {
+	case FM_SYNTH:
+		return fm;
+		break;
+#ifdef AWE32_SYNTH_SUPPORT
+	case AWE32_SYNTH:
+		return awe;
+		break;
+#endif
+	case NO_SYNTH:
+		return num;
+		break;
+	default:
+		return -1;
+		break;
+	}
+}
+
+#ifdef AWE32_SYNTH_SUPPORT
+void setup_awe(int num_awe)
+{
+	use_dev = AWE32_SYNTH;
+	seq_dev = num_awe;
+	if (verbose)
+		fprintf(stderr, "Using synth device number %d (%s)\n", seq_dev + 1, sinfo[seq_dev].name);
+}
+#endif
+
+void setup_midi(int num_midi)
+{
+	use_dev = EXT_MIDI;
+	seq_dev = num_midi;
+	if (verbose)
+		fprintf(stderr, "Using midi device number %d (%s)\n", seq_dev + 1, minfo[seq_dev].name);
+}
+
+void setup_fm(int num_fm)
+{
+	int x;
+	int y;
+	FILE *sndstat;
+	char sndver[100];
+	char snddate[100];
+
+
+	use_dev = FM_SYNTH;
+	seq_dev = num_fm;
+
+	sndstat = fopen("/dev/sndstat", "r");
+	if (sndstat == NULL) {
+		fprintf(stderr, "musserver: could not open /dev/sndstat, exiting.\n");
+		exit(1);
+	}
+	fgets(sndver, 100, sndstat);
+	for (x = 0; x < strlen(sndver); x++)
+		if (sndver[x] == '-') {
+			x++;
+			for (y = x; y < strlen(sndver); y++)
+				if (sndver[y] != ' ')
+					snddate[y - x] = sndver[y];
+				else {
+					snddate[y - x] = 0;
+					break;
+				}
+			break;
+		}
+	voxdate = atoi(snddate);
+	fclose(sndstat);
+
+	voices = malloc(sinfo[seq_dev].nr_voices * sizeof(struct synth_voice));
+	for (x = 0; x < sinfo[seq_dev].nr_voices; x++) {
+		voices[x].note = -1;
+		voices[x].channel = -1;
+	}
+	for (x = 0; x < 16; x++)
+		synth_patches[x] = -1;
+
+	mixfd = open("/dev/mixer", O_WRONLY, 0);
+
+	if (verbose)
+		fprintf(stderr, "Using synth device number %d (%s)\n", seq_dev + 1, sinfo[seq_dev].name);
+}
+
+void list_devs()
+{
+	int dummy;
+	int x;
+
+	if ((seqfd = open("/dev/sequencer", O_WRONLY, 0)) < 0) {
+		perror("open /dev/sequencer");
+		exit(1);
+	}
+	dummy = find_midi(NO_SYNTH, NO_SYNTH);
+	for (x = 0; x < dummy; x++)
+		fprintf(stderr, "Found a midi device of type %d (%s)\n", minfo[x].dev_type,
+			minfo[x].name);
+	dummy = find_synth(NO_SYNTH, NO_SYNTH);
+	for (x = 0; x < dummy; x++)
+		fprintf(stderr, "Found a synth device of type %d (%s)\n", sinfo[x].synth_type,
+			sinfo[x].name);
+	exit(0);
+}
+
+void seq_setup(int pref_dev, int dev_type)
+{
+	int num_midi;
+	int num_awe;
+	int num_fm;
+
+	if ((seqfd = open("/dev/sequencer", O_WRONLY, 0)) < 0) {
+		perror("open /dev/sequencer");
+		exit(1);
+	}
+	num_midi = find_midi(EXT_MIDI, dev_type);
+	num_fm = find_synth(FM_SYNTH, dev_type);
+	num_awe = find_synth(AWE32_SYNTH, dev_type);
+
+	if ((num_midi == -1) && (num_fm == -1) && (num_awe == -1)) {
+		fprintf(stderr, "musserver: no music devices found, exiting.\n");
+		exit(1);
+	}
+	switch (pref_dev) {
+	case EXT_MIDI:
+		if (num_midi != -1)
+			setup_midi(num_midi);
+#ifdef AWE32_SYNTH_SUPPORT
+		else if (num_awe != -1)
+			setup_awe(num_awe);
+#endif
+		else if (num_fm != -1)
+			setup_fm(num_fm);
+		break;
+	case FM_SYNTH:
+		if (num_fm != -1)
+			setup_fm(num_fm);
+		else if (num_midi != -1)
+			setup_midi(num_midi);
+#ifdef AWE32_SYNTH_SUPPORT
+		else if (num_awe != -1)
+			setup_awe(num_awe);
+#endif
+		break;
+#ifdef AWE32_SYNTH_SUPPORT
+	case AWE32_SYNTH:
+		if (num_awe != -1)
+			setup_awe(num_awe);
+		else if (num_midi != -1)
+			setup_midi(num_midi);
+		else if (num_fm != -1)
+			setup_fm(num_fm);
+		break;
+#endif
+	default:
+		break;
+	}
+	reset_midi();
+}
+
+void cleanup_midi(void)
+{
+  reset_midi();
+#ifdef LINUX
+  ioctl(seqfd, SNDCTL_SEQ_SYNC); // sync before closing the fd, 
+  // or the sound driver may hang for a bit - rain
+#endif
+  close(seqfd);  
+  
+  if (use_dev == FM_SYNTH)
+    close(mixfd);
+}
+
+void reset_midi(void)
+{
+	unsigned int channel;
+
+#ifdef AWE32_SYNTH_SUPPORT
+	if (use_dev == AWE32_SYNTH) {
+		AWE_SET_CHANNEL_MODE(seq_dev, 1);
+		AWE_NOTEOFF_ALL(seq_dev);
+		for (channel = 0; channel < 16; channel++) {
+			SEQ_BENDER_RANGE(seq_dev, channel, 200);
+			SEQ_BENDER(seq_dev, channel, 0);
+		}
+	} else
+#endif
+	if (use_dev == EXT_MIDI)
+		for (channel = 0; channel < 16; channel++) {
+			/* all notes off */
+			SEQ_MIDIOUT(seq_dev, MIDI_CTL_CHANGE + channel);
+			SEQ_MIDIOUT(seq_dev, 0x7b);
+			SEQ_MIDIOUT(seq_dev, 0);
+			/* reset pitch bender */
+			SEQ_MIDIOUT(seq_dev, MIDI_PITCH_BEND + channel);
+			SEQ_MIDIOUT(seq_dev, 64 >> 7);
+			SEQ_MIDIOUT(seq_dev, 64 & 127);
+			/* reset volume to 100 */
+			SEQ_MIDIOUT(seq_dev, MIDI_CTL_CHANGE + channel);
+			SEQ_MIDIOUT(seq_dev, CTL_MAIN_VOLUME);
+			SEQ_MIDIOUT(seq_dev, volscale);
+			chanvol[channel] = 100;
+			/* reset pan */
+			SEQ_MIDIOUT(seq_dev, MIDI_CTL_CHANGE + channel);
+			SEQ_MIDIOUT(seq_dev, CTL_PAN);
+			SEQ_MIDIOUT(seq_dev, 64);
+
+	} else
+		for (channel = 0; channel < sinfo[seq_dev].nr_voices; channel++) {
+			SEQ_STOP_NOTE(seq_dev, channel, voices[channel].note, 64);
+			SEQ_BENDER_RANGE(seq_dev, channel, 200);
+			voices[channel].note = -1;
+			voices[channel].channel = -1;
+		}
+	SEQ_DUMPBUF();
+}
+
+void note_off(int note, int channel, int volume)
+{
+	int x = 0;
+
+#ifdef AWE32_SYNTH_SUPPORT
+	if (use_dev == AWE32_SYNTH) {
+		SEQ_STOP_NOTE(seq_dev, channel, note, volume);
+	} else
+#endif
+	if (use_dev == EXT_MIDI) {
+		SEQ_MIDIOUT(seq_dev, MIDI_NOTEOFF + channel);
+		SEQ_MIDIOUT(seq_dev, note);
+		SEQ_MIDIOUT(seq_dev, volume);
+	} else {
+		for (x = 0; x < sinfo[seq_dev].nr_voices; x++)
+			if ((voices[x].note == note) && (voices[x].channel == channel))
+				break;
+		if (x != sinfo[seq_dev].nr_voices) {
+			voices[x].note = -1;
+			voices[x].channel = -1;
+			SEQ_STOP_NOTE(seq_dev, x, note, volume);
+		}
+	}
+	SEQ_DUMPBUF();
+}
+
+void note_on(int note, int channel, int volume)
+{
+	int x = 0;
+
+#ifdef AWE32_SYNTH_SUPPORT
+	if (use_dev == AWE32_SYNTH) {
+		SEQ_START_NOTE(seq_dev, channel, note, volume);
+	} else
+#endif
+	if (use_dev == EXT_MIDI) {
+		SEQ_MIDIOUT(seq_dev, MIDI_NOTEON + channel);
+		SEQ_MIDIOUT(seq_dev, note);
+		SEQ_MIDIOUT(seq_dev, volume);
+	} else {
+		for (x = 0; x < sinfo[seq_dev].nr_voices; x++)
+			if ((voices[x].note == -1) && (voices[x].channel == -1))
+				break;
+		if (x != sinfo[seq_dev].nr_voices) {
+			voices[x].note = note;
+			voices[x].channel = channel;
+			if (channel == 9) {	/* drum note */
+				if (use_dev == FM_SYNTH) {
+					SEQ_SET_PATCH(seq_dev, x, note + 93);
+					note = fm_instruments[note + 93].note;
+				} else
+					SEQ_SET_PATCH(seq_dev, x, note + 128);
+			} else {
+				SEQ_SET_PATCH(seq_dev, x, synth_patches[channel]);
+				if ((voxdate != 950728) && (use_dev == FM_SYNTH))
+					note = note + 12;
+			}
+			SEQ_START_NOTE(seq_dev, x, note, volume);
+		}
+	}
+	SEQ_DUMPBUF();
+}
+
+void pitch_bend(int channel, signed int value)
+{
+	int x;
+
+#ifdef AWE32_SYNTH_SUPPORT
+	if (use_dev == AWE32_SYNTH) {
+		SEQ_BENDER(seq_dev, channel, 128 * value);
+	} else
+#endif
+	if (use_dev == EXT_MIDI) {
+		SEQ_MIDIOUT(seq_dev, MIDI_PITCH_BEND + channel);
+		SEQ_MIDIOUT(seq_dev, value >> 7);
+		SEQ_MIDIOUT(seq_dev, value & 127);
+	} else {
+		for (x = 0; x < sinfo[seq_dev].nr_voices; x++)
+			if (voices[x].channel == channel) {
+				SEQ_BENDER_RANGE(seq_dev, x, 200);
+				SEQ_BENDER(seq_dev, x, 128 * value);
+			}
+	}
+	SEQ_DUMPBUF();
+}
+
+void control_change(int controller, int channel, int value)
+{
+	int x;
+
+	if (controller == CTL_MAIN_VOLUME) {
+		chanvol[channel] = value;
+		value = value * volscale / 100;
+	}
+#ifdef AWE32_SYNTH_SUPPORT
+	if (use_dev == AWE32_SYNTH) {
+		SEQ_CONTROL(seq_dev, channel, controller, value);
+	} else
+#endif
+	if (use_dev == EXT_MIDI) {
+		SEQ_MIDIOUT(seq_dev, MIDI_CTL_CHANGE + channel);
+		SEQ_MIDIOUT(seq_dev, controller);
+		SEQ_MIDIOUT(seq_dev, value);
+	} else {
+		for (x = 0; x < sinfo[seq_dev].nr_voices; x++)
+			if ((voices[x].channel == channel) && (controller == CTL_MAIN_VOLUME))
+				SEQ_MAIN_VOLUME(seq_dev, x, value);
+	}
+	SEQ_DUMPBUF();
+}
+
+void patch_change(int patch, int channel)
+{
+	int x;
+
+#ifdef AWE32_SYNTH_SUPPORT
+	if (use_dev == AWE32_SYNTH) {
+		SEQ_SET_PATCH(seq_dev, channel, patch);
+	} else
+#endif
+	if (use_dev == EXT_MIDI) {
+		SEQ_MIDIOUT(seq_dev, MIDI_PGM_CHANGE + channel);
+		SEQ_MIDIOUT(seq_dev, patch);
+	} else {
+		for (x = 0; x < sinfo[seq_dev].nr_voices; x++)
+			if (((voices[x].channel == -1) && (voices[x].note == -1)) || (voices[x].channel == channel)) {
+				synth_patches[channel] = patch;
+				break;
+			}
+	}
+	SEQ_DUMPBUF();
+}
+
+void midi_wait(float time)
+{
+	ioctl(seqfd, SNDCTL_SEQ_SYNC);
+	SEQ_WAIT_TIME((int) time);
+	SEQ_DUMPBUF();
+}
+
+void midi_timer(int action)
+{
+	switch (action) {
+	case 0:
+		SEQ_START_TIMER();
+		break;
+	case 1:
+		SEQ_STOP_TIMER();
+		break;
+	case 2:
+		SEQ_CONTINUE_TIMER();
+		break;
+	}
+}
+
+void vol_change(int volume)
+{
+	int x;
+	int logscale[16] =
+	{0, 25, 40, 50, 58, 65, 70, 75, 79, 83, 86, 90, 93, 95,
+	 98, 100};
+
+	volume = (volume < 0 ? 0 : (volume > 15 ? 15 : volume));
+	volscale = logscale[volume];
+#ifdef AWE32_SYNTH_SUPPORT
+	if (use_dev == AWE32_SYNTH) {
+		for (x = 0; x < 16; x++)
+			SEQ_CONTROL(seq_dev, x, CTL_MAIN_VOLUME, chanvol[x] * volscale / 100);
+	} else
+#endif
+	if (use_dev == EXT_MIDI) {
+		for (x = 0; x < 16; x++) {
+			SEQ_MIDIOUT(seq_dev, MIDI_CTL_CHANGE + x);
+			SEQ_MIDIOUT(seq_dev, CTL_MAIN_VOLUME);
+			SEQ_MIDIOUT(seq_dev, chanvol[x] * volscale / 100);
+		}
+	} else {
+		volume = volscale;
+		volume |= (volume << 8);
+		//if (-1 == ioctl(mixfd, SOUND_MIXER_WRITE_SYNTH, &volume))
+		//  perror("volume change");
+		ioctl(mixfd, SOUND_MIXER_WRITE_SYNTH, &volume);
+		ioctl(mixfd, SOUND_MIXER_WRITE_LINE2, &volume);
+	}
+	SEQ_DUMPBUF();
+}
+
+
+
+void fmload(void)
+{
+	int x;
+
+	for (x = 0; x < 175; x++) {
+		fm_sbi[x].key = FM_PATCH;
+		fm_sbi[x].device = seq_dev;
+		fm_sbi[x].channel = x;
+		fm_sbi[x].operators[0] = fm_instruments[x].patchdata[0];
+		fm_sbi[x].operators[1] = fm_instruments[x].patchdata[7];
+		fm_sbi[x].operators[2] = fm_instruments[x].patchdata[4] + fm_instruments[x].patchdata[5];
+		fm_sbi[x].operators[3] = fm_instruments[x].patchdata[11] + fm_instruments[x].patchdata[12];
+		fm_sbi[x].operators[4] = fm_instruments[x].patchdata[1];
+		fm_sbi[x].operators[5] = fm_instruments[x].patchdata[8];
+		fm_sbi[x].operators[6] = fm_instruments[x].patchdata[2];
+		fm_sbi[x].operators[7] = fm_instruments[x].patchdata[9];
+		fm_sbi[x].operators[8] = fm_instruments[x].patchdata[3];
+		fm_sbi[x].operators[9] = fm_instruments[x].patchdata[10];
+		fm_sbi[x].operators[10] = fm_instruments[x].patchdata[6];
+		fm_sbi[x].operators[11] = fm_instruments[x].patchdata[16];
+		fm_sbi[x].operators[12] = fm_instruments[x].patchdata[23];
+		fm_sbi[x].operators[13] = fm_instruments[x].patchdata[20] + fm_instruments[x].patchdata[21];
+		fm_sbi[x].operators[14] = fm_instruments[x].patchdata[27] + fm_instruments[x].patchdata[28];
+		fm_sbi[x].operators[15] = fm_instruments[x].patchdata[17];
+		fm_sbi[x].operators[16] = fm_instruments[x].patchdata[24];
+		fm_sbi[x].operators[17] = fm_instruments[x].patchdata[18];
+		fm_sbi[x].operators[18] = fm_instruments[x].patchdata[25];
+		fm_sbi[x].operators[19] = fm_instruments[x].patchdata[19];
+		fm_sbi[x].operators[20] = fm_instruments[x].patchdata[26];
+		fm_sbi[x].operators[21] = fm_instruments[x].patchdata[22];
+		SEQ_WRPATCH(&fm_sbi[x], sizeof(fm_sbi[x]));
+	}
+}
+
+extern int returnval;		// CPhipps - Patch to musserver code
+
+int playmus(char *musdata, unsigned int mussize, int play_once)
+{
+	unsigned char event;
+	unsigned char event1;
+	unsigned char event2;
+	unsigned char eventtype;
+	unsigned char channelnum;
+	unsigned char last = 0;
+	unsigned char notenum;
+	unsigned char notevol;
+	unsigned int pitchwheel;
+	unsigned char controlnum;
+	unsigned char controlval;
+	unsigned int ticks;
+	unsigned char tmpch;
+	unsigned int done = 0;
+	unsigned int lastvol[16];
+	unsigned int i;
+	unsigned int dticks;
+	double dtime;
+	double delaytime;
+	double curtime = 0.0;
+	char *muscopy;
+
+	{			/* CPhipps - patch this here */
+		struct mus_header *phead = (struct mus_header *) musdata;
+
+		musdata += phead->header_size;
+	}
+
+
+	returnval = 0;
+	muscopy = musdata;
+
+	if (play_once == 2)
+		get_mesg(1);
+
+
+	reset_midi();
+	midi_timer(0);
+
+	while (!done) {
+		if (!returnval)
+			get_mesg(0);
+		if (returnval != 0)
+			return returnval;
+		event = *musdata++;
+		channelnum = event & 15;
+		if (channelnum > 8)
+			channelnum++;
+		if (channelnum == 16)
+			channelnum = 9;
+		eventtype = (event >> 4) & 7;
+		last = event & 128;
+
+		switch (eventtype) {
+		case 0:	/* note off */
+			event1 = *musdata++;
+			notenum = event1 & 127;
+			note_off(notenum, channelnum, lastvol[channelnum]);
+			break;
+
+		case 1:	/* note on */
+			event1 = *musdata++;
+			notenum = event1 & 127;
+			if (event1 & 128) {
+				event2 = *musdata++;
+				notevol = event2 & 127;
+				lastvol[channelnum] = notevol;
+			}
+			note_on(notenum, channelnum, lastvol[channelnum]);
+			break;
+
+		case 2:	/* pitch wheel */
+			event1 = *musdata++;
+			pitchwheel = event1 / 2;
+			pitch_bend(channelnum, pitchwheel);
+			break;
+
+		case 4:	/* midi controller change */
+			event1 = *musdata++;
+			controlnum = event1 & 127;
+			event2 = *musdata++;
+			controlval = event2 & 127;
+			switch (controlnum) {
+			case 0:	/* patch change */
+				patch_change(controlval, channelnum);
+				break;
+			case 3:	/* volume */
+				control_change(CTL_MAIN_VOLUME, channelnum, controlval);
+				break;
+			case 4:	/* pan */
+				control_change(CTL_PAN, channelnum, controlval);
+				break;
+			}
+			break;
+
+		case 6:	/* end of music data */
+			if (play_once)
+				return 0;
+			else {
+				musdata = muscopy;
+				midi_timer(0);
+				curtime = 0.0;
+				last = 0;
+			}
+			break;
+
+		case 3:	/* unknown, but contains data */
+			musdata++;
+			break;
+
+		default:	/* unknown */
+			break;
+		}
+		if (last) {	/* next data portion is time data */
+			tmpch = *musdata++;
+			ticks = tmpch & 127;
+			while (tmpch & 128) {
+				tmpch = *musdata++;
+				ticks = (ticks * 128) + (tmpch & 127);
+			}
+			delaytime = (double) ticks / 1.4;
+			dticks = (int) (delaytime / 10);
+			for (i = 1; i < dticks; i++) {
+				dtime = delaytime * (double) i / (double) dticks;
+				midi_wait(curtime + dtime);
+				if (!returnval)
+					get_mesg(0);
+				if (returnval != 0)
+					return returnval;
+			}
+			curtime += delaytime;
+			midi_wait(curtime);
+		}
+	}
+	return returnval;
+}
+
+//
+// $Log: l_sequencer.c,v $
+// Revision 1.6  1998/12/02 10:25:46  cphipps
+// Fix delay on shutdown
+// Add log to end of file
+//
+//
diff -uNr linux-heretic-0.9.5/musserv/l_sequencer.h patched-linux-heretic-0.9.5/musserv/l_sequencer.h
--- linux-heretic-0.9.5/musserv/l_sequencer.h	Wed Dec 31 19:00:00 1969
+++ patched-linux-heretic-0.9.5/musserv/l_sequencer.h	Thu Mar 11 13:12:18 1999
@@ -0,0 +1,118 @@
+// Emacs style mode select   -*- C++ -*- 
+/************************************************************************
+ *  l_sequencer.h ripped from l_sequencer.c from musserv for LxDoom
+ *  (modified by Colin Phipps from the original musserver)
+ *  sequencer.c
+ *
+ *  Copyright (C) 1995-1997 Michael Heasley (mheasley@hmc.edu)
+ *
+ *  Portions Copyright (c) 1997 Takashi Iwai (iwai@dragon.mm.t.u-tokyo.ac.jp)
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *************************************************************************/
+
+/* 	$Id: l_sequencer.h,v 1.2 1998/11/28 13:01:16 cphipps Exp $	 */
+
+// l_sequencer.h code ripped from l_sequencer.c
+// by Spirilis (hannibal@bitsmart.com)
+
+#ifndef L_SEQUENCER_H
+#define L_SEQUENCER_H
+/**************************************************/
+/* User-configurable parameters: program defaults */
+/**************************************************/
+
+
+/*************************************************************************
+ * Change this to your preferred default playback device: external midi, *
+ * FM synth, or AWE32 synth                                              *
+ *************************************************************************/
+
+// #define DEFAULT_EXT_MIDI
+// #define DEFAULT_FM_SYNTH
+// #define DEFAULT_AWE32_SYNTH
+
+
+/************************************************************************
+ * To compile in support for AWE32 synth (requires AWE32 kernel driver, *
+ * see README) regardless of the default playback device, define the    *
+ * following                                                            *
+ * ** Moved to Makefile -DAWE32_SYNTH_SUPPORT  -Spirilis                *
+ ************************************************************************/
+
+// #define AWE32_SYNTH_SUPPORT
+
+
+/***************************************************************************
+ * If you normally need the -u command-line switch to specify a particular *
+ * device type, uncomment this line and change the type as needed          *
+ ***************************************************************************/
+
+/* #define DEFAULT_TYPE 8 */
+
+
+/************************************/
+/* End of user-configurable section */
+/************************************/
+
+#ifndef AWE32_SYNTH_SUPPORT
+#ifdef DEFAULT_AWE32_SYNTH
+#define AWE32_SYNTH_SUPPORT
+#endif	/* (DEFAULT_AWE32_SYNTH) */
+#endif	/* (AWE32_SYNTH_SUPPORT) */
+
+#ifdef LINUX
+#include <sys/soundcard.h>
+#ifdef AWE32_SYNTH_SUPPORT
+#include <linux/awe_voice.h>
+#endif
+#elif defined(SCOOS5) || defined(SCOUW2) || defined(SCOUW7)
+#include <sys/soundcard.h>
+#ifdef AWE32_SYNTH_SUPPORT
+#include <sys/awe_voice.h>
+#endif
+#elif defined(__FreeBSD__)
+#include <machine/soundcard.h>
+#ifdef AWE32_SYNTH_SUPPORT
+#include <awe_voice.h>
+#endif
+#endif
+
+#define MUS_VERSION "1.4"
+
+#define NO_SYNTH -1
+#define FM_SYNTH 1
+#define EXT_MIDI 2
+#define AWE32_SYNTH 3
+#define LIST_DEV -1
+#define TERMINATED 4
+#define MSG_WAIT 0
+
+#ifdef DEFAULT_AWE32_SYNTH
+#define DEFAULT_DEV AWE32_SYNTH
+#elif defined(DEFAULT_FM_SYNTH)
+#define DEFAULT_DEV FM_SYNTH
+#else
+#define DEFAULT_DEV EXT_MIDI
+#endif
+
+#endif	/* (L_SEQUENCER.H) */
+
+// CPhipps - incorporated into my source tree, version logging headers
+// added
+// $Log: l_sequencer.h,v $
+// Revision 1.2  1998/11/28 13:01:16  cphipps
+// Added header info
+//
diff -uNr linux-heretic-0.9.5/sndserv/Makefile patched-linux-heretic-0.9.5/sndserv/Makefile
--- linux-heretic-0.9.5/sndserv/Makefile	Sat Feb 13 16:03:48 1999
+++ patched-linux-heretic-0.9.5/sndserv/Makefile	Thu Mar 11 13:12:18 1999
@@ -2,8 +2,11 @@
 
 COPT.x86 = -m486 -O2 -malign-jumps=2 -malign-functions=2
 COPT.m68k = -m68020-60 -O2 -fomit-frame-pointer -D__BIG_ENDIAN__
+COPT.arm = -O2 -fomit-frame-pointer -fpack-struct -fsigned-char
 
-CFLAGS=	-Wall -Wstrict-prototypes $(COPT.x86)
+# For arm, replace $(COPT.x86) with $(COPT.arm)
+
+CFLAGS=	-Wall -Wstrict-prototypes $(COPT.x86)
 
 LIBS=	-lm
 
diff -uNr linux-heretic-0.9.5/sndserv/soundsrv.c patched-linux-heretic-0.9.5/sndserv/soundsrv.c
--- linux-heretic-0.9.5/sndserv/soundsrv.c	Fri Feb  5 11:57:57 1999
+++ patched-linux-heretic-0.9.5/sndserv/soundsrv.c	Thu Mar 11 13:12:18 1999
@@ -558,7 +558,7 @@
 
 void quit(void)
 {
-  I_ShutdownMusic();
+//  I_ShutdownMusic();
   I_ShutdownSound();
   exit(0);
 }
@@ -594,7 +594,7 @@
   
   I_InitSound(11025, 16);
   
-  I_InitMusic();
+//  I_InitMusic();
   
   if (snd_verbose)
     fprintf(stderr, "ready\n");
diff -uNr linux-heretic-0.9.5/soundclient/i_sound.c patched-linux-heretic-0.9.5/soundclient/i_sound.c
--- linux-heretic-0.9.5/soundclient/i_sound.c	Sat Jan 23 19:30:53 1999
+++ patched-linux-heretic-0.9.5/soundclient/i_sound.c	Thu Mar 11 13:11:23 1999
@@ -1,4 +1,3 @@
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -24,9 +23,11 @@
 #include "doomdef.h"
 
 #ifdef MUSSERV /* musserver music hack */
-int musserver_msgid=-1;
+//int musserver_msgid=-1;
+FILE *musserver=0;
 char *musserver_filename = "./musserver";
-char *musserver_options = "-f";
+char *musserver_options = "";
+//char *musserver_options = "-f";
 #endif /* MUSSERV */
 
 /* UNIX hack, to be removed. */
@@ -112,6 +113,12 @@
 int*		channelleftvol_lookup[NUM_CHANNELS];
 int*		channelrightvol_lookup[NUM_CHANNELS];
 
+extern boolean mus_paused;
+char *musdata = NULL;
+long muslen = 0;
+int playing_handle = 1;
+int loaded_handle = 1;
+boolean looping_current = 0;
 
 
 void I_SetChannels()
@@ -147,24 +154,18 @@
   snd_SfxVolume = volume;
 }
 
-/* MUSIC API - dummy. Some code from DOS version. */
 void I_SetMusicVolume(int volume)
 {
   /* Internal state variable. */
   snd_MusicVolume = volume;
   /* Now set volume on output device. */
 #ifdef MUSSERV
-  /* Whatever( snd_MusicVolume ); */
   
-  if (musserver_msgid != -1) {
-    struct musmsg msg_buffer;
-    msg_buffer.msg_type=6;
-    memset(msg_buffer.msg_text,0,sizeof(msg_buffer.msg_text));
-    msg_buffer.msg_text[0]='v';
-    msg_buffer.msg_text[1]=volume;
-    msgsnd(musserver_msgid,(struct msgbuf *)&msg_buffer,
-	   sizeof(msg_buffer.msg_text),IPC_NOWAIT);
-  }
+  if ((musserver == NULL) || (playing_handle == 0)) return;
+  
+  fputc('V', musserver);
+  fwrite(&volume, sizeof(int), 1, musserver);
+  fflush(musserver);
 #endif /* #ifdef MUSSERV */
 }
 
@@ -393,7 +394,6 @@
       fflush(sndserver);
     }
 #endif /* SNDSERV */
-  
   /* Done. */
   return;
 }
@@ -401,8 +401,8 @@
 
 void I_InitSound(void)
 {
-#ifdef SNDSERV
   char buffer[256];
+#ifdef SNDSERV
   
   sprintf(buffer, "%s", sndserver_filename);
   
@@ -425,9 +425,29 @@
 {
 #ifdef MUSSERV
   char buffer[256];
+  sprintf(buffer, "%s", musserver_filename);
+  if (!access(buffer, X_OK))
+  {
+    strcat(buffer, " ");
+    strcat(buffer, musserver_options);
+    musserver = popen(buffer, "w");
+
+    { // Pass GENMIDI
+      int lump = W_GetNumForName("GENMIDI");
+      size_t len = W_LumpLength(lump);
+      fwrite(&len, 1, sizeof(size_t), musserver);
+      fwrite(W_CacheLumpNum(lump, PU_MUSIC), len, 1, musserver);
+      fflush(musserver);
+    }
+  }
+  else
+    fprintf(stderr, "Could not start music server [%s]\n", buffer);  
+#endif
+#if 0
+#ifdef MUSSERV
+  char buffer[256];
   int old_uid=-1;
-  
-  musserver_msgid=-1;
+//  musserver_msgid=-1;
   
   sprintf(buffer, "%s", musserver_filename);
   
@@ -446,7 +466,7 @@
       return;
     }
     /* give all permissions I can */
-    musserver_msgid=msgget(53075,IPC_CREAT | 0777);
+//    musserver_msgid=msgget(53075,IPC_CREAT | 0777);
     if (old_uid != -1)
       seteuid(old_uid);
   }
@@ -454,61 +474,105 @@
     fprintf(stderr,"Could not start music server [%s]\n",buffer);
   }
 #endif /* MUSSERV */
+#endif /* 0 */
 }
 
 void I_ShutdownMusic(void)
 {
 #ifdef MUSSERV
-  if (musserver_msgid != -1) {
+/*  if (musserver_msgid != -1) {
     if (msgctl(musserver_msgid,IPC_RMID,(struct msqid_ds *) NULL)) {
       fprintf(stderr,"I_ShutdownMusic failed: %s\n",strerror(errno));
     }
-  }
+  }*/
 #endif /* MUSSERV */
+#ifdef MUSSERV
+  if (musserver)
+  {
+     fprintf(musserver, "Q\n");
+     fflush(musserver);
+  }
+#endif
 }
 
 static int	looping=0;
 static int	musicdies=-1;
 
+typedef struct {
+  int loop;
+  unsigned long vol;
+  size_t len;
+} __attribute__ ((packed)) new_mus_desc;
+
+
 void I_PlaySong(int handle, int looping)
 {
-  /* UNUSED. */
-  handle = looping = 0;
-  musicdies = gametic + TICRATE*30;
+  if (musserver == NULL) return;
+
+//  mus_paused = 0;
+  if (mus_paused) I_ResumeSong(playing_handle);
+
+  if (playing_handle != 0) I_StopSong(playing_handle);
+
+  if (musdata == NULL)
+    fprintf(stderr, "I_PlaySong: no MUS data available\n");
+  else if (loaded_handle != handle)
+    fprintf(stderr, "I_PlaySong: non-current handle used\n");
+  else {
+    new_mus_desc nm;
+
+    nm.len = muslen;
+    nm.vol = snd_MusicVolume;
+    looping_current = nm.loop = looping;
+
+    putc('N',musserver);
+    fwrite(&nm, sizeof(nm), 1, musserver);
+    fwrite(musdata, nm.len, 1, musserver);
+
+    fflush(musserver);
+
+    playing_handle = handle;
+  }
+
 }
 
 void I_PauseSong (int handle)
 {
-  /* UNUSED. */
-  handle = 0;
+/*	if ((musserver == NULL) || (playing_handle == 0))
+		return;
+		
+	if (mus_paused) I_ResumeSong(playing_handle);
+	
+	fputc('S', musserver);
+	fflush(musserver);*/
 }
 
 void I_ResumeSong (int handle)
 {
-  /* UNUSED. */
-  handle = 0;
+//	I_PlaySong(playing_handle, looping_current);	
+	mus_paused = 0;
 }
 
 void I_StopSong(int handle)
 {
-  /* UNUSED. */
-  handle = 0;
-  
-  looping = 0;
-  musicdies = 0;
+	I_PauseSong(handle);
+	playing_handle = 0;
+	
 }
 
 void I_UnRegisterSong(int handle)
 {
-  /* UNUSED. */
-  handle = 0;
+  free(musdata);
+  musdata = NULL;
 }
 
-int I_RegisterSong(void* data)
+int I_RegisterSong(void* data, long len)
 {
-  /* UNUSED. */
-  data = NULL;
-  
+  if (musdata) free(musdata);
+  musdata = malloc(len);
+  memcpy(musdata, data, len);
+  muslen = len;
+  loaded_handle = 1;
   return 1;
 }
 
diff -uNr linux-heretic-0.9.5/soundclient/i_sound.h patched-linux-heretic-0.9.5/soundclient/i_sound.h
--- linux-heretic-0.9.5/soundclient/i_sound.h	Sat Jan 23 11:46:41 1999
+++ patched-linux-heretic-0.9.5/soundclient/i_sound.h	Thu Mar 11 13:11:32 1999
@@ -94,7 +94,7 @@
 void I_ResumeSong(int handle);
 
 /* Registers a song handle to song data. */
-int I_RegisterSong(void *data);
+int I_RegisterSong(void *data, long len);
 
 /*
  * Called by anything that wishes to start music.
diff -uNr linux-heretic-0.9.5/soundclient/soundst.c patched-linux-heretic-0.9.5/soundclient/soundst.c
--- linux-heretic-0.9.5/soundclient/soundst.c	Sat Jan 23 21:42:44 1999
+++ patched-linux-heretic-0.9.5/soundclient/soundst.c	Thu Mar 11 13:12:25 1999
@@ -65,11 +65,11 @@
 
 /* whether songs are mus_paused */
 #ifdef __DOMUSIC__
-static boolean		mus_paused;
+boolean		mus_paused;
 #endif /* __DOMUSIC__ */
 
 #ifdef __DOMUSIC__
-static musicinfo_t*	mus_playing=0;
+musicinfo_t*	mus_playing=0;
 #endif /* __DOMUSIC__ */
 
 /*
@@ -311,6 +311,9 @@
  */
 void S_Start(void)
 {
+#ifdef __DOMUSIC__
+  int mnum;
+#endif
 #ifdef __DOSOUND__
   int cnum;
   
@@ -324,7 +327,6 @@
 
   /* start new music for the level */
 #ifdef __DOMUSIC__
-  int mnum;
   mus_paused = 0;
   
   if (!shareware)
@@ -545,14 +547,14 @@
 
 void S_PauseSound(void)
 {
-#if 0 /* ToDo !!! */
+//#if 0 /* ToDo !!! */
   if (mus_playing && !mus_paused)
     {
       I_PauseSong(mus_playing->handle);
       mus_paused = true;
     }
 
-#endif
+//#endif
   
 #ifdef _DEBUGSOUND
   fprintf(stderr, "FIXME: Calling S_PauseSound...\n");
@@ -562,14 +564,14 @@
 
 void S_ResumeSound(void)
 {
-#if 0 /* ToDo !!! */
+//#if 0 /* ToDo !!! */
   if (mus_playing && mus_paused)
     {
       I_ResumeSong(mus_playing->handle);
       mus_paused = false;
     }
 
-#endif
+//#endif
 
 #ifdef _DEBUGSOUND
   fprintf(stderr, "FIXME: Calling S_ResumeSound...\n");
@@ -662,10 +664,10 @@
  */
 void S_StartMusic(int music_id)
 {
-#if 0 /* ToDo !!! */
+//#if 0 /* ToDo !!! */
   S_ChangeMusic(music_id, false);
 
-#endif
+//#endif
 
 #ifdef _DEBUGSOUND
   fprintf(stderr, "FIXME: Calling S_StartMusic...\n");
@@ -675,7 +677,7 @@
 
 void S_StopMusic(void)
 {
-#if 0 /* ToDo !!! */
+//#if 0 /* ToDo !!! */
   if (mus_playing)
     {
       if (mus_paused)
@@ -689,7 +691,7 @@
       mus_playing = 0;
     }
 
-#endif
+//#endif
 
 #ifdef _DEBUGSOUND
   fprintf(stderr, "FIXME: Calling S_StopMusic...\n");
@@ -699,7 +701,7 @@
 
 void S_ChangeMusic( int	music_id, int looping )
 {
-#if 0 /* ToDo !!! */
+//#if 0 /* ToDo !!! */
   musicinfo_t*	music;
   char		namebuf[9];
   
@@ -707,6 +709,7 @@
        || (music_id >= NUMMUSIC) )
     {
       I_Error("Bad music number %d", music_id);
+	return;
     }
   else
     music = &S_music[music_id];
@@ -720,25 +723,25 @@
   /* get lumpnum if neccessary */
   if (!music->lumpnum)
     {
-      sprintf(namebuf, "d_%s", music->name);
+      sprintf(namebuf, "%s", music->name);
       music->lumpnum = W_GetNumForName(namebuf);
     }
   
   /* load & register it */
   music->data = (void *) W_CacheLumpNum(music->lumpnum, PU_MUSIC);
-  music->handle = I_RegisterSong(music->data);
+  music->handle = I_RegisterSong(music->data, W_LumpLength(music->lumpnum));
   
 #ifdef MUSSERV
   
-  if (musserver_msgid != -1) {
+/*  if (musserver_msgid != -1) {
     struct musmsg msg_buffer;
     
-    sprintf(namebuf, "d_%s", music->name);
+    sprintf(namebuf, "%s", music->name);
     msg_buffer.msg_type=6;
     memset(msg_buffer.msg_text,0,sizeof(msg_buffer.msg_text));
     strcpy(msg_buffer.msg_text,namebuf);
     msgsnd(musserver_msgid,(struct msgbuf *)&msg_buffer,sizeof(msg_buffer.msg_text),IPC_NOWAIT);
-  }
+  }*/
   
 #endif /* #ifdef MUSSERV */
 
@@ -747,7 +750,7 @@
   
   mus_playing = music;
 
-#endif
+//#endif
 
 #ifdef _DEBUGSOUND
   fprintf(stderr, "FIXME: Calling S_ChangeMusic...\n");
@@ -757,21 +760,21 @@
 
 void S_SetMusicVolume(int volume)
 {
-#if 0 /* ToDo !!! */
+//#if 0 /* ToDo !!! */
   if (volume < 0 || volume > 127)
     {
       I_Error("Attempt to set music volume at %d",
 	      volume);
     }
   
-  I_SetMusicVolume(127);
+//  I_SetMusicVolume(127);
   I_SetMusicVolume(volume);
   snd_MusicVolume = volume;
 
-#endif
+//#endif
 
 #ifdef _DEBUGSOUND
-  fprintf(strerr, "FIXME: Calling S_SetMusicVolume...\n");
+  fprintf(stderr, "FIXME: Calling S_SetMusicVolume...\n");
 #endif
 }
 
diff -uNr linux-heretic-0.9.5/w_wad.c patched-linux-heretic-0.9.5/w_wad.c
--- linux-heretic-0.9.5/w_wad.c	Mon Feb  8 07:36:23 1999
+++ patched-linux-heretic-0.9.5/w_wad.c	Thu Mar 11 13:12:25 1999
@@ -52,13 +52,12 @@
  * =============== 
  */
 
-
 typedef struct
 {
   char		identification[4];	/* should be IWAD */
-  int		numlumps;
-  int		infotableofs;
-} wadinfo_t;
+  int		numlumps __attribute__ ((packed));
+  int		infotableofs __attribute__ ((packed));
+} __attribute__ ((packed)) wadinfo_t;
 
 
 typedef struct
@@ -66,7 +65,7 @@
   int		filepos;
   int		size;
   char		name[8];
-} filelump_t;
+}__attribute__ ((packed)) filelump_t;
 
 
 /* =============
